diff --git a/src/Components/Modules/ClanTags.cpp b/src/Components/Modules/ClanTags.cpp index 89086c11..bc0da39e 100644 --- a/src/Components/Modules/ClanTags.cpp +++ b/src/Components/Modules/ClanTags.cpp @@ -44,7 +44,7 @@ namespace Components } else { - strncpy_s(ClientState[i], clanTag, _TRUNCATE); + Game::I_strncpyz(ClientState[i], clanTag, sizeof(ClientState[0]) / sizeof(char)); } } } @@ -74,20 +74,21 @@ namespace Components std::memset(saneNameBuf, 0, sizeof(saneNameBuf)); auto* saneName = saneNameBuf; - const auto* currentName = Game::Dvar_GetString("clanName"); + const auto* currentName = ClanName->current.string; if (currentName) { auto nameLen = std::strlen(currentName); - for (std::size_t i = 0; i < nameLen; ++i) + for (std::size_t i = 0; (i < nameLen) && (i < sizeof(saneNameBuf)); ++i) { auto curChar = CL_FilterChar(static_cast(currentName[i])); if (curChar > 0) { - *saneName++ = curChar & 0xFF; + *saneName++ = (curChar & 0xFF); } } - Game::Dvar_SetStringByName("clanName", saneNameBuf); + saneNameBuf[sizeof(saneNameBuf) - 1] = '\0'; + Game::Dvar_SetString(ClanName, saneNameBuf); } } @@ -96,7 +97,7 @@ namespace Components assert(static_cast(controllerIndex) < Game::MAX_LOCAL_CLIENTS); CL_SanitizeClanName(); - strncpy_s(Game::gamerSettings[0].exeConfig.clanPrefix, Game::Dvar_GetString("clanName"), _TRUNCATE); + Game::I_strncpyz(Game::gamerSettings[0].exeConfig.clanPrefix, ClanName->current.string, sizeof(Game::GamerSettingExeConfig::clanPrefix)); return Game::gamerSettings[controllerIndex].exeConfig.clanPrefix; } @@ -121,10 +122,8 @@ namespace Components } else { - strncpy_s(ClientState[clientNum], clanAbbrev, _TRUNCATE); + Game::I_strncpyz(ClientState[clientNum], clanAbbrev, sizeof(ClientState[0]) / sizeof(char)); } - - SendClanTagsToClients(); } void __declspec(naked) ClanTags::ClientUserinfoChanged_Stub() @@ -185,7 +184,7 @@ namespace Components void ClanTags::PlayerCards_SetCachedPlayerData(Game::PlayerCardData* data, const int clientNum) { - strncpy_s(data->clanAbbrev, ClientState[clientNum], _TRUNCATE); + Game::I_strncpyz(data->clanAbbrev, ClientState[clientNum], sizeof(Game::PlayerCardData::clanAbbrev)); } void __declspec(naked) ClanTags::PlayerCards_SetCachedPlayerData_Stub() @@ -214,7 +213,7 @@ namespace Components Game::PlayerCardData* ClanTags::PlayerCards_GetLiveProfileDataForClient_Stub(const unsigned int clientIndex) { auto* result = Utils::Hook::Call(0x46C0F0)(clientIndex); - strncpy_s(result->clanAbbrev, ClientState[clientIndex], _TRUNCATE); + Game::I_strncpyz(result->clanAbbrev, GamerProfile_GetClanName(static_cast(clientIndex)), sizeof(Game::PlayerCardData::clanAbbrev)); return result; } @@ -222,7 +221,8 @@ namespace Components Game::PlayerCardData* ClanTags::PlayerCards_GetLiveProfileDataForController_Stub(const unsigned int controllerIndex) { auto* result = Utils::Hook::Call(0x463B90)(controllerIndex); - strncpy_s(result->clanAbbrev, GamerProfile_GetClanName(static_cast(controllerIndex)), _TRUNCATE); // controllerIndex should always be 0 + // controllerIndex should always be 0 + Game::I_strncpyz(result->clanAbbrev, GamerProfile_GetClanName(static_cast(controllerIndex)), sizeof(Game::PlayerCardData::clanAbbrev)); return result; } @@ -230,7 +230,7 @@ namespace Components Game::PlayerCardData* ClanTags::PlayerCards_GetPartyMemberData(const int localClientNum, const Game::PlayerCardClientLookupType lookupType, const unsigned int memberIndex) { auto* result = Utils::Hook::Call(0x4A4A90)(localClientNum, lookupType, memberIndex); - strncpy_s(result->clanAbbrev, ClientState[memberIndex], _TRUNCATE); // controllerIndex should always be 0 + Game::I_strncpyz(result->clanAbbrev, ClientState[memberIndex], sizeof(Game::PlayerCardData::clanAbbrev)); return result; } diff --git a/src/Components/Modules/Dedicated.cpp b/src/Components/Modules/Dedicated.cpp index 436a13a4..e2172144 100644 --- a/src/Components/Modules/Dedicated.cpp +++ b/src/Components/Modules/Dedicated.cpp @@ -294,6 +294,7 @@ namespace Components Scheduler::Loop([] { CardTitles::SendCustomTitlesToClients(); + ClanTags::SendClanTagsToClients(); }, Scheduler::Pipeline::SERVER, 10s); // Heartbeats diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 5e4b2893..00d96a3f 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -471,6 +471,8 @@ namespace Game Z_VirtualAlloc_t Z_VirtualAlloc = Z_VirtualAlloc_t(0x4CFBA0); + I_strncpyz_t I_strncpyz = I_strncpyz_t(0x4D6F80); + XAssetHeader* DB_XAssetPool = reinterpret_cast(0x7998A8); unsigned int* g_poolSize = reinterpret_cast(0x7995E8); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index f7828d12..cc0b30f8 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -1131,6 +1131,9 @@ namespace Game typedef void*(__cdecl * Z_VirtualAlloc_t)(int size); extern Z_VirtualAlloc_t Z_VirtualAlloc; + typedef void(__cdecl * I_strncpyz_t)(char* dest, const char* src, int destsize); + extern I_strncpyz_t I_strncpyz; + constexpr std::size_t STATIC_MAX_LOCAL_CLIENTS = 1; constexpr std::size_t MAX_LOCAL_CLIENTS = 1; constexpr std::size_t MAX_CLIENTS = 18;