flag letter assignment is now handled by core
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401304
This commit is contained in:
		
							parent
							
								
									267f2bd60a
								
							
						
					
					
						commit
						2a8d9a7aee
					
				@ -37,8 +37,181 @@
 | 
			
		||||
#include "ForwardSys.h"
 | 
			
		||||
#include "PlayerManager.h"
 | 
			
		||||
#include "ConCmdManager.h"
 | 
			
		||||
#include "TextParsers.h"
 | 
			
		||||
#include "Logger.h"
 | 
			
		||||
#include "sourcemod.h"
 | 
			
		||||
#include "sm_stringutil.h"
 | 
			
		||||
 | 
			
		||||
#define LEVEL_STATE_NONE		0
 | 
			
		||||
#define LEVEL_STATE_LEVELS		1
 | 
			
		||||
#define LEVEL_STATE_FLAGS		2
 | 
			
		||||
 | 
			
		||||
AdminCache g_Admins;
 | 
			
		||||
AdminFlag g_FlagLetters[26];
 | 
			
		||||
bool g_FlagSet[26];
 | 
			
		||||
 | 
			
		||||
/* Default flags */
 | 
			
		||||
AdminFlag g_DefaultFlags[26] = 
 | 
			
		||||
{
 | 
			
		||||
	Admin_Reservation, Admin_Generic, Admin_Kick, Admin_Ban, Admin_Unban,
 | 
			
		||||
	Admin_Slay, Admin_Changemap, Admin_Convars, Admin_Config, Admin_Chat,
 | 
			
		||||
	Admin_Vote, Admin_Password, Admin_RCON, Admin_Cheats, Admin_Custom1, 
 | 
			
		||||
	Admin_Custom2, Admin_Custom3, Admin_Custom4, Admin_Custom5, Admin_Custom6,
 | 
			
		||||
	Admin_Generic, Admin_Generic, Admin_Generic, Admin_Generic, Admin_Generic,
 | 
			
		||||
	Admin_Root
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FlagReader : public ITextListener_SMC
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	void LoadLevels()
 | 
			
		||||
	{
 | 
			
		||||
		if (!Parse())
 | 
			
		||||
		{
 | 
			
		||||
			memcpy(g_FlagLetters, g_DefaultFlags, sizeof(AdminFlag) * 26);
 | 
			
		||||
			for (unsigned int i=0; i<20; i++)
 | 
			
		||||
			{
 | 
			
		||||
				g_FlagSet[i] = true;
 | 
			
		||||
			}
 | 
			
		||||
			g_FlagSet[25] = true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
private:
 | 
			
		||||
	bool Parse()
 | 
			
		||||
	{
 | 
			
		||||
		unsigned int line = 0;
 | 
			
		||||
		SMCParseError error;
 | 
			
		||||
 | 
			
		||||
		m_Line = 0;
 | 
			
		||||
		m_bFileNameLogged = false;
 | 
			
		||||
		g_SourceMod.BuildPath(Path_SM, m_File, sizeof(m_File), "configs/admin_levels.cfg");
 | 
			
		||||
 | 
			
		||||
		if ((error = g_TextParser.ParseFile_SMC(m_File, this, &line, NULL))
 | 
			
		||||
			!= SMCParse_Okay)
 | 
			
		||||
		{
 | 
			
		||||
			const char *err_string = g_TextParser.GetSMCErrorString(error);
 | 
			
		||||
			if (!err_string)
 | 
			
		||||
			{
 | 
			
		||||
				err_string = "Unknown error";
 | 
			
		||||
			}
 | 
			
		||||
			ParseError("Error %d (%s)", error, err_string);
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	void ReadSMC_ParseStart()
 | 
			
		||||
	{
 | 
			
		||||
		m_LevelState = LEVEL_STATE_NONE;
 | 
			
		||||
		m_IgnoreLevel = 0;
 | 
			
		||||
		memset(g_FlagSet, 0, sizeof(g_FlagSet));
 | 
			
		||||
	}
 | 
			
		||||
	SMCParseResult ReadSMC_NewSection(const char *name, bool opt_quotes)
 | 
			
		||||
	{
 | 
			
		||||
		if (m_IgnoreLevel)
 | 
			
		||||
		{
 | 
			
		||||
			m_IgnoreLevel++;
 | 
			
		||||
			return SMCParse_Continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (m_LevelState == LEVEL_STATE_NONE)
 | 
			
		||||
		{
 | 
			
		||||
			if (strcmp(name, "Levels") == 0)
 | 
			
		||||
			{
 | 
			
		||||
				m_IgnoreLevel = LEVEL_STATE_LEVELS;
 | 
			
		||||
			} else {
 | 
			
		||||
				m_IgnoreLevel++;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (m_IgnoreLevel == LEVEL_STATE_LEVELS) {
 | 
			
		||||
			if (strcmp(name, "Flags") == 0)
 | 
			
		||||
			{
 | 
			
		||||
				m_IgnoreLevel = LEVEL_STATE_FLAGS;
 | 
			
		||||
			} else {
 | 
			
		||||
				m_IgnoreLevel++;
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			m_IgnoreLevel++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return SMCParse_Continue;
 | 
			
		||||
	}
 | 
			
		||||
	SMCParseResult ReadSMC_KeyValue(const char *key, const char *value, bool key_quotes, bool value_quotes)
 | 
			
		||||
	{
 | 
			
		||||
		if (m_IgnoreLevel != LEVEL_STATE_FLAGS || m_IgnoreLevel)
 | 
			
		||||
		{
 | 
			
		||||
			return SMCParse_Continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		unsigned char c = (unsigned)value[0];
 | 
			
		||||
 | 
			
		||||
		if (c < (unsigned)'a' || c > (unsigned)'z')
 | 
			
		||||
		{
 | 
			
		||||
			ParseError("Flag \"%c\" is not a lower-case ASCII letter", c);
 | 
			
		||||
			return SMCParse_Continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		c -= (unsigned)'a';
 | 
			
		||||
 | 
			
		||||
		assert(c >= 0 && c < 26);
 | 
			
		||||
 | 
			
		||||
		if (!g_Admins.FindFlag(key, &g_FlagLetters[c]))
 | 
			
		||||
		{
 | 
			
		||||
			ParseError("Unrecognized admin level \"%s\"", key);
 | 
			
		||||
			return SMCParse_Continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		g_FlagSet[c] = true;
 | 
			
		||||
 | 
			
		||||
		return SMCParse_Continue;
 | 
			
		||||
	}
 | 
			
		||||
	SMCParseResult ReadSMC_LeavingSection()
 | 
			
		||||
	{
 | 
			
		||||
		if (m_IgnoreLevel)
 | 
			
		||||
		{
 | 
			
		||||
			m_IgnoreLevel--;
 | 
			
		||||
			return SMCParse_Continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (m_LevelState == LEVEL_STATE_FLAGS)
 | 
			
		||||
		{
 | 
			
		||||
			m_LevelState = LEVEL_STATE_LEVELS;
 | 
			
		||||
			return SMCParse_Halt;
 | 
			
		||||
		} else if (m_LevelState == LEVEL_STATE_LEVELS) {
 | 
			
		||||
			m_LevelState = LEVEL_STATE_NONE;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return SMCParse_Continue;
 | 
			
		||||
	}
 | 
			
		||||
	SMCParseResult ReadSMC_RawLine(const char *line, unsigned int curline)
 | 
			
		||||
	{
 | 
			
		||||
		m_Line = curline;
 | 
			
		||||
		return SMCParse_Continue;
 | 
			
		||||
	}
 | 
			
		||||
	void ParseError(const char *message, ...)
 | 
			
		||||
	{
 | 
			
		||||
		va_list ap;
 | 
			
		||||
		char buffer[256];
 | 
			
		||||
 | 
			
		||||
		va_start(ap, message);
 | 
			
		||||
		UTIL_FormatArgs(buffer, sizeof(buffer), message, ap);
 | 
			
		||||
		va_end(ap);
 | 
			
		||||
 | 
			
		||||
		if (!m_bFileNameLogged)
 | 
			
		||||
		{
 | 
			
		||||
			g_Logger.LogError("[SM] Parse error(s) detected in file \"%s\":", m_File);
 | 
			
		||||
			m_bFileNameLogged = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		g_Logger.LogError("[SM] (Line %d): %s", m_Line, buffer);
 | 
			
		||||
	}
 | 
			
		||||
private:
 | 
			
		||||
	bool m_bFileNameLogged;
 | 
			
		||||
	char m_File[PLATFORM_MAX_PATH];
 | 
			
		||||
	int m_LevelState;
 | 
			
		||||
	int m_IgnoreLevel;
 | 
			
		||||
	unsigned int m_Line;
 | 
			
		||||
} s_FlagReader;
 | 
			
		||||
 | 
			
		||||
AdminCache::AdminCache()
 | 
			
		||||
{
 | 
			
		||||
@ -54,6 +227,7 @@ AdminCache::AdminCache()
 | 
			
		||||
	m_pAuthTables = sm_trie_create();
 | 
			
		||||
	m_InvalidatingAdmins = false;
 | 
			
		||||
	m_destroying = false;
 | 
			
		||||
	m_pLevelNames = sm_trie_create();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AdminCache::~AdminCache()
 | 
			
		||||
@ -81,6 +255,8 @@ AdminCache::~AdminCache()
 | 
			
		||||
	sm_trie_destroy(m_pAuthTables);
 | 
			
		||||
 | 
			
		||||
	delete m_pStrings;
 | 
			
		||||
 | 
			
		||||
	sm_trie_destroy(m_pLevelNames);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AdminCache::OnSourceModStartup(bool late)
 | 
			
		||||
@ -88,6 +264,28 @@ void AdminCache::OnSourceModStartup(bool late)
 | 
			
		||||
	RegisterAuthIdentType("steam");
 | 
			
		||||
	RegisterAuthIdentType("name");
 | 
			
		||||
	RegisterAuthIdentType("ip");
 | 
			
		||||
 | 
			
		||||
	NameFlag("reservation", Admin_Reservation);
 | 
			
		||||
	NameFlag("kick", Admin_Kick);
 | 
			
		||||
	NameFlag("generic", Admin_Generic);
 | 
			
		||||
	NameFlag("ban", Admin_Ban);
 | 
			
		||||
	NameFlag("unban", Admin_Unban);
 | 
			
		||||
	NameFlag("slay", Admin_Slay);
 | 
			
		||||
	NameFlag("changemap", Admin_Changemap);
 | 
			
		||||
	NameFlag("cvars", Admin_Convars);
 | 
			
		||||
	NameFlag("config", Admin_Config);
 | 
			
		||||
	NameFlag("chat", Admin_Chat);
 | 
			
		||||
	NameFlag("vote", Admin_Vote);
 | 
			
		||||
	NameFlag("password", Admin_Password);
 | 
			
		||||
	NameFlag("rcon", Admin_RCON);
 | 
			
		||||
	NameFlag("cheats", Admin_Cheats);
 | 
			
		||||
	NameFlag("root", Admin_Root);
 | 
			
		||||
	NameFlag("custom1", Admin_Custom1);
 | 
			
		||||
	NameFlag("custom2", Admin_Custom2);
 | 
			
		||||
	NameFlag("custom3", Admin_Custom3);
 | 
			
		||||
	NameFlag("custom4", Admin_Custom4);
 | 
			
		||||
	NameFlag("custom5", Admin_Custom5);
 | 
			
		||||
	NameFlag("custom6", Admin_Custom6);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AdminCache::OnSourceModAllInitialized()
 | 
			
		||||
@ -96,6 +294,12 @@ void AdminCache::OnSourceModAllInitialized()
 | 
			
		||||
	g_ShareSys.AddInterface(NULL, this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AdminCache::OnSourceModLevelChange(const char *mapName)
 | 
			
		||||
{
 | 
			
		||||
	/* For now, we only read these once per level. */
 | 
			
		||||
	s_FlagReader.LoadLevels();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AdminCache::OnSourceModShutdown()
 | 
			
		||||
{
 | 
			
		||||
	g_Forwards.ReleaseForward(m_pCacheFwd);
 | 
			
		||||
@ -108,6 +312,27 @@ void AdminCache::OnSourceModPluginsLoaded()
 | 
			
		||||
	DumpAdminCache(AdminCache_Groups, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AdminCache::NameFlag(const char *str, AdminFlag flag)
 | 
			
		||||
{
 | 
			
		||||
	sm_trie_insert(m_pLevelNames, str, (void *)flag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AdminCache::FindFlag(const char *str, AdminFlag *pFlag)
 | 
			
		||||
{
 | 
			
		||||
	void *obj;
 | 
			
		||||
	if (!sm_trie_retrieve(m_pLevelNames, str, &obj))
 | 
			
		||||
	{
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (pFlag)
 | 
			
		||||
	{
 | 
			
		||||
		*pFlag = (AdminFlag)(int)obj;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AdminCache::AddCommandOverride(const char *cmd, OverrideType type, FlagBits flags)
 | 
			
		||||
{
 | 
			
		||||
	Trie *pTrie = NULL;
 | 
			
		||||
@ -1289,3 +1514,41 @@ bool AdminCache::CanAdminTarget(AdminId id, AdminId target)
 | 
			
		||||
	
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AdminCache::FindFlag(char c, AdminFlag *pAdmFlag)
 | 
			
		||||
{
 | 
			
		||||
	if (c < 'a' || c > 'z')
 | 
			
		||||
	{
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (*pAdmFlag)
 | 
			
		||||
	{
 | 
			
		||||
		*pAdmFlag = g_FlagLetters[(unsigned)c - (unsigned)'a'];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FlagBits AdminCache::ReadFlagString(const char *flags, const char **end)
 | 
			
		||||
{
 | 
			
		||||
	FlagBits bits = 0;
 | 
			
		||||
 | 
			
		||||
	while (flags && (*flags != '\0'))
 | 
			
		||||
	{
 | 
			
		||||
		AdminFlag flag;
 | 
			
		||||
		if (!FindFlag(*flags, &flag))
 | 
			
		||||
		{
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		bits |= FlagArrayToBits(&flag, 1);
 | 
			
		||||
		flags++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (end)
 | 
			
		||||
	{
 | 
			
		||||
		*end = flags;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return bits;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -105,6 +105,7 @@ public:
 | 
			
		||||
public: //SMGlobalClass
 | 
			
		||||
	void OnSourceModStartup(bool late);
 | 
			
		||||
	void OnSourceModAllInitialized();
 | 
			
		||||
	void OnSourceModLevelChange(const char *mapName);
 | 
			
		||||
	void OnSourceModShutdown();
 | 
			
		||||
	void OnSourceModPluginsLoaded();
 | 
			
		||||
public: //IAdminSystem
 | 
			
		||||
@ -151,6 +152,9 @@ public: //IAdminSystem
 | 
			
		||||
	bool CheckAdminFlags(AdminId id, FlagBits bits);
 | 
			
		||||
	bool CanAdminTarget(AdminId id, AdminId target);
 | 
			
		||||
	void SetAdminFlags(AdminId id, AccessMode mode, FlagBits bits);
 | 
			
		||||
	bool FindFlag(const char *str, AdminFlag *pFlag);
 | 
			
		||||
	bool FindFlag(char c, AdminFlag *pAdmFlag);
 | 
			
		||||
	FlagBits ReadFlagString(const char *flags, const char **end);
 | 
			
		||||
public:
 | 
			
		||||
	bool IsValidAdmin(AdminId id);
 | 
			
		||||
private:
 | 
			
		||||
@ -161,6 +165,7 @@ private:
 | 
			
		||||
	void DumpCommandOverrideCache(OverrideType type);
 | 
			
		||||
	Trie *GetMethodByIndex(unsigned int index);
 | 
			
		||||
	bool GetMethodIndex(const char *name, unsigned int *_index);
 | 
			
		||||
	void NameFlag(const char *str, AdminFlag flag);
 | 
			
		||||
public:
 | 
			
		||||
	BaseStringTable *m_pStrings;
 | 
			
		||||
	BaseMemTable *m_pMemory;
 | 
			
		||||
@ -179,6 +184,7 @@ public:
 | 
			
		||||
	int m_FreeUserList;
 | 
			
		||||
	bool m_InvalidatingAdmins;
 | 
			
		||||
	bool m_destroying;
 | 
			
		||||
	Trie *m_pLevelNames;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern AdminCache g_Admins;
 | 
			
		||||
 | 
			
		||||
@ -451,6 +451,57 @@ static cell_t CreateAuthMethod(IPluginContext *pContext, const cell_t *params)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cell_t FindFlagByName(IPluginContext *pContext, const cell_t *params)
 | 
			
		||||
{
 | 
			
		||||
	char *flag;
 | 
			
		||||
	pContext->LocalToString(params[1], &flag);
 | 
			
		||||
 | 
			
		||||
	cell_t *addr;
 | 
			
		||||
	pContext->LocalToPhysAddr(params[2], &addr);
 | 
			
		||||
 | 
			
		||||
	AdminFlag admflag;
 | 
			
		||||
	if (!g_Admins.FindFlag(flag, &admflag))
 | 
			
		||||
	{
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*addr = (cell_t)admflag;
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cell_t FindFlagByChar(IPluginContext *pContext, const cell_t *params)
 | 
			
		||||
{
 | 
			
		||||
	cell_t *addr;
 | 
			
		||||
	pContext->LocalToPhysAddr(params[2], &addr);
 | 
			
		||||
 | 
			
		||||
	AdminFlag admflag;
 | 
			
		||||
	if (!g_Admins.FindFlag((char)params[1], &admflag))
 | 
			
		||||
	{
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*addr = (cell_t)admflag;
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cell_t ReadFlagString(IPluginContext *pContext, const cell_t *params)
 | 
			
		||||
{
 | 
			
		||||
	char *flag;
 | 
			
		||||
	pContext->LocalToString(params[1], &flag);
 | 
			
		||||
 | 
			
		||||
	cell_t *addr;
 | 
			
		||||
	pContext->LocalToPhysAddr(params[2], &addr);
 | 
			
		||||
 | 
			
		||||
	const char *end = flag;
 | 
			
		||||
	FlagBits bits = g_Admins.ReadFlagString(flag, &end);
 | 
			
		||||
 | 
			
		||||
	*addr = end - flag;
 | 
			
		||||
 | 
			
		||||
	return bits;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
REGISTER_NATIVES(adminNatives)
 | 
			
		||||
{
 | 
			
		||||
	{"DumpAdminCache",			DumpAdminCache},
 | 
			
		||||
@ -489,6 +540,9 @@ REGISTER_NATIVES(adminNatives)
 | 
			
		||||
	{"FlagBitsToArray",			FlagBitsToArray},
 | 
			
		||||
	{"CanAdminTarget",			CanAdminTarget},
 | 
			
		||||
	{"CreateAuthMethod",		CreateAuthMethod},
 | 
			
		||||
	{"FindFlagByName",			FindFlagByName},
 | 
			
		||||
	{"FindFlagByChar",			FindFlagByChar},
 | 
			
		||||
	{"ReadFlagString",			ReadFlagString},
 | 
			
		||||
	/* -------------------------------------------------- */
 | 
			
		||||
	{NULL,						NULL},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -35,14 +35,11 @@ public Plugin:myinfo =
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Various parsing globals */
 | 
			
		||||
new bool:g_FlagsSet[26];					/* Maps whether flags are set */
 | 
			
		||||
new AdminFlag:g_FlagLetters[26];			/* Maps the flag letters */		
 | 
			
		||||
new bool:g_LoggedFileName = false;			/* Whether or not the file name has been logged */
 | 
			
		||||
new g_ErrorCount = 0;						/* Current error count */
 | 
			
		||||
new g_IgnoreLevel = 0;						/* Nested ignored section count, so users can screw up files safely */
 | 
			
		||||
new String:g_Filename[PLATFORM_MAX_PATH];	/* Used for error messages */
 | 
			
		||||
 | 
			
		||||
#include "admin-levels.sp"
 | 
			
		||||
#include "admin-overrides.sp"
 | 
			
		||||
#include "admin-groups.sp"
 | 
			
		||||
#include "admin-users.sp"
 | 
			
		||||
@ -50,7 +47,6 @@ new String:g_Filename[PLATFORM_MAX_PATH];	/* Used for error messages */
 | 
			
		||||
 | 
			
		||||
public OnRebuildAdminCache(AdminCachePart:part)
 | 
			
		||||
{
 | 
			
		||||
	RefreshLevels();
 | 
			
		||||
	if (part == AdminCache_Overrides)
 | 
			
		||||
	{
 | 
			
		||||
		ReadOverrides();
 | 
			
		||||
 | 
			
		||||
@ -92,15 +92,10 @@ public SMCResult:ReadGroups_KeyValue(Handle:smc,
 | 
			
		||||
				new len = strlen(value);
 | 
			
		||||
				for (new i=0; i<len; i++)
 | 
			
		||||
				{
 | 
			
		||||
					if (value[i] < 'a' || value[i] > 'z')
 | 
			
		||||
					if (!FindFlagByChar(value[i], flag))
 | 
			
		||||
					{
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
					if (!g_FlagsSet[value[i] - 'a'])
 | 
			
		||||
					{
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
					flag = g_FlagLetters[value[i] - 'a'];
 | 
			
		||||
					SetAdmGroupAddFlag(g_CurGrp, flag, true);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (StrEqual(key, "immunity")) {
 | 
			
		||||
 | 
			
		||||
@ -1,217 +0,0 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * admin-levels.sp
 | 
			
		||||
 * Reads access flags from the admin_levels.cfg file.  Do not compile this directly.
 | 
			
		||||
 * This file is part of SourceMod, Copyright (C) 2004-2007 AlliedModders LLC
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2
 | 
			
		||||
 * of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Version: $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define LEVEL_STATE_NONE		0
 | 
			
		||||
#define LEVEL_STATE_LEVELS		1
 | 
			
		||||
#define LEVEL_STATE_FLAGS		2
 | 
			
		||||
 | 
			
		||||
static Handle:g_hLevelParser = INVALID_HANDLE;
 | 
			
		||||
static g_LevelState = LEVEL_STATE_NONE;
 | 
			
		||||
 | 
			
		||||
/* :TODO: log line numbers? */
 | 
			
		||||
 | 
			
		||||
LoadDefaultLetters()
 | 
			
		||||
{
 | 
			
		||||
	for (new i='t'; i<'z'; i++)
 | 
			
		||||
	{
 | 
			
		||||
		g_FlagsSet[i-'a'] = false;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	g_FlagLetters['a'-'a'] = Admin_Reservation;
 | 
			
		||||
	g_FlagLetters['b'-'a'] = Admin_Generic;
 | 
			
		||||
	g_FlagLetters['c'-'a'] = Admin_Kick;
 | 
			
		||||
	g_FlagLetters['d'-'a'] = Admin_Ban;
 | 
			
		||||
	g_FlagLetters['e'-'a'] = Admin_Unban;
 | 
			
		||||
	g_FlagLetters['f'-'a'] = Admin_Slay;
 | 
			
		||||
	g_FlagLetters['g'-'a'] = Admin_Changemap;
 | 
			
		||||
	g_FlagLetters['h'-'a'] = Admin_Convars;
 | 
			
		||||
	g_FlagLetters['i'-'a'] = Admin_Config;
 | 
			
		||||
	g_FlagLetters['j'-'a'] = Admin_Chat;
 | 
			
		||||
	g_FlagLetters['k'-'a'] = Admin_Vote;
 | 
			
		||||
	g_FlagLetters['l'-'a'] = Admin_Password;
 | 
			
		||||
	g_FlagLetters['m'-'a'] = Admin_RCON;
 | 
			
		||||
	g_FlagLetters['n'-'a'] = Admin_Cheats;
 | 
			
		||||
	g_FlagLetters['o'-'a'] = Admin_Custom1;
 | 
			
		||||
	g_FlagLetters['p'-'a'] = Admin_Custom2;
 | 
			
		||||
	g_FlagLetters['q'-'a'] = Admin_Custom3;
 | 
			
		||||
	g_FlagLetters['r'-'a'] = Admin_Custom4;
 | 
			
		||||
	g_FlagLetters['s'-'a'] = Admin_Custom5;
 | 
			
		||||
	g_FlagLetters['t'-'a'] = Admin_Custom6;
 | 
			
		||||
	g_FlagLetters['z'-'a'] = Admin_Root;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public SMCResult:ReadLevels_NewSection(Handle:smc, const String:name[], bool:opt_quotes)
 | 
			
		||||
{
 | 
			
		||||
	if (g_IgnoreLevel)
 | 
			
		||||
	{
 | 
			
		||||
		g_IgnoreLevel++;
 | 
			
		||||
		return SMCParse_Continue;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (g_LevelState == LEVEL_STATE_NONE)
 | 
			
		||||
	{
 | 
			
		||||
		if (StrEqual(name, "Levels"))
 | 
			
		||||
		{
 | 
			
		||||
			g_LevelState = LEVEL_STATE_LEVELS;
 | 
			
		||||
		} else {
 | 
			
		||||
			g_IgnoreLevel++;
 | 
			
		||||
		}
 | 
			
		||||
	} else if (g_LevelState == LEVEL_STATE_LEVELS) {
 | 
			
		||||
		if (StrEqual(name, "Flags"))
 | 
			
		||||
		{
 | 
			
		||||
			g_LevelState = LEVEL_STATE_FLAGS;
 | 
			
		||||
		} else {
 | 
			
		||||
			g_IgnoreLevel++;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		g_IgnoreLevel++;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return SMCParse_Continue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public SMCResult:ReadLevels_KeyValue(Handle:smc, const String:key[], const String:value[], bool:key_quotes, bool:value_quotes)
 | 
			
		||||
{
 | 
			
		||||
	if (g_LevelState == LEVEL_STATE_FLAGS && !g_IgnoreLevel)
 | 
			
		||||
	{
 | 
			
		||||
		new chr = value[0];
 | 
			
		||||
		
 | 
			
		||||
		if (chr < 'a' || chr > 'z')
 | 
			
		||||
		{
 | 
			
		||||
			ParseError("Unrecognized character: \"%s\"", value);
 | 
			
		||||
			return SMCParse_Continue;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		chr -= 'a';
 | 
			
		||||
		
 | 
			
		||||
		new AdminFlag:flag;
 | 
			
		||||
		
 | 
			
		||||
		if (StrEqual(key, "reservation"))
 | 
			
		||||
		{
 | 
			
		||||
			flag = Admin_Reservation;
 | 
			
		||||
		} else if (StrEqual(key, "kick")) {
 | 
			
		||||
			flag = Admin_Kick;
 | 
			
		||||
		} else if (StrEqual(key, "generic")) {
 | 
			
		||||
			flag = Admin_Generic;
 | 
			
		||||
		} else if (StrEqual(key, "ban")) {
 | 
			
		||||
			flag = Admin_Ban;
 | 
			
		||||
		} else if (StrEqual(key, "unban")) {
 | 
			
		||||
			flag = Admin_Unban;
 | 
			
		||||
		} else if (StrEqual(key, "slay")) {
 | 
			
		||||
			flag = Admin_Slay;
 | 
			
		||||
		} else if (StrEqual(key, "changemap")) {
 | 
			
		||||
			flag = Admin_Changemap;
 | 
			
		||||
		} else if (StrEqual(key, "cvars")) {
 | 
			
		||||
			flag = Admin_Convars;
 | 
			
		||||
		} else if (StrEqual(key, "config")) {
 | 
			
		||||
			flag = Admin_Config;
 | 
			
		||||
		} else if (StrEqual(key, "chat")) {
 | 
			
		||||
			flag = Admin_Chat;
 | 
			
		||||
		} else if (StrEqual(key, "vote")) {
 | 
			
		||||
			flag = Admin_Vote;
 | 
			
		||||
		} else if (StrEqual(key, "password")) {
 | 
			
		||||
			flag = Admin_Password;
 | 
			
		||||
		} else if (StrEqual(key, "rcon")) {
 | 
			
		||||
			flag = Admin_RCON;
 | 
			
		||||
		} else if (StrEqual(key, "cheats")) {
 | 
			
		||||
			flag = Admin_Cheats;
 | 
			
		||||
		} else if (StrEqual(key, "root")) {
 | 
			
		||||
			flag = Admin_Root;
 | 
			
		||||
		} else if (StrEqual(key, "custom1")) {
 | 
			
		||||
			flag = Admin_Custom1;
 | 
			
		||||
		} else if (StrEqual(key, "custom2")) {
 | 
			
		||||
			flag = Admin_Custom2;
 | 
			
		||||
		} else if (StrEqual(key, "custom3")) {
 | 
			
		||||
			flag = Admin_Custom3;
 | 
			
		||||
		} else if (StrEqual(key, "custom4")) {
 | 
			
		||||
			flag = Admin_Custom4;
 | 
			
		||||
		} else if (StrEqual(key, "custom5")) {
 | 
			
		||||
			flag = Admin_Custom5;
 | 
			
		||||
		} else if (StrEqual(key, "custom6")) {
 | 
			
		||||
			flag = Admin_Custom6;
 | 
			
		||||
		} else {
 | 
			
		||||
			ParseError("Unrecognized flag type: %s", key);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		g_FlagLetters[chr] = flag;
 | 
			
		||||
		g_FlagsSet[chr] = true;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return SMCParse_Continue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public SMCResult:ReadLevels_EndSection(Handle:smc)
 | 
			
		||||
{
 | 
			
		||||
	/* If we're ignoring, skip out */
 | 
			
		||||
	if (g_IgnoreLevel)
 | 
			
		||||
	{
 | 
			
		||||
		g_IgnoreLevel--;
 | 
			
		||||
		return SMCParse_Continue;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (g_LevelState == LEVEL_STATE_FLAGS)
 | 
			
		||||
	{
 | 
			
		||||
		/* We're totally done parsing */
 | 
			
		||||
		g_LevelState = LEVEL_STATE_LEVELS;
 | 
			
		||||
		return SMCParse_Halt;
 | 
			
		||||
	} else if (g_LevelState == LEVEL_STATE_LEVELS) {
 | 
			
		||||
		g_LevelState = LEVEL_STATE_NONE;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return SMCParse_Continue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static InitializeLevelParser()
 | 
			
		||||
{
 | 
			
		||||
	if (g_hLevelParser == INVALID_HANDLE)
 | 
			
		||||
	{
 | 
			
		||||
		g_hLevelParser = SMC_CreateParser();
 | 
			
		||||
		SMC_SetReaders(g_hLevelParser, 
 | 
			
		||||
				   	ReadLevels_NewSection,
 | 
			
		||||
				   	ReadLevels_KeyValue,
 | 
			
		||||
				   	ReadLevels_EndSection);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RefreshLevels()
 | 
			
		||||
{
 | 
			
		||||
	LoadDefaultLetters();
 | 
			
		||||
	InitializeLevelParser();
 | 
			
		||||
	
 | 
			
		||||
	BuildPath(Path_SM, g_Filename, sizeof(g_Filename), "configs/admin_levels.cfg");
 | 
			
		||||
	
 | 
			
		||||
	/* Set states */
 | 
			
		||||
	InitGlobalStates();
 | 
			
		||||
	g_LevelState = LEVEL_STATE_NONE;
 | 
			
		||||
		
 | 
			
		||||
	new SMCError:err = SMC_ParseFile(g_hLevelParser, g_Filename);
 | 
			
		||||
	if (err != SMCError_Okay)
 | 
			
		||||
	{
 | 
			
		||||
		decl String:buffer[64];
 | 
			
		||||
		if (SMC_GetErrorString(err, buffer, sizeof(buffer)))
 | 
			
		||||
		{
 | 
			
		||||
			ParseError("%s", buffer);
 | 
			
		||||
		} else {
 | 
			
		||||
			ParseError("Fatal parse error");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -69,27 +69,7 @@ public SMCResult:ReadOverrides_KeyValue(Handle:smc,
 | 
			
		||||
		return SMCParse_Continue;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	new AdminFlag:array[AdminFlags_TOTAL];
 | 
			
		||||
	new flags_total;
 | 
			
		||||
	
 | 
			
		||||
	new len = strlen(value);
 | 
			
		||||
	for (new i=0; i<len; i++)
 | 
			
		||||
	{
 | 
			
		||||
		if (value[i] < 'a' || value[i] > 'z')
 | 
			
		||||
		{
 | 
			
		||||
			ParseError("Invalid flag detected: %c", value[i]);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		new val = value[i] - 'a';
 | 
			
		||||
		if (!g_FlagsSet[val])
 | 
			
		||||
		{
 | 
			
		||||
			ParseError("Invalid flag detected: %c", value[i]);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		array[flags_total++] = g_FlagLetters[val];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	new flags = FlagArrayToBits(array, flags_total);
 | 
			
		||||
	new flags = ReadFlagString(value);
 | 
			
		||||
	
 | 
			
		||||
	if (key[0] == '@')
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
@ -114,24 +114,20 @@ ReadAdminLine(const String:line[])
 | 
			
		||||
		new len = strlen(flags);
 | 
			
		||||
		new bool:is_default = false;
 | 
			
		||||
		for (new i=0; i<len; i++)
 | 
			
		||||
		{
 | 
			
		||||
			if (flags[i] < 'a' || flags[i] > 'z')
 | 
			
		||||
		{
 | 
			
		||||
			if (flags[i] == '$')
 | 
			
		||||
			{
 | 
			
		||||
				is_default = true;
 | 
			
		||||
			} else {
 | 
			
		||||
					ParseError("Invalid flag detected: %c", flags[i]);
 | 
			
		||||
				}
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			new val = flags[i] - 'a';
 | 
			
		||||
			if (!g_FlagsSet[val])
 | 
			
		||||
				new AdminFlag:flag;
 | 
			
		||||
				
 | 
			
		||||
				if (!FindFlagByChar(flags[i], flag))
 | 
			
		||||
				{
 | 
			
		||||
					ParseError("Invalid flag detected: %c", flags[i]);
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
			SetAdminFlag(admin, g_FlagLetters[val], true);
 | 
			
		||||
				SetAdminFlag(admin, flag, true);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (is_default)
 | 
			
		||||
 | 
			
		||||
@ -93,21 +93,15 @@ public SMCResult:ReadUsers_KeyValue(Handle:smc,
 | 
			
		||||
		}
 | 
			
		||||
	} else if (StrEqual(key, "flags")) {
 | 
			
		||||
		new len = strlen(value);
 | 
			
		||||
		new AdminFlag:flag;
 | 
			
		||||
		
 | 
			
		||||
		for (new i=0; i<len; i++)
 | 
			
		||||
		{
 | 
			
		||||
			if (value[i] < 'a' || value[i] > 'z')
 | 
			
		||||
			if (!FindFlagByChar(value[i], flag))
 | 
			
		||||
			{
 | 
			
		||||
				ParseError("Invalid flag detected: %c", value[i]);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			new val = value[i] - 'a';
 | 
			
		||||
			if (!g_FlagsSet[val])
 | 
			
		||||
			{
 | 
			
		||||
				ParseError("Invalid flag detected: %c", value[i]);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			SetAdminFlag(g_CurUser, g_FlagLetters[val], true);
 | 
			
		||||
			SetAdminFlag(g_CurUser, flag, true);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -488,6 +488,33 @@ native FlagArrayToBits(const AdminFlag:array[], numFlags);
 | 
			
		||||
 */
 | 
			
		||||
native FlagBitsToArray(bits, AdminFlag:array[], maxSize);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Finds a flag by its string name.
 | 
			
		||||
 *
 | 
			
		||||
 * @param name			Flag name (like "kick"), case sensitive.
 | 
			
		||||
 * @param flag			Variable to store flag in.
 | 
			
		||||
 * @return				True on success, false if not found.
 | 
			
		||||
 */
 | 
			
		||||
native bool:FindFlagByName(const String:name[], &AdminFlag:flag);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Finds a flag by a given character.
 | 
			
		||||
 *
 | 
			
		||||
 * @param c				Flag ASCII character/token.
 | 
			
		||||
 * @param flag			Variable to store flag in.
 | 
			
		||||
 * @return				True on success, false if not found.
 | 
			
		||||
 */
 | 
			
		||||
native bool:FindFlagByChar(c, &AdminFlag:flag);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Converts a string of flag characters to a bit string.
 | 
			
		||||
 *
 | 
			
		||||
 * @param flags			Flag ASCII string.
 | 
			
		||||
 * @param numchars		Optional variable to store the number of bytes read.
 | 
			
		||||
 * @return				Bit string of ADMFLAG values.
 | 
			
		||||
 */
 | 
			
		||||
native ReadFlagString(const String:flags[], &numchars=0);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests whether one admin can target another.
 | 
			
		||||
 *
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@
 | 
			
		||||
#include <IShareSys.h>
 | 
			
		||||
 | 
			
		||||
#define SMINTERFACE_ADMINSYS_NAME		"IAdminSys"
 | 
			
		||||
#define SMINTERFACE_ADMINSYS_VERSION	1
 | 
			
		||||
#define SMINTERFACE_ADMINSYS_VERSION	2
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file IAdminSystem.h
 | 
			
		||||
@ -599,6 +599,34 @@ namespace SourceMod
 | 
			
		||||
		 * @return			True if this admin has permission to target the other admin.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual bool CanAdminTarget(AdminId id, AdminId target) =0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Returns a flag from a named string.
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param flagname	Case sensitive flag name string (like "kick").
 | 
			
		||||
		 * @param pAdmFlag	Pointer to store the found admin flag in.
 | 
			
		||||
		 * @return			True on success, false on failure.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual bool FindFlag(const char *flagname, AdminFlag *pAdmFlag) =0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Reads a single character as a flag.
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param flag		Flag character.
 | 
			
		||||
		 * @param pAdmFlag	Pointer to store the admin flag.
 | 
			
		||||
		 * @return			True on success, false if invalid.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual bool FindFlag(char c, AdminFlag *pAdmFlag) =0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Reads a string of flag letters and returns its access value.
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param flags		Flag string.
 | 
			
		||||
		 * @param end		Pointer to store the last value read.  On success, 
 | 
			
		||||
		 *					this will store a pointer to the null terminator.
 | 
			
		||||
		 * @return			FlagBits value of the flags.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual FlagBits ReadFlagString(const char *flags, const char **end) =0;
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user