From b24cb183176bd6f7f32496817106cbb425b5ba5a Mon Sep 17 00:00:00 2001 From: d1str4ught <> Date: Sat, 23 Aug 2025 19:46:08 +0200 Subject: [PATCH] start.py and stop.py added --- .gitignore | 1 + start.py | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++ stop.py | 70 ++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+) create mode 100644 start.py create mode 100644 stop.py diff --git a/.gitignore b/.gitignore index 3718058..502c0e3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ share/bin channels +pids.json diff --git a/start.py b/start.py new file mode 100644 index 0000000..06b5a55 --- /dev/null +++ b/start.py @@ -0,0 +1,117 @@ +import sys +sys.dont_write_bytecode = True + +import os +import time +import json +import subprocess +import traceback +import channels + +GAMEDIR = os.getcwd() +PIDS_FILE = os.path.join(GAMEDIR, "pids.json") + +def print_green(text): + print("\033[1;32m" + text + "\033[0m") + +def print_magenta_prompt(): + print("\033[0;35m> ", end="", flush=True) + +def start_process(exe): + if os.name == "nt": + exe += ".exe" + return subprocess.Popen([exe], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + +def try_start(name, cd, exe, pids, key=None): + try: + os.chdir(cd) + proc = start_process(exe) + entry = {"name": name, "pid": proc.pid} + + if key: + pids.setdefault(key, []).append(entry) + else: + pids[name] = entry + + return True + except Exception as e: + print(f"> Failed to start {name}: {e}") + traceback.print_exc() + return False + +def main(): + if len(sys.argv) == 1: + print_green("> How many channels to start?") + print_magenta_prompt() + + try: + user_input = int(input()) + except ValueError: + print("> Invalid number.") + sys.exit(1) + else: + try: + user_input = int(sys.argv[1]) + except ValueError: + print("> Invalid argument.") + sys.exit(1) + + pids = {} + + try: + print_green("> Starting database...") + try_start( + "db", + os.path.join(GAMEDIR, "channels", "db"), + "./db", + pids + ) + time.sleep(1) + + print_green("> Starting auth...") + try_start( + "auth", + os.path.join(GAMEDIR, "channels", "auth"), + "./game_auth", + pids + ) + time.sleep(1) + + # Start Channel cores + for channel_id, cores in channels.CHANNEL_MAP.items(): + print_green(f"> Starting CH{channel_id}:") + for core_id, maps in cores.items(): + name = f"channel{channel_id}_core{core_id}" + print_green(f"\t> {name}") + try_start( + name, + os.path.join(GAMEDIR, "channels", f"channel{channel_id}", f"core{core_id}"), + f"./{name}", + pids, + "channel" + ) + time.sleep(1) + print() + + if user_input and channel_id == user_input: + break + + print_green("> The server is running!") + + except Exception as e: + print(f"> Unexpected error: {e}") + traceback.print_exc() + + finally: + os.chdir(GAMEDIR) + try: + with open(PIDS_FILE, "w") as f: + json.dump(pids, f, indent=2) + print_green(f"> PID file written to {PIDS_FILE}") + + except Exception as e: + print(f"> Failed to write PID file: {e}") + traceback.print_exc() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/stop.py b/stop.py new file mode 100644 index 0000000..6185506 --- /dev/null +++ b/stop.py @@ -0,0 +1,70 @@ +import os +import sys +import time +import json +import subprocess +import signal +import traceback + +GAMEDIR = os.getcwd() +PIDS_FILE = os.path.join(GAMEDIR, "pids.json") + +def print_green(text): + print("\033[1;32m" + text + "\033[0m") + +def stop_pid(pid, name): + try: + if os.name == "nt": + subprocess.call(["taskkill", "/F", "/PID", str(pid)], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + else: + os.kill(pid, signal.SIGHUP) + except ProcessLookupError: + print(f"> Process {pid} ({name}) not found, skipping.") + except Exception as e: + print(f"> Error stopping {name} (PID {pid}): {e}") + traceback.print_exc() + +def kill_by_name(name): + try: + if os.name == "nt": + subprocess.call(["taskkill", "/F", "/IM", f"{name}.exe"], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + else: + subprocess.call(["pkill", "-1", name], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + except Exception as e: + print(f"> Error killing {name} by name: {e}") + traceback.print_exc() + +def main(): + try: + with open(PIDS_FILE, "r") as f: + entries = json.load(f) + except Exception as e: + print(f"> Could not read PID file: {e}") + traceback.print_exc() + sys.exit(1) + + for entry in entries.get("channel", []): + name = entry.get("name") + pid = entry.get("pid") + print_green(f"> Stopping {name} (PID {pid})...") + stop_pid(pid, name) + time.sleep(0.2) + + auth = entries.get("auth") + if auth: + print_green(f"> Stopping {auth.get('name')} (PID {auth.get('pid')})...") + stop_pid(auth.get('pid'), auth.get('name')) + time.sleep(1) + + db = entries.get("db") + if db: + print_green(f"> Stopping {db.get('name')} (PID {db.get('pid')})...") + stop_pid(db.get('pid'), db.get('name')) + + print_green("> All requested processes signaled.") + +if __name__ == "__main__": + main() \ No newline at end of file