Fix various problems with unloading ClientPrefs and SourceMod (bug 5874, r=ds).

--HG--
extra : rebase_source : 0a35f8380d651ca65fac9dd402c5cd3625e3105c
This commit is contained in:
David Anderson
2013-08-22 14:05:44 -07:00
parent d79b41e4a7
commit 94d33a4ef1
17 changed files with 195 additions and 183 deletions
+61 -52
View File
@@ -129,6 +129,8 @@ ConfigResult SourceModBase::OnSourceModConfigChanged(const char *key,
return ConfigResult_Ignore;
}
static bool sSourceModInitialized = false;
bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late)
{
const char *gamepath = g_SMAPI->GetBaseDir();
@@ -240,6 +242,8 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late
g_pSourcePawn2->SetDebugListener(logicore.debugger);
sSourceModInitialized = true;
/* Hook this now so we can detect startup without calling StartSourceMod() */
SH_ADD_HOOK(IServerGameDLL, LevelInit, gamedll, SH_MEMBER(this, &SourceModBase::LevelInit), false);
@@ -475,69 +479,74 @@ size_t SourceModBase::BuildPath(PathType type, char *buffer, size_t maxlength, c
void SourceModBase::CloseSourceMod()
{
/* Force a level end */
LevelShutdown();
if (!sSourceModInitialized)
return;
SH_REMOVE_HOOK(IServerGameDLL, LevelInit, gamedll, SH_MEMBER(this, &SourceModBase::LevelInit), false);
if (g_Loaded)
{
/* Force a level end */
LevelShutdown();
ShutdownServices();
}
/* Rest In Peace */
ShutdownLogicBridge();
ShutdownJIT();
}
void SourceModBase::ShutdownServices()
{
/* Unload plugins */
scripts->Shutdown();
/* Unload extensions */
extsys->Shutdown();
SH_REMOVE_HOOK(IServerGameDLL, LevelInit, gamedll, SH_MEMBER(this, &SourceModBase::LevelInit), false);
if (g_pOnMapEnd)
g_Forwards.ReleaseForward(g_pOnMapEnd);
if (g_Loaded)
/* Notify! */
SMGlobalClass *pBase = SMGlobalClass::head;
while (pBase)
{
if (g_pOnMapEnd)
{
g_Forwards.ReleaseForward(g_pOnMapEnd);
}
/* Notify! */
SMGlobalClass *pBase = SMGlobalClass::head;
while (pBase)
{
pBase->OnSourceModShutdown();
pBase = pBase->m_pGlobalClassNext;
}
/* Delete all data packs */
CStack<CDataPack *>::iterator iter;
CDataPack *pd;
for (iter=m_freepacks.begin(); iter!=m_freepacks.end(); iter++)
{
pd = (*iter);
delete pd;
}
m_freepacks.popall();
/* Notify! */
pBase = SMGlobalClass::head;
while (pBase)
{
pBase->OnSourceModAllShutdown();
pBase = pBase->m_pGlobalClassNext;
}
if (enginePatch)
{
SH_RELEASE_CALLCLASS(enginePatch);
enginePatch = NULL;
}
if (gamedllPatch)
{
SH_RELEASE_CALLCLASS(gamedllPatch);
gamedllPatch = NULL;
}
SH_REMOVE_HOOK(IServerGameDLL, LevelShutdown, gamedll, SH_MEMBER(this, &SourceModBase::LevelShutdown), false);
SH_REMOVE_HOOK(IServerGameDLL, GameFrame, gamedll, SH_MEMBER(&g_Timers, &TimerSystem::GameFrame), false);
pBase->OnSourceModShutdown();
pBase = pBase->m_pGlobalClassNext;
}
/* Rest In Peace */
ShutdownLogicBridge();
ShutdownJIT();
/* Delete all data packs */
CStack<CDataPack *>::iterator iter;
CDataPack *pd;
for (iter=m_freepacks.begin(); iter!=m_freepacks.end(); iter++)
{
pd = (*iter);
delete pd;
}
m_freepacks.popall();
/* Notify! */
pBase = SMGlobalClass::head;
while (pBase)
{
pBase->OnSourceModAllShutdown();
pBase = pBase->m_pGlobalClassNext;
}
if (enginePatch)
{
SH_RELEASE_CALLCLASS(enginePatch);
enginePatch = NULL;
}
if (gamedllPatch)
{
SH_RELEASE_CALLCLASS(gamedllPatch);
gamedllPatch = NULL;
}
SH_REMOVE_HOOK(IServerGameDLL, LevelShutdown, gamedll, SH_MEMBER(this, &SourceModBase::LevelShutdown), false);
SH_REMOVE_HOOK(IServerGameDLL, GameFrame, gamedll, SH_MEMBER(&g_Timers, &TimerSystem::GameFrame), false);
}
void SourceModBase::LogMessage(IExtension *pExt, const char *format, ...)