making the simulate movement plugin obsolete and moving all the connection management related content into a separate plugin so that its isolated from other functionality
This commit is contained in:
@@ -0,0 +1,400 @@
|
||||
#pragma semicolon 1
|
||||
#pragma newdecls required
|
||||
|
||||
#define PLUGIN_AUTHOR "jenz"
|
||||
#define PLUGIN_VERSION "1.0"
|
||||
#define generic_length 256
|
||||
|
||||
#include <sourcemod>
|
||||
#include <cstrike>
|
||||
#include <socket>
|
||||
#include <sdktools>
|
||||
#include <UNLOZE.secret>
|
||||
#include <mapchooser_extended>
|
||||
#include <BotTargeting>
|
||||
|
||||
#define MAX_AUTISM_BOTS 4
|
||||
|
||||
int g_BotIndex[MAXPLAYERS + 1]; // 0 = not an autism bot, 1-4 = autism bot index
|
||||
|
||||
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 communication
|
||||
Handle global_socket = null;
|
||||
|
||||
ConVar g_cvHostPort;
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "autism bot connection",
|
||||
author = PLUGIN_AUTHOR,
|
||||
description = "connection state management for the autism bots",
|
||||
version = PLUGIN_VERSION,
|
||||
url = ""
|
||||
};
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
g_cvHostPort = FindConVar("hostport");
|
||||
|
||||
//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;
|
||||
|
||||
// map downloads go to the first port only, once per cycle
|
||||
CreateTimer(60.0, Timer_MapDownload, _, TIMER_REPEAT);
|
||||
|
||||
// per-bot connect checks, staggered 5 seconds apart
|
||||
for (int index = 1; index <= MAX_AUTISM_BOTS; index++)
|
||||
{
|
||||
CreateTimer(float(index - 1) * 5.0 + 0.1, Timer_StartConnectCheck, index);
|
||||
}
|
||||
|
||||
// team joining / killing bots when no human is left alive
|
||||
CreateTimer(2.0, Timer_CheckTeam, _, TIMER_REPEAT);
|
||||
|
||||
// late load
|
||||
for (int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if (IsValidClient(i) && IsClientAuthorized(i))
|
||||
{
|
||||
OnClientPostAdminCheck(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// bot identification
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
int GetBotClientForIndex(int index)
|
||||
{
|
||||
for (int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if (IsValidClient(i) && g_BotIndex[i] == index)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void OnClientPutInServer(int client)
|
||||
{
|
||||
g_BotIndex[client] = 0;
|
||||
}
|
||||
|
||||
public void OnClientPostAdminCheck(int client)
|
||||
{
|
||||
g_BotIndex[client] = 0;
|
||||
if (IsFakeClient(client))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int index = GetClientAutismBotIndex(client);
|
||||
if (index < 1 || index > MAX_AUTISM_BOTS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
g_BotIndex[client] = index;
|
||||
|
||||
//checks if ze or ze2
|
||||
char msg[generic_length];
|
||||
if (g_cvHostPort.IntValue == server_ports[0])
|
||||
{
|
||||
Format(msg, sizeof(msg), "autismo connected to ze");
|
||||
}
|
||||
else if (g_cvHostPort.IntValue == server_ports[1])
|
||||
{
|
||||
Format(msg, sizeof(msg), "autismo connected to ze2");
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
send_socket_msg(msg, strlen(msg), ports[index - 1]);
|
||||
}
|
||||
|
||||
public void OnClientDisconnect(int client)
|
||||
{
|
||||
g_BotIndex[client] = 0;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// team joining
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
public Action Timer_CheckTeam(Handle timer, any data)
|
||||
{
|
||||
for (int client = 1; client <= MaxClients; client++)
|
||||
{
|
||||
if (!IsValidClient(client) || g_BotIndex[client] == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (GetClientTeam(client) <= CS_TEAM_SPECTATOR)
|
||||
{
|
||||
ChangeClientTeam(client, CS_TEAM_T);
|
||||
CreateTimer(1.0, zspawn, GetClientSerial(client));
|
||||
}
|
||||
}
|
||||
|
||||
// no real human alive on CT anymore -> kill the bots so they dont hold up the round
|
||||
bool found_valid_ct = false;
|
||||
for (int client = 1; client <= MaxClients; client++)
|
||||
{
|
||||
if (!IsValidClient(client)) continue;
|
||||
if (g_BotIndex[client] == 0 && GetClientTeam(client) > CS_TEAM_T && IsPlayerAlive(client))
|
||||
{
|
||||
found_valid_ct = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found_valid_ct)
|
||||
{
|
||||
for (int client = 1; client <= MaxClients; client++)
|
||||
{
|
||||
if (!IsValidClient(client)) continue;
|
||||
if (g_BotIndex[client] != 0 && IsPlayerAlive(client))
|
||||
{
|
||||
ForcePlayerSuicide(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action zspawn(Handle hTimer, int Serial)
|
||||
{
|
||||
int client;
|
||||
if ((client = GetClientFromSerial(Serial)) == 0)
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
if (IsValidClient(client))
|
||||
{
|
||||
FakeClientCommandEx(client, "joinclass");
|
||||
FakeClientCommandEx(client, "say /zspawn");
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// chat / rtv
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
public void Event_RoundStart(Handle event, const char[] name, bool dontBroadcast)
|
||||
{
|
||||
chat_cooldown = false;
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
// kept from the original plugin: only the bot accounts themselves can use sm_autism
|
||||
if (g_BotIndex[client] == 0)
|
||||
{
|
||||
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) && g_BotIndex[i] != 0)
|
||||
{
|
||||
cmd_talk_help(ports[g_BotIndex[i] - 1], 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 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) && g_BotIndex[i] != 0)
|
||||
{
|
||||
FakeClientCommandEx(i, "say rtv");
|
||||
}
|
||||
}
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// connection management
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
public void OnMapVoteEnd(const char[] map)
|
||||
{
|
||||
if (StrEqual(map, "##extend##") || StrEqual(map, "##dontchange##"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char msg[generic_length];
|
||||
Format(msg, sizeof(msg), "download map:%s", map);
|
||||
send_socket_msg(msg, strlen(msg), ports[0]);
|
||||
}
|
||||
|
||||
public Action Timer_MapDownload(Handle timer, any data)
|
||||
{
|
||||
char map[64];
|
||||
char msg[generic_length];
|
||||
if (GetNextMap(map, sizeof(map)))
|
||||
{
|
||||
Format(msg, sizeof(msg), "download map:%s", map);
|
||||
send_socket_msg(msg, strlen(msg), ports[0]);
|
||||
}
|
||||
|
||||
GetCurrentMap(map, sizeof(map));
|
||||
Format(msg, sizeof(msg), "download map:%s", map);
|
||||
send_socket_msg(msg, strlen(msg), ports[0]);
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action Timer_StartConnectCheck(Handle timer, int index)
|
||||
{
|
||||
CreateTimer(60.0, Timer_ConnectCheck, index, TIMER_REPEAT);
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
//this is designed for being ran from several css servers
|
||||
public Action Timer_ConnectCheck(Handle timer, int index)
|
||||
{
|
||||
char msg[generic_length];
|
||||
int client_count = GetClientCount(false);
|
||||
bool connected = GetBotClientForIndex(index) != -1;
|
||||
int port = ports[index - 1];
|
||||
|
||||
if (g_cvHostPort.IntValue == server_ports[0])
|
||||
{
|
||||
int max_allowed_players = 55;
|
||||
if (client_count > max_allowed_players)
|
||||
{
|
||||
Format(msg, sizeof(msg), "connect to ze2");
|
||||
send_socket_msg(msg, strlen(msg), port);
|
||||
}
|
||||
else if (client_count < max_allowed_players - 5 && !connected)
|
||||
{
|
||||
Format(msg, sizeof(msg), "connect to ze");
|
||||
send_socket_msg(msg, strlen(msg), port);
|
||||
}
|
||||
}
|
||||
else if (!connected)
|
||||
{
|
||||
//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");
|
||||
send_socket_msg(msg, strlen(msg), port);
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// socket
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
public void send_socket_msg(char[] query_msg, int len, int port)
|
||||
{
|
||||
if (global_socket != null && SocketIsConnected(global_socket))
|
||||
{
|
||||
SocketSendTo(global_socket, query_msg, len, "127.0.0.1", port); //udp
|
||||
}
|
||||
}
|
||||
|
||||
stock void connect_socket()
|
||||
{
|
||||
if (global_socket == null || !SocketIsConnected(global_socket))
|
||||
{
|
||||
int target_port = ports[4]; //default ze
|
||||
if (g_cvHostPort.IntValue == server_ports[1])
|
||||
{
|
||||
//ze2
|
||||
target_port = ports[5];
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnSocketError(Handle socket, const int errorType, const int errorNum, any args)
|
||||
{
|
||||
CloseHandle(socket);
|
||||
if (socket == global_socket)
|
||||
{
|
||||
global_socket = null; // otherwise connect_socket would query a closed handle
|
||||
}
|
||||
LogError("[autism bot] Socket error: %d (errno %d)", errorType, errorNum);
|
||||
CreateTimer(10.0, TimerConnect);
|
||||
}
|
||||
|
||||
public void OnSocketConnected(Handle socket, int arg)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnSocketReceive(Handle socket, char receiveData[3500], int dataSize, int hFile)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnSocketDisconnected(Handle socket, int arg)
|
||||
{
|
||||
CreateTimer(10.0, TimerConnect);
|
||||
}
|
||||
|
||||
public Action TimerConnect(Handle timer, any arg)
|
||||
{
|
||||
connect_socket();
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
stock bool IsValidClient(int client)
|
||||
{
|
||||
return client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client);
|
||||
}
|
||||
Reference in New Issue
Block a user