From d739b1c6f9f59a33bea2fd3e4808903f031cd60c Mon Sep 17 00:00:00 2001 From: FutureRave Date: Thu, 10 Mar 2022 12:32:22 +0000 Subject: [PATCH] Fix some stuff --- premake5.lua | 5 ++--- src/game/game.cpp | 38 +++++++++++++++++++++++++++++++++++-- src/game/game.hpp | 7 +++++++ src/module/test_clients.cpp | 18 ++++++++++++------ src/utils/flags.cpp | 1 + 5 files changed, 58 insertions(+), 11 deletions(-) diff --git a/premake5.lua b/premake5.lua index 36bdf27..4f1c1be 100644 --- a/premake5.lua +++ b/premake5.lua @@ -69,9 +69,8 @@ workspace "open-iw5" filter {} filter "configurations:Release" - optimize "Size" - buildoptions { "/GL" } - linkoptions { "/IGNORE:4702", "/LTCG" } + optimize "Full" + buildoptions { "/Os" } defines { "NDEBUG" } flags { "FatalCompileWarnings" } filter {} diff --git a/src/game/game.cpp b/src/game/game.cpp index ec4b347..6ddbf5d 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -45,6 +45,8 @@ namespace game SV_Cmd_EndTokenizedString_t SV_Cmd_EndTokenizedString; + XUIDToString_t XUIDToString; + decltype(longjmp)* _longjmp; CmdArgs* sv_cmd_args; @@ -183,6 +185,31 @@ namespace game return scrMemTreeGlob + 12 * size_t(MT_AllocIndex(numBytes, type)); } + __declspec(naked) dvar_t* dvar_find_malleable_var(const char* dvarName) + { + static DWORD func = 0x531320; + + __asm + { + mov edi, dvarName + call func + retn + } + } + + dvar_t* Dvar_FindVar(const char* dvarName) + { + if (is_dedi()) + { + return dvar_find_malleable_var(dvarName); + } + else + { + return reinterpret_cast + (SELECT_VALUE(0x539550, 0x5BDCC0, 0x0))(dvarName); + } + } + const float* Scr_AllocVector(const float* v) { const auto mem = static_cast(MT_Alloc(16, 2)); @@ -309,7 +336,7 @@ namespace game } } - void scr_add_string_dedi(const char* value) + __declspec(naked) void scr_add_string_dedi(const char* value) { static DWORD func = 0x4F1010; @@ -399,7 +426,7 @@ namespace game if (mp::svs_clients[i].header.state != CS_FREE && mp::svs_clients[i].header.netchan.remoteAddress.type == NA_BOT) { - SV_DropClient(&mp::svs_clients[i], "EXE_TIMEDOUT", 1); + SV_DropClient(&mp::svs_clients[i], "EXE_TIMEDOUT", true); } } } @@ -411,6 +438,11 @@ namespace game sv_drop_all_bots_mp(); } } + + int GetProtocolVersion() + { + return 0x507C; + } } launcher::mode mode = launcher::mode::none; @@ -487,6 +519,8 @@ namespace game native::SV_Cmd_EndTokenizedString = native::SV_Cmd_EndTokenizedString_t(SELECT_VALUE(0x0, 0x545D70, 0x0)); + native::XUIDToString = native::XUIDToString_t(SELECT_VALUE(0x4FAA30, 0x55CC20, 0x0)); + native::_longjmp = reinterpret_cast(SELECT_VALUE(0x73AC20, 0x7363BC, 0x655558)); native::sv_cmd_args = reinterpret_cast(SELECT_VALUE(0x0, 0x1CAA998, 0x1B5E7D8)); diff --git a/src/game/game.hpp b/src/game/game.hpp index b0af38b..3176e70 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -71,6 +71,9 @@ namespace game typedef void (*SV_Cmd_EndTokenizedString_t)(); extern SV_Cmd_EndTokenizedString_t SV_Cmd_EndTokenizedString; + typedef void (*XUIDToString_t)(const unsigned __int64* xuid, char* str); + extern XUIDToString_t XUIDToString; + extern decltype(longjmp)* _longjmp; extern CmdArgs* sv_cmd_args; @@ -114,6 +117,8 @@ namespace game void* MT_Alloc(int numBytes, int type); + dvar_t* Dvar_FindVar(const char* dvarName); + const float* Scr_AllocVector(const float* v); void Scr_ClearOutParams(); scr_entref_t Scr_GetEntityIdRef(unsigned int id); @@ -129,6 +134,8 @@ namespace game int SV_IsTestClient(int clientNum); void SV_DropClient(mp::client_t* drop, const char* reason, bool tellThem); void SV_DropAllBots(); + + int GetProtocolVersion(); } bool is_mp(); diff --git a/src/module/test_clients.cpp b/src/module/test_clients.cpp index 8aff365..f6d7641 100644 --- a/src/module/test_clients.cpp +++ b/src/module/test_clients.cpp @@ -30,13 +30,20 @@ game::native::gentity_s* test_clients::sv_add_test_client() return nullptr; } + assert(game::native::Dvar_FindVar("sv_running")->current.enabled); + assert(game::native::Dvar_FindVar("sv_maxclients")->current.integer <= *game::native::svs_clientCount); + static auto bot_port = 0; char user_info[1024] = {0}; + char xuid[32] = {0}; - // Most basic string the game will accept. Xuid and Xnaddr can be empty + const std::uint64_t random_xuid = std::rand(); + game::native::XUIDToString(&random_xuid, xuid); + + // Most basic string the game will accept. _snprintf_s(user_info, _TRUNCATE, "connect bot%d \"\\invited\\0\\cl_anonymous\\0\\color\\4\\head\\default\\model\\multi\\snaps\\20\\rate\\5000\\name\\bot%d\\xuid\\%s\\xnaddr\\%s\\natType\\2\\protocol\\%d\\checksum\\%u\\statver\\%d %u\"", - bot_port, bot_port, "", "", 0x507C, game::native::BG_NetDataChecksum(), + bot_port, bot_port, xuid, "", game::native::GetProtocolVersion(), game::native::BG_NetDataChecksum(), game::native::LiveStorage_GetPersistentDataDefVersion(), game::native::LiveStorage_GetPersistentDataDefFormatChecksum()); game::native::netadr_s adr; @@ -50,8 +57,8 @@ game::native::gentity_s* test_clients::sv_add_test_client() game::native::SV_Cmd_EndTokenizedString(); // Find the bot - auto idx = 0; - while (idx < *game::native::svs_clientCount) + auto idx = 1; + for (idx = 0; idx < *game::native::svs_clientCount; idx++) { if (game::native::mp::svs_clients[idx].header.state == game::native::clientState_t::CS_FREE) continue; @@ -121,7 +128,6 @@ __declspec(naked) void test_clients::reset_reliable_mp() cmp [esi + 0x41CB4], 1 // bIsTestClient jnz resume - push eax mov eax, [esi + 0x20E70] // Move reliableSequence to eax mov [esi + 0x20E74], eax // Move eax to reliableAcknowledge @@ -165,7 +171,7 @@ void test_clients::post_load() if (game::is_mp()) this->patch_mp(); else return; // No sp/dedi bots for now :( - command::add("spawnBot", [](const std::vector& params) + command::add("spawnBot", []([[maybe_unused]] const std::vector& params) { // Because I am unable to expand the scheduler at the moment // we only get one bot at the time diff --git a/src/utils/flags.cpp b/src/utils/flags.cpp index b099639..c86e6cf 100644 --- a/src/utils/flags.cpp +++ b/src/utils/flags.cpp @@ -34,6 +34,7 @@ namespace utils::flags if (!parsed) { parse_flags(enabled_flags); + parsed = true; } for (const auto& entry : enabled_flags)