extends Node const PORT = 25565 const PORT_RANGE := 10 const MAX_CONNECTIONS = 20 var counter = 0 @onready var before_connect_container = get_node("BeforeConnect") as Container @onready var host_text_edit = get_node("%HostTextEdit") as TextEdit @onready var connect_button = get_node("%ConnectButton") as Button @onready var host_button = get_node("%HostButton") as Button @onready var server_discovery = get_node("%ServerDiscovery") as ServerDiscovery @onready var after_connect_container = get_node("%AfterConnect") as Container @onready var counter_label = get_node("%CounterLabel") as Label @onready var decrement_button = get_node("%DecrementButton") as Button @onready var increment_button = get_node("%IncrementButton") as Button @onready var disconnect_button = get_node("%DisconnectButton") as Button @onready var start_game_button = get_node("%StartGameButton") as Button var active_port: int var server_buttons: Dictionary = Dictionary() func _clean_room(): # this is if someone left the room and we will just clean the game room again # should only called on host _set_counter(0) pass func _on_start_game_clicked(): if !multiplayer.multiplayer_peer: return if !multiplayer.get_unique_id() != 1: return if (multiplayer.get_peers().size() == 0): return # do start game here, should only run on host pass func _ready() -> void: host_button.button_up.connect(_on_host_pressed) host_button.text = "Host (%s)" % server_discovery.id start_game_button.button_up.connect(_on_start_game_clicked) print("Attach client") multiplayer.peer_connected.connect(_on_player_connected) multiplayer.peer_disconnected.connect(_on_player_disconnected) multiplayer.connected_to_server.connect(_on_connected_ok) #multiplayer.connection_failed.connect(_on_connected_fail) multiplayer.server_disconnected.connect(_on_server_disconnected) increment_button.button_up.connect(func(): _increment.rpc()) decrement_button.button_up.connect(func(): _decrement.rpc()) disconnect_button.button_up.connect(_on_disconnect_clicked) connect_button.get_parent().remove_child(connect_button) server_discovery.server_added.connect(_on_server_added) server_discovery.server_removed.connect(_on_server_removed) func _on_disconnect_clicked(): if (multiplayer.is_server()): server_discovery.disable_server() for peer_id in multiplayer.get_peers(): multiplayer.disconnect_peer(peer_id) multiplayer.multiplayer_peer = null $BeforeConnect.visible = true $AfterConnect.visible = false func _on_server_added(id, ip, port): print("%s | Server added %s %s" % [server_discovery.id, id, ip]) var button = connect_button.duplicate() before_connect_container.add_child(button) var key = "%s|%s" % [id,ip] server_buttons[key] = button button.text = "%s\nConnect\n%s:%d" % [id, ip, port] for conn in button.button_down.get_connections(): button.button_down.disconnect(conn) var _on_button_downed = func(): _do_connect(ip, port) button.button_down.connect(_on_button_downed) func _on_server_removed(id, ip): print("%s | Server removed %s %s" % [server_discovery.id, id, ip]) var key = "%s|%s" % [id,ip] var button = server_buttons[key] button.queue_free() server_buttons.erase(key) func _do_connect(ip: String, port: int): var peer = ENetMultiplayerPeer.new() print("%s Connecting to %s:%d" % [server_discovery.id, ip, port]) peer.create_client(ip, port) multiplayer.multiplayer_peer = peer func _on_host_pressed(): print("%s | Starting dedicated server" % server_discovery.id) var peer = ENetMultiplayerPeer.new() for offset in range(PORT_RANGE): if not is_port_available(PORT + offset): continue active_port = PORT + offset var err = peer.create_server(active_port, MAX_CONNECTIONS) if err: print(err) break multiplayer.multiplayer_peer = peer _on_connected_ok() start_game_button.text = "Start Game (Not enough player)" server_discovery.enable_server(active_port) func is_port_available(port: int) -> bool: var udp_peer = PacketPeerUDP.new() var error = udp_peer.bind(port) if error == OK: udp_peer.close() return true else: return false @rpc("any_peer", "call_local") func _increment(): counter += 1 counter_label.text = str(counter) @rpc("any_peer", "call_local") func _decrement(): counter -= 1 counter_label.text = str(counter) @rpc("authority", "call_remote") func _set_counter(value: int): counter = value counter_label.text = str(counter) func _on_player_connected(id: int): if multiplayer.get_unique_id() == 1: _set_counter.rpc_id(id, counter) if (multiplayer.get_peers().size() > 0): start_game_button.text = "Start Game" server_discovery.disable_server() func _on_player_disconnected(id): print("%s | _on_player_disconnected %s" % [server_discovery.id, id]) if multiplayer.get_unique_id() == id: $BeforeConnect.visible = true $AfterConnect.visible = false if (id != 1 and multiplayer.get_unique_id() == 1): _clean_room() start_game_button.text = "Start Game (Not enough player)" server_discovery.enable_server(active_port) func _on_connected_ok(): $AfterConnect.visible = true $BeforeConnect.visible = false counter_label.text = str(counter) if (multiplayer.is_server()): disconnect_button.text = "Disconnect (Host)" if start_game_button.get_parent() != after_connect_container: after_connect_container.add_child(start_game_button) else: disconnect_button.text = "Disconnect" if start_game_button.get_parent() == after_connect_container: after_connect_container.remove_child(start_game_button) func _on_connected_fail(): pass func _on_server_disconnected(): print("%s | _on_server_disconnected" % [server_discovery.id]) $AfterConnect.visible = false $BeforeConnect.visible = true