[ClanTag] Add back component + extras (#357)
* [ClanTags] Add back component
This commit is contained in:
parent
e961f70fda
commit
491d4d3ac3
@ -61,7 +61,7 @@ namespace Components
|
|||||||
Loader::Register(new Network());
|
Loader::Register(new Network());
|
||||||
Loader::Register(new Session());
|
Loader::Register(new Session());
|
||||||
Loader::Register(new Theatre());
|
Loader::Register(new Theatre());
|
||||||
//Loader::Register(new ClanTags());
|
Loader::Register(new ClanTags());
|
||||||
Loader::Register(new Download());
|
Loader::Register(new Download());
|
||||||
Loader::Register(new Playlist());
|
Loader::Register(new Playlist());
|
||||||
Loader::Register(new RawFiles());
|
Loader::Register(new RawFiles());
|
||||||
|
@ -366,7 +366,7 @@ namespace Components
|
|||||||
// In case a loaded mod didn't call "BotStop" before the VM shutdown
|
// In case a loaded mod didn't call "BotStop" before the VM shutdown
|
||||||
Events::OnVMShutdown([]
|
Events::OnVMShutdown([]
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < std::extent_v<decltype(g_botai)>; i++)
|
for (std::size_t i = 0; i < std::extent_v<decltype(g_botai)>; ++i)
|
||||||
{
|
{
|
||||||
g_botai[i].active = false;
|
g_botai[i].active = false;
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,14 @@
|
|||||||
namespace Components
|
namespace Components
|
||||||
{
|
{
|
||||||
std::string CardTitles::CustomTitles[18];
|
std::string CardTitles::CustomTitles[18];
|
||||||
Dvar::Var CardTitles::CustomTitleDvar;
|
Dvar::Var CardTitles::CustomTitle;
|
||||||
|
|
||||||
CClient* CardTitles::GetClientByIndex(std::uint32_t index)
|
CClient* CardTitles::GetClientByIndex(std::uint32_t index)
|
||||||
{
|
{
|
||||||
return &reinterpret_cast<CClient*>(0x8E77B0)[index];
|
return &reinterpret_cast<CClient*>(0x8E77B0)[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::int32_t CardTitles::GetPlayerCardClientInfo(std::int32_t lookupResult, playercarddata_s* data)
|
std::int32_t CardTitles::GetPlayerCardClientInfo(std::int32_t lookupResult, Game::PlayerCardData* data)
|
||||||
{
|
{
|
||||||
std::int32_t returnResult = lookupResult;
|
std::int32_t returnResult = lookupResult;
|
||||||
|
|
||||||
@ -22,12 +22,12 @@ namespace Components
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (auto clientNum = 0; clientNum < 18; clientNum++)
|
for (std::size_t clientNum = 0; clientNum < Game::MAX_CLIENTS; ++clientNum)
|
||||||
{
|
{
|
||||||
CClient* c = GetClientByIndex(clientNum);
|
CClient* c = GetClientByIndex(clientNum);
|
||||||
if (c != nullptr)
|
if (c != nullptr)
|
||||||
{
|
{
|
||||||
if (!strcmp(data->name, c->Name))
|
if (!std::strcmp(data->name, c->Name))
|
||||||
{
|
{
|
||||||
// Since a 4 byte integer is overkill for a row num: We can use it to store the customprefix + clientNum and use a 2 byte integer for the row number
|
// Since a 4 byte integer is overkill for a row num: We can use it to store the customprefix + clientNum and use a 2 byte integer for the row number
|
||||||
returnResult += 0xFF000000;
|
returnResult += 0xFF000000;
|
||||||
@ -62,7 +62,6 @@ namespace Components
|
|||||||
mov [ebx + 4], eax
|
mov [ebx + 4], eax
|
||||||
pop ebx
|
pop ebx
|
||||||
|
|
||||||
push 62EB2Ch
|
|
||||||
retn
|
retn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,10 +82,10 @@ namespace Components
|
|||||||
{
|
{
|
||||||
if (prefix == 0xFE)
|
if (prefix == 0xFE)
|
||||||
{
|
{
|
||||||
if (!CardTitles::CustomTitleDvar.get<std::string>().empty())
|
if (!CardTitles::CustomTitle.get<std::string>().empty())
|
||||||
{
|
{
|
||||||
// 0xFF in front of the title to skip localization. Or else it will wait for a couple of seconds for the asset of type localize
|
// 0xFF in front of the title to skip localization. Or else it will wait for a couple of seconds for the asset of type localize
|
||||||
const char* title = Utils::String::VA("\x15%s", CardTitles::CustomTitleDvar.get<const char*>());
|
const char* title = Utils::String::VA("\x15%s", CardTitles::CustomTitle.get<const char*>());
|
||||||
|
|
||||||
// prepare return value
|
// prepare return value
|
||||||
operand->internals.stringVal.string = title;
|
operand->internals.stringVal.string = title;
|
||||||
@ -157,20 +156,20 @@ namespace Components
|
|||||||
{
|
{
|
||||||
std::string list;
|
std::string list;
|
||||||
|
|
||||||
for (int i = 0; i < 18; i++)
|
for (std::size_t i = 0; i < Game::MAX_CLIENTS; i++)
|
||||||
{
|
{
|
||||||
char playerTitle[18];
|
char playerTitle[18];
|
||||||
|
|
||||||
if (Game::svs_clients[i].state >= 3)
|
if (Game::svs_clients[i].state >= Game::CS_CONNECTED)
|
||||||
{
|
{
|
||||||
strncpy_s(playerTitle, Game::Info_ValueForKey(Game::svs_clients[i].connectInfoString, "customTitle"), 17);
|
strncpy_s(playerTitle, Game::Info_ValueForKey(Game::svs_clients[i].userinfo, "customTitle"), _TRUNCATE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memset(playerTitle, 0, 18);
|
playerTitle[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
list.append(Utils::String::VA("\\%s\\%s", std::to_string(i).c_str(), playerTitle));
|
list.append(Utils::String::VA("\\%s\\%s", std::to_string(i).data(), playerTitle));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto* command = Utils::String::VA("%c customTitles \"%s\"", 21, list.data());
|
const auto* command = Utils::String::VA("%c customTitles \"%s\"", 21, list.data());
|
||||||
@ -179,7 +178,7 @@ namespace Components
|
|||||||
|
|
||||||
void CardTitles::ParseCustomTitles(const char* msg)
|
void CardTitles::ParseCustomTitles(const char* msg)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 18; ++i)
|
for (std::size_t i = 0; i < Game::MAX_CLIENTS; ++i)
|
||||||
{
|
{
|
||||||
const char* playerTitle = Game::Info_ValueForKey(msg, std::to_string(i).c_str());
|
const char* playerTitle = Game::Info_ValueForKey(msg, std::to_string(i).c_str());
|
||||||
|
|
||||||
@ -192,7 +191,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
Scheduler::Once([]
|
Scheduler::Once([]
|
||||||
{
|
{
|
||||||
CardTitles::CustomTitleDvar = Dvar::Register<const char*>("customtitle", "", Game::DVAR_USERINFO | Game::DVAR_ARCHIVE, "Custom card title");
|
CardTitles::CustomTitle = Dvar::Register<const char*>("customTitle", "", Game::DVAR_USERINFO | Game::DVAR_ARCHIVE, "Custom card title");
|
||||||
}, Scheduler::Pipeline::MAIN);
|
}, Scheduler::Pipeline::MAIN);
|
||||||
|
|
||||||
ServerCommands::OnCommand(21, [](Command::Params* params)
|
ServerCommands::OnCommand(21, [](Command::Params* params)
|
||||||
@ -215,8 +214,5 @@ namespace Components
|
|||||||
// Table lookup stuff
|
// Table lookup stuff
|
||||||
Utils::Hook(0x62DCC1, CardTitles::TableLookupByRowHookStub).install()->quick();
|
Utils::Hook(0x62DCC1, CardTitles::TableLookupByRowHookStub).install()->quick();
|
||||||
Utils::Hook::Nop(0x62DCC6, 1);
|
Utils::Hook::Nop(0x62DCC6, 1);
|
||||||
|
|
||||||
// This is placed here in case the anticheat has been disabled!
|
|
||||||
// This checks specifically for launching the process suspended to inject a dll
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,18 +12,6 @@ namespace Components
|
|||||||
std::int32_t tableColumn;
|
std::int32_t tableColumn;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct playercarddata_s
|
|
||||||
{
|
|
||||||
std::uint32_t padding;
|
|
||||||
std::uint32_t playercardNumber;
|
|
||||||
std::uint32_t unknown;
|
|
||||||
std::uint32_t unknown2;
|
|
||||||
std::uint32_t level; //Level is counted from 0 -> Value 69 is Level 70
|
|
||||||
std::uint32_t prestige;
|
|
||||||
std::uint32_t padding2;
|
|
||||||
char name[40];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CClient
|
struct CClient
|
||||||
{
|
{
|
||||||
std::uint32_t IsValid; // 0x0000
|
std::uint32_t IsValid; // 0x0000
|
||||||
@ -54,7 +42,9 @@ namespace Components
|
|||||||
class CardTitles : public Component
|
class CardTitles : public Component
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static Dvar::Var CustomTitleDvar;
|
AssertOffset(Game::PlayerCardData, Game::PlayerCardData::name, 0x1C);
|
||||||
|
|
||||||
|
static Dvar::Var CustomTitle;
|
||||||
static std::string CustomTitles[18];
|
static std::string CustomTitles[18];
|
||||||
|
|
||||||
static void SendCustomTitlesToClients();
|
static void SendCustomTitlesToClients();
|
||||||
@ -64,11 +54,9 @@ namespace Components
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static CClient* GetClientByIndex(std::uint32_t index);
|
static CClient* GetClientByIndex(std::uint32_t index);
|
||||||
static std::int32_t GetPlayerCardClientInfo(std::int32_t lookupResult, playercarddata_s * data);
|
static std::int32_t GetPlayerCardClientInfo(std::int32_t lookupResult, Game::PlayerCardData* data);
|
||||||
static void GetPlayerCardClientInfoStub();
|
static void GetPlayerCardClientInfoStub();
|
||||||
static const char* TableLookupByRowHook(Game::Operand* operand, tablelookuprequest_s* request);
|
static const char* TableLookupByRowHook(Game::Operand* operand, tablelookuprequest_s* request);
|
||||||
static void TableLookupByRowHookStub();
|
static void TableLookupByRowHookStub();
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
295
src/Components/Modules/ClanTags.cpp
Normal file
295
src/Components/Modules/ClanTags.cpp
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
#include <STDInclude.hpp>
|
||||||
|
|
||||||
|
namespace Components
|
||||||
|
{
|
||||||
|
Game::dvar_t* ClanTags::ClanName;
|
||||||
|
|
||||||
|
// bgs_t and clientState_s do not have this
|
||||||
|
char ClanTags::ClientState[Game::MAX_CLIENTS][5];
|
||||||
|
|
||||||
|
const char* ClanTags::GetClanTagWithName(int clientNum, const char* playerName)
|
||||||
|
{
|
||||||
|
assert(static_cast<std::size_t>(clientNum) < Game::MAX_CLIENTS);
|
||||||
|
|
||||||
|
if (ClientState[clientNum][0] == '\0')
|
||||||
|
{
|
||||||
|
return playerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Utils::String::VA("[%s]%s", ClientState[clientNum], playerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClanTags::SendClanTagsToClients()
|
||||||
|
{
|
||||||
|
std::string list;
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < Game::MAX_CLIENTS; ++i)
|
||||||
|
{
|
||||||
|
list.append(std::format("\\{}\\{}", std::to_string(i), ClientState[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto* command = Utils::String::VA("%c clanNames \"%s\"", 22, list.data());
|
||||||
|
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClanTags::ParseClanTags(const char* infoString)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < Game::MAX_CLIENTS; ++i)
|
||||||
|
{
|
||||||
|
const auto* clanTag = Game::Info_ValueForKey(infoString, std::to_string(i).data());
|
||||||
|
|
||||||
|
if (clanTag[0] == '\0')
|
||||||
|
{
|
||||||
|
ClientState[i][0] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strncpy_s(ClientState[i], clanTag, _TRUNCATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ClanTags::CL_FilterChar(unsigned char input)
|
||||||
|
{
|
||||||
|
if (input == '^')
|
||||||
|
{
|
||||||
|
return ' ';
|
||||||
|
}
|
||||||
|
if (input < ' ')
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input == 188 || input == 189)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClanTags::CL_SanitizeClanName()
|
||||||
|
{
|
||||||
|
char saneNameBuf[5];
|
||||||
|
std::memset(saneNameBuf, 0, sizeof(saneNameBuf));
|
||||||
|
|
||||||
|
auto* saneName = saneNameBuf;
|
||||||
|
const auto* currentName = Game::Dvar_GetString("clanName");
|
||||||
|
if (currentName)
|
||||||
|
{
|
||||||
|
auto nameLen = std::strlen(currentName);
|
||||||
|
for (std::size_t i = 0; i < nameLen; ++i)
|
||||||
|
{
|
||||||
|
auto curChar = CL_FilterChar(static_cast<unsigned char>(currentName[i]));
|
||||||
|
if (curChar > 0)
|
||||||
|
{
|
||||||
|
*saneName++ = curChar & 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::Dvar_SetStringByName("clanName", saneNameBuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char* ClanTags::GamerProfile_GetClanName(int controllerIndex)
|
||||||
|
{
|
||||||
|
assert(static_cast<std::size_t>(controllerIndex) < Game::MAX_LOCAL_CLIENTS);
|
||||||
|
|
||||||
|
CL_SanitizeClanName();
|
||||||
|
strncpy_s(Game::gamerSettings[0].exeConfig.clanPrefix, Game::Dvar_GetString("clanName"), _TRUNCATE);
|
||||||
|
|
||||||
|
return Game::gamerSettings[controllerIndex].exeConfig.clanPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClanTags::Dvar_InfoString_Stub(char* s, const char* key, const char* value)
|
||||||
|
{
|
||||||
|
Utils::Hook::Call<void(char*, const char*, const char*)>(0x4AE560)(s, key, value); // Info_SetValueForKey
|
||||||
|
|
||||||
|
// Set 'clanAbbrev' in the info string
|
||||||
|
Utils::Hook::Call<void(char*, const char*, const char*)>(0x4AE560)(s, "clanAbbrev", GamerProfile_GetClanName(0)); // Info_SetValueForKey
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClanTags::ClientUserinfoChanged(const char* s, int clientNum)
|
||||||
|
{
|
||||||
|
assert(static_cast<std::size_t>(clientNum) < Game::MAX_CLIENTS);
|
||||||
|
|
||||||
|
auto* clanAbbrev = Game::Info_ValueForKey(s, "clanAbbrev");
|
||||||
|
|
||||||
|
if (clanAbbrev[0] == '\0')
|
||||||
|
{
|
||||||
|
ClientState[clientNum][0] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strncpy_s(ClientState[clientNum], clanAbbrev, _TRUNCATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
SendClanTagsToClients();
|
||||||
|
}
|
||||||
|
|
||||||
|
void __declspec(naked) ClanTags::ClientUserinfoChanged_Stub()
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
pushad
|
||||||
|
|
||||||
|
push [esp + 0x20 + 0x824] // clientNum
|
||||||
|
push ecx // s
|
||||||
|
call ClientUserinfoChanged
|
||||||
|
add esp, 0x8
|
||||||
|
|
||||||
|
popad
|
||||||
|
|
||||||
|
push 0x445334 // Return address
|
||||||
|
push 0x47C820 // Info_ValueForKey
|
||||||
|
// Jump to Info_ValueForKey & add return address
|
||||||
|
retn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __declspec(naked) ClanTags::DrawPlayerNameOnScoreboard()
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
push eax
|
||||||
|
pushad
|
||||||
|
|
||||||
|
push edi
|
||||||
|
push [ebp]
|
||||||
|
|
||||||
|
call GetClanTagWithName
|
||||||
|
add esp, 0x8
|
||||||
|
|
||||||
|
mov [esp + 0x20], eax
|
||||||
|
|
||||||
|
popad
|
||||||
|
pop edi
|
||||||
|
|
||||||
|
push 0x591247 // Return address
|
||||||
|
push 0x5909E0 // DrawListString
|
||||||
|
retn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// s1 is always an empty string
|
||||||
|
int ClanTags::PartyClient_Frame_Stub(const char* s0, [[maybe_unused]] const char* s1)
|
||||||
|
{
|
||||||
|
return Utils::Hook::Call<int(const char*, const char*)>(0x4B0100)(s0, GamerProfile_GetClanName(0)); // I_strcmp
|
||||||
|
}
|
||||||
|
|
||||||
|
// clanAbbrev is always an empty string
|
||||||
|
void ClanTags::Party_UpdateClanName_Stub(Game::PartyData* party, [[maybe_unused]] const char* clanAbbrev)
|
||||||
|
{
|
||||||
|
Utils::Hook::Call<void(Game::PartyData*, const char*)>(0x4B3B10)(party, GamerProfile_GetClanName(0)); // Party_UpdateClanName
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClanTags::PlayerCards_SetCachedPlayerData(Game::PlayerCardData* data, const int clientNum)
|
||||||
|
{
|
||||||
|
strncpy_s(data->clanAbbrev, ClientState[clientNum], _TRUNCATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __declspec(naked) ClanTags::PlayerCards_SetCachedPlayerData_Stub()
|
||||||
|
{
|
||||||
|
static DWORD func = 0x4D6F80; // I_strncpyz
|
||||||
|
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
call func
|
||||||
|
add esp, 0xC
|
||||||
|
|
||||||
|
mov byte ptr [esi + 0x3C], 0x0
|
||||||
|
|
||||||
|
// Copy the clanName
|
||||||
|
push [esp + 0xC] // clientNum
|
||||||
|
push esi // g_PlayerCardCache
|
||||||
|
call PlayerCards_SetCachedPlayerData
|
||||||
|
add esp, 0x8
|
||||||
|
|
||||||
|
// Exit function
|
||||||
|
pop esi
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::PlayerCardData* ClanTags::PlayerCards_GetLiveProfileDataForClient_Stub(const unsigned int clientIndex)
|
||||||
|
{
|
||||||
|
auto* result = Utils::Hook::Call<Game::PlayerCardData*(unsigned int)>(0x46C0F0)(clientIndex);
|
||||||
|
strncpy_s(result->clanAbbrev, ClientState[clientIndex], _TRUNCATE);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::PlayerCardData* ClanTags::PlayerCards_GetLiveProfileDataForController_Stub(const unsigned int controllerIndex)
|
||||||
|
{
|
||||||
|
auto* result = Utils::Hook::Call<Game::PlayerCardData*(unsigned int)>(0x463B90)(controllerIndex);
|
||||||
|
strncpy_s(result->clanAbbrev, GamerProfile_GetClanName(static_cast<int>(controllerIndex)), _TRUNCATE); // controllerIndex should always be 0
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::PlayerCardData* ClanTags::PlayerCards_GetPartyMemberData(const int localClientNum, const Game::PlayerCardClientLookupType lookupType, const unsigned int memberIndex)
|
||||||
|
{
|
||||||
|
auto* result = Utils::Hook::Call<Game::PlayerCardData*(int, Game::PlayerCardClientLookupType, unsigned int)>(0x4A4A90)(localClientNum, lookupType, memberIndex);
|
||||||
|
strncpy_s(result->clanAbbrev, ClientState[memberIndex], _TRUNCATE); // controllerIndex should always be 0
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClanTags::ClanTags()
|
||||||
|
{
|
||||||
|
Scheduler::Once([]
|
||||||
|
{
|
||||||
|
ClanName = Game::Dvar_RegisterString("clanName", "", Game::DVAR_ARCHIVE,
|
||||||
|
"Your clan abbreviation");
|
||||||
|
}, Scheduler::Pipeline::MAIN);
|
||||||
|
|
||||||
|
std::memset(&ClientState, 0, sizeof(char[Game::MAX_CLIENTS][5]));
|
||||||
|
|
||||||
|
ServerCommands::OnCommand(22, [](Command::Params* params)
|
||||||
|
{
|
||||||
|
if (std::strcmp(params->get(1), "clanNames") == 0)
|
||||||
|
{
|
||||||
|
if (params->size() == 3)
|
||||||
|
{
|
||||||
|
ParseClanTags(params->get(2));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
Utils::Hook(0x430B00, Dvar_InfoString_Stub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
|
Utils::Hook(0x44532F, ClientUserinfoChanged_Stub, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
|
// clanName before playerName
|
||||||
|
Utils::Hook(0x591242, DrawPlayerNameOnScoreboard, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
|
Utils::Hook(0x49765B, PartyClient_Frame_Stub, HOOK_CALL).install()->quick();
|
||||||
|
Utils::Hook(0x49767E, Party_UpdateClanName_Stub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
|
// clanName in the PlayerCard (GetPlayerCardClientData)
|
||||||
|
Utils::Hook(0x458DF4, PlayerCards_SetCachedPlayerData_Stub, HOOK_JUMP).install()->quick();
|
||||||
|
Utils::Hook(0x62EAB6, PlayerCards_GetLiveProfileDataForClient_Stub, HOOK_CALL).install()->quick();
|
||||||
|
Utils::Hook(0x62EAC3, PlayerCards_GetLiveProfileDataForController_Stub, HOOK_CALL).install()->quick();
|
||||||
|
Utils::Hook(0x62EAE8, PlayerCards_GetPartyMemberData, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
|
// clanName in CG_Obituary
|
||||||
|
Utils::Hook(0x586DD6, PlayerName::GetClientName, HOOK_CALL).install()->quick();
|
||||||
|
Utils::Hook(0x586E2A, PlayerName::GetClientName, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
|
Command::Add("statGet", [](Command::Params* params)
|
||||||
|
{
|
||||||
|
if (params->size() < 2)
|
||||||
|
{
|
||||||
|
Logger::PrintError(Game::CON_CHANNEL_SERVER, "statget usage: statget <index>\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto index = std::atoi(params->get(1));
|
||||||
|
const auto stat = Game::LiveStorage_GetStat(0, index);
|
||||||
|
Logger::Print(Game::CON_CHANNEL_SYSTEM, "Stat {}: {}\n", index, stat);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
48
src/Components/Modules/ClanTags.hpp
Normal file
48
src/Components/Modules/ClanTags.hpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Components
|
||||||
|
{
|
||||||
|
class ClanTags : public Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ClanTags();
|
||||||
|
|
||||||
|
static const char* GetClanTagWithName(int clientNum, const char* playerName);
|
||||||
|
|
||||||
|
static void SendClanTagsToClients();
|
||||||
|
|
||||||
|
static void CL_SanitizeClanName();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Game::dvar_t* ClanName;
|
||||||
|
|
||||||
|
static const char* dvarNameList[];
|
||||||
|
|
||||||
|
static char ClientState[Game::MAX_CLIENTS][5];
|
||||||
|
|
||||||
|
static void ParseClanTags(const char* infoString);
|
||||||
|
|
||||||
|
static int CL_FilterChar(unsigned char input);
|
||||||
|
|
||||||
|
static char* GamerProfile_GetClanName(int controllerIndex);
|
||||||
|
|
||||||
|
static void Dvar_InfoString_Stub(char* s, const char* key, const char* value);
|
||||||
|
|
||||||
|
static void SetCachedPlayerData(int clientNum);
|
||||||
|
|
||||||
|
static void ClientUserinfoChanged(const char* s, int clientNum);
|
||||||
|
static void ClientUserinfoChanged_Stub();
|
||||||
|
|
||||||
|
static void DrawPlayerNameOnScoreboard();
|
||||||
|
|
||||||
|
static int PartyClient_Frame_Stub(const char* s0, const char* s1);
|
||||||
|
static void Party_UpdateClanName_Stub(Game::PartyData* party, const char* clanAbbrev);
|
||||||
|
|
||||||
|
static void PlayerCards_SetCachedPlayerData(Game::PlayerCardData* data, int clientNum);
|
||||||
|
static void PlayerCards_SetCachedPlayerData_Stub();
|
||||||
|
|
||||||
|
static Game::PlayerCardData* PlayerCards_GetLiveProfileDataForClient_Stub(unsigned int clientIndex);
|
||||||
|
static Game::PlayerCardData* PlayerCards_GetLiveProfileDataForController_Stub(unsigned int controllerIndex);
|
||||||
|
static Game::PlayerCardData* PlayerCards_GetPartyMemberData(int localClientNum, Game::PlayerCardClientLookupType lookupType, unsigned int memberIndex);
|
||||||
|
};
|
||||||
|
}
|
@ -1,100 +0,0 @@
|
|||||||
#include <STDInclude.hpp>
|
|
||||||
|
|
||||||
namespace Components
|
|
||||||
{
|
|
||||||
std::string ClanTags::Tags[18];
|
|
||||||
|
|
||||||
void ClanTags::ParseClantags(const char* infoString)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 18; i++)
|
|
||||||
{
|
|
||||||
const char* clantag = Game::Info_ValueForKey(infoString, std::to_string(i).data());
|
|
||||||
|
|
||||||
if (clantag) ClanTags::Tags[i] = clantag;
|
|
||||||
else ClanTags::Tags[i].clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClanTags::SendClantagsToClients()
|
|
||||||
{
|
|
||||||
std::string list;
|
|
||||||
|
|
||||||
for (int i = 0; i < 18; ++i)
|
|
||||||
{
|
|
||||||
char clantag[5] = { 0 };
|
|
||||||
|
|
||||||
if (Game::svs_clients[i].state >= 3)
|
|
||||||
{
|
|
||||||
strncpy_s(clantag, Game::Info_ValueForKey(Game::svs_clients[i].connectInfoString, "clantag"), 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
list.append(Utils::String::VA("\\%s\\%s", std::to_string(i).data(), clantag));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string command = Utils::String::VA("%c clantags \"%s\"", 22, list.data());
|
|
||||||
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, command.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* ClanTags::GetUserClantag(std::uint32_t /*clientnum*/, const char* playername)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
if (ClanTags::Tags[clientnum].empty()) return playername;
|
|
||||||
return Utils::String::VA("[%s] %s", ClanTags::Tags[clientnum].data(), playername);
|
|
||||||
#else
|
|
||||||
return playername;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
__declspec(naked) void ClanTags::DrawPlayerNameOnScoreboard()
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
push eax
|
|
||||||
pushad
|
|
||||||
|
|
||||||
push edi
|
|
||||||
push [ebp]
|
|
||||||
|
|
||||||
call ClanTags::GetUserClantag
|
|
||||||
add esp, 8
|
|
||||||
|
|
||||||
mov [esp + 20h], eax
|
|
||||||
|
|
||||||
popad
|
|
||||||
pop edi
|
|
||||||
|
|
||||||
push 591247h // Return address
|
|
||||||
push 5909E0h // Draw string func
|
|
||||||
retn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ClanTags::ClanTags()
|
|
||||||
{
|
|
||||||
// Create clantag dvar
|
|
||||||
Scheduler::Once([]
|
|
||||||
{
|
|
||||||
Dvar::Register<const char*>("clantag", "", Game::DVAR_USERINFO | Game::DVAR_ARCHIVE,
|
|
||||||
"If set, your clantag will be shown on the scoreboard.");
|
|
||||||
}, Scheduler::Pipeline::MAIN);
|
|
||||||
|
|
||||||
// Servercommand hook
|
|
||||||
ServerCommands::OnCommand(22, [](Command::Params* params)
|
|
||||||
{
|
|
||||||
if (params->get(1) == "clantags"s && !Dedicated::IsEnabled())
|
|
||||||
{
|
|
||||||
if (params->size() == 3)
|
|
||||||
{
|
|
||||||
ClanTags::ParseClantags(params->get(2));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Draw clantag before playername
|
|
||||||
Utils::Hook(0x591242, ClanTags::DrawPlayerNameOnScoreboard).install()->quick();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Components
|
|
||||||
{
|
|
||||||
class ClanTags : public Component
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static void ParseClantags(const char * infoString);
|
|
||||||
static void SendClantagsToClients();
|
|
||||||
static const char* GetUserClantag(std::uint32_t clientnum, const char * playername);
|
|
||||||
|
|
||||||
ClanTags();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static std::string Tags[18];
|
|
||||||
|
|
||||||
static void DrawPlayerNameOnScoreboard();
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
@ -334,17 +334,17 @@ namespace Components
|
|||||||
ClientCommand::Add("kill", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
ClientCommand::Add("kill", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
||||||
{
|
{
|
||||||
assert(ent->client != nullptr);
|
assert(ent->client != nullptr);
|
||||||
assert(ent->client->connected != Game::clientConnected_t::CON_DISCONNECTED);
|
assert(ent->client->sess.connected != Game::CON_DISCONNECTED);
|
||||||
|
|
||||||
if (ent->client->sessionState != Game::sessionState_t::SESS_STATE_PLAYING || !ClientCommand::CheatsOk(ent))
|
if (ent->client->sess.sessionState != Game::SESS_STATE_PLAYING || !ClientCommand::CheatsOk(ent))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Scheduler::Once([ent]
|
Scheduler::Once([ent]
|
||||||
{
|
{
|
||||||
ent->flags &= ~(Game::entityFlag::FL_GODMODE | Game::entityFlag::FL_DEMI_GODMODE);
|
ent->flags &= ~(Game::FL_GODMODE | Game::FL_DEMI_GODMODE);
|
||||||
ent->health = 0;
|
ent->health = 0;
|
||||||
ent->client->ps.stats[0] = 0;
|
ent->client->ps.stats[0] = 0;
|
||||||
Game::player_die(ent, ent, ent, 100000, 12, 0, nullptr, Game::hitLocation_t::HITLOC_NONE, 0);
|
Game::player_die(ent, ent, ent, 100000, 12, 0, nullptr, Game::HITLOC_NONE, 0);
|
||||||
}, Scheduler::Pipeline::SERVER);
|
}, Scheduler::Pipeline::SERVER);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
maxclientCount = Dvar::Var("party_maxplayers").get<int>();
|
maxclientCount = Dvar::Var("party_maxplayers").get<int>();
|
||||||
//maxclientCount = Game::Party_GetMaxPlayers(*Game::partyIngame);
|
//maxclientCount = Game::Party_GetMaxPlayers(*Game::partyIngame);
|
||||||
clientCount = Game::PartyHost_CountMembers(reinterpret_cast<Game::PartyData_s*>(0x1081C00));
|
clientCount = Game::PartyHost_CountMembers(reinterpret_cast<Game::PartyData*>(0x1081C00));
|
||||||
}
|
}
|
||||||
|
|
||||||
wclear(Console::InfoWindow);
|
wclear(Console::InfoWindow);
|
||||||
|
@ -87,7 +87,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
list.append(Utils::String::VA(" %llX", Game::svs_clients[i].steamID));
|
list.append(Utils::String::VA(" %llX", Game::svs_clients[i].steamID));
|
||||||
|
|
||||||
Utils::InfoString info(Game::svs_clients[i].connectInfoString);
|
Utils::InfoString info(Game::svs_clients[i].userinfo);
|
||||||
list.append(Utils::String::VA(" %llX", strtoull(info.get("realsteamId").data(), nullptr, 16)));
|
list.append(Utils::String::VA(" %llX", strtoull(info.get("realsteamId").data(), nullptr, 16)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -294,7 +294,6 @@ namespace Components
|
|||||||
Scheduler::Loop([]
|
Scheduler::Loop([]
|
||||||
{
|
{
|
||||||
CardTitles::SendCustomTitlesToClients();
|
CardTitles::SendCustomTitlesToClients();
|
||||||
//Clantags::SendClantagsToClients();
|
|
||||||
}, Scheduler::Pipeline::SERVER, 10s);
|
}, Scheduler::Pipeline::SERVER, 10s);
|
||||||
|
|
||||||
// Heartbeats
|
// Heartbeats
|
||||||
|
@ -760,7 +760,7 @@ namespace Components
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Score and ping are irrelevant
|
// Score and ping are irrelevant
|
||||||
const char* namePtr = Game::PartyHost_GetMemberName(reinterpret_cast<Game::PartyData_t*>(0x1081C00), i);
|
const char* namePtr = Game::PartyHost_GetMemberName(reinterpret_cast<Game::PartyData*>(0x1081C00), i);
|
||||||
if (!namePtr || !namePtr[0]) continue;
|
if (!namePtr || !namePtr[0]) continue;
|
||||||
|
|
||||||
playerInfo["name"] = namePtr;
|
playerInfo["name"] = namePtr;
|
||||||
|
@ -5,6 +5,7 @@ namespace Components
|
|||||||
Utils::Signal<Events::ClientCallback> Events::ClientDisconnectSignal;
|
Utils::Signal<Events::ClientCallback> Events::ClientDisconnectSignal;
|
||||||
Utils::Signal<Events::Callback> Events::SteamDisconnectSignal;
|
Utils::Signal<Events::Callback> Events::SteamDisconnectSignal;
|
||||||
Utils::Signal<Events::Callback> Events::ShutdownSystemSignal;
|
Utils::Signal<Events::Callback> Events::ShutdownSystemSignal;
|
||||||
|
Utils::Signal<Events::Callback> Events::ClientInitSignal;
|
||||||
Utils::Signal<Events::Callback> Events::ServerInitSignal;
|
Utils::Signal<Events::Callback> Events::ServerInitSignal;
|
||||||
|
|
||||||
void Events::OnClientDisconnect(const Utils::Slot<ClientCallback>& callback)
|
void Events::OnClientDisconnect(const Utils::Slot<ClientCallback>& callback)
|
||||||
@ -22,6 +23,11 @@ namespace Components
|
|||||||
ShutdownSystemSignal.connect(callback);
|
ShutdownSystemSignal.connect(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Events::OnClientInit(const Utils::Slot<Callback>& callback)
|
||||||
|
{
|
||||||
|
ClientInitSignal.connect(callback);
|
||||||
|
}
|
||||||
|
|
||||||
void Events::OnSVInit(const Utils::Slot<Callback>& callback)
|
void Events::OnSVInit(const Utils::Slot<Callback>& callback)
|
||||||
{
|
{
|
||||||
ServerInitSignal.connect(callback);
|
ServerInitSignal.connect(callback);
|
||||||
@ -52,6 +58,14 @@ namespace Components
|
|||||||
Utils::Hook::Call<void(unsigned char)>(0x421EE0)(sys); // Scr_ShutdownSystem
|
Utils::Hook::Call<void(unsigned char)>(0x421EE0)(sys); // Scr_ShutdownSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Events::CL_InitOnceForAllClients_HK()
|
||||||
|
{
|
||||||
|
ClientInitSignal();
|
||||||
|
ClientInitSignal.clear();
|
||||||
|
|
||||||
|
Utils::Hook::Call<void()>(0x404CA0)(); // CL_InitOnceForAllClients
|
||||||
|
}
|
||||||
|
|
||||||
void Events::SV_Init_Hk()
|
void Events::SV_Init_Hk()
|
||||||
{
|
{
|
||||||
ServerInitSignal();
|
ServerInitSignal();
|
||||||
@ -69,6 +83,8 @@ namespace Components
|
|||||||
Utils::Hook(0x47548B, Scr_ShutdownSystem_Hk, HOOK_CALL).install()->quick(); // G_LoadGame
|
Utils::Hook(0x47548B, Scr_ShutdownSystem_Hk, HOOK_CALL).install()->quick(); // G_LoadGame
|
||||||
Utils::Hook(0x4D06BA, Scr_ShutdownSystem_Hk, HOOK_CALL).install()->quick(); // G_ShutdownGame
|
Utils::Hook(0x4D06BA, Scr_ShutdownSystem_Hk, HOOK_CALL).install()->quick(); // G_ShutdownGame
|
||||||
|
|
||||||
|
Utils::Hook(0x60BE5B, CL_InitOnceForAllClients_HK, HOOK_CALL).install()->quick(); // Com_Init_Try_Block_Function
|
||||||
|
|
||||||
Utils::Hook(0x4D3665, SV_Init_Hk, HOOK_CALL).install()->quick(); // SV_Init
|
Utils::Hook(0x4D3665, SV_Init_Hk, HOOK_CALL).install()->quick(); // SV_Init
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@ namespace Components
|
|||||||
|
|
||||||
static void OnVMShutdown(const Utils::Slot<Callback>& callback);
|
static void OnVMShutdown(const Utils::Slot<Callback>& callback);
|
||||||
|
|
||||||
|
static void OnClientInit(const Utils::Slot<Callback>& callback);
|
||||||
|
|
||||||
// Client & Server (triggered once)
|
// Client & Server (triggered once)
|
||||||
static void OnSVInit(const Utils::Slot<Callback>& callback);
|
static void OnSVInit(const Utils::Slot<Callback>& callback);
|
||||||
|
|
||||||
@ -25,11 +27,13 @@ namespace Components
|
|||||||
static Utils::Signal<ClientCallback> ClientDisconnectSignal;
|
static Utils::Signal<ClientCallback> ClientDisconnectSignal;
|
||||||
static Utils::Signal<Callback> SteamDisconnectSignal;
|
static Utils::Signal<Callback> SteamDisconnectSignal;
|
||||||
static Utils::Signal<Callback> ShutdownSystemSignal;
|
static Utils::Signal<Callback> ShutdownSystemSignal;
|
||||||
|
static Utils::Signal<Callback> ClientInitSignal;
|
||||||
static Utils::Signal<Callback> ServerInitSignal;
|
static Utils::Signal<Callback> ServerInitSignal;
|
||||||
|
|
||||||
static void ClientDisconnect_Hk(int clientNum);
|
static void ClientDisconnect_Hk(int clientNum);
|
||||||
static void SteamDisconnect_Hk();
|
static void SteamDisconnect_Hk();
|
||||||
static void Scr_ShutdownSystem_Hk(unsigned char sys);
|
static void Scr_ShutdownSystem_Hk(unsigned char sys);
|
||||||
|
static void CL_InitOnceForAllClients_HK();
|
||||||
static void SV_Init_Hk();
|
static void SV_Init_Hk();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -859,6 +859,7 @@ namespace Components
|
|||||||
Menus::Add("ui_mp/iw4x_credits.menu");
|
Menus::Add("ui_mp/iw4x_credits.menu");
|
||||||
Menus::Add("ui_mp/resetclass.menu");
|
Menus::Add("ui_mp/resetclass.menu");
|
||||||
Menus::Add("ui_mp/popup_customtitle.menu");
|
Menus::Add("ui_mp/popup_customtitle.menu");
|
||||||
|
Menus::Add("ui_mp/popup_customclan.menu");
|
||||||
}
|
}
|
||||||
|
|
||||||
Menus::~Menus()
|
Menus::~Menus()
|
||||||
|
@ -332,7 +332,7 @@ namespace Components
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
maxclientCount = Dvar::Var("party_maxplayers").get<int>();
|
maxclientCount = Dvar::Var("party_maxplayers").get<int>();
|
||||||
clientCount = Game::PartyHost_CountMembers(reinterpret_cast<Game::PartyData_s*>(0x1081C00));
|
clientCount = Game::PartyHost_CountMembers(reinterpret_cast<Game::PartyData*>(0x1081C00));
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::InfoString info;
|
Utils::InfoString info;
|
||||||
|
@ -44,14 +44,14 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char* PlayerName::GetClientName(int localClientNum, int index, char* buf, size_t size)
|
int PlayerName::GetClientName(int localClientNum, int index, char* buf, int size)
|
||||||
{
|
{
|
||||||
Game::CL_GetClientName(localClientNum, index, buf, size);
|
const auto result = Game::CL_GetClientName(localClientNum, index, buf, size);
|
||||||
|
|
||||||
// Append clantag to username & remove the colors
|
// Prepend clanName to username & remove the colors
|
||||||
strncpy_s(buf, size, TextRenderer::StripColors(ClanTags::GetUserClantag(index, buf)).data(), size);
|
strncpy_s(buf, size, TextRenderer::StripColors(ClanTags::GetClanTagWithName(index, buf)).data(), size);
|
||||||
|
|
||||||
return buf;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* PlayerName::CleanStrStub(char* string)
|
char* PlayerName::CleanStrStub(char* string)
|
||||||
|
@ -9,6 +9,8 @@ namespace Components
|
|||||||
|
|
||||||
static void UserInfoCopy(char* buffer, const char* name, size_t size);
|
static void UserInfoCopy(char* buffer, const char* name, size_t size);
|
||||||
|
|
||||||
|
static int GetClientName(int localClientNum, int index, char* buf, int size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Dvar::Var sv_allowColoredNames;
|
static Dvar::Var sv_allowColoredNames;
|
||||||
// Message used when kicking players
|
// Message used when kicking players
|
||||||
@ -16,7 +18,6 @@ namespace Components
|
|||||||
|
|
||||||
static char* CleanStrStub(char* string);
|
static char* CleanStrStub(char* string);
|
||||||
static void ClientCleanName();
|
static void ClientCleanName();
|
||||||
static char* GetClientName(int localClientNum, int index, char* buf, size_t size);
|
|
||||||
|
|
||||||
static bool CopyClientNameCheck(char* dest, const char* source, int size);
|
static bool CopyClientNameCheck(char* dest, const char* source, int size);
|
||||||
static void SV_UserinfoChangedStub();
|
static void SV_UserinfoChangedStub();
|
||||||
|
@ -64,5 +64,6 @@ namespace Components
|
|||||||
{
|
{
|
||||||
// Server command receive hook
|
// Server command receive hook
|
||||||
Utils::Hook(0x59449F, ServerCommands::CG_DeployServerCommand_Stub).install()->quick();
|
Utils::Hook(0x59449F, ServerCommands::CG_DeployServerCommand_Stub).install()->quick();
|
||||||
|
Utils::Hook::Nop(0x5944A4, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,7 +217,7 @@ namespace Components
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Score and ping are irrelevant
|
// Score and ping are irrelevant
|
||||||
const auto* namePtr = Game::PartyHost_GetMemberName(reinterpret_cast<Game::PartyData_t*>(0x1081C00), i);
|
const auto* namePtr = Game::PartyHost_GetMemberName(reinterpret_cast<Game::PartyData*>(0x1081C00), i);
|
||||||
if (!namePtr || !namePtr[0]) continue;
|
if (!namePtr || !namePtr[0]) continue;
|
||||||
|
|
||||||
name = namePtr;
|
name = namePtr;
|
||||||
|
@ -67,6 +67,30 @@ namespace Components
|
|||||||
UserInfoOverrides[ent->s.number].erase("name");
|
UserInfoOverrides[ent->s.number].erase("name");
|
||||||
Game::ClientUserinfoChanged(ent->s.number);
|
Game::ClientUserinfoChanged(ent->s.number);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Script::AddMethod("SetClanTag", [](Game::scr_entref_t entref) // gsc: self setClanTag(<string>)
|
||||||
|
{
|
||||||
|
const auto* ent = Game::GetPlayerEntity(entref);
|
||||||
|
const auto* clanName = Game::Scr_GetString(0);
|
||||||
|
|
||||||
|
if (clanName == nullptr)
|
||||||
|
{
|
||||||
|
Game::Scr_ParamError(0, "^1SetClanTag: Illegal parameter!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::Debug("Setting clanName of {} to {}", ent->s.number, clanName);
|
||||||
|
UserInfoOverrides[ent->s.number]["clanAbbrev"] = clanName;
|
||||||
|
Game::ClientUserinfoChanged(ent->s.number);
|
||||||
|
});
|
||||||
|
|
||||||
|
Script::AddMethod("ResetClanTag", [](Game::scr_entref_t entref) // gsc: self ResetClanTag()
|
||||||
|
{
|
||||||
|
const auto* ent = Game::GetPlayerEntity(entref);
|
||||||
|
|
||||||
|
Logger::Debug("Resetting clanName of {}", ent->s.number);
|
||||||
|
UserInfoOverrides[ent->s.number].erase("clanAbbrev");
|
||||||
|
Game::ClientUserinfoChanged(ent->s.number);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
UserInfo::UserInfo()
|
UserInfo::UserInfo()
|
||||||
|
@ -66,6 +66,8 @@ namespace Game
|
|||||||
CL_SelectStringTableEntryInDvar_f_t CL_SelectStringTableEntryInDvar_f = CL_SelectStringTableEntryInDvar_f_t(0x4A4560);
|
CL_SelectStringTableEntryInDvar_f_t CL_SelectStringTableEntryInDvar_f = CL_SelectStringTableEntryInDvar_f_t(0x4A4560);
|
||||||
CL_DrawStretchPic_t CL_DrawStretchPic = CL_DrawStretchPic_t(0x412490);
|
CL_DrawStretchPic_t CL_DrawStretchPic = CL_DrawStretchPic_t(0x412490);
|
||||||
CL_ConsoleFixPosition_t CL_ConsoleFixPosition = CL_ConsoleFixPosition_t(0x44A430);
|
CL_ConsoleFixPosition_t CL_ConsoleFixPosition = CL_ConsoleFixPosition_t(0x44A430);
|
||||||
|
CL_GetLocalClientActiveCount_t CL_GetLocalClientActiveCount = CL_GetLocalClientActiveCount_t(0x5BAD90);
|
||||||
|
CL_ControllerIndexFromClientNum_t CL_ControllerIndexFromClientNum = CL_ControllerIndexFromClientNum_t(0x449E30);
|
||||||
|
|
||||||
Cmd_AddCommand_t Cmd_AddCommand = Cmd_AddCommand_t(0x470090);
|
Cmd_AddCommand_t Cmd_AddCommand = Cmd_AddCommand_t(0x470090);
|
||||||
Cmd_AddServerCommand_t Cmd_AddServerCommand = Cmd_AddServerCommand_t(0x4DCE00);
|
Cmd_AddServerCommand_t Cmd_AddServerCommand = Cmd_AddServerCommand_t(0x4DCE00);
|
||||||
@ -128,6 +130,8 @@ namespace Game
|
|||||||
Dvar_RegisterVec3Color_t Dvar_RegisterVec3Color = Dvar_RegisterVec3Color_t(0x4918B0);
|
Dvar_RegisterVec3Color_t Dvar_RegisterVec3Color = Dvar_RegisterVec3Color_t(0x4918B0);
|
||||||
|
|
||||||
Dvar_GetUnpackedColorByName_t Dvar_GetUnpackedColorByName = Dvar_GetUnpackedColorByName_t(0x406530);
|
Dvar_GetUnpackedColorByName_t Dvar_GetUnpackedColorByName = Dvar_GetUnpackedColorByName_t(0x406530);
|
||||||
|
Dvar_GetString_t Dvar_GetString = Dvar_GetString_t(0x4EC6B0);
|
||||||
|
Dvar_GetVariantString_t Dvar_GetVariantString = Dvar_GetVariantString_t(0x4C47E0);
|
||||||
Dvar_FindVar_t Dvar_FindVar = Dvar_FindVar_t(0x4D5390);
|
Dvar_FindVar_t Dvar_FindVar = Dvar_FindVar_t(0x4D5390);
|
||||||
Dvar_InfoString_Big_t Dvar_InfoString_Big = Dvar_InfoString_Big_t(0x4D98A0);
|
Dvar_InfoString_Big_t Dvar_InfoString_Big = Dvar_InfoString_Big_t(0x4D98A0);
|
||||||
Dvar_SetCommand_t Dvar_SetCommand = Dvar_SetCommand_t(0x4EE430);
|
Dvar_SetCommand_t Dvar_SetCommand = Dvar_SetCommand_t(0x4EE430);
|
||||||
@ -253,6 +257,8 @@ namespace Game
|
|||||||
Live_GetPrestige_t Live_GetPrestige = Live_GetPrestige_t(0x430F90);
|
Live_GetPrestige_t Live_GetPrestige = Live_GetPrestige_t(0x430F90);
|
||||||
Live_GetXp_t Live_GetXp = Live_GetXp_t(0x404C60);
|
Live_GetXp_t Live_GetXp = Live_GetXp_t(0x404C60);
|
||||||
|
|
||||||
|
LiveStorage_GetStat_t LiveStorage_GetStat = LiveStorage_GetStat_t(0x471F60);
|
||||||
|
|
||||||
Scr_AddSourceBuffer_t Scr_AddSourceBuffer = Scr_AddSourceBuffer_t(0x61ABC0);
|
Scr_AddSourceBuffer_t Scr_AddSourceBuffer = Scr_AddSourceBuffer_t(0x61ABC0);
|
||||||
|
|
||||||
PC_ReadToken_t PC_ReadToken = PC_ReadToken_t(0x4ACCD0);
|
PC_ReadToken_t PC_ReadToken = PC_ReadToken_t(0x4ACCD0);
|
||||||
@ -498,8 +504,8 @@ namespace Game
|
|||||||
int* g_streamPosIndex = reinterpret_cast<int*>(0x16E5578);
|
int* g_streamPosIndex = reinterpret_cast<int*>(0x16E5578);
|
||||||
|
|
||||||
bool* g_lobbyCreateInProgress = reinterpret_cast<bool*>(0x66C9BC2);
|
bool* g_lobbyCreateInProgress = reinterpret_cast<bool*>(0x66C9BC2);
|
||||||
party_t** partyIngame = reinterpret_cast<party_t**>(0x1081C00);
|
PartyData* g_lobbyData = reinterpret_cast<PartyData*>(0x1081C00);
|
||||||
PartyData_s** partyData = reinterpret_cast<PartyData_s**>(0x107E500);
|
PartyData* g_partyData = reinterpret_cast<PartyData*>(0x107E500);
|
||||||
|
|
||||||
int* numIP = reinterpret_cast<int*>(0x64A1E68);
|
int* numIP = reinterpret_cast<int*>(0x64A1E68);
|
||||||
netIP_t* localIP = reinterpret_cast<netIP_t*>(0x64A1E28);
|
netIP_t* localIP = reinterpret_cast<netIP_t*>(0x64A1E28);
|
||||||
@ -552,7 +558,7 @@ namespace Game
|
|||||||
scrVmPub_t* scrVmPub = reinterpret_cast<scrVmPub_t*>(0x2040CF0);
|
scrVmPub_t* scrVmPub = reinterpret_cast<scrVmPub_t*>(0x2040CF0);
|
||||||
scrVarPub_t* scrVarPub = reinterpret_cast<scrVarPub_t*>(0x201A408);
|
scrVarPub_t* scrVarPub = reinterpret_cast<scrVarPub_t*>(0x201A408);
|
||||||
|
|
||||||
clientstate_t* clcState = reinterpret_cast<clientstate_t*>(0xB2C540);
|
clientState_t* clcState = reinterpret_cast<clientState_t*>(0xB2C540);
|
||||||
|
|
||||||
GfxScene* scene = reinterpret_cast<GfxScene*>(0x6944914);
|
GfxScene* scene = reinterpret_cast<GfxScene*>(0x6944914);
|
||||||
|
|
||||||
@ -616,6 +622,11 @@ namespace Game
|
|||||||
|
|
||||||
clientConnection_t* clientConnections = reinterpret_cast<clientConnection_t*>(0xA1E878);
|
clientConnection_t* clientConnections = reinterpret_cast<clientConnection_t*>(0xA1E878);
|
||||||
|
|
||||||
|
unsigned int* playerCardUIStringIndex = reinterpret_cast<unsigned int*>(0x62CD7A8);
|
||||||
|
char (*playerCardUIStringBuf)[PLAYER_CARD_UI_STRING_COUNT][38] = reinterpret_cast<char(*)[PLAYER_CARD_UI_STRING_COUNT][38]>(0x62CB4F8);
|
||||||
|
|
||||||
|
GamerSettingState* gamerSettings = reinterpret_cast<GamerSettingState*>(0x107D3E8);
|
||||||
|
|
||||||
void Sys_LockRead(FastCriticalSection* critSect)
|
void Sys_LockRead(FastCriticalSection* critSect)
|
||||||
{
|
{
|
||||||
InterlockedIncrement(&critSect->readCount);
|
InterlockedIncrement(&critSect->readCount);
|
||||||
@ -836,8 +847,8 @@ namespace Game
|
|||||||
{
|
{
|
||||||
for (auto i = 0; i < *svs_clientCount; ++i)
|
for (auto i = 0; i < *svs_clientCount; ++i)
|
||||||
{
|
{
|
||||||
if (svs_clients[i].state != clientstate_t::CS_FREE
|
if (svs_clients[i].state != CS_FREE
|
||||||
&& svs_clients[i].netchan.remoteAddress.type == netadrtype_t::NA_BOT)
|
&& svs_clients[i].netchan.remoteAddress.type == NA_BOT)
|
||||||
{
|
{
|
||||||
SV_GameDropClient(i, "GAME_GET_TO_COVER");
|
SV_GameDropClient(i, "GAME_GET_TO_COVER");
|
||||||
}
|
}
|
||||||
@ -1746,6 +1757,5 @@ namespace Game
|
|||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma optimize("", on)
|
#pragma optimize("", on)
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ namespace Game
|
|||||||
typedef void(__cdecl * CG_SetupWeaponDef_t)(int localClientNum, unsigned int weapIndex);
|
typedef void(__cdecl * CG_SetupWeaponDef_t)(int localClientNum, unsigned int weapIndex);
|
||||||
extern CG_SetupWeaponDef_t CG_SetupWeaponDef;
|
extern CG_SetupWeaponDef_t CG_SetupWeaponDef;
|
||||||
|
|
||||||
typedef char*(__cdecl * CL_GetClientName_t)(int localClientNum, int index, char *buf, size_t size);
|
typedef int(__cdecl * CL_GetClientName_t)(int localClientNum, int index, char *buf, int size);
|
||||||
extern CL_GetClientName_t CL_GetClientName;
|
extern CL_GetClientName_t CL_GetClientName;
|
||||||
|
|
||||||
typedef int(__cdecl * CL_IsCgameInitialized_t)();
|
typedef int(__cdecl * CL_IsCgameInitialized_t)();
|
||||||
@ -139,6 +139,12 @@ namespace Game
|
|||||||
typedef void(__cdecl * CL_ConsoleFixPosition_t)();
|
typedef void(__cdecl * CL_ConsoleFixPosition_t)();
|
||||||
extern CL_ConsoleFixPosition_t CL_ConsoleFixPosition;
|
extern CL_ConsoleFixPosition_t CL_ConsoleFixPosition;
|
||||||
|
|
||||||
|
typedef int(__cdecl * CL_GetLocalClientActiveCount_t)();
|
||||||
|
extern CL_GetLocalClientActiveCount_t CL_GetLocalClientActiveCount;
|
||||||
|
|
||||||
|
typedef int(__cdecl * CL_ControllerIndexFromClientNum_t)(int localActiveClientNum);
|
||||||
|
extern CL_ControllerIndexFromClientNum_t CL_ControllerIndexFromClientNum;
|
||||||
|
|
||||||
typedef void(__cdecl * Cmd_AddCommand_t)(const char* cmdName, void(*function), cmd_function_t* allocedCmd, bool isKey);
|
typedef void(__cdecl * Cmd_AddCommand_t)(const char* cmdName, void(*function), cmd_function_t* allocedCmd, bool isKey);
|
||||||
extern Cmd_AddCommand_t Cmd_AddCommand;
|
extern Cmd_AddCommand_t Cmd_AddCommand;
|
||||||
|
|
||||||
@ -325,6 +331,12 @@ namespace Game
|
|||||||
typedef void(__cdecl * Dvar_GetUnpackedColorByName_t)(const char* dvarName, float* expandedColor);
|
typedef void(__cdecl * Dvar_GetUnpackedColorByName_t)(const char* dvarName, float* expandedColor);
|
||||||
extern Dvar_GetUnpackedColorByName_t Dvar_GetUnpackedColorByName;
|
extern Dvar_GetUnpackedColorByName_t Dvar_GetUnpackedColorByName;
|
||||||
|
|
||||||
|
typedef char*(__cdecl* Dvar_GetString_t)(const char* dvarName);
|
||||||
|
extern Dvar_GetString_t Dvar_GetString;
|
||||||
|
|
||||||
|
typedef char*(__cdecl * Dvar_GetVariantString_t)(const char* dvarName);
|
||||||
|
extern Dvar_GetVariantString_t Dvar_GetVariantString;
|
||||||
|
|
||||||
typedef dvar_t*(__cdecl * Dvar_FindVar_t)(const char* dvarName);
|
typedef dvar_t*(__cdecl * Dvar_FindVar_t)(const char* dvarName);
|
||||||
extern Dvar_FindVar_t Dvar_FindVar;
|
extern Dvar_FindVar_t Dvar_FindVar;
|
||||||
|
|
||||||
@ -456,7 +468,7 @@ namespace Game
|
|||||||
typedef void(__cdecl * Image_Release_t)(GfxImage* image);
|
typedef void(__cdecl * Image_Release_t)(GfxImage* image);
|
||||||
extern Image_Release_t Image_Release;
|
extern Image_Release_t Image_Release;
|
||||||
|
|
||||||
typedef char*(__cdecl * Info_ValueForKey_t)(const char* infoString, const char* key);
|
typedef char*(__cdecl * Info_ValueForKey_t)(const char* s, const char* key);
|
||||||
extern Info_ValueForKey_t Info_ValueForKey;
|
extern Info_ValueForKey_t Info_ValueForKey;
|
||||||
|
|
||||||
typedef void(__cdecl * Key_SetCatcher_t)(int localClientNum, int catcher);
|
typedef void(__cdecl * Key_SetCatcher_t)(int localClientNum, int catcher);
|
||||||
@ -651,6 +663,9 @@ namespace Game
|
|||||||
typedef int(__cdecl * Live_GetXp_t)(int controllerIndex);
|
typedef int(__cdecl * Live_GetXp_t)(int controllerIndex);
|
||||||
extern Live_GetXp_t Live_GetXp;
|
extern Live_GetXp_t Live_GetXp;
|
||||||
|
|
||||||
|
typedef int(__cdecl * LiveStorage_GetStat_t)(int controllerIndex, int index);
|
||||||
|
extern LiveStorage_GetStat_t LiveStorage_GetStat;
|
||||||
|
|
||||||
typedef char*(__cdecl * Scr_AddSourceBuffer_t)(const char* filename, const char* extFilename, const char* codePos, bool archive);
|
typedef char*(__cdecl * Scr_AddSourceBuffer_t)(const char* filename, const char* extFilename, const char* codePos, bool archive);
|
||||||
extern Scr_AddSourceBuffer_t Scr_AddSourceBuffer;
|
extern Scr_AddSourceBuffer_t Scr_AddSourceBuffer;
|
||||||
|
|
||||||
@ -663,16 +678,16 @@ namespace Game
|
|||||||
typedef void(__cdecl * PC_SourceError_t)(int, const char*, ...);
|
typedef void(__cdecl * PC_SourceError_t)(int, const char*, ...);
|
||||||
extern PC_SourceError_t PC_SourceError;
|
extern PC_SourceError_t PC_SourceError;
|
||||||
|
|
||||||
typedef int(__cdecl * Party_GetMaxPlayers_t)(party_s* party);
|
typedef int(__cdecl * Party_GetMaxPlayers_t)(PartyData* party);
|
||||||
extern Party_GetMaxPlayers_t Party_GetMaxPlayers;
|
extern Party_GetMaxPlayers_t Party_GetMaxPlayers;
|
||||||
|
|
||||||
typedef int(__cdecl * PartyHost_CountMembers_t)(PartyData_s* party);
|
typedef int(__cdecl * PartyHost_CountMembers_t)(PartyData* party);
|
||||||
extern PartyHost_CountMembers_t PartyHost_CountMembers;
|
extern PartyHost_CountMembers_t PartyHost_CountMembers;
|
||||||
|
|
||||||
typedef netadr_t *(__cdecl * PartyHost_GetMemberAddressBySlot_t)(int unk, void *party, const int slot);
|
typedef netadr_t *(__cdecl * PartyHost_GetMemberAddressBySlot_t)(int unk, void *party, const int slot);
|
||||||
extern PartyHost_GetMemberAddressBySlot_t PartyHost_GetMemberAddressBySlot;
|
extern PartyHost_GetMemberAddressBySlot_t PartyHost_GetMemberAddressBySlot;
|
||||||
|
|
||||||
typedef const char *(__cdecl * PartyHost_GetMemberName_t)(PartyData_s* party, const int clientNum);
|
typedef const char *(__cdecl * PartyHost_GetMemberName_t)(PartyData* party, const int clientNum);
|
||||||
extern PartyHost_GetMemberName_t PartyHost_GetMemberName;
|
extern PartyHost_GetMemberName_t PartyHost_GetMemberName;
|
||||||
|
|
||||||
typedef void(__cdecl * Playlist_ParsePlaylists_t)(const char* data);
|
typedef void(__cdecl * Playlist_ParsePlaylists_t)(const char* data);
|
||||||
@ -1116,6 +1131,10 @@ namespace Game
|
|||||||
typedef void*(__cdecl * Z_VirtualAlloc_t)(int size);
|
typedef void*(__cdecl * Z_VirtualAlloc_t)(int size);
|
||||||
extern Z_VirtualAlloc_t Z_VirtualAlloc;
|
extern Z_VirtualAlloc_t Z_VirtualAlloc;
|
||||||
|
|
||||||
|
constexpr std::size_t STATIC_MAX_LOCAL_CLIENTS = 1;
|
||||||
|
constexpr std::size_t MAX_LOCAL_CLIENTS = 1;
|
||||||
|
constexpr std::size_t MAX_CLIENTS = 18;
|
||||||
|
|
||||||
extern XAssetHeader* DB_XAssetPool;
|
extern XAssetHeader* DB_XAssetPool;
|
||||||
extern unsigned int* g_poolSize;
|
extern unsigned int* g_poolSize;
|
||||||
|
|
||||||
@ -1150,8 +1169,8 @@ namespace Game
|
|||||||
extern int* g_streamPosIndex;
|
extern int* g_streamPosIndex;
|
||||||
|
|
||||||
extern bool* g_lobbyCreateInProgress;
|
extern bool* g_lobbyCreateInProgress;
|
||||||
extern party_t** partyIngame;
|
extern PartyData* g_lobbyData;
|
||||||
extern PartyData_s** partyData;
|
extern PartyData* g_partyData;
|
||||||
|
|
||||||
extern int* numIP;
|
extern int* numIP;
|
||||||
extern netIP_t* localIP;
|
extern netIP_t* localIP;
|
||||||
@ -1205,7 +1224,7 @@ namespace Game
|
|||||||
extern scrVmPub_t* scrVmPub;
|
extern scrVmPub_t* scrVmPub;
|
||||||
extern scrVarPub_t* scrVarPub;
|
extern scrVarPub_t* scrVarPub;
|
||||||
|
|
||||||
extern clientstate_t* clcState;
|
extern clientState_t* clcState;
|
||||||
|
|
||||||
extern GfxScene* scene;
|
extern GfxScene* scene;
|
||||||
|
|
||||||
@ -1273,6 +1292,12 @@ namespace Game
|
|||||||
|
|
||||||
extern clientConnection_t* clientConnections;
|
extern clientConnection_t* clientConnections;
|
||||||
|
|
||||||
|
constexpr std::size_t PLAYER_CARD_UI_STRING_COUNT = 18;
|
||||||
|
extern unsigned int* playerCardUIStringIndex;
|
||||||
|
extern char (*playerCardUIStringBuf)[PLAYER_CARD_UI_STRING_COUNT][38];
|
||||||
|
|
||||||
|
extern GamerSettingState* gamerSettings;
|
||||||
|
|
||||||
void Sys_LockRead(FastCriticalSection* critSect);
|
void Sys_LockRead(FastCriticalSection* critSect);
|
||||||
void Sys_UnlockRead(FastCriticalSection* critSect);
|
void Sys_UnlockRead(FastCriticalSection* critSect);
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ namespace Game
|
|||||||
CS_CONNECTED = 0x3,
|
CS_CONNECTED = 0x3,
|
||||||
CS_CLIENTLOADING = 0x4,
|
CS_CLIENTLOADING = 0x4,
|
||||||
CS_ACTIVE = 0x5,
|
CS_ACTIVE = 0x5,
|
||||||
} clientstate_t;
|
} clientState_t;
|
||||||
|
|
||||||
enum serverState_t
|
enum serverState_t
|
||||||
{
|
{
|
||||||
@ -1611,6 +1611,32 @@ namespace Game
|
|||||||
unsigned int playerCardNameplate;
|
unsigned int playerCardNameplate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum PlayerCardClientLookupType
|
||||||
|
{
|
||||||
|
PLAYERCARD_LOOKUP_SCRIPTSLOT = 0x0,
|
||||||
|
PLAYERCARD_LOOKUP_LIVEPROFILE_CLIENT = 0x1,
|
||||||
|
PLAYERCARD_LOOKUP_LIVEPROFILE_CONTROLLER = 0x2,
|
||||||
|
PLAYERCARD_LOOKUP_LOBBY = 0x3,
|
||||||
|
PLAYERCARD_LOOKUP_MYTEAM = 0x4,
|
||||||
|
PLAYERCARD_LOOKUP_ENEMYTEAM = 0x5,
|
||||||
|
PLAYERCARD_LOOKUP_COUNT = 0x6,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlayerCardData
|
||||||
|
{
|
||||||
|
unsigned int lastUpdateTime;
|
||||||
|
unsigned int titleIndex;
|
||||||
|
unsigned int iconIndex;
|
||||||
|
unsigned int nameplateIndex;
|
||||||
|
int rank;
|
||||||
|
int prestige;
|
||||||
|
team_t team;
|
||||||
|
char name[32];
|
||||||
|
char clanAbbrev[5];
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(PlayerCardData) == 0x44);
|
||||||
|
|
||||||
enum usercmdButtonBits
|
enum usercmdButtonBits
|
||||||
{
|
{
|
||||||
CMD_BUTTON_ATTACK = 0x1,
|
CMD_BUTTON_ATTACK = 0x1,
|
||||||
@ -5082,18 +5108,6 @@ namespace Game
|
|||||||
char uiName[32];
|
char uiName[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct party_s
|
|
||||||
{
|
|
||||||
unsigned char pad1[544];
|
|
||||||
int privateSlots;
|
|
||||||
int publicSlots;
|
|
||||||
} party_t;
|
|
||||||
|
|
||||||
typedef struct PartyData_s
|
|
||||||
{
|
|
||||||
DWORD unk;
|
|
||||||
} PartyData_t;
|
|
||||||
|
|
||||||
struct fileInIwd_s
|
struct fileInIwd_s
|
||||||
{
|
{
|
||||||
unsigned int pos;
|
unsigned int pos;
|
||||||
@ -6046,15 +6060,66 @@ namespace Game
|
|||||||
VISIONSETCOUNT
|
VISIONSETCOUNT
|
||||||
} visionSetMode_t;
|
} visionSetMode_t;
|
||||||
|
|
||||||
|
enum hintType_t
|
||||||
|
{
|
||||||
|
HINT_NONE = 0x0,
|
||||||
|
HINT_NOICON = 0x1,
|
||||||
|
HINT_ACTIVATE = 0x2,
|
||||||
|
HINT_HEALTH = 0x3,
|
||||||
|
HINT_FRIENDLY = 0x4,
|
||||||
|
FIRST_WEAPON_HINT = 0x5,
|
||||||
|
LAST_WEAPON_HINT = 0x57C,
|
||||||
|
HINT_NUM_HINTS = 0x57D,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct playerTeamState_t
|
||||||
|
{
|
||||||
|
int location;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct clientSession_t
|
||||||
|
{
|
||||||
|
sessionState_t sessionState;
|
||||||
|
int forceSpectatorClient;
|
||||||
|
int killCamEntity;
|
||||||
|
int killCamLookAtEntity;
|
||||||
|
int status_icon;
|
||||||
|
int archiveTime;
|
||||||
|
int score;
|
||||||
|
int deaths;
|
||||||
|
int kills;
|
||||||
|
int assists;
|
||||||
|
unsigned __int16 scriptPersId;
|
||||||
|
clientConnected_t connected;
|
||||||
|
usercmd_s cmd;
|
||||||
|
usercmd_s oldcmd;
|
||||||
|
int localClient;
|
||||||
|
int predictItemPickup;
|
||||||
|
char newnetname[16];
|
||||||
|
int maxHealth;
|
||||||
|
int enterTime;
|
||||||
|
playerTeamState_t teamState;
|
||||||
|
int voteCount;
|
||||||
|
int teamVoteCount;
|
||||||
|
float moveSpeedScaleMultiplier;
|
||||||
|
int viewmodelIndex;
|
||||||
|
int noSpectate;
|
||||||
|
int teamInfo;
|
||||||
|
clientState_s cs;
|
||||||
|
int psOffsetTime;
|
||||||
|
int hasRadar;
|
||||||
|
int isRadarBlocked;
|
||||||
|
int radarMode;
|
||||||
|
int weaponHudIconOverrides[6];
|
||||||
|
unsigned int unusableEntFlags[64];
|
||||||
|
float spectateDefaultPos[3];
|
||||||
|
float spectateDefaultAngles[3];
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct gclient_s
|
typedef struct gclient_s
|
||||||
{
|
{
|
||||||
playerState_s ps;
|
playerState_s ps;
|
||||||
sessionState_t sessionState; // 12572
|
clientSession_t sess;
|
||||||
unsigned char __pad0[40];
|
|
||||||
clientConnected_t connected; // 12616
|
|
||||||
unsigned char __pad1[144];
|
|
||||||
team_t team; // 12764
|
|
||||||
unsigned char __pad2[436];
|
|
||||||
int flags; // 13204
|
int flags; // 13204
|
||||||
int spectatorClient;
|
int spectatorClient;
|
||||||
int lastCmdTime;
|
int lastCmdTime;
|
||||||
@ -6065,7 +6130,13 @@ namespace Game
|
|||||||
unsigned char __pad3[324]; // 13232
|
unsigned char __pad3[324]; // 13232
|
||||||
int visionDuration[5];
|
int visionDuration[5];
|
||||||
char visionName[5][64];
|
char visionName[5][64];
|
||||||
unsigned char __pad4[36];
|
int lastStand;
|
||||||
|
int lastStandTime;
|
||||||
|
int hudElemLastAssignedSoundID;
|
||||||
|
float lockedTargetOffset[3];
|
||||||
|
unsigned __int16 attachShieldTagName;
|
||||||
|
hintType_t hintForcedType;
|
||||||
|
int hintForcedString;
|
||||||
} gclient_t;
|
} gclient_t;
|
||||||
|
|
||||||
static_assert(sizeof(gclient_t) == 13932);
|
static_assert(sizeof(gclient_t) == 13932);
|
||||||
@ -6224,14 +6295,14 @@ namespace Game
|
|||||||
|
|
||||||
typedef struct client_s
|
typedef struct client_s
|
||||||
{
|
{
|
||||||
clientstate_t state; // 0
|
clientState_t state; // 0
|
||||||
char __pad0[4]; // 4
|
int sendAsActive; // 4
|
||||||
int deltaMessage; // 8
|
int deltaMessage; // 8
|
||||||
char __pad1[12]; // 12
|
char __pad1[12]; // 12
|
||||||
netchan_t netchan; // 24
|
netchan_t netchan; // 24
|
||||||
char __pad2[20]; // 1604
|
char __pad2[20]; // 1604
|
||||||
const char* delayDropReason; // 1624
|
const char* delayDropReason; // 1624
|
||||||
char connectInfoString[1024]; // 1628
|
char userinfo[1024]; // 1628
|
||||||
char __pad3[132096]; // 2652
|
char __pad3[132096]; // 2652
|
||||||
int reliableSequence; // 134748
|
int reliableSequence; // 134748
|
||||||
int reliableAcknowledge; // 134752
|
int reliableAcknowledge; // 134752
|
||||||
@ -6244,7 +6315,7 @@ namespace Game
|
|||||||
char lastClientCommandString[1024]; // 134816
|
char lastClientCommandString[1024]; // 134816
|
||||||
gentity_t* gentity; // 135840
|
gentity_t* gentity; // 135840
|
||||||
char name[16]; // 135844
|
char name[16]; // 135844
|
||||||
char __pad4[4]; // 135860
|
int nextReliableTime; // 135860
|
||||||
int lastPacketTime; // 135864
|
int lastPacketTime; // 135864
|
||||||
int lastConnectTime; // 135868
|
int lastConnectTime; // 135868
|
||||||
int snapNum; // 135872
|
int snapNum; // 135872
|
||||||
@ -7875,6 +7946,8 @@ namespace Game
|
|||||||
unsigned int playerCardNameplate;
|
unsigned int playerCardNameplate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(clientInfo_t) == 0x52C);
|
||||||
|
|
||||||
struct cgs_t
|
struct cgs_t
|
||||||
{
|
{
|
||||||
int viewX;
|
int viewX;
|
||||||
@ -8181,6 +8254,375 @@ namespace Game
|
|||||||
|
|
||||||
static_assert(sizeof(DeferredQueue) == 0x5908);
|
static_assert(sizeof(DeferredQueue) == 0x5908);
|
||||||
|
|
||||||
|
struct GamerSettingCommonConfig
|
||||||
|
{
|
||||||
|
float viewSensitivity;
|
||||||
|
float snd_volume;
|
||||||
|
float blacklevel;
|
||||||
|
float gpadButtonLStickDeflect;
|
||||||
|
float gpadButtonRStickDeflect;
|
||||||
|
float safearea_adjusted_horizontal;
|
||||||
|
float safearea_adjusted_vertical;
|
||||||
|
int playTimeSP;
|
||||||
|
int playTimeMP;
|
||||||
|
int playTimeSO;
|
||||||
|
int percentCompleteSP;
|
||||||
|
int percentCompleteMP;
|
||||||
|
int percentCompleteSO;
|
||||||
|
float gamma;
|
||||||
|
bool hasEverPlayed_MainMenu;
|
||||||
|
bool hasEverPlayed_SP;
|
||||||
|
bool hasEverPlayed_SO;
|
||||||
|
bool hasEverPlayed_MP;
|
||||||
|
bool invertPitch;
|
||||||
|
bool autoAim;
|
||||||
|
bool delicateFlower;
|
||||||
|
char gpadButtonsConfig[32];
|
||||||
|
char gpadSticksConfig[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct KeyPairStringData
|
||||||
|
{
|
||||||
|
short index;
|
||||||
|
short maxSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
union KeyPairDataUnion
|
||||||
|
{
|
||||||
|
char byteVal;
|
||||||
|
bool boolVal;
|
||||||
|
short shortVal;
|
||||||
|
int intVal;
|
||||||
|
float floatVal;
|
||||||
|
KeyPairStringData stringData;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GamerSettingKeyPair
|
||||||
|
{
|
||||||
|
char type;
|
||||||
|
char unused[3];
|
||||||
|
KeyPairDataUnion u;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GamerSettingExeConfig
|
||||||
|
{
|
||||||
|
int playlist;
|
||||||
|
bool mapPrefs[16];
|
||||||
|
char clanPrefix[5];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GamerSettingState
|
||||||
|
{
|
||||||
|
bool isProfileLoggedIn;
|
||||||
|
bool errorOnRead;
|
||||||
|
GamerSettingCommonConfig commonConfig;
|
||||||
|
GamerSettingKeyPair commonKeyPairs[50];
|
||||||
|
char commonKeyPairsStringPool[512];
|
||||||
|
GamerSettingExeConfig exeConfig;
|
||||||
|
GamerSettingKeyPair exeKeyPairs[50];
|
||||||
|
char exeKeyPairsStringPool[512];
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(GamerSettingState) == 0x7C0);
|
||||||
|
|
||||||
|
struct SessionStaticData
|
||||||
|
{
|
||||||
|
char* sessionName;
|
||||||
|
bool registerUsersWithVoice;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum IWNetServerSessionStatus
|
||||||
|
{
|
||||||
|
SESSION_ONCLIENTONLY = 0x0,
|
||||||
|
SESSION_BEINGCREATED = 0x1,
|
||||||
|
SESSION_CREATED = 0x2,
|
||||||
|
SESSION_BEINGDELETED = 0x3,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IWNetServerInfoAboutPlayer
|
||||||
|
{
|
||||||
|
bool active;
|
||||||
|
__int64 uid;
|
||||||
|
char skill;
|
||||||
|
char teamIndex;
|
||||||
|
int mapPackFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IWNetSessionStatus
|
||||||
|
{
|
||||||
|
IWNetServerSessionStatus status;
|
||||||
|
int sessionId;
|
||||||
|
int lastHeartbeatSent;
|
||||||
|
bool needsUpdate;
|
||||||
|
bool updatingPlayers;
|
||||||
|
int newPlayerCount;
|
||||||
|
IWNetServerInfoAboutPlayer pendingServerInfoForPlayers[18];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct XSESSION_INFO
|
||||||
|
{
|
||||||
|
XNKID sessionID;
|
||||||
|
XNADDR hostAddress;
|
||||||
|
XNKEY keyExchangeKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ClientInfo
|
||||||
|
{
|
||||||
|
bool registered;
|
||||||
|
bool voiceRegistered;
|
||||||
|
unsigned __int64 xuid;
|
||||||
|
int natType;
|
||||||
|
netadr_t addr;
|
||||||
|
int voiceConnectivityBits;
|
||||||
|
int lastConnectivityTestTime;
|
||||||
|
bool muted;
|
||||||
|
bool privateSlot;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NomineeInfo
|
||||||
|
{
|
||||||
|
int upload;
|
||||||
|
int NAT;
|
||||||
|
bool onLSP;
|
||||||
|
int connectivity;
|
||||||
|
int cpuSpeed;
|
||||||
|
int avgPing;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RegisteredUser
|
||||||
|
{
|
||||||
|
bool active;
|
||||||
|
unsigned __int64 xuid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SessionDynamicData
|
||||||
|
{
|
||||||
|
bool sessionHandle;
|
||||||
|
IWNetSessionStatus iwnetServerSessionStatus;
|
||||||
|
XSESSION_INFO sessionInfo;
|
||||||
|
bool keysGenerated;
|
||||||
|
bool sessionStartCalled;
|
||||||
|
unsigned __int64 sessionNonce;
|
||||||
|
int privateSlots;
|
||||||
|
int publicSlots;
|
||||||
|
int flags;
|
||||||
|
bool qosListenEnabled;
|
||||||
|
ClientInfo users[18];
|
||||||
|
int voiceConnectivityBits;
|
||||||
|
int sessionCreateController;
|
||||||
|
int sessionDeleteTime;
|
||||||
|
RegisteredUser internalRegisteredUsers[18];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SessionData
|
||||||
|
{
|
||||||
|
SessionStaticData staticData;
|
||||||
|
SessionDynamicData dyn;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BestHostData
|
||||||
|
{
|
||||||
|
int nominee;
|
||||||
|
NomineeInfo info;
|
||||||
|
int lastHeardFrom;
|
||||||
|
int lastSentTo;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BandwidthTestPerClientData
|
||||||
|
{
|
||||||
|
int bytesReceived;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BandwidthTestData
|
||||||
|
{
|
||||||
|
int testIndex;
|
||||||
|
int testClientNum;
|
||||||
|
int startTimeArbitrator;
|
||||||
|
int announceTime;
|
||||||
|
int winnerClientNum;
|
||||||
|
BandwidthTestPerClientData clientData[18];
|
||||||
|
char testClientName[32];
|
||||||
|
bool inProgress;
|
||||||
|
int startTime;
|
||||||
|
int roundsComplete;
|
||||||
|
bool receiving;
|
||||||
|
int receiveIndex;
|
||||||
|
int receiveStartTime;
|
||||||
|
int receiveBytes;
|
||||||
|
int resultsSendTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MigrateData
|
||||||
|
{
|
||||||
|
bool migrateActive;
|
||||||
|
bool weAreArbitrating;
|
||||||
|
int arbitratorClientNum;
|
||||||
|
int indexBits;
|
||||||
|
int startTime;
|
||||||
|
int timeoutDuration;
|
||||||
|
int lastBroadcastTime;
|
||||||
|
bool decidedOurNominee;
|
||||||
|
BestHostData bestHost;
|
||||||
|
int expectedNewHost;
|
||||||
|
BandwidthTestData bandwidthTestData;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QoSData
|
||||||
|
{
|
||||||
|
float percent;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PartyInfo
|
||||||
|
{
|
||||||
|
bool active;
|
||||||
|
XSESSION_INFO info;
|
||||||
|
int occupiedPublicSlots;
|
||||||
|
int occupiedPrivateSlots;
|
||||||
|
int numPublicSlots;
|
||||||
|
int numPrivateSlots;
|
||||||
|
int pingBias;
|
||||||
|
int ping;
|
||||||
|
int upload;
|
||||||
|
int desirability;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PartyMember
|
||||||
|
{
|
||||||
|
char status;
|
||||||
|
bool headsetPresent;
|
||||||
|
char gamertag[32];
|
||||||
|
char clanAbbrev[5];
|
||||||
|
int qport;
|
||||||
|
char challenge[6];
|
||||||
|
int lastPacketTime;
|
||||||
|
int lastHeartbeatTime;
|
||||||
|
int lastPartyStateAck;
|
||||||
|
XNADDR xnaddr;
|
||||||
|
int availableMapPackFlags;
|
||||||
|
int ackedMembers;
|
||||||
|
XNKID privatePartyId;
|
||||||
|
int subpartyIndex;
|
||||||
|
int trueSkill;
|
||||||
|
int rank;
|
||||||
|
int prestige;
|
||||||
|
int team;
|
||||||
|
unsigned __int16 score;
|
||||||
|
int deaths;
|
||||||
|
bool vetoedMap;
|
||||||
|
unsigned int playerCardIcon;
|
||||||
|
unsigned int playerCardTitle;
|
||||||
|
unsigned int playerCardNameplate;
|
||||||
|
int voiceConnectivityBits;
|
||||||
|
bool invited;
|
||||||
|
int natType;
|
||||||
|
unsigned __int64 player;
|
||||||
|
bool migrateHeardFrom;
|
||||||
|
int migratePingTime;
|
||||||
|
int migratePing;
|
||||||
|
bool migrateNominated;
|
||||||
|
NomineeInfo migrateNomineeInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SubpartyInfo
|
||||||
|
{
|
||||||
|
int members[18];
|
||||||
|
int count;
|
||||||
|
int skill;
|
||||||
|
int score;
|
||||||
|
int team;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PartyHostDetails
|
||||||
|
{
|
||||||
|
int partyListSlot;
|
||||||
|
netadr_t addr;
|
||||||
|
XSESSION_INFO sessionInfo;
|
||||||
|
int lastPacketTime;
|
||||||
|
int lastPacketSentTime;
|
||||||
|
int numPrivateSlots;
|
||||||
|
int numPublicSlots;
|
||||||
|
int hostNum;
|
||||||
|
bool accepted;
|
||||||
|
char challenge[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PartyHostData
|
||||||
|
{
|
||||||
|
int partyStateChangeTime;
|
||||||
|
int partyStateLastSendTime;
|
||||||
|
int expectedPlayers;
|
||||||
|
int vetoPassTime;
|
||||||
|
bool vetoPossible;
|
||||||
|
bool preloadingMap;
|
||||||
|
bool firstLobby;
|
||||||
|
bool migrateAfterRound;
|
||||||
|
bool stopAfterRound;
|
||||||
|
int partyCreationTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PartyData
|
||||||
|
{
|
||||||
|
SessionData* session;
|
||||||
|
SessionData* presenceSession;
|
||||||
|
SessionData* searchSession;
|
||||||
|
MigrateData migrateData;
|
||||||
|
QoSData qosData;
|
||||||
|
PartyInfo* partyList;
|
||||||
|
int partyListSize;
|
||||||
|
PartyMember partyMembers[18];
|
||||||
|
SubpartyInfo subparties[18];
|
||||||
|
int subpartyCount;
|
||||||
|
PartyHostDetails currentHost;
|
||||||
|
PartyHostDetails potentialHost;
|
||||||
|
PartyHostData hostData;
|
||||||
|
unsigned __int64 lobbySteamID;
|
||||||
|
int areWeHost;
|
||||||
|
int joiningAnotherParty;
|
||||||
|
int searchingForGames;
|
||||||
|
int inParty;
|
||||||
|
int party_systemActive;
|
||||||
|
bool veto;
|
||||||
|
int vetoTime;
|
||||||
|
int headsetPresent;
|
||||||
|
int headsetTime;
|
||||||
|
int clanAbbrevTime;
|
||||||
|
int rankTime;
|
||||||
|
int playerCardTime;
|
||||||
|
int uploadSentTime;
|
||||||
|
int voiceBitsTime;
|
||||||
|
int idTime;
|
||||||
|
int availableMapPackFlagsTime;
|
||||||
|
int searchStartTime;
|
||||||
|
int searchEndTime;
|
||||||
|
int joinAttemptForUI;
|
||||||
|
int lastMergeTime;
|
||||||
|
int mergeAttemptStartTime;
|
||||||
|
int originalPartiesInList;
|
||||||
|
int partyId;
|
||||||
|
int nextSessionSearchTime;
|
||||||
|
int mapPackFlags;
|
||||||
|
int lastPartyStateTime;
|
||||||
|
int gameStartTime;
|
||||||
|
int interEndTime;
|
||||||
|
int inactiveKeepaliveTime;
|
||||||
|
int hostTimeouts;
|
||||||
|
char lobbyFlags;
|
||||||
|
PartyData* partyToNotify;
|
||||||
|
bool registeredWithArbitration;
|
||||||
|
bool rejoining;
|
||||||
|
int partyStatePacketCount;
|
||||||
|
int partyStateLastMemberIndex;
|
||||||
|
int unfinishedPartServerTimes[2];
|
||||||
|
msg_t partyStatePartMsgs[2];
|
||||||
|
char partyStatePartMsgBufs[2][1400];
|
||||||
|
char lastEntries[8];
|
||||||
|
int currentEntry;
|
||||||
|
char axisWins;
|
||||||
|
char alliesWins;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(PartyData) == 0x23D8);
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#ifndef IDA
|
#ifndef IDA
|
||||||
|
Loading…
x
Reference in New Issue
Block a user