- added new system for detecting convar/concmd removals in one nice place
- convar code overhaul - reorganized handle contents to make removal easier --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401588
This commit is contained in:
		
							parent
							
								
									60d8e4f248
								
							
						
					
					
						commit
						796d9b2de8
					
				@ -37,6 +37,7 @@
 | 
				
			|||||||
#include "sm_srvcmds.h"
 | 
					#include "sm_srvcmds.h"
 | 
				
			||||||
#include "sm_stringutil.h"
 | 
					#include "sm_stringutil.h"
 | 
				
			||||||
#include <sh_vector.h>
 | 
					#include <sh_vector.h>
 | 
				
			||||||
 | 
					#include <sm_trie_tpl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ConVarManager g_ConVarManager;
 | 
					ConVarManager g_ConVarManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -45,31 +46,14 @@ SH_DECL_HOOK5_void(IServerPluginCallbacks, OnQueryCvarValueFinished, SH_NOATTRIB
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const ParamType CONVARCHANGE_PARAMS[] = {Param_Cell, Param_String, Param_String};
 | 
					const ParamType CONVARCHANGE_PARAMS[] = {Param_Cell, Param_String, Param_String};
 | 
				
			||||||
typedef List<const ConVar *> ConVarList;
 | 
					typedef List<const ConVar *> ConVarList;
 | 
				
			||||||
 | 
					KTrie<ConVarInfo *> convar_cache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ConVarManager::ConVarManager() : m_ConVarType(0), m_bIsDLLQueryHooked(false), m_bIsVSPQueryHooked(false)
 | 
					ConVarManager::ConVarManager() : m_ConVarType(0), m_bIsDLLQueryHooked(false), m_bIsVSPQueryHooked(false)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if PLAPI_VERSION < 12
 | 
					 | 
				
			||||||
	m_IgnoreHandle = false;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Create a convar lookup trie */
 | 
					 | 
				
			||||||
	m_ConVarCache = sm_trie_create();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ConVarManager::~ConVarManager()
 | 
					ConVarManager::~ConVarManager()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	List<ConVarInfo *>::iterator iter;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Destroy our convar lookup trie */
 | 
					 | 
				
			||||||
	sm_trie_destroy(m_ConVarCache);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Destroy all the ConVarInfo structures */
 | 
					 | 
				
			||||||
	for (iter = m_ConVars.begin(); iter != m_ConVars.end(); iter++)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		delete (*iter);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	m_ConVars.clear();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ConVarManager::OnSourceModAllInitialized()
 | 
					void ConVarManager::OnSourceModAllInitialized()
 | 
				
			||||||
@ -101,6 +85,48 @@ void ConVarManager::OnSourceModAllInitialized()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void ConVarManager::OnSourceModShutdown()
 | 
					void ConVarManager::OnSourceModShutdown()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						List<ConVarInfo *>::iterator iter = m_ConVars.begin();
 | 
				
			||||||
 | 
						HandleSecurity sec(NULL, g_pCoreIdent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Iterate list of ConVarInfo structures, remove every one of them */
 | 
				
			||||||
 | 
						while (iter != m_ConVars.end())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ConVarInfo *pInfo = (*iter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							iter = m_ConVars.erase(iter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							g_HandleSys.FreeHandle(pInfo->handle, &sec);
 | 
				
			||||||
 | 
							if (pInfo->pChangeForward != NULL)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								g_Forwards.ReleaseForward(pInfo->pChangeForward);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (pInfo->sourceMod)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* If we created it, we won't be tracking it, therefore it is 
 | 
				
			||||||
 | 
								 * safe to remove everything in one go.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								META_UNREGCVAR(pInfo->pVar);
 | 
				
			||||||
 | 
								delete [] pInfo->pVar->GetName();
 | 
				
			||||||
 | 
								delete [] pInfo->pVar->GetHelpText();
 | 
				
			||||||
 | 
								delete [] pInfo->pVar->GetDefault();
 | 
				
			||||||
 | 
								delete pInfo->pVar;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* If we didn't create it, we might be tracking it.  Also, 
 | 
				
			||||||
 | 
								 * it could be unreadable.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								UntrackConCommandBase(pInfo->pVar, this);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* It's not safe to read the name here, so we simply delete the 
 | 
				
			||||||
 | 
							 * the info struct and clear the lookup cache at the end.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							delete pInfo;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						convar_cache.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Unhook things */
 | 
				
			||||||
	if (m_bIsDLLQueryHooked)
 | 
						if (m_bIsDLLQueryHooked)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, OnQueryCvarValueFinished, gamedll, this, &ConVarManager::OnQueryCvarValueFinished, false);
 | 
							SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, OnQueryCvarValueFinished, gamedll, this, &ConVarManager::OnQueryCvarValueFinished, false);
 | 
				
			||||||
@ -112,21 +138,6 @@ void ConVarManager::OnSourceModShutdown()
 | 
				
			|||||||
		m_bIsVSPQueryHooked = false;
 | 
							m_bIsVSPQueryHooked = false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	IChangeableForward *fwd;
 | 
					 | 
				
			||||||
	List<ConVarInfo *>::iterator i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Iterate list of ConVarInfo structures */
 | 
					 | 
				
			||||||
	for (i = m_ConVars.begin(); i != m_ConVars.end(); i++)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		fwd = (*i)->pChangeForward;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* Free any convar-change forwards that still exist */
 | 
					 | 
				
			||||||
		if (fwd)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			g_Forwards.ReleaseForward(fwd);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Remove the 'convars' option from the 'sm' console command */
 | 
						/* Remove the 'convars' option from the 'sm' console command */
 | 
				
			||||||
	g_RootMenu.RemoveRootConsoleCommand("cvars", this);
 | 
						g_RootMenu.RemoveRootConsoleCommand("cvars", this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -165,54 +176,55 @@ void ConVarManager::OnSourceModVSPReceived()
 | 
				
			|||||||
	m_bIsVSPQueryHooked = true;
 | 
						m_bIsVSPQueryHooked = true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if PLAPI_VERSION >= 12
 | 
					bool convar_cache_lookup(const char *name, ConVarInfo **pVar)
 | 
				
			||||||
void ConVarManager::OnUnlinkConCommandBase(PluginId id, ConCommandBase *pCommand)
 | 
					{
 | 
				
			||||||
 | 
						ConVarInfo **pLookup = convar_cache.retrieve(name);
 | 
				
			||||||
 | 
						if (pLookup != NULL)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							*pVar = *pLookup;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ConVarManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* Only check convars that have not been created by SourceMod's core */
 | 
						/* Only check convars that have not been created by SourceMod's core */
 | 
				
			||||||
	if (id != g_PLID && !pCommand->IsCommand())
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	ConVarInfo *pInfo;
 | 
						ConVarInfo *pInfo;
 | 
				
			||||||
		const char *cvarName = pCommand->GetName();
 | 
						if (!convar_cache_lookup(name, &pInfo))
 | 
				
			||||||
		HandleSecurity sec(NULL, g_pCoreIdent);
 | 
					 | 
				
			||||||
		bool handleExists = sm_trie_retrieve(m_ConVarCache, cvarName, reinterpret_cast<void **>(&pInfo));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (handleExists)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
			g_HandleSys.FreeHandle(pInfo->handle, &sec);
 | 
							return;
 | 
				
			||||||
			sm_trie_delete(m_ConVarCache, cvarName);
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						HandleSecurity sec(NULL, g_pCoreIdent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Remove it from our cache */
 | 
				
			||||||
	m_ConVars.remove(pInfo);
 | 
						m_ConVars.remove(pInfo);
 | 
				
			||||||
		}
 | 
						convar_cache.remove(name);
 | 
				
			||||||
	}
 | 
					
 | 
				
			||||||
 | 
						/* Now make sure no plugins are referring to this pointer */
 | 
				
			||||||
 | 
						IPluginIterator *pl_iter = g_PluginSys.GetPluginIterator();
 | 
				
			||||||
 | 
						while (pl_iter->MorePlugins())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							IPlugin *pl = pl_iter->GetPlugin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ConVarList *pConVarList;
 | 
				
			||||||
 | 
							if (pl->GetProperty("ConVarList", (void **)&pConVarList, true) 
 | 
				
			||||||
 | 
								&& pConVarList != NULL)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								pConVarList->remove(pInfo->pVar);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else
 | 
							pl_iter->NextPlugin();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* I truly detest this code */
 | 
						/* Free resources */
 | 
				
			||||||
void ConVarManager::OnMetamodPluginUnloaded(PluginId id)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	ConVarInfo *pInfo;
 | 
					 | 
				
			||||||
	const char *cvarName;
 | 
					 | 
				
			||||||
	HandleSecurity sec(NULL, g_pCoreIdent);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	List<ConVarInfo *>::iterator i;
 | 
					 | 
				
			||||||
	for (i = m_ConVars.begin(); i != m_ConVars.end(); i++)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		pInfo = (*i);
 | 
					 | 
				
			||||||
		cvarName = pInfo->name;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (cvarName && !icvar->FindVar(cvarName))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			m_IgnoreHandle = true;
 | 
					 | 
				
			||||||
	g_HandleSys.FreeHandle(pInfo->handle, &sec);
 | 
						g_HandleSys.FreeHandle(pInfo->handle, &sec);
 | 
				
			||||||
 | 
						delete pInfo;
 | 
				
			||||||
			sm_trie_delete(m_ConVarCache, cvarName);
 | 
					 | 
				
			||||||
			m_ConVars.erase(i);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			delete [] cvarName;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ConVarManager::OnPluginUnloaded(IPlugin *plugin)
 | 
					void ConVarManager::OnPluginUnloaded(IPlugin *plugin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -227,33 +239,6 @@ void ConVarManager::OnPluginUnloaded(IPlugin *plugin)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void ConVarManager::OnHandleDestroy(HandleType_t type, void *object)
 | 
					void ConVarManager::OnHandleDestroy(HandleType_t type, void *object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if PLAPI_VERSION < 12
 | 
					 | 
				
			||||||
	/* Lovely workaround for our workaround! */
 | 
					 | 
				
			||||||
	if (m_IgnoreHandle)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		m_IgnoreHandle = false;
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ConVarInfo *info;
 | 
					 | 
				
			||||||
	ConVar *pConVar = static_cast<ConVar *>(object);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Find convar in lookup trie */
 | 
					 | 
				
			||||||
	sm_trie_retrieve(m_ConVarCache, pConVar->GetName(), reinterpret_cast<void **>(&info));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* If convar was created by SourceMod plugin... */
 | 
					 | 
				
			||||||
	if (info->sourceMod)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		/* Then unlink it from SourceMM */
 | 
					 | 
				
			||||||
		g_SMAPI->UnregisterConCommandBase(g_PLAPI, pConVar);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* Delete string allocations */
 | 
					 | 
				
			||||||
		delete [] pConVar->GetName(); 
 | 
					 | 
				
			||||||
		delete [] pConVar->GetDefault();
 | 
					 | 
				
			||||||
		delete [] pConVar->GetHelpText();
 | 
					 | 
				
			||||||
		delete pConVar;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ConVarManager::OnRootConsoleCommand(const char *cmdname, const CCommand &command)
 | 
					void ConVarManager::OnRootConsoleCommand(const char *cmdname, const CCommand &command)
 | 
				
			||||||
@ -320,28 +305,33 @@ Handle_t ConVarManager::CreateConVar(IPluginContext *pContext, const char *name,
 | 
				
			|||||||
		AddConVarToPluginList(pContext, pConVar);
 | 
							AddConVarToPluginList(pContext, pConVar);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* First find out if we already have a handle to it */
 | 
							/* First find out if we already have a handle to it */
 | 
				
			||||||
		if (sm_trie_retrieve(m_ConVarCache, name, (void **)&pInfo))
 | 
							if (convar_cache_lookup(name, &pInfo))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return pInfo->handle;
 | 
								return pInfo->handle;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			/* If we don't, then create a new handle from the convar */
 | 
					 | 
				
			||||||
			hndl = g_HandleSys.CreateHandle(m_ConVarType, pConVar, NULL, g_pCoreIdent, NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			/* Create and initialize ConVarInfo structure */
 | 
								/* Create and initialize ConVarInfo structure */
 | 
				
			||||||
			pInfo = new ConVarInfo();
 | 
								pInfo = new ConVarInfo();
 | 
				
			||||||
			pInfo->handle = hndl;
 | 
					 | 
				
			||||||
			pInfo->sourceMod = false;
 | 
								pInfo->sourceMod = false;
 | 
				
			||||||
			pInfo->pChangeForward = NULL;
 | 
								pInfo->pChangeForward = NULL;
 | 
				
			||||||
			pInfo->origCallback = pConVar->GetCallback();
 | 
								pInfo->origCallback = pConVar->GetCallback();
 | 
				
			||||||
		#if PLAPI_VERSION < 12
 | 
								pInfo->pVar = pConVar;
 | 
				
			||||||
			pInfo->name = sm_strdup(pConVar->GetName());
 | 
					
 | 
				
			||||||
		#endif
 | 
								/* If we don't, then create a new handle from the convar */
 | 
				
			||||||
 | 
								hndl = g_HandleSys.CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL);
 | 
				
			||||||
 | 
								if (hndl == BAD_HANDLE)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									delete pInfo;
 | 
				
			||||||
 | 
									return BAD_HANDLE;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								pInfo->handle = hndl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* Insert struct into caches */
 | 
								/* Insert struct into caches */
 | 
				
			||||||
			m_ConVars.push_back(pInfo);
 | 
								m_ConVars.push_back(pInfo);
 | 
				
			||||||
			sm_trie_insert(m_ConVarCache, name, pInfo);
 | 
								convar_cache.insert(name, pInfo);
 | 
				
			||||||
 | 
								TrackConCommandBase(pConVar, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return hndl;
 | 
								return hndl;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -360,28 +350,33 @@ Handle_t ConVarManager::CreateConVar(IPluginContext *pContext, const char *name,
 | 
				
			|||||||
		pBase = const_cast<ConCommandBase *>(pBase->GetNext());
 | 
							pBase = const_cast<ConCommandBase *>(pBase->GetNext());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Since an existing convar (or concmd with the same name) was not found , now we can finally create it */
 | 
					 | 
				
			||||||
	pConVar = new ConVar(sm_strdup(name), sm_strdup(defaultVal), flags, sm_strdup(description), hasMin, min, hasMax, max);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Add convar to plugin's list */
 | 
					 | 
				
			||||||
	AddConVarToPluginList(pContext, pConVar);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Create a handle from the new convar */
 | 
					 | 
				
			||||||
	hndl = g_HandleSys.CreateHandle(m_ConVarType, pConVar, NULL, g_pCoreIdent, NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Create and initialize ConVarInfo structure */
 | 
						/* Create and initialize ConVarInfo structure */
 | 
				
			||||||
	pInfo = new ConVarInfo();
 | 
						pInfo = new ConVarInfo();
 | 
				
			||||||
	pInfo->handle = hndl;
 | 
						pInfo->handle = hndl;
 | 
				
			||||||
	pInfo->sourceMod = true;
 | 
						pInfo->sourceMod = true;
 | 
				
			||||||
	pInfo->pChangeForward = NULL;
 | 
						pInfo->pChangeForward = NULL;
 | 
				
			||||||
	pInfo->origCallback = NULL;
 | 
						pInfo->origCallback = NULL;
 | 
				
			||||||
#if PLAPI_VERSION < 12
 | 
					
 | 
				
			||||||
	pInfo->name = NULL;
 | 
						/* Create a handle from the new convar */
 | 
				
			||||||
#endif
 | 
						hndl = g_HandleSys.CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL);
 | 
				
			||||||
 | 
						if (hndl == BAD_HANDLE)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							delete pInfo;
 | 
				
			||||||
 | 
							return BAD_HANDLE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pInfo->handle = hndl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Since an existing convar (or concmd with the same name) was not found , now we can finally create it */
 | 
				
			||||||
 | 
						pConVar = new ConVar(sm_strdup(name), sm_strdup(defaultVal), flags, sm_strdup(description), hasMin, min, hasMax, max);
 | 
				
			||||||
 | 
						pInfo->pVar = pConVar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Add convar to plugin's list */
 | 
				
			||||||
 | 
						AddConVarToPluginList(pContext, pConVar);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Insert struct into caches */
 | 
						/* Insert struct into caches */
 | 
				
			||||||
	m_ConVars.push_back(pInfo);
 | 
						m_ConVars.push_back(pInfo);
 | 
				
			||||||
	sm_trie_insert(m_ConVarCache, name, pInfo);
 | 
						convar_cache.insert(name, pInfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return hndl;
 | 
						return hndl;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -402,27 +397,32 @@ Handle_t ConVarManager::FindConVar(const char *name)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* At this point, the convar exists. So, find out if we already have a handle */
 | 
						/* At this point, the convar exists. So, find out if we already have a handle */
 | 
				
			||||||
	if (sm_trie_retrieve(m_ConVarCache, name, (void **)&pInfo))
 | 
						if (convar_cache_lookup(name, &pInfo))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return pInfo->handle;
 | 
							return pInfo->handle;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If we don't have a handle, then create a new one */
 | 
					 | 
				
			||||||
	hndl = g_HandleSys.CreateHandle(m_ConVarType, pConVar, NULL, g_pCoreIdent, NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Create and initialize ConVarInfo structure */
 | 
						/* Create and initialize ConVarInfo structure */
 | 
				
			||||||
	pInfo = new ConVarInfo();
 | 
						pInfo = new ConVarInfo();
 | 
				
			||||||
	pInfo->handle = hndl;
 | 
					 | 
				
			||||||
	pInfo->sourceMod = false;
 | 
						pInfo->sourceMod = false;
 | 
				
			||||||
	pInfo->pChangeForward = NULL;
 | 
						pInfo->pChangeForward = NULL;
 | 
				
			||||||
	pInfo->origCallback = pConVar->GetCallback();
 | 
						pInfo->origCallback = pConVar->GetCallback();
 | 
				
			||||||
#if PLAPI_VERSION < 12
 | 
						pInfo->pVar = pConVar;
 | 
				
			||||||
	pInfo->name = sm_strdup(pConVar->GetName());
 | 
					
 | 
				
			||||||
#endif
 | 
						/* If we don't have a handle, then create a new one */
 | 
				
			||||||
 | 
						hndl = g_HandleSys.CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL);
 | 
				
			||||||
 | 
						if (hndl == BAD_HANDLE)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							delete pInfo;
 | 
				
			||||||
 | 
							return BAD_HANDLE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pInfo->handle = hndl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Insert struct into our caches */
 | 
						/* Insert struct into our caches */
 | 
				
			||||||
	m_ConVars.push_back(pInfo);
 | 
						m_ConVars.push_back(pInfo);
 | 
				
			||||||
	sm_trie_insert(m_ConVarCache, name, pInfo);
 | 
						convar_cache.insert(name, pInfo);
 | 
				
			||||||
 | 
						TrackConCommandBase(pConVar, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return hndl;
 | 
						return hndl;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -433,7 +433,7 @@ void ConVarManager::HookConVarChange(ConVar *pConVar, IPluginFunction *pFunction
 | 
				
			|||||||
	IChangeableForward *pForward;
 | 
						IChangeableForward *pForward;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Find the convar in the lookup trie */
 | 
						/* Find the convar in the lookup trie */
 | 
				
			||||||
	if (sm_trie_retrieve(m_ConVarCache, pConVar->GetName(), (void **)&pInfo))
 | 
						if (convar_cache_lookup(pConVar->GetName(), &pInfo))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* Get the forward */
 | 
							/* Get the forward */
 | 
				
			||||||
		pForward = pInfo->pChangeForward;
 | 
							pForward = pInfo->pChangeForward;
 | 
				
			||||||
@ -460,7 +460,7 @@ void ConVarManager::UnhookConVarChange(ConVar *pConVar, IPluginFunction *pFuncti
 | 
				
			|||||||
	IPluginContext *pContext = pFunction->GetParentContext();
 | 
						IPluginContext *pContext = pFunction->GetParentContext();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Find the convar in the lookup trie */
 | 
						/* Find the convar in the lookup trie */
 | 
				
			||||||
	if (sm_trie_retrieve(m_ConVarCache, pConVar->GetName(), (void **)&pInfo))
 | 
						if (convar_cache_lookup(pConVar->GetName(), &pInfo))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* Get the forward */
 | 
							/* Get the forward */
 | 
				
			||||||
		pForward = pInfo->pChangeForward;
 | 
							pForward = pInfo->pChangeForward;
 | 
				
			||||||
@ -569,11 +569,13 @@ void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue)
 | 
				
			|||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Trie *pCache = g_ConVarManager.GetConVarCache();
 | 
					 | 
				
			||||||
	ConVarInfo *pInfo;
 | 
						ConVarInfo *pInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Find the convar in the lookup trie */
 | 
						/* Find the convar in the lookup trie */
 | 
				
			||||||
	sm_trie_retrieve(pCache, pConVar->GetName(), (void **)&pInfo);
 | 
						if (!convar_cache_lookup(pConVar->GetName(), &pInfo))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FnChangeCallback_t origCallback = pInfo->origCallback;
 | 
						FnChangeCallback_t origCallback = pInfo->origCallback;
 | 
				
			||||||
	IChangeableForward *pForward = pInfo->pChangeForward;
 | 
						IChangeableForward *pForward = pInfo->pChangeForward;
 | 
				
			||||||
@ -642,6 +644,23 @@ void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HandleError ConVarManager::ReadConVarHandle(Handle_t hndl, ConVar **pVar)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ConVarInfo *pInfo;
 | 
				
			||||||
 | 
						HandleError error;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if ((error = g_HandleSys.ReadHandle(hndl, m_ConVarType, NULL, (void **)&pInfo)) != HandleError_None)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return error;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pVar)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							*pVar = pInfo->pVar;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return error;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int s_YamagramState = 0;
 | 
					static int s_YamagramState = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -34,13 +34,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "sm_globals.h"
 | 
					#include "sm_globals.h"
 | 
				
			||||||
#include "sourcemm_api.h"
 | 
					#include "sourcemm_api.h"
 | 
				
			||||||
#include "sm_trie.h"
 | 
					 | 
				
			||||||
#include <sh_list.h>
 | 
					#include <sh_list.h>
 | 
				
			||||||
#include <IPluginSys.h>
 | 
					#include <IPluginSys.h>
 | 
				
			||||||
#include <IForwardSys.h>
 | 
					#include <IForwardSys.h>
 | 
				
			||||||
#include <IHandleSys.h>
 | 
					#include <IHandleSys.h>
 | 
				
			||||||
#include <IRootConsoleMenu.h>
 | 
					#include <IRootConsoleMenu.h>
 | 
				
			||||||
#include <compat_wrappers.h>
 | 
					#include <compat_wrappers.h>
 | 
				
			||||||
 | 
					#include "concmd_cleaner.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace SourceHook;
 | 
					using namespace SourceHook;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -49,13 +49,11 @@ using namespace SourceHook;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
struct ConVarInfo
 | 
					struct ConVarInfo
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	Handle_t handle;					/**< Handle to convar */
 | 
						Handle_t handle;					/**< Handle to self */
 | 
				
			||||||
	bool sourceMod;						/**< Determines whether or not convar was created by a SourceMod plugin */
 | 
						bool sourceMod;						/**< Determines whether or not convar was created by a SourceMod plugin */
 | 
				
			||||||
	IChangeableForward *pChangeForward;	/**< Forward associated with convar */
 | 
						IChangeableForward *pChangeForward;	/**< Forward associated with convar */
 | 
				
			||||||
	FnChangeCallback_t origCallback;	/**< The original callback function */
 | 
						FnChangeCallback_t origCallback;	/**< The original callback function */
 | 
				
			||||||
#if PLAPI_VERSION < 12
 | 
						ConVar *pVar;						/**< The actual convar */
 | 
				
			||||||
	const char *name;					/**< Name of convar */
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -72,7 +70,8 @@ class ConVarManager :
 | 
				
			|||||||
	public SMGlobalClass,
 | 
						public SMGlobalClass,
 | 
				
			||||||
	public IHandleTypeDispatch,
 | 
						public IHandleTypeDispatch,
 | 
				
			||||||
	public IPluginsListener,
 | 
						public IPluginsListener,
 | 
				
			||||||
	public IRootConsoleCommand
 | 
						public IRootConsoleCommand,
 | 
				
			||||||
 | 
						public IConCommandTracker
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	ConVarManager();
 | 
						ConVarManager();
 | 
				
			||||||
@ -87,22 +86,8 @@ public: // IPluginsListener
 | 
				
			|||||||
	void OnPluginUnloaded(IPlugin *plugin);
 | 
						void OnPluginUnloaded(IPlugin *plugin);
 | 
				
			||||||
public: //IRootConsoleCommand
 | 
					public: //IRootConsoleCommand
 | 
				
			||||||
	void OnRootConsoleCommand(const char *cmdname, const CCommand &command);
 | 
						void OnRootConsoleCommand(const char *cmdname, const CCommand &command);
 | 
				
			||||||
public:
 | 
					public: //IConCommandTracker
 | 
				
			||||||
	/**
 | 
						void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe);
 | 
				
			||||||
	 * Get the 'ConVar' handle type ID.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	inline HandleType_t GetHandleType()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return m_ConVarType;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Get the convar lookup trie.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	inline Trie *GetConVarCache()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return m_ConVarCache;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Create a convar and return a handle to it.
 | 
						 * Create a convar and return a handle to it.
 | 
				
			||||||
@ -133,17 +118,8 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	bool IsQueryingSupported();
 | 
						bool IsQueryingSupported();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if PLAPI_VERSION >= 12
 | 
						HandleError ReadConVarHandle(Handle_t hndl, ConVar **pVar);
 | 
				
			||||||
	/**
 | 
					
 | 
				
			||||||
	 * Called when Metamod:Source is about to remove convar
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	void OnUnlinkConCommandBase(PluginId id, ConCommandBase *pCommand);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Called when Metamod:Source has unloaded a plugin
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	void OnMetamodPluginUnloaded(PluginId id);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Adds a convar to a plugin's list.
 | 
						 * Adds a convar to a plugin's list.
 | 
				
			||||||
@ -168,12 +144,8 @@ private:
 | 
				
			|||||||
	HandleType_t m_ConVarType;
 | 
						HandleType_t m_ConVarType;
 | 
				
			||||||
	List<ConVarInfo *> m_ConVars;
 | 
						List<ConVarInfo *> m_ConVars;
 | 
				
			||||||
	List<ConVarQuery> m_ConVarQueries;
 | 
						List<ConVarQuery> m_ConVarQueries;
 | 
				
			||||||
	Trie *m_ConVarCache;
 | 
					 | 
				
			||||||
	bool m_bIsDLLQueryHooked;
 | 
						bool m_bIsDLLQueryHooked;
 | 
				
			||||||
	bool m_bIsVSPQueryHooked;
 | 
						bool m_bIsVSPQueryHooked;
 | 
				
			||||||
#if PLAPI_VERSION < 12
 | 
					 | 
				
			||||||
	bool m_IgnoreHandle;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern ConVarManager g_ConVarManager;
 | 
					extern ConVarManager g_ConVarManager;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										175
									
								
								core/concmd_cleaner.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								core/concmd_cleaner.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,175 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * vim: set ts=4 :
 | 
				
			||||||
 | 
					 * =============================================================================
 | 
				
			||||||
 | 
					 * SourceMod
 | 
				
			||||||
 | 
					 * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
 | 
				
			||||||
 | 
					 * =============================================================================
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify it under
 | 
				
			||||||
 | 
					 * the terms of the GNU General Public License, version 3.0, as published by the
 | 
				
			||||||
 | 
					 * Free Software Foundation.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful, but WITHOUT
 | 
				
			||||||
 | 
					 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
				
			||||||
 | 
					 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 | 
				
			||||||
 | 
					 * details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License along with
 | 
				
			||||||
 | 
					 * this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * As a special exception, AlliedModders LLC gives you permission to link the
 | 
				
			||||||
 | 
					 * code of this program (as well as its derivative works) to "Half-Life 2," the
 | 
				
			||||||
 | 
					 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
 | 
				
			||||||
 | 
					 * by the Valve Corporation.  You must obey the GNU General Public License in
 | 
				
			||||||
 | 
					 * all respects for all other code used.  Additionally, AlliedModders LLC grants
 | 
				
			||||||
 | 
					 * this exception to all derivative works.  AlliedModders LLC defines further
 | 
				
			||||||
 | 
					 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
 | 
				
			||||||
 | 
					 * or <http://www.sourcemod.net/license.php>.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Version: $Id$
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "sm_globals.h"
 | 
				
			||||||
 | 
					#include <sh_list.h>
 | 
				
			||||||
 | 
					#include <convar.h>
 | 
				
			||||||
 | 
					#include "concmd_cleaner.h"
 | 
				
			||||||
 | 
					#include "sm_stringutil.h"
 | 
				
			||||||
 | 
					#include "sourcemm_api.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined ORANGEBOX_BUILD
 | 
				
			||||||
 | 
					SH_DECL_HOOK1_void(ICvar, UnregisterConCommand, SH_NOATTRIB, 0, ConCommandBase *);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace SourceHook;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ConCommandInfo
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ConCommandBase *pBase;
 | 
				
			||||||
 | 
						IConCommandTracker *cls;
 | 
				
			||||||
 | 
						char name[64];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					List<ConCommandInfo *> tracked_bases;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ConCommandBase *FindConCommandBase(const char *name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ConCommandCleaner : public SMGlobalClass
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					#if defined ORANGEBOX_BUILD
 | 
				
			||||||
 | 
						void OnSourceModAllInitialized()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SH_ADD_HOOK(ICvar, UnregisterConCommand, SH_NOATTRIB, SH_MEMBER(this, &ConCommandCleaner::UnlinkConCommandBase), false);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void OnSourceModShutdown()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SH_REMOVE_HOOK(ICvar, UnregisterConCommand, SH_NOATTRIB, SH_MEMBER(this, &ConCommandCleaner::UnlinkConCommandBase), false);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void UnlinkConCommandBase(ConCommandBase *pBase)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ConCommandInfo *pInfo;
 | 
				
			||||||
 | 
							List<ConCommandInfo *>::iterator iter = tracked_bases.begin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (pBase)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								while (iter != tracked_bases.end())
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if ((*iter)->pBase == pBase)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										pInfo = (*iter);
 | 
				
			||||||
 | 
										iter = tracked_bases.erase(iter);
 | 
				
			||||||
 | 
										pInfo->cls->OnUnlinkConCommandBase(pBase, pBase->GetName(), true);
 | 
				
			||||||
 | 
										delete pInfo;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										iter++;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								while (iter != tracked_bases.end())
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									/* This is just god-awful! */
 | 
				
			||||||
 | 
									if (FindConCommandBase((*iter)->name) != (*iter)->pBase)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										pInfo = (*iter);
 | 
				
			||||||
 | 
										iter = tracked_bases.erase(iter);
 | 
				
			||||||
 | 
										pInfo->cls->OnUnlinkConCommandBase(pBase, pBase->GetName(), true);
 | 
				
			||||||
 | 
										delete pInfo;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										iter++;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void AddTarget(ConCommandBase *pBase, IConCommandTracker *cls)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ConCommandInfo *info = new ConCommandInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							info->pBase = pBase;
 | 
				
			||||||
 | 
							info->cls = cls;
 | 
				
			||||||
 | 
							strncopy(info->name, pBase->GetName(), sizeof(info->name));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							tracked_bases.push_back(info);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void RemoveTarget(ConCommandBase *pBase, IConCommandTracker *cls)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							List<ConCommandInfo *>::iterator iter;
 | 
				
			||||||
 | 
							ConCommandInfo *pInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							iter = tracked_bases.begin();
 | 
				
			||||||
 | 
							while (iter != tracked_bases.end())
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								pInfo = (*iter);
 | 
				
			||||||
 | 
								if (pInfo->pBase == pBase && pInfo->cls == cls)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									delete pInfo;
 | 
				
			||||||
 | 
									iter = tracked_bases.erase(iter);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									iter++;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					} s_ConCmdTracker;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ConCommandBase *FindConCommandBase(const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const ConCommandBase *pBase = icvar->GetCommands();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (pBase != NULL)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (strcmp(pBase->GetName(), name) == 0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return const_cast<ConCommandBase *>(pBase);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							pBase = pBase->GetNext();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						s_ConCmdTracker.AddTarget(pBase, me);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void UntrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						s_ConCmdTracker.RemoveTarget(pBase, me);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Global_OnUnlinkConCommandBase(ConCommandBase *pBase)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						s_ConCmdTracker.UnlinkConCommandBase(pBase);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										41
									
								
								core/concmd_cleaner.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								core/concmd_cleaner.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * vim: set ts=4 :
 | 
				
			||||||
 | 
					 * =============================================================================
 | 
				
			||||||
 | 
					 * SourceMod
 | 
				
			||||||
 | 
					 * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
 | 
				
			||||||
 | 
					 * =============================================================================
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify it under
 | 
				
			||||||
 | 
					 * the terms of the GNU General Public License, version 3.0, as published by the
 | 
				
			||||||
 | 
					 * Free Software Foundation.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful, but WITHOUT
 | 
				
			||||||
 | 
					 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
				
			||||||
 | 
					 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 | 
				
			||||||
 | 
					 * details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License along with
 | 
				
			||||||
 | 
					 * this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * As a special exception, AlliedModders LLC gives you permission to link the
 | 
				
			||||||
 | 
					 * code of this program (as well as its derivative works) to "Half-Life 2," the
 | 
				
			||||||
 | 
					 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
 | 
				
			||||||
 | 
					 * by the Valve Corporation.  You must obey the GNU General Public License in
 | 
				
			||||||
 | 
					 * all respects for all other code used.  Additionally, AlliedModders LLC grants
 | 
				
			||||||
 | 
					 * this exception to all derivative works.  AlliedModders LLC defines further
 | 
				
			||||||
 | 
					 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
 | 
				
			||||||
 | 
					 * or <http://www.sourcemod.net/license.php>.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Version: $Id$
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class IConCommandTracker
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						virtual void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe) = 0;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me);
 | 
				
			||||||
 | 
					void UntrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me);
 | 
				
			||||||
 | 
					void Global_OnUnlinkConCommandBase(ConCommandBase *pBase);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -609,6 +609,10 @@
 | 
				
			|||||||
				RelativePath="..\ChatTriggers.cpp"
 | 
									RelativePath="..\ChatTriggers.cpp"
 | 
				
			||||||
				>
 | 
									>
 | 
				
			||||||
			</File>
 | 
								</File>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath="..\concmd_cleaner.cpp"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
			<File
 | 
								<File
 | 
				
			||||||
				RelativePath="..\ConCmdManager.cpp"
 | 
									RelativePath="..\ConCmdManager.cpp"
 | 
				
			||||||
				>
 | 
									>
 | 
				
			||||||
@ -803,6 +807,10 @@
 | 
				
			|||||||
				RelativePath="..\..\public\compat_wrappers.h"
 | 
									RelativePath="..\..\public\compat_wrappers.h"
 | 
				
			||||||
				>
 | 
									>
 | 
				
			||||||
			</File>
 | 
								</File>
 | 
				
			||||||
 | 
								<File
 | 
				
			||||||
 | 
									RelativePath="..\concmd_cleaner.h"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
 | 
								</File>
 | 
				
			||||||
			<File
 | 
								<File
 | 
				
			||||||
				RelativePath="..\ConCmdManager.h"
 | 
									RelativePath="..\ConCmdManager.h"
 | 
				
			||||||
				>
 | 
									>
 | 
				
			||||||
 | 
				
			|||||||
@ -110,7 +110,9 @@ static void NotifyConVar(ConVar *pConVar)
 | 
				
			|||||||
	if (IsFlagSet(pConVar, FCVAR_PROTECTED))
 | 
						if (IsFlagSet(pConVar, FCVAR_PROTECTED))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		pEvent->SetString("cvarvalue", "***PROTECTED***");
 | 
							pEvent->SetString("cvarvalue", "***PROTECTED***");
 | 
				
			||||||
	} else {
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		pEvent->SetString("cvarvalue", pConVar->GetString());
 | 
							pEvent->SetString("cvarvalue", pConVar->GetString());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -141,7 +143,7 @@ static cell_t sm_CreateConVar(IPluginContext *pContext, const cell_t *params)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if (hndl == BAD_HANDLE)
 | 
						if (hndl == BAD_HANDLE)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return pContext->ThrowNativeError("Convar \"%s\" was not created. A console command with the same name already exists.", name);
 | 
							return pContext->ThrowNativeError("Convar \"%s\" was not created. A console command with the same might already exist.", name);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return hndl;
 | 
						return hndl;
 | 
				
			||||||
@ -162,7 +164,7 @@ static cell_t sm_HookConVarChange(IPluginContext *pContext, const cell_t *params
 | 
				
			|||||||
	HandleError err;
 | 
						HandleError err;
 | 
				
			||||||
	ConVar *pConVar;
 | 
						ConVar *pConVar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
 | 
						if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
 | 
				
			||||||
		!= HandleError_None)
 | 
							!= HandleError_None)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
							return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
				
			||||||
@ -186,7 +188,7 @@ static cell_t sm_UnhookConVarChange(IPluginContext *pContext, const cell_t *para
 | 
				
			|||||||
	HandleError err;
 | 
						HandleError err;
 | 
				
			||||||
	ConVar *pConVar;
 | 
						ConVar *pConVar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
 | 
						if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
 | 
				
			||||||
		!= HandleError_None)
 | 
							!= HandleError_None)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
							return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
				
			||||||
@ -210,7 +212,7 @@ static cell_t sm_GetConVarBool(IPluginContext *pContext, const cell_t *params)
 | 
				
			|||||||
	HandleError err;
 | 
						HandleError err;
 | 
				
			||||||
	ConVar *pConVar;
 | 
						ConVar *pConVar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
 | 
						if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
 | 
				
			||||||
		!= HandleError_None)
 | 
							!= HandleError_None)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
							return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
				
			||||||
@ -225,7 +227,7 @@ static cell_t sm_GetConVarInt(IPluginContext *pContext, const cell_t *params)
 | 
				
			|||||||
	HandleError err;
 | 
						HandleError err;
 | 
				
			||||||
	ConVar *pConVar;
 | 
						ConVar *pConVar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
 | 
						if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
 | 
				
			||||||
		!= HandleError_None)
 | 
							!= HandleError_None)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
							return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
				
			||||||
@ -241,7 +243,7 @@ static cell_t sm_SetConVarNum(IPluginContext *pContext, const cell_t *params)
 | 
				
			|||||||
	HandleError err;
 | 
						HandleError err;
 | 
				
			||||||
	ConVar *pConVar;
 | 
						ConVar *pConVar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
 | 
						if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
 | 
				
			||||||
		!= HandleError_None)
 | 
							!= HandleError_None)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
							return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
				
			||||||
@ -270,7 +272,7 @@ static cell_t sm_GetConVarFloat(IPluginContext *pContext, const cell_t *params)
 | 
				
			|||||||
	HandleError err;
 | 
						HandleError err;
 | 
				
			||||||
	ConVar *pConVar;
 | 
						ConVar *pConVar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
 | 
						if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
 | 
				
			||||||
		!= HandleError_None)
 | 
							!= HandleError_None)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
							return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
				
			||||||
@ -287,7 +289,7 @@ static cell_t sm_SetConVarFloat(IPluginContext *pContext, const cell_t *params)
 | 
				
			|||||||
	HandleError err;
 | 
						HandleError err;
 | 
				
			||||||
	ConVar *pConVar;
 | 
						ConVar *pConVar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
 | 
						if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
 | 
				
			||||||
		!= HandleError_None)
 | 
							!= HandleError_None)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
							return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
				
			||||||
@ -317,7 +319,7 @@ static cell_t sm_GetConVarString(IPluginContext *pContext, const cell_t *params)
 | 
				
			|||||||
	HandleError err;
 | 
						HandleError err;
 | 
				
			||||||
	ConVar *pConVar;
 | 
						ConVar *pConVar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
 | 
						if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
 | 
				
			||||||
		!= HandleError_None)
 | 
							!= HandleError_None)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
							return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
				
			||||||
@ -334,7 +336,7 @@ static cell_t sm_SetConVarString(IPluginContext *pContext, const cell_t *params)
 | 
				
			|||||||
	HandleError err;
 | 
						HandleError err;
 | 
				
			||||||
	ConVar *pConVar;
 | 
						ConVar *pConVar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
 | 
						if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
 | 
				
			||||||
		!= HandleError_None)
 | 
							!= HandleError_None)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
							return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
				
			||||||
@ -366,7 +368,7 @@ static cell_t sm_ResetConVar(IPluginContext *pContext, const cell_t *params)
 | 
				
			|||||||
	HandleError err;
 | 
						HandleError err;
 | 
				
			||||||
	ConVar *pConVar;
 | 
						ConVar *pConVar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
 | 
						if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
 | 
				
			||||||
		!= HandleError_None)
 | 
							!= HandleError_None)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
							return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
				
			||||||
@ -395,7 +397,7 @@ static cell_t sm_GetConVarFlags(IPluginContext *pContext, const cell_t *params)
 | 
				
			|||||||
	HandleError err;
 | 
						HandleError err;
 | 
				
			||||||
	ConVar *pConVar;
 | 
						ConVar *pConVar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
 | 
						if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
 | 
				
			||||||
		!= HandleError_None)
 | 
							!= HandleError_None)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
							return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
				
			||||||
@ -410,7 +412,7 @@ static cell_t sm_SetConVarFlags(IPluginContext *pContext, const cell_t *params)
 | 
				
			|||||||
	HandleError err;
 | 
						HandleError err;
 | 
				
			||||||
	ConVar *pConVar;
 | 
						ConVar *pConVar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
 | 
						if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
 | 
				
			||||||
		!= HandleError_None)
 | 
							!= HandleError_None)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
							return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
				
			||||||
@ -427,7 +429,7 @@ static cell_t sm_GetConVarBounds(IPluginContext *pContext, const cell_t *params)
 | 
				
			|||||||
	HandleError err;
 | 
						HandleError err;
 | 
				
			||||||
	ConVar *pConVar;
 | 
						ConVar *pConVar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
 | 
						if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
 | 
				
			||||||
		!= HandleError_None)
 | 
							!= HandleError_None)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
							return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
				
			||||||
@ -461,7 +463,7 @@ static cell_t sm_SetConVarBounds(IPluginContext *pContext, const cell_t *params)
 | 
				
			|||||||
	HandleError err;
 | 
						HandleError err;
 | 
				
			||||||
	ConVar *pConVar;
 | 
						ConVar *pConVar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
 | 
						if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
 | 
				
			||||||
		!= HandleError_None)
 | 
							!= HandleError_None)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
							return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
				
			||||||
@ -488,7 +490,7 @@ static cell_t sm_GetConVarName(IPluginContext *pContext, const cell_t *params)
 | 
				
			|||||||
	HandleError err;
 | 
						HandleError err;
 | 
				
			||||||
	ConVar *pConVar;
 | 
						ConVar *pConVar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
 | 
						if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
 | 
				
			||||||
		!= HandleError_None)
 | 
							!= HandleError_None)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
							return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);
 | 
				
			||||||
 | 
				
			|||||||
@ -33,7 +33,7 @@
 | 
				
			|||||||
#include "sourcemm_api.h"
 | 
					#include "sourcemm_api.h"
 | 
				
			||||||
#include "sm_version.h"
 | 
					#include "sm_version.h"
 | 
				
			||||||
#include "Logger.h"
 | 
					#include "Logger.h"
 | 
				
			||||||
#include "ConVarManager.h"
 | 
					#include "concmd_cleaner.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SourceMod_Core g_SourceMod_Core;
 | 
					SourceMod_Core g_SourceMod_Core;
 | 
				
			||||||
IVEngineServer *engine = NULL;
 | 
					IVEngineServer *engine = NULL;
 | 
				
			||||||
@ -203,14 +203,18 @@ void SourceMod_Core::OnVSPListening(IServerPluginCallbacks *iface)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if PLAPI_VERSION >= 12
 | 
					#if defined METAMOD_PLAPI_VERSION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SourceMod_Core::OnUnlinkConCommandBase(PluginId id, ConCommandBase *pCommand)
 | 
					void SourceMod_Core::OnUnlinkConCommandBase(PluginId id, ConCommandBase *pCommand)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	g_ConVarManager.OnUnlinkConCommandBase(id, pCommand);
 | 
						Global_OnUnlinkConCommandBase(pCommand);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SourceMod_Core::OnPluginUnload(PluginId id)
 | 
					void SourceMod_Core::OnPluginUnload(PluginId id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	g_ConVarManager.OnMetamodPluginUnloaded(id);
 | 
						Global_OnUnlinkConCommandBase(NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -74,7 +74,7 @@ public:
 | 
				
			|||||||
	const char *GetLogTag();
 | 
						const char *GetLogTag();
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	void OnVSPListening(IServerPluginCallbacks *iface);
 | 
						void OnVSPListening(IServerPluginCallbacks *iface);
 | 
				
			||||||
#if PLAPI_VERSION >= 12
 | 
					#if defined METAMOD_PLAPI_VERSION
 | 
				
			||||||
	void OnUnlinkConCommandBase(PluginId id, ConCommandBase *pCommand);
 | 
						void OnUnlinkConCommandBase(PluginId id, ConCommandBase *pCommand);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	void OnPluginUnload(PluginId id);
 | 
						void OnPluginUnload(PluginId id);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user