#include #include #include #include #include #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 "); 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; } */