diff --git a/osiris_listener_telegram.py b/osiris_listener_telegram.py index 243b0ff..6a09347 100644 --- a/osiris_listener_telegram.py +++ b/osiris_listener_telegram.py @@ -70,11 +70,11 @@ gaming_server_profiles = { "dst_vanilla": { 'profile_id': 'dst_sanders', 'exec_type': 'exe_dst', - 'exec_path': "C:/Program Files (x86)/Steam/steamapps/common/Don't Starve Together Dedicated Server/bin/", + 'exec_path': "C:/Program Files (x86)/Steam/steamapps/common/Don't Starve Together Dedicated Server/bin", 'server_name': 'Dont Starve at Sanders', 'directory': "C:/Users/4lexK/Desktop/GameServers/Dont Starve/Dont Starve at Sanders (Vanilla)", - 'command_DontStarveAtSandersOverworld': ["dontstarve_dedicated_server_nullrenderer.exe", '-persistent_storage_root', '"C:/Users/4lexK/Desktop/GameServers/Dont Starve/Dont Starve at Sanders (Vanilla)"', '-conf_dir', 'DontStarveAtSandersOverworld', '-console'], - 'command_DontStarveAtSandersCave': ["dontstarve_dedicated_server_nullrenderer.exe", '-persistent_storage_root', '"C:/Users/4lexK/Desktop/GameServers/Dont Starve/Dont Starve at Sanders (Vanilla)"', '-conf_dir', 'DontStarveAtSandersCave', '-console'], + 'args_DontStarveAtSandersOverworld': ["C:/Program Files (x86)/Steam/steamapps/common/Don't Starve Together Dedicated Server/bin/dontstarve_dedicated_server_nullrenderer.exe", '-persistent_storage_root', r"C:/Users/4lexK/Desktop/GameServers/Dont Starve/Dont Starve at Sanders (Vanilla)", '-conf_dir', "DontStarveAtSandersOverworld", '-console', '-cluster', 'DontStarveAtSanders', '-shard', 'Master'], + 'args_DontStarveAtSandersCave': ["C:/Program Files (x86)/Steam/steamapps/common/Don't Starve Together Dedicated Server/bin/dontstarve_dedicated_server_nullrenderer.exe", '-persistent_storage_root', r"C:/Users/4lexK/Desktop/GameServers/Dont Starve/Dont Starve at Sanders (Vanilla)", '-conf_dir', "DontStarveAtSandersCave", '-console', '-cluster', 'DontStarveAtSanders', '-shard', 'Caves'], 'wait_time': 30 } # Ragnarok Online @@ -338,7 +338,7 @@ def start_gameserver(profile: str) -> str: os.chdir(server['directory']) # check for all shards -> everyone of them needs a pid and a log cur_dir = Path.cwd() - dst_shards = [shard.name for shard in cur_dir.iterdir() if shard.is_dir() and shard.name != 'Agreements'] + dst_shards = [shard.name for shard in cur_dir.iterdir() if shard.is_dir() and shard.name != 'Agreements' and shard.name != 'logs'] shard_cnt = len(dst_shards) for shard in dst_shards: @@ -348,27 +348,32 @@ def start_gameserver(profile: str) -> str: os.makedirs(os.path.dirname(log_file), exist_ok=True) # checken wie prozesse heißen - #if os.path.exists(pid_file): - # with open(pid_file, 'r') as file: - # pid = int(file.read().strip()) - # if psutil.pid_exists(pid) and is_java_process(pid): - # response_msg = f"Server {server['server_name']} läuft bereits." - # return response_msg - # else: - # os.remove(pid_file) - + if os.path.exists(pid_file): + with open(pid_file, 'r') as file: + pid = int(file.read().strip()) + if psutil.pid_exists(pid) and is_dst_process(pid): + response_msg = f"Server {shard}{server['server_name']} läuft bereits." + return response_msg + else: + os.remove(pid_file) + with open(log_file, 'w') as log: - process = subprocess.Popen( - server[f'command_{shard}'], - cwd=server['exec_path'], - stdout=log, - stderr=log, - creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if os.name == 'nt' else 0 - ) + try: + process = subprocess.Popen( + server[f"args_{shard}"], + cwd=server['exec_path'], + #shell=True, + stdout=log, + stderr=log, + creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if os.name == 'nt' else 0 + ) + except Exception as err: + print(f"{err = }") #time.sleep(wait_time) with open(pid_file, 'w') as file: file.write(str(process.pid)) - response_msg += f"Server {server['server_name']} wurde mit PID '{process.pid}' gestartet. " + response_msg += f"Server {server['server_name']} ({shard}) wurde mit PID '{process.pid}' gestartet. " + else: response_msg = f"Server Informationen für Profile {profile} existieren nicht. Bitte prüfen." return response_msg @@ -380,37 +385,76 @@ def stop_gameserver(profile: str) -> str: return response_msg server = gaming_server_profiles[profile] - pid_file = os.path.join(server['directory'], 'server.pid') - wait_time = server['wait_time'] - flag_delete_pid = False - if os.path.exists(pid_file): - with open(pid_file, 'r') as file: - pid = int(file.read().strip()) - if psutil.pid_exists(pid) and is_java_process(pid): - p = psutil.Process(pid) - if os.name == 'nt': - p.terminate() # Use terminate for Windows - else: - p.send_signal(signal.SIGTERM) - try: - p.wait(timeout=wait_time) - if not psutil.pid_exists(pid): - flag_delete_pid = True - response_msg = f"Server {server['server_name']} mit PID {pid} gestoppt." + executable_type = server['exec_type'] + match executable_type: + case 'java': + pid_file = os.path.join(server['directory'], 'server.pid') + wait_time = server['wait_time'] + flag_delete_pid = False + if os.path.exists(pid_file): + with open(pid_file, 'r') as file: + pid = int(file.read().strip()) + if psutil.pid_exists(pid) and is_java_process(pid): + p = psutil.Process(pid) + if os.name == 'nt': + p.terminate() # Use terminate for Windows + else: + p.send_signal(signal.SIGTERM) + try: + p.wait(timeout=wait_time) + if not psutil.pid_exists(pid): + flag_delete_pid = True + response_msg = f"Server {server['server_name']} mit PID {pid} gestoppt." + else: + response_msg = f"\nFehler beim Stoppen des Servers {server['server_name']} mit PID {pid}." + except psutil.TimeoutExpired: + response_msg = f"Timeout während stoppen des Server {server['server_name']} mit PID {pid}." else: - response_msg = f"\nFehler beim Stoppen des Servers {server['server_name']} mit PID {pid}." - except psutil.TimeoutExpired: - response_msg = f"Timeout während stoppen des Server {server['server_name']} mit PID {pid}." + flag_delete_pid = True + response_msg = f"Stale PID file von Server {server['server_name']} entfernt." + if flag_delete_pid: + os.remove(pid_file) + response_msg += " PID File gelöscht." + flag_delete_pid = False else: - flag_delete_pid = True - response_msg = f"Stale PID file von Server {server['server_name']} entfernt." - if flag_delete_pid: - os.remove(pid_file) - response_msg += " PID File gelöscht." - flag_delete_pid = False - else: - response_msg = f"Es existiert kein PID File für Server {server['server_name']}" - + response_msg = f"Es existiert kein PID File für Server {server['server_name']}" + case 'exe_dst': + os.chdir(server['directory']) + # check for all shards -> everyone of them needs a pid and a log + cur_dir = Path.cwd() + dst_shards = [shard.name for shard in cur_dir.iterdir() if shard.is_dir() and shard.name != 'Agreements' and shard.name != 'logs'] + shard_cnt = len(dst_shards) + for shard in dst_shards: + pid_file = os.path.join(server['directory'], f'{shard}.pid') + wait_time = server['wait_time'] + flag_delete_pid = False + if os.path.exists(pid_file): + with open(pid_file, 'r') as file: + pid = int(file.read().strip()) + if psutil.pid_exists(pid) and is_dst_process(pid): + p = psutil.Process(pid) + if os.name == 'nt': + p.terminate() # Use terminate for Windows + else: + p.send_signal(signal.SIGTERM) + try: + p.wait(timeout=wait_time) + if not psutil.pid_exists(pid): + flag_delete_pid = True + response_msg += f"Server {shard}{server['server_name']} mit PID {pid} gestoppt." + else: + response_msg += f"\nFehler beim Stoppen des Servers {shard}{server['server_name']} mit PID {pid}." + except psutil.TimeoutExpired: + response_msg += f"Timeout während stoppen des Server {shard}{server['server_name']} mit PID {pid}." + else: + flag_delete_pid = True + response_msg += f"Stale PID file von Server {shard}{server['server_name']} entfernt." + if flag_delete_pid: + os.remove(pid_file) + response_msg += " PID File gelöscht." + flag_delete_pid = False + else: + response_msg += f"Es existiert kein PID File für Server {shard}{server['server_name']}" return response_msg def read_pid_file(pid_file): @@ -429,6 +473,17 @@ def is_java_process(pid): except psutil.NoSuchProcess: return False +def is_dst_process(pid): + try: + p = psutil.Process(pid) + #for cmd_arg in p.cmdline(): + # if cmd_arg.startswith('dontstarve_dedicated_server_nullrenderer'): + if 'dontstarve_dedicated_server_nullrenderer' in p.name().lower(): + return True + return False + except psutil.NoSuchProcess: + return False + # Function to send the main menu async def send_main_menu(context: ContextTypes.DEFAULT_TYPE, chat_id: int): # keyboard = [ @@ -617,9 +672,8 @@ async def handle_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> msg = start_gameserver("dst_vanilla") await query.message.reply_text(f"{msg}") case "dst_vanilla_stop": - msg = "Not Implemented yet" + msg = stop_gameserver("dst_vanilla") await query.message.reply_text(f"{msg}") - await send_main_menu(context, query.message.chat_id) case "dst_vanilla_back": await query.message.reply_text("Wähle einen Don't Starve Together Server:", reply_markup=InlineKeyboardMarkup(dont_starve_menu)) # Ragnarok Online Server