293 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
			
		
		
	
	
			293 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
| #pragma semicolon 1
 | |
| #define PLUGIN_AUTHOR "jenz"
 | |
| #define g_dLength 400
 | |
| #define PLUGIN_VERSION "1.1"
 | |
| #pragma newdecls required
 | |
| 
 | |
| #include <sourcemod>
 | |
| #include <sourcebanspp>
 | |
| #include <clientprefs>
 | |
| #include <cstrike>
 | |
| #include <sdktools>
 | |
| 
 | |
| Database g_dDatabase;
 | |
| int g_disable_html_motd[MAXPLAYERS + 1];
 | |
| Handle g_hOnReportBanPostForward;
 | |
| 
 | |
| 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");
 | |
|     }
 | |
| }
 | |
| 
 | |
| public void OnMapStart()
 | |
| {
 | |
|     if (!g_dDatabase)
 | |
|     {
 | |
|         Database.Connect(SQL_OnDatabaseConnect, "jenz_ban_detector");
 | |
|     }
 | |
| }
 | |
| 
 | |
| 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 OnClientDisconnect(int client)
 | |
| {
 | |
|     g_disable_html_motd[client] = 0;
 | |
| }
 | |
| 
 | |
| public void OnClientPostAdminCheck(int client)
 | |
| {
 | |
|     g_disable_html_motd[client] = 0;
 | |
|     if (!IsFakeClient(client) && !IsClientSourceTV(client))
 | |
|     {
 | |
|         SQL_addEntry(client);
 | |
|     }
 | |
| }
 | |
| 
 | |
| 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 ignore into `ban_detector` (`steamid`, `ip`, `name`) SELECT '%s', '%s','%s'", sSID, sIP,sEscapedName);
 | |
|     Format(sQuery, sizeof(sQuery), "insert ignore into `ban_detector` (`steamid`, `ip`, `name`) SELECT '%s', '%s','%s'", sSID, sIP,sEscapedName);
 | |
|     g_dDatabase.Query(SQL_callback_insert_ignore, sQuery, GetClientSerial(client), DBPrio_Low);
 | |
| }
 | |
| 
 | |
| public void SQL_callback_insert_ignore(Database db, DBResultSet results, const char[] error, int Serial)
 | |
| {
 | |
|     if(!db || strlen(error))
 | |
|     {
 | |
|         LogError("Database error: %s", error);
 | |
|         delete results;
 | |
|         return;
 | |
|     }
 | |
|     delete results;
 | |
| 
 | |
|     int client; 
 | |
|     if ((client = GetClientFromSerial(Serial)) == 0)
 | |
|     {
 | |
|         return;
 | |
|     }
 | |
|     if (IsValidClient(client))
 | |
|     {
 | |
|         QueryClientConVar(client, "cl_disablehtmlmotd", CvarQueryFinished);
 | |
|     }
 | |
| }
 | |
| 
 | |
| public void CvarQueryFinished(QueryCookie cookie, int client, ConVarQueryResult res, const char[] sCvarName, const char[] sCvarVal)
 | |
| {
 | |
|     if (res != ConVarQuery_Okay)
 | |
|     {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     int disable_html_motd = StringToInt(sCvarVal);
 | |
|     if (IsValidClient(client))
 | |
|     {
 | |
|         g_disable_html_motd[client] = disable_html_motd;
 | |
|         char sQuery[g_dLength];
 | |
|         char sSID[MAX_NAME_LENGTH];
 | |
|         GetClientAuthId(client, AuthId_Steam2, sSID, sizeof(sSID));
 | |
|         Format(sQuery, sizeof(sQuery), "UPDATE ban_detector SET last_connect = now(), disable_html_motd = '%i' where steamid = '%s'", disable_html_motd, sSID);
 | |
|         g_dDatabase.Query(SQL_callback_update, sQuery, GetClientSerial(client), DBPrio_Low);
 | |
|     }
 | |
| }
 | |
| 
 | |
| public void SQL_callback_update(Database db, DBResultSet results, const char[] error, int Serial)
 | |
| {
 | |
|     if(!db || strlen(error))
 | |
|     {
 | |
|         LogError("Database error: %s", error);
 | |
|         delete results;
 | |
|         return;
 | |
|     }
 | |
|     delete results;
 | |
| 
 | |
|     int client; 
 | |
|     if ((client = GetClientFromSerial(Serial)) == 0)
 | |
|     {
 | |
|         return;
 | |
|     }
 | |
|     if (IsValidClient(client) && !g_disable_html_motd[client])
 | |
|     {
 | |
|         CreateTimer(7.0, re_open_motd, Serial);
 | |
|     }
 | |
| }
 | |
| 
 | |
| public Action re_open_motd(Handle hTimer, int Serial)
 | |
| {
 | |
|     int client; 
 | |
|     if ((client = GetClientFromSerial(Serial)) == 0)
 | |
|     {
 | |
|         return Plugin_Handled;
 | |
|     }
 | |
|     if (IsValidClient(client))
 | |
|     {
 | |
|         //reopening the menu again after info got stored. it still generates the same fingerprint despite not showing the client any menu.
 | |
|         Handle panel = CreateKeyValues("data");
 | |
|         KvSetString(panel, "title", "");
 | |
|         KvSetString(panel, "type", "2");
 | |
|         KvSetString(panel, "msg", "https://unloze.com/motd/CSS_ZE_MOTD.html");
 | |
|         ShowVGUIPanel(client, "info", panel, false);
 | |
|         CloseHandle(panel);
 | |
|         CreateTimer(5.0, SQL_Select_fingerprints, Serial);
 | |
|     }
 | |
|     return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| public Action SQL_Select_fingerprints(Handle hTimer, int Serial)
 | |
| {
 | |
|     int client; 
 | |
|     if ((client = GetClientFromSerial(Serial)) == 0)
 | |
|     {
 | |
|         return Plugin_Handled;
 | |
|     }
 | |
|     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));
 | |
|         //steamID is unique but fingerprint might occur multiple times.
 | |
|         Format(sQuery, sizeof(sQuery), "select steamid from ban_detector.ban_detector where fingerprint = (select fingerprint from ban_detector.ban_detector where steamid = '%s' and fingerprint is not null and length(fingerprint) > 5)", sSID);
 | |
|         //PrintToChatAll("sQuery: %s", sQuery);
 | |
|         g_dDatabase.Query(SQL_FindFingerPrints, sQuery, Serial, DBPrio_Low);
 | |
|     }
 | |
|     return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| 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 authid from unloze_sourceban.sb_bans where authid in (");
 | |
| 
 | |
|     //cant rely on IP cause several chinese players share VPN and end up with same IP despite clearly being different people. 
 | |
|     //now instead of fingerprint returns all steam IDs related to the specific fingerprint.
 | |
|     bool first = true;
 | |
|     while (results.RowCount > 0 && results.FetchRow())
 | |
|     {
 | |
|         char steamid[64];
 | |
|         results.FetchString(0, steamid, sizeof(steamid));
 | |
|         if (first)
 | |
|         {
 | |
|             Format(steamid, sizeof(steamid), "'%s'", steamid);
 | |
|             StrCat(sQuery, sizeof(sQuery), steamid);
 | |
|             first = false;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             Format(steamid, sizeof(steamid), ",'%s'", steamid);
 | |
|             StrCat(sQuery, sizeof(sQuery), steamid);
 | |
|         }
 | |
|     }
 | |
|     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");
 | |
|     delete results;
 | |
|     if (!first)
 | |
|     {
 | |
|         g_dDatabase.Query(sql_select_sb_bans, sQuery, Serial, DBPrio_Low);
 | |
|     }
 | |
| }
 | |
| 
 | |
| 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 we get a result its a steam ID that still has an active ban. the steam ID that is banned is confirmed to have the same fingerprint as the connecting client.
 | |
|     if (results.RowCount && results.FetchRow())
 | |
|     {
 | |
|         char sSID[MAX_NAME_LENGTH];
 | |
|         results.FetchString(0, sSID, sizeof(sSID));    
 | |
|         Call_StartForward(g_hOnReportBanPostForward);
 | |
|         Call_PushCell(client);
 | |
|         Call_PushString(sSID);
 | |
|         Call_Finish();
 | |
|         //bans need to be over 1 hour long for getting detected
 | |
|         char message[1024];
 | |
|         Format(message, sizeof(message), "Ban avoiding (Jenz ban detector). SteamID avoiding ban: %s", sSID);
 | |
|         //instead of permaban now just banning the alt account for circa 3 months.
 | |
|         SBPP_BanPlayer(0, client, 131487, message);
 | |
|         //first parameter is client doing the ban, should be 0 so its console.
 | |
|         //second parameter is the target getting banned
 | |
|         //third parameter was the actual timevalue.
 | |
|     }
 | |
|     delete results;
 | |
| }
 | |
| 
 | |
| stock bool IsValidClient(int client)
 | |
| {
 | |
|     if (client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client) && !IsFakeClient(client))
 | |
|         return true;
 | |
|     return false;
 | |
| }
 |