extends Node @export_category("UI") @export var connect_ui: Control @export var address_input: LineEdit @export var port_input: LineEdit func host(): var host_dict = _parse_input() if host_dict.size() == 0: return ERR_CANT_RESOLVE var port = host_dict.port # Start host print("Starting host on port %s" % port) var peer = ENetMultiplayerPeer.new() if peer.create_server(port) != OK: print("Failed to listen on port %s" % port) get_tree().get_multiplayer().multiplayer_peer = peer print("Listening on port %s" % port) # Wait for server to start await Async.condition( func(): return peer.get_connection_status() != MultiplayerPeer.CONNECTION_CONNECTING ) if peer.get_connection_status() != MultiplayerPeer.CONNECTION_CONNECTED: OS.alert("Failed to start server!") return print("Server started") get_tree().get_multiplayer().server_relay = true connect_ui.hide() # Only start manually if NetworkEvents is not handling it (e.g. multiplayer-simple) if not NetworkEvents.enabled: NetworkTime.start() func join(): var host_dict = _parse_input() if host_dict.size() == 0: return ERR_CANT_RESOLVE var address = host_dict.address var port = host_dict.port # Connect print("Connecting to %s:%s" % [address, port]) var peer = ENetMultiplayerPeer.new() var err = peer.create_client(address, port) if err != OK: OS.alert("Failed to create client, reason: %s" % error_string(err)) return err get_tree().get_multiplayer().multiplayer_peer = peer # Wait for connection process to conclude await Async.condition( func(): return peer.get_connection_status() != MultiplayerPeer.CONNECTION_CONNECTING ) if peer.get_connection_status() != MultiplayerPeer.CONNECTION_CONNECTED: OS.alert("Failed to connect to %s:%s" % [address, port]) return print("Client started") connect_ui.hide() # Ensure game window has keyboard focus for input get_window().grab_focus() # Only start manually if NetworkEvents is not handling it (e.g. multiplayer-simple) if not NetworkEvents.enabled: NetworkTime.start() func _enter_tree(): # Hide and show UI as appropriate # These handlers are necessary, since the game could have started via # autoconnect, or any other method NetworkEvents.on_client_start.connect(func(__): connect_ui.hide() get_window().grab_focus() ) NetworkEvents.on_server_start.connect(func(): connect_ui.hide() get_window().grab_focus() ) NetworkEvents.on_client_stop.connect(func(): connect_ui.show()) NetworkEvents.on_server_stop.connect(func(): connect_ui.show()) func _parse_input() -> Dictionary: # Validate inputs var address = address_input.text var port = port_input.text if address == "": OS.alert("No host specified!") return {} if not port.is_valid_int(): OS.alert("Invalid port!") return {} port = port.to_int() return { "address": address, "port": port }