From adc9569e2332a5e9b46f06a72f1df4247b550f0d Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Sat, 10 May 2014 22:21:38 -0400 Subject: [PATCH] Fix clients being invalid when passed to OnEntityDestroyed (bug 6119, r=KyleS). --HG-- extra : rebase_source : 546168635b7e7cd8f8c4302858aa258025444dfd --- extensions/sdkhooks/extension.cpp | 46 +++++++++++++++++++++---------- extensions/sdkhooks/extension.h | 2 ++ 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/extensions/sdkhooks/extension.cpp b/extensions/sdkhooks/extension.cpp index 51673da0..7aee5948 100644 --- a/extensions/sdkhooks/extension.cpp +++ b/extensions/sdkhooks/extension.cpp @@ -422,6 +422,13 @@ void SDKHooks::OnClientPutInServer(int client) m_EntityExists.Set(client); } +void SDKHooks::OnClientDisconnecting(int client) +{ + CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(client); + + HandleEntityDeleted(pEntity, client); +} + void SDKHooks::AddEntityListener(ISMEntityListener *listener) { m_EntListeners.push_back(listener); @@ -1609,24 +1616,13 @@ void SDKHooks::Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_T void SDKHooks::OnEntityDeleted(CBaseEntity *pEntity) { - // Send OnEntityDestroyed to SM listeners - SourceHook::List::iterator iter; - ISMEntityListener *pListener = NULL; - for (iter=m_EntListeners.begin(); iter!=m_EntListeners.end(); iter++) + int entity = gamehelpers->EntityToBCompatRef(pEntity); + if (entity > 0 && entity <= playerhelpers->GetMaxClients()) { - pListener = (*iter); - pListener->OnEntityDestroyed(pEntity); + return; } - int entity = gamehelpers->EntityToBCompatRef(pEntity); - - // Call OnEntityDestroyed forward - g_pOnEntityDestroyed->PushCell(entity); - g_pOnEntityDestroyed->Execute(NULL); - - Unhook(pEntity); - - m_EntityExists.Set(gamehelpers->ReferenceToIndex(entity), false); + HandleEntityDeleted(pEntity, entity); } void SDKHooks::Hook_VPhysicsUpdate(IPhysicsObject *pPhysics) @@ -1719,3 +1715,23 @@ bool SDKHooks::Hook_WeaponSwitchPost(CBaseCombatWeapon *pWeapon, int viewmodelin cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponSwitchPost, pWeapon); RETURN_META_VALUE(MRES_IGNORED, true); } + +void SDKHooks::HandleEntityDeleted(CBaseEntity *pEntity, int ref) +{ + // Send OnEntityDestroyed to SM listeners + SourceHook::List::iterator iter; + ISMEntityListener *pListener = NULL; + for (iter = m_EntListeners.begin(); iter != m_EntListeners.end(); iter++) + { + pListener = (*iter); + pListener->OnEntityDestroyed(pEntity); + } + + // Call OnEntityDestroyed forward + g_pOnEntityDestroyed->PushCell(ref); + g_pOnEntityDestroyed->Execute(NULL); + + Unhook(pEntity); + + m_EntityExists.Set(gamehelpers->ReferenceToIndex(ref), false); +} diff --git a/extensions/sdkhooks/extension.h b/extensions/sdkhooks/extension.h index 032bd3b8..736f0eb1 100644 --- a/extensions/sdkhooks/extension.h +++ b/extensions/sdkhooks/extension.h @@ -244,6 +244,7 @@ public: // IEntityListener public: // IClientListener virtual void OnClientPutInServer(int client); + virtual void OnClientDisconnecting(int client); public: // ISDKHooks virtual void AddEntityListener(ISMEntityListener *listener); @@ -330,6 +331,7 @@ public: bool Hook_WeaponSwitchPost(CBaseCombatWeapon *pWeapon, int viewmodelindex); private: + void HandleEntityDeleted(CBaseEntity *pEntity, int ref); void Unhook(CBaseEntity *pEntity); void Unhook(IPluginContext *pContext); };