263 lines
7.6 KiB
SourcePawn
263 lines
7.6 KiB
SourcePawn
#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;
|
|
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, GetClientSerial(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_UpdateEntry(Database db, DBResultSet results, const char[] error, int Serial)
|
|
{
|
|
if(!db || strlen(error))
|
|
{
|
|
LogError("Database error: %s", error);
|
|
delete results;
|
|
return;
|
|
}
|
|
int client;
|
|
if ((client = GetClientFromSerial(Serial)) == 0)
|
|
{
|
|
delete results;
|
|
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 distinct (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, GetClientSerial(client), DBPrio_Low);
|
|
}
|
|
delete results;
|
|
}
|
|
|
|
public void SQL_FindFingerPrints(Database db, DBResultSet results, const char[] error, int Serial)
|
|
{
|
|
if (!db || strlen(error))
|
|
{
|
|
LogError("Database error: %s", error);
|
|
delete results;
|
|
return;
|
|
}
|
|
int client;
|
|
if ((client = GetClientFromSerial(Serial)) == 0)
|
|
{
|
|
delete results;
|
|
return;
|
|
}
|
|
if (!IsValidClient(client))
|
|
{
|
|
delete results;
|
|
return;
|
|
}
|
|
|
|
//god knows how big this might need to be
|
|
char sQuery[4344];
|
|
Format(sQuery, sizeof(sQuery), "select sb.authid, sb.ip from ban_detector.ban_detector bd inner join ban_detector.ban_detector_steamids bds on bd.ID = bds.ID inner join unloze_sourceban.sb_bans sb on sb.authid = bds.steamid or sb.ip = bd.ip where fingerprint in (");
|
|
bool first = true;
|
|
while (results.RowCount > 0 && results.FetchRow())
|
|
{
|
|
char fingerprint[1024];
|
|
results.FetchString(0, fingerprint, sizeof(fingerprint));
|
|
char[] sEscapedFingerPrint = new char[1024];
|
|
g_dDatabase.Escape(fingerprint, sEscapedFingerPrint, 1024);
|
|
if (first)
|
|
{
|
|
Format(sEscapedFingerPrint, 1024, "'%s'", sEscapedFingerPrint);
|
|
}
|
|
else
|
|
{
|
|
Format(sEscapedFingerPrint, 1024, ",'%s'", sEscapedFingerPrint);
|
|
}
|
|
StrCat(sQuery, sizeof(sQuery), sEscapedFingerPrint);
|
|
first = false;
|
|
}
|
|
StrCat(sQuery, sizeof(sQuery), ") and (RemoveType != 'U' or RemoveType is NULL) and (ends > UNIX_TIMESTAMP() + 3600 or ends = created) order by created desc limit 1");
|
|
//LogError("LOOK HERE: %s", sQuery);
|
|
if (!first)
|
|
{
|
|
g_dDatabase.Query(sql_select_sb_bans, sQuery, GetClientSerial(client), DBPrio_Low);
|
|
}
|
|
delete results;
|
|
}
|
|
|
|
public void sql_select_sb_bans(Database db, DBResultSet results, const char[] error, int Serial)
|
|
{
|
|
if (!db || strlen(error))
|
|
{
|
|
delete results;
|
|
LogError("Database error 2: %s", error);
|
|
return;
|
|
}
|
|
|
|
int client;
|
|
if ((client = GetClientFromSerial(Serial)) == 0)
|
|
{
|
|
delete results;
|
|
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
|
|
if (strlen(sSID) == 0)
|
|
{
|
|
SBPP_BanPlayer(0, client, 0, "Ban avoiding (Jenz ban detector). Same IP avoiding ban.");
|
|
}
|
|
else
|
|
{
|
|
char message[1024];
|
|
Format(message, sizeof(message), "Ban avoiding (Jenz ban detector). SteamID avoiding ban: %s", sSID);
|
|
SBPP_BanPlayer(0, client, 0, message);
|
|
}
|
|
}
|
|
delete results;
|
|
}
|
|
|
|
public Action start_checks(Handle hTimer)
|
|
{
|
|
for (int i = 0; i < MaxClients; i++)
|
|
{
|
|
if (IsValidClient(i) && validate_state[i] == 0)
|
|
{
|
|
validate_state[i] = -1;
|
|
SQL_addEntry(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void OnMapStart()
|
|
{
|
|
if (!g_dDatabase)
|
|
{
|
|
Database.Connect(SQL_OnDatabaseConnect, "jenz_ban_detector");
|
|
}
|
|
}
|
|
|
|
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, GetClientSerial(client));
|
|
g_bReportedClientBanAvoiding[client] = false;
|
|
}
|
|
|
|
public Action make_db_entry(Handle hTimer, int Serial)
|
|
{
|
|
int client;
|
|
if ((client = GetClientFromSerial(Serial)) == 0)
|
|
{
|
|
return;
|
|
}
|
|
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;
|
|
}
|