1
0
mirror of https://github.com/alliedmodders/metamod-source.git synced 2024-12-01 13:24:25 +01:00

Added unload logic for core and core-legacy; no crash on exit anymore

This commit is contained in:
Scott Ehlert 2008-11-18 07:20:38 -06:00
parent a08dc6056a
commit 08a462ac61
3 changed files with 137 additions and 110 deletions

View File

@ -1,5 +1,6 @@
#include <assert.h> #include <assert.h>
#include "sourcemm.h" #include "sourcemm.h"
#include "concommands.h"
#include <loader_bridge.h> #include <loader_bridge.h>
SH_DECL_HOOK0_void(ConCommand, Dispatch, SH_NOATTRIB, false); SH_DECL_HOOK0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
@ -63,6 +64,19 @@ class VspBridge : public IVspBridge
virtual void Unload() 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() virtual const char *GetDescription()

View File

@ -1,110 +1,122 @@
#include "metamod.h" #include "metamod.h"
#include "metamod_util.h" #include "metamod_util.h"
#include <interface.h> #include <interface.h>
#include <eiface.h> #include <eiface.h>
#include <iplayerinfo.h> #include <iplayerinfo.h>
#include <assert.h> #include <assert.h>
#include <loader_bridge.h> #include <loader_bridge.h>
#include "provider/provider_ep2.h" #include "provider/provider_ep2.h"
SH_DECL_HOOK1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &); SH_DECL_HOOK1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
ConCommand *g_plugin_unload = NULL; ConCommand *g_plugin_unload = NULL;
bool g_bIsTryingToUnload; bool g_bIsTryingToUnload;
void InterceptPluginUnloads(const CCommand &args) void InterceptPluginUnloads(const CCommand &args)
{ {
g_bIsTryingToUnload = true; g_bIsTryingToUnload = true;
} }
void InterceptPluginUnloads_Post(const CCommand &args) void InterceptPluginUnloads_Post(const CCommand &args)
{ {
g_bIsTryingToUnload = false; g_bIsTryingToUnload = false;
} }
class VspBridge : public IVspBridge class VspBridge : public IVspBridge
{ {
public: public:
virtual bool Load(const vsp_bridge_info *info, char *error, size_t maxlength) virtual bool Load(const vsp_bridge_info *info, char *error, size_t maxlength)
{ {
assert(!g_Metamod.IsLoadedAsGameDLL()); assert(!g_Metamod.IsLoadedAsGameDLL());
CGlobalVars *pGlobals; CGlobalVars *pGlobals;
IPlayerInfoManager *playerInfoManager; IPlayerInfoManager *playerInfoManager;
playerInfoManager = (IPlayerInfoManager *)info->gsFactory("PlayerInfoManager002", NULL); playerInfoManager = (IPlayerInfoManager *)info->gsFactory("PlayerInfoManager002", NULL);
if (playerInfoManager == NULL) if (playerInfoManager == NULL)
{ {
UTIL_Format(error, maxlength, "Metamod:Source requires gameinfo.txt modification to load on this game"); UTIL_Format(error, maxlength, "Metamod:Source requires gameinfo.txt modification to load on this game");
return false; return false;
} }
pGlobals = playerInfoManager->GetGlobalVars(); pGlobals = playerInfoManager->GetGlobalVars();
char gamedll_iface[] = "ServerGameDLL000"; char gamedll_iface[] = "ServerGameDLL000";
for (unsigned int i = 5; i <= 50; i++) for (unsigned int i = 5; i <= 50; i++)
{ {
gamedll_iface[15] = '0' + i; gamedll_iface[15] = '0' + i;
if ((server = (IServerGameDLL *)info->gsFactory(gamedll_iface, NULL)) != NULL) if ((server = (IServerGameDLL *)info->gsFactory(gamedll_iface, NULL)) != NULL)
{ {
g_Metamod.SetGameDLLInfo((CreateInterfaceFn)info->gsFactory, i); g_Metamod.SetGameDLLInfo((CreateInterfaceFn)info->gsFactory, i);
break; break;
} }
} }
if (server == NULL) if (server == NULL)
{ {
UTIL_Format(error, maxlength, "Metamod:Source could not load (GameDLL version not compatible)."); UTIL_Format(error, maxlength, "Metamod:Source could not load (GameDLL version not compatible).");
return false; return false;
} }
char gameclients_iface[] = "ServerGameClients000"; char gameclients_iface[] = "ServerGameClients000";
for (unsigned int i = 3; i <= 4; i++) for (unsigned int i = 3; i <= 4; i++)
{ {
gameclients_iface[19] = '0' + i; gameclients_iface[19] = '0' + i;
if ((gameclients = (IServerGameClients *)info->gsFactory(gameclients_iface, NULL)) == NULL) if ((gameclients = (IServerGameClients *)info->gsFactory(gameclients_iface, NULL)) == NULL)
break; break;
} }
if (!mm_DetectGameInformation()) if (!mm_DetectGameInformation())
{ {
UTIL_Format(error, maxlength, "Metamod:Source failed to detect game paths; cannot load."); UTIL_Format(error, maxlength, "Metamod:Source failed to detect game paths; cannot load.");
return false; return false;
} }
mm_InitializeForLoad(); mm_InitializeForLoad();
mm_InitializeGlobals((CreateInterfaceFn)info->engineFactory, mm_InitializeGlobals((CreateInterfaceFn)info->engineFactory,
(CreateInterfaceFn)info->engineFactory, (CreateInterfaceFn)info->engineFactory,
(CreateInterfaceFn)info->engineFactory, (CreateInterfaceFn)info->engineFactory,
pGlobals); pGlobals);
mm_StartupMetamod(true); mm_StartupMetamod(true);
g_plugin_unload = icvar->FindCommand("plugin_unload"); g_plugin_unload = icvar->FindCommand("plugin_unload");
if (g_plugin_unload != NULL) 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, false);
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_plugin_unload, InterceptPluginUnloads_Post, true); SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_plugin_unload, InterceptPluginUnloads_Post, true);
} }
return true; return true;
} }
virtual void Unload() virtual void Unload()
{ {
} if (g_bIsTryingToUnload)
{
virtual const char *GetDescription() Error("Metamod:Source cannot be unloaded from VSP mode. Use \"meta unload\" to unload specific plugins.\n");
{ return;
return "Metamod:Source " SVN_FULL_VERSION; }
} if (g_plugin_unload != NULL)
}; {
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, g_plugin_unload, InterceptPluginUnloads, false);
VspBridge mm16_vsp_bridge; SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, g_plugin_unload, InterceptPluginUnloads_Post, true);
g_plugin_unload = NULL;
SMM_API IVspBridge * }
GetVspBridge() mm_UnloadMetamod();
{ }
return &mm16_vsp_bridge;
} virtual const char *GetDescription()
{
return "Metamod:Source " SVN_FULL_VERSION;
}
};
VspBridge mm16_vsp_bridge;
SMM_API IVspBridge *
GetVspBridge()
{
return &mm16_vsp_bridge;
}

View File

@ -162,6 +162,7 @@ public:
if (bridge == NULL) if (bridge == NULL)
return; return;
bridge->Unload(); bridge->Unload();
mm_UnloadMetamodLibrary();
} }
virtual void Pause() virtual void Pause()
{ {