4040#include " gameconfig.h"
4141#include " gameevents.pb.h"
4242#include " gamesystem.h"
43- #include " gamesystems/spawngroup_manager.h"
4443#include " httpmanager.h"
4544#include " icvar.h"
4645#include " idlemanager.h"
@@ -69,6 +68,7 @@ double g_flUniversalTime;
6968float g_flLastTickedTime;
7069bool g_bHasTicked;
7170int g_iRoundNum = 0 ;
71+ int g_iSpawnGroupLoads = 0 ;
7272
7373void Message (const char * msg, ...)
7474{
@@ -124,7 +124,7 @@ SH_DECL_HOOK2(IGameEventManager2, LoadEventsFromFile, SH_NOATTRIB, 0, int, const
124124SH_DECL_MANUALHOOK1_void (GoToIntermission, 0 , 0 , 0 , bool );
125125SH_DECL_MANUALHOOK2_void (PhysicsTouchShuffle, 0 , 0 , 0 , CUtlVector<TouchLinked_t>*, bool );
126126SH_DECL_MANUALHOOK3_void (DropWeapon, 0 , 0 , 0 , CBasePlayerWeapon*, Vector*, Vector*);
127- SH_DECL_HOOK1_void (CSpawnGroupMgrGameSystem, SetActiveSpawnGroup , SH_NOATTRIB , 0 , SpawnGroupHandle_t );
127+ SH_DECL_HOOK1_void (IServer, SetGameSpawnGroupMgr , SH_NOATTRIB , 0 , IGameSpawnGroupMgr* );
128128
129129CS2Fixes g_CS2Fixes;
130130
@@ -138,7 +138,7 @@ CGameConfig* g_GameConfig = nullptr;
138138ISteamHTTP* g_http = nullptr ;
139139CSteamGameServerAPIContext g_steamAPI;
140140CCSGameRules* g_pGameRules = nullptr ; // Will be null between map end & new map startup, null check if necessary!
141- CSpawnGroupMgrGameSystem* g_pSpawnGroupMgr = nullptr ;
141+ CSpawnGroupMgrGameSystem* g_pSpawnGroupMgr = nullptr ; // Will be null between map end & new map startup, null check if necessary!
142142int g_iCGamePlayerEquipUseId = -1 ;
143143int g_iCGamePlayerEquipPrecacheId = -1 ;
144144int g_iCreateWorkshopMapGroupId = -1 ;
@@ -148,7 +148,7 @@ int g_iLoadEventsFromFileId = -1;
148148int g_iGoToIntermissionId = -1 ;
149149int g_iPhysicsTouchShuffle = -1 ;
150150int g_iWeaponServiceDropWeaponId = -1 ;
151- int g_iReleaseSpawnGroupId = -1 ;
151+ int g_iSetGameSpawnGroupMgrId = -1 ;
152152
153153CGameEntitySystem* GameEntitySystem ()
154154{
@@ -339,9 +339,6 @@ bool CS2Fixes::Load(PluginId id, ISmmAPI* ismm, char* error, size_t maxlen, bool
339339 SH_MANUALHOOK_RECONFIGURE (GoToIntermission, offset, 0 , 0 );
340340 g_iGoToIntermissionId = SH_ADD_MANUALDVPHOOK (GoToIntermission, pCCSGameRulesVTable, SH_MEMBER (this , &CS2Fixes::Hook_GoToIntermission), false );
341341
342- auto pCSpawnGroupMgrGameSystem = (CSpawnGroupMgrGameSystem*)modules::server->FindVirtualTable (" CSpawnGroupMgrGameSystem" );
343- g_iReleaseSpawnGroupId = SH_ADD_DVPHOOK (CSpawnGroupMgrGameSystem, SetActiveSpawnGroup, pCSpawnGroupMgrGameSystem, SH_MEMBER (this , &CS2Fixes::Hook_SetActiveSpawnGroup), true );
344-
345342 Message (" All hooks started!\n " );
346343
347344 UnlockConVars ();
@@ -442,7 +439,9 @@ bool CS2Fixes::Unload(char* error, size_t maxlen)
442439 SH_REMOVE_HOOK_ID (g_iWeaponServiceDropWeaponId);
443440 SH_REMOVE_HOOK_ID (g_iGoToIntermissionId);
444441 SH_REMOVE_HOOK_ID (g_iCGamePlayerEquipUseId);
445- SH_REMOVE_HOOK_ID (g_iReleaseSpawnGroupId);
442+
443+ if (g_iSetGameSpawnGroupMgrId != -1 )
444+ SH_REMOVE_HOOK_ID (g_iSetGameSpawnGroupMgrId);
446445
447446 if (g_iCGamePlayerEquipPrecacheId != -1 )
448447 SH_REMOVE_HOOK_ID (g_iCGamePlayerEquipPrecacheId);
@@ -609,6 +608,9 @@ void CS2Fixes::Hook_StartupServer(const GameSessionConfiguration_t& config, ISou
609608 g_pEntitySystem = GameEntitySystem ();
610609 g_pEntitySystem->AddListenerEntity (g_pEntityListener);
611610
611+ if (g_pNetworkServerService->GetIGameServer ())
612+ g_iSetGameSpawnGroupMgrId = SH_ADD_HOOK (IServer, SetGameSpawnGroupMgr, g_pNetworkServerService->GetIGameServer (), SH_MEMBER (this , &CS2Fixes::Hook_SetGameSpawnGroupMgr), false );
613+
612614 Message (" Hook_StartupServer: %s\n " , pszMapName);
613615
614616 RegisterEventListeners ();
@@ -990,6 +992,7 @@ void CS2Fixes::Hook_CheckTransmit(CCheckTransmitInfo** ppInfoList, int infoCount
990992 for (int i = 0 ; i < infoCount; i++)
991993 {
992994 auto & pInfo = ppInfoList[i];
995+ CUtlVector<SpawnGroupHandle_t> m_vecSpawnGroups = *((uint8*)pInfo + 40 );
993996
994997 // the offset happens to have a player index here,
995998 // though this is probably part of the client class that contains the CCheckTransmitInfo
@@ -1006,10 +1009,13 @@ void CS2Fixes::Hook_CheckTransmit(CCheckTransmitInfo** ppInfoList, int infoCount
10061009 if (!pSelfZEPlayer)
10071010 continue ;
10081011
1012+ if (m_vecSpawnGroups.Count () != pSelfZEPlayer->GetCheckTransmitSpawnGroupCount ())
1013+ pSelfZEPlayer->SetCheckTransmitSpawnGroupCount (m_vecSpawnGroups.Count ());
1014+
10091015 auto pClient = GetClientBySlot (iPlayerSlot);
10101016
1011- if (pClient && pSelfZEPlayer->IsAdminFlagSet ( ADMFLAG_ROOT ))
1012- ClientPrint (pSelfController, HUD_PRINTCENTER , " Client loaded SpawnGroups: %d " , pClient->m_vecLoadedSpawnGroups .Count ());
1017+ if (pClient && pClient-> m_vecLoadedSpawnGroups . Count () != pSelfZEPlayer->GetClientSpawnGroupCount ( ))
1018+ pSelfZEPlayer-> SetClientSpawnGroupCount ( pClient->m_vecLoadedSpawnGroups .Count ());
10131019
10141020 for (int j = 0 ; j < GetGlobals ()->maxClients ; j++)
10151021 {
@@ -1223,29 +1229,10 @@ int CS2Fixes::Hook_LoadEventsFromFile(const char* filename, bool bSearchAll)
12231229 RETURN_META_VALUE (MRES_IGNORED , 0 );
12241230}
12251231
1226- void CS2Fixes::Hook_SetActiveSpawnGroup (SpawnGroupHandle_t h )
1232+ void CS2Fixes::Hook_SetGameSpawnGroupMgr (IGameSpawnGroupMgr* pSpawnGroupMgr )
12271233{
1228- g_pSpawnGroupMgr = META_IFACEPTR (CSpawnGroupMgrGameSystem);
1229-
1230- RETURN_META (MRES_IGNORED );
1231- }
1232-
1233- CON_COMMAND_F (c_clean_client_spawngroups, " " , FCVAR_SPONLY )
1234- {
1235- CUtlVector<SpawnGroupHandle_t> vecActualSpawnGroups;
1236- addresses::GetSpawnGroups (g_pSpawnGroupMgr, &vecActualSpawnGroups);
1237-
1238- auto pClients = GetClientList ();
1239-
1240- FOR_EACH_VEC (*pClients, i)
1241- {
1242- auto pClient = (*pClients)[i];
1243-
1244- if (!pClient || pClient->m_vecLoadedSpawnGroups .Count () == vecActualSpawnGroups.Count ())
1245- continue ;
1246-
1247- pClient->m_vecLoadedSpawnGroups = vecActualSpawnGroups;
1248- }
1234+ // This also resets our stored pointer on deletion, since null gets passed into this function, nice!
1235+ g_pSpawnGroupMgr = (CSpawnGroupMgrGameSystem*)pSpawnGroupMgr;
12491236}
12501237
12511238void CS2Fixes::OnLevelInit (char const * pMapName,
@@ -1284,6 +1271,8 @@ void CS2Fixes::OnLevelShutdown()
12841271{
12851272 Message (" OnLevelShutdown()\n " );
12861273
1274+ g_iSpawnGroupLoads = 0 ;
1275+
12871276 if (g_cvarVoteManagerEnable.Get ())
12881277 g_pMapVoteSystem->OnLevelShutdown ();
12891278}
0 commit comments