From b3fb8cc8de2c7eb545323703b6225b6a18459d61 Mon Sep 17 00:00:00 2001
From: Dr!fter <drifter01620@gmail.com>
Date: Fri, 26 Aug 2016 19:26:52 -0400
Subject: [PATCH] Delay freeing hook manager one frame just in case the entity
 is deleted while the hook is still on the stack.

---
 listeners.cpp | 18 ++++++++++++++++--
 vhook.cpp     |  1 +
 vhook.h       |  1 +
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/listeners.cpp b/listeners.cpp
index ae77bbc..bcf41d0 100644
--- a/listeners.cpp
+++ b/listeners.cpp
@@ -5,6 +5,20 @@ using namespace SourceHook;
 
 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()
 {
 	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);
 		if(manager->callback->entity == entity)
 		{
-			delete manager;
-			g_pHooks.erase(g_pHooks.iterAt(i));
+			manager->bDelete = true;
+			smutils->AddFrameAction(&FrameCleanupHooks, NULL);
 		}
 	}
 }
diff --git a/vhook.cpp b/vhook.cpp
index 8024cd3..3fefab9 100644
--- a/vhook.cpp
+++ b/vhook.cpp
@@ -26,6 +26,7 @@ DHooksManager::DHooksManager(HookSetup *setup, void *iface, IPluginFunction *rem
 	this->callback->params = setup->params;
 
 	this->addr = 0;
+	this->bDelete = false;
 
 	if(this->callback->hookType == HookType_Entity)
 	{
diff --git a/vhook.h b/vhook.h
index 050be4c..0efd281 100644
--- a/vhook.h
+++ b/vhook.h
@@ -364,6 +364,7 @@ public:
 	DHooksCallback *callback;
 	IPluginFunction *remove_callback;
 	SourceHook::HookManagerPubFunc pManager;
+	bool bDelete;
 };
 
 size_t GetStackArgsSize(DHooksCallback *dg);