sm-plugins/FakeClients/scripting/FakeClients.sp

702 lines
18 KiB
SourcePawn
Executable File

#include <sourcemod>
#include <sdktools>
#include <zombiereloaded>
#include <BotTargeting>
#include <cstrike>
#pragma semicolon 1
#pragma newdecls required
#define MAXNAMES 500
ArrayList g_hNames;
ArrayList g_hClanNames;
bool g_bFakePopulation[MAXPLAYERS + 1];
bool g_bMapEnded;
int g_iBaseLatency[MAXPLAYERS + 1];
int g_iLatency[MAXPLAYERS + 1];
int g_iAdminFakes;
int g_iPopulation;
bool g_bCheckRequested;
bool g_bBlockInstantFakeConnects;
Database g_hDatabase;
Database g_hDatabase_hlstats;
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Plugin myinfo =
{
name = "ImprovedHitboxes", //camouflage
author = "Neon + Dogan + Botox",
description = "Handle Hitboxes via Plugin",
version = "5.3.1",
url = "https://steamcommunity.com/id/n3ontm"
};
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnPluginStart()
{
RegAdminCmd("sm_debugfakes", Command_DebugFakes, ADMFLAG_GENERIC, "Shows the amount of fake-clients on server");
RegAdminCmd("sm_fakes", Command_Fakes, ADMFLAG_GENERIC, "Shows the fake-clients on server");
RegAdminCmd("sm_setfakes", Command_SetFakes, ADMFLAG_RCON, "Manually sets the amount of fake-clients");
int arraySize = ByteCountToCells(MAX_NAME_LENGTH);
g_hNames = CreateArray(arraySize);
g_hClanNames = CreateArray(arraySize);
g_iAdminFakes = -1;
g_iPopulation = GetClientCount(false);
for(int i = 1; i <= MaxClients; i++)
{
if(IsClientConnected(i) && IsFakeClient(i))
g_iPopulation--;
}
g_bMapEnded = false;
g_bBlockInstantFakeConnects = false;
CreateTimer(40.0, BlockInstantFakeConnects, _, TIMER_REPEAT);
CreateTimer(3.0, RandomizePing, _, TIMER_REPEAT);
CreateTimer(150.0, RandomizeNames, _, TIMER_REPEAT);
HookUserMessage(GetUserMessageId("SayText2"), UserMessage_SayText2, true);
RequestFrame(CheckPopulation);
if (!g_hDatabase)
{
Database.Connect(SQL_OnDatabaseConnect, "racetimercss");
}
if (!g_hDatabase_hlstats)
{
Database.Connect(SQL_OnDatabaseConnect_hlstats, "hlstatsx");
}
}
public void SQL_OnDatabaseConnect_hlstats(Database db, const char[] error, any data)
{
if(!db || strlen(error))
{
LogError("Database error: %s", error);
return;
}
g_hDatabase_hlstats = db;
randomize_clantags();
}
public void randomize_clantags()
{
char sQuery[512];
Format(sQuery, sizeof(sQuery), "select DISTINCT tag from unloze_stats.hlstats_Clans ORDER BY RAND() limit 500");
g_hDatabase_hlstats.Query(SQL_OnQueryCompleted_hlstats, sQuery, DBPrio_High);
}
public void SQL_OnDatabaseConnect(Database db, const char[] error, any data)
{
if(!db || strlen(error))
{
LogError("Database error: %s", error);
return;
}
g_hDatabase = db;
randomize_names();
}
public void randomize_names()
{
char sQuery[512];
Format(sQuery, sizeof(sQuery), "select name from unloze_racetimer_css.random_names ORDER BY RAND() limit 500");
g_hDatabase.Query(SQL_OnQueryCompleted, sQuery, DBPrio_High);
}
public void SQL_OnQueryCompleted_hlstats(Database db, DBResultSet results, const char[] error, int iSerial)
{
if (!db || strlen(error))
{
delete results;
LogError("Query error for hlstats: %s", error);
if (!g_hDatabase_hlstats)
{
Database.Connect(SQL_OnDatabaseConnect_hlstats, "hlstatsx");
}
return;
}
while (results.RowCount && results.FetchRow())
{
char sName[MAX_NAME_LENGTH];
results.FetchString(0, sName, sizeof(sName));
g_hClanNames.PushString(sName);
}
delete results;
}
public void SQL_OnQueryCompleted(Database db, DBResultSet results, const char[] error, int iSerial)
{
if (!db || strlen(error))
{
delete results;
LogError("Query error for racetimer: %s", error);
if (!g_hDatabase)
{
Database.Connect(SQL_OnDatabaseConnect, "racetimercss");
}
return;
}
while (results.RowCount && results.FetchRow())
{
char sName[MAX_NAME_LENGTH];
results.FetchString(0, sName, sizeof(sName));
g_hNames.PushString(sName);
}
delete results;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnPluginEnd()
{
for(int i = 1; i <= MaxClients; i++)
{
if(g_bFakePopulation[i])
{
g_bFakePopulation[i] = false;
g_iLatency[i] = 0;
KickClient(i, "Disconnect by user.");
}
}
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnMapStart()
{
g_hNames.Clear();
g_hClanNames.Clear();
if (!g_hDatabase)
{
Database.Connect(SQL_OnDatabaseConnect, "racetimercss");
}
else
{
randomize_names();
}
if (!g_hDatabase_hlstats)
{
Database.Connect(SQL_OnDatabaseConnect_hlstats, "hlstatsx");
}
else
{
randomize_clantags();
}
/*
char sFile[PLATFORM_MAX_PATH];
char sLine[MAX_NAME_LENGTH];
BuildPath(Path_SM, sFile, sizeof(sFile), "configs/fakeclients_names.txt");
Handle hFile = OpenFile(sFile, "r");
if(hFile != INVALID_HANDLE)
{
int iLine = 0;
g_hNames.Clear();
while (!IsEndOfFile(hFile))
{
if (!ReadFileLine(hFile, sLine, sizeof(sLine)) || iLine >= MAXNAMES)
break;
TrimString(sLine);
g_hNames.PushString(sLine);
iLine++;
}
delete hFile;
}
else
SetFailState("Could not open file: configs/fakeclients_names.txt");
*/
g_bMapEnded = false;
g_bBlockInstantFakeConnects = false;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnMapEnd()
{
g_bMapEnded = true;
g_iAdminFakes = -1;
g_iPopulation = GetClientCount(false);
for(int i = 1; i <= MaxClients; i++)
{
if(IsClientConnected(i) && IsFakeClient(i))
g_iPopulation--;
}
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Action BlockInstantFakeConnects(Handle timer)
{
g_bBlockInstantFakeConnects = false;
RequestFrame(CheckPopulation);
return Plugin_Continue;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Action RandomizePing(Handle timer)
{
for(int i = 1; i <= MaxClients; i++)
{
if(g_bFakePopulation[i])
g_iLatency[i] = g_iBaseLatency[i] + GetRandomInt(-3, 3);
}
return Plugin_Continue;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Action RandomizeNames(Handle timer)
{
if (g_hNames.Length == 0 || g_hClanNames.Length == 0)
{
return Plugin_Handled;
}
ArrayList hNames = g_hNames.Clone();
ArrayList hClanNames = g_hClanNames.Clone();
for(int i = 1; i <= MaxClients; i++)
{
if(g_bFakePopulation[i] || (IsClientConnected(i) && IsClientInGame(i) && IsClientAuthorized(i) && IsClientAutismBot(i)))
{
int iRand = GetRandomInt(0, hNames.Length - 1);
char sName[MAX_NAME_LENGTH];
hNames.GetString(iRand, sName, sizeof(sName));
hNames.Erase(iRand);
SetClientName(i, sName);
if (GetRandomInt(0, 5) >= 3)
{
int iRandClans = GetRandomInt(0, hClanNames.Length - 1);
hClanNames.GetString(iRandClans, sName, sizeof(sName));
hClanNames.Erase(iRandClans);
CS_SetClientClanTag(i, sName);
}
else
{
CS_SetClientClanTag(i, "");
}
}
}
delete hNames;
delete hClanNames;
return Plugin_Continue;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Action UserMessage_SayText2(UserMsg msg_id, BfRead msg, const int[] players, int playersNum, bool reliable, bool init)
{
if(!reliable)
return Plugin_Continue;
int client;
char sMessage[32];
if(GetUserMessageType() == UM_Protobuf) //fuck cs go but "ClEaN CoDe"
{
PbReadString(msg, "msg_name", sMessage, sizeof(sMessage));
if(!(sMessage[0] == '#' && StrContains(sMessage, "Name_Change")))
return Plugin_Continue;
client = PbReadInt(msg, "ent_idx");
}
else
{
client = BfReadByte(msg);
BfReadByte(msg);
BfReadString(msg, sMessage, sizeof(sMessage));
if(!(sMessage[0] == '#' && StrContains(sMessage, "Name_Change")))
return Plugin_Continue;
}
if(g_bFakePopulation[client] || (IsClientConnected(client) && IsClientInGame(client) && IsClientAutismBot(client)))
return Plugin_Handled;
return Plugin_Continue;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Action Command_DebugFakes(int client, int argc)
{
int iFakes = 0;
int iFakesInTeam = 0;
int iPlayers = GetClientCount(false);
for(int i = 1; i <= MaxClients; i++)
{
if (g_bFakePopulation[i])
iFakes++;
if (g_bFakePopulation[i] && GetClientTeam(i) > 0)
iFakesInTeam++;
if(IsClientConnected(i) && IsFakeClient(i))
iPlayers--;
}
ReplyToCommand(client, "[SM] There are currently %d Fake-Clients, from which %d are in Spectate.", iFakes, iFakes - iFakesInTeam);
ReplyToCommand(client, "[SM] Server Population at the end of the previous Map: %d.", g_iPopulation);
ReplyToCommand(client, "[SM] Current Server Population: %d. Difference: %d.", iPlayers, iPlayers - g_iPopulation);
return Plugin_Handled;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Action Command_SetFakes(int client, int argc)
{
if (argc < 1)
{
ReplyToCommand(client, "[SM] Usage: sm_setfakes <amount of fakes>");
return Plugin_Handled;
}
char sArgs[16];
GetCmdArg(1, sArgs, sizeof(sArgs));
if (!StringToIntEx(sArgs, g_iAdminFakes))
{
ReplyToCommand(client, "[SM] Invalid value");
return Plugin_Handled;
}
ReplyToCommand(client, "[SM] You set the amount of Fake-Clients to %d.", g_iAdminFakes);
CheckPopulation();
return Plugin_Handled;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Action Command_Fakes(int client, int args)
{
char aBuf[1024];
char aBuf2[MAX_NAME_LENGTH];
for(int i = 1; i <= MaxClients; i++)
{
if(IsClientInGame(i))
{
if(g_bFakePopulation[i])
{
GetClientName(i, aBuf2, sizeof(aBuf2));
StrCat(aBuf, sizeof(aBuf), aBuf2);
StrCat(aBuf, sizeof(aBuf), ", ");
}
}
}
if(strlen(aBuf))
{
aBuf[strlen(aBuf) - 2] = 0;
ReplyToCommand(client, "[SM] Fake-Clients online: %s", aBuf);
}
else
ReplyToCommand(client, "[SM] Fake-Clients online: none");
return Plugin_Handled;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnClientConnected(int client)
{
if (!g_bCheckRequested && !IsFakeClient(client))
{
RequestFrame(CheckPopulation);
g_bCheckRequested = true;
}
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnClientDisconnect(int client)
{
if (client > 0)
{
if(g_bFakePopulation[client])
{
g_bFakePopulation[client] = false;
g_iLatency[client] = 0;
}
if (!g_bCheckRequested && !IsFakeClient(client))
{
RequestFrame(CheckPopulation);
g_bCheckRequested = true;
}
}
}
public Action repeatCheckPopulation(Handle timer)
{
CheckPopulation();
return Plugin_Continue;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void CheckPopulation()
{
if (g_hNames.Length == 0 || g_hClanNames.Length == 0)
{
CreateTimer(5.0, repeatCheckPopulation);
return;
}
g_bCheckRequested = false;
if(g_bMapEnded)
return;
int iPlayers = GetClientCount(false);
for(int i = 1; i <= MaxClients; i++)
{
if(IsClientConnected(i) && IsFakeClient(i))
iPlayers--;
}
int iFakes = 0;
int iFakesInTeam = 0;
for(int i = 1; i <= MaxClients; i++)
{
if (g_bFakePopulation[i])
iFakes++;
}
int iFakesNeeded = 0;
int iFakesInTeamNeeded = 0;
int max = 2;
int min = 1;
if (iPlayers == 1)
{
max = iPlayers * 5;
min = 3;
}
else if (iPlayers < 6)
{
max = iPlayers * 5;
min = iPlayers * 2;
}
else if (iPlayers < 11)
{
max = RoundToFloor(iPlayers * 1.5);
min = iPlayers;
}
else if (iPlayers < 20)
{
max = iPlayers;
min = RoundToFloor(iPlayers * 0.5);
}
else if (iPlayers < 26)
{
max = iPlayers;
min = RoundToFloor(iPlayers * 0.3);
}
else if (iPlayers < 36)
{
max = RoundToFloor(iPlayers * 0.5);
min = RoundToFloor(iPlayers * 0.3);
}
else
{
max = RoundToFloor(iPlayers * 0.3);
min = RoundToFloor(iPlayers * 0.1);
}
iFakesNeeded = GetRandomInt(min, max);
//iFakesNeeded = randomAmount - iPlayers;
if (iFakesNeeded < 0 || iPlayers > 50)
{
iFakesNeeded = 0;
iFakesInTeamNeeded = 0;
}
else
{
iFakesInTeamNeeded = iFakesNeeded / 3;
}
if (iFakesInTeamNeeded < 0)
{
iFakesInTeamNeeded = 0;
}
if(g_iAdminFakes != -1)
iFakesNeeded = g_iAdminFakes;
if (iFakes != iFakesNeeded)
{
while (iFakes < iFakesNeeded && !g_bBlockInstantFakeConnects)
{
ArrayList hNames = g_hNames.Clone();
char sName[MAX_NAME_LENGTH];
for(int i = 1; i <= MaxClients; i++)
{
if(g_bFakePopulation[i])
{
GetClientName(i, sName, sizeof(sName));
int iPos = hNames.FindString(sName);
if (iPos > -1)
hNames.Erase(iPos);
}
}
int iRand = GetRandomInt(0, hNames.Length - 1);
hNames.GetString(iRand, sName, sizeof(sName));
delete hNames;
int iIndex = CreateFakeClient(sName);
if(iIndex < 1 || iIndex > MaxClients)
return;
SetEntityFlags(iIndex, FL_CLIENT);
DispatchKeyValue(iIndex, "classname", "player");
DispatchSpawn(iIndex);
g_bFakePopulation[iIndex] = true;
g_iBaseLatency[iIndex] = GetRandomInt(20, 110);
g_iLatency[iIndex] = g_iBaseLatency[iIndex];
AdminId FakeAdmin = CreateAdmin();
SetAdminFlag(FakeAdmin, Admin_Custom6, true);
SetUserAdmin(iIndex, FakeAdmin, true);
if (GetRandomInt(0, 5) >= 3)
{
ArrayList hClanNames = g_hClanNames.Clone();
iRand = GetRandomInt(0, hClanNames.Length - 1);
hClanNames.GetString(iRand, sName, sizeof(sName));
delete hClanNames;
CS_SetClientClanTag(iIndex, sName);
}
else
{
CS_SetClientClanTag(iIndex, "");
}
iFakes++;
g_bBlockInstantFakeConnects = true;
}
while (iFakes > iFakesNeeded)
{
for(int i = 1; i <= MaxClients; i++)
{
if(g_bFakePopulation[i])
{
g_bFakePopulation[i] = false;
g_iLatency[i] = 0;
KickClient(i, "Disconnect by user.");
iFakes--;
break;
}
}
}
}
for(int i = 1; i <= MaxClients; i++)
{
if (g_bFakePopulation[i] && GetClientTeam(i) >= CS_TEAM_T)
iFakesInTeam++;
}
if (iFakes == iFakesNeeded && iFakesInTeam != iFakesInTeamNeeded && g_iAdminFakes == -1)
{
while (iFakesInTeam < iFakesInTeamNeeded)
{
for(int i = 1; i <= MaxClients; i++)
{
if(g_bFakePopulation[i] && GetClientTeam(i) <= CS_TEAM_SPECTATOR)
{
ChangeClientTeam(i, CS_TEAM_CT);
FakeClientCommandEx(i, "joinclass");
iFakesInTeam++;
break;
}
}
}
while (iFakesInTeam > iFakesInTeamNeeded)
{
for(int i = 1; i <= MaxClients; i++)
{
if(g_bFakePopulation[i] && GetClientTeam(i) >= CS_TEAM_T)
{
ChangeClientTeam(i, CS_TEAM_SPECTATOR);
iFakesInTeam--;
break;
}
}
}
}
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnGameFrame()
{
for(int i = 1; i <= MaxClients; i++)
{
if(g_bFakePopulation[i])
{
int iResEnt = GetPlayerResourceEntity();
if(iResEnt == -1)
return;
SetEntProp(iResEnt, Prop_Send, "m_iPing", g_iLatency[i], _, i);
}
}
}
/*
public Action ZR_OnClientMotherZombieEligible(int client)
{
if (g_bFakePopulation[client])
return Plugin_Handled;
return Plugin_Continue;
}
*/