Commands with the same name as an existing convar can no longer be created

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40585
This commit is contained in:
Scott Ehlert 2007-03-06 06:15:19 +00:00
parent ac9051ab71
commit 70ec3db66c
5 changed files with 84 additions and 47 deletions

View File

@ -11,14 +11,14 @@
* Version: $Id$ * Version: $Id$
*/ */
#include "CConCmdManager.h" #include "ConCmdManager.h"
#include "sm_srvcmds.h" #include "sm_srvcmds.h"
#include "AdminCache.h" #include "AdminCache.h"
#include "sm_stringutil.h" #include "sm_stringutil.h"
#include "CPlayerManager.h" #include "CPlayerManager.h"
#include "CTranslator.h" #include "CTranslator.h"
CConCmdManager g_ConCmds; ConCmdManager g_ConCmds;
SH_DECL_HOOK0_void(ConCommand, Dispatch, SH_NOATTRIB, false); SH_DECL_HOOK0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
SH_DECL_HOOK1_void(IServerGameClients, SetCommandClient, SH_NOATTRIB, false, int); SH_DECL_HOOK1_void(IServerGameClients, SetCommandClient, SH_NOATTRIB, false, int);
@ -32,34 +32,34 @@ struct PlCmdInfo
typedef List<PlCmdInfo> CmdList; typedef List<PlCmdInfo> CmdList;
void AddToPlCmdList(CmdList *pList, const PlCmdInfo &info); void AddToPlCmdList(CmdList *pList, const PlCmdInfo &info);
CConCmdManager::CConCmdManager() : m_Strings(1024) ConCmdManager::ConCmdManager() : m_Strings(1024)
{ {
m_pCmds = sm_trie_create(); m_pCmds = sm_trie_create();
m_pCmdGrps = sm_trie_create(); m_pCmdGrps = sm_trie_create();
} }
CConCmdManager::~CConCmdManager() ConCmdManager::~ConCmdManager()
{ {
sm_trie_destroy(m_pCmds); sm_trie_destroy(m_pCmds);
sm_trie_destroy(m_pCmdGrps); sm_trie_destroy(m_pCmdGrps);
} }
void CConCmdManager::OnSourceModAllInitialized() void ConCmdManager::OnSourceModAllInitialized()
{ {
g_PluginSys.AddPluginsListener(this); g_PluginSys.AddPluginsListener(this);
g_RootMenu.AddRootConsoleCommand("cmds", "List console commands", this); g_RootMenu.AddRootConsoleCommand("cmds", "List console commands", this);
SH_ADD_HOOK_MEMFUNC(IServerGameClients, SetCommandClient, serverClients, this, &CConCmdManager::SetCommandClient, false); SH_ADD_HOOK_MEMFUNC(IServerGameClients, SetCommandClient, serverClients, this, &ConCmdManager::SetCommandClient, false);
} }
void CConCmdManager::OnSourceModShutdown() void ConCmdManager::OnSourceModShutdown()
{ {
/* All commands should already be removed by the time we're done */ /* All commands should already be removed by the time we're done */
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, SetCommandClient, serverClients, this, &CConCmdManager::SetCommandClient, false); SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, SetCommandClient, serverClients, this, &ConCmdManager::SetCommandClient, false);
g_RootMenu.RemoveRootConsoleCommand("cmds", this); g_RootMenu.RemoveRootConsoleCommand("cmds", this);
g_PluginSys.RemovePluginsListener(this); g_PluginSys.RemovePluginsListener(this);
} }
void CConCmdManager::RemoveConCmds(List<CmdHook *> &cmdlist, IPluginContext *pContext) void ConCmdManager::RemoveConCmds(List<CmdHook *> &cmdlist, IPluginContext *pContext)
{ {
List<CmdHook *>::iterator iter = cmdlist.begin(); List<CmdHook *>::iterator iter = cmdlist.begin();
CmdHook *pHook; CmdHook *pHook;
@ -78,7 +78,7 @@ void CConCmdManager::RemoveConCmds(List<CmdHook *> &cmdlist, IPluginContext *pCo
} }
} }
void CConCmdManager::OnPluginDestroyed(IPlugin *plugin) void ConCmdManager::OnPluginDestroyed(IPlugin *plugin)
{ {
CmdList *pList; CmdList *pList;
List<ConCmdInfo *> removed; List<ConCmdInfo *> removed;
@ -129,12 +129,12 @@ void CommandCallback()
g_ConCmds.InternalDispatch(); g_ConCmds.InternalDispatch();
} }
void CConCmdManager::SetCommandClient(int client) void ConCmdManager::SetCommandClient(int client)
{ {
m_CmdClient = client + 1; m_CmdClient = client + 1;
} }
ResultType CConCmdManager::DispatchClientCommand(int client, ResultType type) ResultType ConCmdManager::DispatchClientCommand(int client, ResultType type)
{ {
const char *cmd = engine->Cmd_Argv(0); const char *cmd = engine->Cmd_Argv(0);
int args = engine->Cmd_Argc() - 1; int args = engine->Cmd_Argc() - 1;
@ -183,7 +183,7 @@ ResultType CConCmdManager::DispatchClientCommand(int client, ResultType type)
return type; return type;
} }
void CConCmdManager::InternalDispatch() void ConCmdManager::InternalDispatch()
{ {
/** /**
* Note: Console commands will EITHER go through IServerGameDLL::ClientCommand, * Note: Console commands will EITHER go through IServerGameDLL::ClientCommand,
@ -292,7 +292,7 @@ void CConCmdManager::InternalDispatch()
} }
} }
bool CConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin) bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin)
{ {
FlagBits cmdflags = pAdmin->eflags; FlagBits cmdflags = pAdmin->eflags;
if (cmdflags == 0) if (cmdflags == 0)
@ -372,12 +372,18 @@ bool CConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdm
return false; return false;
} }
void CConCmdManager::AddConsoleCommand(IPluginFunction *pFunction, bool ConCmdManager::AddConsoleCommand(IPluginFunction *pFunction,
const char *name, const char *name,
const char *description, const char *description,
int flags) int flags)
{ {
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags); ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags);
if (!pInfo)
{
return false;
}
CmdHook *pHook = new CmdHook(); CmdHook *pHook = new CmdHook();
pHook->pf = pFunction; pHook->pf = pFunction;
@ -400,9 +406,11 @@ void CConCmdManager::AddConsoleCommand(IPluginFunction *pFunction,
info.type = Cmd_Console; info.type = Cmd_Console;
info.pHook = pHook; info.pHook = pHook;
AddToPlCmdList(pList, info); AddToPlCmdList(pList, info);
return true;
} }
bool CConCmdManager::AddAdminCommand(IPluginFunction *pFunction, bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
const char *name, const char *name,
const char *group, const char *group,
int adminflags, int adminflags,
@ -411,6 +419,11 @@ bool CConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
{ {
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags); ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags);
if (!pInfo)
{
return false;
}
CmdHook *pHook = new CmdHook(); CmdHook *pHook = new CmdHook();
AdminCmdInfo *pAdmin = new AdminCmdInfo(); AdminCmdInfo *pAdmin = new AdminCmdInfo();
@ -473,13 +486,19 @@ bool CConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
return true; return true;
} }
void CConCmdManager::AddServerCommand(IPluginFunction *pFunction, bool ConCmdManager::AddServerCommand(IPluginFunction *pFunction,
const char *name, const char *name,
const char *description, const char *description,
int flags) int flags)
{ {
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags); ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags);
if (!pInfo)
{
return false;
}
CmdHook *pHook = new CmdHook(); CmdHook *pHook = new CmdHook();
pHook->pf = pFunction; pHook->pf = pFunction;
@ -503,6 +522,8 @@ void CConCmdManager::AddServerCommand(IPluginFunction *pFunction,
info.type = Cmd_Server; info.type = Cmd_Server;
info.pHook = pHook; info.pHook = pHook;
AddToPlCmdList(pList, info); AddToPlCmdList(pList, info);
return true;
} }
void AddToPlCmdList(CmdList *pList, const PlCmdInfo &info) void AddToPlCmdList(CmdList *pList, const PlCmdInfo &info)
@ -533,7 +554,7 @@ void AddToPlCmdList(CmdList *pList, const PlCmdInfo &info)
} }
} }
void CConCmdManager::AddToCmdList(ConCmdInfo *info) void ConCmdManager::AddToCmdList(ConCmdInfo *info)
{ {
List<ConCmdInfo *>::iterator iter = m_CmdList.begin(); List<ConCmdInfo *>::iterator iter = m_CmdList.begin();
ConCmdInfo *pInfo; ConCmdInfo *pInfo;
@ -563,7 +584,7 @@ void CConCmdManager::AddToCmdList(ConCmdInfo *info)
} }
} }
void CConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits) void ConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits)
{ {
ConCmdInfo *pInfo; ConCmdInfo *pInfo;
@ -623,7 +644,7 @@ void CConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, Fla
} }
} }
void CConCmdManager::RemoveConCmd(ConCmdInfo *info) void ConCmdManager::RemoveConCmd(ConCmdInfo *info)
{ {
/* Remove console-specific information /* Remove console-specific information
* This should always be true as of right now * This should always be true as of right now
@ -655,7 +676,7 @@ void CConCmdManager::RemoveConCmd(ConCmdInfo *info)
delete info; delete info;
} }
ConCmdInfo *CConCmdManager::AddOrFindCommand(const char *name, const char *description, int flags) ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *description, int flags)
{ {
ConCmdInfo *pInfo; ConCmdInfo *pInfo;
if (!sm_trie_retrieve(m_pCmds, name, (void **)&pInfo)) if (!sm_trie_retrieve(m_pCmds, name, (void **)&pInfo))
@ -666,9 +687,14 @@ ConCmdInfo *CConCmdManager::AddOrFindCommand(const char *name, const char *descr
ConCommand *pCmd = NULL; ConCommand *pCmd = NULL;
while (pBase) while (pBase)
{ {
if (pBase->IsCommand() if (strcmp(pBase->GetName(), name) == 0)
&& (strcmp(pBase->GetName(), name) == 0))
{ {
/* Don't want to return convar with same name */
if (!pBase->IsCommand())
{
return NULL;
}
pCmd = (ConCommand *)pBase; pCmd = (ConCommand *)pBase;
break; break;
} }
@ -701,7 +727,7 @@ ConCmdInfo *CConCmdManager::AddOrFindCommand(const char *name, const char *descr
return pInfo; return pInfo;
} }
void CConCmdManager::OnRootConsoleCommand(const char *command, unsigned int argcount) void ConCmdManager::OnRootConsoleCommand(const char *command, unsigned int argcount)
{ {
if (argcount >= 3) if (argcount >= 3)
{ {

View File

@ -12,8 +12,8 @@
* Version: $Id$ * Version: $Id$
*/ */
#ifndef _INCLUDE_SOURCEMOD_CCONCMDMANAGER_H_ #ifndef _INCLUDE_SOURCEMOD_CONCMDMANAGER_H_
#define _INCLUDE_SOURCEMOD_CCONCMDMANAGER_H_ #define _INCLUDE_SOURCEMOD_CONCMDMANAGER_H_
#include "sm_globals.h" #include "sm_globals.h"
#include "sourcemm_api.h" #include "sourcemm_api.h"
@ -72,15 +72,15 @@ struct ConCmdInfo
List<CmdHook *> conhooks; /**< Hooks as a console command */ List<CmdHook *> conhooks; /**< Hooks as a console command */
}; };
class CConCmdManager : class ConCmdManager :
public SMGlobalClass, public SMGlobalClass,
public IRootConsoleCommand, public IRootConsoleCommand,
public IPluginsListener public IPluginsListener
{ {
friend void CommandCallback(); friend void CommandCallback();
public: public:
CConCmdManager(); ConCmdManager();
~CConCmdManager(); ~ConCmdManager();
public: //SMGlobalClass public: //SMGlobalClass
void OnSourceModAllInitialized(); void OnSourceModAllInitialized();
void OnSourceModShutdown(); void OnSourceModShutdown();
@ -89,8 +89,8 @@ public: //IPluginsListener
public: //IRootConsoleCommand public: //IRootConsoleCommand
void OnRootConsoleCommand(const char *command, unsigned int argcount); void OnRootConsoleCommand(const char *command, unsigned int argcount);
public: public:
void AddServerCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags); bool AddServerCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags);
void AddConsoleCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags); bool AddConsoleCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags);
bool AddAdminCommand(IPluginFunction *pFunction, bool AddAdminCommand(IPluginFunction *pFunction,
const char *name, const char *name,
const char *group, const char *group,
@ -116,7 +116,6 @@ private:
BaseStringTable m_Strings; /* string table */ BaseStringTable m_Strings; /* string table */
}; };
extern CConCmdManager g_ConCmds; extern ConCmdManager g_ConCmds;
#endif // _INCLUDE_SOURCEMOD_CCONCMDMANAGER_H_
#endif // _INCLUDE_SOURCEMOD_CONCMDMANAGER_H_

View File

@ -183,10 +183,6 @@
RelativePath="..\AdminCache.cpp" RelativePath="..\AdminCache.cpp"
> >
</File> </File>
<File
RelativePath="..\CConCmdManager.cpp"
>
</File>
<File <File
RelativePath="..\CConVarManager.cpp" RelativePath="..\CConVarManager.cpp"
> >
@ -211,6 +207,10 @@
RelativePath="..\CLogger.cpp" RelativePath="..\CLogger.cpp"
> >
</File> </File>
<File
RelativePath="..\ConCmdManager.cpp"
>
</File>
<File <File
RelativePath="..\CPlayerManager.cpp" RelativePath="..\CPlayerManager.cpp"
> >
@ -269,10 +269,6 @@
RelativePath="..\AdminCache.h" RelativePath="..\AdminCache.h"
> >
</File> </File>
<File
RelativePath="..\CConCmdManager.h"
>
</File>
<File <File
RelativePath="..\CConVarManager.h" RelativePath="..\CConVarManager.h"
> >
@ -305,6 +301,10 @@
RelativePath="..\CMsgListenerWrapper.h" RelativePath="..\CMsgListenerWrapper.h"
> >
</File> </File>
<File
RelativePath="..\ConCmdManager.h"
>
</File>
<File <File
RelativePath="..\CPlayerManager.h" RelativePath="..\CPlayerManager.h"
> >

View File

@ -15,7 +15,7 @@
#include "sourcemm_api.h" #include "sourcemm_api.h"
#include "HandleSys.h" #include "HandleSys.h"
#include "CConVarManager.h" #include "CConVarManager.h"
#include "CConCmdManager.h" #include "ConCmdManager.h"
#include "PluginSys.h" #include "PluginSys.h"
#include "sm_stringutil.h" #include "sm_stringutil.h"
#include "CPlayerManager.h" #include "CPlayerManager.h"
@ -340,7 +340,10 @@ static cell_t sm_RegServerCmd(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Invalid function id (%X)", params[2]); return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
} }
g_ConCmds.AddServerCommand(pFunction, name, help, params[4]); if (!g_ConCmds.AddServerCommand(pFunction, name, help, params[4]))
{
return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
}
return 1; return 1;
} }
@ -359,7 +362,10 @@ static cell_t sm_RegConsoleCmd(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Invalid function id (%X)", params[2]); return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
} }
g_ConCmds.AddConsoleCommand(pFunction, name, help, params[4]); if (!g_ConCmds.AddConsoleCommand(pFunction, name, help, params[4]))
{
return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
}
return 1; return 1;
} }
@ -388,7 +394,10 @@ static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Invalid function id (%X)", params[2]); return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
} }
g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags); if (!g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags))
{
return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
}
return 1; return 1;
} }

View File

@ -126,6 +126,7 @@ functag SrvCmd Action:public(args);
* @param description Optional description to use for command creation. * @param description Optional description to use for command creation.
* @param flags Optional flags to use for command creation. * @param flags Optional flags to use for command creation.
* @noreturn * @noreturn
* @error Command name is the same as an existing convar.
*/ */
native RegServerCmd(const String:cmd[], SrvCmd:callback, const String:description[]="", flags=0); native RegServerCmd(const String:cmd[], SrvCmd:callback, const String:description[]="", flags=0);
@ -147,6 +148,7 @@ functag ConCmd Action:public(client, args);
* @param description Optional description to use for command creation. * @param description Optional description to use for command creation.
* @param flags Optional flags to use for command creation. * @param flags Optional flags to use for command creation.
* @noreturn * @noreturn
* @error Command name is the same as an existing convar.
*/ */
native RegConsoleCmd(const String:cmd[], ConCmd:callback, const String:description[]="", flags=0); native RegConsoleCmd(const String:cmd[], ConCmd:callback, const String:description[]="", flags=0);
@ -163,6 +165,7 @@ native RegConsoleCmd(const String:cmd[], ConCmd:callback, const String:descripti
* @param description Optional description to use for help. * @param description Optional description to use for help.
* @param flags Optional console flags. * @param flags Optional console flags.
* @noreturn * @noreturn
* @error Command name is the same as an existing convar.
*/ */
native RegAdminCmd(const String:cmd[], native RegAdminCmd(const String:cmd[],
ConCmd:callback, ConCmd:callback,
@ -213,7 +216,7 @@ native GetCmdArgString(String:buffer[], maxlength);
* @param hasMax Optional boolean that determines if the convar has a maximum value. * @param hasMax Optional boolean that determines if the convar has a maximum value.
* @param max Maximum floating point value that the convar can have if hasMax is true. * @param max Maximum floating point value that the convar can have if hasMax is true.
* @return A handle to the newly created convar. If the convar already exists, INVALID_HANDLE is returned. * @return A handle to the newly created convar. If the convar already exists, INVALID_HANDLE is returned.
* @error Convar name is blank or is the same as a console command. * @error Convar name is blank or is the same as an existing console command.
*/ */
native Handle:CreateConVar(const String:name[], const String:defaultValue[], const String:helpText[]="", flags=0, bool:hasMin=false, Float:min=0.0, bool:hasMax=false, Float:max=0.0); native Handle:CreateConVar(const String:name[], const String:defaultValue[], const String:helpText[]="", flags=0, bool:hasMin=false, Float:min=0.0, bool:hasMax=false, Float:max=0.0);