Compare commits

...

8 commits

Author SHA1 Message Date
6611830c18 Updated FloatingMenu
Added OBSProc information, and VTuberProc information, for later when
testing if these programs are running, and maybe later implementing
killing of these programs.
2026-03-06 21:26:03 -06:00
00d437b523 Updated SQLiteObject
Updated missing type assignment.  This will be updated from another
repo.
2026-03-06 21:25:21 -06:00
20104cce0e Started working on OverlayPlugin
Started work on implementing OverlayPlugin interface for scripts.
2026-03-06 21:24:42 -06:00
cb50e313a0 Updated ChatbotAuthorization
Added warning ignore for tool function exported variable.
2026-03-06 21:24:18 -06:00
2d25921688 Updated TwitcherExtended
Fixed typo in channel_points_voting_enabled.
Changed poll to _poll to avoid name conflicts with poll() function name.
2026-03-06 21:23:54 -06:00
b47df7ad86 Updated EventManager
Fixed warning about losing percision on a float.
2026-03-06 21:22:36 -06:00
298381b2d9 Updated ObsManager
Added logging
Added reconnecting based upon obs_reconnect.
Added bool check to see if we are connecting, or re-connecting.
2026-03-06 21:22:09 -06:00
95345fc50b Update Util
Updated Util convert_html_to_bbcode() to fix p tags.
2026-03-06 21:20:45 -06:00
8 changed files with 61 additions and 21 deletions

View file

@ -77,8 +77,8 @@ var anchored_position: Vector2
var _set_win: Window
var _edit_win: Window
var _obs_pid: int = -1
var _vtuber_pid: int = -1
var _obs_proc: ProcessTree.ProcessInfo = null
var _vtuber_proc: ProcessTree.ProcessInfo = null
var _vtuber_sid: int
var _camera_sid: int
@ -199,8 +199,15 @@ func _handle_script_editor() -> void:
_edit_win = win
func _handle_run_obs() -> void:
if _obs_proc and _obs_proc.is_running():
print("OBS is running.")
return
elif _obs_proc and not _obs_proc.is_running():
_obs_proc = null
var tree := ProcessTree.new()
if tree.has_process_name(Globals.settings.obs_name):
_obs_proc = tree.get_process_by_name(Globals.settings.obs_name)
print("OBS is running.")
return
else:
@ -224,8 +231,16 @@ func _handle_step_away() -> void:
EventManager.add_alert(alert)
func _handle_run_vtuber() -> void:
if _vtuber_proc and _vtuber_proc.is_running():
print("VTuber is running.")
return
elif _vtuber_proc and not _vtuber_proc.is_running():
_vtuber_proc = null
var tree := ProcessTree.new()
if tree.has_process_name(Globals.settings.vtuber_name):
_vtuber_proc = tree.get_process_by_name(Globals.settings.vtuber_name)
print("VTuber is running.")
return
else:

View file

@ -215,8 +215,9 @@ static func set_column_type(klass: GDScript, column: String, type: DataType, ext
if type == DataType.CHAR and not extra_params.has("size"):
assert(false, "Attempting to set Column type to CHAR without a size parameter!")
_tables[klass].types[column] = _DEFINITION[type] if type != DataType.CHAR else _DEFINITION[type] % extra_params.size
_tables[klass].types[column] = type
_tables[klass].columns[column].data_type = _DEFINITION[type] if type != DataType.CHAR else _DEFINITION[type] % extra_params.size
## Sets a variable that has been defined in the class, to be ignored, so as to not persist the data in the
## [SQLite] database. The variable must be defined, in order for it to be ignored.[br][br]

View file

@ -30,8 +30,8 @@ func test_notification(msg: String) -> void:
lbl.text = msg
lbl.modulate.a = 0
lbl.ready.connect(func() -> void:
var half: Vector2 = lbl.size / 2
lbl.position = Vector2(get_tree().root.size / 2) - half
var half: Vector2 = lbl.size / 2.0
lbl.position = Vector2(get_tree().root.size / 2.0) - half
var tw := create_tween()
tw.tween_property(lbl, "modulate:a", 1.0, 0.5)
tw.tween_interval(2.5)

View file

@ -1,18 +1,34 @@
extends Node
var obs: NoOBSWS
signal obs_ready()
signal obs_disconnect()
signal stream_state_changed(state: bool)
signal input_state_changed(input_name: String, state: bool)
signal scene_changed(scene_name: String, scene_uuid: String)
static var _log: TwitchLogger = TwitchLogger.new(&"ObsManager", true, true)
var obs: NoOBSWS
var _reconnect: bool = false
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
obs = NoOBSWS.new()
add_child(obs)
obs.event_received.connect(_handle_websock_events)
obs.connection_ready.connect(obs_ready.emit)
obs.connection_ready.connect(func():
_reconnect = false
obs_ready.emit()
_log.i("Connected to OBS WebSocket server.")
)
obs.connection_closed_clean.connect(_handle_disconnect)
obs.connection_failed.connect(func():
_log.i("Failed to connect to server.")
if Globals.settings.obs_reconnect:
await get_tree().create_timer(15).timeout
_reconnect = true
connect_to_host()
)
func is_open() -> bool:
return obs.is_open()
@ -23,11 +39,14 @@ func connect_to_host() -> void:
Globals.settings.obs_pass != ""):
return
_log.i("%s to OBS WebSocket server..." % "Reconnecting" if _reconnect else "Connecting")
if _reconnect: _reconnect = false
obs.connect_to_obsws(Globals.settings.obs_port, Globals.settings.obs_host, Globals.settings.obs_pass)
func _handle_disconnect(reason: int, message: String) -> void:
func _handle_disconnect(_reason: int, _message: String) -> void:
obs_disconnect.emit()
if Globals.settings.obs_reconnect:
_reconnect = true
connect_to_host()
func _handle_websock_events(event: NoOBSWS.Message) -> void:

View file

@ -4,13 +4,13 @@ class_name OverlayPlugin
#region Internal Variables
var _twitch: TwitcherExtended
var _obs: NoOBSWS
#endregion
func _ready() -> void:
while not TwitcherExtended.instance:
await get_tree().process_frame
_twitch = TwitcherExtended.instance
@abstract func run() -> void
@ -22,16 +22,16 @@ func _get_script_name() -> String:
func send_notification(message: String) -> void:
EventManager.test_notification(message)
func get_setting(name: String, defval: Variant) -> Variant:
func get_setting(sname: String, defval: Variant) -> Variant:
var script_name := _get_script_name()
if not Globals.settings.script_storage.has(script_name):
return defval
if not Globals.settings.script_storage[script_name].has(name):
if not Globals.settings.script_storage[script_name].has(sname):
return defval
return Globals.settings.script_storage[script_name][name]
return Globals.settings.script_storage[script_name][sname]
func set_setting(name: String, value: Variant) -> void:
func set_setting(sname: String, value: Variant) -> void:
var script_name := _get_script_name()
if not Globals.settings.script_storage.has(script_name):
Globals.settings.script_storage[script_name] = {}
Globals.settings.script_storage[script_name][name] = value
Globals.settings.script_storage[script_name][sname] = value

View file

@ -14,6 +14,7 @@ class_name ChatbotAuthorization
var api: TwitchAPI
var auth: TwitchAuth
@warning_ignore("unused_private_class_variable")
@export_tool_button("Reset Token") var _reset_token := func() -> void:
token.remove_tokens()

View file

@ -454,14 +454,14 @@ func poll(title: String, choices: Array[String], duration: int = 60, channel_poi
var poll_body: TwitchCreatePoll.Body = TwitchCreatePoll.Body.create(streamer_user.id, title, body_choices, duration)
if channel_points_voting_enabled:
poll_body.channel_points_per_vote = channel_points_per_vote
poll_body.channel_points_voiting_enabled = channel_points_voting_enabled
poll_body.channel_points_voting_enabled = channel_points_voting_enabled
var poll_response: TwitchCreatePoll.Response = await api.create_poll(poll_body)
if poll_response.response.response_code != 200:
var error_message: String = poll_response.response.response_data.get_string_from_utf8()
push_error("Can't create poll response cause of ", error_message)
return {}
var poll: TwitchPoll = poll_response.data[0]
var poll_end_time: int = Time.get_ticks_msec() + duration * 100 * POLL_TIMEOUT_MS
var _poll: TwitchPoll = poll_response.data[0]
var poll_end_time: int = Time.get_ticks_msec() + duration * 1000 * POLL_TIMEOUT_MS
var event: TwitchEventsub.Event
if eventsub && eventsub.has_subscription(TwitchEventsubDefinition.CHANNEL_POLL_END, {&"broadcaster_user_id": streamer_user.id}):
var poll_ended: bool
@ -469,8 +469,8 @@ func poll(title: String, choices: Array[String], duration: int = 60, channel_poi
if poll_end_time < Time.get_ticks_msec():
return {}
event = await eventsub.event_received
if event.Type != TwitchEventsubDefinition.CHANNEL_POLL_END: continue
if event.data[&"id"] != poll.id: continue
if event.type != TwitchEventsubDefinition.CHANNEL_POLL_END: continue
if event.data[&"id"] != _poll.id: continue
break
else:
_log.i("Can't wait for poll end. Either eventsub is not set to it not listening to ending polls")

View file

@ -41,10 +41,14 @@ static func convert_html_to_bbcode(html: String) -> String:
# NOTE: Replace <img ... src="..."> with [img]...[/img]
bb = _img_re.sub(bb, "[img]$1[/img]", true)
# NOTE: Remove <p> tags, convert </p> to newline
# NOTE: Replace <h2 ...>...</h2> tags, with [b]...[/b]
bb = _h2_open_re.sub(bb, "[b]", true)
bb = bb.replace("</h2>", "[/b]\n")
# NOTE: Remove <p> tags, convert </p> to new line
bb = _p_open_re.sub(bb, "", true)
bb = bb.replace("</p>", "\n")
# NOTE: List Items: <li> -> •, </li> -> newline
bb = bb.replace("<li>", "")
bb = bb.replace("</li>", "\n")