[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
@@ -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!
@@ -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");
}
+107
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;
}
@@ -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
@@ -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
+564
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
+199
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;
}
+281
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);
}