Add base CommandIterator implementation (#819)
* Add base CommandIterator implementation * Add check for invalid pos & finalize pr
This commit is contained in:
parent
aaac0b9eb2
commit
28f1ea82b6
@ -342,9 +342,10 @@ bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
|
|||||||
const char *group,
|
const char *group,
|
||||||
int adminflags,
|
int adminflags,
|
||||||
const char *description,
|
const char *description,
|
||||||
int flags)
|
int flags,
|
||||||
|
IPlugin *pPlugin)
|
||||||
{
|
{
|
||||||
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags);
|
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags, pPlugin);
|
||||||
|
|
||||||
if (!pInfo)
|
if (!pInfo)
|
||||||
return false;
|
return false;
|
||||||
@ -388,10 +389,11 @@ bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
|
|||||||
bool ConCmdManager::AddServerCommand(IPluginFunction *pFunction,
|
bool ConCmdManager::AddServerCommand(IPluginFunction *pFunction,
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *description,
|
const char *description,
|
||||||
int flags)
|
int flags,
|
||||||
|
IPlugin *pPlugin)
|
||||||
|
|
||||||
{
|
{
|
||||||
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags);
|
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags, pPlugin);
|
||||||
|
|
||||||
if (!pInfo)
|
if (!pInfo)
|
||||||
return false;
|
return false;
|
||||||
@ -555,7 +557,7 @@ bool ConCmdManager::LookForCommandAdminFlags(const char *cmd, FlagBits *pFlags)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *description, int flags)
|
ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *description, int flags, IPlugin *pPlugin)
|
||||||
{
|
{
|
||||||
ConCmdInfo *pInfo;
|
ConCmdInfo *pInfo;
|
||||||
if (!m_Cmds.retrieve(name, &pInfo))
|
if (!m_Cmds.retrieve(name, &pInfo))
|
||||||
@ -580,6 +582,7 @@ ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *descri
|
|||||||
char *new_name = sm_strdup(name);
|
char *new_name = sm_strdup(name);
|
||||||
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->pPlugin = pPlugin;
|
||||||
pInfo->sourceMod = true;
|
pInfo->sourceMod = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -99,8 +99,9 @@ struct ConCmdInfo
|
|||||||
{
|
{
|
||||||
ConCmdInfo()
|
ConCmdInfo()
|
||||||
{
|
{
|
||||||
|
pPlugin = nullptr;
|
||||||
sourceMod = false;
|
sourceMod = false;
|
||||||
pCmd = NULL;
|
pCmd = nullptr;
|
||||||
eflags = 0;
|
eflags = 0;
|
||||||
}
|
}
|
||||||
bool sourceMod; /**< Determines whether or not concmd was created by a SourceMod plugin */
|
bool sourceMod; /**< Determines whether or not concmd was created by a SourceMod plugin */
|
||||||
@ -108,6 +109,7 @@ struct ConCmdInfo
|
|||||||
CmdHookList hooks; /**< Hook list */
|
CmdHookList hooks; /**< Hook list */
|
||||||
FlagBits eflags; /**< Effective admin flags */
|
FlagBits eflags; /**< Effective admin flags */
|
||||||
ke::RefPtr<CommandHook> sh_hook; /**< SourceHook hook, if any. */
|
ke::RefPtr<CommandHook> sh_hook; /**< SourceHook hook, if any. */
|
||||||
|
IPlugin *pPlugin; /**< Owning plugin handle. */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef List<ConCmdInfo *> ConCmdList;
|
typedef List<ConCmdInfo *> ConCmdList;
|
||||||
@ -132,13 +134,14 @@ public: //IRootConsoleCommand
|
|||||||
public: //IConCommandTracker
|
public: //IConCommandTracker
|
||||||
void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name) override;
|
void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name) override;
|
||||||
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, IPlugin *pPlugin);
|
||||||
bool AddAdminCommand(IPluginFunction *pFunction,
|
bool AddAdminCommand(IPluginFunction *pFunction,
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *group,
|
const char *group,
|
||||||
int adminflags,
|
int adminflags,
|
||||||
const char *description,
|
const char *description,
|
||||||
int flags);
|
int flags,
|
||||||
|
IPlugin *pPlugin);
|
||||||
ResultType DispatchClientCommand(int client, const char *cmd, int args, ResultType type);
|
ResultType DispatchClientCommand(int client, const char *cmd, int args, ResultType type);
|
||||||
void UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits, bool remove);
|
void UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits, bool remove);
|
||||||
bool LookForSourceModCommand(const char *cmd);
|
bool LookForSourceModCommand(const char *cmd);
|
||||||
@ -146,7 +149,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
bool InternalDispatch(int client, const ICommandArgs *args);
|
bool InternalDispatch(int client, const ICommandArgs *args);
|
||||||
ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args);
|
ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args);
|
||||||
ConCmdInfo *AddOrFindCommand(const char *name, const char *description, int flags);
|
ConCmdInfo *AddOrFindCommand(const char *name, const char *description, int flags, IPlugin *pPlugin);
|
||||||
void AddToCmdList(ConCmdInfo *info);
|
void AddToCmdList(ConCmdInfo *info);
|
||||||
void RemoveConCmd(ConCmdInfo *info, const char *cmd, bool untrack);
|
void RemoveConCmd(ConCmdInfo *info, const char *cmd, bool untrack);
|
||||||
bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin);
|
bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin);
|
||||||
|
@ -712,7 +712,8 @@ static cell_t sm_RegServerCmd(IPluginContext *pContext, const cell_t *params)
|
|||||||
return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
|
return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_ConCmds.AddServerCommand(pFunction, name, help, params[4]))
|
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
|
||||||
|
if (!g_ConCmds.AddServerCommand(pFunction, name, help, params[4], pPlugin))
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
|
return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
|
||||||
}
|
}
|
||||||
@ -742,7 +743,7 @@ static cell_t sm_RegConsoleCmd(IPluginContext *pContext, const cell_t *params)
|
|||||||
|
|
||||||
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
|
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
|
||||||
const char *group = pPlugin->GetFilename();
|
const char *group = pPlugin->GetFilename();
|
||||||
if (!g_ConCmds.AddAdminCommand(pFunction, name, group, 0, help, params[4]))
|
if (!g_ConCmds.AddAdminCommand(pFunction, name, group, 0, help, params[4], pPlugin))
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
|
return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
|
||||||
}
|
}
|
||||||
@ -769,9 +770,9 @@ static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
|
|||||||
pContext->LocalToString(params[5], (char **)&group);
|
pContext->LocalToString(params[5], (char **)&group);
|
||||||
pFunction = pContext->GetFunctionById(params[2]);
|
pFunction = pContext->GetFunctionById(params[2]);
|
||||||
|
|
||||||
|
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
|
||||||
if (group[0] == '\0')
|
if (group[0] == '\0')
|
||||||
{
|
{
|
||||||
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
|
|
||||||
group = pPlugin->GetFilename();
|
group = pPlugin->GetFilename();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -780,7 +781,7 @@ static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
|
|||||||
return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
|
return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags))
|
if (!g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags, pPlugin))
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
|
return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
|
||||||
}
|
}
|
||||||
@ -1307,6 +1308,141 @@ static cell_t FakeClientCommandKeyValues(IPluginContext *pContext, const cell_t
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cell_t sm_CommandIterator(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
GlobCmdIter *iter = new GlobCmdIter;
|
||||||
|
iter->started = false;
|
||||||
|
|
||||||
|
Handle_t hndl = handlesys->CreateHandle(hCmdIterType, iter, pContext->GetIdentity(), g_pCoreIdent, NULL);
|
||||||
|
if (hndl == BAD_HANDLE)
|
||||||
|
{
|
||||||
|
delete iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hndl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_CommandIteratorNext(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
GlobCmdIter *iter;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = handlesys->ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid CommandIterator Handle %x", params[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
|
||||||
|
|
||||||
|
if (!iter->started)
|
||||||
|
{
|
||||||
|
iter->iter = cmds.begin();
|
||||||
|
iter->started = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iter->iter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterate further, skip non-sourcemod cmds
|
||||||
|
while (iter->iter != cmds.end() && !(*(iter->iter))->sourceMod)
|
||||||
|
{
|
||||||
|
iter->iter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return iter->iter != cmds.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_CommandIteratorFlags(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
GlobCmdIter *iter;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = handlesys->ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid CommandIterator Handle %x", params[1]);
|
||||||
|
}
|
||||||
|
const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
|
||||||
|
if (!iter->started || iter->iter == cmds.end())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid CommandIterator position");
|
||||||
|
}
|
||||||
|
|
||||||
|
ConCmdInfo *pInfo = (*(iter->iter));
|
||||||
|
return pInfo->eflags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_CommandIteratorGetDesc(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
GlobCmdIter *iter;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = handlesys->ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid CommandIterator Handle %x", params[1]);
|
||||||
|
}
|
||||||
|
const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
|
||||||
|
if (!iter->started || iter->iter == cmds.end())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid CommandIterator position");
|
||||||
|
}
|
||||||
|
|
||||||
|
ConCmdInfo *pInfo = (*(iter->iter));
|
||||||
|
pContext->StringToLocalUTF8(params[2], params[3], pInfo->pCmd->GetHelpText(), NULL);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_CommandIteratorGetName(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
GlobCmdIter *iter;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = handlesys->ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid CommandIterator Handle %x", params[1]);
|
||||||
|
}
|
||||||
|
const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
|
||||||
|
if (!iter->started || iter->iter == cmds.end())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid CommandIterator position");
|
||||||
|
}
|
||||||
|
|
||||||
|
ConCmdInfo *pInfo = (*(iter->iter));
|
||||||
|
pContext->StringToLocalUTF8(params[2], params[3], pInfo->pCmd->GetName(), NULL);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_CommandIteratorPlugin(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
GlobCmdIter *iter;
|
||||||
|
HandleError err;
|
||||||
|
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
|
if ((err = handlesys->ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid CommandIterator Handle %x", params[1]);
|
||||||
|
}
|
||||||
|
const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
|
||||||
|
if (!iter->started || iter->iter == cmds.end())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid CommandIterator position");
|
||||||
|
}
|
||||||
|
|
||||||
|
ConCmdInfo *pInfo = (*(iter->iter));
|
||||||
|
return pInfo->pPlugin->GetMyHandle();
|
||||||
|
}
|
||||||
|
|
||||||
REGISTER_NATIVES(consoleNatives)
|
REGISTER_NATIVES(consoleNatives)
|
||||||
{
|
{
|
||||||
{"CreateConVar", sm_CreateConVar},
|
{"CreateConVar", sm_CreateConVar},
|
||||||
@ -1372,5 +1508,12 @@ REGISTER_NATIVES(consoleNatives)
|
|||||||
{"ConVar.AddChangeHook", sm_HookConVarChange},
|
{"ConVar.AddChangeHook", sm_HookConVarChange},
|
||||||
{"ConVar.RemoveChangeHook", sm_UnhookConVarChange},
|
{"ConVar.RemoveChangeHook", sm_UnhookConVarChange},
|
||||||
|
|
||||||
|
{"CommandIterator.CommandIterator", sm_CommandIterator},
|
||||||
|
{"CommandIterator.Next", sm_CommandIteratorNext},
|
||||||
|
{"CommandIterator.GetDescription", sm_CommandIteratorGetDesc},
|
||||||
|
{"CommandIterator.GetName", sm_CommandIteratorGetName},
|
||||||
|
{"CommandIterator.Flags.get", sm_CommandIteratorFlags},
|
||||||
|
{"CommandIterator.Plugin.get", sm_CommandIteratorPlugin},
|
||||||
|
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
@ -433,6 +433,52 @@ native int GetCmdArg(int argnum, char[] buffer, int maxlength);
|
|||||||
*/
|
*/
|
||||||
native int GetCmdArgString(char[] buffer, int maxlength);
|
native int GetCmdArgString(char[] buffer, int maxlength);
|
||||||
|
|
||||||
|
methodmap CommandIterator < Handle {
|
||||||
|
// Creates a new CommandIterator. Must be freed with delete or
|
||||||
|
// CloseHandle().
|
||||||
|
//
|
||||||
|
// The CommandIterator can be used to iterate commands created by
|
||||||
|
// SourceMod plugins and allows inspection of properties associated
|
||||||
|
// with the command.
|
||||||
|
//
|
||||||
|
// @return New CommandIterator Handle.
|
||||||
|
public native CommandIterator();
|
||||||
|
|
||||||
|
// Determines if there is a next command. If one is found, the
|
||||||
|
// iterator is advanced to it.
|
||||||
|
//
|
||||||
|
// @return true if found and iterator is advanced.
|
||||||
|
public native bool Next();
|
||||||
|
|
||||||
|
// Retrieves the command's description.
|
||||||
|
//
|
||||||
|
// @param buffer Buffer to copy to.
|
||||||
|
// @param maxlen Maximum size of the buffer.
|
||||||
|
// @error Invalid iterator position.
|
||||||
|
public native void GetDescription(char[] buffer, int maxlen);
|
||||||
|
|
||||||
|
// Retrieves the command's name.
|
||||||
|
//
|
||||||
|
// @param buffer Buffer to copy to.
|
||||||
|
// @param maxlen Maximum size of the buffer.
|
||||||
|
// @error Invalid iterator position.
|
||||||
|
public native void GetName(char[] buffer, int maxlen);
|
||||||
|
|
||||||
|
// Retrieves the plugin handle of the command's creator
|
||||||
|
//
|
||||||
|
// @error Invalid iterator position.
|
||||||
|
property Handle Plugin {
|
||||||
|
public native get();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieves the command's default flags
|
||||||
|
//
|
||||||
|
// @error Invalid iterator position.
|
||||||
|
property int Flags {
|
||||||
|
public native get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a command iterator. Must be freed with CloseHandle().
|
* Gets a command iterator. Must be freed with CloseHandle().
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user