2023-02-02 00:19:27 +01:00
# pragma semicolon 1
# define PLUGIN_AUTHOR "jenz"
# define g_dLength 400
# define PLUGIN_VERSION "1.0"
# pragma newdecls required
# include <sourcemod>
2023-02-14 21:29:45 +01:00
# include <sourcebanspp>
2023-02-02 00:19:27 +01:00
# include <clientprefs>
# include <cstrike>
# include <sdktools>
int validate_state [ MAXPLAYERS + 1 ] ;
Database g_dDatabase ;
2023-02-03 11:38:47 +01:00
Handle g_hOnReportBanPostForward ;
2023-02-07 20:45:15 +01:00
bool g_bReportedClientBanAvoiding [ MAXPLAYERS + 1 ] ;
2023-02-02 00:19:27 +01:00
public Plugin myinfo =
{
name = " jenz ban detector " ,
author = PLUGIN_AUTHOR ,
description = " my ban detector maybe catches you " ,
version = PLUGIN_VERSION ,
url = " www.unloze.com "
} ;
2023-02-03 11:38:47 +01:00
public APLRes AskPluginLoad2 ( Handle myself , bool late , char [ ] error , int err_max )
{
RegPluginLibrary ( " jenz_ban_detector " ) ;
return APLRes_Success ;
}
2023-02-02 00:19:27 +01:00
public void OnPluginStart ( )
{
2023-02-03 11:38:47 +01:00
g_hOnReportBanPostForward = CreateGlobalForward ( " BanDetectorPost " , ET_Ignore , Param_Cell , Param_String ) ;
2023-02-02 00:19:27 +01:00
if ( ! g_dDatabase )
{
Database . Connect ( SQL_OnDatabaseConnect , " jenz_ban_detector " ) ;
}
for ( int i = 0 ; i < MaxClients ; i + + )
{
if ( IsValidClient ( i ) )
{
validate_state [ i ] = 0 ;
2023-02-07 20:45:15 +01:00
g_bReportedClientBanAvoiding [ i ] = false ;
2023-02-02 00:19:27 +01:00
}
}
CreateTimer ( 10.0 , start_checks , _ , TIMER_REPEAT ) ;
}
2023-02-07 20:45:15 +01:00
public void SQL_addEntry ( int client )
2023-02-02 00:19:27 +01:00
{
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 ) ) ;
2023-02-07 20:45:15 +01:00
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 ) ;
2023-04-30 12:14:28 +02:00
g_dDatabase . Query ( SQL_UpdateEntry , sQuery , GetClientSerial ( client ) , DBPrio_Low ) ;
2023-02-02 00:19:27 +01:00
}
public void SQL_OnDatabaseConnect ( Database db , const char [ ] error , any data )
{
if ( ! db | | strlen ( error ) )
{
LogError ( " Database error: %s " , error ) ;
return ;
}
g_dDatabase = db ;
}
2023-04-30 12:14:28 +02:00
public void SQL_UpdateEntry ( Database db , DBResultSet results , const char [ ] error , int Serial )
2023-02-02 00:19:27 +01:00
{
if ( ! db | | strlen ( error ) )
{
LogError ( " Database error: %s " , error ) ;
2023-04-30 12:14:28 +02:00
delete results ;
return ;
}
int client ;
if ( ( client = GetClientFromSerial ( Serial ) ) = = 0 )
{
delete results ;
2023-02-02 00:19:27 +01:00
return ;
}
2023-02-03 01:44:45 +01:00
if ( IsValidClient ( client ) )
{
char sQuery [ g_dLength ] ;
char sSID [ MAX_NAME_LENGTH ] ;
2023-02-07 20:45:15 +01:00
char sIP [ MAX_NAME_LENGTH ] ;
GetClientIP ( client , sIP , sizeof ( sIP ) ) ;
2023-02-03 01:44:45 +01:00
GetClientAuthId ( client , AuthId_Steam2 , sSID , sizeof ( sSID ) ) ;
2023-06-25 17:21:34 +02:00
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 ) ;
2023-02-03 01:44:45 +01:00
//PrintToChatAll("sQuery: %s", sQuery);
2023-04-30 12:14:28 +02:00
g_dDatabase . Query ( SQL_FindFingerPrints , sQuery , GetClientSerial ( client ) , DBPrio_Low ) ;
2023-02-03 01:44:45 +01:00
}
delete results ;
}
2023-04-30 12:14:28 +02:00
public void SQL_FindFingerPrints ( Database db , DBResultSet results , const char [ ] error , int Serial )
2023-02-03 01:44:45 +01:00
{
if ( ! db | | strlen ( error ) )
{
LogError ( " Database error: %s " , error ) ;
2023-04-30 12:14:28 +02:00
delete results ;
return ;
}
int client ;
if ( ( client = GetClientFromSerial ( Serial ) ) = = 0 )
{
delete results ;
return ;
}
if ( ! IsValidClient ( client ) )
{
delete results ;
2023-02-03 01:44:45 +01:00
return ;
}
2023-06-20 23:47:39 +02:00
2023-06-25 17:21:34 +02:00
//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 ( " ) ;
2023-06-20 23:47:39 +02:00
bool first = true ;
2023-02-07 20:45:15 +01:00
while ( results . RowCount > 0 & & results . FetchRow ( ) )
2023-02-03 01:44:45 +01:00
{
2023-06-20 23:47:39 +02:00
char fingerprint [ 1024 ] ;
2023-02-03 01:44:45 +01:00
results . FetchString ( 0 , fingerprint , sizeof ( fingerprint ) ) ;
char [ ] sEscapedFingerPrint = new char [ 1024 ] ;
g_dDatabase . Escape ( fingerprint , sEscapedFingerPrint , 1024 ) ;
2023-06-20 23:47:39 +02:00
if ( first )
{
Format ( sEscapedFingerPrint , 1024 , " '%s' " , sEscapedFingerPrint ) ;
}
else
2023-02-07 20:45:15 +01:00
{
2023-06-20 23:47:39 +02:00
Format ( sEscapedFingerPrint , 1024 , " ,'%s' " , sEscapedFingerPrint ) ;
2023-02-07 20:45:15 +01:00
}
2023-06-20 23:47:39 +02:00
StrCat ( sQuery , sizeof ( sQuery ) , sEscapedFingerPrint ) ;
first = false ;
2023-02-03 01:44:45 +01:00
}
2023-06-25 17:21:34 +02:00
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 )
2023-02-03 01:44:45 +01:00
{
2023-06-25 17:21:34 +02:00
g_dDatabase . Query ( sql_select_sb_bans , sQuery , GetClientSerial ( client ) , DBPrio_Low ) ;
2023-06-20 23:47:39 +02:00
}
2023-02-03 01:44:45 +01:00
delete results ;
}
2023-04-30 12:14:28 +02:00
public void sql_select_sb_bans ( Database db , DBResultSet results , const char [ ] error , int Serial )
2023-02-03 01:44:45 +01:00
{
if ( ! db | | strlen ( error ) )
{
2023-04-30 12:14:28 +02:00
delete results ;
2023-06-25 17:21:34 +02:00
LogError ( " Database error 2: %s " , error ) ;
2023-02-03 01:44:45 +01:00
return ;
}
2023-04-30 12:14:28 +02:00
int client ;
if ( ( client = GetClientFromSerial ( Serial ) ) = = 0 )
{
delete results ;
return ;
}
2023-02-03 01:44:45 +01:00
if ( ! IsValidClient ( client ) )
{
delete results ;
return ;
}
2023-02-07 20:45:15 +01:00
if ( results . RowCount & & results . FetchRow ( ) & & IsValidClient ( client ) & & ! g_bReportedClientBanAvoiding [ client ] )
2023-02-03 01:44:45 +01:00
{
2023-02-07 20:45:15 +01:00
g_bReportedClientBanAvoiding [ client ] = true ;
2023-02-03 01:44:45 +01:00
char sSID [ MAX_NAME_LENGTH ] ;
char sIP [ MAX_NAME_LENGTH ] ;
results . FetchString ( 0 , sSID , sizeof ( sSID ) ) ;
results . FetchString ( 1 , sIP , sizeof ( sIP ) ) ;
2023-02-03 11:38:47 +01:00
Call_StartForward ( g_hOnReportBanPostForward ) ;
Call_PushCell ( client ) ;
2023-02-03 01:44:45 +01:00
if ( strlen ( sSID ) = = 0 )
{
2023-02-03 11:38:47 +01:00
// use IP instead if no steamID
Call_PushString ( sIP ) ;
2023-02-03 01:44:45 +01:00
}
2023-02-03 11:38:47 +01:00
else
{
//found steamID
Call_PushString ( sSID ) ;
}
Call_Finish ( ) ;
2023-02-14 21:29:45 +01:00
//bans need to be over 1 hour long for getting detected
2023-07-08 23:55:50 +02:00
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 ) ;
}
2023-02-03 01:44:45 +01:00
}
delete results ;
2023-02-02 00:19:27 +01:00
}
public Action start_checks ( Handle hTimer )
2023-06-18 20:34:45 +02:00
{
for ( int i = 0 ; i < MaxClients ; i + + )
{
if ( IsValidClient ( i ) & & validate_state [ i ] = = 0 )
{
validate_state [ i ] = - 1 ;
SQL_addEntry ( i ) ;
}
}
}
public void OnMapStart ( )
2023-02-02 00:19:27 +01:00
{
if ( ! g_dDatabase )
{
Database . Connect ( SQL_OnDatabaseConnect , " jenz_ban_detector " ) ;
}
}
public void OnClientDisconnect ( int client )
{
validate_state [ client ] = - 1 ;
2023-02-07 20:45:15 +01:00
g_bReportedClientBanAvoiding [ client ] = false ;
2023-02-02 00:19:27 +01:00
}
public void OnClientPostAdminCheck ( int client )
{
validate_state [ client ] = - 1 ;
2023-04-30 15:21:36 +02:00
CreateTimer ( 10.0 , make_db_entry , GetClientSerial ( client ) ) ;
2023-02-07 20:45:15 +01:00
g_bReportedClientBanAvoiding [ client ] = false ;
2023-02-02 00:19:27 +01:00
}
2023-04-30 15:21:36 +02:00
public Action make_db_entry ( Handle hTimer , int Serial )
2023-02-02 00:19:27 +01:00
{
2023-04-30 15:21:36 +02:00
int client ;
if ( ( client = GetClientFromSerial ( Serial ) ) = = 0 )
{
return ;
}
2023-02-02 00:19:27 +01:00
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 ;
}