diff --git a/core/AdminCache.cpp b/core/AdminCache.cpp index b03f3110..e8557bc0 100644 --- a/core/AdminCache.cpp +++ b/core/AdminCache.cpp @@ -17,6 +17,7 @@ #include "ShareSys.h" #include "ForwardSys.h" #include "CPlayerManager.h" +#include "CConCmdManager.h" AdminCache g_Admins; @@ -93,6 +94,8 @@ void AdminCache::AddCommandOverride(const char *cmd, OverrideType type, FlagBits } sm_trie_insert(pTrie, cmd, (void *)(unsigned int)flags); + + g_ConCmds.UpdateAdminCmdFlags(cmd, type, flags); } bool AdminCache::GetCommandOverride(const char *cmd, OverrideType type, FlagBits *pFlags) @@ -138,9 +141,9 @@ void AdminCache::_UnsetCommandGroupOverride(const char *group) return; } - /* :TODO: Notify command system */ - sm_trie_delete(m_pCmdGrpOverrides, group); + + g_ConCmds.UpdateAdminCmdFlags(group, Override_CommandGroup, 0); } void AdminCache::_UnsetCommandOverride(const char *cmd) @@ -150,9 +153,9 @@ void AdminCache::_UnsetCommandOverride(const char *cmd) return; } - /* :TODO: Notify command system */ - sm_trie_delete(m_pCmdOverrides, cmd); + + g_ConCmds.UpdateAdminCmdFlags(cmd, Override_Command, 0); } void AdminCache::DumpCommandOverrideCache(OverrideType type) diff --git a/core/CConCmdManager.cpp b/core/CConCmdManager.cpp index 75cca8b4..9bc10721 100644 --- a/core/CConCmdManager.cpp +++ b/core/CConCmdManager.cpp @@ -15,6 +15,8 @@ #include "sm_srvcmds.h" #include "AdminCache.h" #include "sm_stringutil.h" +#include "CPlayerManager.h" +#include "CTranslator.h" CConCmdManager g_ConCmds; @@ -149,10 +151,13 @@ ResultType CConCmdManager::DispatchClientCommand(int client, ResultType type) iter++) { pHook = (*iter); - if (pHook->pAdmin - && pHook->pAdmin->eflags) + if (pHook->pAdmin && !CheckAccess(client, cmd, pHook->pAdmin)) { - /* :TODO: admin calculations */ + if (result < Pl_Handled) + { + result = Pl_Handled; + } + continue; } pHook->pf->PushCell(client); pHook->pf->PushCell(args); @@ -241,9 +246,13 @@ void CConCmdManager::InternalDispatch() pHook = (*iter); if (m_CmdClient && pHook->pAdmin - && pHook->pAdmin->eflags) + && !CheckAccess(m_CmdClient, cmd, pHook->pAdmin)) { - /* :TODO: check admin stuff */ + if (result < Pl_Handled) + { + result = Pl_Handled; + } + continue; } pHook->pf->PushCell(m_CmdClient); pHook->pf->PushCell(args); @@ -271,9 +280,67 @@ void CConCmdManager::InternalDispatch() } } -ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args) +bool CConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin) { - return Pl_Continue; + FlagBits cmdflags = pAdmin->eflags; + if (cmdflags == 0) + { + return true; + } + + CPlayer *player = g_Players.GetPlayerByIndex(client); + if (!player) + { + return false; + } + + AdminId adm = player->GetAdminId(); + if (adm != INVALID_ADMIN_ID) + { + FlagBits bits = g_Admins.GetAdminFlags(adm, Access_Effective); + + /* root knows all, WHOA */ + if ((bits & ADMFLAG_ROOT) == ADMFLAG_ROOT) + { + return true; + } + + /* See if our other flags match */ + if ((bits & cmdflags) != cmdflags) + { + return true; + } + + /* Check for overrides */ + unsigned int groups = g_Admins.GetAdminGroupCount(adm); + GroupId gid; + OverrideRule rule; + bool override = false; + for (unsigned int i=0; i::iterator iter; + CmdHook *pHook; + + for (iter=pInfo->conhooks.begin(); iter!=pInfo->conhooks.end(); iter++) + { + pHook = (*iter); + if (pHook->pAdmin) + { + if (bits) + { + pHook->pAdmin->eflags = bits; + } else { + pHook->pAdmin->eflags = pHook->pAdmin->flags; + } + } + } + } else if (type == Override_CommandGroup) { + void *object; + if (!sm_trie_retrieve(m_pCmdGrps, cmd, &object)) + { + return; + } + int grpid = (int)object; + + /* This is bad :( loop through all commands */ + List::iterator iter; + CmdHook *pHook; + for (iter=m_CmdList.begin(); iter!=m_CmdList.end(); iter++) + { + pInfo = (*iter); + for (List::iterator citer=pInfo->conhooks.begin(); + citer!=pInfo->conhooks.end(); + citer++) + { + pHook = (*citer); + if (pHook->pAdmin && pHook->pAdmin->cmdGrpId == grpid) + { + if (bits) + { + pHook->pAdmin->eflags = bits; + } else { + pHook->pAdmin->eflags = pHook->pAdmin->flags; + } + } + } + } + } +} + void CConCmdManager::RemoveConCmd(ConCmdInfo *info) { /* Remove console-specific information diff --git a/core/CConCmdManager.h b/core/CConCmdManager.h index 0517b7a0..3f0198a6 100644 --- a/core/CConCmdManager.h +++ b/core/CConCmdManager.h @@ -98,6 +98,7 @@ public: const char *description, int flags); ResultType DispatchClientCommand(int client, ResultType type); + void UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits); private: void InternalDispatch(); ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args); @@ -106,10 +107,11 @@ private: void AddToCmdList(ConCmdInfo *info); void RemoveConCmd(ConCmdInfo *info); void RemoveConCmds(List &cmdlist, IPluginContext *pContext); + bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin); private: Trie *m_pCmds; /* command lookup */ Trie *m_pCmdGrps; /* command group lookup */ - List m_CmdList; /* command list, currently unused */ + List m_CmdList; /* command list */ int m_CmdClient; /* current client */ BaseStringTable m_Strings; /* string table */ }; diff --git a/core/smn_console.cpp b/core/smn_console.cpp index 3651e4bf..9ccc5214 100644 --- a/core/smn_console.cpp +++ b/core/smn_console.cpp @@ -16,6 +16,7 @@ #include "HandleSys.h" #include "CConVarManager.h" #include "CConCmdManager.h" +#include "PluginSys.h" static cell_t sm_CreateConVar(IPluginContext *pContext, const cell_t *params) { @@ -361,6 +362,35 @@ static cell_t sm_RegConsoleCmd(IPluginContext *pContext, const cell_t *params) return 1; } +static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params) +{ + char *name,*help; + const char *group; + IPluginFunction *pFunction; + FlagBits flags = params[3]; + int cmdflags = params[6]; + + pContext->LocalToString(params[1], &name); + pContext->LocalToString(params[4], &help); + pContext->LocalToString(params[5], (char **)&group); + pFunction = pContext->GetFunctionById(params[2]); + + if (group[0] == '\0') + { + CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext()); + group = pPlugin->GetFilename(); + } + + if (!pFunction) + { + return pContext->ThrowNativeError("Invalid function id (%X)", params[2]); + } + + g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags); + + return 1; +} + REGISTER_NATIVES(convarNatives) { {"CreateConVar", sm_CreateConVar}, diff --git a/plugins/include/console.inc b/plugins/include/console.inc index 4810e37b..fb74edd5 100644 --- a/plugins/include/console.inc +++ b/plugins/include/console.inc @@ -112,7 +112,6 @@ functag ConCmd Action:public(client, argCount); */ native RegConsoleCmd(const String:cmd[], ConCmd:callback, const String:description[]="", flags=0); -#if 0 /** * Creates a console command as an administrative command. If the command does not exist, * it is created. @@ -126,13 +125,12 @@ native RegConsoleCmd(const String:cmd[], ConCmd:callback, const String:descripti * @param flags Optional console flags. * @noreturn */ -native RegAdminCmd(const String:cmd[], - ConCmd:callback, - adminflags, - const String:group[]="", - const String:description[]="", - flags=0); -#endif +native RegAdminCmd(const String:cmd[], + ConCmd:callback, + adminflags, + const String:description[]="", + const String:group[]="", + flags=0); /** * Creates a new console variable.