From de458c3c37cda2ce27a0afae96718a05ff9b4d34 Mon Sep 17 00:00:00 2001 From: jenz Date: Wed, 4 Jun 2025 17:44:16 +0200 Subject: [PATCH] first changes so far to handling how autism bots connect and their resource ussage --- AutismBotIngame/README.md | 9 +- AutismBotIngame/python/ingamefollowct.py | 146 ++++++++++++------- AutismBotIngame/scripting/autism_bot_info.sp | 6 +- 3 files changed, 105 insertions(+), 56 deletions(-) diff --git a/AutismBotIngame/README.md b/AutismBotIngame/README.md index 69d48c1..58a3377 100644 --- a/AutismBotIngame/README.md +++ b/AutismBotIngame/README.md @@ -23,7 +23,8 @@ #probably good idea to symlink the download folder ln -s /home/autismbot1/.steam/debian-installation/steamapps/common/Counter-Strike\ Source/cstrike/download /home/autismbot2/.steam/debian-installation/steamapps/common/Counter-Strike\ Source/cstrike/download - chmod g+x /home/user1 + + dpkg-reconfigure locales @@ -83,3 +84,9 @@ now using tigervnc instead of x2go. vncviewer -SecurityTypes VncAuth,TLSVnc ip:X Display for example: vncviewer -SecurityTypes VncAuth,TLSVnc 127.0.0.1:1 + +limiting cpu can throttle the download speed as well. if bots cant connect and are missing files, let them try to download stuff with the cpu limiting commented out instead. + +#pip3 extra + +pip3 install watchdog diff --git a/AutismBotIngame/python/ingamefollowct.py b/AutismBotIngame/python/ingamefollowct.py index 2e92c71..fa345ab 100644 --- a/AutismBotIngame/python/ingamefollowct.py +++ b/AutismBotIngame/python/ingamefollowct.py @@ -3,11 +3,10 @@ import os import sys import subprocess import atexit -from threading import Timer -import string +from watchdog.observers import Observer +from watchdog.events import FileSystemEventHandler import random import signal -import traceback import socket import codecs import json @@ -15,8 +14,8 @@ import datetime import time import glob -connection_issue_counter = 0; call_bot_connect = True +restart_time = datetime.datetime.now() + datetime.timedelta(hours=5) whoami = subprocess.getoutput(["whoami"]) with open(f'/home/{whoami}/ze_runner/config.json') as jsonfile: @@ -24,6 +23,10 @@ with open(f'/home/{whoami}/ze_runner/config.json') as 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) @@ -37,17 +40,21 @@ def writeCfgInput(Input_user): time.sleep(0.5) open(looptestPath, 'w').close() #clearing file. +def close_observer(observer): + observer.stop() + observer.join() #supposedly needed to clear resources again. + 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. - subprocess.Popen(["rm -rf /tmp/steam*"], shell=True, stdout=subprocess.PIPE).communicate()[0] - subprocess.Popen(["rm -rf /tmp/dbus*"], shell=True, stdout=subprocess.PIPE).communicate()[0] - subprocess.Popen(["rm -rf /tmp/pressure*"], shell=True, stdout=subprocess.PIPE).communicate()[0] - subprocess.Popen(["rm -rf /tmp/tigervnc*"], shell=True, stdout=subprocess.PIPE).communicate()[0] - subprocess.Popen(["rm -rf /tmp/dumps*"], shell=True, stdout=subprocess.PIPE).communicate()[0] - subprocess.Popen(["rm -rf /dev/shm/u100*"], shell=True, stdout=subprocess.PIPE).communicate()[0] + subprocess.Popen(["rm -rf /tmp/steam*"], shell=True, stdout=subprocess.DEVNULL).communicate()[0] + subprocess.Popen(["rm -rf /tmp/dbus*"], shell=True, stdout=subprocess.DEVNULL).communicate()[0] + subprocess.Popen(["rm -rf /tmp/pressure*"], shell=True, stdout=subprocess.DEVNULL).communicate()[0] + subprocess.Popen(["rm -rf /tmp/tigervnc*"], shell=True, stdout=subprocess.DEVNULL).communicate()[0] + subprocess.Popen(["rm -rf /tmp/dumps*"], shell=True, stdout=subprocess.DEVNULL).communicate()[0] + subprocess.Popen(["rm -rf /dev/shm/u100*"], shell=True, stdout=subprocess.DEVNULL).communicate()[0] #users should only have permissions to delete their own files probably def exit_handler(): @@ -104,7 +111,7 @@ def strinput_append(strInput, nth): return strInput def kill_user_owned_pid(pid): - print('pid: ', pid, ' killed') + #print('pid: ', pid, ' killed') pid = int(pid.strip()) os.kill(pid, signal.SIGKILL) time.sleep(10) @@ -133,11 +140,10 @@ def restart_sdl_and_steam(): 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') - time.sleep(10) - #we sleep here to wait for .bashrc to launch steam. It takes some time def bot_connect(data): #use whatever ip you want here to connect with @@ -149,46 +155,67 @@ def bot_connect(data): writeCfgInput(str1) time.sleep(1) - handle_bz2_map_files() - t = Timer(30, attempt_bot_connect) - t.start() - 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") - cmd = f"cpulimit --pid={pid} --limit=5 --background" - #print('the command is: ', cmd) + cmd = f"cpulimit --pid={pid} --limit=5 --background > /dev/null 2>&1" subprocess.Popen([cmd], shell=True, stdout=subprocess.PIPE).communicate()[0] def delete_lock_file(): #just delete the tmp source_engine .lock file here so multiple instances can run at same time. - subprocess.Popen(["rm -f /tmp/source_engine*.lock"], shell=True, stdout=subprocess.PIPE).communicate()[0] + subprocess.Popen(["rm -f /tmp/source_engine*.lock"], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).communicate()[0] -def attempt_bot_connect(): - global connection_issue_counter +def my_file_created_function(event_path): global call_bot_connect - connection_issue_counter += 1 - call_bot_connect = True - print('finished timer callback') + call_bot_connect = False -def handle_bz2_map_files(): - #if downloading maps we give it 10 seconds delay to see if the size changed, if not its probably safe to delete the .bz2 file as no download in progress - bz2_maps = {} + #print(f"New file created: {event_path}") + if not event_path.lower().endswith(".bsp.bz2"): + return + + file_size = None while True: - found = False - for f in glob.glob(f"/home/{whoami}/.steam/debian-installation/steamapps/common/Counter-Strike Source/cstrike/download/maps/*.bz2"): - found = True - fsize = subprocess.Popen(["du", "-sh", f], stdout=subprocess.PIPE).communicate()[0].decode().split("\t")[0] - #deleting left over bz2 files because they give missing map issue - if f in bz2_maps: - #if the size is still the same it should be abandoned bz2 file that we can delete - if bz2_maps[f] == fsize: - subprocess.Popen(["rm", f], stdout=subprocess.PIPE).communicate()[0] - bz2_maps[f] = fsize - #no bz2 maps left to be concerned about - if not found: - break + #repeatedly spamming to kill cpu limitting, its bottlenecking the download speed + kill_owned_process("pidof cpulimit") time.sleep(10) + stdout, stderr = subprocess.Popen(["ls", "-l", event_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() + #print('stdout: ', stdout) + #print('stderr: ', stderr) + if stderr: + print('finished downloading the bz2 file.') + break + user = stdout.decode().split("autismbots")[0] + if whoami not in user: + writeCfgInput("disconnect;") + print("disconnected from server until other user finished downloading bz2 file") + continue + + #in case the bz2 download is not progressing just delete the file and disconnect. + cur_file_size = stdout.decode().split("autismbots")[1].strip().split(" ")[0] + if file_size == cur_file_size: + print("Aborting connection. file download is stuck.") + writeCfgInput("disconnect;") + break + file_size = cur_file_size + + call_bot_connect = True + +class NewFileHandler(FileSystemEventHandler): + def on_created(self, event): + my_file_created_function(event.src_path) + +def handle_bz2_files(): + #mostly its just downloading maps that we will be doing + root_dir = f"/home/{whoami}/.steam/debian-installation/steamapps/common/Counter-Strike Source/cstrike/download" + event_handler = NewFileHandler() + observer = Observer() + # Schedule the observer to watch the root directory and its subdirectories recursively + observer.schedule(event_handler, root_dir, recursive=True) + observer.start() + return observer + if __name__ == '__main__': atexit.register(exit_handler) local_port = data_ports['udp_port'] @@ -197,10 +224,10 @@ if __name__ == '__main__': clean_up_files() delete_lock_file() - handle_bz2_map_files() + observer = handle_bz2_files() maps_folder_size = subprocess.Popen(["du", "-sh", f"/home/{whoami}/.steam/debian-installation/steamapps/common/Counter-Strike Source/cstrike/download/maps"], stdout=subprocess.PIPE).communicate()[0].decode().split("\t")[0] - #deleting when maps folder larger than 150GB + #deleting when maps folder larger than some GB if maps_folder_size.endswith("G"): maps_folder_size = float(maps_folder_size[:-1]) if maps_folder_size > 40.0: @@ -217,9 +244,16 @@ if __name__ == '__main__': sock.settimeout(5.0) messager_name = "" - #limit the cpu allowed to be used by the game instance. - time.sleep(11) - cpulimit_pid_of_game() + #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) try: while True: @@ -252,25 +286,32 @@ if __name__ == '__main__': print('bot kicked server full: ', datetime.datetime.now().time()) elif "autismo connected to ze" == data: print('Bot connected to ze!') - connection_issue_counter = 0 + cpulimit_pid_of_game() + call_bot_connect = True is_bot_connected_to_ze2 = False + overwrite_file_access() elif "not connected to ze2" == data: is_bot_connected_to_ze2 = False elif "autismo connected to ze2" == data: print('Bot connected to ze2!') - connection_issue_counter = 0 + cpulimit_pid_of_game() + call_bot_connect = True is_bot_connected_to_ze2 = True + overwrite_file_access() elif "connect to ze" == data or ("connect to ze2" == data and not is_bot_connected_to_ze2): - if connection_issue_counter == 5: + if datetime.datetime.now() >= restart_time: kill_owned_process("pidof cstrike_linux64") sock.close() - print('exiting') + close_observer(observer) + print('exiting after running the game for several hours.') sys.exit(1) else: if call_bot_connect: - call_bot_connect = False + #stop cpu limitting, its bottlenecking the connection to the server. + kill_owned_process("pidof cpulimit") + print('data: ', data) - print("connection_issue_counter: ", connection_issue_counter) + call_bot_connect = False bot_connect(data) elif "clientmessage:" in data: messager_name = data.split("clientmessage:", 1)[1].split(f" {data_ports['magic_secret']}")[0] @@ -291,3 +332,4 @@ if __name__ == '__main__': writeCfgInput(strInput) finally: sock.close() + close_observer(observer) diff --git a/AutismBotIngame/scripting/autism_bot_info.sp b/AutismBotIngame/scripting/autism_bot_info.sp index d19dfce..eafb1fd 100755 --- a/AutismBotIngame/scripting/autism_bot_info.sp +++ b/AutismBotIngame/scripting/autism_bot_info.sp @@ -13,6 +13,7 @@ #include #include #include +#include int target_friend_afk_counter[MAXPLAYERS][MAXPLAYERS + 1]; int target_friend[MAXPLAYERS + 1]; @@ -336,7 +337,7 @@ 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), "add_magic_value_here"); + 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); @@ -513,7 +514,6 @@ public Action bot_check_connect(Handle timer, any data) if (i_port == server_ports[0]) { - //revert again to either 10 or 55 int max_allowed_players = 55; char current_map[128]; GetCurrentMap(current_map, sizeof(current_map)); @@ -525,7 +525,7 @@ public Action bot_check_connect(Handle timer, any data) send_socket_msg(msg, strlen(msg), ports[2]); send_socket_msg(msg, strlen(msg), ports[3]); } - else if (client_count < 50) + else if (client_count < max_allowed_players) { Format(msg, sizeof(msg), "connect to ze"); if (!bot1_connected)