Fix clients being invalid when passed to OnEntityDestroyed (bug 6119, r=KyleS).

--HG--
extra : rebase_source : 546168635b7e7cd8f8c4302858aa258025444dfd
This commit is contained in:
Nicholas Hastings 2014-05-10 22:21:38 -04:00
parent 4cd6c37ab5
commit adc9569e23
2 changed files with 33 additions and 15 deletions

View File

@ -422,6 +422,13 @@ void SDKHooks::OnClientPutInServer(int client)
m_EntityExists.Set(client); m_EntityExists.Set(client);
} }
void SDKHooks::OnClientDisconnecting(int client)
{
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(client);
HandleEntityDeleted(pEntity, client);
}
void SDKHooks::AddEntityListener(ISMEntityListener *listener) void SDKHooks::AddEntityListener(ISMEntityListener *listener)
{ {
m_EntListeners.push_back(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) void SDKHooks::OnEntityDeleted(CBaseEntity *pEntity)
{ {
// Send OnEntityDestroyed to SM listeners int entity = gamehelpers->EntityToBCompatRef(pEntity);
SourceHook::List<ISMEntityListener *>::iterator iter; if (entity > 0 && entity <= playerhelpers->GetMaxClients())
ISMEntityListener *pListener = NULL;
for (iter=m_EntListeners.begin(); iter!=m_EntListeners.end(); iter++)
{ {
pListener = (*iter); return;
pListener->OnEntityDestroyed(pEntity);
} }
int entity = gamehelpers->EntityToBCompatRef(pEntity); HandleEntityDeleted(pEntity, entity);
// Call OnEntityDestroyed forward
g_pOnEntityDestroyed->PushCell(entity);
g_pOnEntityDestroyed->Execute(NULL);
Unhook(pEntity);
m_EntityExists.Set(gamehelpers->ReferenceToIndex(entity), false);
} }
void SDKHooks::Hook_VPhysicsUpdate(IPhysicsObject *pPhysics) 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); cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponSwitchPost, pWeapon);
RETURN_META_VALUE(MRES_IGNORED, true); RETURN_META_VALUE(MRES_IGNORED, true);
} }
void SDKHooks::HandleEntityDeleted(CBaseEntity *pEntity, int ref)
{
// Send OnEntityDestroyed to SM listeners
SourceHook::List<ISMEntityListener *>::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);
}

View File

@ -244,6 +244,7 @@ public: // IEntityListener
public: // IClientListener public: // IClientListener
virtual void OnClientPutInServer(int client); virtual void OnClientPutInServer(int client);
virtual void OnClientDisconnecting(int client);
public: // ISDKHooks public: // ISDKHooks
virtual void AddEntityListener(ISMEntityListener *listener); virtual void AddEntityListener(ISMEntityListener *listener);
@ -330,6 +331,7 @@ public:
bool Hook_WeaponSwitchPost(CBaseCombatWeapon *pWeapon, int viewmodelindex); bool Hook_WeaponSwitchPost(CBaseCombatWeapon *pWeapon, int viewmodelindex);
private: private:
void HandleEntityDeleted(CBaseEntity *pEntity, int ref);
void Unhook(CBaseEntity *pEntity); void Unhook(CBaseEntity *pEntity);
void Unhook(IPluginContext *pContext); void Unhook(IPluginContext *pContext);
}; };