diff --git a/src/AutoTracking.gd b/src/AutoTracking.gd index 91d83b9..ccf5a1f 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.substr(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 new file mode 100644 index 0000000..3983508 --- /dev/null +++ b/src/CoopClient.gd @@ -0,0 +1,83 @@ +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" +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. + _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" + connected_to = websocket_url + +func _closed(_was_clean = false): + connect_status.text = "Connection closed" + gui_status.text = "Disconnected" + +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() == "": + 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()) + 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) + 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() + 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..16cb00f --- /dev/null +++ b/src/CoopServer.gd @@ -0,0 +1,68 @@ +extends Node + +var _server = WebSocketServer.new() +var _clients = {} +var _write_mode = WebSocketPeer.WRITE_MODE_BINARY +var _use_multiplayer = true + +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. +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") + Events.connect("stop_coop_server", self, "_on_stop_coop_server") + + +func _on_start_coop_server(port: int) -> void: + server_status.text = "Starting server..." + var ip_address = Util.get_external_ip_address() + var err = _server.listen(port) + if err != OK: + 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 _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 + if (len(_clients) > 1): + gui_status.text = "Server Running [" + str(len(_clients)-1) + " clients]" + +func _close_request(id, _code, _reason): + _clients.erase(id) + +func _disconnected(id, _was_clean = false): + _clients.erase(id) + +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() diff --git a/src/Events.gd b/src/Events.gd index ecb3555..d57d405 100644 --- a/src/Events.gd +++ b/src/Events.gd @@ -37,6 +37,22 @@ 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 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) +# warning-ignore:unused_signal +signal coop_update_marker(data) +# warning-ignore:unused_signal +signal coop_remove_marker(data) +# warning-ignore:unused_signal signal open_menu() # warning-ignore:unused_signal signal undo() 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: 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..a00d0ee --- /dev/null +++ b/src/GUI/CoopServerSettings.gd @@ -0,0 +1,79 @@ +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 new file mode 100644 index 0000000..40a90b4 --- /dev/null +++ b/src/GUI/CoopServerSettings.tscn @@ -0,0 +1,104 @@ +[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 = 12 +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! Entrando will attempt to open the port via UPnP automatically." +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 +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="."] +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: " + +[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/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/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..2f7a42d 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=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] @@ -49,7 +49,12 @@ [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://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] @@ -278,7 +283,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 @@ -311,10 +316,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 @@ -331,26 +336,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 @@ -358,7 +363,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 ) @@ -368,7 +373,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 ) @@ -378,7 +383,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 ) @@ -388,7 +393,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 ) @@ -398,7 +403,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" @@ -407,7 +412,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" @@ -416,7 +421,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" @@ -425,7 +430,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" @@ -434,7 +439,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 ) @@ -444,7 +449,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 ) @@ -454,7 +459,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 ) @@ -464,7 +469,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 ) @@ -474,7 +479,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 ) @@ -484,7 +489,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 ) @@ -494,7 +499,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 ) @@ -504,7 +509,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 ) @@ -514,7 +519,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 ) @@ -524,7 +529,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 ) @@ -534,7 +539,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 ) @@ -544,7 +549,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 ) @@ -554,7 +559,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 ) @@ -564,7 +569,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 ) @@ -574,7 +579,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 ) @@ -584,42 +589,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 = 46.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 = 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 @@ -1522,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 ) @@ -1573,6 +1629,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..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"); @@ -15,13 +14,24 @@ func _gui_input(event: InputEvent) -> void: if event is InputEventMouseButton \ and event.is_pressed(): match(event.button_index): - BUTTON_RIGHT: - set_pressed_texture(BLANK_TEXTURE); + 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 + 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", + "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..339bcf0 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,38 @@ 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) + if data.count != null: + marker.set_count(data.count) + 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 +145,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..f7ce9b1 100644 --- a/src/Objects/Icon.gd +++ b/src/Objects/Icon.gd @@ -33,3 +33,7 @@ func _input_event(_viewport: Object, event: InputEvent, _shape_idx: int) -> void and event.is_pressed(): hide() Util.add_hidden(self) + 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..6689118 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,26 @@ 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, + "count": marker.count, + "connector": marker.connector, + "color": marker.modulate.to_html(false), + "is_connector": marker.is_connector, + "sprite_path": marker.sprite_path, + } + + func init() -> void: sprite = $Sprite @@ -54,24 +75,30 @@ 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() 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) + 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 diff --git a/src/Util.gd b/src/Util.gd index de54731..969e4a5 100644 --- a/src/Util.gd +++ b/src/Util.gd @@ -14,6 +14,9 @@ var andy_mode: bool = false var drag_and_drop: bool = false var nodes_hidden: Array = [] var last_marker +var alph = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" +var coop_server = false + func _ready() -> void: Events.connect("tracker_restarted", self, "_on_tracker_restarted") @@ -26,9 +29,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 +52,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