Compare commits

...

9 commits

Author SHA1 Message Date
33b5e826bd Updated Project Settings
Added custom run command /usr/bin/obs-gamecapture.
2026-03-10 10:32:31 -05:00
4d6de8d46f Created ImageLoader class.
Created ImageLoader class to load images.  Since Twitch doesn't always
send proper information about the file, we detect image format by the
file byte header, to ensure we are loading the correct image format.
2026-03-10 10:32:06 -05:00
eb64045e41 Updated OverlayPlugin
Added send_message() function, more functionality to be implemented.
2026-03-10 10:31:16 -05:00
7b1237b702 Created Larger Logo
This is the same as twitch.svg, but since we can't "update" svg to have
multiple sizes, manually setup size of the same SVG as a new file of the
same content.
2026-03-10 10:30:50 -05:00
f782cc32d4 Updated Custom Runner
Added check to see if the setting exists, before setting it to prevent
over-writting.
Need to figure out if output is working or not, since not able to
clear() the RichTextLabel.
Changed launch parameters to use Remote Debug.  Need to ensure that
Debug > Keep Debug Server Open in order to use.
2026-03-10 10:29:46 -05:00
eb16b80134 Updated UserGames
Renamed search and add functions for Steam to _handle_steam_*, Added
ItchIO handlers
Updated Steam Add to check and see if we have already fetched the App
information, and if so, use it, otherwise try to search.  *Note* Need to
clear after adding, so we don't accidently add to the wrong user, and
need to validate if the game has already been added or not.
Added Logic to for ItchIO.
2026-03-10 10:27:40 -05:00
cc01a207fc Updated InternalUserLive
Added Offline details to Live panel.
When user has an Offline Image, we load the image to display in the
Stream Preview, otherwise we do a Generic Twitch Logo, with text saying
the Stream is Offline.
2026-03-10 10:25:17 -05:00
23fdd1e972 Updated GameEntry
Switched to using ImageLoader.load_image()
Fixed bug in developer, to use itchio_data.authors
2026-03-10 10:16:33 -05:00
446e4a291c Updated Alerts
Updated pathing for Alerts.
2026-03-10 10:15:52 -05:00
16 changed files with 270 additions and 55 deletions

View file

@ -190,7 +190,7 @@ offset_bottom = 270.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
script = ExtResource("1_7rajh") script = ExtResource("1_7rajh")
path = "res://UI/assets/video/Backgrounds/Lightning-Synthwave.webm" path = "res://assets/video/Backgrounds/Lightning-Synthwave.webm"
metadata/_custom_type_script = "uid://ivx7m2bfysip" metadata/_custom_type_script = "uid://ivx7m2bfysip"
[node name="Icon" type="Control" parent="." unique_id=823113899] [node name="Icon" type="Control" parent="." unique_id=823113899]
@ -209,7 +209,7 @@ offset_bottom = -43.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
script = ExtResource("1_7rajh") script = ExtResource("1_7rajh")
path = "res://UI/assets/video/Backgrounds/Bits-Synthwave.webm" path = "res://assets/video/Backgrounds/Bits-Synthwave.webm"
enable_audio = false enable_audio = false
metadata/_custom_type_script = "uid://ivx7m2bfysip" metadata/_custom_type_script = "uid://ivx7m2bfysip"
@ -228,7 +228,7 @@ offset_right = 183.0
offset_bottom = -25.0 offset_bottom = -25.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
text = "x40 Bits" text = "x0 bits"
label_settings = SubResource("LabelSettings_t8pat") label_settings = SubResource("LabelSettings_t8pat")
horizontal_alignment = 1 horizontal_alignment = 1
@ -267,7 +267,6 @@ offset_right = 500.0
offset_bottom = 255.0 offset_bottom = 255.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
text = "Born to late to explore Earth, born to early to explore the universe"
label_settings = SubResource("LabelSettings_vhkt3") label_settings = SubResource("LabelSettings_vhkt3")
horizontal_alignment = 1 horizontal_alignment = 1
autowrap_mode = 2 autowrap_mode = 2

View file

@ -161,7 +161,7 @@ offset_bottom = 270.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
script = ExtResource("1_86a2m") script = ExtResource("1_86a2m")
path = "res://UI/assets/video/Backgrounds/Stripes-Synthwave.webm" path = "res://assets/video/Backgrounds/Stripes-Synthwave.webm"
metadata/_custom_type_script = "uid://ivx7m2bfysip" metadata/_custom_type_script = "uid://ivx7m2bfysip"
[node name="Icon" type="Control" parent="." unique_id=823113899] [node name="Icon" type="Control" parent="." unique_id=823113899]
@ -180,7 +180,7 @@ offset_bottom = -43.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
script = ExtResource("1_86a2m") script = ExtResource("1_86a2m")
path = "res://UI/assets/video/Icons/Joystick-Synthwave.webm" path = "res://assets/video/Icons/Joystick-Synthwave.webm"
enable_audio = false enable_audio = false
metadata/_custom_type_script = "uid://ivx7m2bfysip" metadata/_custom_type_script = "uid://ivx7m2bfysip"

View file

@ -163,7 +163,7 @@ offset_bottom = 270.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
script = ExtResource("1_yqbii") script = ExtResource("1_yqbii")
path = "res://UI/assets/video/Backgrounds/Grid-Synthwave.webm" path = "res://assets/video/Backgrounds/Grid-Synthwave.webm"
metadata/_custom_type_script = "uid://ivx7m2bfysip" metadata/_custom_type_script = "uid://ivx7m2bfysip"
[node name="Icon" type="Control" parent="." unique_id=823113899] [node name="Icon" type="Control" parent="." unique_id=823113899]
@ -182,7 +182,7 @@ offset_bottom = -43.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
script = ExtResource("1_yqbii") script = ExtResource("1_yqbii")
path = "res://UI/assets/video/Icons/Computer-Synthwave.webm" path = "res://assets/video/Icons/Computer-Synthwave.webm"
enable_audio = false enable_audio = false
metadata/_custom_type_script = "uid://ivx7m2bfysip" metadata/_custom_type_script = "uid://ivx7m2bfysip"
@ -201,7 +201,7 @@ offset_right = 183.0
offset_bottom = -18.0 offset_bottom = -18.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
text = "Raid x10" text = "Raid x0"
label_settings = SubResource("LabelSettings_t8pat") label_settings = SubResource("LabelSettings_t8pat")
horizontal_alignment = 1 horizontal_alignment = 1

View file

@ -190,7 +190,7 @@ offset_bottom = 270.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
script = ExtResource("1_b3tp1") script = ExtResource("1_b3tp1")
path = "res://UI/assets/video/Backgrounds/Triangle-Synthwave.webm" path = "res://assets/video/Backgrounds/Triangle-Synthwave.webm"
metadata/_custom_type_script = "uid://ivx7m2bfysip" metadata/_custom_type_script = "uid://ivx7m2bfysip"
[node name="Icon" type="Control" parent="." unique_id=823113899] [node name="Icon" type="Control" parent="." unique_id=823113899]
@ -209,7 +209,7 @@ offset_bottom = -43.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
script = ExtResource("1_b3tp1") script = ExtResource("1_b3tp1")
path = "res://UI/assets/video/Icons/Hoverboard-Synthwave.webm" path = "res://assets/video/Icons/Hoverboard-Synthwave.webm"
enable_audio = false enable_audio = false
metadata/_custom_type_script = "uid://ivx7m2bfysip" metadata/_custom_type_script = "uid://ivx7m2bfysip"
@ -228,7 +228,7 @@ offset_right = 183.0
offset_bottom = -25.0 offset_bottom = -25.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
text = "New Sub" text = "New Teir 1 Sub"
label_settings = SubResource("LabelSettings_t8pat") label_settings = SubResource("LabelSettings_t8pat")
horizontal_alignment = 1 horizontal_alignment = 1
@ -267,7 +267,6 @@ offset_right = 500.0
offset_bottom = 255.0 offset_bottom = 255.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
text = "Born to late to explore Earth, born to early to explore the universe"
label_settings = SubResource("LabelSettings_dx50j") label_settings = SubResource("LabelSettings_dx50j")
horizontal_alignment = 1 horizontal_alignment = 1
autowrap_mode = 2 autowrap_mode = 2

View file

@ -34,13 +34,13 @@ func populate() -> void:
%GameName.text = steam_data.name %GameName.text = steam_data.name
%GameName.tooltip_text = steam_data.name %GameName.tooltip_text = steam_data.name
var url_no_query: String = steam_data.header_image.split("?")[0] var url_no_query: String = steam_data.header_image.split("?")[0]
%Background.texture = ImageTexture.create_from_image(await Globals.twitcher.media.load_image(url_no_query)) %Background.texture = await ImageLoader.load_image(url_no_query)
Type.ITCHIO: Type.ITCHIO:
if not itchio_data: if not itchio_data:
itchio_data = await %ItchIOService.get_itch_app_data(itchio_app_url) itchio_data = await %ItchIOService.get_itch_app_data(itchio_app_url)
%GameName.text = itchio_data.title %GameName.text = itchio_data.title
var url: String = itchio_data.cover_image var url: String = itchio_data.cover_image
%Background.texture = ImageTexture.create_from_image(await Globals.twitcher.media.load_image(url)) %Background.texture = await ImageLoader.load_image(url)
func _reload_data() -> void: func _reload_data() -> void:
match type: match type:
@ -72,7 +72,7 @@ func _promote_game() -> void:
pass pass
Type.ITCHIO: Type.ITCHIO:
title = itchio_data.title title = itchio_data.title
developer = itchio_data.developer developer = itchio_data.authors.front()["name"]
description = itchio_data.description.left(200) + "..." description = itchio_data.description.left(200) + "..."
link = itchio_data.url link = itchio_data.url
msg = msg.format({ msg = msg.format({

View file

@ -1,10 +1,14 @@
extends PanelContainer extends PanelContainer
var _offline_color := Color.html("d36dff4e")
var _offline_no_thumbnail := preload("res://assets/bootstrap/twitch_large.svg")
var chatter: Chatter: var chatter: Chatter:
set(value): set(value):
chatter = value chatter = value
if not chatter: if not chatter:
live = null live = null
clear()
return return
live = Globals.live_streamers[chatter.twitch_id] if chatter.twitch_id in Globals.live_streamers.keys() else null live = Globals.live_streamers[chatter.twitch_id] if chatter.twitch_id in Globals.live_streamers.keys() else null
_populate_view() _populate_view()
@ -17,21 +21,44 @@ var _ticks: int = 0
func _ready() -> void: func _ready() -> void:
%StreamTitle.pressed.connect(_open_stream) %StreamTitle.pressed.connect(_open_stream)
%RaidCurrentUser.pressed.connect(_raid_stream) %RaidCurrentUser.pressed.connect(_raid_stream)
if not chatter: return if not chatter:
clear()
return
if not live and chatter.twitch_id in Globals.live_streamers.keys(): if not live and chatter.twitch_id in Globals.live_streamers.keys():
live = Globals.live_streamers[chatter.twitch_id] live = Globals.live_streamers[chatter.twitch_id]
_populate_view() _populate_view()
elif not live:
clear()
return
func clear() -> void:
%StreamTitle.text = "Not Live"
%StreamViewerCount.text = "0"
%StreamTime.text = "00:00:00"
%StreamThumbnail.visible = false
%OfflineThumbnail.visible = true
%NoThumbText.visible = true
if chatter:
if chatter.user.offline_image_url != "":
%OfflineThumbnail.texture = await ImageLoader.load_image(chatter.user.offline_image_url)
%OfflineThumbnail.self_modulate = Color.WHITE
%NoThumbText.visible = false
return
%OfflineThumbnail.texture = _offline_no_thumbnail
%OfflineThumbnail.self_modulate = _offline_color
func _populate_view() -> void: func _populate_view() -> void:
if not live: if not live:
set_process(false) set_process(false)
clear()
return return
set_process(true) set_process(true)
%StreamTitle.text = live.title %StreamTitle.text = live.title
%StreamViewerCount.text = str(live.viewer_count) %StreamViewerCount.text = str(live.viewer_count)
var url := live.thumbnail_url.format({"width": 640, "height": 360}) var url := live.thumbnail_url.format({"width": 640, "height": 360})
var img = await Globals.twitcher.media.load_image(url) %StreamThumbnail.texture = await ImageLoader.load_image(url)
%StreamThumbnail.texture = ImageTexture.create_from_image(img) %StreamThumbnail.visible = true
%OfflineThumbnail.visible = false
func _process(_d: float) -> void: func _process(_d: float) -> void:
if not live: if not live:

View file

@ -2,8 +2,12 @@
[ext_resource type="Script" uid="uid://cdtfvedghei5f" path="res://UI/Panels/User/internal_user_live.gd" id="1_rl2q8"] [ext_resource type="Script" uid="uid://cdtfvedghei5f" path="res://UI/Panels/User/internal_user_live.gd" id="1_rl2q8"]
[ext_resource type="Texture2D" uid="uid://b3372gsnwqsyn" path="res://assets/bootstrap/twitch.svg" id="1_sw5jj"] [ext_resource type="Texture2D" uid="uid://b3372gsnwqsyn" path="res://assets/bootstrap/twitch.svg" id="1_sw5jj"]
[ext_resource type="Texture2D" uid="uid://bvmx86tvio46h" path="res://assets/bootstrap/twitch_large.svg" id="2_lcbo3"]
[ext_resource type="Texture2D" uid="uid://bu2juj2beyws7" path="res://assets/twitch_user_profile_pic.png" id="2_rl2q8"] [ext_resource type="Texture2D" uid="uid://bu2juj2beyws7" path="res://assets/twitch_user_profile_pic.png" id="2_rl2q8"]
[sub_resource type="LabelSettings" id="LabelSettings_2ohcs"]
font_size = 72
[node name="InternalUserLive" type="PanelContainer" unique_id=17956466] [node name="InternalUserLive" type="PanelContainer" unique_id=17956466]
anchors_preset = 15 anchors_preset = 15
anchor_right = 1.0 anchor_right = 1.0
@ -26,11 +30,38 @@ size_flags_vertical = 3
[node name="StreamThumbnail" type="TextureRect" parent="VBoxContainer/HBoxContainer" unique_id=641456832] [node name="StreamThumbnail" type="TextureRect" parent="VBoxContainer/HBoxContainer" unique_id=641456832]
unique_name_in_owner = true unique_name_in_owner = true
visible = false
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
expand_mode = 1 expand_mode = 1
stretch_mode = 5 stretch_mode = 5
[node name="OfflineThumbnail" type="TextureRect" parent="VBoxContainer/HBoxContainer" unique_id=924088665]
unique_name_in_owner = true
self_modulate = Color(0.827451, 0.42745098, 1, 0.30588236)
layout_mode = 2
size_flags_horizontal = 3
texture = ExtResource("2_lcbo3")
expand_mode = 1
stretch_mode = 5
[node name="NoThumbText" type="Label" parent="VBoxContainer/HBoxContainer/OfflineThumbnail" unique_id=1187072643]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -20.0
offset_top = -11.5
offset_right = 20.0
offset_bottom = 11.5
grow_horizontal = 2
grow_vertical = 2
text = "Stream Offline"
label_settings = SubResource("LabelSettings_2ohcs")
[node name="UserChat" type="PanelContainer" parent="VBoxContainer/HBoxContainer" unique_id=1609959534] [node name="UserChat" type="PanelContainer" parent="VBoxContainer/HBoxContainer" unique_id=1609959534]
unique_name_in_owner = true unique_name_in_owner = true
visible = false visible = false

View file

@ -11,10 +11,13 @@ var chatter: Chatter:
populate_games() populate_games()
func _ready() -> void: func _ready() -> void:
%SteamSearch.pressed.connect(_handle_search) %SteamSearch.pressed.connect(_handle_steam_search)
%AddSteamGame.pressed.connect(_handle_add) %AddSteamGame.pressed.connect(_handle_steam_add)
%ItchFetch.pressed.connect(_handle_itch_search)
%ItchAdd.pressed.connect(_handle_itch_add)
func _handle_search() -> void: #region Steam Search
func _handle_steam_search() -> void:
var info: String = %SteamGameInput.text var info: String = %SteamGameInput.text
var app_id: int = -1 var app_id: int = -1
if info.begins_with("https:"): if info.begins_with("https:"):
@ -32,7 +35,11 @@ func _handle_search() -> void:
%SteamAppPanel.display_app_info(data) %SteamAppPanel.display_app_info(data)
%SteamAppPanel.show() %SteamAppPanel.show()
func _handle_add() -> void: func _handle_steam_add() -> void:
if %SteamAppPanel.data:
var app: SteamAppData = %SteamAppPanel.data
chatter.steam_games.append(app.steam_app_id)
else:
var info: String = %SteamGameInput.text var info: String = %SteamGameInput.text
var app_id: int = -1 var app_id: int = -1
if info.begins_with("https:"): if info.begins_with("https:"):
@ -50,9 +57,36 @@ func _handle_add() -> void:
var data: SteamAppData = await %SteamService.get_steam_app_data(app_id) var data: SteamAppData = await %SteamService.get_steam_app_data(app_id)
if data: if data:
chatter.steam_games.append(app_id) chatter.steam_games.append(app_id)
chatter.save() chatter.save()
clear() clear()
populate_games() populate_games()
#endregion
#region Itch Search
func _handle_itch_search() -> void:
var info: String = %ItchInput.text
if not (info.begins_with("http://") or info.begins_with("https://")): return
var data: ItchIOAppData = await %ItchIOService.get_itch_app_data(info)
if data:
%ItchAppPanel.display_app_info(data)
%ItchAppPanel.show()
func _handle_itch_add() -> void:
if %ItchAppPanel.data:
var app: ItchIOAppData = %ItchAppPanel.data
chatter.itch_games[app.title] = app.url
else:
var info: String = %ItchInput.text
if not (info.begins_with("http://") or info.begins_with("https://")): return
var data: ItchIOAppData = await %ItchIOService.get_itch_app_data(info)
if data:
chatter.itch_games[data.title] = data.url
chatter.save()
clear()
populate_games()
#endregion
func populate_games() -> void: func populate_games() -> void:
for game in chatter.steam_games: for game in chatter.steam_games:

View file

@ -9,7 +9,7 @@
[ext_resource type="Script" uid="uid://bllsv2cy6komw" path="res://lib/models/steam_app_data.gd" id="4_myc1y"] [ext_resource type="Script" uid="uid://bllsv2cy6komw" path="res://lib/models/steam_app_data.gd" id="4_myc1y"]
[ext_resource type="PackedScene" uid="uid://c0ahhupmdstxq" path="res://UI/Panels/itch_app_panel.tscn" id="8_hk3mv"] [ext_resource type="PackedScene" uid="uid://c0ahhupmdstxq" path="res://UI/Panels/itch_app_panel.tscn" id="8_hk3mv"]
[sub_resource type="Resource" id="Resource_hk3mv"] [sub_resource type="Resource" id="Resource_yiww1"]
script = ExtResource("4_myc1y") script = ExtResource("4_myc1y")
steam_app_id = 3712430 steam_app_id = 3712430
type = "game" type = "game"
@ -240,7 +240,7 @@ tabs_visible = false
unique_name_in_owner = true unique_name_in_owner = true
visible = false visible = false
layout_mode = 2 layout_mode = 2
test_data = SubResource("Resource_hk3mv") test_data = SubResource("Resource_yiww1")
metadata/_tab_index = 0 metadata/_tab_index = 0
[node name="ItchAppPanel" parent="Splitter/TabContainer" unique_id=691251029 instance=ExtResource("8_hk3mv")] [node name="ItchAppPanel" parent="Splitter/TabContainer" unique_id=691251029 instance=ExtResource("8_hk3mv")]

View file

@ -6,6 +6,7 @@ var _play_icon: Texture2D
var _stop_icon: Texture2D var _stop_icon: Texture2D
func _enter_tree() -> void: func _enter_tree() -> void:
if not ProjectSettings.has_setting("application/run/custom_rinner"):
ProjectSettings.set("application/run/custom_runner", "") ProjectSettings.set("application/run/custom_runner", "")
ProjectSettings.add_property_info({ ProjectSettings.add_property_info({
"name": "application/run/custom_runner", "name": "application/run/custom_runner",
@ -25,7 +26,6 @@ func _exit_tree() -> void:
_runner_btn.queue_free() _runner_btn.queue_free()
_runner_btn = null _runner_btn = null
class RunnerButton: class RunnerButton:
extends Button extends Button
@ -34,6 +34,7 @@ class RunnerButton:
var _running_pid: int = -1 var _running_pid: int = -1
var _io: FileAccess = null var _io: FileAccess = null
var _err: FileAccess = null var _err: FileAccess = null
var _output: RichTextLabel = null
func _init() -> void: func _init() -> void:
_play = EditorInterface.get_editor_theme().get_icon(&"Play", &"EditorIcons") _play = EditorInterface.get_editor_theme().get_icon(&"Play", &"EditorIcons")
@ -85,13 +86,16 @@ class RunnerButton:
var run_arguments := [ var run_arguments := [
godot, godot,
"--path", project, "--path", project,
"-d" #"-d"
#"--remote-debug", "tcp://%s:%s" % [host, port], "--remote-debug", "tcp://%s:%s" % [host, port],
#"--editor-pid", "%s" % pid, "--editor-pid", "%s" % pid,
#"--position", "320,-24", "--position", "320,-24",
#"--scene", main_scene "--scene", main_scene
] ]
# --remote-debug tcp://127.0.0.1:6007 --editor-pid 3480813 --position 320,-24 --scene uid://2t2hslaaewee # --remote-debug tcp://127.0.0.1:6007 --editor-pid 3480813 --position 320,-24 --scene uid://2t2hslaaewee
if not _output: _output = _get_output()
if _output:
_output.clear()
print("Executing project with the following Command Line: %s %s" % [runner, run_arguments]) print("Executing project with the following Command Line: %s %s" % [runner, run_arguments])
@ -117,12 +121,12 @@ class RunnerButton:
await get_tree().process_frame await get_tree().process_frame
var res := _read_io(_io, output) var res := _read_io(_io, output)
if res != "": #if res != "":
print_rich(res) #print_rich(res)
res = _read_io(_err, err) res = _read_io(_err, err)
if res != "": #if res != "":
print_rich(res) #print_rich(res)
await get_tree().process_frame await get_tree().process_frame
var str := _read_io(_io, output) var str := _read_io(_io, output)
@ -149,3 +153,15 @@ class RunnerButton:
buffer.clear() buffer.clear()
buffer.append_array(leftover) buffer.append_array(leftover)
return part.get_string_from_utf8() return part.get_string_from_utf8()
func _get_output() -> RichTextLabel:
return _find_output(get_tree().root)
func _find_output(current: Node) -> RichTextLabel:
if current is RichTextLabel and current.get_parent() and current.get_parent().get_parent() and current.get_parent().get_parent().name.begins_with("@EditorLog"):
return current
for c in current.get_children(true):
var r = _find_output(c)
if r:
return r
return null

View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="white" class="bi bi-twitch" viewBox="0 0 16 16">
<path d="M3.857 0 1 2.857v10.286h3.429V16l2.857-2.857H9.57L14.714 8V0zm9.714 7.429-2.285 2.285H9l-2 2v-2H4.429V1.143h9.142z"/>
<path d="M11.857 3.143h-1.143V6.57h1.143zm-3.143 0H7.571V6.57h1.143z"/>
</svg>>
</svg>

After

Width:  |  Height:  |  Size: 335 B

View file

@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bvmx86tvio46h"
path="res://.godot/imported/twitch_large.svg-f412c62f24767edcd1ef4fb3abeb1597.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/bootstrap/twitch_large.svg"
dest_files=["res://.godot/imported/twitch_large.svg-f412c62f24767edcd1ef4fb3abeb1597.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
svg/scale=20.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

56
lib/image_loader.gd Normal file
View file

@ -0,0 +1,56 @@
extends Node
var _client: BufferedHTTPClient
enum ImgFmt { PNG, JPG, WEBP, BMP, GIF, UNKNOWN }
func _identify_image(byte_array: PackedByteArray) -> ImgFmt:
if byte_array.size() < 8:
return ImgFmt.UNKNOWN
# PNG magic bytes: 0x89, P, N, G, \r, \n, 0x1a, \n
if byte_array[0] == 0x89 and byte_array[1] == 0x50 and byte_array[2] == 0x4E and byte_array[3] == 0x47:
return ImgFmt.PNG
# JPEG magic bytes (starts with 0xFF, 0xD8)
if byte_array[0] == 0xFF and byte_array[1] == 0xD8:
return ImgFmt.JPG
# WebP magic bytes (RIFF header, "WEBP" at offset 8)
if byte_array[0] == 0x52 and byte_array[1] == 0x49 and byte_array[2] == 0x46 and byte_array[3] == 0x46 and \
byte_array[8] == 0x57 and byte_array[9] == 0x45 and byte_array[10] == 0x42 and byte_array[11] == 0x50:
return ImgFmt.JPG
# BMP Magic (Starts with 0x42, 0x4D
if byte_array[0] == 0x42 and byte_array[1] == 0x4D:
return ImgFmt.BMP
if byte_array[0] == 0x47 and byte_array[1] == 0x49 and byte_array[2] == 0x46:
return ImgFmt.GIF
return ImgFmt.UNKNOWN
func _ready() -> void:
_client = BufferedHTTPClient.new()
_client.name = "ImageLoaderHTTPClient"
add_child(_client)
func load_image(url: String) -> ImageTexture:
var request : BufferedHTTPClient.RequestData = _client.request(url, HTTPClient.METHOD_GET, {}, "")
var response : BufferedHTTPClient.ResponseData = await _client.wait_for_request(request)
var img_buffer: PackedByteArray = response.response_data
var img: Image = Image.new()
match _identify_image(img_buffer):
ImgFmt.PNG:
img.load_png_from_buffer(img_buffer)
ImgFmt.JPG:
img.load_jpg_from_buffer(img_buffer)
ImgFmt.WEBP:
img.load_webp_from_buffer(img_buffer)
ImgFmt.BMP:
img.load_bmp_from_buffer(img_buffer)
ImgFmt.GIF:
push_error("Attempting to load a GIF image, use media loader to load.")
ImgFmt.UNKNOWN:
push_error("Failed to identify file!")
return ImageTexture.create_from_image(img)

1
lib/image_loader.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://b1m82tihhr2p7

View file

@ -19,6 +19,9 @@ func _get_script_name() -> String:
return self.get_script().get_global_name() return self.get_script().get_global_name()
#endregion #endregion
func send_message(msg: String) -> void:
_twitch.send_message(msg)
func send_notification(message: String) -> void: func send_notification(message: String) -> void:
EventManager.test_notification(message) EventManager.test_notification(message)

View file

@ -15,7 +15,7 @@ config/description="Enter an interesting project description here!"
run/main_scene="uid://2t2hslaaewee" run/main_scene="uid://2t2hslaaewee"
config/features=PackedStringArray("4.6") config/features=PackedStringArray("4.6")
config/icon="res://icon.png" config/icon="res://icon.png"
run/custom_runner="" run/custom_runner="/usr/bin/obs-gamecapture"
GData_ORM/migration/use_number=true GData_ORM/migration/use_number=true
GData_ORM/migration/folder="res://migrations" GData_ORM/migration/folder="res://migrations"
GData_ORM/migration/debug_migrations=true GData_ORM/migration/debug_migrations=true
@ -26,6 +26,7 @@ Globals="*uid://cuap0k5jagdtj"
ChatManager="*uid://ct1s5eymb8mns" ChatManager="*uid://ct1s5eymb8mns"
EventManager="*uid://cvjhecj1me4xl" EventManager="*uid://cvjhecj1me4xl"
ObsManager="*uid://c447ij3oc24q3" ObsManager="*uid://c447ij3oc24q3"
ImageLoader="*uid://b1m82tihhr2p7"
[display] [display]
@ -41,7 +42,7 @@ window/per_pixel_transparency/allowed=true
[editor_plugins] [editor_plugins]
enabled=PackedStringArray("res://addons/gdata_orm/plugin.cfg", "res://addons/gde_gozen/plugin.cfg", "res://addons/kenny_spritesheet_importer/plugin.cfg", "res://addons/no-obs-ws/plugin.cfg", "res://addons/sc_editor/plugin.cfg", "res://addons/twitcher/plugin.cfg") enabled=PackedStringArray("res://addons/custom_runner/plugin.cfg", "res://addons/gdata_orm/plugin.cfg", "res://addons/gde_gozen/plugin.cfg", "res://addons/kenny_spritesheet_importer/plugin.cfg", "res://addons/no-obs-ws/plugin.cfg", "res://addons/sc_editor/plugin.cfg", "res://addons/twitcher/plugin.cfg")
[gui] [gui]