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)
{
return true;
@ -321,7 +320,9 @@ bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmi
}
CPlayer *player = g_Players.GetPlayerByIndex(client);
if (!player)
if (!player
|| player->GetEdict() == NULL
|| player->IsFakeClient())
{
return false;
}
@ -370,11 +371,17 @@ bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmi
}
}
if (player->IsFakeClient()
|| player->GetEdict() == NULL)
return false;
}
bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin)
{
if (CheckCommandAccess(client, cmd, pAdmin->eflags))
{
return false;
return true;
}
edict_t *pEdict = engine->PEntityOfEntIndex(client);
/* If we got here, the command failed... */
char buffer[128];
@ -389,7 +396,7 @@ bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmi
{
char fullbuffer[192];
snprintf(fullbuffer, sizeof(fullbuffer), "[SM] %s.\n", buffer);
engine->ClientPrintf(player->GetEdict(), fullbuffer);
engine->ClientPrintf(pEdict, fullbuffer);
} else if (replyto == SM_REPLY_CHAT) {
char fullbuffer[192];
snprintf(fullbuffer, sizeof(fullbuffer), "[SM] %s.", buffer);
@ -495,6 +502,7 @@ bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
/* Finally, add the hook */
pInfo->conhooks.push_back(pHook);
pInfo->admin = *(pHook->pAdmin);
/* Now add to the plugin */
CmdList *pList;
@ -636,6 +644,7 @@ void ConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, Flag
} else {
pHook->pAdmin->eflags = pHook->pAdmin->flags;
}
pInfo->admin = *(pHook->pAdmin);
}
}
} else if (type == Override_CommandGroup) {
@ -665,6 +674,7 @@ void ConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, Flag
} else {
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 */
List<CmdHook *> srvhooks; /**< Hooks as a server command */
List<CmdHook *> conhooks; /**< Hooks as a console command */
AdminCmdInfo admin; /**< Admin info, if any */
};
class ConCmdManager :
@ -100,6 +101,7 @@ public:
ResultType DispatchClientCommand(int client, ResultType type);
void UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits);
bool LookForSourceModCommand(const char *cmd);
bool CheckCommandAccess(int client, const char *cmd, FlagBits flags);
private:
void InternalDispatch();
ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args);
@ -114,6 +116,10 @@ public:
{
return m_CmdClient;
}
inline const List<ConCmdInfo *> & GetCommandList()
{
return m_CmdList;
}
private:
Trie *m_pCmds; /* command lookup */
Trie *m_pCmdGrps; /* command group lookup */

View File

@ -33,6 +33,34 @@ enum ConVarBounds
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)
{
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]);
}
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)
{
{"CreateConVar", sm_CreateConVar},
@ -839,5 +939,8 @@ REGISTER_NATIVES(consoleNatives)
{"ReplyToCommand", ReplyToCommand},
{"GetCmdReplySource", GetCmdReplyTarget},
{"SetCmdReplySource", SetCmdReplyTarget},
{"GetCommandIterator", GetCommandIterator},
{"ReadCommandIterator", ReadCommandIterator},
{"CheckCommandAccess", CheckCommandAccess},
{NULL, NULL}
};

View File

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

View File

@ -571,3 +571,40 @@ funcenum ConVarQueryFinished
* Returns QUERYCOOKIE_FAILED on failure, such as when used on a bot.
*/
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);