Delay freeing hook manager one frame just in case the entity is deleted while the hook is still on the stack.

This commit is contained in:
Dr!fter 2016-08-26 19:26:52 -04:00
parent bfd6abfb6c
commit b3fb8cc8de
3 changed files with 18 additions and 2 deletions

View File

@ -5,6 +5,20 @@ using namespace SourceHook;
SourceHook::CVector<EntityListener> g_EntityListeners; SourceHook::CVector<EntityListener> g_EntityListeners;
void FrameCleanupHooks(void *data)
{
for (int i = g_pHooks.size() - 1; i >= 0; i--)
{
DHooksManager *manager = g_pHooks.at(i);
if (manager->bDelete)
{
delete manager;
g_pHooks.erase(g_pHooks.iterAt(i));
}
}
}
void DHooks::OnCoreMapEnd() void DHooks::OnCoreMapEnd()
{ {
for(int i = g_pHooks.size() -1; i >= 0; i--) for(int i = g_pHooks.size() -1; i >= 0; i--)
@ -66,8 +80,8 @@ void DHooksEntityListener::OnEntityDestroyed(CBaseEntity *pEntity)
DHooksManager *manager = g_pHooks.at(i); DHooksManager *manager = g_pHooks.at(i);
if(manager->callback->entity == entity) if(manager->callback->entity == entity)
{ {
delete manager; manager->bDelete = true;
g_pHooks.erase(g_pHooks.iterAt(i)); smutils->AddFrameAction(&FrameCleanupHooks, NULL);
} }
} }
} }

View File

@ -26,6 +26,7 @@ DHooksManager::DHooksManager(HookSetup *setup, void *iface, IPluginFunction *rem
this->callback->params = setup->params; this->callback->params = setup->params;
this->addr = 0; this->addr = 0;
this->bDelete = false;
if(this->callback->hookType == HookType_Entity) if(this->callback->hookType == HookType_Entity)
{ {

View File

@ -364,6 +364,7 @@ public:
DHooksCallback *callback; DHooksCallback *callback;
IPluginFunction *remove_callback; IPluginFunction *remove_callback;
SourceHook::HookManagerPubFunc pManager; SourceHook::HookManagerPubFunc pManager;
bool bDelete;
}; };
size_t GetStackArgsSize(DHooksCallback *dg); size_t GetStackArgsSize(DHooksCallback *dg);