aboutsummaryrefslogtreecommitdiff
path: root/NorthstarDLL/maxplayers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'NorthstarDLL/maxplayers.cpp')
-rw-r--r--NorthstarDLL/maxplayers.cpp1304
1 files changed, 624 insertions, 680 deletions
diff --git a/NorthstarDLL/maxplayers.cpp b/NorthstarDLL/maxplayers.cpp
index 22f2f59a..c79284cc 100644
--- a/NorthstarDLL/maxplayers.cpp
+++ b/NorthstarDLL/maxplayers.cpp
@@ -1,681 +1,625 @@
-#include "pch.h"
-#include "tier0.h"
-
-// never set this to anything below 32
-#define NEW_MAX_PLAYERS 64
-// dg note: the theoretical limit is actually 100, 76 works without entity issues, and 64 works without clientside prediction issues.
-
-#define PAD_NUMBER(number, boundary) (((number) + ((boundary)-1)) / (boundary)) * (boundary)
-
-// this is horrible
-constexpr int PlayerResource_Name_Start = 0; // Start of modded allocated space.
-constexpr int PlayerResource_Name_Size = ((NEW_MAX_PLAYERS + 1) * 8); // const char* m_szName[MAX_PLAYERS + 1];
-
-constexpr int PlayerResource_Ping_Start = PlayerResource_Name_Start + PlayerResource_Name_Size;
-constexpr int PlayerResource_Ping_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int m_iPing[MAX_PLAYERS + 1];
-
-constexpr int PlayerResource_Team_Start = PlayerResource_Ping_Start + PlayerResource_Ping_Size;
-constexpr int PlayerResource_Team_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int m_iTeam[MAX_PLAYERS + 1];
-
-constexpr int PlayerResource_PRHealth_Start = PlayerResource_Team_Start + PlayerResource_Team_Size;
-constexpr int PlayerResource_PRHealth_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int m_iPRHealth[MAX_PLAYERS + 1];
-
-constexpr int PlayerResource_Connected_Start = PlayerResource_PRHealth_Start + PlayerResource_PRHealth_Size;
-constexpr int PlayerResource_Connected_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int (used as a bool) m_bConnected[MAX_PLAYERS + 1];
-
-constexpr int PlayerResource_Alive_Start = PlayerResource_Connected_Start + PlayerResource_Connected_Size;
-constexpr int PlayerResource_Alive_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int (used as a bool) m_bAlive[MAX_PLAYERS + 1];
-
-constexpr int PlayerResource_BoolStats_Start = PlayerResource_Alive_Start + PlayerResource_Alive_Size;
-constexpr int PlayerResource_BoolStats_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int (used as a bool idk) m_boolStats[MAX_PLAYERS + 1];
-
-constexpr int PlayerResource_KillStats_Start = PlayerResource_BoolStats_Start + PlayerResource_BoolStats_Size;
-constexpr int PlayerResource_KillStats_Length = PAD_NUMBER((NEW_MAX_PLAYERS + 1) * 6, 4);
-constexpr int PlayerResource_KillStats_Size = (PlayerResource_KillStats_Length * 6); // int m_killStats[MAX_PLAYERS + 1][6];
-
-constexpr int PlayerResource_ScoreStats_Start = PlayerResource_KillStats_Start + PlayerResource_KillStats_Size;
-constexpr int PlayerResource_ScoreStats_Length = PAD_NUMBER((NEW_MAX_PLAYERS + 1) * 5, 4);
-constexpr int PlayerResource_ScoreStats_Size = (PlayerResource_ScoreStats_Length * 4); // int m_scoreStats[MAX_PLAYERS + 1][5];
-
-// must be the usage of the last field to account for any possible paddings
-constexpr int PlayerResource_TotalSize = PlayerResource_ScoreStats_Start + PlayerResource_ScoreStats_Size;
-
-constexpr int Team_PlayerArray_AddedLength = NEW_MAX_PLAYERS - 32;
-constexpr int Team_PlayerArray_AddedSize = PAD_NUMBER(Team_PlayerArray_AddedLength * 8, 4);
-constexpr int Team_AddedSize = Team_PlayerArray_AddedSize;
-
-#include "NSMem.h"
-template <class T> void ChangeOffset(void* addr, unsigned int offset)
-{
- NSMem::BytePatch((uintptr_t)addr, (BYTE*)&offset, sizeof(T));
-}
-
-/*
-typedef bool(*MatchRecvPropsToSendProps_R_Type)(__int64 lookup, __int64 tableNameBroken, __int64 sendTable, __int64 recvTable);
-MatchRecvPropsToSendProps_R_Type MatchRecvPropsToSendProps_R_Original;
-
-bool MatchRecvPropsToSendProps_R_Hook(__int64 lookup, __int64 tableNameBroken, __int64 sendTable, __int64 recvTable)
-{
- const char* tableName = *(const char**)(sendTable + 0x118);
-
- spdlog::info("MatchRecvPropsToSendProps_R table name {}", tableName);
-
- bool orig = MatchRecvPropsToSendProps_R_Original(lookup, tableNameBroken, sendTable, recvTable);
- return orig;
-}
-
-typedef bool(*DataTable_SetupReceiveTableFromSendTable_Type)(__int64 sendTable, bool needsDecoder);
-DataTable_SetupReceiveTableFromSendTable_Type DataTable_SetupReceiveTableFromSendTable_Original;
-
-bool DataTable_SetupReceiveTableFromSendTable_Hook(__int64 sendTable, bool needsDecoder)
-{
- const char* tableName = *(const char**)(sendTable + 0x118);
-
- spdlog::info("DataTable_SetupReceiveTableFromSendTable table name {}", tableName);
- if (!strcmp(tableName, "m_bConnected")) {
- char f[64];
- sprintf_s(f, "%p", sendTable);
- MessageBoxA(0, f, "DataTable_SetupReceiveTableFromSendTable", 0);
- }
-
- return DataTable_SetupReceiveTableFromSendTable_Original(sendTable, needsDecoder);
-}
-*/
-
-typedef void* (*StringTables_CreateStringTable_Type)(
- __int64 thisptr, const char* name, int maxentries, int userdatafixedsize, int userdatanetworkbits, int flags);
-StringTables_CreateStringTable_Type StringTables_CreateStringTable_Original;
-
-void* StringTables_CreateStringTable_Hook(
- __int64 thisptr, const char* name, int maxentries, int userdatafixedsize, int userdatanetworkbits, int flags)
-{
- // Change the amount of entries to account for a bigger player amount
- if (!strcmp(name, "userinfo"))
- {
- int maxPlayersPowerOf2 = 1;
- while (maxPlayersPowerOf2 < NEW_MAX_PLAYERS)
- maxPlayersPowerOf2 <<= 1;
-
- maxentries = maxPlayersPowerOf2;
- }
-
- return StringTables_CreateStringTable_Original(thisptr, name, maxentries, userdatafixedsize, userdatanetworkbits, flags);
-}
-
-bool MaxPlayersIncreaseEnabled()
-{
- return Tier0::CommandLine() && Tier0::CommandLine()->CheckParm("-experimentalmaxplayersincrease");
-}
-
-ON_DLL_LOAD("engine.dll", MaxPlayersOverride_Engine, [](HMODULE baseAddress)
-{
- if (!MaxPlayersIncreaseEnabled())
- return;
-
- // patch GetPlayerLimits to ignore the boundary limit
- ChangeOffset<unsigned char>((char*)baseAddress + 0x116458, 0xEB); // jle => jmp
-
- // patch ED_Alloc to change nFirstIndex
- ChangeOffset<int>((char*)baseAddress + 0x18F46C + 1, NEW_MAX_PLAYERS + 8 + 1); // original: 41 (sv.GetMaxClients() + 1)
-
- // patch CGameServer::SpawnServer to change GetMaxClients inline
- ChangeOffset<int>((char*)baseAddress + 0x119543 + 2, NEW_MAX_PLAYERS + 8 + 1); // original: 41 (sv.GetMaxClients() + 1)
-
- // patch CGameServer::SpawnServer to change for loop
- ChangeOffset<unsigned char>((char*)baseAddress + 0x11957F + 2, NEW_MAX_PLAYERS); // original: 32
-
- // patch CGameServer::SpawnServer to change for loop (there are two)
- ChangeOffset<unsigned char>((char*)baseAddress + 0x119586 + 2, NEW_MAX_PLAYERS + 1); // original: 33 (32 + 1)
-
- // patch max players somewhere in CClientState
- ChangeOffset<unsigned char>((char*)baseAddress + 0x1A162C + 2, NEW_MAX_PLAYERS - 1); // original: 31 (32 - 1)
-
- // patch max players in userinfo stringtable creation
- /*{
- int maxPlayersPowerOf2 = 1;
- while (maxPlayersPowerOf2 < NEW_MAX_PLAYERS)
- maxPlayersPowerOf2 <<= 1;
- ChangeOffset<unsigned char>((char*)baseAddress + 0x114B79 + 3, maxPlayersPowerOf2); // original: 32
- }*/
- // this is not supposed to work at all but it does on 64 players (how)
- // proper fix below
-
- // patch max players in userinfo stringtable creation loop
- ChangeOffset<unsigned char>((char*)baseAddress + 0x114C48 + 2, NEW_MAX_PLAYERS); // original: 32
-
- // do not load prebaked SendTable message list
- ChangeOffset<unsigned char>((char*)baseAddress + 0x75859, 0xEB); // jnz -> jmp
-
- HookEnabler hook;
-
- // ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x209000, &MatchRecvPropsToSendProps_R_Hook,
- // reinterpret_cast<LPVOID*>(&MatchRecvPropsToSendProps_R_Original)); ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1FACD0,
- // &DataTable_SetupReceiveTableFromSendTable_Hook, reinterpret_cast<LPVOID*>(&DataTable_SetupReceiveTableFromSendTable_Original));
-
- ENABLER_CREATEHOOK(
- hook,
- (char*)baseAddress + 0x22E220,
- &StringTables_CreateStringTable_Hook,
- reinterpret_cast<LPVOID*>(&StringTables_CreateStringTable_Original));
-})
-
-typedef void (*RunUserCmds_Type)(bool a1, float a2);
-RunUserCmds_Type RunUserCmds_Original;
-
-HMODULE serverBase = 0;
-auto RandomIntZeroMax = (__int64(__fastcall*)())0;
-
-// lazy rebuild
-void RunUserCmds_Hook(bool a1, float a2)
-{
- unsigned char v3; // bl
- int v5; // er14
- int i; // edi
- __int64 v7; // rax
- DWORD* v8; // rbx
- int v9; // edi
- __int64* v10; // rsi
- __int64 v11; // rax
- int v12; // er12
- __int64 v13; // rdi
- int v14; // ebx
- int v15; // eax
- __int64 v16; // r8
- int v17; // edx
- char v18; // r15
- char v19; // bp
- int v20; // esi
- __int64* v21; // rdi
- __int64 v22; // rcx
- bool v23; // al
- __int64 v24; // rax
- __int64 v25[NEW_MAX_PLAYERS]; // [rsp+20h] [rbp-138h] BYREF
-
- uintptr_t base = (__int64)serverBase;
- auto g_pGlobals = *(__int64*)(base + 0xBFBE08);
- __int64 globals = g_pGlobals;
-
- auto g_pEngineServer = *(__int64*)(base + 0xBFBD98);
-
- auto qword_1814D9648 = *(__int64*)(base + 0x14D9648);
- auto qword_1814DA408 = *(__int64*)(base + 0x14DA408);
- auto qword_1812107E8 = *(__int64*)(base + 0x12107E8);
- auto qword_1812105A8 = *(__int64*)(base + 0x12105A8);
-
- auto UTIL_PlayerByIndex = (__int64(__fastcall*)(int index))(base + 0x26AA10);
- auto sub_180485590 = (void(__fastcall*)(__int64))(base + 0x485590);
- auto sub_18058CD80 = (void(__fastcall*)(__int64))(base + 0x58CD80);
- auto sub_1805A6D90 = (void(__fastcall*)(__int64))(base + 0x5A6D90);
- auto sub_1805A6E50 = (bool(__fastcall*)(__int64, int, char))(base + 0x5A6E50);
- auto sub_1805A6C20 = (void(__fastcall*)(__int64))(base + 0x5A6C20);
-
- v3 = *(unsigned char*)(g_pGlobals + 73);
- if (*(DWORD*)(qword_1814D9648 + 92) &&
- ((*(unsigned __int8(__fastcall**)(__int64))(*(__int64*)g_pEngineServer + 32i64))(g_pEngineServer) ||
- !*(DWORD*)(qword_1814DA408 + 92)) &&
- v3)
- {
- globals = g_pGlobals;
- v5 = 1;
- for (i = 1; i <= *(DWORD*)(g_pGlobals + 52); ++i)
- {
- v7 = UTIL_PlayerByIndex(i);
- v8 = (DWORD*)v7;
- if (v7)
- {
- *(__int64*)(base + 0x1210420) = v7;
- *(float*)(g_pGlobals + 16) = a2;
- if (!a1)
- sub_18058CD80(v7);
- sub_1805A6D90((__int64)v8);
- }
- globals = g_pGlobals;
- }
- memset(v25, 0, sizeof(v25));
- v9 = 0;
- if (*(int*)(globals + 52) > 0)
- {
- v10 = v25;
- do
- {
- v11 = UTIL_PlayerByIndex(++v9);
- globals = g_pGlobals;
- *v10++ = v11;
- } while (v9 < *(DWORD*)(globals + 52));
- }
- v12 = *(DWORD*)(qword_1812107E8 + 92);
- if (*(DWORD*)(qword_1812105A8 + 92))
- {
- v13 = *(DWORD*)(globals + 52) - 1;
- if (v13 >= 1)
- {
- v14 = *(DWORD*)(globals + 52);
- do
- {
- v15 = RandomIntZeroMax();
- v16 = v25[v13--];
- v17 = v15 % v14--;
- v25[v13 + 1] = v25[v17];
- v25[v17] = v16;
- } while (v13 >= 1);
- globals = g_pGlobals;
- }
- }
- v18 = 1;
- do
- {
- v19 = 0;
- v20 = 0;
- if (*(int*)(globals + 52) > 0)
- {
- v21 = v25;
- do
- {
- v22 = *v21;
- if (*v21)
- {
- *(__int64*)(base + 0x1210420) = *v21;
- *(float*)(globals + 16) = a2;
- v23 = sub_1805A6E50(v22, v12, v18);
- globals = g_pGlobals;
- if (v23)
- v19 = 1;
- else
- *v21 = 0i64;
- }
- ++v20;
- ++v21;
- } while (v20 < *(DWORD*)(globals + 52));
- }
- v18 = 0;
- } while (v19);
- if (*(int*)(globals + 52) >= 1)
- {
- do
- {
- v24 = UTIL_PlayerByIndex(v5);
- if (v24)
- {
- *(__int64*)(base + 0x1210420) = v24;
- *(float*)(g_pGlobals + 16) = a2;
- sub_1805A6C20(v24);
- }
- ++v5;
- } while (v5 <= *(DWORD*)(g_pGlobals + 52));
- }
- sub_180485590(*(__int64*)(base + 0xB7B2D8));
- }
-}
-
-typedef __int64 (*SendPropArray2_Type)(__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn, unsigned char unk1);
-SendPropArray2_Type SendPropArray2_Original;
-
-__int64 __fastcall SendPropArray2_Hook(__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn, unsigned char unk1)
-{
- // Change the amount of elements to account for a bigger player amount
- if (!strcmp(name, "\"player_array\""))
- elements = NEW_MAX_PLAYERS;
-
- return SendPropArray2_Original(recvProp, elements, flags, name, proxyFn, unk1);
-}
-
-ON_DLL_LOAD("server.dll", MaxPlayersOverride_Server, [](HMODULE baseAddress)
-{
- if (!MaxPlayersIncreaseEnabled())
- return;
-
- // get required data
- serverBase = GetModuleHandleA("server.dll");
- RandomIntZeroMax = (decltype(RandomIntZeroMax))(GetProcAddress(GetModuleHandleA("vstdlib.dll"), "RandomIntZeroMax"));
-
- // patch max players amount
- ChangeOffset<unsigned char>((char*)baseAddress + 0x9A44D + 3, NEW_MAX_PLAYERS); // 0x20 (32) => 0x80 (128)
-
- // patch SpawnGlobalNonRewinding to change forced edict index
- ChangeOffset<unsigned char>((char*)baseAddress + 0x2BC403 + 2, NEW_MAX_PLAYERS + 1); // original: 33 (32 + 1)
-
- constexpr int CPlayerResource_OriginalSize = 4776;
- constexpr int CPlayerResource_AddedSize = PlayerResource_TotalSize;
- constexpr int CPlayerResource_ModifiedSize = CPlayerResource_OriginalSize + CPlayerResource_AddedSize;
-
- // CPlayerResource class allocation function - allocate a bigger amount to fit all new max player data
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C560A + 1, CPlayerResource_ModifiedSize);
-
- // DT_PlayerResource::m_iPing SendProp
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5059 + 2, CPlayerResource_OriginalSize + PlayerResource_Ping_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C50A8 + 2, CPlayerResource_OriginalSize + PlayerResource_Ping_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C50E2 + 4, NEW_MAX_PLAYERS + 1);
-
- // DT_PlayerResource::m_iPing DataMap
- ChangeOffset<unsigned int>((char*)baseAddress + 0xB94598, CPlayerResource_OriginalSize + PlayerResource_Ping_Start);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xB9459C, NEW_MAX_PLAYERS + 1);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xB945C0, PlayerResource_Ping_Size);
-
- // DT_PlayerResource::m_iTeam SendProp
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5110 + 2, CPlayerResource_OriginalSize + PlayerResource_Team_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C519C + 2, CPlayerResource_OriginalSize + PlayerResource_Team_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C517E + 4, NEW_MAX_PLAYERS + 1);
-
- // DT_PlayerResource::m_iTeam DataMap
- ChangeOffset<unsigned int>((char*)baseAddress + 0xB94600, CPlayerResource_OriginalSize + PlayerResource_Team_Start);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xB94604, NEW_MAX_PLAYERS + 1);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xB94628, PlayerResource_Team_Size);
-
- // DT_PlayerResource::m_iPRHealth SendProp
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C51C0 + 2, CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5204 + 2, CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C523E + 4, NEW_MAX_PLAYERS + 1);
-
- // DT_PlayerResource::m_iPRHealth DataMap
- ChangeOffset<unsigned int>((char*)baseAddress + 0xB94668, CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xB9466C, NEW_MAX_PLAYERS + 1);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xB94690, PlayerResource_PRHealth_Size);
-
- // DT_PlayerResource::m_bConnected SendProp
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C526C + 2, CPlayerResource_OriginalSize + PlayerResource_Connected_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C52B4 + 2, CPlayerResource_OriginalSize + PlayerResource_Connected_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C52EE + 4, NEW_MAX_PLAYERS + 1);
-
- // DT_PlayerResource::m_bConnected DataMap
- ChangeOffset<unsigned int>((char*)baseAddress + 0xB946D0, CPlayerResource_OriginalSize + PlayerResource_Connected_Start);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xB946D4, NEW_MAX_PLAYERS + 1);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xB946F8, PlayerResource_Connected_Size);
-
- // DT_PlayerResource::m_bAlive SendProp
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5321 + 2, CPlayerResource_OriginalSize + PlayerResource_Alive_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5364 + 2, CPlayerResource_OriginalSize + PlayerResource_Alive_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C539E + 4, NEW_MAX_PLAYERS + 1);
-
- // DT_PlayerResource::m_bAlive DataMap
- ChangeOffset<unsigned int>((char*)baseAddress + 0xB94738, CPlayerResource_OriginalSize + PlayerResource_Alive_Start);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xB9473C, NEW_MAX_PLAYERS + 1);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xB94760, PlayerResource_Alive_Size);
-
- // DT_PlayerResource::m_boolStats SendProp
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C53CC + 2, CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5414 + 2, CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C544E + 4, NEW_MAX_PLAYERS + 1);
-
- // DT_PlayerResource::m_boolStats DataMap
- ChangeOffset<unsigned int>((char*)baseAddress + 0xB947A0, CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xB947A4, NEW_MAX_PLAYERS + 1);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xB947C8, PlayerResource_BoolStats_Size);
-
- // DT_PlayerResource::m_killStats SendProp
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C547C + 2, CPlayerResource_OriginalSize + PlayerResource_KillStats_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C54E2 + 2, CPlayerResource_OriginalSize + PlayerResource_KillStats_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C54FE + 4, PlayerResource_KillStats_Length);
-
- // DT_PlayerResource::m_killStats DataMap
- ChangeOffset<unsigned int>((char*)baseAddress + 0xB94808, CPlayerResource_OriginalSize + PlayerResource_KillStats_Start);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xB9480C, PlayerResource_KillStats_Length);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xB94830, PlayerResource_KillStats_Size);
-
- // DT_PlayerResource::m_scoreStats SendProp
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5528 + 2, CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5576 + 2, CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5584 + 4, PlayerResource_ScoreStats_Length);
-
- // DT_PlayerResource::m_scoreStats DataMap
- ChangeOffset<unsigned int>((char*)baseAddress + 0xB94870, CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xB94874, PlayerResource_ScoreStats_Length);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xB94898, PlayerResource_ScoreStats_Size);
-
- // CPlayerResource::UpdatePlayerData - m_bConnected
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C66EE + 4, CPlayerResource_OriginalSize + PlayerResource_Connected_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C672E + 4, CPlayerResource_OriginalSize + PlayerResource_Connected_Start);
-
- // CPlayerResource::UpdatePlayerData - m_iPing
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C6394 + 4, CPlayerResource_OriginalSize + PlayerResource_Ping_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C63DB + 4, CPlayerResource_OriginalSize + PlayerResource_Ping_Start);
-
- // CPlayerResource::UpdatePlayerData - m_iTeam
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C63FD + 4, CPlayerResource_OriginalSize + PlayerResource_Team_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C6442 + 4, CPlayerResource_OriginalSize + PlayerResource_Team_Start);
-
- // CPlayerResource::UpdatePlayerData - m_iPRHealth
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C645B + 4, CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C64A0 + 4, CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start);
-
- // CPlayerResource::UpdatePlayerData - m_bConnected
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C64AA + 4, CPlayerResource_OriginalSize + PlayerResource_Connected_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C64F0 + 4, CPlayerResource_OriginalSize + PlayerResource_Connected_Start);
-
- // CPlayerResource::UpdatePlayerData - m_bAlive
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C650A + 4, CPlayerResource_OriginalSize + PlayerResource_Alive_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C654F + 4, CPlayerResource_OriginalSize + PlayerResource_Alive_Start);
-
- // CPlayerResource::UpdatePlayerData - m_boolStats
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C6557 + 4, CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C65A5 + 4, CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start);
-
- // CPlayerResource::UpdatePlayerData - m_scoreStats
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C65C2 + 3, CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C65E3 + 4, CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start);
-
- // CPlayerResource::UpdatePlayerData - m_killStats
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C6654 + 3, CPlayerResource_OriginalSize + PlayerResource_KillStats_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x5C665B + 3, CPlayerResource_OriginalSize + PlayerResource_KillStats_Start);
-
- // GameLoop::RunUserCmds - rebuild
- HookEnabler hook;
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x483D10, &RunUserCmds_Hook, reinterpret_cast<LPVOID*>(&RunUserCmds_Original));
-
- *(DWORD*)((char*)baseAddress + 0x14E7390) = 0;
- auto DT_PlayerResource_Construct = (__int64(__fastcall*)())((char*)baseAddress + 0x5C4FE0);
- DT_PlayerResource_Construct();
-
- constexpr int CTeam_OriginalSize = 3336;
- constexpr int CTeam_AddedSize = Team_AddedSize;
- constexpr int CTeam_ModifiedSize = CTeam_OriginalSize + CTeam_AddedSize;
-
- // CTeam class allocation function - allocate a bigger amount to fit all new team player data
- ChangeOffset<unsigned int>((char*)baseAddress + 0x23924A + 1, CTeam_ModifiedSize);
-
- // CTeam::CTeam - increase memset length to clean newly allocated data
- ChangeOffset<unsigned int>((char*)baseAddress + 0x2395AE + 2, 256 + CTeam_AddedSize);
-
- // hook required to change the size of DT_Team::"player_array"
- HookEnabler hook2;
- ENABLER_CREATEHOOK(hook2, (char*)baseAddress + 0x12B130, &SendPropArray2_Hook, reinterpret_cast<LPVOID*>(&SendPropArray2_Original));
- hook2.~HookEnabler(); // force hook before calling construct function
-
- *(DWORD*)((char*)baseAddress + 0xC945A0) = 0;
- auto DT_Team_Construct = (__int64(__fastcall*)())((char*)baseAddress + 0x238F50);
- DT_Team_Construct();
-})
-
-typedef __int64 (*RecvPropArray2_Type)(__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn);
-RecvPropArray2_Type RecvPropArray2_Original;
-
-__int64 __fastcall RecvPropArray2_Hook(__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn)
-{
- // Change the amount of elements to account for a bigger player amount
- if (!strcmp(name, "\"player_array\""))
- elements = NEW_MAX_PLAYERS;
-
- return RecvPropArray2_Original(recvProp, elements, flags, name, proxyFn);
-}
-
-ON_DLL_LOAD("client.dll", MaxPlayersOverride_Client, [](HMODULE baseAddress)
-{
- if (!MaxPlayersIncreaseEnabled())
- return;
-
- constexpr int C_PlayerResource_OriginalSize = 5768;
- constexpr int C_PlayerResource_AddedSize = PlayerResource_TotalSize;
- constexpr int C_PlayerResource_ModifiedSize = C_PlayerResource_OriginalSize + C_PlayerResource_AddedSize;
-
- // C_PlayerResource class allocation function - allocate a bigger amount to fit all new max player data
- ChangeOffset<unsigned int>((char*)baseAddress + 0x164C41 + 1, C_PlayerResource_ModifiedSize);
-
- // C_PlayerResource::C_PlayerResource - change loop end value
- ChangeOffset<unsigned char>((char*)baseAddress + 0x1640C4 + 2, NEW_MAX_PLAYERS - 32);
-
- // C_PlayerResource::C_PlayerResource - change m_szName address
- ChangeOffset<unsigned int>(
- (char*)baseAddress + 0x1640D0 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); // appended to the end of the class
-
- // C_PlayerResource::C_PlayerResource - change m_szName address
- ChangeOffset<unsigned int>(
- (char*)baseAddress + 0x1640D0 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); // appended to the end of the class
-
- // C_PlayerResource::C_PlayerResource - increase memset length to clean newly allocated data
- ChangeOffset<unsigned int>((char*)baseAddress + 0x1640D0 + 3, 2244 + C_PlayerResource_AddedSize);
-
- // C_PlayerResource::UpdatePlayerName - change m_szName address
- ChangeOffset<unsigned int>((char*)baseAddress + 0x16431F + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
-
- // C_PlayerResource::GetPlayerName - change m_szName address 1
- ChangeOffset<unsigned int>((char*)baseAddress + 0x1645B1 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
-
- // C_PlayerResource::GetPlayerName - change m_szName address 2
- ChangeOffset<unsigned int>((char*)baseAddress + 0x1645C0 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
-
- // C_PlayerResource::GetPlayerName - change m_szName address 3
- ChangeOffset<unsigned int>((char*)baseAddress + 0x1645DD + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
-
- // C_PlayerResource::GetPlayerName internal func - change m_szName address 1
- ChangeOffset<unsigned int>((char*)baseAddress + 0x164B71 + 4, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
-
- // C_PlayerResource::GetPlayerName internal func - change m_szName address 2
- ChangeOffset<unsigned int>((char*)baseAddress + 0x164B9B + 4, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
-
- // C_PlayerResource::GetPlayerName2 (?) - change m_szName address 1
- ChangeOffset<unsigned int>((char*)baseAddress + 0x164641 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
-
- // C_PlayerResource::GetPlayerName2 (?) - change m_szName address 2
- ChangeOffset<unsigned int>((char*)baseAddress + 0x164650 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
-
- // C_PlayerResource::GetPlayerName2 (?) - change m_szName address 3
- ChangeOffset<unsigned int>((char*)baseAddress + 0x16466D + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
-
- // C_PlayerResource::GetPlayerName internal func - change m_szName2 (?) address 1
- ChangeOffset<unsigned int>((char*)baseAddress + 0x164BA3 + 4, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
-
- // C_PlayerResource::GetPlayerName internal func - change m_szName2 (?) address 2
- ChangeOffset<unsigned int>((char*)baseAddress + 0x164BCE + 4, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
-
- // C_PlayerResource::GetPlayerName internal func - change m_szName2 (?) address 3
- ChangeOffset<unsigned int>((char*)baseAddress + 0x164BE7 + 4, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
-
- // C_PlayerResource::m_szName
- ChangeOffset<unsigned int>((char*)baseAddress + 0xc350f8, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xc350f8 + 4, NEW_MAX_PLAYERS + 1);
-
- // DT_PlayerResource size
- ChangeOffset<unsigned int>((char*)baseAddress + 0x163415 + 6, C_PlayerResource_ModifiedSize);
-
- // DT_PlayerResource::m_iPing RecvProp
- ChangeOffset<unsigned int>((char*)baseAddress + 0x163492 + 2, C_PlayerResource_OriginalSize + PlayerResource_Ping_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x1634D6 + 2, C_PlayerResource_OriginalSize + PlayerResource_Ping_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x163515 + 5, NEW_MAX_PLAYERS + 1);
-
- // C_PlayerResource::m_iPing
- ChangeOffset<unsigned int>((char*)baseAddress + 0xc35170, C_PlayerResource_OriginalSize + PlayerResource_Ping_Start);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xc35170 + 4, NEW_MAX_PLAYERS + 1);
-
- // DT_PlayerResource::m_iTeam RecvProp
- ChangeOffset<unsigned int>((char*)baseAddress + 0x163549 + 2, C_PlayerResource_OriginalSize + PlayerResource_Team_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x1635C8 + 2, C_PlayerResource_OriginalSize + PlayerResource_Team_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x1635AD + 5, NEW_MAX_PLAYERS + 1);
-
- // C_PlayerResource::m_iTeam
- ChangeOffset<unsigned int>((char*)baseAddress + 0xc351e8, C_PlayerResource_OriginalSize + PlayerResource_Team_Start);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xc351e8 + 4, NEW_MAX_PLAYERS + 1);
-
- // DT_PlayerResource::m_iPRHealth RecvProp
- ChangeOffset<unsigned int>((char*)baseAddress + 0x1635F9 + 2, C_PlayerResource_OriginalSize + PlayerResource_PRHealth_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x163625 + 2, C_PlayerResource_OriginalSize + PlayerResource_PRHealth_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x163675 + 5, NEW_MAX_PLAYERS + 1);
-
- // C_PlayerResource::m_iPRHealth
- ChangeOffset<unsigned int>((char*)baseAddress + 0xc35260, C_PlayerResource_OriginalSize + PlayerResource_PRHealth_Start);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xc35260 + 4, NEW_MAX_PLAYERS + 1);
-
- // DT_PlayerResource::m_bConnected RecvProp
- ChangeOffset<unsigned int>((char*)baseAddress + 0x1636A9 + 2, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x1636D5 + 2, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x163725 + 5, NEW_MAX_PLAYERS + 1);
-
- // C_PlayerResource::m_bConnected
- ChangeOffset<unsigned int>((char*)baseAddress + 0xc352d8, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xc352d8 + 4, NEW_MAX_PLAYERS + 1);
-
- // DT_PlayerResource::m_bAlive RecvProp
- ChangeOffset<unsigned int>((char*)baseAddress + 0x163759 + 2, C_PlayerResource_OriginalSize + PlayerResource_Alive_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x163785 + 2, C_PlayerResource_OriginalSize + PlayerResource_Alive_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x1637D5 + 5, NEW_MAX_PLAYERS + 1);
-
- // C_PlayerResource::m_bAlive
- ChangeOffset<unsigned int>((char*)baseAddress + 0xc35350, C_PlayerResource_OriginalSize + PlayerResource_Alive_Start);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xc35350 + 4, NEW_MAX_PLAYERS + 1);
-
- // DT_PlayerResource::m_boolStats RecvProp
- ChangeOffset<unsigned int>((char*)baseAddress + 0x163809 + 2, C_PlayerResource_OriginalSize + PlayerResource_BoolStats_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x163835 + 2, C_PlayerResource_OriginalSize + PlayerResource_BoolStats_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x163885 + 5, NEW_MAX_PLAYERS + 1);
-
- // C_PlayerResource::m_boolStats
- ChangeOffset<unsigned int>((char*)baseAddress + 0xc353c8, C_PlayerResource_OriginalSize + PlayerResource_BoolStats_Start);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xc353c8 + 4, NEW_MAX_PLAYERS + 1);
-
- // DT_PlayerResource::m_killStats RecvProp
- ChangeOffset<unsigned int>((char*)baseAddress + 0x1638B3 + 2, C_PlayerResource_OriginalSize + PlayerResource_KillStats_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x1638E5 + 2, C_PlayerResource_OriginalSize + PlayerResource_KillStats_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x163935 + 5, PlayerResource_KillStats_Length);
-
- // C_PlayerResource::m_killStats
- ChangeOffset<unsigned int>((char*)baseAddress + 0xc35440, C_PlayerResource_OriginalSize + PlayerResource_KillStats_Start);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xc35440 + 4, PlayerResource_KillStats_Length);
-
- // DT_PlayerResource::m_scoreStats RecvProp
- ChangeOffset<unsigned int>((char*)baseAddress + 0x163969 + 2, C_PlayerResource_OriginalSize + PlayerResource_ScoreStats_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x163995 + 2, C_PlayerResource_OriginalSize + PlayerResource_ScoreStats_Start);
- ChangeOffset<unsigned int>((char*)baseAddress + 0x1639E5 + 5, PlayerResource_ScoreStats_Length);
-
- // C_PlayerResource::m_scoreStats
- ChangeOffset<unsigned int>((char*)baseAddress + 0xc354b8, C_PlayerResource_OriginalSize + PlayerResource_ScoreStats_Start);
- ChangeOffset<unsigned short>((char*)baseAddress + 0xc354b8 + 4, PlayerResource_ScoreStats_Length);
-
- // C_PlayerResource::GetPlayerName - change m_bConnected address
- ChangeOffset<unsigned int>((char*)baseAddress + 0x164599 + 3, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start);
-
- // C_PlayerResource::GetPlayerName2 (?) - change m_bConnected address
- ChangeOffset<unsigned int>((char*)baseAddress + 0x164629 + 3, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start);
-
- // C_PlayerResource::GetPlayerName internal func - change m_bConnected address
- ChangeOffset<unsigned int>((char*)baseAddress + 0x164B13 + 3, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start);
-
- // Some other get name func (that seems to be unused) - change m_bConnected address
- ChangeOffset<unsigned int>((char*)baseAddress + 0x164860 + 3, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start);
-
- // Some other get name func 2 (that seems to be unused too) - change m_bConnected address
- ChangeOffset<unsigned int>((char*)baseAddress + 0x164834 + 3, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start);
-
- *(DWORD*)((char*)baseAddress + 0xC35068) = 0;
- auto DT_PlayerResource_Construct = (__int64(__fastcall*)())((char*)baseAddress + 0x163400);
- DT_PlayerResource_Construct();
-
- constexpr int C_Team_OriginalSize = 3200;
- constexpr int C_Team_AddedSize = Team_AddedSize;
- constexpr int C_Team_ModifiedSize = C_Team_OriginalSize + C_Team_AddedSize;
-
- // C_Team class allocation function - allocate a bigger amount to fit all new team player data
- ChangeOffset<unsigned int>((char*)baseAddress + 0x182321 + 1, C_Team_ModifiedSize);
-
- // C_Team::C_Team - increase memset length to clean newly allocated data
- ChangeOffset<unsigned int>((char*)baseAddress + 0x1804A2 + 2, 256 + C_Team_AddedSize);
-
- // DT_Team size
- ChangeOffset<unsigned int>((char*)baseAddress + 0xC3AA0C, C_Team_ModifiedSize);
-
- // hook required to change the size of DT_Team::"player_array"
- HookEnabler hook;
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1CEDA0, &RecvPropArray2_Hook, reinterpret_cast<LPVOID*>(&RecvPropArray2_Original));
- hook.~HookEnabler(); // force hook before calling construct function
-
- *(DWORD*)((char*)baseAddress + 0xC3AFF8) = 0;
- auto DT_Team_Construct = (__int64(__fastcall*)())((char*)baseAddress + 0x17F950);
- DT_Team_Construct();
+#include "pch.h"
+#include "tier0.h"
+
+AUTOHOOK_INIT()
+
+// never set this to anything below 32
+#define NEW_MAX_PLAYERS 64
+// dg note: the theoretical limit is actually 100, 76 works without entity issues, and 64 works without clientside prediction issues.
+
+#define PAD_NUMBER(number, boundary) (((number) + ((boundary)-1)) / (boundary)) * (boundary)
+
+// this is horrible
+constexpr int PlayerResource_Name_Start = 0; // Start of modded allocated space.
+constexpr int PlayerResource_Name_Size = ((NEW_MAX_PLAYERS + 1) * 8); // const char* m_szName[MAX_PLAYERS + 1];
+
+constexpr int PlayerResource_Ping_Start = PlayerResource_Name_Start + PlayerResource_Name_Size;
+constexpr int PlayerResource_Ping_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int m_iPing[MAX_PLAYERS + 1];
+
+constexpr int PlayerResource_Team_Start = PlayerResource_Ping_Start + PlayerResource_Ping_Size;
+constexpr int PlayerResource_Team_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int m_iTeam[MAX_PLAYERS + 1];
+
+constexpr int PlayerResource_PRHealth_Start = PlayerResource_Team_Start + PlayerResource_Team_Size;
+constexpr int PlayerResource_PRHealth_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int m_iPRHealth[MAX_PLAYERS + 1];
+
+constexpr int PlayerResource_Connected_Start = PlayerResource_PRHealth_Start + PlayerResource_PRHealth_Size;
+constexpr int PlayerResource_Connected_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int (used as a bool) m_bConnected[MAX_PLAYERS + 1];
+
+constexpr int PlayerResource_Alive_Start = PlayerResource_Connected_Start + PlayerResource_Connected_Size;
+constexpr int PlayerResource_Alive_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int (used as a bool) m_bAlive[MAX_PLAYERS + 1];
+
+constexpr int PlayerResource_BoolStats_Start = PlayerResource_Alive_Start + PlayerResource_Alive_Size;
+constexpr int PlayerResource_BoolStats_Size = ((NEW_MAX_PLAYERS + 1) * 4); // int (used as a bool idk) m_boolStats[MAX_PLAYERS + 1];
+
+constexpr int PlayerResource_KillStats_Start = PlayerResource_BoolStats_Start + PlayerResource_BoolStats_Size;
+constexpr int PlayerResource_KillStats_Length = PAD_NUMBER((NEW_MAX_PLAYERS + 1) * 6, 4);
+constexpr int PlayerResource_KillStats_Size = (PlayerResource_KillStats_Length * 6); // int m_killStats[MAX_PLAYERS + 1][6];
+
+constexpr int PlayerResource_ScoreStats_Start = PlayerResource_KillStats_Start + PlayerResource_KillStats_Size;
+constexpr int PlayerResource_ScoreStats_Length = PAD_NUMBER((NEW_MAX_PLAYERS + 1) * 5, 4);
+constexpr int PlayerResource_ScoreStats_Size = (PlayerResource_ScoreStats_Length * 4); // int m_scoreStats[MAX_PLAYERS + 1][5];
+
+// must be the usage of the last field to account for any possible paddings
+constexpr int PlayerResource_TotalSize = PlayerResource_ScoreStats_Start + PlayerResource_ScoreStats_Size;
+
+constexpr int Team_PlayerArray_AddedLength = NEW_MAX_PLAYERS - 32;
+constexpr int Team_PlayerArray_AddedSize = PAD_NUMBER(Team_PlayerArray_AddedLength * 8, 4);
+constexpr int Team_AddedSize = Team_PlayerArray_AddedSize;
+
+bool MaxPlayersIncreaseEnabled()
+{
+ static bool bMaxPlayersIncreaseEnabled = Tier0::CommandLine()->CheckParm("-experimentalmaxplayersincrease");
+ return bMaxPlayersIncreaseEnabled;
+}
+
+#include "NSMem.h"
+template <class T> void ChangeOffset(void* addr, unsigned int offset)
+{
+ NSMem::BytePatch((uintptr_t)addr, (BYTE*)&offset, sizeof(T));
+}
+
+AUTOHOOK(StringTables_CreateStringTable, engine.dll + 0x22E220,
+void*,, (__int64 thisptr, const char* name, int maxentries, int userdatafixedsize, int userdatanetworkbits, int flags))
+{
+ // Change the amount of entries to account for a bigger player amount
+ if (!strcmp(name, "userinfo"))
+ {
+ int maxPlayersPowerOf2 = 1;
+ while (maxPlayersPowerOf2 < NEW_MAX_PLAYERS)
+ maxPlayersPowerOf2 <<= 1;
+
+ maxentries = maxPlayersPowerOf2;
+ }
+
+ return StringTables_CreateStringTable(thisptr, name, maxentries, userdatafixedsize, userdatanetworkbits, flags);
+}
+
+ON_DLL_LOAD("engine.dll", MaxPlayersOverride_Engine, [](HMODULE baseAddress)
+{
+ if (!MaxPlayersIncreaseEnabled())
+ return;
+
+ AUTOHOOK_DISPATCH_MODULE(engine.dll)
+
+ // patch GetPlayerLimits to ignore the boundary limit
+ ChangeOffset<unsigned char>((char*)baseAddress + 0x116458, 0xEB); // jle => jmp
+
+ // patch ED_Alloc to change nFirstIndex
+ ChangeOffset<int>((char*)baseAddress + 0x18F46C + 1, NEW_MAX_PLAYERS + 8 + 1); // original: 41 (sv.GetMaxClients() + 1)
+
+ // patch CGameServer::SpawnServer to change GetMaxClients inline
+ ChangeOffset<int>((char*)baseAddress + 0x119543 + 2, NEW_MAX_PLAYERS + 8 + 1); // original: 41 (sv.GetMaxClients() + 1)
+
+ // patch CGameServer::SpawnServer to change for loop
+ ChangeOffset<unsigned char>((char*)baseAddress + 0x11957F + 2, NEW_MAX_PLAYERS); // original: 32
+
+ // patch CGameServer::SpawnServer to change for loop (there are two)
+ ChangeOffset<unsigned char>((char*)baseAddress + 0x119586 + 2, NEW_MAX_PLAYERS + 1); // original: 33 (32 + 1)
+
+ // patch max players somewhere in CClientState
+ ChangeOffset<unsigned char>((char*)baseAddress + 0x1A162C + 2, NEW_MAX_PLAYERS - 1); // original: 31 (32 - 1)
+
+ // patch max players in userinfo stringtable creation
+ /*{
+ int maxPlayersPowerOf2 = 1;
+ while (maxPlayersPowerOf2 < NEW_MAX_PLAYERS)
+ maxPlayersPowerOf2 <<= 1;
+ ChangeOffset<unsigned char>((char*)baseAddress + 0x114B79 + 3, maxPlayersPowerOf2); // original: 32
+ }*/
+ // this is not supposed to work at all but it does on 64 players (how)
+ // proper fix below
+
+ // patch max players in userinfo stringtable creation loop
+ ChangeOffset<unsigned char>((char*)baseAddress + 0x114C48 + 2, NEW_MAX_PLAYERS); // original: 32
+
+ // do not load prebaked SendTable message list
+ ChangeOffset<unsigned char>((char*)baseAddress + 0x75859, 0xEB); // jnz -> jmp
+})
+
+typedef void (*RunUserCmds_Type)(bool a1, float a2);
+RunUserCmds_Type RunUserCmds_Original;
+
+HMODULE serverBase = 0;
+auto RandomIntZeroMax = (__int64(__fastcall*)())0;
+
+// lazy rebuild
+AUTOHOOK(RunUserCmds, server.dll + 0x483D10,
+void,, (bool a1, float a2))
+{
+ unsigned char v3; // bl
+ int v5; // er14
+ int i; // edi
+ __int64 v7; // rax
+ DWORD* v8; // rbx
+ int v9; // edi
+ __int64* v10; // rsi
+ __int64 v11; // rax
+ int v12; // er12
+ __int64 v13; // rdi
+ int v14; // ebx
+ int v15; // eax
+ __int64 v16; // r8
+ int v17; // edx
+ char v18; // r15
+ char v19; // bp
+ int v20; // esi
+ __int64* v21; // rdi
+ __int64 v22; // rcx
+ bool v23; // al
+ __int64 v24; // rax
+ __int64 v25[NEW_MAX_PLAYERS]; // [rsp+20h] [rbp-138h] BYREF
+
+ uintptr_t base = (__int64)serverBase;
+ auto g_pGlobals = *(__int64*)(base + 0xBFBE08);
+ __int64 globals = g_pGlobals;
+
+ auto g_pEngineServer = *(__int64*)(base + 0xBFBD98);
+
+ auto qword_1814D9648 = *(__int64*)(base + 0x14D9648);
+ auto qword_1814DA408 = *(__int64*)(base + 0x14DA408);
+ auto qword_1812107E8 = *(__int64*)(base + 0x12107E8);
+ auto qword_1812105A8 = *(__int64*)(base + 0x12105A8);
+
+ auto UTIL_PlayerByIndex = (__int64(__fastcall*)(int index))(base + 0x26AA10);
+ auto sub_180485590 = (void(__fastcall*)(__int64))(base + 0x485590);
+ auto sub_18058CD80 = (void(__fastcall*)(__int64))(base + 0x58CD80);
+ auto sub_1805A6D90 = (void(__fastcall*)(__int64))(base + 0x5A6D90);
+ auto sub_1805A6E50 = (bool(__fastcall*)(__int64, int, char))(base + 0x5A6E50);
+ auto sub_1805A6C20 = (void(__fastcall*)(__int64))(base + 0x5A6C20);
+
+ v3 = *(unsigned char*)(g_pGlobals + 73);
+ if (*(DWORD*)(qword_1814D9648 + 92) &&
+ ((*(unsigned __int8(__fastcall**)(__int64))(*(__int64*)g_pEngineServer + 32i64))(g_pEngineServer) ||
+ !*(DWORD*)(qword_1814DA408 + 92)) &&
+ v3)
+ {
+ globals = g_pGlobals;
+ v5 = 1;
+ for (i = 1; i <= *(DWORD*)(g_pGlobals + 52); ++i)
+ {
+ v7 = UTIL_PlayerByIndex(i);
+ v8 = (DWORD*)v7;
+ if (v7)
+ {
+ *(__int64*)(base + 0x1210420) = v7;
+ *(float*)(g_pGlobals + 16) = a2;
+ if (!a1)
+ sub_18058CD80(v7);
+ sub_1805A6D90((__int64)v8);
+ }
+ globals = g_pGlobals;
+ }
+ memset(v25, 0, sizeof(v25));
+ v9 = 0;
+ if (*(int*)(globals + 52) > 0)
+ {
+ v10 = v25;
+ do
+ {
+ v11 = UTIL_PlayerByIndex(++v9);
+ globals = g_pGlobals;
+ *v10++ = v11;
+ } while (v9 < *(DWORD*)(globals + 52));
+ }
+ v12 = *(DWORD*)(qword_1812107E8 + 92);
+ if (*(DWORD*)(qword_1812105A8 + 92))
+ {
+ v13 = *(DWORD*)(globals + 52) - 1;
+ if (v13 >= 1)
+ {
+ v14 = *(DWORD*)(globals + 52);
+ do
+ {
+ v15 = RandomIntZeroMax();
+ v16 = v25[v13--];
+ v17 = v15 % v14--;
+ v25[v13 + 1] = v25[v17];
+ v25[v17] = v16;
+ } while (v13 >= 1);
+ globals = g_pGlobals;
+ }
+ }
+ v18 = 1;
+ do
+ {
+ v19 = 0;
+ v20 = 0;
+ if (*(int*)(globals + 52) > 0)
+ {
+ v21 = v25;
+ do
+ {
+ v22 = *v21;
+ if (*v21)
+ {
+ *(__int64*)(base + 0x1210420) = *v21;
+ *(float*)(globals + 16) = a2;
+ v23 = sub_1805A6E50(v22, v12, v18);
+ globals = g_pGlobals;
+ if (v23)
+ v19 = 1;
+ else
+ *v21 = 0i64;
+ }
+ ++v20;
+ ++v21;
+ } while (v20 < *(DWORD*)(globals + 52));
+ }
+ v18 = 0;
+ } while (v19);
+ if (*(int*)(globals + 52) >= 1)
+ {
+ do
+ {
+ v24 = UTIL_PlayerByIndex(v5);
+ if (v24)
+ {
+ *(__int64*)(base + 0x1210420) = v24;
+ *(float*)(g_pGlobals + 16) = a2;
+ sub_1805A6C20(v24);
+ }
+ ++v5;
+ } while (v5 <= *(DWORD*)(g_pGlobals + 52));
+ }
+ sub_180485590(*(__int64*)(base + 0xB7B2D8));
+ }
+}
+
+AUTOHOOK(SendPropArray2, server.dll + 0x12B130,
+__int64, __fastcall, (__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn, unsigned char unk1))
+{
+ // Change the amount of elements to account for a bigger player amount
+ if (!strcmp(name, "\"player_array\""))
+ elements = NEW_MAX_PLAYERS;
+
+ return SendPropArray2(recvProp, elements, flags, name, proxyFn, unk1);
+}
+
+ON_DLL_LOAD("server.dll", MaxPlayersOverride_Server, [](HMODULE baseAddress)
+{
+ if (!MaxPlayersIncreaseEnabled())
+ return;
+
+ AUTOHOOK_DISPATCH_MODULE(server.dll)
+
+ // get required data
+ serverBase = baseAddress;
+ RandomIntZeroMax = (decltype(RandomIntZeroMax))(GetProcAddress(GetModuleHandleA("vstdlib.dll"), "RandomIntZeroMax"));
+
+ // patch max players amount
+ ChangeOffset<unsigned char>((char*)baseAddress + 0x9A44D + 3, NEW_MAX_PLAYERS); // 0x20 (32) => 0x80 (128)
+
+ // patch SpawnGlobalNonRewinding to change forced edict index
+ ChangeOffset<unsigned char>((char*)baseAddress + 0x2BC403 + 2, NEW_MAX_PLAYERS + 1); // original: 33 (32 + 1)
+
+ constexpr int CPlayerResource_OriginalSize = 4776;
+ constexpr int CPlayerResource_AddedSize = PlayerResource_TotalSize;
+ constexpr int CPlayerResource_ModifiedSize = CPlayerResource_OriginalSize + CPlayerResource_AddedSize;
+
+ // CPlayerResource class allocation function - allocate a bigger amount to fit all new max player data
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C560A + 1, CPlayerResource_ModifiedSize);
+
+ // DT_PlayerResource::m_iPing SendProp
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5059 + 2, CPlayerResource_OriginalSize + PlayerResource_Ping_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C50A8 + 2, CPlayerResource_OriginalSize + PlayerResource_Ping_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C50E2 + 4, NEW_MAX_PLAYERS + 1);
+
+ // DT_PlayerResource::m_iPing DataMap
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xB94598, CPlayerResource_OriginalSize + PlayerResource_Ping_Start);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xB9459C, NEW_MAX_PLAYERS + 1);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xB945C0, PlayerResource_Ping_Size);
+
+ // DT_PlayerResource::m_iTeam SendProp
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5110 + 2, CPlayerResource_OriginalSize + PlayerResource_Team_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C519C + 2, CPlayerResource_OriginalSize + PlayerResource_Team_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C517E + 4, NEW_MAX_PLAYERS + 1);
+
+ // DT_PlayerResource::m_iTeam DataMap
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xB94600, CPlayerResource_OriginalSize + PlayerResource_Team_Start);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xB94604, NEW_MAX_PLAYERS + 1);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xB94628, PlayerResource_Team_Size);
+
+ // DT_PlayerResource::m_iPRHealth SendProp
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C51C0 + 2, CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5204 + 2, CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C523E + 4, NEW_MAX_PLAYERS + 1);
+
+ // DT_PlayerResource::m_iPRHealth DataMap
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xB94668, CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xB9466C, NEW_MAX_PLAYERS + 1);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xB94690, PlayerResource_PRHealth_Size);
+
+ // DT_PlayerResource::m_bConnected SendProp
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C526C + 2, CPlayerResource_OriginalSize + PlayerResource_Connected_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C52B4 + 2, CPlayerResource_OriginalSize + PlayerResource_Connected_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C52EE + 4, NEW_MAX_PLAYERS + 1);
+
+ // DT_PlayerResource::m_bConnected DataMap
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xB946D0, CPlayerResource_OriginalSize + PlayerResource_Connected_Start);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xB946D4, NEW_MAX_PLAYERS + 1);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xB946F8, PlayerResource_Connected_Size);
+
+ // DT_PlayerResource::m_bAlive SendProp
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5321 + 2, CPlayerResource_OriginalSize + PlayerResource_Alive_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5364 + 2, CPlayerResource_OriginalSize + PlayerResource_Alive_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C539E + 4, NEW_MAX_PLAYERS + 1);
+
+ // DT_PlayerResource::m_bAlive DataMap
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xB94738, CPlayerResource_OriginalSize + PlayerResource_Alive_Start);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xB9473C, NEW_MAX_PLAYERS + 1);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xB94760, PlayerResource_Alive_Size);
+
+ // DT_PlayerResource::m_boolStats SendProp
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C53CC + 2, CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5414 + 2, CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C544E + 4, NEW_MAX_PLAYERS + 1);
+
+ // DT_PlayerResource::m_boolStats DataMap
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xB947A0, CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xB947A4, NEW_MAX_PLAYERS + 1);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xB947C8, PlayerResource_BoolStats_Size);
+
+ // DT_PlayerResource::m_killStats SendProp
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C547C + 2, CPlayerResource_OriginalSize + PlayerResource_KillStats_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C54E2 + 2, CPlayerResource_OriginalSize + PlayerResource_KillStats_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C54FE + 4, PlayerResource_KillStats_Length);
+
+ // DT_PlayerResource::m_killStats DataMap
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xB94808, CPlayerResource_OriginalSize + PlayerResource_KillStats_Start);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xB9480C, PlayerResource_KillStats_Length);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xB94830, PlayerResource_KillStats_Size);
+
+ // DT_PlayerResource::m_scoreStats SendProp
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5528 + 2, CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5576 + 2, CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C5584 + 4, PlayerResource_ScoreStats_Length);
+
+ // DT_PlayerResource::m_scoreStats DataMap
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xB94870, CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xB94874, PlayerResource_ScoreStats_Length);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xB94898, PlayerResource_ScoreStats_Size);
+
+ // CPlayerResource::UpdatePlayerData - m_bConnected
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C66EE + 4, CPlayerResource_OriginalSize + PlayerResource_Connected_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C672E + 4, CPlayerResource_OriginalSize + PlayerResource_Connected_Start);
+
+ // CPlayerResource::UpdatePlayerData - m_iPing
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C6394 + 4, CPlayerResource_OriginalSize + PlayerResource_Ping_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C63DB + 4, CPlayerResource_OriginalSize + PlayerResource_Ping_Start);
+
+ // CPlayerResource::UpdatePlayerData - m_iTeam
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C63FD + 4, CPlayerResource_OriginalSize + PlayerResource_Team_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C6442 + 4, CPlayerResource_OriginalSize + PlayerResource_Team_Start);
+
+ // CPlayerResource::UpdatePlayerData - m_iPRHealth
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C645B + 4, CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C64A0 + 4, CPlayerResource_OriginalSize + PlayerResource_PRHealth_Start);
+
+ // CPlayerResource::UpdatePlayerData - m_bConnected
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C64AA + 4, CPlayerResource_OriginalSize + PlayerResource_Connected_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C64F0 + 4, CPlayerResource_OriginalSize + PlayerResource_Connected_Start);
+
+ // CPlayerResource::UpdatePlayerData - m_bAlive
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C650A + 4, CPlayerResource_OriginalSize + PlayerResource_Alive_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C654F + 4, CPlayerResource_OriginalSize + PlayerResource_Alive_Start);
+
+ // CPlayerResource::UpdatePlayerData - m_boolStats
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C6557 + 4, CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C65A5 + 4, CPlayerResource_OriginalSize + PlayerResource_BoolStats_Start);
+
+ // CPlayerResource::UpdatePlayerData - m_scoreStats
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C65C2 + 3, CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C65E3 + 4, CPlayerResource_OriginalSize + PlayerResource_ScoreStats_Start);
+
+ // CPlayerResource::UpdatePlayerData - m_killStats
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C6654 + 3, CPlayerResource_OriginalSize + PlayerResource_KillStats_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x5C665B + 3, CPlayerResource_OriginalSize + PlayerResource_KillStats_Start);
+
+ *(DWORD*)((char*)baseAddress + 0x14E7390) = 0;
+ auto DT_PlayerResource_Construct = (__int64(__fastcall*)())((char*)baseAddress + 0x5C4FE0);
+ DT_PlayerResource_Construct();
+
+ constexpr int CTeam_OriginalSize = 3336;
+ constexpr int CTeam_AddedSize = Team_AddedSize;
+ constexpr int CTeam_ModifiedSize = CTeam_OriginalSize + CTeam_AddedSize;
+
+ // CTeam class allocation function - allocate a bigger amount to fit all new team player data
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x23924A + 1, CTeam_ModifiedSize);
+
+ // CTeam::CTeam - increase memset length to clean newly allocated data
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x2395AE + 2, 256 + CTeam_AddedSize);
+
+ *(DWORD*)((char*)baseAddress + 0xC945A0) = 0;
+ auto DT_Team_Construct = (__int64(__fastcall*)())((char*)baseAddress + 0x238F50);
+ DT_Team_Construct();
+})
+
+AUTOHOOK(RecvPropArray2, client.dll + 0x1CEDA0,
+__int64, __fastcall, (__int64 recvProp, int elements, int flags, const char* name, __int64 proxyFn))
+{
+ // Change the amount of elements to account for a bigger player amount
+ if (!strcmp(name, "\"player_array\""))
+ elements = NEW_MAX_PLAYERS;
+
+ return RecvPropArray2(recvProp, elements, flags, name, proxyFn);
+}
+
+ON_DLL_LOAD("client.dll", MaxPlayersOverride_Client, [](HMODULE baseAddress)
+{
+ if (!MaxPlayersIncreaseEnabled())
+ return;
+
+ AUTOHOOK_DISPATCH_MODULE(client.dll)
+
+ constexpr int C_PlayerResource_OriginalSize = 5768;
+ constexpr int C_PlayerResource_AddedSize = PlayerResource_TotalSize;
+ constexpr int C_PlayerResource_ModifiedSize = C_PlayerResource_OriginalSize + C_PlayerResource_AddedSize;
+
+ // C_PlayerResource class allocation function - allocate a bigger amount to fit all new max player data
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x164C41 + 1, C_PlayerResource_ModifiedSize);
+
+ // C_PlayerResource::C_PlayerResource - change loop end value
+ ChangeOffset<unsigned char>((char*)baseAddress + 0x1640C4 + 2, NEW_MAX_PLAYERS - 32);
+
+ // C_PlayerResource::C_PlayerResource - change m_szName address
+ ChangeOffset<unsigned int>(
+ (char*)baseAddress + 0x1640D0 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); // appended to the end of the class
+
+ // C_PlayerResource::C_PlayerResource - change m_szName address
+ ChangeOffset<unsigned int>(
+ (char*)baseAddress + 0x1640D0 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start); // appended to the end of the class
+
+ // C_PlayerResource::C_PlayerResource - increase memset length to clean newly allocated data
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x1640D0 + 3, 2244 + C_PlayerResource_AddedSize);
+
+ // C_PlayerResource::UpdatePlayerName - change m_szName address
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x16431F + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
+
+ // C_PlayerResource::GetPlayerName - change m_szName address 1
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x1645B1 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
+
+ // C_PlayerResource::GetPlayerName - change m_szName address 2
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x1645C0 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
+
+ // C_PlayerResource::GetPlayerName - change m_szName address 3
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x1645DD + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
+
+ // C_PlayerResource::GetPlayerName internal func - change m_szName address 1
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x164B71 + 4, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
+
+ // C_PlayerResource::GetPlayerName internal func - change m_szName address 2
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x164B9B + 4, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
+
+ // C_PlayerResource::GetPlayerName2 (?) - change m_szName address 1
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x164641 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
+
+ // C_PlayerResource::GetPlayerName2 (?) - change m_szName address 2
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x164650 + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
+
+ // C_PlayerResource::GetPlayerName2 (?) - change m_szName address 3
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x16466D + 3, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
+
+ // C_PlayerResource::GetPlayerName internal func - change m_szName2 (?) address 1
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x164BA3 + 4, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
+
+ // C_PlayerResource::GetPlayerName internal func - change m_szName2 (?) address 2
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x164BCE + 4, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
+
+ // C_PlayerResource::GetPlayerName internal func - change m_szName2 (?) address 3
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x164BE7 + 4, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
+
+ // C_PlayerResource::m_szName
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xc350f8, C_PlayerResource_OriginalSize + PlayerResource_Name_Start);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xc350f8 + 4, NEW_MAX_PLAYERS + 1);
+
+ // DT_PlayerResource size
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x163415 + 6, C_PlayerResource_ModifiedSize);
+
+ // DT_PlayerResource::m_iPing RecvProp
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x163492 + 2, C_PlayerResource_OriginalSize + PlayerResource_Ping_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x1634D6 + 2, C_PlayerResource_OriginalSize + PlayerResource_Ping_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x163515 + 5, NEW_MAX_PLAYERS + 1);
+
+ // C_PlayerResource::m_iPing
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xc35170, C_PlayerResource_OriginalSize + PlayerResource_Ping_Start);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xc35170 + 4, NEW_MAX_PLAYERS + 1);
+
+ // DT_PlayerResource::m_iTeam RecvProp
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x163549 + 2, C_PlayerResource_OriginalSize + PlayerResource_Team_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x1635C8 + 2, C_PlayerResource_OriginalSize + PlayerResource_Team_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x1635AD + 5, NEW_MAX_PLAYERS + 1);
+
+ // C_PlayerResource::m_iTeam
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xc351e8, C_PlayerResource_OriginalSize + PlayerResource_Team_Start);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xc351e8 + 4, NEW_MAX_PLAYERS + 1);
+
+ // DT_PlayerResource::m_iPRHealth RecvProp
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x1635F9 + 2, C_PlayerResource_OriginalSize + PlayerResource_PRHealth_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x163625 + 2, C_PlayerResource_OriginalSize + PlayerResource_PRHealth_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x163675 + 5, NEW_MAX_PLAYERS + 1);
+
+ // C_PlayerResource::m_iPRHealth
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xc35260, C_PlayerResource_OriginalSize + PlayerResource_PRHealth_Start);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xc35260 + 4, NEW_MAX_PLAYERS + 1);
+
+ // DT_PlayerResource::m_bConnected RecvProp
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x1636A9 + 2, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x1636D5 + 2, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x163725 + 5, NEW_MAX_PLAYERS + 1);
+
+ // C_PlayerResource::m_bConnected
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xc352d8, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xc352d8 + 4, NEW_MAX_PLAYERS + 1);
+
+ // DT_PlayerResource::m_bAlive RecvProp
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x163759 + 2, C_PlayerResource_OriginalSize + PlayerResource_Alive_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x163785 + 2, C_PlayerResource_OriginalSize + PlayerResource_Alive_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x1637D5 + 5, NEW_MAX_PLAYERS + 1);
+
+ // C_PlayerResource::m_bAlive
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xc35350, C_PlayerResource_OriginalSize + PlayerResource_Alive_Start);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xc35350 + 4, NEW_MAX_PLAYERS + 1);
+
+ // DT_PlayerResource::m_boolStats RecvProp
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x163809 + 2, C_PlayerResource_OriginalSize + PlayerResource_BoolStats_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x163835 + 2, C_PlayerResource_OriginalSize + PlayerResource_BoolStats_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x163885 + 5, NEW_MAX_PLAYERS + 1);
+
+ // C_PlayerResource::m_boolStats
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xc353c8, C_PlayerResource_OriginalSize + PlayerResource_BoolStats_Start);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xc353c8 + 4, NEW_MAX_PLAYERS + 1);
+
+ // DT_PlayerResource::m_killStats RecvProp
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x1638B3 + 2, C_PlayerResource_OriginalSize + PlayerResource_KillStats_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x1638E5 + 2, C_PlayerResource_OriginalSize + PlayerResource_KillStats_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x163935 + 5, PlayerResource_KillStats_Length);
+
+ // C_PlayerResource::m_killStats
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xc35440, C_PlayerResource_OriginalSize + PlayerResource_KillStats_Start);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xc35440 + 4, PlayerResource_KillStats_Length);
+
+ // DT_PlayerResource::m_scoreStats RecvProp
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x163969 + 2, C_PlayerResource_OriginalSize + PlayerResource_ScoreStats_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x163995 + 2, C_PlayerResource_OriginalSize + PlayerResource_ScoreStats_Start);
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x1639E5 + 5, PlayerResource_ScoreStats_Length);
+
+ // C_PlayerResource::m_scoreStats
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xc354b8, C_PlayerResource_OriginalSize + PlayerResource_ScoreStats_Start);
+ ChangeOffset<unsigned short>((char*)baseAddress + 0xc354b8 + 4, PlayerResource_ScoreStats_Length);
+
+ // C_PlayerResource::GetPlayerName - change m_bConnected address
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x164599 + 3, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start);
+
+ // C_PlayerResource::GetPlayerName2 (?) - change m_bConnected address
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x164629 + 3, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start);
+
+ // C_PlayerResource::GetPlayerName internal func - change m_bConnected address
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x164B13 + 3, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start);
+
+ // Some other get name func (that seems to be unused) - change m_bConnected address
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x164860 + 3, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start);
+
+ // Some other get name func 2 (that seems to be unused too) - change m_bConnected address
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x164834 + 3, C_PlayerResource_OriginalSize + PlayerResource_Connected_Start);
+
+ *(DWORD*)((char*)baseAddress + 0xC35068) = 0;
+ auto DT_PlayerResource_Construct = (__int64(__fastcall*)())((char*)baseAddress + 0x163400);
+ DT_PlayerResource_Construct();
+
+ constexpr int C_Team_OriginalSize = 3200;
+ constexpr int C_Team_AddedSize = Team_AddedSize;
+ constexpr int C_Team_ModifiedSize = C_Team_OriginalSize + C_Team_AddedSize;
+
+ // C_Team class allocation function - allocate a bigger amount to fit all new team player data
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x182321 + 1, C_Team_ModifiedSize);
+
+ // C_Team::C_Team - increase memset length to clean newly allocated data
+ ChangeOffset<unsigned int>((char*)baseAddress + 0x1804A2 + 2, 256 + C_Team_AddedSize);
+
+ // DT_Team size
+ ChangeOffset<unsigned int>((char*)baseAddress + 0xC3AA0C, C_Team_ModifiedSize);
+
+ *(DWORD*)((char*)baseAddress + 0xC3AFF8) = 0;
+ auto DT_Team_Construct = (__int64(__fastcall*)())((char*)baseAddress + 0x17F950);
+ DT_Team_Construct();
}) \ No newline at end of file