diff --git a/src/Components/Modules/CardTitles.cpp b/src/Components/Modules/CardTitles.cpp index 84a2e50a..2aa7929b 100644 --- a/src/Components/Modules/CardTitles.cpp +++ b/src/Components/Modules/CardTitles.cpp @@ -144,12 +144,36 @@ namespace Components } } + void CardTitles::SendCustomTitlesToClients() + { + const char* list = ""; + + for (int i = 0; i < 18; i++) + { + char playerTitle[18] = { 0 }; + + if (Game::svs_clients[i].state >= 3) + { + strncpy_s(playerTitle, Game::Info_ValueForKey(Game::svs_clients[i].connectInfoString, "customTitle"), 18); + } + else + { + memset(playerTitle, 0, 18); + } + + list = Utils::String::VA("%s\\%s\\%s", list, std::to_string(i).c_str(), playerTitle); + } + + list = Utils::String::VA("%c customTitles \"%s", 20, list); + Game::SV_GameSendServerCommand(-1, 0, list); + } + void CardTitles::ParseCustomTitles(const char* msg) { const char* playerTitle; for (int i = 0; i < 18; i++) { - playerTitle = Utils::Hook::Call(0x47C820)(msg, std::to_string(i).c_str()); + playerTitle = Game::Info_ValueForKey(msg, std::to_string(i).c_str()); if (playerTitle != nullptr) { diff --git a/src/Components/Modules/CardTitles.hpp b/src/Components/Modules/CardTitles.hpp index a3d7839f..4e154b74 100644 --- a/src/Components/Modules/CardTitles.hpp +++ b/src/Components/Modules/CardTitles.hpp @@ -55,6 +55,7 @@ namespace Components public: static Game::dvar_t* CustomTitleDvar; + static void SendCustomTitlesToClients(); static void ParseCustomTitles(const char * msg); CardTitles(); @@ -71,5 +72,6 @@ namespace Components static const char* TableLookupByRowHook(Game::Operand * operand, tablelookuprequest_s * request); static void TableLookupByRowHookStub(); + }; } diff --git a/src/Components/Modules/Dedicated.cpp b/src/Components/Modules/Dedicated.cpp index ea99e51f..a711e1a6 100644 --- a/src/Components/Modules/Dedicated.cpp +++ b/src/Components/Modules/Dedicated.cpp @@ -452,6 +452,17 @@ namespace Components // Post initialization point Utils::Hook(0x60BFBF, Dedicated::PostInitializationStub, HOOK_JUMP).install()->quick(); + // Custom cardtitles + Dedicated::OnFrame([]() + { + static std::uint64_t LastUpdate = 0; + + if ((GetTickCount64() - LastUpdate) > 120 * 1000) + { + CardTitles::SendCustomTitlesToClients(); + } + }); + #ifdef USE_LEGACY_SERVER_LIST // Heartbeats diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 3b3f0834..948e5822 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -121,6 +121,8 @@ namespace Game Image_LoadFromFileWithReader_t Image_LoadFromFileWithReader = Image_LoadFromFileWithReader_t(0x53ABF0); Image_Release_t Image_Release = Image_Release_t(0x51F010); + Info_ValueForKey_t Info_ValueForKey = Info_ValueForKey_t(0x47C820); + Key_SetCatcher_t Key_SetCatcher = Key_SetCatcher_t(0x43BD00); LargeLocalInit_t LargeLocalInit = LargeLocalInit_t(0x4A62A0); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 8ff2aa51..669aea85 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -304,6 +304,9 @@ namespace Game typedef void(__cdecl * Image_Release_t)(GfxImage* image); extern Image_Release_t Image_Release; + typedef char*(__cdecl * Info_ValueForKey_t)(const char* infoString, const char* key); + extern Info_ValueForKey_t Info_ValueForKey; + typedef void(__cdecl * Key_SetCatcher_t)(int localClientNum, int catcher); extern Key_SetCatcher_t Key_SetCatcher;