diff --git a/src/game/game.cpp b/src/game/game.cpp index fcb3d77..ea0333b 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -9,6 +9,8 @@ namespace game Conbuf_AppendText_t Conbuf_AppendText; + DB_LoadXAssets_t DB_LoadXAssets; + Sys_ShowConsole_t Sys_ShowConsole; int* cmd_args; @@ -42,6 +44,8 @@ namespace game native::Conbuf_AppendText = native::Conbuf_AppendText_t(SELECT_VALUE(0x4C84E0, 0x5CF610, 0x53C790)); + native::DB_LoadXAssets = native::DB_LoadXAssets_t(SELECT_VALUE(0x48A8E0, 0x4CD020, 0x44F770)); + native::Sys_ShowConsole = native::Sys_ShowConsole_t(SELECT_VALUE(0x470AF0, 0x5CF590, 0)); native::cmd_args = reinterpret_cast(SELECT_VALUE(0x1750750, 0x1C978D0, 0x1B455F8)); diff --git a/src/game/game.hpp b/src/game/game.hpp index a635bac..57bbc1f 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -9,12 +9,15 @@ namespace game { namespace native { - typedef void (*Cmd_AddCommand_t)(const char* cmdName, void(*function)(), cmd_function_t* allocedCmd); + typedef void (*Cmd_AddCommand_t)(const char* cmdName, void (*function)(), cmd_function_t* allocedCmd); extern Cmd_AddCommand_t Cmd_AddCommand; typedef void (*Conbuf_AppendText_t)(const char* message); extern Conbuf_AppendText_t Conbuf_AppendText; + typedef void (*DB_LoadXAssets_t)(XZoneInfo* zoneInfo, unsigned int zoneCount, int sync); + extern DB_LoadXAssets_t DB_LoadXAssets; + typedef void (*Sys_ShowConsole_t)(); extern Sys_ShowConsole_t Sys_ShowConsole; diff --git a/src/game/structs.hpp b/src/game/structs.hpp index 8df2f05..9fb06e5 100644 --- a/src/game/structs.hpp +++ b/src/game/structs.hpp @@ -378,5 +378,12 @@ namespace game void (__cdecl *function)(); int flags; } cmd_function_t; + + struct XZoneInfo + { + const char* name; + int allocFlags; + int freeFlags; + }; } } diff --git a/src/module/ceg.cpp b/src/module/ceg.cpp index 9516547..706c814 100644 --- a/src/module/ceg.cpp +++ b/src/module/ceg.cpp @@ -77,17 +77,13 @@ public: signature.process(); // Function fixup - utils::hook(0x4CA310, 0x48A8E0, HOOK_JUMP).install()->quick(); // DB_LoadXAssets + utils::hook(0x4CA310, game::native::DB_LoadXAssets, HOOK_JUMP).install()->quick(); // Some value obfuscation utils::hook(0x493B81, 0x493BFC, HOOK_JUMP).install()->quick(); // CEG uninitialization utils::hook::set(0x527110, 0xC3); - - // SP doesn't initialize WSA - WSADATA wsa_data; - WSAStartup(MAKEWORD(2, 2), &wsa_data); } }; diff --git a/src/module/fastfiles.cpp b/src/module/fastfiles.cpp new file mode 100644 index 0000000..29157bc --- /dev/null +++ b/src/module/fastfiles.cpp @@ -0,0 +1,60 @@ +#include +#include "loader/module_loader.hpp" +#include "game/structs.hpp" +#include "game/game.hpp" +#include "utils/hook.hpp" + +static __declspec(naked) void db_load_stub_client(game::native::XZoneInfo*, unsigned int, int) +{ + __asm + { + sub esp, 0Ch + mov eax, [esp + 18h] + + mov ecx, game::native::DB_LoadXAssets + add ecx, 7h + push ecx + retn + } +} + +static __declspec(naked) void db_load_stub_server(game::native::XZoneInfo*, unsigned int, int) +{ + __asm + { + sub esp, 10h + mov eax, [esp + 1Ch] + + mov ecx, game::native::DB_LoadXAssets + add ecx, 7h + push ecx + retn + } +} + +class fastfiles final : public module +{ +public: + void post_load() override + { + utils::hook(game::native::DB_LoadXAssets, db_load_stub, HOOK_JUMP).install()->quick(); + } + +private: + static void db_load_stub(game::native::XZoneInfo* zone_info, const unsigned int zone_count, const int sync) + { + for (unsigned int i = 0; i < zone_count; ++i) + { + if (zone_info[i].name) + { + printf("Loading FastFile: %s (0x%X | 0x%X)\n", zone_info[i].name, zone_info[i].allocFlags, + zone_info[i].freeFlags); + } + } + + if (game::is_dedi()) return db_load_stub_server(zone_info, zone_count, sync); + else return db_load_stub_client(zone_info, zone_count, sync); + } +}; + +REGISTER_MODULE(fastfiles)