- 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:
David Anderson 2007-10-16 01:17:08 +00:00
parent 60d8e4f248
commit 796d9b2de8
8 changed files with 412 additions and 191 deletions

View File

@ -37,6 +37,7 @@
#include "sm_srvcmds.h"
#include "sm_stringutil.h"
#include <sh_vector.h>
#include <sm_trie_tpl.h>
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};
typedef List<const ConVar *> ConVarList;
KTrie<ConVarInfo *> convar_cache;
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()
{
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()
@ -101,6 +85,48 @@ void ConVarManager::OnSourceModAllInitialized()
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)
{
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, OnQueryCvarValueFinished, gamedll, this, &ConVarManager::OnQueryCvarValueFinished, false);
@ -112,21 +138,6 @@ void ConVarManager::OnSourceModShutdown()
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 */
g_RootMenu.RemoveRootConsoleCommand("cvars", this);
@ -165,54 +176,55 @@ void ConVarManager::OnSourceModVSPReceived()
m_bIsVSPQueryHooked = true;
}
#if PLAPI_VERSION >= 12
void ConVarManager::OnUnlinkConCommandBase(PluginId id, ConCommandBase *pCommand)
bool convar_cache_lookup(const char *name, ConVarInfo **pVar)
{
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 */
if (id != g_PLID && !pCommand->IsCommand())
{
ConVarInfo *pInfo;
const char *cvarName = pCommand->GetName();
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);
sm_trie_delete(m_ConVarCache, cvarName);
m_ConVars.remove(pInfo);
}
}
}
#else
/* I truly detest this code */
void ConVarManager::OnMetamodPluginUnloaded(PluginId id)
{
ConVarInfo *pInfo;
const char *cvarName;
if (!convar_cache_lookup(name, &pInfo))
{
return;
}
HandleSecurity sec(NULL, g_pCoreIdent);
List<ConVarInfo *>::iterator i;
for (i = m_ConVars.begin(); i != m_ConVars.end(); i++)
/* Remove it from our cache */
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())
{
pInfo = (*i);
cvarName = pInfo->name;
IPlugin *pl = pl_iter->GetPlugin();
if (cvarName && !icvar->FindVar(cvarName))
ConVarList *pConVarList;
if (pl->GetProperty("ConVarList", (void **)&pConVarList, true)
&& pConVarList != NULL)
{
m_IgnoreHandle = true;
g_HandleSys.FreeHandle(pInfo->handle, &sec);
sm_trie_delete(m_ConVarCache, cvarName);
m_ConVars.erase(i);
delete [] cvarName;
pConVarList->remove(pInfo->pVar);
}
pl_iter->NextPlugin();
}
/* Free resources */
g_HandleSys.FreeHandle(pInfo->handle, &sec);
delete pInfo;
}
#endif
void ConVarManager::OnPluginUnloaded(IPlugin *plugin)
{
@ -227,33 +239,6 @@ void ConVarManager::OnPluginUnloaded(IPlugin *plugin)
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)
@ -320,28 +305,33 @@ Handle_t ConVarManager::CreateConVar(IPluginContext *pContext, const char *name,
AddConVarToPluginList(pContext, pConVar);
/* 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;
}
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 */
pInfo = new ConVarInfo();
pInfo->handle = hndl;
pInfo->sourceMod = false;
pInfo->pChangeForward = NULL;
pInfo->origCallback = pConVar->GetCallback();
#if PLAPI_VERSION < 12
pInfo->name = sm_strdup(pConVar->GetName());
#endif
pInfo->pVar = pConVar;
/* 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 */
m_ConVars.push_back(pInfo);
sm_trie_insert(m_ConVarCache, name, pInfo);
convar_cache.insert(name, pInfo);
TrackConCommandBase(pConVar, this);
return hndl;
}
@ -360,28 +350,33 @@ Handle_t ConVarManager::CreateConVar(IPluginContext *pContext, const char *name,
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 */
pInfo = new ConVarInfo();
pInfo->handle = hndl;
pInfo->sourceMod = true;
pInfo->pChangeForward = NULL;
pInfo->origCallback = NULL;
#if PLAPI_VERSION < 12
pInfo->name = NULL;
#endif
/* Create a handle from the new convar */
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 */
m_ConVars.push_back(pInfo);
sm_trie_insert(m_ConVarCache, name, pInfo);
convar_cache.insert(name, pInfo);
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 */
if (sm_trie_retrieve(m_ConVarCache, name, (void **)&pInfo))
if (convar_cache_lookup(name, &pInfo))
{
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 */
pInfo = new ConVarInfo();
pInfo->handle = hndl;
pInfo->sourceMod = false;
pInfo->pChangeForward = NULL;
pInfo->origCallback = pConVar->GetCallback();
#if PLAPI_VERSION < 12
pInfo->name = sm_strdup(pConVar->GetName());
#endif
pInfo->pVar = pConVar;
/* 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 */
m_ConVars.push_back(pInfo);
sm_trie_insert(m_ConVarCache, name, pInfo);
convar_cache.insert(name, pInfo);
TrackConCommandBase(pConVar, this);
return hndl;
}
@ -433,7 +433,7 @@ void ConVarManager::HookConVarChange(ConVar *pConVar, IPluginFunction *pFunction
IChangeableForward *pForward;
/* 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 */
pForward = pInfo->pChangeForward;
@ -460,7 +460,7 @@ void ConVarManager::UnhookConVarChange(ConVar *pConVar, IPluginFunction *pFuncti
IPluginContext *pContext = pFunction->GetParentContext();
/* 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 */
pForward = pInfo->pChangeForward;
@ -569,11 +569,13 @@ void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue)
return;
}
Trie *pCache = g_ConVarManager.GetConVarCache();
ConVarInfo *pInfo;
/* 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;
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;

View File

@ -34,13 +34,13 @@
#include "sm_globals.h"
#include "sourcemm_api.h"
#include "sm_trie.h"
#include <sh_list.h>
#include <IPluginSys.h>
#include <IForwardSys.h>
#include <IHandleSys.h>
#include <IRootConsoleMenu.h>
#include <compat_wrappers.h>
#include "concmd_cleaner.h"
using namespace SourceHook;
@ -49,13 +49,11 @@ using namespace SourceHook;
*/
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 */
IChangeableForward *pChangeForward; /**< Forward associated with convar */
FnChangeCallback_t origCallback; /**< The original callback function */
#if PLAPI_VERSION < 12
const char *name; /**< Name of convar */
#endif
ConVar *pVar; /**< The actual convar */
};
/**
@ -72,7 +70,8 @@ class ConVarManager :
public SMGlobalClass,
public IHandleTypeDispatch,
public IPluginsListener,
public IRootConsoleCommand
public IRootConsoleCommand,
public IConCommandTracker
{
public:
ConVarManager();
@ -87,22 +86,8 @@ public: // IPluginsListener
void OnPluginUnloaded(IPlugin *plugin);
public: //IRootConsoleCommand
void OnRootConsoleCommand(const char *cmdname, const CCommand &command);
public:
/**
* 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: //IConCommandTracker
void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe);
public:
/**
* Create a convar and return a handle to it.
@ -133,17 +118,8 @@ public:
bool IsQueryingSupported();
#if PLAPI_VERSION >= 12
/**
* 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
HandleError ReadConVarHandle(Handle_t hndl, ConVar **pVar);
private:
/**
* Adds a convar to a plugin's list.
@ -168,12 +144,8 @@ private:
HandleType_t m_ConVarType;
List<ConVarInfo *> m_ConVars;
List<ConVarQuery> m_ConVarQueries;
Trie *m_ConVarCache;
bool m_bIsDLLQueryHooked;
bool m_bIsVSPQueryHooked;
#if PLAPI_VERSION < 12
bool m_IgnoreHandle;
#endif
};
extern ConVarManager g_ConVarManager;

175
core/concmd_cleaner.cpp Normal file
View 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
View 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);

View File

@ -609,6 +609,10 @@
RelativePath="..\ChatTriggers.cpp"
>
</File>
<File
RelativePath="..\concmd_cleaner.cpp"
>
</File>
<File
RelativePath="..\ConCmdManager.cpp"
>
@ -803,6 +807,10 @@
RelativePath="..\..\public\compat_wrappers.h"
>
</File>
<File
RelativePath="..\concmd_cleaner.h"
>
</File>
<File
RelativePath="..\ConCmdManager.h"
>

View File

@ -110,7 +110,9 @@ static void NotifyConVar(ConVar *pConVar)
if (IsFlagSet(pConVar, FCVAR_PROTECTED))
{
pEvent->SetString("cvarvalue", "***PROTECTED***");
} else {
}
else
{
pEvent->SetString("cvarvalue", pConVar->GetString());
}
@ -141,7 +143,7 @@ static cell_t sm_CreateConVar(IPluginContext *pContext, const cell_t *params)
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;
@ -162,7 +164,7 @@ static cell_t sm_HookConVarChange(IPluginContext *pContext, const cell_t *params
HandleError err;
ConVar *pConVar;
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
!= HandleError_None)
{
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;
ConVar *pConVar;
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
!= HandleError_None)
{
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;
ConVar *pConVar;
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
!= HandleError_None)
{
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;
ConVar *pConVar;
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
!= HandleError_None)
{
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;
ConVar *pConVar;
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
!= HandleError_None)
{
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;
ConVar *pConVar;
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
!= HandleError_None)
{
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;
ConVar *pConVar;
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
!= HandleError_None)
{
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;
ConVar *pConVar;
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
!= HandleError_None)
{
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;
ConVar *pConVar;
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
!= HandleError_None)
{
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;
ConVar *pConVar;
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
!= HandleError_None)
{
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;
ConVar *pConVar;
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
!= HandleError_None)
{
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;
ConVar *pConVar;
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
!= HandleError_None)
{
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;
ConVar *pConVar;
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
!= HandleError_None)
{
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;
ConVar *pConVar;
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
!= HandleError_None)
{
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;
ConVar *pConVar;
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
if ((err=g_ConVarManager.ReadConVarHandle(hndl, &pConVar))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid convar handle %x (error %d)", hndl, err);

View File

@ -33,7 +33,7 @@
#include "sourcemm_api.h"
#include "sm_version.h"
#include "Logger.h"
#include "ConVarManager.h"
#include "concmd_cleaner.h"
SourceMod_Core g_SourceMod_Core;
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)
{
g_ConVarManager.OnUnlinkConCommandBase(id, pCommand);
Global_OnUnlinkConCommandBase(pCommand);
}
#else
void SourceMod_Core::OnPluginUnload(PluginId id)
{
g_ConVarManager.OnMetamodPluginUnloaded(id);
Global_OnUnlinkConCommandBase(NULL);
}
#endif

View File

@ -74,7 +74,7 @@ public:
const char *GetLogTag();
public:
void OnVSPListening(IServerPluginCallbacks *iface);
#if PLAPI_VERSION >= 12
#if defined METAMOD_PLAPI_VERSION
void OnUnlinkConCommandBase(PluginId id, ConCommandBase *pCommand);
#else
void OnPluginUnload(PluginId id);