added api to walk cmd list
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401125
This commit is contained in:
parent
d8ca563305
commit
d218f638b1
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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}
|
||||
};
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user