extends Node const MAX_PEERS = 4 const LOBBY_READY_WAIT_TIME = 3 const EMPTY_WAIT_TIME = 30 var port:int = -1 var dedicated_server:bool = false var server_secret:String = "" var server_id:String = "[GAME:-1] " var timer:Timer signal server_error(type, data) func _ready(): for argument in OS.get_cmdline_args(): if argument.split("=")[0] == "--port": dedicated_server = true port = int(argument.split("=")[1]) if argument.split("=")[0] == "--server-id": server_id = "[GAME:" + str(argument.split("=")[1]) + "] " if argument.split("=")[0] == "--secret": server_secret=argument.split("=")[1] if argument.split("=")[0] == "--bots": gamestate.set_bots(bool(int(argument.split("=")[1]))) if dedicated_server: var err = host_game(port) if err == OK: print(server_id + "New game hosted: port=" + str(port) + " secret=" + str(server_secret) + " bots=" + str(gamestate.bots)) else: print(server_id + "Could not create Server! (port=" + str(port) + " secret=" + str(server_secret) + ")") quit_server() func host_game(port:int, set_bots:bool = false): var host = NetworkedMultiplayerENet.new() var err = host.create_server(port, MAX_PEERS) get_tree().set_network_peer(host) get_tree().connect("network_peer_connected", self, "_client_connected") get_tree().connect("network_peer_disconnected", self,"_client_disconnected") gamestate.connect("players_changed",self,"_players_changed") gamestate.connect("game_ready",self,"_game_ready") gamestate.connect("game_ended",self,"_game_ended") if set_bots: gamestate.bots = true if timer == null: timer = Timer.new() timer.set_name("timer") timer.set_timer_process_mode(Timer.TIMER_PROCESS_PHYSICS) timer.set_one_shot(true) timer.set_autostart(false) add_child(timer) if err != OK: emit_signal("server_error", "HOST", err) return err func local_game(name:String, color:Color, bots:bool): var localhost = NetworkedMultiplayerENet.new() localhost.create_server(0, 0) get_tree().set_network_peer(localhost) gamestate.bots = bots gamestate.set_player(get_tree().get_network_unique_id(), name, color) gamestate.prepare_game() gamestate.post_start_game() func update_server_data(): var req = game_server.http() req.put_request("game",to_json({'secret' : server_secret, 'player_count' : gamestate.players.size(), 'running' : gamestate.game_running})) func _client_connected(id): if get_tree().is_network_server(): if dedicated_server: print(server_id + "peer connected: " + str(id)) gamestate.rpc_id(id, "set_bots" ,gamestate.bots) if not timer.is_stopped(): timer.disconnect("timeout",self,"quit_server") timer.stop() func _client_disconnected(id): if get_tree().is_network_server(): if dedicated_server: print(server_id + "peer disconnected: " + str(id)) if gamestate.game_running: emit_signal("server_error", "DISCONNECTED", [id]) gamestate.rpc("remove_player" ,id) else: gamestate.rpc("remove_player" ,id) func _players_changed(players): if get_tree().is_network_server(): if dedicated_server: update_server_data() if players.empty(): if gamestate.game_running: print(server_id + "All players disconnected, close server.") quit_server() else: print(server_id + "All players disconnected, wait for closing...") timer.set_wait_time(EMPTY_WAIT_TIME) timer.connect("timeout",self,"quit_server",[true]) timer.start() func quit_server(triggered:bool = false): if dedicated_server && triggered: print(server_id + "Closing time over...quit") var req = game_server.http() req.connect_http(self,"_on_delete_server") req.delete_request("game",to_json({'secret' : server_secret})) func _on_delete_server(result, response_code, headers, body): if result != OK || response_code != HTTPClient.RESPONSE_OK: print(server_id + "ERROR: _on_delete_server, server might be in undefined state!") get_tree().quit() func _start_game(): if get_tree().is_network_server(): get_tree().set_refuse_new_network_connections(true) gamestate.rpc("prepare_game") func _game_ready(all_ready): if get_tree().is_network_server(): if all_ready: timer.set_wait_time(LOBBY_READY_WAIT_TIME) timer.connect("timeout",self,"_start_game") timer.start() else: timer.disconnect("timeout",self,"_start_game") timer.stop() func _game_ended(): get_tree().disconnect("network_peer_connected", self, "_client_connected") get_tree().disconnect("network_peer_disconnected", self,"_client_disconnected") gamestate.disconnect("players_changed",self,"_players_changed") gamestate.disconnect("game_ready",self,"_game_ready") gamestate.disconnect("game_ended",self,"_game_ended") get_tree().set_refuse_new_network_connections(false) get_tree().set_network_peer(null)