diff --git a/src/game/game.cpp b/src/game/game.cpp index 4026fdd..2d469b7 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -8,6 +8,8 @@ namespace game Cmd_AddCommand_t Cmd_AddCommand; Cmd_RemoveCommand_t Cmd_RemoveCommand; + Cbuf_AddText_t Cbuf_AddText; + Com_Error_t Com_Error; Com_Filter_t Com_Filter; @@ -149,6 +151,8 @@ namespace game FastCriticalSection* db_hashCritSect; + const char** g_assetNames; + int Vec4Compare(const float* a, const float* b) { return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3]; @@ -451,12 +455,6 @@ namespace game addr->type = type; } - void Cbuf_AddText(LocalClientNum_t localClientNum, const char* text) - { - reinterpret_cast // - (SELECT_VALUE(0x457C90, 0x545680))(localClientNum, text); - } - void TeleportPlayer(gentity_s* player, float* origin, float* angles) { if (is_mp()) @@ -690,6 +688,8 @@ namespace game native::Cmd_AddCommand = native::Cmd_AddCommand_t(SELECT_VALUE(0x558820, 0x545DF0)); native::Cmd_RemoveCommand = native::Cmd_RemoveCommand_t(SELECT_VALUE(0x443A30, 0x545E20)); + native::Cbuf_AddText = native::Cbuf_AddText_t(SELECT_VALUE(0x457C90, 0x545680)); + native::Com_Error = native::Com_Error_t(SELECT_VALUE(0x425540, 0x555450)); native::Com_Filter = native::Com_Filter_t(SELECT_VALUE(0x44EFF0, 0x5B7C30)); @@ -845,5 +845,7 @@ namespace game native::sortedDvars = reinterpret_cast(SELECT_VALUE(0x1C423C0, 0x59CCE00)); native::db_hashCritSect = reinterpret_cast(SELECT_VALUE(0xFA9E7C, 0x18596E4)); + + native::g_assetNames = reinterpret_cast(SELECT_VALUE(0x92A688, 0x8AAB30)); } } diff --git a/src/game/game.hpp b/src/game/game.hpp index 6bb0ebd..63ecb15 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -17,6 +17,9 @@ namespace game typedef void (*Cmd_RemoveCommand_t)(const char* cmdName); extern Cmd_RemoveCommand_t Cmd_RemoveCommand; + typedef void (*Cbuf_AddText_t)(LocalClientNum_t localClientNum, const char* text); + extern Cbuf_AddText_t Cbuf_AddText; + typedef void (*Com_Error_t)(errorParm_t code, const char* fmt, ...); extern Com_Error_t Com_Error; @@ -258,6 +261,8 @@ namespace game extern FastCriticalSection* db_hashCritSect; + extern const char** g_assetNames; + // Global Definitions & Functions constexpr auto JUMP_LAND_SLOWDOWN_TIME = 1800; @@ -334,8 +339,6 @@ namespace game void NetAdr_SetType(netadr_s* addr, netadrtype_t type); - void Cbuf_AddText(LocalClientNum_t localClientNum, const char* text); - void TeleportPlayer(gentity_s* player, float* origin, float* angles); void CG_GameMessage(LocalClientNum_t localClientNum, const char* msg, int flags = 0); diff --git a/src/module/fastfiles.cpp b/src/module/fastfiles.cpp index b8e1566..4aae09e 100644 --- a/src/module/fastfiles.cpp +++ b/src/module/fastfiles.cpp @@ -6,17 +6,44 @@ #include -static __declspec(naked) void db_load_stub_client(game::native::XZoneInfo*, unsigned int, int) +namespace { - __asm - { - sub esp, 0Ch - mov eax, [esp + 18h] + utils::hook::detour db_find_x_asset_header_hook; - mov ecx, game::native::DB_LoadXAssets - add ecx, 7h - push ecx - ret + __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 + ret + } + } + + game::native::XAssetHeader db_find_x_asset_header_stub(game::native::XAssetType type, const char* name, int allow_create_default) + { + const auto start = game::native::Sys_Milliseconds(); + const auto result = db_find_x_asset_header_hook.invoke(type, name, allow_create_default); + const auto diff = game::native::Sys_Milliseconds() - start; + + if (diff > 100) + { + console::print( + result.data == nullptr + ? console::con_type_error + : console::con_type_warning, + "Waited %i msec for asset '%s' of type '%s'.\n", + diff, + name, + game::native::g_assetNames[type] + ); + } + + return result; } } @@ -26,6 +53,8 @@ public: void post_load() override { utils::hook(game::native::DB_LoadXAssets, db_load_stub, HOOK_JUMP).install()->quick(); + + db_find_x_asset_header_hook.create(game::native::DB_FindXAssetHeader, &db_find_x_asset_header_stub); } private: