551 lines
16 KiB
SourcePawn
Executable File
551 lines
16 KiB
SourcePawn
Executable File
#pragma semicolon 1
|
|
#pragma newdecls required
|
|
#define DEBUG
|
|
|
|
#define PLUGIN_AUTHOR "jenz"
|
|
#define PLUGIN_VERSION "1.9"
|
|
#define generic_length 256
|
|
|
|
#include <sourcemod>
|
|
#include <sdktools>
|
|
#include <AFKManager>
|
|
#include <sdkhooks>
|
|
#include <cstrike>
|
|
#include <socket>
|
|
#include <UNLOZE.secret>
|
|
|
|
int target_client[5]; //4 autism bots.
|
|
|
|
#define BUFFER_SIZE 198 // ~2 seconds at 66 tick
|
|
enum struct FrameData {
|
|
int buttons;
|
|
float vel[3];
|
|
float angles[3];
|
|
int impulse;
|
|
}
|
|
|
|
FrameData g_Buffer[MAXPLAYERS+1][BUFFER_SIZE];
|
|
int g_WriteHead[MAXPLAYERS+1]; // where were writing next
|
|
int g_FrameCount[MAXPLAYERS+1]; // total frames captured
|
|
int g_DelayTicks = 128; // delay
|
|
|
|
int ports[7] = {48470, 48471, 48472, 48473, 48474, 48479, 48480}; //last three indexes are ports its sending udp from in plugin
|
|
int server_ports[2] = {27015, 27035}; //server ports: ze, ze2
|
|
|
|
bool chat_cooldown = false;
|
|
|
|
//socket for bot input
|
|
Handle global_socket;
|
|
|
|
//timer handle
|
|
Handle g_hTimer_pressing = null;
|
|
Handle g_hTimer_bot_connect = null;
|
|
|
|
int specific_bot_player[MAXPLAYERS + 1];
|
|
|
|
public Plugin myinfo =
|
|
{
|
|
name = "autism bot simulate player movement",
|
|
author = PLUGIN_AUTHOR,
|
|
description = "just copies player movement to the autism bots",
|
|
version = PLUGIN_VERSION,
|
|
url = ""
|
|
};
|
|
|
|
public void OnPluginStart()
|
|
{
|
|
//talking
|
|
RegConsoleCmd("sm_autism", cmd_talk, "talking to the bot through java application");
|
|
RegConsoleCmd("sm_botrtv", cmd_botrtv, "making bots rtv");
|
|
|
|
HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy);
|
|
|
|
//UDP connection
|
|
connect_socket();
|
|
chat_cooldown = false;
|
|
|
|
g_hTimer_bot_connect = CreateTimer(90.0, bot_check_connect, _, TIMER_REPEAT);
|
|
g_hTimer_pressing = CreateTimer(2.0, check_team, _, TIMER_REPEAT);
|
|
|
|
target_client[1] = -1;
|
|
target_client[2] = -1;
|
|
target_client[3] = -1;
|
|
target_client[4] = -1;
|
|
|
|
for (int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if (IsValidClient(i))
|
|
{
|
|
OnClientPostAdminCheck(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void OnPluginEnd()
|
|
{
|
|
if (g_hTimer_pressing != null)
|
|
{
|
|
delete g_hTimer_pressing;
|
|
}
|
|
if (g_hTimer_bot_connect != null)
|
|
{
|
|
delete g_hTimer_bot_connect;
|
|
}
|
|
}
|
|
|
|
public void OnMapEnd()
|
|
{
|
|
int autism_bot_counter = 0;
|
|
for (int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if (IsValidClient(i) && specific_bot_player[i] != -1)
|
|
{
|
|
autism_bot_counter++;
|
|
}
|
|
}
|
|
for (int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if (autism_bot_counter <= 1)
|
|
{
|
|
break;
|
|
}
|
|
if (IsValidClient(i) && specific_bot_player[i] != -1)
|
|
{
|
|
KickClient(i);
|
|
autism_bot_counter--;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void OnPlayerRunCmdPost(int client, int buttons, int impulse, const float vel[3], const float angles[3], int weapon, int subtype, int cmdnum, int tickcount, int seed, const int mouse[2])
|
|
{
|
|
if (!IsValidClient(client) || IsFakeClient(client))
|
|
{
|
|
return;
|
|
}
|
|
int head = g_WriteHead[client];
|
|
g_Buffer[client][head].buttons = buttons;
|
|
g_Buffer[client][head].impulse = impulse;
|
|
g_Buffer[client][head].vel = vel;
|
|
g_Buffer[client][head].angles = angles;
|
|
|
|
g_WriteHead[client] = (head + 1) % BUFFER_SIZE;
|
|
g_FrameCount[client]++;
|
|
}
|
|
|
|
public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3], float angles[3], int& weapon, int& subtype, int& cmdnum, int& tickcount, int& seed, int mouse[2])
|
|
{
|
|
if (specific_bot_player[client] == -1 || !IsValidClient(target_client[specific_bot_player[client]]))
|
|
{
|
|
return Plugin_Continue;
|
|
}
|
|
int target = target_client[specific_bot_player[client]];
|
|
// Read from the slot that is DelayTicks behind current write head
|
|
int readSlot = (g_WriteHead[target] - g_DelayTicks + BUFFER_SIZE) % BUFFER_SIZE;
|
|
|
|
buttons = g_Buffer[target][readSlot].buttons;
|
|
impulse = g_Buffer[target][readSlot].impulse;
|
|
vel = g_Buffer[target][readSlot].vel;
|
|
angles = g_Buffer[target][readSlot].angles;
|
|
|
|
return Plugin_Changed;
|
|
}
|
|
|
|
public void Event_RoundStart(Handle event, const char[] name, bool dontBroadcast)
|
|
{
|
|
target_client[1] = -1;
|
|
target_client[2] = -1;
|
|
target_client[3] = -1;
|
|
target_client[4] = -1;
|
|
|
|
chat_cooldown = false;
|
|
for (int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if (IsValidClient(i) && IsPlayerAlive(i) && specific_bot_player[i] != -1)
|
|
{
|
|
for (int j = 1; j <= MaxClients; j++)
|
|
{
|
|
if (IsValidClient(j) && GetClientTeam(j) == GetClientTeam(i) && IsPlayerAlive(j) && GetClientIdleTime(j) < 20)
|
|
{
|
|
if (target_client[1] == j || target_client[2] == j || target_client[3] == j || target_client[4])
|
|
{
|
|
continue; //one of the autism bots already got this dude as their target.
|
|
}
|
|
float vec[3];
|
|
GetClientAbsOrigin(j, vec);
|
|
TeleportEntity(i, vec, NULL_VECTOR, NULL_VECTOR);
|
|
target_client[specific_bot_player[i]] = j;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void cmd_talk_help(int port, int client, char[] info)
|
|
{
|
|
char msg[generic_length * 5];
|
|
chat_cooldown = true;
|
|
char magic_code[16];
|
|
Format(magic_code, sizeof(magic_code), autism_bot_code); //included with unloze.secrets simply.
|
|
Format(msg, sizeof(msg), "clientmessage:%N %s %s", client, magic_code, info);
|
|
send_socket_msg(msg, strlen(msg), port);
|
|
CreateTimer(2.0, bot_chat_cooldown);
|
|
|
|
}
|
|
|
|
public void is_autism_bot1(int client)
|
|
{
|
|
char auth[50];
|
|
GetClientAuthId(client, AuthId_Engine, auth, sizeof(auth));
|
|
if (StrEqual("[U:1:120378081]", auth, false) || StrEqual("STEAM_0:1:60189040", auth, false))
|
|
{
|
|
specific_bot_player[client] = 1;
|
|
}
|
|
}
|
|
|
|
public void is_autism_bot2(int client)
|
|
{
|
|
char auth[50];
|
|
GetClientAuthId(client, AuthId_Engine, auth, sizeof(auth));
|
|
if (StrEqual("[U:1:1036189204]", auth, false) || StrEqual("STEAM_0:0:518094602", auth, false))
|
|
{
|
|
specific_bot_player[client] = 2;
|
|
}
|
|
}
|
|
|
|
public void is_autism_bot3(int client)
|
|
{
|
|
char auth[50];
|
|
GetClientAuthId(client, AuthId_Engine, auth, sizeof(auth));
|
|
if (StrEqual("[U:1:408797742]", auth, false) || StrEqual("STEAM_0:0:204398871", auth, false))
|
|
{
|
|
specific_bot_player[client] = 3;
|
|
}
|
|
}
|
|
|
|
public void is_autism_bot4(int client)
|
|
{
|
|
char auth[50];
|
|
GetClientAuthId(client, AuthId_Engine, auth, sizeof(auth));
|
|
if (StrEqual("[U:1:1221121532]", auth, false) || StrEqual("STEAM_0:0:610560766", auth, false))
|
|
{
|
|
specific_bot_player[client] = 4;
|
|
}
|
|
}
|
|
|
|
public Action cmd_botrtv(int client, int args)
|
|
{
|
|
if ((CheckCommandAccess(client, "sm_kick", ADMFLAG_KICK)) || (CheckCommandAccess(client, "sm_reserved", ADMFLAG_RESERVATION)))
|
|
{
|
|
for (int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if (IsValidClient(i) && specific_bot_player[i] != -1)
|
|
{
|
|
FakeClientCommandEx(i, "say rtv");
|
|
}
|
|
}
|
|
}
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
public Action cmd_talk(int client, int args)
|
|
{
|
|
char info[generic_length];
|
|
GetCmdArgString(info, sizeof(info));
|
|
|
|
if (strlen(info) == 0)
|
|
{
|
|
PrintToChat(client, "Add a message to the command if autism bot is ingame and running on discord");
|
|
return Plugin_Handled;
|
|
}
|
|
if (specific_bot_player[client] == -1)
|
|
{
|
|
return Plugin_Handled;
|
|
}
|
|
if (chat_cooldown)
|
|
{
|
|
PrintToChat(client, "spamming bot too much, applying cooldown");
|
|
return Plugin_Handled;
|
|
}
|
|
bool bot_found = false;
|
|
for (int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if (IsValidClient(i) && specific_bot_player[i] != -1)
|
|
{
|
|
int port_number = specific_bot_player[i] - 1;
|
|
cmd_talk_help(ports[port_number], client, info);
|
|
bot_found = true;
|
|
}
|
|
}
|
|
if (!bot_found)
|
|
PrintToChat(client, "bot not connected to server");
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
public Action bot_chat_cooldown(Handle timer, any data)
|
|
{
|
|
chat_cooldown = false;
|
|
return Plugin_Continue;
|
|
}
|
|
|
|
public void send_socket_msg(char[] query_msg, int len, int port)
|
|
{
|
|
//LogMessage("query_msg: %s port: %i", query_msg, port);
|
|
if (global_socket != INVALID_HANDLE && SocketIsConnected(global_socket))
|
|
SocketSendTo(global_socket, query_msg, len, "127.0.0.1", port); //udp
|
|
}
|
|
|
|
public Action bot_check_connect(Handle timer, any data)
|
|
{
|
|
//this is designed for being ran from several css servers
|
|
int client_count = GetClientCount(false);
|
|
char msg[generic_length];
|
|
int i_port = GetConVarInt(FindConVar("hostport"));
|
|
bool bot1_connected = false;
|
|
bool bot2_connected = false;
|
|
bool bot3_connected = false;
|
|
bool bot4_connected = false;
|
|
for (int i = 1; i <= MaxClients; i++)
|
|
if (IsValidClient(i) && !IsFakeClient(i))
|
|
{
|
|
if (specific_bot_player[i] == 1)
|
|
bot1_connected = true;
|
|
if (specific_bot_player[i] == 2)
|
|
bot2_connected = true;
|
|
if (specific_bot_player[i] == 3)
|
|
bot3_connected = true;
|
|
if (specific_bot_player[i] == 4)
|
|
bot4_connected = true;
|
|
}
|
|
|
|
if (i_port == server_ports[0])
|
|
{
|
|
int max_allowed_players = 55;
|
|
char current_map[128];
|
|
GetCurrentMap(current_map, sizeof(current_map));
|
|
if (client_count > max_allowed_players)
|
|
{
|
|
Format(msg, sizeof(msg), "connect to ze2");
|
|
send_socket_msg(msg, strlen(msg), ports[0]);
|
|
send_socket_msg(msg, strlen(msg), ports[1]);
|
|
send_socket_msg(msg, strlen(msg), ports[2]);
|
|
send_socket_msg(msg, strlen(msg), ports[3]);
|
|
}
|
|
else if (client_count < max_allowed_players - 5)
|
|
{
|
|
Format(msg, sizeof(msg), "connect to ze");
|
|
if (!bot1_connected)
|
|
send_socket_msg(msg, strlen(msg), ports[0]);
|
|
if (!bot2_connected)
|
|
send_socket_msg(msg, strlen(msg), ports[1]);
|
|
if (!bot3_connected)
|
|
send_socket_msg(msg, strlen(msg), ports[2]);
|
|
if (!bot4_connected)
|
|
send_socket_msg(msg, strlen(msg), ports[3]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//in case the bot is not connected to ze2 anymore make sure that is_bot_connected_to_ze2 is set to false again
|
|
Format(msg, sizeof(msg), "not connected to ze2");
|
|
if (!bot1_connected)
|
|
send_socket_msg(msg, strlen(msg), ports[0]);
|
|
if (!bot2_connected)
|
|
send_socket_msg(msg, strlen(msg), ports[1]);
|
|
if (!bot3_connected)
|
|
send_socket_msg(msg, strlen(msg), ports[2]);
|
|
if (!bot4_connected)
|
|
send_socket_msg(msg, strlen(msg), ports[3]);
|
|
}
|
|
return Plugin_Continue;
|
|
}
|
|
|
|
public Action check_team(Handle timer, any data)
|
|
{
|
|
int valid_ct_counter = 0;
|
|
for (int client = 1; client <= MaxClients; client++)
|
|
{
|
|
if (!IsValidClient(client)) continue;
|
|
if (specific_bot_player[client] == -1 && GetClientTeam(client) > CS_TEAM_SPECTATOR)
|
|
{
|
|
valid_ct_counter++;
|
|
}
|
|
}
|
|
for (int client = 1; client <= MaxClients; client++)
|
|
{
|
|
if (!IsValidClient(client))
|
|
{
|
|
continue;
|
|
}
|
|
if (specific_bot_player[client] != -1 && GetClientTeam(client) <= CS_TEAM_SPECTATOR)
|
|
{
|
|
if (valid_ct_counter < 3)
|
|
{
|
|
continue;
|
|
}
|
|
ChangeClientTeam(client, CS_TEAM_T);
|
|
continue;
|
|
}
|
|
if (specific_bot_player[client] != -1)
|
|
{
|
|
if (IsPlayerAlive(client))
|
|
{
|
|
target_client[specific_bot_player[client]] = GetClosestClient_option1(client);
|
|
}
|
|
}
|
|
}
|
|
bool found_valid_ct = false;
|
|
for (int client = 1; client <= MaxClients; client++)
|
|
{
|
|
if (!IsValidClient(client)) continue;
|
|
if (specific_bot_player[client] == -1 && GetClientTeam(client) > CS_TEAM_SPECTATOR && IsPlayerAlive(client))
|
|
{
|
|
found_valid_ct = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found_valid_ct)
|
|
{
|
|
for (int client = 1; client <= MaxClients; client++)
|
|
{
|
|
if (!IsValidClient(client)) continue;
|
|
if (specific_bot_player[client] != -1 && IsPlayerAlive(client))
|
|
{
|
|
ForcePlayerSuicide(client);
|
|
}
|
|
}
|
|
}
|
|
return Plugin_Continue;
|
|
}
|
|
|
|
stock bool IsValidClient(int client)
|
|
{
|
|
if (client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
public int GetClosestClient_option1(int autism_client)
|
|
{
|
|
float nearestdistance = -1.0;
|
|
int nearest = -1;
|
|
for (int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if (IsValidClient(i) && !IsFakeClient(i) && IsPlayerAlive(i) && i != autism_client)
|
|
{
|
|
if (GetClientIdleTime(i) > 20 || GetClientTeam(autism_client) != GetClientTeam(i))
|
|
{
|
|
continue;
|
|
}
|
|
float pos[3];
|
|
GetEntPropVector(i, Prop_Send, "m_vecOrigin", pos);
|
|
float dist_target = get_power_distance(autism_client, pos);
|
|
|
|
if (specific_bot_player[i] != -1)
|
|
{
|
|
//just making sure bots have lowest priority
|
|
dist_target = 9000000.0;
|
|
}
|
|
if (nearestdistance < 0 || dist_target < nearestdistance)
|
|
{
|
|
nearest = i;
|
|
nearestdistance = dist_target;
|
|
}
|
|
}
|
|
}
|
|
return nearest;
|
|
}
|
|
|
|
public float get_power_distance(int target_player, float pos[3])
|
|
{
|
|
float vec[3];
|
|
GetClientAbsOrigin(target_player, vec);
|
|
return GetVectorDistance(vec, pos);
|
|
}
|
|
|
|
public void OnClientPutInServer(int client)
|
|
{
|
|
specific_bot_player[client] = -1;
|
|
}
|
|
|
|
public void OnClientPostAdminCheck(int client)
|
|
{
|
|
specific_bot_player[client] = -1;
|
|
is_autism_bot1(client);
|
|
is_autism_bot2(client);
|
|
is_autism_bot3(client);
|
|
is_autism_bot4(client);
|
|
|
|
//checks if ze or ze2
|
|
int i_port = GetConVarInt(FindConVar("hostport"));
|
|
char msg[generic_length];
|
|
if (i_port == server_ports[0])
|
|
{
|
|
Format(msg, sizeof(msg), "autismo connected to ze");
|
|
}
|
|
else
|
|
{
|
|
Format(msg, sizeof(msg), "autismo connected to ze2");
|
|
}
|
|
|
|
if (specific_bot_player[client] != -1)
|
|
{
|
|
send_socket_msg(msg, strlen(msg), ports[specific_bot_player[client] - 1]);
|
|
}
|
|
}
|
|
|
|
public void OnSocketError(Handle socket, const int errorType, const int errorNum, any args)
|
|
{
|
|
CloseHandle(socket);
|
|
LogError("[MR] Socket error: %d (errno %d)", errorType, errorNum);
|
|
CreateTimer(10.0, TimerConnect, INVALID_HANDLE, TIMER_HNDL_CLOSE);
|
|
}
|
|
|
|
stock void connect_socket()
|
|
{
|
|
if (global_socket == INVALID_HANDLE || !SocketIsConnected(global_socket))
|
|
{
|
|
int i_port = GetConVarInt(FindConVar("hostport"));
|
|
int target_port = ports[4]; //default ze
|
|
if (i_port == server_ports[1])
|
|
{
|
|
//ze2
|
|
target_port = ports[5];
|
|
}
|
|
//socket otherwise declare in public OnConfigsExecuted(){}
|
|
global_socket = SocketCreate(SOCKET_UDP, OnSocketError);
|
|
SocketSetOption(global_socket, SocketReuseAddr, 1);
|
|
SocketBind(global_socket, "127.0.0.0", target_port);
|
|
SocketConnect(global_socket, OnSocketConnected, OnSocketReceive, OnSocketDisconnected, "127.0.0.1", target_port); //48474 on ze
|
|
}
|
|
}
|
|
|
|
public void OnClientDisconnect(int client)
|
|
{
|
|
specific_bot_player[client] = -1;
|
|
}
|
|
|
|
//Socket callback
|
|
public void OnSocketConnected(Handle socket, int arg)
|
|
{
|
|
|
|
}
|
|
|
|
//manage message
|
|
public void OnSocketReceive(Handle socket, char receiveData [3500], int dataSize, int hFile)
|
|
{
|
|
|
|
}
|
|
|
|
public void OnSocketDisconnected(Handle socket, int arg)
|
|
{
|
|
CreateTimer(10.0, TimerConnect, INVALID_HANDLE, TIMER_HNDL_CLOSE);
|
|
}
|
|
|
|
public Action TimerConnect(Handle timer, any arg)
|
|
{
|
|
connect_socket();
|
|
return Plugin_Handled;
|
|
}
|