From 79a788a8eaae35cb97c9122abb1e35ae3eae461e Mon Sep 17 00:00:00 2001 From: KrisDavie Date: Thu, 13 Mar 2025 18:51:13 +0100 Subject: [PATCH 1/6] Add coop mode. Fully working, status etc. todo. --- src/CoopClient.gd | 63 ++++++++++++++++++++++ src/CoopServer.gd | 53 ++++++++++++++++++ src/Events.gd | 12 +++++ src/GUI/CoopClientConnect.gd | 32 +++++++++++ src/GUI/CoopClientConnect.tscn | 60 +++++++++++++++++++++ src/GUI/CoopServerSettings.gd | 21 ++++++++ src/GUI/CoopServerSettings.tscn | 84 +++++++++++++++++++++++++++++ src/GUI/DisableButton.gd | 8 +-- src/GUI/GUI.gd | 22 ++++++-- src/GUI/GUI.tscn | 96 ++++++++++++++++++++++++++++++++- src/GUI/Notes.gd | 8 +-- src/GUI/StatusButton.gd | 12 ++++- src/Main.gd | 36 +++++++++++++ src/Main.tscn | 14 ++++- src/Objects/Icon.gd | 5 ++ src/Objects/Marker.gd | 25 ++++++++- src/Util.gd | 47 +++++++++++++++- 17 files changed, 579 insertions(+), 19 deletions(-) create mode 100644 src/CoopClient.gd create mode 100644 src/CoopServer.gd create mode 100644 src/GUI/CoopClientConnect.gd create mode 100644 src/GUI/CoopClientConnect.tscn create mode 100644 src/GUI/CoopServerSettings.gd create mode 100644 src/GUI/CoopServerSettings.tscn diff --git a/src/CoopClient.gd b/src/CoopClient.gd new file mode 100644 index 0000000..ca17157 --- /dev/null +++ b/src/CoopClient.gd @@ -0,0 +1,63 @@ +extends Node + +# The URL we will connect to + +# Our WebSocketClient instance +var _client = WebSocketClient.new() +var connected_to = "" +onready var connect_status = $"/root/Tracker/GUILayer/GUI/CoopClientContainer/CoopClientConnect/Shadow/Container/BG/Control/StatusText" +const TODO_TEXTURE = preload("res://assets/icons/todo.png"); + + +func _ready(): + # Connect base signals to get notified of connection open, close, and errors. + _client.connect("connection_closed", self, "_closed") + _client.connect("connection_error", self, "_closed") + _client.connect("connection_established", self, "_connected") + _client.connect("data_received", self, "_on_data") + Events.connect("coop_send_update", self, "_send_update") + Events.connect("connect_to_coop_server", self, "_on_connect_to_server") + +func _on_connect_to_server(websocket_url) -> void: + # Initiate connection to the given URL. + var err = _client.connect_to_url(websocket_url, []) + if err != OK: + connect_status.text = "Unable to connect" + print("Unable to connect") + set_process(false) + connected_to = websocket_url + +func _closed(was_clean = false): + connect_status.text = "Connection closed" + print("Closed, clean: ", was_clean) + set_process(false) + +func _connected(_proto = ""): + connect_status.text = "Connected to " + connected_to + +func _send_update(data: Dictionary) -> void: + if _client.get_connected_host() == "": + return + _client.get_peer(1).put_packet(JSON.print(data).to_utf8()) + +func _on_data(): + var pkt = parse_json(_client.get_peer(1).get_packet().get_string_from_utf8()) + print(pkt) + if typeof(pkt) != TYPE_DICTIONARY: + return + if pkt['event'] == "update_marker": + Events.emit_signal("coop_update_marker", pkt) + elif pkt['event'] == "remove_marker": + Events.emit_signal("coop_remove_marker", pkt.uuid) + elif pkt['event'] == "toggle_todo": + var icon = get_node(pkt['node_path']) + if (icon.get_pressed_texture() != TODO_TEXTURE): + icon.set_pressed_texture(TODO_TEXTURE); + icon.set_pressed(pkt['is_pressed']); + elif pkt['event'] == "remove_location": + var location = get_node(pkt['node_path']) + location.hide() + Util.add_hidden(location) + +func _process(delta): + _client.poll() diff --git a/src/CoopServer.gd b/src/CoopServer.gd new file mode 100644 index 0000000..ecdb344 --- /dev/null +++ b/src/CoopServer.gd @@ -0,0 +1,53 @@ +extends Node + +var _server = WebSocketServer.new() +var _clients = {} +var _write_mode = WebSocketPeer.WRITE_MODE_BINARY +var _use_multiplayer = true +var last_connected_client = 0 + +onready var server_status = $"/root/Tracker/GUILayer/GUI/CoopServerContainer/CoopServerSettings/Shadow/Container/BG/Control/StatusText" + + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + _server.connect("client_connected", self, "_connected") + _server.connect("client_disconnected", self, "_disconnected") + _server.connect("client_close_request", self, "_close_request") + _server.connect("data_received", self, "_on_data") + Events.connect("start_coop_server", self, "_on_start_coop_server") + + +func _on_start_coop_server(port: int) -> void: + print("Starting Co-op server on port", port) + server_status.text = "Starting server..." + var ip_address = Util.get_external_ip_address() + var err = _server.listen(port) + if err != OK: + print("Unable to start server") + set_process(false) + server_status.text = "Server started on " + ip_address + ":" + str(port) + Events.emit_signal('connect_to_coop_server', "ws://127.0.0.1:" + str(port)) + + +func _connected(id, proto): + _clients[id] = true + print("Client %d connected with protocol: %s" % [id, proto]) + +func _close_request(id, code, reason): + _clients.erase(id) + print("Client %d disconnecting with code: %d, reason: %s" % [id, code, reason]) + +func _disconnected(id, was_clean = false): + _clients.erase(id) + print("Client %d disconnected, clean: %s" % [id, str(was_clean)]) + +func _on_data(id): + var pkt = _server.get_peer(id).get_packet() + # Broadcast the packet to all clients except the one that sent it. + for client_id in _clients.keys(): + if client_id != id: + _server.get_peer(client_id).put_packet(pkt) + +func _process(delta): + _server.poll() \ No newline at end of file diff --git a/src/Events.gd b/src/Events.gd index ecb3555..8a4bfe9 100644 --- a/src/Events.gd +++ b/src/Events.gd @@ -37,6 +37,18 @@ signal set_connected_device(device) # warning-ignore:unused_signal signal refresh_devices() # warning-ignore:unused_signal +signal start_coop_server(port) +# warning-ignore:unused_signal +signal connect_to_coop_server() +# warning-ignore:unused_signal +signal coop_send_update(data) +# warning-ignore:unused_signal +signal coop_update_marker(data) +# warning-ignore:unused_signal +signal coop_remove_marker(data) +# warning-ignore:unused_signal +signal coop_toggle_todo(data) +# warning-ignore:unused_signal signal open_menu() # warning-ignore:unused_signal signal undo() diff --git a/src/GUI/CoopClientConnect.gd b/src/GUI/CoopClientConnect.gd new file mode 100644 index 0000000..dd5691a --- /dev/null +++ b/src/GUI/CoopClientConnect.gd @@ -0,0 +1,32 @@ +extends Control +onready var server_info = $ServerInfo + +onready var connect_button = $Connect +onready var close_button = $Close + +onready var shadow = $"/root/Tracker/GUILayer/GUI/CoopClientContainer/CoopClientConnect/Shadow" +onready var connect_status = $"/root/Tracker/GUILayer/GUI/CoopClientContainer/CoopClientConnect/Shadow/Container/BG/Control/StatusText" + +var regex = RegEx.new() + + +func _ready() -> void: + Events.connect('set_discovered_devices', self, '_on_devices_discovered') + Events.connect('set_connected_device', self, '_on_set_connected_device') + close_button.connect('pressed', self, '_on_close_pressed') + connect_button.connect('pressed', self, '_on_start_pressed') + + +func _on_start_pressed() -> void: + var server_address = server_info.text + if server_address == "": + server_address = server_info.placeholder_text + regex.compile("^wss?://[a-zA-Z0-9.-]+:[0-9]+$") + if not regex.search(server_address): + connect_status.text = "Invalid server address" + return + connect_status.text = "Connecting to server..." + Events.emit_signal('connect_to_coop_server', server_address) + +func _on_close_pressed() -> void: + shadow.hide() \ No newline at end of file diff --git a/src/GUI/CoopClientConnect.tscn b/src/GUI/CoopClientConnect.tscn new file mode 100644 index 0000000..d53030c --- /dev/null +++ b/src/GUI/CoopClientConnect.tscn @@ -0,0 +1,60 @@ +[gd_scene format=2] + +[node name="Control" type="Control"] +process_priority = -1 +anchor_right = 0.324 +anchor_bottom = 0.283 +margin_bottom = 0.149994 + +[node name="Title" type="Label" parent="."] +margin_left = 128.0 +margin_top = 16.0 +margin_right = 269.0 +margin_bottom = 30.0 +text = "Connect to Co-op Server..." +align = 1 + +[node name="PortTitle" type="Label" parent="."] +margin_left = 19.0 +margin_top = 49.0 +margin_right = 148.0 +margin_bottom = 63.0 +rect_pivot_offset = Vector2( 38, 20 ) +text = "Server Address (ws(s)://:)" + +[node name="Close" type="Button" parent="."] +margin_left = 25.0 +margin_top = 202.0 +margin_right = 97.0 +margin_bottom = 225.0 +text = "Close " + +[node name="Connect" type="Button" parent="."] +margin_left = 25.0 +margin_top = 169.0 +margin_right = 97.0 +margin_bottom = 192.0 +text = "Connect" + +[node name="StatusText" type="Label" parent="."] +margin_left = 50.0 +margin_top = 143.0 +margin_right = 179.0 +margin_bottom = 157.0 +rect_pivot_offset = Vector2( 38, 20 ) +text = "Not Running" + +[node name="Status" type="Label" parent="."] +margin_left = 25.0 +margin_top = 118.0 +margin_right = 73.0 +margin_bottom = 132.0 +rect_pivot_offset = Vector2( 38, 20 ) +text = "Status: " + +[node name="ServerInfo" type="LineEdit" parent="."] +margin_left = 30.0 +margin_top = 75.0 +margin_right = 471.0 +margin_bottom = 99.0 +placeholder_text = "ws://127.0.0.1:23216" diff --git a/src/GUI/CoopServerSettings.gd b/src/GUI/CoopServerSettings.gd new file mode 100644 index 0000000..71ec7f0 --- /dev/null +++ b/src/GUI/CoopServerSettings.gd @@ -0,0 +1,21 @@ +extends Control +onready var selected_port = $PortNum + +onready var start_button = $Start +onready var close_button = $Close + +onready var shadow = $"/root/Tracker/GUILayer/GUI/CoopServerContainer/CoopServerSettings/Shadow" +onready var server_status = $"/root/Tracker/GUILayer/GUI/CoopServerContainer/CoopServerSettings/Shadow/Container/BG/Control/StatusText" + +func _ready() -> void: + Events.connect('set_discovered_devices', self, '_on_devices_discovered') + Events.connect('set_connected_device', self, '_on_set_connected_device') + close_button.connect('pressed', self, '_on_close_pressed') + start_button.connect('pressed', self, '_on_start_pressed') + + +func _on_start_pressed() -> void: + Events.emit_signal('start_coop_server', int(selected_port.get_line_edit().text)) + +func _on_close_pressed() -> void: + shadow.hide() \ No newline at end of file diff --git a/src/GUI/CoopServerSettings.tscn b/src/GUI/CoopServerSettings.tscn new file mode 100644 index 0000000..9ac1e3c --- /dev/null +++ b/src/GUI/CoopServerSettings.tscn @@ -0,0 +1,84 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://src/GUI/OptionsTheme.tres" type="Theme" id=2] + +[sub_resource type="DynamicFontData" id=1] +font_path = "res://assets/font/Ubuntu.ttf" + +[sub_resource type="DynamicFont" id=2] +size = 14 +use_mipmaps = true +use_filter = true +font_data = SubResource( 1 ) + +[node name="Control" type="Control"] +process_priority = -1 +anchor_right = 0.324 +anchor_bottom = 0.283 +margin_bottom = 0.149994 + +[node name="Title" type="Label" parent="."] +margin_left = 128.0 +margin_top = 16.0 +margin_right = 269.0 +margin_bottom = 30.0 +text = "Co-op Server Settings" +align = 1 + +[node name="PortTitle" type="Label" parent="."] +margin_left = 19.0 +margin_top = 49.0 +margin_right = 148.0 +margin_bottom = 63.0 +rect_pivot_offset = Vector2( 38, 20 ) +text = "Select Port Number:" + +[node name="PortNum" type="SpinBox" parent="."] +margin_left = 24.0 +margin_top = 74.0 +margin_right = 110.0 +margin_bottom = 107.0 +theme = ExtResource( 2 ) +min_value = 1.0 +max_value = 65563.0 +value = 23216.0 +rounded = true + +[node name="Label" type="Label" parent="."] +margin_left = 115.0 +margin_top = 69.0 +margin_right = 480.0 +margin_bottom = 126.0 +custom_fonts/font = SubResource( 2 ) +text = "NOTE: This port must be open, and forwarded to this machine via your router for people outside your network to be able to connect!" +autowrap = true + +[node name="Close" type="Button" parent="."] +margin_left = 25.0 +margin_top = 226.0 +margin_right = 179.0 +margin_bottom = 249.0 +text = "Close Without Starting" + +[node name="Start" type="Button" parent="."] +margin_left = 25.0 +margin_top = 193.0 +margin_right = 151.0 +margin_bottom = 216.0 +text = "Start Co-op Server" + +[node name="StatusText" type="Label" parent="."] +margin_left = 50.0 +margin_top = 167.0 +margin_right = 179.0 +margin_bottom = 181.0 +rect_pivot_offset = Vector2( 38, 20 ) +text = "Not Running" + +[node name="Status" type="Label" parent="."] +margin_left = 25.0 +margin_top = 142.0 +margin_right = 73.0 +margin_bottom = 156.0 +rect_pivot_offset = Vector2( 38, 20 ) +text = "Status: " diff --git a/src/GUI/DisableButton.gd b/src/GUI/DisableButton.gd index f6eff9a..d93ca6a 100644 --- a/src/GUI/DisableButton.gd +++ b/src/GUI/DisableButton.gd @@ -16,7 +16,7 @@ func _ready(): # pass func _gui_input(event: InputEvent) -> void: if event is InputEventMouseButton \ - and event.is_pressed(): - match(event.button_index): - BUTTON_RIGHT: - set_disabled(!is_disabled()) + and event.is_pressed(): + match(event.button_index): + BUTTON_RIGHT: + set_disabled(!is_disabled()) diff --git a/src/GUI/GUI.gd b/src/GUI/GUI.gd index 91ffac7..c90e9c6 100644 --- a/src/GUI/GUI.gd +++ b/src/GUI/GUI.gd @@ -13,10 +13,14 @@ enum { MENU_START_AUTOTRACKING = 9, MENU_AUTOTRACKING_SETTINGS = 10, # 11 separator - MENU_TOGGLE_DOORS_NOTES = 12, - MENU_NOTES_ONLY = 13, - MENU_MOVE_DOORS_NOTES = 14, - MENU_SUB_MENU = 15 + MENU_COOP_SERVER_SETTINGS = 12, + MENU_COOP_CONNECT = 13, + # 14 separator + MENU_TOGGLE_DOORS_NOTES = 15, + MENU_NOTES_ONLY = 16, + MENU_MOVE_DOORS_NOTES = 17, + MENU_SUB_MENU = 18 + } enum { @@ -37,6 +41,8 @@ onready var menu = $PopupMenu onready var autotrack_menu = $ATContainer/AutoTrackingSettings onready var autotrack_menu_modal = $ATContainer/AutoTrackingSettings/Shadow onready var autotrack_menu_container = $ATContainer/AutoTrackingSettings/Shadow/Container/BG +onready var coopserver_modal = $CoopServerContainer/CoopServerSettings/Shadow +onready var coopclient_modal = $CoopClientContainer/CoopClientConnect/Shadow onready var tooltip = $TooltipPopup onready var tooltip_container = $TooltipPopup/Margin/Container onready var tooltip_timer = $TooltipPopup/Timer @@ -70,6 +76,9 @@ func _ready() -> void: menu.add_item("(Re)connect Auto-Tracking", MENU_START_AUTOTRACKING) menu.add_item("Auto-Tracking Settings", MENU_AUTOTRACKING_SETTINGS) menu.add_separator() + menu.add_item("Start Co-op Server", MENU_COOP_SERVER_SETTINGS) + menu.add_item("Connect To Co-op Server", MENU_COOP_CONNECT) + menu.add_separator() menu.add_item("Toggle Doors Notes", MENU_TOGGLE_DOORS_NOTES) menu.add_item("Toggle Notes Only Mode", MENU_NOTES_ONLY) @@ -135,6 +144,11 @@ func menu_pressed(id: int) -> void: Events.emit_signal("start_autotracking") MENU_AUTOTRACKING_SETTINGS: autotrack_menu_modal.show() + MENU_COOP_SERVER_SETTINGS: + coopserver_modal.show() + MENU_COOP_CONNECT: + coopclient_modal.show() + MENU_TOGGLE_DOORS_NOTES: #close notes if $"/root".get_viewport().size.x > 1600: diff --git a/src/GUI/GUI.tscn b/src/GUI/GUI.tscn index f1dfec4..88f6ac9 100644 --- a/src/GUI/GUI.tscn +++ b/src/GUI/GUI.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=123 format=2] +[gd_scene load_steps=127 format=2] [ext_resource path="res://src/GUI/MarkerButton.tscn" type="PackedScene" id=1] [ext_resource path="res://src/GUI/GUI.gd" type="Script" id=2] @@ -49,6 +49,10 @@ [ext_resource path="res://assets/icons/items/glove.png" type="Texture" id=47] [ext_resource path="res://src/GUI/AutoTrackingSettings.tscn" type="PackedScene" id=48] [ext_resource path="res://assets/icons/undo.png" type="Texture" id=49] +[ext_resource path="res://src/GUI/CoopServerSettings.tscn" type="PackedScene" id=50] +[ext_resource path="res://src/GUI/CoopServerSettings.gd" type="Script" id=51] +[ext_resource path="res://src/GUI/CoopClientConnect.tscn" type="PackedScene" id=52] +[ext_resource path="res://src/GUI/CoopClientConnect.gd" type="Script" id=53] [ext_resource path="res://assets/icons/blankTextureSmaller.png" type="Texture" id=54] [ext_resource path="res://assets/icons/notes.png" type="Texture" id=69] [ext_resource path="res://src/GUI/Map.gd" type="Script" id=70] @@ -1573,6 +1577,96 @@ margin_right = 493.0 margin_bottom = 368.0 script = ExtResource( 105 ) +[node name="CoopClientContainer" type="VBoxContainer" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +mouse_filter = 2 + +[node name="CoopClientConnect" type="Control" parent="CoopClientContainer"] +margin_right = 1500.0 +margin_bottom = 950.0 +mouse_filter = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="Shadow" type="ColorRect" parent="CoopClientContainer/CoopClientConnect"] +visible = false +anchor_right = 1.0 +anchor_bottom = 1.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +color = Color( 0.0745098, 0.0745098, 0.0745098, 0.631373 ) +script = ExtResource( 73 ) + +[node name="Container" type="MarginContainer" parent="CoopClientContainer/CoopClientConnect/Shadow"] +anchor_right = 1.0 +anchor_bottom = 1.0 +mouse_filter = 2 +custom_constants/margin_right = 500 +custom_constants/margin_top = 275 +custom_constants/margin_left = 500 +custom_constants/margin_bottom = 390 + +[node name="BG" type="PanelContainer" parent="CoopClientContainer/CoopClientConnect/Shadow/Container"] +margin_left = 500.0 +margin_top = 275.0 +margin_right = 1000.0 +margin_bottom = 560.0 + +[node name="Control" parent="CoopClientContainer/CoopClientConnect/Shadow/Container/BG" instance=ExtResource( 52 )] +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 7.0 +margin_top = 7.0 +margin_right = 493.0 +margin_bottom = 278.0 +script = ExtResource( 53 ) + +[node name="CoopServerContainer" type="VBoxContainer" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +mouse_filter = 2 + +[node name="CoopServerSettings" type="Control" parent="CoopServerContainer"] +margin_right = 1500.0 +margin_bottom = 950.0 +mouse_filter = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="Shadow" type="ColorRect" parent="CoopServerContainer/CoopServerSettings"] +visible = false +anchor_right = 1.0 +anchor_bottom = 1.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +color = Color( 0.0745098, 0.0745098, 0.0745098, 0.631373 ) +script = ExtResource( 73 ) + +[node name="Container" type="MarginContainer" parent="CoopServerContainer/CoopServerSettings/Shadow"] +anchor_right = 1.0 +anchor_bottom = 1.0 +mouse_filter = 2 +custom_constants/margin_right = 500 +custom_constants/margin_top = 275 +custom_constants/margin_left = 500 +custom_constants/margin_bottom = 390 + +[node name="BG" type="PanelContainer" parent="CoopServerContainer/CoopServerSettings/Shadow/Container"] +margin_left = 500.0 +margin_top = 275.0 +margin_right = 1000.0 +margin_bottom = 560.0 + +[node name="Control" parent="CoopServerContainer/CoopServerSettings/Shadow/Container/BG" instance=ExtResource( 50 )] +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 7.0 +margin_top = 7.0 +margin_right = 493.0 +margin_bottom = 278.0 +script = ExtResource( 51 ) + [node name="PopupMenu" type="PopupMenu" parent="."] margin_right = 44.0 margin_bottom = 250.0 diff --git a/src/GUI/Notes.gd b/src/GUI/Notes.gd index ac2dcab..ff1eef5 100644 --- a/src/GUI/Notes.gd +++ b/src/GUI/Notes.gd @@ -2,7 +2,7 @@ extends ColorRect func _gui_input(event: InputEvent) -> void: if event is InputEventMouseButton \ - and event.button_index == BUTTON_LEFT \ - and event.is_pressed(): - Events.emit_signal("mode_changed", Util.MODE_OW) - hide() + and event.button_index == BUTTON_LEFT \ + and event.is_pressed(): + Events.emit_signal("mode_changed", Util.MODE_OW) + hide() diff --git a/src/GUI/StatusButton.gd b/src/GUI/StatusButton.gd index db90b33..e29623b 100644 --- a/src/GUI/StatusButton.gd +++ b/src/GUI/StatusButton.gd @@ -15,13 +15,23 @@ func _gui_input(event: InputEvent) -> void: if event is InputEventMouseButton \ and event.is_pressed(): match(event.button_index): - BUTTON_RIGHT: + BUTTON_RIGHT: set_pressed_texture(BLANK_TEXTURE); if get_parent().self_modulate == CHECKED_GREY: get_parent().self_modulate = Color.white else: get_parent().self_modulate = CHECKED_GREY + # Events.emit_signal("coop_send_update", { + # "event": "toggle_todo", + # "node_path": get_path(), + # "is_pressed": false + # }) BUTTON_MIDDLE: + Events.emit_signal("coop_send_update", { + "event": "toggle_todo", + "node_path": get_path(), + "is_pressed": !is_pressed() + }) if (get_pressed_texture() != TODO_TEXTURE): set_pressed_texture(TODO_TEXTURE); set_pressed(false); diff --git a/src/Main.gd b/src/Main.gd index 97f7735..be5df6c 100644 --- a/src/Main.gd +++ b/src/Main.gd @@ -9,6 +9,8 @@ onready var markers: Node2D = $Markers func _ready() -> void: OS.low_processor_usage_mode = true get_tree().set_auto_accept_quit(false) + # Randomize for unique "UUIDs" + randomize() $GUILayer/Quit.hide() $GUILayer/Quit/Confirmation.connect("confirmed", self, "_on_confirmed") $GUILayer/Quit/Confirmation.connect("popup_hide", self, "_on_cancelled") @@ -20,6 +22,8 @@ func _ready() -> void: Events.connect("save_file_clicked", self, "open_save_dialog") Events.connect("load_file_clicked", self, "open_load_dialog") Events.connect("move_doors_notes", self, "_move_doors_notes") + Events.connect("coop_update_marker", self, "_update_or_add_marker") + Events.connect("coop_remove_marker", self, "coop_remove_marker") Events.emit_signal("start_autotracking") set_window_size() @@ -100,6 +104,36 @@ func load_data(path: String) -> bool: save_file.close() return true +func _update_or_add_marker(data: Dictionary) -> void: + for i in markers.get_child_count(): + var marker = markers.get_child(i) + if marker.uuid == data.uuid: + marker.position = Vector2(data.x, data.y) + return + add_coop_marker(data) + +func add_coop_marker(marker_data: Dictionary) -> void: + var marker = marker_scene.instance() + marker.init() + marker.sprite_path = marker_data.sprite_path + if marker_data.connector != "": + marker.add_to_group(marker_data.connector) + marker.connector = marker_data.connector + marker.is_connector = true + marker.modulate = Color(marker_data.color) + marker.is_following = false + marker.uuid = marker_data.uuid + markers.add_child(marker) + marker.position = Vector2(marker_data.x, marker_data.y) + +func coop_remove_marker(uuid: String) -> void: + for i in markers.get_child_count(): + var marker = markers.get_child(i) + if marker.uuid == uuid: + marker.hide() + Util.add_hidden(marker) + return + func generate_marker(texture: Texture, color: Color, connector: String) -> void: if Util.mode != Util.MODE_OW: return @@ -109,6 +143,8 @@ func generate_marker(texture: Texture, color: Color, connector: String) -> void: var marker = marker_scene.instance() marker.modulate = color + marker.uuid = Util.generate_uuid() + if connector != "": marker.add_to_group(connector) marker.connector = connector diff --git a/src/Main.tscn b/src/Main.tscn index 494af68..574f069 100644 --- a/src/Main.tscn +++ b/src/Main.tscn @@ -1,14 +1,24 @@ -[gd_scene load_steps=8 format=2] +[gd_scene load_steps=10 format=2] [ext_resource path="res://src/Map/LightWorld.tscn" type="PackedScene" id=1] [ext_resource path="res://src/GUI/GUI.tscn" type="PackedScene" id=2] -[ext_resource path="res://src/Main.gd" type="Script" id=3] +[ext_resource path="res://src/CoopClient.gd" type="Script" id=3] [ext_resource path="res://src/Map/DarkWorld.tscn" type="PackedScene" id=4] [ext_resource path="res://src/Map/Markers.gd" type="Script" id=5] [ext_resource path="res://src/AutoTracking.gd" type="Script" id=6] [ext_resource path="res://src/GUI/NotesWindow.tscn" type="PackedScene" id=7] +[ext_resource path="res://src/CoopServer.gd" type="Script" id=8] +[ext_resource path="res://src/Main.gd" type="Script" id=9] [node name="Tracker" type="Node"] +script = ExtResource( 9 ) + +[node name="Coop" type="Node" parent="."] + +[node name="Server" type="Node" parent="Coop"] +script = ExtResource( 8 ) + +[node name="Client" type="Node" parent="Coop"] script = ExtResource( 3 ) [node name="AutoTracker" type="Node" parent="."] diff --git a/src/Objects/Icon.gd b/src/Objects/Icon.gd index 058ff70..75b8dfe 100644 --- a/src/Objects/Icon.gd +++ b/src/Objects/Icon.gd @@ -33,3 +33,8 @@ func _input_event(_viewport: Object, event: InputEvent, _shape_idx: int) -> void and event.is_pressed(): hide() Util.add_hidden(self) + if !is_item: + Events.emit_signal("coop_send_update", { + "event": "remove_location", + "node_path": get_path() + }) diff --git a/src/Objects/Marker.gd b/src/Objects/Marker.gd index e22d20e..192fb35 100644 --- a/src/Objects/Marker.gd +++ b/src/Objects/Marker.gd @@ -1,6 +1,7 @@ extends Area2D var connector: String = "" +var uuid: String = "" var is_following: bool = true var is_connector: bool = false var is_hovering: bool = false @@ -11,6 +12,25 @@ var sprite: Sprite onready var count_label = $Label onready var count = 0 +func _get_marker_data(marker: Node2D, delete: bool = false) -> Dictionary: + if delete: + return { + "event": "remove_marker", + "uuid": marker.uuid + } + + return { + "event": "update_marker", + "uuid": marker.uuid, + "x": marker.position.x, + "y": marker.position.y, + "connector": marker.connector, + "color": marker.modulate.to_html(false), + "is_connector": marker.is_connector, + "sprite_path": marker.sprite_path, + } + + func init() -> void: sprite = $Sprite @@ -60,13 +80,16 @@ func _input(event: InputEvent) -> void: func _input_event(_viewport: Object, event: InputEvent, _shape_idx: int) -> void: if event is InputEventMouseButton: if event.button_index == BUTTON_LEFT: - is_following = event.is_pressed() + is_following = event.is_pressed() if !is_following and global_position.y > 750: queue_free() + if !is_following: + Events.emit_signal("coop_send_update", _get_marker_data(self)) elif event.button_index == BUTTON_RIGHT \ and event.is_pressed(): hide() Util.add_hidden(self) + Events.emit_signal("coop_send_update", _get_marker_data(self, true)) elif event.button_index == BUTTON_WHEEL_UP and event.is_pressed(): set_count(count + 1) elif event.button_index == BUTTON_WHEEL_DOWN and event.is_pressed(): diff --git a/src/Util.gd b/src/Util.gd index de54731..68e2f78 100644 --- a/src/Util.gd +++ b/src/Util.gd @@ -14,6 +14,8 @@ var andy_mode: bool = false var drag_and_drop: bool = false var nodes_hidden: Array = [] var last_marker +var alph = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + func _ready() -> void: Events.connect("tracker_restarted", self, "_on_tracker_restarted") @@ -26,9 +28,8 @@ func _unhandled_input(event: InputEvent) -> void: match(event.button_index): BUTTON_XBUTTON1: unhide_node() - - + func add_hidden(node: Node) -> void: nodes_hidden.append(node) if len(nodes_hidden) > 10: @@ -50,3 +51,45 @@ func unhide_node() -> void: node.show() nodes_hidden.erase(node) Events.emit_signal("entrances_changed", 1) + +func generate_uuid() -> String: + """ This is a super simple UUID generator. It's not perfect, but it's good enough for this project.""" + var uuid = "" + for _i in range(0, 32): + uuid += alph[randi() % alph.length()] + return uuid + +func get_external_ip_address() -> String: + var http = HTTPClient.new() + var err = 0 + var headers = [ + "User-Agent: Pirulo/1.0 (Godot)", + "Accept: */*" + ] + err = http.connect_to_host("http://api.ipify.org") + assert(err == OK) + while http.get_status() == HTTPClient.STATUS_CONNECTING or http.get_status() == HTTPClient.STATUS_RESOLVING: + http.poll() + if not OS.has_feature("web"): + OS.delay_msec(500) + else: + yield(Engine.get_main_loop(), "idle_frame") + + assert(http.get_status() == HTTPClient.STATUS_CONNECTED) + + err = http.request(HTTPClient.METHOD_GET, "/", headers) + + while http.get_status() == HTTPClient.STATUS_REQUESTING: + http.poll() + if OS.has_feature("web"): + yield(Engine.get_main_loop(), "idle_frame") + else: + OS.delay_msec(500) + + assert(http.get_status() == HTTPClient.STATUS_BODY or http.get_status() == HTTPClient.STATUS_CONNECTED) + var ip_address = "" + if http.has_response(): + ip_address = http.read_response_body_chunk().get_string_from_utf8() + else: + ip_address = "127.0.0.1" + return ip_address From 884e21b914129c50fa49593f2d4a9e6dfb1b9597 Mon Sep 17 00:00:00 2001 From: KrisDavie Date: Sun, 16 Mar 2025 16:12:58 +0100 Subject: [PATCH 2/6] New behaviour: * Manually grey out an entance -> Greyed on on coop clients * Autotracking greys out an entrance -> TODO marked on coop clients * Manually mark TODO -> TODO marked on coop clients * Copy address button added when server starts * Add Coop server/client status * Fix overflowing autotracking label --- src/AutoTracking.gd | 15 +++- src/CoopClient.gd | 31 ++++++- src/CoopServer.gd | 11 +++ src/Events.gd | 4 +- src/GUI/CoopServerSettings.gd | 13 ++- src/GUI/CoopServerSettings.tscn | 8 ++ src/GUI/GUI.tscn | 140 ++++++++++++++++++++++---------- src/GUI/StatusButton.gd | 16 ++-- src/Objects/Marker.gd | 1 + src/Util.gd | 1 + 10 files changed, 176 insertions(+), 64 deletions(-) diff --git a/src/AutoTracking.gd b/src/AutoTracking.gd index 91d83b9..52d7e08 100644 --- a/src/AutoTracking.gd +++ b/src/AutoTracking.gd @@ -1,6 +1,5 @@ extends Node -const DISABLED_TEXTURE = preload("res://assets/icons/disabled.png"); const TODO_TEXTURE = preload("res://assets/icons/todo.png"); const BLANK_TEXTURE = preload("res://assets/icons/blankTexture.png"); const CHECKED_GREY = Color("282626") @@ -124,7 +123,7 @@ enum AUTOTRACKER_STATUS { var _at_status = AUTOTRACKER_STATUS.DISCONNECTED -onready var status_label = $"/root/Tracker/GUILayer/GUI/Container/Margin/HSplitContainer/Entrances/Dungeons/VBoxContainer/AutoTrackStatus" +onready var status_label = $"/root/Tracker/GUILayer/GUI/Container/Margin/HSplitContainer/Entrances/Dungeons/MarginContainer/VBoxContainer/HBoxContainer4/AutoTrackStatus" onready var notes_window = $"/root/Tracker/NotesWindow" func _ready() -> void: @@ -218,7 +217,10 @@ func _on_data(): var connect_data = {'Opcode': "Attach", 'Space': "SNES", 'Operands': [device]} _client.get_peer(1).put_packet(JSON.print(connect_data).to_utf8()) Events.emit_signal('set_connected_device', device_index) - status_label.text = "Connected to " + device + if (device.length() > 23): + status_label.text = "Connected to " + device.substring(0, 20) + "..." + else: + status_label.text = "Connected to " + device _at_status = AUTOTRACKER_STATUS.CONNECTED _timer.start() @@ -268,8 +270,13 @@ func process_location_data(): if !(loc == "ParadoxM" or loc == "ParadoxL"): underworld_node.get_child(0).set_pressed_texture(BLANK_TEXTURE) underworld_node.get_child(0).set_pressed(true) + Events.emit_signal("coop_send_update", { + "event": "toggle_todo", + "node_path": underworld_node.get_child(0).get_path(), + "is_pressed": true + }) else: - underworld_node.get_child(0).set_pressed_texture(DISABLED_TEXTURE if all_locs_checked else TODO_TEXTURE) + underworld_node.get_child(0).set_pressed_texture(TODO_TEXTURE) underworld_node.get_child(0).set_pressed(true) else: # after loading a save locations on the map get loaded as @loc@[RANDOM NUMBER] instead of just loc diff --git a/src/CoopClient.gd b/src/CoopClient.gd index ca17157..ab61504 100644 --- a/src/CoopClient.gd +++ b/src/CoopClient.gd @@ -6,8 +6,11 @@ extends Node var _client = WebSocketClient.new() var connected_to = "" onready var connect_status = $"/root/Tracker/GUILayer/GUI/CoopClientContainer/CoopClientConnect/Shadow/Container/BG/Control/StatusText" +onready var gui_status = $"/root/Tracker/GUILayer/GUI/Container/Margin/HSplitContainer/Entrances/Dungeons/MarginContainer/VBoxContainer/HBoxContainer2/CoopStatus" +onready var gui_status_container = $"/root/Tracker/GUILayer/GUI/Container/Margin/HSplitContainer/Entrances/Dungeons/MarginContainer/VBoxContainer/HBoxContainer2" +onready var gui_label_container = $"/root/Tracker/GUILayer/GUI/Container/Margin/HSplitContainer/Entrances/Dungeons/MarginContainer/VBoxContainer/HBoxContainer" const TODO_TEXTURE = preload("res://assets/icons/todo.png"); - +const CHECKED_GREY = Color("282626") func _ready(): # Connect base signals to get notified of connection open, close, and errors. @@ -29,11 +32,16 @@ func _on_connect_to_server(websocket_url) -> void: func _closed(was_clean = false): connect_status.text = "Connection closed" + gui_status.text = "Disconnected" print("Closed, clean: ", was_clean) set_process(false) func _connected(_proto = ""): connect_status.text = "Connected to " + connected_to + gui_status_container.show() + gui_label_container.show() + if (!Util.coop_server): + gui_status.text = "Connected" func _send_update(data: Dictionary) -> void: if _client.get_connected_host() == "": @@ -47,13 +55,30 @@ func _on_data(): return if pkt['event'] == "update_marker": Events.emit_signal("coop_update_marker", pkt) + elif pkt['event'] == "remove_marker": Events.emit_signal("coop_remove_marker", pkt.uuid) + elif pkt['event'] == "toggle_todo": var icon = get_node(pkt['node_path']) if (icon.get_pressed_texture() != TODO_TEXTURE): - icon.set_pressed_texture(TODO_TEXTURE); - icon.set_pressed(pkt['is_pressed']); + icon.set_pressed_texture(TODO_TEXTURE) + if (icon.get_parent().self_modulate != CHECKED_GREY) and !icon.is_pressed(): + icon.set_pressed(pkt['is_pressed']) + + elif pkt['event'] == "toggle_button": + var button = get_node(pkt['node_path']) + button.set_pressed(false) + if button.get_parent().self_modulate != CHECKED_GREY && pkt['checked']: + button.get_parent().self_modulate = CHECKED_GREY + elif button.get_parent().self_modulate == CHECKED_GREY && !pkt['checked']: + button.get_parent().self_modulate = Color.white + + elif pkt['event'] == "add_location": + var location = get_node(pkt['node_path']) + location.show() + Util.remove_hidden(location) + elif pkt['event'] == "remove_location": var location = get_node(pkt['node_path']) location.hide() diff --git a/src/CoopServer.gd b/src/CoopServer.gd index ecdb344..afd1056 100644 --- a/src/CoopServer.gd +++ b/src/CoopServer.gd @@ -7,6 +7,9 @@ var _use_multiplayer = true var last_connected_client = 0 onready var server_status = $"/root/Tracker/GUILayer/GUI/CoopServerContainer/CoopServerSettings/Shadow/Container/BG/Control/StatusText" +onready var gui_status = $"/root/Tracker/GUILayer/GUI/Container/Margin/HSplitContainer/Entrances/Dungeons/MarginContainer/VBoxContainer/HBoxContainer2/CoopStatus" +onready var gui_status_container = $"/root/Tracker/GUILayer/GUI/Container/Margin/HSplitContainer/Entrances/Dungeons/MarginContainer/VBoxContainer/HBoxContainer2" +onready var gui_label_container = $"/root/Tracker/GUILayer/GUI/Container/Margin/HSplitContainer/Entrances/Dungeons/MarginContainer/VBoxContainer/HBoxContainer" # Called when the node enters the scene tree for the first time. @@ -28,11 +31,19 @@ func _on_start_coop_server(port: int) -> void: set_process(false) server_status.text = "Server started on " + ip_address + ":" + str(port) Events.emit_signal('connect_to_coop_server', "ws://127.0.0.1:" + str(port)) + Events.emit_signal('coop_server_started', ip_address + ":" + str(port)) + Util.coop_server = true + gui_status_container.show() + gui_label_container.show() func _connected(id, proto): _clients[id] = true print("Client %d connected with protocol: %s" % [id, proto]) + if (len(_clients) == 1): + gui_status.text = "Server Running" + gui_status.text = "Server Running [" + str(len(_clients)-1) + " clients]" + func _close_request(id, code, reason): _clients.erase(id) diff --git a/src/Events.gd b/src/Events.gd index 8a4bfe9..b40040d 100644 --- a/src/Events.gd +++ b/src/Events.gd @@ -39,6 +39,8 @@ signal refresh_devices() # warning-ignore:unused_signal signal start_coop_server(port) # warning-ignore:unused_signal +signal coop_server_started(address) +# warning-ignore:unused_signal signal connect_to_coop_server() # warning-ignore:unused_signal signal coop_send_update(data) @@ -47,8 +49,6 @@ signal coop_update_marker(data) # warning-ignore:unused_signal signal coop_remove_marker(data) # warning-ignore:unused_signal -signal coop_toggle_todo(data) -# warning-ignore:unused_signal signal open_menu() # warning-ignore:unused_signal signal undo() diff --git a/src/GUI/CoopServerSettings.gd b/src/GUI/CoopServerSettings.gd index 71ec7f0..7a13326 100644 --- a/src/GUI/CoopServerSettings.gd +++ b/src/GUI/CoopServerSettings.gd @@ -1,18 +1,27 @@ extends Control onready var selected_port = $PortNum -onready var start_button = $Start +onready var start_button = $Start onready var close_button = $Close +onready var copy_button = $Copy onready var shadow = $"/root/Tracker/GUILayer/GUI/CoopServerContainer/CoopServerSettings/Shadow" -onready var server_status = $"/root/Tracker/GUILayer/GUI/CoopServerContainer/CoopServerSettings/Shadow/Container/BG/Control/StatusText" +var server_address = "" func _ready() -> void: Events.connect('set_discovered_devices', self, '_on_devices_discovered') Events.connect('set_connected_device', self, '_on_set_connected_device') + Events.connect('coop_server_started', self, '_on_server_started') close_button.connect('pressed', self, '_on_close_pressed') start_button.connect('pressed', self, '_on_start_pressed') + copy_button.connect('pressed', self, '_on_copy_pressed') +func _on_server_started(ip) -> void: + server_address = ip + copy_button.show() + +func _on_copy_pressed() -> void: + OS.set_clipboard(server_address) func _on_start_pressed() -> void: Events.emit_signal('start_coop_server', int(selected_port.get_line_edit().text)) diff --git a/src/GUI/CoopServerSettings.tscn b/src/GUI/CoopServerSettings.tscn index 9ac1e3c..ab02542 100644 --- a/src/GUI/CoopServerSettings.tscn +++ b/src/GUI/CoopServerSettings.tscn @@ -82,3 +82,11 @@ margin_right = 73.0 margin_bottom = 156.0 rect_pivot_offset = Vector2( 38, 20 ) text = "Status: " + +[node name="Copy" type="Button" parent="."] +visible = false +margin_left = 245.0 +margin_top = 193.0 +margin_right = 345.0 +margin_bottom = 216.0 +text = "Copy Address" diff --git a/src/GUI/GUI.tscn b/src/GUI/GUI.tscn index 88f6ac9..6f2e3b7 100644 --- a/src/GUI/GUI.tscn +++ b/src/GUI/GUI.tscn @@ -282,7 +282,7 @@ size_flags_vertical = 0 [node name="Notes" type="Control" parent="Container"] margin_right = 1500.0 -margin_bottom = 744.0 +margin_bottom = 746.0 mouse_filter = 2 size_flags_horizontal = 3 size_flags_vertical = 3 @@ -315,10 +315,10 @@ __meta__ = { margin_left = 400.0 margin_top = 120.0 margin_right = 1100.0 -margin_bottom = 624.0 +margin_bottom = 626.0 [node name="Margin" type="MarginContainer" parent="Container"] -margin_top = 748.0 +margin_top = 750.0 margin_right = 1482.0 margin_bottom = 950.0 size_flags_horizontal = 0 @@ -335,26 +335,26 @@ __meta__ = { margin_left = 2.0 margin_top = 2.0 margin_right = 1480.0 -margin_bottom = 200.0 +margin_bottom = 198.0 [node name="Entrances" type="VSplitContainer" parent="Container/Margin/HSplitContainer"] margin_right = 1478.0 -margin_bottom = 198.0 +margin_bottom = 196.0 [node name="Dungeons" type="HBoxContainer" parent="Container/Margin/HSplitContainer/Entrances"] margin_right = 1478.0 -margin_bottom = 46.0 +margin_bottom = 44.0 [node name="Rows" type="VBoxContainer" parent="Container/Margin/HSplitContainer/Entrances/Dungeons"] margin_right = 1294.0 -margin_bottom = 46.0 +margin_bottom = 44.0 size_flags_horizontal = 3 size_flags_vertical = 3 custom_constants/separation = 2 [node name="1" type="HBoxContainer" parent="Container/Margin/HSplitContainer/Entrances/Dungeons/Rows"] margin_right = 1294.0 -margin_bottom = 46.0 +margin_bottom = 44.0 size_flags_horizontal = 3 size_flags_vertical = 3 @@ -362,7 +362,7 @@ size_flags_vertical = 3 anchor_right = 0.0 anchor_bottom = 0.0 margin_right = 44.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 29 ) connector = "hc" line_color = Color( 0.678431, 0.380392, 0.235294, 1 ) @@ -372,7 +372,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 48.0 margin_right = 92.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 30 ) connector = "hc" line_color = Color( 0.678431, 0.380392, 0.235294, 1 ) @@ -382,7 +382,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 96.0 margin_right = 140.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 31 ) connector = "hc" line_color = Color( 0.678431, 0.380392, 0.235294, 1 ) @@ -392,7 +392,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 144.0 margin_right = 188.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 32 ) connector = "ep" line_color = Color( 0.627451, 0.25098, 0.905882, 1 ) @@ -402,7 +402,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 192.0 margin_right = 236.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 33 ) connector = "dp" @@ -411,7 +411,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 240.0 margin_right = 284.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 13 ) connector = "dp" @@ -420,7 +420,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 288.0 margin_right = 332.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 34 ) connector = "dp" @@ -429,7 +429,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 336.0 margin_right = 380.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 9 ) connector = "dp" @@ -438,7 +438,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 384.0 margin_right = 428.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 35 ) connector = "th" line_color = Color( 1, 0.556863, 0.839216, 1 ) @@ -448,7 +448,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 432.0 margin_right = 476.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 36 ) connector = "at" line_color = Color( 1, 0.647059, 0, 1 ) @@ -458,7 +458,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 480.0 margin_right = 524.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 37 ) connector = "pd" line_color = Color( 1, 1, 0, 1 ) @@ -468,7 +468,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 528.0 margin_right = 572.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 38 ) connector = "sp" line_color = Color( 0.105882, 0.937255, 1, 1 ) @@ -478,7 +478,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 576.0 margin_right = 620.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 6 ) connector = "sw" line_color = Color( 0.419608, 0.831373, 0.419608, 1 ) @@ -488,7 +488,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 624.0 margin_right = 668.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 5 ) connector = "sw" line_color = Color( 0.419608, 0.831373, 0.419608, 1 ) @@ -498,7 +498,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 672.0 margin_right = 716.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 7 ) connector = "sw" line_color = Color( 0.419608, 0.831373, 0.419608, 1 ) @@ -508,7 +508,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 720.0 margin_right = 764.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 8 ) connector = "sw" line_color = Color( 0.419608, 0.831373, 0.419608, 1 ) @@ -518,7 +518,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 768.0 margin_right = 812.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 39 ) connector = "tt" line_color = Color( 1, 0, 1, 1 ) @@ -528,7 +528,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 816.0 margin_right = 860.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 40 ) connector = "ip" line_color = Color( 0.392157, 0.65098, 0.929412, 1 ) @@ -538,7 +538,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 864.0 margin_right = 908.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 41 ) connector = "mm" line_color = Color( 0, 1, 0, 1 ) @@ -548,7 +548,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 912.0 margin_right = 956.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 10 ) connector = "tr" line_color = Color( 1, 0.894118, 0.768627, 1 ) @@ -558,7 +558,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 960.0 margin_right = 1004.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 42 ) connector = "tr" line_color = Color( 1, 0.894118, 0.768627, 1 ) @@ -568,7 +568,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 1008.0 margin_right = 1052.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 43 ) connector = "tr" line_color = Color( 1, 0.894118, 0.768627, 1 ) @@ -578,7 +578,7 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 1056.0 margin_right = 1100.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 11 ) connector = "tr" line_color = Color( 1, 0.894118, 0.768627, 1 ) @@ -588,42 +588,92 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 1104.0 margin_right = 1148.0 -margin_bottom = 46.0 +margin_bottom = 44.0 texture_normal = SubResource( 44 ) connector = "gt" line_color = Color( 0.501961, 0, 0, 1 ) -[node name="VBoxContainer" type="VBoxContainer" parent="Container/Margin/HSplitContainer/Entrances/Dungeons"] +[node name="MarginContainer" type="MarginContainer" parent="Container/Margin/HSplitContainer/Entrances/Dungeons"] margin_left = 1298.0 margin_right = 1478.0 -margin_bottom = 46.0 -size_flags_stretch_ratio = 0.0 +margin_bottom = 44.0 +rect_pivot_offset = Vector2( -73, -314 ) +custom_constants/margin_bottom = -4 + +[node name="VBoxContainer" type="VBoxContainer" parent="Container/Margin/HSplitContainer/Entrances/Dungeons/MarginContainer"] +margin_right = 180.0 +margin_bottom = 48.0 +grow_horizontal = 0 +grow_vertical = 0 +rect_pivot_offset = Vector2( 526, -36 ) alignment = 2 -[node name="AutoTrackLabel" type="Label" parent="Container/Margin/HSplitContainer/Entrances/Dungeons/VBoxContainer"] +[node name="HBoxContainer" type="HBoxContainer" parent="Container/Margin/HSplitContainer/Entrances/Dungeons/MarginContainer/VBoxContainer"] +visible = false margin_right = 180.0 -margin_bottom = 33.0 +margin_bottom = 9.0 +alignment = 2 + +[node name="CoopLabel" type="Label" parent="Container/Margin/HSplitContainer/Entrances/Dungeons/MarginContainer/VBoxContainer/HBoxContainer"] +margin_left = 72.0 +margin_right = 180.0 +margin_bottom = 9.0 size_flags_horizontal = 0 size_flags_vertical = 0 theme = SubResource( 2 ) custom_fonts/font = SubResource( 4 ) -text = " - -Autotracking Status:" +text = "Coop Status:" align = 2 -[node name="AutoTrackStatus" type="Label" parent="Container/Margin/HSplitContainer/Entrances/Dungeons/VBoxContainer"] -margin_top = 37.0 +[node name="HBoxContainer2" type="HBoxContainer" parent="Container/Margin/HSplitContainer/Entrances/Dungeons/MarginContainer/VBoxContainer"] +visible = false +margin_top = 13.0 +margin_right = 180.0 +margin_bottom = 22.0 +alignment = 2 + +[node name="CoopStatus" type="Label" parent="Container/Margin/HSplitContainer/Entrances/Dungeons/MarginContainer/VBoxContainer/HBoxContainer2"] +margin_left = 63.0 margin_right = 180.0 -margin_bottom = 46.0 +margin_bottom = 9.0 custom_fonts/font = SubResource( 4 ) text = " Disconnected" align = 2 +[node name="HBoxContainer3" type="HBoxContainer" parent="Container/Margin/HSplitContainer/Entrances/Dungeons/MarginContainer/VBoxContainer"] +margin_top = 26.0 +margin_right = 180.0 +margin_bottom = 35.0 +alignment = 2 + +[node name="AutoTrackLabel" type="Label" parent="Container/Margin/HSplitContainer/Entrances/Dungeons/MarginContainer/VBoxContainer/HBoxContainer3"] +margin_right = 180.0 +margin_bottom = 9.0 +size_flags_horizontal = 0 +size_flags_vertical = 0 +theme = SubResource( 2 ) +custom_fonts/font = SubResource( 4 ) +text = "Autotracking Status:" +align = 2 + +[node name="HBoxContainer4" type="HBoxContainer" parent="Container/Margin/HSplitContainer/Entrances/Dungeons/MarginContainer/VBoxContainer"] +margin_top = 39.0 +margin_right = 180.0 +margin_bottom = 48.0 +alignment = 2 + +[node name="AutoTrackStatus" type="Label" parent="Container/Margin/HSplitContainer/Entrances/Dungeons/MarginContainer/VBoxContainer/HBoxContainer4"] +margin_left = 72.0 +margin_right = 180.0 +margin_bottom = 9.0 +custom_fonts/font = SubResource( 4 ) +text = "Disconnected" +align = 2 + [node name="Entrances" type="HBoxContainer" parent="Container/Margin/HSplitContainer/Entrances"] -margin_top = 58.0 +margin_top = 56.0 margin_right = 1478.0 -margin_bottom = 198.0 +margin_bottom = 196.0 [node name="Connectors" type="VBoxContainer" parent="Container/Margin/HSplitContainer/Entrances/Entrances"] margin_right = 332.0 diff --git a/src/GUI/StatusButton.gd b/src/GUI/StatusButton.gd index e29623b..2ce7303 100644 --- a/src/GUI/StatusButton.gd +++ b/src/GUI/StatusButton.gd @@ -1,6 +1,5 @@ extends TextureButton -const DISABLED_TEXTURE = preload("res://assets/icons/disabled.png"); const TODO_TEXTURE = preload("res://assets/icons/todo.png"); const BLANK_TEXTURE = preload("res://assets/icons/blankTexture.png"); @@ -16,16 +15,17 @@ func _gui_input(event: InputEvent) -> void: and event.is_pressed(): match(event.button_index): BUTTON_RIGHT: - set_pressed_texture(BLANK_TEXTURE); + set_pressed_texture(BLANK_TEXTURE); if get_parent().self_modulate == CHECKED_GREY: get_parent().self_modulate = Color.white else: - get_parent().self_modulate = CHECKED_GREY - # Events.emit_signal("coop_send_update", { - # "event": "toggle_todo", - # "node_path": get_path(), - # "is_pressed": false - # }) + get_parent().self_modulate = CHECKED_GREY + + Events.emit_signal("coop_send_update", { + "event": "toggle_button", + "node_path": get_path(), + "checked": get_parent().self_modulate == CHECKED_GREY + }) BUTTON_MIDDLE: Events.emit_signal("coop_send_update", { "event": "toggle_todo", diff --git a/src/Objects/Marker.gd b/src/Objects/Marker.gd index 192fb35..f6e58fd 100644 --- a/src/Objects/Marker.gd +++ b/src/Objects/Marker.gd @@ -74,6 +74,7 @@ func _input(event: InputEvent) -> void: and event.button_index == BUTTON_LEFT \ and !event.is_pressed(): is_following = false + Events.emit_signal("coop_send_update", _get_marker_data(self)) if global_position.y > 750: queue_free() diff --git a/src/Util.gd b/src/Util.gd index 68e2f78..969e4a5 100644 --- a/src/Util.gd +++ b/src/Util.gd @@ -15,6 +15,7 @@ var drag_and_drop: bool = false var nodes_hidden: Array = [] var last_marker var alph = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" +var coop_server = false func _ready() -> void: From 1dc7dd0cf37a02ed6a0e0df39b7126d7983e2bc6 Mon Sep 17 00:00:00 2001 From: KrisDavie Date: Sun, 16 Mar 2025 16:17:23 +0100 Subject: [PATCH 3/6] Mark off items on coop partners when done manually --- src/Objects/Icon.gd | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Objects/Icon.gd b/src/Objects/Icon.gd index 75b8dfe..f7ce9b1 100644 --- a/src/Objects/Icon.gd +++ b/src/Objects/Icon.gd @@ -33,8 +33,7 @@ func _input_event(_viewport: Object, event: InputEvent, _shape_idx: int) -> void and event.is_pressed(): hide() Util.add_hidden(self) - if !is_item: - Events.emit_signal("coop_send_update", { - "event": "remove_location", - "node_path": get_path() - }) + Events.emit_signal("coop_send_update", { + "event": "remove_location", + "node_path": get_path() + }) From 21390e8ca17e2c4e6bf0b4fa8528072f6e5a32f6 Mon Sep 17 00:00:00 2001 From: KrisDavie Date: Sun, 16 Mar 2025 16:26:47 +0100 Subject: [PATCH 4/6] Remove logging and fix reconnecting --- src/CoopClient.gd | 8 ++------ src/CoopServer.gd | 20 +++++++------------- src/GUI/AutoTrackingSettings.gd | 1 - 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/CoopClient.gd b/src/CoopClient.gd index ab61504..29ca7e7 100644 --- a/src/CoopClient.gd +++ b/src/CoopClient.gd @@ -26,15 +26,12 @@ func _on_connect_to_server(websocket_url) -> void: var err = _client.connect_to_url(websocket_url, []) if err != OK: connect_status.text = "Unable to connect" - print("Unable to connect") - set_process(false) connected_to = websocket_url -func _closed(was_clean = false): +func _closed(_was_clean = false): connect_status.text = "Connection closed" gui_status.text = "Disconnected" - print("Closed, clean: ", was_clean) - set_process(false) + _client.close() func _connected(_proto = ""): connect_status.text = "Connected to " + connected_to @@ -50,7 +47,6 @@ func _send_update(data: Dictionary) -> void: func _on_data(): var pkt = parse_json(_client.get_peer(1).get_packet().get_string_from_utf8()) - print(pkt) if typeof(pkt) != TYPE_DICTIONARY: return if pkt['event'] == "update_marker": diff --git a/src/CoopServer.gd b/src/CoopServer.gd index afd1056..3f224e8 100644 --- a/src/CoopServer.gd +++ b/src/CoopServer.gd @@ -22,36 +22,30 @@ func _ready() -> void: func _on_start_coop_server(port: int) -> void: - print("Starting Co-op server on port", port) server_status.text = "Starting server..." var ip_address = Util.get_external_ip_address() var err = _server.listen(port) if err != OK: - print("Unable to start server") - set_process(false) + return server_status.text = "Server started on " + ip_address + ":" + str(port) Events.emit_signal('connect_to_coop_server', "ws://127.0.0.1:" + str(port)) Events.emit_signal('coop_server_started', ip_address + ":" + str(port)) + gui_status.text = "Server Running" Util.coop_server = true gui_status_container.show() gui_label_container.show() -func _connected(id, proto): +func _connected(id, _proto): _clients[id] = true - print("Client %d connected with protocol: %s" % [id, proto]) - if (len(_clients) == 1): - gui_status.text = "Server Running" - gui_status.text = "Server Running [" + str(len(_clients)-1) + " clients]" + if (len(_clients) > 1): + gui_status.text = "Server Running [" + str(len(_clients)-1) + " clients]" - -func _close_request(id, code, reason): +func _close_request(id, _code, _reason): _clients.erase(id) - print("Client %d disconnecting with code: %d, reason: %s" % [id, code, reason]) -func _disconnected(id, was_clean = false): +func _disconnected(id, _was_clean = false): _clients.erase(id) - print("Client %d disconnected, clean: %s" % [id, str(was_clean)]) func _on_data(id): var pkt = _server.get_peer(id).get_packet() diff --git a/src/GUI/AutoTrackingSettings.gd b/src/GUI/AutoTrackingSettings.gd index e321924..98f1508 100644 --- a/src/GUI/AutoTrackingSettings.gd +++ b/src/GUI/AutoTrackingSettings.gd @@ -47,7 +47,6 @@ func _on_devices_discovered(_devices) -> void: selected_device.add_item(_devices[i], i) func _on_refresh_devices_pressed() -> void: - print("Refreshing devices") Events.emit_signal('refresh_devices') func _on_set_connected_device(_device) -> void: From c9408288d84ffe95636405b014f580d0d9566503 Mon Sep 17 00:00:00 2001 From: B-D-I1701 Date: Tue, 18 Mar 2025 12:48:38 +0800 Subject: [PATCH 5/6] Stop crashes when connecting to autotracking When connecting to auto tracking if the device name is longer than 20 characters e.g. "emunwa://" or "luabridge://" the program will crash with "Invalid call. Nonexistent function 'substring' in base 'String'.". Changing this to the correct .substr() allows for autotracking to be used. (im assuming you tested in retro arch which is "ra://") --- src/AutoTracking.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AutoTracking.gd b/src/AutoTracking.gd index 52d7e08..ccf5a1f 100644 --- a/src/AutoTracking.gd +++ b/src/AutoTracking.gd @@ -218,7 +218,7 @@ func _on_data(): _client.get_peer(1).put_packet(JSON.print(connect_data).to_utf8()) Events.emit_signal('set_connected_device', device_index) if (device.length() > 23): - status_label.text = "Connected to " + device.substring(0, 20) + "..." + status_label.text = "Connected to " + device.substr(0, 20) + "..." else: status_label.text = "Connected to " + device From 343bbed0430255fbe2d61fc10eba77b84fddfc62 Mon Sep 17 00:00:00 2001 From: KrisDavie Date: Wed, 19 Mar 2025 23:24:13 +0100 Subject: [PATCH 6/6] * Enable UPnP support when starting a server * Change start to stop button when server starts * Sync numbers on icons on the map --- src/CoopClient.gd | 1 - src/CoopServer.gd | 14 +++- src/Events.gd | 4 + src/GUI/CoopServerSettings.gd | 109 +++++++++++++++++++-------- src/GUI/CoopServerSettings.tscn | 18 ++++- src/GUI/CoopServerSettingsTheme.tres | 13 ++++ src/GUI/GUI.tscn | 4 +- src/Main.gd | 2 + src/Objects/Marker.gd | 3 + 9 files changed, 131 insertions(+), 37 deletions(-) create mode 100644 src/GUI/CoopServerSettingsTheme.tres diff --git a/src/CoopClient.gd b/src/CoopClient.gd index 29ca7e7..3983508 100644 --- a/src/CoopClient.gd +++ b/src/CoopClient.gd @@ -31,7 +31,6 @@ func _on_connect_to_server(websocket_url) -> void: func _closed(_was_clean = false): connect_status.text = "Connection closed" gui_status.text = "Disconnected" - _client.close() func _connected(_proto = ""): connect_status.text = "Connected to " + connected_to diff --git a/src/CoopServer.gd b/src/CoopServer.gd index 3f224e8..16cb00f 100644 --- a/src/CoopServer.gd +++ b/src/CoopServer.gd @@ -4,7 +4,6 @@ var _server = WebSocketServer.new() var _clients = {} var _write_mode = WebSocketPeer.WRITE_MODE_BINARY var _use_multiplayer = true -var last_connected_client = 0 onready var server_status = $"/root/Tracker/GUILayer/GUI/CoopServerContainer/CoopServerSettings/Shadow/Container/BG/Control/StatusText" onready var gui_status = $"/root/Tracker/GUILayer/GUI/Container/Margin/HSplitContainer/Entrances/Dungeons/MarginContainer/VBoxContainer/HBoxContainer2/CoopStatus" @@ -19,6 +18,7 @@ func _ready() -> void: _server.connect("client_close_request", self, "_close_request") _server.connect("data_received", self, "_on_data") Events.connect("start_coop_server", self, "_on_start_coop_server") + Events.connect("stop_coop_server", self, "_on_stop_coop_server") func _on_start_coop_server(port: int) -> void: @@ -35,6 +35,16 @@ func _on_start_coop_server(port: int) -> void: gui_status_container.show() gui_label_container.show() +func _on_stop_coop_server() -> void: + server_status.text = "Stopping server..." + _server.stop() + gui_status_container.hide() + gui_label_container.hide() + Events.emit_signal('coop_server_stopped') + Util.coop_server = false + server_status.text = "Server Stopped" + _clients.clear() + func _connected(id, _proto): _clients[id] = true @@ -55,4 +65,4 @@ func _on_data(id): _server.get_peer(client_id).put_packet(pkt) func _process(delta): - _server.poll() \ No newline at end of file + _server.poll() diff --git a/src/Events.gd b/src/Events.gd index b40040d..d57d405 100644 --- a/src/Events.gd +++ b/src/Events.gd @@ -39,8 +39,12 @@ signal refresh_devices() # warning-ignore:unused_signal signal start_coop_server(port) # warning-ignore:unused_signal +signal stop_coop_server() +# warning-ignore:unused_signal signal coop_server_started(address) # warning-ignore:unused_signal +signal coop_server_stopped() +# warning-ignore:unused_signal signal connect_to_coop_server() # warning-ignore:unused_signal signal coop_send_update(data) diff --git a/src/GUI/CoopServerSettings.gd b/src/GUI/CoopServerSettings.gd index 7a13326..a00d0ee 100644 --- a/src/GUI/CoopServerSettings.gd +++ b/src/GUI/CoopServerSettings.gd @@ -1,30 +1,79 @@ -extends Control -onready var selected_port = $PortNum - -onready var start_button = $Start -onready var close_button = $Close -onready var copy_button = $Copy - -onready var shadow = $"/root/Tracker/GUILayer/GUI/CoopServerContainer/CoopServerSettings/Shadow" -var server_address = "" - -func _ready() -> void: - Events.connect('set_discovered_devices', self, '_on_devices_discovered') - Events.connect('set_connected_device', self, '_on_set_connected_device') - Events.connect('coop_server_started', self, '_on_server_started') - close_button.connect('pressed', self, '_on_close_pressed') - start_button.connect('pressed', self, '_on_start_pressed') - copy_button.connect('pressed', self, '_on_copy_pressed') - -func _on_server_started(ip) -> void: - server_address = ip - copy_button.show() - -func _on_copy_pressed() -> void: - OS.set_clipboard(server_address) - -func _on_start_pressed() -> void: - Events.emit_signal('start_coop_server', int(selected_port.get_line_edit().text)) - -func _on_close_pressed() -> void: - shadow.hide() \ No newline at end of file +extends Control +onready var selected_port = $PortNum + +onready var start_button = $Start +onready var close_button = $Close +onready var copy_button = $Copy + +var upnp = null +var upnp_port = null +var server_status = null +var hint_text = "" + +onready var shadow = $"/root/Tracker/GUILayer/GUI/CoopServerContainer/CoopServerSettings/Shadow" + +var server_address = "" + +func _ready() -> void: + Events.connect('set_discovered_devices', self, '_on_devices_discovered') + Events.connect('set_connected_device', self, '_on_set_connected_device') + Events.connect('coop_server_started', self, '_on_server_started') + Events.connect('coop_server_stopped', self, '_on_server_stopped') + close_button.connect('pressed', self, '_on_close_pressed') + start_button.connect('pressed', self, '_on_start_pressed') + copy_button.connect('pressed', self, '_on_copy_pressed') + +func _on_server_started(ip) -> void: + server_address = "ws://" + ip + server_status = "Running" + start_button.text = "Stop Co-op Server" + hint_text = start_button.hint_tooltip + start_button.hint_tooltip = "" + copy_button.show() + +func _on_server_stopped() -> void: + server_status = "Stopped" + start_button.text = "Start Co-op Server" + start_button.hint_tooltip = hint_text + copy_button.hide() + +func _on_copy_pressed() -> void: + OS.set_clipboard(server_address) + +func _on_start_pressed() -> void: + if server_status == "Running": + Events.emit_signal('stop_coop_server') + return + else: + _upnp_setup(int(selected_port.get_line_edit().text)) + + +func _on_close_pressed() -> void: + shadow.hide() + +func _on_upnp_completed(_err): + Events.emit_signal('start_coop_server', int(selected_port.get_line_edit().text)) + +func _upnp_setup(server_port): + # UPNP queries take some time. + upnp = UPNP.new() + var err = upnp.discover() + + if err != OK: + push_error(str(err)) + _on_upnp_completed(err) + return + + if upnp.get_gateway() and upnp.get_gateway().is_valid_gateway(): + upnp.add_port_mapping(server_port, server_port, ProjectSettings.get_setting("application/config/name"), "UDP") + upnp.add_port_mapping(server_port, server_port, ProjectSettings.get_setting("application/config/name"), "TCP") + upnp_port = server_port + _on_upnp_completed(OK) + else: + _on_upnp_completed(ERR_CANT_CONNECT) + + +func _exit_tree(): + if (upnp != null and upnp_port != null): + upnp.delete_port_mapping(upnp_port, "UDP") + upnp.delete_port_mapping(upnp_port, "TCP") diff --git a/src/GUI/CoopServerSettings.tscn b/src/GUI/CoopServerSettings.tscn index ab02542..40a90b4 100644 --- a/src/GUI/CoopServerSettings.tscn +++ b/src/GUI/CoopServerSettings.tscn @@ -1,12 +1,13 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=5 format=2] +[ext_resource path="res://src/GUI/CoopServerSettingsTheme.tres" type="Theme" id=1] [ext_resource path="res://src/GUI/OptionsTheme.tres" type="Theme" id=2] [sub_resource type="DynamicFontData" id=1] font_path = "res://assets/font/Ubuntu.ttf" [sub_resource type="DynamicFont" id=2] -size = 14 +size = 12 use_mipmaps = true use_filter = true font_data = SubResource( 1 ) @@ -50,7 +51,7 @@ margin_top = 69.0 margin_right = 480.0 margin_bottom = 126.0 custom_fonts/font = SubResource( 2 ) -text = "NOTE: This port must be open, and forwarded to this machine via your router for people outside your network to be able to connect!" +text = "NOTE: This port must be open, and forwarded to this machine via your router for people outside your network to be able to connect! Entrando will attempt to open the port via UPnP automatically." autowrap = true [node name="Close" type="Button" parent="."] @@ -65,6 +66,17 @@ margin_left = 25.0 margin_top = 193.0 margin_right = 151.0 margin_bottom = 216.0 +rect_min_size = Vector2( 126, 0 ) +hint_tooltip = "Entrando will attempt to open this port via UPnP, then it will +start a co-op server, it will hang while it works! Entrando will +look for a UPnP device on your network and attempt to open +the selected port automatically. This is not guaranteed to work +as every network differs. If this does not work and people still +cannot connect to you,you MUST open the port yourself to act +as the server. Information on how to do this can usually be +found on your ISP or router manufacturer's website. Entrando +devs can not and will not help with this." +theme = ExtResource( 1 ) text = "Start Co-op Server" [node name="StatusText" type="Label" parent="."] diff --git a/src/GUI/CoopServerSettingsTheme.tres b/src/GUI/CoopServerSettingsTheme.tres new file mode 100644 index 0000000..2d1a89a --- /dev/null +++ b/src/GUI/CoopServerSettingsTheme.tres @@ -0,0 +1,13 @@ +[gd_resource type="Theme" load_steps=3 format=2] + +[ext_resource path="res://assets/font/PressStart2P.ttf" type="DynamicFontData" id=1] + +[sub_resource type="DynamicFont" id=1] +size = 14 +outline_color = Color( 0, 0, 0, 1 ) +font_data = ExtResource( 1 ) + +[resource] +TooltipLabel/colors/font_color = Color( 0, 0, 0, 1 ) +TooltipLabel/colors/font_color_shadow = Color( 0, 0, 0, 0 ) +TooltipLabel/fonts/font = SubResource( 1 ) diff --git a/src/GUI/GUI.tscn b/src/GUI/GUI.tscn index 6f2e3b7..2f7a42d 100644 --- a/src/GUI/GUI.tscn +++ b/src/GUI/GUI.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=127 format=2] +[gd_scene load_steps=128 format=2] [ext_resource path="res://src/GUI/MarkerButton.tscn" type="PackedScene" id=1] [ext_resource path="res://src/GUI/GUI.gd" type="Script" id=2] @@ -54,6 +54,7 @@ [ext_resource path="res://src/GUI/CoopClientConnect.tscn" type="PackedScene" id=52] [ext_resource path="res://src/GUI/CoopClientConnect.gd" type="Script" id=53] [ext_resource path="res://assets/icons/blankTextureSmaller.png" type="Texture" id=54] +[ext_resource path="res://src/GUI/CoopServerSettingsTheme.tres" type="Theme" id=55] [ext_resource path="res://assets/icons/notes.png" type="Texture" id=69] [ext_resource path="res://src/GUI/Map.gd" type="Script" id=70] [ext_resource path="res://assets/font/PressStart2P-12.tres" type="DynamicFont" id=71] @@ -1576,6 +1577,7 @@ margin_top = 96.0 margin_right = 44.0 margin_bottom = 140.0 hint_tooltip = "Undo (Mouse 4)" +theme = ExtResource( 55 ) texture_normal = ExtResource( 49 ) texture_hover = ExtResource( 31 ) diff --git a/src/Main.gd b/src/Main.gd index be5df6c..339bcf0 100644 --- a/src/Main.gd +++ b/src/Main.gd @@ -109,6 +109,8 @@ func _update_or_add_marker(data: Dictionary) -> void: var marker = markers.get_child(i) if marker.uuid == data.uuid: marker.position = Vector2(data.x, data.y) + if data.count != null: + marker.set_count(data.count) return add_coop_marker(data) diff --git a/src/Objects/Marker.gd b/src/Objects/Marker.gd index f6e58fd..6689118 100644 --- a/src/Objects/Marker.gd +++ b/src/Objects/Marker.gd @@ -24,6 +24,7 @@ func _get_marker_data(marker: Node2D, delete: bool = false) -> Dictionary: "uuid": marker.uuid, "x": marker.position.x, "y": marker.position.y, + "count": marker.count, "connector": marker.connector, "color": marker.modulate.to_html(false), "is_connector": marker.is_connector, @@ -93,9 +94,11 @@ func _input_event(_viewport: Object, event: InputEvent, _shape_idx: int) -> void Events.emit_signal("coop_send_update", _get_marker_data(self, true)) elif event.button_index == BUTTON_WHEEL_UP and event.is_pressed(): set_count(count + 1) + Events.emit_signal("coop_send_update", _get_marker_data(self)) elif event.button_index == BUTTON_WHEEL_DOWN and event.is_pressed(): if count >= 0: set_count(count - 1) + Events.emit_signal("coop_send_update", _get_marker_data(self)) func _on_mouse_entered() -> void: is_hovering = true