dvander@444: /**
ds@1330: * vim: set ts=4 :
ds@1330: * =============================================================================
ds@1330: * SourceMod Admin File Reader Plugin
dvander@444: * Reads the admins.cfg file. Do not compile this directly.
ds@1330: *
ds@1947: * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
ds@1330: * =============================================================================
dvander@444: *
ds@1330: * This program is free software; you can redistribute it and/or modify it under
ds@1330: * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330: * Free Software Foundation.
ds@1330: *
ds@1330: * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
ds@1330: * details.
dvander@444: *
ds@1330: * You should have received a copy of the GNU General Public License along with
ds@1330: * this program. If not, see .
ds@1330: *
ds@1330: * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330: * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330: * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330: * by the Valve Corporation. You must obey the GNU General Public License in
ds@1330: * all respects for all other code used. Additionally, AlliedModders LLC grants
ds@1330: * this exception to all derivative works. AlliedModders LLC defines further
ds@1330: * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330: * or .
ds@908: *
ds@908: * Version: $Id$
dvander@444: */
dvander@444:
dvander@444: #define USER_STATE_NONE 0
dvander@444: #define USER_STATE_ADMINS 1
dvander@444: #define USER_STATE_INADMIN 2
dvander@444:
dvander@444: static Handle:g_hUserParser = INVALID_HANDLE;
dvander@444: static g_UserState = USER_STATE_NONE;
dvander@444: static String:g_CurAuth[64];
dvander@444: static String:g_CurIdent[64];
dvander@2052: static String:g_CurName[64];
dvander@2052: static String:g_CurPass[64];
dvander@2052: static Handle:g_GroupArray;
dvander@2052: static g_CurFlags;
dvander@2052: static g_CurImmunity;
dvander@444:
dvander@444: public SMCResult:ReadUsers_NewSection(Handle:smc, const String:name[], bool:opt_quotes)
dvander@444: {
dvander@444: if (g_IgnoreLevel)
dvander@444: {
dvander@444: g_IgnoreLevel++;
dvander@444: return SMCParse_Continue;
dvander@444: }
dvander@444:
dvander@444: if (g_UserState == USER_STATE_NONE)
dvander@444: {
dvander@444: if (StrEqual(name, "Admins"))
dvander@444: {
dvander@444: g_UserState = USER_STATE_ADMINS;
dvander@2052: }
dvander@2052: else
dvander@2052: {
dvander@444: g_IgnoreLevel++;
dvander@444: }
dvander@2052: }
dvander@2052: else if (g_UserState == USER_STATE_ADMINS)
dvander@2052: {
dvander@444: g_UserState = USER_STATE_INADMIN;
dvander@2052: strcopy(g_CurName, sizeof(g_CurName), name);
dvander@444: g_CurAuth[0] = '\0';
dvander@444: g_CurIdent[0] = '\0';
dvander@2052: g_CurPass[0] = '\0';
dvander@2052: ClearArray(g_GroupArray);
dvander@2052: g_CurFlags = 0;
dvander@2052: g_CurImmunity = 0;
dvander@2052: }
dvander@2052: else
dvander@2052: {
dvander@444: g_IgnoreLevel++;
dvander@444: }
dvander@444:
dvander@444: return SMCParse_Continue;
dvander@444: }
dvander@444:
dvander@444: public SMCResult:ReadUsers_KeyValue(Handle:smc,
dvander@444: const String:key[],
dvander@444: const String:value[],
dvander@444: bool:key_quotes,
dvander@444: bool:value_quotes)
dvander@444: {
dvander@2052: if (g_UserState != USER_STATE_INADMIN || g_IgnoreLevel)
dvander@444: {
dvander@444: return SMCParse_Continue;
dvander@444: }
dvander@444:
dvander@444: if (StrEqual(key, "auth"))
dvander@444: {
ds@1268: strcopy(g_CurAuth, sizeof(g_CurAuth), value);
dvander@1403: }
dvander@1403: else if (StrEqual(key, "identity"))
dvander@1403: {
ds@1268: strcopy(g_CurIdent, sizeof(g_CurIdent), value);
dvander@1403: }
dvander@1403: else if (StrEqual(key, "password"))
dvander@1403: {
dvander@2052: strcopy(g_CurPass, sizeof(g_CurPass), value);
dvander@1403: }
dvander@1403: else if (StrEqual(key, "group"))
dvander@1403: {
dvander@444: new GroupId:id = FindAdmGroup(value);
dvander@444: if (id == INVALID_GROUP_ID)
dvander@444: {
dvander@444: ParseError("Unknown group \"%s\"", value);
dvander@444: }
dvander@2052:
dvander@2052: PushArrayCell(g_GroupArray, id);
dvander@1403: }
dvander@1403: else if (StrEqual(key, "flags"))
dvander@1403: {
dvander@444: new len = strlen(value);
dvander@1298: new AdminFlag:flag;
dvander@444:
dvander@2052: for (new i = 0; i < len; i++)
dvander@444: {
dvander@1298: if (!FindFlagByChar(value[i], flag))
dvander@444: {
dvander@444: ParseError("Invalid flag detected: %c", value[i]);
dvander@444: }
dvander@2052: else
dvander@2052: {
dvander@2052: g_CurFlags |= FlagToBit(flag);
dvander@2052: }
dvander@444: }
dvander@1403: }
dvander@1403: else if (StrEqual(key, "immunity"))
dvander@1403: {
dvander@2052: g_CurImmunity = StringToInt(value);
dvander@444: }
dvander@444:
dvander@444: return SMCParse_Continue;
dvander@444: }
dvander@444:
dvander@444: public SMCResult:ReadUsers_EndSection(Handle:smc)
dvander@444: {
dvander@444: if (g_IgnoreLevel)
dvander@444: {
dvander@444: g_IgnoreLevel--;
dvander@444: return SMCParse_Continue;
dvander@444: }
dvander@444:
dvander@444: if (g_UserState == USER_STATE_INADMIN)
dvander@444: {
dvander@2052: /* Dump this user to memory */
dvander@2052: if (g_CurIdent[0] != '\0' && g_CurAuth[0] != '\0')
dvander@2052: {
dvander@2052: decl AdminFlag:flags[26];
dvander@2052: new AdminId:id, i, num_groups, num_flags;
dvander@2052:
dvander@2052: if ((id = FindAdminByIdentity(g_CurAuth, g_CurIdent)) == INVALID_ADMIN_ID)
dvander@2052: {
dvander@2052: id = CreateAdmin(g_CurName);
dvander@2052: if (!BindAdminIdentity(id, g_CurAuth, g_CurIdent))
dvander@2052: {
rbutler14@2490: RemoveAdmin(id);
dvander@2052: ParseError("Failed to bind auth \"%s\" to identity \"%s\"", g_CurAuth, g_CurIdent);
rbutler14@2490: return SMCParse_Continue;
dvander@2052: }
dvander@2052: }
dvander@2052:
dvander@2052: num_groups = GetArraySize(g_GroupArray);
dvander@2052: for (i = 0; i < num_groups; i++)
dvander@2052: {
dvander@2052: AdminInheritGroup(id, GetArrayCell(g_GroupArray, i));
dvander@2052: }
dvander@2052:
dvander@2052: SetAdminPassword(id, g_CurPass);
dvander@2052: if (GetAdminImmunityLevel(id) < g_CurImmunity)
dvander@2052: {
dvander@2052: SetAdminImmunityLevel(id, g_CurImmunity);
dvander@2052: }
dvander@2052:
dvander@2052: num_flags = FlagBitsToArray(g_CurFlags, flags, sizeof(flags));
dvander@2052: for (i = 0; i < num_flags; i++)
dvander@2052: {
dvander@2052: SetAdminFlag(id, flags[i], true);
dvander@2052: }
dvander@2052: }
dvander@2052: else
dvander@2052: {
dvander@2052: ParseError("Failed to create admin: did you forget either the auth or identity properties?");
dvander@2052: }
dvander@2052:
dvander@444: g_UserState = USER_STATE_ADMINS;
dvander@2052: }
dvander@2052: else if (g_UserState == USER_STATE_ADMINS)
dvander@2052: {
dvander@444: g_UserState = USER_STATE_NONE;
dvander@444: }
dvander@444:
dvander@444: return SMCParse_Continue;
dvander@444: }
dvander@444:
dvander@1432: public SMCResult:ReadUsers_CurrentLine(Handle:smc, const String:line[], lineno)
dvander@1432: {
dvander@1432: g_CurrentLine = lineno;
dvander@1432:
dvander@1432: return SMCParse_Continue;
dvander@1432: }
dvander@1432:
dvander@444: static InitializeUserParser()
dvander@444: {
dvander@444: if (g_hUserParser == INVALID_HANDLE)
dvander@444: {
dvander@444: g_hUserParser = SMC_CreateParser();
dvander@444: SMC_SetReaders(g_hUserParser,
dvander@444: ReadUsers_NewSection,
dvander@444: ReadUsers_KeyValue,
dvander@444: ReadUsers_EndSection);
dvander@1432: SMC_SetRawLine(g_hUserParser, ReadUsers_CurrentLine);
dvander@2052:
dvander@2052: g_GroupArray = CreateArray();
dvander@444: }
dvander@444: }
dvander@444:
dvander@444: ReadUsers()
dvander@444: {
dvander@444: InitializeUserParser();
dvander@444:
dvander@446: BuildPath(Path_SM, g_Filename, sizeof(g_Filename), "configs/admins.cfg");
dvander@444:
dvander@444: /* Set states */
dvander@444: InitGlobalStates();
dvander@444: g_UserState = USER_STATE_NONE;
dvander@444:
dvander@444: new SMCError:err = SMC_ParseFile(g_hUserParser, g_Filename);
dvander@444: if (err != SMCError_Okay)
dvander@444: {
dvander@444: decl String:buffer[64];
dvander@444: if (SMC_GetErrorString(err, buffer, sizeof(buffer)))
dvander@444: {
dvander@444: ParseError("%s", buffer);
dvander@2052: }
dvander@2052: else
dvander@2052: {
dvander@444: ParseError("Fatal parse error");
dvander@444: }
dvander@444: }
dvander@444: }