#!/home/autismbot1/ze_runner/venv/bin/python3 import os import sys import subprocess import atexit from threading import Timer import string import random import signal import socket import codecs import json import datetime import time import glob connection_issue_counter = 0; call_bot_connect = True 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 writeCfgInput(Input_user): with open(looptestPath, 'w') as f: f.write(Input_user) time.sleep(0.1) open(looptestPath, 'w').close() def exit_handler(): print('reached exithandler') writeCfgInput('') #securing the looptest.cfg wont be stuck accidently with commands kill_owned_process("pidof hl2_linux") kill_owned_process("pidof xterm") #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.getoutput([f"pkill -9 -u {whoami}"]) def bot_process_movement(input_line): dist_target = input_line[input_line.index("dist_target:") + len("dist_target:"):input_line.index("enemy_distance")] enemy_distance = input_line[input_line.index("enemy_distance:") + len("enemy_distance:"):input_line.index("targeteam:")] targeteam = input_line[input_line.index("targeteam:") + len("targeteam:"):input_line.index("state:")] state = input_line[input_line.index("state:") + len("state:"):] state = int(state.strip()) dist_target = float(dist_target) enemy_distance = float(enemy_distance) targeteam = int(targeteam) #request by bane that bots should simply not infect people shrug strInput = "-attack; wait 2; -use; wait 5; -attack; wait 5; cl_minmodels 1; wait 2; +use; wait 5; " if targeteam == 3: strInput = "-attack; wait 2; -use; wait 5; +attack; wait 5; cl_minmodels 1; wait 2; +use; wait 5; " #python has no switches and such if state in [5, 7]: strInput += "-forward; wait 2; use weapon_knife; wait 5;" elif state >= 3: strInput += "use weapon_knife; wait 5; +forward; wait 2;" elif state == 0: strInput += "use weapon_p90; wait 2; -forward; wait 2;" elif state == 1: strInput += "wait 2; use weapon_elite; wait 3; +forward; wait 2;" elif state == 2: strInput += "-forward; wait 2; use weapon_elite; wait 3;" elif state == 8: strInput += "use weapon_knife; wait 5; +forward; wait 2;" #print('dist_target: ', dist_target, ' enemy distance: ', enemy_distance, ' targeteam: ', targeteam, ' state:', state) if state not in [0, 2, 5, 7, 8]: strInput = strinput_append(strInput, 2) #print('strInput final:', strInput) writeCfgInput(strInput) def strinput_append(strInput, nth): for _ in range(3 * nth): boolean_val = random.choice([True, False]) if boolean_val: strInput += " +moveleft; wait 15; -moveleft; " else: strInput += " +moveright; wait 15; -moveright; " return strInput 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 hl2_linux") kill_owned_process("pidof xterm") x2go_session_list = subprocess.getoutput(["x2golistsessions"]) print('x2golistsessions: ', x2go_session_list) if not x2go_session_list: print('no session. creating Display to make idle session') subprocess.getoutput([f"screen -d -m -S pyhoca_display ./run_follow.sh"]) while not x2go_session_list or len(x2go_session_list.split('|')[0].replace(" ", "")) == 0: time.sleep(5) x2go_session_list = subprocess.getoutput(["x2golistsessions"]) print(f'finally found x2go_session_list: {x2go_session_list}') hostname = subprocess.getoutput(['hostname']) x2go_session_display = x2go_session_list.split(f'|{hostname}')[0].rsplit('|', 1)[1] x2go_session_pid = x2go_session_list.split('|')[0] x2go_session_id = x2go_session_list.split('|')[1].split('|')[0] x2go_session_command = 'TERMINAL xterm' xterm_cmd = f'screen -d -m -S XTERM x2goruncommand {x2go_session_display} {x2go_session_pid} {x2go_session_id} {x2go_session_command}' print(f'xterm_cmd: {xterm_cmd}') subprocess.getoutput([xterm_cmd]) print('reached .bashrc executing steam and variables') time.sleep(40) #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 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) time.sleep(1) writeCfgInput("") t = Timer(150, attempt_bot_connect) t.start() def attempt_bot_connect(): global connection_issue_counter global call_bot_connect connection_issue_counter += 1 call_bot_connect = True print('finished timer callback') 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? #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 = {} 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 time.sleep(10) 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 if maps_folder_size.endswith("G"): maps_folder_size = float(maps_folder_size[:-1]) if maps_folder_size > 40.0: for f in glob.glob(f"/home/{whoami}/.steam/debian-installation/steamapps/common/Counter-Strike Source/cstrike/download/maps/*"): subprocess.Popen(["rm", f], stdout=subprocess.PIPE).communicate()[0] 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 = "" try: while True: try: 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 == "rtv": response_msg = "say rtv" writeCfgInput(response_msg) 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!') connection_issue_counter = 0 is_bot_connected_to_ze2 = False 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 is_bot_connected_to_ze2 = True elif "connect to ze" == data or ("connect to ze2" == data and not is_bot_connected_to_ze2): if connection_issue_counter == 5: kill_owned_process("pidof hl2_linux") print('exiting') sock.close() sys.exit(1) else: if call_bot_connect: call_bot_connect = False print('data: ', data) print("connection_issue_counter: ", connection_issue_counter) bot_connect(data) elif "clientmessage:" in data: messager_name = data.split("clientmessage:", 1)[1].split(" put your magic code here.")[0] databyte_send_message = messager_name + data.split("put your magic code here.")[1] sock.sendto(databyte_send_message.encode(), (data_ports["discord_bot_ip"], external_port_messages)) #print('databyte_send_message: ', databyte_send_message) elif data.startswith("dist_target:"): bot_process_movement(data) elif data.startswith("surfing:"): bot_process_surf(data) elif data.startswith("hull info:"): hull_info = data[data.index("hull info:") + len("hull info:"):] strInput = "" if hull_info == "jump": strInput += "+jump; wait 5; -jump; +duck; wait 50; -duck; wait 5; " elif hull_info == "crouch": strInput += "+duck; wait 50; -duck; wait 5; " writeCfgInput(strInput) finally: sock.close()