Fixed crash on plugin unload when two cmds exist with same name, different casing (bug 4698, r=Fyren).
This commit is contained in:
parent
9a5f788807
commit
859678536f
@ -226,30 +226,38 @@ void ConCmdManager::SetCommandClient(int client)
|
|||||||
m_CmdClient = client + 1;
|
m_CmdClient = client + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConCmdInfo *ConCmdManager::FindInTrie(const char *name)
|
||||||
|
{
|
||||||
|
ConCmdInfo *pInfo;
|
||||||
|
if (!sm_trie_retrieve(m_pCmds, name, (void **)&pInfo))
|
||||||
|
return NULL;
|
||||||
|
return pInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConCmdList::iterator ConCmdManager::FindInList(const char *cmd)
|
||||||
|
{
|
||||||
|
List<ConCmdInfo *>::iterator iter = m_CmdList.begin();
|
||||||
|
|
||||||
|
while (iter != m_CmdList.end())
|
||||||
|
{
|
||||||
|
if (strcasecmp((*iter)->pCmd->GetName(), cmd) == 0)
|
||||||
|
break;
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
|
||||||
ResultType ConCmdManager::DispatchClientCommand(int client, const char *cmd, int args, ResultType type)
|
ResultType ConCmdManager::DispatchClientCommand(int client, const char *cmd, int args, ResultType type)
|
||||||
{
|
{
|
||||||
ConCmdInfo *pInfo;
|
ConCmdInfo *pInfo;
|
||||||
|
|
||||||
if (!sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo))
|
if ((pInfo = FindInTrie(cmd)) == NULL)
|
||||||
{
|
{
|
||||||
List<ConCmdInfo *>::iterator iter;
|
ConCmdList::iterator item = FindInList(cmd);
|
||||||
|
if (item == m_CmdList.end())
|
||||||
pInfo = NULL;
|
|
||||||
iter = m_CmdList.begin();
|
|
||||||
while (iter != m_CmdList.end())
|
|
||||||
{
|
|
||||||
if (strcasecmp((*iter)->pCmd->GetName(), cmd) == 0)
|
|
||||||
{
|
|
||||||
pInfo = (*iter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pInfo == NULL)
|
|
||||||
{
|
|
||||||
return type;
|
return type;
|
||||||
}
|
pInfo = *item;
|
||||||
}
|
}
|
||||||
|
|
||||||
cell_t result = type;
|
cell_t result = type;
|
||||||
@ -314,35 +322,20 @@ void ConCmdManager::InternalDispatch(const CCommand &command)
|
|||||||
*/
|
*/
|
||||||
const char *cmd = g_HL2.CurrentCommandName();
|
const char *cmd = g_HL2.CurrentCommandName();
|
||||||
|
|
||||||
ConCmdInfo *pInfo;
|
ConCmdInfo *pInfo = FindInTrie(cmd);
|
||||||
if (!sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo))
|
if (pInfo == NULL)
|
||||||
{
|
{
|
||||||
/* Unfortunately, we now have to do a slow lookup because Valve made client commands
|
/* Unfortunately, we now have to do a slow lookup because Valve made client commands
|
||||||
* case-insensitive. We can't even use our sortedness.
|
* case-insensitive. We can't even use our sortedness.
|
||||||
*/
|
*/
|
||||||
if (client == 0 && !engine->IsDedicatedServer())
|
if (client == 0 && !engine->IsDedicatedServer())
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
List<ConCmdInfo *>::iterator iter;
|
ConCmdList::iterator item = FindInList(cmd);
|
||||||
|
if (item == m_CmdList.end())
|
||||||
|
return;
|
||||||
|
|
||||||
pInfo = NULL;
|
pInfo = *item;
|
||||||
iter = m_CmdList.begin();
|
|
||||||
while (iter != m_CmdList.end())
|
|
||||||
{
|
|
||||||
if (strcasecmp((*iter)->pCmd->GetName(), cmd) == 0)
|
|
||||||
{
|
|
||||||
pInfo = (*iter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pInfo == NULL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is a hack to prevent say triggers from firing on messages that were
|
/* This is a hack to prevent say triggers from firing on messages that were
|
||||||
@ -916,6 +909,10 @@ ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *descri
|
|||||||
ConCmdInfo *pInfo;
|
ConCmdInfo *pInfo;
|
||||||
if (!sm_trie_retrieve(m_pCmds, name, (void **)&pInfo))
|
if (!sm_trie_retrieve(m_pCmds, name, (void **)&pInfo))
|
||||||
{
|
{
|
||||||
|
ConCmdList::iterator item = FindInList(name);
|
||||||
|
if (item != m_CmdList.end())
|
||||||
|
return *item;
|
||||||
|
|
||||||
pInfo = new ConCmdInfo();
|
pInfo = new ConCmdInfo();
|
||||||
/* Find the commandopan */
|
/* Find the commandopan */
|
||||||
ConCommand *pCmd = FindCommand(name);
|
ConCommand *pCmd = FindCommand(name);
|
||||||
|
@ -92,6 +92,8 @@ struct ConCmdInfo
|
|||||||
bool is_admin_set; /**< Whether or not admin info is set */
|
bool is_admin_set; /**< Whether or not admin info is set */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef List<ConCmdInfo *> ConCmdList;
|
||||||
|
|
||||||
class ConCmdManager :
|
class ConCmdManager :
|
||||||
public SMGlobalClass,
|
public SMGlobalClass,
|
||||||
public IRootConsoleCommand,
|
public IRootConsoleCommand,
|
||||||
@ -139,6 +141,12 @@ private:
|
|||||||
void RemoveConCmds(List<CmdHook *> &cmdlist);
|
void RemoveConCmds(List<CmdHook *> &cmdlist);
|
||||||
void RemoveConCmds(List<CmdHook *> &cmdlist, IPluginContext *pContext);
|
void RemoveConCmds(List<CmdHook *> &cmdlist, IPluginContext *pContext);
|
||||||
bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin);
|
bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin);
|
||||||
|
|
||||||
|
// Case insensitive
|
||||||
|
ConCmdList::iterator FindInList(const char *name);
|
||||||
|
|
||||||
|
// Case sensitive
|
||||||
|
ConCmdInfo *FindInTrie(const char *name);
|
||||||
public:
|
public:
|
||||||
inline int GetCommandClient()
|
inline int GetCommandClient()
|
||||||
{
|
{
|
||||||
@ -151,7 +159,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
Trie *m_pCmds; /* command lookup */
|
Trie *m_pCmds; /* command lookup */
|
||||||
Trie *m_pCmdGrps; /* command group lookup */
|
Trie *m_pCmdGrps; /* command group lookup */
|
||||||
List<ConCmdInfo *> m_CmdList; /* command list */
|
ConCmdList m_CmdList; /* command list */
|
||||||
int m_CmdClient; /* current client */
|
int m_CmdClient; /* current client */
|
||||||
BaseStringTable m_Strings; /* string table */
|
BaseStringTable m_Strings; /* string table */
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user