From 547948a3248dff89c55d7c7d89157636bf97c99f Mon Sep 17 00:00:00 2001 From: diamante0018 Date: Mon, 3 Feb 2025 20:49:48 +0100 Subject: [PATCH] fix(dedicated): remove loreless patch --- src/client/component/dedicated.cpp | 102 ++++++++++++++++++++++------- src/client/component/party.cpp | 88 ------------------------- src/client/component/party.hpp | 1 - src/client/component/patches.cpp | 19 ++++++ src/client/game/symbols.hpp | 3 +- 5 files changed, 101 insertions(+), 112 deletions(-) diff --git a/src/client/component/dedicated.cpp b/src/client/component/dedicated.cpp index ccc66ad..18ed590 100644 --- a/src/client/component/dedicated.cpp +++ b/src/client/component/dedicated.cpp @@ -3,12 +3,14 @@ #include "game/game.hpp" #include "game/engine/sv_game.hpp" +#include "command.hpp" #include "console.hpp" +#include "dvars.hpp" +#include "network.hpp" #include "scheduler.hpp" #include "server_list.hpp" -#include "network.hpp" -#include "command.hpp" -#include "dvars.hpp" + +#include "component/gsc/script_extension.hpp" #include #include @@ -17,9 +19,6 @@ namespace dedicated { namespace { - utils::hook::detour gscr_set_dynamic_dvar_hook; - utils::hook::detour com_quit_f_hook; - const game::dvar_t* sv_lanOnly; void init_dedicated_server() @@ -109,23 +108,53 @@ namespace dedicated std::this_thread::sleep_for(1ms); } - void gscr_set_dynamic_dvar() + void sv_kill_server_f() { - auto s = game::Scr_GetString(0); - auto* dvar = game::Dvar_FindVar(s); - if (dvar && !std::strncmp("scr_", dvar->name, 4)) + game::Com_Shutdown("EXE_SERVERKILLED"); + } + + void start_map(const std::string& map_name) + { + if (game::Live_SyncOnlineDataFlags(0) > 32) { + scheduler::once([map_name]() + { + command::execute(std::format("map {}", map_name), false); + }, scheduler::pipeline::main, 1s); + return; } - gscr_set_dynamic_dvar_hook.invoke(); + if (!game::SV_MapExists(map_name.c_str())) + { + console::info("Map '%s' doesn't exist.\n", map_name.c_str()); + return; + } + + auto* current_mapname = game::Dvar_FindVar("mapname"); + if (current_mapname && utils::string::to_lower(current_mapname->current.string) == utils::string::to_lower(map_name) && (game::SV_Loaded() && !game::VirtualLobby_Loaded())) + { + console::info("Restarting map: %s\n", map_name.c_str()); + command::execute("map_restart", false); + return; + } + + console::info("Starting map: %s\n", map_name.c_str()); + + auto* gametype = game::Dvar_FindVar("g_gametype"); + if (gametype && gametype->current.string) + { + command::execute(utils::string::va("ui_gametype %s", gametype->current.string), true); + } + + command::execute(utils::string::va("ui_mapname %s", map_name.c_str()), true); + + game::SV_StartMapForParty(0, map_name.c_str(), false, false); } - void kill_server() + void gscr_is_using_match_rules_data_stub() { - game::engine::SV_GameSendServerCommand(-1, game::SV_CMD_CAN_IGNORE, utils::string::va("r \"%s\"", "EXE_ENDOFGAME")); - - com_quit_f_hook.invoke(); + game::Scr_AddInt(0); } } @@ -164,10 +193,12 @@ namespace dedicated // Don't allow sv_hostname to be changed by the game dvars::disable::set_string("sv_hostname"); - // Hook R_SyncGpu utils::hook::jump(0x1405A7630, sync_gpu_stub); + // Make GScr_IsUsingMatchRulesData return 0 so the game doesn't override the cfg + gsc::override_function("isusingmatchrulesdata", gscr_is_using_match_rules_data_stub); + utils::hook::jump(0x14020C6B0, init_dedicated_server); // delay startup commands until the initialization is done @@ -177,9 +208,6 @@ namespace dedicated utils::hook::call(0x1403CEC35, execute_console_command); utils::hook::nop(0x1403CEC4B, 5); - // patch GScr_SetDynamicDvar to behave better - gscr_set_dynamic_dvar_hook.create(0x140312D00, &gscr_set_dynamic_dvar); - utils::hook::nop(0x1404AE6AE, 5); // don't load config file utils::hook::nop(0x1403AF719, 5); // ^ utils::hook::set(0x1403D2490, 0xC3); // don't save config file @@ -278,7 +306,7 @@ namespace dedicated console::info("==================================\n"); // remove disconnect command - game::Cmd_RemoveCommand(reinterpret_cast(751)); + game::Cmd_RemoveCommand(751); execute_startup_command_queue(); execute_console_command_queue(); @@ -289,8 +317,38 @@ namespace dedicated command::add("heartbeat", send_heartbeat); }, scheduler::pipeline::main, 1s); - command::add("killserver", kill_server); - com_quit_f_hook.create(0x1403D08C0, &kill_server); + command::add("killserver", sv_kill_server_f); + + command::add("map", [](const command::params& argument) + { + if (argument.size() != 2) + { + return; + } + + start_map(argument[1]); + }); + + command::add("map_restart", []() + { + if (!game::SV_Loaded() || game::VirtualLobby_Loaded()) + { + return; + } + + *reinterpret_cast(0x1488692B0) = 1; // sv_map_restart + *reinterpret_cast(0x1488692B4) = 1; // sv_loadScripts + *reinterpret_cast(0x1488692B8) = 0; // sv_migrate + reinterpret_cast(0x140437460)(0); // SV_CheckLoadGame + }); + + command::add("fast_restart", []() + { + if (game::SV_Loaded() && !game::VirtualLobby_Loaded()) + { + game::SV_FastRestart(0); + } + }); } }; } diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index 1749047..8f94790 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -227,64 +227,6 @@ namespace party network::send(target, "getInfo", connect_state.challenge); } - void start_map(const std::string& mapname) - { - if (game::Live_SyncOnlineDataFlags(0) > 32) - { - scheduler::once([=]() - { - command::execute("map " + mapname, false); - }, scheduler::pipeline::main, 1s); - } - else - { - if (!game::SV_MapExists(mapname.data())) - { - console::info("Map '%s' doesn't exist.\n", mapname.data()); - return; - } - - auto* current_mapname = game::Dvar_FindVar("mapname"); - if (current_mapname && utils::string::to_lower(current_mapname->current.string) == - utils::string::to_lower(mapname) && (game::SV_Loaded() && !game::VirtualLobby_Loaded())) - { - console::info("Restarting map: %s\n", mapname.data()); - command::execute("map_restart", false); - return; - } - - if (!game::environment::is_dedi()) - { - if (game::SV_Loaded()) - { - const auto* args = "Leave"; - game::UI_RunMenuScript(0, &args); - } - - perform_game_initialization(); - } - - console::info("Starting map: %s\n", mapname.data()); - - auto* gametype = game::Dvar_FindVar("g_gametype"); - if (gametype && gametype->current.string) - { - command::execute(utils::string::va("ui_gametype %s", gametype->current.string), true); - } - command::execute(utils::string::va("ui_mapname %s", mapname.data()), true); - - /*auto* maxclients = game::Dvar_FindVar("sv_maxclients"); - if (maxclients) - { - command::execute(utils::string::va("ui_maxclients %i", maxclients->current.integer), true); - command::execute(utils::string::va("party_maxplayers %i", maxclients->current.integer), true); - }*/ - - const auto* args = "StartServer"; - game::UI_RunMenuScript(0, &args); - } - } - int server_client_count() { return sv_maxclients; @@ -315,36 +257,6 @@ namespace party // enable custom kick reason in GScr_KickPlayer utils::hook::set(0x14032ED80, 0xEB); - command::add("map", [](const command::params& argument) - { - if (argument.size() != 2) - { - return; - } - - start_map(argument[1]); - }); - - command::add("map_restart", []() - { - if (!game::SV_Loaded() || game::VirtualLobby_Loaded()) - { - return; - } - *reinterpret_cast(0x1488692B0) = 1; // sv_map_restart - *reinterpret_cast(0x1488692B4) = 1; // sv_loadScripts - *reinterpret_cast(0x1488692B8) = 0; // sv_migrate - reinterpret_cast(0x140437460)(0); // SV_CheckLoadGame - }); - - command::add("fast_restart", []() - { - if (game::SV_Loaded() && !game::VirtualLobby_Loaded()) - { - game::SV_FastRestart(0); - } - }); - command::add("reconnect", [](const command::params& argument) { if (!connect_state.hostDefined) diff --git a/src/client/component/party.hpp b/src/client/component/party.hpp index 4c45014..f9d452a 100644 --- a/src/client/component/party.hpp +++ b/src/client/component/party.hpp @@ -5,7 +5,6 @@ namespace party void reset_connect_state(); void connect(const game::netadr_s& target); - void start_map(const std::string& mapname); void clear_sv_motd(); int server_client_count(); diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 7cbfdbe..b71cebc 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -20,6 +20,8 @@ namespace patches { namespace { + utils::hook::detour com_quit_f_hook; + utils::hook::detour sv_shutdown_hook; utils::hook::detour live_get_local_client_name_hook; const char* live_get_local_client_name() @@ -186,6 +188,20 @@ namespace patches cmd_lui_notify_server_hook.invoke(ent); } + + void sv_shutdown_stub(const char* finalmsg) + { + console::info("----- Server Shutdown -----\n"); + + sv_shutdown_hook.invoke(finalmsg); + } + + void com_quit_f_stub() + { + console::info("quitting...\n"); + + com_quit_f_hook.invoke(); + } } class component final : public component_interface @@ -313,6 +329,9 @@ namespace patches // Prevent clients from ending the game as non host by sending 'end_game' lui notification cmd_lui_notify_server_hook.create(0x1402E9390, cmd_lui_notify_server_stub); + + com_quit_f_hook.create(0x1403D08C0, com_quit_f_stub); + sv_shutdown_hook.create(0x140440170, sv_shutdown_stub); } static void patch_sp() diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 6b35668..3ff18aa 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -23,10 +23,11 @@ namespace game WEAK symbol Com_GetCurrentCoDPlayMode{0, 0x1404C9690}; WEAK symbol Com_SetSlowMotion{0, 0x1403D19B0}; WEAK symbol Com_Quit_f{0x1402F9390, 0x1403D08C0}; + WEAK symbol Com_Shutdown{0x0, 0x1403D1BF0}; WEAK symbol Cmd_AddCommandInternal{0x1402EDDB0, 0x1403AF2C0}; WEAK symbol Cmd_ExecuteSingleCommand{0x1402EE350, 0x1403AF900}; - WEAK symbol Cmd_RemoveCommand{0x1402EE910, 0x1403AFEF0}; + WEAK symbol Cmd_RemoveCommand{0x1402EE910, 0x1403AFEF0}; WEAK symbol Cmd_TokenizeString{0x1402EEA30, 0x1403B0020}; WEAK symbol Cmd_EndTokenizeString{0x1402EE000, 0x1403AF5B0};