removed autism bot movement from python file over to sourcemod and redid how connections are done to the server as well as map delection

This commit is contained in:
jenz 2026-05-06 14:01:06 +02:00
parent 0c760a08e5
commit 435d3edf6c
2 changed files with 765 additions and 0 deletions

View File

@ -0,0 +1,237 @@
#!/home/autismbot1/ze_runner/venv/bin/python3
import os
import sys
import subprocess
import atexit
import pwd
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import random
import signal
import socket
import codecs
import json
import datetime
import time
import glob
restart_time = datetime.datetime.now() + datetime.timedelta(hours=3)
the_undesired_crash_counter = 0 #hate this monkey solution
whoami = subprocess.getoutput("whoami")
with open(f'/home/{whoami}/ze_runner/config.json') as jsonfile:
data_ports = json.load(jsonfile)
looptestPath = f"/home/{whoami}/.steam/debian-installation/steamapps/common/Counter-Strike Source/cstrike/cfg/looptest.cfg"
chatmsg = ""
def overwrite_file_access():
#setting defaults with setfacl for the download directory does not work seemingly
subprocess.Popen(["chmod", "-R", "g+rwx", f"/home/{whoami}/.steam/debian-installation/steamapps/common/Counter-Strike Source/cstrike/download"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).communicate()
def writeCfgInput(Input_user):
with open(looptestPath, 'w') as f:
f.write(Input_user)
#print("wrote to file: ", Input_user)
if "connect" in Input_user or "retry;" in Input_user:
#give extra time for disconnect, retry and connect commands
time.sleep(1.0)
else:
time.sleep(0.35)
open(looptestPath, 'w').close() #clearing file.
def clean_up_files():
#deleting POSIX shared memory objects, as long as one process has them open they exist. THis is to prevent /dev/shm from being full
#due to steam child processes.
#even with steam turned offline might there be chromium web browsers left over from steam who still hold processes open.
#only kind of potential issues from this is steam cloud being out of sync, which is really fucking irrelevant.
for pattern in ["/tmp/steam*", "/tmp/dbus*", "/tmp/pressure*", "/tmp/tigervnc*", "/tmp/dumps*", "/dev/shm/u100*"]:
for path in glob.glob(pattern):
subprocess.run(["rm", "-rf", path], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
#clean up the game cache as it otherwise just keeps growing in gigabyte size
subprocess.run(["rm", "-rf", f"/home/{whoami}/.steam/steam/steamapps/common/Counter-Strike Source/cstrike/cache"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
def check_if_bz2_downloading():
#users should only have permissions to delete their own files probably
#check if any bz2 files left over.
for f in glob.glob(f"/home/{whoami}/.steam/steam/steamapps/common/Counter-Strike Source/cstrike/download/**/*.bz2", recursive=True):
file_size = None
while True:
time.sleep(10)
if not os.path.exists(f):
break # finished downloading, bz2 file is removed.
cur_file_size = os.path.getsize(f)
if file_size == cur_file_size:
# delete the bz2 file if its not progressing downloading
subprocess.run(["rm", "-rf", f], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
break
file_size = cur_file_size
def delete_bsp_files():
#quite a more radical approach to just always delete all maps, well the download should be quick and the remaining bots have the bsp in memory...
#the bots would have struggle connecting sometimes due to bsp files that were already downloaded before hand (maybe corrupted?)
for f in glob.glob(f"/home/{whoami}/.steam/debian-installation/steamapps/common/Counter-Strike Source/cstrike/download/maps/*"):
#ai slop IF statement for checking if file modified less than 10 minutes ago.
if time.time() - os.path.getmtime(f) < 600:
continue
subprocess.run(["rm", "-rf", f], stdout=subprocess.PIPE)
def exit_handler():
print('reached exithandler')
#securing the looptest.cfg wont be stuck accidently with commands
kill_owned_process("pidof cstrike_linux64")
kill_owned_process("pidof xterm")
clean_up_files()
check_if_bz2_downloading()
delete_bsp_files()
subprocess.getoutput(f"pkill -9 -u {whoami}")
def kill_user_owned_pid(pid):
#print('pid: ', pid, ' killed')
pid = int(pid.strip())
os.kill(pid, signal.SIGKILL)
time.sleep(10)
def return_user_owned_pid(pidof):
owner_pid = subprocess.getoutput([f"{pidof}"])
if owner_pid:
for pid in owner_pid.split(" "):
username = subprocess.getoutput([f"""ps -o user= -p {pid}"""])
if username == whoami:
return pid
return None
def kill_owned_process(pidof):
pid = return_user_owned_pid(pidof)
while pid:
kill_user_owned_pid(pid)
pid = return_user_owned_pid(pidof)
def restart_sdl_and_steam():
#subprocess.getoutput(["screen -XS XTERM quit"])
kill_owned_process("pidof cstrike_linux64")
kill_owned_process("pidof xterm")
subprocess.getoutput([f'vncserver -kill']) #only displays vncservers for the specific user.
subprocess.getoutput([f'vncserver -list -cleanstale']) #cleans stale sessions by removing files from disk
time.sleep(5)
cmd = f'vncserver -localhost no -geometry 1x1 -depth 24'
#cmd = f'vncserver -localhost no -geometry 800x800 -depth 24'
#print(f'cmd: {cmd}')
subprocess.getoutput(cmd)
print('reached .bashrc executing steam and variables')
def bot_connect(data):
#use whatever ip you want here to connect with
str1 = ""
if "connect to ze" == data:
str1 = f"connect {data_ports['server_ip_port_ze']};"
elif "connect to ze2" == data:
str1 = f"connect {data_ports['server_ip_port_ze2']};" #wait 15000;
writeCfgInput(str1)
def cpulimit_pid_of_game():
# ' > /dev/null' redirects stdout to /dev/null
# '2>&1' redirects stderr to the same place as stdout
pid = return_user_owned_pid("pidof cstrike_linux64")
if pid is None:
return
cmd = f"cpulimit --pid={pid} --limit=25 --background > /dev/null 2>&1"
#cmd = f"cpulimit --pid={pid} --limit=55 --background > /dev/null 2>&1"
subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).communicate()[0]
time.sleep(3)
for source_engine_lock in glob.glob("/tmp/source_engine_*"):
subprocess.run(["rm", "-rf", source_engine_lock], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
overwrite_file_access()
if __name__ == '__main__':
atexit.register(exit_handler)
local_port = data_ports['udp_port']
external_port_messages = data_ports['chat_external_port']
buffer_size = 4096 #potentially not large enough?
clean_up_files()
check_if_bz2_downloading()
delete_bsp_files()
restart_sdl_and_steam()
is_bot_connected_to_ze2 = False
print('preparing to launch game....')
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("", local_port))
sock.settimeout(5.0)
messager_name = ""
#give the game some time to launch
fail_safe = 5
while return_user_owned_pid("pidof cstrike_linux64") is None:
#just a fail safe to prevent being stuck forever.
if fail_safe <= 0:
sys.exit(1)
time.sleep(10)
print("launching game...")
fail_safe -= 1
time.sleep(10)
cpulimit_pid_of_game()
try:
while True:
try:
#print("socket waiting for recvfrom")
data, addr = sock.recvfrom(buffer_size)
except socket.timeout:
continue
data = codecs.decode(data, "utf-8", "ignore")
ip = addr[0]
port = addr[1]
#print('port: ', port, " ip: ", ip)
#print('data: ', data)
if not data:
continue
#print("ip: ", ip, " port: ", port)
if ip == data_ports['discord_bot_ip'] and port == external_port_messages:
if messager_name in data:
messager_name = ""
response_msg = f"""say {messager_name} {data}"""
print("remote UDP packet response_msg: ", response_msg)
writeCfgInput(response_msg)
if ip != data_ports['ovh_ip']:
continue
elif data == "bot kicked server full":
print('bot kicked server full: ', datetime.datetime.now().time())
elif "autismo connected to ze" == data:
print('Bot connected to ze!')
is_bot_connected_to_ze2 = False
the_undesired_crash_counter = 0
elif "not connected to ze2" == data:
is_bot_connected_to_ze2 = False
elif "autismo connected to ze2" == data:
print('Bot connected to ze2!')
the_undesired_crash_counter = 0
is_bot_connected_to_ze2 = True
elif "connect to ze" == data or ("connect to ze2" == data and not is_bot_connected_to_ze2):
if datetime.datetime.now() >= restart_time or return_user_owned_pid("pidof cstrike_linux64") is None or the_undesired_crash_counter >= 5:
#it already finished downloading the contnet, it just cant connect. probably stuck. shitty solution welp
kill_owned_process("pidof cstrike_linux64")
sock.close()
print('exiting after running the game for several hours or game being stuck on map change.')
sys.exit(1)
print('data: ', data, ' the_undesired_crash_counter: ', the_undesired_crash_counter)
the_undesired_crash_counter += 1
check_if_bz2_downloading()
overwrite_file_access()
bot_connect(data)
elif "clientmessage:" in data:
messager_name = data.split("clientmessage:", 1)[1].split(f" {data_ports['magic_secret']}")[0]
databyte_send_message = messager_name + data.split(f"{data_ports['magic_secret']}")[1]
sock.sendto(databyte_send_message.encode(), (data_ports["discord_bot_ip"], external_port_messages))
#print('databyte_send_message: ', databyte_send_message)
finally:
sock.close()

View File

@ -0,0 +1,528 @@
#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(30.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 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;
}