Show touch icon on games with custom layouts

This commit is contained in:
redphx 2024-05-07 21:40:12 +07:00
parent fc56d486a7
commit c948b63b8d
6 changed files with 78 additions and 28 deletions

View File

@ -22,7 +22,7 @@ import { Patcher } from "@modules/patcher";
import { RemotePlay } from "@modules/remote-play";
import { onHistoryChanged, patchHistoryMethod } from "@utils/history";
import { VibrationManager } from "@modules/vibration-manager";
import { PreloadedState } from "@utils/titles-info";
import { overridePreloadState } from "@utils/preload-state";
import { patchAudioContext, patchCanvasContext, patchMeControl, patchRtcCodecs, patchRtcPeerConnection, patchVideoApi } from "@utils/monkey-patches";
import { STATES } from "@utils/global";
import { injectStreamMenuButtons } from "@modules/stream/stream-ui";
@ -220,7 +220,7 @@ function main() {
getPref(PrefKey.AUDIO_ENABLE_VOLUME_CONTROL) && patchAudioContext();
getPref(PrefKey.BLOCK_TRACKING) && patchMeControl();
PreloadedState.override();
overridePreloadState();
VibrationManager.initialSetup();

View File

@ -3,7 +3,7 @@ import { BX_FLAGS } from "@utils/bx-flags";
import { getPref, PrefKey } from "@utils/preferences";
import { VibrationManager } from "@modules/vibration-manager";
import { BxLogger } from "@utils/bx-logger";
import { hashCode } from "@/utils/utils";
import { hashCode } from "@utils/utils";
type PatchArray = (keyof typeof PATCHES)[];

View File

@ -10,6 +10,8 @@ import { BxLogger } from "@utils/bx-logger";
const LOG_TAG = 'TouchController';
export const GALLERY_TOUCH_GAMES = '9c86f07a-f3e8-45ad-82a0-a1f759597059';
export class TouchController {
static readonly #EVENT_SHOW_DEFAULT_CONTROLLER = new MessageEvent('message', {
data: '{"content":"{\\"layoutId\\":\\"\\"}","target":"/streaming/touchcontrols/showlayoutv2","type":"Message"}',
@ -184,6 +186,18 @@ export class TouchController {
}, delay);
}
static updateCustomList() {
NATIVE_FETCH('https://raw.githubusercontent.com/redphx/better-xcloud/gh-pages/touch-layouts/ids.json')
.then(response => response.json())
.then(json => {
window.localStorage.setItem('better_xcloud_custom_touch_layouts', JSON.stringify(json));
});
}
static getCustomList(): string[] {
return JSON.parse(window.localStorage.getItem('better_xcloud_custom_touch_layouts') || '[]');
}
static setup() {
// Function for testing touch control
window.BX_EXPOSED.test_touch_control = (layout: any) => {

View File

@ -4,7 +4,7 @@ import { LoadingScreen } from "@modules/loading-screen";
import { PrefKey, getPref } from "@utils/preferences";
import { RemotePlay } from "@modules/remote-play";
import { StreamBadges } from "@modules/stream/stream-badges";
import { TouchController } from "@modules/touch-controller";
import { GALLERY_TOUCH_GAMES, TouchController } from "@modules/touch-controller";
import { STATES } from "@utils/global";
import { getPreferredServerRegion } from "@utils/region";
@ -549,6 +549,20 @@ export function interceptHttpRequests() {
BxEvent.dispatch(window, BxEvent.STREAM_STARTING);
}
// Add list of games with custom layouts to the official list
if (url.includes('catalog.gamepass.com') && url.includes(GALLERY_TOUCH_GAMES)) {
const response = await NATIVE_FETCH(request, init);
const obj = await response.clone().json();
try {
const customList = TouchController.getCustomList().map(item => ({ id: item }));
obj.push(...customList);
} catch (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;

View File

@ -0,0 +1,46 @@
import { STATES } from "@utils/global";
import { UserAgent } from "@utils/user-agent";
import { BxLogger } from "./bx-logger";
import { GALLERY_TOUCH_GAMES, TouchController } from "@modules/touch-controller";
const LOG_TAG = 'PreloadState';
export function overridePreloadState() {
let _state: any;
Object.defineProperty(window, '__PRELOADED_STATE__', {
configurable: true,
get: () => {
// @ts-ignore
return _state;
},
set: state => {
// Override User-Agent
const userAgent = UserAgent.spoof();
if (userAgent) {
try {
// @ts-ignore
state.appContext.requestInfo.userAgent = userAgent;
} catch (e) {
BxLogger.error(LOG_TAG, e);
}
}
// Add list of games with custom layouts to the official list
if (STATES.hasTouchSupport) {
TouchController.updateCustomList();
const customList = TouchController.getCustomList();
try {
state.xcloud.sigls[GALLERY_TOUCH_GAMES]?.data.products.push(...customList);
} catch (e) {
BxLogger.error(LOG_TAG, e);
}
}
// @ts-ignore
_state = state;
STATES.appContext = structuredClone(state.appContext);
}
});
}

View File

@ -1,24 +0,0 @@
import { STATES } from "@utils/global";
import { UserAgent } from "@utils/user-agent";
export class PreloadedState {
static override() {
Object.defineProperty(window, '__PRELOADED_STATE__', {
configurable: true,
get: () => {
// Override User-Agent
const userAgent = UserAgent.spoof();
if (userAgent) {
(this as any)._state.appContext.requestInfo.userAgent = userAgent;
}
return (this as any)._state;
},
set: state => {
(this as any)._state = state;
STATES.appContext = structuredClone(state.appContext);
}
});
}
}