extends Node #region Signals signal live_streamers_updating signal live_streamers_updated #endregion #region Public Variables var twitcher: TwitcherExtended: set(val): twitcher = val twitcher.streamer_token_validated.connect(_setup_live_stream_timer) var context: OverlayContext var settings: OverlaySettings var main_win: OverlayWindow var live_streamers: Dictionary[String, TwitchStream] = {} #endregion #region Private Variables var _pt_except: Array[Control] = [] var _pt_mouse: bool = false var _current_pt_mask: PackedVector2Array = [] var _hull_points: PackedVector2Array = [] var _debug_draw: DebugDraw var _tmr_live_stream: Timer #endregion # Called when the node enters the scene tree for the first time. func _ready() -> void: context = OverlayContext.new() context.setup() context.open_db("user://overlay.db") # Method one, just create all tables, prevents alterations to existing tables. #context.ensure_tables() # Method two, use migrations to handle setting up database tables, ensuring that # tables can be modified in the future context.run_migrations() if FileAccess.file_exists("user://settings.tres"): settings = load("user://settings.tres") else: settings = OverlaySettings.new() func _exit_tree() -> void: save_settings() func _input(_event: InputEvent) -> void: if Input.is_action_just_pressed("debug_draw"): if _debug_draw: _debug_draw.queue_free() _debug_draw = null else: _debug_draw = DebugDraw.new() add_child(_debug_draw) func _setup_live_stream_timer() -> void: if _tmr_live_stream: return _tmr_live_stream = Timer.new() _tmr_live_stream.name = "TimerLiveStreamCheck" _tmr_live_stream.wait_time = 240 _tmr_live_stream.one_shot = false _tmr_live_stream.timeout.connect(_run_live_streamer_update) add_child(_tmr_live_stream) _run_live_streamer_update() _tmr_live_stream.start() get_indie_game_devs_members() func _run_live_streamer_update() -> void: live_streamers_updating.emit() live_streamers = await twitcher.get_live_streamers_data() live_streamers_updated.emit() func save_settings() -> void: ResourceSaver.save(settings, "user://settings.tres") func clear_mouse_passthrough() -> void: DisplayServer.window_set_mouse_passthrough([]) func _update_mouse_passthrough() -> void: if not _pt_mouse: return var _pt_mask: PackedVector2Array = [] for node in _pt_except: var rect := node.get_global_rect() _pt_mask.append_array([ rect.position, Vector2(rect.position.x + rect.size.x, rect.position.y), rect.position + rect.size, Vector2(rect.position.x, rect.position.y + rect.size.y) ]) _current_pt_mask = _pt_mask var hull_points := Geometry2D.convex_hull(_pt_mask) _hull_points = hull_points DisplayServer.window_set_mouse_passthrough(hull_points) func _process(_d: float) -> void: if _pt_except.size() == 0: return if not _pt_mouse: return _update_mouse_passthrough() func add_to_passthrough_exception(control: Control) -> void: if not _pt_except.has(control): _pt_except.append(control) control.item_rect_changed.connect(_update_mouse_passthrough) func add_children_to_passthrough_exception(control: Control, ignore: Array[Control] = []) -> void: if not _pt_except.has(control): _pt_except.append(control) for child in control.get_children(): if child in ignore: continue if child.get_child_count() > 0: add_children_to_passthrough_exception(child, ignore) else: _pt_except.append(child) child.item_rect_changed.connect(_update_mouse_passthrough) func remove_from_passthrough_exceptioon(control: Control) -> void: if _pt_except.has(control): _pt_except.erase(control) control.item_rect_changed.disconnect(_update_mouse_passthrough) func enable_mouse_passthrough() -> void: if _pt_mouse: return _pt_mouse = true _update_mouse_passthrough() func disable_mouse_passthrough() -> void: if not _pt_mouse: return _pt_mouse = false clear_mouse_passthrough() func get_exception_points() -> PackedVector2Array: return _current_pt_mask func get_polygon_points() -> PackedVector2Array: return _hull_points func get_indie_game_devs_members() -> void: var team = await twitcher.get_team_info("indiegamedevs") var new_users: Array[TwitchUser] if team: var chatters: Array[Chatter] = [] chatters.assign(context.chatters.all()) var new_members: Array[TwitchTeam.Users] = [] print("Got team: ", team.team_name) print("Member Count: ", team.users.size()) for team_member: TwitchTeam.Users in team.users: if not chatters.any(func(x: Chatter): return x.twitch_id == team_member.user_id): new_members.append(team_member) if new_members.size() > 0: var iter = 0 const MAX_ITER = 100 while not new_members.is_empty(): iter += 1 if iter > MAX_ITER: return var new_batch: Array[String] = [] new_batch.assign(new_members.slice(0,99).map(func(x): return x.user_id)) new_members.assign(new_members.slice(99)) var res = await twitcher.get_users_by_id(new_batch) new_users.append_array(res) print("Found: %d new members not in database" % new_users.size()) for user: TwitchUser in new_users: var chatter = Chatter.new() chatter.twitch_id = user.id chatter.is_streamer = true chatter.is_indie_game_dev = true chatter.user = user chatter.first_added = Time.get_unix_time_from_system() chatter.first_seen = -1 chatter.last_seen = -1 context.chatters.append(chatter)