mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-07-20 05:04:27 +02:00
Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a34ae75131 | ||
![]() |
139543aaa5 | ||
![]() |
8099115959 | ||
![]() |
21efa5ffdc | ||
![]() |
07ebf3926b |
2
dist/better-xcloud.meta.js
vendored
2
dist/better-xcloud.meta.js
vendored
@@ -1,5 +1,5 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name Better xCloud
|
// @name Better xCloud
|
||||||
// @namespace https://github.com/redphx
|
// @namespace https://github.com/redphx
|
||||||
// @version 5.7.2
|
// @version 5.7.3
|
||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
|
61
dist/better-xcloud.user.js
vendored
61
dist/better-xcloud.user.js
vendored
@@ -1,7 +1,7 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name Better xCloud
|
// @name Better xCloud
|
||||||
// @namespace https://github.com/redphx
|
// @namespace https://github.com/redphx
|
||||||
// @version 5.7.2
|
// @version 5.7.3
|
||||||
// @description Improve Xbox Cloud Gaming (xCloud) experience
|
// @description Improve Xbox Cloud Gaming (xCloud) experience
|
||||||
// @author redphx
|
// @author redphx
|
||||||
// @license MIT
|
// @license MIT
|
||||||
@@ -139,7 +139,7 @@ function deepClone(obj) {
|
|||||||
return {};
|
return {};
|
||||||
return JSON.parse(JSON.stringify(obj));
|
return JSON.parse(JSON.stringify(obj));
|
||||||
}
|
}
|
||||||
var SCRIPT_VERSION = "5.7.2", AppInterface = window.AppInterface;
|
var SCRIPT_VERSION = "5.7.3", AppInterface = window.AppInterface;
|
||||||
UserAgent.init();
|
UserAgent.init();
|
||||||
var userAgent = window.navigator.userAgent.toLowerCase(), isTv = userAgent.includes("smart-tv") || userAgent.includes("smarttv") || /\baft.*\b/.test(userAgent), isVr = window.navigator.userAgent.includes("VR") && window.navigator.userAgent.includes("OculusBrowser"), browserHasTouchSupport = "ontouchstart" in window || navigator.maxTouchPoints > 0, userAgentHasTouchSupport = !isTv && !isVr && browserHasTouchSupport, STATES = {
|
var userAgent = window.navigator.userAgent.toLowerCase(), isTv = userAgent.includes("smart-tv") || userAgent.includes("smarttv") || /\baft.*\b/.test(userAgent), isVr = window.navigator.userAgent.includes("VR") && window.navigator.userAgent.includes("OculusBrowser"), browserHasTouchSupport = "ontouchstart" in window || navigator.maxTouchPoints > 0, userAgentHasTouchSupport = !isTv && !isVr && browserHasTouchSupport, STATES = {
|
||||||
supportedRegion: !0,
|
supportedRegion: !0,
|
||||||
@@ -327,6 +327,7 @@ var SUPPORTED_LANGUAGES = {
|
|||||||
"badge-playtime": "Playtime",
|
"badge-playtime": "Playtime",
|
||||||
"badge-server": "Server",
|
"badge-server": "Server",
|
||||||
"badge-video": "Video",
|
"badge-video": "Video",
|
||||||
|
"battery-saving": "Battery saving",
|
||||||
"better-xcloud": "Better xCloud",
|
"better-xcloud": "Better xCloud",
|
||||||
"bitrate-audio-maximum": "Maximum audio bitrate",
|
"bitrate-audio-maximum": "Maximum audio bitrate",
|
||||||
"bitrate-video-maximum": "Maximum video bitrate",
|
"bitrate-video-maximum": "Maximum video bitrate",
|
||||||
@@ -422,7 +423,6 @@ var SUPPORTED_LANGUAGES = {
|
|||||||
"load-failed-message": "Failed to run Better xCloud",
|
"load-failed-message": "Failed to run Better xCloud",
|
||||||
"loading-screen": "Loading screen",
|
"loading-screen": "Loading screen",
|
||||||
"local-co-op": "Local co-op",
|
"local-co-op": "Local co-op",
|
||||||
"low-power": "Low power",
|
|
||||||
"lowest-quality": "Lowest quality",
|
"lowest-quality": "Lowest quality",
|
||||||
"map-mouse-to": "Map mouse to",
|
"map-mouse-to": "Map mouse to",
|
||||||
"may-not-work-properly": "May not work properly!",
|
"may-not-work-properly": "May not work properly!",
|
||||||
@@ -437,6 +437,27 @@ var SUPPORTED_LANGUAGES = {
|
|||||||
name: "Name",
|
name: "Name",
|
||||||
"native-mkb": "Native Mouse & Keyboard",
|
"native-mkb": "Native Mouse & Keyboard",
|
||||||
new: "New",
|
new: "New",
|
||||||
|
"new-version-available": [
|
||||||
|
(e) => `Version ${e.version} available`,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
(e) => `Ver ${e.version} が利用可能です`,
|
||||||
|
(e) => `${e.version} 버전 사용가능`,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
(e) => `Đã có phiên bản ${e.version}`,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
],
|
||||||
"no-consoles-found": "No consoles found",
|
"no-consoles-found": "No consoles found",
|
||||||
normal: "Normal",
|
normal: "Normal",
|
||||||
off: "Off",
|
off: "Off",
|
||||||
@@ -479,7 +500,7 @@ var SUPPORTED_LANGUAGES = {
|
|||||||
recommended: "Recommended",
|
recommended: "Recommended",
|
||||||
"recommended-settings-for-device": [
|
"recommended-settings-for-device": [
|
||||||
(e) => `Recommended settings for ${e.device}`,
|
(e) => `Recommended settings for ${e.device}`,
|
||||||
,
|
(e) => `Configuració recomanada per a ${e.device}`,
|
||||||
,
|
,
|
||||||
(e) => `Empfohlene Einstellungen für ${e.device}`,
|
(e) => `Empfohlene Einstellungen für ${e.device}`,
|
||||||
,
|
,
|
||||||
@@ -1622,7 +1643,7 @@ class GlobalSettingsStorage extends BaseSettingsStore {
|
|||||||
default: "default",
|
default: "default",
|
||||||
options: {
|
options: {
|
||||||
default: t("default"),
|
default: t("default"),
|
||||||
"low-power": t("low-power"),
|
"low-power": t("battery-saving"),
|
||||||
"high-performance": t("high-performance")
|
"high-performance": t("high-performance")
|
||||||
},
|
},
|
||||||
suggest: {
|
suggest: {
|
||||||
@@ -4197,6 +4218,14 @@ if (this.baseStorageKey in window.BX_EXPOSED.overrideSettings) {
|
|||||||
if (index = PatcherUtils.lastIndexOf(str, "return", index, 100), index < 0)
|
if (index = PatcherUtils.lastIndexOf(str, "return", index, 100), index < 0)
|
||||||
return !1;
|
return !1;
|
||||||
return str = PatcherUtils.insertAt(str, index, "window.BxEvent.dispatch(window, window.BxEvent.XCLOUD_ROUTER_HISTORY_READY, {history: this.history});"), str;
|
return str = PatcherUtils.insertAt(str, index, "window.BxEvent.dispatch(window, window.BxEvent.XCLOUD_ROUTER_HISTORY_READY, {history: this.history});"), str;
|
||||||
|
},
|
||||||
|
guideAchievementsDefaultLocked(str) {
|
||||||
|
let index = str.indexOf("FilterButton-module__container");
|
||||||
|
if (index >= 0 && (index = PatcherUtils.lastIndexOf(str, ".All", index, 150)), index < 0)
|
||||||
|
return !1;
|
||||||
|
if (str = PatcherUtils.replaceWith(str, index, ".All", ".Locked"), index = str.indexOf('"Guide_Achievements_Unlocked_Empty","Guide_Achievements_Locked_Empty"'), index >= 0 && (index = PatcherUtils.indexOf(str, ".All", index, 250)), index < 0)
|
||||||
|
return !1;
|
||||||
|
return str = PatcherUtils.replaceWith(str, index, ".All", ".Locked"), str;
|
||||||
}
|
}
|
||||||
}, PATCH_ORDERS = [
|
}, PATCH_ORDERS = [
|
||||||
...getPref("native_mkb_enabled") === "on" ? [
|
...getPref("native_mkb_enabled") === "on" ? [
|
||||||
@@ -4213,6 +4242,7 @@ if (this.baseStorageKey in window.BX_EXPOSED.overrideSettings) {
|
|||||||
"patchGamepadPolling",
|
"patchGamepadPolling",
|
||||||
"exposeStreamSession",
|
"exposeStreamSession",
|
||||||
"exposeDialogRoutes",
|
"exposeDialogRoutes",
|
||||||
|
"guideAchievementsDefaultLocked",
|
||||||
"enableTvRoutes",
|
"enableTvRoutes",
|
||||||
AppInterface && "detectProductDetailsPage",
|
AppInterface && "detectProductDetailsPage",
|
||||||
"overrideStorageGetSettings",
|
"overrideStorageGetSettings",
|
||||||
@@ -4433,12 +4463,17 @@ class SettingsNavigationDialog extends NavigationDialog {
|
|||||||
items: [
|
items: [
|
||||||
($parent) => {
|
($parent) => {
|
||||||
const PREF_LATEST_VERSION = getPref("version_latest"), topButtons = [];
|
const PREF_LATEST_VERSION = getPref("version_latest"), topButtons = [];
|
||||||
if (!SCRIPT_VERSION.includes("beta") && PREF_LATEST_VERSION && PREF_LATEST_VERSION != SCRIPT_VERSION)
|
if (!SCRIPT_VERSION.includes("beta") && PREF_LATEST_VERSION && PREF_LATEST_VERSION != SCRIPT_VERSION) {
|
||||||
topButtons.push(createButton({
|
const opts = {
|
||||||
label: `🌟 Version ${PREF_LATEST_VERSION} available`,
|
label: "🌟 " + t("new-version-available", { version: PREF_LATEST_VERSION }),
|
||||||
style: 1 | 32 | 64,
|
style: 1 | 32 | 64
|
||||||
url: "https://github.com/redphx/better-xcloud/releases/latest"
|
};
|
||||||
}));
|
if (AppInterface && AppInterface.updateLatestScript)
|
||||||
|
opts.onClick = (e) => AppInterface.updateLatestScript();
|
||||||
|
else
|
||||||
|
opts.url = "https://github.com/redphx/better-xcloud/releases/latest";
|
||||||
|
topButtons.push(createButton(opts));
|
||||||
|
}
|
||||||
if (AppInterface)
|
if (AppInterface)
|
||||||
topButtons.push(createButton({
|
topButtons.push(createButton({
|
||||||
label: t("app-settings"),
|
label: t("app-settings"),
|
||||||
@@ -7873,7 +7908,7 @@ class GameBar {
|
|||||||
}), window.addEventListener(BxEvent.GAME_BAR_ACTION_ACTIVATED, this.hideBar.bind(this)), $container.addEventListener("pointerover", this.clearHideTimeout.bind(this)), $container.addEventListener("pointerout", this.beginHideTimeout.bind(this)), $container.addEventListener("transitionend", (e) => {
|
}), window.addEventListener(BxEvent.GAME_BAR_ACTION_ACTIVATED, this.hideBar.bind(this)), $container.addEventListener("pointerover", this.clearHideTimeout.bind(this)), $container.addEventListener("pointerout", this.beginHideTimeout.bind(this)), $container.addEventListener("transitionend", (e) => {
|
||||||
const classList = $container.classList;
|
const classList = $container.classList;
|
||||||
if (classList.contains("bx-hide"))
|
if (classList.contains("bx-hide"))
|
||||||
classList.remove("bx-offscreen", "bx-hide"), classList.add("bx-offscreen");
|
classList.remove("bx-hide"), classList.add("bx-offscreen");
|
||||||
}), document.documentElement.appendChild($gameBar), this.$gameBar = $gameBar, this.$container = $container, getPref("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) {
|
if (!STATES.isPlaying) {
|
||||||
this.disable();
|
this.disable();
|
||||||
@@ -7902,7 +7937,7 @@ class GameBar {
|
|||||||
this.$container.classList.remove("bx-offscreen", "bx-hide", "bx-gone"), this.$container.classList.add("bx-show"), this.beginHideTimeout();
|
this.$container.classList.remove("bx-offscreen", "bx-hide", "bx-gone"), this.$container.classList.add("bx-show"), this.beginHideTimeout();
|
||||||
}
|
}
|
||||||
hideBar() {
|
hideBar() {
|
||||||
if (clearFocus(), !this.$container)
|
if (this.clearHideTimeout(), clearFocus(), !this.$container)
|
||||||
return;
|
return;
|
||||||
this.$container.classList.remove("bx-show"), this.$container.classList.add("bx-hide");
|
this.$container.classList.remove("bx-show"), this.$container.classList.add("bx-hide");
|
||||||
}
|
}
|
||||||
|
@@ -78,7 +78,7 @@ export class GameBar {
|
|||||||
$container.addEventListener('transitionend', e => {
|
$container.addEventListener('transitionend', e => {
|
||||||
const classList = $container.classList;
|
const classList = $container.classList;
|
||||||
if (classList.contains('bx-hide')) {
|
if (classList.contains('bx-hide')) {
|
||||||
classList.remove('bx-offscreen', 'bx-hide');
|
classList.remove('bx-hide');
|
||||||
classList.add('bx-offscreen');
|
classList.add('bx-offscreen');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -135,6 +135,8 @@ export class GameBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hideBar() {
|
hideBar() {
|
||||||
|
this.clearHideTimeout();
|
||||||
|
|
||||||
// Stop focusing Game Bar
|
// Stop focusing Game Bar
|
||||||
clearFocus();
|
clearFocus();
|
||||||
|
|
||||||
|
@@ -912,6 +912,26 @@ if (this.baseStorageKey in window.BX_EXPOSED.overrideSettings) {
|
|||||||
str = PatcherUtils.insertAt(str, index, 'window.BxEvent.dispatch(window, window.BxEvent.XCLOUD_ROUTER_HISTORY_READY, {history: this.history});');
|
str = PatcherUtils.insertAt(str, index, 'window.BxEvent.dispatch(window, window.BxEvent.XCLOUD_ROUTER_HISTORY_READY, {history: this.history});');
|
||||||
return str;
|
return str;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Set Achievements list's filter default to "Locked"
|
||||||
|
guideAchievementsDefaultLocked(str: string) {
|
||||||
|
let index = str.indexOf('FilterButton-module__container');
|
||||||
|
index >= 0 && (index = PatcherUtils.lastIndexOf(str, '.All', index, 150));
|
||||||
|
if (index < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
str = PatcherUtils.replaceWith(str, index, '.All', '.Locked');
|
||||||
|
|
||||||
|
index = str.indexOf('"Guide_Achievements_Unlocked_Empty","Guide_Achievements_Locked_Empty"');
|
||||||
|
index >= 0 && (index = PatcherUtils.indexOf(str, '.All', index, 250));
|
||||||
|
if (index < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
str = PatcherUtils.replaceWith(str, index, '.All', '.Locked');
|
||||||
|
return str;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let PATCH_ORDERS: PatchArray = [
|
let PATCH_ORDERS: PatchArray = [
|
||||||
@@ -933,6 +953,8 @@ let PATCH_ORDERS: PatchArray = [
|
|||||||
'exposeStreamSession',
|
'exposeStreamSession',
|
||||||
'exposeDialogRoutes',
|
'exposeDialogRoutes',
|
||||||
|
|
||||||
|
'guideAchievementsDefaultLocked',
|
||||||
|
|
||||||
'enableTvRoutes',
|
'enableTvRoutes',
|
||||||
AppInterface && 'detectProductDetailsPage',
|
AppInterface && 'detectProductDetailsPage',
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { onChangeVideoPlayerType, updateVideoPlayer } from "@/modules/stream/stream-settings-utils";
|
import { onChangeVideoPlayerType, updateVideoPlayer } from "@/modules/stream/stream-settings-utils";
|
||||||
import { ButtonStyle, CE, createButton, createSvgIcon, removeChildElements } from "@/utils/html";
|
import { ButtonStyle, CE, createButton, createSvgIcon, removeChildElements, type BxButton } from "@/utils/html";
|
||||||
import { NavigationDialog, NavigationDirection } from "./navigation-dialog";
|
import { NavigationDialog, NavigationDirection } from "./navigation-dialog";
|
||||||
import { ControllerShortcut } from "@/modules/controller-shortcut";
|
import { ControllerShortcut } from "@/modules/controller-shortcut";
|
||||||
import { MkbRemapper } from "@/modules/mkb/mkb-remapper";
|
import { MkbRemapper } from "@/modules/mkb/mkb-remapper";
|
||||||
@@ -97,12 +97,19 @@ export class SettingsNavigationDialog extends NavigationDialog {
|
|||||||
|
|
||||||
// "New version available" button
|
// "New version available" button
|
||||||
if (!SCRIPT_VERSION.includes('beta') && PREF_LATEST_VERSION && PREF_LATEST_VERSION != SCRIPT_VERSION) {
|
if (!SCRIPT_VERSION.includes('beta') && PREF_LATEST_VERSION && PREF_LATEST_VERSION != SCRIPT_VERSION) {
|
||||||
// Show new version indicator
|
// Show new version button
|
||||||
topButtons.push(createButton({
|
const opts = {
|
||||||
label: `🌟 Version ${PREF_LATEST_VERSION} available`,
|
label: '🌟 ' + t('new-version-available', {version: PREF_LATEST_VERSION}),
|
||||||
style: ButtonStyle.PRIMARY | ButtonStyle.FOCUSABLE | ButtonStyle.FULL_WIDTH,
|
style: ButtonStyle.PRIMARY | ButtonStyle.FOCUSABLE | ButtonStyle.FULL_WIDTH,
|
||||||
url: 'https://github.com/redphx/better-xcloud/releases/latest',
|
} as BxButton;
|
||||||
}));
|
|
||||||
|
if (AppInterface && AppInterface.updateLatestScript) {
|
||||||
|
opts.onClick = e => AppInterface.updateLatestScript();
|
||||||
|
} else {
|
||||||
|
opts.url = 'https://github.com/redphx/better-xcloud/releases/latest';
|
||||||
|
}
|
||||||
|
|
||||||
|
topButtons.push(createButton(opts));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buttons for Android app
|
// Buttons for Android app
|
||||||
|
@@ -32,7 +32,7 @@ const ButtonStyleClass = {
|
|||||||
[ButtonStyle.NORMAL_LINK]: 'bx-normal-link',
|
[ButtonStyle.NORMAL_LINK]: 'bx-normal-link',
|
||||||
}
|
}
|
||||||
|
|
||||||
type BxButton = {
|
export type BxButton = {
|
||||||
style?: ButtonStyle;
|
style?: ButtonStyle;
|
||||||
url?: string;
|
url?: string;
|
||||||
classes?: string[];
|
classes?: string[];
|
||||||
|
@@ -584,7 +584,7 @@ export class GlobalSettingsStorage extends BaseSettingsStorage {
|
|||||||
default: 'default',
|
default: 'default',
|
||||||
options: {
|
options: {
|
||||||
'default': t('default'),
|
'default': t('default'),
|
||||||
'low-power': t('low-power'),
|
'low-power': t('battery-saving'),
|
||||||
'high-performance': t('high-performance'),
|
'high-performance': t('high-performance'),
|
||||||
},
|
},
|
||||||
suggest: {
|
suggest: {
|
||||||
|
@@ -47,6 +47,7 @@ const Texts = {
|
|||||||
"badge-playtime": "Playtime",
|
"badge-playtime": "Playtime",
|
||||||
"badge-server": "Server",
|
"badge-server": "Server",
|
||||||
"badge-video": "Video",
|
"badge-video": "Video",
|
||||||
|
"battery-saving": "Battery saving",
|
||||||
"better-xcloud": "Better xCloud",
|
"better-xcloud": "Better xCloud",
|
||||||
"bitrate-audio-maximum": "Maximum audio bitrate",
|
"bitrate-audio-maximum": "Maximum audio bitrate",
|
||||||
"bitrate-video-maximum": "Maximum video bitrate",
|
"bitrate-video-maximum": "Maximum video bitrate",
|
||||||
@@ -142,7 +143,6 @@ const Texts = {
|
|||||||
"load-failed-message": "Failed to run Better xCloud",
|
"load-failed-message": "Failed to run Better xCloud",
|
||||||
"loading-screen": "Loading screen",
|
"loading-screen": "Loading screen",
|
||||||
"local-co-op": "Local co-op",
|
"local-co-op": "Local co-op",
|
||||||
"low-power": "Low power",
|
|
||||||
"lowest-quality": "Lowest quality",
|
"lowest-quality": "Lowest quality",
|
||||||
"map-mouse-to": "Map mouse to",
|
"map-mouse-to": "Map mouse to",
|
||||||
"may-not-work-properly": "May not work properly!",
|
"may-not-work-properly": "May not work properly!",
|
||||||
@@ -157,6 +157,27 @@ const Texts = {
|
|||||||
"name": "Name",
|
"name": "Name",
|
||||||
"native-mkb": "Native Mouse & Keyboard",
|
"native-mkb": "Native Mouse & Keyboard",
|
||||||
"new": "New",
|
"new": "New",
|
||||||
|
"new-version-available": [
|
||||||
|
(e: any) => `Version ${e.version} available`,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
(e: any) => `Ver ${e.version} が利用可能です`,
|
||||||
|
(e: any) => `${e.version} 버전 사용가능`,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
(e: any) => `Đã có phiên bản ${e.version}`,
|
||||||
|
,
|
||||||
|
,
|
||||||
|
],
|
||||||
"no-consoles-found": "No consoles found",
|
"no-consoles-found": "No consoles found",
|
||||||
"normal": "Normal",
|
"normal": "Normal",
|
||||||
"off": "Off",
|
"off": "Off",
|
||||||
@@ -199,7 +220,7 @@ const Texts = {
|
|||||||
"recommended": "Recommended",
|
"recommended": "Recommended",
|
||||||
"recommended-settings-for-device": [
|
"recommended-settings-for-device": [
|
||||||
(e: any) => `Recommended settings for ${e.device}`,
|
(e: any) => `Recommended settings for ${e.device}`,
|
||||||
,
|
(e: any) => `Configuració recomanada per a ${e.device}`,
|
||||||
,
|
,
|
||||||
(e: any) => `Empfohlene Einstellungen für ${e.device}`,
|
(e: any) => `Empfohlene Einstellungen für ${e.device}`,
|
||||||
,
|
,
|
||||||
|
Reference in New Issue
Block a user