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:
parent
a08dc6056a
commit
08a462ac61
@ -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()
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user