extends Node var port_range_start: int = 5000 var port_range_end: int = 5010 var threads: Dictionary = Dictionary() func _wait_for_child(id: String, port: String, mode: String) -> void: if port == "-1": call_deferred("_child_finished", id, -1) return var output := [] var exit_code := OS.execute( "./game.sh", [ "--headless", "--", "server_" + port, "game", mode ], output, true ) call_deferred("_child_finished", id, exit_code) func _child_finished(id: String, exit_code: int) -> void: var thread: Thread = threads.get(id) if not thread: return push_warning("Game Server [ %s ] Exited: %d" % [id, exit_code]) thread.wait_to_finish() threads.erase(id) func is_port_free(port: int) -> bool: var server := TCPServer.new() var state := server.listen(port) match state: OK: server.stop() return true _: return false func find_free_port(start_port: int = 1024, end_port: int = 65535) -> int: for port in range(start_port, end_port + 1): if is_port_free(port): return port return -1 func launch_game_server(mode: String) -> String: var thread := Thread.new() var thread_id := str( thread.get_instance_id() ) var port := str( find_free_port( port_range_start, port_range_end ) ) thread.start( _wait_for_child.bind( thread_id, port, mode ) ) threads.set(thread_id, thread) return port