1.1 --- a/core/AdminCache.cpp Fri Aug 10 01:07:07 2007 +0000
1.2 +++ b/core/AdminCache.cpp Fri Aug 10 04:53:30 2007 +0000
1.3 @@ -37,8 +37,181 @@
1.4 #include "ForwardSys.h"
1.5 #include "PlayerManager.h"
1.6 #include "ConCmdManager.h"
1.7 +#include "TextParsers.h"
1.8 +#include "Logger.h"
1.9 +#include "sourcemod.h"
1.10 +#include "sm_stringutil.h"
1.11 +
1.12 +#define LEVEL_STATE_NONE 0
1.13 +#define LEVEL_STATE_LEVELS 1
1.14 +#define LEVEL_STATE_FLAGS 2
1.15
1.16 AdminCache g_Admins;
1.17 +AdminFlag g_FlagLetters[26];
1.18 +bool g_FlagSet[26];
1.19 +
1.20 +/* Default flags */
1.21 +AdminFlag g_DefaultFlags[26] =
1.22 +{
1.23 + Admin_Reservation, Admin_Generic, Admin_Kick, Admin_Ban, Admin_Unban,
1.24 + Admin_Slay, Admin_Changemap, Admin_Convars, Admin_Config, Admin_Chat,
1.25 + Admin_Vote, Admin_Password, Admin_RCON, Admin_Cheats, Admin_Custom1,
1.26 + Admin_Custom2, Admin_Custom3, Admin_Custom4, Admin_Custom5, Admin_Custom6,
1.27 + Admin_Generic, Admin_Generic, Admin_Generic, Admin_Generic, Admin_Generic,
1.28 + Admin_Root
1.29 +};
1.30 +
1.31 +
1.32 +class FlagReader : public ITextListener_SMC
1.33 +{
1.34 +public:
1.35 + void LoadLevels()
1.36 + {
1.37 + if (!Parse())
1.38 + {
1.39 + memcpy(g_FlagLetters, g_DefaultFlags, sizeof(AdminFlag) * 26);
1.40 + for (unsigned int i=0; i<20; i++)
1.41 + {
1.42 + g_FlagSet[i] = true;
1.43 + }
1.44 + g_FlagSet[25] = true;
1.45 + }
1.46 + }
1.47 +private:
1.48 + bool Parse()
1.49 + {
1.50 + unsigned int line = 0;
1.51 + SMCParseError error;
1.52 +
1.53 + m_Line = 0;
1.54 + m_bFileNameLogged = false;
1.55 + g_SourceMod.BuildPath(Path_SM, m_File, sizeof(m_File), "configs/admin_levels.cfg");
1.56 +
1.57 + if ((error = g_TextParser.ParseFile_SMC(m_File, this, &line, NULL))
1.58 + != SMCParse_Okay)
1.59 + {
1.60 + const char *err_string = g_TextParser.GetSMCErrorString(error);
1.61 + if (!err_string)
1.62 + {
1.63 + err_string = "Unknown error";
1.64 + }
1.65 + ParseError("Error %d (%s)", error, err_string);
1.66 + return false;
1.67 + }
1.68 +
1.69 + return true;
1.70 + }
1.71 + void ReadSMC_ParseStart()
1.72 + {
1.73 + m_LevelState = LEVEL_STATE_NONE;
1.74 + m_IgnoreLevel = 0;
1.75 + memset(g_FlagSet, 0, sizeof(g_FlagSet));
1.76 + }
1.77 + SMCParseResult ReadSMC_NewSection(const char *name, bool opt_quotes)
1.78 + {
1.79 + if (m_IgnoreLevel)
1.80 + {
1.81 + m_IgnoreLevel++;
1.82 + return SMCParse_Continue;
1.83 + }
1.84 +
1.85 + if (m_LevelState == LEVEL_STATE_NONE)
1.86 + {
1.87 + if (strcmp(name, "Levels") == 0)
1.88 + {
1.89 + m_IgnoreLevel = LEVEL_STATE_LEVELS;
1.90 + } else {
1.91 + m_IgnoreLevel++;
1.92 + }
1.93 + } else if (m_IgnoreLevel == LEVEL_STATE_LEVELS) {
1.94 + if (strcmp(name, "Flags") == 0)
1.95 + {
1.96 + m_IgnoreLevel = LEVEL_STATE_FLAGS;
1.97 + } else {
1.98 + m_IgnoreLevel++;
1.99 + }
1.100 + } else {
1.101 + m_IgnoreLevel++;
1.102 + }
1.103 +
1.104 + return SMCParse_Continue;
1.105 + }
1.106 + SMCParseResult ReadSMC_KeyValue(const char *key, const char *value, bool key_quotes, bool value_quotes)
1.107 + {
1.108 + if (m_IgnoreLevel != LEVEL_STATE_FLAGS || m_IgnoreLevel)
1.109 + {
1.110 + return SMCParse_Continue;
1.111 + }
1.112 +
1.113 + unsigned char c = (unsigned)value[0];
1.114 +
1.115 + if (c < (unsigned)'a' || c > (unsigned)'z')
1.116 + {
1.117 + ParseError("Flag \"%c\" is not a lower-case ASCII letter", c);
1.118 + return SMCParse_Continue;
1.119 + }
1.120 +
1.121 + c -= (unsigned)'a';
1.122 +
1.123 + assert(c >= 0 && c < 26);
1.124 +
1.125 + if (!g_Admins.FindFlag(key, &g_FlagLetters[c]))
1.126 + {
1.127 + ParseError("Unrecognized admin level \"%s\"", key);
1.128 + return SMCParse_Continue;
1.129 + }
1.130 +
1.131 + g_FlagSet[c] = true;
1.132 +
1.133 + return SMCParse_Continue;
1.134 + }
1.135 + SMCParseResult ReadSMC_LeavingSection()
1.136 + {
1.137 + if (m_IgnoreLevel)
1.138 + {
1.139 + m_IgnoreLevel--;
1.140 + return SMCParse_Continue;
1.141 + }
1.142 +
1.143 + if (m_LevelState == LEVEL_STATE_FLAGS)
1.144 + {
1.145 + m_LevelState = LEVEL_STATE_LEVELS;
1.146 + return SMCParse_Halt;
1.147 + } else if (m_LevelState == LEVEL_STATE_LEVELS) {
1.148 + m_LevelState = LEVEL_STATE_NONE;
1.149 + }
1.150 +
1.151 + return SMCParse_Continue;
1.152 + }
1.153 + SMCParseResult ReadSMC_RawLine(const char *line, unsigned int curline)
1.154 + {
1.155 + m_Line = curline;
1.156 + return SMCParse_Continue;
1.157 + }
1.158 + void ParseError(const char *message, ...)
1.159 + {
1.160 + va_list ap;
1.161 + char buffer[256];
1.162 +
1.163 + va_start(ap, message);
1.164 + UTIL_FormatArgs(buffer, sizeof(buffer), message, ap);
1.165 + va_end(ap);
1.166 +
1.167 + if (!m_bFileNameLogged)
1.168 + {
1.169 + g_Logger.LogError("[SM] Parse error(s) detected in file \"%s\":", m_File);
1.170 + m_bFileNameLogged = true;
1.171 + }
1.172 +
1.173 + g_Logger.LogError("[SM] (Line %d): %s", m_Line, buffer);
1.174 + }
1.175 +private:
1.176 + bool m_bFileNameLogged;
1.177 + char m_File[PLATFORM_MAX_PATH];
1.178 + int m_LevelState;
1.179 + int m_IgnoreLevel;
1.180 + unsigned int m_Line;
1.181 +} s_FlagReader;
1.182
1.183 AdminCache::AdminCache()
1.184 {
1.185 @@ -54,6 +227,7 @@
1.186 m_pAuthTables = sm_trie_create();
1.187 m_InvalidatingAdmins = false;
1.188 m_destroying = false;
1.189 + m_pLevelNames = sm_trie_create();
1.190 }
1.191
1.192 AdminCache::~AdminCache()
1.193 @@ -81,6 +255,8 @@
1.194 sm_trie_destroy(m_pAuthTables);
1.195
1.196 delete m_pStrings;
1.197 +
1.198 + sm_trie_destroy(m_pLevelNames);
1.199 }
1.200
1.201 void AdminCache::OnSourceModStartup(bool late)
1.202 @@ -88,6 +264,28 @@
1.203 RegisterAuthIdentType("steam");
1.204 RegisterAuthIdentType("name");
1.205 RegisterAuthIdentType("ip");
1.206 +
1.207 + NameFlag("reservation", Admin_Reservation);
1.208 + NameFlag("kick", Admin_Kick);
1.209 + NameFlag("generic", Admin_Generic);
1.210 + NameFlag("ban", Admin_Ban);
1.211 + NameFlag("unban", Admin_Unban);
1.212 + NameFlag("slay", Admin_Slay);
1.213 + NameFlag("changemap", Admin_Changemap);
1.214 + NameFlag("cvars", Admin_Convars);
1.215 + NameFlag("config", Admin_Config);
1.216 + NameFlag("chat", Admin_Chat);
1.217 + NameFlag("vote", Admin_Vote);
1.218 + NameFlag("password", Admin_Password);
1.219 + NameFlag("rcon", Admin_RCON);
1.220 + NameFlag("cheats", Admin_Cheats);
1.221 + NameFlag("root", Admin_Root);
1.222 + NameFlag("custom1", Admin_Custom1);
1.223 + NameFlag("custom2", Admin_Custom2);
1.224 + NameFlag("custom3", Admin_Custom3);
1.225 + NameFlag("custom4", Admin_Custom4);
1.226 + NameFlag("custom5", Admin_Custom5);
1.227 + NameFlag("custom6", Admin_Custom6);
1.228 }
1.229
1.230 void AdminCache::OnSourceModAllInitialized()
1.231 @@ -96,6 +294,12 @@
1.232 g_ShareSys.AddInterface(NULL, this);
1.233 }
1.234
1.235 +void AdminCache::OnSourceModLevelChange(const char *mapName)
1.236 +{
1.237 + /* For now, we only read these once per level. */
1.238 + s_FlagReader.LoadLevels();
1.239 +}
1.240 +
1.241 void AdminCache::OnSourceModShutdown()
1.242 {
1.243 g_Forwards.ReleaseForward(m_pCacheFwd);
1.244 @@ -108,6 +312,27 @@
1.245 DumpAdminCache(AdminCache_Groups, true);
1.246 }
1.247
1.248 +void AdminCache::NameFlag(const char *str, AdminFlag flag)
1.249 +{
1.250 + sm_trie_insert(m_pLevelNames, str, (void *)flag);
1.251 +}
1.252 +
1.253 +bool AdminCache::FindFlag(const char *str, AdminFlag *pFlag)
1.254 +{
1.255 + void *obj;
1.256 + if (!sm_trie_retrieve(m_pLevelNames, str, &obj))
1.257 + {
1.258 + return false;
1.259 + }
1.260 +
1.261 + if (pFlag)
1.262 + {
1.263 + *pFlag = (AdminFlag)(int)obj;
1.264 + }
1.265 +
1.266 + return true;
1.267 +}
1.268 +
1.269 void AdminCache::AddCommandOverride(const char *cmd, OverrideType type, FlagBits flags)
1.270 {
1.271 Trie *pTrie = NULL;
1.272 @@ -1289,3 +1514,41 @@
1.273
1.274 return true;
1.275 }
1.276 +
1.277 +bool AdminCache::FindFlag(char c, AdminFlag *pAdmFlag)
1.278 +{
1.279 + if (c < 'a' || c > 'z')
1.280 + {
1.281 + return false;
1.282 + }
1.283 +
1.284 + if (*pAdmFlag)
1.285 + {
1.286 + *pAdmFlag = g_FlagLetters[(unsigned)c - (unsigned)'a'];
1.287 + }
1.288 +
1.289 + return true;
1.290 +}
1.291 +
1.292 +FlagBits AdminCache::ReadFlagString(const char *flags, const char **end)
1.293 +{
1.294 + FlagBits bits = 0;
1.295 +
1.296 + while (flags && (*flags != '\0'))
1.297 + {
1.298 + AdminFlag flag;
1.299 + if (!FindFlag(*flags, &flag))
1.300 + {
1.301 + break;
1.302 + }
1.303 + bits |= FlagArrayToBits(&flag, 1);
1.304 + flags++;
1.305 + }
1.306 +
1.307 + if (end)
1.308 + {
1.309 + *end = flags;
1.310 + }
1.311 +
1.312 + return bits;
1.313 +}
2.1 --- a/core/AdminCache.h Fri Aug 10 01:07:07 2007 +0000
2.2 +++ b/core/AdminCache.h Fri Aug 10 04:53:30 2007 +0000
2.3 @@ -105,6 +105,7 @@
2.4 public: //SMGlobalClass
2.5 void OnSourceModStartup(bool late);
2.6 void OnSourceModAllInitialized();
2.7 + void OnSourceModLevelChange(const char *mapName);
2.8 void OnSourceModShutdown();
2.9 void OnSourceModPluginsLoaded();
2.10 public: //IAdminSystem
2.11 @@ -151,6 +152,9 @@
2.12 bool CheckAdminFlags(AdminId id, FlagBits bits);
2.13 bool CanAdminTarget(AdminId id, AdminId target);
2.14 void SetAdminFlags(AdminId id, AccessMode mode, FlagBits bits);
2.15 + bool FindFlag(const char *str, AdminFlag *pFlag);
2.16 + bool FindFlag(char c, AdminFlag *pAdmFlag);
2.17 + FlagBits ReadFlagString(const char *flags, const char **end);
2.18 public:
2.19 bool IsValidAdmin(AdminId id);
2.20 private:
2.21 @@ -161,6 +165,7 @@
2.22 void DumpCommandOverrideCache(OverrideType type);
2.23 Trie *GetMethodByIndex(unsigned int index);
2.24 bool GetMethodIndex(const char *name, unsigned int *_index);
2.25 + void NameFlag(const char *str, AdminFlag flag);
2.26 public:
2.27 BaseStringTable *m_pStrings;
2.28 BaseMemTable *m_pMemory;
2.29 @@ -179,6 +184,7 @@
2.30 int m_FreeUserList;
2.31 bool m_InvalidatingAdmins;
2.32 bool m_destroying;
2.33 + Trie *m_pLevelNames;
2.34 };
2.35
2.36 extern AdminCache g_Admins;
3.1 --- a/core/smn_admin.cpp Fri Aug 10 01:07:07 2007 +0000
3.2 +++ b/core/smn_admin.cpp Fri Aug 10 04:53:30 2007 +0000
3.3 @@ -451,6 +451,57 @@
3.4 return 1;
3.5 }
3.6
3.7 +static cell_t FindFlagByName(IPluginContext *pContext, const cell_t *params)
3.8 +{
3.9 + char *flag;
3.10 + pContext->LocalToString(params[1], &flag);
3.11 +
3.12 + cell_t *addr;
3.13 + pContext->LocalToPhysAddr(params[2], &addr);
3.14 +
3.15 + AdminFlag admflag;
3.16 + if (!g_Admins.FindFlag(flag, &admflag))
3.17 + {
3.18 + return 0;
3.19 + }
3.20 +
3.21 + *addr = (cell_t)admflag;
3.22 +
3.23 + return 1;
3.24 +}
3.25 +
3.26 +static cell_t FindFlagByChar(IPluginContext *pContext, const cell_t *params)
3.27 +{
3.28 + cell_t *addr;
3.29 + pContext->LocalToPhysAddr(params[2], &addr);
3.30 +
3.31 + AdminFlag admflag;
3.32 + if (!g_Admins.FindFlag((char)params[1], &admflag))
3.33 + {
3.34 + return 0;
3.35 + }
3.36 +
3.37 + *addr = (cell_t)admflag;
3.38 +
3.39 + return 1;
3.40 +}
3.41 +
3.42 +static cell_t ReadFlagString(IPluginContext *pContext, const cell_t *params)
3.43 +{
3.44 + char *flag;
3.45 + pContext->LocalToString(params[1], &flag);
3.46 +
3.47 + cell_t *addr;
3.48 + pContext->LocalToPhysAddr(params[2], &addr);
3.49 +
3.50 + const char *end = flag;
3.51 + FlagBits bits = g_Admins.ReadFlagString(flag, &end);
3.52 +
3.53 + *addr = end - flag;
3.54 +
3.55 + return bits;
3.56 +}
3.57 +
3.58 REGISTER_NATIVES(adminNatives)
3.59 {
3.60 {"DumpAdminCache", DumpAdminCache},
3.61 @@ -489,6 +540,9 @@
3.62 {"FlagBitsToArray", FlagBitsToArray},
3.63 {"CanAdminTarget", CanAdminTarget},
3.64 {"CreateAuthMethod", CreateAuthMethod},
3.65 + {"FindFlagByName", FindFlagByName},
3.66 + {"FindFlagByChar", FindFlagByChar},
3.67 + {"ReadFlagString", ReadFlagString},
3.68 /* -------------------------------------------------- */
3.69 {NULL, NULL},
3.70 };
4.1 --- a/plugins/admin-flatfile/admin-flatfile.sp Fri Aug 10 01:07:07 2007 +0000
4.2 +++ b/plugins/admin-flatfile/admin-flatfile.sp Fri Aug 10 04:53:30 2007 +0000
4.3 @@ -35,14 +35,11 @@
4.4 };
4.5
4.6 /** Various parsing globals */
4.7 -new bool:g_FlagsSet[26]; /* Maps whether flags are set */
4.8 -new AdminFlag:g_FlagLetters[26]; /* Maps the flag letters */
4.9 new bool:g_LoggedFileName = false; /* Whether or not the file name has been logged */
4.10 new g_ErrorCount = 0; /* Current error count */
4.11 new g_IgnoreLevel = 0; /* Nested ignored section count, so users can screw up files safely */
4.12 new String:g_Filename[PLATFORM_MAX_PATH]; /* Used for error messages */
4.13
4.14 -#include "admin-levels.sp"
4.15 #include "admin-overrides.sp"
4.16 #include "admin-groups.sp"
4.17 #include "admin-users.sp"
4.18 @@ -50,7 +47,6 @@
4.19
4.20 public OnRebuildAdminCache(AdminCachePart:part)
4.21 {
4.22 - RefreshLevels();
4.23 if (part == AdminCache_Overrides)
4.24 {
4.25 ReadOverrides();
5.1 --- a/plugins/admin-flatfile/admin-groups.sp Fri Aug 10 01:07:07 2007 +0000
5.2 +++ b/plugins/admin-flatfile/admin-groups.sp Fri Aug 10 04:53:30 2007 +0000
5.3 @@ -92,15 +92,10 @@
5.4 new len = strlen(value);
5.5 for (new i=0; i<len; i++)
5.6 {
5.7 - if (value[i] < 'a' || value[i] > 'z')
5.8 + if (!FindFlagByChar(value[i], flag))
5.9 {
5.10 continue;
5.11 }
5.12 - if (!g_FlagsSet[value[i] - 'a'])
5.13 - {
5.14 - continue;
5.15 - }
5.16 - flag = g_FlagLetters[value[i] - 'a'];
5.17 SetAdmGroupAddFlag(g_CurGrp, flag, true);
5.18 }
5.19 } else if (StrEqual(key, "immunity")) {
6.1 --- a/plugins/admin-flatfile/admin-levels.sp Fri Aug 10 01:07:07 2007 +0000
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,217 +0,0 @@
6.4 -/*
6.5 - * admin-levels.sp
6.6 - * Reads access flags from the admin_levels.cfg file. Do not compile this directly.
6.7 - * This file is part of SourceMod, Copyright (C) 2004-2007 AlliedModders LLC
6.8 - *
6.9 - * This program is free software; you can redistribute it and/or
6.10 - * modify it under the terms of the GNU General Public License
6.11 - * as published by the Free Software Foundation; either version 2
6.12 - * of the License, or (at your option) any later version.
6.13 - *
6.14 - * This program is distributed in the hope that it will be useful,
6.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.17 - * GNU General Public License for more details.
6.18 - *
6.19 - * You should have received a copy of the GNU General Public License
6.20 - * along with this program; if not, write to the Free Software
6.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
6.22 - *
6.23 - * Version: $Id$
6.24 - */
6.25 -
6.26 -#define LEVEL_STATE_NONE 0
6.27 -#define LEVEL_STATE_LEVELS 1
6.28 -#define LEVEL_STATE_FLAGS 2
6.29 -
6.30 -static Handle:g_hLevelParser = INVALID_HANDLE;
6.31 -static g_LevelState = LEVEL_STATE_NONE;
6.32 -
6.33 -/* :TODO: log line numbers? */
6.34 -
6.35 -LoadDefaultLetters()
6.36 -{
6.37 - for (new i='t'; i<'z'; i++)
6.38 - {
6.39 - g_FlagsSet[i-'a'] = false;
6.40 - }
6.41 -
6.42 - g_FlagLetters['a'-'a'] = Admin_Reservation;
6.43 - g_FlagLetters['b'-'a'] = Admin_Generic;
6.44 - g_FlagLetters['c'-'a'] = Admin_Kick;
6.45 - g_FlagLetters['d'-'a'] = Admin_Ban;
6.46 - g_FlagLetters['e'-'a'] = Admin_Unban;
6.47 - g_FlagLetters['f'-'a'] = Admin_Slay;
6.48 - g_FlagLetters['g'-'a'] = Admin_Changemap;
6.49 - g_FlagLetters['h'-'a'] = Admin_Convars;
6.50 - g_FlagLetters['i'-'a'] = Admin_Config;
6.51 - g_FlagLetters['j'-'a'] = Admin_Chat;
6.52 - g_FlagLetters['k'-'a'] = Admin_Vote;
6.53 - g_FlagLetters['l'-'a'] = Admin_Password;
6.54 - g_FlagLetters['m'-'a'] = Admin_RCON;
6.55 - g_FlagLetters['n'-'a'] = Admin_Cheats;
6.56 - g_FlagLetters['o'-'a'] = Admin_Custom1;
6.57 - g_FlagLetters['p'-'a'] = Admin_Custom2;
6.58 - g_FlagLetters['q'-'a'] = Admin_Custom3;
6.59 - g_FlagLetters['r'-'a'] = Admin_Custom4;
6.60 - g_FlagLetters['s'-'a'] = Admin_Custom5;
6.61 - g_FlagLetters['t'-'a'] = Admin_Custom6;
6.62 - g_FlagLetters['z'-'a'] = Admin_Root;
6.63 -}
6.64 -
6.65 -public SMCResult:ReadLevels_NewSection(Handle:smc, const String:name[], bool:opt_quotes)
6.66 -{
6.67 - if (g_IgnoreLevel)
6.68 - {
6.69 - g_IgnoreLevel++;
6.70 - return SMCParse_Continue;
6.71 - }
6.72 -
6.73 - if (g_LevelState == LEVEL_STATE_NONE)
6.74 - {
6.75 - if (StrEqual(name, "Levels"))
6.76 - {
6.77 - g_LevelState = LEVEL_STATE_LEVELS;
6.78 - } else {
6.79 - g_IgnoreLevel++;
6.80 - }
6.81 - } else if (g_LevelState == LEVEL_STATE_LEVELS) {
6.82 - if (StrEqual(name, "Flags"))
6.83 - {
6.84 - g_LevelState = LEVEL_STATE_FLAGS;
6.85 - } else {
6.86 - g_IgnoreLevel++;
6.87 - }
6.88 - } else {
6.89 - g_IgnoreLevel++;
6.90 - }
6.91 -
6.92 - return SMCParse_Continue;
6.93 -}
6.94 -
6.95 -public SMCResult:ReadLevels_KeyValue(Handle:smc, const String:key[], const String:value[], bool:key_quotes, bool:value_quotes)
6.96 -{
6.97 - if (g_LevelState == LEVEL_STATE_FLAGS && !g_IgnoreLevel)
6.98 - {
6.99 - new chr = value[0];
6.100 -
6.101 - if (chr < 'a' || chr > 'z')
6.102 - {
6.103 - ParseError("Unrecognized character: \"%s\"", value);
6.104 - return SMCParse_Continue;
6.105 - }
6.106 -
6.107 - chr -= 'a';
6.108 -
6.109 - new AdminFlag:flag;
6.110 -
6.111 - if (StrEqual(key, "reservation"))
6.112 - {
6.113 - flag = Admin_Reservation;
6.114 - } else if (StrEqual(key, "kick")) {
6.115 - flag = Admin_Kick;
6.116 - } else if (StrEqual(key, "generic")) {
6.117 - flag = Admin_Generic;
6.118 - } else if (StrEqual(key, "ban")) {
6.119 - flag = Admin_Ban;
6.120 - } else if (StrEqual(key, "unban")) {
6.121 - flag = Admin_Unban;
6.122 - } else if (StrEqual(key, "slay")) {
6.123 - flag = Admin_Slay;
6.124 - } else if (StrEqual(key, "changemap")) {
6.125 - flag = Admin_Changemap;
6.126 - } else if (StrEqual(key, "cvars")) {
6.127 - flag = Admin_Convars;
6.128 - } else if (StrEqual(key, "config")) {
6.129 - flag = Admin_Config;
6.130 - } else if (StrEqual(key, "chat")) {
6.131 - flag = Admin_Chat;
6.132 - } else if (StrEqual(key, "vote")) {
6.133 - flag = Admin_Vote;
6.134 - } else if (StrEqual(key, "password")) {
6.135 - flag = Admin_Password;
6.136 - } else if (StrEqual(key, "rcon")) {
6.137 - flag = Admin_RCON;
6.138 - } else if (StrEqual(key, "cheats")) {
6.139 - flag = Admin_Cheats;
6.140 - } else if (StrEqual(key, "root")) {
6.141 - flag = Admin_Root;
6.142 - } else if (StrEqual(key, "custom1")) {
6.143 - flag = Admin_Custom1;
6.144 - } else if (StrEqual(key, "custom2")) {
6.145 - flag = Admin_Custom2;
6.146 - } else if (StrEqual(key, "custom3")) {
6.147 - flag = Admin_Custom3;
6.148 - } else if (StrEqual(key, "custom4")) {
6.149 - flag = Admin_Custom4;
6.150 - } else if (StrEqual(key, "custom5")) {
6.151 - flag = Admin_Custom5;
6.152 - } else if (StrEqual(key, "custom6")) {
6.153 - flag = Admin_Custom6;
6.154 - } else {
6.155 - ParseError("Unrecognized flag type: %s", key);
6.156 - }
6.157 -
6.158 - g_FlagLetters[chr] = flag;
6.159 - g_FlagsSet[chr] = true;
6.160 - }
6.161 -
6.162 - return SMCParse_Continue;
6.163 -}
6.164 -
6.165 -public SMCResult:ReadLevels_EndSection(Handle:smc)
6.166 -{
6.167 - /* If we're ignoring, skip out */
6.168 - if (g_IgnoreLevel)
6.169 - {
6.170 - g_IgnoreLevel--;
6.171 - return SMCParse_Continue;
6.172 - }
6.173 -
6.174 - if (g_LevelState == LEVEL_STATE_FLAGS)
6.175 - {
6.176 - /* We're totally done parsing */
6.177 - g_LevelState = LEVEL_STATE_LEVELS;
6.178 - return SMCParse_Halt;
6.179 - } else if (g_LevelState == LEVEL_STATE_LEVELS) {
6.180 - g_LevelState = LEVEL_STATE_NONE;
6.181 - }
6.182 -
6.183 - return SMCParse_Continue;
6.184 -}
6.185 -
6.186 -static InitializeLevelParser()
6.187 -{
6.188 - if (g_hLevelParser == INVALID_HANDLE)
6.189 - {
6.190 - g_hLevelParser = SMC_CreateParser();
6.191 - SMC_SetReaders(g_hLevelParser,
6.192 - ReadLevels_NewSection,
6.193 - ReadLevels_KeyValue,
6.194 - ReadLevels_EndSection);
6.195 - }
6.196 -}
6.197 -
6.198 -RefreshLevels()
6.199 -{
6.200 - LoadDefaultLetters();
6.201 - InitializeLevelParser();
6.202 -
6.203 - BuildPath(Path_SM, g_Filename, sizeof(g_Filename), "configs/admin_levels.cfg");
6.204 -
6.205 - /* Set states */
6.206 - InitGlobalStates();
6.207 - g_LevelState = LEVEL_STATE_NONE;
6.208 -
6.209 - new SMCError:err = SMC_ParseFile(g_hLevelParser, g_Filename);
6.210 - if (err != SMCError_Okay)
6.211 - {
6.212 - decl String:buffer[64];
6.213 - if (SMC_GetErrorString(err, buffer, sizeof(buffer)))
6.214 - {
6.215 - ParseError("%s", buffer);
6.216 - } else {
6.217 - ParseError("Fatal parse error");
6.218 - }
6.219 - }
6.220 -}
7.1 --- a/plugins/admin-flatfile/admin-overrides.sp Fri Aug 10 01:07:07 2007 +0000
7.2 +++ b/plugins/admin-flatfile/admin-overrides.sp Fri Aug 10 04:53:30 2007 +0000
7.3 @@ -69,27 +69,7 @@
7.4 return SMCParse_Continue;
7.5 }
7.6
7.7 - new AdminFlag:array[AdminFlags_TOTAL];
7.8 - new flags_total;
7.9 -
7.10 - new len = strlen(value);
7.11 - for (new i=0; i<len; i++)
7.12 - {
7.13 - if (value[i] < 'a' || value[i] > 'z')
7.14 - {
7.15 - ParseError("Invalid flag detected: %c", value[i]);
7.16 - continue;
7.17 - }
7.18 - new val = value[i] - 'a';
7.19 - if (!g_FlagsSet[val])
7.20 - {
7.21 - ParseError("Invalid flag detected: %c", value[i]);
7.22 - continue;
7.23 - }
7.24 - array[flags_total++] = g_FlagLetters[val];
7.25 - }
7.26 -
7.27 - new flags = FlagArrayToBits(array, flags_total);
7.28 + new flags = ReadFlagString(value);
7.29
7.30 if (key[0] == '@')
7.31 {
8.1 --- a/plugins/admin-flatfile/admin-simple.sp Fri Aug 10 01:07:07 2007 +0000
8.2 +++ b/plugins/admin-flatfile/admin-simple.sp Fri Aug 10 04:53:30 2007 +0000
8.3 @@ -115,23 +115,19 @@
8.4 new bool:is_default = false;
8.5 for (new i=0; i<len; i++)
8.6 {
8.7 - if (flags[i] < 'a' || flags[i] > 'z')
8.8 + if (flags[i] == '$')
8.9 {
8.10 - if (flags[i] == '$')
8.11 + is_default = true;
8.12 + } else {
8.13 + new AdminFlag:flag;
8.14 +
8.15 + if (!FindFlagByChar(flags[i], flag))
8.16 {
8.17 - is_default = true;
8.18 - } else {
8.19 ParseError("Invalid flag detected: %c", flags[i]);
8.20 + continue;
8.21 }
8.22 - continue;
8.23 + SetAdminFlag(admin, flag, true);
8.24 }
8.25 - new val = flags[i] - 'a';
8.26 - if (!g_FlagsSet[val])
8.27 - {
8.28 - ParseError("Invalid flag detected: %c", flags[i]);
8.29 - continue;
8.30 - }
8.31 - SetAdminFlag(admin, g_FlagLetters[val], true);
8.32 }
8.33
8.34 if (is_default)
9.1 --- a/plugins/admin-flatfile/admin-users.sp Fri Aug 10 01:07:07 2007 +0000
9.2 +++ b/plugins/admin-flatfile/admin-users.sp Fri Aug 10 04:53:30 2007 +0000
9.3 @@ -93,21 +93,15 @@
9.4 }
9.5 } else if (StrEqual(key, "flags")) {
9.6 new len = strlen(value);
9.7 + new AdminFlag:flag;
9.8
9.9 for (new i=0; i<len; i++)
9.10 {
9.11 - if (value[i] < 'a' || value[i] > 'z')
9.12 + if (!FindFlagByChar(value[i], flag))
9.13 {
9.14 ParseError("Invalid flag detected: %c", value[i]);
9.15 - continue;
9.16 }
9.17 - new val = value[i] - 'a';
9.18 - if (!g_FlagsSet[val])
9.19 - {
9.20 - ParseError("Invalid flag detected: %c", value[i]);
9.21 - continue;
9.22 - }
9.23 - SetAdminFlag(g_CurUser, g_FlagLetters[val], true);
9.24 + SetAdminFlag(g_CurUser, flag, true);
9.25 }
9.26 }
9.27
10.1 --- a/plugins/include/admin.inc Fri Aug 10 01:07:07 2007 +0000
10.2 +++ b/plugins/include/admin.inc Fri Aug 10 04:53:30 2007 +0000
10.3 @@ -489,6 +489,33 @@
10.4 native FlagBitsToArray(bits, AdminFlag:array[], maxSize);
10.5
10.6 /**
10.7 + * Finds a flag by its string name.
10.8 + *
10.9 + * @param name Flag name (like "kick"), case sensitive.
10.10 + * @param flag Variable to store flag in.
10.11 + * @return True on success, false if not found.
10.12 + */
10.13 +native bool:FindFlagByName(const String:name[], &AdminFlag:flag);
10.14 +
10.15 +/**
10.16 + * Finds a flag by a given character.
10.17 + *
10.18 + * @param c Flag ASCII character/token.
10.19 + * @param flag Variable to store flag in.
10.20 + * @return True on success, false if not found.
10.21 + */
10.22 +native bool:FindFlagByChar(c, &AdminFlag:flag);
10.23 +
10.24 +/**
10.25 + * Converts a string of flag characters to a bit string.
10.26 + *
10.27 + * @param flags Flag ASCII string.
10.28 + * @param numchars Optional variable to store the number of bytes read.
10.29 + * @return Bit string of ADMFLAG values.
10.30 + */
10.31 +native ReadFlagString(const String:flags[], &numchars=0);
10.32 +
10.33 +/**
10.34 * Tests whether one admin can target another.
10.35 *
10.36 * @param admin Admin doing the targetting (may be INVALID_ADMIN_ID).
11.1 --- a/public/IAdminSystem.h Fri Aug 10 01:07:07 2007 +0000
11.2 +++ b/public/IAdminSystem.h Fri Aug 10 04:53:30 2007 +0000
11.3 @@ -36,7 +36,7 @@
11.4 #include <IShareSys.h>
11.5
11.6 #define SMINTERFACE_ADMINSYS_NAME "IAdminSys"
11.7 -#define SMINTERFACE_ADMINSYS_VERSION 1
11.8 +#define SMINTERFACE_ADMINSYS_VERSION 2
11.9
11.10 /**
11.11 * @file IAdminSystem.h
11.12 @@ -599,6 +599,34 @@
11.13 * @return True if this admin has permission to target the other admin.
11.14 */
11.15 virtual bool CanAdminTarget(AdminId id, AdminId target) =0;
11.16 +
11.17 + /**
11.18 + * @brief Returns a flag from a named string.
11.19 + *
11.20 + * @param flagname Case sensitive flag name string (like "kick").
11.21 + * @param pAdmFlag Pointer to store the found admin flag in.
11.22 + * @return True on success, false on failure.
11.23 + */
11.24 + virtual bool FindFlag(const char *flagname, AdminFlag *pAdmFlag) =0;
11.25 +
11.26 + /**
11.27 + * @brief Reads a single character as a flag.
11.28 + *
11.29 + * @param flag Flag character.
11.30 + * @param pAdmFlag Pointer to store the admin flag.
11.31 + * @return True on success, false if invalid.
11.32 + */
11.33 + virtual bool FindFlag(char c, AdminFlag *pAdmFlag) =0;
11.34 +
11.35 + /**
11.36 + * @brief Reads a string of flag letters and returns its access value.
11.37 + *
11.38 + * @param flags Flag string.
11.39 + * @param end Pointer to store the last value read. On success,
11.40 + * this will store a pointer to the null terminator.
11.41 + * @return FlagBits value of the flags.
11.42 + */
11.43 + virtual FlagBits ReadFlagString(const char *flags, const char **end) =0;
11.44 };
11.45 }
11.46