diff --git a/core/PlayerManager.cpp b/core/PlayerManager.cpp index d6d6e8c3..9c236aeb 100644 --- a/core/PlayerManager.cpp +++ b/core/PlayerManager.cpp @@ -61,6 +61,7 @@ int lifestate_offset = -1; List target_processors; SH_DECL_HOOK5(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, edict_t *, const char *, const char *, char *, int); +SH_DECL_HOOK2_void(IServerGameClients, ClientActive, SH_NOATTRIB, 0, edict_t *, bool); SH_DECL_HOOK2_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, edict_t *, const char *); SH_DECL_HOOK1_void(IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, edict_t *); #if SOURCE_ENGINE >= SE_ORANGEBOX @@ -135,6 +136,7 @@ void PlayerManager::OnSourceModAllInitialized() SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientCommand, serverClients, this, &PlayerManager::OnClientCommand, false); SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientSettingsChanged, serverClients, this, &PlayerManager::OnClientSettingsChanged, true); SH_ADD_HOOK_MEMFUNC(IServerGameDLL, ServerActivate, gamedll, this, &PlayerManager::OnServerActivate, true); + SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientActive, serverClients, this, &PlayerManager::OnClientActive, true); g_ShareSys.AddInterface(NULL, this); @@ -171,6 +173,7 @@ void PlayerManager::OnSourceModAllInitialized() void PlayerManager::OnSourceModShutdown() { + SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientActive, serverClients, this, &PlayerManager::OnClientActive, true); SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientConnect, serverClients, this, &PlayerManager::OnClientConnect, false); SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, serverClients, this, &PlayerManager::OnClientPutInServer, true); SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &PlayerManager::OnClientDisconnect, false); @@ -489,6 +492,14 @@ bool PlayerManager::OnClientConnect_Post(edict_t *pEntity, const char *pszName, return true; } +void PlayerManager::OnClientActive(edict_t *pEntity, bool bLoadGame) +{ + int client = IndexOfEdict(pEntity); + CPlayer *pPlayer = &m_Players[client]; + + pPlayer->Activate(); +} + void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername) { cell_t res; @@ -1445,6 +1456,7 @@ CPlayer::CPlayer() m_LastPassword.clear(); m_LangId = SOURCEMOD_LANGUAGE_ENGLISH; m_bFakeClient = false; + m_IsActive = false; } void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity) @@ -1516,6 +1528,7 @@ void CPlayer::Disconnect() m_UserId = -1; m_bIsInKickQueue = false; m_bFakeClient = false; + m_IsActive = false; } void CPlayer::SetName(const char *name) @@ -1827,3 +1840,14 @@ unsigned int CPlayer::GetSerial() { return m_Serial.value; } + +bool CPlayer::IsActive() +{ + return m_IsActive; +} + +void CPlayer::Activate() +{ + m_IsActive = true; +} + diff --git a/core/PlayerManager.h b/core/PlayerManager.h index 52931cd8..88b204f8 100644 --- a/core/PlayerManager.h +++ b/core/PlayerManager.h @@ -72,6 +72,7 @@ public: const char *GetAuthString(); edict_t *GetEdict(); bool IsInGame(); + bool IsActive(); bool WasCountedAsInGame(); bool IsConnected(); bool IsAuthorized(); @@ -90,6 +91,7 @@ public: void DoBasicAdminChecks(); void MarkAsBeingKicked(); int GetLifeState(); + void Activate(); private: void Initialize(const char *name, const char *ip, edict_t *pEntity); void Connect(); @@ -119,6 +121,7 @@ private: int m_UserId; bool m_bFakeClient; serial_t m_Serial; + bool m_IsActive; }; class PlayerManager : @@ -147,6 +150,7 @@ public: void OnClientPutInServer(edict_t *pEntity, char const *playername); void OnClientDisconnect(edict_t *pEntity); void OnClientDisconnect_Post(edict_t *pEntity); + void OnClientActive(edict_t *pEntity, bool bLoadGame); #if SOURCE_ENGINE >= SE_ORANGEBOX void OnClientCommand(edict_t *pEntity, const CCommand &args); #else diff --git a/core/smn_console.cpp b/core/smn_console.cpp index 5f76426b..99abeb42 100644 --- a/core/smn_console.cpp +++ b/core/smn_console.cpp @@ -45,6 +45,7 @@ #include #include "Logger.h" #include "ConsoleDetours.h" +#include #if (SOURCE_ENGINE == SE_LEFT4DEAD) || (SOURCE_ENGINE == SE_LEFT4DEAD2) #define NET_SETCONVAR 6 @@ -200,6 +201,7 @@ static void ReplicateConVar(ConVar *pConVar) if (pPlayer && pPlayer->IsInGame() && !pPlayer->IsFakeClient()) { + assert(pPlayer->IsActive()); INetChannel *netchan = static_cast(engine->GetPlayerNetInfo(i)); netchan->SendData(buffer); } @@ -1321,6 +1323,11 @@ static cell_t SendConVarValue(IPluginContext *pContext, const cell_t *params) return pContext->ThrowNativeError("Client %d is fake and cannot be targeted", params[1]); } + if (!pPlayer->IsActive()) + { + return 1; + } + INetChannel *netchan = static_cast(engine->GetPlayerNetInfo(params[1])); netchan->SendData(buffer);