diff --git a/addons/no_twitch/twitch_connection.gd b/addons/no_twitch/twitch_connection.gd index 2c4abab..1749705 100644 --- a/addons/no_twitch/twitch_connection.gd +++ b/addons/no_twitch/twitch_connection.gd @@ -26,13 +26,14 @@ func _ready(): chat_socket.chat_received.connect(check_chat_socket) -## Handles the basic Twitch Authentication process to request and then later receive a Token (using [method check_auth_peer]) -func authenticate_with_twitch(client_id = client_id): +## Handles the basic Twitch Authentication process to request and then later receive a Token (using [method check_auth_peer]). +## Returns the authentication URL. +func authenticate_with_twitch(client_id = client_id) -> String: auth_server = TCPServer.new() - - OS.shell_open(create_auth_url()) + var url := create_auth_url() auth_server.listen(int(redirect_port)) - + return url + ## Sets up a single chat connection. Joining 1 room with [param token] as it's "PASS" specifying what account it's on. And the optional [param default_chat] specifying the default room to join. While [param nick] specifies the "nickname" (Not the username on Twitch) func setup_chat_connection(default_chat : String = "", token : String = token, request_twitch_info = true, nick = "terribletwitch"): @@ -77,7 +78,7 @@ func _process(delta): ## [param scopes], Twitch Client ID ([param id]) and [param redirect_uri]. ## [param id] defaults to [member client_id] and both [param redirect] and ## [param redirect_port] -func create_auth_url(scopes : Array[String] = ["chat:read", "chat:edit"], port := redirect_port, id : String = client_id, redirect : String = redirect_uri): +func create_auth_url(scopes : Array[String] = ["chat:read", "chat:edit"], port := redirect_port, id : String = client_id, redirect : String = redirect_uri) -> String: var str_scopes : String @@ -90,7 +91,7 @@ func create_auth_url(scopes : Array[String] = ["chat:read", "chat:edit"], port : if !port.is_empty(): full_redirect_uri += ":" + port - var url = twitch_url + "client_id=" + id + "&redirect_uri=" + full_redirect_uri + "&scope=" + str_scopes + "&state=" + str(state) + var url := twitch_url + "client_id=" + id + "&redirect_uri=" + full_redirect_uri + "&scope=" + str_scopes + "&state=" + str(state) return url diff --git a/classes/deck/nodes/array_get_index.gd b/classes/deck/nodes/array_get_index.gd new file mode 100644 index 0000000..aa65af4 --- /dev/null +++ b/classes/deck/nodes/array_get_index.gd @@ -0,0 +1,45 @@ +# (c) 2023-present Eroax +# (c) 2023-present Yagich +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +extends DeckNode + + +func _init() -> void: + name = "Get Array Index" + node_type = "array_get_index" + description = "Returns an element from an array. 0-indexed." + category = "general" + + add_input_port( + DeckType.Types.ARRAY, + "Array" + ) + + add_input_port( + DeckType.Types.NUMERIC, + "Index", + "spinbox:unbounded" + ) + + add_output_port( + DeckType.Types.ANY, + "Values" + ) + + +func _value_request(on_port: int) -> Variant: + var arr = request_value(0) + if arr == null: + DeckHolder.logger.log_node("Array index: Input array is null. Returning null.", Logger.LogType.ERROR) + return null + + var idx := int(resolve_input_port_value(1)) + + if idx < 0: + idx = (arr as Array).size() + idx + + if idx >= (arr as Array).size(): + DeckHolder.logger.log_node("Array index: Index > size. Returning null.", Logger.LogType.ERROR) + return null + + return arr[idx] diff --git a/classes/deck/nodes/is_equal.gd b/classes/deck/nodes/is_equal.gd new file mode 100644 index 0000000..a1067ca --- /dev/null +++ b/classes/deck/nodes/is_equal.gd @@ -0,0 +1,35 @@ +# (c) 2023-present Eroax +# (c) 2023-present Yagich +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +extends DeckNode + + +func _init() -> void: + name = "Compare Values" + node_type = "is_equal" + description = "Returns true if the values are equal, false otherwise." + category = "general" + + add_input_port( + DeckType.Types.ANY, + "Value A", + "field" + ) + + add_input_port( + DeckType.Types.ANY, + "Value B", + "field" + ) + + add_output_port( + DeckType.Types.BOOL, + "Result" + ) + + +func _value_request(on_port: int) -> Variant: + var a = resolve_input_port_value(0) + var b = resolve_input_port_value(1) + + return a == b diff --git a/classes/deck/nodes/string_split.gd b/classes/deck/nodes/string_split.gd new file mode 100644 index 0000000..e4f7c63 --- /dev/null +++ b/classes/deck/nodes/string_split.gd @@ -0,0 +1,39 @@ +# (c) 2023-present Eroax +# (c) 2023-present Yagich +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +extends DeckNode + + +func _init() -> void: + name = "Split String" + node_type = "string_split" + description = "Splits a string by a delimiter." + category = "general" + + add_input_port( + DeckType.Types.STRING, + "String", + "field" + ) + + add_input_port( + DeckType.Types.STRING, + "Delimiter", + "field" + ) + + add_output_port( + DeckType.Types.ARRAY, + "Result" + ) + + +func _value_request(on_port: int) -> Variant: + if !resolve_input_port_value(1): + DeckHolder.logger.log_node("Split: could not resolve delimiter. Returning: []", Logger.LogType.ERROR) + return [] + + var string := str(resolve_input_port_value(0)) + var del := str(resolve_input_port_value(1)) + + return Array(string.split(del)) diff --git a/graph_node_renderer/deck_node_renderer_graph_node.gd b/graph_node_renderer/deck_node_renderer_graph_node.gd index 26544ad..49ddd69 100644 --- a/graph_node_renderer/deck_node_renderer_graph_node.gd +++ b/graph_node_renderer/deck_node_renderer_graph_node.gd @@ -144,6 +144,27 @@ func update_port(port: Port) -> void: cb.text = port.label port.value_callback = cb.is_pressed cb.toggled.connect(port.set_value) + "spinbox": + var sb := SpinBox.new() + add_child(sb) + if port.value != null: + sb.value = float(port.value) + if "unbounded" in descriptor_split: + sb.max_value = 99999 + sb.allow_greater = true + sb.allow_lesser = true + if descriptor_split.size() > 2: + sb.step = float(descriptor_split[1]) + else: + sb.step = 1.0 + else: + sb.min_value = float(descriptor_split[1]) + if descriptor_split.size() > 2: + sb.max_value = float(descriptor_split[2]) + if descriptor_split.size() > 3: + sb.step = float(descriptor_split[3]) + port.value_callback = sb.get_value + sb.value_changed.connect(port.set_value) _: var label := Label.new() add_child(label) diff --git a/graph_node_renderer/deck_node_renderer_graph_node.tscn b/graph_node_renderer/deck_node_renderer_graph_node.tscn index ecd574c..9194da6 100644 --- a/graph_node_renderer/deck_node_renderer_graph_node.tscn +++ b/graph_node_renderer/deck_node_renderer_graph_node.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=2 format=3 uid="uid://vjpj2074hiex"] +[gd_scene load_steps=2 format=3 uid="uid://timc6qnw46h"] [ext_resource type="Script" path="res://graph_node_renderer/deck_node_renderer_graph_node.gd" id="1_pos0w"] diff --git a/graph_node_renderer/twitch_setup_dialog.gd b/graph_node_renderer/twitch_setup_dialog.gd index 34ca81a..f10ef95 100644 --- a/graph_node_renderer/twitch_setup_dialog.gd +++ b/graph_node_renderer/twitch_setup_dialog.gd @@ -7,13 +7,20 @@ class_name TwitchSetupDialog func _ready(): %Authenticate.pressed.connect(authenticate_twitch) + %CopyURLButton.pressed.connect(copy_auth_link) confirmed.connect(connect_to_chat) func authenticate_twitch(): - Connections.twitch.authenticate_with_twitch(%Client_ID.text) - + var url = Connections.twitch.authenticate_with_twitch(%Client_ID.text) + OS.shell_open(url) + + +func copy_auth_link(): + var url = Connections.twitch.authenticate_with_twitch(%Client_ID.text) + DisplayServer.clipboard_set(url) + func connect_to_chat(): diff --git a/graph_node_renderer/twitch_setup_dialog.tscn b/graph_node_renderer/twitch_setup_dialog.tscn index 5af342f..29945a3 100644 --- a/graph_node_renderer/twitch_setup_dialog.tscn +++ b/graph_node_renderer/twitch_setup_dialog.tscn @@ -4,8 +4,8 @@ [node name="twitch_setup_dialog" type="ConfirmationDialog"] title = "Twitch Connection Setup" -position = Vector2i(0, 36) -size = Vector2i(375, 158) +initial_position = 2 +size = Vector2i(465, 158) min_size = Vector2i(375, 150) script = ExtResource("1_xx7my") @@ -13,9 +13,9 @@ script = ExtResource("1_xx7my") anchors_preset = 5 anchor_left = 0.5 anchor_right = 0.5 -offset_left = -179.5 +offset_left = -224.5 offset_top = 8.0 -offset_right = 179.5 +offset_right = 224.5 offset_bottom = 109.0 grow_horizontal = 2 size_flags_horizontal = 4 @@ -37,6 +37,13 @@ size_flags_horizontal = 3 size_flags_stretch_ratio = 0.25 text = "Authenticate" +[node name="CopyURLButton" type="Button" parent="VBoxContainer/Authentication"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 0.25 +text = "Copy" + [node name="CheckBox" type="CheckBox" parent="VBoxContainer"] layout_mode = 2 disabled = true