From 12816a2caafff91c8a9c554ba94a1d446cb772bc Mon Sep 17 00:00:00 2001 From: John Breaux Date: Tue, 23 Nov 2021 22:44:53 -0600 Subject: [PATCH] Multiplayer: Add Lobby --- ...k.png-664d38fd54271fbacb81205517c40701.md5 | 3 + ....png-664d38fd54271fbacb81205517c40701.stex | Bin 0 -> 184 bytes ...t.png-25b7c30a8a8b20ed722b3b35c8a79d7b.md5 | 3 + ....png-25b7c30a8a8b20ed722b3b35c8a79d7b.stex | Bin 0 -> 184 bytes .../assets/backgrounds/PanelBG_Dark.png | Bin 0 -> 152 bytes .../backgrounds/PanelBG_Dark.png.import | 34 ++++ .../assets/backgrounds/PanelBG_Dark.tres | 12 ++ .../assets/backgrounds/PanelBG_Light.png | Bin 0 -> 152 bytes .../backgrounds/PanelBG_Light.png.import | 34 ++++ .../assets/backgrounds/PanelBG_Light.tres | 11 ++ godot_ship/dark_theme.tres | 18 +- godot_ship/light_theme.tres | 15 +- godot_ship/scenes/Lobby.tscn | 171 ++++++++++++++++++ godot_ship/scenes/Title Screen.tscn | 1 + godot_ship/script/Main.gd | 3 +- godot_ship/script/game/Gameplay/Game.gd | 33 +--- godot_ship/script/network/Lobby.gd | 92 ++++++++++ godot_ship/script/network/Net.gd | 95 ++++++---- 18 files changed, 453 insertions(+), 72 deletions(-) create mode 100644 godot_ship/.import/PanelBG_Dark.png-664d38fd54271fbacb81205517c40701.md5 create mode 100644 godot_ship/.import/PanelBG_Dark.png-664d38fd54271fbacb81205517c40701.stex create mode 100644 godot_ship/.import/PanelBG_Light.png-25b7c30a8a8b20ed722b3b35c8a79d7b.md5 create mode 100644 godot_ship/.import/PanelBG_Light.png-25b7c30a8a8b20ed722b3b35c8a79d7b.stex create mode 100644 godot_ship/assets/backgrounds/PanelBG_Dark.png create mode 100644 godot_ship/assets/backgrounds/PanelBG_Dark.png.import create mode 100644 godot_ship/assets/backgrounds/PanelBG_Dark.tres create mode 100644 godot_ship/assets/backgrounds/PanelBG_Light.png create mode 100644 godot_ship/assets/backgrounds/PanelBG_Light.png.import create mode 100644 godot_ship/assets/backgrounds/PanelBG_Light.tres create mode 100644 godot_ship/scenes/Lobby.tscn create mode 100644 godot_ship/script/network/Lobby.gd diff --git a/godot_ship/.import/PanelBG_Dark.png-664d38fd54271fbacb81205517c40701.md5 b/godot_ship/.import/PanelBG_Dark.png-664d38fd54271fbacb81205517c40701.md5 new file mode 100644 index 0000000..18e3cff --- /dev/null +++ b/godot_ship/.import/PanelBG_Dark.png-664d38fd54271fbacb81205517c40701.md5 @@ -0,0 +1,3 @@ +source_md5="136899ff4c68986c4cc62e296277b8ab" +dest_md5="3d16ccd1874686296ee01de7097a3a6f" + diff --git a/godot_ship/.import/PanelBG_Dark.png-664d38fd54271fbacb81205517c40701.stex b/godot_ship/.import/PanelBG_Dark.png-664d38fd54271fbacb81205517c40701.stex new file mode 100644 index 0000000000000000000000000000000000000000..4362eb9fe48093f5f8035e589af19fc09aea0350 GIT binary patch literal 184 zcmZ>F2@X+UU|;}Y2oPXr1Ty9Tae$w@LMM>m<&xq8a(O*HT!MhK0tj=k0mF2@X+UU|;}Y2oPXr1Ty9Tae$w@LMM>m<&xq8a(O*HT!MhK0tj=k0m=_&$08klfJ5Sz*%^7;rqJFJy-OO&o;wEeGsv(fQ$133p<6=IE(gQ1) q;X({c(_8K&FBF&fARtk|&cMK~z^?ebVzw>NbOujXKbLh*2~7aKC@zcu literal 0 HcmV?d00001 diff --git a/godot_ship/assets/backgrounds/PanelBG_Dark.png.import b/godot_ship/assets/backgrounds/PanelBG_Dark.png.import new file mode 100644 index 0000000..0921b1b --- /dev/null +++ b/godot_ship/assets/backgrounds/PanelBG_Dark.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/PanelBG_Dark.png-664d38fd54271fbacb81205517c40701.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/backgrounds/PanelBG_Dark.png" +dest_files=[ "res://.import/PanelBG_Dark.png-664d38fd54271fbacb81205517c40701.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/godot_ship/assets/backgrounds/PanelBG_Dark.tres b/godot_ship/assets/backgrounds/PanelBG_Dark.tres new file mode 100644 index 0000000..1e6ac82 --- /dev/null +++ b/godot_ship/assets/backgrounds/PanelBG_Dark.tres @@ -0,0 +1,12 @@ +[gd_resource type="StyleBoxTexture" load_steps=2 format=2] + +[ext_resource path="res://assets/backgrounds/PanelBG_Dark.png" type="Texture" id=1] + +[resource] +texture = ExtResource( 1 ) +region_rect = Rect2( 0, 0, 32, 32 ) +margin_left = 6.0 +margin_right = 6.0 +margin_top = 6.0 +margin_bottom = 6.0 +axis_stretch_horizontal = 1 diff --git a/godot_ship/assets/backgrounds/PanelBG_Light.png b/godot_ship/assets/backgrounds/PanelBG_Light.png new file mode 100644 index 0000000000000000000000000000000000000000..318b484bb398c50bade6fc27a37cb74cfe0976a1 GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}L7py-ArY;~ zJ@&t!*dJzKTGqIwCcvVBb>`&5>W<>x%WJ9_)A=hndaM$zFfQhkC_S)(*-h5qRYM>< qT!_KzJjc%CPWlE96b&BmF)-|%z;SR(=^h@S=?tE(elF{r5}E*m$}aW* literal 0 HcmV?d00001 diff --git a/godot_ship/assets/backgrounds/PanelBG_Light.png.import b/godot_ship/assets/backgrounds/PanelBG_Light.png.import new file mode 100644 index 0000000..35d34d1 --- /dev/null +++ b/godot_ship/assets/backgrounds/PanelBG_Light.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/PanelBG_Light.png-25b7c30a8a8b20ed722b3b35c8a79d7b.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/backgrounds/PanelBG_Light.png" +dest_files=[ "res://.import/PanelBG_Light.png-25b7c30a8a8b20ed722b3b35c8a79d7b.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/godot_ship/assets/backgrounds/PanelBG_Light.tres b/godot_ship/assets/backgrounds/PanelBG_Light.tres new file mode 100644 index 0000000..89f2eb8 --- /dev/null +++ b/godot_ship/assets/backgrounds/PanelBG_Light.tres @@ -0,0 +1,11 @@ +[gd_resource type="StyleBoxTexture" load_steps=2 format=2] + +[ext_resource path="res://assets/backgrounds/PanelBG_Light.png" type="Texture" id=1] + +[resource] +texture = ExtResource( 1 ) +region_rect = Rect2( 0, 0, 32, 32 ) +margin_left = 6.0 +margin_right = 6.0 +margin_top = 6.0 +margin_bottom = 7.0 diff --git a/godot_ship/dark_theme.tres b/godot_ship/dark_theme.tres index 24098cd..3ed6bd8 100644 --- a/godot_ship/dark_theme.tres +++ b/godot_ship/dark_theme.tres @@ -1,6 +1,7 @@ [gd_resource type="Theme" load_steps=6 format=2] [ext_resource path="res://assets/font/Minecraft.ttf" type="DynamicFontData" id=1] +[ext_resource path="res://assets/backgrounds/PanelBG_Dark.tres" type="StyleBox" id=2] [sub_resource type="StyleBoxFlat" id=1] bg_color = Color( 0.239216, 0.211765, 0.317647, 1 ) @@ -19,10 +20,7 @@ corner_radius_bottom_left = 3 shadow_size = 3 [sub_resource type="DynamicFont" id=3] -outline_color = Color( 0, 0, 0, 1 ) -font_data = ExtResource( 1 ) - -[sub_resource type="DynamicFont" id=4] +outline_size = 1 outline_color = Color( 0, 0, 0, 1 ) extra_spacing_top = 5 extra_spacing_bottom = 3 @@ -30,9 +28,9 @@ extra_spacing_char = 1 font_data = ExtResource( 1 ) [resource] -default_font = SubResource( 4 ) +default_font = SubResource( 3 ) Button/colors/font_color = Color( 1, 1, 1, 1 ) -Button/colors/font_color_disabled = Color( 0.9, 0.9, 0.9, 0.2 ) +Button/colors/font_color_disabled = Color( 0.901961, 0.901961, 0.901961, 0.2 ) Button/colors/font_color_hover = Color( 1, 1, 1, 1 ) Button/colors/font_color_pressed = Color( 1, 1, 1, 1 ) Button/constants/hseparation = 2 @@ -45,14 +43,16 @@ Button/styles/pressed = null Dialogs/constants/button_margin = 100 Dialogs/constants/margin = 8 Label/colors/font_color = Color( 1, 1, 1, 1 ) -Label/colors/font_color_shadow = Color( 0, 0, 0, 0 ) +Label/colors/font_color_shadow = Color( 0, 0, 0, 0.25098 ) Label/colors/font_outline_modulate = Color( 0, 0, 0, 1 ) Label/constants/line_spacing = 3 Label/constants/shadow_as_outline = 0 Label/constants/shadow_offset_x = 0 -Label/constants/shadow_offset_y = 0 -Label/fonts/font = SubResource( 3 ) +Label/constants/shadow_offset_y = 2 +Label/fonts/font = null Label/styles/normal = null +Panel/styles/panel = ExtResource( 2 ) +PanelContainer/styles/panel = ExtResource( 2 ) WindowDialog/colors/title_color = Color( 0.152941, 0.152941, 0.152941, 1 ) WindowDialog/constants/close_h_ofs = 18 WindowDialog/constants/close_v_ofs = 18 diff --git a/godot_ship/light_theme.tres b/godot_ship/light_theme.tres index dfa1f4b..f7605a8 100644 --- a/godot_ship/light_theme.tres +++ b/godot_ship/light_theme.tres @@ -1,6 +1,7 @@ [gd_resource type="Theme" load_steps=6 format=2] [ext_resource path="res://assets/font/Minecraft.ttf" type="DynamicFontData" id=1] +[ext_resource path="res://assets/backgrounds/PanelBG_Light.tres" type="StyleBox" id=2] [sub_resource type="StyleBoxFlat" id=1] bg_color = Color( 1, 1, 1, 1 ) @@ -18,12 +19,8 @@ corner_radius_bottom_right = 3 corner_radius_bottom_left = 3 shadow_size = 3 -[sub_resource type="DynamicFont" id=3] -outline_color = Color( 0, 0, 0, 1 ) -font_data = ExtResource( 1 ) - [sub_resource type="DynamicFont" id=4] -outline_color = Color( 0, 0, 0, 1 ) +outline_size = 1 extra_spacing_top = 5 extra_spacing_bottom = 3 extra_spacing_char = 1 @@ -45,14 +42,16 @@ Button/styles/pressed = null Dialogs/constants/button_margin = 100 Dialogs/constants/margin = 8 Label/colors/font_color = Color( 1, 1, 1, 1 ) -Label/colors/font_color_shadow = Color( 0, 0, 0, 0 ) +Label/colors/font_color_shadow = Color( 0, 0, 0, 1 ) Label/colors/font_outline_modulate = Color( 0, 0, 0, 1 ) Label/constants/line_spacing = 3 Label/constants/shadow_as_outline = 0 Label/constants/shadow_offset_x = 0 -Label/constants/shadow_offset_y = 0 -Label/fonts/font = SubResource( 3 ) +Label/constants/shadow_offset_y = 2 +Label/fonts/font = null Label/styles/normal = null +Panel/styles/panel = ExtResource( 2 ) +PanelContainer/styles/panel = ExtResource( 2 ) WindowDialog/colors/title_color = Color( 0.152941, 0.152941, 0.152941, 1 ) WindowDialog/constants/close_h_ofs = 18 WindowDialog/constants/close_v_ofs = 18 diff --git a/godot_ship/scenes/Lobby.tscn b/godot_ship/scenes/Lobby.tscn new file mode 100644 index 0000000..22e3714 --- /dev/null +++ b/godot_ship/scenes/Lobby.tscn @@ -0,0 +1,171 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://script/network/Lobby.gd" type="Script" id=1] + +[node name="Lobby" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +mouse_filter = 2 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Player List Container" type="PanelContainer" parent="."] +anchor_left = 0.6 +anchor_top = 0.2 +anchor_right = 0.9 +anchor_bottom = 0.8 +size_flags_vertical = 4 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Align Vertically" type="VBoxContainer" parent="Player List Container"] +margin_left = 7.0 +margin_top = 7.0 +margin_right = 185.0 +margin_bottom = 209.0 +grow_horizontal = 2 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Players" type="Label" parent="Player List Container/Align Vertically"] +margin_right = 178.0 +margin_bottom = 14.0 +text = "Players" +align = 1 + +[node name="Player List" type="Label" parent="Player List Container/Align Vertically"] +margin_top = 18.0 +margin_right = 178.0 +margin_bottom = 32.0 +align = 1 + +[node name="Lobby Options" type="VBoxContainer" parent="."] +anchor_left = 0.2 +anchor_top = 0.2 +anchor_right = 0.2 +anchor_bottom = 0.2 +margin_right = 123.0 +margin_bottom = 84.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Lobby Text" type="Label" parent="Lobby Options"] +margin_right = 123.0 +margin_bottom = 14.0 +text = "Multiplayer Lobby" +align = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="IP Address" type="Label" parent="Lobby Options"] +margin_top = 18.0 +margin_right = 123.0 +margin_bottom = 32.0 +align = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Host or Connect" type="VBoxContainer" parent="Lobby Options"] +margin_top = 36.0 +margin_right = 123.0 +margin_bottom = 80.0 + +[node name="Host Button" type="Button" parent="Lobby Options/Host or Connect"] +margin_right = 123.0 +margin_bottom = 20.0 +text = "Host Game" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Connect Button" type="Button" parent="Lobby Options/Host or Connect"] +margin_top = 24.0 +margin_right = 123.0 +margin_bottom = 44.0 +text = "Connect to Game" + +[node name="Connected Options" type="VBoxContainer" parent="Lobby Options"] +visible = false +margin_top = 84.0 +margin_right = 123.0 +margin_bottom = 104.0 + +[node name="Disconnect Button" type="Button" parent="Lobby Options/Connected Options"] +margin_right = 123.0 +margin_bottom = 20.0 +text = "Disconnect" + +[node name="Change Name Button" type="Button" parent="Lobby Options"] +margin_top = 84.0 +margin_right = 123.0 +margin_bottom = 104.0 +text = "Change Name" + +[node name="Exit Lobby" type="Button" parent="Lobby Options"] +margin_top = 108.0 +margin_right = 123.0 +margin_bottom = 128.0 +text = "Exit Lobby" + +[node name="Change Name" type="AcceptDialog" parent="."] +margin_left = 402.272 +margin_top = 809.953 +margin_right = 642.272 +margin_bottom = 883.953 +rect_min_size = Vector2( 240, 74 ) +window_title = "Change Name" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Name Entry" type="TextEdit" parent="Change Name"] +anchor_left = 0.5 +anchor_right = 0.5 +margin_left = -112.0 +margin_top = 8.0 +margin_right = 112.0 +margin_bottom = 38.0 +grow_horizontal = 2 +text = "127.0.0.1" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Connect to Game" type="AcceptDialog" parent="."] +margin_left = 201.136 +margin_top = 404.977 +margin_right = 441.136 +margin_bottom = 478.977 +rect_min_size = Vector2( 240, 74 ) +window_title = "Connect to Game" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="IP and Port Entry" type="TextEdit" parent="Connect to Game"] +anchor_left = 0.5 +anchor_right = 0.5 +margin_left = -112.0 +margin_top = 8.0 +margin_right = 112.0 +margin_bottom = 38.0 +grow_horizontal = 2 +text = "127.0.0.1" +__meta__ = { +"_edit_use_anchors_": false +} + +[connection signal="pressed" from="Lobby Options/Host or Connect/Host Button" to="." method="_on_Host_Button_pressed"] +[connection signal="pressed" from="Lobby Options/Host or Connect/Connect Button" to="." method="_on_Connect_Button_pressed"] +[connection signal="pressed" from="Lobby Options/Connected Options/Disconnect Button" to="." method="_on_Disconnect_Button_pressed"] +[connection signal="pressed" from="Lobby Options/Change Name Button" to="." method="_on_Change_Name_Button_pressed"] +[connection signal="pressed" from="Lobby Options/Exit Lobby" to="." method="_on_Exit_Lobby_pressed"] +[connection signal="confirmed" from="Change Name" to="." method="_on_Change_Name_confirmed"] +[connection signal="confirmed" from="Connect to Game" to="." method="_on_Connect_to_Game_confirmed"] diff --git a/godot_ship/scenes/Title Screen.tscn b/godot_ship/scenes/Title Screen.tscn index 8f04e9f..0b4f4dc 100644 --- a/godot_ship/scenes/Title Screen.tscn +++ b/godot_ship/scenes/Title Screen.tscn @@ -74,6 +74,7 @@ margin_right = 157.0 margin_bottom = -15.0 size_flags_stretch_ratio = 0.0 custom_fonts/font = SubResource( 1 ) +custom_colors/font_color = Color( 1, 1, 1, 1 ) custom_colors/font_outline_modulate = Color( 0, 0, 0, 1 ) custom_colors/font_color_shadow = Color( 0, 0, 0, 1 ) custom_constants/shadow_offset_x = 0 diff --git a/godot_ship/script/Main.gd b/godot_ship/script/Main.gd index e906b58..34f2dd8 100644 --- a/godot_ship/script/Main.gd +++ b/godot_ship/script/Main.gd @@ -3,6 +3,7 @@ extends Control # Scenes onready var Title_Screen = preload("res://scenes/Title Screen.tscn") onready var Game = preload("res://scenes/Game/Game.tscn" ) +onready var Lobby = preload("res://scenes/Lobby.tscn" ) onready var Options = preload("res://scenes/Options.tscn" ) onready var Credits = preload("res://scenes/Credits.tscn" ) onready var Debug_Menu = preload("res://scenes/Debug Menu.tscn" ) @@ -64,7 +65,7 @@ func _on_scene_start(scene): add_child (instance) return true "Multiplayer": - instance = Game.instance() + instance = Lobby.instance() add_child (instance) return true "Options": diff --git a/godot_ship/script/game/Gameplay/Game.gd b/godot_ship/script/game/Gameplay/Game.gd index 41ff096..5fb28f3 100644 --- a/godot_ship/script/game/Gameplay/Game.gd +++ b/godot_ship/script/game/Gameplay/Game.gd @@ -29,22 +29,15 @@ func _ready(): get_node("ConfirmationDialog").get_cancel().text = "No" get_node("ConfirmationDialog").get_ok().rect_min_size.x = 100 get_node("ConfirmationDialog").get_cancel().rect_min_size.x = 100 - if multiplayer: # TODO: Spawn a lobby where people can either connect to a peer or create a server pass - game_setup() # Function used to keep track of which players are ready +# TODO: Change this to keep track of ready states only func player_ready(): - var who = get_tree().get_rpc_sender_id() - if get_tree().is_network_server() and who in Net.peer_info and not who in players_ready: - print ("ASSERT SUCCESS") - players_ready.append(who) - - if players_ready.size() == Net.peer_info.size(): - rpc("game_start") + pass # Member functions: # game_start: starts the game @@ -54,45 +47,39 @@ sync func game_setup(): # TODO: Create a fake peer who we can automate, for single-player mode Net.start_host() network_id = Net.get_network_id() - # Create players for every player in Net.peer_info - for k in Net.peer_info.keys(): - # Create a new player - var player = Player.instance() - # Give the player a recognizable name, like "1", instead of "@@97" - player.name = str(k) - # The player controls themselves - player.set_network_master(k) - # Add the player to the list of players - players.append(player) - # Add the player to the scene tree - add_child(player) pass +# game_start: func game_start(): # Make sure we're the server pass +# _on_player_ready: Player Ready signal handler func _on_player_ready(): print ("_on_player_ready") - rpc_id(1, "player_ready") + Net.send(1, ["player_ready", Net.Mail.REPLY]) # victory_screen: display the victory screen func victory_screen(): # TODO: Create the victory screen, fill it with knowledge pass -# display_turn(): display which turn it is on the screen +# display_turn: display which turn it is on the screen func display_turn(): # TODO: Update the turn display, if there is one? pass +# _on_Forfeit_pressed: Handle forfeit button press func _on_Forfeit_pressed(): AudioBus.emit_signal("button_clicked") get_node("ConfirmationDialog").popup() +# end: end the Game func end(): queue_free() +# _on_Button_button_down: Handle win button press +# TODO: This isn't a thing any more func _on_Button_button_down(): AudioBus.emit_signal("button_clicked") var victory = Victory.instance() diff --git a/godot_ship/script/network/Lobby.gd b/godot_ship/script/network/Lobby.gd new file mode 100644 index 0000000..d73d8ca --- /dev/null +++ b/godot_ship/script/network/Lobby.gd @@ -0,0 +1,92 @@ +extends Control +# Ignore discarded return values +# warning-ignore:return_value_discarded +onready var text = 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 + +func _on_peers_updated(): + var connected_peers = "" + 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() + pass + +func set_IP_Address_text(show): + # Print the IP address and port + if show: + ip.text = "IP: %s\nPort: %s" % [Net.get_ip(), Net.DEFAULT_PORT] + else: + ip.text = "" + +func _ready(): + Net.connect("peers_updated", self, "_on_peers_updated") + _on_peers_updated() + pass + +func show_Connected_Options(show): + # Hide the host and connect buttons + get_node("Lobby Options/Host or Connect").visible = !show + # Show the host options + get_node("Lobby Options/Connected Options").visible = show + +# Buttons +# Host Button: Host a game +# Hides the connect button +func _on_Host_Button_pressed(): + # Show "Connected Options" + show_Connected_Options(true) + # Show the host IP address + set_IP_Address_text(true) + # Begin hosting + Net.start_host() + +# Disconnect +# 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() + +func _on_Change_Name_Button_pressed(): + # Show the Change Name dialogue + get_node("Change Name").popup_centered() + pass + +func _on_Connect_Button_pressed(): + # Show the Connect to Game dialogue + get_node("Connect to Game").popup_centered() + pass + +func _on_Connect_to_Game_confirmed(): + # Get the IP and port specified by the player + var ipbox = find_node("IP and Port Entry") + # Split it into IP and Port segments + var ip_port = ipbox.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 + Net.callv("connect_host", ip_port) + # 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() diff --git a/godot_ship/script/network/Net.gd b/godot_ship/script/network/Net.gd index 65b9be9..22409e8 100644 --- a/godot_ship/script/network/Net.gd +++ b/godot_ship/script/network/Net.gd @@ -1,33 +1,39 @@ extends Node +# Constants +# DEFAULT_PORT: The port GodotShip will listen on/connect to by default const DEFAULT_PORT = 35879 +# LOCALHOST: loopback address const LOCALHOST = "127.0.0.1" +# Enums, used for mail types +# Mail types: +# 1: REQUEST: Message is a request for information +# 0: REPLY: Message is a reply +enum {REPLY, REQUEST} + +# Signals +# incoming(mail): Sent when there's an incoming message signal incoming +# peers_updated(): Sent when the peer list is updated +signal peers_updated +# -# Let's pretend this is actually passed from send to receive -class Mail: - # Sender address - var from:int - var message - var type:int - enum {FROM, MESSAGE, TYPE} - enum {REPLY, REQUEST} - -# Store peer info in a dictionary, by player ID -var peer_info = {} -# Store this player's hostname -var local_info = {"hostname": ""} - -var connected = false -var hosting = false - -# FIFO queue of Mails +# Variables +# inbox: Array: Message history var inbox = [] +# connected: Boolean: True when in the Connected state +var connected = false +# hosting: Boolean: True when in the Hosting state +var hosting = false +# peer_info: Dictionary: Store peer info in a dictionary, by player ID +var peer_info = {} +# local_info: Dictionary: Store this player's info +var local_info = {"name": ""} # Network -- handles server and client setup, and facilitates communication between the two -# receive: Called when an incoming message is received -# item: The message received from the sender +# 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): # Get the sender's ID and force letter to be properly addressed mail[0] = get_tree().get_rpc_sender_id() @@ -36,7 +42,7 @@ sync func receive(mail): # Sent it off to anything that expects mail emit_signal("incoming", mail) -# send: Called when sending a message +# 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): @@ -49,12 +55,17 @@ func send(id, mail): func start_host(port = DEFAULT_PORT, max_players = 2): get_hostname() peer_info[1] = local_info + # Notify that peer list has updated + emit_signal("peers_updated") + # Create a new NetworkedMultiplayerENet (handles multiplayer communication through ENet) var peer = NetworkedMultiplayerENet.new() + # Create a server peer.create_server(port, max_players) + # Add the server to the scene tree get_tree().network_peer = peer + # Update state connected = true hosting = true - return # connect_host: Connect to a host func connect_host(ip = LOCALHOST, port = DEFAULT_PORT): @@ -65,6 +76,8 @@ func connect_host(ip = LOCALHOST, port = DEFAULT_PORT): # disconnect_host func disconnect_host(): + # Send intent to disconnect + rpc("unregister_peer", get_network_id()) # Set state to disconnected connected = false hosting = false @@ -75,19 +88,33 @@ func disconnect_host(): get_tree().network_peer = null # Clear peer info peer_info = {} + # Notify that peer list has updated + emit_signal("peers_updated") +# change_name: Change the local name, and re-register with all peers (including self) +func change_name(name): + # Change name locally + local_info["name"] = name + # Send updated info info to all peers + rpc("register_peer", local_info) + pass + +# 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(): - if local_info["hostname"] == "": - var hostname = [] - var _ret = OS.execute("hostname", [], true, hostname) - local_info["hostname"] = hostname[0].split("\n")[0] - return local_info["hostname"] + var hostname = [] + # Execute the `hostname` command + var _ret = OS.execute("hostname", [], true, hostname) + # If there's no name set, set it to the hostname + if local_info["name"] == "": + local_info["name"] = hostname[0].split("\n")[0] + return hostname[0].split("\n")[0] func get_network_id(): return get_tree().get_network_unique_id() func get_ip(): - print(IP.resolve_hostname(get_hostname(), IP.TYPE_IPV4)) + return IP.resolve_hostname(get_hostname(), IP.TYPE_IPV4) pass func _ready(): @@ -100,11 +127,13 @@ func _ready(): func _peer_connected(id): + # Send peer info to remote peer rpc_id(id, "register_peer", local_info) pass func _peer_disconnected(id): - peer_info.erase(id) + # Unregister the peer locally + unregister_peer(id) pass @@ -123,7 +152,11 @@ func _connection_fail(): # Ensure Net state is clear disconnect_host() -remote func register_peer(info): +sync func register_peer(info): # Save player information under the sender id's peer info peer_info[get_tree().get_rpc_sender_id()] = info - pass + emit_signal("peers_updated") + +sync func unregister_peer(id): + peer_info.erase(id) + emit_signal("peers_updated")