From bfd005d01c1b1a190d81026cacec823844bec4c9 Mon Sep 17 00:00:00 2001 From: John Breaux Date: Wed, 24 Nov 2021 02:48:02 -0600 Subject: [PATCH] Lobby: Return to Host/Connect menu when connection to server unexpectedly closes --- godot_ship/script/network/Lobby.gd | 48 +++++++++++++++++++++--------- godot_ship/script/network/Net.gd | 36 ++++++++++++++++------ 2 files changed, 61 insertions(+), 23 deletions(-) diff --git a/godot_ship/script/network/Lobby.gd b/godot_ship/script/network/Lobby.gd index d73d8ca..ba9c7c3 100644 --- a/godot_ship/script/network/Lobby.gd +++ b/godot_ship/script/network/Lobby.gd @@ -1,7 +1,7 @@ extends Control # Ignore discarded return values # warning-ignore:return_value_discarded -onready var text = find_node("Player List") +onready var player_list = find_node("Player List") onready var ip = find_node("IP Address") # TODO: Write a function to update Player List with the list of attached players @@ -11,7 +11,7 @@ func _on_peers_updated(): for peer in Net.peer_info: connected_peers += ("%s\n" % Net.peer_info[peer]["name"]) pass - text.text = connected_peers.rsplit("\n", true, 1)[0].c_unescape() + player_list.text = connected_peers.rsplit("\n", true, 1)[0].c_unescape() pass func set_IP_Address_text(show): @@ -23,6 +23,7 @@ func set_IP_Address_text(show): func _ready(): Net.connect("peers_updated", self, "_on_peers_updated") + Net.connect("disconnected", self, "_on_Net_disconnected") _on_peers_updated() pass @@ -47,12 +48,18 @@ func _on_Host_Button_pressed(): # Disconnect from (or stop hosting) a game # Shows the host/connect buttons func _on_Disconnect_Button_pressed(): - # Hide "Connected Options" - show_Connected_Options(false) - # Show the host IP address - set_IP_Address_text(false) # Disconnect Net.disconnect_host() + # Hide "Connected Options" + show_Connected_Options(false) + # Hide the host IP address + set_IP_Address_text(false) + +func _on_Net_disconnected(): + # Hide "Connected Options" + show_Connected_Options(false) + # Hide the host IP address + set_IP_Address_text(false) func _on_Change_Name_Button_pressed(): # Show the Change Name dialogue @@ -76,17 +83,30 @@ func _on_Connect_to_Game_confirmed(): # Show "Connected Options" show_Connected_Options(true) -func _on_Change_Name_confirmed(): - # Get the new name - var name = find_node("Name Entry").text.split("\n")[0] - # Set it as the name - Net.change_name(name) - - - func _on_Exit_Lobby_pressed(): # Disconnect if Net.connected: Net.disconnect_host() # Close Lobby menu queue_free() + + +func _on_IP_and_Port_Entry_text_entered(text): + # Split it into IP and Port segments + var ip_port = text.split(":") + # If text exists and contains valid IP address + if ip_port.size() > 0 and ip_port[0].is_valid_ip_address(): + # Connect to host + var connected = Net.callv("connect_host", ip_port) + if connected == OK: + # Show "Connected Options" + show_Connected_Options(true) + # Hide the popup + find_node("Connect to Game").hide() + + +func _on_Name_Entry_text_entered(text): + # Change the name + Net.change_name(text) + # Hide the popup + find_node("Change Name").hide() diff --git a/godot_ship/script/network/Net.gd b/godot_ship/script/network/Net.gd index 22409e8..6b75b99 100644 --- a/godot_ship/script/network/Net.gd +++ b/godot_ship/script/network/Net.gd @@ -10,15 +10,15 @@ const LOCALHOST = "127.0.0.1" # Mail types: # 1: REQUEST: Message is a request for information # 0: REPLY: Message is a reply -enum {REPLY, REQUEST} +enum {REPLY, REQUEST, READY, ACK} # Signals # incoming(mail): Sent when there's an incoming message signal incoming # peers_updated(): Sent when the peer list is updated signal peers_updated -# - +# disconnected(): Sent when unexpectedly disconnected +signal disconnected # Variables # inbox: Array: Message history var inbox = [] @@ -33,8 +33,9 @@ var local_info = {"name": ""} # Network -- handles server and client setup, and facilitates communication between the two # receive: Receive a message (called by sender's `send` function) -# item: The message received from the sender (implicitly JSON-decoded by JSONRPC) -sync func receive(mail): +# mail: The message received from the sender (implicitly JSON-decoded by JSONRPC) +# mail_type: Type of mail (see "Mail Types" enum above) +remote func receive(mail): # Get the sender's ID and force letter to be properly addressed mail[0] = get_tree().get_rpc_sender_id() # Add the mail to the inbox (so it can be read back later if necessary @@ -45,10 +46,12 @@ sync func receive(mail): # send: Send a message # id: Peer ID of the recipient # mail: Variant of a json-encodable type (non-Object) to send -func send(id, mail): +# mail_type: Type of mail (see "Mail Types" enum above) +func send(id, mail, mail_type = REPLY): # Make the recipient receive the mail - rpc_id(id, "receive", to_json(mail)) + rpc_id(id, "receive", to_json([-1, mail, mail_type])) +# Host # start_host: Host the game # port: TCP port # max_players: Largest number of players allowed to connect at a time @@ -67,12 +70,20 @@ func start_host(port = DEFAULT_PORT, max_players = 2): connected = true hosting = true +# accept_guests: +# Select whether to accept new guests +func accept_guests(accept:bool): + if hosting: + multiplayer.refuse_new_network_connections = not accept + +# Guest # connect_host: Connect to a host func connect_host(ip = LOCALHOST, port = DEFAULT_PORT): get_hostname() var peer = NetworkedMultiplayerENet.new() - peer.create_client(ip, port) + var ret = peer.create_client(ip, port) get_tree().network_peer = peer + return ret # disconnect_host func disconnect_host(): @@ -99,6 +110,7 @@ func change_name(name): rpc("register_peer", local_info) pass +# Helper Functions # get_hostname: Asks the host machine to provide its hostname, # and if the peer name isn't set, set it to the hostname func get_hostname(): @@ -125,15 +137,19 @@ func _ready(): _trash = get_tree().connect("server_disconnected", self, "_host_disconnected") _trash = get_tree().connect("connection_failed", self, "_connection_fail" ) - +# Signal Handlers func _peer_connected(id): # Send peer info to remote peer rpc_id(id, "register_peer", local_info) + if hosting and peer_info.size() >= 2: + pass pass func _peer_disconnected(id): # Unregister the peer locally unregister_peer(id) + if hosting and peer_info.size() < 2: + pass pass @@ -147,6 +163,8 @@ func _host_connected(): func _host_disconnected(): # Ensure host is disconnected disconnect_host() + # Send disconnection message to listeners + emit_signal("disconnected") func _connection_fail(): # Ensure Net state is clear