projects-jenz/jenz_ban_detector/scripting/jenz_ban_detector.sp

256 lines
7.7 KiB
SourcePawn
Raw Normal View History

#pragma semicolon 1
#define PLUGIN_AUTHOR "jenz"
#define g_dLength 400
#define PLUGIN_VERSION "1.0"
#pragma newdecls required
#include <sourcemod>
#include <sourcebanspp>
#include <clientprefs>
#include <cstrike>
#include <sdktools>
int validate_state [MAXPLAYERS + 1];
Database g_dDatabase;
Database g_hDatabase_sourceban;
Handle g_hOnReportBanPostForward;
bool g_bReportedClientBanAvoiding[MAXPLAYERS + 1];
public Plugin myinfo =
{
name = "jenz ban detector",
author = PLUGIN_AUTHOR,
description = "my ban detector maybe catches you",
version = PLUGIN_VERSION,
url = "www.unloze.com"
};
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
{
RegPluginLibrary("jenz_ban_detector");
return APLRes_Success;
}
public void OnPluginStart()
{
g_hOnReportBanPostForward = CreateGlobalForward("BanDetectorPost", ET_Ignore, Param_Cell, Param_String);
if (!g_dDatabase)
{
Database.Connect(SQL_OnDatabaseConnect, "jenz_ban_detector");
}
for (int i = 0; i < MaxClients; i++)
{
if (IsValidClient(i))
{
validate_state[i] = 0;
g_bReportedClientBanAvoiding[i] = false;
}
}
CreateTimer(10.0, start_checks, _, TIMER_REPEAT);
}
public void SQL_addEntry(int client)
{
char sQuery[g_dLength];
char sSID[MAX_NAME_LENGTH];
char sIP[MAX_NAME_LENGTH];
char sName[MAX_NAME_LENGTH];
GetClientName(client, sName, sizeof(sName));
int size2 = 2 * strlen(sName) + 1;
char[] sEscapedName = new char[size2 + 1];
GetClientAuthId(client, AuthId_Steam2, sSID, sizeof(sSID));
g_dDatabase.Escape(sName, sEscapedName, size2 + 1);
GetClientIP(client, sIP, sizeof(sIP));
Format(sQuery, sizeof(sQuery), "insert into `ban_detector_steamids` (`steamid`, `name`, `ID`) SELECT '%s', '%s', bd.ID from `ban_detector` bd where bd.ip = '%s' and not exists (select bds.ID from `ban_detector_steamids` bds where bds.ID = bd.ID and bds.steamid = '%s')", sSID, sEscapedName, sIP, sSID);
g_dDatabase.Query(SQL_UpdateEntry, sQuery, client, DBPrio_Low);
}
public void SQL_OnDatabaseConnect(Database db, const char[] error, any data)
{
if(!db || strlen(error))
{
LogError("Database error: %s", error);
return;
}
g_dDatabase = db;
}
public void SQL_OnDatabaseConnect_sb(Database db, const char[] error, any data)
{
if(!db || strlen(error))
{
LogError("Database error: %s", error);
return;
}
g_hDatabase_sourceban = db;
}
public void SQL_UpdateEntry(Database db, DBResultSet results, const char[] error, int client)
{
if(!db || strlen(error))
{
LogError("Database error: %s", error);
return;
}
if (IsValidClient(client))
{
char sQuery[g_dLength];
char sSID[MAX_NAME_LENGTH];
char sIP[MAX_NAME_LENGTH];
GetClientIP(client, sIP, sizeof(sIP));
GetClientAuthId(client, AuthId_Steam2, sSID, sizeof(sSID));
Format(sQuery, sizeof(sQuery), "SELECT bd.fingerprint FROM `ban_detector` bd inner join `ban_detector_steamids` bds on bd.ID = bds.ID where bds.steamid = '%s' or bd.ip = '%s'", sSID, sIP);
//PrintToChatAll("sQuery: %s", sQuery);
g_dDatabase.Query(SQL_FindFingerPrints, sQuery, client, DBPrio_Low);
}
delete results;
}
public void SQL_FindFingerPrints(Database db, DBResultSet results, const char[] error, int client)
{
if (!db || strlen(error))
{
LogError("Database error: %s", error);
return;
}
char fingerprint[1024];
while (results.RowCount > 0 && results.FetchRow())
{
results.FetchString(0, fingerprint, sizeof(fingerprint));
char sQuery[1024];
char[] sEscapedFingerPrint = new char[1024];
g_dDatabase.Escape(fingerprint, sEscapedFingerPrint, 1024);
Format(sQuery, sizeof(sQuery), "select steamid, ip from ban_detector bd inner join ban_detector_steamids bds on bd.ID = bds.ID where fingerprint = '%s'", sEscapedFingerPrint);
//PrintToChatAll("sQuery: %s", sQuery);
g_dDatabase.Query(SQL_checkSourcebans, sQuery, client, DBPrio_Low);
if (IsValidClient(client) && g_bReportedClientBanAvoiding[client])
{
break;
}
}
delete results;
}
public void SQL_checkSourcebans(Database db, DBResultSet results, const char[] error, int client)
{
if (!db || strlen(error))
{
LogError("Database error: %s", error);
return;
}
while (results.RowCount > 0 && results.FetchRow())
{
char sSID[MAX_NAME_LENGTH];
char sIP[MAX_NAME_LENGTH];
results.FetchString(0, sSID, sizeof(sSID));
results.FetchString(1, sIP, sizeof(sIP));
char sql_statement[512];
2023-02-03 12:57:30 +01:00
//PrintToChatAll(sSID);
//PrintToChatAll(sIP);
// + 3600 for one hour to accomdate timezone difference
2023-02-03 12:57:30 +01:00
Format(sql_statement, sizeof(sql_statement), "select authid, ip from sb_bans where ((ip = '%s' and ip is not null and ip != '') or (authid = '%s' and authid is not null and authid =! '')) and (RemoveType != 'U' or RemoveType is NULL) and (ends > UNIX_TIMESTAMP() + 3600 or ends = created) order by created desc limit 1", sIP, sSID);
g_hDatabase_sourceban.Query(sql_select_sb_bans, sql_statement, client, DBPrio_Low);
if (IsValidClient(client) && g_bReportedClientBanAvoiding[client])
{
break;
}
}
delete results;
}
public void sql_select_sb_bans(Database db, DBResultSet results, const char[] error, int client)
{
if (!db || strlen(error))
{
LogError("Database error: %s", error);
return;
}
if (!IsValidClient(client))
{
delete results;
return;
}
if (results.RowCount && results.FetchRow() && IsValidClient(client) && !g_bReportedClientBanAvoiding[client])
{
g_bReportedClientBanAvoiding[client] = true;
char sSID[MAX_NAME_LENGTH];
char sIP[MAX_NAME_LENGTH];
results.FetchString(0, sSID, sizeof(sSID));
results.FetchString(1, sIP, sizeof(sIP));
Call_StartForward(g_hOnReportBanPostForward);
Call_PushCell(client);
if (strlen(sSID) == 0)
{
// use IP instead if no steamID
Call_PushString(sIP);
}
else
{
//found steamID
Call_PushString(sSID);
}
Call_Finish();
//bans need to be over 1 hour long for getting detected
SBPP_BanPlayer(0, client, 240, "Ban avoiding (Jenz ban detector)");
}
delete results;
}
public Action start_checks(Handle hTimer)
{
if (!g_dDatabase)
{
Database.Connect(SQL_OnDatabaseConnect, "jenz_ban_detector");
}
else
{
if (!g_hDatabase_sourceban)
{
Database.Connect(SQL_OnDatabaseConnect_sb, "sourcebans");
}
else
{
for (int i = 0; i < MaxClients; i++)
{
if (IsValidClient(i) && validate_state[i] == 0)
{
validate_state[i] = -1;
SQL_addEntry(i);
}
}
}
}
}
public void OnClientDisconnect(int client)
{
validate_state[client] = -1;
g_bReportedClientBanAvoiding[client] = false;
}
public void OnClientPostAdminCheck(int client)
{
validate_state[client] = -1;
CreateTimer(10.0, make_db_entry, client);
g_bReportedClientBanAvoiding[client] = false;
}
public Action make_db_entry(Handle hTimer, int client)
{
if (IsValidClient(client))
{
validate_state[client] = 0;
}
}
stock bool IsValidClient(int client)
{
if (client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client) && !IsFakeClient(client))
return true;
return false;
}