diff --git a/core/AdminCache.cpp b/core/AdminCache.cpp index fa6bcc9d..5f79433b 100644 --- a/core/AdminCache.cpp +++ b/core/AdminCache.cpp @@ -21,8 +21,8 @@ AdminCache g_Admins; AdminCache::AdminCache() { - m_pCmdOverrides = NULL; - m_pCmdGrpOverrides = NULL; + m_pCmdOverrides = sm_trie_create(); + m_pCmdGrpOverrides = sm_trie_create(); m_pStrings = new BaseStringTable(1024); m_pMemory = m_pStrings->GetMemTable(); m_FreeGroupList = m_FirstGroup = m_LastGroup = INVALID_GROUP_ID; @@ -84,23 +84,42 @@ void AdminCache::OnSourceModShutdown() m_pCacheFwd = NULL; } -void AdminCache::AddCommandOverride(const char *cmd, OverrideType type, AdminFlag flag) +void AdminCache::AddCommandOverride(const char *cmd, OverrideType type, FlagBits flags) { + Trie *pTrie = NULL; if (type == Override_Command) { - _AddCommandOverride(cmd, flag); + pTrie = m_pCmdOverrides; } else if (type == Override_CommandGroup) { - _AddCommandGroupOverride(cmd, flag); + pTrie = m_pCmdGrpOverrides; + } else { + return; } + + sm_trie_insert(pTrie, cmd, (void *)(unsigned int)flags); } -bool AdminCache::GetCommandOverride(const char *cmd, OverrideType type, AdminFlag *pFlag) +bool AdminCache::GetCommandOverride(const char *cmd, OverrideType type, FlagBits *pFlags) { + Trie *pTrie = NULL; + if (type == Override_Command) { - return _GetCommandOverride(cmd, pFlag); + pTrie = m_pCmdOverrides; } else if (type == Override_CommandGroup) { - return _GetCommandGroupOverride(cmd, pFlag); + pTrie = m_pCmdGrpOverrides; + } else { + return false; + } + + void *object; + if (sm_trie_retrieve(pTrie, cmd, &object)) + { + if (pFlags) + { + *pFlags = (FlagBits)object; + } + return true; } return false; @@ -116,72 +135,6 @@ void AdminCache::UnsetCommandOverride(const char *cmd, OverrideType type) } } -void AdminCache::_AddCommandGroupOverride(const char *group, AdminFlag flag) -{ - if (!m_pCmdGrpOverrides) - { - m_pCmdGrpOverrides = sm_trie_create(); - } - - /* :TODO: Notify command system */ - - sm_trie_insert(m_pCmdGrpOverrides, group, (void *)flag); -} - -void AdminCache::_AddCommandOverride(const char *cmd, AdminFlag flag) -{ - if (!m_pCmdOverrides) - { - m_pCmdOverrides = sm_trie_create(); - } - - /* :TODO: Notify command system */ - - sm_trie_insert(m_pCmdOverrides, cmd, (void *)flag); -} - -bool AdminCache::_GetCommandGroupOverride(const char *cmd, AdminFlag *pFlag) -{ - if (!m_pCmdGrpOverrides) - { - return false; - } - - if (!pFlag) - { - return sm_trie_retrieve(m_pCmdGrpOverrides, cmd, NULL); - } else { - void *object; - bool ret; - if (ret=sm_trie_retrieve(m_pCmdGrpOverrides, cmd, &object)) - { - *pFlag = (AdminFlag)(int)object; - } - return ret; - } -} - -bool AdminCache::_GetCommandOverride(const char *cmd, AdminFlag *pFlag) -{ - if (!m_pCmdOverrides) - { - return false; - } - - if (!pFlag) - { - return sm_trie_retrieve(m_pCmdOverrides, cmd, NULL); - } else { - void *object; - bool ret; - if (ret=sm_trie_retrieve(m_pCmdOverrides, cmd, &object)) - { - *pFlag = (AdminFlag)(int)object; - } - return ret; - } -} - void AdminCache::_UnsetCommandGroupOverride(const char *group) { if (!m_pCmdGrpOverrides) @@ -233,8 +186,8 @@ AdminId AdminCache::CreateAdmin(const char *name) pUser->grp_table = -1; } - memset(pUser->flags, 0, sizeof(pUser->flags)); - memset(pUser->eflags, 0, sizeof(pUser->flags)); + pUser->flags = 0; + pUser->eflags = 0; pUser->grp_count = 0; pUser->password = -1; pUser->magic = USR_MAGIC_SET; @@ -286,7 +239,7 @@ GroupId AdminCache::AddGroup(const char *group_name) pGroup->next_grp = INVALID_GROUP_ID; pGroup->pCmdGrpTable = NULL; pGroup->pCmdTable = NULL; - memset(pGroup->addflags, 0, sizeof(AdminFlag) * AdminFlags_TOTAL); + pGroup->addflags = 0; if (m_FirstGroup == INVALID_GROUP_ID) { @@ -336,12 +289,12 @@ void AdminCache::SetGroupAddFlag(GroupId id, AdminFlag flag, bool enabled) return; } - if (flag < Admin_None || flag >= AdminFlags_TOTAL) + if (flag < Admin_Reservation || flag >= AdminFlags_TOTAL) { return; } - pGroup->addflags[flag] = enabled; + pGroup->addflags |= (1<<(unsigned int)flag); } bool AdminCache::GetGroupAddFlag(GroupId id, AdminFlag flag) @@ -352,15 +305,16 @@ bool AdminCache::GetGroupAddFlag(GroupId id, AdminFlag flag) return false; } - if (flag < Admin_None || flag >= AdminFlags_TOTAL) + if (flag < Admin_Reservation || flag >= AdminFlags_TOTAL) { return false; } - return pGroup->addflags[flag]; + FlagBits bit = 1<<(FlagBits)flag; + return ((pGroup->addflags & bit) == bit); } -unsigned int AdminCache::GetGroupAddFlagBits(GroupId id, bool flags[], unsigned int total) +FlagBits AdminCache::GetGroupAddFlags(GroupId id) { AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id); if (!pGroup || pGroup->magic != GRP_MAGIC_SET) @@ -368,16 +322,7 @@ unsigned int AdminCache::GetGroupAddFlagBits(GroupId id, bool flags[], unsigned return 0; } - unsigned int i; - - for (i = Admin_None; - i < AdminFlags_TOTAL && i < total; - i++) - { - flags[i] = pGroup->addflags[i]; - } - - return i; + return pGroup->addflags; } void AdminCache::SetGroupGenericImmunity(GroupId id, ImmunityType type, bool enabled) @@ -436,8 +381,16 @@ void AdminCache::AddGroupImmunity(GroupId id, GroupId other_id) table[0] = 0; } else { int *old_table = (int *)m_pMemory->GetAddress(pOther->immune_table); + /* Break out if this group is already in the list */ + for (int i=0; iCreateMem(sizeof(int) * (old_table[0] + 2), (void **)&table); - /* Get the old address again in caes of resize */ + /* Get the old address again in case of resize */ old_table = (int *)m_pMemory->GetAddress(pOther->immune_table); table[0] = old_table[0]; for (unsigned int i=1; i<=(unsigned int)old_table[0]; i++) @@ -702,14 +655,11 @@ void AdminCache::InvalidateGroup(GroupId id) /* Decrease count */ pUser->grp_count--; /* Recalculate effective flags */ - memset(pUser->eflags, 0, sizeof(pUser->eflags)); + pUser->eflags = pUser->flags; for (unsigned int j=0; jgrp_count; j++) { pOther = (AdminGroup *)m_pMemory->GetAddress(table[j]); - for (unsigned int k=0; keflags[k] = (pUser->flags[k] || pOther->addflags[k]); - } + pUser->eflags |= pOther->addflags; } /* Break now, duplicates aren't allowed */ break; @@ -922,13 +872,14 @@ void AdminCache::SetAdminFlag(AdminId id, AdminFlag flag, bool enabled) return; } - if (flag < Admin_None + if (flag < Admin_Reservation || flag >= AdminFlags_TOTAL) { return; } - pUser->flags[enabled] = false; + pUser->flags |= (1<<(FlagBits)flag); + pUser->eflags |= (1<<(FlagBits)flag); } bool AdminCache::GetAdminFlag(AdminId id, AdminFlag flag, AccessMode mode) @@ -939,23 +890,25 @@ bool AdminCache::GetAdminFlag(AdminId id, AdminFlag flag, AccessMode mode) return false; } - if (flag < Admin_None + if (flag < Admin_Reservation || flag >= AdminFlags_TOTAL) { return false; } + FlagBits bit = (1<<(FlagBits)flag); + if (mode == Access_Real) { - return pUser->flags[flag]; + return ((pUser->flags & bit) == bit); } else if (mode == Access_Effective) { - return (pUser->flags[flag] || pUser->eflags[flag]); + return ((pUser->eflags & bit) == bit); } return false; } -unsigned int AdminCache::GetAdminFlags(AdminId id, bool flags[], unsigned int total, AccessMode mode) +FlagBits AdminCache::GetAdminFlags(AdminId id, AccessMode mode) { AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); if (!pUser || pUser->magic != USR_MAGIC_SET) @@ -963,21 +916,14 @@ unsigned int AdminCache::GetAdminFlags(AdminId id, bool flags[], unsigned int to return 0; } - unsigned int i = 0; if (mode == Access_Real) { - for (i=0; iflags[i]; - } + return pUser->flags; } else if (mode == Access_Effective) { - for (i=0; iflags[i] || pUser->eflags[i]); - } + return pUser->eflags; } - return i; + return 0; } bool AdminCache::AdminInheritGroup(AdminId id, GroupId gid) @@ -994,6 +940,19 @@ bool AdminCache::AdminInheritGroup(AdminId id, GroupId gid) return false; } + /* First check for duplicates */ + if (pUser->grp_count != 0) + { + int *temp_table = (int *)m_pMemory->GetAddress(pUser->grp_table); + for (unsigned int i=0; igrp_count; i++) + { + if (temp_table[i] == gid) + { + return false; + } + } + } + int *table; if (pUser->grp_count + 1 > pUser->grp_size) { @@ -1024,28 +983,11 @@ bool AdminCache::AdminInheritGroup(AdminId id, GroupId gid) table = (int *)m_pMemory->GetAddress(pUser->grp_table); } - for (unsigned int i=0; igrp_count; i++) - { - if (table[i] == gid) - { - return false; - } - } - table[pUser->grp_count] = gid; pUser->grp_count++; /* Compute new effective flags */ - for (unsigned int i=Admin_None; - ieflags[i]) - { - pUser->eflags[i] = pGroup->addflags[i]; - } - } + pUser->eflags |= pGroup->addflags; return true; } @@ -1096,3 +1038,52 @@ void AdminCache::SetAdminPassword(AdminId id, const char *password) pUser->password = m_pStrings->AddString(password); } +unsigned int AdminCache::FlagBitsToBitArray(FlagBits bits, bool array[], unsigned int maxSize) +{ + unsigned int i; + for (i=0; i - - + + LocalToString(params[1], &cmd); - if (!g_Admins.GetCommandOverride(cmd, (OverrideType)params[2], &flag)) + if (!g_Admins.GetCommandOverride(cmd, (OverrideType)params[2], &flags)) { return 0; } @@ -46,7 +46,7 @@ static cell_t GetCommandOverride(IPluginContext *pContext, const cell_t *params) cell_t *addr; pContext->LocalToPhysAddr(params[3], &addr); - *addr = (cell_t)flag; + *addr = (cell_t)flags; return 1; } @@ -177,24 +177,10 @@ static cell_t GetAdmGroupCmdOverride(IPluginContext *pContext, const cell_t *par return 1; } -static cell_t GetAdmGroupAddFlagBits(IPluginContext *pContext, const cell_t *params) +static cell_t GetAdmGroupAddFlags(IPluginContext *pContext, const cell_t *params) { GroupId id = (GroupId)params[1]; - bool flags[AdminFlags_TOTAL]; - unsigned int num = g_Admins.GetGroupAddFlagBits(id, flags, AdminFlags_TOTAL); - unsigned int i; - - cell_t *addr; - pContext->LocalToPhysAddr(params[2], &addr); - - for (i=0; - i < num && i < (unsigned int)params[3]; - i++) - { - addr[i] = flags[i] ? 1 : 0; - } - - return i; + return g_Admins.GetGroupAddFlags(id); } REGISTER_NATIVES(adminNatives) @@ -214,6 +200,6 @@ REGISTER_NATIVES(adminNatives) {"GetAdmGroupImmuneCount", GetAdmGroupImmuneCount}, {"AddAdmGroupCmdOverride", AddAdmGroupCmdOverride}, {"GetAdmGroupCmdOverride", GetAdmGroupCmdOverride}, - {"GetAdmGroupAddFlagBits", GetAdmGroupAddFlagBits}, + {"GetAdmGroupAddFlags", GetAdmGroupAddFlags}, {NULL, NULL}, }; diff --git a/plugins/include/admin.inc b/plugins/include/admin.inc index 465c35a8..e0ca35ec 100644 --- a/plugins/include/admin.inc +++ b/plugins/include/admin.inc @@ -17,27 +17,71 @@ #endif #define _admin_included +/** + * Access levels (flags) for admins. + */ 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 */ - Admin_Root, /* Root access */ + Admin_Reservation = 0, /**< Reserved slot */ + Admin_Generic, /**< Generic admin abilities */ + 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_Config, /**< Change configuration */ + 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 */ + Admin_Root, /**< All access by default */ + Admin_Custom1, /**< First custom flag type */ + Admin_Custom2, /**< Second custom flag type */ + Admin_Custom3, /**< Third custom flag type */ + Admin_Custom4, /**< Fourth custom flag type */ + Admin_Custom5, /**< Fifth custom flag type */ + Admin_Custom6, /**< Sixth custom flag type */ /* --- */ AdminFlags_TOTAL, }; +/** + * These define bitwise values for bitstrings (numbers containing bitwise flags). + */ +#define ADMFLAG_RESERVATION (1<<0) /**< Convenience macro for Admin_Reservation as a FlagBit */ +#define ADMFLAG_GENERIC (1<<1) /**< Convenience macro for Admin_Generic as a FlagBit */ +#define ADMFLAG_KICK (1<<2) /**< Convenience macro for Admin_Kick as a FlagBit */ +#define ADMFLAG_BAN (1<<3) /**< Convenience macro for Admin_Ban as a FlagBit */ +#define ADMFLAG_UNBAN (1<<4) /**< Convenience macro for Admin_Unban as a FlagBit */ +#define ADMFLAG_SLAY (1<<5) /**< Convenience macro for Admin_Slay as a FlagBit */ +#define ADMFLAG_CHANGEMAP (1<<6) /**< Convenience macro for Admin_Changemap as a FlagBit */ +#define ADMFLAG_CONVARS (1<<7) /**< Convenience macro for Admin_Convars as a FlagBit */ +#define ADMFLAG_CONFIG (1<<8) /**< Convenience macro for Admin_Config as a FlagBit */ +#define ADMFLAG_CHAT (1<<9) /**< Convenience macro for Admin_Chat as a FlagBit */ +#define ADMFLAG_VOTE (1<<10) /**< Convenience macro for Admin_Vote as a FlagBit */ +#define ADMFLAG_PASSWORD (1<<11) /**< Convenience macro for Admin_Password as a FlagBit */ +#define ADMFLAG_RCON (1<<12) /**< Convenience macro for Admin_RCON as a FlagBit */ +#define ADMFLAG_CHEATS (1<<13) /**< Convenience macro for Admin_Cheats as a FlagBit */ +#define ADMFLAG_ROOT (1<<14) /**< Convenience macro for Admin_Root as a FlagBit */ +#define ADMFLAG_CUSTOM1 (1<<15) /**< Convenience macro for Admin_Custom1 as a FlagBit */ +#define ADMFLAG_CUSTOM2 (1<<16) /**< Convenience macro for Admin_Custom2 as a FlagBit */ +#define ADMFLAG_CUSTOM3 (1<<17) /**< Convenience macro for Admin_Custom3 as a FlagBit */ +#define ADMFLAG_CUSTOM4 (1<<18) /**< Convenience macro for Admin_Custom4 as a FlagBit */ +#define ADMFLAG_CUSTOM5 (1<<19) /**< Convenience macro for Admin_Custom5 as a FlagBit */ +#define ADMFLAG_CUSTOM6 (1<<20) /**< Convenience macro for Admin_Custom6 as a FlagBit */ + +stock FlagToBit(AdminFlag:flag) +{ + return (1<<_:flag); +} + +stock AdminFlag:BitToFlag(bit) +{ + /* :TODO: implement */ +} + enum OverrideType { Override_Command = 1, /* Command */ @@ -95,20 +139,20 @@ native DumpAdminCache(cache_flags, bool:rebuild); * * @param cmd String containing command name (case sensitive). * @param type Override type (specific command or group). - * @param flag New admin flag. + * @param flags New admin flag. * @noreturn */ -native AddCommandOverride(const String:cmd[], OverrideType:type, AdminFlag:flag); +native AddCommandOverride(const String:cmd[], OverrideType:type, flags); /** * 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). + * @param flags 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); +native bool:GetCommandOverride(const String:cmd[], OverrideType:type, &flags); /** * Unsets a command override. @@ -161,11 +205,9 @@ native bool:GetAdmGroupAddFlag(GroupId:id, AdminFlag:flag); * @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. + * @return Bitstring containing the flags enabled. */ -native GetAdmGroupAddFlagBits(GroupId:id, bool:flags[], total); +native GetAdmGroupAddFlags(GroupId:id); /** * Toggles a generic immunity type. diff --git a/public/IAdminSystem.h b/public/IAdminSystem.h index 9877b893..87558576 100644 --- a/public/IAdminSystem.h +++ b/public/IAdminSystem.h @@ -54,25 +54,53 @@ namespace SourceMod */ enum AdminFlag { - Admin_None = 0, - Admin_Reservation, /**< Reserved slot */ + Admin_Reservation = 0, /**< Reserved slot */ + Admin_Generic, /**< Generic admin abilities */ 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_Config, /**< Change configuration */ 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 */ Admin_Root, /**< All access by default */ + Admin_Custom1, /**< First custom flag type */ + Admin_Custom2, /**< Second custom flag type */ + Admin_Custom3, /**< Third custom flag type */ + Admin_Custom4, /**< Fourth custom flag type */ + Admin_Custom5, /**< Fifth custom flag type */ + Admin_Custom6, /**< Sixth custom flag type */ /* --- */ AdminFlags_TOTAL, }; + #define ADMFLAG_RESERVATION (1<<0) /**< Convenience macro for Admin_Reservation as a FlagBit */ + #define ADMFLAG_GENERIC (1<<1) /**< Convenience macro for Admin_Generic as a FlagBit */ + #define ADMFLAG_KICK (1<<2) /**< Convenience macro for Admin_Kick as a FlagBit */ + #define ADMFLAG_BAN (1<<3) /**< Convenience macro for Admin_Ban as a FlagBit */ + #define ADMFLAG_UNBAN (1<<4) /**< Convenience macro for Admin_Unban as a FlagBit */ + #define ADMFLAG_SLAY (1<<5) /**< Convenience macro for Admin_Slay as a FlagBit */ + #define ADMFLAG_CHANGEMAP (1<<6) /**< Convenience macro for Admin_Changemap as a FlagBit */ + #define ADMFLAG_CONVARS (1<<7) /**< Convenience macro for Admin_Convars as a FlagBit */ + #define ADMFLAG_CONFIG (1<<8) /**< Convenience macro for Admin_Config as a FlagBit */ + #define ADMFLAG_CHAT (1<<9) /**< Convenience macro for Admin_Chat as a FlagBit */ + #define ADMFLAG_VOTE (1<<10) /**< Convenience macro for Admin_Vote as a FlagBit */ + #define ADMFLAG_PASSWORD (1<<11) /**< Convenience macro for Admin_Password as a FlagBit */ + #define ADMFLAG_RCON (1<<12) /**< Convenience macro for Admin_RCON as a FlagBit */ + #define ADMFLAG_CHEATS (1<<13) /**< Convenience macro for Admin_Cheats as a FlagBit */ + #define ADMFLAG_ROOT (1<<14) /**< Convenience macro for Admin_Root as a FlagBit */ + #define ADMFLAG_CUSTOM1 (1<<15) /**< Convenience macro for Admin_Custom1 as a FlagBit */ + #define ADMFLAG_CUSTOM2 (1<<16) /**< Convenience macro for Admin_Custom2 as a FlagBit */ + #define ADMFLAG_CUSTOM3 (1<<17) /**< Convenience macro for Admin_Custom3 as a FlagBit */ + #define ADMFLAG_CUSTOM4 (1<<18) /**< Convenience macro for Admin_Custom4 as a FlagBit */ + #define ADMFLAG_CUSTOM5 (1<<19) /**< Convenience macro for Admin_Custom5 as a FlagBit */ + #define ADMFLAG_CUSTOM6 (1<<20) /**< Convenience macro for Admin_Custom6 as a FlagBit */ + /** * @brief Specifies which type of command to override (command or command group). */ @@ -148,6 +176,8 @@ namespace SourceMod virtual void OnRebuildAdminCache(int cache_flags) =0; }; + typedef unsigned int FlagBits; + /** * @brief Provides functions for manipulating the admin options cache. */ @@ -169,19 +199,19 @@ namespace SourceMod * * @param cmd String containing command name (case sensitive). * @param type Override type (specific command or group). - * @param flag New admin flag. + * @param flags New admin flag. */ - virtual void AddCommandOverride(const char *cmd, OverrideType type, AdminFlag flag) =0; + virtual void AddCommandOverride(const char *cmd, OverrideType type, FlagBits flags) =0; /** * @brief Returns a command override. * * @param cmd String containing command name (case sensitive). * @param type Override type (specific command or group). - * @param pFlag Optional pointer to the set flag. + * @param pFlags Optional pointer to the set flag. * @return True if there is an override, false otherwise. */ - virtual bool GetCommandOverride(const char *cmd, OverrideType type, AdminFlag *pFlag) =0; + virtual bool GetCommandOverride(const char *cmd, OverrideType type, FlagBits *pFlags) =0; /** * @brief Unsets a command override. @@ -231,11 +261,9 @@ namespace SourceMod * 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 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. + * @return Bit string containing the bits of each flag. */ - virtual unsigned int GetGroupAddFlagBits(GroupId id, bool flags[], unsigned int total) =0; + virtual FlagBits GetGroupAddFlags(GroupId id) =0; /** * @brief Toggles a generic immunity type. @@ -391,15 +419,10 @@ namespace SourceMod * @brief Returns a bitarray of flags enabled on an admin. * * @param id AdminId index of the admin. - * @param flag Array to store flag bits in. - * @param total Maximum size of the flag array. * @param mode Access mode to use. - * @return Number of flags written to the array. + * @return A bit string containing which flags are enabled. */ - virtual unsigned int GetAdminFlags(AdminId id, - bool flags[], - unsigned int total, - AccessMode mode) =0; + virtual FlagBits GetAdminFlags(AdminId id, AccessMode mode) =0; /** * @brief Adds a group to an admin's inherited group list. @@ -463,6 +486,44 @@ namespace SourceMod * @return True on success, false otherwise. */ virtual bool InvalidateAdmin(AdminId id) =0; + + /** + * @brief Converts a flag bit string to a bit array. + * + * @param bits Bit string containing the flags. + * @param array Array to write the flags to. Enabled flags will be 'true'. + * @param maxSize Maximum number of flags the array can store. + * @return Number of flags written. + */ + virtual unsigned int FlagBitsToBitArray(FlagBits bits, bool array[], unsigned int maxSize) =0; + + /** + * @brief Converts a flag array to a bit string. + * + * @param array Array containing true or false for each AdminFlag. + * @param maxSize Maximum size of the flag array. + * @return A bit string composed of the array bits. + */ + virtual FlagBits FlagBitArrayToBits(const bool array[], unsigned int maxSize) =0; + + /** + * @brief Converts an array of flags to bits. + * + * @param array Array containing flags that are enabled. + * @param numFlags Number of flags in the array. + * @return A bit string composed of the array flags. + */ + virtual FlagBits FlagArrayToBits(const AdminFlag array[], unsigned int numFlags) =0; + + /** + * @brief Converts a bit string to an array of flags. + * + * @param bits Bit string containing the flags. + * @param array Output array to write flags. + * @param maxSize Maximum size of the flag array. + * @return Number of flags written. + */ + virtual unsigned int FlagBitsToArray(FlagBits bits, AdminFlag array[], unsigned int maxSize) =0; }; }