# Undercooked - a game about cooking # Copyright 2024 metamuffin # Copyright 2024 nokoe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, version 3 of the License only. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # class_name GameServer extends Node var thread = null var pid = null var state = State.TESTING enum State { TESTING, UNAVAILABLE, FAILED, STOPPED, STARTING, RUNNING, } var sem = Semaphore.new() var thread_result = null; func _ready(): state = State.TESTING thread = Thread.new() thread.start(_test_server) func test(): pass func start(): if state != State.STOPPED and state != State.FAILED: push_error("server cant be started") return state = State.STARTING thread = Thread.new() thread.start(_server_exec) func stop(): if state != State.RUNNING: push_error("server cant be stopped") return OS.kill(pid) func _test_server(): var output = [] thread_result = OS.execute(get_server_path(), ["-v"], output, true, false) sem.post() func _server_exec(): var args = [] var data_path = get_server_data() if data_path != null: args.push_back("--data-dir") args.push_back(data_path) thread_result = OS.create_process(get_server_path(), args, false) print(get_server_path(), args) if thread_result >= 0: var ok = false while not ok: var conn = StreamPeerTCP.new() if conn.connect_to_host("127.0.0.1", 27032) == OK: while conn.poll() == OK: if conn.get_status() == StreamPeerTCP.STATUS_ERROR: break elif conn.get_status() == StreamPeerTCP.STATUS_CONNECTED: ok = true; break OS.delay_msec(10) OS.delay_msec(500 if not ok else 50) if !OS.is_process_running(thread_result): thread_result = -1 break sem.post() func get_server_path() -> String: var path: String = Global.settings["server_binary"]["value"] if path != "": return path else: return "undercooked-server" func get_server_data(): var path: String = Global.settings["server_data"]["value"] if path != "": return path else: return null func _process(_delta): match state: State.TESTING: if sem.try_wait(): print("Server: Test result=", thread_result) if thread_result == 0: state = State.STOPPED else: state = State.UNAVAILABLE thread.wait_to_finish() thread = null State.STARTING: if sem.try_wait(): if thread_result >= 0: state = State.RUNNING pid = thread_result print("Server: Started pid=", thread_result) else: state = State.FAILED print("Server: Failed") thread.wait_to_finish() thread = null State.RUNNING: if not OS.is_process_running(pid): print("Server: Stopped") state = State.STOPPED pid = null func _exit_tree(): if thread != null: thread.wait_to_finish() if pid != null: OS.kill(pid)