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 +}