1.1 --- a/core/AdminCache.cpp Fri Jul 11 06:51:21 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,2081 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod
1.8 - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
1.9 - * =============================================================================
1.10 - *
1.11 - * This program is free software; you can redistribute it and/or modify it under
1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
1.13 - * Free Software Foundation.
1.14 - *
1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 - * details.
1.19 - *
1.20 - * You should have received a copy of the GNU General Public License along with
1.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
1.22 - *
1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 - * by the Valve Corporation. You must obey the GNU General Public License in
1.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 - * this exception to all derivative works. AlliedModders LLC defines further
1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 - * or <http://www.sourcemod.net/license.php>.
1.31 - *
1.32 - * Version: $Id$
1.33 - */
1.34 -
1.35 -#include <string.h>
1.36 -#include <assert.h>
1.37 -#include <ITextParsers.h>
1.38 -#include "AdminCache.h"
1.39 -#include "ShareSys.h"
1.40 -#include "ForwardSys.h"
1.41 -#include "PlayerManager.h"
1.42 -#include "ConCmdManager.h"
1.43 -#include "Logger.h"
1.44 -#include "sourcemod.h"
1.45 -#include "sm_stringutil.h"
1.46 -#include "sourcemm_api.h"
1.47 -#include "sm_srvcmds.h"
1.48 -
1.49 -#define LEVEL_STATE_NONE 0
1.50 -#define LEVEL_STATE_LEVELS 1
1.51 -#define LEVEL_STATE_FLAGS 2
1.52 -
1.53 -AdminCache g_Admins;
1.54 -char g_ReverseFlags[26];
1.55 -AdminFlag g_FlagLetters[26];
1.56 -bool g_FlagSet[26];
1.57 -
1.58 -ConVar sm_immunity_mode("sm_immunity_mode", "1", FCVAR_SPONLY, "Mode for deciding immunity protection");
1.59 -
1.60 -/* Default flags */
1.61 -AdminFlag g_DefaultFlags[26] =
1.62 -{
1.63 - Admin_Reservation, Admin_Generic, Admin_Kick, Admin_Ban, Admin_Unban,
1.64 - Admin_Slay, Admin_Changemap, Admin_Convars, Admin_Config, Admin_Chat,
1.65 - Admin_Vote, Admin_Password, Admin_RCON, Admin_Cheats, Admin_Custom1,
1.66 - Admin_Custom2, Admin_Custom3, Admin_Custom4, Admin_Custom5, Admin_Custom6,
1.67 - Admin_Generic, Admin_Generic, Admin_Generic, Admin_Generic, Admin_Generic,
1.68 - Admin_Root
1.69 -};
1.70 -
1.71 -
1.72 -class FlagReader : public ITextListener_SMC
1.73 -{
1.74 -public:
1.75 - void LoadLevels()
1.76 - {
1.77 - if (!Parse())
1.78 - {
1.79 - memcpy(g_FlagLetters, g_DefaultFlags, sizeof(AdminFlag) * 26);
1.80 - for (unsigned int i=0; i<20; i++)
1.81 - {
1.82 - g_FlagSet[i] = true;
1.83 - }
1.84 - g_FlagSet[25] = true;
1.85 - }
1.86 - }
1.87 -private:
1.88 - bool Parse()
1.89 - {
1.90 - SMCStates states;
1.91 - SMCError error;
1.92 -
1.93 - m_bFileNameLogged = false;
1.94 - g_SourceMod.BuildPath(Path_SM, m_File, sizeof(m_File), "configs/admin_levels.cfg");
1.95 -
1.96 - if ((error = textparsers->ParseFile_SMC(m_File, this, &states))
1.97 - != SMCError_Okay)
1.98 - {
1.99 - const char *err_string = textparsers->GetSMCErrorString(error);
1.100 - if (!err_string)
1.101 - {
1.102 - err_string = "Unknown error";
1.103 - }
1.104 - ParseError(NULL, "Error %d (%s)", error, err_string);
1.105 - return false;
1.106 - }
1.107 -
1.108 - return true;
1.109 - }
1.110 - void ReadSMC_ParseStart()
1.111 - {
1.112 - m_LevelState = LEVEL_STATE_NONE;
1.113 - m_IgnoreLevel = 0;
1.114 - memset(g_FlagSet, 0, sizeof(g_FlagSet));
1.115 - }
1.116 - SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name)
1.117 - {
1.118 - if (m_IgnoreLevel)
1.119 - {
1.120 - m_IgnoreLevel++;
1.121 - return SMCResult_Continue;
1.122 - }
1.123 -
1.124 - if (m_LevelState == LEVEL_STATE_NONE)
1.125 - {
1.126 - if (strcmp(name, "Levels") == 0)
1.127 - {
1.128 - m_LevelState = LEVEL_STATE_LEVELS;
1.129 - }
1.130 - else
1.131 - {
1.132 - m_IgnoreLevel++;
1.133 - }
1.134 - } else if (m_LevelState == LEVEL_STATE_LEVELS) {
1.135 - if (strcmp(name, "Flags") == 0)
1.136 - {
1.137 - m_LevelState = LEVEL_STATE_FLAGS;
1.138 - }
1.139 - else
1.140 - {
1.141 - m_IgnoreLevel++;
1.142 - }
1.143 - }
1.144 - else
1.145 - {
1.146 - m_IgnoreLevel++;
1.147 - }
1.148 -
1.149 - return SMCResult_Continue;
1.150 - }
1.151 - SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
1.152 - {
1.153 - if (m_LevelState != LEVEL_STATE_FLAGS || m_IgnoreLevel)
1.154 - {
1.155 - return SMCResult_Continue;
1.156 - }
1.157 -
1.158 - unsigned char c = (unsigned)value[0];
1.159 -
1.160 - if (c < (unsigned)'a' || c > (unsigned)'z')
1.161 - {
1.162 - ParseError(states, "Flag \"%c\" is not a lower-case ASCII letter", c);
1.163 - return SMCResult_Continue;
1.164 - }
1.165 -
1.166 - c -= (unsigned)'a';
1.167 -
1.168 - if (!g_Admins.FindFlag(key, &g_FlagLetters[c]))
1.169 - {
1.170 - ParseError(states, "Unrecognized admin level \"%s\"", key);
1.171 - return SMCResult_Continue;
1.172 - }
1.173 -
1.174 - g_FlagSet[c] = true;
1.175 -
1.176 - return SMCResult_Continue;
1.177 - }
1.178 - SMCResult ReadSMC_LeavingSection(const SMCStates *states)
1.179 - {
1.180 - if (m_IgnoreLevel)
1.181 - {
1.182 - m_IgnoreLevel--;
1.183 - return SMCResult_Continue;
1.184 - }
1.185 -
1.186 - if (m_LevelState == LEVEL_STATE_FLAGS)
1.187 - {
1.188 - m_LevelState = LEVEL_STATE_LEVELS;
1.189 - return SMCResult_Halt;
1.190 - }
1.191 - else if (m_LevelState == LEVEL_STATE_LEVELS)
1.192 - {
1.193 - m_LevelState = LEVEL_STATE_NONE;
1.194 - }
1.195 -
1.196 - return SMCResult_Continue;
1.197 - }
1.198 - void ParseError(const SMCStates *states, const char *message, ...)
1.199 - {
1.200 - va_list ap;
1.201 - char buffer[256];
1.202 -
1.203 - va_start(ap, message);
1.204 - UTIL_FormatArgs(buffer, sizeof(buffer), message, ap);
1.205 - va_end(ap);
1.206 -
1.207 - if (!m_bFileNameLogged)
1.208 - {
1.209 - g_Logger.LogError("[SM] Parse error(s) detected in file \"%s\":", m_File);
1.210 - m_bFileNameLogged = true;
1.211 - }
1.212 -
1.213 - g_Logger.LogError("[SM] (Line %d): %s", states ? states->line : 0, buffer);
1.214 - }
1.215 -private:
1.216 - bool m_bFileNameLogged;
1.217 - char m_File[PLATFORM_MAX_PATH];
1.218 - int m_LevelState;
1.219 - int m_IgnoreLevel;
1.220 -} s_FlagReader;
1.221 -
1.222 -AdminCache::AdminCache()
1.223 -{
1.224 - m_pCmdOverrides = sm_trie_create();
1.225 - m_pCmdGrpOverrides = sm_trie_create();
1.226 - m_pStrings = new BaseStringTable(1024);
1.227 - m_pMemory = m_pStrings->GetMemTable();
1.228 - m_FreeGroupList = m_FirstGroup = m_LastGroup = INVALID_GROUP_ID;
1.229 - m_FreeUserList = m_FirstUser = m_LastUser = INVALID_ADMIN_ID;
1.230 - m_pGroups = sm_trie_create();
1.231 - m_pCacheFwd = NULL;
1.232 - m_FirstGroup = -1;
1.233 - m_pAuthTables = sm_trie_create();
1.234 - m_InvalidatingAdmins = false;
1.235 - m_destroying = false;
1.236 - m_pLevelNames = sm_trie_create();
1.237 -}
1.238 -
1.239 -AdminCache::~AdminCache()
1.240 -{
1.241 - m_destroying = true;
1.242 - DumpAdminCache(AdminCache_Overrides, false);
1.243 - DumpAdminCache(AdminCache_Groups, false);
1.244 -
1.245 - sm_trie_destroy(m_pCmdGrpOverrides);
1.246 - sm_trie_destroy(m_pCmdOverrides);
1.247 -
1.248 - if (m_pGroups)
1.249 - {
1.250 - sm_trie_destroy(m_pGroups);
1.251 - }
1.252 -
1.253 - List<AuthMethod>::iterator iter;
1.254 - for (iter=m_AuthMethods.begin();
1.255 - iter!=m_AuthMethods.end();
1.256 - iter++)
1.257 - {
1.258 - sm_trie_destroy((*iter).table);
1.259 - }
1.260 -
1.261 - sm_trie_destroy(m_pAuthTables);
1.262 -
1.263 - delete m_pStrings;
1.264 -
1.265 - sm_trie_destroy(m_pLevelNames);
1.266 -}
1.267 -
1.268 -void AdminCache::OnSourceModStartup(bool late)
1.269 -{
1.270 - RegisterAuthIdentType("steam");
1.271 - RegisterAuthIdentType("name");
1.272 - RegisterAuthIdentType("ip");
1.273 -
1.274 - NameFlag("reservation", Admin_Reservation);
1.275 - NameFlag("kick", Admin_Kick);
1.276 - NameFlag("generic", Admin_Generic);
1.277 - NameFlag("ban", Admin_Ban);
1.278 - NameFlag("unban", Admin_Unban);
1.279 - NameFlag("slay", Admin_Slay);
1.280 - NameFlag("changemap", Admin_Changemap);
1.281 - NameFlag("cvars", Admin_Convars);
1.282 - NameFlag("config", Admin_Config);
1.283 - NameFlag("chat", Admin_Chat);
1.284 - NameFlag("vote", Admin_Vote);
1.285 - NameFlag("password", Admin_Password);
1.286 - NameFlag("rcon", Admin_RCON);
1.287 - NameFlag("cheats", Admin_Cheats);
1.288 - NameFlag("root", Admin_Root);
1.289 - NameFlag("custom1", Admin_Custom1);
1.290 - NameFlag("custom2", Admin_Custom2);
1.291 - NameFlag("custom3", Admin_Custom3);
1.292 - NameFlag("custom4", Admin_Custom4);
1.293 - NameFlag("custom5", Admin_Custom5);
1.294 - NameFlag("custom6", Admin_Custom6);
1.295 -}
1.296 -
1.297 -void AdminCache::OnSourceModAllInitialized()
1.298 -{
1.299 - m_pCacheFwd = g_Forwards.CreateForward("OnRebuildAdminCache", ET_Ignore, 1, NULL, Param_Cell);
1.300 - g_ShareSys.AddInterface(NULL, this);
1.301 -}
1.302 -
1.303 -void AdminCache::OnSourceModLevelChange(const char *mapName)
1.304 -{
1.305 - int i;
1.306 - AdminFlag flag;
1.307 -
1.308 - /* For now, we only read these once per level. */
1.309 - s_FlagReader.LoadLevels();
1.310 -
1.311 - for (i = 0; i < 26; i++)
1.312 - {
1.313 - if (FindFlag('a' + i, &flag))
1.314 - {
1.315 - g_ReverseFlags[flag] = 'a' + i;
1.316 - }
1.317 - else
1.318 - {
1.319 - g_ReverseFlags[flag] = '?';
1.320 - }
1.321 - }
1.322 -}
1.323 -
1.324 -void AdminCache::OnSourceModShutdown()
1.325 -{
1.326 - g_Forwards.ReleaseForward(m_pCacheFwd);
1.327 - m_pCacheFwd = NULL;
1.328 -}
1.329 -
1.330 -void AdminCache::OnSourceModPluginsLoaded()
1.331 -{
1.332 - DumpAdminCache(AdminCache_Overrides, true);
1.333 - DumpAdminCache(AdminCache_Groups, true);
1.334 -}
1.335 -
1.336 -void AdminCache::NameFlag(const char *str, AdminFlag flag)
1.337 -{
1.338 - sm_trie_insert(m_pLevelNames, str, (void *)flag);
1.339 -}
1.340 -
1.341 -bool AdminCache::FindFlag(const char *str, AdminFlag *pFlag)
1.342 -{
1.343 - void *obj;
1.344 - if (!sm_trie_retrieve(m_pLevelNames, str, &obj))
1.345 - {
1.346 - return false;
1.347 - }
1.348 -
1.349 - if (pFlag)
1.350 - {
1.351 - *pFlag = (AdminFlag)(int)obj;
1.352 - }
1.353 -
1.354 - return true;
1.355 -}
1.356 -
1.357 -void AdminCache::AddCommandOverride(const char *cmd, OverrideType type, FlagBits flags)
1.358 -{
1.359 - Trie *pTrie = NULL;
1.360 - if (type == Override_Command)
1.361 - {
1.362 - pTrie = m_pCmdOverrides;
1.363 - } else if (type == Override_CommandGroup) {
1.364 - pTrie = m_pCmdGrpOverrides;
1.365 - } else {
1.366 - return;
1.367 - }
1.368 -
1.369 - sm_trie_insert(pTrie, cmd, (void *)(unsigned int)flags);
1.370 -
1.371 - g_ConCmds.UpdateAdminCmdFlags(cmd, type, flags, false);
1.372 -}
1.373 -
1.374 -bool AdminCache::GetCommandOverride(const char *cmd, OverrideType type, FlagBits *pFlags)
1.375 -{
1.376 - Trie *pTrie = NULL;
1.377 -
1.378 - if (type == Override_Command)
1.379 - {
1.380 - pTrie = m_pCmdOverrides;
1.381 - } else if (type == Override_CommandGroup) {
1.382 - pTrie = m_pCmdGrpOverrides;
1.383 - } else {
1.384 - return false;
1.385 - }
1.386 -
1.387 - void *object;
1.388 - if (sm_trie_retrieve(pTrie, cmd, &object))
1.389 - {
1.390 - if (pFlags)
1.391 - {
1.392 - *pFlags = (FlagBits)object;
1.393 - }
1.394 - return true;
1.395 - }
1.396 -
1.397 - return false;
1.398 -}
1.399 -
1.400 -void AdminCache::UnsetCommandOverride(const char *cmd, OverrideType type)
1.401 -{
1.402 - if (type == Override_Command)
1.403 - {
1.404 - return _UnsetCommandOverride(cmd);
1.405 - } else if (type == Override_CommandGroup) {
1.406 - return _UnsetCommandGroupOverride(cmd);
1.407 - }
1.408 -}
1.409 -
1.410 -void AdminCache::_UnsetCommandGroupOverride(const char *group)
1.411 -{
1.412 - if (!m_pCmdGrpOverrides)
1.413 - {
1.414 - return;
1.415 - }
1.416 -
1.417 - sm_trie_delete(m_pCmdGrpOverrides, group);
1.418 -
1.419 - g_ConCmds.UpdateAdminCmdFlags(group, Override_CommandGroup, 0, true);
1.420 -}
1.421 -
1.422 -void AdminCache::_UnsetCommandOverride(const char *cmd)
1.423 -{
1.424 - if (!m_pCmdOverrides)
1.425 - {
1.426 - return;
1.427 - }
1.428 -
1.429 - sm_trie_delete(m_pCmdOverrides, cmd);
1.430 -
1.431 - g_ConCmds.UpdateAdminCmdFlags(cmd, Override_Command, 0, true);
1.432 -}
1.433 -
1.434 -void AdminCache::DumpCommandOverrideCache(OverrideType type)
1.435 -{
1.436 - if (type == Override_Command && m_pCmdOverrides)
1.437 - {
1.438 - sm_trie_clear(m_pCmdOverrides);
1.439 - } else if (type == Override_CommandGroup && m_pCmdGrpOverrides) {
1.440 - sm_trie_clear(m_pCmdGrpOverrides);
1.441 - }
1.442 -}
1.443 -
1.444 -AdminId AdminCache::CreateAdmin(const char *name)
1.445 -{
1.446 - AdminId id;
1.447 - AdminUser *pUser;
1.448 -
1.449 - if (m_FreeUserList != INVALID_ADMIN_ID)
1.450 - {
1.451 - pUser = (AdminUser *)m_pMemory->GetAddress(m_FreeUserList);
1.452 - assert(pUser->magic == USR_MAGIC_UNSET);
1.453 - id = m_FreeUserList;
1.454 - m_FreeUserList = pUser->next_user;
1.455 - }
1.456 - else
1.457 - {
1.458 - id = m_pMemory->CreateMem(sizeof(AdminUser), (void **)&pUser);
1.459 - pUser->grp_size = 0;
1.460 - pUser->grp_table = -1;
1.461 - }
1.462 -
1.463 - pUser->flags = 0;
1.464 - pUser->eflags = 0;
1.465 - pUser->grp_count = 0;
1.466 - pUser->password = -1;
1.467 - pUser->magic = USR_MAGIC_SET;
1.468 - pUser->auth.identidx = -1;
1.469 - pUser->auth.index = 0;
1.470 - pUser->immunity_level = 0;
1.471 - pUser->serialchange = 1;
1.472 -
1.473 - if (m_FirstUser == INVALID_ADMIN_ID)
1.474 - {
1.475 - m_FirstUser = id;
1.476 - m_LastUser = id;
1.477 - }
1.478 - else
1.479 - {
1.480 - AdminUser *pPrev = (AdminUser *)m_pMemory->GetAddress(m_LastUser);
1.481 - pPrev->next_user = id;
1.482 - pUser->prev_user = m_LastUser;
1.483 - m_LastUser = id;
1.484 - }
1.485 -
1.486 - /* Since we always append to the tail, we should invalidate their next */
1.487 - pUser->next_user = -1;
1.488 -
1.489 - if (name && name[0] != '\0')
1.490 - {
1.491 - int nameidx = m_pStrings->AddString(name);
1.492 - pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.493 - pUser->nameidx = nameidx;
1.494 - }
1.495 - else
1.496 - {
1.497 - pUser->nameidx = -1;
1.498 - }
1.499 -
1.500 - return id;
1.501 -}
1.502 -
1.503 -GroupId AdminCache::AddGroup(const char *group_name)
1.504 -{
1.505 - if (sm_trie_retrieve(m_pGroups, group_name, NULL))
1.506 - {
1.507 - return INVALID_GROUP_ID;
1.508 - }
1.509 -
1.510 - GroupId id;
1.511 - AdminGroup *pGroup;
1.512 - if (m_FreeGroupList != INVALID_GROUP_ID)
1.513 - {
1.514 - pGroup = (AdminGroup *)m_pMemory->GetAddress(m_FreeGroupList);
1.515 - assert(pGroup->magic == GRP_MAGIC_UNSET);
1.516 - id = m_FreeGroupList;
1.517 - m_FreeGroupList = pGroup->next_grp;
1.518 - } else {
1.519 - id = m_pMemory->CreateMem(sizeof(AdminGroup), (void **)&pGroup);
1.520 - }
1.521 -
1.522 - pGroup->immunity_level = 0;
1.523 - pGroup->immune_table = -1;
1.524 - pGroup->magic = GRP_MAGIC_SET;
1.525 - pGroup->next_grp = INVALID_GROUP_ID;
1.526 - pGroup->pCmdGrpTable = NULL;
1.527 - pGroup->pCmdTable = NULL;
1.528 - pGroup->addflags = 0;
1.529 -
1.530 - if (m_FirstGroup == INVALID_GROUP_ID)
1.531 - {
1.532 - m_FirstGroup = id;
1.533 - m_LastGroup = id;
1.534 - pGroup->prev_grp = INVALID_GROUP_ID;
1.535 - } else {
1.536 - AdminGroup *pPrev = (AdminGroup *)m_pMemory->GetAddress(m_LastGroup);
1.537 - assert(pPrev->magic == GRP_MAGIC_SET);
1.538 - pPrev->next_grp = id;
1.539 - pGroup->prev_grp = m_LastGroup;
1.540 - m_LastGroup = id;
1.541 - }
1.542 -
1.543 - int nameidx = m_pStrings->AddString(group_name);
1.544 - pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
1.545 - pGroup->nameidx = nameidx;
1.546 -
1.547 - sm_trie_insert(m_pGroups, group_name, (void *)id);
1.548 -
1.549 - return id;
1.550 -}
1.551 -
1.552 -GroupId AdminCache::FindGroupByName(const char *group_name)
1.553 -{
1.554 - void *object;
1.555 -
1.556 - if (!sm_trie_retrieve(m_pGroups, group_name, &object))
1.557 - {
1.558 - return INVALID_GROUP_ID;
1.559 - }
1.560 -
1.561 - GroupId id = (GroupId)object;
1.562 - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
1.563 -
1.564 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.565 - {
1.566 - return INVALID_GROUP_ID;
1.567 - }
1.568 -
1.569 - return id;
1.570 -}
1.571 -
1.572 -void AdminCache::SetGroupAddFlag(GroupId id, AdminFlag flag, bool enabled)
1.573 -{
1.574 - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
1.575 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.576 - {
1.577 - return;
1.578 - }
1.579 -
1.580 - if (flag < Admin_Reservation || flag >= AdminFlags_TOTAL)
1.581 - {
1.582 - return;
1.583 - }
1.584 -
1.585 - FlagBits bits = (1<<(FlagBits)flag);
1.586 -
1.587 - if (enabled)
1.588 - {
1.589 - pGroup->addflags |= bits;
1.590 - } else {
1.591 - pGroup->addflags &= ~bits;
1.592 - }
1.593 -}
1.594 -
1.595 -bool AdminCache::GetGroupAddFlag(GroupId id, AdminFlag flag)
1.596 -{
1.597 - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
1.598 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.599 - {
1.600 - return false;
1.601 - }
1.602 -
1.603 - if (flag < Admin_Reservation || flag >= AdminFlags_TOTAL)
1.604 - {
1.605 - return false;
1.606 - }
1.607 -
1.608 - FlagBits bit = 1<<(FlagBits)flag;
1.609 - return ((pGroup->addflags & bit) == bit);
1.610 -}
1.611 -
1.612 -FlagBits AdminCache::GetGroupAddFlags(GroupId id)
1.613 -{
1.614 - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
1.615 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.616 - {
1.617 - return 0;
1.618 - }
1.619 -
1.620 - return pGroup->addflags;
1.621 -}
1.622 -
1.623 -const char *AdminCache::GetGroupName(GroupId gid)
1.624 -{
1.625 - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(gid);
1.626 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.627 - {
1.628 - return NULL;
1.629 - }
1.630 -
1.631 - return m_pStrings->GetString(pGroup->nameidx);
1.632 -}
1.633 -
1.634 -void AdminCache::SetGroupGenericImmunity(GroupId id, ImmunityType type, bool enabled)
1.635 -{
1.636 - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
1.637 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.638 - {
1.639 - return;
1.640 - }
1.641 -
1.642 - unsigned int level = 0;
1.643 -
1.644 - if (enabled)
1.645 - {
1.646 - if (type == Immunity_Default)
1.647 - {
1.648 - level = 1;
1.649 - } else if (type == Immunity_Global) {
1.650 - level = 2;
1.651 - }
1.652 - if (level > pGroup->immunity_level)
1.653 - {
1.654 - pGroup->immunity_level = level;
1.655 - }
1.656 - } else {
1.657 - pGroup->immunity_level = 0;
1.658 - }
1.659 -}
1.660 -
1.661 -bool AdminCache::GetGroupGenericImmunity(GroupId id, ImmunityType type)
1.662 -{
1.663 - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
1.664 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.665 - {
1.666 - return false;
1.667 - }
1.668 -
1.669 - if (type == Immunity_Default && pGroup->immunity_level >= 1)
1.670 - {
1.671 - return true;
1.672 - } else if (type == Immunity_Global && pGroup->immunity_level >= 2) {
1.673 - return true;
1.674 - }
1.675 -
1.676 - return false;
1.677 -}
1.678 -
1.679 -void AdminCache::AddGroupImmunity(GroupId id, GroupId other_id)
1.680 -{
1.681 - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(other_id);
1.682 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.683 - {
1.684 - return;
1.685 - }
1.686 -
1.687 - pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
1.688 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.689 - {
1.690 - return;
1.691 - }
1.692 -
1.693 - /* We always need to resize the immunity table */
1.694 - int *table, tblidx;
1.695 - if (pGroup->immune_table == -1)
1.696 - {
1.697 - tblidx = m_pMemory->CreateMem(sizeof(int) * 2, (void **)&table);
1.698 - pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
1.699 - table[0] = 0;
1.700 - } else {
1.701 - int *old_table = (int *)m_pMemory->GetAddress(pGroup->immune_table);
1.702 - /* Break out if this group is already in the list */
1.703 - for (int i=0; i<old_table[0]; i++)
1.704 - {
1.705 - if (old_table[1+i] == other_id)
1.706 - {
1.707 - return;
1.708 - }
1.709 - }
1.710 - tblidx = m_pMemory->CreateMem(sizeof(int) * (old_table[0] + 2), (void **)&table);
1.711 - /* Get the old address again in case of resize */
1.712 - pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
1.713 - old_table = (int *)m_pMemory->GetAddress(pGroup->immune_table);
1.714 - table[0] = old_table[0];
1.715 - for (unsigned int i=1; i<=(unsigned int)old_table[0]; i++)
1.716 - {
1.717 - table[i] = old_table[i];
1.718 - }
1.719 - }
1.720 -
1.721 - /* Assign */
1.722 - pGroup->immune_table = tblidx;
1.723 -
1.724 - /* Add to the array */
1.725 - table[0]++;
1.726 - table[table[0]] = other_id;
1.727 -}
1.728 -
1.729 -unsigned int AdminCache::GetGroupImmunityCount(GroupId id)
1.730 -{
1.731 - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
1.732 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.733 - {
1.734 - return 0;
1.735 - }
1.736 -
1.737 - if (pGroup->immune_table == -1)
1.738 - {
1.739 - return 0;
1.740 - }
1.741 -
1.742 - int *table = (int *)m_pMemory->GetAddress(pGroup->immune_table);
1.743 -
1.744 - return table[0];
1.745 -}
1.746 -
1.747 -GroupId AdminCache::GetGroupImmunity(GroupId id, unsigned int number)
1.748 -{
1.749 - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
1.750 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.751 - {
1.752 - return INVALID_GROUP_ID;
1.753 - }
1.754 -
1.755 - if (pGroup->immune_table == -1)
1.756 - {
1.757 - return INVALID_GROUP_ID;
1.758 - }
1.759 -
1.760 - int *table = (int *)m_pMemory->GetAddress(pGroup->immune_table);
1.761 - if (number >= (unsigned int)table[0])
1.762 - {
1.763 - return INVALID_GROUP_ID;
1.764 - }
1.765 -
1.766 - return table[1 + number];
1.767 -}
1.768 -
1.769 -void AdminCache::AddGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule rule)
1.770 -{
1.771 - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
1.772 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.773 - {
1.774 - return;
1.775 - }
1.776 -
1.777 - Trie *pTrie = NULL;
1.778 - if (type == Override_Command)
1.779 - {
1.780 - if (pGroup->pCmdTable == NULL)
1.781 - {
1.782 - pGroup->pCmdTable = sm_trie_create();
1.783 - }
1.784 - pTrie = pGroup->pCmdTable;
1.785 - } else if (type == Override_CommandGroup) {
1.786 - if (pGroup->pCmdGrpTable == NULL)
1.787 - {
1.788 - pGroup->pCmdGrpTable = sm_trie_create();
1.789 - }
1.790 - pTrie = pGroup->pCmdGrpTable;
1.791 - } else {
1.792 - return;
1.793 - }
1.794 -
1.795 - sm_trie_insert(pTrie, name, (void *)(int)rule);
1.796 -}
1.797 -
1.798 -bool AdminCache::GetGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule *pRule)
1.799 -{
1.800 - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
1.801 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.802 - {
1.803 - return false;
1.804 - }
1.805 -
1.806 - Trie *pTrie = NULL;
1.807 - if (type == Override_Command)
1.808 - {
1.809 - if (pGroup->pCmdTable == NULL)
1.810 - {
1.811 - return false;
1.812 - }
1.813 - pTrie = pGroup->pCmdTable;
1.814 - } else if (type == Override_CommandGroup) {
1.815 - if (pGroup->pCmdGrpTable == NULL)
1.816 - {
1.817 - return false;
1.818 - }
1.819 - pTrie = pGroup->pCmdGrpTable;
1.820 - } else {
1.821 - return false;
1.822 - }
1.823 -
1.824 - void *object;
1.825 - if (!sm_trie_retrieve(pTrie, name, &object))
1.826 - {
1.827 - return false;
1.828 - }
1.829 -
1.830 - if (pRule)
1.831 - {
1.832 - *pRule = (OverrideRule)(int)object;
1.833 - }
1.834 -
1.835 - return true;
1.836 -}
1.837 -
1.838 -Trie *AdminCache::GetMethodByIndex(unsigned int index)
1.839 -{
1.840 - List<AuthMethod>::iterator iter;
1.841 - for (iter=m_AuthMethods.begin();
1.842 - iter!=m_AuthMethods.end();
1.843 - iter++)
1.844 - {
1.845 - if (index-- == 0)
1.846 - {
1.847 - return (*iter).table;
1.848 - }
1.849 - }
1.850 -
1.851 - return NULL;
1.852 -}
1.853 -
1.854 -bool AdminCache::InvalidateAdmin(AdminId id)
1.855 -{
1.856 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.857 - AdminUser *pOther;
1.858 - if (!pUser || pUser->magic != USR_MAGIC_SET)
1.859 - {
1.860 - return false;
1.861 - }
1.862 -
1.863 - if (!m_InvalidatingAdmins && !m_destroying)
1.864 - {
1.865 - g_Players.ClearAdminId(id);
1.866 - }
1.867 -
1.868 - /* Unlink from the dbl link list */
1.869 - if (id == m_FirstUser && id == m_LastUser)
1.870 - {
1.871 - m_FirstUser = INVALID_ADMIN_ID;
1.872 - m_LastUser = INVALID_ADMIN_ID;
1.873 - } else if (id == m_FirstUser) {
1.874 - m_FirstUser = pUser->next_user;
1.875 - pOther = (AdminUser *)m_pMemory->GetAddress(m_FirstUser);
1.876 - pOther->prev_user = INVALID_ADMIN_ID;
1.877 - } else if (id == m_LastUser) {
1.878 - m_LastUser = pUser->prev_user;
1.879 - pOther = (AdminUser *)m_pMemory->GetAddress(m_LastUser);
1.880 - pOther->next_user = INVALID_ADMIN_ID;
1.881 - } else {
1.882 - pOther = (AdminUser *)m_pMemory->GetAddress(pUser->prev_user);
1.883 - pOther->next_user = pUser->next_user;
1.884 - pOther = (AdminUser *)m_pMemory->GetAddress(pUser->next_user);
1.885 - pOther->prev_user = pUser->prev_user;
1.886 - }
1.887 -
1.888 - /* Unlink from auth tables */
1.889 - if (pUser->auth.identidx != -1)
1.890 - {
1.891 - Trie *pTrie = GetMethodByIndex(pUser->auth.index);
1.892 - if (pTrie)
1.893 - {
1.894 - sm_trie_delete(pTrie, m_pStrings->GetString(pUser->auth.identidx));
1.895 - }
1.896 - }
1.897 -
1.898 - /* Clear table counts */
1.899 - pUser->grp_count = 0;
1.900 -
1.901 - /* Link into free list */
1.902 - pUser->magic = USR_MAGIC_UNSET;
1.903 - pUser->next_user = m_FreeUserList;
1.904 - m_FreeUserList = id;
1.905 -
1.906 - /* Unset serial change */
1.907 - pUser->serialchange = 0;
1.908 -
1.909 - return true;
1.910 -}
1.911 -
1.912 -
1.913 -void AdminCache::InvalidateGroup(GroupId id)
1.914 -{
1.915 - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
1.916 - AdminGroup *pOther;
1.917 -
1.918 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.919 - {
1.920 - return;
1.921 - }
1.922 -
1.923 - const char *str = m_pStrings->GetString(pGroup->nameidx);
1.924 - sm_trie_delete(m_pGroups, str);
1.925 -
1.926 - /* Unlink from the live dbllink list */
1.927 - if (id == m_FirstGroup && id == m_LastGroup)
1.928 - {
1.929 - m_LastGroup = INVALID_GROUP_ID;
1.930 - m_FirstGroup = INVALID_GROUP_ID;
1.931 - } else if (id == m_FirstGroup) {
1.932 - m_FirstGroup = pGroup->next_grp;
1.933 - pOther = (AdminGroup *)m_pMemory->GetAddress(m_FirstGroup);
1.934 - pOther->prev_grp = INVALID_GROUP_ID;
1.935 - } else if (id == m_LastGroup) {
1.936 - m_LastGroup = pGroup->prev_grp;
1.937 - pOther = (AdminGroup *)m_pMemory->GetAddress(m_LastGroup);
1.938 - pOther->next_grp = INVALID_GROUP_ID;
1.939 - } else {
1.940 - pOther = (AdminGroup *)m_pMemory->GetAddress(pGroup->prev_grp);
1.941 - pOther->next_grp = pGroup->next_grp;
1.942 - pOther = (AdminGroup *)m_pMemory->GetAddress(pGroup->next_grp);
1.943 - pOther->prev_grp = pGroup->prev_grp;
1.944 - }
1.945 -
1.946 - /* Free any used memory to be safe */
1.947 - if (pGroup->pCmdGrpTable)
1.948 - {
1.949 - sm_trie_destroy(pGroup->pCmdGrpTable);
1.950 - pGroup->pCmdGrpTable = NULL;
1.951 - }
1.952 - if (pGroup->pCmdTable)
1.953 - {
1.954 - sm_trie_destroy(pGroup->pCmdTable);
1.955 - pGroup->pCmdTable = NULL;
1.956 - }
1.957 -
1.958 - /* Link into the free list */
1.959 - pGroup->magic = GRP_MAGIC_UNSET;
1.960 - pGroup->next_grp = m_FreeGroupList;
1.961 - m_FreeGroupList = id;
1.962 -
1.963 - int idx = m_FirstUser;
1.964 - AdminUser *pUser;
1.965 - int *table;
1.966 - while (idx != INVALID_ADMIN_ID)
1.967 - {
1.968 - pUser = (AdminUser *)m_pMemory->GetAddress(idx);
1.969 - if (pUser->grp_count > 0)
1.970 - {
1.971 - table = (int *)m_pMemory->GetAddress(pUser->grp_table);
1.972 - for (unsigned int i=0; i<pUser->grp_count; i++)
1.973 - {
1.974 - if (table[i] == id)
1.975 - {
1.976 - /* We have to remove this entry */
1.977 - for (unsigned int j=i+1; j<pUser->grp_count; j++)
1.978 - {
1.979 - /* Move everything down by one */
1.980 - table[j-1] = table[j];
1.981 - }
1.982 - /* Decrease count */
1.983 - pUser->grp_count--;
1.984 - /* Recalculate effective flags */
1.985 - pUser->eflags = pUser->flags;
1.986 - for (unsigned int j=0; j<pUser->grp_count; j++)
1.987 - {
1.988 - pOther = (AdminGroup *)m_pMemory->GetAddress(table[j]);
1.989 - pUser->eflags |= pOther->addflags;
1.990 - }
1.991 - /* Mark as changed */
1.992 - pUser->serialchange++;
1.993 - /* Break now, duplicates aren't allowed */
1.994 - break;
1.995 - }
1.996 - }
1.997 - }
1.998 - idx = pUser->next_user;
1.999 - }
1.1000 -}
1.1001 -
1.1002 -void AdminCache::InvalidateGroupCache()
1.1003 -{
1.1004 - /* Nuke the free list */
1.1005 - m_FreeGroupList = -1;
1.1006 -
1.1007 - /* Nuke reverse lookups */
1.1008 - sm_trie_clear(m_pGroups);
1.1009 -
1.1010 - /* Free memory on groups */
1.1011 - GroupId cur = m_FirstGroup;
1.1012 - AdminGroup *pGroup;
1.1013 - while (cur != INVALID_GROUP_ID)
1.1014 - {
1.1015 - pGroup = (AdminGroup *)m_pMemory->GetAddress(cur);
1.1016 - assert(pGroup->magic == GRP_MAGIC_SET);
1.1017 - if (pGroup->pCmdGrpTable)
1.1018 - {
1.1019 - sm_trie_destroy(pGroup->pCmdGrpTable);
1.1020 - }
1.1021 - if (pGroup->pCmdTable)
1.1022 - {
1.1023 - sm_trie_destroy(pGroup->pCmdTable);
1.1024 - }
1.1025 - cur = pGroup->next_grp;
1.1026 - }
1.1027 -
1.1028 - m_FirstGroup = INVALID_GROUP_ID;
1.1029 - m_LastGroup = INVALID_GROUP_ID;
1.1030 -
1.1031 - InvalidateAdminCache(false);
1.1032 -
1.1033 - /* Reset the memory table */
1.1034 - m_pMemory->Reset();
1.1035 -}
1.1036 -
1.1037 -void AdminCache::AddAdminListener(IAdminListener *pListener)
1.1038 -{
1.1039 - m_hooks.push_back(pListener);
1.1040 -}
1.1041 -
1.1042 -void AdminCache::RemoveAdminListener(IAdminListener *pListener)
1.1043 -{
1.1044 - m_hooks.remove(pListener);
1.1045 -}
1.1046 -
1.1047 -void AdminCache::RegisterAuthIdentType(const char *name)
1.1048 -{
1.1049 - if (sm_trie_retrieve(m_pAuthTables, name, NULL))
1.1050 - {
1.1051 - return;
1.1052 - }
1.1053 -
1.1054 - Trie *pAuth = sm_trie_create();
1.1055 -
1.1056 - AuthMethod method;
1.1057 - method.name.assign(name);
1.1058 - method.table = pAuth;
1.1059 -
1.1060 - m_AuthMethods.push_back(method);
1.1061 -
1.1062 - sm_trie_insert(m_pAuthTables, name, pAuth);
1.1063 -}
1.1064 -
1.1065 -void AdminCache::InvalidateAdminCache(bool unlink_admins)
1.1066 -{
1.1067 - m_InvalidatingAdmins = true;
1.1068 - if (!m_destroying)
1.1069 - {
1.1070 - g_Players.ClearAllAdmins();
1.1071 - }
1.1072 - /* Wipe the identity cache first */
1.1073 - List<AuthMethod>::iterator iter;
1.1074 - for (iter=m_AuthMethods.begin();
1.1075 - iter!=m_AuthMethods.end();
1.1076 - iter++)
1.1077 - {
1.1078 - sm_trie_clear((*iter).table);
1.1079 - }
1.1080 -
1.1081 - if (unlink_admins)
1.1082 - {
1.1083 - while (m_FirstUser != INVALID_ADMIN_ID)
1.1084 - {
1.1085 - InvalidateAdmin(m_FirstUser);
1.1086 - }
1.1087 - } else {
1.1088 - m_FirstUser = -1;
1.1089 - m_LastUser = -1;
1.1090 - m_FreeUserList = -1;
1.1091 - }
1.1092 - m_InvalidatingAdmins = false;
1.1093 -}
1.1094 -
1.1095 -void AdminCache::DumpAdminCache(AdminCachePart part, bool rebuild)
1.1096 -{
1.1097 - List<IAdminListener *>::iterator iter;
1.1098 - IAdminListener *pListener;
1.1099 - cell_t result;
1.1100 -
1.1101 - if (part == AdminCache_Overrides)
1.1102 - {
1.1103 - DumpCommandOverrideCache(Override_Command);
1.1104 - DumpCommandOverrideCache(Override_CommandGroup);
1.1105 - if (rebuild && !m_destroying)
1.1106 - {
1.1107 - for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
1.1108 - {
1.1109 - pListener = (*iter);
1.1110 - pListener->OnRebuildOverrideCache();
1.1111 - }
1.1112 - m_pCacheFwd->PushCell(part);
1.1113 - m_pCacheFwd->Execute(&result);
1.1114 - }
1.1115 - } else if (part == AdminCache_Groups || part == AdminCache_Admins) {
1.1116 - if (part == AdminCache_Groups)
1.1117 - {
1.1118 - InvalidateGroupCache();
1.1119 - if (rebuild && !m_destroying)
1.1120 - {
1.1121 - for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
1.1122 - {
1.1123 - pListener = (*iter);
1.1124 - pListener->OnRebuildGroupCache();
1.1125 - }
1.1126 - m_pCacheFwd->PushCell(part);
1.1127 - m_pCacheFwd->Execute(&result);
1.1128 - }
1.1129 - }
1.1130 - InvalidateAdminCache(true);
1.1131 - if (rebuild && !m_destroying)
1.1132 - {
1.1133 - for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
1.1134 - {
1.1135 - pListener = (*iter);
1.1136 - pListener->OnRebuildAdminCache((part == AdminCache_Groups));
1.1137 - }
1.1138 - m_pCacheFwd->PushCell(AdminCache_Admins);
1.1139 - m_pCacheFwd->Execute(&result);
1.1140 - g_Players.RecheckAnyAdmins();
1.1141 - }
1.1142 - }
1.1143 -}
1.1144 -
1.1145 -const char *AdminCache::GetAdminName(AdminId id)
1.1146 -{
1.1147 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1148 - if (!pUser || pUser->magic != USR_MAGIC_SET)
1.1149 - {
1.1150 - return NULL;
1.1151 - }
1.1152 -
1.1153 - return m_pStrings->GetString(pUser->nameidx);
1.1154 -}
1.1155 -
1.1156 -bool AdminCache::GetMethodIndex(const char *name, unsigned int *_index)
1.1157 -{
1.1158 - List<AuthMethod>::iterator iter;
1.1159 - unsigned int index = 0;
1.1160 - for (iter=m_AuthMethods.begin();
1.1161 - iter!=m_AuthMethods.end();
1.1162 - iter++,index++)
1.1163 - {
1.1164 - if ((*iter).name.compare(name) == 0)
1.1165 - {
1.1166 - *_index = index;
1.1167 - return true;
1.1168 - }
1.1169 - }
1.1170 -
1.1171 - return false;
1.1172 -}
1.1173 -
1.1174 -bool AdminCache::BindAdminIdentity(AdminId id, const char *auth, const char *ident)
1.1175 -{
1.1176 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1177 - if (!pUser || pUser->magic != USR_MAGIC_SET)
1.1178 - {
1.1179 - return false;
1.1180 - }
1.1181 -
1.1182 - Trie *pTable;
1.1183 - if (!sm_trie_retrieve(m_pAuthTables, auth, (void **)&pTable))
1.1184 - {
1.1185 - return false;
1.1186 - }
1.1187 -
1.1188 - if (sm_trie_retrieve(pTable, ident, NULL))
1.1189 - {
1.1190 - return false;
1.1191 - }
1.1192 -
1.1193 - int i_ident = m_pStrings->AddString(ident);
1.1194 -
1.1195 - pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1196 - pUser->auth.identidx = i_ident;
1.1197 - GetMethodIndex(auth, &pUser->auth.index);
1.1198 -
1.1199 - return sm_trie_insert(pTable, ident, (void **)id);
1.1200 -}
1.1201 -
1.1202 -AdminId AdminCache::FindAdminByIdentity(const char *auth, const char *identity)
1.1203 -{
1.1204 - Trie *pTable;
1.1205 - if (!sm_trie_retrieve(m_pAuthTables, auth, (void **)&pTable))
1.1206 - {
1.1207 - return INVALID_ADMIN_ID;
1.1208 - }
1.1209 -
1.1210 - void *object;
1.1211 - if (!sm_trie_retrieve(pTable, identity, &object))
1.1212 - {
1.1213 - return INVALID_ADMIN_ID;
1.1214 - }
1.1215 -
1.1216 - return (AdminId)object;
1.1217 -}
1.1218 -
1.1219 -void AdminCache::SetAdminFlag(AdminId id, AdminFlag flag, bool enabled)
1.1220 -{
1.1221 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1222 - if (!pUser || pUser->magic != USR_MAGIC_SET)
1.1223 - {
1.1224 - return;
1.1225 - }
1.1226 -
1.1227 - if (flag < Admin_Reservation
1.1228 - || flag >= AdminFlags_TOTAL)
1.1229 - {
1.1230 - return;
1.1231 - }
1.1232 -
1.1233 - FlagBits bits = (1<<(FlagBits)flag);
1.1234 -
1.1235 - if (enabled)
1.1236 - {
1.1237 - pUser->flags |= bits;
1.1238 - pUser->eflags |= bits;
1.1239 - } else {
1.1240 - pUser->flags &= ~bits;
1.1241 - pUser->eflags &= ~bits;
1.1242 - }
1.1243 -
1.1244 - pUser->serialchange++;
1.1245 -}
1.1246 -
1.1247 -bool AdminCache::GetAdminFlag(AdminId id, AdminFlag flag, AccessMode mode)
1.1248 -{
1.1249 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1250 - if (!pUser || pUser->magic != USR_MAGIC_SET)
1.1251 - {
1.1252 - return false;
1.1253 - }
1.1254 -
1.1255 - if (flag < Admin_Reservation
1.1256 - || flag >= AdminFlags_TOTAL)
1.1257 - {
1.1258 - return false;
1.1259 - }
1.1260 -
1.1261 - FlagBits bit = (1<<(FlagBits)flag);
1.1262 -
1.1263 - if (mode == Access_Real)
1.1264 - {
1.1265 - return ((pUser->flags & bit) == bit);
1.1266 - } else if (mode == Access_Effective) {
1.1267 - bool has_bit = ((pUser->eflags & bit) == bit);
1.1268 - if (!has_bit && flag != Admin_Root && ((pUser->eflags & ADMFLAG_ROOT) == ADMFLAG_ROOT))
1.1269 - {
1.1270 - has_bit = true;
1.1271 - }
1.1272 - return has_bit;
1.1273 - }
1.1274 -
1.1275 - return false;
1.1276 -}
1.1277 -
1.1278 -FlagBits AdminCache::GetAdminFlags(AdminId id, AccessMode mode)
1.1279 -{
1.1280 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1281 - if (!pUser || pUser->magic != USR_MAGIC_SET)
1.1282 - {
1.1283 - return 0;
1.1284 - }
1.1285 -
1.1286 - if (mode == Access_Real)
1.1287 - {
1.1288 - return pUser->flags;
1.1289 - } else if (mode == Access_Effective) {
1.1290 - return pUser->eflags;
1.1291 - }
1.1292 -
1.1293 - return 0;
1.1294 -}
1.1295 -
1.1296 -void AdminCache::SetAdminFlags(AdminId id, AccessMode mode, FlagBits bits)
1.1297 -{
1.1298 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1299 - if (!pUser || pUser->magic != USR_MAGIC_SET)
1.1300 - {
1.1301 - return;
1.1302 - }
1.1303 -
1.1304 - if (mode == Access_Real)
1.1305 - {
1.1306 - pUser->flags = bits;
1.1307 - pUser->eflags = bits;
1.1308 - } else if (mode == Access_Effective) {
1.1309 - pUser->eflags = bits;
1.1310 - }
1.1311 -
1.1312 - pUser->serialchange++;
1.1313 -}
1.1314 -
1.1315 -bool AdminCache::AdminInheritGroup(AdminId id, GroupId gid)
1.1316 -{
1.1317 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1318 - if (!pUser || pUser->magic != USR_MAGIC_SET)
1.1319 - {
1.1320 - return false;
1.1321 - }
1.1322 -
1.1323 - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(gid);
1.1324 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.1325 - {
1.1326 - return false;
1.1327 - }
1.1328 -
1.1329 - /* First check for duplicates */
1.1330 - if (pUser->grp_count != 0)
1.1331 - {
1.1332 - int *temp_table = (int *)m_pMemory->GetAddress(pUser->grp_table);
1.1333 - for (unsigned int i=0; i<pUser->grp_count; i++)
1.1334 - {
1.1335 - if (temp_table[i] == gid)
1.1336 - {
1.1337 - return false;
1.1338 - }
1.1339 - }
1.1340 - }
1.1341 -
1.1342 - int *table;
1.1343 - if (pUser->grp_count + 1 > pUser->grp_size)
1.1344 - {
1.1345 - int new_size = 0;
1.1346 - int tblidx;
1.1347 -
1.1348 - if (pUser->grp_size == 0)
1.1349 - {
1.1350 - new_size = 2;
1.1351 - } else {
1.1352 - new_size = pUser->grp_size * 2;
1.1353 - }
1.1354 -
1.1355 - /* Create and refresh pointers */
1.1356 - tblidx = m_pMemory->CreateMem(new_size * sizeof(int), (void **)&table);
1.1357 - pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1358 - pGroup = (AdminGroup *)m_pMemory->GetAddress(gid);
1.1359 -
1.1360 - /* Copy old data if necessary */
1.1361 - if (pUser->grp_table != -1)
1.1362 - {
1.1363 - int *old_table = (int *)m_pMemory->GetAddress(pUser->grp_table);
1.1364 - memcpy(table, old_table, sizeof(int) * pUser->grp_count);
1.1365 - }
1.1366 - pUser->grp_table = tblidx;
1.1367 - pUser->grp_size = new_size;
1.1368 - } else {
1.1369 - table = (int *)m_pMemory->GetAddress(pUser->grp_table);
1.1370 - }
1.1371 -
1.1372 - table[pUser->grp_count] = gid;
1.1373 - pUser->grp_count++;
1.1374 -
1.1375 - /* Compute new effective permissions */
1.1376 - pUser->eflags |= pGroup->addflags;
1.1377 -
1.1378 - if (pGroup->immunity_level > pUser->immunity_level)
1.1379 - {
1.1380 - pUser->immunity_level = pGroup->immunity_level;
1.1381 - }
1.1382 -
1.1383 - pUser->serialchange++;
1.1384 -
1.1385 - return true;
1.1386 -}
1.1387 -
1.1388 -bool AdminCache::IsValidAdmin(AdminId id)
1.1389 -{
1.1390 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1391 - return (pUser != NULL && pUser->magic == USR_MAGIC_SET);
1.1392 -}
1.1393 -
1.1394 -unsigned int AdminCache::GetAdminGroupCount(AdminId id)
1.1395 -{
1.1396 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1397 - if (!pUser || pUser->magic != USR_MAGIC_SET)
1.1398 - {
1.1399 - return 0;
1.1400 - }
1.1401 -
1.1402 - return pUser->grp_count;
1.1403 -}
1.1404 -
1.1405 -GroupId AdminCache::GetAdminGroup(AdminId id, unsigned int index, const char **name)
1.1406 -{
1.1407 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1408 - if (!pUser || pUser->magic != USR_MAGIC_SET || index >= pUser->grp_count)
1.1409 - {
1.1410 - return INVALID_GROUP_ID;
1.1411 - }
1.1412 -
1.1413 - int *table = (int *)m_pMemory->GetAddress(pUser->grp_table);
1.1414 -
1.1415 - GroupId gid = table[index];
1.1416 -
1.1417 - if (name)
1.1418 - {
1.1419 - *name = GetGroupName(gid);
1.1420 - }
1.1421 -
1.1422 - return gid;
1.1423 -}
1.1424 -
1.1425 -const char *AdminCache::GetAdminPassword(AdminId id)
1.1426 -{
1.1427 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1428 - if (!pUser || pUser->magic != USR_MAGIC_SET)
1.1429 - {
1.1430 - return NULL;
1.1431 - }
1.1432 -
1.1433 - return m_pStrings->GetString(pUser->password);
1.1434 -}
1.1435 -
1.1436 -void AdminCache::SetAdminPassword(AdminId id, const char *password)
1.1437 -{
1.1438 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1439 - if (!pUser || pUser->magic != USR_MAGIC_SET)
1.1440 - {
1.1441 - return;
1.1442 - }
1.1443 -
1.1444 - if (password[0] == '\0')
1.1445 - {
1.1446 - pUser->password = -1;
1.1447 - return;
1.1448 - }
1.1449 -
1.1450 - int i_password = m_pStrings->AddString(password);
1.1451 - pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1452 - pUser->password = i_password;
1.1453 -}
1.1454 -
1.1455 -unsigned int AdminCache::FlagBitsToBitArray(FlagBits bits, bool array[], unsigned int maxSize)
1.1456 -{
1.1457 - unsigned int i;
1.1458 - for (i=0; i<maxSize && i<AdminFlags_TOTAL; i++)
1.1459 - {
1.1460 - array[i] = ((bits & (1<<i)) == (unsigned)(1<<i));
1.1461 - }
1.1462 -
1.1463 - return i;
1.1464 -}
1.1465 -
1.1466 -FlagBits AdminCache::FlagBitArrayToBits(const bool array[], unsigned int maxSize)
1.1467 -{
1.1468 - FlagBits bits = 0;
1.1469 - for (unsigned int i=0; i<maxSize && i<AdminFlags_TOTAL; i++)
1.1470 - {
1.1471 - if (array[i])
1.1472 - {
1.1473 - bits |= (1<<i);
1.1474 - }
1.1475 - }
1.1476 -
1.1477 - return bits;
1.1478 -}
1.1479 -
1.1480 -FlagBits AdminCache::FlagArrayToBits(const AdminFlag array[], unsigned int numFlags)
1.1481 -{
1.1482 - FlagBits bits = 0;
1.1483 - for (unsigned int i=0; i<numFlags && i<AdminFlags_TOTAL; i++)
1.1484 - {
1.1485 - bits |= (1 << (FlagBits)array[i]);
1.1486 - }
1.1487 -
1.1488 - return bits;
1.1489 -}
1.1490 -
1.1491 -unsigned int AdminCache::FlagBitsToArray(FlagBits bits, AdminFlag array[], unsigned int maxSize)
1.1492 -{
1.1493 - unsigned int i, num=0;
1.1494 - for (i=0; num<maxSize && i<AdminFlags_TOTAL; i++)
1.1495 - {
1.1496 - if ((bits & (1<<i)) == (unsigned)(1<<i))
1.1497 - {
1.1498 - array[num++] = (AdminFlag)i;
1.1499 - }
1.1500 - }
1.1501 -
1.1502 - return num;
1.1503 -}
1.1504 -
1.1505 -bool AdminCache::CheckAdminFlags(AdminId id, FlagBits bits)
1.1506 -{
1.1507 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1508 - if (!pUser || pUser->magic != USR_MAGIC_SET)
1.1509 - {
1.1510 - return false;
1.1511 - }
1.1512 -
1.1513 - return ((pUser->eflags & bits) == bits);
1.1514 -}
1.1515 -
1.1516 -bool AdminCache::CanAdminTarget(AdminId id, AdminId target)
1.1517 -{
1.1518 - /**
1.1519 - * Zeroth, if the targeting AdminId is INVALID_ADMIN_ID, targeting fails.
1.1520 - * First, if the targeted AdminId is INVALID_ADMIN_ID, targeting succeeds.
1.1521 - */
1.1522 -
1.1523 - if (id == INVALID_ADMIN_ID)
1.1524 - {
1.1525 - return false;
1.1526 - }
1.1527 -
1.1528 - if (target == INVALID_ADMIN_ID)
1.1529 - {
1.1530 - return true;
1.1531 - }
1.1532 -
1.1533 - if (id == target)
1.1534 - {
1.1535 - return true;
1.1536 - }
1.1537 -
1.1538 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1539 - if (!pUser || pUser->magic != USR_MAGIC_SET)
1.1540 - {
1.1541 - return false;
1.1542 - }
1.1543 -
1.1544 - AdminUser *pTarget = (AdminUser *)m_pMemory->GetAddress(target);
1.1545 - if (!pTarget || pTarget->magic != USR_MAGIC_SET)
1.1546 - {
1.1547 - return false;
1.1548 - }
1.1549 -
1.1550 - /**
1.1551 - * Second, if the targeting admin is root, targeting succeeds.
1.1552 - */
1.1553 - if (pUser->eflags & ADMFLAG_ROOT)
1.1554 - {
1.1555 - return true;
1.1556 - }
1.1557 -
1.1558 - /** Fourth, if the targeted admin is immune from targeting admin. */
1.1559 - int mode = sm_immunity_mode.GetInt();
1.1560 - switch (mode)
1.1561 - {
1.1562 - case 1:
1.1563 - {
1.1564 - if (pTarget->immunity_level > pUser->immunity_level)
1.1565 - {
1.1566 - return false;
1.1567 - }
1.1568 - break;
1.1569 - }
1.1570 - case 3:
1.1571 - {
1.1572 - /* If neither has any immunity, let this pass. */
1.1573 - if (!pUser->immunity_level && !pTarget->immunity_level)
1.1574 - {
1.1575 - return true;
1.1576 - }
1.1577 - /* Don't break, go to the next case. */
1.1578 - }
1.1579 - case 2:
1.1580 - {
1.1581 - if (pTarget->immunity_level >= pUser->immunity_level)
1.1582 - {
1.1583 - return false;
1.1584 - }
1.1585 - break;
1.1586 - }
1.1587 - }
1.1588 -
1.1589 - /**
1.1590 - * Fifth, if the targeted admin has specific immunity from the
1.1591 - * targeting admin via group immunities, targeting fails.
1.1592 - */
1.1593 - //:TODO: speed this up... maybe with trie hacks.
1.1594 - //idea is to insert %d.%d in the trie after computing this and use it as a cache lookup.
1.1595 - //problem is the trie cannot delete prefixes, so we'd have a problem with invalidations.
1.1596 - if (pTarget->grp_count > 0 && pUser->grp_count > 0)
1.1597 - {
1.1598 - int *grp_table = (int *)m_pMemory->GetAddress(pTarget->grp_table);
1.1599 - int *src_table = (int *)m_pMemory->GetAddress(pUser->grp_table);
1.1600 - GroupId id, other;
1.1601 - unsigned int num;
1.1602 - for (unsigned int i=0; i<pTarget->grp_count; i++)
1.1603 - {
1.1604 - id = grp_table[i];
1.1605 - num = GetGroupImmunityCount(id);
1.1606 - for (unsigned int j=0; j<num; i++)
1.1607 - {
1.1608 - other = GetGroupImmunity(id, j);
1.1609 - for (unsigned int k=0; k<pUser->grp_count; k++)
1.1610 - {
1.1611 - if (other == src_table[k])
1.1612 - {
1.1613 - return false;
1.1614 - }
1.1615 - }
1.1616 - }
1.1617 - }
1.1618 - }
1.1619 -
1.1620 - return true;
1.1621 -}
1.1622 -
1.1623 -bool AdminCache::FindFlag(char c, AdminFlag *pAdmFlag)
1.1624 -{
1.1625 - if (c < 'a'
1.1626 - || c > 'z'
1.1627 - || !g_FlagSet[(unsigned)c - (unsigned)'a'])
1.1628 - {
1.1629 - return false;
1.1630 - }
1.1631 -
1.1632 - if (pAdmFlag)
1.1633 - {
1.1634 - *pAdmFlag = g_FlagLetters[(unsigned)c - (unsigned)'a'];
1.1635 - }
1.1636 -
1.1637 - return true;
1.1638 -}
1.1639 -
1.1640 -bool AdminCache::FindFlagChar(AdminFlag flag, char *c)
1.1641 -{
1.1642 - if (!g_FlagSet[flag])
1.1643 - {
1.1644 - return false;
1.1645 - }
1.1646 -
1.1647 - if (c)
1.1648 - {
1.1649 - *c = g_ReverseFlags[flag];
1.1650 - }
1.1651 -
1.1652 - return true;
1.1653 -}
1.1654 -
1.1655 -FlagBits AdminCache::ReadFlagString(const char *flags, const char **end)
1.1656 -{
1.1657 - FlagBits bits = 0;
1.1658 -
1.1659 - while (flags && (*flags != '\0'))
1.1660 - {
1.1661 - AdminFlag flag;
1.1662 - if (!FindFlag(*flags, &flag))
1.1663 - {
1.1664 - break;
1.1665 - }
1.1666 - bits |= FlagArrayToBits(&flag, 1);
1.1667 - flags++;
1.1668 - }
1.1669 -
1.1670 - if (end)
1.1671 - {
1.1672 - *end = flags;
1.1673 - }
1.1674 -
1.1675 - return bits;
1.1676 -}
1.1677 -
1.1678 -unsigned int AdminCache::GetAdminSerialChange(AdminId id)
1.1679 -{
1.1680 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1681 - if (!pUser || pUser->magic != USR_MAGIC_SET)
1.1682 - {
1.1683 - return 0;
1.1684 - }
1.1685 -
1.1686 - return pUser->serialchange;
1.1687 -}
1.1688 -
1.1689 -bool AdminCache::CanAdminUseCommand(int client, const char *cmd)
1.1690 -{
1.1691 - FlagBits bits;
1.1692 - OverrideType otype = Override_Command;
1.1693 -
1.1694 - if (cmd[0] == '@')
1.1695 - {
1.1696 - otype = Override_CommandGroup;
1.1697 - cmd++;
1.1698 - }
1.1699 -
1.1700 - if (!g_ConCmds.LookForCommandAdminFlags(cmd, &bits))
1.1701 - {
1.1702 - if (!GetCommandOverride(cmd, otype, &bits))
1.1703 - {
1.1704 - bits = 0;
1.1705 - }
1.1706 - }
1.1707 -
1.1708 - return g_ConCmds.CheckCommandAccess(client, cmd, bits);
1.1709 -}
1.1710 -
1.1711 -unsigned int AdminCache::SetGroupImmunityLevel(GroupId gid, unsigned int level)
1.1712 -{
1.1713 - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(gid);
1.1714 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.1715 - {
1.1716 - return 0;
1.1717 - }
1.1718 -
1.1719 - unsigned int old_level = pGroup->immunity_level;
1.1720 -
1.1721 - pGroup->immunity_level = level;
1.1722 -
1.1723 - return old_level;
1.1724 -}
1.1725 -
1.1726 -unsigned int AdminCache::GetGroupImmunityLevel(GroupId gid)
1.1727 -{
1.1728 - AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(gid);
1.1729 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.1730 - {
1.1731 - return 0;
1.1732 - }
1.1733 -
1.1734 - return pGroup->immunity_level;
1.1735 -}
1.1736 -
1.1737 -unsigned int AdminCache::SetAdminImmunityLevel(AdminId id, unsigned int level)
1.1738 -{
1.1739 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1740 - if (!pUser || pUser->magic != USR_MAGIC_SET)
1.1741 - {
1.1742 - return 0;
1.1743 - }
1.1744 -
1.1745 - unsigned int old_level = pUser->immunity_level;
1.1746 -
1.1747 - pUser->immunity_level = level;
1.1748 -
1.1749 - return old_level;
1.1750 -}
1.1751 -
1.1752 -unsigned int AdminCache::GetAdminImmunityLevel(AdminId id)
1.1753 -{
1.1754 - AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1.1755 - if (!pUser || pUser->magic != USR_MAGIC_SET)
1.1756 - {
1.1757 - return 0;
1.1758 - }
1.1759 -
1.1760 - return pUser->immunity_level;
1.1761 -}
1.1762 -
1.1763 -bool AdminCache::CheckAccess(int client, const char *cmd, FlagBits flags, bool override_only)
1.1764 -{
1.1765 - if (client == 0)
1.1766 - {
1.1767 - return true;
1.1768 - }
1.1769 -
1.1770 - /* Auto-detect a command if we can */
1.1771 - FlagBits bits = flags;
1.1772 - bool found_command = false;
1.1773 - if (!override_only)
1.1774 - {
1.1775 - found_command = g_ConCmds.LookForCommandAdminFlags(cmd, &bits);
1.1776 - }
1.1777 -
1.1778 - if (!found_command)
1.1779 - {
1.1780 - GetCommandOverride(cmd, Override_Command, &bits);
1.1781 - }
1.1782 -
1.1783 - return g_ConCmds.CheckCommandAccess(client, cmd, bits) ? 1 : 0;
1.1784 -}
1.1785 -
1.1786 -void iterator_glob_basic_override(Trie *pTrie, const char *key, void **value, void *data)
1.1787 -{
1.1788 - FILE *fp;
1.1789 - int flags;
1.1790 - char flagstr[64];
1.1791 -
1.1792 - fp = (FILE *)data;
1.1793 - flags = (int)*value;
1.1794 - g_Admins.FillFlagString(flags, flagstr, sizeof(flagstr));
1.1795 -
1.1796 - fprintf(fp, "\t\"%s\"\t\t\"%s\"\n", key, flagstr);
1.1797 -}
1.1798 -
1.1799 -void iterator_glob_grp_override(Trie *pTrie, const char *key, void **value, void *data)
1.1800 -{
1.1801 - FILE *fp;
1.1802 - int flags;
1.1803 - char flagstr[64];
1.1804 -
1.1805 - fp = (FILE *)data;
1.1806 - flags = (int)*value;
1.1807 - g_Admins.FillFlagString(flags, flagstr, sizeof(flagstr));
1.1808 -
1.1809 - fprintf(fp, "\t\"@%s\"\t\t\"%s\"\n", key, flagstr);
1.1810 -}
1.1811 -
1.1812 -void iterator_group_basic_override(Trie *pTrie, const char *key, void **value, void *data)
1.1813 -{
1.1814 - FILE *fp;
1.1815 - int flags;
1.1816 - char flagstr[64];
1.1817 -
1.1818 - fp = (FILE *)data;
1.1819 - flags = (int)*value;
1.1820 - g_Admins.FillFlagString(flags, flagstr, sizeof(flagstr));
1.1821 -
1.1822 - fprintf(fp, "\t\t\t\"%s\"\t\t\"%s\"\n", key, flagstr);
1.1823 -}
1.1824 -
1.1825 -void iterator_group_grp_override(Trie *pTrie, const char *key, void **value, void *data)
1.1826 -{
1.1827 - FILE *fp;
1.1828 - int flags;
1.1829 - char flagstr[64];
1.1830 -
1.1831 - fp = (FILE *)data;
1.1832 - flags = (int)*value;
1.1833 - g_Admins.FillFlagString(flags, flagstr, sizeof(flagstr));
1.1834 -
1.1835 - fprintf(fp, "\t\t\t\"@%s\"\t\t\"%s\"\n", key, flagstr);
1.1836 -}
1.1837 -
1.1838 -void AdminCache::DumpCache(FILE *fp)
1.1839 -{
1.1840 - int *itable;
1.1841 - AdminId aid;
1.1842 - GroupId gid;
1.1843 - char flagstr[64];
1.1844 - unsigned int num;
1.1845 - AdminUser *pAdmin;
1.1846 - AdminGroup *pGroup;
1.1847 - char name_buffer[512];
1.1848 -
1.1849 - fprintf(fp, "\"Groups\"\n{\n");
1.1850 -
1.1851 - num = 0;
1.1852 - gid = m_FirstGroup;
1.1853 - while (gid != INVALID_GROUP_ID
1.1854 - && (pGroup = GetGroup(gid)) != NULL)
1.1855 - {
1.1856 - num++;
1.1857 - FillFlagString(pGroup->addflags, flagstr, sizeof(flagstr));
1.1858 -
1.1859 - fprintf(fp, "\t/* num = %d, gid = 0x%X */\n", num, gid);
1.1860 - fprintf(fp, "\t\"%s\"\n\t{\n", GetString(pGroup->nameidx));
1.1861 - fprintf(fp, "\t\t\"flags\"\t\t\t\"%s\"\n", flagstr);
1.1862 - fprintf(fp, "\t\t\"immunity\"\t\t\"%d\"\n", pGroup->immunity_level);
1.1863 -
1.1864 - if (pGroup->immune_table != -1
1.1865 - && (itable = (int *)m_pMemory->GetAddress(pGroup->immune_table)) != NULL)
1.1866 - {
1.1867 - AdminGroup *pAltGroup;
1.1868 - const char *gname, *mod;
1.1869 -
1.1870 - for (int i = 1; i <= itable[0]; i++)
1.1871 - {
1.1872 - if ((pAltGroup = GetGroup(itable[i])) == NULL)
1.1873 - {
1.1874 - /* Assume the rest of the table is corrupt */
1.1875 - break;
1.1876 - }
1.1877 - gname = GetString(pAltGroup->nameidx);
1.1878 - if (atoi(gname) != 0)
1.1879 - {
1.1880 - mod = "@";
1.1881 - }
1.1882 - else
1.1883 - {
1.1884 - mod = "";
1.1885 - }
1.1886 - fprintf(fp, "\t\t\"immunity\"\t\t\"%s%s\"\n", mod, gname);
1.1887 - }
1.1888 - }
1.1889 -
1.1890 - fprintf(fp, "\n\t\t\"Overrides\"\n\t\t{\n");
1.1891 - if (pGroup->pCmdGrpTable != NULL)
1.1892 - {
1.1893 - sm_trie_bad_iterator(pGroup->pCmdGrpTable,
1.1894 - name_buffer,
1.1895 - sizeof(name_buffer),
1.1896 - iterator_group_grp_override,
1.1897 - fp);
1.1898 - }
1.1899 - if (pGroup->pCmdTable != NULL)
1.1900 - {
1.1901 - sm_trie_bad_iterator(pGroup->pCmdTable,
1.1902 - name_buffer,
1.1903 - sizeof(name_buffer),
1.1904 - iterator_group_basic_override,
1.1905 - fp);
1.1906 - }
1.1907 - fprintf(fp, "\t\t}\n");
1.1908 -
1.1909 - fprintf(fp, "\t}\n");
1.1910 -
1.1911 - if ((gid = pGroup->next_grp) != INVALID_GROUP_ID)
1.1912 - {
1.1913 - fprintf(fp, "\n");
1.1914 - }
1.1915 - }
1.1916 -
1.1917 - fprintf(fp, "}\n\n");
1.1918 - fprintf(fp, "\"Admins\"\n{\n");
1.1919 -
1.1920 - num = 0;
1.1921 - aid = m_FirstUser;
1.1922 - while (aid != INVALID_ADMIN_ID
1.1923 - && (pAdmin = GetUser(aid)) != NULL)
1.1924 - {
1.1925 - num++;
1.1926 - FillFlagString(pAdmin->flags, flagstr, sizeof(flagstr));
1.1927 -
1.1928 - fprintf(fp, "\t/* num = %d, aid = 0x%X, serialno = 0x%X*/\n", num, aid, pAdmin->serialchange);
1.1929 -
1.1930 - if (pAdmin->nameidx != -1)
1.1931 - {
1.1932 - fprintf(fp, "\t\"%s\"\n\t{\n", GetString(pAdmin->nameidx));
1.1933 - }
1.1934 - else
1.1935 - {
1.1936 - fprintf(fp, "\t\"\"\n\t{\n");
1.1937 - }
1.1938 -
1.1939 - if (pAdmin->auth.identidx != -1)
1.1940 - {
1.1941 - fprintf(fp, "\t\t\"auth\"\t\t\t\"%s\"\n", GetMethodName(pAdmin->auth.index));
1.1942 - fprintf(fp, "\t\t\"identity\"\t\t\"%s\"\n", GetString(pAdmin->auth.identidx));
1.1943 - }
1.1944 - if (pAdmin->password != -1)
1.1945 - {
1.1946 - fprintf(fp, "\t\t\"password\"\t\t\"%s\"\n", GetString(pAdmin->password));
1.1947 - }
1.1948 - fprintf(fp, "\t\t\"flags\"\t\t\t\"%s\"\n", flagstr);
1.1949 - fprintf(fp, "\t\t\"immunity\"\t\t\"%d\"\n", pAdmin->immunity_level);
1.1950 -
1.1951 - if (pAdmin->grp_count != 0
1.1952 - && pAdmin->grp_table != -1
1.1953 - && (itable = (int *)m_pMemory->GetAddress(pAdmin->grp_table)) != NULL)
1.1954 - {
1.1955 - unsigned int i;
1.1956 -
1.1957 - for (i = 0; i < pAdmin->grp_count; i++)
1.1958 - {
1.1959 - if ((pGroup = GetGroup(itable[i])) == NULL)
1.1960 - {
1.1961 - /* Assume the rest of the table is corrupt */
1.1962 - break;
1.1963 - }
1.1964 - fprintf(fp, "\t\t\"group\"\t\t\t\"%s\"\n", GetString(pGroup->nameidx));
1.1965 - }
1.1966 - }
1.1967 -
1.1968 - fprintf(fp, "\t}\n");
1.1969 -
1.1970 - if ((aid = pAdmin->next_user) != INVALID_ADMIN_ID)
1.1971 - {
1.1972 - fprintf(fp, "\n");
1.1973 - }
1.1974 - }
1.1975 -
1.1976 - fprintf(fp, "}\n\n");
1.1977 -
1.1978 - fprintf(fp, "\"Overrides\"\n{\n");
1.1979 - if (m_pCmdGrpOverrides != NULL)
1.1980 - {
1.1981 - sm_trie_bad_iterator(m_pCmdGrpOverrides,
1.1982 - name_buffer,
1.1983 - sizeof(name_buffer),
1.1984 - iterator_glob_grp_override,
1.1985 - fp);
1.1986 - }
1.1987 - if (m_pCmdOverrides != NULL)
1.1988 - {
1.1989 - sm_trie_bad_iterator(m_pCmdOverrides,
1.1990 - name_buffer,
1.1991 - sizeof(name_buffer),
1.1992 - iterator_glob_basic_override,
1.1993 - fp);
1.1994 - }
1.1995 - fprintf(fp, "}\n");
1.1996 -}
1.1997 -
1.1998 -AdminGroup *AdminCache::GetGroup(GroupId gid)
1.1999 -{
1.2000 - AdminGroup *pGroup;
1.2001 -
1.2002 - pGroup = (AdminGroup *)m_pMemory->GetAddress(gid);
1.2003 - if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
1.2004 - {
1.2005 - return NULL;
1.2006 - }
1.2007 -
1.2008 - return pGroup;
1.2009 -}
1.2010 -
1.2011 -AdminUser *AdminCache::GetUser(AdminId aid)
1.2012 -{
1.2013 - AdminUser *pAdmin;
1.2014 -
1.2015 - pAdmin = (AdminUser *)m_pMemory->GetAddress(aid);
1.2016 - if (!pAdmin || pAdmin->magic != USR_MAGIC_SET)
1.2017 - {
1.2018 - return NULL;
1.2019 - }
1.2020 -
1.2021 - return pAdmin;
1.2022 -}
1.2023 -
1.2024 -const char *AdminCache::GetMethodName(unsigned int index)
1.2025 -{
1.2026 - List<AuthMethod>::iterator iter;
1.2027 - for (iter=m_AuthMethods.begin();
1.2028 - iter!=m_AuthMethods.end();
1.2029 - iter++)
1.2030 - {
1.2031 - if (index-- == 0)
1.2032 - {
1.2033 - return (*iter).name.c_str();
1.2034 - }
1.2035 - }
1.2036 -
1.2037 - return NULL;
1.2038 -}
1.2039 -
1.2040 -const char *AdminCache::GetString(int idx)
1.2041 -{
1.2042 - return m_pStrings->GetString(idx);
1.2043 -}
1.2044 -
1.2045 -size_t AdminCache::FillFlagString(FlagBits bits, char *buffer, size_t maxlen)
1.2046 -{
1.2047 - size_t pos;
1.2048 - unsigned int i, num_flags;
1.2049 - AdminFlag flags[AdminFlags_TOTAL];
1.2050 -
1.2051 - num_flags = FlagBitsToArray(bits, flags, AdminFlags_TOTAL);
1.2052 -
1.2053 - pos = 0;
1.2054 - for (i = 0; pos < maxlen && i < num_flags; i++)
1.2055 - {
1.2056 - if (FindFlagChar(flags[i], &buffer[pos]))
1.2057 - {
1.2058 - pos++;
1.2059 - }
1.2060 - }
1.2061 - buffer[pos] = '\0';
1.2062 -
1.2063 - return pos;
1.2064 -}
1.2065 -
1.2066 -CON_COMMAND(sm_dump_admcache, "Dumps the admin cache for debugging")
1.2067 -{
1.2068 - FILE *fp;
1.2069 - char buffer[PLATFORM_MAX_PATH];
1.2070 -
1.2071 - g_SourceMod.BuildPath(Path_SM, buffer, sizeof(buffer), "data/admin_cache_dump.txt");
1.2072 -
1.2073 - if ((fp = fopen(buffer, "wt")) == NULL)
1.2074 - {
1.2075 - g_RootMenu.ConsolePrint("Could not open file for writing: %s", buffer);
1.2076 - return;
1.2077 - }
1.2078 -
1.2079 - g_Admins.DumpCache(fp);
1.2080 -
1.2081 - g_RootMenu.ConsolePrint("Admin cache dumped to: %s", buffer);
1.2082 -
1.2083 - fclose(fp);
1.2084 -}