[SB++] Initialize with version 1.6.4

This commit is contained in:
zaCade 2023-01-27 16:21:44 +01:00
parent 50ac606c28
commit e385e661d4
19 changed files with 9963 additions and 0 deletions

View File

@ -0,0 +1,105 @@
/**
* sourcebans.cfg
*
* This file contains settings for the SourceBans Source Server Plugin
* @author SteamFriends Development Team
* @version 0.0.0.$Rev: 74 $
* @copyright SteamFriends (www.steamfriends.com)
* @package SourceBans
*/
"SourceBans"
{
"Config"
{
// Website address to tell where the player to go for unban, etc
"Website" "http://www.yourwebsite.net/"
// Allow or disallow admins access to addban command
"Addban" "1"
// Allow or disallow admins access to unban command
"Unban" "1"
// The Tableprefix you set while installing the webpanel. (default: "sb")
"DatabasePrefix" "sb"
// How many seconds to wait before retrying when a players ban fails to be checked. Min = 15.0 Max = 60.0
"RetryTime" "45.0"
// How often should we process the failed ban queue in minutes
"ProcessQueueTime" "5"
// Should the plugin automaticaly add the server to sourcebans
// (servers without -ip being set on startup need this set to 0)
"AutoAddServer" "0"
// Enable backing up config files after getting admins from database (1 = enabled, 0 = disabled)
"BackupConfigs" "1"
// Enable admin part of the plugin (1 = enabled, 0 = disabled)
"EnableAdmins" "1"
// Require the admin to login once into website
"RequireSiteLogin" "0"
// This is the ID of this server (Check in the admin panel -> servers to find the ID of this server)
"ServerID" "-1"
}
/*
* Generic menu options for if a reason isn't supplied in a ban
* Without a supplied reason the ban will never be written to the database
*/
"BanReasons"
{
"Hacking" "Hacking"
"Exploit" "General Exploit of Game/Map/Server"
"TK" "Team Killing"
"TF" "Team Flashing"
"CommSpam" "Spamming Mic/Chat"
"BadSpray" "Inappropriate Spray"
"BadLang" "Inappropriate Language"
"BadName" "Inappropriate Name"
"IgnoreAdmin" "Ignoring Admins"
"Stacking" "Team Stacking"
"Own Reason" "Own Reason"
}
/*
* Submenu options for when "Hacking" is selected
* If "Hacking" is removed from the menu above this will not be accessable
*/
"HackingReasons"
{
"Aimbot" "Aimbot"
"Antirecoil" "Anti Recoil"
"Wallhack" "Wallhack"
"Spinhack" "Spinhack"
"Speedhack" "Speedhack"
"Multi-Hack" "Multi-Hack"
"No Smoke" "No Smoke"
"No Flash" "No Flash"
}
/*
* Available time for bans.
* Permanent (0) available only for admins with access for command "sm_unban"
*/
"BanTime"
{
// "time in minutes" "display text"
"0" "Permanent"
"10" "10 Minutes"
"30" "30 Minutes"
"60" "1 Hour"
"240" "4 Hours"
"1440" "1 Day"
"10080" "1 Week"
// Examples:
// "43200" "1 Month"
// "525600" "1 Year"
}
}

View File

@ -0,0 +1,66 @@
/**
* sourcecomms.cfg
*
* This file contains settings for the SourceComms Plugin
*/
"SourceComms"
{
"Config"
{
"DefaultTime" "30" // default time in minutes. if < 0 -> blocking for session. Permanent (0) - is not allowed!
"DisableUnblockImmunityCheck" "0" // 0, 1. If 1, player can be ungagged only by issuer admin, console or admin with special flag
// Also, If 0 player maybe unblocked by Admin with higher immunity level then issuer admin.
// Default value is 0
"ConsoleImmunity" "20" // Immunity Level of server console. If not specified - 0.
"MaxLength" "0" // Max allowed punishment length (in minutes) for admins without ADMFLAG_CUSTOM2 (p).
// 0 disables restriction. Any value > 0 restricts permanent punishment.
"OnlyWhiteListServers" "0" // Set this option to 1 to applying on players punishments only from servers listed in WhiteList and this server.
// 0 applies on players punishments from any server.
}
"CommsReasons"
{
//Generic menu options for if a reason isn't supplied in a block
//-------------------------------------------------------------//
// "Reason to store in DB" "Reason to display in menu" //
//-------------------------------------------------------------//
"Obscene language" "Obscene language"
"Insult players" "Insult players"
"Admin disrespect" "Admin disrespect"
"Inappropriate Language" "Inappropriate Language"
"Spam in chat/voice" "Spam"
"Trading" "Trading"
"Other" "Other"
"Advertisement" "Advertisement"
"Played music in voice" "Music in voice"
}
"CommsTimes"
{
// Times to show in duration menu //
//-----------------------------------------------//
// "Time in minutes" "Time to display in menu" //
//-----------------------------------------------//
"-1" "Session" // If time < 0 -> blocking comms for player session
"30" "30 minutes"
"60" "60 minutes"
"120" "2 hours"
"360" "6 hours"
"720" "12 hours"
"1440" "24 hours"
"2880" "2 days"
"10080" "7 days"
"20160" "2 weeks"
"0" "Permanent"
}
"ServersWhiteList"
{
//-----------------------------------------//
// "id" "ServerID from sourcebans.cfg" //
//-----------------------------------------//
"id" "0" // Web Punishments (from sourcebans web pages)
// "id" "3" // for example: uncommenting this line will add server with ServerID 3 to white list.
}
}

View File

@ -0,0 +1 @@
//STEAM_1:0:8055392

View File

@ -0,0 +1,106 @@
// *************************************************************************
// 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 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>
//
// *************************************************************************
#if defined _sourcebanspp_included
#endinput
#endif
#define _sourcebanspp_included
public SharedPlugin __pl_sourcebanspp =
{
name = "sourcebans++",
file = "sbpp_main.smx",
#if defined REQUIRE_PLUGIN
required = 1
#else
required = 0
#endif
};
#if !defined REQUIRE_PLUGIN
public __pl_sourcebanspp_SetNTVOptional()
{
MarkNativeAsOptional("SBBanPlayer");
MarkNativeAsOptional("SBPP_BanPlayer");
MarkNativeAsOptional("SBPP_ReportPlayer");
}
#endif
/*********************************************************
* Ban Player from server
*
* @param iAdmin The client index of the admin who is banning the client
* @param iTarget The client index of the player to ban
* @param iTime The time to ban the player for (in minutes, 0 = permanent)
* @param sReason The reason to ban the player from the server
* @noreturn
*********************************************************/
#pragma deprecated Use SBPP_BanPlayer() instead.
native void SBBanPlayer(int iAdmin, int iTarget, int iTime, const char[] sReason);
/*********************************************************
* Ban Player from server
*
* @param iAdmin The client index of the admin who is banning the client
* @param iTarget The client index of the player to ban
* @param iTime The time to ban the player for (in minutes, 0 = permanent)
* @param sReason The reason to ban the player from the server
* @noreturn
*********************************************************/
native void SBPP_BanPlayer(int iAdmin, int iTarget, int iTime, const char[] sReason);
/*********************************************************
* Reports a player
*
* @param iReporter The client index of the reporter
* @param iTarget The client index of the player to report
* @param sReason The reason to report the player
* @noreturn
*********************************************************/
native void SBPP_ReportPlayer(int iReporter, int iTarget, const char[] sReason);
/*********************************************************
* Called when the admin banning the player.
*
* @param iAdmin The client index of the admin who is banning the client
* @param iTarget The client index of the player to ban
* @param iTime The time to ban the player for (in minutes, 0 = permanent)
* @param sReason The reason to ban the player from the server
*********************************************************/
forward void SBPP_OnBanPlayer(int iAdmin, int iTarget, int iTime, const char[] sReason);
/*********************************************************
* Called when a new report is inserted
*
* @param iReporter The client index of the reporter
* @param iTarget The client index of the player to report
* @param sReason The reason to report the player
* @noreturn
*********************************************************/
forward void SBPP_OnReportPlayer(int iReporter, int iTarget, const char[] sReason);
//Yarr!

View File

@ -0,0 +1,128 @@
// *************************************************************************
// 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 based off work(s) covered by the following copyright(s):
//
// SourceComms 0.9.266
// Copyright (C) 2013-2014 Alexandr Duplishchev
// Licensed under GNU GPL version 3, or later.
// Page: <https://forums.alliedmods.net/showthread.php?p=1883705> - <https://github.com/d-ai/SourceComms>
//
// *************************************************************************
#if defined _sourcecomms_included
#endinput
#endif
#define _sourcecomms_included
/**
* @section Int definitions for punishments types.
*/
#define TYPE_MUTE 1 /**< Voice Mute */
#define TYPE_GAG 2 /**< Gag (text chat) */
#define TYPE_SILENCE 3 /**< Silence (mute + gag) */
#define TYPE_UNMUTE 4 /**< Voice Unmute*/
#define TYPE_UNGAG 5 /**< Ungag*/
#define TYPE_UNSILENCE 6 /**< Unsilence */
#define TYPE_TEMP_UNMUTE 14 /**< Temp mute removed */
#define TYPE_TEMP_UNGAG 15 /**< Temp gag removed */
#define TYPE_TEMP_UNSILENCE 16 /**< Temp silence removed */
/* Punishments types */
enum bType {
bNot = 0, // Player chat or voice is not blocked
bSess, // ... blocked for player session (until reconnect)
bTime, // ... blocked for some time
bPerm // ... permanently blocked
}
/**
* Sets a client's mute state.
*
* @param client Client index.
* @param muteState True to mute client, false to unmute.
* -------------------------------------Parameters below this line are used only for muteState=true-------------------------------------
* ----------------------------------for muteState=false these parameters are ignored (saveToDB=false)----------------------------------
* @param muteLength Length of punishment in minutes. Value < 0 muting client for session. Permanent (0) is not allowed at this time.
* @param saveToDB If true, punishment will be saved in database.
* @param reason Reason for punishment.
* @return True if this caused a change in mute state, false otherwise.
*/
native bool:SourceComms_SetClientMute(client, bool:muteState, muteLength = -1, bool:saveToDB = false, const String:reason[] = "Muted through natives");
/**
* Sets a client's gag state.
*
* @param client Client index.
* @param gagState True to gag client, false to ungag.
* --------------------------------------Parameters below this line are used only for gagState=true--------------------------------------
* -----------------------------------for gagState=false these parameters are ignored (saveToDB=false)-----------------------------------
* @param gagLength Length of punishment in minutes. Value < 0 gagging client for session. Permanent (0) is not allowed at this time.
* @param saveToDB If true, punishment will be saved in database.
* @param reason Reason for punishment.
* @return True if this caused a change in gag state, false otherwise.
*/
native bool:SourceComms_SetClientGag(client, bool:gagState, gagLength = -1, bool:saveToDB = false, const String:reason[] = "Gagged through natives");
/**
* Returns the client's mute type
*
* @param client The client index of the player to check mute status
* @return The client's current mute type index (see enum bType in the begin).
*/
native bType:SourceComms_GetClientMuteType(client);
/**
* Returns the client's gag type
*
* @param client The client index of the player to check gag status
* @return The client's current gag type index (see enum bType in the begin).
*/
native bType:SourceComms_GetClientGagType(client);
/**
* Called when added communication block for player.
*
* @param client The client index of the admin who is blocking the client.
* @param target The client index of the player to blocked.
* @param time The time to blocked the player for (in minutes, 0 = permanent).
* @param type The type of block. See section "Int definitions for punishments types".
* @param reason The reason to block the player.
*/
forward SourceComms_OnBlockAdded(client, target, time, type, String:reason[]);
public SharedPlugin:__pl_sourcecomms =
{
name = "sourcecomms++",
file = "sbpp_comms.smx",
#if defined REQUIRE_PLUGIN
required = 1
#else
required = 0
#endif
};
public __pl_sourcecomms_SetNTVOptional()
{
MarkNativeAsOptional("SourceComms_SetClientMute");
MarkNativeAsOptional("SourceComms_SetClientGag");
MarkNativeAsOptional("SourceComms_GetClientMuteType");
MarkNativeAsOptional("SourceComms_GetClientGagType");
}

View File

@ -0,0 +1,107 @@
// *************************************************************************
// 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):
//
// SourceMod Admin File Reader Plugin
// Copyright (C) 2004-2008 AlliedModders LLC
// Licensed under GNU GPL version 3
// Page: <http://www.sourcemod.net/>
//
// *************************************************************************
#pragma semicolon 1
#include <sourcemod>
#if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 7
public Plugin:myinfo =
#else
public Plugin myinfo =
#endif
{
name = "SourceBans++: Admin Config Loader",
author = "AlliedModders LLC, SourceBans++ Dev Team",
description = "Reads Admin Files",
version = "1.6.4",
url = "https://sbpp.github.io"
};
/** Various parsing globals */
#if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 7
new bool:g_LoggedFileName = false; /* Whether or not the file name has been logged */
new g_ErrorCount = 0; /* Current error count */
new g_IgnoreLevel = 0; /* Nested ignored section count, so users can screw up files safely */
new g_CurrentLine = 0; /* Current line we're on */
new String:g_Filename[PLATFORM_MAX_PATH]; /* Used for error messages */
#else
bool g_LoggedFileName = false; /* Whether or not the file name has been logged */
int g_ErrorCount = 0; /* Current error count */
int g_IgnoreLevel = 0; /* Nested ignored section count, so users can screw up files safely */
int g_CurrentLine = 0; /* Current line we're on */
char g_Filename[PLATFORM_MAX_PATH]; /* Used for error messages */
#endif
#include "sbpp_admcfg/sbpp_admin_groups.sp"
#include "sbpp_admcfg/sbpp_admin_users.sp"
#if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 7
public OnRebuildAdminCache(AdminCachePart:part)
#else
public void OnRebuildAdminCache(AdminCachePart part)
#endif
{
if (part == AdminCache_Groups) {
ReadGroups();
} else if (part == AdminCache_Admins) {
ReadUsers();
}
}
#if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 7
ParseError(const String:format[], any:...)
#else
void ParseError(const char[] format, any...)
#endif
{
#if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 7
decl String:buffer[512];
#else
char buffer[512];
#endif
if (!g_LoggedFileName)
{
LogError("Error(s) Detected Parsing %s", g_Filename);
g_LoggedFileName = true;
}
VFormat(buffer, sizeof(buffer), format, 2);
LogError(" (line %d) %s", g_CurrentLine, buffer);
g_ErrorCount++;
}
void InitGlobalStates()
{
g_ErrorCount = 0;
g_IgnoreLevel = 0;
g_CurrentLine = 0;
g_LoggedFileName = false;
}

View File

@ -0,0 +1,454 @@
// *************************************************************************
// 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 based off work(s) covered by the following copyright(s):
//
// SourceMod Admin File Reader Plugin
// Copyright (C) 2004-2008 AlliedModders LLC
// Licensed under GNU GPL version 3
// Page: <http://www.sourcemod.net/>
//
// *************************************************************************
#if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 7
#define GROUP_STATE_NONE 0
#define GROUP_STATE_GROUPS 1
#define GROUP_STATE_INGROUP 2
#define GROUP_STATE_OVERRIDES 3
#define GROUP_PASS_FIRST 1
#define GROUP_PASS_SECOND 2
static SMCParser g_hGroupParser;
static GroupId:g_CurGrp = INVALID_GROUP_ID;
static g_GroupState = GROUP_STATE_NONE;
static g_GroupPass = 0;
static bool:g_NeedReparse = false;
public SMCResult ReadGroups_NewSection(SMCParser smc, const char[] name, bool opt_quotes)
{
if (g_IgnoreLevel)
{
g_IgnoreLevel++;
return SMCParse_Continue;
}
if (g_GroupState == GROUP_STATE_NONE)
{
if (StrEqual(name, "Groups", false))
{
g_GroupState = GROUP_STATE_GROUPS;
} else {
g_IgnoreLevel++;
}
} else if (g_GroupState == GROUP_STATE_GROUPS) {
if ((g_CurGrp = CreateAdmGroup(name)) == INVALID_GROUP_ID)
{
g_CurGrp = FindAdmGroup(name);
}
g_GroupState = GROUP_STATE_INGROUP;
} else if (g_GroupState == GROUP_STATE_INGROUP) {
if (StrEqual(name, "Overrides", false))
{
g_GroupState = GROUP_STATE_OVERRIDES;
} else {
g_IgnoreLevel++;
}
} else {
g_IgnoreLevel++;
}
return SMCParse_Continue;
}
public SMCResult ReadGroups_KeyValue(SMCParser smc,
const char[] key,
const char[] value,
bool key_quotes,
bool value_quotes)
{
if (g_CurGrp == INVALID_GROUP_ID || g_IgnoreLevel)
{
return SMCParse_Continue;
}
new AdminFlag:flag;
if (g_GroupPass == GROUP_PASS_FIRST)
{
if (g_GroupState == GROUP_STATE_INGROUP)
{
if (StrEqual(key, "flags", false))
{
new len = strlen(value);
for (new i = 0; i < len; i++)
{
if (!FindFlagByChar(value[i], flag))
{
continue;
}
SetAdmGroupAddFlag(g_CurGrp, flag, true);
}
} else if (StrEqual(key, "immunity", false)) {
g_NeedReparse = true;
}
} else if (g_GroupState == GROUP_STATE_OVERRIDES) {
new OverrideRule:rule = Command_Deny;
if (StrEqual(value, "allow", false))
{
rule = Command_Allow;
}
if (key[0] == '@')
{
AddAdmGroupCmdOverride(g_CurGrp, key[1], Override_CommandGroup, rule);
} else {
AddAdmGroupCmdOverride(g_CurGrp, key, Override_Command, rule);
}
}
} else if (g_GroupPass == GROUP_PASS_SECOND
&& g_GroupState == GROUP_STATE_INGROUP) {
/* Check for immunity again, core should handle double inserts */
if (StrEqual(key, "immunity", false))
{
/* If it's a value we know about, use it */
if (StrEqual(value, "*"))
{
SetAdmGroupImmunityLevel(g_CurGrp, 2);
} else if (StrEqual(value, "$")) {
SetAdmGroupImmunityLevel(g_CurGrp, 1);
} else {
new level;
if (StringToIntEx(value, level))
{
SetAdmGroupImmunityLevel(g_CurGrp, level);
} else {
new GroupId:id;
if (value[0] == '@')
{
id = FindAdmGroup(value[1]);
} else {
id = FindAdmGroup(value);
}
if (id != INVALID_GROUP_ID)
{
SetAdmGroupImmuneFrom(g_CurGrp, id);
} else {
ParseError("Unable to find group: \"%s\"", value);
}
}
}
}
}
return SMCParse_Continue;
}
public SMCResult ReadGroups_EndSection(SMCParser smc)
{
/* If we're ignoring, skip out */
if (g_IgnoreLevel)
{
g_IgnoreLevel--;
return SMCParse_Continue;
}
if (g_GroupState == GROUP_STATE_OVERRIDES)
{
g_GroupState = GROUP_STATE_INGROUP;
} else if (g_GroupState == GROUP_STATE_INGROUP) {
g_GroupState = GROUP_STATE_GROUPS;
g_CurGrp = INVALID_GROUP_ID;
} else if (g_GroupState == GROUP_STATE_GROUPS) {
g_GroupState = GROUP_STATE_NONE;
}
return SMCParse_Continue;
}
public SMCResult ReadGroups_CurrentLine(SMCParser smc, const char[] line, int lineno)
{
g_CurrentLine = lineno;
return SMCParse_Continue;
}
static InitializeGroupParser()
{
if (!g_hGroupParser)
{
g_hGroupParser = new SMCParser();
g_hGroupParser.OnEnterSection = ReadGroups_NewSection;
g_hGroupParser.OnKeyValue = ReadGroups_KeyValue;
g_hGroupParser.OnLeaveSection = ReadGroups_EndSection;
g_hGroupParser.OnRawLine = ReadGroups_CurrentLine;
}
}
static InternalReadGroups(const String:path[], pass)
{
/* Set states */
InitGlobalStates();
g_GroupState = GROUP_STATE_NONE;
g_CurGrp = INVALID_GROUP_ID;
g_GroupPass = pass;
g_NeedReparse = false;
SMCError err = g_hGroupParser.ParseFile(path);
if (err != SMCError_Okay)
{
char buffer[64];
if (g_hGroupParser.GetErrorString(err, buffer, sizeof(buffer)))
{
ParseError("%s", buffer);
} else {
ParseError("Fatal parse error");
}
}
}
ReadGroups()
{
InitializeGroupParser();
BuildPath(Path_SM, g_Filename, sizeof(g_Filename), "configs/sourcebans/sb_admin_groups.cfg");
InternalReadGroups(g_Filename, GROUP_PASS_FIRST);
if (g_NeedReparse)
{
InternalReadGroups(g_Filename, GROUP_PASS_SECOND);
}
}
/* SOURCEMOD 1.7 PLUGIN STOPS HERE */
#else
enum GroupState
{
GroupState_None,
GroupState_Groups,
GroupState_InGroup,
GroupState_Overrides,
}
enum GroupPass
{
GroupPass_Invalid,
GroupPass_First,
GroupPass_Second,
}
static SMCParser g_hGroupParser;
static GroupId g_CurGrp = INVALID_GROUP_ID;
static GroupState g_GroupState = GroupState_None;
static GroupPass g_GroupPass = GroupPass_Invalid;
static bool g_NeedReparse = false;
public SMCResult ReadGroups_NewSection(SMCParser smc, const char[] name, bool opt_quotes)
{
if (g_IgnoreLevel)
{
g_IgnoreLevel++;
return SMCParse_Continue;
}
if (g_GroupState == GroupState_None)
{
if (StrEqual(name, "Groups", false))
{
g_GroupState = GroupState_Groups;
} else {
g_IgnoreLevel++;
}
} else if (g_GroupState == GroupState_Groups) {
if ((g_CurGrp = CreateAdmGroup(name)) == INVALID_GROUP_ID)
{
g_CurGrp = FindAdmGroup(name);
}
g_GroupState = GroupState_InGroup;
} else if (g_GroupState == GroupState_InGroup) {
if (StrEqual(name, "Overrides", false))
{
g_GroupState = GroupState_Overrides;
} else {
g_IgnoreLevel++;
}
} else {
g_IgnoreLevel++;
}
return SMCParse_Continue;
}
public SMCResult ReadGroups_KeyValue(SMCParser smc,
const char[] key,
const char[] value,
bool key_quotes,
bool value_quotes)
{
if (g_CurGrp == INVALID_GROUP_ID || g_IgnoreLevel)
{
return SMCParse_Continue;
}
AdminFlag flag;
if (g_GroupPass == GroupPass_First)
{
if (g_GroupState == GroupState_InGroup)
{
if (StrEqual(key, "flags", false))
{
int len = strlen(value);
for (int i = 0; i < len; i++)
{
if (!FindFlagByChar(value[i], flag))
{
continue;
}
g_CurGrp.SetFlag(flag, true);
}
} else if (StrEqual(key, "immunity", false)) {
g_NeedReparse = true;
}
} else if (g_GroupState == GroupState_Overrides) {
OverrideRule rule = Command_Deny;
if (StrEqual(value, "allow", false))
{
rule = Command_Allow;
}
if (key[0] == '@')
{
g_CurGrp.AddCommandOverride(key[1], Override_CommandGroup, rule);
} else {
g_CurGrp.AddCommandOverride(key, Override_Command, rule);
}
}
} else if (g_GroupPass == GroupPass_Second
&& g_GroupState == GroupState_InGroup) {
/* Check for immunity again, core should handle double inserts */
if (StrEqual(key, "immunity", false))
{
/* If it's a value we know about, use it */
if (StrEqual(value, "*"))
{
g_CurGrp.ImmunityLevel = 2;
} else if (StrEqual(value, "$")) {
g_CurGrp.ImmunityLevel = 1;
} else {
int level;
if (StringToIntEx(value, level))
{
g_CurGrp.ImmunityLevel = level;
} else {
GroupId id;
if (value[0] == '@')
{
id = FindAdmGroup(value[1]);
} else {
id = FindAdmGroup(value);
}
if (id != INVALID_GROUP_ID)
{
g_CurGrp.AddGroupImmunity(id);
} else {
ParseError("Unable to find group: \"%s\"", value);
}
}
}
}
}
return SMCParse_Continue;
}
public SMCResult ReadGroups_EndSection(SMCParser smc)
{
/* If we're ignoring, skip out */
if (g_IgnoreLevel)
{
g_IgnoreLevel--;
return SMCParse_Continue;
}
if (g_GroupState == GroupState_Overrides)
{
g_GroupState = GroupState_InGroup;
} else if (g_GroupState == GroupState_InGroup) {
g_GroupState = GroupState_Groups;
g_CurGrp = INVALID_GROUP_ID;
} else if (g_GroupState == GroupState_Groups) {
g_GroupState = GroupState_None;
}
return SMCParse_Continue;
}
public SMCResult ReadGroups_CurrentLine(SMCParser smc, const char[] line, int lineno)
{
g_CurrentLine = lineno;
return SMCParse_Continue;
}
static void InitializeGroupParser()
{
if (!g_hGroupParser)
{
g_hGroupParser = new SMCParser();
g_hGroupParser.OnEnterSection = ReadGroups_NewSection;
g_hGroupParser.OnKeyValue = ReadGroups_KeyValue;
g_hGroupParser.OnLeaveSection = ReadGroups_EndSection;
g_hGroupParser.OnRawLine = ReadGroups_CurrentLine;
}
}
static void InternalReadGroups(const char[] path, GroupPass pass)
{
/* Set states */
InitGlobalStates();
g_GroupState = GroupState_None;
g_CurGrp = INVALID_GROUP_ID;
g_GroupPass = pass;
g_NeedReparse = false;
SMCError err = g_hGroupParser.ParseFile(path);
if (err != SMCError_Okay)
{
char buffer[64];
if (g_hGroupParser.GetErrorString(err, buffer, sizeof(buffer)))
{
ParseError("%s", buffer);
} else {
ParseError("Fatal parse error");
}
}
}
void ReadGroups()
{
InitializeGroupParser();
BuildPath(Path_SM, g_Filename, sizeof(g_Filename), "configs/sourcebans/sb_admin_groups.cfg");
InternalReadGroups(g_Filename, GroupPass_First);
if (g_NeedReparse)
{
InternalReadGroups(g_Filename, GroupPass_Second);
}
}
#endif

View File

@ -0,0 +1,464 @@
// *************************************************************************
// 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):
//
// SourceMod Admin File Reader Plugin
// Copyright (C) 2004-2008 AlliedModders LLC
// Licensed under GNU GPL version 3
// Page: <http://www.sourcemod.net/>
//
// *************************************************************************
#if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 7
#define USER_STATE_NONE 0
#define USER_STATE_ADMINS 1
#define USER_STATE_INADMIN 2
static SMCParser g_hUserParser;
static g_UserState = USER_STATE_NONE;
static String:g_CurAuth[64];
static String:g_CurIdent[64];
static String:g_CurName[64];
static String:g_CurPass[64];
static Handle:g_GroupArray;
static g_CurFlags;
static g_CurImmunity;
public SMCResult:ReadUsers_NewSection(Handle:smc, const String:name[], bool:opt_quotes)
{
if (g_IgnoreLevel)
{
g_IgnoreLevel++;
return SMCParse_Continue;
}
if (g_UserState == USER_STATE_NONE)
{
if (StrEqual(name, "Admins", false))
{
g_UserState = USER_STATE_ADMINS;
}
else
{
g_IgnoreLevel++;
}
}
else if (g_UserState == USER_STATE_ADMINS)
{
g_UserState = USER_STATE_INADMIN;
strcopy(g_CurName, sizeof(g_CurName), name);
g_CurAuth[0] = '\0';
g_CurIdent[0] = '\0';
g_CurPass[0] = '\0';
ClearArray(g_GroupArray);
g_CurFlags = 0;
g_CurImmunity = 0;
}
else
{
g_IgnoreLevel++;
}
return SMCParse_Continue;
}
public SMCResult:ReadUsers_KeyValue(Handle:smc,
const String:key[],
const String:value[],
bool:key_quotes,
bool:value_quotes)
{
if (g_UserState != USER_STATE_INADMIN || g_IgnoreLevel)
{
return SMCParse_Continue;
}
if (StrEqual(key, "auth", false))
{
strcopy(g_CurAuth, sizeof(g_CurAuth), value);
}
else if (StrEqual(key, "identity", false))
{
strcopy(g_CurIdent, sizeof(g_CurIdent), value);
}
else if (StrEqual(key, "password", false))
{
strcopy(g_CurPass, sizeof(g_CurPass), value);
}
else if (StrEqual(key, "group", false))
{
new GroupId:id = FindAdmGroup(value);
if (id == INVALID_GROUP_ID)
{
ParseError("Unknown group \"%s\"", value);
}
PushArrayCell(g_GroupArray, id);
}
else if (StrEqual(key, "flags", false))
{
new len = strlen(value);
new AdminFlag:flag;
for (new i = 0; i < len; i++)
{
if (!FindFlagByChar(value[i], flag))
{
ParseError("Invalid flag detected: %c", value[i]);
}
else
{
g_CurFlags |= FlagToBit(flag);
}
}
}
else if (StrEqual(key, "immunity", false))
{
g_CurImmunity = StringToInt(value);
}
return SMCParse_Continue;
}
public SMCResult:ReadUsers_EndSection(Handle:smc)
{
if (g_IgnoreLevel)
{
g_IgnoreLevel--;
return SMCParse_Continue;
}
if (g_UserState == USER_STATE_INADMIN)
{
/* Dump this user to memory */
if (g_CurIdent[0] != '\0' && g_CurAuth[0] != '\0')
{
decl AdminFlag:flags[26];
new AdminId:id, i, num_groups, num_flags;
if ((id = FindAdminByIdentity(g_CurAuth, g_CurIdent)) == INVALID_ADMIN_ID)
{
id = CreateAdmin(g_CurName);
if (!BindAdminIdentity(id, g_CurAuth, g_CurIdent))
{
RemoveAdmin(id);
ParseError("Failed to bind auth \"%s\" to identity \"%s\"", g_CurAuth, g_CurIdent);
return SMCParse_Continue;
}
}
num_groups = GetArraySize(g_GroupArray);
for (i = 0; i < num_groups; i++)
{
AdminInheritGroup(id, GetArrayCell(g_GroupArray, i));
}
SetAdminPassword(id, g_CurPass);
if (GetAdminImmunityLevel(id) < g_CurImmunity)
{
SetAdminImmunityLevel(id, g_CurImmunity);
}
num_flags = FlagBitsToArray(g_CurFlags, flags, sizeof(flags));
for (i = 0; i < num_flags; i++)
{
SetAdminFlag(id, flags[i], true);
}
}
else
{
ParseError("Failed to create admin: did you forget either the auth or identity properties?");
}
g_UserState = USER_STATE_ADMINS;
}
else if (g_UserState == USER_STATE_ADMINS)
{
g_UserState = USER_STATE_NONE;
}
return SMCParse_Continue;
}
public SMCResult:ReadUsers_CurrentLine(Handle:smc, const String:line[], lineno)
{
g_CurrentLine = lineno;
return SMCParse_Continue;
}
static InitializeUserParser()
{
if (!g_hUserParser)
{
g_hUserParser = new SMCParser();
g_hUserParser.OnEnterSection = ReadUsers_NewSection;
g_hUserParser.OnKeyValue = ReadUsers_KeyValue;
g_hUserParser.OnLeaveSection = ReadUsers_EndSection;
g_hUserParser.OnRawLine = ReadUsers_CurrentLine;
g_GroupArray = CreateArray();
}
}
ReadUsers()
{
InitializeUserParser();
BuildPath(Path_SM, g_Filename, sizeof(g_Filename), "configs/sourcebans/sb_admins.cfg");
/* Set states */
InitGlobalStates();
g_UserState = USER_STATE_NONE;
SMCError err = g_hUserParser.ParseFile(g_Filename);
if (err != SMCError_Okay)
{
char buffer[64];
if (g_hUserParser.GetErrorString(err, buffer, sizeof(buffer)))
{
ParseError("%s", buffer);
}
else
{
ParseError("Fatal parse error");
}
}
}
/* SOURCEMOD 1.7 PLUGIN STOPS HERE */
#else
enum UserState
{
UserState_None,
UserState_Admins,
UserState_InAdmin,
}
static SMCParser g_hUserParser;
static UserState g_UserState = UserState_None;
static char g_CurAuth[64];
static char g_CurIdent[64];
static char g_CurName[64];
static char g_CurPass[64];
static ArrayList g_GroupArray;
static int g_CurFlags;
static int g_CurImmunity;
public SMCResult ReadUsers_NewSection(SMCParser smc, const char[] name, bool opt_quotes)
{
if (g_IgnoreLevel)
{
g_IgnoreLevel++;
return SMCParse_Continue;
}
if (g_UserState == UserState_None)
{
if (StrEqual(name, "Admins", false))
{
g_UserState = UserState_Admins;
}
else
{
g_IgnoreLevel++;
}
}
else if (g_UserState == UserState_Admins)
{
g_UserState = UserState_InAdmin;
strcopy(g_CurName, sizeof(g_CurName), name);
g_CurAuth[0] = '\0';
g_CurIdent[0] = '\0';
g_CurPass[0] = '\0';
g_GroupArray.Clear();
g_CurFlags = 0;
g_CurImmunity = 0;
}
else
{
g_IgnoreLevel++;
}
return SMCParse_Continue;
}
public SMCResult ReadUsers_KeyValue(SMCParser smc,
const char[] key,
const char[] value,
bool key_quotes,
bool value_quotes)
{
if (g_UserState != UserState_InAdmin || g_IgnoreLevel)
{
return SMCParse_Continue;
}
if (StrEqual(key, "auth", false))
{
strcopy(g_CurAuth, sizeof(g_CurAuth), value);
}
else if (StrEqual(key, "identity", false))
{
strcopy(g_CurIdent, sizeof(g_CurIdent), value);
}
else if (StrEqual(key, "password", false))
{
strcopy(g_CurPass, sizeof(g_CurPass), value);
}
else if (StrEqual(key, "group", false))
{
GroupId id = FindAdmGroup(value);
if (id == INVALID_GROUP_ID)
{
ParseError("Unknown group \"%s\"", value);
}
g_GroupArray.Push(id);
}
else if (StrEqual(key, "flags", false))
{
int len = strlen(value);
AdminFlag flag;
for (int i = 0; i < len; i++)
{
if (!FindFlagByChar(value[i], flag))
{
ParseError("Invalid flag detected: %c", value[i]);
}
else
{
g_CurFlags |= FlagToBit(flag);
}
}
}
else if (StrEqual(key, "immunity", false))
{
g_CurImmunity = StringToInt(value);
}
return SMCParse_Continue;
}
public SMCResult ReadUsers_EndSection(SMCParser smc)
{
if (g_IgnoreLevel)
{
g_IgnoreLevel--;
return SMCParse_Continue;
}
if (g_UserState == UserState_InAdmin)
{
/* Dump this user to memory */
if (g_CurIdent[0] != '\0' && g_CurAuth[0] != '\0')
{
AdminFlag flags[26];
AdminId id;
int i, num_groups, num_flags;
if ((id = FindAdminByIdentity(g_CurAuth, g_CurIdent)) == INVALID_ADMIN_ID)
{
id = CreateAdmin(g_CurName);
if (!BindAdminIdentity(id, g_CurAuth, g_CurIdent))
{
RemoveAdmin(id);
ParseError("Failed to bind auth \"%s\" to identity \"%s\"", g_CurAuth, g_CurIdent);
return SMCParse_Continue;
}
}
num_groups = g_GroupArray.Length;
for (i = 0; i < num_groups; i++)
{
AdminInheritGroup(id, g_GroupArray.Get(i));
}
SetAdminPassword(id, g_CurPass);
if (GetAdminImmunityLevel(id) < g_CurImmunity)
{
SetAdminImmunityLevel(id, g_CurImmunity);
}
num_flags = FlagBitsToArray(g_CurFlags, flags, sizeof(flags));
for (i = 0; i < num_flags; i++)
{
SetAdminFlag(id, flags[i], true);
}
}
else
{
ParseError("Failed to create admin: did you forget either the auth or identity properties?");
}
g_UserState = UserState_Admins;
}
else if (g_UserState == UserState_Admins)
{
g_UserState = UserState_None;
}
return SMCParse_Continue;
}
public SMCResult ReadUsers_CurrentLine(SMCParser smc, const char[] line, int lineno)
{
g_CurrentLine = lineno;
return SMCParse_Continue;
}
static void InitializeUserParser()
{
if (!g_hUserParser)
{
g_hUserParser = new SMCParser();
g_hUserParser.OnEnterSection = ReadUsers_NewSection;
g_hUserParser.OnKeyValue = ReadUsers_KeyValue;
g_hUserParser.OnLeaveSection = ReadUsers_EndSection;
g_hUserParser.OnRawLine = ReadUsers_CurrentLine;
g_GroupArray = CreateArray();
}
}
void ReadUsers()
{
InitializeUserParser();
BuildPath(Path_SM, g_Filename, sizeof(g_Filename), "configs/sourcebans/sb_admins.cfg");
/* Set states */
InitGlobalStates();
g_UserState = UserState_None;
SMCError err = g_hUserParser.ParseFile(g_Filename);
if (err != SMCError_Okay)
{
char buffer[64];
if (g_hUserParser.GetErrorString(err, buffer, sizeof(buffer)))
{
ParseError("%s", buffer);
}
else
{
ParseError("Fatal Parse Error");
}
}
}
#endif

View File

@ -0,0 +1,564 @@
// *************************************************************************
// 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 Checker 1.0.2
// Copyright (C) 2010-2013 Nicholas Hastings
// Licensed under GNU GPL version 3, or later.
// Page: <https://forums.alliedmods.net/showthread.php?p=1288490>
//
// *************************************************************************
#include <sourcemod>
#define VERSION "1.6.4"
#define LISTBANS_USAGE "sm_listbans <#userid|name> - Lists a user's prior bans from Sourcebans"
#define LISTCOMMS_USAGE "sm_listcomms <#userid|name> - Lists a user's prior comms from Sourcebans"
#define INVALID_TARGET -1
new String:g_DatabasePrefix[10] = "sb";
new Handle:g_ConfigParser;
new Handle:g_DB;
public Plugin:myinfo =
{
name = "SourceBans++: Bans Checker",
author = "psychonic, Ca$h Munny, SourceBans++ Dev Team",
description = "Notifies admins of prior bans from Sourcebans upon player connect.",
version = VERSION,
url = "https://sbpp.github.io"
};
public OnPluginStart()
{
LoadTranslations("common.phrases");
CreateConVar("sbchecker_version", VERSION, "", FCVAR_NOTIFY);
RegAdminCmd("sm_listbans", OnListSourceBansCmd, ADMFLAG_BAN, LISTBANS_USAGE);
RegAdminCmd("sm_listcomms", OnListSourceCommsCmd, ADMFLAG_BAN, LISTCOMMS_USAGE);
RegAdminCmd("sb_reload", OnReloadCmd, ADMFLAG_RCON, "Reload sourcebans config and ban reason menu options");
SQL_TConnect(OnDatabaseConnected, "sourcebans");
}
public OnMapStart()
{
ReadConfig();
}
public Action:OnReloadCmd(client, args)
{
ReadConfig();
return Plugin_Handled;
}
public OnDatabaseConnected(Handle:owner, Handle:hndl, const String:error[], any:data)
{
if (hndl == INVALID_HANDLE)
SetFailState("Failed to connect to SourceBans DB, %s", error);
g_DB = hndl;
}
public OnClientAuthorized(client, const String:auth[])
{
if (g_DB == INVALID_HANDLE)
return;
/* Do not check bots nor check player with lan steamid. */
if (auth[0] == 'B' || auth[9] == 'L')
return;
decl String:query[512], String:ip[30];
GetClientIP(client, ip, sizeof(ip));
FormatEx(query, sizeof(query), "SELECT COUNT(bid) FROM %s_bans WHERE ((type = 0 AND authid REGEXP '^STEAM_[0-9]:%s$') OR (type = 1 AND ip = '%s')) UNION SELECT COUNT(bid) FROM %s_comms WHERE authid REGEXP '^STEAM_[0-9]:%s$'", g_DatabasePrefix, auth[8], ip, g_DatabasePrefix,auth[8]);
SQL_TQuery(g_DB, OnConnectBanCheck, query, GetClientUserId(client), DBPrio_Low);
}
public OnConnectBanCheck(Handle:owner, Handle:hndl, const String:error[], any:userid)
{
new client = GetClientOfUserId(userid);
if (!client || hndl == INVALID_HANDLE || !SQL_FetchRow(hndl))
return;
new bancount = SQL_FetchInt(hndl, 0);
new commcount = 0;
if(SQL_FetchRow(hndl)){
commcount = SQL_FetchInt(hndl, 0);
}
if (bancount > 0 || commcount > 0)
{
if(bancount == 0){
PrintToBanAdmins("\x04[SourceBans++]\x01 Warning: Player \"%N\" has %d previous commban%s.",
client,commcount,((commcount > 1 || commcount == 0) ? "s":""));
}
else if(commcount == 0){
PrintToBanAdmins("\x04[SourceBans++]\x01 Warning: Player \"%N\" has %d previous ban%s.",
client, bancount, ((bancount > 1 || bancount == 0) ? "s":""));
}
else{
PrintToBanAdmins("\x04[SourceBans++]\x01 Warning: Player \"%N\" has %d previous ban%s and %d previous commban%s.",
client, bancount, ((bancount > 1 || bancount == 0) ? "s":""),commcount,((commcount > 1 || commcount == 0) ? "s":""));
}
}
}
public Action:OnListSourceBansCmd(client, args)
{
if (args < 1)
{
ReplyToCommand(client, LISTBANS_USAGE);
}
if (g_DB == INVALID_HANDLE)
{
ReplyToCommand(client, "Error: Database not ready.");
return Plugin_Handled;
}
decl String:targetarg[64];
GetCmdArg(1, targetarg, sizeof(targetarg));
new target = FindTarget(client, targetarg, true, true);
if (target == INVALID_TARGET)
{
ReplyToCommand(client, "Error: Could not find a target matching '%s'.", targetarg);
return Plugin_Handled;
}
decl String:auth[32];
if (!GetClientAuthId(target, AuthId_Steam2, auth, sizeof(auth))
|| auth[0] == 'B' || auth[9] == 'L')
{
ReplyToCommand(client, "Error: Could not retrieve %N's steam id.", target);
return Plugin_Handled;
}
decl String:query[1024], String:ip[30];
GetClientIP(target, ip, sizeof(ip));
FormatEx(query, sizeof(query), "SELECT created, %s_admins.user, ends, length, reason, RemoveType FROM %s_bans LEFT JOIN %s_admins ON %s_bans.aid = %s_admins.aid WHERE ((type = 0 AND %s_bans.authid REGEXP '^STEAM_[0-9]:%s$') OR (type = 1 AND ip = '%s')) AND ((length > '0' AND ends > UNIX_TIMESTAMP()) OR RemoveType IS NOT NULL)", g_DatabasePrefix, g_DatabasePrefix, g_DatabasePrefix, g_DatabasePrefix, g_DatabasePrefix, g_DatabasePrefix, auth[8], ip);
decl String:targetName[MAX_NAME_LENGTH];
GetClientName(target, targetName, sizeof(targetName));
new Handle:pack = CreateDataPack();
WritePackCell(pack, (client == 0) ? 0 : GetClientUserId(client));
WritePackString(pack, targetName);
SQL_TQuery(g_DB, OnListBans, query, pack, DBPrio_Low);
if (client == 0)
{
ReplyToCommand(client, "[SourceBans++] Note: if you are using this command through an rcon tool, you will not see results.");
}
else
{
ReplyToCommand(client, "\x04[SourceBans++]\x01 Look for %N's ban results in console.", target);
}
return Plugin_Handled;
}
public OnListBans(Handle:owner, Handle:hndl, const String:error[], any:pack)
{
ResetPack(pack);
new clientuid = ReadPackCell(pack);
new client = GetClientOfUserId(clientuid);
decl String:targetName[MAX_NAME_LENGTH];
ReadPackString(pack, targetName, sizeof(targetName));
CloseHandle(pack);
if (clientuid > 0 && client == 0)
return;
if (hndl == INVALID_HANDLE)
{
PrintListResponse(clientuid, client, "[SourceBans++] DB error while retrieving bans for %s:\n%s", targetName, error);
return;
}
if (SQL_GetRowCount(hndl) == 0)
{
PrintListResponse(clientuid, client, "[SourceBans++] No bans found for %s.", targetName);
return;
}
PrintListResponse(clientuid, client, "[SourceBans++] Listing bans for %s", targetName);
PrintListResponse(clientuid, client, "Ban Date Banned By Length End Date R Reason");
PrintListResponse(clientuid, client, "-------------------------------------------------------------------------------");
while (SQL_FetchRow(hndl))
{
new String:createddate[11] = "<Unknown> ";
new String:bannedby[11] = "<Unknown> ";
new String:lenstring[11] = "N/A ";
new String:enddate[11] = "N/A ";
new String:reason[28];
new String:RemoveType[2] = " ";
if (!SQL_IsFieldNull(hndl, 0))
{
FormatTime(createddate, sizeof(createddate), "%Y-%m-%d", SQL_FetchInt(hndl, 0));
}
if (!SQL_IsFieldNull(hndl, 1))
{
new size_bannedby = sizeof(bannedby);
SQL_FetchString(hndl, 1, bannedby, size_bannedby);
new len = SQL_FetchSize(hndl, 1);
if (len > size_bannedby - 1)
{
reason[size_bannedby - 4] = '.';
reason[size_bannedby - 3] = '.';
reason[size_bannedby - 2] = '.';
}
else
{
for (new i = len; i < size_bannedby - 1; i++)
{
bannedby[i] = ' ';
}
}
}
// NOT NULL
new size_lenstring = sizeof(lenstring);
new length = SQL_FetchInt(hndl, 3);
if (length == 0)
{
strcopy(lenstring, size_lenstring, "Permanent ");
}
else
{
new len = IntToString(length, lenstring, size_lenstring);
if (len < size_lenstring - 1)
{
// change the '\0' to a ' '. the original \0 at the end will still be there
lenstring[len] = ' ';
}
}
if (!SQL_IsFieldNull(hndl, 2))
{
FormatTime(enddate, sizeof(enddate), "%Y-%m-%d", SQL_FetchInt(hndl, 2));
}
// NOT NULL
new reason_size = sizeof(reason);
SQL_FetchString(hndl, 4, reason, reason_size);
new len = SQL_FetchSize(hndl, 4);
if (len > reason_size - 1)
{
reason[reason_size - 4] = '.';
reason[reason_size - 3] = '.';
reason[reason_size - 2] = '.';
}
else
{
for (new i = len; i < reason_size - 1; i++)
{
reason[i] = ' ';
}
}
if (!SQL_IsFieldNull(hndl, 5))
{
SQL_FetchString(hndl, 5, RemoveType, sizeof(RemoveType));
}
PrintListResponse(clientuid, client, "%s %s %s %s %s %s", createddate, bannedby, lenstring, enddate, RemoveType, reason);
}
}
public Action:OnListSourceCommsCmd(client, args)
{
if (args < 1)
{
ReplyToCommand(client, LISTCOMMS_USAGE);
}
if (g_DB == INVALID_HANDLE)
{
ReplyToCommand(client, "Error: Database not ready.");
return Plugin_Handled;
}
decl String:targetarg[64];
GetCmdArg(1, targetarg, sizeof(targetarg));
new target = FindTarget(client, targetarg, true, true);
if (target == INVALID_TARGET)
{
ReplyToCommand(client, "Error: Could not find a target matching '%s'.", targetarg);
return Plugin_Handled;
}
decl String:auth[32];
if (!GetClientAuthId(target, AuthId_Steam2, auth, sizeof(auth))
|| auth[0] == 'B' || auth[9] == 'L')
{
ReplyToCommand(client, "Error: Could not retrieve %N's steam id.", target);
return Plugin_Handled;
}
decl String:query[1024];
FormatEx(query, sizeof(query), "SELECT created, %s_admins.user, ends, length, reason, RemoveType, type FROM %s_comms LEFT JOIN %s_admins ON %s_comms.aid = %s_admins.aid WHERE %s_comms.authid REGEXP '^STEAM_[0-9]:%s$' AND ((length > '0' AND ends > UNIX_TIMESTAMP()) OR RemoveType IS NOT NULL)", g_DatabasePrefix, g_DatabasePrefix, g_DatabasePrefix, g_DatabasePrefix, g_DatabasePrefix, g_DatabasePrefix, auth[8]);
decl String:targetName[MAX_NAME_LENGTH];
GetClientName(target, targetName, sizeof(targetName));
new Handle:pack = CreateDataPack();
WritePackCell(pack, (client == 0) ? 0 : GetClientUserId(client));
WritePackString(pack, targetName);
SQL_TQuery(g_DB, OnListComms, query, pack, DBPrio_Low);
if (client == 0)
{
ReplyToCommand(client, "[SourceBans++] Note: if you are using this command through an rcon tool, you will not see results.");
}
else
{
ReplyToCommand(client, "\x04[SourceBans++]\x01 Look for %N's comm results in console.", target);
}
return Plugin_Handled;
}
public OnListComms(Handle:owner, Handle:hndl, const String:error[], any:pack)
{
ResetPack(pack);
new clientuid = ReadPackCell(pack);
new client = GetClientOfUserId(clientuid);
decl String:targetName[MAX_NAME_LENGTH];
ReadPackString(pack, targetName, sizeof(targetName));
CloseHandle(pack);
if (clientuid > 0 && client == 0)
return;
if (hndl == INVALID_HANDLE)
{
PrintListResponse(clientuid, client, "[SourceBans++] DB error while retrieving comms for %s:\n%s", targetName, error);
return;
}
if (SQL_GetRowCount(hndl) == 0)
{
PrintListResponse(clientuid, client, "[SourceBans++] No comms found for %s.", targetName);
return;
}
PrintListResponse(clientuid, client, "[SourceBans++] Listing comms for %s", targetName);
PrintListResponse(clientuid, client, "Ban Date Banned By Length End Date T R Reason");
PrintListResponse(clientuid, client, "-------------------------------------------------------------------------------");
while (SQL_FetchRow(hndl))
{
new String:createddate[11] = "<Unknown> ";
new String:bannedby[11] = "<Unknown> ";
new String:lenstring[11] = "N/A ";
new String:enddate[11] = "N/A ";
new String:reason[23];
new String:CommType[2] = " ";
new String:RemoveType[2] = " ";
if (!SQL_IsFieldNull(hndl, 0))
{
FormatTime(createddate, sizeof(createddate), "%Y-%m-%d", SQL_FetchInt(hndl, 0));
}
if (!SQL_IsFieldNull(hndl, 1))
{
new size_bannedby = sizeof(bannedby);
SQL_FetchString(hndl, 1, bannedby, size_bannedby);
new len = SQL_FetchSize(hndl, 1);
if (len > size_bannedby - 1)
{
reason[size_bannedby - 4] = '.';
reason[size_bannedby - 3] = '.';
reason[size_bannedby - 2] = '.';
}
else
{
for (new i = len; i < size_bannedby - 1; i++)
{
bannedby[i] = ' ';
}
}
}
// NOT NULL
new size_lenstring = sizeof(lenstring);
new length = SQL_FetchInt(hndl, 3);
if (length == 0)
{
strcopy(lenstring, size_lenstring, "Permanent ");
}
else
{
new len = IntToString(length, lenstring, size_lenstring);
if (len < size_lenstring - 1)
{
// change the '\0' to a ' '. the original \0 at the end will still be there
lenstring[len] = ' ';
}
}
if (!SQL_IsFieldNull(hndl, 2))
{
FormatTime(enddate, sizeof(enddate), "%Y-%m-%d", SQL_FetchInt(hndl, 2));
}
// NOT NULL
new reason_size = sizeof(reason);
SQL_FetchString(hndl, 4, reason, reason_size);
new len = SQL_FetchSize(hndl, 4);
if (len > reason_size - 1)
{
reason[reason_size - 4] = '.';
reason[reason_size - 3] = '.';
reason[reason_size - 2] = '.';
}
else
{
for (new i = len; i < reason_size - 1; i++)
{
reason[i] = ' ';
}
}
if (!SQL_IsFieldNull(hndl, 5))
{
SQL_FetchString(hndl, 5, RemoveType, sizeof(RemoveType));
}
// NOT NULL
SQL_FetchString(hndl, 6, CommType, sizeof(RemoveType));
if(StrEqual(CommType,"1"))
strcopy(CommType, sizeof(CommType), "M");
if(StrEqual(CommType,"2"))
strcopy(CommType, sizeof(CommType), "G");
PrintListResponse(clientuid, client, "%s %s %s %s %s %s %s", createddate, bannedby, lenstring, enddate, CommType, RemoveType, reason);
}
}
PrintListResponse(userid, client, const String:format[], any:...)
{
decl String:msg[192];
VFormat(msg, sizeof(msg), format, 4);
if (userid == 0)
{
PrintToServer("%s", msg);
}
else
{
PrintToConsole(client, "%s", msg);
}
}
PrintToBanAdmins(const String:format[], any:...)
{
decl String:msg[128];
VFormat(msg, sizeof(msg), format, 2);
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientInGame(i) && !IsFakeClient(i)
&& CheckCommandAccess(i, "sm_listsourcebans", ADMFLAG_BAN)
)
{
PrintToChat(i, "%s", msg);
}
}
}
stock ReadConfig()
{
InitializeConfigParser();
if (g_ConfigParser == INVALID_HANDLE)
{
return;
}
decl String:ConfigFile[PLATFORM_MAX_PATH];
BuildPath(Path_SM, ConfigFile, sizeof(ConfigFile), "configs/sourcebans/sourcebans.cfg");
if (FileExists(ConfigFile))
{
InternalReadConfig(ConfigFile);
}
else
{
decl String:Error[PLATFORM_MAX_PATH + 64];
FormatEx(Error, sizeof(Error), "FATAL *** ERROR *** can not find %s", ConfigFile);
SetFailState(Error);
}
}
static InitializeConfigParser()
{
if (g_ConfigParser == INVALID_HANDLE)
{
g_ConfigParser = SMC_CreateParser();
SMC_SetReaders(g_ConfigParser, ReadConfig_NewSection, ReadConfig_KeyValue, ReadConfig_EndSection);
}
}
static InternalReadConfig(const String:path[])
{
new SMCError:err = SMC_ParseFile(g_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)
{
return SMCParse_Continue;
}
public SMCResult:ReadConfig_KeyValue(Handle:smc, const String:key[], const String:value[], bool:key_quotes, bool:value_quotes)
{
if (strcmp("DatabasePrefix", key, false) == 0)
{
strcopy(g_DatabasePrefix, sizeof(g_DatabasePrefix), value);
if (g_DatabasePrefix[0] == '\0')
{
g_DatabasePrefix = "sb";
}
}
return SMCParse_Continue;
}
public SMCResult:ReadConfig_EndSection(Handle:smc)
{
return SMCParse_Continue;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,199 @@
#pragma semicolon 1
#define PLUGIN_AUTHOR "RumbleFrog, SourceBans++ Dev Team"
#define PLUGIN_VERSION "1.6.4"
#include <sourcemod>
#include <sourcebanspp>
#pragma newdecls required
#define Chat_Prefix "[SourceBans++] "
enum
{
Cooldown = 0,
MinLen,
Settings_Count
};
ConVar Convars[Settings_Count];
bool bInReason[MAXPLAYERS + 1];
int iMinLen = 10
, iTargetCache[MAXPLAYERS + 1];
float fCooldown = 60.0
, fNextUse[MAXPLAYERS + 1];
public Plugin myinfo =
{
name = "SourceBans++ Report Plugin",
author = PLUGIN_AUTHOR,
description = "Adds ability for player to report offending players",
version = PLUGIN_VERSION,
url = "https://sbpp.github.io"
};
public void OnPluginStart()
{
CreateConVar("sbpp_report_version", PLUGIN_VERSION, "SBPP Report Version", FCVAR_REPLICATED | FCVAR_SPONLY | FCVAR_DONTRECORD | FCVAR_NOTIFY);
Convars[Cooldown] = CreateConVar("sbpp_report_cooldown", "60.0", "Cooldown in seconds between per report per user", FCVAR_NONE, true, 0.0, false);
Convars[MinLen] = CreateConVar("sbpp_report_minlen", "10", "Minimum reason length", FCVAR_NONE, true, 0.0, false);
LoadTranslations("sourcereport.phrases");
RegConsoleCmd("sm_report", CmdReport, "Initialize Report");
Convars[Cooldown].AddChangeHook(OnConvarChanged);
Convars[MinLen].AddChangeHook(OnConvarChanged);
}
public Action CmdReport(int iClient, int iArgs)
{
if (!IsValidClient(iClient))
return Plugin_Handled;
if (OnCooldown(iClient))
{
PrintToChat(iClient, "%s%T", Chat_Prefix, "In Cooldown", iClient, GetRemainingTime(iClient));
return Plugin_Handled;
}
Menu PList = new Menu(ReportMenu);
char sName[MAX_NAME_LENGTH], sIndex[4];
for (int i = 0; i <= MaxClients; i++)
{
if (!IsValidClient(i))
continue;
GetClientName(i, sName, sizeof sName);
IntToString(i, sIndex, sizeof sIndex);
PList.AddItem(sIndex, sName);
}
PList.Display(iClient, MENU_TIME_FOREVER);
return Plugin_Handled;
}
public int ReportMenu(Menu menu, MenuAction action, int iClient, int iItem)
{
switch (action)
{
case MenuAction_Select:
{
char sIndex[4];
menu.GetItem(iItem, sIndex, sizeof sIndex);
iTargetCache[iClient] = StringToInt(sIndex);
bInReason[iClient] = true;
PrintToChat(iClient, "%s%T", Chat_Prefix, "Reason Prompt", iClient);
}
case MenuAction_End:
delete menu;
}
}
public Action OnClientSayCommand(int iClient, const char[] sCommand, const char[] sArgs)
{
if (!bInReason[iClient])
return Plugin_Continue;
if (!IsValidClient(iClient) || (iTargetCache[iClient] != -1 && !IsValidClient(iTargetCache[iClient])))
{
ResetInReason(iClient);
return Plugin_Continue;
}
if (StrEqual(sArgs, "cancel", false))
{
PrintToChat(iClient, "%s%T", Chat_Prefix, "Report Canceled", iClient);
ResetInReason(iClient);
return Plugin_Stop;
}
if (strlen(sArgs) < iMinLen)
{
PrintToChat(iClient, "%s%T", Chat_Prefix, "Reason Short Need More", iClient);
return Plugin_Stop;
}
SBPP_ReportPlayer(iClient, iTargetCache[iClient], sArgs);
AddCooldown(iClient);
ResetInReason(iClient);
return Plugin_Stop;
}
public void SBPP_OnReportPlayer(int iReporter, int iTarget, const char[] sReason)
{
if (!IsValidClient(iReporter))
return;
PrintToChat(iReporter, "%s%T", Chat_Prefix, "Report Sent", iReporter);
}
void ResetInReason(int iClient)
{
bInReason[iClient] = false;
iTargetCache[iClient] = -1;
}
void AddCooldown(int iClient)
{
fNextUse[iClient] = GetGameTime() + fCooldown;
}
bool OnCooldown(int iClient)
{
return (fNextUse[iClient] - GetGameTime()) > 0.0;
}
float GetRemainingTime(int iClient)
{
float fOffset = fNextUse[iClient] - GetGameTime();
if (fOffset > 0.0)
return fOffset;
else
return 0.0;
}
public void OnConvarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
{
if (convar == Convars[Cooldown])
fCooldown = Convars[Cooldown].FloatValue;
else if (convar == Convars[MinLen])
iMinLen = Convars[MinLen].IntValue;
}
stock bool IsValidClient(int iClient, bool bAlive = false)
{
if (iClient >= 1 &&
iClient <= MaxClients &&
IsClientConnected(iClient) &&
IsClientInGame(iClient) &&
!IsFakeClient(iClient) &&
(bAlive == false || IsPlayerAlive(iClient)))
{
return true;
}
return false;
}

View File

@ -0,0 +1,281 @@
// *************************************************************************
// 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):
//
// SourceSleuth 1.3 fix
// Copyright (C) 2013-2015 ecca
// Licensed under GNU GPL version 3, or later.
// Page: <https://forums.alliedmods.net/showthread.php?p=1818793> - <https://github.com/ecca/SourceMod-Plugins>
//
// *************************************************************************
#pragma semicolon 1
#include <sourcemod>
#undef REQUIRE_PLUGIN
#include <sourcebanspp>
#define PLUGIN_VERSION "1.6.4"
#define LENGTH_ORIGINAL 1
#define LENGTH_CUSTOM 2
#define LENGTH_DOUBLE 3
#define LENGTH_NOTIFY 4
//- Handles -//
new Handle:hDatabase = INVALID_HANDLE;
new Handle:g_hAllowedArray = INVALID_HANDLE;
//- ConVars -//
ConVar g_cVar_actions;
ConVar g_cVar_banduration;
ConVar g_cVar_sbprefix;
ConVar g_cVar_bansAllowed;
ConVar g_cVar_bantype;
ConVar g_cVar_bypass;
ConVar g_cVar_excludeOld;
ConVar g_cVar_excludeTime;
//- Bools -//
new bool:CanUseSourcebans = false;
public Plugin:myinfo =
{
name = "SourceBans++: SourceSleuth",
author = "ecca, SourceBans++ Dev Team",
description = "Useful for TF2 servers. Plugin will check for banned ips and ban the player.",
version = PLUGIN_VERSION,
url = "https://sbpp.github.io"
};
public OnPluginStart()
{
LoadTranslations("sourcesleuth.phrases");
CreateConVar("sm_sourcesleuth_version", PLUGIN_VERSION, "SourceSleuth plugin version", FCVAR_SPONLY | FCVAR_REPLICATED | FCVAR_NOTIFY | FCVAR_DONTRECORD);
g_cVar_actions = CreateConVar("sm_sleuth_actions", "3", "Sleuth Ban Type: 1 - Original Length, 2 - Custom Length, 3 - Double Length, 4 - Notify Admins Only", 0, true, 1.0, true, 4.0);
g_cVar_banduration = CreateConVar("sm_sleuth_duration", "0", "Required: sm_sleuth_actions 1: Bantime to ban player if we got a match (0 = permanent (defined in minutes) )", 0);
g_cVar_sbprefix = CreateConVar("sm_sleuth_prefix", "sb", "Prexfix for sourcebans tables: Default sb", 0);
g_cVar_bansAllowed = CreateConVar("sm_sleuth_bansallowed", "0", "How many active bans are allowed before we act", 0);
g_cVar_bantype = CreateConVar("sm_sleuth_bantype", "0", "0 - ban all type of lengths, 1 - ban only permanent bans", 0, true, 0.0, true, 1.0);
g_cVar_bypass = CreateConVar("sm_sleuth_adminbypass", "0", "0 - Inactivated, 1 - Allow all admins with ban flag to pass the check", 0, true, 0.0, true, 1.0);
g_cVar_excludeOld = CreateConVar("sm_sleuth_excludeold", "0", "0 - Inactivated, 1 - Allow old bans to be excluded from ban check", 0, true, 0.0, true, 1.0);
g_cVar_excludeTime = CreateConVar("sm_sleuth_excludetime", "31536000", "Amount of time in seconds to allow old bans to be excluded from ban check", 0, true, 1.0, false);
g_hAllowedArray = CreateArray(256);
AutoExecConfig(true, "Sm_SourceSleuth");
SQL_TConnect(SQL_OnConnect, "sourcebans");
RegAdminCmd("sm_sleuth_reloadlist", ReloadListCallBack, ADMFLAG_ROOT);
LoadWhiteList();
}
public OnAllPluginsLoaded()
{
CanUseSourcebans = LibraryExists("sourcebans");
}
public OnLibraryAdded(const String:name[])
{
if (StrEqual("sourcebans", name))
{
CanUseSourcebans = true;
}
}
public OnLibraryRemoved(const String:name[])
{
if (StrEqual("sourcebans", name))
{
CanUseSourcebans = false;
}
}
public SQL_OnConnect(Handle:owner, Handle:hndl, const String:error[], any:data)
{
if (hndl == INVALID_HANDLE)
{
LogError("SourceSleuth: Database connection error: %s", error);
}
else
{
hDatabase = hndl;
}
}
public Action:ReloadListCallBack(client, args)
{
ClearArray(g_hAllowedArray);
LoadWhiteList();
LogMessage("%L reloaded the whitelist", client);
if (client != 0)
{
PrintToChat(client, "[SourceSleuth] WhiteList has been reloaded!");
}
return Plugin_Continue;
}
public OnClientPostAdminCheck(client)
{
if (CanUseSourcebans && !IsFakeClient(client))
{
new String:steamid[32];
GetClientAuthId(client, AuthId_Steam2, steamid, sizeof(steamid));
if (g_cVar_bypass.BoolValue && CheckCommandAccess(client, "sleuth_admin", ADMFLAG_BAN, false))
{
return;
}
if (FindStringInArray(g_hAllowedArray, steamid) == -1)
{
new String:IP[32], String:Prefix[64];
GetClientIP(client, IP, sizeof(IP));
g_cVar_sbprefix.GetString(Prefix, sizeof(Prefix));
new String:query[1024];
FormatEx(query, sizeof(query), "SELECT * FROM %s_bans WHERE ip='%s' AND RemoveType IS NULL AND (ends > %d OR ((1 = %d AND length = 0 AND ends > %d) OR (0 = %d AND length = 0)))", Prefix, IP, g_cVar_bantype.IntValue == 0 ? GetTime() : 0, g_cVar_excludeOld.IntValue, GetTime() - g_cVar_excludeTime.IntValue, g_cVar_excludeOld.IntValue);
new Handle:datapack = CreateDataPack();
WritePackCell(datapack, GetClientUserId(client));
WritePackString(datapack, steamid);
WritePackString(datapack, IP);
ResetPack(datapack);
SQL_TQuery(hDatabase, SQL_CheckHim, query, datapack);
}
}
}
public SQL_CheckHim(Handle:owner, Handle:hndl, const String:error[], any:datapack)
{
new client;
decl String:steamid[32], String:IP[32];
client = GetClientOfUserId(ReadPackCell(datapack));
ReadPackString(datapack, steamid, sizeof(steamid));
ReadPackString(datapack, IP, sizeof(IP));
CloseHandle(datapack);
if (hndl == INVALID_HANDLE)
{
LogError("SourceSleuth: Database query error: %s", error);
return;
}
if (SQL_FetchRow(hndl))
{
new TotalBans = SQL_GetRowCount(hndl);
if (TotalBans > g_cVar_bansAllowed.IntValue)
{
switch (g_cVar_actions.IntValue)
{
case LENGTH_ORIGINAL:
{
new length = SQL_FetchInt(hndl, 6);
new time = length * 60;
BanPlayer(client, time);
}
case LENGTH_CUSTOM:
{
new time = g_cVar_banduration.IntValue;
BanPlayer(client, time);
}
case LENGTH_DOUBLE:
{
new length = SQL_FetchInt(hndl, 6);
new time = 0;
if (length != 0)
{
time = length / 60 * 2;
}
BanPlayer(client, time);
}
case LENGTH_NOTIFY:
{
/* Notify Admins when a client with an ip on the bans list connects */
PrintToAdmins("[SourceSleuth] %t", "sourcesleuth_admintext", client, steamid, IP);
}
}
}
}
}
stock BanPlayer(client, time)
{
decl String:Reason[255];
Format(Reason, sizeof(Reason), "[SourceSleuth] %T", "sourcesleuth_banreason", client);
SBPP_BanPlayer(0, client, time, Reason);
}
PrintToAdmins(const String:format[], any:...)
{
new String:g_Buffer[256];
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientInGame(i) && CheckCommandAccess(i, "sm_sourcesleuth_printtoadmins", ADMFLAG_BAN))
{
SetGlobalTransTarget(i);
VFormat(g_Buffer, sizeof(g_Buffer), format, 2);
PrintToChat(i, "%s", g_Buffer);
}
}
}
public LoadWhiteList()
{
decl String:path[PLATFORM_MAX_PATH], String:line[256];
BuildPath(Path_SM, path, PLATFORM_MAX_PATH, "configs/sourcebans/sourcesleuth_whitelist.cfg");
new Handle:fileHandle = OpenFile(path, "r");
if (fileHandle == INVALID_HANDLE)
{
LogError("Could not find the config file (%s)", path);
return;
}
while (!IsEndOfFile(fileHandle) && ReadFileLine(fileHandle, line, sizeof(line)))
{
ReplaceString(line, sizeof(line), "\n", "", false);
PushArrayString(g_hAllowedArray, line);
}
CloseHandle(fileHandle);
}

View File

@ -0,0 +1,149 @@
"Phrases"
{
"Banned Check Site"
{
"#format" "{1:s}"
"en" "You have been banned by this server, check {1} for more info"
"nl" "U bent gebanned van deze server, kijk op {1} voor meer informatie"
"fr" "Vous avez été banni de ce serveur, allez sur {1} pour plus d'informations"
"pl" "Zostałeś zbanowany na tym serwerze, odwiedź {1} aby poznać szczegóły"
"de" "Sie wurden von diesem Server gebannt, weitere Informationen auf {1}"
"ru" "Вы были забанены на этом сервере, для получения информации посетите: {1}"
"da" "Du er blevet udlukket fra denne server, check {1} for mere info"
"no" "Du har blitt stengt ute fra denne serveren, sjekk {1} for mer info."
"hu" "Bannolva vagy erről a szerverről, látogass el {1} honlapra a további információkért."
"chi" "你已被此服务器封禁,详情请参阅: {1}."
}
"DB Connect Fail"
{
"en" "Database connection failed. Please contact server operator."
"nl" "Database connectie is mislukt. Neem contact op met uw server beheerder."
"fr" "Problème de connection avec la base de données. Merci de bien vouloir contacter un admin."
"pl" "Błąd połączenia z bazą danych. Skontaktuj się z adminem serwera."
"de" "Datenbankverbindung fehlgeschlagen. Bitte kontaktieren Sie den Serveradministrator."
"ru" "Не удалось подключиться к базе данных. Свяжитесь с администратором сервера."
"da" "Database tilslutningen fejlede. Kontakt venligst server bestyrren."
"no" "Kommunikasjon med databasen feilet. Vennligst kontakt serveradmin."
"hu" "Sikertelen adatbázis csatlakozás. Kérlek vedd fel a kapcsolatott egy szerver operátorral."
"chi" "数据库连接失败,请联系服务器管理员."
}
"Not In Game"
{
"en" "The player is not in game, please visit the web panel to ban them."
"nl" "De speler is niet in het spel, gaat u alstublieft naar het web panel om de speler op de banlijst te plaatsen."
"fr" "Le joueur n'est pas en jeu, merci d'aller sur le panel internet pour le bannir."
"pl" "Gracz nie znajduje się w grze, odwiedź panel www aby go zbanować."
"de" "Der Spieler ist nicht im Spiel. Bitte benutzen Sie das Webpanel um ihn zu bannen."
"ru" "Так как игрок не в игре вы должны посетить веб-панель, чтобы забанить его."
"da" "Spilleren er ikke i spillet, besøg venligst web panelet for at udelukke ham."
"no" "Spilleren er ikke på serveren, vennligst besøk web panelet for og stenge han ute."
"hu" "A játékos nincs játékban, kérlek nézd meg a honlapon a bannolásért."
"chi" "此玩家目前不在游戏内,请通过web管理面板来进行封禁."
}
"Ban Not Verified"
{
"en" "This player has not been verified. Please wait thirty seconds before retrying."
"nl" "Deze speler zijn ban is niet geverifieerd. Wacht u alstublieft 30 seconden voordat u het opnieuw probeerd."
"fr" "Le systeme n'a pas réussi à déterminer si ce joueur est banni. Merci d'attendre 30 secondes avant de re-essayer."
"pl" "Gracz nie został jeszcze zweryfikowany. Spróbuj ponownie za 30 sekund."
"de" "Dieser Spieler wurde noch nicht verifiziert. Bitte warten Sie 30 Sekunden und versuchen Sie es nochmal."
"ru" "Игрок еще не идентифицирован. Подождите 30 секунд перед следующей попыткой."
"da" "Denne spiller er ikke blevet identificeret. Vent venligst 30 sekunder før du prøver igen."
"no" "Denne spilleren har ikke blitt indentifisert. Vennligst vent 30 sekunder før du prøver igjen."
"hu" "Ez a játékos nincs hitelesítve. Kérlek várj 30 másodpercet mielőtt újra próbálnád."
"chi" "此玩家尚未被认证,请等待30秒后再试."
}
"Can Not Unban"
{
"#format" "{1:s}"
"en" "You can not unban from in the server, visit {1} to unban."
"nl" "U kunt de speler niet vanuit de server unbannen, bezoek {1} om te unbannen."
"fr" "Vous ne pouvez pas annuler de ban depuis ce serveur, allez sur {1} pour le faire."
"pl" "Nie możesz odbanować z serwera, odwiedź {1} by zdjąć bana."
"de" "Sie können nicht vom Server aus entbannen, entbannen Sie auf {1} ."
"ru" "Вы не можете разбанить игрока на сервере, зайдите на {1} для удаления бана."
"da" "Du kan ikke fjerne udelukkelserne inde fra serveren, besøg {1} for at fjerne udelukkelsen."
"no" "Du kan ikke fjerne utestengelsen inne fra serveren, besøk {1} for og fjerne utestengelsen."
"hu" "Nem tudsz unbannolni a szerverről, látogasd meg {1} a ban feloldásért."
"chi" "你无法从游戏中解除封禁,请访问此链接来解除: {1} ."
}
"Can Not Add Ban"
{
"#format" "{1:s}"
"en" "You can not add a ban from in the server, visit {1} to add a ban."
"nl" "U kunt geen ban toevoegen vanuit de server, bezoek {1} om de ban toe te voegen."
"fr" "Vous ne pouvez pas ajouter de ban depuis ce serveur, allez sur {1} pour ajouter un ban."
"pl" "Nie możesz dodać bana z serwera, odwiedź {1} by dodać bana."
"de" "Sie können keinen Ban vom Server aus hinzufügen, bannen Sie auf {1} ."
"ru" "Вы не можете дать бан на сервере, зайдите на {1} для добавления бана."
"da" "Du kan ikke tilføje en udelukkelse fra serveren, besøg {1} for at tilføje en udelukkelse."
"no" "Du kan ikke legge til en utestengelse fra serveren, besøk {1} for og legge til en utestengelse."
"hu" "Nem tudsz a szerverről bannolni, látogasd meg {1} a bannolásért."
"chi" "你不能在游戏中添加封禁,请访问此链接来封禁: {1} ."
}
"Check Menu"
{
"en" "Please check the menu to select a reason for ban."
"nl" "Controleerdt u alstublieft het menu om een reden te selecteren voor de ban."
"fr" "Merci d'utiliser le menu pour sélectionner la raison du ban."
"pl" "Sprawdź menu aby wybrać powód bana."
"de" "Bitte benutzen Sie das Menü um einen Grund für den Ban auszuwählen."
"ru" "Выберите причину бана из меню."
"da" "Check venligst menuen for en grund til udelukkelse"
"no" "Venligst sjekk menyen for en grunn til utestengelse"
"hu" "Kérjük, ellenőrizze a menüt, hogy kiválassza a tilalom okait."
"chi" "请从菜单中选择封禁理由."
}
"Include Reason"
{
"en" "Please include a reason for banning the client."
"nl" "Voegt u alstublieft een reden toe voor het bannen van deze persoon."
"fr" "Merci d'ajouter la raison du ban."
"pl" "Proszę dodać powód bana."
"de" "Bitte geben Sie einen Grund für den Ban an."
"ru" "Добавьте причину бана игрока."
"da" "Indkludere venligst en grund for at udelukke klienten."
"no" "Inkluder vennligst en grunn for og utelukke klienten."
"hu" "Kérlek írj indokot is a kliens bannolásához."
"chi" "请填写封禁此玩家的理由."
}
"Ban Fail"
{
"en" "Failed to ban player, please try again."
"nl" "Er is een fout opgetreden tijdens de ban procedure, probeert u het alstublieft nogmaals."
"fr" "Le joueur n'a pas pu être banni merci d'essayer ultérieurement."
"pl" "Błąd przy dodawaniu bana, spróbuj ponownie."
"de" "Es ist ein Fehler beim bannen des Spielers aufgetreten, bitte versuchen Sie es erneut."
"ru" "Не удалось забанить игрока, попробуйте еще раз."
"da" "Fejlede udelukkelsen, prøv venligst igen."
"no" "Utestengelse feilet, vennligst prøv igjen."
"hu" "Sikertelen bannolás, próbáld újra."
"chi" "无法封禁此玩家,请重试."
}
"Chat Reason"
{
"en" "Please type the reason for ban in chat and press enter. Type '!noreason' to abort."
"nl" "Typ alstublieft de reden voor de ban in chat and druk op enter. Typ '!noreason' om the annuleren."
"fr" "Merci d'écrire la raison du ban dans le chat. Tapez '!noreason' pour annuler."
"pl" "Proszę wpisać powód bana w czacie oraz potwierdzić przyciskiem Enter. Wpisz !noreason by anulować."
"de" "Bitte schreiben Sie den Grund für den Ban in den Chat. Schreiben Sie '!noreason' um abzubrechen."
"ru" "Введите причину бана и нажмите Ввод. Введите '!noreason' для отмены бана."
"da" "Skriv venligst din grund for udelukkelsen ind i chatten og tryk enter. Skriv '!noreason' for at annullere."
"no" "Vennligst skriv din grunn for utestengelse i chaten og trykk enter. Skriv 'noreason' for og annulere."
"hu" "Írd be a chatre az indokot, majd nyomj entert. Írd '!noreason' a megszakításhoz."
"chi" "请在聊天框中填写封禁理由并提交或输入 '!noreason' 放弃操作."
}
"Chat Reason Aborted"
{
"en" "The ban procedure has been stopped successfully."
"nl" "De ban procedure is succesvol gestopt."
"fr" "La procédure de ban a été arrêté avec succès."
"pl" "Procedura banowania została pomyślnie zatrzymana."
"de" "Der Banvorgang wurde erfolgreich angehalten."
"ru" "Бан отменён."
"da" "Udelukkelses proceduren blev stoppet med success"
"no" "Utestengelses prossedyren ble stoppet vellykket."
"hu" "A ban eljárás sikeresen leállítva."
"chi" "封禁操作已成功取消."
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,44 @@
"Phrases"
{
"In Cooldown"
{
"#format" "{1:.0f}"
"en" "Please wait {1} seconds before reporting again"
"fr" "Veuillez patienter {1} secondes avant de rapporter à nouveau"
"pl" "Zaczekaj {1} sekund przed ponownym wysłaniem zgłoszenia"
"chi" "请等待 {1} 秒后再试"
}
"Report Canceled"
{
"en" "Report canceled"
"fr" "Report annulé"
"pl" "Raport został anulowany"
"chi" "报告已取消"
}
"Report Sent"
{
"en" "Your report has been sent"
"fr" "Votre report a été envoyé"
"pl" "Twój raport został wysłany"
"chi" "你的报告已发送"
}
"Reason Prompt"
{
"en" "Please enter the reason for the report or \"cancel\" to cancel"
"fr" "Veuillez entrer la raison du rapport ou \"cancel\" pour annuler
"pl" "Podaj przyczynę zgłoszenia lub \"cancel\", aby anulować"
"chi" "请填写报告填写理由或者 \"cancel\" 来取消"
}
"Reason Short Need More"
{
"en" "Reason is too short, more details is required"
"fr" "La raison est trop courte, plus de détails sont requis"
"pl" "Powód jest za krótki, więcej szczegółów jest wymaganych"
"chi" "理由过于简短,请做更多说明"
}
}

View File

@ -0,0 +1,25 @@
"Phrases"
{
"sourcesleuth_banreason"
{
"#format" ""
"en" "Duplicate account"
"hu" "Duplikált account"
"ru" "Аккаунт дубликат"
"fr" "Compte dupliquer"
"pl" "Zduplikowane konto"
"chi" "马甲/多重账户"
}
"sourcesleuth_admintext"
{
"#format" "{1:N},{2:s},{3:s}"
"en" "Player {1} (ID: {2} | IP: {3}) has active bans on IP"
"hu" "{1} (ID: {2} | IP: {3}) játékosnak van aktív kitiltása az alábbi IP-n"
"ru" "Игрок {1} (ID: {2} | IP: {3}) имеет активный бан по IP"
"sv" "Spelare {1} (ID: {2} | IP: {3}) har aktiva bannlysningar på IP"
"fr" "Le joueur {1} (ID: {2} | IP: {3}) a des bannissements actives sur IP"
"pl" "Gracz {1} (ID: {2} | IP: {3}) ma aktywne blokady na IP"
"chi" "玩家 {1} (ID: {2} | IP: {3}) 目前有多次IP封禁"
}
}