dvander@444: /** dvander@444: * admin-groups.sp dvander@444: * Reads the admin_groups.cfg file. Do not compile this directly. dvander@444: * This file is part of SourceMod, Copyright (C) 2004-2007 AlliedModders LLC dvander@444: * dvander@444: * This program is free software; you can redistribute it and/or dvander@444: * modify it under the terms of the GNU General Public License dvander@444: * as published by the Free Software Foundation; either version 2 dvander@444: * of the License, or (at your option) any later version. dvander@444: * dvander@444: * This program is distributed in the hope that it will be useful, dvander@444: * but WITHOUT ANY WARRANTY; without even the implied warranty of dvander@444: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dvander@444: * GNU General Public License for more details. dvander@444: * dvander@444: * You should have received a copy of the GNU General Public License dvander@444: * along with this program; if not, write to the Free Software dvander@444: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ds@908: * ds@908: * Version: $Id$ dvander@444: */ dvander@444: dvander@437: #define GROUP_STATE_NONE 0 dvander@437: #define GROUP_STATE_GROUPS 1 dvander@437: #define GROUP_STATE_INGROUP 2 dvander@437: #define GROUP_STATE_OVERRIDES 3 dvander@437: #define GROUP_PASS_FIRST 1 dvander@437: #define GROUP_PASS_SECOND 2 dvander@437: dvander@437: static Handle:g_hGroupParser = INVALID_HANDLE; dvander@437: static GroupId:g_CurGrp = INVALID_GROUP_ID; dvander@437: static g_GroupState = GROUP_STATE_NONE; dvander@637: static g_GroupPass = 0; dvander@437: static bool:g_NeedReparse = false; dvander@437: dvander@437: public SMCResult:ReadGroups_NewSection(Handle:smc, const String:name[], bool:opt_quotes) dvander@437: { dvander@442: if (g_IgnoreLevel) dvander@442: { dvander@442: g_IgnoreLevel++; dvander@442: return SMCParse_Continue; dvander@442: } dvander@442: dvander@437: if (g_GroupState == GROUP_STATE_NONE) dvander@437: { dvander@437: if (StrEqual(name, "Groups")) dvander@437: { dvander@437: g_GroupState = GROUP_STATE_GROUPS; dvander@442: } else { dvander@442: g_IgnoreLevel++; dvander@437: } dvander@437: } else if (g_GroupState == GROUP_STATE_GROUPS) { dvander@437: if ((g_CurGrp = CreateAdmGroup(name)) == INVALID_GROUP_ID) dvander@437: { dvander@437: g_CurGrp = FindAdmGroup(name); dvander@437: } dvander@437: g_GroupState = GROUP_STATE_INGROUP; dvander@437: } else if (g_GroupState == GROUP_STATE_INGROUP) { dvander@437: if (StrEqual(name, "Overrides")) dvander@437: { dvander@437: g_GroupState = GROUP_STATE_OVERRIDES; dvander@442: } else { dvander@442: g_IgnoreLevel++; dvander@437: } dvander@442: } else { dvander@442: g_IgnoreLevel++; dvander@437: } dvander@437: dvander@437: return SMCParse_Continue; dvander@437: } dvander@437: dvander@437: public SMCResult:ReadGroups_KeyValue(Handle:smc, dvander@437: const String:key[], dvander@437: const String:value[], dvander@437: bool:key_quotes, dvander@437: bool:value_quotes) dvander@437: { dvander@442: if (g_CurGrp == INVALID_GROUP_ID dvander@442: || g_IgnoreLevel) dvander@437: { dvander@437: return SMCParse_Continue; dvander@437: } dvander@437: dvander@437: new AdminFlag:flag; dvander@437: dvander@437: if (g_GroupPass == GROUP_PASS_FIRST) dvander@437: { dvander@437: if (g_GroupState == GROUP_STATE_INGROUP) dvander@437: { dvander@437: if (StrEqual(key, "flags")) dvander@437: { dvander@437: new len = strlen(value); dvander@437: for (new i=0; i 'z') dvander@437: { dvander@437: continue; dvander@437: } dvander@439: if (!g_FlagsSet[value[i] - 'a']) dvander@439: { dvander@439: continue; dvander@439: } dvander@437: flag = g_FlagLetters[value[i] - 'a']; dvander@437: SetAdmGroupAddFlag(g_CurGrp, flag, true); dvander@437: } dvander@437: } else if (StrEqual(key, "immunity")) { dvander@437: /* If it's a value we know about, use it */ dvander@437: if (StrEqual(value, "*")) dvander@437: { dvander@437: SetAdmGroupImmunity(g_CurGrp, Immunity_Global, true); dvander@437: } else if (StrEqual(value, "$")) { dvander@437: SetAdmGroupImmunity(g_CurGrp, Immunity_Default, true); dvander@437: } else { dvander@437: /* If we can't find the group, we'll need to schedule a reparse */ dvander@437: new GroupId:id = FindAdmGroup(value); dvander@445: if (id != INVALID_GROUP_ID) dvander@437: { dvander@437: SetAdmGroupImmuneFrom(g_CurGrp, id); dvander@437: } else { dvander@437: g_NeedReparse = true; dvander@437: } dvander@437: } dvander@437: } dvander@437: } else if (g_GroupState == GROUP_STATE_OVERRIDES) { dvander@437: new OverrideRule:rule = Command_Deny; dvander@437: dvander@437: if (StrEqual(value, "allow", false)) dvander@437: { dvander@437: rule = Command_Allow; dvander@437: } dvander@437: dvander@437: if (key[0] == '@') dvander@437: { dvander@437: AddAdmGroupCmdOverride(g_CurGrp, key[1], Override_CommandGroup, rule); dvander@437: } else { dvander@437: AddAdmGroupCmdOverride(g_CurGrp, key, Override_Command, rule); dvander@437: } dvander@437: } dvander@437: } else if (g_GroupPass == GROUP_PASS_SECOND dvander@437: && g_GroupState == GROUP_STATE_INGROUP) { dvander@437: /* Check for immunity again, core should handle double inserts */ dvander@437: if (StrEqual(key, "immunity")) dvander@437: { dvander@1279: if (StrEqual(value, "$")) dvander@437: { dvander@1279: SetAdmGroupImmunity(g_CurGrp, Immunity_Default, true); dvander@1279: } else if (StrEqual(value, "*")) { dvander@1279: SetAdmGroupImmunity(g_CurGrp, Immunity_Global, true); dvander@437: } else { dvander@1279: new GroupId:id = FindAdmGroup(value); dvander@1279: if (id != INVALID_GROUP_ID) dvander@1279: { dvander@1279: SetAdmGroupImmuneFrom(g_CurGrp, id); dvander@1279: } else { dvander@1279: ParseError("Unable to find group: \"%s\"", value); dvander@1279: } dvander@437: } dvander@437: } dvander@437: } dvander@437: dvander@437: return SMCParse_Continue; dvander@437: } dvander@437: dvander@437: public SMCResult:ReadGroups_EndSection(Handle:smc) dvander@437: { dvander@442: /* If we're ignoring, skip out */ dvander@442: if (g_IgnoreLevel) dvander@442: { dvander@442: g_IgnoreLevel--; dvander@442: return SMCParse_Continue; dvander@442: } dvander@442: dvander@437: if (g_GroupState == GROUP_STATE_OVERRIDES) dvander@437: { dvander@437: g_GroupState = GROUP_STATE_INGROUP; dvander@437: } else if (g_GroupState == GROUP_STATE_INGROUP) { dvander@437: g_GroupState = GROUP_STATE_GROUPS; dvander@437: g_CurGrp = INVALID_GROUP_ID; dvander@437: } else if (g_GroupState == GROUP_STATE_GROUPS) { dvander@437: g_GroupState = GROUP_STATE_NONE; dvander@437: } dvander@437: dvander@437: return SMCParse_Continue; dvander@437: } dvander@437: dvander@437: static InitializeGroupParser() dvander@437: { dvander@437: if (g_hGroupParser == INVALID_HANDLE) dvander@437: { dvander@437: g_hGroupParser = SMC_CreateParser(); dvander@437: SMC_SetReaders(g_hGroupParser, dvander@437: ReadGroups_NewSection, dvander@437: ReadGroups_KeyValue, dvander@437: ReadGroups_EndSection); dvander@437: } dvander@437: } dvander@437: dvander@444: static InternalReadGroups(const String:path[], pass) dvander@437: { dvander@437: /* Set states */ dvander@442: InitGlobalStates(); dvander@437: g_GroupState = GROUP_STATE_NONE; dvander@437: g_CurGrp = INVALID_GROUP_ID; dvander@442: g_GroupPass = pass; dvander@437: g_NeedReparse = false; dvander@437: dvander@437: new SMCError:err = SMC_ParseFile(g_hGroupParser, path); dvander@437: if (err != SMCError_Okay) dvander@437: { dvander@437: decl String:buffer[64]; dvander@437: if (SMC_GetErrorString(err, buffer, sizeof(buffer))) dvander@437: { dvander@442: ParseError("%s", buffer); dvander@437: } else { dvander@442: ParseError("Fatal parse error"); dvander@437: } dvander@437: } dvander@437: } dvander@437: dvander@442: ReadGroups() dvander@442: { dvander@442: InitializeGroupParser(); dvander@442: dvander@442: BuildPath(Path_SM, g_Filename, sizeof(g_Filename), "configs/admin_groups.cfg"); dvander@442: dvander@442: InternalReadGroups(g_Filename, GROUP_PASS_FIRST); dvander@442: if (g_NeedReparse) dvander@442: { dvander@442: InternalReadGroups(g_Filename, GROUP_PASS_SECOND); dvander@442: } dvander@442: } dvander@442: