diff --git a/project.godot b/project.godot index 6c81e50..1524ec6 100644 --- a/project.godot +++ b/project.godot @@ -65,3 +65,7 @@ gdscript/warnings/confusable_capture_reassignment=2 gdscript/warnings/property_used_as_function=2 gdscript/warnings/constant_used_as_function=2 gdscript/warnings/function_used_as_property=2 + +[editor] + +run/main_run_args="--client" diff --git a/scripts/utils/game.gd b/scripts/utils/game.gd index 0f55da3..179841b 100644 --- a/scripts/utils/game.gd +++ b/scripts/utils/game.gd @@ -23,5 +23,7 @@ func _ready() -> void: Log.error("Failed to start server! Closing application.", "Failed to start server!") "--client": Networking.join_room() + "res://start.tscn": + pass # Catch in order to prevent a warning. _: Log.warning("Unknown argument: %s!" % args[i]) diff --git a/scripts/utils/networking.gd b/scripts/utils/networking.gd index 5ed509e..a155916 100644 --- a/scripts/utils/networking.gd +++ b/scripts/utils/networking.gd @@ -10,6 +10,8 @@ func _ready() -> void: Log.error("FAILED to connect the connection_failed signal to _on_connected_fail!", "Internal Error: Failed to connect signal.") if multiplayer.server_disconnected.connect(close_network) != OK: Log.error("FAILED to connect the server_disconnected signal to _on_server_disconnected!", "Internal Error: Failed to connect signal.") + if multiplayer.peer_disconnected.connect(_on_peer_disconnected) != OK: + Log.error("FAILED to connect the peer_disconnected signal to _on_peer_disconnected!", "Internal Error: Failed to connect signal.") # Start the network listener. func start_server() -> Error: @@ -50,6 +52,36 @@ func _on_connected_ok() -> void: if rpc_id(1, "send_roomname", Game.room_name) != OK: Log.warning("Failed to send roomname!") +func _on_peer_disconnected(id: int) -> void: + mutex.lock() + if multiplayer.get_unique_id() == 1: + if rooms.has(id): + var roomname: String = rooms[id] + if !rooms.erase(roomname): + Log.warning("The room %s associated with %d doesn't exist in rooms, even though it should!" % [roomname, id]) + if !rooms.erase(id): + Log.warning("The peer %d doesn't exist in rooms, even though it should!" % id) + for peer: int in peers[roomname]: + if peer == id: + continue + if rpc_id(peer, "host_disconnected_message"): + Log.warning("Peer %d couldn't be disconnected!" % peer) + if !peers.erase(roomname): + Log.warning("Room %s couldn't be found, even though it should exist!" % roomname) + Log.info("Room %s terminated." % roomname) + else: + for room: String in peers: + for peer: int in peers[room]: + if peer == id: + var peer_array: Array = peers[room] + peer_array.erase(id) + peers[room] = peer_array + for found_peer: int in peers[room]: + if rpc_id(found_peer, "peer_disconnected_message") != OK: + Log.warning("Failed to send disconnect message to %d!" % found_peer) + mutex.unlock() + +# The following function sends the roomname selected by the client. @rpc("any_peer", "call_remote", "reliable") func send_roomname(roomname: String) -> void: mutex.lock() @@ -59,12 +91,39 @@ func send_roomname(roomname: String) -> void: rooms[multiplayer.get_remote_sender_id()] = roomname peers[roomname] = [multiplayer.get_remote_sender_id()] Log.info("Room %s registered." % roomname) + if rpc_id(multiplayer.get_remote_sender_id(), "server_response", 0) != OK: + Log.warning("Failed to send elevation reply to %d!") elif peers[roomname] is Array: # For some odd reason, Godot doesn't allow casting peers[roomname] to an Array, but this works? var peer_array: Array = peers[roomname] peer_array.append(multiplayer.get_remote_sender_id()) peers[roomname] = peer_array + if rpc_id(multiplayer.get_remote_sender_id(), "server_response", 1) != OK: + Log.warning("Failed to send join reply to %d!") Log.debug("Room %s joined by peer %d." % [roomname, multiplayer.get_remote_sender_id()]) else: Log.warning("Peer %d tried to send this client a request meant for the authority!" % multiplayer.get_remote_sender_id()) + if rpc_id(multiplayer.get_remote_sender_id(), "server_response", 2) != OK: + Log.warning("Failed to send fail reply to %d!") mutex.unlock() + +# This is the message sent out if the host of the room has left. +@rpc("authority", "call_remote", "reliable") +func host_disconnected_message() -> void: + pass # TODO: Implement this + +# This is the message sent out if a peer in the room has left. +@rpc("authority", "call_remote", "reliable") +func peer_disconnected_message() -> void: + pass # TODO: Implement this + +# This is the initial server response, which tells the client what its role is. +@rpc("authority", "call_remote", "reliable") +func server_response(status: int) -> void: + match status: + 0: + pass # TODO: makes new room manager + 1: + pass # TODO: makes new room member + 2: + pass # TODO: server error