From fb500705ef3ba7088872dd592ec124c4fc2cc371 Mon Sep 17 00:00:00 2001 From: Sebastian Lohff Date: Sun, 13 Apr 2025 00:20:10 +0200 Subject: [PATCH] Working Multiplayer ...now with a GUI Theme! Players can leave a room as well. Actually usable on mobile! --- scenes/GUITheme.tres | 4 ++++ scenes/MultiplayerConnect.tscn | 30 +++++++++++++++++++++++------- scenes/main.gd | 2 +- scenes/main.tscn | 20 +++++++++++++++----- scenes/multiplayer_connect.gd | 30 ++++++++++++++++++++++++++---- signalsrv/signalsrv.py | 11 +++++++++++ 6 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 scenes/GUITheme.tres diff --git a/scenes/GUITheme.tres b/scenes/GUITheme.tres new file mode 100644 index 0000000..b723596 --- /dev/null +++ b/scenes/GUITheme.tres @@ -0,0 +1,4 @@ +[gd_resource type="Theme" format=3 uid="uid://xxoc27tvaiut"] + +[resource] +default_font_size = 30 diff --git a/scenes/MultiplayerConnect.tscn b/scenes/MultiplayerConnect.tscn index 308c4c2..6b8d360 100644 --- a/scenes/MultiplayerConnect.tscn +++ b/scenes/MultiplayerConnect.tscn @@ -1,5 +1,6 @@ -[gd_scene load_steps=2 format=3 uid="uid://dnxcrx04kl3xy"] +[gd_scene load_steps=3 format=3 uid="uid://dnxcrx04kl3xy"] +[ext_resource type="Theme" uid="uid://xxoc27tvaiut" path="res://scenes/GUITheme.tres" id="1_2wc0w"] [ext_resource type="Script" uid="uid://di8r70441xdms" path="res://scenes/multiplayer_connect.gd" id="1_uyd8l"] [node name="MultiplayerConnect" type="Control"] @@ -9,6 +10,7 @@ anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 +theme = ExtResource("1_2wc0w") script = ExtResource("1_uyd8l") [node name="ConnectView" type="Control" parent="."] @@ -35,6 +37,7 @@ layout_mode = 2 unique_name_in_owner = true custom_minimum_size = Vector2(100, 0) layout_mode = 2 +theme_override_font_sizes/font_size = 20 text = "430.200" [node name="Label" type="Label" parent="ConnectView/VBoxContainer/HBoxContainer"] @@ -42,6 +45,7 @@ layout_mode = 2 text = "MHz" [node name="CreateButton" type="Button" parent="ConnectView/VBoxContainer/HBoxContainer"] +custom_minimum_size = Vector2(0, 100) layout_mode = 2 size_flags_stretch_ratio = 2.41 text = "Create Frequency" @@ -58,14 +62,20 @@ size_flags_vertical = 3 [node name="MorseView" type="Control" parent="."] unique_name_in_owner = true visible = false -anchors_preset = 0 -offset_right = 40.0 -offset_bottom = 40.0 +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 [node name="VBoxContainer" type="VBoxContainer" parent="MorseView"] -layout_mode = 0 -offset_right = 40.0 -offset_bottom = 40.0 +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 [node name="HBoxContainer" type="HBoxContainer" parent="MorseView/VBoxContainer"] layout_mode = 2 @@ -81,6 +91,7 @@ layout_mode = 2 [node name="PlayerContainer" type="VBoxContainer" parent="MorseView/VBoxContainer"] unique_name_in_owner = true layout_mode = 2 +size_flags_vertical = 3 [node name="MorseButton" type="Button" parent="MorseView/VBoxContainer"] layout_mode = 2 @@ -88,8 +99,13 @@ size_flags_vertical = 3 size_flags_stretch_ratio = 2.0 text = "MORSE" +[node name="LeaveButton" type="Button" parent="MorseView/VBoxContainer"] +layout_mode = 2 +text = "Leave Frequency" + [connection signal="pressed" from="ConnectView/VBoxContainer/HBoxContainer/CreateButton" to="." method="_on_create_button_pressed"] [connection signal="pressed" from="ConnectView/VBoxContainer/RefreshButton" to="." method="_on_refresh_button_pressed"] [connection signal="item_clicked" from="ConnectView/VBoxContainer/FreqList" to="." method="_on_freq_list_join"] [connection signal="button_down" from="MorseView/VBoxContainer/MorseButton" to="." method="_on_morse_button_button_down"] [connection signal="button_up" from="MorseView/VBoxContainer/MorseButton" to="." method="_on_morse_button_button_up"] +[connection signal="pressed" from="MorseView/VBoxContainer/LeaveButton" to="." method="_on_leave_button_pressed"] diff --git a/scenes/main.gd b/scenes/main.gd index 881ac4b..4c386df 100644 --- a/scenes/main.gd +++ b/scenes/main.gd @@ -27,7 +27,7 @@ func _ready(): fill_buffer() if multiplayer_enabled: - $VBoxContainer/MultiplayerButton.visible = true + %MultiplayerButton.visible = true OS.open_midi_inputs() print(OS.get_connected_midi_inputs()) diff --git a/scenes/main.tscn b/scenes/main.tscn index e3f2099..6bec0ff 100644 --- a/scenes/main.tscn +++ b/scenes/main.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=5 format=3 uid="uid://ctak1goemnnc5"] +[gd_scene load_steps=6 format=3 uid="uid://ctak1goemnnc5"] [ext_resource type="Script" uid="uid://dmeokosn7gr27" path="res://scenes/main.gd" id="1_8bx00"] +[ext_resource type="Theme" uid="uid://xxoc27tvaiut" path="res://scenes/GUITheme.tres" id="1_jyhfs"] [ext_resource type="PackedScene" uid="uid://xqic6oa5d7oc" path="res://scenes/MorseBanner.tscn" id="2_v02md"] [ext_resource type="Script" uid="uid://bjt60u6r1hqf7" path="res://addons/SharePlugin/Share.gd" id="3_sugp2"] @@ -15,6 +16,7 @@ anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 +theme = ExtResource("1_jyhfs") script = ExtResource("1_8bx00") [node name="VBoxContainer" type="VBoxContainer" parent="."] @@ -57,15 +59,23 @@ layout_mode = 2 size_flags_vertical = 3 text = "Write Wav" -[node name="ResetButton" type="Button" parent="VBoxContainer"] +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"] layout_mode = 2 size_flags_vertical = 3 + +[node name="ResetButton" type="Button" parent="VBoxContainer/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 size_flags_stretch_ratio = 0.5 text = "Reset" -[node name="MultiplayerButton" type="Button" parent="VBoxContainer"] +[node name="MultiplayerButton" type="Button" parent="VBoxContainer/HBoxContainer"] +unique_name_in_owner = true visible = false layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 0.5 text = "Connect to Frequency" [node name="Player" type="AudioStreamPlayer" parent="."] @@ -78,5 +88,5 @@ script = ExtResource("3_sugp2") [connection signal="button_down" from="VBoxContainer/MorseButton" to="." method="_on_morse_button_down"] [connection signal="button_up" from="VBoxContainer/MorseButton" to="." method="_on_morse_button_up"] [connection signal="pressed" from="VBoxContainer/WavButton" to="." method="_on_wav_button_pressed"] -[connection signal="pressed" from="VBoxContainer/ResetButton" to="." method="_on_reset_button_pressed"] -[connection signal="pressed" from="VBoxContainer/MultiplayerButton" to="." method="_on_multiplayer_button_pressed"] +[connection signal="pressed" from="VBoxContainer/HBoxContainer/ResetButton" to="." method="_on_reset_button_pressed"] +[connection signal="pressed" from="VBoxContainer/HBoxContainer/MultiplayerButton" to="." method="_on_multiplayer_button_pressed"] diff --git a/scenes/multiplayer_connect.gd b/scenes/multiplayer_connect.gd index 3ad34ef..8e7a450 100644 --- a/scenes/multiplayer_connect.gd +++ b/scenes/multiplayer_connect.gd @@ -2,6 +2,8 @@ extends Control var server := "seba-geek.de" var port := "3784" +var ws_url := "wss://seba-geek.de/godot/cw-generator-ws/" +var IS_DEBUG = false var ws := WebSocketPeer.new() var available_freqs = [] @@ -30,9 +32,14 @@ func _ready() -> void: # FIXME: status / error messages # FIXME: randomize default join frquency # FIXME: automatic refresh - print("ws://%s:%s" % [server, port]) - ws.connect_to_url("ws://%s:%s" % [server, port]) - + if not IS_DEBUG: + print(ws_url) + ws.connect_to_url(ws_url) + else: + print("ws://%s:%s" % [server, port]) + ws.connect_to_url("ws://%s:%s" % [server, port]) + + func refresh_list() -> void: pass @@ -43,6 +50,8 @@ func _process(_delta: float) -> void: # print("moin ", state) while state == WebSocketPeer.STATE_OPEN and ws.get_available_packet_count(): _handle_packet() + if state != WebSocketPeer.STATE_OPEN: + print("Error: websocket in state", state) func _handle_packet() -> void: var data := ws.get_packet().get_string_from_utf8() @@ -101,7 +110,16 @@ func _handle_packet() -> void: print("Error: player not part of freq ", player) return remove_player(parsed["player"]) - + "leave": + %MorseView.hide() + mmb_self.set_morse_state(false) + for mmb: MultiMorseBanner in mmb_others.values(): + mmb.set_morse_state(false) + mmb_self = null + mmb_others.clear() + for child in %PlayerContainer.get_children(): + %PlayerContainer.remove_child(child) + %ConnectView.show() _: print("Unhandled message: ", parsed["type"]) @@ -172,3 +190,7 @@ func _on_morse_button_button_up() -> void: if not mmb_self: return set_morse_state(false) + + +func _on_leave_button_pressed() -> void: + send_data({"cmd": "leave"}) diff --git a/signalsrv/signalsrv.py b/signalsrv/signalsrv.py index cdcecab..ff22ddd 100644 --- a/signalsrv/signalsrv.py +++ b/signalsrv/signalsrv.py @@ -62,6 +62,8 @@ class Client: await self._create_room(data) case "join": await self._join_room(data) + case "leave": + await self._leave_room() case "list": freqs = [{"freq": freq, "players": len(players)} for freq, players in self.freqs.items()] @@ -131,6 +133,10 @@ class Client: await other._send(type="morse-state", state=data["state"], from_player=self.id) async def _leave_room(self): + if not self.curr_freq: + self._send_error("You are not on a frequency") + return + for other in self._others(self.curr_freq): await other._send(type="player-left", player=self.id) try: @@ -141,6 +147,11 @@ class Client: del self.freqs[self.curr_freq] self.curr_freq = None + try: + await self._send(type="leave") + except Exception: + pass + def _others(self, freq): return [c for c in self.freqs[freq] if c.id != self.id]