mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-06-29 02:41:44 +02:00
Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
29ff1bc09c | |||
8998daf14c | |||
8bdad8b319 | |||
5dd3ebdea1 | |||
55d7796f96 | |||
0b02a758db | |||
3b2abbf6bb | |||
43a66db697 | |||
a3130101f4 | |||
3483672554 | |||
75d7443e0f | |||
b5d2d0fdec | |||
20afe92371 | |||
5738412f71 |
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 6.4.1
|
// @version 6.4.6
|
||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
|
87
dist/better-xcloud.pretty.user.js
vendored
87
dist/better-xcloud.pretty.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 6.4.1
|
// @version 6.4.6
|
||||||
// @description Improve Xbox Cloud Gaming (xCloud) experience
|
// @description Improve Xbox Cloud Gaming (xCloud) experience
|
||||||
// @author redphx
|
// @author redphx
|
||||||
// @license MIT
|
// @license MIT
|
||||||
@ -192,7 +192,7 @@ class UserAgent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var SCRIPT_VERSION = "6.4.1", SCRIPT_VARIANT = "full", AppInterface = window.AppInterface;
|
var SCRIPT_VERSION = "6.4.6", 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, 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,
|
||||||
@ -382,6 +382,7 @@ class GhPagesUtils {
|
|||||||
var SUPPORTED_LANGUAGES = {
|
var SUPPORTED_LANGUAGES = {
|
||||||
"en-US": "English (US)",
|
"en-US": "English (US)",
|
||||||
"ca-CA": "Català",
|
"ca-CA": "Català",
|
||||||
|
"cs-CZ": "čeština",
|
||||||
"da-DK": "dansk",
|
"da-DK": "dansk",
|
||||||
"de-DE": "Deutsch",
|
"de-DE": "Deutsch",
|
||||||
"en-ID": "Bahasa Indonesia",
|
"en-ID": "Bahasa Indonesia",
|
||||||
@ -571,6 +572,7 @@ var SUPPORTED_LANGUAGES = {
|
|||||||
"new-version-available": [
|
"new-version-available": [
|
||||||
e => `Version ${e.version} available`,
|
e => `Version ${e.version} available`,
|
||||||
e => `Versió ${e.version} disponible`,
|
e => `Versió ${e.version} disponible`,
|
||||||
|
e => `Verze ${e.version} dostupná`,
|
||||||
,
|
,
|
||||||
e => `Version ${e.version} verfügbar`,
|
e => `Version ${e.version} verfügbar`,
|
||||||
e => `Versi ${e.version} tersedia`,
|
e => `Versi ${e.version} tersedia`,
|
||||||
@ -616,6 +618,7 @@ var SUPPORTED_LANGUAGES = {
|
|||||||
"press-key-to-toggle-mkb": [
|
"press-key-to-toggle-mkb": [
|
||||||
e => `Press ${e.key} to toggle this feature`,
|
e => `Press ${e.key} to toggle this feature`,
|
||||||
e => `Premeu ${e.key} per alternar aquesta funció`,
|
e => `Premeu ${e.key} per alternar aquesta funció`,
|
||||||
|
e => `Zmáčknete ${e.key} pro přepnutí této funkce`,
|
||||||
e => `Tryk på ${e.key} for at slå denne funktion til`,
|
e => `Tryk på ${e.key} for at slå denne funktion til`,
|
||||||
e => `${e.key}: Funktion an-/ausschalten`,
|
e => `${e.key}: Funktion an-/ausschalten`,
|
||||||
e => `Tekan ${e.key} untuk mengaktifkan fitur ini`,
|
e => `Tekan ${e.key} untuk mengaktifkan fitur ini`,
|
||||||
@ -641,6 +644,7 @@ var SUPPORTED_LANGUAGES = {
|
|||||||
e => `Recommended settings for ${e.device}`,
|
e => `Recommended settings for ${e.device}`,
|
||||||
e => `Configuració recomanada per a ${e.device}`,
|
e => `Configuració recomanada per a ${e.device}`,
|
||||||
,
|
,
|
||||||
|
,
|
||||||
e => `Empfohlene Einstellungen für ${e.device}`,
|
e => `Empfohlene Einstellungen für ${e.device}`,
|
||||||
e => `Rekomendasi pengaturan untuk ${e.device}`,
|
e => `Rekomendasi pengaturan untuk ${e.device}`,
|
||||||
e => `Ajustes recomendados para ${e.device}`,
|
e => `Ajustes recomendados para ${e.device}`,
|
||||||
@ -751,6 +755,7 @@ var SUPPORTED_LANGUAGES = {
|
|||||||
"touch-control-layout-by": [
|
"touch-control-layout-by": [
|
||||||
e => `Touch control layout by ${e.name}`,
|
e => `Touch control layout by ${e.name}`,
|
||||||
e => `Format del control tàctil per ${e.name}`,
|
e => `Format del control tàctil per ${e.name}`,
|
||||||
|
e => `Rozložení dotykového ovládání ${e.name}`,
|
||||||
e => `Touch-kontrol layout af ${e.name}`,
|
e => `Touch-kontrol layout af ${e.name}`,
|
||||||
e => `Touch-Steuerungslayout von ${e.name}`,
|
e => `Touch-Steuerungslayout von ${e.name}`,
|
||||||
e => `Tata letak Sentuhan layar oleh ${e.name}`,
|
e => `Tata letak Sentuhan layar oleh ${e.name}`,
|
||||||
@ -2688,11 +2693,12 @@ function setPref(prefKey, value, origin) {
|
|||||||
}
|
}
|
||||||
function checkForUpdate() {
|
function checkForUpdate() {
|
||||||
if (SCRIPT_VERSION.includes("beta")) return;
|
if (SCRIPT_VERSION.includes("beta")) return;
|
||||||
|
fetch("https://api.github.com/repos/redphx/better-xcloud/releases/latest").then((response) => response.json()).then((json) => {
|
||||||
|
setGlobalPref("version.latest", json.tag_name.substring(1), "direct"), setGlobalPref("version.current", SCRIPT_VERSION, "direct");
|
||||||
|
});
|
||||||
let CHECK_INTERVAL_SECONDS = 7200, currentVersion = getGlobalPref("version.current"), lastCheck = getGlobalPref("version.lastCheck"), now = Math.round(+new Date / 1000);
|
let CHECK_INTERVAL_SECONDS = 7200, currentVersion = getGlobalPref("version.current"), lastCheck = getGlobalPref("version.lastCheck"), now = Math.round(+new Date / 1000);
|
||||||
if (currentVersion === SCRIPT_VERSION && now - lastCheck < CHECK_INTERVAL_SECONDS) return;
|
if (currentVersion === SCRIPT_VERSION && now - lastCheck < CHECK_INTERVAL_SECONDS) return;
|
||||||
setGlobalPref("version.lastCheck", now, "direct"), fetch("https://api.github.com/repos/redphx/better-xcloud/releases/latest").then((response) => response.json()).then((json) => {
|
setGlobalPref("version.lastCheck", now, "direct"), Translations.updateTranslations(currentVersion === SCRIPT_VERSION);
|
||||||
setGlobalPref("version.latest", json.tag_name.substring(1), "direct"), setGlobalPref("version.current", SCRIPT_VERSION, "direct");
|
|
||||||
}), Translations.updateTranslations(currentVersion === SCRIPT_VERSION);
|
|
||||||
}
|
}
|
||||||
function disablePwa() {
|
function disablePwa() {
|
||||||
if (!(window.navigator.orgUserAgent || window.navigator.userAgent || "").toLowerCase()) return;
|
if (!(window.navigator.orgUserAgent || window.navigator.userAgent || "").toLowerCase()) return;
|
||||||
@ -4981,7 +4987,7 @@ class TouchController {
|
|||||||
}
|
}
|
||||||
if (!layoutId) layoutId = TouchController.#customLayouts[xboxTitleId]?.default_layout || null;
|
if (!layoutId) layoutId = TouchController.#customLayouts[xboxTitleId]?.default_layout || null;
|
||||||
if (!layoutId) {
|
if (!layoutId) {
|
||||||
BxLogger.error(LOG_TAG, "Invalid layoutId, show default controller"), TouchController.#enabled && TouchController.#showDefault();
|
BxLogger.warning(LOG_TAG, "Invalid layoutId, show default controller"), TouchController.#enabled && TouchController.#showDefault();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let layoutChanged = TouchController.#currentLayoutId !== layoutId;
|
let layoutChanged = TouchController.#currentLayoutId !== layoutId;
|
||||||
@ -5073,7 +5079,7 @@ var poll_gamepad_default = "var self=this;if(window.BX_EXPOSED.disableGamepadPol
|
|||||||
var expose_stream_session_default = 'var self=this;window.BX_EXPOSED.streamSession=self;var orgSetMicrophoneState=self.setMicrophoneState.bind(self);self.setMicrophoneState=(state)=>{orgSetMicrophoneState(state),window.BxEventBus.Stream.emit("microphone.state.changed",{state})};window.dispatchEvent(new Event(BxEvent.STREAM_SESSION_READY));var updateDimensionsStr=self.updateDimensions.toString();if(updateDimensionsStr.startsWith("function "))updateDimensionsStr=updateDimensionsStr.substring(9);var renderTargetVar=updateDimensionsStr.match(/if\\((\\w+)\\){/)[1];updateDimensionsStr=updateDimensionsStr.replaceAll(renderTargetVar+".scroll","scroll");updateDimensionsStr=updateDimensionsStr.replace(`if(${renderTargetVar}){`,`\nif (${renderTargetVar}) {\nconst scrollWidth = ${renderTargetVar}.dataset.width ? parseInt(${renderTargetVar}.dataset.width) : ${renderTargetVar}.scrollWidth;\nconst scrollHeight = ${renderTargetVar}.dataset.height ? parseInt(${renderTargetVar}.dataset.height) : ${renderTargetVar}.scrollHeight;\n`);eval(`this.updateDimensions = function ${updateDimensionsStr}`);\n';
|
var expose_stream_session_default = 'var self=this;window.BX_EXPOSED.streamSession=self;var orgSetMicrophoneState=self.setMicrophoneState.bind(self);self.setMicrophoneState=(state)=>{orgSetMicrophoneState(state),window.BxEventBus.Stream.emit("microphone.state.changed",{state})};window.dispatchEvent(new Event(BxEvent.STREAM_SESSION_READY));var updateDimensionsStr=self.updateDimensions.toString();if(updateDimensionsStr.startsWith("function "))updateDimensionsStr=updateDimensionsStr.substring(9);var renderTargetVar=updateDimensionsStr.match(/if\\((\\w+)\\){/)[1];updateDimensionsStr=updateDimensionsStr.replaceAll(renderTargetVar+".scroll","scroll");updateDimensionsStr=updateDimensionsStr.replace(`if(${renderTargetVar}){`,`\nif (${renderTargetVar}) {\nconst scrollWidth = ${renderTargetVar}.dataset.width ? parseInt(${renderTargetVar}.dataset.width) : ${renderTargetVar}.scrollWidth;\nconst scrollHeight = ${renderTargetVar}.dataset.height ? parseInt(${renderTargetVar}.dataset.height) : ${renderTargetVar}.scrollHeight;\n`);eval(`this.updateDimensions = function ${updateDimensionsStr}`);\n';
|
||||||
var game_card_icons_default = `var supportedInputIcons=$supportedInputIcons$,{productId}=$param$;supportedInputIcons.shift();if(window.BX_EXPOSED.localCoOpManager.isSupported(productId))supportedInputIcons.push(window.BX_EXPOSED.createReactLocalCoOpIcon);`;
|
var game_card_icons_default = `var supportedInputIcons=$supportedInputIcons$,{productId}=$param$;supportedInputIcons.shift();if(window.BX_EXPOSED.localCoOpManager.isSupported(productId))supportedInputIcons.push(window.BX_EXPOSED.createReactLocalCoOpIcon);`;
|
||||||
var local_co_op_enable_default = 'this.orgOnGamepadChanged=this.onGamepadChanged;this.orgOnGamepadInput=this.onGamepadInput;var match,onGamepadChangedStr=this.onGamepadChanged.toString();if(onGamepadChangedStr.startsWith("function "))onGamepadChangedStr=onGamepadChangedStr.substring(9);onGamepadChangedStr=onGamepadChangedStr.replaceAll("0","arguments[1]");eval(`this.patchedOnGamepadChanged = function ${onGamepadChangedStr}`);var onGamepadInputStr=this.onGamepadInput.toString();if(onGamepadInputStr.startsWith("function "))onGamepadInputStr=onGamepadInputStr.substring(9);match=onGamepadInputStr.match(/(\\w+\\.GamepadIndex)/);if(match){let gamepadIndexVar=match[0];onGamepadInputStr=onGamepadInputStr.replace("this.gamepadStates.get(",`this.gamepadStates.get(${gamepadIndexVar},`),eval(`this.patchedOnGamepadInput = function ${onGamepadInputStr}`),BxLogger.info("supportLocalCoOp","✅ Successfully patched local co-op support")}else BxLogger.error("supportLocalCoOp","❌ Unable to patch local co-op support");this.toggleLocalCoOp=(enable)=>{BxLogger.info("toggleLocalCoOp",enable?"Enabled":"Disabled"),this.onGamepadChanged=enable?this.patchedOnGamepadChanged:this.orgOnGamepadChanged,this.onGamepadInput=enable?this.patchedOnGamepadInput:this.orgOnGamepadInput;let gamepads=window.navigator.getGamepads();for(let gamepad of gamepads){if(!gamepad?.connected)continue;if(gamepad.id.includes("Better xCloud"))continue;gamepad._noToast=!0,window.dispatchEvent(new GamepadEvent("gamepaddisconnected",{gamepad})),window.dispatchEvent(new GamepadEvent("gamepadconnected",{gamepad}))}};window.BX_EXPOSED.toggleLocalCoOp=this.toggleLocalCoOp.bind(null);\n';
|
var local_co_op_enable_default = 'this.orgOnGamepadChanged=this.onGamepadChanged;this.orgOnGamepadInput=this.onGamepadInput;var match,onGamepadChangedStr=this.onGamepadChanged.toString();if(onGamepadChangedStr.startsWith("function "))onGamepadChangedStr=onGamepadChangedStr.substring(9);onGamepadChangedStr=onGamepadChangedStr.replaceAll("0","arguments[1]");eval(`this.patchedOnGamepadChanged = function ${onGamepadChangedStr}`);var onGamepadInputStr=this.onGamepadInput.toString();if(onGamepadInputStr.startsWith("function "))onGamepadInputStr=onGamepadInputStr.substring(9);match=onGamepadInputStr.match(/(\\w+\\.GamepadIndex)/);if(match){let gamepadIndexVar=match[0];onGamepadInputStr=onGamepadInputStr.replace("this.gamepadStates.get(",`this.gamepadStates.get(${gamepadIndexVar},`),eval(`this.patchedOnGamepadInput = function ${onGamepadInputStr}`),BxLogger.info("supportLocalCoOp","✅ Successfully patched local co-op support")}else BxLogger.error("supportLocalCoOp","❌ Unable to patch local co-op support");this.toggleLocalCoOp=(enable)=>{BxLogger.info("toggleLocalCoOp",enable?"Enabled":"Disabled"),this.onGamepadChanged=enable?this.patchedOnGamepadChanged:this.orgOnGamepadChanged,this.onGamepadInput=enable?this.patchedOnGamepadInput:this.orgOnGamepadInput;let gamepads=window.navigator.getGamepads();for(let gamepad of gamepads){if(!gamepad?.connected)continue;if(gamepad.id.includes("Better xCloud"))continue;gamepad._noToast=!0,window.dispatchEvent(new GamepadEvent("gamepaddisconnected",{gamepad})),window.dispatchEvent(new GamepadEvent("gamepadconnected",{gamepad}))}};window.BX_EXPOSED.toggleLocalCoOp=this.toggleLocalCoOp.bind(null);\n';
|
||||||
var remote_play_keep_alive_default = `try{if(JSON.parse(e).reason==="WarningForBeingIdle"&&!window.location.pathname.includes("/launch/")){this.sendKeepAlive();return}}catch(ex){console.log(ex)}`;
|
var remote_play_keep_alive_default = `try{if(JSON.parse(e).reason==="WarningForBeingIdle"&&window.location.pathname.includes("/consoles/launch/")){this.sendKeepAlive();return}}catch(ex){console.log(ex)}`;
|
||||||
var vibration_adjust_default = `if(e?.gamepad?.connected){let gamepadSettings=window.BX_STREAM_SETTINGS.controllers[e.gamepad.id];if(gamepadSettings?.customization){let intensity=gamepadSettings.customization.vibrationIntensity;if(intensity<=0){e.repeat=0;return}else if(intensity<1)e.leftMotorPercent*=intensity,e.rightMotorPercent*=intensity,e.leftTriggerMotorPercent*=intensity,e.rightTriggerMotorPercent*=intensity}}`;
|
var vibration_adjust_default = `if(e?.gamepad?.connected){let gamepadSettings=window.BX_STREAM_SETTINGS.controllers[e.gamepad.id];if(gamepadSettings?.customization){let intensity=gamepadSettings.customization.vibrationIntensity;if(intensity<=0){e.repeat=0;return}else if(intensity<1)e.leftMotorPercent*=intensity,e.rightMotorPercent*=intensity,e.leftTriggerMotorPercent*=intensity,e.rightTriggerMotorPercent*=intensity}}`;
|
||||||
var stream_hud_default = `var options=arguments[0];window.BX_EXPOSED.showStreamMenu=options.onShowStreamMenu;options.guideUI=null;window.BX_EXPOSED.reactUseEffect(()=>{window.BxEventBus.Stream.emit("ui.streamHud.rendered",{expanded:options.offset.x===0})});`;
|
var stream_hud_default = `var options=arguments[0];window.BX_EXPOSED.showStreamMenu=options.onShowStreamMenu;options.guideUI=null;window.BX_EXPOSED.reactUseEffect(()=>{window.BxEventBus.Stream.emit("ui.streamHud.rendered",{expanded:options.offset.x===0})});`;
|
||||||
var create_portal_default = `var $dom=arguments[1];if($dom&&$dom instanceof HTMLElement&&$dom.id==="gamepass-dialog-root"){let showing=!1,$dialog=$dom.firstElementChild?.firstElementChild;if($dialog)showing=!$dialog.className.includes("pageChangeExit");window.BxEventBus.Script.emit(showing?"dialog.shown":"dialog.dismissed",{})}`;
|
var create_portal_default = `var $dom=arguments[1];if($dom&&$dom instanceof HTMLElement&&$dom.id==="gamepass-dialog-root"){let showing=!1,$dialog=$dom.firstElementChild?.firstElementChild;if($dialog)showing=!$dialog.className.includes("pageChangeExit");window.BxEventBus.Script.emit(showing?"dialog.shown":"dialog.dismissed",{})}`;
|
||||||
@ -5133,11 +5139,6 @@ var LOG_TAG2 = "Patcher", PATCHES = {
|
|||||||
if (index < 0 || PatcherUtils.indexOf(str, '"AppInsightsCore', index, 200) < 0) return !1;
|
if (index < 0 || PatcherUtils.indexOf(str, '"AppInsightsCore', index, 200) < 0) return !1;
|
||||||
return PatcherUtils.replaceWith(str, index, text, ".track=function(e){},!!function(");
|
return PatcherUtils.replaceWith(str, index, text, ".track=function(e){},!!function(");
|
||||||
},
|
},
|
||||||
disableTelemetry(str) {
|
|
||||||
let text = ".disableTelemetry=function(){return!1}";
|
|
||||||
if (!str.includes(text)) return !1;
|
|
||||||
return str.replace(text, ".disableTelemetry=function(){return!0}");
|
|
||||||
},
|
|
||||||
disableTelemetryProvider(str) {
|
disableTelemetryProvider(str) {
|
||||||
let text = "this.enableLightweightTelemetry=!";
|
let text = "this.enableLightweightTelemetry=!";
|
||||||
if (!str.includes(text)) return !1;
|
if (!str.includes(text)) return !1;
|
||||||
@ -5165,10 +5166,10 @@ var LOG_TAG2 = "Patcher", PATCHES = {
|
|||||||
let layout = getGlobalPref("ui.layout") === "tv" ? "tv" : "default";
|
let layout = getGlobalPref("ui.layout") === "tv" ? "tv" : "default";
|
||||||
return str.replace(text, `?"${layout}":"${layout}"`);
|
return str.replace(text, `?"${layout}":"${layout}"`);
|
||||||
},
|
},
|
||||||
remotePlayDirectConnectUrl(str) {
|
remotePlayPostStreamRedirectUrl(str) {
|
||||||
let index = str.indexOf("/direct-connect");
|
let text = ".RemotePlayRoot.getLink()):";
|
||||||
if (index < 0) return !1;
|
if (!str.includes(text)) return !1;
|
||||||
return str.replace(str.substring(index - 9, index + 15), "https://www.xbox.com/play");
|
return str = str.replace(text, ".Home.getLink()):"), str;
|
||||||
},
|
},
|
||||||
remotePlayKeepAlive(str) {
|
remotePlayKeepAlive(str) {
|
||||||
let text = "onServerDisconnectMessage(e){";
|
let text = "onServerDisconnectMessage(e){";
|
||||||
@ -5188,17 +5189,6 @@ remotePlayServerId: (window.BX_REMOTE_PLAY_CONFIG && window.BX_REMOTE_PLAY_CONFI
|
|||||||
let newCode = "if (!!window.BX_REMOTE_PLAY_CONFIG) return;";
|
let newCode = "if (!!window.BX_REMOTE_PLAY_CONFIG) return;";
|
||||||
return str.replace(text, text + newCode);
|
return str.replace(text, text + newCode);
|
||||||
},
|
},
|
||||||
remotePlayRecentlyUsedTitleIds(str) {
|
|
||||||
let text = "(e.data.recentlyUsedTitleIds)){";
|
|
||||||
if (!str.includes(text)) return !1;
|
|
||||||
let newCode = "if (window.BX_REMOTE_PLAY_CONFIG) return;";
|
|
||||||
return str.replace(text, text + newCode);
|
|
||||||
},
|
|
||||||
remotePlayWebTitle(str) {
|
|
||||||
let text = "titleTemplate:void 0,title:", index = str.indexOf(text);
|
|
||||||
if (index < 0) return !1;
|
|
||||||
return str = PatcherUtils.insertAt(str, index + text.length, `!!window.BX_REMOTE_PLAY_CONFIG ? "${t("remote-play")} - Better xCloud" :`), str;
|
|
||||||
},
|
|
||||||
blockWebRtcStatsCollector(str) {
|
blockWebRtcStatsCollector(str) {
|
||||||
let text = "this.shouldCollectStats=!0";
|
let text = "this.shouldCollectStats=!0";
|
||||||
if (!str.includes(text)) return !1;
|
if (!str.includes(text)) return !1;
|
||||||
@ -5223,14 +5213,14 @@ remotePlayServerId: (window.BX_REMOTE_PLAY_CONFIG && window.BX_REMOTE_PLAY_CONFI
|
|||||||
return customizationCode += renderString(controller_customization_default, { xCloudGamepadVar }), codeBlock = PatcherUtils.insertAt(codeBlock, backetIndex, customizationCode), str = str.substring(0, index) + codeBlock + str.substring(setTimeoutIndex), str;
|
return customizationCode += renderString(controller_customization_default, { xCloudGamepadVar }), codeBlock = PatcherUtils.insertAt(codeBlock, backetIndex, customizationCode), str = str.substring(0, index) + codeBlock + str.substring(setTimeoutIndex), str;
|
||||||
},
|
},
|
||||||
enableXcloudLogger(str) {
|
enableXcloudLogger(str) {
|
||||||
let text = "this.telemetryProvider=e}log(e,t,r){";
|
let index = str.indexOf("this.telemetryProvider.trackErrorLike");
|
||||||
if (!str.includes(text)) return !1;
|
if (index > -1 && (index = PatcherUtils.lastIndexOf(str, "}log(", index, 1500)), index > -1 && (index = PatcherUtils.indexOf(str, "{", index, 30, !0)), index < 0) return !1;
|
||||||
let newCode = `
|
let newCode = `
|
||||||
const [logTag, logLevel, logMessage] = Array.from(arguments);
|
const [logTag, logLevel, logMessage] = Array.from(arguments);
|
||||||
const logFunc = [console.debug, console.log, console.warn, console.error][logLevel];
|
const logFunc = [console.debug, console.log, console.warn, console.error][logLevel];
|
||||||
logFunc(logTag, '//', logMessage);
|
logFunc(logTag, '//', logMessage);
|
||||||
`;
|
`;
|
||||||
return str = str.replaceAll(text, text + newCode), str;
|
return str = PatcherUtils.insertAt(str, index, newCode), str;
|
||||||
},
|
},
|
||||||
enableConsoleLogging(str) {
|
enableConsoleLogging(str) {
|
||||||
let text = "static isConsoleLoggingAllowed(){";
|
let text = "static isConsoleLoggingAllowed(){";
|
||||||
@ -5559,11 +5549,6 @@ if (this.baseStorageKey in window.BX_EXPOSED.overrideSettings) {
|
|||||||
if (index >= 0 && (index = str.indexOf('addEventListener("touchstart"', index)), index >= 0 && (index = PatcherUtils.lastIndexOf(str, "return ", index, 50)), index < 0) return !1;
|
if (index >= 0 && (index = str.indexOf('addEventListener("touchstart"', index)), index >= 0 && (index = PatcherUtils.lastIndexOf(str, "return ", index, 50)), index < 0) return !1;
|
||||||
return str = PatcherUtils.replaceWith(str, index, "return", "return () => {};"), str;
|
return str = PatcherUtils.replaceWith(str, index, "return", "return () => {};"), str;
|
||||||
},
|
},
|
||||||
optimizeGameSlugGenerator(str) {
|
|
||||||
let text = "/[;,/?:@&=+_`~$%#^*()!^\\u2122\\xae\\xa9]/g";
|
|
||||||
if (!str.includes(text)) return !1;
|
|
||||||
return str = str.replace(text, "window.BX_EXPOSED.GameSlugRegexes[0]"), str = str.replace("/ {2,}/g", "window.BX_EXPOSED.GameSlugRegexes[1]"), str = str.replace("/ /g", "window.BX_EXPOSED.GameSlugRegexes[2]"), str;
|
|
||||||
},
|
|
||||||
modifyPreloadedState(str) {
|
modifyPreloadedState(str) {
|
||||||
let text = "=window.__PRELOADED_STATE__;";
|
let text = "=window.__PRELOADED_STATE__;";
|
||||||
if (!str.includes(text)) return !1;
|
if (!str.includes(text)) return !1;
|
||||||
@ -5680,7 +5665,6 @@ ${subsVar} = subs;
|
|||||||
"broadcastPollingMode",
|
"broadcastPollingMode",
|
||||||
getGlobalPref("ui.gameCard.waitTime.show") && "patchSetCurrentFocus",
|
getGlobalPref("ui.gameCard.waitTime.show") && "patchSetCurrentFocus",
|
||||||
"patchGamepadPolling",
|
"patchGamepadPolling",
|
||||||
"optimizeGameSlugGenerator",
|
|
||||||
"modifyPreloadedState",
|
"modifyPreloadedState",
|
||||||
"detectBrowserRouterReady",
|
"detectBrowserRouterReady",
|
||||||
"exposeStreamSession",
|
"exposeStreamSession",
|
||||||
@ -5710,17 +5694,13 @@ ${subsVar} = subs;
|
|||||||
] : [],
|
] : [],
|
||||||
...getGlobalPref("block.tracking") ? [
|
...getGlobalPref("block.tracking") ? [
|
||||||
"disableAiTrack",
|
"disableAiTrack",
|
||||||
"disableTelemetry",
|
|
||||||
"blockWebRtcStatsCollector",
|
"blockWebRtcStatsCollector",
|
||||||
"disableIndexDbLogging",
|
"disableIndexDbLogging",
|
||||||
"disableTelemetryProvider"
|
"disableTelemetryProvider"
|
||||||
] : [],
|
] : [],
|
||||||
...getGlobalPref("xhome.enabled") ? [
|
...getGlobalPref("xhome.enabled") ? [
|
||||||
"remotePlayDirectConnectUrl",
|
|
||||||
"remotePlayKeepAlive",
|
"remotePlayKeepAlive",
|
||||||
"remotePlayWebTitle",
|
|
||||||
"remotePlayDisableAchievementToast",
|
"remotePlayDisableAchievementToast",
|
||||||
"remotePlayRecentlyUsedTitleIds",
|
|
||||||
STATES.userAgent.capabilities.touch && "patchUpdateInputConfigurationAsync"
|
STATES.userAgent.capabilities.touch && "patchUpdateInputConfigurationAsync"
|
||||||
] : [],
|
] : [],
|
||||||
...BX_FLAGS.EnableXcloudLogging ? [
|
...BX_FLAGS.EnableXcloudLogging ? [
|
||||||
@ -5761,6 +5741,7 @@ ${subsVar} = subs;
|
|||||||
"patchPollGamepads",
|
"patchPollGamepads",
|
||||||
getGlobalPref("stream.video.combineAudio") && "streamCombineSources",
|
getGlobalPref("stream.video.combineAudio") && "streamCombineSources",
|
||||||
...getGlobalPref("xhome.enabled") ? [
|
...getGlobalPref("xhome.enabled") ? [
|
||||||
|
"remotePlayPostStreamRedirectUrl",
|
||||||
"patchRemotePlayMkb",
|
"patchRemotePlayMkb",
|
||||||
"remotePlayConnectMode"
|
"remotePlayConnectMode"
|
||||||
] : [],
|
] : [],
|
||||||
@ -8161,7 +8142,8 @@ var FeatureGates = {
|
|||||||
EnableUpdateRequiredPage: !1,
|
EnableUpdateRequiredPage: !1,
|
||||||
ShowForcedUpdateScreen: !1,
|
ShowForcedUpdateScreen: !1,
|
||||||
EnableTakControlResizing: !0,
|
EnableTakControlResizing: !0,
|
||||||
EnableLazyLoadedHome: !1
|
EnableLazyLoadedHome: !1,
|
||||||
|
EnableRemotePlay: getGlobalPref("xhome.enabled")
|
||||||
}, nativeMkbMode = getGlobalPref("nativeMkb.mode");
|
}, nativeMkbMode = getGlobalPref("nativeMkb.mode");
|
||||||
if (nativeMkbMode !== "default") FeatureGates.EnableMouseAndKeyboard = nativeMkbMode === "on";
|
if (nativeMkbMode !== "default") FeatureGates.EnableMouseAndKeyboard = nativeMkbMode === "on";
|
||||||
var blockFeatures = getGlobalPref("block.features");
|
var blockFeatures = getGlobalPref("block.features");
|
||||||
@ -8384,7 +8366,7 @@ class RemotePlayDialog extends NavigationDialog {
|
|||||||
BxLogger.info(this.LOG_TAG, "constructor()"), this.setupDialog();
|
BxLogger.info(this.LOG_TAG, "constructor()"), this.setupDialog();
|
||||||
}
|
}
|
||||||
setupDialog() {
|
setupDialog() {
|
||||||
let $fragment = CE("div", { class: "bx-centered-dialog" }, CE("div", { class: "bx-dialog-title" }, CE("p", !1, t("remote-play")))), $settingNote = CE("p", {}), currentResolution = getGlobalPref("xhome.video.resolution"), $resolutions = CE("select", !1, CE("option", { value: "720p" }, "720p"), CE("option", { value: "1080p" }, "1080p"));
|
let $fragment = CE("div", { class: "bx-centered-dialog" }, CE("div", { class: "bx-dialog-title" }, CE("p", !1, t("remote-play")))), $settingNote = CE("p", {}), currentResolution = getGlobalPref("xhome.video.resolution"), $resolutions = CE("select", !1, CE("option", { value: "720p" }, "720p"), CE("option", { value: "1080p" }, "1080p"), CE("option", { value: "1080p-hq" }, "1080p (HQ)"));
|
||||||
$resolutions = BxSelectElement.create($resolutions), $resolutions.addEventListener("input", (e) => {
|
$resolutions = BxSelectElement.create($resolutions), $resolutions.addEventListener("input", (e) => {
|
||||||
let value = e.target.value;
|
let value = e.target.value;
|
||||||
$settingNote.textContent = value === "1080p" ? "✅ " + t("can-stream-xbox-360-games") : "❌ " + t("cant-stream-xbox-360-games"), setGlobalPref("xhome.video.resolution", value, "ui");
|
$settingNote.textContent = value === "1080p" ? "✅ " + t("can-stream-xbox-360-games") : "❌ " + t("cant-stream-xbox-360-games"), setGlobalPref("xhome.video.resolution", value, "ui");
|
||||||
@ -8514,6 +8496,9 @@ class RemotePlayManager {
|
|||||||
Authorization: `Bearer ${this.XHOME_TOKEN}`
|
Authorization: `Bearer ${this.XHOME_TOKEN}`
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
this.regions.sort((a, b) => {
|
||||||
|
return a.isDefault ? -1 : 0;
|
||||||
|
});
|
||||||
for (let region of this.regions)
|
for (let region of this.regions)
|
||||||
try {
|
try {
|
||||||
let request = new Request(`${region.baseUri}/v6/servers/home?mr=50`, options), json = await (await fetch(request)).json();
|
let request = new Request(`${region.baseUri}/v6/servers/home?mr=50`, options), json = await (await fetch(request)).json();
|
||||||
@ -8528,7 +8513,7 @@ class RemotePlayManager {
|
|||||||
if (resolution) setGlobalPref("xhome.video.resolution", resolution, "ui");
|
if (resolution) setGlobalPref("xhome.video.resolution", resolution, "ui");
|
||||||
STATES.remotePlay.config = {
|
STATES.remotePlay.config = {
|
||||||
serverId
|
serverId
|
||||||
}, window.BX_REMOTE_PLAY_CONFIG = STATES.remotePlay.config, localRedirect("/launch/fortnite/BT5P2X999VH2#remote-play");
|
}, window.BX_REMOTE_PLAY_CONFIG = STATES.remotePlay.config, localRedirect("/launch/fortnite/BT5P2X999VH2#remote-play"), setTimeout(() => localRedirect("/consoles/launch/" + serverId), 100);
|
||||||
}
|
}
|
||||||
togglePopup(force = null) {
|
togglePopup(force = null) {
|
||||||
if (!this.isReady()) {
|
if (!this.isReady()) {
|
||||||
@ -8597,7 +8582,7 @@ class XhomeInterceptor {
|
|||||||
if (hasTouchSupport) TouchController.disable(), BxEvent.dispatch(window, BxEvent.CUSTOM_TOUCH_LAYOUTS_LOADED, {
|
if (hasTouchSupport) TouchController.disable(), BxEvent.dispatch(window, BxEvent.CUSTOM_TOUCH_LAYOUTS_LOADED, {
|
||||||
data: null
|
data: null
|
||||||
});
|
});
|
||||||
else TouchController.enable(), TouchController.requestCustomLayouts(xboxTitleId);
|
else TouchController.enable(), TouchController.requestCustomLayouts();
|
||||||
return response.json = () => Promise.resolve(obj), response.text = () => Promise.resolve(JSON.stringify(obj)), response;
|
return response.json = () => Promise.resolve(obj), response.text = () => Promise.resolve(JSON.stringify(obj)), response;
|
||||||
}
|
}
|
||||||
static async handleTitles(request) {
|
static async handleTitles(request) {
|
||||||
@ -8662,7 +8647,8 @@ class LoadingScreen {
|
|||||||
let $bgStyle = CE("style");
|
let $bgStyle = CE("style");
|
||||||
document.documentElement.appendChild($bgStyle), LoadingScreen.$bgStyle = $bgStyle;
|
document.documentElement.appendChild($bgStyle), LoadingScreen.$bgStyle = $bgStyle;
|
||||||
}
|
}
|
||||||
if (LoadingScreen.setBackground(titleInfo.product.heroImageUrl || titleInfo.product.titledHeroImageUrl || titleInfo.product.tileImageUrl), getGlobalPref("loadingScreen.rocket") === "hide") LoadingScreen.hideRocket();
|
if (titleInfo.productInfo) LoadingScreen.setBackground(titleInfo.productInfo.heroImageUrl || titleInfo.productInfo.titledHeroImageUrl || titleInfo.productInfo.tileImageUrl);
|
||||||
|
if (getGlobalPref("loadingScreen.rocket") === "hide") LoadingScreen.hideRocket();
|
||||||
}
|
}
|
||||||
static hideRocket() {
|
static hideRocket() {
|
||||||
let $bgStyle = LoadingScreen.$bgStyle;
|
let $bgStyle = LoadingScreen.$bgStyle;
|
||||||
@ -9094,8 +9080,11 @@ function updateIceCandidates(candidates, options) {
|
|||||||
let pattern = new RegExp(/a=candidate:(?<foundation>\d+) (?<component>\d+) UDP (?<priority>\d+) (?<ip>[^\s]+) (?<port>\d+) (?<the_rest>.*)/), lst = [];
|
let pattern = new RegExp(/a=candidate:(?<foundation>\d+) (?<component>\d+) UDP (?<priority>\d+) (?<ip>[^\s]+) (?<port>\d+) (?<the_rest>.*)/), lst = [];
|
||||||
for (let item2 of candidates) {
|
for (let item2 of candidates) {
|
||||||
if (item2.candidate == "a=end-of-candidates") continue;
|
if (item2.candidate == "a=end-of-candidates") continue;
|
||||||
let groups = pattern.exec(item2.candidate).groups;
|
let match = pattern.exec(item2.candidate);
|
||||||
lst.push(groups);
|
if (match && match.groups) {
|
||||||
|
let groups = match.groups;
|
||||||
|
lst.push(groups);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (options.preferIpv6Server) lst.sort((a, b) => {
|
if (options.preferIpv6Server) lst.sort((a, b) => {
|
||||||
let firstIp = a.ip, secondIp = b.ip;
|
let firstIp = a.ip, secondIp = b.ip;
|
||||||
@ -9579,7 +9568,7 @@ function patchVideoApi() {
|
|||||||
return nativePlay.apply(this);
|
return nativePlay.apply(this);
|
||||||
}
|
}
|
||||||
let $parent = this.parentElement;
|
let $parent = this.parentElement;
|
||||||
if (!this.src && $parent.dataset.testid === "media-container") this.addEventListener("loadedmetadata", showFunc, { once: !0 });
|
if (!this.src && $parent?.dataset.testid === "media-container") this.addEventListener("loadedmetadata", showFunc, { once: !0 });
|
||||||
return nativePlay.apply(this);
|
return nativePlay.apply(this);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -10256,7 +10245,7 @@ BxEventBus.Script.on("ui.header.rendered", () => {
|
|||||||
HeaderSection.getInstance().checkHeader();
|
HeaderSection.getInstance().checkHeader();
|
||||||
});
|
});
|
||||||
BxEventBus.Stream.on("state.loading", () => {
|
BxEventBus.Stream.on("state.loading", () => {
|
||||||
if (window.location.pathname.includes("/launch/") && STATES.currentStream.titleInfo) STATES.currentStream.titleSlug = productTitleToSlug(STATES.currentStream.titleInfo.product.title);
|
if (window.location.pathname.includes("/launch/") && STATES.currentStream.titleInfo) STATES.currentStream.titleSlug = productTitleToSlug(STATES.currentStream.titleInfo.productInfo.title);
|
||||||
else STATES.currentStream.titleSlug = "remote-play";
|
else STATES.currentStream.titleSlug = "remote-play";
|
||||||
});
|
});
|
||||||
getGlobalPref("loadingScreen.gameArt.show") && BxEventBus.Script.on("titleInfo.ready", LoadingScreen.setup);
|
getGlobalPref("loadingScreen.gameArt.show") && BxEventBus.Script.on("titleInfo.ready", LoadingScreen.setup);
|
||||||
|
40
dist/better-xcloud.user.js
vendored
40
dist/better-xcloud.user.js
vendored
File diff suppressed because one or more lines are too long
@ -204,7 +204,7 @@ BxEventBus.Script.on('ui.header.rendered', () => {
|
|||||||
BxEventBus.Stream.on('state.loading', () => {
|
BxEventBus.Stream.on('state.loading', () => {
|
||||||
// Get title ID for screenshot's name
|
// Get title ID for screenshot's name
|
||||||
if (window.location.pathname.includes('/launch/') && STATES.currentStream.titleInfo) {
|
if (window.location.pathname.includes('/launch/') && STATES.currentStream.titleInfo) {
|
||||||
STATES.currentStream.titleSlug = productTitleToSlug(STATES.currentStream.titleInfo.product.title);
|
STATES.currentStream.titleSlug = productTitleToSlug(STATES.currentStream.titleInfo.productInfo.title);
|
||||||
} else {
|
} else {
|
||||||
STATES.currentStream.titleSlug = 'remote-play';
|
STATES.currentStream.titleSlug = 'remote-play';
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,9 @@ export class LoadingScreen {
|
|||||||
LoadingScreen.$bgStyle = $bgStyle;
|
LoadingScreen.$bgStyle = $bgStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadingScreen.setBackground(titleInfo.product.heroImageUrl || titleInfo.product.titledHeroImageUrl || titleInfo.product.tileImageUrl);
|
if (titleInfo.productInfo) {
|
||||||
|
LoadingScreen.setBackground(titleInfo.productInfo.heroImageUrl || titleInfo.productInfo.titledHeroImageUrl || titleInfo.productInfo.tileImageUrl);
|
||||||
|
}
|
||||||
|
|
||||||
if (getGlobalPref(GlobalPref.LOADING_SCREEN_ROCKET) === LoadingScreenRocket.HIDE) {
|
if (getGlobalPref(GlobalPref.LOADING_SCREEN_ROCKET) === LoadingScreenRocket.HIDE) {
|
||||||
LoadingScreen.hideRocket();
|
LoadingScreen.hideRocket();
|
||||||
|
@ -16,7 +16,6 @@ import codeCreatePortal from "./patches/create-portal.js" with { type: "text" };
|
|||||||
import { GlobalPref, StorageKey } from "@/enums/pref-keys.js";
|
import { GlobalPref, StorageKey } from "@/enums/pref-keys.js";
|
||||||
import { getGlobalPref } from "@/utils/pref-utils.js";
|
import { getGlobalPref } from "@/utils/pref-utils.js";
|
||||||
import { GamePassCloudGallery } from "@/enums/game-pass-gallery";
|
import { GamePassCloudGallery } from "@/enums/game-pass-gallery";
|
||||||
import { t } from "@/utils/translation";
|
|
||||||
import { BlockFeature, NativeMkbMode, TouchControllerMode, UiLayout, UiSection } from "@/enums/pref-values";
|
import { BlockFeature, NativeMkbMode, TouchControllerMode, UiLayout, UiSection } from "@/enums/pref-values";
|
||||||
import { PatcherUtils } from "./patcher-utils.js";
|
import { PatcherUtils } from "./patcher-utils.js";
|
||||||
|
|
||||||
@ -40,6 +39,7 @@ const PATCHES = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Set disableTelemetry() to true
|
// Set disableTelemetry() to true
|
||||||
|
/*
|
||||||
disableTelemetry(str: string) {
|
disableTelemetry(str: string) {
|
||||||
let text = '.disableTelemetry=function(){return!1}';
|
let text = '.disableTelemetry=function(){return!1}';
|
||||||
if (!str.includes(text)) {
|
if (!str.includes(text)) {
|
||||||
@ -48,6 +48,7 @@ const PATCHES = {
|
|||||||
|
|
||||||
return str.replace(text, '.disableTelemetry=function(){return!0}');
|
return str.replace(text, '.disableTelemetry=function(){return!0}');
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
|
|
||||||
disableTelemetryProvider(str: string) {
|
disableTelemetryProvider(str: string) {
|
||||||
let text = 'this.enableLightweightTelemetry=!';
|
let text = 'this.enableLightweightTelemetry=!';
|
||||||
@ -92,14 +93,14 @@ const PATCHES = {
|
|||||||
return str.replace(text, `?"${layout}":"${layout}"`);
|
return str.replace(text, `?"${layout}":"${layout}"`);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Replace "/direct-connect" with "/play"
|
remotePlayPostStreamRedirectUrl(str: string) {
|
||||||
remotePlayDirectConnectUrl(str: string) {
|
let text = '.RemotePlayRoot.getLink()):';
|
||||||
const index = str.indexOf('/direct-connect');
|
if (!str.includes(text)) {
|
||||||
if (index < 0) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return str.replace(str.substring(index - 9, index + 15), 'https://www.xbox.com/play');
|
str = str.replace(text, '.Home.getLink()):');
|
||||||
|
return str;
|
||||||
},
|
},
|
||||||
|
|
||||||
remotePlayKeepAlive(str: string) {
|
remotePlayKeepAlive(str: string) {
|
||||||
@ -136,29 +137,6 @@ remotePlayServerId: (window.BX_REMOTE_PLAY_CONFIG && window.BX_REMOTE_PLAY_CONFI
|
|||||||
return str.replace(text, text + newCode);
|
return str.replace(text, text + newCode);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Remote Play: Prevent adding "Fortnite" to the "Jump back in" list
|
|
||||||
remotePlayRecentlyUsedTitleIds(str: string) {
|
|
||||||
let text = '(e.data.recentlyUsedTitleIds)){';
|
|
||||||
if (!str.includes(text)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const newCode = `if (window.BX_REMOTE_PLAY_CONFIG) return;`;
|
|
||||||
return str.replace(text, text + newCode);
|
|
||||||
},
|
|
||||||
|
|
||||||
// Remote Play: change web page's title
|
|
||||||
remotePlayWebTitle(str: string) {
|
|
||||||
let text = 'titleTemplate:void 0,title:';
|
|
||||||
const index = str.indexOf(text);
|
|
||||||
if (index < 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
str = PatcherUtils.insertAt(str, index + text.length, `!!window.BX_REMOTE_PLAY_CONFIG ? "${t('remote-play')} - Better xCloud" :`);
|
|
||||||
return str;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Block WebRTC stats collector
|
// Block WebRTC stats collector
|
||||||
blockWebRtcStatsCollector(str: string) {
|
blockWebRtcStatsCollector(str: string) {
|
||||||
let text = 'this.shouldCollectStats=!0';
|
let text = 'this.shouldCollectStats=!0';
|
||||||
@ -226,8 +204,11 @@ remotePlayServerId: (window.BX_REMOTE_PLAY_CONFIG && window.BX_REMOTE_PLAY_CONFI
|
|||||||
},
|
},
|
||||||
|
|
||||||
enableXcloudLogger(str: string) {
|
enableXcloudLogger(str: string) {
|
||||||
let text = 'this.telemetryProvider=e}log(e,t,r){';
|
let index = str.indexOf('this.telemetryProvider.trackErrorLike');
|
||||||
if (!str.includes(text)) {
|
index > -1 && (index = PatcherUtils.lastIndexOf(str, '}log(', index, 1500));
|
||||||
|
index > -1 && (index = PatcherUtils.indexOf(str, '{', index, 30, true));
|
||||||
|
|
||||||
|
if (index < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +218,7 @@ const logFunc = [console.debug, console.log, console.warn, console.error][logLev
|
|||||||
logFunc(logTag, '//', logMessage);
|
logFunc(logTag, '//', logMessage);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
str = str.replaceAll(text, text + newCode);
|
str = PatcherUtils.insertAt(str, index, newCode);
|
||||||
return str;
|
return str;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -933,20 +914,6 @@ if (this.baseStorageKey in window.BX_EXPOSED.overrideSettings) {
|
|||||||
return str;
|
return str;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Optimize Game slug generator by using cached RegEx
|
|
||||||
optimizeGameSlugGenerator(str: string) {
|
|
||||||
let text = '/[;,/?:@&=+_`~$%#^*()!^\\u2122\\xae\\xa9]/g';
|
|
||||||
if (!str.includes(text)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
str = str.replace(text, 'window.BX_EXPOSED.GameSlugRegexes[0]');
|
|
||||||
str = str.replace('/ {2,}/g', 'window.BX_EXPOSED.GameSlugRegexes[1]');
|
|
||||||
str = str.replace('/ /g', 'window.BX_EXPOSED.GameSlugRegexes[2]');
|
|
||||||
|
|
||||||
return str;
|
|
||||||
},
|
|
||||||
|
|
||||||
modifyPreloadedState(str: string) {
|
modifyPreloadedState(str: string) {
|
||||||
let text = '=window.__PRELOADED_STATE__;';
|
let text = '=window.__PRELOADED_STATE__;';
|
||||||
if (!str.includes(text)) {
|
if (!str.includes(text)) {
|
||||||
@ -1243,8 +1210,6 @@ let PATCH_ORDERS = PatcherUtils.filterPatches([
|
|||||||
|
|
||||||
'patchGamepadPolling',
|
'patchGamepadPolling',
|
||||||
|
|
||||||
'optimizeGameSlugGenerator',
|
|
||||||
|
|
||||||
'modifyPreloadedState',
|
'modifyPreloadedState',
|
||||||
|
|
||||||
'detectBrowserRouterReady',
|
'detectBrowserRouterReady',
|
||||||
@ -1293,7 +1258,7 @@ let PATCH_ORDERS = PatcherUtils.filterPatches([
|
|||||||
|
|
||||||
...(getGlobalPref(GlobalPref.BLOCK_TRACKING) ? [
|
...(getGlobalPref(GlobalPref.BLOCK_TRACKING) ? [
|
||||||
'disableAiTrack',
|
'disableAiTrack',
|
||||||
'disableTelemetry',
|
// 'disableTelemetry',
|
||||||
|
|
||||||
'blockWebRtcStatsCollector',
|
'blockWebRtcStatsCollector',
|
||||||
'disableIndexDbLogging',
|
'disableIndexDbLogging',
|
||||||
@ -1302,11 +1267,8 @@ let PATCH_ORDERS = PatcherUtils.filterPatches([
|
|||||||
] : []) as PatchArray,
|
] : []) as PatchArray,
|
||||||
|
|
||||||
...(getGlobalPref(GlobalPref.REMOTE_PLAY_ENABLED) ? [
|
...(getGlobalPref(GlobalPref.REMOTE_PLAY_ENABLED) ? [
|
||||||
'remotePlayDirectConnectUrl',
|
|
||||||
'remotePlayKeepAlive',
|
'remotePlayKeepAlive',
|
||||||
'remotePlayWebTitle',
|
|
||||||
'remotePlayDisableAchievementToast',
|
'remotePlayDisableAchievementToast',
|
||||||
'remotePlayRecentlyUsedTitleIds',
|
|
||||||
STATES.userAgent.capabilities.touch && 'patchUpdateInputConfigurationAsync',
|
STATES.userAgent.capabilities.touch && 'patchUpdateInputConfigurationAsync',
|
||||||
] : []) as PatchArray,
|
] : []) as PatchArray,
|
||||||
|
|
||||||
@ -1374,6 +1336,7 @@ let STREAM_PAGE_PATCH_ORDERS = PatcherUtils.filterPatches([
|
|||||||
getGlobalPref(GlobalPref.STREAM_COMBINE_SOURCES) && 'streamCombineSources',
|
getGlobalPref(GlobalPref.STREAM_COMBINE_SOURCES) && 'streamCombineSources',
|
||||||
|
|
||||||
...(getGlobalPref(GlobalPref.REMOTE_PLAY_ENABLED) ? [
|
...(getGlobalPref(GlobalPref.REMOTE_PLAY_ENABLED) ? [
|
||||||
|
'remotePlayPostStreamRedirectUrl',
|
||||||
'patchRemotePlayMkb',
|
'patchRemotePlayMkb',
|
||||||
'remotePlayConnectMode',
|
'remotePlayConnectMode',
|
||||||
] : []) as PatchArray,
|
] : []) as PatchArray,
|
||||||
|
@ -3,7 +3,7 @@ declare const e: string;
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const msg = JSON.parse(e);
|
const msg = JSON.parse(e);
|
||||||
if (msg.reason === 'WarningForBeingIdle' && !window.location.pathname.includes('/launch/')) {
|
if (msg.reason === 'WarningForBeingIdle' && window.location.pathname.includes('/consoles/launch/')) {
|
||||||
$this$.sendKeepAlive();
|
$this$.sendKeepAlive();
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return;
|
return;
|
||||||
|
@ -156,6 +156,11 @@ export class RemotePlayManager {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Start with "isDefault" = true first
|
||||||
|
this.regions.sort((a: RemotePlayRegion, b: RemotePlayRegion) => {
|
||||||
|
return a.isDefault ? -1 : 0;
|
||||||
|
})
|
||||||
|
|
||||||
// Test servers one by one
|
// Test servers one by one
|
||||||
for (const region of this.regions) {
|
for (const region of this.regions) {
|
||||||
try {
|
try {
|
||||||
@ -195,6 +200,7 @@ export class RemotePlayManager {
|
|||||||
window.BX_REMOTE_PLAY_CONFIG = STATES.remotePlay.config;
|
window.BX_REMOTE_PLAY_CONFIG = STATES.remotePlay.config;
|
||||||
|
|
||||||
localRedirect('/launch/fortnite/BT5P2X999VH2#remote-play');
|
localRedirect('/launch/fortnite/BT5P2X999VH2#remote-play');
|
||||||
|
setTimeout(() => localRedirect('/consoles/launch/' + serverId), 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
togglePopup(force = null) {
|
togglePopup(force = null) {
|
||||||
|
@ -209,7 +209,7 @@ export class TouchController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!layoutId) {
|
if (!layoutId) {
|
||||||
BxLogger.error(LOG_TAG, 'Invalid layoutId, show default controller');
|
BxLogger.warning(LOG_TAG, 'Invalid layoutId, show default controller');
|
||||||
TouchController.#enabled && TouchController.#showDefault();
|
TouchController.#enabled && TouchController.#showDefault();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -44,14 +44,14 @@ export class RemotePlayDialog extends NavigationDialog {
|
|||||||
let $resolutions : HTMLSelectElement | NavigationElement = CE('select', false,
|
let $resolutions : HTMLSelectElement | NavigationElement = CE('select', false,
|
||||||
CE('option', { value: StreamResolution.DIM_720P }, '720p'),
|
CE('option', { value: StreamResolution.DIM_720P }, '720p'),
|
||||||
CE('option', { value: StreamResolution.DIM_1080P }, '1080p'),
|
CE('option', { value: StreamResolution.DIM_1080P }, '1080p'),
|
||||||
// CE('option', { value: StreamResolution.DIM_1080P_HQ }, `1080p (HQ)`),
|
CE('option', { value: StreamResolution.DIM_1080P_HQ }, `1080p (HQ)`),
|
||||||
);
|
);
|
||||||
|
|
||||||
$resolutions = BxSelectElement.create($resolutions as HTMLSelectElement);
|
$resolutions = BxSelectElement.create($resolutions as HTMLSelectElement);
|
||||||
$resolutions.addEventListener('input', (e: Event) => {
|
$resolutions.addEventListener('input', (e: Event) => {
|
||||||
const value = (e.target as HTMLSelectElement).value;
|
const value = (e.target as HTMLSelectElement).value;
|
||||||
|
|
||||||
$settingNote.textContent = value === '1080p' ? '✅ ' + t('can-stream-xbox-360-games') : '❌ ' + t('cant-stream-xbox-360-games');
|
$settingNote.textContent = value === StreamResolution.DIM_1080P ? '✅ ' + t('can-stream-xbox-360-games') : '❌ ' + t('cant-stream-xbox-360-games');
|
||||||
setGlobalPref(GlobalPref.REMOTE_PLAY_STREAM_RESOLUTION, value, 'ui');
|
setGlobalPref(GlobalPref.REMOTE_PLAY_STREAM_RESOLUTION, value, 'ui');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
2
src/types/index.d.ts
vendored
2
src/types/index.d.ts
vendored
@ -36,7 +36,7 @@ type XcloudTitleInfo = {
|
|||||||
hasMkbSupport: boolean;
|
hasMkbSupport: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
product: {
|
productInfo: {
|
||||||
title: string;
|
title: string;
|
||||||
heroImageUrl: string;
|
heroImageUrl: string;
|
||||||
titledHeroImageUrl: string;
|
titledHeroImageUrl: string;
|
||||||
|
@ -10,6 +10,7 @@ export let FeatureGates: { [key: string]: boolean } = {
|
|||||||
ShowForcedUpdateScreen: false,
|
ShowForcedUpdateScreen: false,
|
||||||
EnableTakControlResizing: true, // Experimenting
|
EnableTakControlResizing: true, // Experimenting
|
||||||
EnableLazyLoadedHome: false,
|
EnableLazyLoadedHome: false,
|
||||||
|
EnableRemotePlay: getGlobalPref(GlobalPref.REMOTE_PLAY_ENABLED),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Enable Native Mouse & Keyboard
|
// Enable Native Mouse & Keyboard
|
||||||
|
@ -55,9 +55,9 @@ export function patchVideoApi() {
|
|||||||
return nativePlay.apply(this);
|
return nativePlay.apply(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
const $parent = this.parentElement!!;
|
const $parent = this.parentElement;
|
||||||
// Video tag is stream player
|
// Video tag is stream player
|
||||||
if (!this.src && $parent.dataset.testid === 'media-container') {
|
if (!this.src && $parent?.dataset.testid === 'media-container') {
|
||||||
this.addEventListener('loadedmetadata', showFunc, { once: true });
|
this.addEventListener('loadedmetadata', showFunc, { once: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,8 +49,11 @@ function updateIceCandidates(candidates: any, options: { preferIpv6Server: boole
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const groups: { [index: string]: string | number } = pattern.exec(item.candidate)!.groups!;
|
const match = pattern.exec(item.candidate);
|
||||||
lst.push(groups);
|
if (match && match.groups) {
|
||||||
|
const groups: { [index: string]: string | number } = match.groups;
|
||||||
|
lst.push(groups);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.preferIpv6Server) {
|
if (options.preferIpv6Server) {
|
||||||
|
@ -7,6 +7,7 @@ export const SUPPORTED_LANGUAGES = {
|
|||||||
'en-US': 'English (US)',
|
'en-US': 'English (US)',
|
||||||
|
|
||||||
'ca-CA': 'Català',
|
'ca-CA': 'Català',
|
||||||
|
'cs-CZ': 'čeština',
|
||||||
'da-DK': 'dansk',
|
'da-DK': 'dansk',
|
||||||
'de-DE': 'Deutsch',
|
'de-DE': 'Deutsch',
|
||||||
'en-ID': 'Bahasa Indonesia',
|
'en-ID': 'Bahasa Indonesia',
|
||||||
@ -198,6 +199,7 @@ const Texts = {
|
|||||||
"new-version-available": [
|
"new-version-available": [
|
||||||
(e: any) => `Version ${e.version} available`,
|
(e: any) => `Version ${e.version} available`,
|
||||||
(e: any) => `Versió ${e.version} disponible`,
|
(e: any) => `Versió ${e.version} disponible`,
|
||||||
|
(e: any) => `Verze ${e.version} dostupná`,
|
||||||
,
|
,
|
||||||
(e: any) => `Version ${e.version} verfügbar`,
|
(e: any) => `Version ${e.version} verfügbar`,
|
||||||
(e: any) => `Versi ${e.version} tersedia`,
|
(e: any) => `Versi ${e.version} tersedia`,
|
||||||
@ -243,6 +245,7 @@ const Texts = {
|
|||||||
"press-key-to-toggle-mkb": [
|
"press-key-to-toggle-mkb": [
|
||||||
(e: any) => `Press ${e.key} to toggle this feature`,
|
(e: any) => `Press ${e.key} to toggle this feature`,
|
||||||
(e: any) => `Premeu ${e.key} per alternar aquesta funció`,
|
(e: any) => `Premeu ${e.key} per alternar aquesta funció`,
|
||||||
|
(e: any) => `Zmáčknete ${e.key} pro přepnutí této funkce`,
|
||||||
(e: any) => `Tryk på ${e.key} for at slå denne funktion til`,
|
(e: any) => `Tryk på ${e.key} for at slå denne funktion til`,
|
||||||
(e: any) => `${e.key}: Funktion an-/ausschalten`,
|
(e: any) => `${e.key}: Funktion an-/ausschalten`,
|
||||||
(e: any) => `Tekan ${e.key} untuk mengaktifkan fitur ini`,
|
(e: any) => `Tekan ${e.key} untuk mengaktifkan fitur ini`,
|
||||||
@ -268,6 +271,7 @@ const Texts = {
|
|||||||
(e: any) => `Recommended settings for ${e.device}`,
|
(e: any) => `Recommended settings for ${e.device}`,
|
||||||
(e: any) => `Configuració recomanada per a ${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}`,
|
||||||
(e: any) => `Rekomendasi pengaturan untuk ${e.device}`,
|
(e: any) => `Rekomendasi pengaturan untuk ${e.device}`,
|
||||||
(e: any) => `Ajustes recomendados para ${e.device}`,
|
(e: any) => `Ajustes recomendados para ${e.device}`,
|
||||||
@ -378,6 +382,7 @@ const Texts = {
|
|||||||
"touch-control-layout-by": [
|
"touch-control-layout-by": [
|
||||||
(e: any) => `Touch control layout by ${e.name}`,
|
(e: any) => `Touch control layout by ${e.name}`,
|
||||||
(e: any) => `Format del control tàctil per ${e.name}`,
|
(e: any) => `Format del control tàctil per ${e.name}`,
|
||||||
|
(e: any) => `Rozložení dotykového ovládání ${e.name}`,
|
||||||
(e: any) => `Touch-kontrol layout af ${e.name}`,
|
(e: any) => `Touch-kontrol layout af ${e.name}`,
|
||||||
(e: any) => `Touch-Steuerungslayout von ${e.name}`,
|
(e: any) => `Touch-Steuerungslayout von ${e.name}`,
|
||||||
(e: any) => `Tata letak Sentuhan layar oleh ${e.name}`,
|
(e: any) => `Tata letak Sentuhan layar oleh ${e.name}`,
|
||||||
|
@ -16,6 +16,15 @@ export function checkForUpdate() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always check for new version
|
||||||
|
fetch('https://api.github.com/repos/redphx/better-xcloud/releases/latest')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(json => {
|
||||||
|
// Store the latest version
|
||||||
|
setGlobalPref(GlobalPref.VERSION_LATEST, json.tag_name.substring(1), 'direct');
|
||||||
|
setGlobalPref(GlobalPref.VERSION_CURRENT, SCRIPT_VERSION, 'direct');
|
||||||
|
});
|
||||||
|
|
||||||
const CHECK_INTERVAL_SECONDS = 2 * 3600; // check every 2 hours
|
const CHECK_INTERVAL_SECONDS = 2 * 3600; // check every 2 hours
|
||||||
|
|
||||||
const currentVersion = getGlobalPref(GlobalPref.VERSION_CURRENT);
|
const currentVersion = getGlobalPref(GlobalPref.VERSION_CURRENT);
|
||||||
@ -28,13 +37,6 @@ export function checkForUpdate() {
|
|||||||
|
|
||||||
// Start checking
|
// Start checking
|
||||||
setGlobalPref(GlobalPref.VERSION_LAST_CHECK, now, 'direct');
|
setGlobalPref(GlobalPref.VERSION_LAST_CHECK, now, 'direct');
|
||||||
fetch('https://api.github.com/repos/redphx/better-xcloud/releases/latest')
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(json => {
|
|
||||||
// Store the latest version
|
|
||||||
setGlobalPref(GlobalPref.VERSION_LATEST, json.tag_name.substring(1), 'direct');
|
|
||||||
setGlobalPref(GlobalPref.VERSION_CURRENT, SCRIPT_VERSION, 'direct');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update translations
|
// Update translations
|
||||||
Translations.updateTranslations(currentVersion === SCRIPT_VERSION);
|
Translations.updateTranslations(currentVersion === SCRIPT_VERSION);
|
||||||
|
@ -95,7 +95,7 @@ export class XhomeInterceptor {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
TouchController.enable();
|
TouchController.enable();
|
||||||
TouchController.requestCustomLayouts(xboxTitleId);
|
TouchController.requestCustomLayouts();
|
||||||
}
|
}
|
||||||
|
|
||||||
response.json = () => Promise.resolve(obj);
|
response.json = () => Promise.resolve(obj);
|
||||||
|
Reference in New Issue
Block a user