From 0b8b26042ed7f7aa984184a7359571338619287f Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 24 Jan 2007 23:43:31 +0000 Subject: [PATCH] Added initial admin system natives Added a few API changes to the admin system Exposed more interfaces --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40341 --- core/AdminCache.cpp | 67 +++++++++-- core/AdminCache.h | 16 ++- core/CTextParsers.cpp | 6 + core/CTextParsers.h | 7 +- core/msvc8/sourcemod_mm.vcproj | 4 + core/systems/ExtensionSys.cpp | 1 + core/systems/ForwardSys.cpp | 2 + core/systems/PluginSys.cpp | 2 + core/systems/ShareSys.cpp | 4 +- plugins/include/admin.inc | 214 +++++++++++++++++++++++++++++++++ public/IAdminSystem.h | 54 ++++++--- 11 files changed, 349 insertions(+), 28 deletions(-) create mode 100644 plugins/include/admin.inc diff --git a/core/AdminCache.cpp b/core/AdminCache.cpp index 82adfafd..f98380d3 100644 --- a/core/AdminCache.cpp +++ b/core/AdminCache.cpp @@ -2,6 +2,7 @@ #include #include "AdminCache.h" #include "ShareSys.h" +#include "ForwardSys.h" AdminCache g_Admins; @@ -13,6 +14,7 @@ AdminCache::AdminCache() m_pMemory = m_pStrings->GetMemTable(); m_FreeGroupList = m_FirstGroup = m_LastGroup = INVALID_GROUP_ID; m_pGroups = sm_trie_create(); + m_pCacheFwd = NULL; } AdminCache::~AdminCache() @@ -39,9 +41,16 @@ AdminCache::~AdminCache() void AdminCache::OnSourceModAllInitialized() { + m_pCacheFwd = g_Forwards.CreateForward("OnRebuildAdminCache", ET_Ignore, 1, NULL, Param_Cell); g_ShareSys.AddInterface(NULL, this); } +void AdminCache::OnSourceModShutdown() +{ + g_Forwards.ReleaseForward(m_pCacheFwd); + m_pCacheFwd = NULL; +} + void AdminCache::AddCommandOverride(const char *cmd, OverrideType type, AdminFlag flag) { if (type == Override_Command) @@ -273,7 +282,7 @@ bool AdminCache::GetGroupAddFlag(GroupId id, AdminFlag flag) return pGroup->addflags[flag]; } -unsigned int AdminCache::GetGroupAddFlags(GroupId id, AdminFlag flags[], unsigned int total) +unsigned int AdminCache::GetGroupAddFlagBits(GroupId id, bool flags[], unsigned int total) { AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id); if (!pGroup || pGroup->magic != GRP_MAGIC_SET) @@ -281,19 +290,16 @@ unsigned int AdminCache::GetGroupAddFlags(GroupId id, AdminFlag flags[], unsigne return 0; } - unsigned int r = 0; + unsigned int i; - for (unsigned int i = Admin_None + 1; - i < AdminFlags_TOTAL && r < total; + for (i = Admin_None; + i < AdminFlags_TOTAL && i < total; i++) { - if (pGroup->addflags[i]) - { - flags[r++] = (AdminFlag)i; - } + flags[i] = pGroup->addflags[i]; } - return r; + return i; } void AdminCache::SetGroupGenericImmunity(GroupId id, ImmunityType type, bool enabled) @@ -566,3 +572,46 @@ void AdminCache::InvalidateGroupCache() /* Reset the memory table */ m_pMemory->Reset(); } + +void AdminCache::AddAdminListener(IAdminListener *pListener) +{ + m_hooks.push_back(pListener); +} + +void AdminCache::RemoveAdminListener(IAdminListener *pListener) +{ + m_hooks.remove(pListener); +} + +void AdminCache::DumpAdminCache(int cache_flags, bool rebuild) +{ + if (cache_flags & ADMIN_CACHE_OVERRIDES) + { + DumpCommandOverrideCache(Override_Command); + DumpCommandOverrideCache(Override_CommandGroup); + } + + if ((cache_flags & ADMIN_CACHE_ADMINS) || + (cache_flags & ADMIN_CACHE_GROUPS)) + { + /* Make sure the flag is set */ + cache_flags |= ADMIN_CACHE_ADMINS; + /* :TODO: Dump admin cache */ + } + + if (cache_flags & ADMIN_CACHE_GROUPS) + { + InvalidateGroupCache(); + } + + if (rebuild) + { + List::iterator iter; + IAdminListener *pListener; + for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++) + { + pListener = (*iter); + pListener->OnRebuildAdminCache(cache_flags); + } + } +} diff --git a/core/AdminCache.h b/core/AdminCache.h index b551d6e2..19382995 100644 --- a/core/AdminCache.h +++ b/core/AdminCache.h @@ -3,8 +3,12 @@ #include "sm_memtable.h" #include +#include #include #include "sm_globals.h" +#include + +using namespace SourceHook; #define GRP_MAGIC_SET 0xDEADFADE #define GRP_MAGIC_UNSET 0xFACEFACE @@ -36,27 +40,29 @@ public: ~AdminCache(); public: //SMGlobalClass void OnSourceModAllInitialized(); + void OnSourceModShutdown(); public: //IAdminSystem /** Command cache stuff */ void AddCommandOverride(const char *cmd, OverrideType type, AdminFlag flag); bool GetCommandOverride(const char *cmd, OverrideType type, AdminFlag *pFlag); void UnsetCommandOverride(const char *cmd, OverrideType type); - void DumpCommandOverrideCache(OverrideType type); /** Group cache stuff */ GroupId AddGroup(const char *group_name); GroupId FindGroupByName(const char *group_name); void SetGroupAddFlag(GroupId id, AdminFlag flag, bool enabled); bool GetGroupAddFlag(GroupId id, AdminFlag flag); - unsigned int GetGroupAddFlags(GroupId Id, AdminFlag flags[], unsigned int total); + unsigned int GetGroupAddFlagBits(GroupId id, bool flags[], unsigned int total); void SetGroupGenericImmunity(GroupId id, ImmunityType type, bool enabled); bool GetGroupGenericImmunity(GroupId id, ImmunityType type); void InvalidateGroup(GroupId id); - void InvalidateGroupCache(); void AddGroupImmunity(GroupId id, GroupId other_id); unsigned int GetGroupImmunityCount(GroupId id); GroupId GetGroupImmunity(GroupId id, unsigned int number); void AddGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule rule); bool GetGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule *pRule); + void DumpAdminCache(int cache_flags, bool rebuild); + void AddAdminListener(IAdminListener *pListener); + void RemoveAdminListener(IAdminListener *pListener); private: void _AddCommandOverride(const char *cmd, AdminFlag flag); void _AddCommandGroupOverride(const char *group, AdminFlag flag); @@ -64,6 +70,8 @@ private: bool _GetCommandGroupOverride(const char *group, AdminFlag *pFlag); void _UnsetCommandOverride(const char *cmd); void _UnsetCommandGroupOverride(const char *group); + void InvalidateGroupCache(); + void DumpCommandOverrideCache(OverrideType type); public: BaseStringTable *m_pStrings; BaseMemTable *m_pMemory; @@ -73,6 +81,8 @@ public: int m_LastGroup; int m_FreeGroupList; Trie *m_pGroups; + List m_hooks; + IForward *m_pCacheFwd; }; extern AdminCache g_Admins; diff --git a/core/CTextParsers.cpp b/core/CTextParsers.cpp index c653601e..296be553 100644 --- a/core/CTextParsers.cpp +++ b/core/CTextParsers.cpp @@ -5,6 +5,7 @@ #include #include #include "CTextParsers.h" +#include "ShareSys.h" CTextParsers g_TextParser; @@ -29,6 +30,11 @@ CTextParsers::CTextParsers() g_ws_chartable[' '] = 1; } +void CTextParsers::OnSourceModAllInitialized() +{ + g_ShareSys.AddInterface(NULL, this); +} + unsigned int CTextParsers::GetUTF8CharBytes(const char *stream) { return _GetUTF8CharBytes(stream); diff --git a/core/CTextParsers.h b/core/CTextParsers.h index 49cadb1c..f1e8c158 100644 --- a/core/CTextParsers.h +++ b/core/CTextParsers.h @@ -2,6 +2,7 @@ #define _INCLUDE_SOURCEMOD_TEXTPARSERS_H_ #include +#include "sm_globals.h" using namespace SourceMod; @@ -32,10 +33,14 @@ inline unsigned int _GetUTF8CharBytes(const char *stream) */ typedef bool (*STREAMREADER)(void *, char *, size_t, unsigned int *); -class CTextParsers : public ITextParsers +class CTextParsers : + public ITextParsers, + public SMGlobalClass { public: CTextParsers(); +public: //SMGlobalClass + void OnSourceModAllInitialized(); public: bool ParseFile_INI(const char *file, ITextListener_INI *ini_listener, diff --git a/core/msvc8/sourcemod_mm.vcproj b/core/msvc8/sourcemod_mm.vcproj index dd3ee7a3..0855fd4a 100644 --- a/core/msvc8/sourcemod_mm.vcproj +++ b/core/msvc8/sourcemod_mm.vcproj @@ -227,6 +227,10 @@ RelativePath="..\sm_trie.cpp" > + + diff --git a/core/systems/ExtensionSys.cpp b/core/systems/ExtensionSys.cpp index b95e46e7..b459649a 100644 --- a/core/systems/ExtensionSys.cpp +++ b/core/systems/ExtensionSys.cpp @@ -244,6 +244,7 @@ void CExtensionManager::OnSourceModAllInitialized() g_ExtType = g_ShareSys.CreateIdentType("EXTENSION"); g_PluginSys.AddPluginsListener(this); g_RootMenu.AddRootConsoleCommand("exts", "Manage extensions", this); + g_ShareSys.AddInterface(NULL, this); } void CExtensionManager::OnSourceModShutdown() diff --git a/core/systems/ForwardSys.cpp b/core/systems/ForwardSys.cpp index 9465840a..70de62cf 100644 --- a/core/systems/ForwardSys.cpp +++ b/core/systems/ForwardSys.cpp @@ -1,6 +1,7 @@ #include #include "ForwardSys.h" #include "PluginSys.h" +#include "ShareSys.h" CForwardManager g_Forwards; @@ -19,6 +20,7 @@ CForwardManager g_Forwards; void CForwardManager::OnSourceModAllInitialized() { g_PluginSys.AddPluginsListener(this); + g_ShareSys.AddInterface(NULL, this); } void CForwardManager::OnSourceModShutdown() diff --git a/core/systems/PluginSys.cpp b/core/systems/PluginSys.cpp index cdfff088..c6f99289 100644 --- a/core/systems/PluginSys.cpp +++ b/core/systems/PluginSys.cpp @@ -1249,6 +1249,8 @@ void CPluginManager::OnSourceModAllInitialized() g_PluginIdent = g_ShareSys.CreateIdentType("PLUGIN"); g_RootMenu.AddRootConsoleCommand("plugins", "Manage Plugins", this); + + g_ShareSys.AddInterface(NULL, this); } void CPluginManager::OnSourceModShutdown() diff --git a/core/systems/ShareSys.cpp b/core/systems/ShareSys.cpp index e05a0abf..f72f1f99 100644 --- a/core/systems/ShareSys.cpp +++ b/core/systems/ShareSys.cpp @@ -1,6 +1,7 @@ #include "ShareSys.h" #include "HandleSys.h" #include "ExtensionSys.h" +#include "LibrarySys.h" ShareSystem g_ShareSys; @@ -35,8 +36,9 @@ void ShareSystem::OnSourceModStartup(bool late) /* Initialize our static identity handle */ m_IdentRoot.ident = g_HandleSys.CreateHandle(m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL); - /* Add the Handle System... it's too innocent and pure to do it itself */ + /* Add the Handle System and others... they are too innocent and pure to do it themselves */ AddInterface(NULL, &g_HandleSys); + AddInterface(NULL, &g_LibSys); } void ShareSystem::OnSourceModShutdown() diff --git a/plugins/include/admin.inc b/plugins/include/admin.inc new file mode 100644 index 00000000..a0206a31 --- /dev/null +++ b/plugins/include/admin.inc @@ -0,0 +1,214 @@ +#if defined _admin_included + #endinput +#endif +#define _admin_included + +enum AdminFlag +{ + Admin_None = 0, /* Unused */ + Admin_Reservation, /* Reserved slot */ + Admin_Kick, /* Kick another user */ + Admin_Ban, /* Ban another user */ + Admin_Unban, /* Unban another user */ + Admin_Slay, /* Slay/kill/damage another user */ + Admin_Changemap, /* Change the map */ + Admin_Convars, /* Change basic convars */ + Admin_Configs, /* Change configs */ + Admin_Chat, /* Special chat privileges */ + Admin_Vote, /* Special vote privileges */ + Admin_Password, /* Set a server password */ + Admin_RCON, /* Use RCON */ + Admin_Cheats, /* Change sv_cheats and use its commands */ + /* --- */ + AdminFlags_TOTAL, +}; + +enum OverrideType +{ + Override_Command = 1, /* Command */ + Override_CommandGroup, /* Command group */ +}; + +enum OverrideRule +{ + Command_Deny = 0, + Command_Allow = 1, +}; + +enum ImmunityType +{ + Immunity_Default = 1, /* Immune from everyone with no immunity */ + Immunity_Global, /* Immune from everyone (except root admins) */ +}; + +/** Note: Groups are not Handles, nor are they indexes */ +enum GroupId +{ + INVALID_GROUP_ID = -1, +}; + +#define ADMIN_CACHE_OVERRIDES (1<<0) +#define ADMIN_CACHE_ADMINS (1<<1) +#define ADMIN_CACHE_GROUPS ((1<<2)|ADMIN_CACHE_ADMINS) + +/** + * Called when part of the admin cache needs to be rebuilt. + * @note Groups should always be rebuilt before admins. + * + * @param cache_flags Flags for which cache to dump. + */ +forward OnRebuildAdminCache(cache_flags); + +/** + * Tells the admin system to dump a portion of the cache. + * + * @param cache_flags Flags for which cache to dump. Specifying groups also dumps admins. + * @param rebuild If true, the rebuild forwards will fire. + * @noreturn + */ +native DumpAdminCache(cache_flags, bool:rebuild); + +/** + * Adds a global command flag override. Any command registered with this name + * will assume the new flag. This is applied retroactively as well. + * + * @param cmd String containing command name (case sensitive). + * @param type Override type (specific command or group). + * @param flag New admin flag. + * @noreturn + */ +native AddCommandOverride(const String:cmd[], OverrideType:type, AdminFlag:flag); + +/** + * Returns a command override. + * + * @param cmd String containing command name (case sensitive). + * @param type Override type (specific command or group). + * @param pFlag By-reference cell to store the flag (undefined if not found). + * @return True if there is an override, false otherwise. + */ +native bool:GetCommandOverride(const String:cmd[], OverrideType:type, &AdminFlag:flag); + +/** + * Unsets a command override. + * + * @param cmd String containing command name (case sensitive). + * @param type Override type (specific command or group). + * @noreturn + */ +native UnsetCommandOverride(const String:cmd[], OverrideType:type); + +/** + * Adds a new group. Name must be unique. + * + * @param group_name String containing the group name. + * @return A new group id, INVALID_GROUP_ID if it already exists. + */ +native GroupId:CreateAdmGroup(const String:group_name[]); + +/** + * @brief Finds a group by name. + * + * @param group_name String containing the group name. + * @return A group id, or INVALID_GROUP_ID if not found. + */ +native FindAdmGroup(const String:group_name[]); + +/** + * Adds or removes a flag from a group's flag set. + * @note These are called "add flags" because they add to a user's flags. + * + * @param id Group id. + * @param flag Admin flag to toggle. + * @param enabled True to set the flag, false to unset/disable. + * @noreturn + */ +native SetAdmGroupAddFlag(GroupId:id, AdminFlag:flag, bool:enabled); + +/** + * Gets the set value of an add flag on a group's flag set. + * @note These are called "add flags" because they add to a user's flags. + * + * @param id Group id. + * @param flag Admin flag to retrieve. + * @return True if enabled, false otherwise, + */ +native bool:GetAdmGroupAddFlag(GroupId:id, AdminFlag:flag); + +/** + * Returns the flag set that is added to a user from their group. + * @note These are called "add flags" because they add to a user's flags. + * + * @param id GroupId of the group. + * @param flags Array to store flags in. + * @param total Total number of flags that can be stored in the array (AdminFlags_TOTAL, usually). + * @return Number of flags that were written to the array. + */ +native GetAdmGroupAddFlagBits(GroupId:id, bool flags[], total); + +/** + * Toggles a generic immunity type. + * + * @param id Group id. + * @param type Generic immunity type. + * @param enabled True to enable, false otherwise. + * @noreturn + */ +native SetAdmGroupImmunity(GroupId:id, ImmunityType:type, bool:enabled); + +/** + * Returns whether or not a group has global immunity. + * + * @param id Group id. + * @param type Generic immunity type. + * @return True if the group has this immunity, false otherwise. + */ +native bool:GetAdmGroupImmunity(GroupId:id, ImmunityType:type); + +/** + * Adds immunity to a specific group. + * + * @param id Group id. + * @param other_id Group id to receive immunity to. + * @noreturn + */ +native SetAdmGroupImmuneFrom(GroupId:id, GroupId:other_id); + +/** + * Returns the number of specific group immunities. + * + * @param id Group id. + * @return Number of group immunities. + */ +native GetAdmGroupImmuneCount(GroupId:id); + +/** + * Returns a group that this group is immune to given an index. + * + * @param id Group id. + * @param number Index from 0 to N-1, from GetAdmGroupImmuneCount(). + * @return GroupId that this group is immune to, or INVALID_GROUP_ID on failure. + */ +native GroupId:GetAdmGroupImmuneFrom(GroupId:id, number); + +/** + * Adds a group-specific override type. + * + * @param id Group id. + * @param name String containing command name (case sensitive). + * @param type Override type (specific command or group). + * @param rule Override allow/deny setting. + * @noreturn + */ +native AddAdmGroupCmdOverride(GroupId:id, const String:name[], OverrideType:type, OverrideRule:rule); + +/** + * Retrieves a group-specific command override. + * + * @param id Group id. + * @param name String containing command name (case sensitive). + * @param type Override type (specific command or group). + * @param rule Optional pointer to store allow/deny setting. + * @return True if an override exists, false otherwise. + */ +native bool:GetAdmGroupCmdOverride(GroupId:id, const String:name[], OverrideType:type, &OverrideRule:rule); diff --git a/public/IAdminSystem.h b/public/IAdminSystem.h index b1a43f7e..bbf02632 100644 --- a/public/IAdminSystem.h +++ b/public/IAdminSystem.h @@ -62,14 +62,30 @@ namespace SourceMod enum ImmunityType { - Immunity_Default = 1, /* Immune from everyone with no immunity */ + Immunity_Default = 1, /* Immune from everyone with no immunity */ Immunity_Global, /* Immune from everyone (except root admins) */ }; typedef int GroupId; + #define ADMIN_CACHE_OVERRIDES (1<<0) + #define ADMIN_CACHE_ADMINS (1<<1) + #define ADMIN_CACHE_GROUPS ((1<<2)|ADMIN_CACHE_ADMINS) + #define INVALID_GROUP_ID -1 + class IAdminListener + { + public: + /** + * Called when part of the admin cache needs to be rebuilt. + * Groups should always be rebuilt before admins. + * + * @param cache_flags Flags for which cache to dump. + */ + virtual void OnRebuildAdminCache(int cache_flags) =0; + }; + /** * @brief This is the administration options cache. */ @@ -113,13 +129,6 @@ namespace SourceMod */ virtual void UnsetCommandOverride(const char *cmd, OverrideType type) =0; - /** - * @brief Dumps the global command override cache (unset all). - * - * @param type Override type (specific command or group). - */ - virtual void DumpCommandOverrideCache(OverrideType type) =0; - /** * @brief Adds a new group. Name must be unique. * @@ -156,15 +165,15 @@ namespace SourceMod virtual bool GetGroupAddFlag(GroupId id, AdminFlag flag) =0; /** - * @brief Returns the flag set that is added to a user from their group. + * @brief Returns an array of flag bits that are added to a user from their group. * Note: These are called "add flags" because they add to a user's flags. * * @param id GroupId of the group. - * @param flags Array to store flags in. + * @param flags Array to store flags bits in. * @param total Total number of flags that can be stored in the array. * @return Number of flags that were written to the array. */ - virtual unsigned int GetGroupAddFlags(GroupId id, AdminFlag flags[], unsigned int total) =0; + virtual unsigned int GetGroupAddFlagBits(GroupId id, bool flags[], unsigned int total) =0; /** * @brief Toggles a generic immunity type. @@ -244,10 +253,27 @@ namespace SourceMod virtual void InvalidateGroup(GroupId id) =0; /** - * @brief Invalidates the entire group cache. WARNING: This will trigger - * an admin cache dump as well! + * @brief Tells the admin system to dump a portion of the cache. + * This calls into plugin forwards to rebuild the cache. + * + * @param cache_flags Flags for which cache to dump. Specifying groups also dumps admins. + * @param rebuild If true, the rebuild forwards/events will fire. */ - virtual void InvalidateGroupCache() =0; + virtual void DumpAdminCache(int cache_flags, bool rebuild) =0; + + /** + * @brief Adds an admin interface listener. + * + * @param pListener Pointer to an IAdminListener to add. + */ + virtual void AddAdminListener(IAdminListener *pListener) =0; + + /** + * @brief Removes an admin interface listener. + * + * @param pListener Pointer to an IAdminListener to remove. + */ + virtual void RemoveAdminListener(IAdminListener *pListener) =0; }; };