Clean up ConCmdManager (bug 5900, r=fyren).
This commit is contained in:
parent
435f2b8e39
commit
ba927964c8
@ -50,15 +50,8 @@ ConCmdManager g_ConCmds;
|
||||
|
||||
SH_DECL_HOOK1_void(IServerGameClients, SetCommandClient, SH_NOATTRIB, false, int);
|
||||
|
||||
struct PlCmdInfo
|
||||
{
|
||||
ConCmdInfo *pInfo;
|
||||
CmdHook *pHook;
|
||||
CmdType type;
|
||||
};
|
||||
typedef List<PlCmdInfo> CmdList;
|
||||
|
||||
void AddToPlCmdList(CmdList *pList, const PlCmdInfo &info);
|
||||
typedef ke::LinkedList<CmdHook *> PluginHookList;
|
||||
void RegisterInPlugin(CmdHook *hook);
|
||||
|
||||
ConCmdManager::ConCmdManager() : m_Strings(1024)
|
||||
{
|
||||
@ -92,116 +85,56 @@ void ConCmdManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *na
|
||||
if (!m_Cmds.retrieve(name, &pInfo))
|
||||
return;
|
||||
|
||||
RemoveConCmds(pInfo->srvhooks);
|
||||
RemoveConCmds(pInfo->conhooks);
|
||||
CmdHookList::iterator iter = pInfo->hooks.begin();
|
||||
while (iter != pInfo->hooks.end())
|
||||
{
|
||||
CmdHook *hook = *iter;
|
||||
|
||||
IPluginContext *pContext = hook->pf->GetParentContext();
|
||||
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
|
||||
|
||||
// The list is guaranteed to exist.
|
||||
PluginHookList *list;
|
||||
pPlugin->GetProperty("CommandList", (void **)&list, false);
|
||||
for (PluginHookList::iterator hiter = list->begin(); hiter != list->end(); hiter++)
|
||||
{
|
||||
if (*hiter == hook)
|
||||
{
|
||||
list->erase(hiter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
iter = pInfo->hooks.erase(iter);
|
||||
delete hook;
|
||||
}
|
||||
|
||||
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 = scripts->FindPluginByContext(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)
|
||||
{
|
||||
List<CmdHook *>::iterator iter = cmdlist.begin();
|
||||
CmdHook *pHook;
|
||||
|
||||
while (iter != cmdlist.end())
|
||||
{
|
||||
pHook = (*iter);
|
||||
if (pHook->pf->GetParentContext() == pContext)
|
||||
{
|
||||
delete pHook->pAdmin;
|
||||
delete pHook;
|
||||
iter = cmdlist.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConCmdManager::OnPluginDestroyed(IPlugin *plugin)
|
||||
{
|
||||
CmdList *pList;
|
||||
List<ConCmdInfo *> removed;
|
||||
if (plugin->GetProperty("CommandList", (void **)&pList, true))
|
||||
{
|
||||
IPluginContext *pContext = plugin->GetBaseContext();
|
||||
CmdList::iterator iter;
|
||||
/* First pass!
|
||||
* Only bother if there's an actual command list on this plugin...
|
||||
*/
|
||||
for (iter=pList->begin();
|
||||
iter!=pList->end();
|
||||
iter++)
|
||||
{
|
||||
PlCmdInfo &cmd = (*iter);
|
||||
ConCmdInfo *pInfo = cmd.pInfo;
|
||||
PluginHookList *pList;
|
||||
if (!plugin->GetProperty("CommandList", (void **)&pList, true))
|
||||
return;
|
||||
|
||||
/* Has this chain already been fully cleaned/removed? */
|
||||
if (removed.find(pInfo) != removed.end())
|
||||
PluginHookList::iterator iter = pList->begin();
|
||||
while (iter != pList->end())
|
||||
{
|
||||
continue;
|
||||
CmdHook *hook = *iter;
|
||||
|
||||
hook->info->hooks.remove(hook);
|
||||
|
||||
if (hook->info->hooks.empty())
|
||||
RemoveConCmd(hook->info, hook->info->pCmd->GetName(), true, true);
|
||||
|
||||
iter = pList->erase(iter);
|
||||
delete hook;
|
||||
}
|
||||
|
||||
/* Remove any hooks from us on this command */
|
||||
RemoveConCmds(pInfo->conhooks, pContext);
|
||||
RemoveConCmds(pInfo->srvhooks, pContext);
|
||||
|
||||
/* See if there are still hooks */
|
||||
if (pInfo->srvhooks.size())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (pInfo->conhooks.size())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Remove the command, it should be safe now */
|
||||
RemoveConCmd(pInfo, pInfo->pCmd->GetName(), true, true);
|
||||
removed.push_back(pInfo);
|
||||
}
|
||||
delete pList;
|
||||
}
|
||||
}
|
||||
|
||||
#if SOURCE_ENGINE == SE_DOTA
|
||||
void CommandCallback(const CCommandContext &context, const CCommand &command)
|
||||
{
|
||||
@ -261,44 +194,34 @@ ResultType ConCmdManager::DispatchClientCommand(int client, const char *cmd, int
|
||||
}
|
||||
|
||||
cell_t result = type;
|
||||
cell_t tempres = result;
|
||||
List<CmdHook *>::iterator iter;
|
||||
CmdHook *pHook;
|
||||
for (iter=pInfo->conhooks.begin();
|
||||
iter!=pInfo->conhooks.end();
|
||||
iter++)
|
||||
{
|
||||
pHook = (*iter);
|
||||
if (!pHook->pf->IsRunnable())
|
||||
for (CmdHookList::iterator iter = pInfo->hooks.begin(); iter != pInfo->hooks.end(); iter++)
|
||||
{
|
||||
CmdHook *hook = *iter;
|
||||
|
||||
if (hook->type == CmdHook::Server || !hook->pf->IsRunnable())
|
||||
continue;
|
||||
}
|
||||
if (pHook->pAdmin && !CheckAccess(client, cmd, pHook->pAdmin))
|
||||
|
||||
if (hook->admin && !CheckAccess(client, cmd, hook->admin))
|
||||
{
|
||||
if (result < Pl_Handled)
|
||||
{
|
||||
result = Pl_Handled;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
pHook->pf->PushCell(client);
|
||||
pHook->pf->PushCell(args);
|
||||
if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE)
|
||||
|
||||
hook->pf->PushCell(client);
|
||||
hook->pf->PushCell(args);
|
||||
|
||||
cell_t tempres = result;
|
||||
if (hook->pf->Execute(&tempres) == SP_ERROR_NONE)
|
||||
{
|
||||
if (tempres > result)
|
||||
{
|
||||
result = tempres;
|
||||
}
|
||||
if (result == Pl_Stop)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type = (ResultType)result;
|
||||
|
||||
return type;
|
||||
return (ResultType)result;
|
||||
}
|
||||
|
||||
void ConCmdManager::InternalDispatch(const CCommand &command)
|
||||
@ -309,10 +232,8 @@ void ConCmdManager::InternalDispatch(const CCommand &command)
|
||||
{
|
||||
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
|
||||
if (!pPlayer || !pPlayer->IsConnected())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: Console commands will EITHER go through IServerGameDLL::ClientCommand,
|
||||
@ -343,109 +264,61 @@ void ConCmdManager::InternalDispatch(const CCommand &command)
|
||||
* "nicer" when we expose explicit say hooks.
|
||||
*/
|
||||
if (g_ChatTriggers.WasFloodedMessage())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cell_t result = Pl_Continue;
|
||||
int args = command.ArgC() - 1;
|
||||
|
||||
List<CmdHook *>::iterator iter;
|
||||
CmdHook *pHook;
|
||||
// On a listen server, sometimes the server host's client index can be set
|
||||
// as 0. So index 1 is passed to the command callback to correct this
|
||||
// potential problem.
|
||||
int realClient = (!engine->IsDedicatedServer() && client == 0)
|
||||
? g_Players.ListenClient()
|
||||
: client;
|
||||
int dedicatedClient = engine->IsDedicatedServer() ? 0 : g_Players.ListenClient();
|
||||
|
||||
/* Execute server-only commands if viable */
|
||||
if (client == 0 && pInfo->srvhooks.size())
|
||||
{
|
||||
cell_t tempres = result;
|
||||
for (iter=pInfo->srvhooks.begin();
|
||||
iter!=pInfo->srvhooks.end();
|
||||
iter++)
|
||||
{
|
||||
pHook = (*iter);
|
||||
if (!pHook->pf->IsRunnable())
|
||||
for (CmdHookList::iterator iter = pInfo->hooks.begin(); iter != pInfo->hooks.end(); iter++)
|
||||
{
|
||||
CmdHook *hook = *iter;
|
||||
|
||||
if (!hook->pf->IsRunnable())
|
||||
continue;
|
||||
}
|
||||
pHook->pf->PushCell(args);
|
||||
if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE)
|
||||
{
|
||||
if (tempres > result)
|
||||
{
|
||||
result = tempres;
|
||||
}
|
||||
if (result == Pl_Stop)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if there's an early stop */
|
||||
if (result >= Pl_Stop)
|
||||
{
|
||||
if (!pInfo->sourceMod)
|
||||
{
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Execute console commands */
|
||||
if (pInfo->conhooks.size())
|
||||
{
|
||||
cell_t tempres = result;
|
||||
for (iter=pInfo->conhooks.begin();
|
||||
iter!=pInfo->conhooks.end();
|
||||
iter++)
|
||||
{
|
||||
pHook = (*iter);
|
||||
if (!pHook->pf->IsRunnable())
|
||||
if (hook->type == CmdHook::Server)
|
||||
{
|
||||
// Don't execute unless we're in the server console.
|
||||
if (realClient != dedicatedClient)
|
||||
continue;
|
||||
}
|
||||
if (client
|
||||
&& pHook->pAdmin
|
||||
&& !CheckAccess(client, cmd, pHook->pAdmin))
|
||||
} else {
|
||||
// Check admin rights if needed. realClient isn't needed since we
|
||||
// should bypass admin checks if client == 0 anyway.
|
||||
if (client && hook->admin && !CheckAccess(client, cmd, hook->admin))
|
||||
{
|
||||
if (result < Pl_Handled)
|
||||
{
|
||||
result = Pl_Handled;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* On a listen server, sometimes the server host's client index can be set as 0.
|
||||
* So index 1 is passed to the command callback to correct this potential problem.
|
||||
*/
|
||||
if (!engine->IsDedicatedServer())
|
||||
{
|
||||
client = g_Players.ListenClient();
|
||||
// Client hooks get a client argument.
|
||||
hook->pf->PushCell(realClient);
|
||||
}
|
||||
|
||||
pHook->pf->PushCell(client);
|
||||
pHook->pf->PushCell(args);
|
||||
hook->pf->PushCell(args);
|
||||
|
||||
if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE)
|
||||
cell_t tempres = result;
|
||||
if (hook->pf->Execute(&tempres) == SP_ERROR_NONE)
|
||||
{
|
||||
if (tempres > result)
|
||||
{
|
||||
result = tempres;
|
||||
}
|
||||
if (result == Pl_Stop)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result >= Pl_Handled)
|
||||
{
|
||||
if (!pInfo->sourceMod)
|
||||
{
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -575,19 +448,11 @@ bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
|
||||
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags);
|
||||
|
||||
if (!pInfo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CmdHook *pHook = new CmdHook();
|
||||
AdminCmdInfo *pAdmin = new AdminCmdInfo();
|
||||
CmdHook *pHook = new CmdHook(CmdHook::Client, pInfo, pFunction, description);
|
||||
|
||||
pHook->pf = pFunction;
|
||||
if (description && description[0])
|
||||
{
|
||||
pHook->helptext.assign(description);
|
||||
}
|
||||
pHook->pAdmin = pAdmin;
|
||||
pHook->admin = new AdminCmdInfo();
|
||||
|
||||
int grpid;
|
||||
if (!m_CmdGrps.retrieve(group, &grpid))
|
||||
@ -596,46 +461,29 @@ bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
|
||||
m_CmdGrps.insert(group, grpid);
|
||||
}
|
||||
|
||||
pAdmin->cmdGrpId = grpid;
|
||||
pAdmin->flags = adminflags;
|
||||
pHook->admin->cmdGrpId = grpid;
|
||||
pHook->admin->flags = adminflags;
|
||||
|
||||
/* First get the command group override, if any */
|
||||
bool override = g_Admins.GetCommandOverride(group,
|
||||
Override_CommandGroup,
|
||||
&(pAdmin->eflags));
|
||||
&(pHook->admin->eflags));
|
||||
|
||||
/* Next get the command override, if any */
|
||||
if (g_Admins.GetCommandOverride(name,
|
||||
Override_Command,
|
||||
&(pAdmin->eflags)))
|
||||
&(pHook->admin->eflags)))
|
||||
{
|
||||
override = true;
|
||||
}
|
||||
|
||||
/* Assign normal flags if there were no overrides */
|
||||
if (!override)
|
||||
{
|
||||
pAdmin->eflags = pAdmin->flags;
|
||||
}
|
||||
|
||||
/* Finally, add the hook */
|
||||
pInfo->conhooks.push_back(pHook);
|
||||
pInfo->admin = *(pHook->pAdmin);
|
||||
|
||||
/* Now add to the plugin */
|
||||
CmdList *pList;
|
||||
IPlugin *pPlugin = scripts->FindPluginByContext(pFunction->GetParentContext()->GetContext());
|
||||
if (!pPlugin->GetProperty("CommandList", (void **)&pList))
|
||||
{
|
||||
pList = new CmdList();
|
||||
pPlugin->SetProperty("CommandList", pList);
|
||||
}
|
||||
PlCmdInfo info;
|
||||
info.pInfo = pInfo;
|
||||
info.type = Cmd_Admin;
|
||||
info.pHook = pHook;
|
||||
AddToPlCmdList(pList, info);
|
||||
pHook->admin->eflags = pHook->admin->flags;
|
||||
pInfo->eflags = pHook->admin->eflags;
|
||||
|
||||
pInfo->hooks.append(pHook);
|
||||
RegisterInPlugin(pHook);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -648,63 +496,42 @@ bool ConCmdManager::AddServerCommand(IPluginFunction *pFunction,
|
||||
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags);
|
||||
|
||||
if (!pInfo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CmdHook *pHook = new CmdHook();
|
||||
|
||||
pHook->pf = pFunction;
|
||||
if (description && description[0])
|
||||
{
|
||||
pHook->helptext.assign(description);
|
||||
}
|
||||
|
||||
pInfo->srvhooks.push_back(pHook);
|
||||
|
||||
/* Add to the plugin */
|
||||
CmdList *pList;
|
||||
IPlugin *pPlugin = scripts->FindPluginByContext(pFunction->GetParentContext()->GetContext());
|
||||
if (!pPlugin->GetProperty("CommandList", (void **)&pList))
|
||||
{
|
||||
pList = new CmdList();
|
||||
pPlugin->SetProperty("CommandList", pList);
|
||||
}
|
||||
PlCmdInfo info;
|
||||
info.pInfo = pInfo;
|
||||
info.type = Cmd_Server;
|
||||
info.pHook = pHook;
|
||||
AddToPlCmdList(pList, info);
|
||||
CmdHook *pHook = new CmdHook(CmdHook::Server, pInfo, pFunction, description);
|
||||
|
||||
pInfo->hooks.append(pHook);
|
||||
RegisterInPlugin(pHook);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddToPlCmdList(CmdList *pList, const PlCmdInfo &info)
|
||||
void RegisterInPlugin(CmdHook *hook)
|
||||
{
|
||||
CmdList::iterator iter = pList->begin();
|
||||
bool inserted = false;
|
||||
const char *orig = NULL;
|
||||
PluginHookList *pList;
|
||||
|
||||
orig = info.pInfo->pCmd->GetName();
|
||||
IPlugin *pPlugin = scripts->FindPluginByContext(hook->pf->GetParentContext());
|
||||
if (!pPlugin->GetProperty("CommandList", (void **)&pList))
|
||||
{
|
||||
pList = new PluginHookList();
|
||||
pPlugin->SetProperty("CommandList", pList);
|
||||
}
|
||||
|
||||
const char *orig = hook->info->pCmd->GetName();
|
||||
|
||||
/* Insert this into the help list, SORTED alphabetically. */
|
||||
PluginHookList::iterator iter = pList->begin();
|
||||
while (iter != pList->end())
|
||||
{
|
||||
PlCmdInfo &obj = (*iter);
|
||||
const char *cmd = obj.pInfo->pCmd->GetName();
|
||||
const char *cmd = (*iter)->info->pCmd->GetName();
|
||||
if (strcmp(orig, cmd) < 0)
|
||||
{
|
||||
pList->insert(iter, info);
|
||||
inserted = true;
|
||||
break;
|
||||
pList->insertBefore(iter, hook);
|
||||
return;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
|
||||
if (!inserted)
|
||||
{
|
||||
pList->push_back(info);
|
||||
}
|
||||
pList->append(hook);
|
||||
}
|
||||
|
||||
void ConCmdManager::AddToCmdList(ConCmdInfo *info)
|
||||
@ -739,29 +566,22 @@ void ConCmdManager::AddToCmdList(ConCmdInfo *info)
|
||||
|
||||
void ConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits, bool remove)
|
||||
{
|
||||
ConCmdInfo *pInfo;
|
||||
|
||||
if (type == Override_Command)
|
||||
{
|
||||
ConCmdInfo *pInfo;
|
||||
if (!m_Cmds.retrieve(cmd, &pInfo))
|
||||
return;
|
||||
|
||||
List<CmdHook *>::iterator iter;
|
||||
CmdHook *pHook;
|
||||
for (CmdHookList::iterator iter = pInfo->hooks.begin(); iter != pInfo->hooks.end(); iter++)
|
||||
{
|
||||
if (!iter->admin)
|
||||
continue;
|
||||
|
||||
for (iter=pInfo->conhooks.begin(); iter!=pInfo->conhooks.end(); iter++)
|
||||
{
|
||||
pHook = (*iter);
|
||||
if (pHook->pAdmin)
|
||||
{
|
||||
if (!remove)
|
||||
{
|
||||
pHook->pAdmin->eflags = bits;
|
||||
} else {
|
||||
pHook->pAdmin->eflags = pHook->pAdmin->flags;
|
||||
}
|
||||
pInfo->admin = *(pHook->pAdmin);
|
||||
}
|
||||
iter->admin->eflags = bits;
|
||||
else
|
||||
iter->admin->eflags = iter->admin->flags;
|
||||
pInfo->eflags = iter->admin->eflags;
|
||||
}
|
||||
}
|
||||
else if (type == Override_CommandGroup)
|
||||
@ -772,25 +592,20 @@ void ConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, Flag
|
||||
|
||||
/* This is bad :( loop through all commands */
|
||||
List<ConCmdInfo *>::iterator iter;
|
||||
CmdHook *pHook;
|
||||
for (iter=m_CmdList.begin(); iter!=m_CmdList.end(); iter++)
|
||||
{
|
||||
pInfo = (*iter);
|
||||
for (List<CmdHook *>::iterator citer=pInfo->conhooks.begin();
|
||||
citer!=pInfo->conhooks.end();
|
||||
citer++)
|
||||
{
|
||||
pHook = (*citer);
|
||||
if (pHook->pAdmin && pHook->pAdmin->cmdGrpId == grpid)
|
||||
ConCmdInfo *pInfo = *iter;
|
||||
for (CmdHookList::iterator citer = pInfo->hooks.begin(); citer != pInfo->hooks.end(); citer++)
|
||||
{
|
||||
CmdHook *hook = (*citer);
|
||||
if (!hook->admin || hook->admin->cmdGrpId != grpid)
|
||||
continue;
|
||||
|
||||
if (remove)
|
||||
{
|
||||
pHook->pAdmin->eflags = bits;
|
||||
} else {
|
||||
pHook->pAdmin->eflags = pHook->pAdmin->flags;
|
||||
}
|
||||
pInfo->admin = *(pHook->pAdmin);
|
||||
}
|
||||
hook->admin->eflags = bits;
|
||||
else
|
||||
hook->admin->eflags = hook->admin->flags;
|
||||
pInfo->eflags = hook->admin->eflags;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -843,7 +658,7 @@ bool ConCmdManager::LookForSourceModCommand(const char *cmd)
|
||||
if (!m_Cmds.retrieve(cmd, &pInfo))
|
||||
return false;
|
||||
|
||||
return pInfo->sourceMod && (pInfo->conhooks.size() > 0);
|
||||
return pInfo->sourceMod && !pInfo->hooks.empty();
|
||||
}
|
||||
|
||||
bool ConCmdManager::LookForCommandAdminFlags(const char *cmd, FlagBits *pFlags)
|
||||
@ -852,7 +667,7 @@ bool ConCmdManager::LookForCommandAdminFlags(const char *cmd, FlagBits *pFlags)
|
||||
if (!m_Cmds.retrieve(cmd, &pInfo))
|
||||
return false;
|
||||
|
||||
*pFlags = pInfo->admin.eflags;
|
||||
*pFlags = pInfo->eflags;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -915,46 +730,36 @@ void ConCmdManager::OnRootConsoleCommand(const char *cmdname, const CCommand &co
|
||||
const sm_plugininfo_t *plinfo = pPlugin->GetPublicInfo();
|
||||
const char *plname = IS_STR_FILLED(plinfo->name) ? plinfo->name : pPlugin->GetFilename();
|
||||
|
||||
CmdList *pList;
|
||||
PluginHookList *pList;
|
||||
if (!pPlugin->GetProperty("CommandList", (void **)&pList))
|
||||
{
|
||||
g_RootMenu.ConsolePrint("[SM] No commands found for: %s", plname);
|
||||
return;
|
||||
}
|
||||
if (!pList->size())
|
||||
if (pList->empty())
|
||||
{
|
||||
g_RootMenu.ConsolePrint("[SM] No commands found for: %s", plname);
|
||||
return;
|
||||
}
|
||||
|
||||
CmdList::iterator iter;
|
||||
const char *type = NULL;
|
||||
const char *name;
|
||||
const char *help;
|
||||
g_RootMenu.ConsolePrint("[SM] Listing %d commands for: %s", pList->size(), plname);
|
||||
g_RootMenu.ConsolePrint("[SM] Listing commands for: %s", plname);
|
||||
g_RootMenu.ConsolePrint(" %-17.16s %-8.7s %s", "[Name]", "[Type]", "[Help]");
|
||||
for (iter=pList->begin();
|
||||
iter!=pList->end();
|
||||
iter++)
|
||||
{
|
||||
PlCmdInfo &cmd = (*iter);
|
||||
if (cmd.type == Cmd_Server)
|
||||
for (PluginHookList::iterator iter = pList->begin(); iter != pList->end(); iter++)
|
||||
{
|
||||
CmdHook *hook = *iter;
|
||||
if (hook->type == CmdHook::Server)
|
||||
type = "server";
|
||||
}
|
||||
else if (cmd.type == Cmd_Admin)
|
||||
{
|
||||
type = (cmd.pInfo->admin.eflags == 0)?"console":"admin";
|
||||
}
|
||||
name = cmd.pInfo->pCmd->GetName();
|
||||
if (cmd.pHook->helptext.size())
|
||||
{
|
||||
help = cmd.pHook->helptext.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
help = cmd.pInfo->pCmd->GetHelpText();
|
||||
}
|
||||
type = hook->info->eflags == 0 ? "console" : "admin";
|
||||
|
||||
name = hook->info->pCmd->GetName();
|
||||
if (hook->helptext.length())
|
||||
help = hook->helptext.chars();
|
||||
else
|
||||
help = hook->info->pCmd->GetHelpText();
|
||||
g_RootMenu.ConsolePrint(" %-17.16s %-12.11s %s", name, type, help);
|
||||
}
|
||||
|
||||
|
@ -43,15 +43,11 @@
|
||||
#include "concmd_cleaner.h"
|
||||
#include <sm_stringhashmap.h>
|
||||
#include <am-utility.h>
|
||||
#include <am-inlinelist.h>
|
||||
#include <am-linkedlist.h>
|
||||
|
||||
using namespace SourceHook;
|
||||
|
||||
enum CmdType
|
||||
{
|
||||
Cmd_Server,
|
||||
Cmd_Admin,
|
||||
};
|
||||
|
||||
struct AdminCmdInfo
|
||||
{
|
||||
AdminCmdInfo()
|
||||
@ -65,30 +61,44 @@ struct AdminCmdInfo
|
||||
FlagBits eflags; /* effective flags */
|
||||
};
|
||||
|
||||
struct CmdHook
|
||||
struct ConCmdInfo;
|
||||
|
||||
struct CmdHook : public ke::InlineListNode<CmdHook>
|
||||
{
|
||||
CmdHook()
|
||||
enum Type {
|
||||
Server,
|
||||
Client
|
||||
};
|
||||
|
||||
CmdHook(Type type, ConCmdInfo *cmd, IPluginFunction *fun, const char *description)
|
||||
: type(type),
|
||||
info(cmd),
|
||||
pf(fun),
|
||||
helptext(description)
|
||||
{
|
||||
pf = NULL;
|
||||
pAdmin = NULL;
|
||||
}
|
||||
|
||||
Type type;
|
||||
ConCmdInfo *info;
|
||||
IPluginFunction *pf; /* function hook */
|
||||
String helptext; /* help text */
|
||||
AdminCmdInfo *pAdmin; /* admin requirements, if any */
|
||||
ke::AString helptext; /* help text */
|
||||
ke::AutoPtr<AdminCmdInfo> admin; /* admin requirements, if any */
|
||||
};
|
||||
|
||||
typedef ke::InlineList<CmdHook> CmdHookList;
|
||||
|
||||
struct ConCmdInfo
|
||||
{
|
||||
ConCmdInfo()
|
||||
{
|
||||
sourceMod = false;
|
||||
pCmd = NULL;
|
||||
eflags = 0;
|
||||
}
|
||||
bool sourceMod; /**< Determines whether or not concmd was created by a SourceMod plugin */
|
||||
ConCommand *pCmd; /**< Pointer to the command itself */
|
||||
List<CmdHook *> srvhooks; /**< Hooks as a server command */
|
||||
List<CmdHook *> conhooks; /**< Hooks as a console command */
|
||||
AdminCmdInfo admin; /**< Admin info, if any */
|
||||
CmdHookList hooks; /**< Hook list */
|
||||
FlagBits eflags; /**< Effective admin flags */
|
||||
};
|
||||
|
||||
typedef List<ConCmdInfo *> ConCmdList;
|
||||
@ -139,8 +149,6 @@ private:
|
||||
void SetCommandClient(int client);
|
||||
void AddToCmdList(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);
|
||||
bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin);
|
||||
|
||||
// Case insensitive
|
||||
|
@ -1278,7 +1278,7 @@ static cell_t ReadCommandIterator(IPluginContext *pContext, const cell_t *params
|
||||
|
||||
cell_t *addr;
|
||||
pContext->LocalToPhysAddr(params[4], &addr);
|
||||
*addr = pInfo->admin.eflags;
|
||||
*addr = pInfo->eflags;
|
||||
|
||||
iter->iter++;
|
||||
|
||||
|
@ -140,6 +140,22 @@ class InlineList
|
||||
return iterator(&head_);
|
||||
}
|
||||
|
||||
iterator erase(iterator &at) {
|
||||
iterator next = at;
|
||||
next++;
|
||||
|
||||
remove(at.iter_);
|
||||
|
||||
// Iterator is no longer valid.
|
||||
at.iter_ = NULL;
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return head_.next_ == &head_;
|
||||
}
|
||||
|
||||
void remove(Node *t) {
|
||||
t->prev_->next_ = t->next_;
|
||||
t->next_->prev_ = t->prev_;
|
||||
|
Loading…
Reference in New Issue
Block a user