# @name Xbox Monitor # @desc Status z xbl.io (Standalone) # @author strusic # @version 1.6 # @config apikey text "Klucz API z xbl.io" default="" # @config speed number "Prędkość" default=200 min=50 max=300 step=10 # @config repeat number "Ilość powtórzeń" default=2 min=1 max=5 # @config every number "Interwał (min)" default=2 min=1 max=15 # @config ignored text "Ignorowane gry" default="Kodi,Netflix,YouTube,Plex,Microsoft Store" import string class XboxXbl var apikey, period var game_name, start_time, ic, label var ticks, in_flight, is_finished var ignored_list def init() self.apikey = store.get("apikey") self.period = store.get("every") * 60 self.game_name = "" self.start_time = 0 self.ic = "4687" self.ticks = 0 self.in_flight = false self.is_finished = false # Przetworzenie czystej listy ignorowanych aplikacji self.ignored_list = [] var raw_ignored = store.get("ignored") if raw_ignored != nil && raw_ignored != "" var parts = re.matchall("([^,]+)", raw_ignored) if parts != nil for p : parts var m = re.search("^\\s*(.*\\S)\\s*$", p) if m != nil self.ignored_list.push(m[1]) end end end end log("Xbox Monitor: Gotowy do pracy") end def now_minutes() var d = day() var mo = month() var a = int((14 - mo) / 12) var yy = year() + 4800 - a var mm = mo + 12 * a - 3 var jd = d + int((153 * mm + 2) / 5) + 365 * yy + int(yy / 4) - int(yy / 100) + int(yy / 400) return jd * 1440 + hour() * 60 + minute() end def duration() return 1000 end def on_show() self.is_finished = false end def should_show() return self.game_name != "" end def on_body(body, status) self.in_flight = false if body == nil || status != 200 log("Xbox Monitor: Błąd API (Status: " + str(status) + "). Czekam na kolejny cykl.") return end var is_online = re.search("\"state\"\\s*:\\s*\"Online\"", body) if is_online == nil self.game_name = "" return end var found_game = "" var m = re.search("\"name\"\\s*:\\s*\"([^\"]+)\"[^{}]*\"placement\"\\s*:\\s*\"Full\"", body) if m != nil found_game = m[1] else m = re.search("\"placement\"\\s*:\\s*\"Full\"[^{}]*\"name\"\\s*:\\s*\"([^\"]+)\"", body) if m != nil found_game = m[1] end end if found_game != "" # Usunięcie znaków specjalnych i ukrytych (w tym ZWJ), które renderują się jako '?' found_game = string.replace(found_game, "®", "") found_game = string.replace(found_game, "™", "") found_game = string.replace(found_game, "©", "") found_game = string.replace(found_game, "\xC2\xA0", " ") found_game = string.replace(found_game, "\xE2\x80\x8D", "") var is_ignored = false for ig : self.ignored_list # Rozbija wpisaną frazę na słowa i sprawdza, czy WSZYSTKIE słowa są w nazwie z API var words = string.split(ig, " ") var all_words_found = true for w : words if w != "" if re.search(w, found_game) == nil all_words_found = false end end end if all_words_found is_ignored = true end end if is_ignored self.game_name = "" else if self.game_name != found_game self.game_name = found_game self.start_time = self.now_minutes() log("Xbox Monitor: Nowa gra -> " + found_game) end end else self.game_name = "" end end def loop() if self.ticks <= 0 self.ticks = self.period if !self.in_flight && self.apikey != "" && self.apikey != nil self.in_flight = true var url = "https://xbl.io/api/v2/presence" var opts = { 'headers': {'X-Authorization': self.apikey}, 'keep': 8192 } http.get(url, / b, st -> self.on_body(b, st), opts) end end self.ticks -= 1 end def draw() if self.apikey == "" || self.apikey == nil clear() font("small") text(1, 1, "Brak klucza", 0xFF0000) text(1, 8, "xbl.io", 0xFF0000) return end if self.game_name == "" return end clear() var diff = self.now_minutes() - self.start_time if diff < 0 diff = 0 end var h = diff / 60 var m = diff % 60 var time_str = "" if h > 0 time_str = format("%dh %02dm", h, m) else time_str = format("%02d min", m) end self.label = self.game_name + " - " + time_str if !icon(self.ic, 0, 0) rect_fill(0, 0, 8, 8, 0x107C10) end var target_repeats = int(store.get("repeat")) var label_opts = { "speed": int(store.get("speed")), "repeat": target_repeats, "mode": "wrap" } if !self.is_finished var completed = scroll_text(9, 6, width() - 9, self.label, 0xFFFFFF, label_opts) if completed >= target_repeats self.is_finished = true end end end end return XboxXbl()