diff --git a/dist/better-xcloud.user.js b/dist/better-xcloud.user.js index fda4b6a..9562003 100644 --- a/dist/better-xcloud.user.js +++ b/dist/better-xcloud.user.js @@ -12,19 +12,7 @@ // @updateURL https://raw.githubusercontent.com/redphx/better-xcloud/typescript/dist/better-xcloud.meta.js // @downloadURL https://github.com/redphx/better-xcloud/releases/latest/download/better-xcloud.user.js // ==/UserScript== -'use strict'; -// src/enums/user-agent.ts -var UserAgentProfile = { - WINDOWS_EDGE: "windows-edge", - MACOS_SAFARI: "macos-safari", - SMART_TV_GENERIC: "smarttv-generic", - SMART_TV_TIZEN: "smarttv-tizen", - VR_OCULUS: "vr-oculus", - DEFAULT: "default", - CUSTOM: "custom" -}; - -// src/utils/bx-flags.ts +"use strict"; /* ADDITIONAL CODE */ @@ -48,7 +36,6 @@ if (!BX_FLAGS.DeviceInfo.userAgent) BX_FLAGS.DeviceInfo.userAgent = window.navigator.userAgent; var NATIVE_FETCH = window.fetch; -// src/utils/user-agent.ts var SMART_TV_UNIQUE_ID = "FC4A1DA2-711C-4E9C-BC7F-047AF8A672EA", CHROMIUM_VERSION = "123.0.0.0"; if (!!window.chrome || window.navigator.userAgent.includes("Chrome")) { const match = window.navigator.userAgent.match(/\s(?:Chrome|Edg)\/([\d\.]+)/); @@ -63,22 +50,22 @@ class UserAgent { static #isSafari = null; static #isSafariMobile = null; static #USER_AGENTS = { - [UserAgentProfile.WINDOWS_EDGE]: `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${CHROMIUM_VERSION} Safari/537.36 Edg/${CHROMIUM_VERSION}`, - [UserAgentProfile.MACOS_SAFARI]: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5.2 Safari/605.1.1", - [UserAgentProfile.SMART_TV_GENERIC]: `${window.navigator.userAgent} SmartTV`, - [UserAgentProfile.SMART_TV_TIZEN]: `Mozilla/5.0 (SMART-TV; LINUX; Tizen 7.0) AppleWebKit/537.36 (KHTML, like Gecko) ${CHROMIUM_VERSION}/7.0 TV Safari/537.36 ${SMART_TV_UNIQUE_ID}`, - [UserAgentProfile.VR_OCULUS]: window.navigator.userAgent + " OculusBrowser VR" + "windows-edge": `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${CHROMIUM_VERSION} Safari/537.36 Edg/${CHROMIUM_VERSION}`, + "macos-safari": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5.2 Safari/605.1.1", + "smarttv-generic": `${window.navigator.userAgent} SmartTV`, + "smarttv-tizen": `Mozilla/5.0 (SMART-TV; LINUX; Tizen 7.0) AppleWebKit/537.36 (KHTML, like Gecko) ${CHROMIUM_VERSION}/7.0 TV Safari/537.36 ${SMART_TV_UNIQUE_ID}`, + "vr-oculus": window.navigator.userAgent + " OculusBrowser VR" }; static init() { if (UserAgent.#config = JSON.parse(window.localStorage.getItem(UserAgent.STORAGE_KEY) || "{}"), !UserAgent.#config.profile) - UserAgent.#config.profile = UserAgentProfile.DEFAULT; + UserAgent.#config.profile = "default"; if (!UserAgent.#config.custom) UserAgent.#config.custom = ""; UserAgent.spoof(); } static updateStorage(profile, custom) { const config = UserAgent.#config; - if (config.profile = profile, profile === UserAgentProfile.CUSTOM && typeof custom !== "undefined") + if (config.profile = profile, profile === "custom" && typeof custom !== "undefined") config.custom = custom; window.localStorage.setItem(UserAgent.STORAGE_KEY, JSON.stringify(config)); } @@ -88,9 +75,9 @@ class UserAgent { static get(profile) { const defaultUserAgent = window.navigator.userAgent; switch (profile) { - case UserAgentProfile.DEFAULT: + case "default": return defaultUserAgent; - case UserAgentProfile.CUSTOM: + case "custom": return UserAgent.#config.custom || defaultUserAgent; default: return UserAgent.#USER_AGENTS[profile] || defaultUserAgent; @@ -117,7 +104,7 @@ class UserAgent { } static spoof() { const profile = UserAgent.#config.profile; - if (profile === UserAgentProfile.DEFAULT) + if (profile === "default") return; let newUserAgent = UserAgent.get(profile); if (BX_FLAGS.IsSupportedTvBrowser) @@ -128,7 +115,6 @@ class UserAgent { } } -// src/utils/global.ts function deepClone(obj) { if ("structuredClone" in window) return structuredClone(obj); @@ -163,46 +149,9 @@ var userAgent = window.navigator.userAgent.toLowerCase(), isTv = userAgent.inclu pointerServerPort: 9269 }, STORAGE = {}; -// src/utils/bx-event.ts var BxEvent; -(function(BxEvent2) { - BxEvent2["JUMP_BACK_IN_READY"] = "bx-jump-back-in-ready"; - BxEvent2["POPSTATE"] = "bx-popstate"; - BxEvent2["TITLE_INFO_READY"] = "bx-title-info-ready"; - BxEvent2["SETTINGS_CHANGED"] = "bx-settings-changed"; - BxEvent2["STREAM_LOADING"] = "bx-stream-loading"; - BxEvent2["STREAM_STARTING"] = "bx-stream-starting"; - BxEvent2["STREAM_STARTED"] = "bx-stream-started"; - BxEvent2["STREAM_PLAYING"] = "bx-stream-playing"; - BxEvent2["STREAM_STOPPED"] = "bx-stream-stopped"; - BxEvent2["STREAM_ERROR_PAGE"] = "bx-stream-error-page"; - BxEvent2["STREAM_WEBRTC_CONNECTED"] = "bx-stream-webrtc-connected"; - BxEvent2["STREAM_WEBRTC_DISCONNECTED"] = "bx-stream-webrtc-disconnected"; - BxEvent2["STREAM_SESSION_READY"] = "bx-stream-session-ready"; - BxEvent2["CUSTOM_TOUCH_LAYOUTS_LOADED"] = "bx-custom-touch-layouts-loaded"; - BxEvent2["TOUCH_LAYOUT_MANAGER_READY"] = "bx-touch-layout-manager-ready"; - BxEvent2["REMOTE_PLAY_READY"] = "bx-remote-play-ready"; - BxEvent2["REMOTE_PLAY_FAILED"] = "bx-remote-play-failed"; - BxEvent2["XCLOUD_SERVERS_READY"] = "bx-servers-ready"; - BxEvent2["XCLOUD_SERVERS_UNAVAILABLE"] = "bx-servers-unavailable"; - BxEvent2["DATA_CHANNEL_CREATED"] = "bx-data-channel-created"; - BxEvent2["GAME_BAR_ACTION_ACTIVATED"] = "bx-game-bar-action-activated"; - BxEvent2["MICROPHONE_STATE_CHANGED"] = "bx-microphone-state-changed"; - BxEvent2["CAPTURE_SCREENSHOT"] = "bx-capture-screenshot"; - BxEvent2["POINTER_LOCK_REQUESTED"] = "bx-pointer-lock-requested"; - BxEvent2["POINTER_LOCK_EXITED"] = "bx-pointer-lock-exited"; - BxEvent2["NAVIGATION_FOCUS_CHANGED"] = "bx-nav-focus-changed"; - BxEvent2["XCLOUD_DIALOG_SHOWN"] = "bx-xcloud-dialog-shown"; - BxEvent2["XCLOUD_DIALOG_DISMISSED"] = "bx-xcloud-dialog-dismissed"; - BxEvent2["XCLOUD_GUIDE_MENU_SHOWN"] = "bx-xcloud-guide-menu-shown"; - BxEvent2["XCLOUD_POLLING_MODE_CHANGED"] = "bx-xcloud-polling-mode-changed"; - BxEvent2["XCLOUD_RENDERING_COMPONENT"] = "bx-xcloud-rendering-page"; -})(BxEvent || (BxEvent = {})); -var XcloudEvent; -(function(XcloudEvent2) { - XcloudEvent2["MICROPHONE_STATE_CHANGED"] = "microphoneStateChanged"; -})(XcloudEvent || (XcloudEvent = {})); -(function(BxEvent) { +((BxEvent) => { + BxEvent.JUMP_BACK_IN_READY = "bx-jump-back-in-ready", BxEvent.POPSTATE = "bx-popstate", BxEvent.TITLE_INFO_READY = "bx-title-info-ready", BxEvent.SETTINGS_CHANGED = "bx-settings-changed", BxEvent.STREAM_LOADING = "bx-stream-loading", BxEvent.STREAM_STARTING = "bx-stream-starting", BxEvent.STREAM_STARTED = "bx-stream-started", BxEvent.STREAM_PLAYING = "bx-stream-playing", BxEvent.STREAM_STOPPED = "bx-stream-stopped", BxEvent.STREAM_ERROR_PAGE = "bx-stream-error-page", BxEvent.STREAM_WEBRTC_CONNECTED = "bx-stream-webrtc-connected", BxEvent.STREAM_WEBRTC_DISCONNECTED = "bx-stream-webrtc-disconnected", BxEvent.STREAM_SESSION_READY = "bx-stream-session-ready", BxEvent.CUSTOM_TOUCH_LAYOUTS_LOADED = "bx-custom-touch-layouts-loaded", BxEvent.TOUCH_LAYOUT_MANAGER_READY = "bx-touch-layout-manager-ready", BxEvent.REMOTE_PLAY_READY = "bx-remote-play-ready", BxEvent.REMOTE_PLAY_FAILED = "bx-remote-play-failed", BxEvent.XCLOUD_SERVERS_READY = "bx-servers-ready", BxEvent.XCLOUD_SERVERS_UNAVAILABLE = "bx-servers-unavailable", BxEvent.DATA_CHANNEL_CREATED = "bx-data-channel-created", BxEvent.GAME_BAR_ACTION_ACTIVATED = "bx-game-bar-action-activated", BxEvent.MICROPHONE_STATE_CHANGED = "bx-microphone-state-changed", BxEvent.CAPTURE_SCREENSHOT = "bx-capture-screenshot", BxEvent.POINTER_LOCK_REQUESTED = "bx-pointer-lock-requested", BxEvent.POINTER_LOCK_EXITED = "bx-pointer-lock-exited", BxEvent.NAVIGATION_FOCUS_CHANGED = "bx-nav-focus-changed", BxEvent.XCLOUD_DIALOG_SHOWN = "bx-xcloud-dialog-shown", BxEvent.XCLOUD_DIALOG_DISMISSED = "bx-xcloud-dialog-dismissed", BxEvent.XCLOUD_GUIDE_MENU_SHOWN = "bx-xcloud-guide-menu-shown", BxEvent.XCLOUD_POLLING_MODE_CHANGED = "bx-xcloud-polling-mode-changed", BxEvent.XCLOUD_RENDERING_COMPONENT = "bx-xcloud-rendering-page"; function dispatch(target, eventName, data) { if (!target) return; @@ -217,22 +166,9 @@ var XcloudEvent; target.dispatchEvent(event), AppInterface && AppInterface.onEvent(eventName); } BxEvent.dispatch = dispatch; -})(BxEvent || (BxEvent = {})); +})(BxEvent ||= {}); window.BxEvent = BxEvent; -// src/enums/stream-player.ts -var StreamPlayerType; -(function(StreamPlayerType2) { - StreamPlayerType2["VIDEO"] = "default"; - StreamPlayerType2["WEBGL2"] = "webgl2"; -})(StreamPlayerType || (StreamPlayerType = {})); -var StreamVideoProcessing; -(function(StreamVideoProcessing2) { - StreamVideoProcessing2["USM"] = "usm"; - StreamVideoProcessing2["CAS"] = "cas"; -})(StreamVideoProcessing || (StreamVideoProcessing = {})); - -// src/utils/navigation-utils.ts class NavigationUtils { static setNearby($elm, nearby) { $elm.nearby = $elm.nearby || {}; @@ -243,8 +179,7 @@ class NavigationUtils { } var setNearby = NavigationUtils.setNearby; -// src/utils/html.ts -var createElement = function(elmName, props = {}, ..._) { +function createElement(elmName, props = {}, ..._) { let $elm; const hasNs = "xmlns" in props; if (hasNs) @@ -272,7 +207,7 @@ var createElement = function(elmName, props = {}, ..._) { $elm.appendChild(document.createTextNode(arg)); } return $elm; -}; +} function getReactProps($elm) { for (let key in $elm) if (key.startsWith("__reactProps")) @@ -314,103 +249,16 @@ var ButtonStyleIndices = Object.keys(ButtonStyle).splice(0, Object.keys(ButtonSt }, CTN = document.createTextNode.bind(document); window.BX_CE = createElement; -// src/enums/pref-keys.ts -var StorageKey; -(function(StorageKey2) { - StorageKey2["GLOBAL"] = "better_xcloud"; -})(StorageKey || (StorageKey = {})); -var PrefKey; -(function(PrefKey2) { - PrefKey2["LAST_UPDATE_CHECK"] = "version_last_check"; - PrefKey2["LATEST_VERSION"] = "version_latest"; - PrefKey2["CURRENT_VERSION"] = "version_current"; - PrefKey2["BETTER_XCLOUD_LOCALE"] = "bx_locale"; - PrefKey2["SERVER_REGION"] = "server_region"; - PrefKey2["SERVER_BYPASS_RESTRICTION"] = "server_bypass_restriction"; - PrefKey2["PREFER_IPV6_SERVER"] = "prefer_ipv6_server"; - PrefKey2["STREAM_TARGET_RESOLUTION"] = "stream_target_resolution"; - PrefKey2["STREAM_PREFERRED_LOCALE"] = "stream_preferred_locale"; - PrefKey2["STREAM_CODEC_PROFILE"] = "stream_codec_profile"; - PrefKey2["USER_AGENT_PROFILE"] = "user_agent_profile"; - PrefKey2["STREAM_SIMPLIFY_MENU"] = "stream_simplify_menu"; - PrefKey2["STREAM_COMBINE_SOURCES"] = "stream_combine_sources"; - PrefKey2["STREAM_TOUCH_CONTROLLER"] = "stream_touch_controller"; - PrefKey2["STREAM_TOUCH_CONTROLLER_AUTO_OFF"] = "stream_touch_controller_auto_off"; - PrefKey2["STREAM_TOUCH_CONTROLLER_DEFAULT_OPACITY"] = "stream_touch_controller_default_opacity"; - PrefKey2["STREAM_TOUCH_CONTROLLER_STYLE_STANDARD"] = "stream_touch_controller_style_standard"; - PrefKey2["STREAM_TOUCH_CONTROLLER_STYLE_CUSTOM"] = "stream_touch_controller_style_custom"; - PrefKey2["STREAM_DISABLE_FEEDBACK_DIALOG"] = "stream_disable_feedback_dialog"; - PrefKey2["BITRATE_VIDEO_MAX"] = "bitrate_video_max"; - PrefKey2["GAME_BAR_POSITION"] = "game_bar_position"; - PrefKey2["LOCAL_CO_OP_ENABLED"] = "local_co_op_enabled"; - PrefKey2["CONTROLLER_ENABLE_SHORTCUTS"] = "controller_enable_shortcuts"; - PrefKey2["CONTROLLER_ENABLE_VIBRATION"] = "controller_enable_vibration"; - PrefKey2["CONTROLLER_DEVICE_VIBRATION"] = "controller_device_vibration"; - PrefKey2["CONTROLLER_VIBRATION_INTENSITY"] = "controller_vibration_intensity"; - PrefKey2["CONTROLLER_SHOW_CONNECTION_STATUS"] = "controller_show_connection_status"; - PrefKey2["NATIVE_MKB_ENABLED"] = "native_mkb_enabled"; - PrefKey2["NATIVE_MKB_SCROLL_HORIZONTAL_SENSITIVITY"] = "native_mkb_scroll_x_sensitivity"; - PrefKey2["NATIVE_MKB_SCROLL_VERTICAL_SENSITIVITY"] = "native_mkb_scroll_y_sensitivity"; - PrefKey2["MKB_ENABLED"] = "mkb_enabled"; - PrefKey2["MKB_HIDE_IDLE_CURSOR"] = "mkb_hide_idle_cursor"; - PrefKey2["MKB_ABSOLUTE_MOUSE"] = "mkb_absolute_mouse"; - PrefKey2["MKB_DEFAULT_PRESET_ID"] = "mkb_default_preset_id"; - PrefKey2["SCREENSHOT_APPLY_FILTERS"] = "screenshot_apply_filters"; - PrefKey2["BLOCK_TRACKING"] = "block_tracking"; - PrefKey2["BLOCK_SOCIAL_FEATURES"] = "block_social_features"; - PrefKey2["SKIP_SPLASH_VIDEO"] = "skip_splash_video"; - PrefKey2["HIDE_DOTS_ICON"] = "hide_dots_icon"; - PrefKey2["REDUCE_ANIMATIONS"] = "reduce_animations"; - PrefKey2["UI_LOADING_SCREEN_GAME_ART"] = "ui_loading_screen_game_art"; - PrefKey2["UI_LOADING_SCREEN_WAIT_TIME"] = "ui_loading_screen_wait_time"; - PrefKey2["UI_LOADING_SCREEN_ROCKET"] = "ui_loading_screen_rocket"; - PrefKey2["UI_CONTROLLER_FRIENDLY"] = "ui_controller_friendly"; - PrefKey2["UI_LAYOUT"] = "ui_layout"; - PrefKey2["UI_SCROLLBAR_HIDE"] = "ui_scrollbar_hide"; - PrefKey2["UI_HIDE_SECTIONS"] = "ui_hide_sections"; - PrefKey2["UI_HOME_CONTEXT_MENU_DISABLED"] = "ui_home_context_menu_disabled"; - PrefKey2["UI_GAME_CARD_SHOW_WAIT_TIME"] = "ui_game_card_show_wait_time"; - PrefKey2["VIDEO_PLAYER_TYPE"] = "video_player_type"; - PrefKey2["VIDEO_PROCESSING"] = "video_processing"; - PrefKey2["VIDEO_POWER_PREFERENCE"] = "video_power_preference"; - PrefKey2["VIDEO_SHARPNESS"] = "video_sharpness"; - PrefKey2["VIDEO_RATIO"] = "video_ratio"; - PrefKey2["VIDEO_BRIGHTNESS"] = "video_brightness"; - PrefKey2["VIDEO_CONTRAST"] = "video_contrast"; - PrefKey2["VIDEO_SATURATION"] = "video_saturation"; - PrefKey2["AUDIO_MIC_ON_PLAYING"] = "audio_mic_on_playing"; - PrefKey2["AUDIO_ENABLE_VOLUME_CONTROL"] = "audio_enable_volume_control"; - PrefKey2["AUDIO_VOLUME"] = "audio_volume"; - PrefKey2["STATS_ITEMS"] = "stats_items"; - PrefKey2["STATS_SHOW_WHEN_PLAYING"] = "stats_show_when_playing"; - PrefKey2["STATS_QUICK_GLANCE"] = "stats_quick_glance"; - PrefKey2["STATS_POSITION"] = "stats_position"; - PrefKey2["STATS_TEXT_SIZE"] = "stats_text_size"; - PrefKey2["STATS_TRANSPARENT"] = "stats_transparent"; - PrefKey2["STATS_OPACITY"] = "stats_opacity"; - PrefKey2["STATS_CONDITIONAL_FORMATTING"] = "stats_conditional_formatting"; - PrefKey2["REMOTE_PLAY_ENABLED"] = "xhome_enabled"; - PrefKey2["REMOTE_PLAY_RESOLUTION"] = "xhome_resolution"; - PrefKey2["GAME_FORTNITE_FORCE_CONSOLE"] = "game_fortnite_force_console"; -})(PrefKey || (PrefKey = {})); - -// src/utils/bx-logger.ts -var TextColor = { - INFO: "#008746", - WARNING: "#c1a404", - ERROR: "#c10404" -}; - class BxLogger { static #PREFIX = "[BxC]"; static info(tag, ...args) { - BxLogger.#log(TextColor.INFO, tag, ...args); + BxLogger.#log("#008746", tag, ...args); } static warning(tag, ...args) { - BxLogger.#log(TextColor.WARNING, tag, ...args); + BxLogger.#log("#c1a404", tag, ...args); } static error(tag, ...args) { - BxLogger.#log(TextColor.ERROR, tag, ...args); + BxLogger.#log("#c10404", tag, ...args); } static #log(color, tag, ...args) { console.log(`%c${BxLogger.#PREFIX}`, `color:${color};font-weight:bold;`, tag, "//", ...args); @@ -418,7 +266,6 @@ class BxLogger { } window.BxLogger = BxLogger; -// src/utils/translation.ts var SUPPORTED_LANGUAGES = { "en-US": "English (United States)", "ca-CA": "Català", @@ -808,7 +655,6 @@ class Translations { var t = Translations.get; Translations.init(); -// src/enums/bypass-servers.ts var BypassServers = { br: t("brazil"), jp: t("japan"), @@ -821,27 +667,6 @@ var BypassServers = { us: "143.244.47.65" }; -// src/enums/ui-sections.ts -var UiSection = { - ALL_GAMES: "all-games", - FRIENDS: "friends", - MOST_POPULAR: "most-popular", - NATIVE_MKB: "native-mkb", - NEWS: "news", - TOUCH: "touch" -}; - -// src/modules/stream/stream-stats.ts -var StreamStat; -(function(StreamStat2) { - StreamStat2["PING"] = "ping"; - StreamStat2["FPS"] = "fps"; - StreamStat2["BITRATE"] = "btr"; - StreamStat2["DECODE_TIME"] = "dt"; - StreamStat2["PACKETS_LOST"] = "pl"; - StreamStat2["FRAMES_LOST"] = "fl"; -})(StreamStat || (StreamStat = {})); - class StreamStats { static instance; static getInstance() { @@ -915,7 +740,7 @@ class StreamStats { return; } this.#timeoutId = null; - const startTime = performance.now(), PREF_STATS_CONDITIONAL_FORMATTING = getPref(PrefKey.STATS_CONDITIONAL_FORMATTING), stats = await STATES.currentStream.peerConnection.getStats(); + const startTime = performance.now(), PREF_STATS_CONDITIONAL_FORMATTING = getPref("stats_conditional_formatting"), stats = await STATES.currentStream.peerConnection.getStats(); let grade = ""; stats.forEach((stat) => { if (stat.type === "inbound-rtp" && stat.kind === "video") { @@ -947,21 +772,21 @@ class StreamStats { this.#timeoutId = window.setTimeout(this.#update.bind(this), this.#updateInterval - lapsedTime); } refreshStyles() { - const PREF_ITEMS = getPref(PrefKey.STATS_ITEMS), PREF_POSITION = getPref(PrefKey.STATS_POSITION), PREF_TRANSPARENT = getPref(PrefKey.STATS_TRANSPARENT), PREF_OPACITY = getPref(PrefKey.STATS_OPACITY), PREF_TEXT_SIZE = getPref(PrefKey.STATS_TEXT_SIZE), $container = this.#$container; + const PREF_ITEMS = getPref("stats_items"), PREF_POSITION = getPref("stats_position"), PREF_TRANSPARENT = getPref("stats_transparent"), PREF_OPACITY = getPref("stats_opacity"), PREF_TEXT_SIZE = getPref("stats_text_size"), $container = this.#$container; $container.dataset.stats = "[" + PREF_ITEMS.join("][") + "]", $container.dataset.position = PREF_POSITION, $container.dataset.transparent = PREF_TRANSPARENT, $container.style.opacity = PREF_OPACITY + "%", $container.style.fontSize = PREF_TEXT_SIZE; } hideSettingsUi() { - if (this.isGlancing() && !getPref(PrefKey.STATS_QUICK_GLANCE)) + if (this.isGlancing() && !getPref("stats_quick_glance")) this.stop(); } #render() { const stats = { - [StreamStat.PING]: [t("stat-ping"), this.#$ping = CE("span", {}, "0")], - [StreamStat.FPS]: [t("stat-fps"), this.#$fps = CE("span", {}, "0")], - [StreamStat.BITRATE]: [t("stat-bitrate"), this.#$br = CE("span", {}, "0 Mbps")], - [StreamStat.DECODE_TIME]: [t("stat-decode-time"), this.#$dt = CE("span", {}, "0ms")], - [StreamStat.PACKETS_LOST]: [t("stat-packets-lost"), this.#$pl = CE("span", {}, "0")], - [StreamStat.FRAMES_LOST]: [t("stat-frames-lost"), this.#$fl = CE("span", {}, "0")] + ["ping"]: [t("stat-ping"), this.#$ping = CE("span", {}, "0")], + ["fps"]: [t("stat-fps"), this.#$fps = CE("span", {}, "0")], + ["btr"]: [t("stat-bitrate"), this.#$br = CE("span", {}, "0 Mbps")], + ["dt"]: [t("stat-decode-time"), this.#$dt = CE("span", {}, "0ms")], + ["pl"]: [t("stat-packets-lost"), this.#$pl = CE("span", {}, "0")], + ["fl"]: [t("stat-frames-lost"), this.#$fl = CE("span", {}, "0")] }, $barFragment = document.createDocumentFragment(); let statKey; for (statKey in stats) { @@ -975,7 +800,7 @@ class StreamStats { } static setupEvents() { window.addEventListener(BxEvent.STREAM_PLAYING, (e) => { - const PREF_STATS_QUICK_GLANCE = getPref(PrefKey.STATS_QUICK_GLANCE), PREF_STATS_SHOW_WHEN_PLAYING = getPref(PrefKey.STATS_SHOW_WHEN_PLAYING), streamStats = StreamStats.getInstance(); + const PREF_STATS_QUICK_GLANCE = getPref("stats_quick_glance"), PREF_STATS_SHOW_WHEN_PLAYING = getPref("stats_show_when_playing"), streamStats = StreamStats.getInstance(); if (PREF_STATS_SHOW_WHEN_PLAYING) streamStats.start(); else if (PREF_STATS_QUICK_GLANCE) @@ -987,16 +812,6 @@ class StreamStats { } } -// src/utils/setting-element.ts -var SettingElementType; -(function(SettingElementType2) { - SettingElementType2["OPTIONS"] = "options"; - SettingElementType2["MULTIPLE_OPTIONS"] = "multiple-options"; - SettingElementType2["NUMBER"] = "number"; - SettingElementType2["NUMBER_STEPPER"] = "number-stepper"; - SettingElementType2["CHECKBOX"] = "checkbox"; -})(SettingElementType || (SettingElementType = {})); - class SettingElement { static #renderOptions(key, setting, currentValue, onChange) { const $control = CE("select", { @@ -1142,17 +957,17 @@ class SettingElement { }), $wrapper; } static #METHOD_MAP = { - [SettingElementType.OPTIONS]: SettingElement.#renderOptions, - [SettingElementType.MULTIPLE_OPTIONS]: SettingElement.#renderMultipleOptions, - [SettingElementType.NUMBER]: SettingElement.#renderNumber, - [SettingElementType.NUMBER_STEPPER]: SettingElement.#renderNumberStepper, - [SettingElementType.CHECKBOX]: SettingElement.#renderCheckbox + ["options"]: SettingElement.#renderOptions, + ["multiple-options"]: SettingElement.#renderMultipleOptions, + ["number"]: SettingElement.#renderNumber, + ["number-stepper"]: SettingElement.#renderNumberStepper, + ["checkbox"]: SettingElement.#renderCheckbox }; static render(type, key, setting, currentValue, onChange, options) { const method = SettingElement.#METHOD_MAP[type], $control = method(...Array.from(arguments).slice(1)); - if (type !== SettingElementType.NUMBER_STEPPER) + if (type !== "number-stepper") $control.id = `bx_setting_${key}`; - if (type === SettingElementType.OPTIONS || type === SettingElementType.MULTIPLE_OPTIONS) + if (type === "options" || type === "multiple-options") $control.name = $control.id; return $control; } @@ -1162,13 +977,13 @@ class SettingElement { if ("type" in definition) type = definition.type; else if ("options" in definition) - type = SettingElementType.OPTIONS; + type = "options"; else if ("multipleOptions" in definition) - type = SettingElementType.MULTIPLE_OPTIONS; + type = "multiple-options"; else if (typeof definition.default === "number") - type = SettingElementType.NUMBER; + type = "number"; else - type = SettingElementType.CHECKBOX; + type = "checkbox"; const params = Object.assign(overrideParams, definition.params || {}); if (params.disabled) currentValue = definition.default; @@ -1178,7 +993,6 @@ class SettingElement { } } -// src/utils/settings-storages/base-settings-storage.ts class BaseSettingsStore { storage; storageKey; @@ -1252,8 +1066,7 @@ class BaseSettingsStore { } } -// src/utils/settings-storages/global-settings-storage.ts -var getSupportedCodecProfiles = function() { +function getSupportedCodecProfiles() { const options = { default: t("default") }; @@ -1288,29 +1101,29 @@ var getSupportedCodecProfiles = function() { else options.low = t("visual-quality-low"); return options; -}; +} class GlobalSettingsStorage extends BaseSettingsStore { static DEFINITIONS = { - [PrefKey.LAST_UPDATE_CHECK]: { + version_last_check: { default: 0 }, - [PrefKey.LATEST_VERSION]: { + version_latest: { default: "" }, - [PrefKey.CURRENT_VERSION]: { + version_current: { default: "" }, - [PrefKey.BETTER_XCLOUD_LOCALE]: { + bx_locale: { label: t("language"), default: localStorage.getItem("better_xcloud_locale") || "en-US", options: SUPPORTED_LANGUAGES }, - [PrefKey.SERVER_REGION]: { + server_region: { label: t("region"), default: "default" }, - [PrefKey.SERVER_BYPASS_RESTRICTION]: { + server_bypass_restriction: { label: t("bypass-region-restriction"), note: "⚠️ " + t("use-this-at-your-own-risk"), default: "off", @@ -1319,7 +1132,7 @@ class GlobalSettingsStorage extends BaseSettingsStore { off: t("off") }, BypassServers) }, - [PrefKey.STREAM_PREFERRED_LOCALE]: { + stream_preferred_locale: { label: t("preferred-game-language"), default: "default", options: { @@ -1353,7 +1166,7 @@ class GlobalSettingsStorage extends BaseSettingsStore { "zh-TW": "中文 (繁體)" } }, - [PrefKey.STREAM_TARGET_RESOLUTION]: { + stream_target_resolution: { label: t("target-resolution"), default: "auto", options: { @@ -1362,7 +1175,7 @@ class GlobalSettingsStorage extends BaseSettingsStore { "720p": "720p" } }, - [PrefKey.STREAM_CODEC_PROFILE]: { + stream_codec_profile: { label: t("visual-quality"), default: "default", options: getSupportedCodecProfiles(), @@ -1372,29 +1185,29 @@ class GlobalSettingsStorage extends BaseSettingsStore { setting.unsupported = !0, setting.note = "⚠️ " + t("browser-unsupported-feature"); } }, - [PrefKey.PREFER_IPV6_SERVER]: { + prefer_ipv6_server: { label: t("prefer-ipv6-server"), default: !1 }, - [PrefKey.SCREENSHOT_APPLY_FILTERS]: { + screenshot_apply_filters: { label: t("screenshot-apply-filters"), default: !1 }, - [PrefKey.SKIP_SPLASH_VIDEO]: { + skip_splash_video: { label: t("skip-splash-video"), default: !1 }, - [PrefKey.HIDE_DOTS_ICON]: { + hide_dots_icon: { label: t("hide-system-menu-icon"), default: !1 }, - [PrefKey.STREAM_COMBINE_SOURCES]: { + stream_combine_sources: { label: t("combine-audio-video-streams"), default: !1, experimental: !0, note: t("combine-audio-video-streams-summary") }, - [PrefKey.STREAM_TOUCH_CONTROLLER]: { + stream_touch_controller: { label: t("tc-availability"), default: "all", options: { @@ -1408,13 +1221,13 @@ class GlobalSettingsStorage extends BaseSettingsStore { setting.default = "default"; } }, - [PrefKey.STREAM_TOUCH_CONTROLLER_AUTO_OFF]: { + stream_touch_controller_auto_off: { label: t("tc-auto-off"), default: !1, unsupported: !STATES.userAgent.capabilities.touch }, - [PrefKey.STREAM_TOUCH_CONTROLLER_DEFAULT_OPACITY]: { - type: SettingElementType.NUMBER_STEPPER, + stream_touch_controller_default_opacity: { + type: "number-stepper", label: t("tc-default-opacity"), default: 100, min: 10, @@ -1427,7 +1240,7 @@ class GlobalSettingsStorage extends BaseSettingsStore { }, unsupported: !STATES.userAgent.capabilities.touch }, - [PrefKey.STREAM_TOUCH_CONTROLLER_STYLE_STANDARD]: { + stream_touch_controller_style_standard: { label: t("tc-standard-layout-style"), default: "default", options: { @@ -1437,7 +1250,7 @@ class GlobalSettingsStorage extends BaseSettingsStore { }, unsupported: !STATES.userAgent.capabilities.touch }, - [PrefKey.STREAM_TOUCH_CONTROLLER_STYLE_CUSTOM]: { + stream_touch_controller_style_custom: { label: t("tc-custom-layout-style"), default: "default", options: { @@ -1446,20 +1259,20 @@ class GlobalSettingsStorage extends BaseSettingsStore { }, unsupported: !STATES.userAgent.capabilities.touch }, - [PrefKey.STREAM_SIMPLIFY_MENU]: { + stream_simplify_menu: { label: t("simplify-stream-menu"), default: !1 }, - [PrefKey.MKB_HIDE_IDLE_CURSOR]: { + mkb_hide_idle_cursor: { label: t("hide-idle-cursor"), default: !1 }, - [PrefKey.STREAM_DISABLE_FEEDBACK_DIALOG]: { + stream_disable_feedback_dialog: { label: t("disable-post-stream-feedback-dialog"), default: !1 }, - [PrefKey.BITRATE_VIDEO_MAX]: { - type: SettingElementType.NUMBER_STEPPER, + bitrate_video_max: { + type: "number-stepper", label: t("bitrate-video-maximum"), note: "⚠️ " + t("unexpected-behavior"), default: 0, @@ -1476,7 +1289,7 @@ class GlobalSettingsStorage extends BaseSettingsStore { } } }, - [PrefKey.GAME_BAR_POSITION]: { + game_bar_position: { label: t("position"), default: "bottom-left", options: { @@ -1485,7 +1298,7 @@ class GlobalSettingsStorage extends BaseSettingsStore { off: t("off") } }, - [PrefKey.LOCAL_CO_OP_ENABLED]: { + local_co_op_enabled: { label: t("enable-local-co-op-support"), default: !1, note: CE("a", { @@ -1493,18 +1306,18 @@ class GlobalSettingsStorage extends BaseSettingsStore { target: "_blank" }, t("enable-local-co-op-support-note")) }, - [PrefKey.CONTROLLER_SHOW_CONNECTION_STATUS]: { + controller_show_connection_status: { label: t("show-controller-connection-status"), default: !0 }, - [PrefKey.CONTROLLER_ENABLE_SHORTCUTS]: { + controller_enable_shortcuts: { default: !1 }, - [PrefKey.CONTROLLER_ENABLE_VIBRATION]: { + controller_enable_vibration: { label: t("controller-vibration"), default: !0 }, - [PrefKey.CONTROLLER_DEVICE_VIBRATION]: { + controller_device_vibration: { label: t("device-vibration"), default: "off", options: { @@ -1513,9 +1326,9 @@ class GlobalSettingsStorage extends BaseSettingsStore { off: t("off") } }, - [PrefKey.CONTROLLER_VIBRATION_INTENSITY]: { + controller_vibration_intensity: { label: t("vibration-intensity"), - type: SettingElementType.NUMBER_STEPPER, + type: "number-stepper", default: 100, min: 0, max: 100, @@ -1525,7 +1338,7 @@ class GlobalSettingsStorage extends BaseSettingsStore { ticks: 10 } }, - [PrefKey.MKB_ENABLED]: { + mkb_enabled: { label: t("enable-mkb"), default: !1, unsupported: (() => { @@ -1544,7 +1357,7 @@ class GlobalSettingsStorage extends BaseSettingsStore { }, "⚠️ " + note); } }, - [PrefKey.NATIVE_MKB_ENABLED]: { + native_mkb_enabled: { label: t("native-mkb"), default: "default", options: { @@ -1561,9 +1374,9 @@ class GlobalSettingsStorage extends BaseSettingsStore { delete setting.options.on; } }, - [PrefKey.NATIVE_MKB_SCROLL_HORIZONTAL_SENSITIVITY]: { + native_mkb_scroll_x_sensitivity: { label: t("horizontal-scroll-sensitivity"), - type: SettingElementType.NUMBER_STEPPER, + type: "number-stepper", default: 0, min: 0, max: 1e4, @@ -1577,9 +1390,9 @@ class GlobalSettingsStorage extends BaseSettingsStore { } } }, - [PrefKey.NATIVE_MKB_SCROLL_VERTICAL_SENSITIVITY]: { + native_mkb_scroll_y_sensitivity: { label: t("vertical-scroll-sensitivity"), - type: SettingElementType.NUMBER_STEPPER, + type: "number-stepper", default: 0, min: 0, max: 1e4, @@ -1593,25 +1406,25 @@ class GlobalSettingsStorage extends BaseSettingsStore { } } }, - [PrefKey.MKB_DEFAULT_PRESET_ID]: { + mkb_default_preset_id: { default: 0 }, - [PrefKey.MKB_ABSOLUTE_MOUSE]: { + mkb_absolute_mouse: { default: !1 }, - [PrefKey.REDUCE_ANIMATIONS]: { + reduce_animations: { label: t("reduce-animations"), default: !1 }, - [PrefKey.UI_LOADING_SCREEN_GAME_ART]: { + ui_loading_screen_game_art: { label: t("show-game-art"), default: !0 }, - [PrefKey.UI_LOADING_SCREEN_WAIT_TIME]: { + ui_loading_screen_wait_time: { label: t("show-wait-time"), default: !0 }, - [PrefKey.UI_LOADING_SCREEN_ROCKET]: { + ui_loading_screen_rocket: { label: t("rocket-animation"), default: "show", options: { @@ -1620,11 +1433,11 @@ class GlobalSettingsStorage extends BaseSettingsStore { hide: t("rocket-always-hide") } }, - [PrefKey.UI_CONTROLLER_FRIENDLY]: { + ui_controller_friendly: { label: t("controller-friendly-ui"), default: BX_FLAGS.DeviceInfo.deviceType !== "unknown" }, - [PrefKey.UI_LAYOUT]: { + ui_layout: { label: t("layout"), default: "default", options: { @@ -1633,72 +1446,72 @@ class GlobalSettingsStorage extends BaseSettingsStore { tv: t("smart-tv") } }, - [PrefKey.UI_SCROLLBAR_HIDE]: { + ui_scrollbar_hide: { label: t("hide-scrollbar"), default: !1 }, - [PrefKey.UI_HOME_CONTEXT_MENU_DISABLED]: { + ui_home_context_menu_disabled: { label: t("disable-home-context-menu"), default: STATES.browser.capabilities.touch }, - [PrefKey.UI_HIDE_SECTIONS]: { + ui_hide_sections: { label: t("hide-sections"), default: [], multipleOptions: { - [UiSection.NEWS]: t("section-news"), - [UiSection.FRIENDS]: t("section-play-with-friends"), - [UiSection.NATIVE_MKB]: t("section-native-mkb"), - [UiSection.TOUCH]: t("section-touch"), - [UiSection.MOST_POPULAR]: t("section-most-popular"), - [UiSection.ALL_GAMES]: t("section-all-games") + news: t("section-news"), + friends: t("section-play-with-friends"), + "native-mkb": t("section-native-mkb"), + touch: t("section-touch"), + "most-popular": t("section-most-popular"), + "all-games": t("section-all-games") }, params: { size: 6 } }, - [PrefKey.UI_GAME_CARD_SHOW_WAIT_TIME]: { + ui_game_card_show_wait_time: { label: t("show-wait-time-in-game-card"), default: !1 }, - [PrefKey.BLOCK_SOCIAL_FEATURES]: { + block_social_features: { label: t("disable-social-features"), default: !1 }, - [PrefKey.BLOCK_TRACKING]: { + block_tracking: { label: t("disable-xcloud-analytics"), default: !1 }, - [PrefKey.USER_AGENT_PROFILE]: { + user_agent_profile: { label: t("user-agent-profile"), note: "⚠️ " + t("unexpected-behavior"), - default: BX_FLAGS.DeviceInfo.deviceType === "android-tv" ? UserAgentProfile.VR_OCULUS : "default", + default: BX_FLAGS.DeviceInfo.deviceType === "android-tv" ? "vr-oculus" : "default", options: { - [UserAgentProfile.DEFAULT]: t("default"), - [UserAgentProfile.WINDOWS_EDGE]: "Edge + Windows", - [UserAgentProfile.MACOS_SAFARI]: "Safari + macOS", - [UserAgentProfile.VR_OCULUS]: "Android TV", - [UserAgentProfile.SMART_TV_GENERIC]: "Smart TV", - [UserAgentProfile.SMART_TV_TIZEN]: "Samsung Smart TV", - [UserAgentProfile.CUSTOM]: t("custom") + default: t("default"), + "windows-edge": "Edge + Windows", + "macos-safari": "Safari + macOS", + "vr-oculus": "Android TV", + "smarttv-generic": "Smart TV", + "smarttv-tizen": "Samsung Smart TV", + custom: t("custom") } }, - [PrefKey.VIDEO_PLAYER_TYPE]: { + video_player_type: { label: t("renderer"), default: "default", options: { - [StreamPlayerType.VIDEO]: t("default"), - [StreamPlayerType.WEBGL2]: t("webgl2") + default: t("default"), + webgl2: t("webgl2") } }, - [PrefKey.VIDEO_PROCESSING]: { + video_processing: { label: t("clarity-boost"), - default: StreamVideoProcessing.USM, + default: "usm", options: { - [StreamVideoProcessing.USM]: t("unsharp-masking"), - [StreamVideoProcessing.CAS]: t("amd-fidelity-cas") + usm: t("unsharp-masking"), + cas: t("amd-fidelity-cas") } }, - [PrefKey.VIDEO_POWER_PREFERENCE]: { + video_power_preference: { label: t("renderer-configuration"), default: "default", options: { @@ -1707,9 +1520,9 @@ class GlobalSettingsStorage extends BaseSettingsStore { "high-performance": t("high-performance") } }, - [PrefKey.VIDEO_SHARPNESS]: { + video_sharpness: { label: t("sharpness"), - type: SettingElementType.NUMBER_STEPPER, + type: "number-stepper", default: 0, min: 0, max: 10, @@ -1720,7 +1533,7 @@ class GlobalSettingsStorage extends BaseSettingsStore { } } }, - [PrefKey.VIDEO_RATIO]: { + video_ratio: { label: t("aspect-ratio"), note: t("aspect-ratio-note"), default: "16:9", @@ -1733,9 +1546,9 @@ class GlobalSettingsStorage extends BaseSettingsStore { fill: t("stretch") } }, - [PrefKey.VIDEO_SATURATION]: { + video_saturation: { label: t("saturation"), - type: SettingElementType.NUMBER_STEPPER, + type: "number-stepper", default: 100, min: 50, max: 150, @@ -1744,9 +1557,9 @@ class GlobalSettingsStorage extends BaseSettingsStore { ticks: 25 } }, - [PrefKey.VIDEO_CONTRAST]: { + video_contrast: { label: t("contrast"), - type: SettingElementType.NUMBER_STEPPER, + type: "number-stepper", default: 100, min: 50, max: 150, @@ -1755,9 +1568,9 @@ class GlobalSettingsStorage extends BaseSettingsStore { ticks: 25 } }, - [PrefKey.VIDEO_BRIGHTNESS]: { + video_brightness: { label: t("brightness"), - type: SettingElementType.NUMBER_STEPPER, + type: "number-stepper", default: 100, min: 50, max: 150, @@ -1766,17 +1579,17 @@ class GlobalSettingsStorage extends BaseSettingsStore { ticks: 25 } }, - [PrefKey.AUDIO_MIC_ON_PLAYING]: { + audio_mic_on_playing: { label: t("enable-mic-on-startup"), default: !1 }, - [PrefKey.AUDIO_ENABLE_VOLUME_CONTROL]: { + audio_enable_volume_control: { label: t("enable-volume-control"), default: !1 }, - [PrefKey.AUDIO_VOLUME]: { + audio_volume: { label: t("volume"), - type: SettingElementType.NUMBER_STEPPER, + type: "number-stepper", default: 100, min: 0, max: 600, @@ -1786,30 +1599,30 @@ class GlobalSettingsStorage extends BaseSettingsStore { ticks: 100 } }, - [PrefKey.STATS_ITEMS]: { + stats_items: { label: t("stats"), - default: [StreamStat.PING, StreamStat.FPS, StreamStat.BITRATE, StreamStat.DECODE_TIME, StreamStat.PACKETS_LOST, StreamStat.FRAMES_LOST], + default: ["ping", "fps", "btr", "dt", "pl", "fl"], multipleOptions: { - [StreamStat.PING]: `${StreamStat.PING.toUpperCase()}: ${t("stat-ping")}`, - [StreamStat.FPS]: `${StreamStat.FPS.toUpperCase()}: ${t("stat-fps")}`, - [StreamStat.BITRATE]: `${StreamStat.BITRATE.toUpperCase()}: ${t("stat-bitrate")}`, - [StreamStat.DECODE_TIME]: `${StreamStat.DECODE_TIME.toUpperCase()}: ${t("stat-decode-time")}`, - [StreamStat.PACKETS_LOST]: `${StreamStat.PACKETS_LOST.toUpperCase()}: ${t("stat-packets-lost")}`, - [StreamStat.FRAMES_LOST]: `${StreamStat.FRAMES_LOST.toUpperCase()}: ${t("stat-frames-lost")}` + ping: `${"ping".toUpperCase()}: ${t("stat-ping")}`, + fps: `${"fps".toUpperCase()}: ${t("stat-fps")}`, + btr: `${"btr".toUpperCase()}: ${t("stat-bitrate")}`, + dt: `${"dt".toUpperCase()}: ${t("stat-decode-time")}`, + pl: `${"pl".toUpperCase()}: ${t("stat-packets-lost")}`, + fl: `${"fl".toUpperCase()}: ${t("stat-frames-lost")}` }, params: { size: 6 } }, - [PrefKey.STATS_SHOW_WHEN_PLAYING]: { + stats_show_when_playing: { label: t("show-stats-on-startup"), default: !1 }, - [PrefKey.STATS_QUICK_GLANCE]: { + stats_quick_glance: { label: "👀 " + t("enable-quick-glance-mode"), default: !0 }, - [PrefKey.STATS_POSITION]: { + stats_position: { label: t("position"), default: "top-right", options: { @@ -1818,7 +1631,7 @@ class GlobalSettingsStorage extends BaseSettingsStore { "top-right": t("top-right") } }, - [PrefKey.STATS_TEXT_SIZE]: { + stats_text_size: { label: t("text-size"), default: "0.9rem", options: { @@ -1827,13 +1640,13 @@ class GlobalSettingsStorage extends BaseSettingsStore { "1.1rem": t("large") } }, - [PrefKey.STATS_TRANSPARENT]: { + stats_transparent: { label: t("transparent-background"), default: !1 }, - [PrefKey.STATS_OPACITY]: { + stats_opacity: { label: t("opacity"), - type: SettingElementType.NUMBER_STEPPER, + type: "number-stepper", default: 80, min: 50, max: 100, @@ -1843,35 +1656,34 @@ class GlobalSettingsStorage extends BaseSettingsStore { ticks: 10 } }, - [PrefKey.STATS_CONDITIONAL_FORMATTING]: { + stats_conditional_formatting: { label: t("conditional-formatting"), default: !1 }, - [PrefKey.REMOTE_PLAY_ENABLED]: { + xhome_enabled: { label: t("enable-remote-play-feature"), default: !1 }, - [PrefKey.REMOTE_PLAY_RESOLUTION]: { + xhome_resolution: { default: "1080p", options: { "1080p": "1080p", "720p": "720p" } }, - [PrefKey.GAME_FORTNITE_FORCE_CONSOLE]: { + game_fortnite_force_console: { label: "🎮 " + t("fortnite-force-console-version"), default: !1, note: t("fortnite-allow-stw-mode") } }; constructor() { - super(StorageKey.GLOBAL, GlobalSettingsStorage.DEFINITIONS); + super("better_xcloud", GlobalSettingsStorage.DEFINITIONS); } } var globalSettings = new GlobalSettingsStorage, getPrefDefinition = globalSettings.getDefinition.bind(globalSettings), getPref = globalSettings.getSetting.bind(globalSettings), setPref = globalSettings.setSetting.bind(globalSettings); STORAGE.Global = globalSettings; -// src/utils/screenshot.ts class Screenshot { static #$canvas; static #canvasContext; @@ -1899,10 +1711,10 @@ class Screenshot { if (!streamPlayer || !$canvas) return; let $player; - if (getPref(PrefKey.SCREENSHOT_APPLY_FILTERS)) + if (getPref("screenshot_apply_filters")) $player = streamPlayer.getPlayerElement(); else - $player = streamPlayer.getPlayerElement(StreamPlayerType.VIDEO); + $player = streamPlayer.getPlayerElement("default"); if (!$player || !$player.isConnected) return; $player.parentElement.addEventListener("animationend", this.#onAnimationEnd, { once: !0 }), $player.parentElement.classList.add("bx-taking-screenshot"); @@ -1924,140 +1736,55 @@ class Screenshot { } } -// src/enums/prompt-font.ts -var PrompFont; -(function(PrompFont2) { - PrompFont2["A"] = "⇓"; - PrompFont2["B"] = "⇒"; - PrompFont2["X"] = "⇐"; - PrompFont2["Y"] = "⇑"; - PrompFont2["LB"] = "↘"; - PrompFont2["RB"] = "↙"; - PrompFont2["LT"] = "↖"; - PrompFont2["RT"] = "↗"; - PrompFont2["SELECT"] = "⇺"; - PrompFont2["START"] = "⇻"; - PrompFont2["HOME"] = ""; - PrompFont2["UP"] = "≻"; - PrompFont2["DOWN"] = "≽"; - PrompFont2["LEFT"] = "≺"; - PrompFont2["RIGHT"] = "≼"; - PrompFont2["L3"] = "↺"; - PrompFont2["LS_UP"] = "↾"; - PrompFont2["LS_DOWN"] = "⇂"; - PrompFont2["LS_LEFT"] = "↼"; - PrompFont2["LS_RIGHT"] = "⇀"; - PrompFont2["R3"] = "↻"; - PrompFont2["RS_UP"] = "↿"; - PrompFont2["RS_DOWN"] = "⇃"; - PrompFont2["RS_LEFT"] = "↽"; - PrompFont2["RS_RIGHT"] = "⇁"; -})(PrompFont || (PrompFont = {})); - -// src/enums/mkb.ts -var GamepadKey; -(function(GamepadKey2) { - GamepadKey2[GamepadKey2["A"] = 0] = "A"; - GamepadKey2[GamepadKey2["B"] = 1] = "B"; - GamepadKey2[GamepadKey2["X"] = 2] = "X"; - GamepadKey2[GamepadKey2["Y"] = 3] = "Y"; - GamepadKey2[GamepadKey2["LB"] = 4] = "LB"; - GamepadKey2[GamepadKey2["RB"] = 5] = "RB"; - GamepadKey2[GamepadKey2["LT"] = 6] = "LT"; - GamepadKey2[GamepadKey2["RT"] = 7] = "RT"; - GamepadKey2[GamepadKey2["SELECT"] = 8] = "SELECT"; - GamepadKey2[GamepadKey2["START"] = 9] = "START"; - GamepadKey2[GamepadKey2["L3"] = 10] = "L3"; - GamepadKey2[GamepadKey2["R3"] = 11] = "R3"; - GamepadKey2[GamepadKey2["UP"] = 12] = "UP"; - GamepadKey2[GamepadKey2["DOWN"] = 13] = "DOWN"; - GamepadKey2[GamepadKey2["LEFT"] = 14] = "LEFT"; - GamepadKey2[GamepadKey2["RIGHT"] = 15] = "RIGHT"; - GamepadKey2[GamepadKey2["HOME"] = 16] = "HOME"; - GamepadKey2[GamepadKey2["SHARE"] = 17] = "SHARE"; - GamepadKey2[GamepadKey2["LS_UP"] = 100] = "LS_UP"; - GamepadKey2[GamepadKey2["LS_DOWN"] = 101] = "LS_DOWN"; - GamepadKey2[GamepadKey2["LS_LEFT"] = 102] = "LS_LEFT"; - GamepadKey2[GamepadKey2["LS_RIGHT"] = 103] = "LS_RIGHT"; - GamepadKey2[GamepadKey2["RS_UP"] = 200] = "RS_UP"; - GamepadKey2[GamepadKey2["RS_DOWN"] = 201] = "RS_DOWN"; - GamepadKey2[GamepadKey2["RS_LEFT"] = 202] = "RS_LEFT"; - GamepadKey2[GamepadKey2["RS_RIGHT"] = 203] = "RS_RIGHT"; -})(GamepadKey || (GamepadKey = {})); var GamepadKeyName = { - [GamepadKey.A]: ["A", PrompFont.A], - [GamepadKey.B]: ["B", PrompFont.B], - [GamepadKey.X]: ["X", PrompFont.X], - [GamepadKey.Y]: ["Y", PrompFont.Y], - [GamepadKey.LB]: ["LB", PrompFont.LB], - [GamepadKey.RB]: ["RB", PrompFont.RB], - [GamepadKey.LT]: ["LT", PrompFont.LT], - [GamepadKey.RT]: ["RT", PrompFont.RT], - [GamepadKey.SELECT]: ["Select", PrompFont.SELECT], - [GamepadKey.START]: ["Start", PrompFont.START], - [GamepadKey.HOME]: ["Home", PrompFont.HOME], - [GamepadKey.UP]: ["D-Pad Up", PrompFont.UP], - [GamepadKey.DOWN]: ["D-Pad Down", PrompFont.DOWN], - [GamepadKey.LEFT]: ["D-Pad Left", PrompFont.LEFT], - [GamepadKey.RIGHT]: ["D-Pad Right", PrompFont.RIGHT], - [GamepadKey.L3]: ["L3", PrompFont.L3], - [GamepadKey.LS_UP]: ["Left Stick Up", PrompFont.LS_UP], - [GamepadKey.LS_DOWN]: ["Left Stick Down", PrompFont.LS_DOWN], - [GamepadKey.LS_LEFT]: ["Left Stick Left", PrompFont.LS_LEFT], - [GamepadKey.LS_RIGHT]: ["Left Stick Right", PrompFont.LS_RIGHT], - [GamepadKey.R3]: ["R3", PrompFont.R3], - [GamepadKey.RS_UP]: ["Right Stick Up", PrompFont.RS_UP], - [GamepadKey.RS_DOWN]: ["Right Stick Down", PrompFont.RS_DOWN], - [GamepadKey.RS_LEFT]: ["Right Stick Left", PrompFont.RS_LEFT], - [GamepadKey.RS_RIGHT]: ["Right Stick Right", PrompFont.RS_RIGHT] -}, GamepadStick; -(function(GamepadStick2) { - GamepadStick2[GamepadStick2["LEFT"] = 0] = "LEFT"; - GamepadStick2[GamepadStick2["RIGHT"] = 1] = "RIGHT"; -})(GamepadStick || (GamepadStick = {})); -var MouseButtonCode; -(function(MouseButtonCode2) { - MouseButtonCode2["LEFT_CLICK"] = "Mouse0"; - MouseButtonCode2["RIGHT_CLICK"] = "Mouse2"; - MouseButtonCode2["MIDDLE_CLICK"] = "Mouse1"; -})(MouseButtonCode || (MouseButtonCode = {})); + [0]: ["A", "⇓"], + [1]: ["B", "⇒"], + [2]: ["X", "⇐"], + [3]: ["Y", "⇑"], + [4]: ["LB", "↘"], + [5]: ["RB", "↙"], + [6]: ["LT", "↖"], + [7]: ["RT", "↗"], + [8]: ["Select", "⇺"], + [9]: ["Start", "⇻"], + [16]: ["Home", ""], + [12]: ["D-Pad Up", "≻"], + [13]: ["D-Pad Down", "≽"], + [14]: ["D-Pad Left", "≺"], + [15]: ["D-Pad Right", "≼"], + [10]: ["L3", "↺"], + [100]: ["Left Stick Up", "↾"], + [101]: ["Left Stick Down", "⇂"], + [102]: ["Left Stick Left", "↼"], + [103]: ["Left Stick Right", "⇀"], + [11]: ["R3", "↻"], + [200]: ["Right Stick Up", "↿"], + [201]: ["Right Stick Down", "⇃"], + [202]: ["Right Stick Left", "↽"], + [203]: ["Right Stick Right", "⇁"] +}; var MouseMapTo; -(function(MouseMapTo2) { - MouseMapTo2[MouseMapTo2["OFF"] = 0] = "OFF"; - MouseMapTo2[MouseMapTo2["LS"] = 1] = "LS"; - MouseMapTo2[MouseMapTo2["RS"] = 2] = "RS"; -})(MouseMapTo || (MouseMapTo = {})); -var WheelCode; -(function(WheelCode2) { - WheelCode2["SCROLL_UP"] = "ScrollUp"; - WheelCode2["SCROLL_DOWN"] = "ScrollDown"; - WheelCode2["SCROLL_LEFT"] = "ScrollLeft"; - WheelCode2["SCROLL_RIGHT"] = "ScrollRight"; -})(WheelCode || (WheelCode = {})); -var MkbPresetKey; -(function(MkbPresetKey2) { - MkbPresetKey2["MOUSE_MAP_TO"] = "map_to"; - MkbPresetKey2["MOUSE_SENSITIVITY_X"] = "sensitivity_x"; - MkbPresetKey2["MOUSE_SENSITIVITY_Y"] = "sensitivity_y"; - MkbPresetKey2["MOUSE_DEADZONE_COUNTERWEIGHT"] = "deadzone_counterweight"; -})(MkbPresetKey || (MkbPresetKey = {})); +((MouseMapTo2) => { + MouseMapTo2[MouseMapTo2.OFF = 0] = "OFF"; + MouseMapTo2[MouseMapTo2.LS = 1] = "LS"; + MouseMapTo2[MouseMapTo2.RS = 2] = "RS"; +})(MouseMapTo ||= {}); -// src/modules/mkb/mkb-preset.ts class MkbPreset { static MOUSE_SETTINGS = { - [MkbPresetKey.MOUSE_MAP_TO]: { + map_to: { label: t("map-mouse-to"), - type: SettingElementType.OPTIONS, - default: MouseMapTo[MouseMapTo.RS], + type: "options", + default: MouseMapTo[2], options: { - [MouseMapTo[MouseMapTo.RS]]: t("right-stick"), - [MouseMapTo[MouseMapTo.LS]]: t("left-stick"), - [MouseMapTo[MouseMapTo.OFF]]: t("off") + [MouseMapTo[2]]: t("right-stick"), + [MouseMapTo[1]]: t("left-stick"), + [MouseMapTo[0]]: t("off") } }, - [MkbPresetKey.MOUSE_SENSITIVITY_Y]: { + sensitivity_y: { label: t("horizontal-sensitivity"), - type: SettingElementType.NUMBER_STEPPER, + type: "number-stepper", default: 50, min: 1, max: 300, @@ -2066,9 +1793,9 @@ class MkbPreset { exactTicks: 50 } }, - [MkbPresetKey.MOUSE_SENSITIVITY_X]: { + sensitivity_x: { label: t("vertical-sensitivity"), - type: SettingElementType.NUMBER_STEPPER, + type: "number-stepper", default: 50, min: 1, max: 300, @@ -2077,9 +1804,9 @@ class MkbPreset { exactTicks: 50 } }, - [MkbPresetKey.MOUSE_DEADZONE_COUNTERWEIGHT]: { + deadzone_counterweight: { label: t("deadzone-counterweight"), - type: SettingElementType.NUMBER_STEPPER, + type: "number-stepper", default: 20, min: 1, max: 50, @@ -2091,37 +1818,37 @@ class MkbPreset { }; static DEFAULT_PRESET = { mapping: { - [GamepadKey.UP]: ["ArrowUp"], - [GamepadKey.DOWN]: ["ArrowDown"], - [GamepadKey.LEFT]: ["ArrowLeft"], - [GamepadKey.RIGHT]: ["ArrowRight"], - [GamepadKey.LS_UP]: ["KeyW"], - [GamepadKey.LS_DOWN]: ["KeyS"], - [GamepadKey.LS_LEFT]: ["KeyA"], - [GamepadKey.LS_RIGHT]: ["KeyD"], - [GamepadKey.RS_UP]: ["KeyI"], - [GamepadKey.RS_DOWN]: ["KeyK"], - [GamepadKey.RS_LEFT]: ["KeyJ"], - [GamepadKey.RS_RIGHT]: ["KeyL"], - [GamepadKey.A]: ["Space", "KeyE"], - [GamepadKey.X]: ["KeyR"], - [GamepadKey.B]: ["ControlLeft", "Backspace"], - [GamepadKey.Y]: ["KeyV"], - [GamepadKey.START]: ["Enter"], - [GamepadKey.SELECT]: ["Tab"], - [GamepadKey.LB]: ["KeyC", "KeyG"], - [GamepadKey.RB]: ["KeyQ"], - [GamepadKey.HOME]: ["Backquote"], - [GamepadKey.RT]: [MouseButtonCode.LEFT_CLICK], - [GamepadKey.LT]: [MouseButtonCode.RIGHT_CLICK], - [GamepadKey.L3]: ["ShiftLeft"], - [GamepadKey.R3]: ["KeyF"] + 12: ["ArrowUp"], + 13: ["ArrowDown"], + 14: ["ArrowLeft"], + 15: ["ArrowRight"], + 100: ["KeyW"], + 101: ["KeyS"], + 102: ["KeyA"], + 103: ["KeyD"], + 200: ["KeyI"], + 201: ["KeyK"], + 202: ["KeyJ"], + 203: ["KeyL"], + 0: ["Space", "KeyE"], + 2: ["KeyR"], + 1: ["ControlLeft", "Backspace"], + 3: ["KeyV"], + 9: ["Enter"], + 8: ["Tab"], + 4: ["KeyC", "KeyG"], + 5: ["KeyQ"], + 16: ["Backquote"], + 7: ["Mouse0"], + 6: ["Mouse2"], + 10: ["ShiftLeft"], + 11: ["KeyF"] }, mouse: { - [MkbPresetKey.MOUSE_MAP_TO]: MouseMapTo[MouseMapTo.RS], - [MkbPresetKey.MOUSE_SENSITIVITY_X]: 100, - [MkbPresetKey.MOUSE_SENSITIVITY_Y]: 100, - [MkbPresetKey.MOUSE_DEADZONE_COUNTERWEIGHT]: 20 + map_to: MouseMapTo[2], + sensitivity_x: 100, + sensitivity_y: 100, + deadzone_counterweight: 20 } }; static convert(preset) { @@ -2133,17 +1860,16 @@ class MkbPreset { for (let keyName of preset.mapping[parseInt(buttonIndex)]) obj.mapping[keyName] = parseInt(buttonIndex); const mouse = obj.mouse; - mouse[MkbPresetKey.MOUSE_SENSITIVITY_X] *= EmulatedMkbHandler.DEFAULT_PANNING_SENSITIVITY, mouse[MkbPresetKey.MOUSE_SENSITIVITY_Y] *= EmulatedMkbHandler.DEFAULT_PANNING_SENSITIVITY, mouse[MkbPresetKey.MOUSE_DEADZONE_COUNTERWEIGHT] *= EmulatedMkbHandler.DEFAULT_DEADZONE_COUNTERWEIGHT; - const mouseMapTo = MouseMapTo[mouse[MkbPresetKey.MOUSE_MAP_TO]]; + mouse["sensitivity_x"] *= EmulatedMkbHandler.DEFAULT_PANNING_SENSITIVITY, mouse["sensitivity_y"] *= EmulatedMkbHandler.DEFAULT_PANNING_SENSITIVITY, mouse["deadzone_counterweight"] *= EmulatedMkbHandler.DEFAULT_DEADZONE_COUNTERWEIGHT; + const mouseMapTo = MouseMapTo[mouse["map_to"]]; if (typeof mouseMapTo !== "undefined") - mouse[MkbPresetKey.MOUSE_MAP_TO] = mouseMapTo; + mouse["map_to"] = mouseMapTo; else - mouse[MkbPresetKey.MOUSE_MAP_TO] = MkbPreset.MOUSE_SETTINGS[MkbPresetKey.MOUSE_MAP_TO].default; + mouse["map_to"] = MkbPreset.MOUSE_SETTINGS["map_to"].default; return console.log(obj), obj; } } -// src/utils/toast.ts class Toast { static #$wrapper; static #$msg; @@ -2192,7 +1918,6 @@ class Toast { } } -// src/utils/local-db.ts class LocalDb { static #instance; static get INSTANCE() { @@ -2284,24 +2009,23 @@ class LocalDb { }; return new Promise((resolve) => { this.#add(table, preset).then(([table2, id2]) => { - preset.id = id2, setPref(PrefKey.MKB_DEFAULT_PRESET_ID, id2), resolve({ [id2]: preset }); + preset.id = id2, setPref("mkb_default_preset_id", id2), resolve({ [id2]: preset }); }); }); }); } } -// src/modules/mkb/key-helper.ts class KeyHelper { static #NON_PRINTABLE_KEYS = { Backquote: "`", - [MouseButtonCode.LEFT_CLICK]: "Left Click", - [MouseButtonCode.RIGHT_CLICK]: "Right Click", - [MouseButtonCode.MIDDLE_CLICK]: "Middle Click", - [WheelCode.SCROLL_UP]: "Scroll Up", - [WheelCode.SCROLL_DOWN]: "Scroll Down", - [WheelCode.SCROLL_LEFT]: "Scroll Left", - [WheelCode.SCROLL_RIGHT]: "Scroll Right" + Mouse0: "Left Click", + Mouse2: "Right Click", + Mouse1: "Middle Click", + ScrollUp: "Scroll Up", + ScrollDown: "Scroll Down", + ScrollLeft: "Scroll Left", + ScrollRight: "Scroll Right" }; static getKeyFromEvent(e) { let code, name; @@ -2309,13 +2033,13 @@ class KeyHelper { code = e.code || e.key; else if (e instanceof WheelEvent) { if (e.deltaY < 0) - code = WheelCode.SCROLL_UP; + code = "ScrollUp"; else if (e.deltaY > 0) - code = WheelCode.SCROLL_DOWN; + code = "ScrollDown"; else if (e.deltaX < 0) - code = WheelCode.SCROLL_LEFT; + code = "ScrollLeft"; else if (e.deltaX > 0) - code = WheelCode.SCROLL_RIGHT; + code = "ScrollRight"; } else if (e instanceof MouseEvent) code = "Mouse" + e.button; if (code) @@ -2327,16 +2051,7 @@ class KeyHelper { } } -// src/modules/mkb/pointer-client.ts -var LOG_TAG = "PointerClient", PointerAction; -(function(PointerAction2) { - PointerAction2[PointerAction2["MOVE"] = 1] = "MOVE"; - PointerAction2[PointerAction2["BUTTON_PRESS"] = 2] = "BUTTON_PRESS"; - PointerAction2[PointerAction2["BUTTON_RELEASE"] = 3] = "BUTTON_RELEASE"; - PointerAction2[PointerAction2["SCROLL"] = 4] = "SCROLL"; - PointerAction2[PointerAction2["POINTER_CAPTURE_CHANGED"] = 5] = "POINTER_CAPTURE_CHANGED"; -})(PointerAction || (PointerAction = {})); - +var LOG_TAG = "PointerClient"; class PointerClient { static instance; static getInstance() { @@ -2359,17 +2074,17 @@ class PointerClient { const dataView = new DataView(event.data); let messageType = dataView.getInt8(0), offset = Int8Array.BYTES_PER_ELEMENT; switch (messageType) { - case PointerAction.MOVE: + case 1: this.onMove(dataView, offset); break; - case PointerAction.BUTTON_PRESS: - case PointerAction.BUTTON_RELEASE: + case 2: + case 3: this.onPress(messageType, dataView, offset); break; - case PointerAction.SCROLL: + case 4: this.onScroll(dataView, offset); break; - case PointerAction.POINTER_CAPTURE_CHANGED: + case 5: this.onPointerCaptureChanged(dataView, offset); } }); @@ -2387,7 +2102,7 @@ class PointerClient { const button = dataView.getUint8(offset); this.#mkbHandler?.handleMouseClick({ pointerButton: button, - pressed: messageType === PointerAction.BUTTON_PRESS + pressed: messageType === 2 }); } onScroll(dataView, offset) { @@ -2411,7 +2126,6 @@ class PointerClient { } } -// src/modules/mkb/base-mkb-handler.ts class MouseDataProvider { mkbHandler; constructor(handler) { @@ -2422,7 +2136,6 @@ class MouseDataProvider { class MkbHandler { } -// src/modules/mkb/native-mkb-handler.ts class NativeMkbHandler extends MkbHandler { static instance; #pointerClient; @@ -2506,7 +2219,7 @@ class NativeMkbHandler extends MkbHandler { } catch (e) { Toast.show("Cannot enable Mouse & Keyboard feature"); } - if (this.#mouseVerticalMultiply = getPref(PrefKey.NATIVE_MKB_SCROLL_VERTICAL_SENSITIVITY), this.#mouseHorizontalMultiply = getPref(PrefKey.NATIVE_MKB_SCROLL_HORIZONTAL_SENSITIVITY), window.addEventListener("keyup", this), window.addEventListener(BxEvent.XCLOUD_DIALOG_SHOWN, this), window.addEventListener(BxEvent.POINTER_LOCK_REQUESTED, this), window.addEventListener(BxEvent.POINTER_LOCK_EXITED, this), window.addEventListener(BxEvent.XCLOUD_POLLING_MODE_CHANGED, this), this.#initMessage(), AppInterface) + if (this.#mouseVerticalMultiply = getPref("native_mkb_scroll_y_sensitivity"), this.#mouseHorizontalMultiply = getPref("native_mkb_scroll_x_sensitivity"), window.addEventListener("keyup", this), window.addEventListener(BxEvent.XCLOUD_DIALOG_SHOWN, this), window.addEventListener(BxEvent.POINTER_LOCK_REQUESTED, this), window.addEventListener(BxEvent.POINTER_LOCK_EXITED, this), window.addEventListener(BxEvent.XCLOUD_POLLING_MODE_CHANGED, this), this.#initMessage(), AppInterface) Toast.show(t("press-key-to-toggle-mkb", { key: "F8" }), t("native-mkb"), { html: !0 }), this.#$message?.classList.add("bx-gone"); else this.#$message?.classList.remove("bx-gone"); @@ -2601,43 +2314,33 @@ class NativeMkbHandler extends MkbHandler { } } -// src/modules/stream/stream-settings-utils.ts function onChangeVideoPlayerType() { - const playerType = getPref(PrefKey.VIDEO_PLAYER_TYPE), $videoProcessing = document.getElementById("bx_setting_video_processing"), $videoSharpness = document.getElementById("bx_setting_video_sharpness"), $videoPowerPreference = document.getElementById("bx_setting_video_power_preference"); + const playerType = getPref("video_player_type"), $videoProcessing = document.getElementById("bx_setting_video_processing"), $videoSharpness = document.getElementById("bx_setting_video_sharpness"), $videoPowerPreference = document.getElementById("bx_setting_video_power_preference"); if (!$videoProcessing) return; let isDisabled = !1; - const $optCas = $videoProcessing.querySelector(`option[value=${StreamVideoProcessing.CAS}]`); - if (playerType === StreamPlayerType.WEBGL2) + const $optCas = $videoProcessing.querySelector(`option[value=${"cas"}]`); + if (playerType === "webgl2") $optCas && ($optCas.disabled = !1); - else if ($videoProcessing.value = StreamVideoProcessing.USM, setPref(PrefKey.VIDEO_PROCESSING, StreamVideoProcessing.USM), $optCas && ($optCas.disabled = !0), UserAgent.isSafari()) + else if ($videoProcessing.value = "usm", setPref("video_processing", "usm"), $optCas && ($optCas.disabled = !0), UserAgent.isSafari()) isDisabled = !0; - $videoProcessing.disabled = isDisabled, $videoSharpness.dataset.disabled = isDisabled.toString(), $videoPowerPreference.closest(".bx-settings-row").classList.toggle("bx-gone", playerType !== StreamPlayerType.WEBGL2), updateVideoPlayer(); + $videoProcessing.disabled = isDisabled, $videoSharpness.dataset.disabled = isDisabled.toString(), $videoPowerPreference.closest(".bx-settings-row").classList.toggle("bx-gone", playerType !== "webgl2"), updateVideoPlayer(); } function updateVideoPlayer() { const streamPlayer = STATES.currentStream.streamPlayer; if (!streamPlayer) return; const options = { - processing: getPref(PrefKey.VIDEO_PROCESSING), - sharpness: getPref(PrefKey.VIDEO_SHARPNESS), - saturation: getPref(PrefKey.VIDEO_SATURATION), - contrast: getPref(PrefKey.VIDEO_CONTRAST), - brightness: getPref(PrefKey.VIDEO_BRIGHTNESS) + processing: getPref("video_processing"), + sharpness: getPref("video_sharpness"), + saturation: getPref("video_saturation"), + contrast: getPref("video_contrast"), + brightness: getPref("video_brightness") }; - streamPlayer.setPlayerType(getPref(PrefKey.VIDEO_PLAYER_TYPE)), streamPlayer.updateOptions(options), streamPlayer.refreshPlayer(); + streamPlayer.setPlayerType(getPref("video_player_type")), streamPlayer.updateOptions(options), streamPlayer.refreshPlayer(); } window.addEventListener("resize", updateVideoPlayer); -// src/modules/ui/dialog/navigation-dialog.ts -var NavigationDirection; -(function(NavigationDirection2) { - NavigationDirection2[NavigationDirection2["UP"] = 1] = "UP"; - NavigationDirection2[NavigationDirection2["RIGHT"] = 2] = "RIGHT"; - NavigationDirection2[NavigationDirection2["DOWN"] = 3] = "DOWN"; - NavigationDirection2[NavigationDirection2["LEFT"] = 4] = "LEFT"; -})(NavigationDirection || (NavigationDirection = {})); - class NavigationDialog { dialogManager; constructor() { @@ -2683,35 +2386,35 @@ class NavigationDialogManager { } static GAMEPAD_POLLING_INTERVAL = 50; static GAMEPAD_KEYS = [ - GamepadKey.UP, - GamepadKey.DOWN, - GamepadKey.LEFT, - GamepadKey.RIGHT, - GamepadKey.A, - GamepadKey.B, - GamepadKey.LB, - GamepadKey.RB, - GamepadKey.LT, - GamepadKey.RT + 12, + 13, + 14, + 15, + 0, + 1, + 4, + 5, + 6, + 7 ]; static GAMEPAD_DIRECTION_MAP = { - [GamepadKey.UP]: NavigationDirection.UP, - [GamepadKey.DOWN]: NavigationDirection.DOWN, - [GamepadKey.LEFT]: NavigationDirection.LEFT, - [GamepadKey.RIGHT]: NavigationDirection.RIGHT, - [GamepadKey.LS_UP]: NavigationDirection.UP, - [GamepadKey.LS_DOWN]: NavigationDirection.DOWN, - [GamepadKey.LS_LEFT]: NavigationDirection.LEFT, - [GamepadKey.LS_RIGHT]: NavigationDirection.RIGHT + 12: 1, + 13: 3, + 14: 4, + 15: 2, + 100: 1, + 101: 3, + 102: 4, + 103: 2 }; static SIBLING_PROPERTY_MAP = { horizontal: { - [NavigationDirection.LEFT]: "previousElementSibling", - [NavigationDirection.RIGHT]: "nextElementSibling" + [4]: "previousElementSibling", + [2]: "nextElementSibling" }, vertical: { - [NavigationDirection.UP]: "previousElementSibling", - [NavigationDirection.DOWN]: "nextElementSibling" + [1]: "previousElementSibling", + [3]: "nextElementSibling" } }; gamepadPollingIntervalId = null; @@ -2735,10 +2438,10 @@ class NavigationDialogManager { return; } if (keyCode === "ArrowUp" || keyCode === "ArrowDown") - handled = !0, this.focusDirection(keyCode === "ArrowUp" ? NavigationDirection.UP : NavigationDirection.DOWN); + handled = !0, this.focusDirection(keyCode === "ArrowUp" ? 1 : 3); else if (keyCode === "ArrowLeft" || keyCode === "ArrowRight") { if (!($target instanceof HTMLInputElement && ($target.type === "text" || $target.type === "range"))) - handled = !0, this.focusDirection(keyCode === "ArrowLeft" ? NavigationDirection.LEFT : NavigationDirection.RIGHT); + handled = !0, this.focusDirection(keyCode === "ArrowLeft" ? 4 : 2); } else if (keyCode === "Enter" || keyCode === "NumpadEnter" || keyCode === "Space") { if (!($target instanceof HTMLInputElement && $target.type === "text")) handled = !0, $target.dispatchEvent(new MouseEvent("click")); @@ -2775,19 +2478,19 @@ class NavigationDialogManager { } if (heldButton === null && releasedButton === null && axes && axes.length >= 2) { if (lastKey) { - const releasedHorizontal = Math.abs(axes[0]) < 0.1 && (lastKey === GamepadKey.LS_LEFT || lastKey === GamepadKey.LS_RIGHT), releasedVertical = Math.abs(axes[1]) < 0.1 && (lastKey === GamepadKey.LS_UP || lastKey === GamepadKey.LS_DOWN); + const releasedHorizontal = Math.abs(axes[0]) < 0.1 && (lastKey === 102 || lastKey === 103), releasedVertical = Math.abs(axes[1]) < 0.1 && (lastKey === 100 || lastKey === 101); if (releasedHorizontal || releasedVertical) releasedButton = lastKey; else heldButton = lastKey; } else if (axes[0] < -0.5) - heldButton = GamepadKey.LS_LEFT; + heldButton = 102; else if (axes[0] > 0.5) - heldButton = GamepadKey.LS_RIGHT; + heldButton = 103; else if (axes[1] < -0.5) - heldButton = GamepadKey.LS_UP; + heldButton = 100; else if (axes[1] > 0.5) - heldButton = GamepadKey.LS_DOWN; + heldButton = 101; } if (heldButton !== null) { if (this.gamepadLastStates[gamepad.index] = [gamepad.timestamp, heldButton, !1], this.clearGamepadHoldingInterval(), NavigationDialogManager.GAMEPAD_DIRECTION_MAP[heldButton]) @@ -2809,10 +2512,10 @@ class NavigationDialogManager { } if (this.gamepadLastStates[gamepad.index] = null, lastKeyPressed) return; - if (releasedButton === GamepadKey.A) { + if (releasedButton === 0) { document.activeElement && document.activeElement.dispatchEvent(new MouseEvent("click")); return; - } else if (releasedButton === GamepadKey.B) { + } else if (releasedButton === 1) { this.hide(); return; } @@ -2829,8 +2532,8 @@ class NavigationDialogManager { return !1; if (document.activeElement instanceof HTMLInputElement && document.activeElement.type === "range") { const $range = document.activeElement; - if (direction === NavigationDirection.LEFT || direction === NavigationDirection.RIGHT) - $range.value = (parseInt($range.value) + parseInt($range.step) * (direction === NavigationDirection.LEFT ? -1 : 1)).toString(), $range.dispatchEvent(new InputEvent("input")), handled = !0; + if (direction === 4 || direction === 2) + $range.value = (parseInt($range.value) + parseInt($range.step) * (direction === 4 ? -1 : 1)).toString(), $range.dispatchEvent(new InputEvent("input")), handled = !0; } if (!handled) this.focusDirection(direction); @@ -2920,7 +2623,7 @@ class NavigationDialogManager { } } const children = Array.from($elm.children), orientation = $elm.nearby?.orientation; - if (orientation === "horizontal" || orientation === "vertical" && direction === NavigationDirection.UP) + if (orientation === "horizontal" || orientation === "vertical" && direction === 1) children.reverse(); for (let $child of children) { if (!$child || !($child instanceof HTMLElement)) @@ -2953,100 +2656,68 @@ class NavigationDialogManager { } } -// src/assets/svg/better-xcloud.svg var better_xcloud_default = "\n \n \n\n"; -// src/assets/svg/close.svg var close_default = "\n \n \n\n"; -// src/assets/svg/command.svg var command_default = "\n \n \n\n"; -// src/assets/svg/controller.svg var controller_default = "\n \n\n"; -// src/assets/svg/copy.svg var copy_default = "\n \n\n"; -// src/assets/svg/create-shortcut.svg var create_shortcut_default = "\n \n \n\n"; -// src/assets/svg/cursor-text.svg var cursor_text_default = "\n \n\n"; -// src/assets/svg/display.svg var display_default = "\n \n\n"; -// src/assets/svg/home.svg var home_default = "\n \n\n"; -// src/assets/svg/native-mkb.svg var native_mkb_default = "\n \n \n \n \n \n \n \n \n\n"; -// src/assets/svg/new.svg var new_default = "\n \n\n"; -// src/assets/svg/question.svg var question_default = "\n \n\n"; -// src/assets/svg/refresh.svg var refresh_default = "\n \n\n"; -// src/assets/svg/remote-play.svg var remote_play_default = "\n \n\n"; -// src/assets/svg/stream-settings.svg var stream_settings_default = "\n \n\n"; -// src/assets/svg/stream-stats.svg var stream_stats_default = "\n \n\n"; -// src/assets/svg/touch-control-disable.svg var touch_control_disable_default = "\n \n \n \n \n \n \n \n\n"; -// src/assets/svg/touch-control-enable.svg var touch_control_enable_default = "\n \n \n \n \n\n"; -// src/assets/svg/trash.svg var trash_default = "\n \n\n"; -// src/assets/svg/virtual-controller.svg var virtual_controller_default = "\n \n \n \n \n \n \n \n \n \n\n"; -// src/assets/svg/caret-left.svg var caret_left_default = "\n \n\n"; -// src/assets/svg/caret-right.svg var caret_right_default = "\n \n\n"; -// src/assets/svg/camera.svg var camera_default = "\n \n \n \n \n\n"; -// src/assets/svg/microphone.svg var microphone_default = "\n \n\n"; -// src/assets/svg/microphone-slash.svg var microphone_slash_default = "\n \n \n\n"; -// src/assets/svg/battery-full.svg var battery_full_default = "\n \n\n"; -// src/assets/svg/clock.svg var clock_default = "\n \n \n \n \n\n"; -// src/assets/svg/cloud.svg var cloud_default = "\n \n\n"; -// src/assets/svg/download.svg var download_default = "\n \n \n\n"; -// src/assets/svg/speaker-high.svg var speaker_high_default = "\n \n \n\n"; -// src/assets/svg/upload.svg var upload_default = "\n \n \n\n"; -// src/utils/bx-icon.ts var BxIcon = { BETTER_XCLOUD: better_xcloud_default, STREAM_SETTINGS: stream_settings_default, @@ -3081,7 +2752,6 @@ var BxIcon = { AUDIO: speaker_high_default }; -// src/modules/dialog.ts class Dialog { $dialog; $title; @@ -3124,34 +2794,33 @@ class Dialog { } } -// src/modules/mkb/mkb-remapper.ts class MkbRemapper { #BUTTON_ORDERS = [ - GamepadKey.UP, - GamepadKey.DOWN, - GamepadKey.LEFT, - GamepadKey.RIGHT, - GamepadKey.A, - GamepadKey.B, - GamepadKey.X, - GamepadKey.Y, - GamepadKey.LB, - GamepadKey.RB, - GamepadKey.LT, - GamepadKey.RT, - GamepadKey.SELECT, - GamepadKey.START, - GamepadKey.HOME, - GamepadKey.L3, - GamepadKey.LS_UP, - GamepadKey.LS_DOWN, - GamepadKey.LS_LEFT, - GamepadKey.LS_RIGHT, - GamepadKey.R3, - GamepadKey.RS_UP, - GamepadKey.RS_DOWN, - GamepadKey.RS_LEFT, - GamepadKey.RS_RIGHT + 12, + 13, + 14, + 15, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 16, + 10, + 100, + 101, + 102, + 103, + 11, + 200, + 201, + 202, + 203 ]; static #instance; static get INSTANCE() { @@ -3175,7 +2844,7 @@ class MkbRemapper { }; bindingDialog; constructor() { - this.#STATE.currentPresetId = getPref(PrefKey.MKB_DEFAULT_PRESET_ID), this.bindingDialog = new Dialog({ + this.#STATE.currentPresetId = getPref("mkb_default_preset_id"), this.bindingDialog = new Dialog({ className: "bx-binding-dialog", content: CE("div", {}, CE("p", {}, t("press-to-bind")), CE("i", {}, t("press-esc-to-cancel"))), hideCloseButton: !0 @@ -3242,7 +2911,7 @@ class MkbRemapper { value = MkbPreset.MOUSE_SETTINGS[key].default; "setValue" in $elm && $elm.setValue(value); } - const activated = getPref(PrefKey.MKB_DEFAULT_PRESET_ID) === this.#STATE.currentPresetId; + const activated = getPref("mkb_default_preset_id") === this.#STATE.currentPresetId; this.#$.activateButton.disabled = activated, this.#$.activateButton.querySelector("span").textContent = activated ? t("activated") : t("activate"); }; #refresh() { @@ -3253,9 +2922,9 @@ class MkbRemapper { const $fragment = document.createDocumentFragment(); let defaultPresetId; if (this.#STATE.currentPresetId === 0) - this.#STATE.currentPresetId = parseInt(Object.keys(presets)[0]), defaultPresetId = this.#STATE.currentPresetId, setPref(PrefKey.MKB_DEFAULT_PRESET_ID, defaultPresetId), EmulatedMkbHandler.getInstance().refreshPresetData(); + this.#STATE.currentPresetId = parseInt(Object.keys(presets)[0]), defaultPresetId = this.#STATE.currentPresetId, setPref("mkb_default_preset_id", defaultPresetId), EmulatedMkbHandler.getInstance().refreshPresetData(); else - defaultPresetId = getPref(PrefKey.MKB_DEFAULT_PRESET_ID); + defaultPresetId = getPref("mkb_default_preset_id"); for (let id2 in presets) { let name = presets[id2].name; if (id2 === defaultPresetId) @@ -3383,7 +3052,7 @@ class MkbRemapper { style: ButtonStyle.PRIMARY, tabIndex: -1, onClick: (e) => { - setPref(PrefKey.MKB_DEFAULT_PRESET_ID, this.#STATE.currentPresetId), EmulatedMkbHandler.getInstance().refreshPresetData(), this.#refresh(); + setPref("mkb_default_preset_id", this.#STATE.currentPresetId), EmulatedMkbHandler.getInstance().refreshPresetData(), this.#refresh(); } })), CE("div", {}, createButton({ label: t("cancel"), @@ -3399,7 +3068,7 @@ class MkbRemapper { onClick: (e) => { const updatedPreset = deepClone(this.#getCurrentPreset()); updatedPreset.data = this.#STATE.editingPresetData, LocalDb.INSTANCE.updatePreset(updatedPreset).then((id2) => { - if (id2 === getPref(PrefKey.MKB_DEFAULT_PRESET_ID)) + if (id2 === getPref("mkb_default_preset_id")) EmulatedMkbHandler.getInstance().refreshPresetData(); this.#toggleEditing(!1), this.#refresh(); }); @@ -3409,15 +3078,14 @@ class MkbRemapper { } } -// src/utils/utils.ts function checkForUpdate() { if (SCRIPT_VERSION.includes("beta")) return; - const CHECK_INTERVAL_SECONDS = 7200, currentVersion = getPref(PrefKey.CURRENT_VERSION), lastCheck = getPref(PrefKey.LAST_UPDATE_CHECK), now = Math.round(+new Date / 1000); + const CHECK_INTERVAL_SECONDS = 7200, currentVersion = getPref("version_current"), lastCheck = getPref("version_last_check"), now = Math.round(+new Date / 1000); if (currentVersion === SCRIPT_VERSION && now - lastCheck < CHECK_INTERVAL_SECONDS) return; - setPref(PrefKey.LAST_UPDATE_CHECK, now), fetch("https://api.github.com/repos/redphx/better-xcloud/releases/latest").then((response) => response.json()).then((json) => { - setPref(PrefKey.LATEST_VERSION, json.tag_name.substring(1)), setPref(PrefKey.CURRENT_VERSION, SCRIPT_VERSION); + setPref("version_last_check", now), fetch("https://api.github.com/repos/redphx/better-xcloud/releases/latest").then((response) => response.json()).then((json) => { + setPref("version_latest", json.tag_name.substring(1)), setPref("version_current", SCRIPT_VERSION); }), Translations.updateTranslations(currentVersion === SCRIPT_VERSION); } function disablePwa() { @@ -3459,12 +3127,11 @@ async function copyToClipboard(text, showToast = !0) { return !1; } -// src/modules/shortcuts/shortcut-sound.ts class SoundShortcut { static adjustGainNodeVolume(amount) { - if (!getPref(PrefKey.AUDIO_ENABLE_VOLUME_CONTROL)) + if (!getPref("audio_enable_volume_control")) return 0; - const currentValue = getPref(PrefKey.AUDIO_VOLUME); + const currentValue = getPref("audio_volume"); let nearestValue; if (amount > 0) nearestValue = ceilToNearest(currentValue, amount); @@ -3475,17 +3142,17 @@ class SoundShortcut { newValue = nearestValue; else newValue = currentValue + amount; - return newValue = setPref(PrefKey.AUDIO_VOLUME, newValue, !0), SoundShortcut.setGainNodeVolume(newValue), Toast.show(`${t("stream")} ❯ ${t("volume")}`, newValue + "%", { instant: !0 }), newValue; + return newValue = setPref("audio_volume", newValue, !0), SoundShortcut.setGainNodeVolume(newValue), Toast.show(`${t("stream")} ❯ ${t("volume")}`, newValue + "%", { instant: !0 }), newValue; } static setGainNodeVolume(value) { STATES.currentStream.audioGainNode && (STATES.currentStream.audioGainNode.gain.value = value / 100); } static muteUnmute() { - if (getPref(PrefKey.AUDIO_ENABLE_VOLUME_CONTROL) && STATES.currentStream.audioGainNode) { - const gainValue = STATES.currentStream.audioGainNode.gain.value, settingValue = getPref(PrefKey.AUDIO_VOLUME); + if (getPref("audio_enable_volume_control") && STATES.currentStream.audioGainNode) { + const gainValue = STATES.currentStream.audioGainNode.gain.value, settingValue = getPref("audio_volume"); let targetValue; if (settingValue === 0) - targetValue = 100, setPref(PrefKey.AUDIO_VOLUME, targetValue, !0); + targetValue = 100, setPref("audio_volume", targetValue, !0); else if (gainValue === 0) targetValue = settingValue; else @@ -3509,7 +3176,6 @@ class SoundShortcut { } } -// src/modules/touch-controller.ts var LOG_TAG2 = "TouchController"; class TouchController { @@ -3676,7 +3342,7 @@ class TouchController { }; const $style = document.createElement("style"); document.documentElement.appendChild($style), TouchController.#$style = $style; - const PREF_STYLE_STANDARD = getPref(PrefKey.STREAM_TOUCH_CONTROLLER_STYLE_STANDARD), PREF_STYLE_CUSTOM = getPref(PrefKey.STREAM_TOUCH_CONTROLLER_STYLE_CUSTOM); + const PREF_STYLE_STANDARD = getPref("stream_touch_controller_style_standard"), PREF_STYLE_CUSTOM = getPref("stream_touch_controller_style_custom"); window.addEventListener(BxEvent.DATA_CHANNEL_CREATED, (e) => { const dataChannel = e.dataChannel; if (!dataChannel || dataChannel.label !== "message") @@ -3723,7 +3389,6 @@ class TouchController { } } -// src/modules/vibration-manager.ts var VIBRATION_DATA_MAP = { gamepadIndex: 8, leftMotorPercent: 8, @@ -3754,12 +3419,12 @@ class VibrationManager { return !!window.navigator.vibrate; } static updateGlobalVars(stopVibration = !0) { - if (window.BX_ENABLE_CONTROLLER_VIBRATION = VibrationManager.supportControllerVibration() ? getPref(PrefKey.CONTROLLER_ENABLE_VIBRATION) : !1, window.BX_VIBRATION_INTENSITY = getPref(PrefKey.CONTROLLER_VIBRATION_INTENSITY) / 100, !VibrationManager.supportDeviceVibration()) { + if (window.BX_ENABLE_CONTROLLER_VIBRATION = VibrationManager.supportControllerVibration() ? getPref("controller_enable_vibration") : !1, window.BX_VIBRATION_INTENSITY = getPref("controller_vibration_intensity") / 100, !VibrationManager.supportDeviceVibration()) { window.BX_ENABLE_DEVICE_VIBRATION = !1; return; } stopVibration && window.navigator.vibrate(0); - const value = getPref(PrefKey.CONTROLLER_DEVICE_VIBRATION); + const value = getPref("controller_device_vibration"); let enabled; if (value === "on") enabled = !0; @@ -3810,7 +3475,6 @@ class VibrationManager { } } -// src/web-components/bx-select.ts class BxSelectElement { static wrap($select) { $select.removeAttribute("tabindex"); @@ -3900,50 +3564,33 @@ class BxSelectElement { } } -// src/modules/patches/controller-shortcuts.js var controller_shortcuts_default = "if (window.BX_EXPOSED.disableGamepadPolling) {\n this.inputConfiguration.useIntervalWorkerThreadForInput && this.intervalWorker ? this.intervalWorker.scheduleTimer(50) : this.pollGamepadssetTimeoutTimerID = setTimeout(this.pollGamepads, 50);\n return;\n}\n\nconst currentGamepad = ${gamepadVar};\n\n// Share button on XS controller\nif (currentGamepad.buttons[17] && currentGamepad.buttons[17].pressed) {\n window.dispatchEvent(new Event(BxEvent.CAPTURE_SCREENSHOT));\n}\n\nconst btnHome = currentGamepad.buttons[16];\nif (btnHome) {\n if (!this.bxHomeStates) {\n this.bxHomeStates = {};\n }\n\n let intervalMs = 0;\n let hijack = false;\n\n if (btnHome.pressed) {\n hijack = true;\n intervalMs = 16;\n this.gamepadIsIdle.set(currentGamepad.index, false);\n\n if (this.bxHomeStates[currentGamepad.index]) {\n const lastTimestamp = this.bxHomeStates[currentGamepad.index].timestamp;\n\n if (currentGamepad.timestamp !== lastTimestamp) {\n this.bxHomeStates[currentGamepad.index].timestamp = currentGamepad.timestamp;\n\n const handled = window.BX_EXPOSED.handleControllerShortcut(currentGamepad);\n if (handled) {\n this.bxHomeStates[currentGamepad.index].shortcutPressed += 1;\n }\n }\n } else {\n // First time pressing > save current timestamp\n window.BX_EXPOSED.resetControllerShortcut(currentGamepad.index);\n this.bxHomeStates[currentGamepad.index] = {\n shortcutPressed: 0,\n timestamp: currentGamepad.timestamp,\n };\n }\n } else if (this.bxHomeStates[currentGamepad.index]) {\n hijack = true;\n const info = structuredClone(this.bxHomeStates[currentGamepad.index]);\n\n // Home button released\n this.bxHomeStates[currentGamepad.index] = null;\n\n if (info.shortcutPressed === 0) {\n const fakeGamepadMappings = [{\n GamepadIndex: currentGamepad.index,\n A: 0,\n B: 0,\n X: 0,\n Y: 0,\n LeftShoulder: 0,\n RightShoulder: 0,\n LeftTrigger: 0,\n RightTrigger: 0,\n View: 0,\n Menu: 0,\n LeftThumb: 0,\n RightThumb: 0,\n DPadUp: 0,\n DPadDown: 0,\n DPadLeft: 0,\n DPadRight: 0,\n Nexus: 1,\n LeftThumbXAxis: 0,\n LeftThumbYAxis: 0,\n RightThumbXAxis: 0,\n RightThumbYAxis: 0,\n PhysicalPhysicality: 0,\n VirtualPhysicality: 0,\n Dirty: true,\n Virtual: false,\n }];\n\n const isLongPress = (currentGamepad.timestamp - info.timestamp) >= 500;\n intervalMs = isLongPress ? 500 : 100;\n\n this.inputSink.onGamepadInput(performance.now() - intervalMs, fakeGamepadMappings);\n } else {\n intervalMs = 4;\n }\n }\n\n if (hijack && intervalMs) {\n // Listen to next button press\n this.inputConfiguration.useIntervalWorkerThreadForInput && this.intervalWorker ? this.intervalWorker.scheduleTimer(intervalMs) : this.pollGamepadssetTimeoutTimerID = setTimeout(this.pollGamepads, intervalMs);\n\n // Hijack this button\n return;\n }\n}\n"; -// src/modules/patches/expose-stream-session.js var expose_stream_session_default = "window.BX_EXPOSED.streamSession = this;\n\nconst orgSetMicrophoneState = this.setMicrophoneState.bind(this);\nthis.setMicrophoneState = state => {\n orgSetMicrophoneState(state);\n\n const evt = new Event(BxEvent.MICROPHONE_STATE_CHANGED);\n evt.microphoneState = state;\n\n window.dispatchEvent(evt);\n};\n\nwindow.dispatchEvent(new Event(BxEvent.STREAM_SESSION_READY));\n\n// Patch updateDimensions() to make native touch work correctly with WebGL2\nlet updateDimensionsStr = this.updateDimensions.toString();\n\nif (updateDimensionsStr.startsWith('function ')) {\n updateDimensionsStr = updateDimensionsStr.substring(9);\n}\n\n// if(r){\nconst renderTargetVar = updateDimensionsStr.match(/if\\((\\w+)\\){/)[1];\n\nupdateDimensionsStr = updateDimensionsStr.replaceAll(renderTargetVar + '.scroll', 'scroll');\n\nupdateDimensionsStr = updateDimensionsStr.replace(`if(${renderTargetVar}){`, `\nif (${renderTargetVar}) {\n const scrollWidth = ${renderTargetVar}.dataset.width ? parseInt(${renderTargetVar}.dataset.width) : ${renderTargetVar}.scrollWidth;\n const scrollHeight = ${renderTargetVar}.dataset.height ? parseInt(${renderTargetVar}.dataset.height) : ${renderTargetVar}.scrollHeight;\n`);\n\neval(`this.updateDimensions = function ${updateDimensionsStr}`);\n"; -// src/modules/patches/local-co-op-enable.js var local_co_op_enable_default = "let match;\nlet onGamepadChangedStr = this.onGamepadChanged.toString();\n\nif (onGamepadChangedStr.startsWith('function ')) {\n onGamepadChangedStr = onGamepadChangedStr.substring(9);\n}\n\nonGamepadChangedStr = onGamepadChangedStr.replaceAll('0', 'arguments[1]');\neval(`this.onGamepadChanged = function ${onGamepadChangedStr}`);\n\nlet onGamepadInputStr = this.onGamepadInput.toString();\n\nmatch = onGamepadInputStr.match(/(\\w+\\.GamepadIndex)/);\nif (match) {\n const gamepadIndexVar = match[0];\n onGamepadInputStr = onGamepadInputStr.replace('this.gamepadStates.get(', `this.gamepadStates.get(${gamepadIndexVar},`);\n eval(`this.onGamepadInput = function ${onGamepadInputStr}`);\n BxLogger.info('supportLocalCoOp', '✅ Successfully patched local co-op support');\n} else {\n BxLogger.error('supportLocalCoOp', '❌ Unable to patch local co-op support');\n}\n"; -// src/modules/patches/set-currently-focused-interactable.js var set_currently_focused_interactable_default = "e && BxEvent.dispatch(window, BxEvent.NAVIGATION_FOCUS_CHANGED, {element: e});\n"; -// src/modules/patches/remote-play-enable.js var remote_play_enable_default = "connectMode: window.BX_REMOTE_PLAY_CONFIG ? \"xhome-connect\" : \"cloud-connect\",\nremotePlayServerId: (window.BX_REMOTE_PLAY_CONFIG && window.BX_REMOTE_PLAY_CONFIG.serverId) || '',\n"; -// src/modules/patches/remote-play-keep-alive.js var remote_play_keep_alive_default = "const msg = JSON.parse(e);\nif (msg.reason === 'WarningForBeingIdle' && !window.location.pathname.includes('/launch/')) {\n try {\n this.sendKeepAlive();\n return;\n } catch (ex) { console.log(ex); }\n}\n"; -// src/modules/patches/vibration-adjust.js var vibration_adjust_default = "if (!window.BX_ENABLE_CONTROLLER_VIBRATION) {\n return void(0);\n}\n\nconst intensity = window.BX_VIBRATION_INTENSITY;\nif (intensity === 0) {\n return void(0);\n}\n\nif (intensity < 1) {\n e.leftMotorPercent *= intensity;\n e.rightMotorPercent *= intensity;\n e.leftTriggerMotorPercent *= intensity;\n e.rightTriggerMotorPercent *= intensity;\n}\n"; -// src/utils/feature-gates.ts var FeatureGates = { PwaPrompt: !1, EnableWifiWarnings: !1, EnableUpdateRequiredPage: !1, ShowForcedUpdateScreen: !1 }; -if (getPref(PrefKey.UI_HOME_CONTEXT_MENU_DISABLED)) +if (getPref("ui_home_context_menu_disabled")) FeatureGates.EnableHomeContextMenu = !1; -if (getPref(PrefKey.BLOCK_SOCIAL_FEATURES)) +if (getPref("block_social_features")) FeatureGates.EnableGuideChatTab = !1; if (BX_FLAGS.FeatureGates) FeatureGates = Object.assign(BX_FLAGS.FeatureGates, FeatureGates); -// src/enums/game-pass-gallery.ts -var GamePassCloudGallery = { - ALL: "29a81209-df6f-41fd-a528-2ae6b91f719c", - MOST_POPULAR: "e7590b22-e299-44db-ae22-25c61405454c", - NATIVE_MKB: "8fa264dd-124f-4af3-97e8-596fcdf4b486", - TOUCH: "9c86f07a-f3e8-45ad-82a0-a1f759597059" -}; - -// src/modules/patcher.ts var ENDING_CHUNKS_PATCH_NAME = "loadingEndingChunks", LOG_TAG3 = "Patcher", PATCHES = { disableAiTrack(str) { const index = str.indexOf(".track=function("); @@ -3982,7 +3629,7 @@ var ENDING_CHUNKS_PATCH_NAME = "loadingEndingChunks", LOG_TAG3 = "Patcher", PATC websiteLayout(str) { if (!str.includes('?"tv":"default"')) return !1; - const layout = getPref(PrefKey.UI_LAYOUT) === "tv" ? "tv" : "default"; + const layout = getPref("ui_layout") === "tv" ? "tv" : "default"; return str.replace('?"tv":"default"', `?"${layout}":"${layout}"`); }, remotePlayDirectConnectUrl(str) { @@ -4029,7 +3676,7 @@ if (!!window.BX_REMOTE_PLAY_CONFIG) { if (nextIndex === -1) return !1; let codeBlock = str.substring(index, nextIndex); - if (getPref(PrefKey.BLOCK_TRACKING)) + if (getPref("block_tracking")) codeBlock = codeBlock.replaceAll("this.inputPollingIntervalStats.addValue", ""); const match = codeBlock.match(/this\.gamepadTimestamps\.set\((\w+)\.index/); if (match) { @@ -4140,7 +3787,7 @@ if (window.BX_EXPOSED.stopTakRendering) { if (!str.includes("const{TakRenderer:")) return !1; let remotePlayCode = ""; - if (getPref(PrefKey.STREAM_TOUCH_CONTROLLER) !== "off" && getPref(PrefKey.STREAM_TOUCH_CONTROLLER_AUTO_OFF)) + if (getPref("stream_touch_controller") !== "off" && getPref("stream_touch_controller_auto_off")) remotePlayCode = ` const gamepads = window.navigator.getGamepads(); let gamepadFound = false; @@ -4182,7 +3829,7 @@ window.BX_EXPOSED.showStreamMenu = e.onShowStreamMenu; // Restore the "..." button e.guideUI = null; `; - if (getPref(PrefKey.STREAM_TOUCH_CONTROLLER) === "off") + if (getPref("stream_touch_controller") === "off") newCode += "e.canShowTakHUD = false;"; return str = str.replace("let{onCollapse", newCode + "let{onCollapse"), str; }, @@ -4241,7 +3888,7 @@ BxLogger.info('patchRemotePlayMkb', ${configsVar}); patchTouchControlDefaultOpacity(str) { if (!str.includes("opacityMultiplier:1")) return !1; - const newCode = `opacityMultiplier: ${(getPref(PrefKey.STREAM_TOUCH_CONTROLLER_DEFAULT_OPACITY) / 100).toFixed(1)}`; + const newCode = `opacityMultiplier: ${(getPref("stream_touch_controller_default_opacity") / 100).toFixed(1)}`; return str = str.replace("opacityMultiplier:1", newCode), str; }, patchShowSensorControls(str) { @@ -4255,7 +3902,7 @@ BxLogger.info('patchRemotePlayMkb', ${configsVar}); return !1; const newCode = `; ${expose_stream_session_default} -true` + ",this._connectionType="; +true,this._connectionType=`; return str = str.replace(",this._connectionType=", newCode), str; }, skipFeedbackDialog(str) { @@ -4336,9 +3983,9 @@ true` + ",this._connectionType="; return !1; if (index = str.indexOf("const[", index - 300), index < 0) return !1; - const PREF_HIDE_SECTIONS = getPref(PrefKey.UI_HIDE_SECTIONS), siglIds = [], sections = { - [UiSection.NATIVE_MKB]: GamePassCloudGallery.NATIVE_MKB, - [UiSection.MOST_POPULAR]: GamePassCloudGallery.MOST_POPULAR + const PREF_HIDE_SECTIONS = getPref("ui_hide_sections"), siglIds = [], sections = { + "native-mkb": "8fa264dd-124f-4af3-97e8-596fcdf4b486", + "most-popular": "e7590b22-e299-44db-ae22-25c61405454c" }; PREF_HIDE_SECTIONS.forEach((section) => { const galleryId = sections[section]; @@ -4392,7 +4039,7 @@ if (this.baseStorageKey in window.BX_EXPOSED.overrideSettings) { return str = str.substring(0, index) + 'BxEvent.dispatch(window, BxEvent.XCLOUD_RENDERING_COMPONENT, {component: "product-details"});' + str.substring(index), str; } }, PATCH_ORDERS = [ - ...getPref(PrefKey.NATIVE_MKB_ENABLED) === "on" ? [ + ...getPref("native_mkb_enabled") === "on" ? [ "enableNativeMkb", "patchMouseAndKeyboardEnabled", "disableNativeRequestPointerLock", @@ -4408,15 +4055,15 @@ if (this.baseStorageKey in window.BX_EXPOSED.overrideSettings) { "enableTvRoutes", AppInterface && "detectProductDetailsPage", "overrideStorageGetSettings", - getPref(PrefKey.UI_GAME_CARD_SHOW_WAIT_TIME) && "patchSetCurrentlyFocusedInteractable", - getPref(PrefKey.UI_LAYOUT) !== "default" && "websiteLayout", - getPref(PrefKey.LOCAL_CO_OP_ENABLED) && "supportLocalCoOp", - getPref(PrefKey.GAME_FORTNITE_FORCE_CONSOLE) && "forceFortniteConsole", - getPref(PrefKey.UI_HIDE_SECTIONS).includes(UiSection.FRIENDS) && "ignorePlayWithFriendsSection", - getPref(PrefKey.UI_HIDE_SECTIONS).includes(UiSection.ALL_GAMES) && "ignoreAllGamesSection", - getPref(PrefKey.UI_HIDE_SECTIONS).includes(UiSection.TOUCH) && "ignorePlayWithTouchSection", - (getPref(PrefKey.UI_HIDE_SECTIONS).includes(UiSection.NATIVE_MKB) || getPref(PrefKey.UI_HIDE_SECTIONS).includes(UiSection.MOST_POPULAR)) && "ignoreSiglSections", - ...getPref(PrefKey.BLOCK_TRACKING) ? [ + getPref("ui_game_card_show_wait_time") && "patchSetCurrentlyFocusedInteractable", + getPref("ui_layout") !== "default" && "websiteLayout", + getPref("local_co_op_enabled") && "supportLocalCoOp", + getPref("game_fortnite_force_console") && "forceFortniteConsole", + getPref("ui_hide_sections").includes("friends") && "ignorePlayWithFriendsSection", + getPref("ui_hide_sections").includes("all-games") && "ignoreAllGamesSection", + getPref("ui_hide_sections").includes("touch") && "ignorePlayWithTouchSection", + (getPref("ui_hide_sections").includes("native-mkb") || getPref("ui_hide_sections").includes("most-popular")) && "ignoreSiglSections", + ...getPref("block_tracking") ? [ "disableAiTrack", "disableTelemetry", "blockWebRtcStatsCollector", @@ -4424,7 +4071,7 @@ if (this.baseStorageKey in window.BX_EXPOSED.overrideSettings) { "disableTelemetryProvider", "disableTrackEvent" ] : [], - ...getPref(PrefKey.REMOTE_PLAY_ENABLED) ? [ + ...getPref("xhome_enabled") ? [ "remotePlayKeepAlive", "remotePlayDirectConnectUrl", "remotePlayDisableAchievementToast", @@ -4440,20 +4087,20 @@ if (this.baseStorageKey in window.BX_EXPOSED.overrideSettings) { "patchStreamHud", "playVibration", "alwaysShowStreamHud", - getPref(PrefKey.AUDIO_ENABLE_VOLUME_CONTROL) && !getPref(PrefKey.STREAM_COMBINE_SOURCES) && "patchAudioMediaStream", - getPref(PrefKey.AUDIO_ENABLE_VOLUME_CONTROL) && getPref(PrefKey.STREAM_COMBINE_SOURCES) && "patchCombinedAudioVideoMediaStream", - getPref(PrefKey.STREAM_DISABLE_FEEDBACK_DIALOG) && "skipFeedbackDialog", + getPref("audio_enable_volume_control") && !getPref("stream_combine_sources") && "patchAudioMediaStream", + getPref("audio_enable_volume_control") && getPref("stream_combine_sources") && "patchCombinedAudioVideoMediaStream", + getPref("stream_disable_feedback_dialog") && "skipFeedbackDialog", ...STATES.userAgent.capabilities.touch ? [ - getPref(PrefKey.STREAM_TOUCH_CONTROLLER) === "all" && "patchShowSensorControls", - getPref(PrefKey.STREAM_TOUCH_CONTROLLER) === "all" && "exposeTouchLayoutManager", - (getPref(PrefKey.STREAM_TOUCH_CONTROLLER) === "off" || getPref(PrefKey.STREAM_TOUCH_CONTROLLER_AUTO_OFF) || !STATES.userAgent.capabilities.touch) && "disableTakRenderer", - getPref(PrefKey.STREAM_TOUCH_CONTROLLER_DEFAULT_OPACITY) !== 100 && "patchTouchControlDefaultOpacity", + getPref("stream_touch_controller") === "all" && "patchShowSensorControls", + getPref("stream_touch_controller") === "all" && "exposeTouchLayoutManager", + (getPref("stream_touch_controller") === "off" || getPref("stream_touch_controller_auto_off") || !STATES.userAgent.capabilities.touch) && "disableTakRenderer", + getPref("stream_touch_controller_default_opacity") !== 100 && "patchTouchControlDefaultOpacity", "patchBabylonRendererClass" ] : [], BX_FLAGS.EnableXcloudLogging && "enableConsoleLogging", "patchPollGamepads", - getPref(PrefKey.STREAM_COMBINE_SOURCES) && "streamCombineSources", - ...getPref(PrefKey.REMOTE_PLAY_ENABLED) ? [ + getPref("stream_combine_sources") && "streamCombineSources", + ...getPref("xhome_enabled") ? [ "patchRemotePlayMkb", "remotePlayConnectMode" ] : [] @@ -4575,7 +4222,6 @@ class PatcherCache { } } -// src/modules/ui/dialog/settings-dialog.ts class SettingsNavigationDialog extends NavigationDialog { static instance; static getInstance() { @@ -4596,7 +4242,7 @@ class SettingsNavigationDialog extends NavigationDialog { helpUrl: "https://better-xcloud.github.io/features/", items: [ ($parent) => { - const PREF_LATEST_VERSION = getPref(PrefKey.LATEST_VERSION), topButtons = []; + const PREF_LATEST_VERSION = getPref("version_latest"), topButtons = []; if (!SCRIPT_VERSION.includes("beta") && PREF_LATEST_VERSION && PREF_LATEST_VERSION != SCRIPT_VERSION) topButtons.push(createButton({ label: `🌟 Version ${PREF_LATEST_VERSION} available`, @@ -4637,52 +4283,52 @@ class SettingsNavigationDialog extends NavigationDialog { }, ...topButtons); $parent.appendChild($div); }, - PrefKey.BETTER_XCLOUD_LOCALE, - PrefKey.SERVER_BYPASS_RESTRICTION, - PrefKey.UI_CONTROLLER_FRIENDLY, - PrefKey.REMOTE_PLAY_ENABLED + "bx_locale", + "server_bypass_restriction", + "ui_controller_friendly", + "xhome_enabled" ] }, { group: "server", label: t("server"), items: [ - PrefKey.SERVER_REGION, - PrefKey.STREAM_PREFERRED_LOCALE, - PrefKey.PREFER_IPV6_SERVER + "server_region", + "stream_preferred_locale", + "prefer_ipv6_server" ] }, { group: "stream", label: t("stream"), items: [ - PrefKey.STREAM_TARGET_RESOLUTION, - PrefKey.STREAM_CODEC_PROFILE, - PrefKey.BITRATE_VIDEO_MAX, - PrefKey.AUDIO_ENABLE_VOLUME_CONTROL, - PrefKey.STREAM_DISABLE_FEEDBACK_DIALOG, - PrefKey.SCREENSHOT_APPLY_FILTERS, - PrefKey.AUDIO_MIC_ON_PLAYING, - PrefKey.GAME_FORTNITE_FORCE_CONSOLE, - PrefKey.STREAM_COMBINE_SOURCES + "stream_target_resolution", + "stream_codec_profile", + "bitrate_video_max", + "audio_enable_volume_control", + "stream_disable_feedback_dialog", + "screenshot_apply_filters", + "audio_mic_on_playing", + "game_fortnite_force_console", + "stream_combine_sources" ] }, { group: "game-bar", label: t("game-bar"), items: [ - PrefKey.GAME_BAR_POSITION + "game_bar_position" ] }, { group: "co-op", label: t("local-co-op"), items: [ - PrefKey.LOCAL_CO_OP_ENABLED + "local_co_op_enabled" ] }, { group: "mkb", label: t("mouse-and-keyboard"), items: [ - PrefKey.NATIVE_MKB_ENABLED, - PrefKey.MKB_ENABLED, - PrefKey.MKB_HIDE_IDLE_CURSOR + "native_mkb_enabled", + "mkb_enabled", + "mkb_hide_idle_cursor" ] }, { group: "touch-control", @@ -4690,48 +4336,48 @@ class SettingsNavigationDialog extends NavigationDialog { note: !STATES.userAgent.capabilities.touch ? "⚠️ " + t("device-unsupported-touch") : null, unsupported: !STATES.userAgent.capabilities.touch, items: [ - PrefKey.STREAM_TOUCH_CONTROLLER, - PrefKey.STREAM_TOUCH_CONTROLLER_AUTO_OFF, - PrefKey.STREAM_TOUCH_CONTROLLER_DEFAULT_OPACITY, - PrefKey.STREAM_TOUCH_CONTROLLER_STYLE_STANDARD, - PrefKey.STREAM_TOUCH_CONTROLLER_STYLE_CUSTOM + "stream_touch_controller", + "stream_touch_controller_auto_off", + "stream_touch_controller_default_opacity", + "stream_touch_controller_style_standard", + "stream_touch_controller_style_custom" ] }, { group: "loading-screen", label: t("loading-screen"), items: [ - PrefKey.UI_LOADING_SCREEN_GAME_ART, - PrefKey.UI_LOADING_SCREEN_WAIT_TIME, - PrefKey.UI_LOADING_SCREEN_ROCKET + "ui_loading_screen_game_art", + "ui_loading_screen_wait_time", + "ui_loading_screen_rocket" ] }, { group: "ui", label: t("ui"), items: [ - PrefKey.UI_LAYOUT, - PrefKey.UI_GAME_CARD_SHOW_WAIT_TIME, - PrefKey.UI_HOME_CONTEXT_MENU_DISABLED, - PrefKey.CONTROLLER_SHOW_CONNECTION_STATUS, - PrefKey.STREAM_SIMPLIFY_MENU, - PrefKey.SKIP_SPLASH_VIDEO, - !AppInterface && PrefKey.UI_SCROLLBAR_HIDE, - PrefKey.HIDE_DOTS_ICON, - PrefKey.REDUCE_ANIMATIONS, - PrefKey.BLOCK_SOCIAL_FEATURES, - PrefKey.UI_HIDE_SECTIONS + "ui_layout", + "ui_game_card_show_wait_time", + "ui_home_context_menu_disabled", + "controller_show_connection_status", + "stream_simplify_menu", + "skip_splash_video", + !AppInterface && "ui_scrollbar_hide", + "hide_dots_icon", + "reduce_animations", + "block_social_features", + "ui_hide_sections" ] }, { group: "other", label: t("other"), items: [ - PrefKey.BLOCK_TRACKING + "block_tracking" ] }, { group: "advanced", label: t("advanced"), items: [ { - pref: PrefKey.USER_AGENT_PROFILE, + pref: "user_agent_profile", onCreated: (setting, $control) => { const defaultUserAgent = window.navigator.orgUserAgent || window.navigator.userAgent, $inpCustomUserAgent = CE("input", { id: `bx_setting_inp_${setting.pref}`, @@ -4793,18 +4439,18 @@ class SettingsNavigationDialog extends NavigationDialog { label: t("audio"), helpUrl: "https://better-xcloud.github.io/ingame-features/#audio", items: [{ - pref: PrefKey.AUDIO_VOLUME, + pref: "audio_volume", onChange: (e, value) => { SoundShortcut.setGainNodeVolume(value); }, params: { - disabled: !getPref(PrefKey.AUDIO_ENABLE_VOLUME_CONTROL) + disabled: !getPref("audio_enable_volume_control") }, onCreated: (setting, $elm) => { const $range = $elm.querySelector("input[type=range"); window.addEventListener(BxEvent.SETTINGS_CHANGED, (e) => { const { storageKey, settingKey, settingValue } = e; - if (storageKey !== StorageKey.GLOBAL || settingKey !== PrefKey.AUDIO_VOLUME) + if (storageKey !== "better_xcloud" || settingKey !== "audio_volume") return; $range.value = settingValue, BxEvent.dispatch($range, "input", { ignoreOnChange: !0 @@ -4817,10 +4463,10 @@ class SettingsNavigationDialog extends NavigationDialog { label: t("video"), helpUrl: "https://better-xcloud.github.io/ingame-features/#video", items: [{ - pref: PrefKey.VIDEO_PLAYER_TYPE, + pref: "video_player_type", onChange: onChangeVideoPlayerType }, { - pref: PrefKey.VIDEO_POWER_PREFERENCE, + pref: "video_power_preference", onChange: () => { const streamPlayer = STATES.currentStream.streamPlayer; if (!streamPlayer) @@ -4828,22 +4474,22 @@ class SettingsNavigationDialog extends NavigationDialog { streamPlayer.reloadPlayer(), updateVideoPlayer(); } }, { - pref: PrefKey.VIDEO_PROCESSING, + pref: "video_processing", onChange: updateVideoPlayer }, { - pref: PrefKey.VIDEO_RATIO, + pref: "video_ratio", onChange: updateVideoPlayer }, { - pref: PrefKey.VIDEO_SHARPNESS, + pref: "video_sharpness", onChange: updateVideoPlayer }, { - pref: PrefKey.VIDEO_SATURATION, + pref: "video_saturation", onChange: updateVideoPlayer }, { - pref: PrefKey.VIDEO_CONTRAST, + pref: "video_contrast", onChange: updateVideoPlayer }, { - pref: PrefKey.VIDEO_BRIGHTNESS, + pref: "video_brightness", onChange: updateVideoPlayer }] }]; @@ -4853,15 +4499,15 @@ class SettingsNavigationDialog extends NavigationDialog { label: t("controller"), helpUrl: "https://better-xcloud.github.io/ingame-features/#controller", items: [{ - pref: PrefKey.CONTROLLER_ENABLE_VIBRATION, + pref: "controller_enable_vibration", unsupported: !VibrationManager.supportControllerVibration(), onChange: () => VibrationManager.updateGlobalVars() }, { - pref: PrefKey.CONTROLLER_DEVICE_VIBRATION, + pref: "controller_device_vibration", unsupported: !VibrationManager.supportDeviceVibration(), onChange: () => VibrationManager.updateGlobalVars() }, (VibrationManager.supportControllerVibration() || VibrationManager.supportDeviceVibration()) && { - pref: PrefKey.CONTROLLER_VIBRATION_INTENSITY, + pref: "controller_vibration_intensity", unsupported: !VibrationManager.supportDeviceVibration(), onChange: () => VibrationManager.updateGlobalVars() }] @@ -4912,12 +4558,12 @@ class SettingsNavigationDialog extends NavigationDialog { group: "native-mkb", label: t("native-mkb"), items: [{ - pref: PrefKey.NATIVE_MKB_SCROLL_VERTICAL_SENSITIVITY, + pref: "native_mkb_scroll_y_sensitivity", onChange: (e, value) => { NativeMkbHandler.getInstance().setVerticalScrollMultiplier(value / 100); } }, { - pref: PrefKey.NATIVE_MKB_SCROLL_HORIZONTAL_SENSITIVITY, + pref: "native_mkb_scroll_x_sensitivity", onChange: (e, value) => { NativeMkbHandler.getInstance().setHorizontalScrollMultiplier(value / 100); } @@ -4934,37 +4580,37 @@ class SettingsNavigationDialog extends NavigationDialog { helpUrl: "https://better-xcloud.github.io/stream-stats/", items: [ { - pref: PrefKey.STATS_SHOW_WHEN_PLAYING + pref: "stats_show_when_playing" }, { - pref: PrefKey.STATS_QUICK_GLANCE, + pref: "stats_quick_glance", onChange: (e) => { const streamStats = StreamStats.getInstance(); e.target.checked ? streamStats.quickGlanceSetup() : streamStats.quickGlanceStop(); } }, { - pref: PrefKey.STATS_ITEMS, + pref: "stats_items", onChange: StreamStats.refreshStyles }, { - pref: PrefKey.STATS_POSITION, + pref: "stats_position", onChange: StreamStats.refreshStyles }, { - pref: PrefKey.STATS_TEXT_SIZE, + pref: "stats_text_size", onChange: StreamStats.refreshStyles }, { - pref: PrefKey.STATS_OPACITY, + pref: "stats_opacity", onChange: StreamStats.refreshStyles }, { - pref: PrefKey.STATS_TRANSPARENT, + pref: "stats_transparent", onChange: StreamStats.refreshStyles }, { - pref: PrefKey.STATS_CONDITIONAL_FORMATTING, + pref: "stats_conditional_formatting", onChange: StreamStats.refreshStyles } ] @@ -4985,12 +4631,12 @@ class SettingsNavigationDialog extends NavigationDialog { group: "controller", items: this.TAB_CONTROLLER_ITEMS }, - getPref(PrefKey.MKB_ENABLED) && { + getPref("mkb_enabled") && { icon: BxIcon.VIRTUAL_CONTROLLER, group: "mkb", items: this.TAB_VIRTUAL_CONTROLLER_ITEMS }, - AppInterface && getPref(PrefKey.NATIVE_MKB_ENABLED) === "on" && { + AppInterface && getPref("native_mkb_enabled") === "on" && { icon: BxIcon.NATIVE_MKB, group: "native-mkb", items: this.TAB_NATIVE_MKB_ITEMS @@ -5021,7 +4667,7 @@ class SettingsNavigationDialog extends NavigationDialog { return; if (onChangeVideoPlayerType(), STATES.userAgent.capabilities.touch) BxEvent.dispatch(window, BxEvent.CUSTOM_TOUCH_LAYOUTS_LOADED); - const $selectUserAgent = document.querySelector(`#bx_setting_${PrefKey.USER_AGENT_PROFILE}`); + const $selectUserAgent = document.querySelector(`#bx_setting_${"user_agent_profile"}`); if ($selectUserAgent) $selectUserAgent.disabled = !0, BxEvent.dispatch($selectUserAgent, "input", {}), $selectUserAgent.disabled = !1; } @@ -5052,7 +4698,7 @@ class SettingsNavigationDialog extends NavigationDialog { }); $control.name = $control.id, $control.addEventListener("input", (e) => { setPref(setting.pref, e.target.value), this.onGlobalSettingChanged(e); - }), selectedValue = getPref(PrefKey.SERVER_REGION), setting.options = {}; + }), selectedValue = getPref("server_region"), setting.options = {}; for (let regionName in STATES.serverRegions) { const region = STATES.serverRegions[regionName]; let value = regionName, label = `${region.shortName} - ${regionName}`; @@ -5081,12 +4727,12 @@ class SettingsNavigationDialog extends NavigationDialog { else $control = setting.content; else if (!setting.unsupported) { - if (pref === PrefKey.SERVER_REGION) + if (pref === "server_region") $control = this.renderServerSetting(setting); - else if (pref === PrefKey.BETTER_XCLOUD_LOCALE) + else if (pref === "bx_locale") $control = SettingElement.fromPref(pref, STORAGE.Global, async (e) => { const newLocale = e.target.value; - if (getPref(PrefKey.UI_CONTROLLER_FRIENDLY)) { + if (getPref("ui_controller_friendly")) { let timeoutId = e.target.timeoutId; timeoutId && window.clearTimeout(timeoutId), e.target.timeoutId = window.setTimeout(() => { Translations.refreshLocale(newLocale), Translations.updateTranslations(); @@ -5095,10 +4741,10 @@ class SettingsNavigationDialog extends NavigationDialog { Translations.refreshLocale(newLocale), Translations.updateTranslations(); this.onGlobalSettingChanged(e); }); - else if (pref === PrefKey.USER_AGENT_PROFILE) - $control = SettingElement.fromPref(PrefKey.USER_AGENT_PROFILE, STORAGE.Global, (e) => { + else if (pref === "user_agent_profile") + $control = SettingElement.fromPref("user_agent_profile", STORAGE.Global, (e) => { const value = e.target.value; - let isCustom = value === UserAgentProfile.CUSTOM, userAgent2 = UserAgent.get(value); + let isCustom = value === "custom", userAgent2 = UserAgent.get(value); UserAgent.updateStorage(value); const $inp = $control.nextElementSibling; $inp.value = userAgent2, $inp.readOnly = !isCustom, $inp.disabled = !isCustom, !e.target.disabled && this.onGlobalSettingChanged(e); @@ -5109,7 +4755,7 @@ class SettingsNavigationDialog extends NavigationDialog { onChange = this.onGlobalSettingChanged.bind(this); $control = SettingElement.fromPref(pref, STORAGE.Global, onChange, setting.params); } - if ($control instanceof HTMLSelectElement && getPref(PrefKey.UI_CONTROLLER_FRIENDLY)) + if ($control instanceof HTMLSelectElement && getPref("ui_controller_friendly")) $control = BxSelectElement.wrap($control); } let prefDefinition = null; @@ -5151,8 +4797,8 @@ class SettingsNavigationDialog extends NavigationDialog { return this.dialogManager.focus($tabs); }, loop: (direction) => { - if (direction === NavigationDirection.UP || direction === NavigationDirection.DOWN) - return this.focusVisibleTab(direction === NavigationDirection.UP ? "last" : "first"), !0; + if (direction === 1 || direction === 3) + return this.focusVisibleTab(direction === 1 ? "last" : "first"), !0; return !1; } } @@ -5179,8 +4825,8 @@ class SettingsNavigationDialog extends NavigationDialog { orientation: "vertical", focus: () => this.jumpToSettingGroup("next"), loop: (direction) => { - if (direction === NavigationDirection.UP || direction === NavigationDirection.DOWN) - return this.focusVisibleSetting(direction === NavigationDirection.UP ? "last" : "first"), !0; + if (direction === 1 || direction === 3) + return this.focusVisibleSetting(direction === 1 ? "last" : "first"), !0; return !1; } } @@ -5315,7 +4961,7 @@ class SettingsNavigationDialog extends NavigationDialog { } let $target; if ($header) - $target = this.dialogManager.findNextTarget($header, NavigationDirection.DOWN, !1); + $target = this.dialogManager.findNextTarget($header, 3, !1); if ($target) return this.dialogManager.focus($target); return !1; @@ -5347,14 +4993,14 @@ class SettingsNavigationDialog extends NavigationDialog { handleGamepad(button) { let handled = !0; switch (button) { - case GamepadKey.LB: - case GamepadKey.RB: + case 4: + case 5: this.focusActiveTab(); break; - case GamepadKey.LT: + case 6: this.jumpToSettingGroup("previous"); break; - case GamepadKey.RT: + case 7: this.jumpToSettingGroup("next"); break; default: @@ -5365,7 +5011,6 @@ class SettingsNavigationDialog extends NavigationDialog { } } -// src/modules/mkb/mkb-handler.ts var LOG_TAG4 = "MkbHandler", PointerToMouseButton = { 1: 0, 2: 2, @@ -5472,14 +5117,14 @@ class EmulatedMkbHandler extends MkbHandler { constructor() { super(); this.#STICK_MAP = { - [GamepadKey.LS_LEFT]: [this.#LEFT_STICK_X, 0, -1], - [GamepadKey.LS_RIGHT]: [this.#LEFT_STICK_X, 0, 1], - [GamepadKey.LS_UP]: [this.#LEFT_STICK_Y, 1, -1], - [GamepadKey.LS_DOWN]: [this.#LEFT_STICK_Y, 1, 1], - [GamepadKey.RS_LEFT]: [this.#RIGHT_STICK_X, 2, -1], - [GamepadKey.RS_RIGHT]: [this.#RIGHT_STICK_X, 2, 1], - [GamepadKey.RS_UP]: [this.#RIGHT_STICK_Y, 3, -1], - [GamepadKey.RS_DOWN]: [this.#RIGHT_STICK_Y, 3, 1] + 102: [this.#LEFT_STICK_X, 0, -1], + 103: [this.#LEFT_STICK_X, 0, 1], + 100: [this.#LEFT_STICK_Y, 1, -1], + 101: [this.#LEFT_STICK_Y, 1, 1], + 202: [this.#RIGHT_STICK_X, 2, -1], + 203: [this.#RIGHT_STICK_X, 2, 1], + 200: [this.#RIGHT_STICK_Y, 3, -1], + 201: [this.#RIGHT_STICK_Y, 3, 1] }; } isEnabled = () => this.#enabled; @@ -5547,7 +5192,7 @@ class EmulatedMkbHandler extends MkbHandler { }; #onMouseStopped = () => { this.#detectMouseStoppedTimeout = null; - const analog = this.#CURRENT_PRESET_DATA.mouse[MkbPresetKey.MOUSE_MAP_TO] === MouseMapTo.LS ? GamepadStick.LEFT : GamepadStick.RIGHT; + const analog = this.#CURRENT_PRESET_DATA.mouse["map_to"] === 1 ? 0 : 1; this.#updateStick(analog, 0, 0); }; handleMouseClick = (data) => { @@ -5568,29 +5213,29 @@ class EmulatedMkbHandler extends MkbHandler { this.#pressButton(buttonIndex, data.pressed); }; handleMouseMove = (data) => { - const mouseMapTo = this.#CURRENT_PRESET_DATA.mouse[MkbPresetKey.MOUSE_MAP_TO]; - if (mouseMapTo === MouseMapTo.OFF) + const mouseMapTo = this.#CURRENT_PRESET_DATA.mouse["map_to"]; + if (mouseMapTo === 0) return; this.#detectMouseStoppedTimeout && clearTimeout(this.#detectMouseStoppedTimeout), this.#detectMouseStoppedTimeout = window.setTimeout(this.#onMouseStopped.bind(this), 50); - const deadzoneCounterweight = this.#CURRENT_PRESET_DATA.mouse[MkbPresetKey.MOUSE_DEADZONE_COUNTERWEIGHT]; - let x = data.movementX * this.#CURRENT_PRESET_DATA.mouse[MkbPresetKey.MOUSE_SENSITIVITY_X], y = data.movementY * this.#CURRENT_PRESET_DATA.mouse[MkbPresetKey.MOUSE_SENSITIVITY_Y], length = this.#vectorLength(x, y); + const deadzoneCounterweight = this.#CURRENT_PRESET_DATA.mouse["deadzone_counterweight"]; + let x = data.movementX * this.#CURRENT_PRESET_DATA.mouse["sensitivity_x"], y = data.movementY * this.#CURRENT_PRESET_DATA.mouse["sensitivity_y"], length = this.#vectorLength(x, y); if (length !== 0 && length < deadzoneCounterweight) x *= deadzoneCounterweight / length, y *= deadzoneCounterweight / length; else if (length > EmulatedMkbHandler.MAXIMUM_STICK_RANGE) x *= EmulatedMkbHandler.MAXIMUM_STICK_RANGE / length, y *= EmulatedMkbHandler.MAXIMUM_STICK_RANGE / length; - const analog = mouseMapTo === MouseMapTo.LS ? GamepadStick.LEFT : GamepadStick.RIGHT; + const analog = mouseMapTo === 1 ? 0 : 1; this.#updateStick(analog, x, y); }; handleMouseWheel = (data) => { let code = ""; if (data.vertical < 0) - code = WheelCode.SCROLL_UP; + code = "ScrollUp"; else if (data.vertical > 0) - code = WheelCode.SCROLL_DOWN; + code = "ScrollDown"; else if (data.horizontal < 0) - code = WheelCode.SCROLL_LEFT; + code = "ScrollLeft"; else if (data.horizontal > 0) - code = WheelCode.SCROLL_RIGHT; + code = "ScrollRight"; if (!code) return !1; const key = { @@ -5617,7 +5262,7 @@ class EmulatedMkbHandler extends MkbHandler { }; #getCurrentPreset = () => { return new Promise((resolve) => { - const presetId = getPref(PrefKey.MKB_DEFAULT_PRESET_ID); + const presetId = getPref("mkb_default_preset_id"); LocalDb.INSTANCE.getPreset(presetId).then((preset) => { resolve(preset); }); @@ -5734,29 +5379,19 @@ class EmulatedMkbHandler extends MkbHandler { static setupEvents() { window.addEventListener(BxEvent.STREAM_PLAYING, () => { if (STATES.currentStream.titleInfo?.details.hasMkbSupport) { - if (AppInterface && getPref(PrefKey.NATIVE_MKB_ENABLED) === "on") + if (AppInterface && getPref("native_mkb_enabled") === "on") AppInterface && NativeMkbHandler.getInstance().init(); - } else if (getPref(PrefKey.MKB_ENABLED) && (AppInterface || !UserAgent.isMobile())) + } else if (getPref("mkb_enabled") && (AppInterface || !UserAgent.isMobile())) BxLogger.info(LOG_TAG4, "Emulate MKB"), EmulatedMkbHandler.getInstance().init(); }); } } -// src/modules/shortcuts/shortcut-microphone.ts -var MicrophoneState; -(function(MicrophoneState2) { - MicrophoneState2["REQUESTED"] = "Requested"; - MicrophoneState2["ENABLED"] = "Enabled"; - MicrophoneState2["MUTED"] = "Muted"; - MicrophoneState2["NOT_ALLOWED"] = "NotAllowed"; - MicrophoneState2["NOT_FOUND"] = "NotFound"; -})(MicrophoneState || (MicrophoneState = {})); - class MicrophoneShortcut { static toggle(showToast = !0) { if (!window.BX_EXPOSED.streamSession) return !1; - const enableMic = window.BX_EXPOSED.streamSession._microphoneState === MicrophoneState.ENABLED ? !1 : !0; + const enableMic = window.BX_EXPOSED.streamSession._microphoneState === "Enabled" ? !1 : !0; try { return window.BX_EXPOSED.streamSession.tryEnableChatAsync(enableMic), showToast && Toast.show(t("microphone"), t(enableMic ? "unmuted" : "muted"), { instant: !0 }), enableMic; } catch (e) { @@ -5766,30 +5401,12 @@ class MicrophoneShortcut { } } -// src/modules/shortcuts/shortcut-stream-ui.ts class StreamUiShortcut { static showHideStreamMenu() { window.BX_EXPOSED.showStreamMenu && window.BX_EXPOSED.showStreamMenu(); } } -// src/modules/controller-shortcut.ts -var ShortcutAction = { - BETTER_XCLOUD_SETTINGS_SHOW: "bx-settings-show", - STREAM_SCREENSHOT_CAPTURE: "stream-screenshot-capture", - STREAM_MENU_SHOW: "stream-menu-show", - STREAM_STATS_TOGGLE: "stream-stats-toggle", - STREAM_SOUND_TOGGLE: "stream-sound-toggle", - STREAM_MICROPHONE_TOGGLE: "stream-microphone-toggle", - STREAM_VOLUME_INC: "stream-volume-inc", - STREAM_VOLUME_DEC: "stream-volume-dec", - DEVICE_SOUND_TOGGLE: "device-sound-toggle", - DEVICE_VOLUME_INC: "device-volume-inc", - DEVICE_VOLUME_DEC: "device-volume-dec", - DEVICE_BRIGHTNESS_INC: "device-brightness-inc", - DEVICE_BRIGHTNESS_DEC: "device-brightness-dec" -}; - class ControllerShortcut { static #STORAGE_KEY = "better_xcloud_controller_shortcuts"; static #buttonsCache = {}; @@ -5811,7 +5428,7 @@ class ControllerShortcut { const pressed = []; let otherButtonPressed = !1; return gamepad.buttons.forEach((button, index) => { - if (button.pressed && index !== GamepadKey.HOME) { + if (button.pressed && index !== 16) { if (otherButtonPressed = !0, pressed[index] = !0, actions[index] && !ControllerShortcut.#buttonsCache[gamepadIndex][index]) setTimeout(() => ControllerShortcut.#runAction(actions[index]), 0); } @@ -5819,35 +5436,35 @@ class ControllerShortcut { } static #runAction(action) { switch (action) { - case ShortcutAction.BETTER_XCLOUD_SETTINGS_SHOW: + case "bx-settings-show": SettingsNavigationDialog.getInstance().show(); break; - case ShortcutAction.STREAM_SCREENSHOT_CAPTURE: + case "stream-screenshot-capture": Screenshot.takeScreenshot(); break; - case ShortcutAction.STREAM_STATS_TOGGLE: + case "stream-stats-toggle": StreamStats.getInstance().toggle(); break; - case ShortcutAction.STREAM_MICROPHONE_TOGGLE: + case "stream-microphone-toggle": MicrophoneShortcut.toggle(); break; - case ShortcutAction.STREAM_MENU_SHOW: + case "stream-menu-show": StreamUiShortcut.showHideStreamMenu(); break; - case ShortcutAction.STREAM_SOUND_TOGGLE: + case "stream-sound-toggle": SoundShortcut.muteUnmute(); break; - case ShortcutAction.STREAM_VOLUME_INC: + case "stream-volume-inc": SoundShortcut.adjustGainNodeVolume(10); break; - case ShortcutAction.STREAM_VOLUME_DEC: + case "stream-volume-dec": SoundShortcut.adjustGainNodeVolume(-10); break; - case ShortcutAction.DEVICE_BRIGHTNESS_INC: - case ShortcutAction.DEVICE_BRIGHTNESS_DEC: - case ShortcutAction.DEVICE_SOUND_TOGGLE: - case ShortcutAction.DEVICE_VOLUME_INC: - case ShortcutAction.DEVICE_VOLUME_DEC: + case "device-brightness-inc": + case "device-brightness-dec": + case "device-sound-toggle": + case "device-volume-inc": + case "device-volume-dec": AppInterface && AppInterface.runShortcut && AppInterface.runShortcut(action); break; } @@ -5906,29 +5523,29 @@ class ControllerShortcut { return JSON.parse(window.localStorage.getItem(ControllerShortcut.#STORAGE_KEY) || "{}"); } static renderSettings() { - const PREF_CONTROLLER_FRIENDLY_UI = getPref(PrefKey.UI_CONTROLLER_FRIENDLY); + const PREF_CONTROLLER_FRIENDLY_UI = getPref("ui_controller_friendly"); ControllerShortcut.#ACTIONS = ControllerShortcut.#getActionsFromStorage(); const buttons = new Map; - buttons.set(GamepadKey.Y, PrompFont.Y), buttons.set(GamepadKey.A, PrompFont.A), buttons.set(GamepadKey.B, PrompFont.B), buttons.set(GamepadKey.X, PrompFont.X), buttons.set(GamepadKey.UP, PrompFont.UP), buttons.set(GamepadKey.DOWN, PrompFont.DOWN), buttons.set(GamepadKey.LEFT, PrompFont.LEFT), buttons.set(GamepadKey.RIGHT, PrompFont.RIGHT), buttons.set(GamepadKey.SELECT, PrompFont.SELECT), buttons.set(GamepadKey.START, PrompFont.START), buttons.set(GamepadKey.LB, PrompFont.LB), buttons.set(GamepadKey.RB, PrompFont.RB), buttons.set(GamepadKey.LT, PrompFont.LT), buttons.set(GamepadKey.RT, PrompFont.RT), buttons.set(GamepadKey.L3, PrompFont.L3), buttons.set(GamepadKey.R3, PrompFont.R3); + buttons.set(3, "⇑"), buttons.set(0, "⇓"), buttons.set(1, "⇒"), buttons.set(2, "⇐"), buttons.set(12, "≻"), buttons.set(13, "≽"), buttons.set(14, "≺"), buttons.set(15, "≼"), buttons.set(8, "⇺"), buttons.set(9, "⇻"), buttons.set(4, "↘"), buttons.set(5, "↙"), buttons.set(6, "↖"), buttons.set(7, "↗"), buttons.set(10, "↺"), buttons.set(11, "↻"); const actions = { [t("better-xcloud")]: { - [ShortcutAction.BETTER_XCLOUD_SETTINGS_SHOW]: [t("settings"), t("show")] + ["bx-settings-show"]: [t("settings"), t("show")] }, [t("device")]: AppInterface && { - [ShortcutAction.DEVICE_SOUND_TOGGLE]: [t("sound"), t("toggle")], - [ShortcutAction.DEVICE_VOLUME_INC]: [t("volume"), t("increase")], - [ShortcutAction.DEVICE_VOLUME_DEC]: [t("volume"), t("decrease")], - [ShortcutAction.DEVICE_BRIGHTNESS_INC]: [t("brightness"), t("increase")], - [ShortcutAction.DEVICE_BRIGHTNESS_DEC]: [t("brightness"), t("decrease")] + ["device-sound-toggle"]: [t("sound"), t("toggle")], + ["device-volume-inc"]: [t("volume"), t("increase")], + ["device-volume-dec"]: [t("volume"), t("decrease")], + ["device-brightness-inc"]: [t("brightness"), t("increase")], + ["device-brightness-dec"]: [t("brightness"), t("decrease")] }, [t("stream")]: { - [ShortcutAction.STREAM_SCREENSHOT_CAPTURE]: t("take-screenshot"), - [ShortcutAction.STREAM_SOUND_TOGGLE]: [t("sound"), t("toggle")], - [ShortcutAction.STREAM_VOLUME_INC]: getPref(PrefKey.AUDIO_ENABLE_VOLUME_CONTROL) && [t("volume"), t("increase")], - [ShortcutAction.STREAM_VOLUME_DEC]: getPref(PrefKey.AUDIO_ENABLE_VOLUME_CONTROL) && [t("volume"), t("decrease")], - [ShortcutAction.STREAM_MENU_SHOW]: [t("menu"), t("show")], - [ShortcutAction.STREAM_STATS_TOGGLE]: [t("stats"), t("show-hide")], - [ShortcutAction.STREAM_MICROPHONE_TOGGLE]: [t("microphone"), t("toggle")] + ["stream-screenshot-capture"]: t("take-screenshot"), + ["stream-sound-toggle"]: [t("sound"), t("toggle")], + ["stream-volume-inc"]: getPref("audio_enable_volume_control") && [t("volume"), t("increase")], + ["stream-volume-dec"]: getPref("audio_enable_volume_control") && [t("volume"), t("decrease")], + ["stream-menu-show"]: [t("menu"), t("show")], + ["stream-stats-toggle"]: [t("stats"), t("show-hide")], + ["stream-microphone-toggle"]: [t("microphone"), t("toggle")] } }, $baseSelect = CE("select", { autocomplete: "off" }, CE("option", { value: "" }, "---")); for (let groupLabel in actions) { @@ -5957,7 +5574,7 @@ class ControllerShortcut { _nearby: { focus: $profile } - }, $profile), CE("p", { class: "bx-shortcut-note" }, CE("span", { class: "bx-prompt" }, PrompFont.HOME), ": " + t("controller-shortcuts-xbox-note")))); + }, $profile), CE("p", { class: "bx-shortcut-note" }, CE("span", { class: "bx-prompt" }, ""), ": " + t("controller-shortcuts-xbox-note")))); $selectProfile.addEventListener("input", (e) => { ControllerShortcut.#switchProfile($selectProfile.value); }); @@ -5977,7 +5594,7 @@ class ControllerShortcut { for (let [button, prompt2] of buttons) { const $row = CE("div", { class: "bx-shortcut-row" - }), $label = CE("label", { class: "bx-prompt" }, `${PrompFont.HOME} + ${prompt2}`), $div = CE("div", { class: "bx-shortcut-actions" }); + }), $label = CE("label", { class: "bx-prompt" }, `${""} + ${prompt2}`), $div = CE("div", { class: "bx-shortcut-actions" }); if (!PREF_CONTROLLER_FRIENDLY_UI) { const $fakeSelect = CE("select", { autocomplete: "off" }, CE("option", {}, "---")); $div.appendChild($fakeSelect); @@ -5998,28 +5615,18 @@ class ControllerShortcut { } } -// src/utils/bx-exposed.ts -var InputType; -(function(InputType2) { - InputType2["CONTROLLER"] = "Controller"; - InputType2["MKB"] = "MKB"; - InputType2["CUSTOM_TOUCH_OVERLAY"] = "CustomTouchOverlay"; - InputType2["GENERIC_TOUCH"] = "GenericTouch"; - InputType2["NATIVE_TOUCH"] = "NativeTouch"; - InputType2["BATIVE_SENSOR"] = "NativeSensor"; -})(InputType || (InputType = {})); var BxExposed = { getTitleInfo: () => STATES.currentStream.titleInfo, modifyTitleInfo: (titleInfo) => { titleInfo = deepClone(titleInfo); let supportedInputTypes = titleInfo.details.supportedInputTypes; if (BX_FLAGS.ForceNativeMkbTitles?.includes(titleInfo.details.productId)) - supportedInputTypes.push(InputType.MKB); - if (getPref(PrefKey.NATIVE_MKB_ENABLED) === "off") - supportedInputTypes = supportedInputTypes.filter((i) => i !== InputType.MKB); - if (titleInfo.details.hasMkbSupport = supportedInputTypes.includes(InputType.MKB), STATES.userAgent.capabilities.touch) { - let touchControllerAvailability = getPref(PrefKey.STREAM_TOUCH_CONTROLLER); - if (touchControllerAvailability !== "off" && getPref(PrefKey.STREAM_TOUCH_CONTROLLER_AUTO_OFF)) { + supportedInputTypes.push("MKB"); + if (getPref("native_mkb_enabled") === "off") + supportedInputTypes = supportedInputTypes.filter((i) => i !== "MKB"); + if (titleInfo.details.hasMkbSupport = supportedInputTypes.includes("MKB"), STATES.userAgent.capabilities.touch) { + let touchControllerAvailability = getPref("stream_touch_controller"); + if (touchControllerAvailability !== "off" && getPref("stream_touch_controller_auto_off")) { const gamepads = window.navigator.getGamepads(); let gamepadFound = !1; for (let gamepad of gamepads) @@ -6030,9 +5637,9 @@ var BxExposed = { gamepadFound && (touchControllerAvailability = "off"); } if (touchControllerAvailability === "off") - supportedInputTypes = supportedInputTypes.filter((i) => i !== InputType.CUSTOM_TOUCH_OVERLAY && i !== InputType.GENERIC_TOUCH), titleInfo.details.supportedTabs = []; - if (titleInfo.details.hasNativeTouchSupport = supportedInputTypes.includes(InputType.NATIVE_TOUCH), titleInfo.details.hasTouchSupport = titleInfo.details.hasNativeTouchSupport || supportedInputTypes.includes(InputType.CUSTOM_TOUCH_OVERLAY) || supportedInputTypes.includes(InputType.GENERIC_TOUCH), !titleInfo.details.hasTouchSupport && touchControllerAvailability === "all") - titleInfo.details.hasFakeTouchSupport = !0, supportedInputTypes.push(InputType.GENERIC_TOUCH); + supportedInputTypes = supportedInputTypes.filter((i) => i !== "CustomTouchOverlay" && i !== "GenericTouch"), titleInfo.details.supportedTabs = []; + if (titleInfo.details.hasNativeTouchSupport = supportedInputTypes.includes("NativeTouch"), titleInfo.details.hasTouchSupport = titleInfo.details.hasNativeTouchSupport || supportedInputTypes.includes("CustomTouchOverlay") || supportedInputTypes.includes("GenericTouch"), !titleInfo.details.hasTouchSupport && touchControllerAvailability === "all") + titleInfo.details.hasFakeTouchSupport = !0, supportedInputTypes.push("GenericTouch"); } return titleInfo.details.supportedInputTypes = supportedInputTypes, STATES.currentStream.titleInfo = titleInfo, BxEvent.dispatch(window, BxEvent.TITLE_INFO_READY), titleInfo; }, @@ -6068,7 +5675,6 @@ var BxExposed = { } }; -// src/modules/ui/ui.ts function localRedirect(path) { const url = window.location.href.substring(0, 31) + path, $pageContent = document.getElementById("PageContent"); if (!$pageContent) @@ -6085,9 +5691,8 @@ function localRedirect(path) { } window.localRedirect = localRedirect; -// src/utils/region.ts function getPreferredServerRegion(shortName = !1) { - let preferredRegion = getPref(PrefKey.SERVER_REGION); + let preferredRegion = getPref("server_region"); if (preferredRegion in STATES.serverRegions) if (shortName && STATES.serverRegions[preferredRegion].shortName) return STATES.serverRegions[preferredRegion].shortName; @@ -6105,7 +5710,6 @@ function getPreferredServerRegion(shortName = !1) { return null; } -// src/modules/ui/header.ts class HeaderSection { static #$remotePlayBtn = createButton({ classes: ["bx-header-remote-play-button", "bx-gone"], @@ -6124,13 +5728,13 @@ class HeaderSection { SettingsNavigationDialog.getInstance().show(); } }); - static #$buttonsWrapper = CE("div", {}, getPref(PrefKey.REMOTE_PLAY_ENABLED) ? HeaderSection.#$remotePlayBtn : null, HeaderSection.#$settingsBtn); + static #$buttonsWrapper = CE("div", {}, getPref("xhome_enabled") ? HeaderSection.#$remotePlayBtn : null, HeaderSection.#$settingsBtn); static #observer; static #timeout; static #injectSettingsButton($parent) { if (!$parent) return; - const PREF_LATEST_VERSION = getPref(PrefKey.LATEST_VERSION), $settingsBtn = HeaderSection.#$settingsBtn; + const PREF_LATEST_VERSION = getPref("version_latest"), $settingsBtn = HeaderSection.#$settingsBtn; if ($settingsBtn.querySelector("span").textContent = getPreferredServerRegion(!0) || t("better-xcloud"), !SCRIPT_VERSION.includes("beta") && PREF_LATEST_VERSION && PREF_LATEST_VERSION !== SCRIPT_VERSION) $settingsBtn.setAttribute("data-update-available", "true"); $parent.appendChild(HeaderSection.#$buttonsWrapper); @@ -6154,24 +5758,17 @@ class HeaderSection { } } -// src/modules/remote-play.ts -var LOG_TAG5 = "RemotePlay", RemotePlayConsoleState = { - ON: "On", - OFF: "Off", - STANDBY: "ConnectedStandby", - UNKNOWN: "Unknown" -}; - +var LOG_TAG5 = "RemotePlay"; class RemotePlay { static XCLOUD_TOKEN; static XHOME_TOKEN; static #CONSOLES; static #REGIONS; static #STATE_LABELS = { - [RemotePlayConsoleState.ON]: t("powered-on"), - [RemotePlayConsoleState.OFF]: t("powered-off"), - [RemotePlayConsoleState.STANDBY]: t("standby"), - [RemotePlayConsoleState.UNKNOWN]: t("unknown") + ["On"]: t("powered-on"), + ["Off"]: t("powered-off"), + ["ConnectedStandby"]: t("standby"), + ["Unknown"]: t("unknown") }; static BASE_DEVICE_INFO = { appInfo: { @@ -6229,7 +5826,7 @@ class RemotePlay { $fragment.appendChild(CE("span", {}, t("no-consoles-found"))), RemotePlay.#$content = CE("div", {}, $fragment); return; } - const $settingNote = CE("p", {}), resolutions = [1080, 720], currentResolution = getPref(PrefKey.REMOTE_PLAY_RESOLUTION), $resolutionGroup = CE("div", {}); + const $settingNote = CE("p", {}), resolutions = [1080, 720], currentResolution = getPref("xhome_resolution"), $resolutionGroup = CE("div", {}); for (let resolution of resolutions) { const value = `${resolution}p`, id2 = `bx_radio_xhome_resolution_${resolution}`, $radio = CE("input", { type: "radio", @@ -6239,7 +5836,7 @@ class RemotePlay { }, value); $radio.addEventListener("change", (e) => { const value2 = e.target.value; - $settingNote.textContent = value2 === "1080p" ? "✅ " + t("can-stream-xbox-360-games") : "❌ " + t("cant-stream-xbox-360-games"), setPref(PrefKey.REMOTE_PLAY_RESOLUTION, value2); + $settingNote.textContent = value2 === "1080p" ? "✅ " + t("can-stream-xbox-360-games") : "❌ " + t("cant-stream-xbox-360-games"), setPref("xhome_resolution", value2); }); const $label = CE("label", { for: id2, @@ -6330,7 +5927,7 @@ class RemotePlay { } static play(serverId, resolution) { if (resolution) - setPref(PrefKey.REMOTE_PLAY_RESOLUTION, resolution); + setPref("xhome_resolution", resolution); STATES.remotePlay.config = { serverId }, window.BX_REMOTE_PLAY_CONFIG = STATES.remotePlay.config, localRedirect("/launch/fortnite/BT5P2X999VH2#remote-play"), RemotePlay.detachPopup(); @@ -6343,7 +5940,7 @@ class RemotePlay { $popup && $popup.remove(); } static togglePopup(force = null) { - if (!getPref(PrefKey.REMOTE_PLAY_ENABLED) || !RemotePlay.isReady()) { + if (!getPref("xhome_enabled") || !RemotePlay.isReady()) { Toast.show(t("getting-consoles-list")); return; } @@ -6362,7 +5959,7 @@ class RemotePlay { RemotePlay.#$content.setAttribute("data-group", group), RemotePlay.#$content.classList.add("bx-remote-play-popup"), RemotePlay.#$content.classList.remove("bx-gone"), $header.insertAdjacentElement("afterend", RemotePlay.#$content); } static detect() { - if (!getPref(PrefKey.REMOTE_PLAY_ENABLED)) + if (!getPref("xhome_enabled")) return; if (STATES.remotePlay.isPlaying = window.location.pathname.includes("/launch/") && window.location.hash.startsWith("#remote-play"), STATES.remotePlay?.isPlaying) window.BX_REMOTE_PLAY_CONFIG = STATES.remotePlay.config, window.history.replaceState({ origin: "better-xcloud" }, "", "https://www.xbox.com/" + location.pathname.substring(1, 6) + "/play"); @@ -6374,7 +5971,6 @@ class RemotePlay { } } -// src/utils/xhome-interceptor.ts class XhomeInterceptor { static #consoleAddrs = {}; static async#handleLogin(request) { @@ -6406,7 +6002,7 @@ class XhomeInterceptor { } static async#handleInputConfigs(request, opts) { const response = await NATIVE_FETCH(request); - if (getPref(PrefKey.STREAM_TOUCH_CONTROLLER) !== "all") + if (getPref("stream_touch_controller") !== "all") return response; const obj = await response.clone().json(), xboxTitleId = JSON.parse(opts.body).titleIds[0]; TouchController.setXboxTitleId(xboxTitleId); @@ -6414,7 +6010,7 @@ class XhomeInterceptor { let hasTouchSupport = inputConfigs.supportedTabs.length > 0; if (!hasTouchSupport) { const supportedInputTypes = inputConfigs.supportedInputTypes; - hasTouchSupport = supportedInputTypes.includes(InputType.NATIVE_TOUCH) || supportedInputTypes.includes(InputType.CUSTOM_TOUCH_OVERLAY); + hasTouchSupport = supportedInputTypes.includes("NativeTouch") || supportedInputTypes.includes("CustomTouchOverlay"); } if (hasTouchSupport) TouchController.disable(), BxEvent.dispatch(window, BxEvent.CUSTOM_TOUCH_LAYOUTS_LOADED, { @@ -6449,7 +6045,7 @@ class XhomeInterceptor { headers[pair[0]] = pair[1]; headers.authorization = `Bearer ${RemotePlay.XHOME_TOKEN}`; const deviceInfo = RemotePlay.BASE_DEVICE_INFO; - if (getPref(PrefKey.REMOTE_PLAY_RESOLUTION) === "720p") + if (getPref("xhome_resolution") === "720p") deviceInfo.dev.os.name = "android"; headers["x-ms-device-info"] = JSON.stringify(deviceInfo); const opts = { @@ -6481,7 +6077,6 @@ class XhomeInterceptor { } } -// src/modules/loading-screen.ts class LoadingScreen { static #$bgStyle; static #$waitTimeBox; @@ -6499,7 +6094,7 @@ class LoadingScreen { const $bgStyle = CE("style"); document.documentElement.appendChild($bgStyle), LoadingScreen.#$bgStyle = $bgStyle; } - if (LoadingScreen.#setBackground(titleInfo.product.heroImageUrl || titleInfo.product.titledHeroImageUrl || titleInfo.product.tileImageUrl), getPref(PrefKey.UI_LOADING_SCREEN_ROCKET) === "hide") + if (LoadingScreen.#setBackground(titleInfo.product.heroImageUrl || titleInfo.product.titledHeroImageUrl || titleInfo.product.tileImageUrl), getPref("ui_loading_screen_rocket") === "hide") LoadingScreen.#hideRocket(); } static #hideRocket() { @@ -6542,7 +6137,7 @@ class LoadingScreen { }, bg.src = imageUrl; } static setupWaitTime(waitTime) { - if (getPref(PrefKey.UI_LOADING_SCREEN_ROCKET) === "hide-queue") + if (getPref("ui_loading_screen_rocket") === "hide-queue") LoadingScreen.#hideRocket(); let secondsLeft = waitTime, $countDown, $estimated; LoadingScreen.#orgWebTitle = document.title; @@ -6561,7 +6156,7 @@ class LoadingScreen { }, 1000); } static hide() { - if (LoadingScreen.#orgWebTitle && (document.title = LoadingScreen.#orgWebTitle), LoadingScreen.#$waitTimeBox && LoadingScreen.#$waitTimeBox.classList.add("bx-gone"), getPref(PrefKey.UI_LOADING_SCREEN_GAME_ART) && LoadingScreen.#$bgStyle) { + if (LoadingScreen.#orgWebTitle && (document.title = LoadingScreen.#orgWebTitle), LoadingScreen.#$waitTimeBox && LoadingScreen.#$waitTimeBox.classList.add("bx-gone"), getPref("ui_loading_screen_game_art") && LoadingScreen.#$bgStyle) { const $rocketBg = document.querySelector('#game-stream rect[width="800"]'); $rocketBg && $rocketBg.addEventListener("transitionend", (e) => { LoadingScreen.#$bgStyle.textContent += ` @@ -6582,23 +6177,14 @@ class LoadingScreen { } } -// src/modules/stream/stream-badges.ts -var StreamBadge = { - PLAYTIME: "playtime", - BATTERY: "battery", - DOWNLOAD: "in", - UPLOAD: "out", - SERVER: "server", - VIDEO: "video", - AUDIO: "audio" -}, StreamBadgeIcon = { - [StreamBadge.PLAYTIME]: BxIcon.PLAYTIME, - [StreamBadge.VIDEO]: BxIcon.DISPLAY, - [StreamBadge.BATTERY]: BxIcon.BATTERY, - [StreamBadge.DOWNLOAD]: BxIcon.DOWNLOAD, - [StreamBadge.UPLOAD]: BxIcon.UPLOAD, - [StreamBadge.SERVER]: BxIcon.SERVER, - [StreamBadge.AUDIO]: BxIcon.AUDIO +var StreamBadgeIcon = { + ["playtime"]: BxIcon.PLAYTIME, + ["video"]: BxIcon.DISPLAY, + ["battery"]: BxIcon.BATTERY, + ["in"]: BxIcon.DOWNLOAD, + ["out"]: BxIcon.UPLOAD, + ["server"]: BxIcon.SERVER, + ["audio"]: BxIcon.AUDIO }; class StreamBadges { @@ -6626,7 +6212,7 @@ class StreamBadges { let $badge; if (this.#cachedDoms[name]) return $badge = this.#cachedDoms[name], $badge.lastElementChild.textContent = value, $badge; - if ($badge = CE("div", { class: "bx-badge", title: t(`badge-${name}`) }, CE("span", { class: "bx-badge-name" }, createSvgIcon(StreamBadgeIcon[name])), CE("span", { class: "bx-badge-value", style: `background-color: ${color}` }, value)), name === StreamBadge.BATTERY) + if ($badge = CE("div", { class: "bx-badge", title: t(`badge-${name}`) }, CE("span", { class: "bx-badge-name" }, createSvgIcon(StreamBadgeIcon[name])), CE("span", { class: "bx-badge-value", style: `background-color: ${color}` }, value)), name === "battery") $badge.classList.add("bx-badge-battery"); return this.#cachedDoms[name] = $badge, $badge; } @@ -6654,10 +6240,10 @@ class StreamBadges { totalIn += stat.bytesReceived, totalOut += stat.bytesSent; }); const badges = { - [StreamBadge.DOWNLOAD]: totalIn ? this.#humanFileSize(totalIn) : null, - [StreamBadge.UPLOAD]: totalOut ? this.#humanFileSize(totalOut) : null, - [StreamBadge.PLAYTIME]: playtime, - [StreamBadge.BATTERY]: batteryLevel + ["in"]: totalIn ? this.#humanFileSize(totalIn) : null, + ["out"]: totalOut ? this.#humanFileSize(totalOut) : null, + ["playtime"]: playtime, + ["battery"]: batteryLevel }; let name; for (name in badges) { @@ -6665,7 +6251,7 @@ class StreamBadges { if (value === null) continue; const $elm = this.#cachedDoms[name]; - if ($elm && ($elm.lastElementChild.textContent = value), name === StreamBadge.BATTERY) + if ($elm && ($elm.lastElementChild.textContent = value), name === "battery") if (this.startBatteryLevel === 100 && batteryLevelInt === 100) $elm.classList.add("bx-gone"); else @@ -6721,13 +6307,13 @@ class StreamBadges { let server = this.#region; server += "@" + (this.#ipv6 ? "IPv6" : "IPv4"); const BADGES = [ - [StreamBadge.PLAYTIME, "1m", "#ff004d"], - [StreamBadge.BATTERY, batteryLevel, "#00b543"], - [StreamBadge.DOWNLOAD, this.#humanFileSize(0), "#29adff"], - [StreamBadge.UPLOAD, this.#humanFileSize(0), "#ff77a8"], - [StreamBadge.SERVER, server, "#ff6c24"], - video ? [StreamBadge.VIDEO, video, "#742f29"] : null, - audio ? [StreamBadge.AUDIO, audio, "#5f574f"] : null + ["playtime", "1m", "#ff004d"], + ["battery", batteryLevel, "#00b543"], + ["in", this.#humanFileSize(0), "#29adff"], + ["out", this.#humanFileSize(0), "#ff77a8"], + ["server", server, "#ff6c24"], + video ? ["video", video, "#742f29"] : null, + audio ? ["audio", audio, "#5f574f"] : null ], $container = CE("div", { class: "bx-badges" }); return BADGES.forEach((item2) => { if (!item2) @@ -6796,10 +6382,9 @@ class StreamBadges { } } -// src/utils/xcloud-interceptor.ts class XcloudInterceptor { static async#handleLogin(request, init) { - const bypassServer = getPref(PrefKey.SERVER_BYPASS_RESTRICTION); + const bypassServer = getPref("server_bypass_restriction"); if (bypassServer !== "off") { const ip = BypassServerIps[bypassServer]; ip && request.headers.set("X-Forwarded-For", ip); @@ -6846,7 +6431,7 @@ class XcloudInterceptor { return STATES.gsToken = obj.gsToken, response.json = () => Promise.resolve(obj), response; } static async#handlePlay(request, init) { - const PREF_STREAM_TARGET_RESOLUTION = getPref(PrefKey.STREAM_TARGET_RESOLUTION), PREF_STREAM_PREFERRED_LOCALE = getPref(PrefKey.STREAM_PREFERRED_LOCALE), url = typeof request === "string" ? request : request.url, parsedUrl = new URL(url); + const PREF_STREAM_TARGET_RESOLUTION = getPref("stream_target_resolution"), PREF_STREAM_PREFERRED_LOCALE = getPref("stream_preferred_locale"), url = typeof request === "string" ? request : request.url, parsedUrl = new URL(url); let badgeRegion = parsedUrl.host.split(".", 1)[0]; for (let regionName in STATES.serverRegions) { const region4 = STATES.serverRegions[regionName]; @@ -6870,7 +6455,7 @@ class XcloudInterceptor { } static async#handleWaitTime(request, init) { const response = await NATIVE_FETCH(request, init); - if (getPref(PrefKey.UI_LOADING_SCREEN_WAIT_TIME)) { + if (getPref("ui_loading_screen_wait_time")) { const json = await response.clone().json(); if (json.estimatedAllocationTimeInSeconds > 0) LoadingScreen.setupWaitTime(json.estimatedTotalWaitTimeInSeconds); @@ -6880,7 +6465,7 @@ class XcloudInterceptor { static async#handleConfiguration(request, init) { if (request.method !== "GET") return NATIVE_FETCH(request, init); - if (getPref(PrefKey.STREAM_TOUCH_CONTROLLER) === "all") + if (getPref("stream_touch_controller") === "all") if (STATES.currentStream.titleInfo?.details.hasTouchSupport) TouchController.disable(); else @@ -6892,9 +6477,9 @@ class XcloudInterceptor { let overrides = JSON.parse(obj.clientStreamingConfigOverrides || "{}") || {}; overrides.inputConfiguration = overrides.inputConfiguration || {}, overrides.inputConfiguration.enableVibration = !0; let overrideMkb = null; - if (getPref(PrefKey.NATIVE_MKB_ENABLED) === "on" || STATES.currentStream.titleInfo && BX_FLAGS.ForceNativeMkbTitles?.includes(STATES.currentStream.titleInfo.details.productId)) + if (getPref("native_mkb_enabled") === "on" || STATES.currentStream.titleInfo && BX_FLAGS.ForceNativeMkbTitles?.includes(STATES.currentStream.titleInfo.details.productId)) overrideMkb = !0; - if (getPref(PrefKey.NATIVE_MKB_ENABLED) === "off") + if (getPref("native_mkb_enabled") === "off") overrideMkb = !1; if (overrideMkb !== null) overrides.inputConfiguration = Object.assign(overrides.inputConfiguration, { @@ -6903,7 +6488,7 @@ class XcloudInterceptor { }); if (TouchController.isEnabled()) overrides.inputConfiguration.enableTouchInput = !0, overrides.inputConfiguration.maxTouchPoints = 10; - if (getPref(PrefKey.AUDIO_MIC_ON_PLAYING)) + if (getPref("audio_mic_on_playing")) overrides.audioConfiguration = overrides.audioConfiguration || {}, overrides.audioConfiguration.enableMicrophone = !0; return obj.clientStreamingConfigOverrides = JSON.stringify(overrides), response.json = () => Promise.resolve(obj), response.text = () => Promise.resolve(JSON.stringify(obj)), response; } @@ -6923,10 +6508,10 @@ class XcloudInterceptor { } } -// src/utils/network.ts -var clearApplicationInsightsBuffers = function() { +function clearApplicationInsightsBuffers() { window.sessionStorage.removeItem("AI_buffer"), window.sessionStorage.removeItem("AI_sentBuffer"); -}, clearDbLogs = function(dbName, table) { +} +function clearDbLogs(dbName, table) { const request = window.indexedDB.open(dbName); request.onsuccess = (e) => { const db = e.target.result; @@ -6938,9 +6523,11 @@ var clearApplicationInsightsBuffers = function() { } catch (ex) { } }; -}, clearAllLogs = function() { +} +function clearAllLogs() { clearApplicationInsightsBuffers(), clearDbLogs("StreamClientLogHandler", "logs"), clearDbLogs("XCloudAppLogs", "logs"); -}, updateIceCandidates = function(candidates, options) { +} +function updateIceCandidates(candidates, options) { const pattern = new RegExp(/a=candidate:(?\d+) (?\d+) UDP (?\d+) (?[^\s]+) (?\d+) (?.*)/), lst = []; for (let item2 of candidates) { if (item2.candidate == "a=end-of-candidates") @@ -6971,13 +6558,13 @@ var clearApplicationInsightsBuffers = function() { newCandidates.push(newCandidate(`a=candidate:${newCandidates.length + 1} 1 UDP 1 ${ip} ${port} typ host`)); } return newCandidates.push(newCandidate("a=end-of-candidates")), BxLogger.info("ICE Candidates", newCandidates), newCandidates; -}; +} async function patchIceCandidates(request, consoleAddrs) { const response = await NATIVE_FETCH(request), text = await response.clone().text(); if (!text.length) return response; const options = { - preferIpv6Server: getPref(PrefKey.PREFER_IPV6_SERVER), + preferIpv6Server: getPref("prefer_ipv6_server"), consoleAddrs }, obj = JSON.parse(text); let exchangeResponse = JSON.parse(obj.exchangeResponse); @@ -6985,14 +6572,14 @@ async function patchIceCandidates(request, consoleAddrs) { } function interceptHttpRequests() { let BLOCKED_URLS = []; - if (getPref(PrefKey.BLOCK_TRACKING)) + if (getPref("block_tracking")) clearAllLogs(), BLOCKED_URLS = BLOCKED_URLS.concat([ "https://arc.msn.com", "https://browser.events.data.microsoft.com", "https://dc.services.visualstudio.com", "https://2c06dea3f26c40c69b8456d319791fd0@o427368.ingest.sentry.io" ]); - if (getPref(PrefKey.BLOCK_SOCIAL_FEATURES)) + if (getPref("block_social_features")) BLOCKED_URLS = BLOCKED_URLS.concat([ "https://peoplehub.xboxlive.com/users/me/people/social", "https://peoplehub.xboxlive.com/users/me/people/recommendations", @@ -7037,10 +6624,10 @@ function interceptHttpRequests() { } if (STATES.userAgent.capabilities.touch && url.includes("catalog.gamepass.com/sigls/")) { const response = await NATIVE_FETCH(request, init), obj = await response.clone().json(); - if (url.includes(GamePassCloudGallery.ALL)) + if (url.includes("29a81209-df6f-41fd-a528-2ae6b91f719c")) for (let i = 1;i < obj.length; i++) gamepassAllGames.push(obj[i].id); - else if (url.includes(GamePassCloudGallery.TOUCH)) + else if (url.includes("9c86f07a-f3e8-45ad-82a0-a1f759597059")) try { let customList = TouchController.getCustomList(); customList = customList.filter((id2) => gamepassAllGames.includes(id2)); @@ -7051,7 +6638,7 @@ function interceptHttpRequests() { } return response.json = () => Promise.resolve(obj), response; } - if (BX_FLAGS.ForceNativeMkbTitles && url.includes("catalog.gamepass.com/sigls/") && url.includes(GamePassCloudGallery.NATIVE_MKB)) { + if (BX_FLAGS.ForceNativeMkbTitles && url.includes("catalog.gamepass.com/sigls/") && url.includes("8fa264dd-124f-4af3-97e8-596fcdf4b486")) { const response = await NATIVE_FETCH(request, init), obj = await response.clone().json(); try { const newCustomList = BX_FLAGS.ForceNativeMkbTitles.map((item2) => ({ id: item2 })); @@ -7072,13 +6659,12 @@ function interceptHttpRequests() { }; } -// src/utils/gamepad.ts function showGamepadToast(gamepad) { if (gamepad.id === EmulatedMkbHandler.VIRTUAL_GAMEPAD_ID) return; BxLogger.info("Gamepad", gamepad); let text = "🎮"; - if (getPref(PrefKey.LOCAL_CO_OP_ENABLED)) + if (getPref("local_co_op_enabled")) text += ` #${gamepad.index + 1}`; const gamepadId = gamepad.id.replace(/ \(.*?Vendor: \w+ Product: \w+\)$/, ""); text += ` - ${gamepadId}`; @@ -7090,31 +6676,30 @@ function showGamepadToast(gamepad) { Toast.show(text, status, { instant: !1 }); } -// src/utils/css.ts function addCss() { let css = `:root{--bx-title-font:Bahnschrift,Arial,Helvetica,sans-serif;--bx-title-font-semibold:Bahnschrift Semibold,Arial,Helvetica,sans-serif;--bx-normal-font:"Segoe UI",Arial,Helvetica,sans-serif;--bx-monospaced-font:Consolas,"Courier New",Courier,monospace;--bx-promptfont-font:promptfont;--bx-button-height:40px;--bx-default-button-color:#2d3036;--bx-default-button-rgb:45,48,54;--bx-default-button-hover-color:#515863;--bx-default-button-hover-rgb:81,88,99;--bx-default-button-active-color:#222428;--bx-default-button-active-rgb:34,36,40;--bx-default-button-disabled-color:#8e8e8e;--bx-default-button-disabled-rgb:142,142,142;--bx-primary-button-color:#008746;--bx-primary-button-rgb:0,135,70;--bx-primary-button-hover-color:#04b358;--bx-primary-button-hover-rgb:4,179,88;--bx-primary-button-active-color:#044e2a;--bx-primary-button-active-rgb:4,78,42;--bx-primary-button-disabled-color:#448262;--bx-primary-button-disabled-rgb:68,130,98;--bx-danger-button-color:#c10404;--bx-danger-button-rgb:193,4,4;--bx-danger-button-hover-color:#e61d1d;--bx-danger-button-hover-rgb:230,29,29;--bx-danger-button-active-color:#a26c6c;--bx-danger-button-active-rgb:162,108,108;--bx-danger-button-disabled-color:#df5656;--bx-danger-button-disabled-rgb:223,86,86;--bx-toast-z-index:9999;--bx-dialog-z-index:9101;--bx-dialog-overlay-z-index:9100;--bx-stats-bar-z-index:9010;--bx-mkb-pointer-lock-msg-z-index:9000;--bx-navigation-dialog-z-index:8999;--bx-navigation-dialog-overlay-z-index:8998;--bx-remote-play-popup-z-index:2000;--bx-game-bar-z-index:1000;--bx-wait-time-box-z-index:100;--bx-screenshot-animation-z-index:1}@font-face{font-family:'promptfont';src:url("https://redphx.github.io/better-xcloud/fonts/promptfont.otf")}div[class^=HUDButton-module__hiddenContainer] ~ div:not([class^=HUDButton-module__hiddenContainer]){opacity:0;pointer-events:none !important;position:absolute;top:-9999px;left:-9999px}@media screen and (max-width:600px){header a[href="/play"]{display:none}}.bx-full-width{width:100% !important}.bx-full-height{height:100% !important}.bx-no-scroll{overflow:hidden !important}.bx-hide-scroll-bar{scrollbar-width:none}.bx-hide-scroll-bar::-webkit-scrollbar{display:none}.bx-gone{display:none !important}.bx-offscreen{position:absolute !important;top:-9999px !important;left:-9999px !important;visibility:hidden !important}.bx-hidden{visibility:hidden !important}.bx-invisible{opacity:0}.bx-unclickable{pointer-events:none}.bx-pixel{width:1px !important;height:1px !important}.bx-no-margin{margin:0 !important}.bx-no-padding{padding:0 !important}.bx-prompt{font-family:var(--bx-promptfont-font)}.bx-line-through{text-decoration:line-through !important}.bx-normal-case{text-transform:none !important}select[multiple]{overflow:auto}#headerArea,#uhfSkipToMain,.uhf-footer{display:none}div[class*=NotFocusedDialog]{position:absolute !important;top:-9999px !important;left:-9999px !important;width:0 !important;height:0 !important}#game-stream video:not([src]){visibility:hidden}div[class*=SupportedInputsBadge]:not(:has(:nth-child(2))),div[class*=SupportedInputsBadge] svg:first-of-type{display:none}.bx-game-tile-wait-time{position:absolute;top:0;left:0;z-index:1;background:rgba(0,0,0,0.549);display:none;border-radius:0 0 4px 0;align-items:center;padding:4px 8px}a[class^=BaseItem-module__container]:focus .bx-game-tile-wait-time,button[class^=BaseItem-module__container]:focus .bx-game-tile-wait-time{display:flex}.bx-game-tile-wait-time svg{width:14px;height:16px;margin-right:2px}.bx-game-tile-wait-time span{display:inline-block;height:16px;line-height:16px;font-size:12px;font-weight:bold}.bx-button{--button-rgb:var(--bx-default-button-rgb);--button-hover-rgb:var(--bx-default-button-hover-rgb);--button-active-rgb:var(--bx-default-button-active-rgb);--button-disabled-rgb:var(--bx-default-button-disabled-rgb);background-color:rgb(var(--button-rgb));user-select:none;-webkit-user-select:none;color:#fff;font-family:var(--bx-title-font-semibold);font-size:14px;border:none;font-weight:400;height:var(--bx-button-height);border-radius:4px;padding:0 8px;text-transform:uppercase;cursor:pointer;overflow:hidden}.bx-button:not([disabled]):active{background-color:rgb(var(--button-active-rgb))}.bx-button:focus{outline:none !important}.bx-button:not([disabled]):not(:active):hover,.bx-button:not([disabled]):not(:active).bx-focusable:focus{background-color:rgb(var(--button-hover-rgb))}.bx-button:disabled{cursor:default;background-color:rgb(var(--button-disabled-rgb))}.bx-button.bx-ghost{background-color:transparent}.bx-button.bx-ghost:not([disabled]):not(:active):hover,.bx-button.bx-ghost:not([disabled]):not(:active).bx-focusable:focus{background-color:rgb(var(--button-hover-rgb))}.bx-button.bx-primary{--button-rgb:var(--bx-primary-button-rgb)}.bx-button.bx-primary:not([disabled]):active{--button-active-rgb:var(--bx-primary-button-active-rgb)}.bx-button.bx-primary:not([disabled]):not(:active):hover,.bx-button.bx-primary:not([disabled]):not(:active).bx-focusable:focus{--button-hover-rgb:var(--bx-primary-button-hover-rgb)}.bx-button.bx-primary:disabled{--button-disabled-rgb:var(--bx-primary-button-disabled-rgb)}.bx-button.bx-danger{--button-rgb:var(--bx-danger-button-rgb)}.bx-button.bx-danger:not([disabled]):active{--button-active-rgb:var(--bx-danger-button-active-rgb)}.bx-button.bx-danger:not([disabled]):not(:active):hover,.bx-button.bx-danger:not([disabled]):not(:active).bx-focusable:focus{--button-hover-rgb:var(--bx-danger-button-hover-rgb)}.bx-button.bx-danger:disabled{--button-disabled-rgb:var(--bx-danger-button-disabled-rgb)}.bx-button.bx-frosted{--button-alpha:.2;background-color:rgba(var(--button-rgb), var(--button-alpha));backdrop-filter:blur(4px) brightness(1.5)}.bx-button.bx-frosted:not([disabled]):not(:active):hover,.bx-button.bx-frosted:not([disabled]):not(:active).bx-focusable:focus{background-color:rgba(var(--button-hover-rgb), var(--button-alpha))}.bx-button.bx-drop-shadow{box-shadow:0 0 4px rgba(0,0,0,0.502)}.bx-button.bx-tall{height:calc(var(--bx-button-height) * 1.5) !important}.bx-button.bx-circular{border-radius:var(--bx-button-height);height:var(--bx-button-height)}.bx-button svg{display:inline-block;width:16px;height:var(--bx-button-height)}.bx-button span{display:inline-block;line-height:var(--bx-button-height);vertical-align:middle;color:#fff;overflow:hidden;white-space:nowrap}.bx-button span:not(:only-child){margin-left:10px}.bx-focusable{position:relative;overflow:visible}.bx-focusable::after{border:2px solid transparent;border-radius:10px}.bx-focusable:focus-visible::after{content:'';border-color:#fff;position:absolute;top:-6px;left:-6px;right:-6px;bottom:-6px}.bx-focusable.bx-circular::after{border-radius:var(--bx-button-height)}a.bx-button{display:inline-block}a.bx-button.bx-full-width{text-align:center}button.bx-inactive{pointer-events:none;opacity:.2;background:transparent !important}.bx-button-shortcut{max-width:max-content;margin:10px 0 0 0;overflow:hidden}@media (min-width:568px) and (max-height:480px){.bx-button-shortcut{margin:8px 0 0 10px}}.bx-header-remote-play-button{height:auto;margin-right:8px !important}.bx-header-remote-play-button svg{width:24px;height:24px}.bx-header-settings-button{line-height:30px;font-size:14px;text-transform:uppercase;position:relative}.bx-header-settings-button[data-update-available]::before{content:'🌟' !important;line-height:var(--bx-button-height);display:inline-block;margin-left:4px}.bx-dialog-overlay{position:fixed;inset:0;z-index:var(--bx-dialog-overlay-z-index);background:#000;opacity:50%}.bx-dialog{display:flex;flex-flow:column;max-height:90vh;position:fixed;top:50%;left:50%;margin-right:-50%;transform:translate(-50%,-50%);min-width:420px;padding:20px;border-radius:8px;z-index:var(--bx-dialog-z-index);background:#1a1b1e;color:#fff;font-weight:400;font-size:16px;font-family:var(--bx-normal-font);box-shadow:0 0 6px #000;user-select:none;-webkit-user-select:none}.bx-dialog *:focus{outline:none !important}.bx-dialog h2{display:flex;margin-bottom:12px}.bx-dialog h2 b{flex:1;color:#fff;display:block;font-family:var(--bx-title-font);font-size:26px;font-weight:400;line-height:var(--bx-button-height)}.bx-dialog.bx-binding-dialog h2 b{font-family:var(--bx-promptfont-font) !important}.bx-dialog > div{overflow:auto;padding:2px 0}.bx-dialog > button{padding:8px 32px;margin:10px auto 0;border:none;border-radius:4px;display:block;background-color:#2d3036;text-align:center;color:#fff;text-transform:uppercase;font-family:var(--bx-title-font);font-weight:400;line-height:18px;font-size:14px}@media (hover:hover){.bx-dialog > button:hover{background-color:#515863}}.bx-dialog > button:focus{background-color:#515863}@media screen and (max-width:450px){.bx-dialog{min-width:100%}}.bx-navigation-dialog{position:absolute;z-index:var(--bx-navigation-dialog-z-index)}.bx-navigation-dialog-overlay{position:fixed;background:rgba(11,11,11,0.89);top:0;left:0;right:0;bottom:0;z-index:var(--bx-navigation-dialog-overlay-z-index)}.bx-navigation-dialog-overlay[data-is-playing="true"]{background:transparent}.bx-settings-dialog{display:flex;position:fixed;top:0;right:0;bottom:0;opacity:.98;user-select:none;-webkit-user-select:none}.bx-settings-dialog .bx-focusable::after{border-radius:4px}.bx-settings-dialog .bx-focusable:focus::after{top:0;left:0;right:0;bottom:0}.bx-settings-dialog .bx-settings-reload-note{font-size:.8rem;display:block;padding:8px;font-style:italic;font-weight:normal;height:var(--bx-button-height)}.bx-settings-tabs-container{position:fixed;width:48px;max-height:100vh;display:flex;flex-direction:column}.bx-settings-tabs-container > div:last-of-type{display:flex;flex-direction:column;align-items:end}.bx-settings-tabs-container > div:last-of-type button{flex-shrink:0;border-top-right-radius:0;border-bottom-right-radius:0;margin-top:8px;height:unset;padding:8px 10px}.bx-settings-tabs-container > div:last-of-type button svg{width:16px;height:16px}.bx-settings-tabs{display:flex;flex-direction:column;border-radius:0 0 0 8px;box-shadow:0 0 6px #000;overflow:overlay;flex:1}.bx-settings-tabs svg{width:24px;height:24px;padding:10px;flex-shrink:0;box-sizing:content-box;background:#131313;cursor:pointer;border-left:4px solid #1e1e1e}.bx-settings-tabs svg.bx-active{background:#222;border-color:#008746}.bx-settings-tabs svg:not(.bx-active):hover{background:#2f2f2f;border-color:#484848}.bx-settings-tabs svg:focus{border-color:#fff;outline:none}.bx-settings-tabs svg[data-group=global][data-need-refresh=true]{background:var(--bx-danger-button-color) !important}.bx-settings-tabs svg[data-group=global][data-need-refresh=true]:hover{background:var(--bx-danger-button-hover-color) !important}.bx-settings-tab-contents{flex-direction:column;padding:10px;margin-left:48px;width:450px;max-width:calc(100vw - tabsWidth);background:#1a1b1e;color:#fff;font-weight:400;font-size:16px;font-family:var(--bx-title-font);text-align:center;box-shadow:0 0 6px #000;overflow:overlay;z-index:1}.bx-settings-tab-contents > div[data-tab-group=mkb]{display:flex;flex-direction:column;height:100%;overflow:hidden}.bx-settings-tab-contents > div[data-tab-group=shortcuts] > div[data-has-gamepad=true] > div:first-of-type{display:none}.bx-settings-tab-contents > div[data-tab-group=shortcuts] > div[data-has-gamepad=true] > div:last-of-type{display:block}.bx-settings-tab-contents > div[data-tab-group=shortcuts] > div[data-has-gamepad=false] > div:first-of-type{display:block}.bx-settings-tab-contents > div[data-tab-group=shortcuts] > div[data-has-gamepad=false] > div:last-of-type{display:none}.bx-settings-tab-contents > div[data-tab-group=shortcuts] .bx-shortcut-profile{width:100%;height:36px;display:block}.bx-settings-tab-contents > div[data-tab-group=shortcuts] .bx-shortcut-note{margin-top:10px;font-size:14px}.bx-settings-tab-contents > div[data-tab-group=shortcuts] .bx-shortcut-row{display:flex;margin-bottom:10px}.bx-settings-tab-contents > div[data-tab-group=shortcuts] .bx-shortcut-row label.bx-prompt{flex:1;font-size:26px;margin-bottom:0}.bx-settings-tab-contents > div[data-tab-group=shortcuts] .bx-shortcut-row .bx-shortcut-actions{flex:2;position:relative}.bx-settings-tab-contents > div[data-tab-group=shortcuts] .bx-shortcut-row .bx-shortcut-actions select{position:absolute;width:100%;height:100%;display:block}.bx-settings-tab-contents > div[data-tab-group=shortcuts] .bx-shortcut-row .bx-shortcut-actions select:last-of-type{opacity:0;z-index:calc(var(--bx-settings-z-index) + 1)}.bx-settings-tab-contents:focus,.bx-settings-tab-contents *:focus{outline:none !important}.bx-settings-tab-contents .bx-top-buttons{display:flex;flex-direction:column;gap:8px;margin-bottom:8px}.bx-settings-tab-contents .bx-top-buttons .bx-button{display:block}.bx-settings-tab-contents h2{margin:16px 0 8px 0;display:flex;align-items:center}.bx-settings-tab-contents h2:first-of-type{margin-top:0}.bx-settings-tab-contents h2 span{display:inline-block;font-size:20px;font-weight:bold;text-align:left;flex:1;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}@media (max-width:500px){.bx-settings-tab-contents{width:calc(100vw - 48px)}}.bx-settings-row{display:flex;gap:10px;border-bottom:1px solid #2c2c2e;padding:16px 8px;margin:0;border-left:2px solid transparent}.bx-settings-row:hover,.bx-settings-row:focus-within{background-color:#242424}.bx-settings-row:not(:has(> input[type=checkbox])){flex-wrap:wrap}.bx-settings-row input[type=checkbox]:focus,.bx-settings-row select:focus{filter:drop-shadow(1px 0 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 1px 0 #fff) drop-shadow(0 -1px 0 #fff)}.bx-settings-row:has(input:focus),.bx-settings-row:has(select:focus),.bx-settings-row:has(button:focus){border-left-color:#fff}.bx-settings-row > span.bx-settings-label{font-size:14px;display:block;text-align:left;align-self:center;margin-bottom:0 !important}.bx-settings-row > span.bx-settings-label + *{margin:0 0 0 auto}.bx-settings-row input{accent-color:var(--bx-primary-button-color)}.bx-settings-row input:focus{accent-color:var(--bx-danger-button-color)}.bx-settings-row select:disabled{-webkit-appearance:none;background:transparent;text-align-last:right;border:none;color:#fff}.bx-settings-row select option:disabled{display:none}.bx-settings-dialog-note{display:block;color:#afafb0;font-size:12px;font-weight:lighter;font-style:italic}.bx-settings-dialog-note:not(:has(a)){margin-top:4px}.bx-settings-dialog-note a{display:inline-block;padding:4px}.bx-settings-custom-user-agent{display:block;width:100%;padding:6px}.bx-donation-link{display:block;text-align:center;text-decoration:none;height:20px;line-height:20px;font-size:14px;margin-top:10px;color:#5dc21e}.bx-donation-link:hover{color:#6dd72b}.bx-donation-link:focus{text-decoration:underline}.bx-debug-info button{margin-top:10px}.bx-debug-info pre{margin-top:10px;cursor:copy;color:#fff;padding:8px;border:1px solid #2d2d2d;background:#212121;white-space:break-spaces;text-align:left}.bx-debug-info pre:hover{background:#272727}.bx-settings-app-version{margin-top:10px;text-align:center;color:#747474;font-size:12px}.bx-note-unsupported{display:block;font-size:12px;font-style:italic;font-weight:normal;color:#828282}.bx-toast{user-select:none;-webkit-user-select:none;position:fixed;left:50%;top:24px;transform:translate(-50%,0);background:#000;border-radius:16px;color:#fff;z-index:var(--bx-toast-z-index);font-family:var(--bx-normal-font);border:2px solid #fff;display:flex;align-items:center;opacity:0;overflow:clip;transition:opacity .2s ease-in}.bx-toast.bx-show{opacity:.85}.bx-toast.bx-hide{opacity:0;pointer-events:none}.bx-toast-msg{font-size:14px;display:inline-block;padding:12px 16px;white-space:pre}.bx-toast-status{font-weight:bold;font-size:14px;text-transform:uppercase;display:inline-block;background:#515863;padding:12px 16px;color:#fff;white-space:pre}.bx-wait-time-box{position:fixed;top:0;right:0;background-color:rgba(0,0,0,0.8);color:#fff;z-index:var(--bx-wait-time-box-z-index);padding:12px;border-radius:0 0 0 8px}.bx-wait-time-box label{display:block;text-transform:uppercase;text-align:right;font-size:12px;font-weight:bold;margin:0}.bx-wait-time-box span{display:block;font-family:var(--bx-monospaced-font);text-align:right;font-size:16px;margin-bottom:10px}.bx-wait-time-box span:last-of-type{margin-bottom:0}.bx-remote-play-popup{width:100%;max-width:1920px;margin:auto;position:relative;height:.1px;overflow:visible;z-index:var(--bx-remote-play-popup-z-index)}.bx-remote-play-container{position:absolute;right:10px;top:0;background:#1a1b1e;border-radius:10px;width:420px;max-width:calc(100vw - 20px);margin:0 0 0 auto;padding:20px;box-shadow:rgba(0,0,0,0.502) 0 0 12px 0}@media (min-width:480px) and (min-height:calc(480px + 1px)){.bx-remote-play-container{right:calc(env(safe-area-inset-right, 0px) + 32px)}}@media (min-width:768px) and (min-height:calc(480px + 1px)){.bx-remote-play-container{right:calc(env(safe-area-inset-right, 0px) + 48px)}}@media (min-width:1920px) and (min-height:calc(480px + 1px)){.bx-remote-play-container{right:calc(env(safe-area-inset-right, 0px) + 80px)}}.bx-remote-play-container > .bx-button{display:table;margin:0 0 0 auto}.bx-remote-play-settings{margin-bottom:12px;padding-bottom:12px;border-bottom:1px solid #2d2d2d}.bx-remote-play-settings > div{display:flex}.bx-remote-play-settings label{flex:1}.bx-remote-play-settings label p{margin:4px 0 0;padding:0;color:#888;font-size:12px}.bx-remote-play-settings span{font-weight:bold;font-size:18px;display:block;margin-bottom:8px;text-align:center}.bx-remote-play-resolution{display:block}.bx-remote-play-resolution input[type="radio"]{accent-color:var(--bx-primary-button-color);margin-right:6px}.bx-remote-play-resolution input[type="radio"]:focus{accent-color:var(--bx-primary-button-hover-color)}.bx-remote-play-device-wrapper{display:flex;margin-bottom:12px}.bx-remote-play-device-wrapper:last-child{margin-bottom:2px}.bx-remote-play-device-info{flex:1;padding:4px 0}.bx-remote-play-device-name{font-size:20px;font-weight:bold;display:inline-block;vertical-align:middle}.bx-remote-play-console-type{font-size:12px;background:#004c87;color:#fff;display:inline-block;border-radius:14px;padding:2px 10px;margin-left:8px;vertical-align:middle}.bx-remote-play-power-state{color:#888;font-size:14px}.bx-remote-play-connect-button{min-height:100%;margin:4px 0}.bx-select{display:flex;align-items:center;flex:0 1 auto}.bx-select select{display:none !important}.bx-select > div,.bx-select button.bx-select-value{min-width:110px;text-align:center;margin:0 8px;line-height:24px;vertical-align:middle;background:#fff;color:#000;border-radius:4px;padding:2px 8px;flex:1}.bx-select > div{display:inline-block}.bx-select > div input{display:inline-block;margin-right:8px}.bx-select > div label{margin-bottom:0;font-size:14px;width:100%}.bx-select > div label span{display:block;font-size:10px;font-weight:bold;text-align:left;line-height:initial}.bx-select button.bx-select-value{border:none;display:inline-flex;cursor:pointer;min-height:30px;font-size:.9rem;align-items:center}.bx-select button.bx-select-value span{flex:1;text-align:center;display:inline-block}.bx-select button.bx-select-value input{margin:0 4px;accent-color:var(--bx-primary-button-color)}.bx-select button.bx-select-value:hover input,.bx-select button.bx-select-value:focus input{accent-color:var(--bx-danger-button-color)}.bx-select button.bx-select-value:hover::after,.bx-select button.bx-select-value:focus::after{border-color:#4d4d4d !important}.bx-select button.bx-button{border:none;height:24px;width:24px;padding:0;line-height:24px;color:#fff;border-radius:4px;font-weight:bold;font-size:12px;font-family:var(--bx-monospaced-font);flex-shrink:0}.bx-select button.bx-button span{line-height:unset}div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module]{overflow:visible}.bx-stream-menu-button-on{fill:#000 !important;background-color:#2d2d2d !important;color:#000 !important}.bx-stream-refresh-button{top:calc(env(safe-area-inset-top, 0px) + 10px + 50px) !important}body[data-media-type=default] .bx-stream-refresh-button{left:calc(env(safe-area-inset-left, 0px) + 11px) !important}body[data-media-type=tv] .bx-stream-refresh-button{top:calc(var(--gds-focus-borderSize) + 80px) !important}.bx-stream-home-button{top:calc(env(safe-area-inset-top, 0px) + 10px + 50px * 2) !important}body[data-media-type=default] .bx-stream-home-button{left:calc(env(safe-area-inset-left, 0px) + 12px) !important}body[data-media-type=tv] .bx-stream-home-button{top:calc(var(--gds-focus-borderSize) + 80px * 2) !important}div[data-testid=media-container]{display:flex}div[data-testid=media-container].bx-taking-screenshot:before{animation:bx-anim-taking-screenshot .5s ease;content:' ';position:absolute;width:100%;height:100%;z-index:var(--bx-screenshot-animation-z-index)}#game-stream video{margin:auto;align-self:center;background:#000}#game-stream canvas{position:absolute;align-self:center;margin:auto;left:0;right:0}#gamepass-dialog-root div[class^=Guide-module__guide] .bx-button{overflow:visible;margin-bottom:12px}@-moz-keyframes bx-anim-taking-screenshot{0%{border:0 solid rgba(255,255,255,0.502)}50%{border:8px solid rgba(255,255,255,0.502)}100%{border:0 solid rgba(255,255,255,0.502)}}@-webkit-keyframes bx-anim-taking-screenshot{0%{border:0 solid rgba(255,255,255,0.502)}50%{border:8px solid rgba(255,255,255,0.502)}100%{border:0 solid rgba(255,255,255,0.502)}}@-o-keyframes bx-anim-taking-screenshot{0%{border:0 solid rgba(255,255,255,0.502)}50%{border:8px solid rgba(255,255,255,0.502)}100%{border:0 solid rgba(255,255,255,0.502)}}@keyframes bx-anim-taking-screenshot{0%{border:0 solid rgba(255,255,255,0.502)}50%{border:8px solid rgba(255,255,255,0.502)}100%{border:0 solid rgba(255,255,255,0.502)}}.bx-number-stepper{text-align:center}.bx-number-stepper span{display:inline-block;min-width:40px;font-family:var(--bx-monospaced-font);font-size:12px;margin:0 4px}.bx-number-stepper button{border:none;width:24px;height:24px;margin:0;line-height:24px;background-color:var(--bx-default-button-color);color:#fff;border-radius:4px;font-weight:bold;font-size:14px;font-family:var(--bx-monospaced-font)}@media (hover:hover){.bx-number-stepper button:hover{background-color:var(--bx-default-button-hover-color)}}.bx-number-stepper button:active{background-color:var(--bx-default-button-hover-color)}.bx-number-stepper button:disabled + span{font-family:var(--bx-title-font)}.bx-number-stepper input[type="range"]{display:block;margin:12px auto 2px;width:180px;color:#959595 !important}.bx-number-stepper input[type=range]:disabled,.bx-number-stepper button:disabled{display:none}.bx-number-stepper[data-disabled=true] input[type=range],.bx-number-stepper[data-disabled=true] button{display:none}#bx-game-bar{z-index:var(--bx-game-bar-z-index);position:fixed;bottom:0;width:40px;height:90px;overflow:visible;cursor:pointer}#bx-game-bar > svg{display:none;pointer-events:none;position:absolute;height:28px;margin-top:16px}@media (hover:hover){#bx-game-bar:hover > svg{display:block}}#bx-game-bar .bx-game-bar-container{opacity:0;position:absolute;display:flex;overflow:hidden;background:rgba(26,27,30,0.91);box-shadow:0 0 6px #1c1c1c;transition:opacity .1s ease-in}#bx-game-bar .bx-game-bar-container.bx-show{opacity:.9}#bx-game-bar .bx-game-bar-container.bx-show + svg{display:none !important}#bx-game-bar .bx-game-bar-container.bx-hide{opacity:0;pointer-events:none}#bx-game-bar .bx-game-bar-container button{width:60px;height:60px;border-radius:0}#bx-game-bar .bx-game-bar-container button svg{width:28px;height:28px;transition:transform .08s ease 0s}#bx-game-bar .bx-game-bar-container button:hover{border-radius:0}#bx-game-bar .bx-game-bar-container button:active svg{transform:scale(.75)}#bx-game-bar .bx-game-bar-container button.bx-activated{background-color:#fff}#bx-game-bar .bx-game-bar-container button.bx-activated svg{filter:invert(1)}#bx-game-bar .bx-game-bar-container div[data-enabled] button{display:none}#bx-game-bar .bx-game-bar-container div[data-enabled='true'] button:first-of-type{display:block}#bx-game-bar .bx-game-bar-container div[data-enabled='false'] button:last-of-type{display:block}#bx-game-bar[data-position="bottom-left"]{left:0;direction:ltr}#bx-game-bar[data-position="bottom-left"] .bx-game-bar-container{border-radius:0 10px 10px 0}#bx-game-bar[data-position="bottom-right"]{right:0;direction:rtl}#bx-game-bar[data-position="bottom-right"] .bx-game-bar-container{direction:ltr;border-radius:10px 0 0 10px}.bx-badges{margin-left:0;user-select:none;-webkit-user-select:none}.bx-badge{border:none;display:inline-block;line-height:24px;color:#fff;font-family:var(--bx-title-font-semibold);font-size:14px;font-weight:400;margin:0 8px 8px 0;box-shadow:0 0 6px #000;border-radius:4px}.bx-badge-name{background-color:#2d3036;border-radius:4px 0 0 4px}.bx-badge-name svg{width:16px;height:16px}.bx-badge-value{background-color:#808080;border-radius:0 4px 4px 0}.bx-badge-name,.bx-badge-value{display:inline-block;padding:0 8px;line-height:30px;vertical-align:bottom}.bx-badge-battery[data-charging=true] span:first-of-type::after{content:' ⚡️'}div[class^=StreamMenu-module__container] .bx-badges{position:absolute;max-width:500px}#gamepass-dialog-root .bx-badges{position:fixed;top:60px;left:460px;max-width:500px}@media (min-width:568px) and (max-height:480px){#gamepass-dialog-root .bx-badges{position:unset;top:unset;left:unset;margin:8px 0}}.bx-stats-bar{display:block;user-select:none;-webkit-user-select:none;position:fixed;top:0;background-color:#000;color:#fff;font-family:var(--bx-monospaced-font);font-size:.9rem;padding-left:8px;z-index:var(--bx-stats-bar-z-index);text-wrap:nowrap}.bx-stats-bar[data-stats*="[fps]"] > .bx-stat-fps,.bx-stats-bar[data-stats*="[ping]"] > .bx-stat-ping,.bx-stats-bar[data-stats*="[btr]"] > .bx-stat-btr,.bx-stats-bar[data-stats*="[dt]"] > .bx-stat-dt,.bx-stats-bar[data-stats*="[pl]"] > .bx-stat-pl,.bx-stats-bar[data-stats*="[fl]"] > .bx-stat-fl{display:inline-block}.bx-stats-bar[data-stats$="[fps]"] > .bx-stat-fps,.bx-stats-bar[data-stats$="[ping]"] > .bx-stat-ping,.bx-stats-bar[data-stats$="[btr]"] > .bx-stat-btr,.bx-stats-bar[data-stats$="[dt]"] > .bx-stat-dt,.bx-stats-bar[data-stats$="[pl]"] > .bx-stat-pl,.bx-stats-bar[data-stats$="[fl]"] > .bx-stat-fl{margin-right:0;border-right:none}.bx-stats-bar::before{display:none;content:'👀';vertical-align:middle;margin-right:8px}.bx-stats-bar[data-display=glancing]::before{display:inline-block}.bx-stats-bar[data-position=top-left]{left:0;border-radius:0 0 4px 0}.bx-stats-bar[data-position=top-right]{right:0;border-radius:0 0 0 4px}.bx-stats-bar[data-position=top-center]{transform:translate(-50%,0);left:50%;border-radius:0 0 4px 4px}.bx-stats-bar[data-transparent=true]{background:none;filter:drop-shadow(1px 0 0 rgba(0,0,0,0.941)) drop-shadow(-1px 0 0 rgba(0,0,0,0.941)) drop-shadow(0 1px 0 rgba(0,0,0,0.941)) drop-shadow(0 -1px 0 rgba(0,0,0,0.941))}.bx-stats-bar > div{display:none;margin-right:8px;border-right:1px solid #fff;padding-right:8px}.bx-stats-bar label{margin:0 8px 0 0;font-family:var(--bx-title-font);font-size:inherit;font-weight:bold;vertical-align:middle;cursor:help}.bx-stats-bar span{min-width:60px;display:inline-block;text-align:right;vertical-align:middle}.bx-stats-bar span[data-grade=good]{color:#6bffff}.bx-stats-bar span[data-grade=ok]{color:#fff16b}.bx-stats-bar span[data-grade=bad]{color:#ff5f5f}.bx-stats-bar span:first-of-type{min-width:22px}.bx-mkb-settings{display:flex;flex-direction:column;flex:1;padding-bottom:10px;overflow:hidden}.bx-mkb-settings select:disabled{-webkit-appearance:none;background:transparent;text-align-last:right;text-align:right;border:none;color:#fff}.bx-mkb-pointer-lock-msg{user-select:none;-webkit-user-select:none;position:fixed;left:50%;top:50%;transform:translateX(-50%) translateY(-50%);margin:auto;background:#151515;z-index:var(--bx-mkb-pointer-lock-msg-z-index);color:#fff;text-align:center;font-weight:400;font-family:"Segoe UI",Arial,Helvetica,sans-serif;font-size:1.3rem;padding:12px;border-radius:8px;align-items:center;box-shadow:0 0 6px #000;min-width:220px;opacity:.9}.bx-mkb-pointer-lock-msg:hover{opacity:1}.bx-mkb-pointer-lock-msg > div:first-of-type{display:flex;flex-direction:column;text-align:left}.bx-mkb-pointer-lock-msg p{margin:0}.bx-mkb-pointer-lock-msg p:first-child{font-size:22px;margin-bottom:4px;font-weight:bold}.bx-mkb-pointer-lock-msg p:last-child{font-size:12px;font-style:italic}.bx-mkb-pointer-lock-msg > div:last-of-type{margin-top:10px}.bx-mkb-pointer-lock-msg > div:last-of-type[data-type='native'] button:first-of-type{margin-bottom:8px}.bx-mkb-pointer-lock-msg > div:last-of-type[data-type='virtual'] div{display:flex;flex-flow:row;margin-top:8px}.bx-mkb-pointer-lock-msg > div:last-of-type[data-type='virtual'] div button{flex:1}.bx-mkb-pointer-lock-msg > div:last-of-type[data-type='virtual'] div button:first-of-type{margin-right:5px}.bx-mkb-pointer-lock-msg > div:last-of-type[data-type='virtual'] div button:last-of-type{margin-left:5px}.bx-mkb-preset-tools{display:flex;margin-bottom:12px}.bx-mkb-preset-tools select{flex:1}.bx-mkb-preset-tools button{margin-left:6px}.bx-mkb-settings-rows{flex:1;overflow:scroll}.bx-mkb-key-row{display:flex;margin-bottom:10px;align-items:center}.bx-mkb-key-row label{margin-bottom:0;font-family:var(--bx-promptfont-font);font-size:26px;text-align:center;width:26px;height:32px;line-height:32px}.bx-mkb-key-row button{flex:1;height:32px;line-height:32px;margin:0 0 0 10px;background:transparent;border:none;color:#fff;border-radius:0;border-left:1px solid #373737}.bx-mkb-key-row button:hover{background:transparent;cursor:default}.bx-mkb-settings.bx-editing .bx-mkb-key-row button{background:#393939;border-radius:4px;border:none}.bx-mkb-settings.bx-editing .bx-mkb-key-row button:hover{background:#333;cursor:pointer}.bx-mkb-action-buttons > div{text-align:right;display:none}.bx-mkb-action-buttons button{margin-left:8px}.bx-mkb-settings:not(.bx-editing) .bx-mkb-action-buttons > div:first-child{display:block}.bx-mkb-settings.bx-editing .bx-mkb-action-buttons > div:last-child{display:block}.bx-mkb-note{display:block;margin:16px 0 10px;font-size:12px}.bx-mkb-note:first-of-type{margin-top:0}`; - const PREF_HIDE_SECTIONS = getPref(PrefKey.UI_HIDE_SECTIONS), selectorToHide = []; - if (PREF_HIDE_SECTIONS.includes(UiSection.NEWS)) + const PREF_HIDE_SECTIONS = getPref("ui_hide_sections"), selectorToHide = []; + if (PREF_HIDE_SECTIONS.includes("news")) selectorToHide.push("#BodyContent > div[class*=CarouselRow-module]"); - if (PREF_HIDE_SECTIONS.includes(UiSection.ALL_GAMES)) + if (PREF_HIDE_SECTIONS.includes("all-games")) selectorToHide.push("#BodyContent div[class*=AllGamesRow-module__gridContainer]"), selectorToHide.push("#BodyContent div[class*=AllGamesRow-module__rowHeader]"); - if (PREF_HIDE_SECTIONS.includes(UiSection.MOST_POPULAR)) + if (PREF_HIDE_SECTIONS.includes("most-popular")) selectorToHide.push('#BodyContent div[class*=HomePage-module__bottomSpacing]:has(a[href="/play/gallery/popular"])'); - if (PREF_HIDE_SECTIONS.includes(UiSection.TOUCH)) + if (PREF_HIDE_SECTIONS.includes("touch")) selectorToHide.push('#BodyContent div[class*=HomePage-module__bottomSpacing]:has(a[href="/play/gallery/touch"])'); - if (getPref(PrefKey.BLOCK_SOCIAL_FEATURES)) + if (getPref("block_social_features")) selectorToHide.push("#gamepass-dialog-root div[class^=AchievementsPreview-module__container] + button[class*=HomeLandingPage-module__button]"); if (selectorToHide) css += selectorToHide.join(",") + "{ display: none; }"; - if (getPref(PrefKey.REDUCE_ANIMATIONS)) + if (getPref("reduce_animations")) css += "div[class*=GameCard-module__gameTitleInnerWrapper],div[class*=GameCard-module__card],div[class*=ScrollArrows-module]{transition:none !important}"; - if (getPref(PrefKey.HIDE_DOTS_ICON)) + if (getPref("hide_dots_icon")) css += "div[class*=Grip-module__container]{visibility:hidden}@media (hover:hover){button[class*=GripHandle-module__container]:hover div[class*=Grip-module__container]{visibility:visible}}button[class*=GripHandle-module__container][aria-expanded=true] div[class*=Grip-module__container]{visibility:visible}button[class*=GripHandle-module__container][aria-expanded=false]{background-color:transparent !important}div[class*=StreamHUD-module__buttonsContainer]{padding:0 !important}"; - if (css += "div[class*=StreamMenu-module__menu]{min-width:100vw !important}", getPref(PrefKey.STREAM_SIMPLIFY_MENU)) + if (css += "div[class*=StreamMenu-module__menu]{min-width:100vw !important}", getPref("stream_simplify_menu")) css += "div[class*=Menu-module__scrollable]{--bxStreamMenuItemSize:80px;--streamMenuItemSize:calc(var(--bxStreamMenuItemSize) + 40px) !important}.bx-badges{top:calc(var(--streamMenuItemSize) - 20px)}body[data-media-type=tv] .bx-badges{top:calc(var(--streamMenuItemSize) - 10px) !important}button[class*=MenuItem-module__container]{min-width:auto !important;min-height:auto !important;width:var(--bxStreamMenuItemSize) !important;height:var(--bxStreamMenuItemSize) !important}div[class*=MenuItem-module__label]{display:none !important}svg[class*=MenuItem-module__icon]{width:36px;height:100% !important;padding:0 !important;margin:0 !important}"; else css += "body[data-media-type=tv] .bx-badges{top:calc(var(--streamMenuItemSize) + 30px)}body:not([data-media-type=tv]) .bx-badges{top:calc(var(--streamMenuItemSize) + 20px)}body:not([data-media-type=tv]) button[class*=MenuItem-module__container]{min-width:auto !important;width:100px !important}body:not([data-media-type=tv]) button[class*=MenuItem-module__container]:nth-child(n+2){margin-left:10px !important}body:not([data-media-type=tv]) div[class*=MenuItem-module__label]{margin-left:8px !important;margin-right:8px !important}"; - if (getPref(PrefKey.UI_SCROLLBAR_HIDE)) + if (getPref("ui_scrollbar_hide")) css += "html{scrollbar-width:none}body::-webkit-scrollbar{display:none}"; const $style = CE("style", {}, css); document.documentElement.appendChild($style); @@ -7130,7 +6715,6 @@ function preloadFonts() { document.querySelector("head")?.appendChild($link); } -// src/modules/mkb/mouse-cursor-hider.ts class MouseCursorHider { static #timeout; static #cursorVisible = !0; @@ -7151,7 +6735,6 @@ class MouseCursorHider { } } -// src/utils/history.ts function patchHistoryMethod(type) { const orig = window.history[type]; return function(...args) { @@ -7170,7 +6753,6 @@ function onHistoryChanged(e) { NavigationDialogManager.getInstance().hide(), RemotePlay.detachPopup(), LoadingScreen.reset(), window.setTimeout(HeaderSection.watchHeader, 2000), BxEvent.dispatch(window, BxEvent.STREAM_STOPPED); } -// src/utils/preload-state.ts function overridePreloadState() { let _state; Object.defineProperty(window, "__PRELOADED_STATE__", { @@ -7187,17 +6769,17 @@ function overridePreloadState() { if (STATES.userAgent.capabilities.touch) try { const sigls = state.xcloud.sigls; - if (GamePassCloudGallery.TOUCH in sigls) { + if ("9c86f07a-f3e8-45ad-82a0-a1f759597059" in sigls) { let customList = TouchController.getCustomList(); - const allGames = sigls[GamePassCloudGallery.ALL].data.products; - customList = customList.filter((id2) => allGames.includes(id2)), sigls[GamePassCloudGallery.TOUCH]?.data.products.push(...customList); + const allGames = sigls["29a81209-df6f-41fd-a528-2ae6b91f719c"].data.products; + customList = customList.filter((id2) => allGames.includes(id2)), sigls["9c86f07a-f3e8-45ad-82a0-a1f759597059"]?.data.products.push(...customList); } - if (BX_FLAGS.ForceNativeMkbTitles && GamePassCloudGallery.NATIVE_MKB in sigls) - sigls[GamePassCloudGallery.NATIVE_MKB]?.data.products.push(...BX_FLAGS.ForceNativeMkbTitles); + if (BX_FLAGS.ForceNativeMkbTitles && "8fa264dd-124f-4af3-97e8-596fcdf4b486" in sigls) + sigls["8fa264dd-124f-4af3-97e8-596fcdf4b486"]?.data.products.push(...BX_FLAGS.ForceNativeMkbTitles); } catch (e) { BxLogger.error(LOG_TAG6, e); } - if (getPref(PrefKey.UI_HOME_CONTEXT_MENU_DISABLED)) + if (getPref("ui_home_context_menu_disabled")) try { state.experiments.experimentationInfo.data.treatments.EnableHomeContextMenu = !1; } catch (e) { @@ -7209,7 +6791,6 @@ function overridePreloadState() { } var LOG_TAG6 = "PreloadState"; -// src/utils/sdp.ts function setCodecPreferences(sdp, preferredCodec) { const h264Pattern = /a=fmtp:(\d+).*profile-level-id=([0-9a-f]{6})/g, profilePrefix = preferredCodec === "high" ? "4d" : preferredCodec === "low" ? "420" : "42e", preferredCodecIds = [], matches = sdp.matchAll(h264Pattern) || []; for (let match of matches) { @@ -7266,13 +6847,10 @@ function patchSdpBitrate(sdp, video, audio) { return lines.join("\r\n"); } -// src/modules/player/shaders/clarity_boost.vert var clarity_boost_default = "attribute vec2 position;\n\nvoid main() {\n gl_Position = vec4(position, 0, 1);\n}\n"; -// src/modules/player/shaders/clarity_boost.fs var clarity_boost_default2 = "const int FILTER_UNSHARP_MASKING = 1;\nconst int FILTER_CAS = 2;\n\nprecision highp float;\nuniform sampler2D data;\nuniform vec2 iResolution;\n\nuniform int filterId;\nuniform float sharpenFactor;\nuniform float brightness;\nuniform float contrast;\nuniform float saturation;\n\nvec3 textureAt(sampler2D tex, vec2 coord) {\n return texture2D(tex, coord / iResolution.xy).rgb;\n}\n\nvec3 clarityBoost(sampler2D tex, vec2 coord)\n{\n // Load a collection of samples in a 3x3 neighorhood, where e is the current pixel.\n // a b c\n // d e f\n // g h i\n vec3 a = textureAt(tex, coord + vec2(-1, 1));\n vec3 b = textureAt(tex, coord + vec2(0, 1));\n vec3 c = textureAt(tex, coord + vec2(1, 1));\n\n vec3 d = textureAt(tex, coord + vec2(-1, 0));\n vec3 e = textureAt(tex, coord);\n vec3 f = textureAt(tex, coord + vec2(1, 0));\n\n vec3 g = textureAt(tex, coord + vec2(-1, -1));\n vec3 h = textureAt(tex, coord + vec2(0, -1));\n vec3 i = textureAt(tex, coord + vec2(1, -1));\n\n if (filterId == FILTER_CAS) {\n // Soft min and max.\n // a b c b\n // d e f * 0.5 + d e f * 0.5\n // g h i h\n // These are 2.0x bigger (factored out the extra multiply).\n vec3 minRgb = min(min(min(d, e), min(f, b)), h);\n vec3 minRgb2 = min(min(a, c), min(g, i));\n minRgb += min(minRgb, minRgb2);\n\n vec3 maxRgb = max(max(max(d, e), max(f, b)), h);\n vec3 maxRgb2 = max(max(a, c), max(g, i));\n maxRgb += max(maxRgb, maxRgb2);\n\n // Smooth minimum distance to signal limit divided by smooth max.\n vec3 reciprocalMaxRgb = 1.0 / maxRgb;\n vec3 amplifyRgb = clamp(min(minRgb, 2.0 - maxRgb) * reciprocalMaxRgb, 0.0, 1.0);\n\n // Shaping amount of sharpening.\n amplifyRgb = inversesqrt(amplifyRgb);\n\n float contrast = 0.8;\n float peak = -3.0 * contrast + 8.0;\n vec3 weightRgb = -(1.0 / (amplifyRgb * peak));\n\n vec3 reciprocalWeightRgb = 1.0 / (4.0 * weightRgb + 1.0);\n\n // 0 w 0\n // Filter shape: w 1 w\n // 0 w 0\n vec3 window = (b + d) + (f + h);\n vec3 outColor = clamp((window * weightRgb + e) * reciprocalWeightRgb, 0.0, 1.0);\n\n outColor = mix(e, outColor, sharpenFactor / 2.0);\n\n return outColor;\n } else if (filterId == FILTER_UNSHARP_MASKING) {\n vec3 gaussianBlur = (a * 1.0 + b * 2.0 + c * 1.0 +\n d * 2.0 + e * 4.0 + f * 2.0 +\n g * 1.0 + h * 2.0 + i * 1.0) / 16.0;\n\n // Return edge detection\n return e + (e - gaussianBlur) * sharpenFactor / 3.0;\n }\n\n return e;\n}\n\nvec3 adjustBrightness(vec3 color) {\n return (1.0 + brightness) * color;\n}\n\nvec3 adjustContrast(vec3 color) {\n return 0.5 + (1.0 + contrast) * (color - 0.5);\n}\n\nvec3 adjustSaturation(vec3 color) {\n const vec3 luminosityFactor = vec3(0.2126, 0.7152, 0.0722);\n vec3 grayscale = vec3(dot(color, luminosityFactor));\n\n return mix(grayscale, color, 1.0 + saturation);\n}\n\nvoid main() {\n vec3 color;\n\n if (sharpenFactor > 0.0) {\n color = clarityBoost(data, gl_FragCoord.xy);\n } else {\n color = textureAt(data, gl_FragCoord.xy);\n }\n\n if (saturation != 0.0) {\n color = adjustSaturation(color);\n }\n\n if (contrast != 0.0) {\n color = adjustContrast(color);\n }\n\n if (brightness != 0.0) {\n color = adjustBrightness(color);\n }\n\n gl_FragColor = vec4(color, 1.0);\n}\n"; -// src/modules/player/webgl2-player.ts var LOG_TAG7 = "WebGL2Player"; class WebGL2Player { @@ -7338,12 +6916,12 @@ class WebGL2Player { }, this.#animFrameId = requestAnimationFrame(animate); } #setupShaders() { - BxLogger.info(LOG_TAG7, "Setting up", getPref(PrefKey.VIDEO_POWER_PREFERENCE)); + BxLogger.info(LOG_TAG7, "Setting up", getPref("video_power_preference")); const gl = this.#$canvas.getContext("webgl2", { isBx: !0, antialias: !0, alpha: !1, - powerPreference: getPref(PrefKey.VIDEO_POWER_PREFERENCE) + powerPreference: getPref("video_power_preference") }); this.#gl = gl, gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferWidth); const vShader = gl.createShader(gl.VERTEX_SHADER); @@ -7406,10 +6984,9 @@ class WebGL2Player { } } -// src/modules/stream-player.ts class StreamPlayer { #$video; - #playerType = StreamPlayerType.VIDEO; + #playerType = "default"; #options = {}; #webGL2Player = null; #$videoCss = null; @@ -7440,7 +7017,7 @@ class StreamPlayer { } #getVideoPlayerFilterStyle() { const filters = [], sharpness = this.#options.sharpness || 0; - if (this.#options.processing === StreamVideoProcessing.USM && sharpness != 0) { + if (this.#options.processing === "usm" && sharpness != 0) { const matrix = `0 -1 0 -1 ${(7 - (sharpness / 2 - 1) * 0.5).toFixed(1)} -1 0 -1 0`; this.#$usmMatrix?.setAttributeNS(null, "kernelMatrix", matrix), filters.push("url(#bx-filter-usm)"); } @@ -7456,9 +7033,9 @@ class StreamPlayer { return filters.join(" "); } #resizePlayer() { - const PREF_RATIO = getPref(PrefKey.VIDEO_RATIO), $video = this.#$video, isNativeTouchGame = STATES.currentStream.titleInfo?.details.hasNativeTouchSupport; + const PREF_RATIO = getPref("video_ratio"), $video = this.#$video, isNativeTouchGame = STATES.currentStream.titleInfo?.details.hasNativeTouchSupport; let $webGL2Canvas; - if (this.#playerType == StreamPlayerType.WEBGL2) + if (this.#playerType == "webgl2") $webGL2Canvas = this.#webGL2Player?.getCanvas(); let targetWidth, targetHeight, targetObjectFit; if (PREF_RATIO.includes(":")) { @@ -7474,12 +7051,12 @@ class StreamPlayer { targetWidth = "100%", targetHeight = "100%", targetObjectFit = PREF_RATIO, $video.dataset.width = window.innerWidth.toString(), $video.dataset.height = window.innerHeight.toString(); if ($video.style.width = targetWidth, $video.style.height = targetHeight, $video.style.objectFit = targetObjectFit, $webGL2Canvas) $webGL2Canvas.style.width = targetWidth, $webGL2Canvas.style.height = targetHeight, $webGL2Canvas.style.objectFit = targetObjectFit; - if (isNativeTouchGame && this.#playerType == StreamPlayerType.WEBGL2) + if (isNativeTouchGame && this.#playerType == "webgl2") window.BX_EXPOSED.streamSession.updateDimensions(); } setPlayerType(type, refreshPlayer = !1) { if (this.#playerType !== type) - if (type === StreamPlayerType.WEBGL2) { + if (type === "webgl2") { if (!this.#webGL2Player) this.#webGL2Player = new WebGL2Player(this.#$video); else @@ -7498,7 +7075,7 @@ class StreamPlayer { getPlayerElement(playerType) { if (typeof playerType === "undefined") playerType = this.#playerType; - if (playerType === StreamPlayerType.WEBGL2) + if (playerType === "webgl2") return this.#webGL2Player?.getCanvas(); return this.#$video; } @@ -7506,9 +7083,9 @@ class StreamPlayer { return this.#webGL2Player; } refreshPlayer() { - if (this.#playerType === StreamPlayerType.WEBGL2) { + if (this.#playerType === "webgl2") { const options = this.#options, webGL2Player = this.#webGL2Player; - if (options.processing === StreamVideoProcessing.USM) + if (options.processing === "usm") webGL2Player.setFilter(1); else webGL2Player.setFilter(2); @@ -7517,7 +7094,7 @@ class StreamPlayer { let filters = this.#getVideoPlayerFilterStyle(), videoCss = ""; if (filters) videoCss += `filter: ${filters} !important;`; - if (getPref(PrefKey.SCREENSHOT_APPLY_FILTERS)) + if (getPref("screenshot_apply_filters")) Screenshot.updateCanvasFilters(filters); let css = ""; if (videoCss) @@ -7527,7 +7104,7 @@ class StreamPlayer { this.#resizePlayer(); } reloadPlayer() { - this.#cleanUpWebGL2Player(), this.#playerType = StreamPlayerType.VIDEO, this.setPlayerType(StreamPlayerType.WEBGL2, !1); + this.#cleanUpWebGL2Player(), this.#playerType = "default", this.setPlayerType("webgl2", !1); } #cleanUpWebGL2Player() { this.#webGL2Player?.destroy(), this.#webGL2Player = null; @@ -7537,19 +7114,18 @@ class StreamPlayer { } } -// src/utils/monkey-patches.ts function patchVideoApi() { - const PREF_SKIP_SPLASH_VIDEO = getPref(PrefKey.SKIP_SPLASH_VIDEO), showFunc = function() { + const PREF_SKIP_SPLASH_VIDEO = getPref("skip_splash_video"), showFunc = function() { if (this.style.visibility = "visible", !this.videoWidth) return; const playerOptions = { - processing: getPref(PrefKey.VIDEO_PROCESSING), - sharpness: getPref(PrefKey.VIDEO_SHARPNESS), - saturation: getPref(PrefKey.VIDEO_SATURATION), - contrast: getPref(PrefKey.VIDEO_CONTRAST), - brightness: getPref(PrefKey.VIDEO_BRIGHTNESS) + processing: getPref("video_processing"), + sharpness: getPref("video_sharpness"), + saturation: getPref("video_saturation"), + contrast: getPref("video_contrast"), + brightness: getPref("video_brightness") }; - STATES.currentStream.streamPlayer = new StreamPlayer(this, getPref(PrefKey.VIDEO_PLAYER_TYPE), playerOptions), BxEvent.dispatch(window, BxEvent.STREAM_PLAYING, { + STATES.currentStream.streamPlayer = new StreamPlayer(this, getPref("video_player_type"), playerOptions), BxEvent.dispatch(window, BxEvent.STREAM_PLAYING, { $video: this }); }, nativePlay = HTMLMediaElement.prototype.play; @@ -7567,7 +7143,7 @@ function patchVideoApi() { }; } function patchRtcCodecs() { - if (getPref(PrefKey.STREAM_CODEC_PROFILE) === "default") + if (getPref("stream_codec_profile") === "default") return; if (typeof RTCRtpTransceiver === "undefined" || !("setCodecPreferences" in RTCRtpTransceiver.prototype)) return !1; @@ -7580,7 +7156,7 @@ function patchRtcPeerConnection() { dataChannel }), dataChannel; }; - const maxVideoBitrate = getPref(PrefKey.BITRATE_VIDEO_MAX), codec = getPref(PrefKey.STREAM_CODEC_PROFILE); + const maxVideoBitrate = getPref("bitrate_video_max"), codec = getPref("stream_codec_profile"); if (codec !== "default" || maxVideoBitrate > 0) { const nativeSetLocalDescription = RTCPeerConnection.prototype.setLocalDescription; RTCPeerConnection.prototype.setLocalDescription = function(description) { @@ -7611,7 +7187,7 @@ function patchAudioContext() { const ctx = new OrgAudioContext(options); return BxLogger.info("patchAudioContext", ctx, options), ctx.createGain = function() { const gainNode = nativeCreateGain.apply(this); - return gainNode.gain.value = getPref(PrefKey.AUDIO_VOLUME) / 100, STATES.currentStream.audioGainNode = gainNode, gainNode; + return gainNode.gain.value = getPref("audio_volume") / 100, STATES.currentStream.audioGainNode = gainNode, gainNode; }, STATES.currentStream.audioContext = ctx, ctx; }; } @@ -7689,8 +7265,7 @@ function patchPointerLockApi() { }; } -// src/modules/stream/stream-ui.ts -var cloneStreamHudButton = function($orgButton, label, svgIcon) { +function cloneStreamHudButton($orgButton, label, svgIcon) { const $container = $orgButton.cloneNode(!0); let timeout; const onTransitionStart = (e) => { @@ -7711,10 +7286,11 @@ var cloneStreamHudButton = function($orgButton, label, svgIcon) { $button.setAttribute("title", label); const $orgSvg = $button.querySelector("svg"), $svg = createSvgIcon(svgIcon); return $svg.style.fill = "none", $svg.setAttribute("class", $orgSvg.getAttribute("class") || ""), $svg.ariaHidden = "true", $orgSvg.replaceWith($svg), $container; -}, cloneCloseButton = function($$btnOrg, icon, className, onChange) { +} +function cloneCloseButton($$btnOrg, icon, className, onChange) { const $btn = $$btnOrg.cloneNode(!0), $svg = createSvgIcon(icon); return $svg.setAttribute("class", $btn.firstElementChild.getAttribute("class") || ""), $svg.style.fill = "none", $btn.classList.add(className), $btn.removeChild($btn.firstElementChild), $btn.appendChild($svg), $btn.addEventListener("click", onChange), $btn; -}; +} function injectStreamMenuButtons() { const $screen = document.querySelector("#PageContent section[class*=PureScreens]"); if (!$screen) @@ -7783,7 +7359,6 @@ function injectStreamMenuButtons() { }).observe($screen, { subtree: !0, childList: !0 }); } -// src/modules/game-bar/action-base.ts class BaseGameBarAction { constructor() { } @@ -7791,7 +7366,6 @@ class BaseGameBarAction { } } -// src/modules/game-bar/action-screenshot.ts class ScreenshotAction extends BaseGameBarAction { $content; constructor() { @@ -7811,7 +7385,6 @@ class ScreenshotAction extends BaseGameBarAction { } } -// src/modules/game-bar/action-touch-control.ts class TouchControlAction extends BaseGameBarAction { $content; constructor() { @@ -7843,7 +7416,6 @@ class TouchControlAction extends BaseGameBarAction { } } -// src/modules/game-bar/action-microphone.ts class MicrophoneAction extends BaseGameBarAction { $content; visible = !1; @@ -7866,7 +7438,7 @@ class MicrophoneAction extends BaseGameBarAction { onClick }); this.$content = CE("div", {}, $btnDefault, $btnMuted), this.reset(), window.addEventListener(BxEvent.MICROPHONE_STATE_CHANGED, (e) => { - const enabled = e.microphoneState === MicrophoneState.ENABLED; + const enabled = e.microphoneState === "Enabled"; this.$content.setAttribute("data-enabled", enabled.toString()), this.$content.classList.remove("bx-gone"); }); } @@ -7878,7 +7450,6 @@ class MicrophoneAction extends BaseGameBarAction { } } -// src/modules/game-bar/game-bar.ts class GameBar { static instance; static getInstance() { @@ -7893,10 +7464,10 @@ class GameBar { actions = []; constructor() { let $container; - const position = getPref(PrefKey.GAME_BAR_POSITION), $gameBar = CE("div", { id: "bx-game-bar", class: "bx-gone", "data-position": position }, $container = CE("div", { class: "bx-game-bar-container bx-offscreen" }), createSvgIcon(position === "bottom-left" ? BxIcon.CARET_RIGHT : BxIcon.CARET_LEFT)); + const position = getPref("game_bar_position"), $gameBar = CE("div", { id: "bx-game-bar", class: "bx-gone", "data-position": position }, $container = CE("div", { class: "bx-game-bar-container bx-offscreen" }), createSvgIcon(position === "bottom-left" ? BxIcon.CARET_RIGHT : BxIcon.CARET_LEFT)); if (this.actions = [ new ScreenshotAction, - ...STATES.userAgent.capabilities.touch && getPref(PrefKey.STREAM_TOUCH_CONTROLLER) !== "off" ? [new TouchControlAction] : [], + ...STATES.userAgent.capabilities.touch && getPref("stream_touch_controller") !== "off" ? [new TouchControlAction] : [], new MicrophoneAction ], position === "bottom-right") this.actions.reverse(); @@ -7910,7 +7481,7 @@ class GameBar { const classList = $container.classList; if (classList.contains("bx-hide")) classList.remove("bx-offscreen", "bx-hide"), classList.add("bx-offscreen"); - }), document.documentElement.appendChild($gameBar), this.$gameBar = $gameBar, this.$container = $container, getPref(PrefKey.GAME_BAR_POSITION) !== "off" && window.addEventListener(BxEvent.XCLOUD_POLLING_MODE_CHANGED, ((e) => { + }), document.documentElement.appendChild($gameBar), this.$gameBar = $gameBar, this.$container = $container, getPref("game_bar_position") !== "off" && window.addEventListener(BxEvent.XCLOUD_POLLING_MODE_CHANGED, ((e) => { if (!STATES.isPlaying) { this.disable(); return; @@ -7948,7 +7519,6 @@ class GameBar { } } -// src/modules/ui/guide-menu.ts class GuideMenu { static #BUTTONS = { scriptSettings: createButton({ @@ -8034,7 +7604,6 @@ class GuideMenu { } } -// src/utils/xcloud-api.ts class XcloudApi { static instance; static getInstance() { @@ -8089,7 +7658,6 @@ class XcloudApi { } } -// src/modules/ui/game-tile.ts class GameTile { static #timeout; static #secondsToHms(seconds) { @@ -8146,7 +7714,6 @@ class GameTile { } } -// src/modules/ui/product-details.ts class ProductDetailsPage { static $btnShortcut = createButton({ classes: ["bx-button-shortcut"], @@ -8170,12 +7737,12 @@ class ProductDetailsPage { } } -// src/index.ts -var unload = function() { +function unload() { if (!STATES.isPlaying) return; EmulatedMkbHandler.getInstance().destroy(), NativeMkbHandler.getInstance().destroy(), STATES.currentStream.streamPlayer?.destroy(), STATES.isPlaying = !1, STATES.currentStream = {}, window.BX_EXPOSED.shouldShowSensorControls = !1, window.BX_EXPOSED.stopTakRendering = !1, NavigationDialogManager.getInstance().hide(), StreamStats.getInstance().onStoppedPlaying(), MouseCursorHider.stop(), TouchController.reset(), GameBar.getInstance().disable(); -}, observeRootDialog = function($root) { +} +function observeRootDialog($root) { let currentShown = !1; new MutationObserver((mutationList) => { for (let mutation of mutationList) { @@ -8203,7 +7770,8 @@ var unload = function() { currentShown = shown, BxEvent.dispatch(window, shown ? BxEvent.XCLOUD_DIALOG_SHOWN : BxEvent.XCLOUD_DIALOG_DISMISSED); } }).observe($root, { subtree: !0, childList: !0 }); -}, waitForRootDialog = function() { +} +function waitForRootDialog() { const observer = new MutationObserver((mutationList) => { for (let mutation of mutationList) { if (mutation.type !== "childList") @@ -8216,17 +7784,18 @@ var unload = function() { } }); observer.observe(document.documentElement, { subtree: !0, childList: !0 }); -}, main = function() { - if (waitForRootDialog(), patchRtcPeerConnection(), patchRtcCodecs(), interceptHttpRequests(), patchVideoApi(), patchCanvasContext(), AppInterface && patchPointerLockApi(), getPref(PrefKey.AUDIO_ENABLE_VOLUME_CONTROL) && patchAudioContext(), getPref(PrefKey.BLOCK_TRACKING) && patchMeControl(), STATES.userAgent.capabilities.touch && TouchController.updateCustomList(), overridePreloadState(), VibrationManager.initialSetup(), BX_FLAGS.CheckForUpdate && checkForUpdate(), addCss(), preloadFonts(), Toast.setup(), getPref(PrefKey.GAME_BAR_POSITION) !== "off" && GameBar.getInstance(), Screenshot.setup(), GuideMenu.observe(), StreamBadges.setupEvents(), StreamStats.setupEvents(), EmulatedMkbHandler.setupEvents(), Patcher.init(), disablePwa(), getPref(PrefKey.CONTROLLER_SHOW_CONNECTION_STATUS)) +} +function main() { + if (waitForRootDialog(), patchRtcPeerConnection(), patchRtcCodecs(), interceptHttpRequests(), patchVideoApi(), patchCanvasContext(), AppInterface && patchPointerLockApi(), getPref("audio_enable_volume_control") && patchAudioContext(), getPref("block_tracking") && patchMeControl(), STATES.userAgent.capabilities.touch && TouchController.updateCustomList(), overridePreloadState(), VibrationManager.initialSetup(), BX_FLAGS.CheckForUpdate && checkForUpdate(), addCss(), Toast.setup(), getPref("game_bar_position") !== "off" && GameBar.getInstance(), Screenshot.setup(), GuideMenu.observe(), StreamBadges.setupEvents(), StreamStats.setupEvents(), EmulatedMkbHandler.setupEvents(), Patcher.init(), disablePwa(), getPref("controller_show_connection_status")) window.addEventListener("gamepadconnected", (e) => showGamepadToast(e.gamepad)), window.addEventListener("gamepaddisconnected", (e) => showGamepadToast(e.gamepad)); - if (getPref(PrefKey.REMOTE_PLAY_ENABLED)) + if (getPref("xhome_enabled")) RemotePlay.detect(); - if (getPref(PrefKey.STREAM_TOUCH_CONTROLLER) === "all") + if (getPref("stream_touch_controller") === "all") TouchController.setup(); - if (getPref(PrefKey.MKB_ENABLED) && AppInterface) + if (getPref("mkb_enabled") && AppInterface) STATES.pointerServerPort = AppInterface.startPointerServer() || 9269, BxLogger.info("startPointerServer", "Port", STATES.pointerServerPort.toString()); - getPref(PrefKey.UI_GAME_CARD_SHOW_WAIT_TIME) && GameTile.setup(); -}; + getPref("ui_game_card_show_wait_time") && GameTile.setup(); +} if (window.location.pathname.includes("/auth/msa")) { const nativePushState = window.history.pushState; throw window.history.pushState = function(...args) { @@ -8268,13 +7837,14 @@ document.addEventListener("readystatechange", (e) => { if (document.readyState !== "interactive") return; if (STATES.isSignedIn = window.xbcUser?.isSignedIn, STATES.isSignedIn) - getPref(PrefKey.REMOTE_PLAY_ENABLED) && BX_FLAGS.PreloadRemotePlay && RemotePlay.preload(); + getPref("xhome_enabled") && BX_FLAGS.PreloadRemotePlay && RemotePlay.preload(); else HeaderSection.watchHeader(); - if (getPref(PrefKey.UI_HIDE_SECTIONS).includes(UiSection.FRIENDS)) { + if (getPref("ui_hide_sections").includes("friends")) { const $parent = document.querySelector("div[class*=PlayWithFriendsSkeleton]")?.closest("div[class*=HomePage-module]"); $parent && ($parent.style.display = "none"); } + preloadFonts(); }); window.BX_EXPOSED = BxExposed; window.addEventListener(BxEvent.POPSTATE, onHistoryChanged); @@ -8295,13 +7865,13 @@ window.addEventListener(BxEvent.STREAM_LOADING, (e) => { } else STATES.currentStream.titleId = "remote-play", STATES.currentStream.productId = ""; }); -getPref(PrefKey.UI_LOADING_SCREEN_GAME_ART) && window.addEventListener(BxEvent.TITLE_INFO_READY, LoadingScreen.setup); +getPref("ui_loading_screen_game_art") && window.addEventListener(BxEvent.TITLE_INFO_READY, LoadingScreen.setup); window.addEventListener(BxEvent.STREAM_STARTING, (e) => { - if (LoadingScreen.hide(), !getPref(PrefKey.MKB_ENABLED) && getPref(PrefKey.MKB_HIDE_IDLE_CURSOR)) + if (LoadingScreen.hide(), !getPref("mkb_enabled") && getPref("mkb_hide_idle_cursor")) MouseCursorHider.start(), MouseCursorHider.hide(); }); window.addEventListener(BxEvent.STREAM_PLAYING, (e) => { - if (STATES.isPlaying = !0, injectStreamMenuButtons(), getPref(PrefKey.GAME_BAR_POSITION) !== "off") { + if (STATES.isPlaying = !0, injectStreamMenuButtons(), getPref("game_bar_position") !== "off") { const gameBar = GameBar.getInstance(); gameBar.reset(), gameBar.enable(), gameBar.showBar(); }