2751 lines
		
	
	
		
			75 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
			
		
		
	
	
			2751 lines
		
	
	
		
			75 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
| // *************************************************************************
 | |
| //  This file is part of SourceBans++.
 | |
| //
 | |
| //  Copyright (C) 2014-2016 SourceBans++ Dev Team <https://github.com/sbpp>
 | |
| //
 | |
| //  SourceBans++ 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, per version 3 of the License.
 | |
| //
 | |
| //  SourceBans++ 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 SourceBans++. If not, see <http://www.gnu.org/licenses/>.
 | |
| //
 | |
| //  This file is based off work(s) covered by the following copyright(s):
 | |
| //
 | |
| //   SourceBans 1.4.11
 | |
| //   Copyright (C) 2007-2015 SourceBans Team - Part of GameConnect
 | |
| //   Licensed under GNU GPL version 3, or later.
 | |
| //   Page: <http://www.sourcebans.net/> - <https://github.com/GameConnect/sourcebansv1>
 | |
| //
 | |
| // *************************************************************************
 | |
| 
 | |
| #pragma semicolon 1
 | |
| #include <sourcemod>
 | |
| #include <sourcebanspp>
 | |
| 
 | |
| #undef REQUIRE_PLUGIN
 | |
| #include <adminmenu>
 | |
| #tryinclude <updater>
 | |
| 
 | |
| #define SB_VERSION "1.6.4"
 | |
| #define SBR_VERSION "1.6.4"
 | |
| 
 | |
| #if defined _updater_included
 | |
| #define UPDATE_URL "https://sbpp.github.io/updater/updatefile.txt"
 | |
| #endif
 | |
| 
 | |
| //GLOBAL DEFINES
 | |
| #define YELLOW				0x01
 | |
| #define NAMECOLOR			0x02
 | |
| #define TEAMCOLOR			0x03
 | |
| #define GREEN				0x04
 | |
| 
 | |
| #define DISABLE_ADDBAN		1
 | |
| #define DISABLE_UNBAN		2
 | |
| 
 | |
| #define FLAG_LETTERS_SIZE 26
 | |
| 
 | |
| //#define DEBUG
 | |
| 
 | |
| enum State/* ConfigState */
 | |
| {
 | |
| 	ConfigStateNone = 0,
 | |
| 	ConfigStateConfig,
 | |
| 	ConfigStateReasons,
 | |
| 	ConfigStateHacking,
 | |
| 	ConfigStateTime
 | |
| }
 | |
| 
 | |
| State ConfigState;
 | |
| 
 | |
| #define Prefix "[SourceBans++] "
 | |
| 
 | |
| /* Admin Stuff*/
 | |
| AdminCachePart loadPart;
 | |
| 
 | |
| AdminFlag g_FlagLetters[FLAG_LETTERS_SIZE];
 | |
| 
 | |
| /* Cvar handle*/
 | |
| ConVar
 | |
| 	CvarHostIp
 | |
| 	, CvarPort;
 | |
| 
 | |
| /* Database handle */
 | |
| Database DB;
 | |
| Database SQLiteDB;
 | |
| 
 | |
| char
 | |
| 	ServerIp[24]
 | |
| 	, ServerPort[7]
 | |
| 	, DatabasePrefix[10] = "sb"
 | |
| 	, WebsiteAddress[128]
 | |
| 	, groupsLoc[128] /* Admin KeyValues */
 | |
| 	, adminsLoc[128]
 | |
| 	, overridesLoc[128]
 | |
| 	, logFile[256]; /* Log Stuff */
 | |
| 
 | |
| float RetryTime = 15.0;
 | |
| 
 | |
| bool
 | |
| 	loadAdmins /* Admin Stuff*/
 | |
| 	, loadGroups
 | |
| 	, loadOverrides
 | |
| 	, LateLoaded
 | |
| 	, AutoAdd
 | |
| 	, g_bConnecting = false
 | |
| 	, requireSiteLogin = false /* Require a lastvisited from SB site */
 | |
| 	, backupConfig = true
 | |
| 	, enableAdmins = true
 | |
| 	, PlayerStatus[MAXPLAYERS + 1]; /* Player ban check status */
 | |
| 
 | |
| int
 | |
| 	g_BanTarget[MAXPLAYERS + 1] =  { -1, ... }
 | |
| 	, g_BanTime[MAXPLAYERS + 1] =  { -1, ... }
 | |
| 	, curLoading
 | |
| 	, serverID = -1
 | |
| 	, ProcessQueueTime = 5
 | |
| 	, g_ownReasons[MAXPLAYERS + 1] =  { false, ... } /* Own Chat Reason */
 | |
| 	, CommandDisable; /* Disable of addban and unban */
 | |
| 
 | |
| Handle
 | |
| 	ConfigParser
 | |
| 	, hTopMenu = INVALID_HANDLE
 | |
| 	, TimeMenuHandle /* Menu file globals */
 | |
| 	, ReasonMenuHandle
 | |
| 	, HackingMenuHandle
 | |
| 	, g_hFwd_OnBanAdded
 | |
| 	, g_hFwd_OnReportAdded
 | |
| 	, PlayerRecheck[MAXPLAYERS + 1] =  { INVALID_HANDLE, ... } /* Datapack and Timer handles */
 | |
| 	, PlayerDataPack[MAXPLAYERS + 1] =  { INVALID_HANDLE, ... };
 | |
| 
 | |
| public Plugin myinfo =
 | |
| {
 | |
| 	name = "SourceBans++: Main Plugin",
 | |
| 	author = "SourceBans Development Team, SourceBans++ Dev Team",
 | |
| 	description = "Advanced ban management for the Source engine",
 | |
| 	version = SBR_VERSION,
 | |
| 	url = "https://sbpp.github.io"
 | |
| };
 | |
| 
 | |
| #if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 3
 | |
| public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
 | |
| #else
 | |
| public bool AskPluginLoad(Handle myself, bool late, char[] error, int err_max)
 | |
| #endif
 | |
| {
 | |
| 	RegPluginLibrary("sourcebans++");
 | |
| 
 | |
| 	CreateNative("SBBanPlayer", Native_SBBanPlayer);
 | |
| 	CreateNative("SBPP_BanPlayer", Native_SBBanPlayer);
 | |
| 	CreateNative("SBPP_ReportPlayer", Native_SBReportPlayer);
 | |
| 
 | |
| 	g_hFwd_OnBanAdded = CreateGlobalForward("SBPP_OnBanPlayer", ET_Ignore, Param_Cell, Param_Cell, Param_Cell, Param_String);
 | |
| 	g_hFwd_OnReportAdded = CreateGlobalForward("SBPP_OnReportPlayer", ET_Ignore, Param_Cell, Param_Cell, Param_String);
 | |
| 
 | |
| 	LateLoaded = late;
 | |
| 
 | |
| 	#if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 3
 | |
| 	return APLRes_Success;
 | |
| 	#else
 | |
| 	return true;
 | |
| 	#endif
 | |
| }
 | |
| 
 | |
| public OnPluginStart()
 | |
| {
 | |
| 	LoadTranslations("common.phrases");
 | |
| 	LoadTranslations("plugin.basecommands");
 | |
| 	LoadTranslations("sourcebans.phrases");
 | |
| 	LoadTranslations("basebans.phrases");
 | |
| 	loadAdmins = loadGroups = loadOverrides = false;
 | |
| 
 | |
| 	CvarHostIp = FindConVar("hostip");
 | |
| 	CvarPort = FindConVar("hostport");
 | |
| 	CreateConVar("sb_version", SB_VERSION, _, FCVAR_SPONLY | FCVAR_REPLICATED | FCVAR_NOTIFY);
 | |
| 	CreateConVar("sbr_version", SBR_VERSION, _, FCVAR_SPONLY | FCVAR_REPLICATED | FCVAR_NOTIFY);
 | |
| 	RegServerCmd("sm_rehash", sm_rehash, "Reload SQL admins");
 | |
| 	RegAdminCmd("sm_ban", CommandBan, ADMFLAG_BAN, "sm_ban <#userid|name> <minutes|0> [reason]", "sourcebans");
 | |
| 	RegAdminCmd("sm_banip", CommandBanIp, ADMFLAG_BAN, "sm_banip <ip|#userid|name> <time> [reason]", "sourcebans");
 | |
| 	RegAdminCmd("sm_addban", CommandAddBan, ADMFLAG_RCON, "sm_addban <time> <steamid> [reason]", "sourcebans");
 | |
| 	RegAdminCmd("sm_unban", CommandUnban, ADMFLAG_UNBAN, "sm_unban <steamid|ip> [reason]", "sourcebans");
 | |
| 	RegAdminCmd("sb_reload",
 | |
| 		_CmdReload,
 | |
| 		ADMFLAG_RCON,
 | |
| 		"Reload sourcebans config and ban reason menu options",
 | |
| 		"sourcebans");
 | |
| 
 | |
| 	RegConsoleCmd("say", ChatHook);
 | |
| 	RegConsoleCmd("say_team", ChatHook);
 | |
| 
 | |
| 	if ((TimeMenuHandle = CreateMenu(MenuHandler_BanTimeList, MenuAction_Select|MenuAction_Cancel|MenuAction_DrawItem)) != INVALID_HANDLE)
 | |
| 	{
 | |
| 		SetMenuPagination(TimeMenuHandle, 8);
 | |
| 		SetMenuExitBackButton(TimeMenuHandle, true);
 | |
| 	}
 | |
| 
 | |
| 	if ((ReasonMenuHandle = CreateMenu(ReasonSelected)) != INVALID_HANDLE)
 | |
| 	{
 | |
| 		SetMenuPagination(ReasonMenuHandle, 8);
 | |
| 		SetMenuExitBackButton(ReasonMenuHandle, true);
 | |
| 	}
 | |
| 
 | |
| 	if ((HackingMenuHandle = CreateMenu(HackingSelected)) != INVALID_HANDLE)
 | |
| 	{
 | |
| 		SetMenuPagination(HackingMenuHandle, 8);
 | |
| 		SetMenuExitBackButton(HackingMenuHandle, true);
 | |
| 	}
 | |
| 
 | |
| 	g_FlagLetters = CreateFlagLetters();
 | |
| 
 | |
| 	BuildPath(Path_SM, logFile, sizeof(logFile), "logs/sourcebans.log");
 | |
| 	g_bConnecting = true;
 | |
| 
 | |
| 	// Catch config error and show link to FAQ
 | |
| 	if (!SQL_CheckConfig("sourcebans"))
 | |
| 	{
 | |
| 		if (ReasonMenuHandle != INVALID_HANDLE)
 | |
| 			CloseHandle(ReasonMenuHandle);
 | |
| 		if (HackingMenuHandle != INVALID_HANDLE)
 | |
| 			CloseHandle(HackingMenuHandle);
 | |
| 		LogToFile(logFile, "Database failure: Could not find Database conf \"sourcebans\". See Docs: https://sbpp.github.io/docs/");
 | |
| 		SetFailState("Database failure: Could not find Database conf \"sourcebans\"");
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	Database.Connect(GotDatabase, "sourcebans");
 | |
| 
 | |
| 	BuildPath(Path_SM, groupsLoc, sizeof(groupsLoc), "configs/sourcebans/sb_admin_groups.cfg");
 | |
| 
 | |
| 	BuildPath(Path_SM, adminsLoc, sizeof(adminsLoc), "configs/sourcebans/sb_admins.cfg");
 | |
| 
 | |
| 	BuildPath(Path_SM, overridesLoc, sizeof(overridesLoc), "configs/sourcebans/overrides_backup.cfg");
 | |
| 
 | |
| 	InitializeBackupDB();
 | |
| 
 | |
| 	// This timer is what processes the SQLite queue when the database is unavailable
 | |
| 	CreateTimer(float(ProcessQueueTime * 60), ProcessQueue);
 | |
| 
 | |
| 	if (LateLoaded)
 | |
| 	{
 | |
| 		AccountForLateLoading();
 | |
| 	}
 | |
| 
 | |
| 	#if defined _updater_included
 | |
| 	if (LibraryExists("updater"))
 | |
| 	{
 | |
| 		Updater_AddPlugin(UPDATE_URL);
 | |
| 	}
 | |
| 	#endif
 | |
| }
 | |
| 
 | |
| #if defined _updater_included
 | |
| public void OnLibraryAdded(const char[] name)
 | |
| {
 | |
| 	if (StrEqual(name, "updater"))
 | |
| 	{
 | |
| 		Updater_AddPlugin(UPDATE_URL);
 | |
| 	}
 | |
| }
 | |
| #endif
 | |
| 
 | |
| public void OnAllPluginsLoaded()
 | |
| {
 | |
| 	Handle topmenu;
 | |
| 	#if defined DEBUG
 | |
| 	LogToFile(logFile, "OnAllPluginsLoaded()");
 | |
| 	#endif
 | |
| 
 | |
| 	if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != INVALID_HANDLE))
 | |
| 	{
 | |
| 		OnAdminMenuReady(topmenu);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| public void OnConfigsExecuted()
 | |
| {
 | |
| 	char filename[200];
 | |
| 	BuildPath(Path_SM, filename, sizeof(filename), "plugins/basebans.smx");
 | |
| 	if (FileExists(filename))
 | |
| 	{
 | |
| 		char newfilename[200];
 | |
| 		BuildPath(Path_SM, newfilename, sizeof(newfilename), "plugins/disabled/basebans.smx");
 | |
| 		ServerCommand("sm plugins unload basebans");
 | |
| 		if (FileExists(newfilename))
 | |
| 			DeleteFile(newfilename);
 | |
| 		RenameFile(newfilename, filename);
 | |
| 		LogToFile(logFile, "plugins/basebans.smx was unloaded and moved to plugins/disabled/basebans.smx");
 | |
| 	}
 | |
| }
 | |
| 
 | |
| public void OnMapStart()
 | |
| {
 | |
| 	ResetSettings();
 | |
| }
 | |
| 
 | |
| public OnMapEnd()
 | |
| {
 | |
| 	for (int i = 0; i <= MaxClients; i++)
 | |
| 	{
 | |
| 		if (PlayerDataPack[i] != INVALID_HANDLE)
 | |
| 		{
 | |
| 			/* Need to close reason pack */
 | |
| 			CloseHandle(PlayerDataPack[i]);
 | |
| 			PlayerDataPack[i] = INVALID_HANDLE;
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // CLIENT CONNECTION FUNCTIONS //
 | |
| 
 | |
| public Action OnClientPreAdminCheck(int client)
 | |
| {
 | |
| 	if (!DB || GetUserAdmin(client) != INVALID_ADMIN_ID)
 | |
| 		return Plugin_Continue;
 | |
| 
 | |
| 	return curLoading > 0 ? Plugin_Handled : Plugin_Continue;
 | |
| }
 | |
| 
 | |
| public OnClientDisconnect(int client)
 | |
| {
 | |
| 	if (PlayerRecheck[client] != INVALID_HANDLE)
 | |
| 	{
 | |
| 		KillTimer(PlayerRecheck[client]);
 | |
| 		PlayerRecheck[client] = INVALID_HANDLE;
 | |
| 	}
 | |
| 	g_ownReasons[client] = false;
 | |
| }
 | |
| 
 | |
| public bool OnClientConnect(int client, char[] rejectmsg, int maxlen)
 | |
| {
 | |
| 	PlayerStatus[client] = false;
 | |
| 	return true;
 | |
| }
 | |
| 
 | |
| public void OnClientAuthorized(int client, const char[] auth)
 | |
| {
 | |
| 	/* Do not check bots nor check player with lan steamid. */
 | |
| 	if (auth[0] == 'B' || auth[9] == 'L' || DB == INVALID_HANDLE)
 | |
| 	{
 | |
| 		PlayerStatus[client] = true;
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	char Query[256], ip[30];
 | |
| 
 | |
| 	GetClientIP(client, ip, sizeof(ip));
 | |
| 
 | |
| 	FormatEx(Query, sizeof(Query), "SELECT bid, ip FROM %s_bans WHERE ((type = 0 AND authid REGEXP '^STEAM_[0-9]:%s$') OR (type = 1 AND ip = '%s')) AND (length = '0' OR ends > UNIX_TIMESTAMP()) AND RemoveType IS NULL", DatabasePrefix, auth[8], ip);
 | |
| 
 | |
| 	#if defined DEBUG
 | |
| 	LogToFile(logFile, "Checking ban for: %s", auth);
 | |
| 	#endif
 | |
| 
 | |
| 	DB.Query(VerifyBan, Query, GetClientUserId(client), DBPrio_High);
 | |
| }
 | |
| 
 | |
| public void OnRebuildAdminCache(AdminCachePart part)
 | |
| {
 | |
| 	loadPart = part;
 | |
| 	switch (loadPart)
 | |
| 	{
 | |
| 		case AdminCache_Overrides:
 | |
| 		loadOverrides = true;
 | |
| 		case AdminCache_Groups:
 | |
| 		loadGroups = true;
 | |
| 		case AdminCache_Admins:
 | |
| 		loadAdmins = true;
 | |
| 	}
 | |
| 	if (DB == INVALID_HANDLE) {
 | |
| 		if (!g_bConnecting) {
 | |
| 			g_bConnecting = true;
 | |
| 			Database.Connect(GotDatabase, "sourcebans");
 | |
| 		}
 | |
| 	}
 | |
| 	else {
 | |
| 		GotDatabase(DB, "", 0);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // COMMAND CODE //
 | |
| 
 | |
| public Action ChatHook(int client, int args)
 | |
| {
 | |
| 	// is this player preparing to ban someone
 | |
| 	if (g_ownReasons[client])
 | |
| 	{
 | |
| 		// get the reason
 | |
| 		char reason[512];
 | |
| 		GetCmdArgString(reason, sizeof(reason));
 | |
| 		StripQuotes(reason);
 | |
| 
 | |
| 		g_ownReasons[client] = false;
 | |
| 
 | |
| 		if (StrEqual(reason[0], "!noreason"))
 | |
| 		{
 | |
| 			PrintToChat(client, "%c[%cSourceBans%c]%c %t", GREEN, NAMECOLOR, GREEN, NAMECOLOR, "Chat Reason Aborted");
 | |
| 			return Plugin_Handled;
 | |
| 		}
 | |
| 
 | |
| 		// ban him!
 | |
| 		PrepareBan(client, g_BanTarget[client], g_BanTime[client], reason, sizeof(reason));
 | |
| 
 | |
| 		// block the reason to be sent in chat
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 	return Plugin_Continue;
 | |
| }
 | |
| 
 | |
| public Action _CmdReload(int client, int args)
 | |
| {
 | |
| 	ResetSettings();
 | |
| 	return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| public Action CommandBan(int client, int args)
 | |
| {
 | |
| 	if (args < 2)
 | |
| 	{
 | |
| 		ReplyToCommand(client, "%sUsage: sm_ban <#userid|name> <time|0> [reason]", Prefix);
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	// This is mainly for me sanity since client used to be called admin and target used to be called client
 | |
| 	int admin = client;
 | |
| 
 | |
| 	// Get the target, find target returns a message on failure so we do not
 | |
| 	char buffer[100];
 | |
| 
 | |
| 	GetCmdArg(1, buffer, sizeof(buffer));
 | |
| 
 | |
| 	int  target = FindTarget(client, buffer, true);
 | |
| 
 | |
| 	if (target == -1)
 | |
| 	{
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	// Get the ban time
 | |
| 	GetCmdArg(2, buffer, sizeof(buffer));
 | |
| 
 | |
| 	int time = StringToInt(buffer);
 | |
| 
 | |
| 	if (!time && client && !(CheckCommandAccess(client, "sm_unban", ADMFLAG_UNBAN | ADMFLAG_ROOT)))
 | |
| 	{
 | |
| 		ReplyToCommand(client, "You do not have Perm Ban Permission");
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	// Get the reason
 | |
| 	char reason[128];
 | |
| 
 | |
| 	if (args >= 3)
 | |
| 	{
 | |
| 		GetCmdArg(3, reason, sizeof(reason));
 | |
| 		for (new i = 4; i <= args; i++)
 | |
| 		{
 | |
| 			GetCmdArg(i, buffer, sizeof(buffer));
 | |
| 			Format(reason, sizeof(reason), "%s %s", reason, buffer);
 | |
| 		}
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		reason[0] = '\0';
 | |
| 	}
 | |
| 
 | |
| 	g_BanTarget[client] = target;
 | |
| 	g_BanTime[client] = time;
 | |
| 
 | |
| 	if (!PlayerStatus[target])
 | |
| 	{
 | |
| 		// The target has not been banned verify. It must be completed before you can ban anyone.
 | |
| 		ReplyToCommand(admin, "%c[%cSourceBans%c]%c %t", GREEN, NAMECOLOR, GREEN, NAMECOLOR, "Ban Not Verified");
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	CreateBan(client, target, time, reason);
 | |
| 	return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| public Action CommandBanIp(int client, int args)
 | |
| {
 | |
| 	if (args < 2)
 | |
| 	{
 | |
| 		ReplyToCommand(client, "%sUsage: sm_banip <ip|#userid|name> <time> [reason]", Prefix);
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	int len, next_len;
 | |
| 	char Arguments[256], arg[50], time[20];
 | |
| 
 | |
| 	GetCmdArgString(Arguments, sizeof(Arguments));
 | |
| 	len = BreakString(Arguments, arg, sizeof(arg));
 | |
| 
 | |
| 	if ((next_len = BreakString(Arguments[len], time, sizeof(time))) != -1)
 | |
| 	{
 | |
| 		len += next_len;
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		len = 0;
 | |
| 		Arguments[0] = '\0';
 | |
| 	}
 | |
| 
 | |
| 	char target_name[MAX_TARGET_LENGTH];
 | |
| 	int target_list[1];
 | |
| 	bool tn_is_ml;
 | |
| 
 | |
| 	int target = -1;
 | |
| 
 | |
| 	if (ProcessTargetString(
 | |
| 			arg,
 | |
| 			client,
 | |
| 			target_list,
 | |
| 			1,
 | |
| 			COMMAND_FILTER_CONNECTED | COMMAND_FILTER_NO_MULTI,
 | |
| 			target_name,
 | |
| 			sizeof(target_name),
 | |
| 			tn_is_ml) > 0)
 | |
| 	{
 | |
| 		target = target_list[0];
 | |
| 
 | |
| 		if (!IsFakeClient(target) && CanUserTarget(client, target))
 | |
| 			GetClientIP(target, arg, sizeof(arg));
 | |
| 	}
 | |
| 
 | |
| 	char adminIp[24], adminAuth[64];
 | |
| 
 | |
| 	int minutes = StringToInt(time);
 | |
| 
 | |
| 	if (!minutes && client && !(CheckCommandAccess(client, "sm_unban", ADMFLAG_UNBAN | ADMFLAG_ROOT)))
 | |
| 	{
 | |
| 		ReplyToCommand(client, "You do not have Perm Ban Permission");
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 	if (!client)
 | |
| 	{
 | |
| 		// setup dummy adminAuth and adminIp for server
 | |
| 		strcopy(adminAuth, sizeof(adminAuth), "STEAM_ID_SERVER");
 | |
| 		strcopy(adminIp, sizeof(adminIp), ServerIp);
 | |
| 	} else {
 | |
| 		GetClientIP(client, adminIp, sizeof(adminIp));
 | |
| 		GetClientAuthId(client, AuthId_Steam2, adminAuth, sizeof(adminAuth));
 | |
| 	}
 | |
| 
 | |
| 	// Pack everything into a data pack so we can retain it
 | |
| 	DataPack dataPack = new DataPack();
 | |
| 	dataPack.WriteCell(client);
 | |
| 	dataPack.WriteCell(minutes);
 | |
| 	dataPack.WriteString(Arguments[len]);
 | |
| 	dataPack.WriteString(arg);
 | |
| 	dataPack.WriteString(adminAuth);
 | |
| 	dataPack.WriteString(adminIp);
 | |
| 
 | |
| 	char sQuery[256];
 | |
| 
 | |
| 	FormatEx(sQuery, sizeof(sQuery), "SELECT bid FROM %s_bans WHERE type = 1 AND ip     = '%s' AND (length = 0 OR ends > UNIX_TIMESTAMP()) AND RemoveType IS NULL",
 | |
| 		DatabasePrefix, arg);
 | |
| 
 | |
| 	SQL_TQuery(DB, SelectBanIpCallback, sQuery, dataPack, DBPrio_High);
 | |
| 
 | |
| 	return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| public Action CommandUnban(int client, int args)
 | |
| {
 | |
| 	if (args < 1)
 | |
| 	{
 | |
| 		ReplyToCommand(client, "%sUsage: sm_unban <steamid|ip> [reason]", Prefix);
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	if (CommandDisable & DISABLE_UNBAN)
 | |
| 	{
 | |
| 		// They must go to the website to unban people
 | |
| 		ReplyToCommand(client, "%s%t", Prefix, "Can Not Unban", WebsiteAddress);
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	int len;
 | |
| 	char Arguments[256], arg[50], adminAuth[64];
 | |
| 
 | |
| 	GetCmdArgString(Arguments, sizeof(Arguments));
 | |
| 
 | |
| 	if ((len = BreakString(Arguments, arg, sizeof(arg))) == -1)
 | |
| 	{
 | |
| 		len = 0;
 | |
| 		Arguments[0] = '\0';
 | |
| 	}
 | |
| 	if (!client)
 | |
| 	{
 | |
| 		// setup dummy adminAuth and adminIp for server
 | |
| 		strcopy(adminAuth, sizeof(adminAuth), "STEAM_ID_SERVER");
 | |
| 	} else {
 | |
| 		GetClientAuthId(client, AuthId_Steam2, adminAuth, sizeof(adminAuth));
 | |
| 	}
 | |
| 
 | |
| 	// Pack everything into a data pack so we can retain it
 | |
| 	DataPack dataPack = new DataPack();
 | |
| 	dataPack.WriteCell(client);
 | |
| 	dataPack.WriteString(Arguments[len]);
 | |
| 	dataPack.WriteString(arg);
 | |
| 	dataPack.WriteString(adminAuth);
 | |
| 
 | |
| 	char query[200];
 | |
| 
 | |
| 	if (strncmp(arg, "STEAM_", 6) == 0)
 | |
| 	{
 | |
| 		Format(query, sizeof(query), "SELECT bid FROM %s_bans WHERE (type = 0 AND authid = '%s') AND (length = '0' OR ends > UNIX_TIMESTAMP()) AND RemoveType IS NULL", DatabasePrefix, arg);
 | |
| 	} else {
 | |
| 		Format(query, sizeof(query), "SELECT bid FROM %s_bans WHERE (type = 1 AND ip     = '%s') AND (length = '0' OR ends > UNIX_TIMESTAMP()) AND RemoveType IS NULL", DatabasePrefix, arg);
 | |
| 	}
 | |
| 
 | |
| 	SQL_TQuery(DB, SelectUnbanCallback, query, dataPack);
 | |
| 
 | |
| 	return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| public Action CommandAddBan(int client, int args)
 | |
| {
 | |
| 	if (args < 2)
 | |
| 	{
 | |
| 		ReplyToCommand(client, "%sUsage: sm_addban <time> <steamid> [reason]", Prefix);
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	if (CommandDisable & DISABLE_ADDBAN)
 | |
| 	{
 | |
| 		// They must go to the website to add bans
 | |
| 		ReplyToCommand(client, "%s%t", Prefix, "Can Not Add Ban", WebsiteAddress);
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	char arg_string[256], time[50], authid[50];
 | |
| 
 | |
| 	GetCmdArgString(arg_string, sizeof(arg_string));
 | |
| 
 | |
| 	int len, total_len;
 | |
| 
 | |
| 	/* Get time */
 | |
| 	if ((len = BreakString(arg_string, time, sizeof(time))) == -1)
 | |
| 	{
 | |
| 		ReplyToCommand(client, "%sUsage: sm_addban <time> <steamid> [reason]", Prefix);
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 	total_len += len;
 | |
| 
 | |
| 	/* Get steamid */
 | |
| 	if ((len = BreakString(arg_string[total_len], authid, sizeof(authid))) != -1)
 | |
| 	{
 | |
| 		total_len += len;
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		total_len = 0;
 | |
| 		arg_string[0] = '\0';
 | |
| 	}
 | |
| 
 | |
| 	char adminIp[24], adminAuth[64];
 | |
| 
 | |
| 	int  minutes = StringToInt(time);
 | |
| 
 | |
| 	if (!minutes && client && !(CheckCommandAccess(client, "sm_unban", ADMFLAG_UNBAN | ADMFLAG_ROOT)))
 | |
| 	{
 | |
| 		ReplyToCommand(client, "You do not have Perm Ban Permission");
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 	if (!client)
 | |
| 	{
 | |
| 		// setup dummy adminAuth and adminIp for server
 | |
| 		strcopy(adminAuth, sizeof(adminAuth), "STEAM_ID_SERVER");
 | |
| 		strcopy(adminIp, sizeof(adminIp), ServerIp);
 | |
| 	} else {
 | |
| 		GetClientIP(client, adminIp, sizeof(adminIp));
 | |
| 		GetClientAuthId(client, AuthId_Steam2, adminAuth, sizeof(adminAuth));
 | |
| 	}
 | |
| 
 | |
| 	// Pack everything into a data pack so we can retain it
 | |
| 	DataPack dataPack = new DataPack();
 | |
| 	dataPack.WriteCell(client);
 | |
| 	dataPack.WriteCell(minutes);
 | |
| 	dataPack.WriteString(arg_string[total_len]);
 | |
| 	dataPack.WriteString(authid);
 | |
| 	dataPack.WriteString(adminAuth);
 | |
| 	dataPack.WriteString(adminIp);
 | |
| 
 | |
| 	char sQuery[256];
 | |
| 
 | |
| 	FormatEx(sQuery, sizeof sQuery, "SELECT bid FROM %s_bans WHERE type = 0 AND authid = '%s' AND (length = 0 OR ends > UNIX_TIMESTAMP()) AND RemoveType IS NULL",
 | |
| 		DatabasePrefix, authid);
 | |
| 
 | |
| 	SQL_TQuery(DB, SelectAddbanCallback, sQuery, dataPack, DBPrio_High);
 | |
| 
 | |
| 	return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| public Action sm_rehash(int args)
 | |
| {
 | |
| 	if (enableAdmins)
 | |
| 		DumpAdminCache(AdminCache_Groups, true);
 | |
| 	DumpAdminCache(AdminCache_Overrides, true);
 | |
| 	return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| // MENU CODE //
 | |
| 
 | |
| public void OnAdminMenuReady(Handle topmenu)
 | |
| {
 | |
| 	#if defined DEBUG
 | |
| 	LogToFile(logFile, "OnAdminMenuReady()");
 | |
| 	#endif
 | |
| 
 | |
| 	/* Block us from being called twice */
 | |
| 	if (topmenu == hTopMenu)
 | |
| 	{
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	/* Save the Handle */
 | |
| 	hTopMenu = topmenu;
 | |
| 
 | |
| 	/* Find the "Player Commands" category */
 | |
| 	TopMenuObject player_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_PLAYERCOMMANDS);
 | |
| 
 | |
| 	if (player_commands != INVALID_TOPMENUOBJECT)
 | |
| 	{
 | |
| 		// just to avoid "unused variable 'res'" warning
 | |
| 		#if defined DEBUG
 | |
| 		TopMenuObject res = AddToTopMenu(hTopMenu,
 | |
| 			"sm_ban",  // Name
 | |
| 			TopMenuObject_Item,  // We are a submenu
 | |
| 			AdminMenu_Ban,  // Handler function
 | |
| 			player_commands,  // We are a submenu of Player Commands
 | |
| 			"sm_ban",  // The command to be finally called (Override checks)
 | |
| 			ADMFLAG_BAN); // What flag do we need to see the menu option
 | |
| 		char temp[125];
 | |
| 		Format(temp, 125, "Result of AddToTopMenu: %d", res);
 | |
| 		LogToFile(logFile, temp);
 | |
| 		LogToFile(logFile, "Added Ban option to admin menu");
 | |
| 		#else
 | |
| 		AddToTopMenu(hTopMenu,
 | |
| 			"sm_ban",  // Name
 | |
| 			TopMenuObject_Item,  // We are a submenu
 | |
| 			AdminMenu_Ban,  // Handler function
 | |
| 			player_commands,  // We are a submenu of Player Commands
 | |
| 			"sm_ban",  // The command to be finally called (Override checks)
 | |
| 			ADMFLAG_BAN); // What flag do we need to see the menu option
 | |
| 		#endif
 | |
| 	}
 | |
| }
 | |
| 
 | |
| public void AdminMenu_Ban(Handle topmenu,
 | |
| 	TopMenuAction action,  // Action being performed
 | |
| 	TopMenuObject object_id,  // The object ID (if used)
 | |
| 	int param,  // client idx of admin who chose the option (if used)
 | |
| 	char[] buffer,  // Output buffer (if used)
 | |
| 	int maxlength) // Output buffer (if used)
 | |
| {
 | |
| 	/* Clear the Ownreason bool, so he is able to chat again;) */
 | |
| 	g_ownReasons[param] = false;
 | |
| 
 | |
| 	#if defined DEBUG
 | |
| 	LogToFile(logFile, "AdminMenu_Ban()");
 | |
| 	#endif
 | |
| 
 | |
| 	switch (action)
 | |
| 	{
 | |
| 		// We are only being displayed, We only need to show the option name
 | |
| 		case TopMenuAction_DisplayOption:
 | |
| 		{
 | |
| 			FormatEx(buffer, maxlength, "%T", "Ban player", param);
 | |
| 
 | |
| 			#if defined DEBUG
 | |
| 			LogToFile(logFile, "AdminMenu_Ban() -> Formatted the Ban option text");
 | |
| 			#endif
 | |
| 		}
 | |
| 
 | |
| 		case TopMenuAction_SelectOption:
 | |
| 		{
 | |
| 			DisplayBanTargetMenu(param); // Someone chose to ban someone, show the list of users menu
 | |
| 
 | |
| 			#if defined DEBUG
 | |
| 			LogToFile(logFile, "AdminMenu_Ban() -> DisplayBanTargetMenu()");
 | |
| 			#endif
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| public int ReasonSelected(Handle menu, MenuAction action, int param1, int param2)
 | |
| {
 | |
| 	switch (action)
 | |
| 	{
 | |
| 		case MenuAction_Select:
 | |
| 		{
 | |
| 			char info[128], key[128];
 | |
| 
 | |
| 			GetMenuItem(menu, param2, key, sizeof(key), _, info, sizeof(info));
 | |
| 
 | |
| 			if (StrEqual("Hacking", key))
 | |
| 			{
 | |
| 				DisplayMenu(HackingMenuHandle, param1, MENU_TIME_FOREVER);
 | |
| 				return;
 | |
| 			}
 | |
| 
 | |
| 			else if (StrEqual("Own Reason", key)) // admin wants to use his own reason
 | |
| 			{
 | |
| 				g_ownReasons[param1] = true;
 | |
| 				PrintToChat(param1, "%c[%cSourceBans%c]%c %t", GREEN, NAMECOLOR, GREEN, NAMECOLOR, "Chat Reason");
 | |
| 				return;
 | |
| 			}
 | |
| 
 | |
| 			else if (g_BanTarget[param1] != -1 && g_BanTime[param1] != -1)
 | |
| 				PrepareBan(param1, g_BanTarget[param1], g_BanTime[param1], info, sizeof(info));
 | |
| 		}
 | |
| 
 | |
| 		case MenuAction_Cancel:
 | |
| 		{
 | |
| 			if (param2 == MenuCancel_Disconnected)
 | |
| 			{
 | |
| 				if (PlayerDataPack[param1] != INVALID_HANDLE)
 | |
| 				{
 | |
| 					CloseHandle(PlayerDataPack[param1]);
 | |
| 					PlayerDataPack[param1] = INVALID_HANDLE;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			else
 | |
| 			{
 | |
| 				DisplayBanTimeMenu(param1);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| public int HackingSelected(Handle menu, MenuAction action, int param1, int param2)
 | |
| {
 | |
| 	switch (action)
 | |
| 	{
 | |
| 		case MenuAction_Select:
 | |
| 		{
 | |
| 			char info[128], key[128];
 | |
| 
 | |
| 			GetMenuItem(menu, param2, key, sizeof(key), _, info, sizeof(info));
 | |
| 
 | |
| 			if (g_BanTarget[param1] != -1 && g_BanTime[param1] != -1)
 | |
| 				PrepareBan(param1, g_BanTarget[param1], g_BanTime[param1], info, sizeof(info));
 | |
| 		}
 | |
| 
 | |
| 		case MenuAction_Cancel:
 | |
| 		{
 | |
| 			if (param2 == MenuCancel_Disconnected)
 | |
| 			{
 | |
| 				DataPack Pack = view_as<DataPack>(PlayerDataPack[param1]);
 | |
| 
 | |
| 				if (Pack != INVALID_HANDLE)
 | |
| 				{
 | |
| 					Pack.ReadCell(); // admin index
 | |
| 					Pack.ReadCell(); // target index
 | |
| 					Pack.ReadCell(); // admin userid
 | |
| 					Pack.ReadCell(); // target userid
 | |
| 					Pack.ReadCell(); // time
 | |
| 
 | |
| 					DataPack ReasonPack = Pack.ReadCell();
 | |
| 
 | |
| 					if (ReasonPack != INVALID_HANDLE)
 | |
| 					{
 | |
| 						CloseHandle(ReasonPack);
 | |
| 					}
 | |
| 
 | |
| 					CloseHandle(Pack);
 | |
| 					PlayerDataPack[param1] = INVALID_HANDLE;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			else
 | |
| 			{
 | |
| 				DisplayMenu(ReasonMenuHandle, param1, MENU_TIME_FOREVER);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| public int MenuHandler_BanPlayerList(Handle menu, MenuAction action, int param1, int param2)
 | |
| {
 | |
| 	#if defined DEBUG
 | |
| 	LogToFile(logFile, "MenuHandler_BanPlayerList()");
 | |
| 	#endif
 | |
| 
 | |
| 	switch (action)
 | |
| 	{
 | |
| 		case MenuAction_End:
 | |
| 		{
 | |
| 			CloseHandle(menu);
 | |
| 		}
 | |
| 
 | |
| 		case MenuAction_Cancel:
 | |
| 		{
 | |
| 			if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
 | |
| 			{
 | |
| 				DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		case MenuAction_Select:
 | |
| 		{
 | |
| 			char info[32], name[32];
 | |
| 			int userid, target;
 | |
| 
 | |
| 			GetMenuItem(menu, param2, info, sizeof(info), _, name, sizeof(name));
 | |
| 			userid = StringToInt(info);
 | |
| 
 | |
| 			if ((target = GetClientOfUserId(userid)) == 0)
 | |
| 			{
 | |
| 				PrintToChat(param1, "%s%t", Prefix, "Player no longer available");
 | |
| 			}
 | |
| 			else if (!CanUserTarget(param1, target))
 | |
| 			{
 | |
| 				PrintToChat(param1, "%s%t", Prefix, "Unable to target");
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				g_BanTarget[param1] = target;
 | |
| 				DisplayBanTimeMenu(param1);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| public int MenuHandler_BanTimeList(Handle menu, MenuAction action, int param1, int param2)
 | |
| {
 | |
| 	#if defined DEBUG
 | |
| 	LogToFile(logFile, "MenuHandler_BanTimeList()");
 | |
| 	#endif
 | |
| 
 | |
| 	switch (action)
 | |
| 	{
 | |
| 		case MenuAction_Cancel:
 | |
| 		{
 | |
| 			if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
 | |
| 			{
 | |
| 				DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		case MenuAction_Select:
 | |
| 		{
 | |
| 			char info[32];
 | |
| 
 | |
| 			GetMenuItem(menu, param2, info, sizeof(info));
 | |
| 			g_BanTime[param1] = StringToInt(info);
 | |
| 
 | |
| 			//DisplayBanReasonMenu(param1);
 | |
| 			DisplayMenu(ReasonMenuHandle, param1, MENU_TIME_FOREVER);
 | |
| 		}
 | |
| 
 | |
| 		case MenuAction_DrawItem:
 | |
| 		{
 | |
| 			char time[16];
 | |
| 
 | |
| 			GetMenuItem(menu, param2, time, sizeof(time));
 | |
| 
 | |
| 			return (StringToInt(time) > 0 || CheckCommandAccess(param1, "sm_unban", ADMFLAG_UNBAN | ADMFLAG_ROOT)) ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| stock void DisplayBanTargetMenu(int client)
 | |
| {
 | |
| 	#if defined DEBUG
 | |
| 	LogToFile(logFile, "DisplayBanTargetMenu()");
 | |
| 	#endif
 | |
| 
 | |
| 	Handle menu = CreateMenu(MenuHandler_BanPlayerList); // Create a new menu, pass it the handler.
 | |
| 
 | |
| 	char title[100];
 | |
| 
 | |
| 	FormatEx(title, sizeof(title), "%T:", "Ban player", client);
 | |
| 
 | |
| 	SetMenuTitle(menu, title); // Set the title
 | |
| 	SetMenuExitBackButton(menu, true); // Yes we want back/exit
 | |
| 
 | |
| 	AddTargetsToMenu(menu,  // Add clients to our menu
 | |
| 		client,  // The client that called the display
 | |
| 		false,  // We want to see people connecting
 | |
| 		false); // And dead people
 | |
| 
 | |
| 	DisplayMenu(menu, client, MENU_TIME_FOREVER); // Show the menu to the client FOREVER!
 | |
| }
 | |
| 
 | |
| stock void DisplayBanTimeMenu(int client)
 | |
| {
 | |
| 	#if defined DEBUG
 | |
| 	LogToFile(logFile, "DisplayBanTimeMenu()");
 | |
| 	#endif
 | |
| 
 | |
| 	char title[100];
 | |
| 	FormatEx(title, sizeof(title), "%T:", "Ban player", client);
 | |
| 	SetMenuTitle(TimeMenuHandle, title);
 | |
| 
 | |
| 	DisplayMenu(TimeMenuHandle, client, MENU_TIME_FOREVER);
 | |
| }
 | |
| 
 | |
| stock void ResetMenu()
 | |
| {
 | |
| 	if (TimeMenuHandle != INVALID_HANDLE)
 | |
| 	{
 | |
| 		RemoveAllMenuItems(TimeMenuHandle);
 | |
| 	}
 | |
| 
 | |
| 	if (ReasonMenuHandle != INVALID_HANDLE)
 | |
| 	{
 | |
| 		RemoveAllMenuItems(ReasonMenuHandle);
 | |
| 	}
 | |
| 
 | |
| 	if (HackingMenuHandle != INVALID_HANDLE)
 | |
| 	{
 | |
| 		RemoveAllMenuItems(HackingMenuHandle);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // QUERY CALL BACKS //
 | |
| 
 | |
| public void GotDatabase(Database db, const char[] error, any data)
 | |
| {
 | |
| 	if (db == INVALID_HANDLE)
 | |
| 	{
 | |
| 		LogToFile(logFile, "Database failure: %s. See Docs: https://sbpp.github.io/docs/", error);
 | |
| 		g_bConnecting = false;
 | |
| 
 | |
| 		// Parse the overrides backup!
 | |
| 		ParseBackupConfig_Overrides();
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	DB = db;
 | |
| 
 | |
| 	char query[1024];
 | |
| 
 | |
| 	SQL_SetCharset(DB, "utf8");
 | |
| 
 | |
| 	InsertServerInfo();
 | |
| 
 | |
| 	//CreateTimer(900.0, PruneBans);
 | |
| 
 | |
| 	if (loadOverrides)
 | |
| 	{
 | |
| 		Format(query, 1024, "SELECT type, name, flags FROM %s_overrides", DatabasePrefix);
 | |
| 		SQL_TQuery(DB, OverridesDone, query);
 | |
| 		loadOverrides = false;
 | |
| 	}
 | |
| 
 | |
| 	if (loadGroups && enableAdmins)
 | |
| 	{
 | |
| 		FormatEx(query, 1024, "SELECT name, flags, immunity, groups_immune   \
 | |
| 					FROM %s_srvgroups ORDER BY id", DatabasePrefix);
 | |
| 		curLoading++;
 | |
| 		SQL_TQuery(DB, GroupsDone, query);
 | |
| 
 | |
| 		#if defined DEBUG
 | |
| 		LogToFile(logFile, "Fetching Group List");
 | |
| 		#endif
 | |
| 		loadGroups = false;
 | |
| 	}
 | |
| 
 | |
| 	if (loadAdmins && enableAdmins)
 | |
| 	{
 | |
| 		char queryLastLogin[50] = "";
 | |
| 
 | |
| 		if (requireSiteLogin)
 | |
| 			queryLastLogin = "lastvisit IS NOT NULL AND lastvisit != '' AND";
 | |
| 
 | |
| 		if (serverID == -1)
 | |
| 		{
 | |
| 			FormatEx(query, 1024, "SELECT authid, srv_password, (SELECT name FROM %s_srvgroups WHERE name = srv_group AND flags != '') AS srv_group, srv_flags, user, immunity  \
 | |
| 						FROM %s_admins_servers_groups AS asg \
 | |
| 						LEFT JOIN %s_admins AS a ON a.aid = asg.admin_id \
 | |
| 						WHERE %s (server_id = (SELECT sid FROM %s_servers WHERE ip = '%s' AND port = '%s' LIMIT 0,1)  \
 | |
| 						OR srv_group_id = ANY (SELECT group_id FROM %s_servers_groups WHERE server_id = (SELECT sid FROM %s_servers WHERE ip = '%s' AND port = '%s' LIMIT 0,1))) \
 | |
| 						GROUP BY aid, authid, srv_password, srv_group, srv_flags, user",
 | |
| 				DatabasePrefix, DatabasePrefix, DatabasePrefix, queryLastLogin, DatabasePrefix, ServerIp, ServerPort, DatabasePrefix, DatabasePrefix, ServerIp, ServerPort);
 | |
| 		} else {
 | |
| 			FormatEx(query, 1024, "SELECT authid, srv_password, (SELECT name FROM %s_srvgroups WHERE name = srv_group AND flags != '') AS srv_group, srv_flags, user, immunity  \
 | |
| 						FROM %s_admins_servers_groups AS asg \
 | |
| 						LEFT JOIN %s_admins AS a ON a.aid = asg.admin_id \
 | |
| 						WHERE %s server_id = %d  \
 | |
| 						OR srv_group_id = ANY (SELECT group_id FROM %s_servers_groups WHERE server_id = %d) \
 | |
| 						GROUP BY aid, authid, srv_password, srv_group, srv_flags, user",
 | |
| 				DatabasePrefix, DatabasePrefix, DatabasePrefix, queryLastLogin, serverID, DatabasePrefix, serverID);
 | |
| 		}
 | |
| 		curLoading++;
 | |
| 		SQL_TQuery(DB, AdminsDone, query);
 | |
| 
 | |
| 		#if defined DEBUG
 | |
| 		LogToFile(logFile, "Fetching Admin List");
 | |
| 		LogToFile(logFile, query);
 | |
| 		#endif
 | |
| 		loadAdmins = false;
 | |
| 	}
 | |
| 	g_bConnecting = false;
 | |
| }
 | |
| 
 | |
| public VerifyInsert(Handle:owner, Handle:hndl, const String:error[], DataPack dataPack)
 | |
| {
 | |
| 	if (dataPack == INVALID_HANDLE)
 | |
| 	{
 | |
| 		LogToFile(logFile, "Ban Failed: %s", error);
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	if (hndl == INVALID_HANDLE || error[0])
 | |
| 	{
 | |
| 		LogToFile(logFile, "Verify Insert Query Failed: %s", error);
 | |
| 
 | |
| 		int admin = dataPack.ReadCell();
 | |
| 		dataPack.ReadCell(); // target
 | |
| 		dataPack.ReadCell(); // admin userid
 | |
| 		dataPack.ReadCell(); // target userid
 | |
| 		int time = dataPack.ReadCell();
 | |
| 
 | |
| 		DataPack reasonPack = dataPack.ReadCell();
 | |
| 
 | |
| 		char reason[128], name[50], auth[30], ip[20], adminAuth[30], adminIp[20];
 | |
| 
 | |
| 		reasonPack.ReadString(reason, sizeof reason);
 | |
| 
 | |
| 		dataPack.ReadString(name, sizeof name);
 | |
| 		dataPack.ReadString(auth, sizeof auth);
 | |
| 		dataPack.ReadString(ip, sizeof ip);
 | |
| 		dataPack.ReadString(adminAuth, sizeof adminAuth);
 | |
| 		dataPack.ReadString(adminIp, sizeof adminIp);
 | |
| 
 | |
| 		dataPack.Reset();
 | |
| 		reasonPack.Reset();
 | |
| 
 | |
| 		PlayerDataPack[admin] = INVALID_HANDLE;
 | |
| 		UTIL_InsertTempBan(time, name, auth, ip, reason, adminAuth, adminIp, dataPack);
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	int admin = dataPack.ReadCell();
 | |
| 	int client = dataPack.ReadCell();
 | |
| 
 | |
| 	if (!IsClientConnected(client) || IsFakeClient(client))
 | |
| 		return;
 | |
| 
 | |
| 	dataPack.ReadCell(); // admin userid
 | |
| 
 | |
| 	int UserId = dataPack.ReadCell();
 | |
| 	int time = dataPack.ReadCell();
 | |
| 
 | |
| 	DataPack ReasonPack = dataPack.ReadCell();
 | |
| 
 | |
| 	char Name[64], Reason[128];
 | |
| 
 | |
| 	dataPack.ReadString(Name, sizeof(Name));
 | |
| 	ReasonPack.ReadString(Reason, sizeof(Reason));
 | |
| 
 | |
| 	if (!time)
 | |
| 	{
 | |
| 		if (Reason[0] == '\0')
 | |
| 		{
 | |
| 			ShowActivityEx(admin, Prefix, "%t", "Permabanned player", Name);
 | |
| 		} else {
 | |
| 			ShowActivityEx(admin, Prefix, "%t", "Permabanned player reason", Name, Reason);
 | |
| 		}
 | |
| 	} else {
 | |
| 		if (Reason[0] == '\0')
 | |
| 		{
 | |
| 			ShowActivityEx(admin, Prefix, "%t", "Banned player", Name, time);
 | |
| 		} else {
 | |
| 			ShowActivityEx(admin, Prefix, "%t", "Banned player reason", Name, time, Reason);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	LogAction(admin, client, "\"%L\" banned \"%L\" (minutes \"%d\") (reason \"%s\")", admin, client, time, Reason);
 | |
| 
 | |
| 	if (PlayerDataPack[admin] != INVALID_HANDLE)
 | |
| 	{
 | |
| 		CloseHandle(PlayerDataPack[admin]);
 | |
| 		CloseHandle(ReasonPack);
 | |
| 		PlayerDataPack[admin] = INVALID_HANDLE;
 | |
| 	}
 | |
| 
 | |
| 	// Kick player
 | |
| 	if (GetClientUserId(client) == UserId)
 | |
| 		KickClient(client, "%t", "Banned Check Site", WebsiteAddress);
 | |
| }
 | |
| 
 | |
| public SelectBanIpCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
 | |
| {
 | |
| 	decl admin, minutes, String:adminAuth[30], String:adminIp[30], String:banReason[256], String:ip[16], String:Query[512];
 | |
| 	new String:reason[128];
 | |
| 	ResetPack(data);
 | |
| 	admin = ReadPackCell(data);
 | |
| 	minutes = ReadPackCell(data);
 | |
| 	ReadPackString(data, reason, sizeof(reason));
 | |
| 	ReadPackString(data, ip, sizeof(ip));
 | |
| 	ReadPackString(data, adminAuth, sizeof(adminAuth));
 | |
| 	ReadPackString(data, adminIp, sizeof(adminIp));
 | |
| 	SQL_EscapeString(DB, reason, banReason, sizeof(banReason));
 | |
| 
 | |
| 	if (error[0])
 | |
| 	{
 | |
| 		LogToFile(logFile, "Ban IP Select Query Failed: %s", error);
 | |
| 		if (admin && IsClientInGame(admin))
 | |
| 			PrintToChat(admin, "%sFailed to ban %s.", Prefix, ip);
 | |
| 		else
 | |
| 			PrintToServer("%sFailed to ban %s.", Prefix, ip);
 | |
| 		return;
 | |
| 	}
 | |
| 	if (SQL_GetRowCount(hndl))
 | |
| 	{
 | |
| 		if (admin && IsClientInGame(admin))
 | |
| 			PrintToChat(admin, "%s%s is already banned.", Prefix, ip);
 | |
| 		else
 | |
| 			PrintToServer("%s%s is already banned.", Prefix, ip);
 | |
| 		return;
 | |
| 	}
 | |
| 	if (serverID == -1)
 | |
| 	{
 | |
| 		FormatEx(Query, sizeof(Query), "INSERT INTO %s_bans (type, ip, name, created, ends, length, reason, aid, adminIp, sid, country) VALUES \
 | |
| 						(1, '%s', '', UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + %d, %d, '%s', (SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'), '%s', \
 | |
| 						(SELECT sid FROM %s_servers WHERE ip = '%s' AND port = '%s' LIMIT 0,1), ' ')",
 | |
| 			DatabasePrefix, ip, (minutes * 60), (minutes * 60), banReason, DatabasePrefix, adminAuth, adminAuth[8], adminIp, DatabasePrefix, ServerIp, ServerPort);
 | |
| 	} else {
 | |
| 		FormatEx(Query, sizeof(Query), "INSERT INTO %s_bans (type, ip, name, created, ends, length, reason, aid, adminIp, sid, country) VALUES \
 | |
| 						(1, '%s', '', UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + %d, %d, '%s', (SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'), '%s', \
 | |
| 						%d, ' ')",
 | |
| 			DatabasePrefix, ip, (minutes * 60), (minutes * 60), banReason, DatabasePrefix, adminAuth, adminAuth[8], adminIp, serverID);
 | |
| 	}
 | |
| 
 | |
| 	SQL_TQuery(DB, InsertBanIpCallback, Query, data, DBPrio_High);
 | |
| }
 | |
| 
 | |
| public InsertBanIpCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
 | |
| {
 | |
| 	// if the pack is good unpack it and close the handle
 | |
| 	new admin, minutes;
 | |
| 	new String:reason[128];
 | |
| 	decl String:arg[30];
 | |
| 	if (data != INVALID_HANDLE)
 | |
| 	{
 | |
| 		ResetPack(data);
 | |
| 		admin = ReadPackCell(data);
 | |
| 		minutes = ReadPackCell(data);
 | |
| 		ReadPackString(data, reason, sizeof(reason));
 | |
| 		ReadPackString(data, arg, sizeof(arg));
 | |
| 		CloseHandle(data);
 | |
| 	} else {
 | |
| 		// Technically this should not be possible
 | |
| 		ThrowError("Invalid Handle in InsertBanIpCallback");
 | |
| 	}
 | |
| 
 | |
| 	// If error is not an empty string the query failed
 | |
| 	if (error[0] != '\0')
 | |
| 	{
 | |
| 		LogToFile(logFile, "Ban IP Insert Query Failed: %s", error);
 | |
| 		if (admin && IsClientInGame(admin))
 | |
| 			PrintToChat(admin, "%ssm_banip failed", Prefix);
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	LogAction(admin,
 | |
| 		-1,
 | |
| 		"\"%L\" added ban (minutes \"%d\") (ip \"%s\") (reason \"%s\")",
 | |
| 		admin,
 | |
| 		minutes,
 | |
| 		arg,
 | |
| 		reason);
 | |
| 	if (admin && IsClientInGame(admin))
 | |
| 		PrintToChat(admin, "%s%s successfully banned", Prefix, arg);
 | |
| 	else
 | |
| 		PrintToServer("%s%s successfully banned", Prefix, arg);
 | |
| }
 | |
| 
 | |
| public SelectUnbanCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
 | |
| {
 | |
| 	decl admin, String:arg[30], String:adminAuth[30], String:unbanReason[256];
 | |
| 	new String:reason[128];
 | |
| 	ResetPack(data);
 | |
| 	admin = ReadPackCell(data);
 | |
| 	ReadPackString(data, reason, sizeof(reason));
 | |
| 	ReadPackString(data, arg, sizeof(arg));
 | |
| 	ReadPackString(data, adminAuth, sizeof(adminAuth));
 | |
| 	SQL_EscapeString(DB, reason, unbanReason, sizeof(unbanReason));
 | |
| 
 | |
| 	// If error is not an empty string the query failed
 | |
| 	if (error[0] != '\0')
 | |
| 	{
 | |
| 		LogToFile(logFile, "Unban Select Query Failed: %s", error);
 | |
| 		if (admin && IsClientInGame(admin))
 | |
| 		{
 | |
| 			PrintToChat(admin, "%ssm_unban failed", Prefix);
 | |
| 		}
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	// If there was no results then a ban does not exist for that id
 | |
| 	if (hndl == INVALID_HANDLE || !SQL_GetRowCount(hndl))
 | |
| 	{
 | |
| 		if (admin && IsClientInGame(admin))
 | |
| 		{
 | |
| 			PrintToChat(admin, "%sNo active bans found for that filter", Prefix);
 | |
| 		} else {
 | |
| 			PrintToServer("%sNo active bans found for that filter", Prefix);
 | |
| 		}
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	// There is ban
 | |
| 	if (hndl != INVALID_HANDLE && SQL_FetchRow(hndl))
 | |
| 	{
 | |
| 		// Get the values from the existing ban record
 | |
| 		new bid = SQL_FetchInt(hndl, 0);
 | |
| 
 | |
| 		decl String:query[1000];
 | |
| 		Format(query, sizeof(query), "UPDATE %s_bans SET RemovedBy = (SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'), RemoveType = 'U', RemovedOn = UNIX_TIMESTAMP(), ureason = '%s' WHERE bid = %d",
 | |
| 			DatabasePrefix, DatabasePrefix, adminAuth, adminAuth[8], unbanReason, bid);
 | |
| 
 | |
| 		SQL_TQuery(DB, InsertUnbanCallback, query, data);
 | |
| 	}
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| public InsertUnbanCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
 | |
| {
 | |
| 	// if the pack is good unpack it and close the handle
 | |
| 	decl admin, String:arg[30];
 | |
| 	new String:reason[128];
 | |
| 	if (data != INVALID_HANDLE)
 | |
| 	{
 | |
| 		ResetPack(data);
 | |
| 		admin = ReadPackCell(data);
 | |
| 		ReadPackString(data, reason, sizeof(reason));
 | |
| 		ReadPackString(data, arg, sizeof(arg));
 | |
| 		CloseHandle(data);
 | |
| 	} else {
 | |
| 		// Technically this should not be possible
 | |
| 		ThrowError("Invalid Handle in InsertUnbanCallback");
 | |
| 	}
 | |
| 
 | |
| 	// If error is not an empty string the query failed
 | |
| 	if (error[0] != '\0')
 | |
| 	{
 | |
| 		LogToFile(logFile, "Unban Insert Query Failed: %s", error);
 | |
| 		if (admin && IsClientInGame(admin))
 | |
| 		{
 | |
| 			PrintToChat(admin, "%ssm_unban failed", Prefix);
 | |
| 		}
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	LogAction(admin, -1, "\"%L\" removed ban (filter \"%s\") (reason \"%s\")", admin, arg, reason);
 | |
| 	if (admin && IsClientInGame(admin))
 | |
| 	{
 | |
| 		PrintToChat(admin, "%s%s successfully unbanned", Prefix, arg);
 | |
| 	} else {
 | |
| 		PrintToServer("%s%s successfully unbanned", Prefix, arg);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| public SelectAddbanCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
 | |
| {
 | |
| 	decl admin, minutes, String:adminAuth[30], String:adminIp[30], String:authid[20], String:banReason[256], String:Query[512];
 | |
| 	new String:reason[128];
 | |
| 	ResetPack(data);
 | |
| 	admin = ReadPackCell(data);
 | |
| 	minutes = ReadPackCell(data);
 | |
| 	ReadPackString(data, reason, sizeof(reason));
 | |
| 	ReadPackString(data, authid, sizeof(authid));
 | |
| 	ReadPackString(data, adminAuth, sizeof(adminAuth));
 | |
| 	ReadPackString(data, adminIp, sizeof(adminIp));
 | |
| 	SQL_EscapeString(DB, reason, banReason, sizeof(banReason));
 | |
| 
 | |
| 	if (error[0])
 | |
| 	{
 | |
| 		LogToFile(logFile, "Add Ban Select Query Failed: %s", error);
 | |
| 		if (admin && IsClientInGame(admin))
 | |
| 			PrintToChat(admin, "%sFailed to ban %s.", Prefix, authid);
 | |
| 		else
 | |
| 			PrintToServer("%sFailed to ban %s.", Prefix, authid);
 | |
| 		return;
 | |
| 	}
 | |
| 	if (SQL_GetRowCount(hndl))
 | |
| 	{
 | |
| 		if (admin && IsClientInGame(admin))
 | |
| 			PrintToChat(admin, "%s%s is already banned.", Prefix, authid);
 | |
| 		else
 | |
| 			PrintToServer("%s%s is already banned.", Prefix, authid);
 | |
| 		return;
 | |
| 	}
 | |
| 	if (serverID == -1)
 | |
| 	{
 | |
| 		FormatEx(Query, sizeof(Query), "INSERT INTO %s_bans (authid, name, created, ends, length, reason, aid, adminIp, sid, country) VALUES \
 | |
| 						('%s', '', UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + %d, %d, '%s', (SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'), '%s', \
 | |
| 						(SELECT sid FROM %s_servers WHERE ip = '%s' AND port = '%s' LIMIT 0,1), ' ')",
 | |
| 			DatabasePrefix, authid, (minutes * 60), (minutes * 60), banReason, DatabasePrefix, adminAuth, adminAuth[8], adminIp, DatabasePrefix, ServerIp, ServerPort);
 | |
| 	} else {
 | |
| 		FormatEx(Query, sizeof(Query), "INSERT INTO %s_bans (authid, name, created, ends, length, reason, aid, adminIp, sid, country) VALUES \
 | |
| 						('%s', '', UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + %d, %d, '%s', (SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'), '%s', \
 | |
| 						%d, ' ')",
 | |
| 			DatabasePrefix, authid, (minutes * 60), (minutes * 60), banReason, DatabasePrefix, adminAuth, adminAuth[8], adminIp, serverID);
 | |
| 	}
 | |
| 
 | |
| 	SQL_TQuery(DB, InsertAddbanCallback, Query, data, DBPrio_High);
 | |
| }
 | |
| 
 | |
| public InsertAddbanCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
 | |
| {
 | |
| 	decl admin, minutes, String:authid[20];
 | |
| 	new String:reason[128];
 | |
| 	ResetPack(data);
 | |
| 	admin = ReadPackCell(data);
 | |
| 	minutes = ReadPackCell(data);
 | |
| 	ReadPackString(data, reason, sizeof(reason));
 | |
| 	ReadPackString(data, authid, sizeof(authid));
 | |
| 
 | |
| 	// If error is not an empty string the query failed
 | |
| 	if (error[0] != '\0')
 | |
| 	{
 | |
| 		LogToFile(logFile, "Add Ban Insert Query Failed: %s", error);
 | |
| 		if (admin && IsClientInGame(admin))
 | |
| 		{
 | |
| 			PrintToChat(admin, "%ssm_addban failed", Prefix);
 | |
| 		}
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	LogAction(admin,
 | |
| 		-1,
 | |
| 		"\"%L\" added ban (minutes \"%i\") (id \"%s\") (reason \"%s\")",
 | |
| 		admin,
 | |
| 		minutes,
 | |
| 		authid,
 | |
| 		reason);
 | |
| 	if (admin && IsClientInGame(admin))
 | |
| 	{
 | |
| 		PrintToChat(admin, "%s%s successfully banned", Prefix, authid);
 | |
| 	} else {
 | |
| 		PrintToServer("%s%s successfully banned", Prefix, authid);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // ProcessQueueCallback is called as the result of selecting all the rows from the queue table
 | |
| public ProcessQueueCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
 | |
| {
 | |
| 	if (hndl == INVALID_HANDLE || strlen(error) > 0)
 | |
| 	{
 | |
| 		LogToFile(logFile, "Failed to retrieve queued bans from sqlite database, %s", error);
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	decl String:auth[30];
 | |
| 	decl time;
 | |
| 	decl startTime;
 | |
| 	new String:reason[128];
 | |
| 	decl String:name[64];
 | |
| 	decl String:ip[20];
 | |
| 	decl String:adminAuth[30];
 | |
| 	decl String:adminIp[20];
 | |
| 	decl String:query[1024];
 | |
| 	decl String:banName[128];
 | |
| 	decl String:banReason[256];
 | |
| 	while (SQL_MoreRows(hndl))
 | |
| 	{
 | |
| 		// Oh noes! What happened?!
 | |
| 		if (!SQL_FetchRow(hndl))
 | |
| 			continue;
 | |
| 
 | |
| 		// if we get to here then there are rows in the queue pending processing
 | |
| 		SQL_FetchString(hndl, 0, auth, sizeof(auth));
 | |
| 		time = SQL_FetchInt(hndl, 1);
 | |
| 		startTime = SQL_FetchInt(hndl, 2);
 | |
| 		SQL_FetchString(hndl, 3, reason, sizeof(reason));
 | |
| 		SQL_FetchString(hndl, 4, name, sizeof(name));
 | |
| 		SQL_FetchString(hndl, 5, ip, sizeof(ip));
 | |
| 		SQL_FetchString(hndl, 6, adminAuth, sizeof(adminAuth));
 | |
| 		SQL_FetchString(hndl, 7, adminIp, sizeof(adminIp));
 | |
| 		SQL_EscapeString(SQLiteDB, name, banName, sizeof(banName));
 | |
| 		SQL_EscapeString(SQLiteDB, reason, banReason, sizeof(banReason));
 | |
| 		if (startTime + time * 60 > GetTime() || time == 0)
 | |
| 		{
 | |
| 			// This ban is still valid and should be entered into the db
 | |
| 			if (serverID == -1)
 | |
| 			{
 | |
| 				FormatEx(query, sizeof(query),
 | |
| 					"INSERT INTO %s_bans (ip, authid, name, created, ends, length, reason, aid, adminIp, sid) VALUES  \
 | |
| 						('%s', '%s', '%s', %d, %d, %d, '%s', (SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'), '%s', \
 | |
| 						(SELECT sid FROM %s_servers WHERE ip = '%s' AND port = '%s' LIMIT 0,1))",
 | |
| 					DatabasePrefix, ip, auth, banName, startTime, startTime + time * 60, time * 60, banReason, DatabasePrefix, adminAuth, adminAuth[8], adminIp, DatabasePrefix, ServerIp, ServerPort);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				FormatEx(query, sizeof(query),
 | |
| 					"INSERT INTO %s_bans (ip, authid, name, created, ends, length, reason, aid, adminIp, sid) VALUES  \
 | |
| 						('%s', '%s', '%s', %d, %d, %d, '%s', (SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'), '%s', \
 | |
| 						%d)",
 | |
| 					DatabasePrefix, ip, auth, banName, startTime, startTime + time * 60, time * 60, banReason, DatabasePrefix, adminAuth, adminAuth[8], adminIp, serverID);
 | |
| 			}
 | |
| 			new Handle:authPack = CreateDataPack();
 | |
| 			WritePackString(authPack, auth);
 | |
| 			ResetPack(authPack);
 | |
| 			SQL_TQuery(DB, AddedFromSQLiteCallback, query, authPack);
 | |
| 		} else {
 | |
| 			// The ban is no longer valid and should be deleted from the queue
 | |
| 			FormatEx(query, sizeof(query), "DELETE FROM queue WHERE steam_id = '%s'", auth);
 | |
| 			SQL_TQuery(SQLiteDB, ErrorCheckCallback, query);
 | |
| 		}
 | |
| 	}
 | |
| 	// We have finished processing the queue but should process again in ProcessQueueTime minutes
 | |
| 	CreateTimer(float(ProcessQueueTime * 60), ProcessQueue);
 | |
| }
 | |
| 
 | |
| public AddedFromSQLiteCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
 | |
| {
 | |
| 	decl String:buffer[512];
 | |
| 	decl String:auth[40];
 | |
| 	ReadPackString(data, auth, sizeof(auth));
 | |
| 	if (error[0] == '\0')
 | |
| 	{
 | |
| 		// The insert was successful so delete the record from the queue
 | |
| 		FormatEx(buffer, sizeof(buffer), "DELETE FROM queue WHERE steam_id = '%s'", auth);
 | |
| 		SQL_TQuery(SQLiteDB, ErrorCheckCallback, buffer);
 | |
| 
 | |
| 		// They are added to main banlist, so remove the temp ban
 | |
| 		RemoveBan(auth, BANFLAG_AUTHID);
 | |
| 
 | |
| 	} else {
 | |
| 		// the insert failed so we leave the record in the queue and increase our temporary ban
 | |
| 		FormatEx(buffer, sizeof(buffer), "banid %d %s", ProcessQueueTime, auth);
 | |
| 		ServerCommand(buffer);
 | |
| 	}
 | |
| 	CloseHandle(data);
 | |
| }
 | |
| 
 | |
| public ServerInfoCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
 | |
| {
 | |
| 	if (error[0])
 | |
| 	{
 | |
| 		LogToFile(logFile, "Server Select Query Failed: %s", error);
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	if (hndl == INVALID_HANDLE || SQL_GetRowCount(hndl) == 0)
 | |
| 	{
 | |
| 		// get the game folder name used to determine the mod
 | |
| 		decl String:desc[64], String:query[200];
 | |
| 		GetGameFolderName(desc, sizeof(desc));
 | |
| 		FormatEx(query, sizeof(query), "INSERT INTO %s_servers (ip, port, rcon, modid) VALUES ('%s', '%s', '', (SELECT mid FROM %s_mods WHERE modfolder = '%s'))", DatabasePrefix, ServerIp, ServerPort, DatabasePrefix, desc);
 | |
| 		SQL_TQuery(DB, ErrorCheckCallback, query);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| public ErrorCheckCallback(Handle:owner, Handle:hndle, const String:error[], any:data)
 | |
| {
 | |
| 	if (error[0])
 | |
| 	{
 | |
| 		LogToFile(logFile, "Query Failed: %s", error);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| public void VerifyBan(Database db, DBResultSet results, const char[] error, int userid)
 | |
| {
 | |
| 	char clientName[64], clientAuth[64], clientIp[64];
 | |
| 
 | |
| 	int client = GetClientOfUserId(userid);
 | |
| 
 | |
| 	if (!client)
 | |
| 		return;
 | |
| 
 | |
| 	/* Failure happen. Do retry with delay */
 | |
| 	if (results == null)
 | |
| 	{
 | |
| 		LogToFile(logFile, "Verify Ban Query Failed: %s", error);
 | |
| 		PlayerRecheck[client] = CreateTimer(RetryTime, ClientRecheck, client);
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	GetClientIP(client, clientIp, sizeof(clientIp));
 | |
| 	GetClientAuthId(client, AuthId_Steam2, clientAuth, sizeof(clientAuth));
 | |
| 	GetClientName(client, clientName, sizeof(clientName));
 | |
| 
 | |
| 	if (results.RowCount > 0)
 | |
| 	{
 | |
| 		char buffer[40], Name[128], Query[512];
 | |
| 
 | |
| 		// Amending to ban record's IP field
 | |
| 		if (results.FetchRow())
 | |
| 		{
 | |
| 			char sIP[32];
 | |
| 
 | |
| 			int iBid = results.FetchInt(0);
 | |
| 			results.FetchString(1, sIP, sizeof sIP);
 | |
| 
 | |
| 			if (StrEqual(sIP, ""))
 | |
| 			{
 | |
| 				char sQuery[256];
 | |
| 
 | |
| 				FormatEx(sQuery, sizeof sQuery, "UPDATE %s_bans SET `ip` = '%s' WHERE `bid` = '%d'", DatabasePrefix, clientIp, iBid);
 | |
| 
 | |
| 				DB.Query(SQL_OnIPMend, sQuery, client);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		DB.Escape(clientName, Name, sizeof Name);
 | |
| 
 | |
| 		if (serverID == -1)
 | |
| 		{
 | |
| 			FormatEx(Query, sizeof(Query), "INSERT INTO %s_banlog (sid ,time ,name ,bid) VALUES  \
 | |
| 				((SELECT sid FROM %s_servers WHERE ip = '%s' AND port = '%s' LIMIT 0,1), UNIX_TIMESTAMP(), '%s', \
 | |
| 				(SELECT bid FROM %s_bans WHERE ((type = 0 AND authid REGEXP '^STEAM_[0-9]:%s$') OR (type = 1 AND ip = '%s')) AND RemoveType IS NULL LIMIT 0,1))",
 | |
| 				DatabasePrefix, DatabasePrefix, ServerIp, ServerPort, Name, DatabasePrefix, clientAuth[8], clientIp);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			FormatEx(Query, sizeof(Query), "INSERT INTO %s_banlog (sid ,time ,name ,bid) VALUES  \
 | |
| 				(%d, UNIX_TIMESTAMP(), '%s', \
 | |
| 				(SELECT bid FROM %s_bans WHERE ((type = 0 AND authid REGEXP '^STEAM_[0-9]:%s$') OR (type = 1 AND ip = '%s')) AND RemoveType IS NULL LIMIT 0,1))",
 | |
| 				DatabasePrefix, serverID, Name, DatabasePrefix, clientAuth[8], clientIp);
 | |
| 		}
 | |
| 
 | |
| 		SQL_TQuery(DB, ErrorCheckCallback, Query, client, DBPrio_High);
 | |
| 
 | |
| 		FormatEx(buffer, sizeof(buffer), "banid 5 %s", clientAuth);
 | |
| 		ServerCommand(buffer);
 | |
| 		KickClient(client, "%t", "Banned Check Site", WebsiteAddress);
 | |
| 
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	#if defined DEBUG
 | |
| 	LogToFile(logFile, "%s is NOT banned.", clientAuth);
 | |
| 	#endif
 | |
| 
 | |
| 	PlayerStatus[client] = true;
 | |
| }
 | |
| 
 | |
| public void SQL_OnIPMend(Database db, DBResultSet results, const char[] error, int iClient)
 | |
| {
 | |
| 	if (results == null)
 | |
| 	{
 | |
| 		char sIP[32], sSteamID[32];
 | |
| 
 | |
| 		GetClientAuthId(iClient, AuthId_Steam3, sSteamID, sizeof sSteamID);
 | |
| 		GetClientIP(iClient, sIP, sizeof sIP);
 | |
| 
 | |
| 		LogToFile(logFile, "Failed to mend IP address for %s (%s): %s", sSteamID, sIP, error);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| public AdminsDone(Handle:owner, Handle:hndl, const String:error[], any:data)
 | |
| {
 | |
| 	//SELECT authid, srv_password , srv_group, srv_flags, user
 | |
| 	if (hndl == INVALID_HANDLE || strlen(error) > 0)
 | |
| 	{
 | |
| 		--curLoading;
 | |
| 		CheckLoadAdmins();
 | |
| 		LogToFile(logFile, "Failed to retrieve admins from the database, %s", error);
 | |
| 		return;
 | |
| 	}
 | |
| 	decl String:authType[] = "steam";
 | |
| 	decl String:identity[66];
 | |
| 	decl String:password[66];
 | |
| 	decl String:groups[256];
 | |
| 	decl String:flags[32];
 | |
| 	decl String:name[66];
 | |
| 	new admCount = 0;
 | |
| 	new Immunity = 0;
 | |
| 	new AdminId:curAdm = INVALID_ADMIN_ID;
 | |
| 	new Handle:adminsKV = CreateKeyValues("Admins");
 | |
| 
 | |
| 	while (SQL_MoreRows(hndl))
 | |
| 	{
 | |
| 		SQL_FetchRow(hndl);
 | |
| 		if (SQL_IsFieldNull(hndl, 0))
 | |
| 			continue; // Sometimes some rows return NULL due to some setups
 | |
| 
 | |
| 		SQL_FetchString(hndl, 0, identity, 66);
 | |
| 		SQL_FetchString(hndl, 1, password, 66);
 | |
| 		SQL_FetchString(hndl, 2, groups, 256);
 | |
| 		SQL_FetchString(hndl, 3, flags, 32);
 | |
| 		SQL_FetchString(hndl, 4, name, 66);
 | |
| 
 | |
| 		Immunity = SQL_FetchInt(hndl, 5);
 | |
| 
 | |
| 		TrimString(name);
 | |
| 		TrimString(identity);
 | |
| 		TrimString(groups);
 | |
| 		TrimString(flags);
 | |
| 
 | |
| 		// Disable writing to file if they chose to
 | |
| 		if (backupConfig)
 | |
| 		{
 | |
| 			KvJumpToKey(adminsKV, name, true);
 | |
| 
 | |
| 			KvSetString(adminsKV, "auth", authType);
 | |
| 			KvSetString(adminsKV, "identity", identity);
 | |
| 
 | |
| 			if (strlen(flags) > 0)
 | |
| 				KvSetString(adminsKV, "flags", flags);
 | |
| 
 | |
| 			if (strlen(groups) > 0)
 | |
| 				KvSetString(adminsKV, "group", groups);
 | |
| 
 | |
| 			if (strlen(password) > 0)
 | |
| 				KvSetString(adminsKV, "password", password);
 | |
| 
 | |
| 			if (Immunity > 0)
 | |
| 				KvSetNum(adminsKV, "immunity", Immunity);
 | |
| 
 | |
| 			KvRewind(adminsKV);
 | |
| 		}
 | |
| 
 | |
| 		// find or create the admin using that identity
 | |
| 		if ((curAdm = FindAdminByIdentity(authType, identity)) == INVALID_ADMIN_ID)
 | |
| 		{
 | |
| 			curAdm = CreateAdmin(name);
 | |
| 			// That should never happen!
 | |
| 			if (!BindAdminIdentity(curAdm, authType, identity))
 | |
| 			{
 | |
| 				LogToFile(logFile, "Unable to bind admin %s to identity %s", name, identity);
 | |
| 				RemoveAdmin(curAdm);
 | |
| 				continue;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		#if defined DEBUG
 | |
| 		LogToFile(logFile, "Given %s (%s) admin", name, identity);
 | |
| 		#endif
 | |
| 
 | |
| 		new curPos = 0;
 | |
| 		new GroupId:curGrp = INVALID_GROUP_ID;
 | |
| 		new numGroups;
 | |
| 		decl String:iterGroupName[64];
 | |
| 
 | |
| 		// Who thought this comma seperated group parsing would be a good idea?!
 | |
| 		/*
 | |
| 		decl String:grp[64];
 | |
| 		new nextPos = 0;
 | |
| 		while ((nextPos = SplitString(groups[curPos],",",grp,64)) != -1)
 | |
| 		{
 | |
| 			curPos += nextPos;
 | |
| 			curGrp = FindAdmGroup(grp);
 | |
| 			if (curGrp == INVALID_GROUP_ID)
 | |
| 			{
 | |
| 				LogToFile(logFile, "Unknown group \"%s\"",grp);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				// Check, if he's not in the group already.
 | |
| 				numGroups = GetAdminGroupCount(curAdm);
 | |
| 				for(new i=0;i<numGroups;i++)
 | |
| 				{
 | |
| 					GetAdminGroup(curAdm, i, iterGroupName, sizeof(iterGroupName));
 | |
| 					// Admin is already part of the group, so don't try to inherit its permissions.
 | |
| 					if(StrEqual(iterGroupName, grp))
 | |
| 					{
 | |
| 						numGroups = -2;
 | |
| 						break;
 | |
| 					}
 | |
| 				}
 | |
| 				// Only try to inherit the group, if it's a new one.
 | |
| 				if (numGroups != -2 && !AdminInheritGroup(curAdm,curGrp))
 | |
| 				{
 | |
| 					LogToFile(logFile, "Unable to inherit group \"%s\"",grp);
 | |
| 				}
 | |
| 			}
 | |
| 		}*/
 | |
| 
 | |
| 		if (strcmp(groups[curPos], "") != 0)
 | |
| 		{
 | |
| 			curGrp = FindAdmGroup(groups[curPos]);
 | |
| 			if (curGrp == INVALID_GROUP_ID)
 | |
| 			{
 | |
| 				LogToFile(logFile, "Unknown group \"%s\"", groups[curPos]);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				// Check, if he's not in the group already.
 | |
| 				numGroups = GetAdminGroupCount(curAdm);
 | |
| 				for (new i = 0; i < numGroups; i++)
 | |
| 				{
 | |
| 					GetAdminGroup(curAdm, i, iterGroupName, sizeof(iterGroupName));
 | |
| 					// Admin is already part of the group, so don't try to inherit its permissions.
 | |
| 					if (StrEqual(iterGroupName, groups[curPos]))
 | |
| 					{
 | |
| 						numGroups = -2;
 | |
| 						break;
 | |
| 					}
 | |
| 				}
 | |
| 
 | |
| 				// Only try to inherit the group, if it's a new one.
 | |
| 				if (numGroups != -2 && !AdminInheritGroup(curAdm, curGrp))
 | |
| 				{
 | |
| 					LogToFile(logFile, "Unable to inherit group \"%s\"", groups[curPos]);
 | |
| 				}
 | |
| 
 | |
| 				if (GetAdminImmunityLevel(curAdm) < Immunity)
 | |
| 				{
 | |
| 					SetAdminImmunityLevel(curAdm, Immunity);
 | |
| 				}
 | |
| 				#if defined DEBUG
 | |
| 				LogToFile(logFile, "Admin %s (%s) has %d immunity", name, identity, Immunity);
 | |
| 				#endif
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		if (strlen(password) > 0)
 | |
| 			SetAdminPassword(curAdm, password);
 | |
| 
 | |
| 		for (new i = 0; i < strlen(flags); ++i)
 | |
| 		{
 | |
| 			if (flags[i] < 'a' || flags[i] > 'z')
 | |
| 				continue;
 | |
| 
 | |
| 			if (g_FlagLetters[flags[i]-'a'] < Admin_Reservation)
 | |
| 				continue;
 | |
| 
 | |
| 			SetAdminFlag(curAdm, g_FlagLetters[flags[i]-'a'], true);
 | |
| 		}
 | |
| 		++admCount;
 | |
| 	}
 | |
| 
 | |
| 	if (backupConfig)
 | |
| 		KeyValuesToFile(adminsKV, adminsLoc);
 | |
| 	CloseHandle(adminsKV);
 | |
| 
 | |
| 	#if defined DEBUG
 | |
| 	LogToFile(logFile, "Finished loading %i admins.", admCount);
 | |
| 	#endif
 | |
| 
 | |
| 	--curLoading;
 | |
| 	CheckLoadAdmins();
 | |
| }
 | |
| 
 | |
| public GroupsDone(Handle:owner, Handle:hndl, const String:error[], any:data)
 | |
| {
 | |
| 	if (hndl == INVALID_HANDLE)
 | |
| 	{
 | |
| 		curLoading--;
 | |
| 		CheckLoadAdmins();
 | |
| 		LogToFile(logFile, "Failed to retrieve groups from the database, %s", error);
 | |
| 		return;
 | |
| 	}
 | |
| 	decl String:grpName[128], String:immuneGrpName[128];
 | |
| 	decl String:grpFlags[32];
 | |
| 	new Immunity;
 | |
| 	new grpCount = 0;
 | |
| 	new Handle:groupsKV = CreateKeyValues("Groups");
 | |
| 
 | |
| 	new GroupId:curGrp = INVALID_GROUP_ID;
 | |
| 	while (SQL_MoreRows(hndl))
 | |
| 	{
 | |
| 		SQL_FetchRow(hndl);
 | |
| 		if (SQL_IsFieldNull(hndl, 0))
 | |
| 			continue; // Sometimes some rows return NULL due to some setups
 | |
| 		SQL_FetchString(hndl, 0, grpName, 128);
 | |
| 		SQL_FetchString(hndl, 1, grpFlags, 32);
 | |
| 		Immunity = SQL_FetchInt(hndl, 2);
 | |
| 		SQL_FetchString(hndl, 3, immuneGrpName, 128);
 | |
| 
 | |
| 		TrimString(grpName);
 | |
| 		TrimString(grpFlags);
 | |
| 		TrimString(immuneGrpName);
 | |
| 
 | |
| 		// Ignore empty rows..
 | |
| 		if (!strlen(grpName))
 | |
| 			continue;
 | |
| 
 | |
| 		curGrp = CreateAdmGroup(grpName);
 | |
| 
 | |
| 		if (backupConfig)
 | |
| 		{
 | |
| 			KvJumpToKey(groupsKV, grpName, true);
 | |
| 			if (strlen(grpFlags) > 0)
 | |
| 				KvSetString(groupsKV, "flags", grpFlags);
 | |
| 			if (Immunity > 0)
 | |
| 				KvSetNum(groupsKV, "immunity", Immunity);
 | |
| 
 | |
| 			KvRewind(groupsKV);
 | |
| 		}
 | |
| 
 | |
| 		if (curGrp == INVALID_GROUP_ID)
 | |
| 		{  //This occurs when the group already exists
 | |
| 			curGrp = FindAdmGroup(grpName);
 | |
| 		}
 | |
| 
 | |
| 		for (new i = 0; i < strlen(grpFlags); ++i)
 | |
| 		{
 | |
| 			if (grpFlags[i] < 'a' || grpFlags[i] > 'z')
 | |
| 				continue;
 | |
| 
 | |
| 			if (g_FlagLetters[grpFlags[i]-'a'] < Admin_Reservation)
 | |
| 				continue;
 | |
| 
 | |
| 			SetAdmGroupAddFlag(curGrp, g_FlagLetters[grpFlags[i]-'a'], true);
 | |
| 		}
 | |
| 
 | |
| 		// Set the group immunity.
 | |
| 		if (Immunity > 0)
 | |
| 		{
 | |
| 			SetAdmGroupImmunityLevel(curGrp, Immunity);
 | |
| 			#if defined DEBUG
 | |
| 			LogToFile(logFile, "Group %s has %d immunity", grpName, Immunity);
 | |
| 			#endif
 | |
| 		}
 | |
| 
 | |
| 		grpCount++;
 | |
| 	}
 | |
| 
 | |
| 	if (backupConfig)
 | |
| 		KeyValuesToFile(groupsKV, groupsLoc);
 | |
| 	CloseHandle(groupsKV);
 | |
| 
 | |
| 	#if defined DEBUG
 | |
| 	LogToFile(logFile, "Finished loading %i groups.", grpCount);
 | |
| 	#endif
 | |
| 
 | |
| 	// Load the group overrides
 | |
| 	decl String:query[512];
 | |
| 	FormatEx(query, 512, "SELECT sg.name, so.type, so.name, so.access FROM %s_srvgroups_overrides so LEFT JOIN %s_srvgroups sg ON sg.id = so.group_id ORDER BY sg.id", DatabasePrefix, DatabasePrefix);
 | |
| 	SQL_TQuery(DB, LoadGroupsOverrides, query);
 | |
| 
 | |
| 	/*if (reparse)
 | |
| 	{
 | |
| 		decl String:query[512];
 | |
| 		FormatEx(query,512,"SELECT name, immunity, groups_immune FROM %s_srvgroups ORDER BY id",DatabasePrefix);
 | |
| 		SQL_TQuery(DB,GroupsSecondPass,query);
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		curLoading--;
 | |
| 		CheckLoadAdmins();
 | |
| 	}*/
 | |
| }
 | |
| 
 | |
| // Reparse to apply inherited immunity
 | |
| public GroupsSecondPass(Handle:owner, Handle:hndl, const String:error[], any:data)
 | |
| {
 | |
| 	if (hndl == INVALID_HANDLE)
 | |
| 	{
 | |
| 		curLoading--;
 | |
| 		CheckLoadAdmins();
 | |
| 		LogToFile(logFile, "Failed to retrieve groups from the database, %s", error);
 | |
| 		return;
 | |
| 	}
 | |
| 	decl String:grpName[128], String:immunityGrpName[128];
 | |
| 
 | |
| 	new GroupId:curGrp = INVALID_GROUP_ID;
 | |
| 	new GroupId:immuneGrp = INVALID_GROUP_ID;
 | |
| 	while (SQL_MoreRows(hndl))
 | |
| 	{
 | |
| 		SQL_FetchRow(hndl);
 | |
| 		if (SQL_IsFieldNull(hndl, 0))
 | |
| 			continue; // Sometimes some rows return NULL due to some setups
 | |
| 
 | |
| 		SQL_FetchString(hndl, 0, grpName, 128);
 | |
| 		TrimString(grpName);
 | |
| 		if (strlen(grpName) == 0)
 | |
| 			continue;
 | |
| 
 | |
| 		SQL_FetchString(hndl, 2, immunityGrpName, sizeof(immunityGrpName));
 | |
| 		TrimString(immunityGrpName);
 | |
| 
 | |
| 		curGrp = FindAdmGroup(grpName);
 | |
| 		if (curGrp == INVALID_GROUP_ID)
 | |
| 			continue;
 | |
| 
 | |
| 		immuneGrp = FindAdmGroup(immunityGrpName);
 | |
| 		if (immuneGrp == INVALID_GROUP_ID)
 | |
| 			continue;
 | |
| 
 | |
| 		SetAdmGroupImmuneFrom(curGrp, immuneGrp);
 | |
| 
 | |
| 		#if defined DEBUG
 | |
| 		LogToFile(logFile, "Group %s inhertied immunity from group %s", grpName, immunityGrpName);
 | |
| 		#endif
 | |
| 	}
 | |
| 	--curLoading;
 | |
| 	CheckLoadAdmins();
 | |
| }
 | |
| 
 | |
| public LoadGroupsOverrides(Handle:owner, Handle:hndl, const String:error[], any:data)
 | |
| {
 | |
| 	if (hndl == INVALID_HANDLE)
 | |
| 	{
 | |
| 		curLoading--;
 | |
| 		CheckLoadAdmins();
 | |
| 		LogToFile(logFile, "Failed to retrieve group overrides from the database, %s", error);
 | |
| 		return;
 | |
| 	}
 | |
| 	decl String:sGroupName[128], String:sType[16], String:sCommand[64], String:sAllowed[16];
 | |
| 	decl OverrideRule:iRule, OverrideType:iType;
 | |
| 
 | |
| 	new Handle:groupsKV = CreateKeyValues("Groups");
 | |
| 	FileToKeyValues(groupsKV, groupsLoc);
 | |
| 
 | |
| 	new GroupId:curGrp = INVALID_GROUP_ID;
 | |
| 	while (SQL_MoreRows(hndl))
 | |
| 	{
 | |
| 		SQL_FetchRow(hndl);
 | |
| 		if (SQL_IsFieldNull(hndl, 0))
 | |
| 			continue; // Sometimes some rows return NULL due to some setups
 | |
| 
 | |
| 		SQL_FetchString(hndl, 0, sGroupName, sizeof(sGroupName));
 | |
| 		TrimString(sGroupName);
 | |
| 		if (strlen(sGroupName) == 0)
 | |
| 			continue;
 | |
| 
 | |
| 		SQL_FetchString(hndl, 1, sType, sizeof(sType));
 | |
| 		SQL_FetchString(hndl, 2, sCommand, sizeof(sCommand));
 | |
| 		SQL_FetchString(hndl, 3, sAllowed, sizeof(sAllowed));
 | |
| 
 | |
| 		curGrp = FindAdmGroup(sGroupName);
 | |
| 		if (curGrp == INVALID_GROUP_ID)
 | |
| 			continue;
 | |
| 
 | |
| 		iRule = StrEqual(sAllowed, "allow") ? Command_Allow : Command_Deny;
 | |
| 		iType = StrEqual(sType, "group") ? Override_CommandGroup : Override_Command;
 | |
| 
 | |
| 		#if defined DEBUG
 | |
| 		PrintToServer("AddAdmGroupCmdOverride(%i, %s, %i, %i)", curGrp, sCommand, iType, iRule);
 | |
| 		#endif
 | |
| 
 | |
| 		// Save overrides into admin_groups.cfg backup
 | |
| 		if (KvJumpToKey(groupsKV, sGroupName))
 | |
| 		{
 | |
| 			KvJumpToKey(groupsKV, "Overrides", true);
 | |
| 			if (iType == Override_Command)
 | |
| 				KvSetString(groupsKV, sCommand, sAllowed);
 | |
| 			else
 | |
| 			{
 | |
| 				Format(sCommand, sizeof(sCommand), "@%s", sCommand);
 | |
| 				KvSetString(groupsKV, sCommand, sAllowed);
 | |
| 			}
 | |
| 			KvRewind(groupsKV);
 | |
| 		}
 | |
| 
 | |
| 		AddAdmGroupCmdOverride(curGrp, sCommand, iType, iRule);
 | |
| 	}
 | |
| 	curLoading--;
 | |
| 	CheckLoadAdmins();
 | |
| 
 | |
| 	if (backupConfig)
 | |
| 		KeyValuesToFile(groupsKV, groupsLoc);
 | |
| 	CloseHandle(groupsKV);
 | |
| }
 | |
| 
 | |
| public OverridesDone(Handle:owner, Handle:hndl, const String:error[], any:data)
 | |
| {
 | |
| 	if (hndl == INVALID_HANDLE)
 | |
| 	{
 | |
| 		LogToFile(logFile, "Failed to retrieve overrides from the database, %s", error);
 | |
| 		ParseBackupConfig_Overrides();
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	new Handle:hKV = CreateKeyValues("SB_Overrides");
 | |
| 
 | |
| 	decl String:sFlags[32], String:sName[64], String:sType[64];
 | |
| 	while (SQL_FetchRow(hndl))
 | |
| 	{
 | |
| 		SQL_FetchString(hndl, 0, sType, sizeof(sType));
 | |
| 		SQL_FetchString(hndl, 1, sName, sizeof(sName));
 | |
| 		SQL_FetchString(hndl, 2, sFlags, sizeof(sFlags));
 | |
| 
 | |
| 		// KeyValuesToFile won't add that key, if the value is ""..
 | |
| 		if (sFlags[0] == '\0')
 | |
| 		{
 | |
| 			sFlags[0] = ' ';
 | |
| 			sFlags[1] = '\0';
 | |
| 		}
 | |
| 
 | |
| 		#if defined DEBUG
 | |
| 		LogToFile(logFile, "Adding override (%s, %s, %s)", sType, sName, sFlags);
 | |
| 		#endif
 | |
| 
 | |
| 		if (StrEqual(sType, "command"))
 | |
| 		{
 | |
| 			AddCommandOverride(sName, Override_Command, ReadFlagString(sFlags));
 | |
| 			KvJumpToKey(hKV, "override_commands", true);
 | |
| 			KvSetString(hKV, sName, sFlags);
 | |
| 			KvGoBack(hKV);
 | |
| 		}
 | |
| 		else if (StrEqual(sType, "group"))
 | |
| 		{
 | |
| 			AddCommandOverride(sName, Override_CommandGroup, ReadFlagString(sFlags));
 | |
| 			KvJumpToKey(hKV, "override_groups", true);
 | |
| 			KvSetString(hKV, sName, sFlags);
 | |
| 			KvGoBack(hKV);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	KvRewind(hKV);
 | |
| 
 | |
| 	if (backupConfig)
 | |
| 		KeyValuesToFile(hKV, overridesLoc);
 | |
| 	CloseHandle(hKV);
 | |
| }
 | |
| 
 | |
| // TIMER CALL BACKS //
 | |
| 
 | |
| public Action:ClientRecheck(Handle:timer, any:client)
 | |
| {
 | |
| 	decl String:Authid[64];
 | |
| 	if (!PlayerStatus[client] && IsClientConnected(client) && GetClientAuthId(client, AuthId_Steam2, Authid, sizeof(Authid)))
 | |
| 	{
 | |
| 		OnClientAuthorized(client, Authid);
 | |
| 	}
 | |
| 
 | |
| 	PlayerRecheck[client] = INVALID_HANDLE;
 | |
| 	return Plugin_Stop;
 | |
| }
 | |
| 
 | |
| /*
 | |
| public Action:PruneBans(Handle:timer)
 | |
| {
 | |
| 	decl String:Query[512];
 | |
| 	FormatEx(Query, sizeof(Query),
 | |
| 			"UPDATE %s_bans SET RemovedBy = 0, RemoveType = 'E', RemovedOn = UNIX_TIMESTAMP() WHERE length != '0' AND ends < UNIX_TIMESTAMP()",
 | |
| 			DatabasePrefix);
 | |
| 
 | |
| 	SQL_TQuery(DB, ErrorCheckCallback, Query);
 | |
| 	return Plugin_Continue;
 | |
| }
 | |
| */
 | |
| 
 | |
| public Action:ProcessQueue(Handle:timer, any:data)
 | |
| {
 | |
| 	decl String:buffer[512];
 | |
| 	Format(buffer, sizeof(buffer), "SELECT steam_id, time, start_time, reason, name, ip, admin_id, admin_ip FROM queue");
 | |
| 	SQL_TQuery(SQLiteDB, ProcessQueueCallback, buffer);
 | |
| }
 | |
| 
 | |
| // PARSER //
 | |
| 
 | |
| static InitializeConfigParser()
 | |
| {
 | |
| 	if (ConfigParser == INVALID_HANDLE)
 | |
| 	{
 | |
| 		ConfigParser = SMC_CreateParser();
 | |
| 		SMC_SetReaders(ConfigParser, ReadConfig_NewSection, ReadConfig_KeyValue, ReadConfig_EndSection);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static InternalReadConfig(const String:path[])
 | |
| {
 | |
| 	ConfigState = ConfigStateNone;
 | |
| 
 | |
| 	new SMCError:err = SMC_ParseFile(ConfigParser, path);
 | |
| 
 | |
| 	if (err != SMCError_Okay)
 | |
| 	{
 | |
| 		decl String:buffer[64];
 | |
| 		PrintToServer("%s", SMC_GetErrorString(err, buffer, sizeof(buffer)) ? buffer : "Fatal parse error");
 | |
| 	}
 | |
| }
 | |
| 
 | |
| public SMCResult:ReadConfig_NewSection(Handle:smc, const String:name[], bool:opt_quotes)
 | |
| {
 | |
| 	if (name[0])
 | |
| 	{
 | |
| 		if (strcmp("Config", name, false) == 0) {
 | |
| 			ConfigState = ConfigStateConfig;
 | |
| 		} else if (strcmp("BanReasons", name, false) == 0) {
 | |
| 			ConfigState = ConfigStateReasons;
 | |
| 		} else if (strcmp("HackingReasons", name, false) == 0) {
 | |
| 			ConfigState = ConfigStateHacking;
 | |
| 		} else if (strcmp("BanTime", name, false) == 0) {
 | |
| 			ConfigState = ConfigStateTime;
 | |
| 		}
 | |
| 	}
 | |
| 	return SMCParse_Continue;
 | |
| }
 | |
| 
 | |
| public SMCResult:ReadConfig_KeyValue(Handle:smc, const String:key[], const String:value[], bool:key_quotes, bool:value_quotes)
 | |
| {
 | |
| 	if (!key[0])
 | |
| 		return SMCParse_Continue;
 | |
| 
 | |
| 	switch (ConfigState)
 | |
| 	{
 | |
| 		case ConfigStateConfig:
 | |
| 		{
 | |
| 			if (strcmp("website", key, false) == 0)
 | |
| 			{
 | |
| 				strcopy(WebsiteAddress, sizeof(WebsiteAddress), value);
 | |
| 			}
 | |
| 			else if (strcmp("Addban", key, false) == 0)
 | |
| 			{
 | |
| 				if (StringToInt(value) == 0)
 | |
| 				{
 | |
| 					CommandDisable |= DISABLE_ADDBAN;
 | |
| 				}
 | |
| 			}
 | |
| 			else if (strcmp("AutoAddServer", key, false) == 0)
 | |
| 			{
 | |
| 				AutoAdd = StringToInt(value) == 1;
 | |
| 			}
 | |
| 			else if (strcmp("Unban", key, false) == 0)
 | |
| 			{
 | |
| 				if (StringToInt(value) == 0)
 | |
| 				{
 | |
| 					CommandDisable |= DISABLE_UNBAN;
 | |
| 				}
 | |
| 			}
 | |
| 			else if (strcmp("DatabasePrefix", key, false) == 0)
 | |
| 			{
 | |
| 				strcopy(DatabasePrefix, sizeof(DatabasePrefix), value);
 | |
| 
 | |
| 				if (DatabasePrefix[0] == '\0')
 | |
| 				{
 | |
| 					DatabasePrefix = "sb";
 | |
| 				}
 | |
| 			}
 | |
| 			else if (strcmp("RetryTime", key, false) == 0)
 | |
| 			{
 | |
| 				RetryTime = StringToFloat(value);
 | |
| 				if (RetryTime < 15.0)
 | |
| 				{
 | |
| 					RetryTime = 15.0;
 | |
| 				} else if (RetryTime > 60.0) {
 | |
| 					RetryTime = 60.0;
 | |
| 				}
 | |
| 			}
 | |
| 			else if (strcmp("ProcessQueueTime", key, false) == 0)
 | |
| 			{
 | |
| 				ProcessQueueTime = StringToInt(value);
 | |
| 			}
 | |
| 			else if (strcmp("BackupConfigs", key, false) == 0)
 | |
| 			{
 | |
| 				backupConfig = StringToInt(value) == 1;
 | |
| 			}
 | |
| 			else if (strcmp("EnableAdmins", key, false) == 0)
 | |
| 			{
 | |
| 				enableAdmins = StringToInt(value) == 1;
 | |
| 			}
 | |
| 			else if (strcmp("RequireSiteLogin", key, false) == 0)
 | |
| 			{
 | |
| 				requireSiteLogin = StringToInt(value) == 1;
 | |
| 			}
 | |
| 			else if (strcmp("ServerID", key, false) == 0)
 | |
| 			{
 | |
| 				serverID = StringToInt(value);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		case ConfigStateReasons:
 | |
| 		{
 | |
| 			if (ReasonMenuHandle != INVALID_HANDLE)
 | |
| 			{
 | |
| 				AddMenuItem(ReasonMenuHandle, key, value);
 | |
| 			}
 | |
| 		}
 | |
| 		case ConfigStateHacking:
 | |
| 		{
 | |
| 			if (HackingMenuHandle != INVALID_HANDLE)
 | |
| 			{
 | |
| 				AddMenuItem(HackingMenuHandle, key, value);
 | |
| 			}
 | |
| 		}
 | |
| 		case ConfigStateTime:
 | |
| 		{
 | |
| 			if (StringToInt(key) > -1 && TimeMenuHandle != INVALID_HANDLE)
 | |
| 			{
 | |
| 				AddMenuItem(TimeMenuHandle, key, value);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	return SMCParse_Continue;
 | |
| }
 | |
| 
 | |
| public SMCResult:ReadConfig_EndSection(Handle:smc)
 | |
| {
 | |
| 	return SMCParse_Continue;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*********************************************************
 | |
|  * Ban Player from server
 | |
|  *
 | |
|  * @param client	The client index of the player to ban
 | |
|  * @param time		The time to ban the player for (in minutes, 0 = permanent)
 | |
|  * @param reason	The reason to ban the player from the server
 | |
|  * @noreturn
 | |
|  *********************************************************/
 | |
| public Native_SBBanPlayer(Handle plugin, int numParams)
 | |
| {
 | |
| 	int client = GetNativeCell(1);
 | |
| 	int target = GetNativeCell(2);
 | |
| 	int time = GetNativeCell(3);
 | |
| 	char reason[128];
 | |
| 	GetNativeString(4, reason, 128);
 | |
| 
 | |
| 	if (reason[0] == '\0')
 | |
| 		strcopy(reason, sizeof(reason), "Banned by SourceBans");
 | |
| 
 | |
| 	if (client && IsClientInGame(client))
 | |
| 	{
 | |
| 		AdminId aid = GetUserAdmin(client);
 | |
| 		if (aid == INVALID_ADMIN_ID)
 | |
| 		{
 | |
| 			ThrowNativeError(SP_ERROR_NATIVE, "Ban Error: Player is not an admin.");
 | |
| 			return 0;
 | |
| 		}
 | |
| 
 | |
| 		if (!GetAdminFlag(aid, Admin_Ban))
 | |
| 		{
 | |
| 			ThrowNativeError(SP_ERROR_NATIVE, "Ban Error: Player does not have BAN flag.");
 | |
| 			return 0;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	PrepareBan(client, target, time, reason, sizeof(reason));
 | |
| 	return true;
 | |
| }
 | |
| 
 | |
| public int Native_SBReportPlayer(Handle plugin, int numParams)
 | |
| {
 | |
| 	if (numParams < 3)
 | |
| 	{
 | |
| 		ThrowNativeError(SP_ERROR_NATIVE, "Invalid amount of arguments. Received %d arguments", numParams);
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	int iReporter = GetNativeCell(1)
 | |
| 	  , iTarget = GetNativeCell(2)
 | |
| 	  , iReasonLen;
 | |
| 
 | |
| 	int iTime = GetTime();
 | |
| 
 | |
| 	GetNativeStringLength(3, iReasonLen);
 | |
| 
 | |
| 	iReasonLen++;
 | |
| 
 | |
| 	char[] sReason = new char[iReasonLen];
 | |
| 
 | |
| 	GetNativeString(3, sReason, iReasonLen);
 | |
| 
 | |
| 	char sRAuth[32], sTAuth[32], sRName[MAX_NAME_LENGTH + 1], sTName[MAX_NAME_LENGTH + 1],
 | |
| 	sRIP[16], sTIP[16], sREscapedName[MAX_NAME_LENGTH * 2 + 1], sTEscapedName[MAX_NAME_LENGTH * 2 + 1];
 | |
| 
 | |
| 	char[] sEscapedReason = new char[iReasonLen * 2 + 1];
 | |
| 
 | |
| 	GetClientAuthId(iReporter, AuthId_Steam2, sRAuth, sizeof sRAuth);
 | |
| 	GetClientAuthId(iTarget, AuthId_Steam2, sTAuth, sizeof sTAuth);
 | |
| 
 | |
| 	GetClientName(iReporter, sRName, sizeof sRName);
 | |
| 	GetClientName(iTarget, sTName, sizeof sTName);
 | |
| 
 | |
| 	GetClientIP(iReporter, sRIP, sizeof sRIP);
 | |
| 	GetClientIP(iTarget, sTIP, sizeof sTIP);
 | |
| 
 | |
| 	DB.Escape(sRName, sREscapedName, sizeof sREscapedName);
 | |
| 	DB.Escape(sTName, sTEscapedName, sizeof sTEscapedName);
 | |
| 	DB.Escape(sReason, sEscapedReason, iReasonLen * 2 + 1);
 | |
| 
 | |
| 	char[] sQuery = new char[512 + (iReasonLen * 2 + 1)];
 | |
| 
 | |
| 	Format(sQuery, 512 + (iReasonLen * 2 + 1), "INSERT INTO %s_submissions (`submitted`, `modid`, `SteamId`, `name`, `email`, `reason`, `ip`, `subname`, `sip`, `archiv`, `server`)"
 | |
| 	... "VALUES ('%d', 0, '%s', '%s', '%s', '%s', '%s', '%s', '%s', 0, 0)", DatabasePrefix, iTime, sTAuth, sTEscapedName, sRAuth, sEscapedReason, sRIP, sREscapedName, sTIP);
 | |
| 
 | |
| 	DataPack ForwardPack = new DataPack();
 | |
| 
 | |
| 	ForwardPack.WriteCell(iReporter);
 | |
| 	ForwardPack.WriteCell(iTarget);
 | |
| 	ForwardPack.WriteCell(iReasonLen);
 | |
| 	ForwardPack.WriteString(sReason);
 | |
| 
 | |
| 	DB.Query(SQL_OnReportPlayer, sQuery, ForwardPack);
 | |
| }
 | |
| 
 | |
| public void SQL_OnReportPlayer(Database db, DBResultSet results, const char[] error, DataPack ForwardPack)
 | |
| {
 | |
| 	if (results == null)
 | |
| 		LogToFile(logFile, "Failed to submit report: %s", error);
 | |
| 	else
 | |
| 	{
 | |
| 		ForwardPack.Reset();
 | |
| 
 | |
| 		int iReporter = ForwardPack.ReadCell();
 | |
| 		int iTarget = ForwardPack.ReadCell();
 | |
| 		int iReasonLen = ForwardPack.ReadCell();
 | |
| 
 | |
| 		char[] sReason = new char[iReasonLen];
 | |
| 
 | |
| 		ForwardPack.ReadString(sReason, iReasonLen);
 | |
| 
 | |
| 		Call_StartForward(g_hFwd_OnReportAdded);
 | |
| 		Call_PushCell(iReporter);
 | |
| 		Call_PushCell(iTarget);
 | |
| 		Call_PushString(sReason);
 | |
| 		Call_Finish();
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // STOCK FUNCTIONS //
 | |
| 
 | |
| public InitializeBackupDB()
 | |
| {
 | |
| 	char error[255];
 | |
| 
 | |
| 	SQLiteDB = SQLite_UseDatabase("sourcebans-queue", error, sizeof(error));
 | |
| 	if (SQLiteDB == INVALID_HANDLE)
 | |
| 		SetFailState(error);
 | |
| 
 | |
| 	SQL_LockDatabase(SQLiteDB);
 | |
| 	SQL_FastQuery(SQLiteDB, "CREATE TABLE IF NOT EXISTS queue (steam_id TEXT PRIMARY KEY ON CONFLICT REPLACE, time INTEGER, start_time INTEGER, reason TEXT, name TEXT, ip TEXT, admin_id TEXT, admin_ip TEXT);");
 | |
| 	SQL_UnlockDatabase(SQLiteDB);
 | |
| }
 | |
| 
 | |
| public bool CreateBan(int client, int target, int time, const char[] reason)
 | |
| {
 | |
| 	char adminIp[24], adminAuth[64];
 | |
| 	int admin = client;
 | |
| 
 | |
| 	// The server is the one calling the ban
 | |
| 	if (!admin)
 | |
| 	{
 | |
| 		if (reason[0] == '\0')
 | |
| 		{
 | |
| 			// We cannot pop the reason menu if the command was issued from the server
 | |
| 			PrintToServer("%s%T", Prefix, "Include Reason", LANG_SERVER);
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		// setup dummy adminAuth and adminIp for server
 | |
| 		strcopy(adminAuth, sizeof(adminAuth), "STEAM_ID_SERVER");
 | |
| 		strcopy(adminIp, sizeof(adminIp), ServerIp);
 | |
| 	} else {
 | |
| 		GetClientIP(admin, adminIp, sizeof(adminIp));
 | |
| 		GetClientAuthId(admin, AuthId_Steam2, adminAuth, sizeof(adminAuth));
 | |
| 	}
 | |
| 
 | |
| 	// target information
 | |
| 	char ip[24], auth[64], name[64];
 | |
| 
 | |
| 	GetClientName(target, name, sizeof(name));
 | |
| 	GetClientIP(target, ip, sizeof(ip));
 | |
| 	if (!GetClientAuthId(target, AuthId_Steam2, auth, sizeof(auth)))
 | |
| 		return false;
 | |
| 
 | |
| 	int userid = admin ? GetClientUserId(admin) : 0;
 | |
| 
 | |
| 	// Pack everything into a data pack so we can retain it
 | |
| 	DataPack dataPack = new DataPack();
 | |
| 	DataPack reasonPack = new DataPack();
 | |
| 
 | |
| 	WritePackString(reasonPack, reason);
 | |
| 
 | |
| 	dataPack.WriteCell(admin);
 | |
| 	dataPack.WriteCell(target);
 | |
| 	dataPack.WriteCell(userid);
 | |
| 	dataPack.WriteCell(GetClientUserId(target));
 | |
| 	dataPack.WriteCell(time);
 | |
| 	dataPack.WriteCell( _:reasonPack);
 | |
| 	dataPack.WriteString(name);
 | |
| 	dataPack.WriteString(auth);
 | |
| 	dataPack.WriteString(ip);
 | |
| 	dataPack.WriteString(adminAuth);
 | |
| 	dataPack.WriteString(adminIp);
 | |
| 
 | |
| 	dataPack.Reset();
 | |
| 	reasonPack.Reset();
 | |
| 
 | |
| 	if (reason[0] != '\0')
 | |
| 	{
 | |
| 		// if we have a valid reason pass move forward with the ban
 | |
| 		if (DB != INVALID_HANDLE)
 | |
| 		{
 | |
| 			UTIL_InsertBan(time, name, auth, ip, reason, adminAuth, adminIp, dataPack);
 | |
| 		} else {
 | |
| 			UTIL_InsertTempBan(time, name, auth, ip, reason, adminAuth, adminIp, dataPack);
 | |
| 		}
 | |
| 	} else {
 | |
| 		// We need a reason so offer the administrator a menu of reasons
 | |
| 		PlayerDataPack[admin] = dataPack;
 | |
| 		DisplayMenu(ReasonMenuHandle, admin, MENU_TIME_FOREVER);
 | |
| 		ReplyToCommand(admin, "%c[%cSourceBans%c]%c %t", GREEN, NAMECOLOR, GREEN, NAMECOLOR, "Check Menu");
 | |
| 	}
 | |
| 
 | |
| 	Call_StartForward(g_hFwd_OnBanAdded);
 | |
| 	Call_PushCell(client);
 | |
| 	Call_PushCell(target);
 | |
| 	Call_PushCell(time);
 | |
| 	Call_PushString(reason);
 | |
| 	Call_Finish();
 | |
| 
 | |
| 	return true;
 | |
| }
 | |
| 
 | |
| stock UTIL_InsertBan(time, const String:Name[], const String:Authid[], const String:Ip[], const String:Reason[], const String:AdminAuthid[], const String:AdminIp[], Handle:Pack)
 | |
| {
 | |
| 	//new Handle:dummy;
 | |
| 	//PruneBans(dummy);
 | |
| 	decl String:banName[128];
 | |
| 	decl String:banReason[256];
 | |
| 	decl String:Query[1024];
 | |
| 	SQL_EscapeString(DB, Name, banName, sizeof(banName));
 | |
| 	SQL_EscapeString(DB, Reason, banReason, sizeof(banReason));
 | |
| 	if (serverID == -1)
 | |
| 	{
 | |
| 		FormatEx(Query, sizeof(Query), "INSERT INTO %s_bans (ip, authid, name, created, ends, length, reason, aid, adminIp, sid, country) VALUES \
 | |
| 						('%s', '%s', '%s', UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + %d, %d, '%s', IFNULL((SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'),'0'), '%s', \
 | |
| 						(SELECT sid FROM %s_servers WHERE ip = '%s' AND port = '%s' LIMIT 0,1), ' ')",
 | |
| 			DatabasePrefix, Ip, Authid, banName, (time * 60), (time * 60), banReason, DatabasePrefix, AdminAuthid, AdminAuthid[8], AdminIp, DatabasePrefix, ServerIp, ServerPort);
 | |
| 	} else {
 | |
| 		FormatEx(Query, sizeof(Query), "INSERT INTO %s_bans (ip, authid, name, created, ends, length, reason, aid, adminIp, sid, country) VALUES \
 | |
| 						('%s', '%s', '%s', UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + %d, %d, '%s', IFNULL((SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'),'0'), '%s', \
 | |
| 						%d, ' ')",
 | |
| 			DatabasePrefix, Ip, Authid, banName, (time * 60), (time * 60), banReason, DatabasePrefix, AdminAuthid, AdminAuthid[8], AdminIp, serverID);
 | |
| 	}
 | |
| 
 | |
| 	SQL_TQuery(DB, VerifyInsert, Query, Pack, DBPrio_High);
 | |
| }
 | |
| 
 | |
| stock UTIL_InsertTempBan(int time, const char[] name, const char[] auth, const char[] ip, const char[] reason, const char[] adminAuth, const char[] adminIp, DataPack dataPack)
 | |
| {
 | |
| 	dataPack.ReadCell(); // admin index
 | |
| 
 | |
| 	int client = ReadPackCell(dataPack);
 | |
| 
 | |
| 	dataPack.ReadCell(); // admin userid
 | |
| 	dataPack.ReadCell(); // target userid
 | |
| 	dataPack.ReadCell(); // time
 | |
| 
 | |
| 	DataPack reasonPack = view_as<DataPack>(dataPack.ReadCell());
 | |
| 
 | |
| 	if (reasonPack != INVALID_HANDLE)
 | |
| 		CloseHandle(reasonPack);
 | |
| 	CloseHandle(dataPack);
 | |
| 
 | |
| 	// we add a temporary ban and then add the record into the queue to be processed when the database is available
 | |
| 	char buffer[50];
 | |
| 
 | |
| 	Format(buffer, sizeof(buffer), "banid %d %s", ProcessQueueTime, auth);
 | |
| 
 | |
| 	ServerCommand(buffer);
 | |
| 
 | |
| 	if (IsClientInGame(client))
 | |
| 		KickClient(client, "%t", "Banned Check Site", WebsiteAddress);
 | |
| 
 | |
| 	char banName[128], banReason[256], query[512];
 | |
| 
 | |
| 	SQL_EscapeString(SQLiteDB, name, banName, sizeof(banName));
 | |
| 	SQL_EscapeString(SQLiteDB, reason, banReason, sizeof(banReason));
 | |
| 
 | |
| 	FormatEx(query, sizeof(query), "INSERT INTO queue VALUES ('%s', %i, %i, '%s', '%s', '%s', '%s', '%s')",
 | |
| 		auth, time, GetTime(), banReason, banName, ip, adminAuth, adminIp);
 | |
| 
 | |
| 	SQL_TQuery(SQLiteDB, ErrorCheckCallback, query);
 | |
| }
 | |
| 
 | |
| stock CheckLoadAdmins()
 | |
| {
 | |
| 	for (new i = 1; i <= MaxClients; i++)
 | |
| 	{
 | |
| 		if (IsClientInGame(i) && IsClientAuthorized(i))
 | |
| 		{
 | |
| 			RunAdminCacheChecks(i);
 | |
| 			NotifyPostAdminCheck(i);
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| stock InsertServerInfo()
 | |
| {
 | |
|     if (DB == INVALID_HANDLE) {
 | |
|         return;
 | |
|     }
 | |
|     
 | |
|     char query[100];
 | |
|     int pieces[4];
 | |
|     int longip = GetConVarInt(CvarHostIp);
 | |
| 
 | |
|     pieces[0] = (longip >> 24) & 0x000000FF;
 | |
|     pieces[1] = (longip >> 16) & 0x000000FF;
 | |
|     pieces[2] = (longip >> 8) & 0x000000FF;
 | |
|     pieces[3] = longip & 0x000000FF;
 | |
| 
 | |
|     FormatEx(ServerIp, sizeof(ServerIp), "%d.%d.%d.%d", pieces[0], pieces[1], pieces[2], pieces[3]);
 | |
|     GetConVarString(CvarPort, ServerPort, sizeof(ServerPort));
 | |
| 
 | |
|     if (AutoAdd != false) {
 | |
|         FormatEx(query, sizeof(query), "SELECT sid FROM %s_servers WHERE ip = '%s' AND port = '%s'", DatabasePrefix, ServerIp, ServerPort);
 | |
|         SQL_TQuery(DB, ServerInfoCallback, query);
 | |
|     }
 | |
| }
 | |
| 
 | |
| stock void PrepareBan(int client, int target, int time, char[] reason, int size)
 | |
| {
 | |
| 	#if defined DEBUG
 | |
| 	LogToFile(logFile, "PrepareBan()");
 | |
| 	#endif
 | |
| 	if (!target || !IsClientInGame(target))
 | |
| 		return;
 | |
| 	char authid[64], name[32], bannedSite[512];
 | |
| 	if (!GetClientAuthId(target, AuthId_Steam2, authid, sizeof(authid)))
 | |
| 		return;
 | |
| 	GetClientName(target, name, sizeof(name));
 | |
| 
 | |
| 
 | |
| 	if (CreateBan(client, target, time, reason))
 | |
| 	{
 | |
| 		if (!time)
 | |
| 		{
 | |
| 			if (reason[0] == '\0')
 | |
| 			{
 | |
| 				ShowActivity(client, "%t", "Permabanned player", name);
 | |
| 			} else {
 | |
| 				ShowActivity(client, "%t", "Permabanned player reason", name, reason);
 | |
| 			}
 | |
| 		} else {
 | |
| 			if (reason[0] == '\0')
 | |
| 			{
 | |
| 				ShowActivity(client, "%t", "Banned player", name, time);
 | |
| 			} else {
 | |
| 				ShowActivity(client, "%t", "Banned player reason", name, time, reason);
 | |
| 			}
 | |
| 		}
 | |
| 		LogAction(client, target, "\"%L\" banned \"%L\" (minutes \"%d\") (reason \"%s\")", client, target, time, reason);
 | |
| 
 | |
| 		if (time > 5 || time == 0)
 | |
| 			time = 5;
 | |
| 		Format(bannedSite, sizeof(bannedSite), "%T", "Banned Check Site", target, WebsiteAddress);
 | |
| 		BanClient(target, time, BANFLAG_AUTO, bannedSite, bannedSite, "sm_ban", client);
 | |
| 	}
 | |
| 
 | |
| 	g_BanTarget[client] = -1;
 | |
| 	g_BanTime[client] = -1;
 | |
| }
 | |
| 
 | |
| stock void ReadConfig()
 | |
| {
 | |
| 	InitializeConfigParser();
 | |
| 
 | |
| 	if (ConfigParser == INVALID_HANDLE)
 | |
| 	{
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	char ConfigFile[PLATFORM_MAX_PATH];
 | |
| 	BuildPath(Path_SM, ConfigFile, sizeof(ConfigFile), "configs/sourcebans/sourcebans.cfg");
 | |
| 
 | |
| 	if (FileExists(ConfigFile))
 | |
| 	{
 | |
| 		InternalReadConfig(ConfigFile);
 | |
| 		PrintToServer("%sLoading configs/sourcebans.cfg config file", Prefix);
 | |
| 	} else {
 | |
| 		char Error[PLATFORM_MAX_PATH + 64];
 | |
| 		FormatEx(Error, sizeof(Error), "%sFATAL *** ERROR *** can not find %s", Prefix, ConfigFile);
 | |
| 		LogToFile(logFile, "FATAL *** ERROR *** can not find %s", ConfigFile);
 | |
| 		SetFailState(Error);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| stock void ResetSettings()
 | |
| {
 | |
| 	CommandDisable = 0;
 | |
| 
 | |
| 	ResetMenu();
 | |
| 	ReadConfig();
 | |
| }
 | |
| 
 | |
| stock void ParseBackupConfig_Overrides()
 | |
| {
 | |
| 	Handle hKV = CreateKeyValues("SB_Overrides");
 | |
| 
 | |
| 	if (!FileToKeyValues(hKV, overridesLoc))
 | |
| 		return;
 | |
| 
 | |
| 	if (!KvGotoFirstSubKey(hKV))
 | |
| 		return;
 | |
| 
 | |
| 	char sSection[16], sFlags[32], sName[64];
 | |
| 	OverrideType type;
 | |
| 
 | |
| 	do
 | |
| 	{
 | |
| 		KvGetSectionName(hKV, sSection, sizeof(sSection));
 | |
| 		if (StrEqual(sSection, "override_commands"))
 | |
| 			type = Override_Command;
 | |
| 		else if (StrEqual(sSection, "override_groups"))
 | |
| 			type = Override_CommandGroup;
 | |
| 		else
 | |
| 			continue;
 | |
| 
 | |
| 		if (KvGotoFirstSubKey(hKV, false))
 | |
| 		{
 | |
| 			do
 | |
| 			{
 | |
| 				KvGetSectionName(hKV, sName, sizeof(sName));
 | |
| 				KvGetString(hKV, NULL_STRING, sFlags, sizeof(sFlags));
 | |
| 				AddCommandOverride(sName, type, ReadFlagString(sFlags));
 | |
| 				#if defined _DEBUG
 | |
| 				PrintToServer("Adding override (%s, %s, %s)", sSection, sName, sFlags);
 | |
| 				#endif
 | |
| 			} while (KvGotoNextKey(hKV, false));
 | |
| 			KvGoBack(hKV);
 | |
| 		}
 | |
| 	}
 | |
| 	while (KvGotoNextKey(hKV));
 | |
| 	CloseHandle(hKV);
 | |
| }
 | |
| 
 | |
| stock AdminFlag CreateFlagLetters()
 | |
| {
 | |
| 	AdminFlag FlagLetters[FLAG_LETTERS_SIZE];
 | |
| 
 | |
| 	FlagLetters['a'-'a'] = Admin_Reservation;
 | |
| 	FlagLetters['b'-'a'] = Admin_Generic;
 | |
| 	FlagLetters['c'-'a'] = Admin_Kick;
 | |
| 	FlagLetters['d'-'a'] = Admin_Ban;
 | |
| 	FlagLetters['e'-'a'] = Admin_Unban;
 | |
| 	FlagLetters['f'-'a'] = Admin_Slay;
 | |
| 	FlagLetters['g'-'a'] = Admin_Changemap;
 | |
| 	FlagLetters['h'-'a'] = Admin_Convars;
 | |
| 	FlagLetters['i'-'a'] = Admin_Config;
 | |
| 	FlagLetters['j'-'a'] = Admin_Chat;
 | |
| 	FlagLetters['k'-'a'] = Admin_Vote;
 | |
| 	FlagLetters['l'-'a'] = Admin_Password;
 | |
| 	FlagLetters['m'-'a'] = Admin_RCON;
 | |
| 	FlagLetters['n'-'a'] = Admin_Cheats;
 | |
| 	FlagLetters['o'-'a'] = Admin_Custom1;
 | |
| 	FlagLetters['p'-'a'] = Admin_Custom2;
 | |
| 	FlagLetters['q'-'a'] = Admin_Custom3;
 | |
| 	FlagLetters['r'-'a'] = Admin_Custom4;
 | |
| 	FlagLetters['s'-'a'] = Admin_Custom5;
 | |
| 	FlagLetters['t'-'a'] = Admin_Custom6;
 | |
| 	FlagLetters['z'-'a'] = Admin_Root;
 | |
| 
 | |
| 	return FlagLetters;
 | |
| }
 | |
| 
 | |
| stock AccountForLateLoading()
 | |
| {
 | |
| 	char auth[30];
 | |
| 
 | |
| 	for (new i = 1; i <= GetMaxClients(); i++)
 | |
| 	{
 | |
| 		if (IsClientConnected(i) && !IsFakeClient(i))
 | |
| 		{
 | |
| 			PlayerStatus[i] = false;
 | |
| 		}
 | |
| 		if (IsClientInGame(i) && !IsFakeClient(i) && IsClientAuthorized(i) && GetClientAuthId(i, AuthId_Steam2, auth, sizeof(auth)))
 | |
| 		{
 | |
| 			OnClientAuthorized(i, auth);
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| //Yarr!
 |