From 08a462ac6181d2231b4143b2af2eae520490c4f5 Mon Sep 17 00:00:00 2001 From: Scott Ehlert Date: Tue, 18 Nov 2008 07:20:38 -0600 Subject: [PATCH] Added unload logic for core and core-legacy; no crash on exit anymore --- core-legacy/vsp_bridge.cpp | 14 +++ core/vsp_bridge.cpp | 232 +++++++++++++++++++------------------ loader/serverplugin.cpp | 1 + 3 files changed, 137 insertions(+), 110 deletions(-) diff --git a/core-legacy/vsp_bridge.cpp b/core-legacy/vsp_bridge.cpp index e54aec2..dda5014 100644 --- a/core-legacy/vsp_bridge.cpp +++ b/core-legacy/vsp_bridge.cpp @@ -1,5 +1,6 @@ #include #include "sourcemm.h" +#include "concommands.h" #include SH_DECL_HOOK0_void(ConCommand, Dispatch, SH_NOATTRIB, false); @@ -63,6 +64,19 @@ class VspBridge : public IVspBridge virtual void Unload() { + if (g_bIsTryingToUnload) + { + Error("Metamod:Source cannot be unloaded from VSP mode. Use \"meta unload\" to unload specific plugins.\n"); + return; + } + if (g_plugin_unload != NULL) + { + SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, g_plugin_unload, InterceptPluginUnloads, false); + SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, g_plugin_unload, InterceptPluginUnloads_Post, true); + g_plugin_unload = NULL; + } + g_SMConVarAccessor.UnloadMetamodCommands(); + UnloadMetamod(false); } virtual const char *GetDescription() diff --git a/core/vsp_bridge.cpp b/core/vsp_bridge.cpp index 248587a..95efb27 100644 --- a/core/vsp_bridge.cpp +++ b/core/vsp_bridge.cpp @@ -1,110 +1,122 @@ -#include "metamod.h" -#include "metamod_util.h" -#include -#include -#include -#include -#include -#include "provider/provider_ep2.h" - -SH_DECL_HOOK1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &); - -ConCommand *g_plugin_unload = NULL; -bool g_bIsTryingToUnload; - -void InterceptPluginUnloads(const CCommand &args) -{ - g_bIsTryingToUnload = true; -} - -void InterceptPluginUnloads_Post(const CCommand &args) -{ - g_bIsTryingToUnload = false; -} - -class VspBridge : public IVspBridge -{ -public: - virtual bool Load(const vsp_bridge_info *info, char *error, size_t maxlength) - { - assert(!g_Metamod.IsLoadedAsGameDLL()); - - CGlobalVars *pGlobals; - IPlayerInfoManager *playerInfoManager; - - playerInfoManager = (IPlayerInfoManager *)info->gsFactory("PlayerInfoManager002", NULL); - if (playerInfoManager == NULL) - { - UTIL_Format(error, maxlength, "Metamod:Source requires gameinfo.txt modification to load on this game"); - return false; - } - - pGlobals = playerInfoManager->GetGlobalVars(); - - char gamedll_iface[] = "ServerGameDLL000"; - for (unsigned int i = 5; i <= 50; i++) - { - gamedll_iface[15] = '0' + i; - if ((server = (IServerGameDLL *)info->gsFactory(gamedll_iface, NULL)) != NULL) - { - g_Metamod.SetGameDLLInfo((CreateInterfaceFn)info->gsFactory, i); - break; - } - } - - if (server == NULL) - { - UTIL_Format(error, maxlength, "Metamod:Source could not load (GameDLL version not compatible)."); - return false; - } - - char gameclients_iface[] = "ServerGameClients000"; - for (unsigned int i = 3; i <= 4; i++) - { - gameclients_iface[19] = '0' + i; - if ((gameclients = (IServerGameClients *)info->gsFactory(gameclients_iface, NULL)) == NULL) - break; - } - - if (!mm_DetectGameInformation()) - { - UTIL_Format(error, maxlength, "Metamod:Source failed to detect game paths; cannot load."); - return false; - } - - mm_InitializeForLoad(); - mm_InitializeGlobals((CreateInterfaceFn)info->engineFactory, - (CreateInterfaceFn)info->engineFactory, - (CreateInterfaceFn)info->engineFactory, - pGlobals); - mm_StartupMetamod(true); - - g_plugin_unload = icvar->FindCommand("plugin_unload"); - - if (g_plugin_unload != NULL) - { - SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_plugin_unload, InterceptPluginUnloads, false); - SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_plugin_unload, InterceptPluginUnloads_Post, true); - } - - return true; - } - - virtual void Unload() - { - } - - virtual const char *GetDescription() - { - return "Metamod:Source " SVN_FULL_VERSION; - } -}; - -VspBridge mm16_vsp_bridge; - -SMM_API IVspBridge * -GetVspBridge() -{ - return &mm16_vsp_bridge; -} - +#include "metamod.h" +#include "metamod_util.h" +#include +#include +#include +#include +#include +#include "provider/provider_ep2.h" + +SH_DECL_HOOK1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &); + +ConCommand *g_plugin_unload = NULL; +bool g_bIsTryingToUnload; + +void InterceptPluginUnloads(const CCommand &args) +{ + g_bIsTryingToUnload = true; +} + +void InterceptPluginUnloads_Post(const CCommand &args) +{ + g_bIsTryingToUnload = false; +} + +class VspBridge : public IVspBridge +{ +public: + virtual bool Load(const vsp_bridge_info *info, char *error, size_t maxlength) + { + assert(!g_Metamod.IsLoadedAsGameDLL()); + + CGlobalVars *pGlobals; + IPlayerInfoManager *playerInfoManager; + + playerInfoManager = (IPlayerInfoManager *)info->gsFactory("PlayerInfoManager002", NULL); + if (playerInfoManager == NULL) + { + UTIL_Format(error, maxlength, "Metamod:Source requires gameinfo.txt modification to load on this game"); + return false; + } + + pGlobals = playerInfoManager->GetGlobalVars(); + + char gamedll_iface[] = "ServerGameDLL000"; + for (unsigned int i = 5; i <= 50; i++) + { + gamedll_iface[15] = '0' + i; + if ((server = (IServerGameDLL *)info->gsFactory(gamedll_iface, NULL)) != NULL) + { + g_Metamod.SetGameDLLInfo((CreateInterfaceFn)info->gsFactory, i); + break; + } + } + + if (server == NULL) + { + UTIL_Format(error, maxlength, "Metamod:Source could not load (GameDLL version not compatible)."); + return false; + } + + char gameclients_iface[] = "ServerGameClients000"; + for (unsigned int i = 3; i <= 4; i++) + { + gameclients_iface[19] = '0' + i; + if ((gameclients = (IServerGameClients *)info->gsFactory(gameclients_iface, NULL)) == NULL) + break; + } + + if (!mm_DetectGameInformation()) + { + UTIL_Format(error, maxlength, "Metamod:Source failed to detect game paths; cannot load."); + return false; + } + + mm_InitializeForLoad(); + mm_InitializeGlobals((CreateInterfaceFn)info->engineFactory, + (CreateInterfaceFn)info->engineFactory, + (CreateInterfaceFn)info->engineFactory, + pGlobals); + mm_StartupMetamod(true); + + g_plugin_unload = icvar->FindCommand("plugin_unload"); + + if (g_plugin_unload != NULL) + { + SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_plugin_unload, InterceptPluginUnloads, false); + SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_plugin_unload, InterceptPluginUnloads_Post, true); + } + + return true; + } + + virtual void Unload() + { + if (g_bIsTryingToUnload) + { + Error("Metamod:Source cannot be unloaded from VSP mode. Use \"meta unload\" to unload specific plugins.\n"); + return; + } + if (g_plugin_unload != NULL) + { + SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, g_plugin_unload, InterceptPluginUnloads, false); + SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, g_plugin_unload, InterceptPluginUnloads_Post, true); + g_plugin_unload = NULL; + } + mm_UnloadMetamod(); + } + + virtual const char *GetDescription() + { + return "Metamod:Source " SVN_FULL_VERSION; + } +}; + +VspBridge mm16_vsp_bridge; + +SMM_API IVspBridge * +GetVspBridge() +{ + return &mm16_vsp_bridge; +} + diff --git a/loader/serverplugin.cpp b/loader/serverplugin.cpp index 44565dc..c6d62c4 100644 --- a/loader/serverplugin.cpp +++ b/loader/serverplugin.cpp @@ -162,6 +162,7 @@ public: if (bridge == NULL) return; bridge->Unload(); + mm_UnloadMetamodLibrary(); } virtual void Pause() {