Compare commits

..

4 Commits

Author SHA1 Message Date
redphx
5d177bd76c Fix "guideAchievementsDefaultLocked" patch 2024-11-18 22:01:24 +07:00
redphx
f18c5c14ed Bump version to 5.9.5 2024-11-06 19:22:07 +07:00
redphx
d0ceed00f8 Add "Server locations" link 2024-11-06 19:21:38 +07:00
redphx
fce8af4b3b Fix custom buttons disappearing in Guide Menu (#551) 2024-11-06 07:36:32 +07:00
8 changed files with 35 additions and 16 deletions

View File

@@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name Better xCloud (Lite) // @name Better xCloud (Lite)
// @namespace https://github.com/redphx // @namespace https://github.com/redphx
// @version 5.9.4 // @version 5.9.6-beta
// @description Improve Xbox Cloud Gaming (xCloud) experience // @description Improve Xbox Cloud Gaming (xCloud) experience
// @author redphx // @author redphx
// @license MIT // @license MIT
@@ -105,7 +105,7 @@ class UserAgent {
}); });
} }
} }
var SCRIPT_VERSION = "5.9.4", SCRIPT_VARIANT = "lite", AppInterface = window.AppInterface; var SCRIPT_VERSION = "5.9.6-beta", SCRIPT_VARIANT = "lite", 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, supportMkb = AppInterface || !userAgent.match(/(android|iphone|ipad)/), 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, supportMkb = AppInterface || !userAgent.match(/(android|iphone|ipad)/), STATES = {
supportedRegion: !0, supportedRegion: !0,
@@ -504,6 +504,7 @@ var SUPPORTED_LANGUAGES = {
"separate-touch-controller": "Separate Touch controller & Controller #1", "separate-touch-controller": "Separate Touch controller & Controller #1",
"separate-touch-controller-note": "Touch controller is Player 1, Controller #1 is Player 2", "separate-touch-controller-note": "Touch controller is Player 1, Controller #1 is Player 2",
server: "Server", server: "Server",
"server-locations": "Server locations",
settings: "Settings", settings: "Settings",
"settings-reload": "Reload page to reflect changes", "settings-reload": "Reload page to reflect changes",
"settings-reload-note": "Settings in this tab only go into effect on the next page load", "settings-reload-note": "Settings in this tab only go into effect on the next page load",
@@ -1148,6 +1149,7 @@ class GlobalSettingsStorage extends BaseSettingsStore {
}, },
server_region: { server_region: {
label: t("region"), label: t("region"),
note: CE("a", { target: "_blank", href: "https://umap.openstreetmap.fr/en/map/xbox-cloud-gaming-servers_1135022" }, t("server-locations")),
default: "default" default: "default"
}, },
server_bypass_restriction: { server_bypass_restriction: {
@@ -4895,6 +4897,8 @@ class GuideMenu {
} }
observe($addedElm) { observe($addedElm) {
let className = $addedElm.className; let className = $addedElm.className;
if (!className) className = $addedElm.firstElementChild?.className ?? "";
if (!className || className.startsWith("bx-")) return;
if (!className.startsWith("NavigationAnimation") && !className.startsWith("DialogRoutes") && !className.startsWith("Dialog-module__container")) return; if (!className.startsWith("NavigationAnimation") && !className.startsWith("DialogRoutes") && !className.startsWith("Dialog-module__container")) return;
let $selectedTab = $addedElm.querySelector("div[class^=NavigationMenu] button[aria-selected=true"); let $selectedTab = $addedElm.querySelector("div[class^=NavigationMenu] button[aria-selected=true");
if ($selectedTab) { if ($selectedTab) {
@@ -5956,7 +5960,7 @@ class RootDialogObserver {
if (mutation.type !== "childList") continue; if (mutation.type !== "childList") continue;
if (BX_FLAGS.Debug && BxLogger.warning("RootDialog", "added", mutation.addedNodes), mutation.addedNodes.length === 1) { if (BX_FLAGS.Debug && BxLogger.warning("RootDialog", "added", mutation.addedNodes), mutation.addedNodes.length === 1) {
let $addedElm = mutation.addedNodes[0]; let $addedElm = mutation.addedNodes[0];
if ($addedElm instanceof HTMLElement && $addedElm.className) RootDialogObserver.handleAddedElement($root, $addedElm); if ($addedElm instanceof HTMLElement) RootDialogObserver.handleAddedElement($root, $addedElm);
} }
let shown = !!($root.firstElementChild && $root.firstElementChild.childElementCount > 0); let shown = !!($root.firstElementChild && $root.firstElementChild.childElementCount > 0);
if (shown !== beingShown) beingShown = shown, BxEvent.dispatch(window, shown ? BxEvent.XCLOUD_DIALOG_SHOWN : BxEvent.XCLOUD_DIALOG_DISMISSED); if (shown !== beingShown) beingShown = shown, BxEvent.dispatch(window, shown ? BxEvent.XCLOUD_DIALOG_SHOWN : BxEvent.XCLOUD_DIALOG_DISMISSED);

View File

@@ -1,5 +1,5 @@
// ==UserScript== // ==UserScript==
// @name Better xCloud // @name Better xCloud
// @namespace https://github.com/redphx // @namespace https://github.com/redphx
// @version 5.9.4 // @version 5.9.5
// ==/UserScript== // ==/UserScript==

View File

@@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name Better xCloud // @name Better xCloud
// @namespace https://github.com/redphx // @namespace https://github.com/redphx
// @version 5.9.4 // @version 5.9.6-beta
// @description Improve Xbox Cloud Gaming (xCloud) experience // @description Improve Xbox Cloud Gaming (xCloud) experience
// @author redphx // @author redphx
// @license MIT // @license MIT
@@ -107,7 +107,7 @@ class UserAgent {
}); });
} }
} }
var SCRIPT_VERSION = "5.9.4", SCRIPT_VARIANT = "full", AppInterface = window.AppInterface; var SCRIPT_VERSION = "5.9.6-beta", SCRIPT_VARIANT = "full", 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, supportMkb = AppInterface || !userAgent.match(/(android|iphone|ipad)/), 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, supportMkb = AppInterface || !userAgent.match(/(android|iphone|ipad)/), STATES = {
supportedRegion: !0, supportedRegion: !0,
@@ -527,6 +527,7 @@ var SUPPORTED_LANGUAGES = {
"separate-touch-controller": "Separate Touch controller & Controller #1", "separate-touch-controller": "Separate Touch controller & Controller #1",
"separate-touch-controller-note": "Touch controller is Player 1, Controller #1 is Player 2", "separate-touch-controller-note": "Touch controller is Player 1, Controller #1 is Player 2",
server: "Server", server: "Server",
"server-locations": "Server locations",
settings: "Settings", settings: "Settings",
"settings-reload": "Reload page to reflect changes", "settings-reload": "Reload page to reflect changes",
"settings-reload-note": "Settings in this tab only go into effect on the next page load", "settings-reload-note": "Settings in this tab only go into effect on the next page load",
@@ -1171,6 +1172,7 @@ class GlobalSettingsStorage extends BaseSettingsStore {
}, },
server_region: { server_region: {
label: t("region"), label: t("region"),
note: CE("a", { target: "_blank", href: "https://umap.openstreetmap.fr/en/map/xbox-cloud-gaming-servers_1135022" }, t("server-locations")),
default: "default" default: "default"
}, },
server_bypass_restriction: { server_bypass_restriction: {
@@ -4397,9 +4399,9 @@ if (this.baseStorageKey in window.BX_EXPOSED.overrideSettings) {
}, },
guideAchievementsDefaultLocked(str) { guideAchievementsDefaultLocked(str) {
let index = str.indexOf("FilterButton-module__container"); let index = str.indexOf("FilterButton-module__container");
if (index >= 0 && (index = PatcherUtils.lastIndexOf(str, ".All", index, 150)), index < 0) return !1; 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; 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; return str = PatcherUtils.replaceWith(str, index, '"All"', '"Locked"'), str;
}, },
disableTouchContextMenu(str) { disableTouchContextMenu(str) {
let index = str.indexOf('"ContextualCardActions-module__container'); let index = str.indexOf('"ContextualCardActions-module__container');
@@ -6514,6 +6516,8 @@ class GuideMenu {
} }
observe($addedElm) { observe($addedElm) {
let className = $addedElm.className; let className = $addedElm.className;
if (!className) className = $addedElm.firstElementChild?.className ?? "";
if (!className || className.startsWith("bx-")) return;
if (className.includes("AchievementsButton-module__progressBarContainer")) { if (className.includes("AchievementsButton-module__progressBarContainer")) {
TrueAchievements.getInstance().injectAchievementsProgress($addedElm); TrueAchievements.getInstance().injectAchievementsProgress($addedElm);
return; return;
@@ -7924,7 +7928,7 @@ class RootDialogObserver {
if (mutation.type !== "childList") continue; if (mutation.type !== "childList") continue;
if (BX_FLAGS.Debug && BxLogger.warning("RootDialog", "added", mutation.addedNodes), mutation.addedNodes.length === 1) { if (BX_FLAGS.Debug && BxLogger.warning("RootDialog", "added", mutation.addedNodes), mutation.addedNodes.length === 1) {
let $addedElm = mutation.addedNodes[0]; let $addedElm = mutation.addedNodes[0];
if ($addedElm instanceof HTMLElement && $addedElm.className) RootDialogObserver.handleAddedElement($root, $addedElm); if ($addedElm instanceof HTMLElement) RootDialogObserver.handleAddedElement($root, $addedElm);
} }
let shown = !!($root.firstElementChild && $root.firstElementChild.childElementCount > 0); let shown = !!($root.firstElementChild && $root.firstElementChild.childElementCount > 0);
if (shown !== beingShown) beingShown = shown, BxEvent.dispatch(window, shown ? BxEvent.XCLOUD_DIALOG_SHOWN : BxEvent.XCLOUD_DIALOG_DISMISSED); if (shown !== beingShown) beingShown = shown, BxEvent.dispatch(window, shown ? BxEvent.XCLOUD_DIALOG_SHOWN : BxEvent.XCLOUD_DIALOG_DISMISSED);

View File

@@ -942,20 +942,20 @@ if (this.baseStorageKey in window.BX_EXPOSED.overrideSettings) {
// Set Achievements list's filter default to "Locked" // Set Achievements list's filter default to "Locked"
guideAchievementsDefaultLocked(str: string) { guideAchievementsDefaultLocked(str: string) {
let index = str.indexOf('FilterButton-module__container'); let index = str.indexOf('FilterButton-module__container');
index >= 0 && (index = PatcherUtils.lastIndexOf(str, '.All', index, 150)); index >= 0 && (index = PatcherUtils.lastIndexOf(str, '"All"', index, 150));
if (index < 0) { if (index < 0) {
return false; return false;
} }
str = PatcherUtils.replaceWith(str, index, '.All', '.Locked'); str = PatcherUtils.replaceWith(str, index, '"All"', '"Locked"');
index = str.indexOf('"Guide_Achievements_Unlocked_Empty","Guide_Achievements_Locked_Empty"'); index = str.indexOf('"Guide_Achievements_Unlocked_Empty","Guide_Achievements_Locked_Empty"');
index >= 0 && (index = PatcherUtils.indexOf(str, '.All', index, 250)); index >= 0 && (index = PatcherUtils.indexOf(str, '"All"', index, 250));
if (index < 0) { if (index < 0) {
return false; return false;
} }
str = PatcherUtils.replaceWith(str, index, '.All', '.Locked'); str = PatcherUtils.replaceWith(str, index, '"All"', '"Locked"');
return str; return str;
}, },

View File

@@ -178,7 +178,16 @@ export class GuideMenu {
} }
observe($addedElm: HTMLElement) { observe($addedElm: HTMLElement) {
const className = $addedElm.className; let className = $addedElm.className;
// Fix custom buttons disappearing in Guide Menu (#551)
if (!className) {
className = $addedElm.firstElementChild?.className ?? '';
}
if (!className || className.startsWith('bx-')) {
return;
}
// TrueAchievements // TrueAchievements
if (isFullVersion() && className.includes('AchievementsButton-module__progressBarContainer')) { if (isFullVersion() && className.includes('AchievementsButton-module__progressBarContainer')) {

View File

@@ -79,7 +79,7 @@ export class RootDialogObserver {
BX_FLAGS.Debug && BxLogger.warning('RootDialog', 'added', mutation.addedNodes); BX_FLAGS.Debug && BxLogger.warning('RootDialog', 'added', mutation.addedNodes);
if (mutation.addedNodes.length === 1) { if (mutation.addedNodes.length === 1) {
const $addedElm = mutation.addedNodes[0]; const $addedElm = mutation.addedNodes[0];
if ($addedElm instanceof HTMLElement && $addedElm.className) { if ($addedElm instanceof HTMLElement) {
RootDialogObserver.handleAddedElement($root, $addedElm); RootDialogObserver.handleAddedElement($root, $addedElm);
} }
} }

View File

@@ -117,6 +117,7 @@ export class GlobalSettingsStorage extends BaseSettingsStorage {
}, },
[PrefKey.SERVER_REGION]: { [PrefKey.SERVER_REGION]: {
label: t('region'), label: t('region'),
note: CE('a', {target: '_blank', href: 'https://umap.openstreetmap.fr/en/map/xbox-cloud-gaming-servers_1135022'}, t('server-locations')),
default: 'default', default: 'default',
}, },
[PrefKey.SERVER_BYPASS_RESTRICTION]: { [PrefKey.SERVER_BYPASS_RESTRICTION]: {

View File

@@ -272,6 +272,7 @@ const Texts = {
"separate-touch-controller": "Separate Touch controller & Controller #1", "separate-touch-controller": "Separate Touch controller & Controller #1",
"separate-touch-controller-note": "Touch controller is Player 1, Controller #1 is Player 2", "separate-touch-controller-note": "Touch controller is Player 1, Controller #1 is Player 2",
"server": "Server", "server": "Server",
"server-locations": "Server locations",
"settings": "Settings", "settings": "Settings",
"settings-reload": "Reload page to reflect changes", "settings-reload": "Reload page to reflect changes",
"settings-reload-note": "Settings in this tab only go into effect on the next page load", "settings-reload-note": "Settings in this tab only go into effect on the next page load",