extends Node class_name MainNode const PORT = 25565 const PORT_RANGE := 10 const MAX_CONNECTIONS = 20 @onready var before_connect_container = get_node("BeforeConnect") as Container @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 Node @onready var disconnect_button = get_node("%DisconnectButton") as Button @onready var demo_game = get_node("AfterConnect/DemoGame") as DemoGame @onready var start_game_button = (get_node("AfterConnect/DemoGame") as DemoGame).start_game_btn var active_port: int var server_buttons: Dictionary = Dictionary() var base_seed: int func _clean_room(): # this is if someone left the room and we will just clean the game room again # should only called on host # need to clean for server pass func _on_start_game_clicked(): if !multiplayer.multiplayer_peer: return if !multiplayer.is_server(): return if (multiplayer.get_peers().size() == 0): return # do start game here, should only run on host _start_game.rpc() 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) 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) demo_game.own_played_card.connect(func (card): _on_own_played_card.rpc(card.id if card else "")) demo_game.opponent_played_card.connect(func (card): _on_opponent_played_card.rpc(card.id if card else "")) demo_game.own_played_rts.connect(func (move): _on_own_played_rts.rpc(move)) demo_game.opponent_played_rts.connect(func (move): _on_opponent_played_rts.rpc(move)) @rpc("any_peer", "call_remote", "reliable") func _on_own_played_card(card_id: String): demo_game.rpc_own_play_card(card_id) @rpc("any_peer", "call_remote", "reliable") func _on_opponent_played_card(card_id: String): demo_game.rpc_opponent_play_card(card_id) @rpc("any_peer", "call_remote", "reliable") func _on_own_played_rts(move: String): demo_game.rpc_own_rps_move(move) @rpc("any_peer", "call_remote", "reliable") func _on_opponent_played_rts(move: String): demo_game.rpc_opponent_rps_move(move) @rpc("authority", "call_local", "reliable") func _sync_seed(seed: int): seed(seed) @rpc("authority", "call_local", "reliable") func _start_game(): if multiplayer.is_server(): demo_game.init(MatchManager.PLAYER_1_ID) else: demo_game.init(MatchManager.PLAYER_2_ID) demo_game.rpc_start_game() 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.disabled = true start_game_button.text = "Start Game (Not enough player)" base_seed = randi() _sync_seed.rpc(base_seed) 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 func _on_player_connected(id: int): if multiplayer.get_unique_id() == 1: _sync_seed.rpc(base_seed) if (multiplayer.get_peers().size() > 0): start_game_button.disabled = false 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.disabled = true 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 if (multiplayer.is_server()): disconnect_button.text = "Disconnect (Host)" start_game_button.visible = true else: disconnect_button.text = "Disconnect" start_game_button.visible = false func _on_connected_fail(): pass func _on_server_disconnected(): print("%s | _on_server_disconnected" % [server_discovery.id]) $AfterConnect.visible = false $BeforeConnect.visible = true