From ba8753836eda3d85784c4e90e467c5ac21dcf1d5 Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Wed, 28 Oct 2020 11:50:16 +0100 Subject: [PATCH] Cleanly remove all hooks on extension unload Allows to e.g. reload sdktools during runtime without crashing. Useful for fast development cycles. --- core/NextMap.cpp | 8 ----- core/logic/PluginSys.cpp | 7 +---- extensions/cstrike/extension.cpp | 22 +++++++++++++ extensions/sdktools/extension.cpp | 1 + extensions/sdktools/extension.h | 1 + extensions/sdktools/hooks.cpp | 52 +++++++++++++++++++++++++++++++ extensions/sdktools/voice.cpp | 10 ++++++ extensions/tf2/extension.cpp | 22 +++++++++++++ 8 files changed, 109 insertions(+), 14 deletions(-) diff --git a/core/NextMap.cpp b/core/NextMap.cpp index 5e426390..41dcb91e 100644 --- a/core/NextMap.cpp +++ b/core/NextMap.cpp @@ -63,11 +63,7 @@ bool g_forcedChange = false; void NextMapManager::OnSourceModAllInitialized_Post() { -#if SOURCE_ENGINE >= SE_ORANGEBOX SH_ADD_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false); -#else - SH_ADD_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false); -#endif ConCommand *pCmd = FindCommand("changelevel"); if (pCmd != NULL) @@ -79,11 +75,7 @@ void NextMapManager::OnSourceModAllInitialized_Post() void NextMapManager::OnSourceModShutdown() { -#if SOURCE_ENGINE >= SE_ORANGEBOX SH_REMOVE_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false); -#else - SH_REMOVE_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false); -#endif if (changeLevelCmd != NULL) { diff --git a/core/logic/PluginSys.cpp b/core/logic/PluginSys.cpp index df6ef4b3..e6cd1dcc 100644 --- a/core/logic/PluginSys.cpp +++ b/core/logic/PluginSys.cpp @@ -846,11 +846,7 @@ CPluginManager::~CPluginManager() void CPluginManager::Shutdown() { - List::iterator iter; - - for (PluginIter iter(m_plugins); !iter.done(); iter.next()) { - UnloadPlugin(*iter); - } + UnloadAll(); } void CPluginManager::LoadAll(const char *config_path, const char *plugins_path) @@ -2208,7 +2204,6 @@ void CPluginManager::UnloadAll() int CPluginManager::GetOrderOfPlugin(IPlugin *pl) { int id = 1; - List::iterator iter; for (PluginIter iter(m_plugins); !iter.done(); iter.next()) { if ((*iter) == pl) diff --git a/extensions/cstrike/extension.cpp b/extensions/cstrike/extension.cpp index 80de1fcc..0e68f5c8 100644 --- a/extensions/cstrike/extension.cpp +++ b/extensions/cstrike/extension.cpp @@ -121,6 +121,28 @@ void CStrike::SDK_OnUnload() SH_REMOVE_HOOK(IServerGameDLL, LevelInit, gamedll, SH_MEMBER(&g_TimeLeftEvents, &TimeLeftEvents::LevelInit), true); hooked_everything = false; } + + if (m_TerminateRoundDetourEnabled) + { + RemoveTerminateRoundDetour(); + m_TerminateRoundDetourEnabled = false; + } + if (m_WeaponPriceDetourEnabled) + { + RemoveWeaponPriceDetour(); + m_WeaponPriceDetourEnabled = false; + } + if (m_HandleBuyDetourEnabled) + { + RemoveHandleBuyDetour(); + m_HandleBuyDetourEnabled = false; + } + if (m_CSWeaponDetourEnabled) + { + RemoveCSWeaponDropDetour(); + m_CSWeaponDetourEnabled = false; + } + g_RegNatives.UnregisterAll(); gameconfs->CloseGameConfigFile(g_pGameConf); plsys->RemovePluginsListener(this); diff --git a/extensions/sdktools/extension.cpp b/extensions/sdktools/extension.cpp index 83381355..ef35c7ba 100644 --- a/extensions/sdktools/extension.cpp +++ b/extensions/sdktools/extension.cpp @@ -261,6 +261,7 @@ void SDKTools::SDK_OnUnload() s_SoundHooks.Shutdown(); g_Hooks.Shutdown(); g_OutputManager.Shutdown(); + VoiceShutdown(); forwards->ReleaseForward(m_OnClientSpeaking); forwards->ReleaseForward(m_OnClientSpeakingEnd); diff --git a/extensions/sdktools/extension.h b/extensions/sdktools/extension.h index 365af704..4e28514e 100644 --- a/extensions/sdktools/extension.h +++ b/extensions/sdktools/extension.h @@ -114,6 +114,7 @@ public: public: // IVoiceServer bool OnSetClientListening(int iReceiver, int iSender, bool bListen); void VoiceInit(); + void VoiceShutdown(); #if SOURCE_ENGINE >= SE_ORANGEBOX void OnClientCommand(edict_t *pEntity, const CCommand &args); #else diff --git a/extensions/sdktools/hooks.cpp b/extensions/sdktools/hooks.cpp index 565a6903..49f62fc6 100644 --- a/extensions/sdktools/hooks.cpp +++ b/extensions/sdktools/hooks.cpp @@ -124,6 +124,58 @@ void CHookManager::Initialize() void CHookManager::Shutdown() { + if (basefilesystemPatch) + { + SH_RELEASE_CALLCLASS(basefilesystemPatch); + basefilesystemPatch = NULL; + } + + if (PRCH_used) + { + for (size_t i = 0; i < m_runUserCmdHooks.size(); ++i) + { + delete m_runUserCmdHooks[i]; + } + + m_runUserCmdHooks.clear(); + PRCH_used = false; + } + + if (PRCHPost_used) + { + for (size_t i = 0; i < m_runUserCmdPostHooks.size(); ++i) + { + delete m_runUserCmdPostHooks[i]; + } + + m_runUserCmdPostHooks.clear(); + PRCHPost_used = false; + } + + if (FILE_used) + { + for (size_t i = 0; i < m_netChannelHooks.size(); ++i) + { + delete m_netChannelHooks[i]; + } + + m_netChannelHooks.clear(); + FILE_used = false; + } + +#if !defined CLIENTVOICE_HOOK_SUPPORT + if (PVD_used) + { + for (size_t i = 0; i < m_netProcessVoiceData.size(); ++i) + { + delete m_netProcessVoiceData[i]; + } + + m_netProcessVoiceData.clear(); + PVD_used = false; + } +#endif + forwards->ReleaseForward(m_usercmdsFwd); forwards->ReleaseForward(m_usercmdsPostFwd); forwards->ReleaseForward(m_netFileSendFwd); diff --git a/extensions/sdktools/voice.cpp b/extensions/sdktools/voice.cpp index c7bb7c39..d872b8f7 100644 --- a/extensions/sdktools/voice.cpp +++ b/extensions/sdktools/voice.cpp @@ -91,6 +91,16 @@ void SDKTools::VoiceInit() SH_ADD_HOOK(IServerGameClients, ClientCommand, serverClients, SH_MEMBER(this, &SDKTools::OnClientCommand), true); } +void SDKTools::VoiceShutdown() +{ + if (g_VoiceHookCount > 0) + { + g_VoiceHookCount = 1; + DecHookCount(); + } + SH_REMOVE_HOOK(IServerGameClients, ClientCommand, serverClients, SH_MEMBER(this, &SDKTools::OnClientCommand), true); +} + #if SOURCE_ENGINE >= SE_ORANGEBOX void SDKTools::OnClientCommand(edict_t *pEntity, const CCommand &args) { diff --git a/extensions/tf2/extension.cpp b/extensions/tf2/extension.cpp index 76e6c234..ce745248 100644 --- a/extensions/tf2/extension.cpp +++ b/extensions/tf2/extension.cpp @@ -167,6 +167,28 @@ void TF2Tools::SDK_OnUnload() SH_REMOVE_HOOK(IServerGameDLL, ServerActivate, gamedll, SH_STATIC(OnServerActivate), true); g_HolidayManager.OnSDKUnload(); + m_GameEventManager->RemoveListener(this); + + if (m_CritDetoursEnabled) + { + g_CritManager.Disable(); + m_CritDetoursEnabled = false; + } + if (m_CondChecksEnabled) + { + g_CondMgr.Shutdown(); + m_CondChecksEnabled = false; + } + if (m_RulesDetoursEnabled) + { + RemoveRulesDetours(); + m_RulesDetoursEnabled = false; + } + if (m_TeleportDetourEnabled) + { + RemoveTeleporterDetour(); + m_TeleportDetourEnabled = false; + } g_RegNatives.UnregisterAll(); gameconfs->CloseGameConfigFile(g_pGameConf);