diff --git a/core/AdminCache.cpp b/core/AdminCache.cpp index d93be67f..4b21338a 100644 --- a/core/AdminCache.cpp +++ b/core/AdminCache.cpp @@ -1719,7 +1719,7 @@ bool AdminCache::CanAdminUseCommand(int client, const char *cmd) } } - return g_ConCmds.CheckCommandAccess(client, cmd, bits); + return g_ConCmds.CheckClientCommandAccess(client, cmd, bits); } unsigned int AdminCache::SetGroupImmunityLevel(GroupId gid, unsigned int level) @@ -1794,7 +1794,7 @@ bool AdminCache::CheckAccess(int client, const char *cmd, FlagBits flags, bool o GetCommandOverride(cmd, Override_Command, &bits); } - return g_ConCmds.CheckCommandAccess(client, cmd, bits) ? 1 : 0; + return g_ConCmds.CheckClientCommandAccess(client, cmd, bits) ? 1 : 0; } void iterator_glob_basic_override(Trie *pTrie, const char *key, void **value, void *data) diff --git a/core/ConCmdManager.cpp b/core/ConCmdManager.cpp index 9c22cfcd..4493d7ff 100644 --- a/core/ConCmdManager.cpp +++ b/core/ConCmdManager.cpp @@ -450,7 +450,7 @@ void ConCmdManager::InternalDispatch(const CCommand &command) } } -bool ConCmdManager::CheckCommandAccess(int client, const char *cmd, FlagBits cmdflags) +bool ConCmdManager::CheckClientCommandAccess(int client, const char *cmd, FlagBits cmdflags) { if (cmdflags == 0 || client == 0) { @@ -471,7 +471,11 @@ bool ConCmdManager::CheckCommandAccess(int client, const char *cmd, FlagBits cmd return false; } - AdminId adm = player->GetAdminId(); + return CheckAdminCommandAccess(player->GetAdminId(), cmd, cmdflags); +} + +bool ConCmdManager::CheckAdminCommandAccess(AdminId adm, const char *cmd, FlagBits cmdflags) +{ if (adm != INVALID_ADMIN_ID) { FlagBits bits = g_Admins.GetAdminFlags(adm, Access_Effective); @@ -524,7 +528,7 @@ bool ConCmdManager::CheckCommandAccess(int client, const char *cmd, FlagBits cmd bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin) { - if (CheckCommandAccess(client, cmd, pAdmin->eflags)) + if (CheckClientCommandAccess(client, cmd, pAdmin->eflags)) { return true; } diff --git a/core/ConCmdManager.h b/core/ConCmdManager.h index 448ff953..38ee6b96 100644 --- a/core/ConCmdManager.h +++ b/core/ConCmdManager.h @@ -130,7 +130,8 @@ public: void UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits, bool remove); bool LookForSourceModCommand(const char *cmd); bool LookForCommandAdminFlags(const char *cmd, FlagBits *pFlags); - bool CheckCommandAccess(int client, const char *cmd, FlagBits flags); + bool CheckClientCommandAccess(int client, const char *cmd, FlagBits flags); + bool CheckAdminCommandAccess(AdminId adm, const char *cmd, FlagBits flags); private: void InternalDispatch(const CCommand &command); ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args); diff --git a/core/smn_console.cpp b/core/smn_console.cpp index 06f29d58..b893e1c0 100644 --- a/core/smn_console.cpp +++ b/core/smn_console.cpp @@ -1257,7 +1257,7 @@ static cell_t CheckCommandAccess(IPluginContext *pContext, const cell_t *params) char *cmd; pContext->LocalToString(params[2], &cmd); - /* Auto-detect a command if we can */ + /* Match up with an admin command if possible */ FlagBits bits = params[3]; bool found_command = false; if (params[0] < 4 || !params[4]) @@ -1270,7 +1270,28 @@ static cell_t CheckCommandAccess(IPluginContext *pContext, const cell_t *params) g_Admins.GetCommandOverride(cmd, Override_Command, &bits); } - return g_ConCmds.CheckCommandAccess(params[1], cmd, bits) ? 1 : 0; + return g_ConCmds.CheckClientCommandAccess(params[1], cmd, bits) ? 1 : 0; +} + +static cell_t CheckAccess(IPluginContext *pContext, const cell_t *params) +{ + char *cmd; + pContext->LocalToString(params[2], &cmd); + + /* Match up with an admin command if possible */ + FlagBits bits = params[3]; + bool found_command = false; + if (params[0] < 4 || !params[4]) + { + found_command = g_ConCmds.LookForCommandAdminFlags(cmd, &bits); + } + + if (!found_command) + { + g_Admins.GetCommandOverride(cmd, Override_Command, &bits); + } + + return g_ConCmds.CheckAdminCommandAccess(params[1], cmd, bits) ? 1 : 0; } static cell_t IsChatTrigger(IPluginContext *pContext, const cell_t *params) @@ -1521,6 +1542,7 @@ REGISTER_NATIVES(consoleNatives) {"GetCommandIterator", GetCommandIterator}, {"ReadCommandIterator", ReadCommandIterator}, {"CheckCommandAccess", CheckCommandAccess}, + {"CheckAccess", CheckAccess}, {"FakeClientCommandEx", FakeClientCommandEx}, {"IsChatTrigger", IsChatTrigger}, {"SetCommandFlags", SetCommandFlags}, diff --git a/plugins/include/console.inc b/plugins/include/console.inc index 96d64806..84524e57 100644 --- a/plugins/include/console.inc +++ b/plugins/include/console.inc @@ -739,8 +739,8 @@ native bool:ReadCommandIterator(Handle:iter, /** * Returns whether a client has access to a given command string. The string - * can also be any override string, as overrides can be independent of - * commands. This important feature essentially allows you to create custom + * can be any override string, as overrides can be independent of + * commands. This feature essentially allows you to create custom * flags using the override system. * * @param client Client index. @@ -759,6 +759,28 @@ native bool:CheckCommandAccess(client, flags, bool:override_only=false); +/** + * Returns whether an admin has access to a given command string. The string + * can be any override string, as overrides can be independent of + * commands. This feature essentially allows you to create custom flags + * using the override system. + * + * @param id AdminId of the admin. + * @param command Command name. If the command is not found, the default + * flags are used. + * @param flags Flag string to use as a default, if the command or override + * is not found. + * @param override_only If true, SourceMod will not attempt to find a matching + * command, and it will only use the default flags specified. + * Otherwise, SourceMod will ignore the default flags if + * there is a matching admin command. + * @return True if the admin has access, false otherwise. + */ +native bool:CheckAccess(AdminId:id, + const String:command[], + flags, + bool:override_only=false); + /** * Returns true if the supplied character is valid in a ConVar name. *