From 2e0a59cbe1695a58569c4df919f521b2edce876d Mon Sep 17 00:00:00 2001 From: redphx <96280+redphx@users.noreply.github.com> Date: Sun, 2 Jun 2024 10:43:59 +0700 Subject: [PATCH] Add back the ability to use native MKB feature on unofficial titles --- scripts/custom-flags.user.js | 39 +++++++++++++++++++++++++++++++++++ src/utils/bx-exposed.ts | 3 +++ src/utils/bx-flags.ts | 20 +++++++++++------- src/utils/gamepass-gallery.ts | 3 ++- src/utils/network.ts | 31 ++++++++++++++++++++++++---- src/utils/preload-state.ts | 7 +++++++ 6 files changed, 90 insertions(+), 13 deletions(-) create mode 100644 scripts/custom-flags.user.js diff --git a/scripts/custom-flags.user.js b/scripts/custom-flags.user.js new file mode 100644 index 0000000..6f0d1a9 --- /dev/null +++ b/scripts/custom-flags.user.js @@ -0,0 +1,39 @@ +// ==UserScript== +// @name Better xCloud - Custom flags +// @namespace https://github.com/redphx +// @version 1.0.0 +// @description Customize Better xCloud script +// @author redphx +// @license MIT +// @match https://www.xbox.com/*/play* +// @run-at document-start +// @grant none +// ==/UserScript== +'use strict'; + +/* +Make sure this script is being loaded before the Better xCloud script. + +How to: +1. Uninstall Better xCloud script. +2. Install this script. +3. Reinstall Better xCloud script. All your settings are still there. +*/ + +// Change this to `false` if you want to temporary disable the script +const enabled = true; + +enabled && (window.BX_FLAGS = { + /* + Add titleId of the game(s) you want to add here + For example: + - Flight Simulator has this link: /play/games/microsoft-flight-simulator-standard-40th-anniversa/9PMQDM08SNK9 + - That means its titleId is "9PMQDM08SNK9" + - So it becomes: + ForceNativeMkbTitles: [ + "9PMQDM08SNK9", + ], + */ + ForceNativeMkbTitles: [ + ], +}); diff --git a/src/utils/bx-exposed.ts b/src/utils/bx-exposed.ts index dd4b767..bd07007 100644 --- a/src/utils/bx-exposed.ts +++ b/src/utils/bx-exposed.ts @@ -4,6 +4,7 @@ import { STATES } from "@utils/global"; import { getPref, PrefKey } from "@utils/preferences"; import { UserAgent } from "@utils/user-agent"; import { BxLogger } from "./bx-logger"; +import { BX_FLAGS } from "./bx-flags"; export enum InputType { CONTROLLER = 'Controller', @@ -26,6 +27,8 @@ export const BxExposed = { // Remove native MKB support on mobile browsers or by user's choice if (getPref(PrefKey.NATIVE_MKB_DISABLED) || UserAgent.isMobile()) { supportedInputTypes = supportedInputTypes.filter(i => i !== InputType.MKB); + } else if (BX_FLAGS.ForceNativeMkbTitles.includes(titleInfo.details.productId)) { + supportedInputTypes.push(InputType.MKB); } titleInfo.details.hasMkbSupport = supportedInputTypes.includes(InputType.MKB); diff --git a/src/utils/bx-flags.ts b/src/utils/bx-flags.ts index 9c0710e..cab900d 100644 --- a/src/utils/bx-flags.ts +++ b/src/utils/bx-flags.ts @@ -1,12 +1,14 @@ -type BxFlags = { - CheckForUpdate?: boolean; - PreloadRemotePlay?: boolean; - PreloadUi?: boolean; - EnableXcloudLogging?: boolean; - SafariWorkaround?: boolean; +type BxFlags = Partial<{ + CheckForUpdate: boolean; + PreloadRemotePlay: boolean; + PreloadUi: boolean; + EnableXcloudLogging: boolean; + SafariWorkaround: boolean; - UseDevTouchLayout?: boolean; -} + UseDevTouchLayout: boolean; + + ForceNativeMkbTitles: string[]; +}> // Setup flags const DEFAULT_FLAGS: BxFlags = { @@ -17,6 +19,8 @@ const DEFAULT_FLAGS: BxFlags = { SafariWorkaround: true, UseDevTouchLayout: false, + + ForceNativeMkbTitles: [], } export const BX_FLAGS = Object.assign(DEFAULT_FLAGS, window.BX_FLAGS || {}); diff --git a/src/utils/gamepass-gallery.ts b/src/utils/gamepass-gallery.ts index c657b74..3a9dcbe 100644 --- a/src/utils/gamepass-gallery.ts +++ b/src/utils/gamepass-gallery.ts @@ -1,4 +1,5 @@ export enum GamePassCloudGallery { - TOUCH = '9c86f07a-f3e8-45ad-82a0-a1f759597059', ALL = '29a81209-df6f-41fd-a528-2ae6b91f719c', + NATIVE_MKB = '8fa264dd-124f-4af3-97e8-596fcdf4b486', + TOUCH = '9c86f07a-f3e8-45ad-82a0-a1f759597059', } diff --git a/src/utils/network.ts b/src/utils/network.ts index 542e3a7..998a670 100644 --- a/src/utils/network.ts +++ b/src/utils/network.ts @@ -439,12 +439,20 @@ class XcloudInterceptor { overrides.inputConfiguration = overrides.inputConfiguration || {}; overrides.inputConfiguration.enableVibration = true; + let overrideMkb: boolean | null = null; + if (getPref(PrefKey.NATIVE_MKB_DISABLED) || UserAgent.isMobile()) { + overrideMkb = false; + } else if (BX_FLAGS.ForceNativeMkbTitles.includes(STATES.currentStream.titleInfo!.details.productId)) { + overrideMkb = true; + } + + if (overrideMkb !== null) { overrides.inputConfiguration = Object.assign(overrides.inputConfiguration, { - enableMouseInput: false, - enableAbsoluteMouse: false, - enableKeyboardInput: false, - }); + enableMouseInput: overrideMkb, + enableAbsoluteMouse: overrideMkb, + enableKeyboardInput: overrideMkb, + }); } overrides.videoConfiguration = overrides.videoConfiguration || {}; @@ -614,6 +622,21 @@ export function interceptHttpRequests() { return response; } + if (BX_FLAGS.ForceNativeMkbTitles && url.includes('catalog.gamepass.com/sigls/') && url.includes(GamePassCloudGallery.NATIVE_MKB)) { + const response = await NATIVE_FETCH(request, init); + const obj = await response.clone().json(); + + try { + const newCustomList = BX_FLAGS.ForceNativeMkbTitles.map((item: string) => ({ id: item })); + obj.push(...newCustomList); + } catch (e) { + console.log(e); + } + + response.json = () => Promise.resolve(obj); + return response; + } + let requestType: RequestType; if (url.includes('/sessions/home') || url.includes('xhome.') || (STATES.remotePlay.isPlaying && url.endsWith('/inputconfigs'))) { requestType = RequestType.XHOME; diff --git a/src/utils/preload-state.ts b/src/utils/preload-state.ts index 48b35de..56a7915 100644 --- a/src/utils/preload-state.ts +++ b/src/utils/preload-state.ts @@ -3,6 +3,7 @@ import { BxLogger } from "./bx-logger"; import { TouchController } from "@modules/touch-controller"; import { GamePassCloudGallery } from "./gamepass-gallery"; import { getPref, PrefKey } from "./preferences"; +import { BX_FLAGS } from "./bx-flags"; const LOG_TAG = 'PreloadState'; @@ -37,6 +38,12 @@ export function overridePreloadState() { // Add to the official list sigls[GamePassCloudGallery.TOUCH]?.data.products.push(...customList); } + + if (BX_FLAGS.ForceNativeMkbTitles && GamePassCloudGallery.NATIVE_MKB in sigls) { + // Add to the official list + sigls[GamePassCloudGallery.NATIVE_MKB]?.data.products.push(...BX_FLAGS.ForceNativeMkbTitles); + } + } catch (e) { BxLogger.error(LOG_TAG, e); }