Fix various problems with unloading ClientPrefs and SourceMod (bug 5874, r=ds).
--HG-- extra : rebase_source : 0a35f8380d651ca65fac9dd402c5cd3625e3105c
This commit is contained in:
parent
d79b41e4a7
commit
94d33a4ef1
@ -775,25 +775,21 @@ CExtension *CExtensionManager::FindByOrder(unsigned int num)
|
||||
bool CExtensionManager::UnloadExtension(IExtension *_pExt)
|
||||
{
|
||||
if (!_pExt)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CExtension *pExt = (CExtension *)_pExt;
|
||||
|
||||
if (m_Libs.find(pExt) == m_Libs.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Tell it to unload */
|
||||
if (pExt->IsLoaded())
|
||||
{
|
||||
IExtensionInterface *pAPI = pExt->GetAPI();
|
||||
pAPI->OnExtensionUnload();
|
||||
}
|
||||
pExt->GetAPI()->OnExtensionUnload();
|
||||
|
||||
/* First remove us from internal lists */
|
||||
// Remove us from internal lists. Note that because we do this, it's
|
||||
// possible that our extension could be added back if another plugin
|
||||
// tries to load during this process. If we ever find this to happen,
|
||||
// we can just block plugin loading.
|
||||
g_ShareSys.RemoveInterfaces(_pExt);
|
||||
m_Libs.remove(pExt);
|
||||
|
||||
@ -827,13 +823,9 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt)
|
||||
{
|
||||
pDep = (*c_iter);
|
||||
if ((pAPI=pDep->GetAPI()) == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (pDep == pExt)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/* Now, get its dependency list */
|
||||
bool dropped = false;
|
||||
List<IfaceInfo>::iterator i_iter = pDep->m_Deps.begin();
|
||||
@ -862,15 +854,11 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt)
|
||||
while (i_iter != pDep->m_ChildDeps.end())
|
||||
{
|
||||
if ((*i_iter).owner == pExt)
|
||||
{
|
||||
i_iter = pDep->m_ChildDeps.erase(i_iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
i_iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Unbind our natives from Core */
|
||||
pExt->DropEverything();
|
||||
@ -887,6 +875,11 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt)
|
||||
}
|
||||
}
|
||||
|
||||
// Everything has been informed that we're unloading, so give the
|
||||
// extension one last notification.
|
||||
if (pExt->IsLoaded() && pExt->GetAPI()->GetExtensionVersion() >= 7)
|
||||
pExt->GetAPI()->OnDependenciesDropped();
|
||||
|
||||
pExt->Unload();
|
||||
delete pExt;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* vim: set ts=4 sw=4 :
|
||||
* vim: set ts=4 sw=4 tw=99 noet:
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
@ -147,6 +147,7 @@ static void logic_init(const sm_core_t* core, sm_logic_t* _logic)
|
||||
gamehelpers = core->gamehelpers;
|
||||
g_pSourcePawn = *core->spe1;
|
||||
g_pSourcePawn2 = *core->spe2;
|
||||
SMGlobalClass::head = core->listeners;
|
||||
|
||||
g_ShareSys.Initialize();
|
||||
g_pCoreIdent = g_ShareSys.CreateCoreIdentity();
|
||||
|
@ -49,7 +49,7 @@ using namespace SourceHook;
|
||||
* Add 1 to the RHS of this expression to bump the intercom file
|
||||
* This is to prevent mismatching core/logic binaries
|
||||
*/
|
||||
#define SM_LOGIC_MAGIC (0x0F47C0DE - 22)
|
||||
#define SM_LOGIC_MAGIC (0x0F47C0DE - 23)
|
||||
|
||||
#if defined SM_LOGIC
|
||||
class IVEngineServer
|
||||
@ -270,6 +270,7 @@ struct sm_core_t
|
||||
void * serverFactory;
|
||||
void * engineFactory;
|
||||
void * matchmakingDSFactory;
|
||||
SMGlobalClass * listeners;
|
||||
};
|
||||
|
||||
struct sm_logic_t
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* vim: set ts=4 sw=4 :
|
||||
* vim: set ts=4 sw=4 tw=99 noet:
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
|
||||
@ -406,6 +406,7 @@ void InitLogicBridge()
|
||||
|
||||
core_bridge.engineFactory = (void *)g_SMAPI->GetEngineFactory(false);
|
||||
core_bridge.serverFactory = (void *)g_SMAPI->GetServerFactory(false);
|
||||
core_bridge.listeners = SMGlobalClass::head;
|
||||
|
||||
ILibrary *mmlib;
|
||||
char path[PLATFORM_MAX_PATH];
|
||||
|
@ -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);
|
||||
|
||||
@ -474,24 +478,34 @@ size_t SourceModBase::BuildPath(PathType type, char *buffer, size_t maxlength, c
|
||||
}
|
||||
|
||||
void SourceModBase::CloseSourceMod()
|
||||
{
|
||||
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_Loaded)
|
||||
{
|
||||
if (g_pOnMapEnd)
|
||||
{
|
||||
g_Forwards.ReleaseForward(g_pOnMapEnd);
|
||||
}
|
||||
|
||||
/* Notify! */
|
||||
SMGlobalClass *pBase = SMGlobalClass::head;
|
||||
@ -535,11 +549,6 @@ void SourceModBase::CloseSourceMod()
|
||||
SH_REMOVE_HOOK(IServerGameDLL, GameFrame, gamedll, SH_MEMBER(&g_Timers, &TimerSystem::GameFrame), false);
|
||||
}
|
||||
|
||||
/* Rest In Peace */
|
||||
ShutdownLogicBridge();
|
||||
ShutdownJIT();
|
||||
}
|
||||
|
||||
void SourceModBase::LogMessage(IExtension *pExt, const char *format, ...)
|
||||
{
|
||||
IExtensionInterface *pAPI = pExt->GetAPI();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* vim: set ts=4 sw=4 tw=99 noet:
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
|
||||
@ -136,6 +136,8 @@ public: // ISourceMod
|
||||
int GetPluginId();
|
||||
int GetShApiVersion();
|
||||
bool IsMapRunning();
|
||||
private:
|
||||
void ShutdownServices();
|
||||
private:
|
||||
CStack<CDataPack *> m_freepacks;
|
||||
char m_SMBaseDir[PLATFORM_MAX_PATH];
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* vim: set ts=4 sw=4 tw=99 noet:
|
||||
* =============================================================================
|
||||
* SourceMod Client Preferences Extension
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
@ -55,35 +55,12 @@ void CookieManager::Unload()
|
||||
for (int i = playerhelpers->GetMaxClients()+1; --i > 0;)
|
||||
{
|
||||
if (connected[i])
|
||||
{
|
||||
OnClientDisconnecting(i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Find all cookies and delete them */
|
||||
Cookie *current;
|
||||
|
||||
for (SourceHook::List<Cookie *>::iterator _iter = cookieList.begin(); _iter != cookieList.end(); _iter++)
|
||||
{
|
||||
current = (Cookie *)*_iter;
|
||||
|
||||
if (current == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
g_ClientPrefs.cookieMutex->Lock();
|
||||
if (current->usedInQuery)
|
||||
{
|
||||
current->shouldDelete = true;
|
||||
g_ClientPrefs.cookieMutex->Unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
g_ClientPrefs.cookieMutex->Unlock();
|
||||
delete current;
|
||||
}
|
||||
}
|
||||
delete (*_iter);
|
||||
|
||||
cookieList.clear();
|
||||
}
|
||||
@ -93,9 +70,7 @@ Cookie *CookieManager::FindCookie(const char *name)
|
||||
Cookie **pCookie = cookieTrie.retrieve(name);
|
||||
|
||||
if (pCookie == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return *pCookie;
|
||||
}
|
||||
@ -116,7 +91,6 @@ Cookie *CookieManager::CreateCookie(const char *name, const char *description, C
|
||||
|
||||
/* First time cookie - Create from scratch */
|
||||
pCookie = new Cookie(name, description, access);
|
||||
pCookie->usedInQuery++;
|
||||
|
||||
/* Attempt to insert cookie into the db and get its ID num */
|
||||
TQueryOp *op = new TQueryOp(Query_InsertCookie, pCookie);
|
||||
|
@ -75,34 +75,23 @@ struct Cookie
|
||||
dbid = -1;
|
||||
|
||||
for (int i=0; i<=MAXCLIENTS; i++)
|
||||
{
|
||||
data[i] = NULL;
|
||||
}
|
||||
|
||||
shouldDelete = false;
|
||||
usedInQuery = 0;
|
||||
}
|
||||
|
||||
~Cookie()
|
||||
{
|
||||
for (int i=0; i<=MAXCLIENTS; i++)
|
||||
{
|
||||
if (data[i] != NULL)
|
||||
{
|
||||
delete data[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char name[MAX_NAME_LENGTH+1];
|
||||
char description[MAX_DESC_LENGTH+1];
|
||||
int dbid;
|
||||
CookieData *data[MAXCLIENTS+1];
|
||||
CookieAccess access;
|
||||
|
||||
/* Reference counting stuff */
|
||||
bool shouldDelete;
|
||||
int usedInQuery;
|
||||
};
|
||||
|
||||
class CookieManager : public IClientListener, public IPluginsListener
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* vim: set ts=4 sw=4 tw=99 noet:
|
||||
* =============================================================================
|
||||
* SourceMod Client Preferences Extension
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
@ -50,9 +50,6 @@ DbDriver g_DriverType;
|
||||
|
||||
bool ClientPrefs::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
{
|
||||
queryMutex = threader->MakeMutex();
|
||||
cookieMutex = threader->MakeMutex();
|
||||
|
||||
DBInfo = dbi->FindDatabaseConf("clientprefs");
|
||||
|
||||
if (DBInfo == NULL)
|
||||
@ -155,13 +152,15 @@ void ClientPrefs::NotifyInterfaceDrop(SMInterface *pInterface)
|
||||
}
|
||||
}
|
||||
|
||||
void ClientPrefs::SDK_OnUnload()
|
||||
void ClientPrefs::SDK_OnDependenciesDropped()
|
||||
{
|
||||
// At this point, we're guaranteed that DBI has flushed the worker thread
|
||||
// for us, so no cookies should have outstanding queries.
|
||||
g_CookieManager.Unload();
|
||||
|
||||
handlesys->RemoveType(g_CookieType, myself->GetIdentity());
|
||||
handlesys->RemoveType(g_CookieIterator, myself->GetIdentity());
|
||||
|
||||
g_CookieManager.Unload();
|
||||
|
||||
if (Database != NULL)
|
||||
{
|
||||
Database->Close();
|
||||
@ -199,9 +198,6 @@ void ClientPrefs::SDK_OnUnload()
|
||||
|
||||
plsys->RemovePluginsListener(&g_CookieManager);
|
||||
playerhelpers->RemoveClientListener(&g_CookieManager);
|
||||
|
||||
queryMutex->DestroyThis();
|
||||
cookieMutex->DestroyThis();
|
||||
}
|
||||
|
||||
void ClientPrefs::OnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax)
|
||||
@ -312,7 +308,11 @@ void ClientPrefs::DatabaseConnect()
|
||||
|
||||
databaseLoading = false;
|
||||
|
||||
// Need a new scope because of the goto above.
|
||||
{
|
||||
ke::AutoLock lock(&queryLock);
|
||||
this->ProcessQueryCache();
|
||||
}
|
||||
return;
|
||||
|
||||
fatal_fail:
|
||||
@ -323,23 +323,17 @@ fatal_fail:
|
||||
|
||||
bool ClientPrefs::AddQueryToQueue(TQueryOp *query)
|
||||
{
|
||||
queryMutex->Lock();
|
||||
{
|
||||
ke::AutoLock lock(&queryLock);
|
||||
if (Database == NULL)
|
||||
{
|
||||
cachedQueries.push_back(query);
|
||||
queryMutex->Unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!cachedQueries.empty())
|
||||
{
|
||||
queryMutex->Unlock();
|
||||
this->ProcessQueryCache();
|
||||
}
|
||||
else
|
||||
{
|
||||
queryMutex->Unlock();
|
||||
}
|
||||
|
||||
query->SetDatabase(Database);
|
||||
dbi->AddToThreadQueue(query, PrioQueue_Normal);
|
||||
@ -348,12 +342,11 @@ bool ClientPrefs::AddQueryToQueue( TQueryOp *query )
|
||||
|
||||
void ClientPrefs::ProcessQueryCache()
|
||||
{
|
||||
if (Database == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
queryLock.AssertCurrentThreadOwns();
|
||||
|
||||
if (Database == NULL)
|
||||
return;
|
||||
|
||||
queryMutex->Lock();
|
||||
TQueryOp *op;
|
||||
for (SourceHook::List<TQueryOp *>::iterator iter = cachedQueries.begin(); iter != cachedQueries.end(); iter++)
|
||||
{
|
||||
@ -363,7 +356,6 @@ void ClientPrefs::ProcessQueryCache()
|
||||
}
|
||||
|
||||
cachedQueries.clear();
|
||||
queryMutex->Unlock();
|
||||
}
|
||||
|
||||
size_t IsAuthIdConnected(char *authID)
|
||||
@ -417,8 +409,7 @@ void ClientPrefs::CatchLateLoadClients()
|
||||
|
||||
void ClientPrefs::ClearQueryCache(int serial)
|
||||
{
|
||||
queryMutex->Lock();
|
||||
|
||||
ke::AutoLock lock(&queryLock);
|
||||
for (SourceHook::List<TQueryOp *>::iterator iter = cachedQueries.begin(); iter != cachedQueries.end();)
|
||||
{
|
||||
TQueryOp *op = *iter;
|
||||
@ -432,7 +423,6 @@ void ClientPrefs::ClearQueryCache(int serial)
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
queryMutex->Unlock();
|
||||
}
|
||||
|
||||
bool Translate(char *buffer,
|
||||
@ -530,7 +520,5 @@ ClientPrefs::ClientPrefs()
|
||||
phrases = NULL;
|
||||
DBInfo = NULL;
|
||||
|
||||
cookieMutex = NULL;
|
||||
queryMutex = NULL;
|
||||
identity = NULL;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* vim: set ts=4 sw=4 tw=99 noet:
|
||||
* =============================================================================
|
||||
* SourceMod Client Preferences Extension
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
@ -39,6 +39,8 @@
|
||||
#include "smsdk_ext.h"
|
||||
#include "sh_list.h"
|
||||
|
||||
#include <ke_thread_utils.h>
|
||||
|
||||
char * UTIL_strncpy(char * destination, const char * source, size_t num);
|
||||
|
||||
#include "cookie.h"
|
||||
@ -74,10 +76,7 @@ public:
|
||||
*/
|
||||
virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
|
||||
|
||||
/**
|
||||
* @brief This is called right before the extension is unloaded.
|
||||
*/
|
||||
virtual void SDK_OnUnload();
|
||||
virtual void SDK_OnDependenciesDropped();
|
||||
|
||||
/**
|
||||
* @brief This is called once all known extensions have been loaded.
|
||||
@ -162,7 +161,7 @@ public:
|
||||
|
||||
private:
|
||||
SourceHook::List<TQueryOp *> cachedQueries;
|
||||
IMutex *queryMutex;
|
||||
ke::Mutex queryLock;
|
||||
IdentityToken_t *identity;
|
||||
};
|
||||
|
||||
|
@ -303,23 +303,6 @@ int TQueryOp::PullQuerySerial()
|
||||
|
||||
ParamData::~ParamData()
|
||||
{
|
||||
if (cookie)
|
||||
{
|
||||
g_ClientPrefs.cookieMutex->Lock();
|
||||
cookie->usedInQuery--;
|
||||
|
||||
if (cookie->shouldDelete && cookie->usedInQuery <= 0)
|
||||
{
|
||||
g_ClientPrefs.cookieMutex->Unlock();
|
||||
delete cookie;
|
||||
cookie = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_ClientPrefs.cookieMutex->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
if (data)
|
||||
{
|
||||
/* Data is only ever passed in a client disconnect query and always needs to be deleted */
|
||||
|
@ -67,7 +67,7 @@
|
||||
//#define SMEXT_ENABLE_MEMUTILS
|
||||
#define SMEXT_ENABLE_GAMEHELPERS
|
||||
//#define SMEXT_ENABLE_TIMERSYS
|
||||
#define SMEXT_ENABLE_THREADER
|
||||
//#define SMEXT_ENABLE_THREADER
|
||||
//#define SMEXT_ENABLE_LIBSYS
|
||||
#define SMEXT_ENABLE_MENUS
|
||||
//#define SMEXT_ENABLE_ADTFACTORY
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* vim: set ts=4 sw=4 tw=99 noet:
|
||||
* =============================================================================
|
||||
* SourceMod Base Extension Code
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
@ -97,6 +97,12 @@ IUserMessages *usermsgs = NULL;
|
||||
#if defined SMEXT_ENABLE_TRANSLATOR
|
||||
ITranslator *translator = NULL;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_NINVOKE
|
||||
INativeInterface *ninvoke = NULL;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_ROOTCONSOLEMENU
|
||||
IRootConsole *rootconsole = NULL;
|
||||
#endif
|
||||
|
||||
/** Exports the main interface */
|
||||
PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI()
|
||||
@ -185,6 +191,12 @@ bool SDKExtension::OnExtensionLoad(IExtension *me, IShareSys *sys, char *error,
|
||||
#if defined SMEXT_ENABLE_TRANSLATOR
|
||||
SM_GET_IFACE(TRANSLATOR, translator);
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_NINVOKE
|
||||
SM_GET_IFACE(NINVOKE, ninvoke);
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_ROOTCONSOLEMENU
|
||||
SM_GET_IFACE(ROOTCONSOLE, rootconsole);
|
||||
#endif
|
||||
|
||||
if (SDK_OnLoad(error, maxlength, late))
|
||||
{
|
||||
@ -227,6 +239,11 @@ void SDKExtension::OnExtensionUnload()
|
||||
SDK_OnUnload();
|
||||
}
|
||||
|
||||
void SDKExtension::OnDependenciesDropped()
|
||||
{
|
||||
SDK_OnDependenciesDropped();
|
||||
}
|
||||
|
||||
const char *SDKExtension::GetExtensionAuthor()
|
||||
{
|
||||
return SMEXT_CONF_AUTHOR;
|
||||
@ -279,6 +296,10 @@ void SDKExtension::SDK_OnAllLoaded()
|
||||
{
|
||||
}
|
||||
|
||||
void SDKExtension::SDK_OnDependenciesDropped()
|
||||
{
|
||||
}
|
||||
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
|
||||
PluginId g_PLID = 0; /**< Metamod plugin ID */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* vim: set ts=4 sw=4 tw=99 noet:
|
||||
* =============================================================================
|
||||
* SourceMod Base Extension Code
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
@ -91,6 +91,12 @@
|
||||
#if defined SMEXT_ENABLE_TRANSLATOR
|
||||
#include <ITranslator.h>
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_NINVOKE
|
||||
#include <INativeInvoker.h>
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_ROOTCONSOLEMENU
|
||||
#include <IRootConsoleMenu.h>
|
||||
#endif
|
||||
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
#include <ISmmPlugin.h>
|
||||
@ -121,7 +127,7 @@ public:
|
||||
virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
|
||||
|
||||
/**
|
||||
* @brief This is called right before the extension is unloaded.
|
||||
* @brief This is called once the extension unloading process begins.
|
||||
*/
|
||||
virtual void SDK_OnUnload();
|
||||
|
||||
@ -135,6 +141,12 @@ public:
|
||||
*/
|
||||
virtual void SDK_OnPauseChange(bool paused);
|
||||
|
||||
/**
|
||||
* @brief Called after SDK_OnUnload, once all dependencies have been
|
||||
* removed, and the extension is about to be removed from memory.
|
||||
*/
|
||||
virtual void SDK_OnDependenciesDropped();
|
||||
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
/**
|
||||
* @brief Called when Metamod is attached, before the extension version is called.
|
||||
@ -197,6 +209,9 @@ public: //IExtensionInterface
|
||||
virtual const char *GetExtensionDescription();
|
||||
/** Returns date string */
|
||||
virtual const char *GetExtensionDateString();
|
||||
|
||||
/** Called after OnExtensionUnload, once dependencies have been dropped. */
|
||||
virtual void OnDependenciesDropped();
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
public: //ISmmPlugin
|
||||
/** Called when the extension is attached to Metamod. */
|
||||
@ -289,6 +304,12 @@ extern IUserMessages *usermsgs;
|
||||
#if defined SMEXT_ENABLE_TRANSLATOR
|
||||
extern ITranslator *translator;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_NINVOKE
|
||||
extern INativeInterface *ninvoke;
|
||||
#endif
|
||||
#if defined SMEXT_ENABLE_ROOTCONSOLEMENU
|
||||
extern IRootConsole *rootconsole;
|
||||
#endif
|
||||
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
PLUGIN_GLOBALVARS();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* vim: set ts=4 sw=4 tw=99 noet:
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
@ -134,8 +134,9 @@ namespace SourceMod
|
||||
* itself is not versioned.
|
||||
*
|
||||
* V6 - added TestFeature() to IShareSys.
|
||||
* V7 - added OnDependenciesDropped() to IExtensionInterface.
|
||||
*/
|
||||
#define SMINTERFACE_EXTENSIONAPI_VERSION 6
|
||||
#define SMINTERFACE_EXTENSIONAPI_VERSION 7
|
||||
|
||||
/**
|
||||
* @brief The interface an extension must expose.
|
||||
@ -313,6 +314,17 @@ namespace SourceMod
|
||||
virtual void OnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Called once all dependencies have been unloaded. This is
|
||||
* called AFTER OnExtensionUnload(), but before the extension library
|
||||
* has been unloaded. It can be used as an alternate unload hook for
|
||||
* cases where having no dependent plugins would make shutdown much
|
||||
* simplier.
|
||||
*/
|
||||
virtual void OnDependenciesDropped()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* vim: set ts=4 sw=4 tw=99 noet:
|
||||
* =============================================================================
|
||||
* SourceMod Base Extension Code
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
@ -239,6 +239,11 @@ void SDKExtension::OnExtensionUnload()
|
||||
SDK_OnUnload();
|
||||
}
|
||||
|
||||
void SDKExtension::OnDependenciesDropped()
|
||||
{
|
||||
SDK_OnDependenciesDropped();
|
||||
}
|
||||
|
||||
const char *SDKExtension::GetExtensionAuthor()
|
||||
{
|
||||
return SMEXT_CONF_AUTHOR;
|
||||
@ -291,6 +296,10 @@ void SDKExtension::SDK_OnAllLoaded()
|
||||
{
|
||||
}
|
||||
|
||||
void SDKExtension::SDK_OnDependenciesDropped()
|
||||
{
|
||||
}
|
||||
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
|
||||
PluginId g_PLID = 0; /**< Metamod plugin ID */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* vim: set ts=4 sw=4 tw=99 noet:
|
||||
* =============================================================================
|
||||
* SourceMod Base Extension Code
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
@ -127,7 +127,7 @@ public:
|
||||
virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
|
||||
|
||||
/**
|
||||
* @brief This is called right before the extension is unloaded.
|
||||
* @brief This is called once the extension unloading process begins.
|
||||
*/
|
||||
virtual void SDK_OnUnload();
|
||||
|
||||
@ -141,6 +141,12 @@ public:
|
||||
*/
|
||||
virtual void SDK_OnPauseChange(bool paused);
|
||||
|
||||
/**
|
||||
* @brief Called after SDK_OnUnload, once all dependencies have been
|
||||
* removed, and the extension is about to be removed from memory.
|
||||
*/
|
||||
virtual void SDK_OnDependenciesDropped();
|
||||
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
/**
|
||||
* @brief Called when Metamod is attached, before the extension version is called.
|
||||
@ -203,6 +209,9 @@ public: //IExtensionInterface
|
||||
virtual const char *GetExtensionDescription();
|
||||
/** Returns date string */
|
||||
virtual const char *GetExtensionDateString();
|
||||
|
||||
/** Called after OnExtensionUnload, once dependencies have been dropped. */
|
||||
virtual void OnDependenciesDropped();
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
public: //ISmmPlugin
|
||||
/** Called when the extension is attached to Metamod. */
|
||||
|
Loading…
Reference in New Issue
Block a user