added api to walk cmd list

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401125
This commit is contained in:
David Anderson 2007-07-15 18:51:25 +00:00
parent d8ca563305
commit d218f638b1
5 changed files with 164 additions and 8 deletions

View File

@ -306,9 +306,8 @@ void ConCmdManager::InternalDispatch()
} }
} }
bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin) bool ConCmdManager::CheckCommandAccess(int client, const char *cmd, FlagBits cmdflags)
{ {
FlagBits cmdflags = pAdmin->eflags;
if (cmdflags == 0) if (cmdflags == 0)
{ {
return true; return true;
@ -321,7 +320,9 @@ bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmi
} }
CPlayer *player = g_Players.GetPlayerByIndex(client); CPlayer *player = g_Players.GetPlayerByIndex(client);
if (!player) if (!player
|| player->GetEdict() == NULL
|| player->IsFakeClient())
{ {
return false; return false;
} }
@ -370,12 +371,18 @@ bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmi
} }
} }
if (player->IsFakeClient()
|| player->GetEdict() == NULL)
{
return false; return false;
} }
bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin)
{
if (CheckCommandAccess(client, cmd, pAdmin->eflags))
{
return true;
}
edict_t *pEdict = engine->PEntityOfEntIndex(client);
/* If we got here, the command failed... */ /* If we got here, the command failed... */
char buffer[128]; char buffer[128];
if (g_Translator.CoreTrans(client, buffer, sizeof(buffer), "No Access", NULL, NULL) if (g_Translator.CoreTrans(client, buffer, sizeof(buffer), "No Access", NULL, NULL)
@ -389,7 +396,7 @@ bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmi
{ {
char fullbuffer[192]; char fullbuffer[192];
snprintf(fullbuffer, sizeof(fullbuffer), "[SM] %s.\n", buffer); snprintf(fullbuffer, sizeof(fullbuffer), "[SM] %s.\n", buffer);
engine->ClientPrintf(player->GetEdict(), fullbuffer); engine->ClientPrintf(pEdict, fullbuffer);
} else if (replyto == SM_REPLY_CHAT) { } else if (replyto == SM_REPLY_CHAT) {
char fullbuffer[192]; char fullbuffer[192];
snprintf(fullbuffer, sizeof(fullbuffer), "[SM] %s.", buffer); snprintf(fullbuffer, sizeof(fullbuffer), "[SM] %s.", buffer);
@ -495,6 +502,7 @@ bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
/* Finally, add the hook */ /* Finally, add the hook */
pInfo->conhooks.push_back(pHook); pInfo->conhooks.push_back(pHook);
pInfo->admin = *(pHook->pAdmin);
/* Now add to the plugin */ /* Now add to the plugin */
CmdList *pList; CmdList *pList;
@ -636,6 +644,7 @@ void ConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, Flag
} else { } else {
pHook->pAdmin->eflags = pHook->pAdmin->flags; pHook->pAdmin->eflags = pHook->pAdmin->flags;
} }
pInfo->admin = *(pHook->pAdmin);
} }
} }
} else if (type == Override_CommandGroup) { } else if (type == Override_CommandGroup) {
@ -665,6 +674,7 @@ void ConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, Flag
} else { } else {
pHook->pAdmin->eflags = pHook->pAdmin->flags; pHook->pAdmin->eflags = pHook->pAdmin->flags;
} }
pInfo->admin = *(pHook->pAdmin);
} }
} }
} }

View File

@ -70,6 +70,7 @@ struct ConCmdInfo
ConCommand *pCmd; /**< Pointer to the command itself */ ConCommand *pCmd; /**< Pointer to the command itself */
List<CmdHook *> srvhooks; /**< Hooks as a server command */ List<CmdHook *> srvhooks; /**< Hooks as a server command */
List<CmdHook *> conhooks; /**< Hooks as a console command */ List<CmdHook *> conhooks; /**< Hooks as a console command */
AdminCmdInfo admin; /**< Admin info, if any */
}; };
class ConCmdManager : class ConCmdManager :
@ -100,6 +101,7 @@ public:
ResultType DispatchClientCommand(int client, ResultType type); ResultType DispatchClientCommand(int client, ResultType type);
void UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits); void UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits);
bool LookForSourceModCommand(const char *cmd); bool LookForSourceModCommand(const char *cmd);
bool CheckCommandAccess(int client, const char *cmd, FlagBits flags);
private: private:
void InternalDispatch(); void InternalDispatch();
ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args); ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args);
@ -114,6 +116,10 @@ public:
{ {
return m_CmdClient; return m_CmdClient;
} }
inline const List<ConCmdInfo *> & GetCommandList()
{
return m_CmdList;
}
private: private:
Trie *m_pCmds; /* command lookup */ Trie *m_pCmds; /* command lookup */
Trie *m_pCmdGrps; /* command group lookup */ Trie *m_pCmdGrps; /* command group lookup */

View File

@ -33,6 +33,34 @@ enum ConVarBounds
ConVarBound_Lower ConVarBound_Lower
}; };
HandleType_t hCmdIterType = 0;
struct GlobCmdIter
{
bool started;
List<ConCmdInfo *>::iterator iter;
};
class ConsoleHelpers :
public SMGlobalClass,
public IHandleTypeDispatch
{
public:
virtual void OnSourceModAllInitialized()
{
HandleAccess access;
g_HandleSys.InitAccessDefaults(NULL, &access);
access.access[HandleAccess_Clone] = HANDLE_RESTRICT_OWNER | HANDLE_RESTRICT_IDENTITY;
hCmdIterType = g_HandleSys.CreateType(NULL, this, 0, NULL, &access, g_pCoreIdent, NULL);
}
virtual void OnHandleDestroy(HandleType_t type, void *object)
{
GlobCmdIter *iter = (GlobCmdIter *)object;
delete iter;
}
} s_ConsoleHelpers;
static void ReplicateConVar(ConVar *pConVar) static void ReplicateConVar(ConVar *pConVar)
{ {
int maxClients = g_Players.GetMaxClients(); int maxClients = g_Players.GetMaxClients();
@ -802,6 +830,78 @@ static cell_t SetCmdReplyTarget(IPluginContext *pContext, const cell_t *params)
return g_ChatTriggers.SetReplyTo(params[1]); return g_ChatTriggers.SetReplyTo(params[1]);
} }
static cell_t GetCommandIterator(IPluginContext *pContext, const cell_t *params)
{
GlobCmdIter *iter = new GlobCmdIter;
iter->started = false;
Handle_t hndl = g_HandleSys.CreateHandle(hCmdIterType, iter, pContext->GetIdentity(), g_pCoreIdent, NULL);
if (hndl == BAD_HANDLE)
{
delete iter;
}
return hndl;
}
static cell_t ReadCommandIterator(IPluginContext *pContext, const cell_t *params)
{
GlobCmdIter *iter;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid GlobCmdIter Handle %x", params[1]);
}
const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
if (!iter->started)
{
iter->iter = cmds.begin();
iter->started = true;
}
while (iter->iter != cmds.end()
&& !(*(iter->iter))->sourceMod)
{
iter->iter++;
}
if (iter->iter == cmds.end())
{
return 0;
}
ConCmdInfo *pInfo = (*(iter->iter));
pContext->StringToLocalUTF8(params[2], params[3], pInfo->pCmd->GetName(), NULL);
pContext->StringToLocalUTF8(params[5], params[6], pInfo->pCmd->GetHelpText(), NULL);
cell_t *addr;
pContext->LocalToPhysAddr(params[4], &addr);
*addr = pInfo->admin.eflags;
iter->iter++;
return 1;
}
static cell_t CheckCommandAccess(IPluginContext *pContext, const cell_t *params)
{
if (params[1] == 0)
{
return 1;
}
char *cmd;
pContext->LocalToString(params[2], &cmd);
return g_ConCmds.CheckCommandAccess(params[1], cmd, params[3]) ? 1 : 0;
}
REGISTER_NATIVES(consoleNatives) REGISTER_NATIVES(consoleNatives)
{ {
{"CreateConVar", sm_CreateConVar}, {"CreateConVar", sm_CreateConVar},
@ -839,5 +939,8 @@ REGISTER_NATIVES(consoleNatives)
{"ReplyToCommand", ReplyToCommand}, {"ReplyToCommand", ReplyToCommand},
{"GetCmdReplySource", GetCmdReplyTarget}, {"GetCmdReplySource", GetCmdReplyTarget},
{"SetCmdReplySource", SetCmdReplyTarget}, {"SetCmdReplySource", SetCmdReplyTarget},
{"GetCommandIterator", GetCommandIterator},
{"ReadCommandIterator", ReadCommandIterator},
{"CheckCommandAccess", CheckCommandAccess},
{NULL, NULL} {NULL, NULL}
}; };

View File

@ -56,7 +56,7 @@ static const char *g_ErrorMsgTable[] =
"Heap memory leaked by native", "Heap memory leaked by native",
"Dynamic array is too big", "Dynamic array is too big",
"Tracker stack is out of bounds", "Tracker stack is out of bounds",
"Native was never bound", "Native is not bound",
"Maximum number of parameters reached", "Maximum number of parameters reached",
"Native detected error", "Native detected error",
"Plugin not runnable", "Plugin not runnable",

View File

@ -571,3 +571,40 @@ funcenum ConVarQueryFinished
* Returns QUERYCOOKIE_FAILED on failure, such as when used on a bot. * Returns QUERYCOOKIE_FAILED on failure, such as when used on a bot.
*/ */
native QueryCookie:QueryClientConVar(client, const String:cvarName[], ConVarQueryFinished:callback, any:value=0); native QueryCookie:QueryClientConVar(client, const String:cvarName[], ConVarQueryFinished:callback, any:value=0);
/**
* Gets a command iterator. Must be freed with CloseHandle().
*
* @return A new command iterator.
*/
native Handle:GetCommandIterator();
/**
* Reads a command iterator, then advances to the next command if any.
* Only SourceMod specific commands are returned.
*
* @param iter Command iterator Handle.
* @param name Name buffer.
* @param nameLen Name buffer size.
* @param eflags Effective default flags of a command.
* @param desc Command description buffer.
* @param descLen Command description buffer size.
* @return True on success, false if there are no more commands.
*/
native bool:ReadCommandIterator(Handle:iter,
String:name[],
nameLen,
&eflags=0,
String:desc[]="",
descLen=0);
/**
* Returns whether a user has access to a command. This takes into account
* the override system built into SourceMod.
*
* @param client Client index.
* @param command Command name.
* @param flags Default command flags.
* @return True if the user has access, false otherwise.
*/
native bool:CheckCommandAccess(client, const String:command[], flags);