From 24d19310b51b576107521171b86a2aba218d28af Mon Sep 17 00:00:00 2001 From: Zacharie Guet Date: Tue, 23 Jun 2026 23:28:12 +0200 Subject: [PATCH] Ajout de l'addon twitch --- addons/very-simple-twitch/auth_server.gd | 101 +++++++ addons/very-simple-twitch/auth_server.gd.uid | 1 + .../very-simple-twitch/chat/vst_chat_dock.gd | 145 +++++++++ .../chat/vst_chat_dock.gd.uid | 1 + .../chat/vst_chat_dock.tscn | 111 +++++++ .../chat/vst_chat_dock_line.gd | 9 + .../chat/vst_chat_dock_line.gd.uid | 1 + .../chat/vst_chat_dock_line.tscn | 16 + addons/very-simple-twitch/doc/Errors.md | 32 ++ addons/very-simple-twitch/doc/Network.md | 46 +++ addons/very-simple-twitch/doc/Testing.md | 21 ++ addons/very-simple-twitch/doc/develop.md | 32 ++ .../doc/img/gdlint-usage-1.png | Bin 0 -> 180558 bytes .../doc/img/gdlint-usage-1.png.import | 40 +++ addons/very-simple-twitch/dock/vst-dock.gd | 62 ++++ .../very-simple-twitch/dock/vst-dock.gd.uid | 1 + addons/very-simple-twitch/dock/vst-dock.tscn | 111 +++++++ addons/very-simple-twitch/emote_location.gd | 15 + .../very-simple-twitch/emote_location.gd.uid | 1 + addons/very-simple-twitch/icon.png | Bin 0 -> 215 bytes addons/very-simple-twitch/icon.png.import | 40 +++ addons/very-simple-twitch/models/chatter.gd | 19 ++ .../very-simple-twitch/models/chatter.gd.uid | 1 + addons/very-simple-twitch/models/irc_tags.gd | 13 + .../very-simple-twitch/models/irc_tags.gd.uid | 1 + .../models/twitch_channel.gd | 5 + .../models/twitch_channel.gd.uid | 1 + addons/very-simple-twitch/network_call.gd | 198 ++++++++++++ addons/very-simple-twitch/network_call.gd.uid | 1 + addons/very-simple-twitch/parse_helper.gd | 74 +++++ addons/very-simple-twitch/parse_helper.gd.uid | 1 + addons/very-simple-twitch/plugin.cfg | 7 + addons/very-simple-twitch/public/index.html | 26 ++ addons/very-simple-twitch/twitch_api.gd | 164 ++++++++++ addons/very-simple-twitch/twitch_api.gd.uid | 1 + addons/very-simple-twitch/twitch_chat.gd | 285 ++++++++++++++++++ addons/very-simple-twitch/twitch_chat.gd.uid | 1 + .../twitch_chat_settings.gd | 124 ++++++++ .../twitch_chat_settings.gd.uid | 1 + addons/very-simple-twitch/twitch_node.gd | 71 +++++ addons/very-simple-twitch/twitch_node.gd.uid | 1 + addons/very-simple-twitch/twitch_utils.gd | 40 +++ addons/very-simple-twitch/twitch_utils.gd.uid | 1 + addons/very-simple-twitch/vst.gd | 36 +++ addons/very-simple-twitch/vst.gd.uid | 1 + addons/very-simple-twitch/vst_error.gd | 32 ++ addons/very-simple-twitch/vst_error.gd.uid | 1 + 47 files changed, 1892 insertions(+) create mode 100644 addons/very-simple-twitch/auth_server.gd create mode 100644 addons/very-simple-twitch/auth_server.gd.uid create mode 100644 addons/very-simple-twitch/chat/vst_chat_dock.gd create mode 100644 addons/very-simple-twitch/chat/vst_chat_dock.gd.uid create mode 100644 addons/very-simple-twitch/chat/vst_chat_dock.tscn create mode 100644 addons/very-simple-twitch/chat/vst_chat_dock_line.gd create mode 100644 addons/very-simple-twitch/chat/vst_chat_dock_line.gd.uid create mode 100644 addons/very-simple-twitch/chat/vst_chat_dock_line.tscn create mode 100644 addons/very-simple-twitch/doc/Errors.md create mode 100644 addons/very-simple-twitch/doc/Network.md create mode 100644 addons/very-simple-twitch/doc/Testing.md create mode 100644 addons/very-simple-twitch/doc/develop.md create mode 100644 addons/very-simple-twitch/doc/img/gdlint-usage-1.png create mode 100644 addons/very-simple-twitch/doc/img/gdlint-usage-1.png.import create mode 100644 addons/very-simple-twitch/dock/vst-dock.gd create mode 100644 addons/very-simple-twitch/dock/vst-dock.gd.uid create mode 100644 addons/very-simple-twitch/dock/vst-dock.tscn create mode 100644 addons/very-simple-twitch/emote_location.gd create mode 100644 addons/very-simple-twitch/emote_location.gd.uid create mode 100644 addons/very-simple-twitch/icon.png create mode 100644 addons/very-simple-twitch/icon.png.import create mode 100644 addons/very-simple-twitch/models/chatter.gd create mode 100644 addons/very-simple-twitch/models/chatter.gd.uid create mode 100644 addons/very-simple-twitch/models/irc_tags.gd create mode 100644 addons/very-simple-twitch/models/irc_tags.gd.uid create mode 100644 addons/very-simple-twitch/models/twitch_channel.gd create mode 100644 addons/very-simple-twitch/models/twitch_channel.gd.uid create mode 100644 addons/very-simple-twitch/network_call.gd create mode 100644 addons/very-simple-twitch/network_call.gd.uid create mode 100644 addons/very-simple-twitch/parse_helper.gd create mode 100644 addons/very-simple-twitch/parse_helper.gd.uid create mode 100644 addons/very-simple-twitch/plugin.cfg create mode 100644 addons/very-simple-twitch/public/index.html create mode 100644 addons/very-simple-twitch/twitch_api.gd create mode 100644 addons/very-simple-twitch/twitch_api.gd.uid create mode 100644 addons/very-simple-twitch/twitch_chat.gd create mode 100644 addons/very-simple-twitch/twitch_chat.gd.uid create mode 100644 addons/very-simple-twitch/twitch_chat_settings.gd create mode 100644 addons/very-simple-twitch/twitch_chat_settings.gd.uid create mode 100644 addons/very-simple-twitch/twitch_node.gd create mode 100644 addons/very-simple-twitch/twitch_node.gd.uid create mode 100644 addons/very-simple-twitch/twitch_utils.gd create mode 100644 addons/very-simple-twitch/twitch_utils.gd.uid create mode 100644 addons/very-simple-twitch/vst.gd create mode 100644 addons/very-simple-twitch/vst.gd.uid create mode 100644 addons/very-simple-twitch/vst_error.gd create mode 100644 addons/very-simple-twitch/vst_error.gd.uid diff --git a/addons/very-simple-twitch/auth_server.gd b/addons/very-simple-twitch/auth_server.gd new file mode 100644 index 0000000..e2262eb --- /dev/null +++ b/addons/very-simple-twitch/auth_server.gd @@ -0,0 +1,101 @@ +class_name VSTAuthServer + +extends Node + +signal OnTokenReceived(token: String) + +var SERVER_IDENTITY = 'AUTH_SERVER' +var TOKEN_KEY = 'token' +var AUTHENTICATION_REDIRECT_FILE_PATH = 'res://addons/very-simple-twitch/public/index.html' + +var _clients: Array[StreamPeerTCP] = [] +var _server: TCPServer + + +func start_server(port: int): + _server = TCPServer.new() + _server.listen(port) + print("Server started") + + +func stop_server(): + if _server: + _server.stop() + _server = null + + +func _process(_delta: float) -> void: + if !_server: + return + + var newConnection = _server.take_connection() + if newConnection: + _clients.push_back(newConnection) + + for client in _clients: + if client.get_status() != StreamPeerTCP.STATUS_CONNECTED: + continue + + var bytes = client.get_available_bytes() + # after finisher reading bytes clear connection + _clients = _clients.filter(func (item): return item != client) + var requestAsString = client.get_string(bytes) + if requestAsString.length() < 1: + continue + + var requestInformation = requestAsString.split('\n')[0].split(' ') + var method = requestInformation[0] + var url = requestInformation[1] + + match method: + 'GET': + # send html login page + handleGet(client) + 'POST': + # handle token extraction + handlePost(client, url) + + +func handlePost(client: StreamPeer, url: String): + var urlSplitted:PackedStringArray = url.split('?') + if (len(urlSplitted) == 1): + return + var query = urlSplitted[1] + var token = getTokenFromQuery(query) + if !token: + return + OnTokenReceived.emit(token) + send200(client) + stop_server() + queue_free() + + +func handleGet(client: StreamPeer): + var pageAsString = loadLoginPage() + send200(client, pageAsString) + + +func getTokenFromQuery(query: String): + var queryKeyValues = query.split('&') + for keyValue in queryKeyValues: + var splittedKeyValue = keyValue.split('=') + var key = splittedKeyValue[0] + if key == TOKEN_KEY: + return splittedKeyValue[1] + + +func send200(client: StreamPeer, data: String = "", content_type: String = "text/html"): + var dataAsBuffer = data.to_ascii_buffer() + client.put_data(("HTTP/1.1 %d %s\r\n" % [200, 'OK']).to_ascii_buffer()) + client.put_data(("Server: %s\r\n" % SERVER_IDENTITY).to_ascii_buffer()) + client.put_data(("Content-Length: %d\r\n" % dataAsBuffer.size()).to_ascii_buffer()) + client.put_data("Connection: close\r\n".to_ascii_buffer()) + client.put_data(("Content-Type: %s\r\n\r\n" % content_type).to_ascii_buffer()) + client.put_data(dataAsBuffer) + + +func loadLoginPage() -> String: + var file = FileAccess.open(AUTHENTICATION_REDIRECT_FILE_PATH, FileAccess.READ) + var loadedFile: String = file.get_as_text() + file.close() + return loadedFile diff --git a/addons/very-simple-twitch/auth_server.gd.uid b/addons/very-simple-twitch/auth_server.gd.uid new file mode 100644 index 0000000..67e492b --- /dev/null +++ b/addons/very-simple-twitch/auth_server.gd.uid @@ -0,0 +1 @@ +uid://cfwdtrrd8w61s diff --git a/addons/very-simple-twitch/chat/vst_chat_dock.gd b/addons/very-simple-twitch/chat/vst_chat_dock.gd new file mode 100644 index 0000000..d0af23d --- /dev/null +++ b/addons/very-simple-twitch/chat/vst_chat_dock.gd @@ -0,0 +1,145 @@ +@tool +extends Control + +const MAX_MESSAGES:int = 50 +var line: PackedScene = load("res://addons/very-simple-twitch/chat/vst_chat_dock_line.tscn") + + +var twitch_chat: VSTChat: + get: + if twitch_chat == null: + twitch_chat = VSTChat.new() + add_child(twitch_chat) + return twitch_chat + +@onready var support_button: Button = %SupportButton +@onready var channel_line_edit: LineEdit = %ChannelLineEdit + +@onready var connect_button: Button = %ConnectButton + +@onready var chat_layout: Control = %ChatLayout + +@onready var chat_scroll:ScrollContainer = %ChatScroll + +@onready var clear_button:Button = %ClearButton + +@onready var disconnect_button:Button = %DisconnectButton + +func _ready(): + support_button.icon = get_theme_icon("Heart", "EditorIcons") + support_button.tooltip_text = "Support me on Ko-fi" + +func _on_button_pressed(): + twitch_chat.Connected.connect(on_chat_connected) + twitch_chat.OnMessage.connect(create_chatter_msg) + + twitch_chat.login_anon(channel_line_edit.text) + connect_button.disabled = true + channel_line_edit.editable = false + +func _on_clear_button_pressed(): + clear_all_messages() + +func _on_line_edit_text_changed(new_text): + connect_button.disabled = len(new_text) == 0 + +func _on_disconnect_button_pressed(): + twitch_chat.disconnect_api() + clear_all_messages() + show_connect_layout() + if twitch_chat.Connected.is_connected(on_chat_connected): + twitch_chat.Connected.disconnect(on_chat_connected) + if twitch_chat.OnMessage.is_connected(create_chatter_msg): + twitch_chat.OnMessage.disconnect(create_chatter_msg) + + +func _on_support_button_pressed() -> void: + OS.shell_open("https://ko-fi.com/rothiotome?ref=VST") + + +func on_chat_connected(): + create_system_msg("Connected to chat") + show_chat_layout() + +func create_system_msg(message: String): + var msg = line.instantiate() + msg.set_chatter_string("[i]"+message+"[/i]") + chat_layout.add_child(msg) + check_scroll() + +func create_chatter_msg(chatter: VSTChatter): + var msg = line.instantiate() + + var badges: String = await get_badges(chatter) + chatter.message = escape_bbcode(chatter.message) + await add_emotes(chatter) + + msg.set_chatter_msg(badges, chatter) + chat_layout.add_child(msg) + + check_scroll() + +func check_scroll(): + var bottom: bool = is_scroll_bottom() + check_number_messages() + await get_tree().process_frame + if bottom: chat_scroll.scroll_vertical = chat_scroll.get_v_scroll_bar().max_value + +func check_number_messages(): + if chat_layout.get_child_count() > MAX_MESSAGES: + chat_layout.remove_child(chat_layout.get_children()[0]) + +# TODO: Can't get badges when the connection is annonymous, we should clear this method +func get_badges(chatter: VSTChatter) -> String: + var badges:= "" + for badge in chatter.tags.badges: + var result = await twitch_chat.get_badge(badge, chatter.tags.badges[badge], chatter.tags.user_id) + if result: + badges += "[img=center]" + result.resource_path + "[/img] " + return badges + +func add_emotes(chatter: VSTChatter): + if chatter.tags.emotes.is_empty(): return + + var locations: Array = [] + for emote in chatter.tags.emotes: + for data in chatter.tags.emotes[emote].split(","): + var start_end = data.split("-") + locations.append(VSTEmoteLocation.new(emote, int(start_end[0]), int(start_end[1]))) + + locations.sort_custom(Callable(VSTEmoteLocation, "smaller")) + var offset = 0 + for loc in locations: + var result = await twitch_chat.get_emote(loc.id) + var emote_string = "[img=center]" + result.resource_path +"[/img]" + var pre: String = chatter.message.substr(0, loc.start + offset) + var post: String = chatter.message.substr(loc.end + offset + 1) + chatter.message = pre + emote_string + post + offset += emote_string.length() + loc.start - loc.end - 1 + +func is_scroll_bottom() -> bool: + var scroll_bar = chat_scroll.get_v_scroll_bar() + return chat_scroll.scroll_vertical >= scroll_bar.max_value - scroll_bar.get_rect().size.y + + +# Returns escaped BBCode that won't be parsed by RichTextLabel as tags. +func escape_bbcode(bbcode_text) -> String: + return bbcode_text.replace("[", "[lb]") + +func clear_all_messages(): + for childen in chat_layout.get_children(): + chat_layout.remove_child(childen) + +func show_chat_layout(): + disconnect_button.visible = true + clear_button.visible = true + channel_line_edit.visible = false + connect_button.visible = false + +func show_connect_layout(): + disconnect_button.visible = false + clear_button.visible = false + channel_line_edit.editable = true + channel_line_edit.visible = true + connect_button.visible = true + connect_button.disabled = false diff --git a/addons/very-simple-twitch/chat/vst_chat_dock.gd.uid b/addons/very-simple-twitch/chat/vst_chat_dock.gd.uid new file mode 100644 index 0000000..3655123 --- /dev/null +++ b/addons/very-simple-twitch/chat/vst_chat_dock.gd.uid @@ -0,0 +1 @@ +uid://lsv481dwwwpu diff --git a/addons/very-simple-twitch/chat/vst_chat_dock.tscn b/addons/very-simple-twitch/chat/vst_chat_dock.tscn new file mode 100644 index 0000000..11c7d48 --- /dev/null +++ b/addons/very-simple-twitch/chat/vst_chat_dock.tscn @@ -0,0 +1,111 @@ +[gd_scene load_steps=4 format=3 uid="uid://c8jard0jvmfmt"] + +[ext_resource type="Script" path="res://addons/very-simple-twitch/chat/vst_chat_dock.gd" id="1_fkddh"] + +[sub_resource type="Image" id="Image_dfhsm"] +data = { +"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0), +"format": "RGBA8", +"height": 16, +"mipmaps": false, +"width": 16 +} + +[sub_resource type="ImageTexture" id="ImageTexture_lqqxv"] +image = SubResource("Image_dfhsm") + +[node name="VstChatDock" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_fkddh") + +[node name="TabContainer" type="TabContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +current_tab = 0 + +[node name="Chat" type="VBoxContainer" parent="TabContainer"] +layout_mode = 2 +metadata/_tab_index = 0 + +[node name="HBoxContainer" type="HBoxContainer" parent="TabContainer/Chat"] +layout_mode = 2 + +[node name="ChannelLineEdit" type="LineEdit" parent="TabContainer/Chat/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +placeholder_text = "Channel name" + +[node name="ConnectButton" type="Button" parent="TabContainer/Chat/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +disabled = true +text = "CONNECT" + +[node name="ClearButton" type="Button" parent="TabContainer/Chat/HBoxContainer"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +text = "CLEAR CHAT" + +[node name="DisconnectButton" type="Button" parent="TabContainer/Chat/HBoxContainer"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +text = "DISCONNECT" + +[node name="VBoxContainer" type="VBoxContainer" parent="TabContainer/Chat"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="Chat" type="Panel" parent="TabContainer/Chat/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="ChatScroll" type="ScrollContainer" parent="TabContainer/Chat/VBoxContainer/Chat"] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="ChatLayout" type="VBoxContainer" parent="TabContainer/Chat/VBoxContainer/Chat/ChatScroll"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -8.0 +offset_bottom = 33.0 +grow_horizontal = 0 +alignment = 2 + +[node name="SupportButton" type="Button" parent="HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 8 +tooltip_text = "Support me on Ko-fi" +icon = SubResource("ImageTexture_lqqxv") +flat = true + +[connection signal="text_changed" from="TabContainer/Chat/HBoxContainer/ChannelLineEdit" to="." method="_on_line_edit_text_changed"] +[connection signal="pressed" from="TabContainer/Chat/HBoxContainer/ConnectButton" to="." method="_on_button_pressed"] +[connection signal="pressed" from="TabContainer/Chat/HBoxContainer/ClearButton" to="." method="_on_clear_button_pressed"] +[connection signal="pressed" from="TabContainer/Chat/HBoxContainer/DisconnectButton" to="." method="_on_disconnect_button_pressed"] +[connection signal="pressed" from="HBoxContainer/SupportButton" to="." method="_on_support_button_pressed"] diff --git a/addons/very-simple-twitch/chat/vst_chat_dock_line.gd b/addons/very-simple-twitch/chat/vst_chat_dock_line.gd new file mode 100644 index 0000000..19cce18 --- /dev/null +++ b/addons/very-simple-twitch/chat/vst_chat_dock_line.gd @@ -0,0 +1,9 @@ +@tool +extends HBoxContainer + +func set_chatter_msg(badges: String, chatter: VSTChatter): + set_chatter_string("%02d:%02d" %[chatter.date_time_dict["hour"], chatter.date_time_dict["minute"]] + " " + badges + " [b][color="+ chatter.tags.color_hex + "]" +chatter.tags.display_name +"[/color][/b]: " + chatter.message) + +func set_chatter_string(message:String): + $RichTextLabel.text = message + queue_sort() diff --git a/addons/very-simple-twitch/chat/vst_chat_dock_line.gd.uid b/addons/very-simple-twitch/chat/vst_chat_dock_line.gd.uid new file mode 100644 index 0000000..e61f97e --- /dev/null +++ b/addons/very-simple-twitch/chat/vst_chat_dock_line.gd.uid @@ -0,0 +1 @@ +uid://u504g1u250up diff --git a/addons/very-simple-twitch/chat/vst_chat_dock_line.tscn b/addons/very-simple-twitch/chat/vst_chat_dock_line.tscn new file mode 100644 index 0000000..6634342 --- /dev/null +++ b/addons/very-simple-twitch/chat/vst_chat_dock_line.tscn @@ -0,0 +1,16 @@ +[gd_scene load_steps=2 format=3 uid="uid://bo1un8cwcrpqr"] + +[ext_resource type="Script" path="res://addons/very-simple-twitch/chat/vst_chat_dock_line.gd" id="1_h0lnd"] + +[node name="VstChatDockLine" type="HBoxContainer"] +offset_right = 1.0 +offset_bottom = 115.0 +size_flags_horizontal = 3 +script = ExtResource("1_h0lnd") + +[node name="RichTextLabel" type="RichTextLabel" parent="."] +layout_mode = 2 +size_flags_horizontal = 3 +bbcode_enabled = true +fit_content = true +scroll_active = false diff --git a/addons/very-simple-twitch/doc/Errors.md b/addons/very-simple-twitch/doc/Errors.md new file mode 100644 index 0000000..9d77047 --- /dev/null +++ b/addons/very-simple-twitch/doc/Errors.md @@ -0,0 +1,32 @@ +# Errors +## Information +This page is to explain the use and implementation of errors in VST. Errors have 3 parameters for code, description and extra information. + +* error_code (enum @see VST_Error.VST_Code_Error) -> This parameter groups the types of errors in a general way. +* description (String) -> The description of the error is a general description of the general grouping in human language. +* info (String) -> The information is the particular description of the error. It should be used to add extra information about the particular error. + +## New errors +To add new errors you must first ask yourself if it is necessary to add a new code or not. If necessary add the code in the VST_Error.VST_Code_Error enumeration. +To illustrate the error let's imagine that we have a function that updates the area of a triangle given a base and a height. This function updates an area parameter only if it is possible to calculate the area (the base or the height is greater than 0). + +```GDScript +func calculateArea(base:int, heigth:int): + if base <= 0: + var error:VST_Error = VST_Error.new(VST_Error.VST_Code_Error.PARAM_ERROR, "base can't be less than or equals 0") + push_warning(str(error)) + area = 0 + elif height <= 0: + var error:VST_Error = VST_Error.new(VST_Error.VST_Code_Error.PARAM_ERROR, "height can't be less than or equals 0") + push_warning(str(error)) + area = 0 + else + area = (base*height)/2 +``` + +## Error Codes + +* PARAM_ERROR Use this code for errors that have to do with invalid parameters. An int that should be a String or a String that cannot be empty. +* TIMEOUT_ERROR Use this code when a timer runs out or there is no response from a system. +* NETWORK_ERROR Use this code when there is a network error ( > 400 and < 500) +* SERVER_ERROR Use this code when, in a network communication, the server is down or has a problem ( > 500 ). diff --git a/addons/very-simple-twitch/doc/Network.md b/addons/very-simple-twitch/doc/Network.md new file mode 100644 index 0000000..ca58921 --- /dev/null +++ b/addons/very-simple-twitch/doc/Network.md @@ -0,0 +1,46 @@ +# Network +## Information +The motivation for using this wrapper is to make easier the call APIs and gather responses and errors from the server. The idea is to make it as verbose as possible using a builder pattern so the request can be read at first glance. + +Before making the network call, the wrapper will check a number of conditions within the "check_request_data" method which will throw a number of errors or warnings if the request is not well built. The wrapper is permissive with the definition of REST APIs, so you can have a GET call with body or a POST with GET parameters in the url (TBD). + +Note: To achieve this effect, it is necessary to call new() and pass a node to the "launch_request" method, which will self manage all that's necessary for it to work. + +## Usage +To use the wrapper for network requests simply build a Network_Call object and start configuring it with the to, with, etc... methods. + +* to (String) -> url destination +* with (String) -> request body +* add_get_param (String,String) y add_all_get_param(Dictionary) -> add get params to request +* add_header(String,String) y add_all_header(Dictionary) -> add headers to request +* verb(Http_Method) -> set the method for REST request +* in_time(int) -> set the timeout time to the request +* set_on_call_success (Callable) -> call this function if the request was ok (200) +* set_on_call_fail (Callable) -> call this function if the request was fail (>400) +* no_cache -> set no cache for request ( only used in GET requests ) + +## Example +```GDScript + func _onReady(): + Network_Call.new().to("https://catfact.ninja/fact").set_on_call_success(on_cat_fact).set_on_call_fail(on_error).launch_request(self) + + func on_cat_fact(result): + $Label.text = str(result) + + func on_error(error): + $Label.text = "Error requesting fact about cats :(" +``` +## Cache +The network module has a cache for GET requests to save time and bandwidth for similar requests in 'short' time spans. + +Since nodes are ephemeral (network requests are nodes that disappear) the cache is stored on disk and not in memory (this resposability was left for the upper layers). + +The cache works as follows: +* 1. The request is hashed ( using the url ) +* 2. A file with the specific name ( the hash ) is searched for on disk. +* 3.a If it exists and it has not passed 300 seconds ( arbitrary and improvable time using an etag? ) the request is resolved and returns the file content. +* 3.b If the file does not exist or it has been more than 300 seconds, the request is made and cached using the same hash. + +The time validity of this cache is on CACHE_TIME_IN_SECONDS constant in network_call.gd + +The cached content is an array of bytes due to the heterogeneous nature of the possible requests (text, images, sound...). diff --git a/addons/very-simple-twitch/doc/Testing.md b/addons/very-simple-twitch/doc/Testing.md new file mode 100644 index 0000000..45a1173 --- /dev/null +++ b/addons/very-simple-twitch/doc/Testing.md @@ -0,0 +1,21 @@ +# Testing + +## Adding test + +Use "assert_eq" for "primitive" values and "assert_eq_deep" for complex data + +For add some test be sure: +1. Your test are inside /test folder +2. Your test file starts with test name +3. Your test script extends from "GutTest" +4. Your test methods starts also with test + +You can use some useful methods for testing like: +* before_all -> Excecuted before all tests in the script +* before_each -> Excecuted before each test in the script +* after_each -> Excecuted after each test in the script +* after_all -> Excecuted after all tests in the script + + +## GUT Documentation +https://gut.readthedocs.io/en/latest/ diff --git a/addons/very-simple-twitch/doc/develop.md b/addons/very-simple-twitch/doc/develop.md new file mode 100644 index 0000000..c7eebd1 --- /dev/null +++ b/addons/very-simple-twitch/doc/develop.md @@ -0,0 +1,32 @@ +# Develop + +## GDLint +The idea behind installing a linter in this plugin is mainly code readability. That can make collaboration easier for other developers. Using the same consistent coding style makes it easier to collaborate with others and easier to understand what the plugin is doing. + +### Installation + +There are a few steps before you can use GDLint. You can consult the official documentation, but here's a summary + +1. GDLinter is installed on addons folders. You don't need do nothing with it. +2. Deactivate GDLint from pluggins ( project -> configuration -> plugins ) +3. Check your python version using 'python --version' or 'py --version' + - no version installed? + - Check windows store for windows ( best option in my opinion ) + - On Mac 'brew install python' using Homebrew + - On Linux, you can use APT 'sudo apt install python3' +4. Install godot toolkit using 'pip3 install "gdtoolkit==4.*"' + - No pip installed? Download the script, from https://bootstrap.pypa.io/get-pip.py and type 'python get-pip.py' to install it. +5. Check gdlint version with 'gdlint --version' + - Nothing or error showed? try repeating the steps from 2 +6. Activate GdLint again. + - If GDLint menu at the bottom doesnt appear, relaunch godot. + + +GDScript Toolkit Documentation -> https://github.com/Scony/godot-gdscript-toolkit +GDLinter Addon Documentation -> https://github.com/el-falso/gdlinter/ + +### Usage + +As soon as you install the plugin and the toolkit you will see a menu at the bottom called GDLint. There it will show the problems with the code :) + +![](img/gdlint-usage-1.png?raw=true) diff --git a/addons/very-simple-twitch/doc/img/gdlint-usage-1.png b/addons/very-simple-twitch/doc/img/gdlint-usage-1.png new file mode 100644 index 0000000000000000000000000000000000000000..a3ce3342f4091951063aaf8a92222a05dcca2134 GIT binary patch literal 180558 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
;fzYGaq^uy|wBI=<_GGNP+dV6qV%~If01T8^ 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Μe|&5qG6HTr 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 N@-iyY6_Un*{{uk*rW^nO literal 0 HcmV?d00001 diff --git a/addons/very-simple-twitch/doc/img/gdlint-usage-1.png.import b/addons/very-simple-twitch/doc/img/gdlint-usage-1.png.import new file mode 100644 index 0000000..1fa3a87 --- /dev/null +++ b/addons/very-simple-twitch/doc/img/gdlint-usage-1.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://beqmxv0pbk5dp" +path="res://.godot/imported/gdlint-usage-1.png-06a3e1d7a5f85d1fd83e80b21ea14d73.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/very-simple-twitch/doc/img/gdlint-usage-1.png" +dest_files=["res://.godot/imported/gdlint-usage-1.png-06a3e1d7a5f85d1fd83e80b21ea14d73.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/very-simple-twitch/dock/vst-dock.gd b/addons/very-simple-twitch/dock/vst-dock.gd new file mode 100644 index 0000000..32571e8 --- /dev/null +++ b/addons/very-simple-twitch/dock/vst-dock.gd @@ -0,0 +1,62 @@ +@tool +extends Control + +@onready var copy_button: Button = %CopyButton +@onready var redirect_uri = %RedirectURI +@onready var client_id_line_edit = %ClientIDLineEdit +@onready var client_id_warning = %ClientIDWarning +@onready var help_icon = %HelpIcon +@onready var warning_icon = %WarningIcon + + +func _ready(): + help_icon.texture = get_theme_icon("Help", "EditorIcons") + warning_icon.texture = get_theme_icon("StatusWarning", "EditorIcons") + copy_button.icon = get_theme_icon("ActionCopy", "EditorIcons") + copy_button.tooltip_text = "Copy Redirect URL to clipboard" + client_id_warning.add_theme_color_override( + "font_color", + EditorInterface.get_editor_settings()\ + .get_setting("text_editor/theme/highlighting/comment_markers/warning_color") + ) + + visibility_changed.connect(on_visibility_changed) + + +func on_visibility_changed(): + if visible: + update_visuals() + ProjectSettings.settings_changed.connect(update_visuals) + else: + if ProjectSettings.settings_changed.is_connected(update_visuals): + ProjectSettings.settings_changed.disconnect(update_visuals) + + +func update_visuals(): + var client_id = VSTSettings.get_setting(VSTSettings.settings.client_id) + var redirect_host = VSTSettings.get_setting(VSTSettings.settings.redirect_host) + var redirect_port = VSTSettings.get_setting(VSTSettings.settings.redirect_port) + var uuid = VSTSettings.get_setting(VSTSettings.settings.uuid) + redirect_uri.text = redirect_host + str(redirect_port) + "/" + uuid + client_id_line_edit.text = client_id + if client_id == "": + client_id_warning.show() + warning_icon.show() + else: + client_id_warning.hide() + warning_icon.hide() + + +func copy_redirect_uri(): + DisplayServer.clipboard_set(redirect_uri.text) + + +func client_id_submitted(): + ProjectSettings.set_setting( + "very_simple_twitch/"+VSTSettings.settings.client_id.path, + client_id_line_edit.text + ) + ProjectSettings.save() + +func open_url(meta): + OS.shell_open(meta) diff --git a/addons/very-simple-twitch/dock/vst-dock.gd.uid b/addons/very-simple-twitch/dock/vst-dock.gd.uid new file mode 100644 index 0000000..0395153 --- /dev/null +++ b/addons/very-simple-twitch/dock/vst-dock.gd.uid @@ -0,0 +1 @@ +uid://bn73uslhjp8aj diff --git a/addons/very-simple-twitch/dock/vst-dock.tscn b/addons/very-simple-twitch/dock/vst-dock.tscn new file mode 100644 index 0000000..98da955 --- /dev/null +++ b/addons/very-simple-twitch/dock/vst-dock.tscn @@ -0,0 +1,111 @@ +[gd_scene load_steps=4 format=3 uid="uid://m77ohpfa7qef"] + +[ext_resource type="Script" path="res://addons/very-simple-twitch/dock/vst-dock.gd" id="1_kyfdh"] + +[sub_resource type="Image" id="Image_cb0pc"] +data = { +"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0), +"format": "RGBA8", +"height": 16, +"mipmaps": false, +"width": 16 +} + +[sub_resource type="ImageTexture" id="ImageTexture_oh773"] +image = SubResource("Image_cb0pc") + +[node name="vst-dock" type="VBoxContainer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_kyfdh") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 + +[node name="HelpIcon" type="TextureRect" parent="HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +texture = SubResource("ImageTexture_oh773") +stretch_mode = 5 + +[node name="RichTextLabel2" type="RichTextLabel" parent="HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +focus_mode = 2 +bbcode_enabled = true +text = " [url=https://github.com/rothiotome/godot-very-simple-twitch?tab=readme-ov-file#quick-setup]Quick Setup section in the readme[/url] and follow the steps in there. +" +fit_content = true +selection_enabled = true + +[node name="Label" type="Label" parent="."] +layout_mode = 2 +text = "Quick Start Guide" + +[node name="RedirectURI" type="HBoxContainer" parent="."] +layout_mode = 2 + +[node name="Label" type="Label" parent="RedirectURI"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Redirect URI: " + +[node name="RedirectURIContainer" type="HBoxContainer" parent="RedirectURI"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 2.0 + +[node name="RedirectURI" type="RichTextLabel" parent="RedirectURI/RedirectURIContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +focus_mode = 2 +text = "Value" +fit_content = true +selection_enabled = true + +[node name="CopyButton" type="Button" parent="RedirectURI/RedirectURIContainer"] +unique_name_in_owner = true +layout_mode = 2 +tooltip_text = "Copy Redirect URL to clipboard" +icon = SubResource("ImageTexture_oh773") + +[node name="ClientID" type="HBoxContainer" parent="."] +layout_mode = 2 + +[node name="Label" type="Label" parent="ClientID"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Client ID:" + +[node name="ClientIDLineEdit" type="LineEdit" parent="ClientID"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 2.0 +placeholder_text = "YOUR CLIENT ID HERE" + +[node name="Warning" type="HBoxContainer" parent="."] +layout_mode = 2 +alignment = 1 + +[node name="WarningIcon" type="TextureRect" parent="Warning"] +unique_name_in_owner = true +layout_mode = 2 +texture = SubResource("ImageTexture_oh773") +stretch_mode = 5 + +[node name="ClientIDWarning" type="Label" parent="Warning"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +theme_override_colors/font_color = Color(0.72, 0.61, 0.48, 1) +text = "To use VST, you need a Client ID. Check the readme above for how to get one." + +[connection signal="meta_clicked" from="HBoxContainer/RichTextLabel2" to="." method="open_url"] +[connection signal="pressed" from="RedirectURI/RedirectURIContainer/CopyButton" to="." method="copy_redirect_uri"] +[connection signal="focus_exited" from="ClientID/ClientIDLineEdit" to="." method="client_id_submitted"] +[connection signal="text_submitted" from="ClientID/ClientIDLineEdit" to="." method="client_id_submitted"] diff --git a/addons/very-simple-twitch/emote_location.gd b/addons/very-simple-twitch/emote_location.gd new file mode 100644 index 0000000..e09ab99 --- /dev/null +++ b/addons/very-simple-twitch/emote_location.gd @@ -0,0 +1,15 @@ +class_name VSTEmoteLocation + +extends RefCounted + +var id : String +var start : int +var end : int + +func _init(emote_id, start_idx, end_idx): + self.id = emote_id + self.start = start_idx + self.end = end_idx + +static func smaller(a: VSTEmoteLocation, b: VSTEmoteLocation): + return a.start < b.start diff --git a/addons/very-simple-twitch/emote_location.gd.uid b/addons/very-simple-twitch/emote_location.gd.uid new file mode 100644 index 0000000..f337757 --- /dev/null +++ b/addons/very-simple-twitch/emote_location.gd.uid @@ -0,0 +1 @@ +uid://dc4gv3t0sj482 diff --git a/addons/very-simple-twitch/icon.png b/addons/very-simple-twitch/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..35f91d346a0b9c1b76f6132f490ce951fda20a88 GIT binary patch literal 215 zcmV;|04V>7P)e7lOu3Vpiw^wVFT|oKf(dbe)(`yPT-K@ z&+z;CV$cJ+muBTaX<#X&c& literal 0 HcmV?d00001 diff --git a/addons/very-simple-twitch/icon.png.import b/addons/very-simple-twitch/icon.png.import new file mode 100644 index 0000000..c72375e --- /dev/null +++ b/addons/very-simple-twitch/icon.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://crhtjoakp6j05" +path="res://.godot/imported/icon.png-952ca81aead1a8efe9432e636ee0d5ac.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/very-simple-twitch/icon.png" +dest_files=["res://.godot/imported/icon.png-952ca81aead1a8efe9432e636ee0d5ac.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/very-simple-twitch/models/chatter.gd b/addons/very-simple-twitch/models/chatter.gd new file mode 100644 index 0000000..fb2a9ad --- /dev/null +++ b/addons/very-simple-twitch/models/chatter.gd @@ -0,0 +1,19 @@ +class_name VSTChatter + +var date_time_dict: Dictionary +var login: String +var channel: String +var message: String +var tags: VSTIRCTags + + +func is_mod() -> bool: + return tags.badges.has("moderator") + + +func is_sub() -> bool: + return tags.badges.has("subscriber") + + +func is_broadcaster() -> bool: + return tags.badges.has("broadcaster") diff --git a/addons/very-simple-twitch/models/chatter.gd.uid b/addons/very-simple-twitch/models/chatter.gd.uid new file mode 100644 index 0000000..bfa6063 --- /dev/null +++ b/addons/very-simple-twitch/models/chatter.gd.uid @@ -0,0 +1 @@ +uid://b5jggcdr67bax diff --git a/addons/very-simple-twitch/models/irc_tags.gd b/addons/very-simple-twitch/models/irc_tags.gd new file mode 100644 index 0000000..0bd34b1 --- /dev/null +++ b/addons/very-simple-twitch/models/irc_tags.gd @@ -0,0 +1,13 @@ +class_name VSTIRCTags + +# Model for a IRC twitch chat +var color_hex: String # color of user used in twtich chat +var display_name: String # name of a user +var channel_id: String # not used +var user_id: String # numeric id of the user used in twitch + +var badges: Dictionary # badges of the user in message +var emotes: Dictionary # emotes writed by user in message + +func _to_string(): + return "color_hex: %s, display_name: %s, channel_id: %s, user_id: %s, badges: %s, emotes: %s" % [color_hex, display_name, str(channel_id), str(user_id), badges, emotes] diff --git a/addons/very-simple-twitch/models/irc_tags.gd.uid b/addons/very-simple-twitch/models/irc_tags.gd.uid new file mode 100644 index 0000000..ae411bb --- /dev/null +++ b/addons/very-simple-twitch/models/irc_tags.gd.uid @@ -0,0 +1 @@ +uid://dngsmhmc1s3ts diff --git a/addons/very-simple-twitch/models/twitch_channel.gd b/addons/very-simple-twitch/models/twitch_channel.gd new file mode 100644 index 0000000..887db4d --- /dev/null +++ b/addons/very-simple-twitch/models/twitch_channel.gd @@ -0,0 +1,5 @@ +class_name VSTChannel + +var login: String +var id: String +var token: String diff --git a/addons/very-simple-twitch/models/twitch_channel.gd.uid b/addons/very-simple-twitch/models/twitch_channel.gd.uid new file mode 100644 index 0000000..c3131be --- /dev/null +++ b/addons/very-simple-twitch/models/twitch_channel.gd.uid @@ -0,0 +1 @@ +uid://b5hhkjxmiuh35 diff --git a/addons/very-simple-twitch/network_call.gd b/addons/very-simple-twitch/network_call.gd new file mode 100644 index 0000000..07cc4c3 --- /dev/null +++ b/addons/very-simple-twitch/network_call.gd @@ -0,0 +1,198 @@ +@tool +class_name VSTNetwork_Call extends Node + +const CACHE_TIME_IN_SECONDS = 300 + +# TODO: add dynamic version here +const USER_AGENT = {"User-Agent": "VSTC/0.1.0 (Godot Engine)"} + +const CACHE_PATH = "user://very-simple-chat/cache" + +var url: String +var timeout: float +var body: String +var headers: Dictionary +var get_params: Dictionary +var on_call_success: Callable +var on_call_fail: Callable +var method: HTTPClient.Method +var use_cache: bool + + +func _init(): + headers = {} + get_params = {} + timeout = 0.0 + use_cache = true + + +func to(url_request: String) -> VSTNetwork_Call: + url = url_request + return self + + +func with(body_object) -> VSTNetwork_Call: + body = JSON.stringify(body_object) + return self + + +func in_time(timeout_request: float) -> VSTNetwork_Call: + timeout = timeout_request + return self + + +func verb(method_request: HTTPClient.Method) -> VSTNetwork_Call: + method = method_request + return self + + +func no_cache() -> VSTNetwork_Call: + use_cache = false + return self + + +func add_header(key_header: String, value_header: String) -> VSTNetwork_Call: + headers[key_header] = value_header + return self + + +func add_all_headers(headers_dic: Dictionary) -> VSTNetwork_Call: + for key in headers_dic: + headers[key] = headers_dic[key] + return self + + +func add_get_param(key_get_param:String, value_get_param) -> VSTNetwork_Call: + get_params[key_get_param] = str(value_get_param) + return self + + +func add_all_get_params(get_params_dic: Dictionary) -> VSTNetwork_Call: + for key in get_params_dic: + get_params[key] = get_params_dic[key] + return self + + +func set_on_call_success(on_call_success_request: Callable) -> VSTNetwork_Call: + on_call_success = on_call_success_request + return self + + +func set_on_call_fail(on_call_fail_request: Callable) -> VSTNetwork_Call: + on_call_fail = on_call_fail_request + return self + + +func _pile_headers(headers_to_pile: Dictionary) -> PackedStringArray: + var array:PackedStringArray = [] + for key in headers_to_pile: + array.append("%s: %s" % [key, headers_to_pile[key]]) + for key in USER_AGENT: + array.append("%s: %s" % [key, USER_AGENT[key]]) + return array + + +func _compile_url(host: String, params_to_pile: Dictionary) -> String: + var final_url:String = host.strip_edges()+"?" + for key in params_to_pile: + var value_safe = str(params_to_pile[key]).uri_encode() + var key_safe = str(key).uri_encode() + final_url += "&%s=%s" % [key_safe, value_safe] + return final_url + + +func launch_request(parent: Node): + if method == HTTPClient.Method.METHOD_GET: + var final_url = _compile_url(url, get_params) + if use_cache: + var cached_data = read_from_cache(get_key_from_url(final_url)) + if !cached_data.is_empty() && on_call_success != null: + on_call_success.call(cached_data) + return + _launch_network_request(parent) + + +func _launch_network_request(parent: Node): + var data_error = check_request_data() + if data_error != "": + var error:VSTError = VSTError.new(VSTError.VSTCodeError.PARAM_ERROR, data_error) + on_call_fail.call(error) + return + + parent.add_child(self) + await get_tree().process_frame + + var final_url = _compile_url(url, get_params) + var client = HTTPRequest.new() + client.timeout = timeout + client.request_completed.connect(func(): + on_request_completed.bind(final_url) + client.queue_free() + ) + + add_child(client) + await get_tree().process_frame + + var request_error = client.request(final_url, _pile_headers(headers), method, body) + if request_error != OK: + var error:VSTError = VSTError.new(VSTError.VSTCodeError.PARAM_ERROR, "The request can't be archieved reason: "+str(request_error)) + on_call_fail.call(error) + client.queue_free() + return + + +func check_request_data() -> String: + if timeout < 0.0: + push_warning("Timeout can't be less than 0. Setted to 0") + timeout = 0 + + if !method: + method = HTTPClient.Method.METHOD_GET + + if url == null or url.strip_edges() == "": + return "Url can't be empty" + return "" + + +func get_key_from_url(url:String) -> String: + var last_part_url:String = url.substr(url.rfind("/")) + return last_part_url.sha256_text() + + +func on_request_completed(_result: int, status: int, _headers: PackedStringArray, body: PackedByteArray, url_request: String): + if (status >= 200 and status < 400): + if method == HTTPClient.Method.METHOD_GET: update_cache(body, get_key_from_url(url_request)) + if on_call_success: on_call_success.call(body) + elif (status >= 400 and status < 500): + if on_call_fail: + var info = "%s -> %s" % [str(status), body.get_string_from_utf8()] + var error:VSTError = VSTError.new(VSTError.VSTCodeError.NETWORK_ERROR, info) + on_call_fail.call(error) + elif (status >= 500): + if on_call_fail: + var info = "%s -> %s" % [str(status), body.get_string_from_utf8()] + var error:VSTError = VSTError.new(VSTError.VSTCodeError.SERVER_ERROR, info) + on_call_fail.call(error) + call_deferred("queue_free") + +func read_from_cache(key:String) -> PackedByteArray: + var filename: String = CACHE_PATH.path_join(key) + if FileAccess.file_exists(filename): # is a hit on cache? + if FileAccess.get_modified_time(filename)+CACHE_TIME_IN_SECONDS > Time.get_unix_time_from_system(): # is expired? + return FileAccess.get_file_as_bytes(filename) + return [] + + +func update_cache(content:PackedByteArray, key:String): + var filename: String = CACHE_PATH.path_join(key) + DirAccess.make_dir_recursive_absolute(filename.get_base_dir()) + var file = FileAccess.open(filename, FileAccess.WRITE) + file.store_buffer(content) + file.close() + + +func clear_cache(): + DirAccess.make_dir_recursive_absolute(CACHE_PATH) + var files:PackedStringArray = DirAccess.get_files_at(CACHE_PATH) + for file in files: + DirAccess.remove_absolute(CACHE_PATH.path_join(file)) diff --git a/addons/very-simple-twitch/network_call.gd.uid b/addons/very-simple-twitch/network_call.gd.uid new file mode 100644 index 0000000..91c722a --- /dev/null +++ b/addons/very-simple-twitch/network_call.gd.uid @@ -0,0 +1 @@ +uid://eq8m4h87n1l5 diff --git a/addons/very-simple-twitch/parse_helper.gd b/addons/very-simple-twitch/parse_helper.gd new file mode 100644 index 0000000..0854702 --- /dev/null +++ b/addons/very-simple-twitch/parse_helper.gd @@ -0,0 +1,74 @@ +class_name VSTParseHelper + +# Parse login name from payload substring of twitch irc chat +static func parse_login(input_string:String) -> String: + return get_substring(input_string, ":", "!") + + +# Parse channel name from payload substring of twitch irc chat +static func parse_channel(input_string:String) -> String: + return input_string.trim_prefix("#") + + +# Parse message from payload substring of twitch irc chat +static func parse_message(input_string:String) -> String: + return input_string.trim_prefix(":").strip_edges() + + +static func parse_tags(input_string:String) -> VSTIRCTags: + var irc_tags = VSTIRCTags.new() + var tags:PackedStringArray = input_string.split(";") + + for i in len(tags): + var splitted_tag:PackedStringArray = tags[i].split("=") + + if splitted_tag.size() <= 1: continue + + match(splitted_tag[0].strip_edges()): + "badges": + irc_tags.badges = parse_badges(splitted_tag[1].split(",")) + "color": + irc_tags.color_hex = splitted_tag[1] + "display-name": + irc_tags.display_name = splitted_tag[1] + "emotes": + irc_tags.emotes = parse_emotes(splitted_tag[1].split("/")) + "room-id": + irc_tags.user_id = splitted_tag[1] + + return irc_tags + + +# Parse badges from payload substring of twitch irc chat. Returns a dictionary with the badge itself +# and the position of the badge +static func parse_badges(input:PackedStringArray) -> Dictionary: + var badges: Dictionary = {} + if input.is_empty() || input[0].is_empty(): return badges + + for i in len(input): + var substrings = input[i].split("/") + if len(substrings) > 1: + badges[substrings[0]] = substrings[1] + return badges + + +# Parse emotes from payload substring of twitch irc chat. Returns a dictionary with the emote +# itself and the position in the user message in order to replace the text with the image emote +static func parse_emotes(input:PackedStringArray) -> Dictionary: + var emotes: Dictionary = {} + if input.is_empty() || input[0].is_empty(): return emotes + for emote in input: + var substring: PackedStringArray = emote.split(":") + if len(substring) > 1: + emotes[substring[0]] = substring[1] + return emotes + + + +static func get_substring(input_string:String, starting_char:String, ending_char:String) -> String: + var first_index = input_string.find(starting_char) + var last_index = input_string.find(ending_char) + + if first_index == -1 or last_index == -1 or last_index < first_index: + return input_string + return input_string.substr(first_index + 1, last_index - first_index - 1) diff --git a/addons/very-simple-twitch/parse_helper.gd.uid b/addons/very-simple-twitch/parse_helper.gd.uid new file mode 100644 index 0000000..5bf59dc --- /dev/null +++ b/addons/very-simple-twitch/parse_helper.gd.uid @@ -0,0 +1 @@ +uid://ccyfmynot5j4y diff --git a/addons/very-simple-twitch/plugin.cfg b/addons/very-simple-twitch/plugin.cfg new file mode 100644 index 0000000..dd7078c --- /dev/null +++ b/addons/very-simple-twitch/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Very Simple Twitch" +description="Godot websocket implementation for Twitch Chat using OICD Authentication flow" +author="RothioTome & collaborators" +version="0.1.0" +script="vst.gd" diff --git a/addons/very-simple-twitch/public/index.html b/addons/very-simple-twitch/public/index.html new file mode 100644 index 0000000..d86e6c5 --- /dev/null +++ b/addons/very-simple-twitch/public/index.html @@ -0,0 +1,26 @@ + + + + + + + + + + + +

Login...

+ + + + + \ No newline at end of file diff --git a/addons/very-simple-twitch/twitch_api.gd b/addons/very-simple-twitch/twitch_api.gd new file mode 100644 index 0000000..696607b --- /dev/null +++ b/addons/very-simple-twitch/twitch_api.gd @@ -0,0 +1,164 @@ +class_name VSTAPI + +extends Node + +signal token_received(TwitchChannel) + +const RESPONSE_TYPE = 'token' + +const TWITCH_VALIDATE_URL = "https://id.twitch.tv/oauth2/validate" +const TWITCH_BAN_URL = "https://api.twitch.tv/helix/moderation/bans" +const TWITCH_OAUTH_URL = "https://id.twitch.tv/oauth2/authorize" +const TWITCH_VIP_URL = "https://api.twitch.tv/helix/channels/vips" +const TWITCH_SETTINGS_URL = "https://api.twitch.tv/helix/chat/settings" +const TWITCH_CHATTERS_URL = "https://api.twitch.tv/helix/chat/chatters" + + +var auth_server: VSTAuthServer + +var _scopes: PackedStringArray +var _client_id: String +var _user: VSTChannel + +func initiate_twitch_auth(): + _scopes = VSTSettings.get_setting(VSTSettings.settings.scopes) + _client_id = VSTSettings.get_setting(VSTSettings.settings.client_id) + var redirect_host = VSTSettings.get_setting(VSTSettings.settings.redirect_host) + var redirect_port = VSTSettings.get_setting(VSTSettings.settings.redirect_port) + var uuid = VSTSettings.get_setting(VSTSettings.settings.uuid) + + if auth_server: + disconnect_api() + + auth_server = VSTAuthServer.new() + add_child(auth_server) + auth_server.OnTokenReceived.connect(_on_auth_server_on_token_received) + auth_server.start_server(redirect_port) + + var redirect_uri = redirect_host + str(redirect_port) + "/" + uuid + var scopes_string = "+".join(_scopes) + var url = "client_id=" + _client_id + url += "&redirect_uri=" +redirect_uri + url += "&response_type=" + RESPONSE_TYPE + url += "&scope=" + scopes_string + + OS.shell_open(TWITCH_OAUTH_URL + "?" + url) + +func _on_auth_server_on_token_received(token) -> void: + var validated_user = await validate_token_and_get_user_id(token) + if !(validated_user): + print('Invalid token') + _user = null + return + _user = validated_user + token_received.emit(_user) + +func request_fail(status:int, error: VSTError, on_fail: Callable): + if status == 401 or status == 403: + #Unauthorized? No mi ciela + initiate_twitch_auth() + # TODO: should chain the request? + else: + push_warning(error) + on_fail.call() + +func validate_token_and_get_user_id(token: String): + var client = HTTPRequest.new() + add_child(client) + client.request(TWITCH_VALIDATE_URL, [ + 'Authorization: OAuth ' + token + ]) + var result = await client.request_completed + var status = result[1] + if status != 200: + return null + var data = (result[3] as PackedByteArray).get_string_from_utf8() + var data_parsed = JSON.parse_string(data) + var user = VSTChannel.new() + user.id = data_parsed['user_id'] + user.login = data_parsed['login'] + user.token = token + client.queue_free() + return user + +func timeout_user(user_to_ban_id: String, duration: int = 1, reason: String = '', + on_success: Callable = Callable(), on_fail: Callable = Callable()) -> void: + if !_user: + return + + var timeout_duration = max(duration, 1) + var body = { + data = { + user_id = user_to_ban_id, + duration = timeout_duration, + reason = reason + }, + } + + var vst = VSTNetwork_Call.new() + vst.to(TWITCH_BAN_URL) + vst.add_all_get_params({ + 'broadcaster_id': _user.id, + 'moderator_id': _user.id + }).\ + vst.with(body) + vst.verb(HTTPClient.METHOD_POST) + vst.add_all_headers({ + 'Client-Id: ' : _client_id, + 'Authorization': 'Bearer ' + _user.token, + 'Content-Type': 'application/json' + }) + vst.set_on_call_success(on_success) + vst.set_on_call_fail(request_fail.bind(on_fail)) + vst.launch_request(self) + + +func add_vip(user_to_vip_id: String, on_success: Callable = Callable(), + on_fail: Callable = Callable()): + if !_user: + return + + var vst = VSTNetwork_Call.new() + vst.to(TWITCH_VIP_URL) + vst.add_all_get_params({ + 'broadcaster_id': _user.id, + 'user_id': user_to_vip_id + }) + vst.verb(HTTPClient.METHOD_POST) + vst.add_all_headers({ + 'Client-Id: ' : _client_id, + 'Authorization': 'Bearer ' + _user.token, + 'Content-Type': 'application/json' + }) + vst.set_on_call_success(on_success) + vst.set_on_call_fail(request_fail.bind(on_fail)) + + vst.launch_request(self) + +func remove_vip(user_to_remove_vip_id: String, on_success: Callable = Callable(), + on_fail: Callable = Callable()) -> void: + if !_user: + return + + var vst = VSTNetwork_Call.new() + vst.to(TWITCH_VIP_URL) + vst.add_all_get_params({ + 'broadcaster_id': _user.id, + 'user_id': user_to_remove_vip_id + }) + vst.verb(HTTPClient.METHOD_DELETE) + vst.add_all_headers({ + 'Client-Id: ' : _client_id, + 'Authorization': 'Bearer ' + _user.token, + 'Content-Type': 'application/json' + }) + vst.set_on_call_success(on_success) + vst.set_on_call_fail(request_fail.bind(on_fail)) + + vst.launch_request(self) + + +func disconnect_api(): + if auth_server: + auth_server.stop_server() + remove_child(auth_server) diff --git a/addons/very-simple-twitch/twitch_api.gd.uid b/addons/very-simple-twitch/twitch_api.gd.uid new file mode 100644 index 0000000..68c167c --- /dev/null +++ b/addons/very-simple-twitch/twitch_api.gd.uid @@ -0,0 +1 @@ +uid://crv2n3rjn1tuf diff --git a/addons/very-simple-twitch/twitch_chat.gd b/addons/very-simple-twitch/twitch_chat.gd new file mode 100644 index 0000000..9f2acb1 --- /dev/null +++ b/addons/very-simple-twitch/twitch_chat.gd @@ -0,0 +1,285 @@ +@tool +class_name VSTChat extends Node + +# TODO: rename to past simple? +signal Connected(_channel) +signal OnMessage(chatter: VSTChatter) + +var _channel: VSTChannel + +var _chatClient: WebSocketPeer +var _hasConnected:= false + +enum RequestType { + EMOTE, + BADGE, + BADGE_MAPPING +} + +var caches := { + RequestType.EMOTE: {}, + RequestType.BADGE: {}, + RequestType.BADGE_MAPPING: {} +} + +var _client_id: String +var _twitch_chat_url: String +var _twitch_chat_port: int + +var _use_cache: bool +var _cache_path: String + +var _use_anon_connection:= false + +var _chat_queue : Array[String] = [] +var _last_msg : int = Time.get_ticks_msec() +var _chat_timeout_ms: int + +const USER_AGENT : String = "User-Agent: VSTC/0.1.0 (Godot Engine)" + +func _process(_delta: float): + if !_chatClient: + return + + _chatClient.poll() + var state = _chatClient.get_ready_state() + match state: + WebSocketPeer.STATE_OPEN: + if (!_hasConnected): + onChatConnected() + while _chatClient.get_available_packet_count(): + onReceivedData(_chatClient.get_packet()) + if !_chat_queue.is_empty() and _last_msg + (_last_msg + _chat_timeout_ms) <= Time.get_ticks_msec(): + _chatClient.send_text(_chat_queue.pop_front()) + _last_msg = Time.get_ticks_msec() + WebSocketPeer.STATE_CLOSED: + if _hasConnected: + _hasConnected = false + var code = _chatClient.get_close_code() + var reason = _chatClient.get_close_reason() + print('Disconnected from twitch chat') + print("WebSocket closed with code: %d, reason %s. Clean: %s" % [code, reason, code != -1]) + print("Reconnecting") + start_chat_client() + +func start_chat_client(): + get_settings() + if _chatClient: + _chatClient.close() + _chatClient = WebSocketPeer.new() + _chatClient.connect_to_url("%s:%d" % [_twitch_chat_url, _twitch_chat_port]) + + +func login_anon(channel_name: String): + _channel = VSTChannel.new() + _channel.login = channel_name.to_lower() + _use_anon_connection = true + start_chat_client() + + +func login(twitch_channel: VSTChannel): + _channel = twitch_channel + start_chat_client() + + +func onChatConnected(): + if !_channel: + return + _hasConnected = true + + _chatClient.send_text("CAP REQ :twitch.tv/tags twitch.tv/commands") + + if _use_anon_connection: + _chatClient.send_text('PASS ' + VSTSettings.get_setting(VSTSettings.settings.twitch_anon_pass)) + _chatClient.send_text('NICK ' + VSTSettings.get_setting(VSTSettings.settings.twitch_anon_user)) + else: + _chatClient.send_text('PASS oauth:' + _channel.token) + _chatClient.send_text('NICK ' + _channel.login.to_lower()) + pass + + _chatClient.send_text('JOIN ' + '#' + _channel.login.to_lower()) + Connected.emit() + +func send_message(message: String): + _chat_queue.append("PRIVMSG #" + _channel.login.to_lower() + " :" + message + "\r\n") + +func onReceivedData(payload: PackedByteArray): + var message = payload.get_string_from_utf8() + var splittled_messages = message.split("\n") + for n in splittled_messages: + handle_message(n) + +#TODO: move this to parse helper? +func parse_message_from_twtich_IRC(message: String) -> PackedStringArray: + return message.split(" ", true, 4) # We might need more than 3 + +func handle_message(message: String): + if message.begins_with("PING"): + _chatClient.send_text(message.replace("PING", "PONG")) + return + + var parsed_message: PackedStringArray = parse_message_from_twtich_IRC(message) + + if parsed_message.size() < 2: return + + match parsed_message[2]: + "NOTICE": + var info : String = parsed_message[3].right(-1) + if (info == "Login authentication failed" || info == "Login unsuccessful"): + print_debug("Authentication failed.") + #login_attempt.emit(false) + elif (info == "You don't have permission to perform that action"): + print_debug("No permission. Check if access token is still valid. Aborting.") + #user_token_invalid.emit() + set_process(false) + else: + pass + #unhandled_message.emit(message, tags) + "001": + print_debug("Authentication successful.") + _chatClient.send_text('ROOMSTATE '+ '#' + _channel.login.to_lower()) + #login_attempt.emit(true) + "PRIVMSG": + handle_privmsg(parsed_message) + #handle_command(sender_data, msg[3].split(" ", true, 1)) + #chat_message.emit(sender_data, msg[3].right(-1)) + "ROOMSTATE": + if _use_anon_connection: + var parsed_tags:VSTIRCTags = VSTParseHelper.parse_tags(parsed_message[0]) + _channel.id = parsed_tags.user_id + +func parse_message_to_chatter(message: PackedStringArray) -> VSTChatter: + var chatter = VSTChatter.new() + chatter.login = VSTParseHelper.parse_login(message[1]) + chatter.channel = VSTParseHelper.parse_channel(message[3]) + chatter.message = VSTParseHelper.parse_message(message[4]) + chatter.tags = VSTParseHelper.parse_tags(message[0]) + chatter.date_time_dict = Time.get_datetime_dict_from_system() + + if chatter.tags.color_hex.is_empty(): + chatter.tags.color_hex = VSTUtils.get_random_name_color(chatter.login) + return chatter + + +func handle_privmsg(msg: PackedStringArray): + var chatter = parse_message_to_chatter(msg) + OnMessage.emit(chatter) + + +func get_emote(emote_id: String, scale: String = "1.0") -> Texture2D: + var texture: Texture2D + var cachename: String = emote_id + "_" + scale + var filename: String = _cache_path + "/" + RequestType.keys()[RequestType.EMOTE] + "/" + cachename + ".png" + + if !caches[RequestType.EMOTE].has(cachename): + if _use_cache && FileAccess.file_exists(filename): + var img: Image = Image.new() + img.load_png_from_buffer(FileAccess.get_file_as_bytes(filename)) + texture = ImageTexture.create_from_image(img) + texture.take_over_path(filename) + else: + var request: HTTPRequest = HTTPRequest.new() + add_child(request) + request.request("https://static-cdn.jtvnw.net/emoticons/v1/" + emote_id + "/" + scale, [USER_AGENT,"Accept: */*"]) + var data = await(request.request_completed) + var img: Image = Image.new() + img.load_png_from_buffer(data[3]) + texture = ImageTexture.create_from_image(img) + if _use_cache: + DirAccess.make_dir_recursive_absolute(filename.get_base_dir()) + texture.get_image().save_png(filename) + request.queue_free() + texture.take_over_path(filename) + caches[RequestType.EMOTE][cachename] = texture + return caches[RequestType.EMOTE][cachename] + +func get_badge(badge_name: String, badge_level: String, channel_id: String = "_global", scale: String = "1") -> Texture2D: + if _use_anon_connection: return + + var texture: Texture2D + var cachename = badge_name + "_" + badge_level + "_" + scale + var filename: String = _cache_path + "/" + RequestType.keys()[RequestType.BADGE] + "/" + channel_id + "/" + cachename + ".png" + if !caches[RequestType.BADGE].has(channel_id): + caches[RequestType.BADGE][channel_id] = {} + if !caches[RequestType.BADGE][channel_id].has(cachename): + if _use_cache && FileAccess.file_exists(filename): + var img : Image = Image.new() + img.load_png_from_buffer(FileAccess.get_file_as_bytes(filename)) + texture = ImageTexture.create_from_image(img) + texture.take_over_path(filename) + else: + var map: Dictionary = caches[RequestType.BADGE_MAPPING].get(channel_id, await(get_badge_mapping(channel_id))) + if !map.is_empty(): + if map.has(badge_name): + var request: HTTPRequest = HTTPRequest.new() + add_child(request) + request.request(map[badge_name]["versions"][badge_level]["image_url_" + scale + "x"], [USER_AGENT,"Accept: */*"]) + var data = await(request.request_completed) + var img: Image = Image.new() + img.load_png_from_buffer(data[3]) + texture = ImageTexture.create_from_image(img) + texture.take_over_path(filename) + request.queue_free() + elif channel_id != "_global": + return await(get_badge(badge_name, badge_level, "_global", scale)) + elif channel_id != "_global": + return await(get_badge(badge_name, badge_level, "_global", scale)) + if _use_cache: + DirAccess.make_dir_recursive_absolute(filename.get_base_dir()) + texture.get_image().save_png(filename) + texture.take_over_path(filename) + caches[RequestType.BADGE][channel_id][cachename] = texture + return caches[RequestType.BADGE][channel_id][cachename] + +func get_badge_mapping(channel_id: String = "_global") -> Dictionary: + + if _use_anon_connection: return {} + + if caches[RequestType.BADGE_MAPPING].has(channel_id): + return caches[RequestType.BADGE_MAPPING][channel_id] + + var filename: String = _cache_path + "/" + RequestType.keys()[RequestType.BADGE_MAPPING] + "/" + channel_id + ".json" + if _use_cache && FileAccess.file_exists(filename): + var cache = JSON.parse_string(FileAccess.get_file_as_string(filename)) + if "badge_sets" in cache: + return cache["badge_sets"] + + var request : HTTPRequest = HTTPRequest.new() + add_child(request) + + request.request("https://api.twitch.tv/helix/chat/badges" + ("/global" if channel_id == "_global" else "?broadcaster_id=" + _channel.id), [USER_AGENT, "Authorization: Bearer " + _channel.token, "Client-Id:" + _client_id, "Content-Type: application/json"], HTTPClient.METHOD_GET) + + var reply : Array = await(request.request_completed) + var response : Dictionary = JSON.parse_string(reply[3].get_string_from_utf8()) + var mappings : Dictionary = {} + for entry in response["data"]: + if (!mappings.has(entry["set_id"])): + mappings[entry["set_id"]] = {"versions": {}} + for version in entry["versions"]: + mappings[entry["set_id"]]["versions"][version["id"]] = version + request.queue_free() + if (reply[1] == HTTPClient.RESPONSE_OK): + caches[RequestType.BADGE_MAPPING][channel_id] = mappings + if _use_cache: + DirAccess.make_dir_recursive_absolute(filename.get_base_dir()) + var file : FileAccess = FileAccess.open(filename, FileAccess.WRITE) + file.store_string(JSON.stringify(mappings)) + else: + print("Could not retrieve badge mapping for channel_id " + channel_id + ".") + return {} + return caches[RequestType.BADGE_MAPPING][channel_id] + +func get_settings(): + _client_id = VSTSettings.get_setting(VSTSettings.settings.client_id) + _twitch_chat_url = VSTSettings.get_setting(VSTSettings.settings.twitch_chat_url) + _twitch_chat_port = VSTSettings.get_setting(VSTSettings.settings.twitch_port) + _use_cache = VSTSettings.get_setting(VSTSettings.settings.disk_cache) + _cache_path = VSTSettings.get_setting(VSTSettings.settings.disk_cache_path) + _chat_timeout_ms = VSTSettings.get_setting(VSTSettings.settings.twitch_timeout_ms) + +# stops chat socket from tts server +func disconnect_api(): + if _chatClient: + _chatClient.close() + + _hasConnected = false diff --git a/addons/very-simple-twitch/twitch_chat.gd.uid b/addons/very-simple-twitch/twitch_chat.gd.uid new file mode 100644 index 0000000..3d05ff7 --- /dev/null +++ b/addons/very-simple-twitch/twitch_chat.gd.uid @@ -0,0 +1 @@ +uid://ckwhjsorarfn0 diff --git a/addons/very-simple-twitch/twitch_chat_settings.gd b/addons/very-simple-twitch/twitch_chat_settings.gd new file mode 100644 index 0000000..4a6c40a --- /dev/null +++ b/addons/very-simple-twitch/twitch_chat_settings.gd @@ -0,0 +1,124 @@ +class_name VSTSettings + +const settings: Dictionary = { + "client_id": { + "path": "config/client_id", + "type": TYPE_STRING, + "hint_string": "The client id from the twitch developer dashboard", + "is_basic": true, + "initial_value": "", + }, + "redirect_host": { + "path": "advanced_config/redirect_host", + "type": TYPE_STRING, + "hint_string": "The host where the OAuth Callback will be received", + "is_basic": false, + "initial_value": "http://localhost:", + }, + "uuid": { + "path": "advanced_config/uuid", + "type": TYPE_STRING, + "hint_string": "The useless UID to hide the token from the web browser", + "is_basic": false, + "initial_value": "53125396-3e32-4fad-8f7e-36475724168b-a8fe83ab-3373-4a6a-8967-2532eafe407f-41483db3-f011-4a23-80da-9a340672692a-e755c6d4-c546-43ce-b722-b5a799561b4e-5ba1697d-79b2-4d5d-96c3-f0d91f13f583-f08f18f9-bd56-4a0f-a597-96f90108cd85-14449d50-6cc9-450f-8119-ff4c525e31db-e41a6912-92a0-48b6-b6d3-845c21bea7eb-7dfd7948-2976-42cf-9cca-b23ae5854813-107224eb-81ea-46dd-9bf5-9ebbfcfc45dc/", + }, + "redirect_port": { + "path": "config/redirect_port", + "type": TYPE_INT, + "hint_string": "The port where the oauth callback will be redirect", + "is_basic": true, + "initial_value": 8090, + }, + + "disk_cache_path": { + "path": "advanced_config/disk_cache_path", + "type": TYPE_STRING, + "hint": PROPERTY_HINT_GLOBAL_DIR, + "hint_string": "The absolute filepath where the images cache will be stored", + "is_basic": false, + "initial_value": "user://very-simple-chat/cache", + }, + "disk_cache": { + "path": "config/disk_cache", + "type": TYPE_BOOL, + "hint_string": "Use cache to store the images from badges and emotes", + "is_basic": true, + "initial_value": true, + }, + "scopes": { + "path": "config/scopes", + "type": TYPE_PACKED_STRING_ARRAY, + "hint_string": "Scopes that will be asked when the token is retrieved", + "is_basic": true, + "initial_value": ["moderator:manage:banned_users","chat:read", "channel:manage:vips"], + }, + "twitch_chat_url": { + "path": "advanced_config/twitch_chat_url", + "type": TYPE_STRING, + "hint_string": "Twitch chat url", + "is_basic": false, + "initial_value": "wss://irc-ws.chat.twitch.tv", + }, + "twitch_port": { + "path": "advanced_config/twitch_port", + "type": TYPE_INT, + "hint_string": "The port the websocket will connect to", + "is_basic": false, + "initial_value": 443, + }, + "twitch_anon_user": { + "path": "advanced_config/twitch_anon_user", + "type": TYPE_STRING, + "hint_string": "Anon connection username", + "is_basic": false, + "initial_value": "justinfan5555", + }, + "twitch_anon_pass": { + "path": "advanced_config/twitch_anon_pass", + "type": TYPE_STRING, + "hint_string": "Anon connection password", + "is_basic": false, + "initial_value": "kappa", + }, + "twitch_timeout_ms":{ + "path": "advanced_config/twitch_timeout_ms", + "type:": TYPE_INT, + "hint_string": "Time between messages sent by the client", + "is_basic": false, + "initial_value": 320, + } +} + +static func add_settings(): + for setting in settings: + var setting_value = settings[setting] + var path = "very_simple_twitch/"+ setting_value.get("path", "config" +setting) + var saved_value = ProjectSettings.get_setting(path) + if !saved_value: + ProjectSettings.set_setting(path, setting_value.get("initial_value")) + var property_info = { + "name": path, + "type": setting_value.get("type", typeof(setting_value.get("initial_value"))), + "hint": setting_value.get("hint"), + "hint_string": setting_value.get("hint_string", "") + } + ProjectSettings.set_as_basic(path, setting_value.get("is_basic", true)) + ProjectSettings.set_initial_value(path, setting_value.get("initial_value")) + ProjectSettings.add_property_info(property_info) + ProjectSettings.save() + + +static func remove_settings(): + for setting in settings: + var setting_value = settings[setting] + var path = "very_simple_twitch/"+ setting_value.get("path", "config") + "/" + setting + ProjectSettings.set_setting(path, null) + + +static func get_setting(setting: Dictionary): + var path = "very_simple_twitch/"+ setting.get("path") + var response = ProjectSettings.get_setting(path) + if !response: + return setting.get("initial_value") + else: + return response diff --git a/addons/very-simple-twitch/twitch_chat_settings.gd.uid b/addons/very-simple-twitch/twitch_chat_settings.gd.uid new file mode 100644 index 0000000..91b47cf --- /dev/null +++ b/addons/very-simple-twitch/twitch_chat_settings.gd.uid @@ -0,0 +1 @@ +uid://7erhidjoher1 diff --git a/addons/very-simple-twitch/twitch_node.gd b/addons/very-simple-twitch/twitch_node.gd new file mode 100644 index 0000000..2b8b9e2 --- /dev/null +++ b/addons/very-simple-twitch/twitch_node.gd @@ -0,0 +1,71 @@ +extends Node + +signal token_received(twitch_channel: VSTChannel) +signal chat_message_received(channel: VSTChatter) +signal chat_connected(channel_name: String) + +var _twitch_api: VSTAPI +var _twitch_chat: VSTChat + +func login_chat_anon(channel_name: String): + _start_chat_client() + _twitch_chat.login_anon(channel_name) + chat_connected.emit(await _twitch_chat.Connected) + + +func login_chat(channel_info: VSTChannel): + _start_chat_client() + _twitch_chat.login(channel_info) + chat_connected.emit(await _twitch_chat.Connected) + + +func get_token_and_login_chat(): + var channel_info = await get_token() + await login_chat(channel_info) + + +func _start_chat_client(): + if !_twitch_chat: + _twitch_chat = VSTChat.new() + add_child(_twitch_chat) + _twitch_chat.OnMessage.connect(on_chat_message_received) + + +func get_token() -> VSTChannel: + if !_twitch_api: + _twitch_api = VSTAPI.new() + add_child(_twitch_api) + _twitch_api.initiate_twitch_auth() + var channel_info = await _twitch_api.token_received + token_received.emit(channel_info) + return channel_info + + +func get_badge(badge_name: String, badge_level: String, + channel_id: String = "_global", scale: String = "1"): + return await _twitch_chat.get_badge(badge_name, badge_level, channel_id, scale) + + +func get_emote(loc_id: String): + return await _twitch_chat.get_emote(loc_id) + +# clear all support nodes, disconects from chat/auth server +func end_chat_client(): + if _twitch_chat: + _twitch_chat.disconnect_api() + _twitch_chat.OnMessage.disconnect(on_chat_message_received) + remove_child(_twitch_chat) + _twitch_chat.queue_free() + _twitch_chat = null + + if _twitch_api: + _twitch_api.disconnect_api() + remove_child(_twitch_api) + _twitch_api.queue_free() + _twitch_api = null + +func send_chat_message(message: String): + _twitch_chat.send_message(message) + +func on_chat_message_received(chatter: VSTChatter): + chat_message_received.emit(chatter) diff --git a/addons/very-simple-twitch/twitch_node.gd.uid b/addons/very-simple-twitch/twitch_node.gd.uid new file mode 100644 index 0000000..7e580c2 --- /dev/null +++ b/addons/very-simple-twitch/twitch_node.gd.uid @@ -0,0 +1 @@ +uid://cbrqfun2syqju diff --git a/addons/very-simple-twitch/twitch_utils.gd b/addons/very-simple-twitch/twitch_utils.gd new file mode 100644 index 0000000..57fec2c --- /dev/null +++ b/addons/very-simple-twitch/twitch_utils.gd @@ -0,0 +1,40 @@ +class_name VSTUtils + +const LUMINANCE_LOW := 0.2 +const LUMINANCE_HIGH := 0.8 + +const DEFAULT_NAME_COLORS:Array[String] = [ + "#FF0000", + "#00FF00", + "#0000FF", + "#B22222", + "#FF7F50", + "#9ACD32", + "#FF4500", + "#2E8B57", + "#DAA520", + "#D2691E", + "#5F9EA0", + "#1E90FF", + "#FF69B4", + "#8A2BE2", + "#00FF7F", + ] + +# Returns a random non-unique color from a name and a seed +static func get_random_name_color(login: String, session_seed:int = 0): + var position: int = session_seed + hash(login) + return DEFAULT_NAME_COLORS[position % DEFAULT_NAME_COLORS.size()] + +# Normalize color in order to be not bright or darker +static func normalize_color(color: Color) -> Color: + var luminance = color.get_luminance() + if luminance > LUMINANCE_HIGH: + return color.darkened(0.2) + if luminance < LUMINANCE_LOW: + return color.lightened(0.2) + return color + +# Normalize color from string representation +static func normalize_hex_color(color: String) -> Color: + return normalize_color(Color(color)) diff --git a/addons/very-simple-twitch/twitch_utils.gd.uid b/addons/very-simple-twitch/twitch_utils.gd.uid new file mode 100644 index 0000000..0f7b3fc --- /dev/null +++ b/addons/very-simple-twitch/twitch_utils.gd.uid @@ -0,0 +1 @@ +uid://pqa2k4i3du34 diff --git a/addons/very-simple-twitch/vst.gd b/addons/very-simple-twitch/vst.gd new file mode 100644 index 0000000..913c067 --- /dev/null +++ b/addons/very-simple-twitch/vst.gd @@ -0,0 +1,36 @@ +@tool +extends EditorPlugin + +var dock +var chat_dock + +func _enter_tree() -> void: + add_custom_type("VerySimpleTwitchChat", "Node", preload("twitch_chat.gd"), preload("icon.png")) + add_custom_type("VerySimpleTwitchAPI", "Node", preload("twitch_api.gd"), preload("icon.png")) + + add_autoload_singleton("VerySimpleTwitch", "twitch_node.gd") + + VSTSettings.add_settings() + + #Bottom setup dock + dock = preload("res://addons/very-simple-twitch/dock/vst-dock.tscn").instantiate() + add_control_to_bottom_panel(dock, "Very Simple Twitch") + + #Chat dock + chat_dock = preload("res://addons/very-simple-twitch/chat/vst_chat_dock.tscn").instantiate() + add_control_to_dock(EditorPlugin.DOCK_SLOT_RIGHT_UL, chat_dock) + + +func _exit_tree() -> void: + remove_custom_type("VerySimpleTwitchChat") + remove_custom_type("VerySimpleTwitchAPI") + + VSTSettings.remove_settings() + + remove_autoload_singleton("VerySimpleTwitch") + + remove_control_from_bottom_panel(dock) + dock.free() + + remove_control_from_docks(chat_dock) + chat_dock.free() diff --git a/addons/very-simple-twitch/vst.gd.uid b/addons/very-simple-twitch/vst.gd.uid new file mode 100644 index 0000000..213949e --- /dev/null +++ b/addons/very-simple-twitch/vst.gd.uid @@ -0,0 +1 @@ +uid://cd4wocpij063j diff --git a/addons/very-simple-twitch/vst_error.gd b/addons/very-simple-twitch/vst_error.gd new file mode 100644 index 0000000..98deafc --- /dev/null +++ b/addons/very-simple-twitch/vst_error.gd @@ -0,0 +1,32 @@ +class_name VSTError + +enum VSTCodeError {PARAM_ERROR, TIMEOUT_ERROR, NETWORK_ERROR, SERVER_ERROR} + +var code: VSTCodeError +var description: String +var info: String + +func _init(error_code: VSTCodeError, error_info: String = ""): + code = error_code + info = error_info + description = _get_description_from_code(error_code) + + +func _get_description_from_code(error_code: VSTCodeError) -> String: + var result = "" + match (error_code): + VSTCodeError.PARAM_ERROR: + result = "The request aren't fullfilled properly. Check the data" + VSTCodeError.NETWORK_ERROR: + result = "The request result in an error" + VSTCodeError.SERVER_ERROR: + result = "There is an error in server" + VSTCodeError.TIMEOUT_ERROR: + result = "The server doesn't response" + _: + result = "Unknown error" + return result + + +func _to_string(): + return "%s %s %s" % [str(code), description, info] diff --git a/addons/very-simple-twitch/vst_error.gd.uid b/addons/very-simple-twitch/vst_error.gd.uid new file mode 100644 index 0000000..b67eba9 --- /dev/null +++ b/addons/very-simple-twitch/vst_error.gd.uid @@ -0,0 +1 @@ +uid://bcle5hp6f77l