diff --git a/deps/mongoose b/deps/mongoose index 8d72c2a7..c151f9bc 160000 --- a/deps/mongoose +++ b/deps/mongoose @@ -1 +1 @@ -Subproject commit 8d72c2a7b22c36f72b0e0be5dd4b54439f2c57df +Subproject commit c151f9bc59969bced3841a53a3ab702752094dd1 diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp index 8f27afb1..08331447 100644 --- a/src/Components/Loader.cpp +++ b/src/Components/Loader.cpp @@ -64,6 +64,7 @@ namespace Components Loader::Register(new ServerInfo()); Loader::Register(new ServerList()); Loader::Register(new SlowMotion()); + Loader::Register(new ArenaLength()); Loader::Register(new StringTable()); Loader::Register(new ZoneBuilder()); Loader::Register(new AssetHandler()); diff --git a/src/Components/Loader.hpp b/src/Components/Loader.hpp index faba9e9a..25628481 100644 --- a/src/Components/Loader.hpp +++ b/src/Components/Loader.hpp @@ -77,6 +77,7 @@ namespace Components #include "Modules\ServerInfo.hpp" #include "Modules\ServerList.hpp" #include "Modules\SlowMotion.hpp" +#include "Modules\ArenaLength.hpp" #include "Modules\StringTable.hpp" #include "Modules\ZoneBuilder.hpp" #include "Modules\AssetHandler.hpp" diff --git a/src/Components/Modules/ArenaLength.cpp b/src/Components/Modules/ArenaLength.cpp new file mode 100644 index 00000000..b3a25922 --- /dev/null +++ b/src/Components/Modules/ArenaLength.cpp @@ -0,0 +1,117 @@ +#include "STDInclude.hpp" + +namespace Components +{ + Game::newMapArena_t ArenaLength::NewArenas[128]; + + __declspec(naked) void ArenaLength::ArenaMapOffsetHook1() + { + __asm + { + lea eax, [esi + Game::newMapArena_t::mapName] + push eax + push ebx + + push 420725h + retn + } + } + + __declspec(naked) void ArenaLength::ArenaMapOffsetHook2() + { + __asm + { + lea eax, [edi + Game::newMapArena_t::mapName] + push eax + push edx + + push 49BD3Eh + retn + } + } + + __declspec(naked) void ArenaLength::ArenaMapOffsetHook3() + { + __asm + { + lea eax, [esi + Game::newMapArena_t::mapName] + push eax + push edx + + push 63279Eh + retn + } + } + + __declspec(naked) void ArenaLength::ArenaMapOffsetHook4() + { + __asm + { + lea edi, [esi - Game::newMapArena_t::mapName] + lea edx, [eax + 1] + + push 4064B8h + retn + } + } + + ArenaLength::ArenaLength() + { + // Reallocate array + Utils::Hook::Set(0x417807, &ArenaLength::NewArenas[0]); + Utils::Hook::Set(0x420717, &ArenaLength::NewArenas[0]); + Utils::Hook::Set(0x49BD22, &ArenaLength::NewArenas[0]); + Utils::Hook::Set(0x4A9649, &ArenaLength::NewArenas[0]); + Utils::Hook::Set(0x4A97C2, &ArenaLength::NewArenas[0]); + Utils::Hook::Set(0x4D077E, &ArenaLength::NewArenas[0]); + Utils::Hook::Set(0x630B00, &ArenaLength::NewArenas[0]); + Utils::Hook::Set(0x630B2E, &ArenaLength::NewArenas[0]); + Utils::Hook::Set(0x632782, &ArenaLength::NewArenas[0]); + + Utils::Hook::Set(0x4A967A, &ArenaLength::NewArenas[0].other[0]); + + Utils::Hook::Set(0x4A96AD, &ArenaLength::NewArenas[0].other[0x20]); + + Utils::Hook::Set(0x42F214, &ArenaLength::NewArenas[0].other[0xA40]); + + Utils::Hook::Set(0x4A96ED, &ArenaLength::NewArenas[0].other[0xA48]); + Utils::Hook::Set(0x4A9769, &ArenaLength::NewArenas[0].other[0xA48]); + Utils::Hook::Set(0x4A97A5, &ArenaLength::NewArenas[0].other[0xA48]); + + Utils::Hook::Set(0x631E92, &ArenaLength::NewArenas[0].other[0xACC]); + + Utils::Hook::Set(0x4A9616, ArenaLength::NewArenas[0].mapName); + Utils::Hook::Set(0x4A9703, ArenaLength::NewArenas[0].mapName); + Utils::Hook::Set(0x4064A8, ArenaLength::NewArenas[0].mapName); + + // Resize the array + Utils::Hook::Set(0x4064DE, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x417802, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x420736, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x42F271, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x49BD4F, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x4A960C, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x4A963F, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x4A9675, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x4A96A3, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x4A96E7, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x4A96FD, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x4A975A, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x4A979F, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x4A97BC, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x4D0779, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x630B29, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x630B81, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x631EBC, sizeof(Game::newMapArena_t)); + Utils::Hook::Set(0x6327AF, sizeof(Game::newMapArena_t)); + + Utils::Hook(0x420720, ArenaLength::ArenaMapOffsetHook1, HOOK_JUMP).Install()->Quick(); + Utils::Hook(0x49BD39, ArenaLength::ArenaMapOffsetHook2, HOOK_JUMP).Install()->Quick(); + Utils::Hook(0x632799, ArenaLength::ArenaMapOffsetHook3, HOOK_JUMP).Install()->Quick(); + Utils::Hook(0x4064B2, ArenaLength::ArenaMapOffsetHook4, HOOK_JUMP).Install()->Quick(); + + Utils::Hook::Set(0x4A95F8, 32); + + Utils::Hook::Set(0x42F22B, offsetof(Game::newMapArena_t, mapName) - offsetof(Game::newMapArena_t, other[0xA40])); + } +} diff --git a/src/Components/Modules/ArenaLength.hpp b/src/Components/Modules/ArenaLength.hpp new file mode 100644 index 00000000..56ac5340 --- /dev/null +++ b/src/Components/Modules/ArenaLength.hpp @@ -0,0 +1,21 @@ +namespace Components +{ + class ArenaLength : public Component + { + public: + ArenaLength(); + +#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) + const char* GetName() { return "ArenaLength"; }; +#endif + + static Game::newMapArena_t NewArenas[128]; + + private: + static void ArenaMapOffsetHook1(); + static void ArenaMapOffsetHook2(); + static void ArenaMapOffsetHook3(); + static void ArenaMapOffsetHook4(); + static void ArenaMapOffsetHook5(); + }; +} diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 105b331b..714ac806 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -336,9 +336,9 @@ namespace Game { for (int i = 0; i < *arenaCount; ++i) { - if (!_stricmp(arenas[i].mapName, mapName)) + if (!_stricmp(Components::ArenaLength::NewArenas[i].mapName, mapName)) { - char* uiName = &arenas[i].uiName[0]; + char* uiName = &Components::ArenaLength::NewArenas[i].uiName[0]; if ((uiName[0] == 'M' && uiName[1] == 'P') || (uiName[0] == 'P' && uiName[1] == 'A')) // MPUI/PATCH { return SEH_StringEd_GetString(uiName); diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index dd2cf825..93a1a672 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -3012,6 +3012,14 @@ namespace Game char pad[2768]; }; + struct newMapArena_t + { + char uiName[32]; + char oldMapName[16]; + char other[2768]; + char mapName[32]; + }; + struct gameTypeName_t { char gameType[12];