From 70d181c8916bfee411a0a4d610f2bec43cc878f3 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Mon, 11 Mar 2024 05:09:33 +0100 Subject: [PATCH] Everything seems to be working as expected! --- scenes/game.gd | 27 +++++++++++++++------------ scenes/game.tscn | 2 ++ scenes/lobby_menu.gd | 7 ++++--- scenes/main.gd | 5 ++++- scenes/network_controller.gd | 17 ----------------- scenes/network_controller.tscn | 24 +++++++++++++++++++++--- scenes/peernode_directory.gd | 12 +++--------- scenes/playernode.gd | 8 +++++++- scenes/playernode_directory.gd | 16 ++++++---------- scenes/players_list.gd | 3 +++ utils/log.gd | 2 +- 11 files changed, 66 insertions(+), 57 deletions(-) delete mode 100644 scenes/network_controller.gd diff --git a/scenes/game.gd b/scenes/game.gd index 2cb9d26..393ba48 100644 --- a/scenes/game.gd +++ b/scenes/game.gd @@ -36,12 +36,19 @@ func _on_multiplayer_peer_connected(peer_id: int) -> void: if multiplayer.is_server(): for peernode in peer_dir.get_children(): peer_dir.rpc_create_peernode.rpc_id(peer_id, peernode.get_multiplayer_authority()) + for playernode in player_dir.get_children(): + player_dir.rpc_possess_playernode.rpc_id(peer_id, playernode.player_name, playernode.get_multiplayer_authority()) + playernode.rpc_query_name.rpc_id(playernode.get_multiplayer_authority()) + playernode.rpc_query_color.rpc_id(playernode.get_multiplayer_authority()) peer_dir.rpc_create_peernode.rpc(peer_id) func _on_multiplayer_peer_disconnected(peer_id: int) -> void: Log.peer(self, "Peer disconnected: %d" % peer_id) if multiplayer.is_server(): - peer_dir.rpc_destroy_peernode(peer_id) + for playernode in player_dir.get_children(): + if playernode.get_multiplayer_authority() == peer_id: + player_dir.rpc_possess_playernode.rpc(playernode.player_name, 1) + peer_dir.rpc_destroy_peernode.rpc(peer_id) func _on_peerdir_peernode_created(peernode: PeerNode) -> void: @@ -51,9 +58,6 @@ func _on_peerdir_peernode_created(peernode: PeerNode) -> void: func _on_peerdir_peernode_destroyed(peernode: PeerNode) -> void: Log.peer(self, "Peernode destroyed: %d" % peernode.get_multiplayer_authority()) - for playernode in player_dir.get_children(): - if playernode.get_multiplayer_authority() == peernode.get_multiplayer_authority(): - playernode.possess(1) func _on_peerdir_peernode_identified(player_name: String, peernode: PeerNode) -> void: Log.peer(self, "Peernode identified: %d → %s" % [peernode.get_multiplayer_authority(), player_name]) @@ -61,20 +65,19 @@ func _on_peerdir_peernode_identified(player_name: String, peernode: PeerNode) -> func _on_playerdir_playernode_created(playernode: PlayerNode) -> void: - Log.peer(self, "Playernode `%s` created" % playernode.name) + Log.peer(self, "Playernode `%s` created" % playernode.player_name) func _on_playerdir_playernode_destroyed(playernode: PlayerNode) -> void: - Log.peer(self, "Playernode `%s` destroyed" % playernode.name) - # Technically, this shouldn't ever happen + Log.peer(self, "Playernode `%s` destroyed" % playernode.player_name) func _on_playerdir_playernode_name_changed(old: String, new: String, playernode: PlayerNode) -> void: - Log.peer(self, "Playernode `%s` changed name: %s (was %s)" % [playernode.name, new, old]) + Log.peer(self, "Playernode `%s` changed name: %s (was %s)" % [playernode.player_name, new, old]) -func _on_playerdir_playernode_color_changed(old: Color, new: String, playernode: PlayerNode) -> void: - Log.peer(self, "Playernode `%s` changed color: %s (was %s)" % [playernode.name, new, old]) +func _on_playerdir_playernode_color_changed(old: Color, new: Color, playernode: PlayerNode) -> void: + Log.peer(self, "Playernode `%s` changed color: %s (was %s)" % [playernode.player_name, new, old]) func _on_playerdir_playernode_possessed(old: int, new: int, playernode: PlayerNode) -> void: - Log.peer(self, "Playernode `%s` possessed: %d (was %d)" % [playernode.name, new, old]) - if playernode.is_multiplayer_authority(): + Log.peer(self, "Playernode `%s` possessed: %d (was %d)" % [playernode.player_name, new, old]) + if playernode.is_multiplayer_authority() and not multiplayer.is_server(): playernode.rpc_set_name.rpc(local_player_name) playernode.rpc_set_color.rpc(local_player_color) diff --git a/scenes/game.tscn b/scenes/game.tscn index ce9b73d..56c92eb 100644 --- a/scenes/game.tscn +++ b/scenes/game.tscn @@ -14,6 +14,8 @@ script = ExtResource("1_cdtng") [connection signal="child_entered_tree" from="PeerNodeDirectory" to="." method="_on_peerdir_peernode_created"] [connection signal="child_exiting_tree" from="PeerNodeDirectory" to="." method="_on_peerdir_peernode_destroyed"] [connection signal="peernode_identified" from="PeerNodeDirectory" to="." method="_on_peerdir_peernode_identified"] +[connection signal="child_entered_tree" from="PlayerNodeDirectory" to="." method="_on_playerdir_playernode_created"] +[connection signal="child_exiting_tree" from="PlayerNodeDirectory" to="." method="_on_playerdir_playernode_destroyed"] [connection signal="playernode_color_changed" from="PlayerNodeDirectory" to="." method="_on_playerdir_playernode_color_changed"] [connection signal="playernode_name_changed" from="PlayerNodeDirectory" to="." method="_on_playerdir_playernode_name_changed"] [connection signal="playernode_possessed" from="PlayerNodeDirectory" to="." method="_on_playerdir_playernode_possessed"] diff --git a/scenes/lobby_menu.gd b/scenes/lobby_menu.gd index 140f66e..875ecde 100644 --- a/scenes/lobby_menu.gd +++ b/scenes/lobby_menu.gd @@ -5,11 +5,12 @@ class_name LobbyMenu signal leave_confirmed signal start_confirmed -@onready var players_list: PlayersList = $"Layout/PlayersList" +var players_list: Container + +func init_refs(): + players_list = $"Layout/PlayersList" -func _on_trackers_changed(trackers: Dictionary): - players_list._on_trackers_changed(trackers) func _on_leave_button_pressed() -> void: leave_confirmed.emit() diff --git a/scenes/main.gd b/scenes/main.gd index c9cb074..d4fd380 100644 --- a/scenes/main.gd +++ b/scenes/main.gd @@ -74,14 +74,17 @@ func init_lobby_menu(): lobby_menu_instance = lobby_menu_scene.instantiate() lobby_menu_instance.leave_confirmed.connect(_on_leave_confirmed) lobby_menu_instance.start_confirmed.connect(_on_start_confirmed) - interface_instance.add_child(lobby_menu_instance) + lobby_menu_instance.init_refs() + client_game_instance.multiplayer.server_disconnected.connect(_on_leave_confirmed) client_game_instance.player_dir.child_entered_tree.connect(lobby_menu_instance.players_list._on_playernode_created) client_game_instance.player_dir.child_exiting_tree.connect(lobby_menu_instance.players_list._on_playernode_destroyed) client_game_instance.player_dir.playernode_name_changed.connect(lobby_menu_instance.players_list._on_playernode_name_changed) client_game_instance.player_dir.playernode_color_changed.connect(lobby_menu_instance.players_list._on_playernode_color_changed) client_game_instance.player_dir.playernode_possessed.connect(lobby_menu_instance.players_list._on_playernode_possessed) + interface_instance.add_child(lobby_menu_instance) func deinit_lobby_menu(): + client_game_instance.multiplayer.server_disconnected.disconnect(_on_leave_confirmed) client_game_instance.player_dir.child_entered_tree.disconnect(lobby_menu_instance.players_list._on_playernode_created) client_game_instance.player_dir.child_exiting_tree.disconnect(lobby_menu_instance.players_list._on_playernode_destroyed) client_game_instance.player_dir.playernode_name_changed.disconnect(lobby_menu_instance.players_list._on_playernode_name_changed) diff --git a/scenes/network_controller.gd b/scenes/network_controller.gd deleted file mode 100644 index 5b435da..0000000 --- a/scenes/network_controller.gd +++ /dev/null @@ -1,17 +0,0 @@ -extends Node -class_name NetworkController - - -@export var port = 12345 - - -func start_server() -> ENetMultiplayerPeer: - var peer = ENetMultiplayerPeer.new() - peer.create_server(port, 32) - return peer - - -func start_client() -> ENetMultiplayerPeer: - var peer = ENetMultiplayerPeer.new() - peer.create_client("127.0.0.1", port) - return peer diff --git a/scenes/network_controller.tscn b/scenes/network_controller.tscn index 600bacb..91e6ff1 100644 --- a/scenes/network_controller.tscn +++ b/scenes/network_controller.tscn @@ -1,6 +1,24 @@ -[gd_scene load_steps=2 format=3 uid="uid://ddmiruki5mjn2"] +[gd_scene load_steps=2 format=3 uid="uid://d25h11x5grlnn"] -[ext_resource type="Script" path="res://scenes/network_controller.gd" id="1_2jxjv"] +[sub_resource type="GDScript" id="GDScript_nrktq"] +script/source = "extends Node +class_name NetworkController + + +@export var port = 12345 + + +func start_server() -> ENetMultiplayerPeer: + var peer = ENetMultiplayerPeer.new() + peer.create_server(port, 32) + return peer + + +func start_client() -> ENetMultiplayerPeer: + var peer = ENetMultiplayerPeer.new() + peer.create_client(\"127.0.0.1\", port) + return peer +" [node name="NetworkController" type="Node"] -script = ExtResource("1_2jxjv") +script = SubResource("GDScript_nrktq") diff --git a/scenes/peernode_directory.gd b/scenes/peernode_directory.gd index c02f12b..9f4b2b6 100644 --- a/scenes/peernode_directory.gd +++ b/scenes/peernode_directory.gd @@ -6,15 +6,9 @@ class_name PeerNodeDirectory @export var peernode_scene: PackedScene = preload("res://scenes/peernode.tscn") -## Cache dictionary mapping peer_ids to their respective [PeerNode]. -## -## This script is responsible for keeping it updated. -var peernodes_by_id: Dictionary = {} - - ## Find the subordinate [PeerNode] with the given peer_id, and return it if found, otherwise return null. func get_peernode(peer_id: int) -> PeerNode: - return peernodes_by_id.get(peer_id) as PeerNode + return get_node_or_null("%d" % peer_id) ## Create a new [PeerNode] for the given peer_id, or do nothing if it already exists. @@ -26,10 +20,10 @@ func rpc_create_peernode(peer_id: int): return # Create a new peernode peernode = peernode_scene.instantiate() - peernodes_by_id[peer_id] = peernode peernode.set_multiplayer_authority(peer_id) peernode.identified.connect(_on_peernode_identified.bind(peernode)) - add_child(peernode, true) + peernode.name = "%d" % peer_id + add_child(peernode) ## Destroy the [PeerNode] for the given peer_id, or do nothing if it does not exist. diff --git a/scenes/playernode.gd b/scenes/playernode.gd index 6ab4209..57cde0f 100644 --- a/scenes/playernode.gd +++ b/scenes/playernode.gd @@ -2,6 +2,11 @@ extends Node class_name PlayerNode +## Remove problematic characters from the player's name +static func sanitize_player_name(s: String) -> String: + return s.replace("/", "_").replace("*", "_").replace(" ", "_") + + ## The name of the player represented by this node. var player_name: String @@ -13,7 +18,8 @@ var player_color: Color func rpc_set_name(value: String): if player_name != value: var old_value: String = player_name - player_name = value + player_name = PlayerNode.sanitize_player_name(value) + name = PlayerNode.sanitize_player_name(value) name_changed.emit(old_value, value) ## Change the [field player_color] everywhere. diff --git a/scenes/playernode_directory.gd b/scenes/playernode_directory.gd index 047eac6..c52c089 100644 --- a/scenes/playernode_directory.gd +++ b/scenes/playernode_directory.gd @@ -6,15 +6,10 @@ class_name PlayerNodeDirectory @export var playernode_scene: PackedScene = preload("res://scenes/playernode.tscn") -## Cache dictionary mapping player names to their respective [PlayerNode]. -## -## This script is responsible for keeping it updated. -var playernodes_by_name: Dictionary = {} - - ## Find the subordinate [PlayerNode] with the given player_name, and return it if found, otherwise return null. func get_playernode(player_name: String) -> PlayerNode: - return playernodes_by_name.get(player_name) + var sanitized_player_name = PlayerNode.sanitize_player_name(player_name) + return get_node_or_null(sanitized_player_name) ## Create a new [PlayerNode] for the given [param player_name], giving control of it to [param peer_id]. @@ -31,15 +26,16 @@ func rpc_possess_playernode(player_name: String, peer_id: int): playernode.name_changed.connect(_on_playernode_name_changed.bind(playernode)) playernode.color_changed.connect(_on_playernode_color_changed.bind(playernode)) playernode.possessed.connect(_on_playernode_possessed.bind(playernode)) - add_child(playernode, true) + var sanitized_player_name = PlayerNode.sanitize_player_name(player_name) + playernode.player_name = sanitized_player_name + playernode.name = sanitized_player_name + add_child(playernode) # If the multiplayer authority does not match the requested one, make it match playernode.possess(peer_id) func _on_playernode_name_changed(old: String, new: String, playernode: PlayerNode): - playernodes_by_name.erase(old) - playernodes_by_name[new] = playernode playernode_name_changed.emit(old, new, playernode) func _on_playernode_color_changed(old: Color, new: Color, playernode: PlayerNode): diff --git a/scenes/players_list.gd b/scenes/players_list.gd index f4df099..71b73dc 100644 --- a/scenes/players_list.gd +++ b/scenes/players_list.gd @@ -11,6 +11,9 @@ var labels_by_playernode: Dictionary = {} func _on_playernode_created(playernode: PlayerNode) -> void: var label_instance = label_scene.instantiate() + label_instance.set_player_name(playernode.player_name) + label_instance.set_player_color(playernode.player_color) + label_instance.set_possessed(playernode.get_multiplayer_authority()) labels_by_playernode[playernode] = label_instance layout.add_child(label_instance) diff --git a/utils/log.gd b/utils/log.gd index 6e13b6d..92c7ac7 100644 --- a/utils/log.gd +++ b/utils/log.gd @@ -3,4 +3,4 @@ class_name Log static func peer(this: Node, string: String): - print("{", this.multiplayer.multiplayer_peer.get_unique_id(), "} ", string) + print("{", this.multiplayer.multiplayer_peer.get_unique_id(), "} [", str(this), "] ", string)