concmd manager now uses the concmd cleaner

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401590
This commit is contained in:
David Anderson 2007-10-16 05:30:41 +00:00
parent 1ab2bf2139
commit 630168a924
4 changed files with 105 additions and 18 deletions

View File

@ -85,6 +85,60 @@ void ConCmdManager::OnSourceModShutdown()
g_RootMenu.RemoveRootConsoleCommand("cmds", this); g_RootMenu.RemoveRootConsoleCommand("cmds", this);
} }
void ConCmdManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe)
{
/* Whoa, first get its information struct */
ConCmdInfo *pInfo;
if (!sm_trie_retrieve(m_pCmds, name, (void **)&pInfo))
{
return;
}
RemoveConCmds(pInfo->srvhooks);
RemoveConCmds(pInfo->conhooks);
RemoveConCmd(pInfo, name, is_read_safe, false);
}
void ConCmdManager::RemoveConCmds(List<CmdHook *> &cmdlist)
{
List<CmdHook *>::iterator iter = cmdlist.begin();
while (iter != cmdlist.end())
{
CmdHook *pHook = (*iter);
IPluginContext *pContext = pHook->pf->GetParentContext();
IPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
CmdList *pList = NULL;
//gaben
if (!pPlugin->GetProperty("CommandList", (void **)&pList, false) || !pList)
{
continue;
}
CmdList::iterator p_iter = pList->begin();
while (p_iter != pList->end())
{
PlCmdInfo &cmd = (*p_iter);
if (cmd.pHook == pHook)
{
p_iter = pList->erase(p_iter);
}
else
{
p_iter++;
}
}
delete pHook->pAdmin;
delete pHook;
iter = cmdlist.erase(iter);
}
}
void ConCmdManager::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();
@ -98,7 +152,9 @@ void ConCmdManager::RemoveConCmds(List<CmdHook *> &cmdlist, IPluginContext *pCon
delete pHook->pAdmin; delete pHook->pAdmin;
delete pHook; delete pHook;
iter = cmdlist.erase(iter); iter = cmdlist.erase(iter);
} else { }
else
{
iter++; iter++;
} }
} }
@ -143,7 +199,7 @@ void ConCmdManager::OnPluginDestroyed(IPlugin *plugin)
} }
/* Remove the command, it should be safe now */ /* Remove the command, it should be safe now */
RemoveConCmd(pInfo); RemoveConCmd(pInfo, pInfo->pCmd->GetName(), true, true);
removed.push_back(pInfo); removed.push_back(pInfo);
} }
delete pList; delete pList;
@ -516,7 +572,9 @@ bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
{ {
grpid = m_Strings.AddString(group); grpid = m_Strings.AddString(group);
sm_trie_insert(m_pCmdGrps, group, (void *)grpid); sm_trie_insert(m_pCmdGrps, group, (void *)grpid);
} else { }
else
{
grpid = (int)object; grpid = (int)object;
} }
@ -691,7 +749,9 @@ void ConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, Flag
} }
} }
pInfo->is_admin_set = true; pInfo->is_admin_set = true;
} else if (type == Override_CommandGroup) { }
else if (type == Override_CommandGroup)
{
void *object; void *object;
if (!sm_trie_retrieve(m_pCmdGrps, cmd, &object)) if (!sm_trie_retrieve(m_pCmdGrps, cmd, &object))
{ {
@ -726,16 +786,16 @@ void ConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, Flag
} }
} }
void ConCmdManager::RemoveConCmd(ConCmdInfo *info) void ConCmdManager::RemoveConCmd(ConCmdInfo *info, const char *name, bool is_read_safe, bool untrack)
{ {
/* Remove from the trie */
sm_trie_delete(m_pCmds, name);
/* 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
*/ */
if (info->pCmd) if (info->pCmd)
{ {
/* Remove from the trie */
sm_trie_delete(m_pCmds, info->pCmd->GetName());
if (info->sourceMod) if (info->sourceMod)
{ {
/* Unlink from SourceMM */ /* Unlink from SourceMM */
@ -746,9 +806,18 @@ void ConCmdManager::RemoveConCmd(ConCmdInfo *info)
delete [] new_help; delete [] new_help;
delete [] new_name; delete [] new_name;
delete info->pCmd; delete info->pCmd;
} else { }
/* Remove the external hook */ else
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, info->pCmd, CommandCallback, false); {
if (is_read_safe)
{
/* Remove the external hook */
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, info->pCmd, CommandCallback, false);
}
if (untrack)
{
UntrackConCommandBase(info->pCmd, this);
}
} }
} }
@ -822,7 +891,10 @@ ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *descri
char *new_help = sm_strdup(description); char *new_help = sm_strdup(description);
pCmd = new ConCommand(new_name, CommandCallback, new_help, flags); pCmd = new ConCommand(new_name, CommandCallback, new_help, flags);
pInfo->sourceMod = true; pInfo->sourceMod = true;
} else { }
else
{
TrackConCommandBase(pCmd, this);
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pCmd, CommandCallback, false); SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pCmd, CommandCallback, false);
} }
@ -880,16 +952,22 @@ void ConCmdManager::OnRootConsoleCommand(const char *cmdname, const CCommand &co
if (cmd.type == Cmd_Server) if (cmd.type == Cmd_Server)
{ {
type = "server"; type = "server";
} else if (cmd.type == Cmd_Console) { }
else if (cmd.type == Cmd_Console)
{
type = "console"; type = "console";
} else if (cmd.type == Cmd_Admin) { }
else if (cmd.type == Cmd_Admin)
{
type = "admin"; type = "admin";
} }
name = cmd.pInfo->pCmd->GetName(); name = cmd.pInfo->pCmd->GetName();
if (cmd.pHook->helptext.size()) if (cmd.pHook->helptext.size())
{ {
help = cmd.pHook->helptext.c_str(); help = cmd.pHook->helptext.c_str();
} else { }
else
{
help = cmd.pInfo->pCmd->GetHelpText(); help = cmd.pInfo->pCmd->GetHelpText();
} }
g_RootMenu.ConsolePrint(" %-17.16s %-12.11s %s", name, type, help); g_RootMenu.ConsolePrint(" %-17.16s %-12.11s %s", name, type, help);

View File

@ -41,6 +41,7 @@
#include <sh_string.h> #include <sh_string.h>
#include <IRootConsoleMenu.h> #include <IRootConsoleMenu.h>
#include <IAdminSystem.h> #include <IAdminSystem.h>
#include "concmd_cleaner.h"
using namespace SourceHook; using namespace SourceHook;
@ -94,7 +95,8 @@ struct ConCmdInfo
class ConCmdManager : class ConCmdManager :
public SMGlobalClass, public SMGlobalClass,
public IRootConsoleCommand, public IRootConsoleCommand,
public IPluginsListener public IPluginsListener,
public IConCommandTracker
{ {
#if defined ORANGEBOX_BUILD #if defined ORANGEBOX_BUILD
friend void CommandCallback(const CCommand &command); friend void CommandCallback(const CCommand &command);
@ -111,6 +113,8 @@ public: //IPluginsListener
void OnPluginDestroyed(IPlugin *plugin); void OnPluginDestroyed(IPlugin *plugin);
public: //IRootConsoleCommand public: //IRootConsoleCommand
void OnRootConsoleCommand(const char *cmdname, const CCommand &command); void OnRootConsoleCommand(const char *cmdname, const CCommand &command);
public: //IConCommandTracker
void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe);
public: public:
bool AddServerCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags); bool AddServerCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags);
bool AddConsoleCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags); bool AddConsoleCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags);
@ -131,7 +135,8 @@ private:
ConCmdInfo *AddOrFindCommand(const char *name, const char *description, int flags); ConCmdInfo *AddOrFindCommand(const char *name, const char *description, int flags);
void SetCommandClient(int client); void SetCommandClient(int client);
void AddToCmdList(ConCmdInfo *info); void AddToCmdList(ConCmdInfo *info);
void RemoveConCmd(ConCmdInfo *info); void RemoveConCmd(ConCmdInfo *info, const char *cmd, bool is_read_safe, bool untrack);
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);
public: public:

View File

@ -99,7 +99,7 @@ public:
{ {
pInfo = (*iter); pInfo = (*iter);
iter = tracked_bases.erase(iter); iter = tracked_bases.erase(iter);
pInfo->cls->OnUnlinkConCommandBase(pBase, pInfo->name, true); pInfo->cls->OnUnlinkConCommandBase(pBase, pInfo->name, false);
delete pInfo; delete pInfo;
} }
else else

View File

@ -29,6 +29,9 @@
* Version: $Id$ * Version: $Id$
*/ */
#ifndef _INCLUDE_CONCMD_TRACKER_H_
#define _INCLUDE_CONCMD_TRACKER_H_
class IConCommandTracker class IConCommandTracker
{ {
public: public:
@ -39,3 +42,4 @@ void TrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me);
void UntrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me); void UntrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me);
void Global_OnUnlinkConCommandBase(ConCommandBase *pBase); void Global_OnUnlinkConCommandBase(ConCommandBase *pBase);
#endif //_INCLUDE_CONCMD_TRACKER_H_