Compare commits

...

11 Commits

Author SHA1 Message Date
fa19a5a68e Bump version to 5.8.5 2024-10-15 19:48:18 +07:00
3f834f74b6 Update "skipFeedbackDialog" patch 2024-10-15 16:49:38 +07:00
749d5d720e Update dist 2024-10-14 21:08:35 +07:00
b969d52a3c Show max FPS value in Stats bar 2024-10-14 21:06:52 +07:00
e5bd7e64a7 Refactor xCloud & xHome interceptors 2024-10-14 20:08:47 +07:00
82ee00b4ae Update dist 2024-10-14 17:17:32 +07:00
8e88af5f8c Set indent of built scripts to 1 space 2024-10-14 17:14:43 +07:00
927eae3f2f Refactor getInstance() methods 2024-10-14 16:56:05 +07:00
9f440e9cf4 Don't call animate() when hiding renderer 2024-10-14 16:47:03 +07:00
1acb30e3af Refactor Game Bar 2024-10-14 16:45:57 +07:00
34159fad22 Update better-xcloud.lite.user.js 2024-10-13 20:04:42 +07:00
31 changed files with 12805 additions and 12989 deletions

View File

@ -87,6 +87,15 @@ const postProcess = (str: string): string => {
return p1.toUpperCase();
});
// Replace " (e) =>" to " e =>"
// str = str.replaceAll(/ \(([^\s,.$()]+)\) =>/g, ' $1 =>');
// Set indent to 1 space
str = str.replaceAll(/\n(\s+)/g, (match, p1) => {
const len = p1.length / 2;
return '\n' + ' '.repeat(len);
});
assert(str.includes('/* ADDITIONAL CODE */'));
assert(str.includes('window.BX_EXPOSED = BxExposed'));
assert(str.includes('window.BxEvent = BxEvent'));

File diff suppressed because one or more lines are too long

View File

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

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,8 @@
import { BxEvent } from "@/utils/bx-event";
export abstract class BaseGameBarAction {
abstract $content: HTMLElement;
constructor() {}
reset() {}
@ -8,5 +10,7 @@ export abstract class BaseGameBarAction {
BxEvent.dispatch(window, BxEvent.GAME_BAR_ACTION_ACTIVATED);
};
abstract render(): HTMLElement;
render(): HTMLElement {
return this.$content;
};
}

View File

@ -8,8 +8,6 @@ import { MicrophoneShortcut, MicrophoneState } from "../shortcuts/shortcut-micro
export class MicrophoneAction extends BaseGameBarAction {
$content: HTMLElement;
visible: boolean = false;
constructor() {
super();
@ -26,12 +24,7 @@ export class MicrophoneAction extends BaseGameBarAction {
onClick: this.onClick.bind(this),
});
this.$content = CE('div', {},
$btnMuted,
$btnDefault,
);
this.reset();
this.$content = CE('div', {}, $btnMuted, $btnDefault);
window.addEventListener(BxEvent.MICROPHONE_STATE_CHANGED, e => {
const microphoneState = (e as any).microphoneState;
@ -49,12 +42,7 @@ export class MicrophoneAction extends BaseGameBarAction {
this.$content.dataset.activated = enabled.toString();
}
render(): HTMLElement {
return this.$content;
}
reset(): void {
this.visible = false;
this.$content.classList.add('bx-gone');
this.$content.dataset.activated = 'false';
}

View File

@ -23,12 +23,7 @@ export class RendererAction extends BaseGameBarAction {
classes: ['bx-activated'],
});
this.$content = CE('div', {},
$btnDefault,
$btnActivated,
);
this.reset();
this.$content = CE('div', {}, $btnDefault, $btnActivated);
}
onClick(e: Event) {
@ -37,10 +32,6 @@ export class RendererAction extends BaseGameBarAction {
this.$content.dataset.activated = (!isVisible).toString();
}
render(): HTMLElement {
return this.$content;
}
reset(): void {
this.$content.dataset.activated = 'false';
}

View File

@ -22,8 +22,4 @@ export class ScreenshotAction extends BaseGameBarAction {
super.onClick(e);
Screenshot.takeScreenshot();
}
render(): HTMLElement {
return this.$content;
}
}

View File

@ -24,12 +24,7 @@ export class SpeakerAction extends BaseGameBarAction {
classes: ['bx-activated'],
});
this.$content = CE('div', {},
$btnEnable,
$btnMuted,
);
this.reset();
this.$content = CE('div', {}, $btnEnable, $btnMuted);
window.addEventListener(BxEvent.SPEAKER_STATE_CHANGED, e => {
const speakerState = (e as any).speakerState;
@ -44,10 +39,6 @@ export class SpeakerAction extends BaseGameBarAction {
SoundShortcut.muteUnmute();
}
render(): HTMLElement {
return this.$content;
}
reset(): void {
this.$content.dataset.activated = 'false';
}

View File

@ -25,12 +25,7 @@ export class TouchControlAction extends BaseGameBarAction {
classes: ['bx-activated'],
});
this.$content = CE('div', {},
$btnEnable,
$btnDisable,
);
this.reset();
this.$content = CE('div', {}, $btnEnable, $btnDisable);
}
onClick(e: Event) {
@ -39,10 +34,6 @@ export class TouchControlAction extends BaseGameBarAction {
this.$content.dataset.activated = (!isVisible).toString();
}
render(): HTMLElement {
return this.$content;
}
reset(): void {
this.$content.dataset.activated = 'false';
}

View File

@ -1,6 +1,5 @@
import { BxIcon } from "@/utils/bx-icon";
import { createButton, ButtonStyle } from "@/utils/html";
import { t } from "@/utils/translation";
import { BaseGameBarAction } from "./action-base";
import { TrueAchievements } from "@/utils/true-achievements";
@ -13,7 +12,6 @@ export class TrueAchievementsAction extends BaseGameBarAction {
this.$content = createButton({
style: ButtonStyle.GHOST,
icon: BxIcon.TRUE_ACHIEVEMENTS,
title: t('true-achievements'),
onClick: this.onClick.bind(this),
});
}
@ -22,8 +20,4 @@ export class TrueAchievementsAction extends BaseGameBarAction {
super.onClick(e);
TrueAchievements.open(false);
}
render(): HTMLElement {
return this.$content;
}
}

View File

@ -7,7 +7,7 @@ import type { BaseGameBarAction } from "./action-base";
import { STATES } from "@utils/global";
import { MicrophoneAction } from "./action-microphone";
import { PrefKey } from "@/enums/pref-keys";
import { getPref, StreamTouchController } from "@/utils/settings-storages/global-settings-storage";
import { getPref, StreamTouchController, type GameBarPosition } from "@/utils/settings-storages/global-settings-storage";
import { TrueAchievementsAction } from "./action-true-achievements";
import { SpeakerAction } from "./action-speaker";
import { RendererAction } from "./action-renderer";
@ -15,13 +15,7 @@ import { RendererAction } from "./action-renderer";
export class GameBar {
private static instance: GameBar;
public static getInstance(): GameBar {
if (!GameBar.instance) {
GameBar.instance = new GameBar();
}
return GameBar.instance;
}
public static getInstance = () => GameBar.instance ?? (GameBar.instance = new GameBar());
private static readonly VISIBLE_DURATION = 2000;
@ -35,12 +29,12 @@ export class GameBar {
private constructor() {
let $container;
const position = getPref(PrefKey.GAME_BAR_POSITION);
const position = getPref(PrefKey.GAME_BAR_POSITION) as GameBarPosition;
const $gameBar = CE('div', {id: 'bx-game-bar', class: 'bx-gone', 'data-position': position},
$container = CE('div', {class: 'bx-game-bar-container bx-offscreen'}),
createSvgIcon(position === 'bottom-left' ? BxIcon.CARET_RIGHT : BxIcon.CARET_LEFT),
);
$container = CE('div', {class: 'bx-game-bar-container bx-offscreen'}),
createSvgIcon(position === 'bottom-left' ? BxIcon.CARET_RIGHT : BxIcon.CARET_LEFT),
);
this.actions = [
new ScreenshotAction(),
@ -78,11 +72,7 @@ export class GameBar {
// Add animation when hiding game bar
$container.addEventListener('transitionend', e => {
const classList = $container.classList;
if (classList.contains('bx-hide')) {
classList.remove('bx-hide');
classList.add('bx-offscreen');
}
$container.classList.replace('bx-hide', 'bx-offscreen');
});
document.documentElement.appendChild($gameBar);
@ -106,9 +96,9 @@ export class GameBar {
this.clearHideTimeout();
this.timeoutId = window.setTimeout(() => {
this.timeoutId = null;
this.hideBar();
}, GameBar.VISIBLE_DURATION);
this.timeoutId = null;
this.hideBar();
}, GameBar.VISIBLE_DURATION);
}
private clearHideTimeout() {
@ -117,19 +107,15 @@ export class GameBar {
}
enable() {
this.$gameBar && this.$gameBar.classList.remove('bx-gone');
this.$gameBar.classList.remove('bx-gone');
}
disable() {
this.hideBar();
this.$gameBar && this.$gameBar.classList.add('bx-gone');
this.$gameBar.classList.add('bx-gone');
}
showBar() {
if (!this.$container) {
return;
}
this.$container.classList.remove('bx-offscreen', 'bx-hide' , 'bx-gone');
this.$container.classList.add('bx-show');
@ -142,18 +128,11 @@ export class GameBar {
// Stop focusing Game Bar
clearFocus();
if (!this.$container) {
return;
}
this.$container.classList.remove('bx-show');
this.$container.classList.add('bx-hide');
this.$container.classList.replace('bx-show', 'bx-hide');
}
// Reset all states
reset() {
for (const action of this.actions) {
action.reset();
}
this.actions.forEach(action => action.reset());
}
}

View File

@ -124,14 +124,8 @@ This class uses some code from Yuzu emulator to handle mouse's movements
Source: https://github.com/yuzu-emu/yuzu-mainline/blob/master/src/input_common/drivers/mouse.cpp
*/
export class EmulatedMkbHandler extends MkbHandler {
static #instance: EmulatedMkbHandler;
public static getInstance(): EmulatedMkbHandler {
if (!EmulatedMkbHandler.#instance) {
EmulatedMkbHandler.#instance = new EmulatedMkbHandler();
}
return EmulatedMkbHandler.#instance;
}
private static instance: EmulatedMkbHandler;
public static getInstance = () => EmulatedMkbHandler.instance ?? (EmulatedMkbHandler.instance = new EmulatedMkbHandler());
#CURRENT_PRESET_DATA = MkbPreset.convert(MkbPreset.DEFAULT_PRESET);

View File

@ -23,6 +23,8 @@ type XcloudInputSink = {
export class NativeMkbHandler extends MkbHandler {
private static instance: NativeMkbHandler;
public static getInstance = () => NativeMkbHandler.instance ?? (NativeMkbHandler.instance = new NativeMkbHandler());
#pointerClient: PointerClient | undefined;
#enabled: boolean = false;
@ -37,14 +39,6 @@ export class NativeMkbHandler extends MkbHandler {
#$message?: HTMLElement;
public static getInstance(): NativeMkbHandler {
if (!NativeMkbHandler.instance) {
NativeMkbHandler.instance = new NativeMkbHandler();
}
return NativeMkbHandler.instance;
}
#onKeyboardEvent(e: KeyboardEvent) {
if (e.type === 'keyup' && e.code === 'F8') {
e.preventDefault();

View File

@ -15,13 +15,7 @@ enum PointerAction {
export class PointerClient {
private static instance: PointerClient;
public static getInstance(): PointerClient {
if (!PointerClient.instance) {
PointerClient.instance = new PointerClient();
}
return PointerClient.instance;
}
public static getInstance = () => PointerClient.instance ?? (PointerClient.instance = new PointerClient());
private socket: WebSocket | undefined | null;
private mkbHandler: MkbHandler | undefined;

View File

@ -632,12 +632,12 @@ true` + text;
},
skipFeedbackDialog(str: string) {
let text = '&&this.shouldTransitionToFeedback(';
let text = 'shouldTransitionToFeedback(e){';
if (!str.includes(text)) {
return false;
}
str = str.replace(text, '&& false ' + text);
str = str.replace(text, text + 'return !1;');
return str;
},

View File

@ -26,7 +26,7 @@ export class WebGL2Player {
};
private targetFps = 60;
private frameInterval = Math.ceil(1000 / this.targetFps);
private frameInterval = 0;
private lastFrameTime = 0;
private animFrameId: number | null = null;
@ -73,7 +73,8 @@ export class WebGL2Player {
setTargetFps(target: number) {
this.targetFps = target;
this.frameInterval = Math.ceil(1000 / target);
this.lastFrameTime = 0;
this.frameInterval = target ? Math.floor(1000 / target) : 0;
}
getCanvas() {
@ -94,6 +95,11 @@ export class WebGL2Player {
}
drawFrame() {
// Don't draw when FPS is 0
if (this.targetFps === 0) {
return;
}
// Limit FPS
if (this.targetFps < 60) {
const currentTime = performance.now();
@ -233,10 +239,10 @@ export class WebGL2Player {
const gl = this.gl;
if (gl) {
gl.getExtension('WEBGL_lose_context')?.loseContext();
gl.useProgram(null);
for (const resource of this.resources) {
if (resource instanceof WebGLProgram) {
gl.useProgram(null);
gl.deleteProgram(resource);
} else if (resource instanceof WebGLShader) {
gl.deleteShader(resource);

View File

@ -37,13 +37,7 @@ type RemotePlayConsole = {
export class RemotePlayManager {
private static instance: RemotePlayManager;
public static getInstance(): RemotePlayManager {
if (!this.instance) {
this.instance = new RemotePlayManager();
}
return this.instance;
}
public static getInstance = () => RemotePlayManager.instance ?? (RemotePlayManager.instance = new RemotePlayManager());
private isInitialized = false;

View File

@ -1,3 +1,7 @@
import { PrefKey } from "@/enums/pref-keys";
import { getPref } from "@/utils/settings-storages/global-settings-storage";
import { limitVideoPlayerFps } from "../stream/stream-settings-utils";
export class RendererShortcut {
static toggleVisibility(): boolean {
const $mediaContainer = document.querySelector('#game-stream div[data-testid="media-container"]');
@ -6,6 +10,9 @@ export class RendererShortcut {
}
$mediaContainer.classList.toggle('bx-gone');
return !$mediaContainer.classList.contains('bx-gone');
const isShowing = !$mediaContainer.classList.contains('bx-gone');
// Switch FPS
limitVideoPlayerFps(isShowing ? getPref(PrefKey.VIDEO_MAX_FPS) : 0);
return isShowing;
}
}

View File

@ -50,13 +50,7 @@ enum StreamBadge {
export class StreamBadges {
private static instance: StreamBadges;
public static getInstance(): StreamBadges {
if (!StreamBadges.instance) {
StreamBadges.instance = new StreamBadges();
}
return StreamBadges.instance;
}
public static getInstance = () => StreamBadges.instance ?? (StreamBadges.instance = new StreamBadges());
private serverInfo: StreamServerInfo = {};

View File

@ -45,8 +45,7 @@ export function onChangeVideoPlayerType() {
}
export function limitVideoPlayerFps() {
const targetFps = getPref(PrefKey.VIDEO_MAX_FPS);
export function limitVideoPlayerFps(targetFps: number) {
const streamPlayer = STATES.currentStream.streamPlayer;
streamPlayer?.getWebGL2Player()?.setTargetFps(targetFps);
}
@ -58,7 +57,7 @@ export function updateVideoPlayer() {
return;
}
limitVideoPlayerFps();
limitVideoPlayerFps(getPref(PrefKey.VIDEO_MAX_FPS));
const options = {
processing: getPref(PrefKey.VIDEO_PROCESSING),

View File

@ -9,13 +9,7 @@ import { StreamStat, StreamStatsCollector, type StreamStatGrade } from "@/utils/
export class StreamStats {
private static instance: StreamStats;
public static getInstance(): StreamStats {
if (!StreamStats.instance) {
StreamStats.instance = new StreamStats();
}
return StreamStats.instance;
}
public static getInstance = () => StreamStats.instance ?? (StreamStats.instance = new StreamStats());
private intervalId?: number | null;
private readonly REFRESH_INTERVAL = 1 * 1000;

View File

@ -88,12 +88,7 @@ export abstract class NavigationDialog {
export class NavigationDialogManager {
private static instance: NavigationDialogManager;
public static getInstance(): NavigationDialogManager {
if (!NavigationDialogManager.instance) {
NavigationDialogManager.instance = new NavigationDialogManager();
}
return NavigationDialogManager.instance;
}
public static getInstance = () => NavigationDialogManager.instance ?? (NavigationDialogManager.instance = new NavigationDialogManager());
private static readonly GAMEPAD_POLLING_INTERVAL = 50;
private static readonly GAMEPAD_KEYS = [

View File

@ -11,12 +11,7 @@ import { BxEvent } from "@/utils/bx-event";
export class RemotePlayNavigationDialog extends NavigationDialog {
private static instance: RemotePlayNavigationDialog;
public static getInstance(): RemotePlayNavigationDialog {
if (!RemotePlayNavigationDialog.instance) {
RemotePlayNavigationDialog.instance = new RemotePlayNavigationDialog();
}
return RemotePlayNavigationDialog.instance;
}
public static getInstance = () => RemotePlayNavigationDialog.instance ?? (RemotePlayNavigationDialog.instance = new RemotePlayNavigationDialog());
private readonly STATE_LABELS: Record<RemotePlayConsoleState, string> = {
[RemotePlayConsoleState.ON]: t('powered-on'),

View File

@ -64,12 +64,7 @@ type SettingTab = {
export class SettingsNavigationDialog extends NavigationDialog {
private static instance: SettingsNavigationDialog;
public static getInstance(): SettingsNavigationDialog {
if (!SettingsNavigationDialog.instance) {
SettingsNavigationDialog.instance = new SettingsNavigationDialog();
}
return SettingsNavigationDialog.instance;
}
public static getInstance = () => SettingsNavigationDialog.instance ?? (SettingsNavigationDialog.instance = new SettingsNavigationDialog());
$container!: HTMLElement;
private $tabs!: HTMLElement;
@ -409,7 +404,9 @@ export class SettingsNavigationDialog extends NavigationDialog {
onChange: onChangeVideoPlayerType,
}, {
pref: PrefKey.VIDEO_MAX_FPS,
onChange: limitVideoPlayerFps,
onChange: e => {
limitVideoPlayerFps(parseInt(e.target.value));
},
}, {
pref: PrefKey.VIDEO_POWER_PREFERENCE,
onChange: () => {

View File

@ -2,12 +2,7 @@ import { CE } from "@/utils/html";
export class FullscreenText {
private static instance: FullscreenText;
public static getInstance(): FullscreenText {
if (!FullscreenText.instance) {
FullscreenText.instance = new FullscreenText();
}
return FullscreenText.instance;
}
public static getInstance = () => FullscreenText.instance ?? (FullscreenText.instance = new FullscreenText());
$text: HTMLElement;

View File

@ -39,6 +39,10 @@ export const enum ControllerDeviceVibration {
}
export type GameBarPosition = 'bottom-left' | 'bottom-right' | 'off';
export type GameBarPositionOptions = Record<GameBarPosition, string>;
function getSupportedCodecProfiles() {
const options: PartialRecord<CodecProfile, string> = {
default: t('default'),
@ -323,12 +327,12 @@ export class GlobalSettingsStorage extends BaseSettingsStorage {
[PrefKey.GAME_BAR_POSITION]: {
requiredVariants: 'full',
label: t('position'),
default: 'bottom-left',
default: 'bottom-left' satisfies GameBarPosition,
options: {
'bottom-left': t('bottom-left'),
'bottom-right': t('bottom-right'),
'off': t('off'),
},
} satisfies GameBarPositionOptions,
},
[PrefKey.LOCAL_CO_OP_ENABLED]: {

View File

@ -1,6 +1,8 @@
import { PrefKey } from "@/enums/pref-keys";
import { BxEvent } from "./bx-event";
import { STATES } from "./global";
import { humanFileSize, secondsToHm } from "./html";
import { getPref } from "./settings-storages/global-settings-storage";
export enum StreamStat {
PING = 'ping',
@ -92,13 +94,7 @@ type CurrentStats = {
export class StreamStatsCollector {
private static instance: StreamStatsCollector;
public static getInstance(): StreamStatsCollector {
if (!StreamStatsCollector.instance) {
StreamStatsCollector.instance = new StreamStatsCollector();
}
return StreamStatsCollector.instance;
}
public static getInstance = () => StreamStatsCollector.instance ?? (StreamStatsCollector.instance = new StreamStatsCollector());
// Collect in background - 60 seconds
static readonly INTERVAL_BACKGROUND = 60 * 1000;
@ -127,7 +123,8 @@ export class StreamStatsCollector {
[StreamStat.FPS]: {
current: 0,
toString() {
return this.current.toString();
const maxFps = getPref(PrefKey.VIDEO_MAX_FPS);
return maxFps < 60 ? `${maxFps}/${this.current}` : this.current.toString();
},
},

View File

@ -3,13 +3,7 @@ import { STATES } from "./global";
export class XcloudApi {
private static instance: XcloudApi;
public static getInstance(): XcloudApi {
if (!XcloudApi.instance) {
XcloudApi.instance = new XcloudApi();
}
return XcloudApi.instance;
}
public static getInstance = () => XcloudApi.instance ?? (XcloudApi.instance = new XcloudApi());
private CACHE_TITLES: {[key: string]: XcloudTitleInfo} = {};
private CACHE_WAIT_TIME: {[key: string]: XcloudWaitTimeInfo} = {};

View File

@ -13,9 +13,25 @@ import { BypassServerIps } from "@/enums/bypass-servers";
import { PrefKey } from "@/enums/pref-keys";
import { getPref, StreamResolution, StreamTouchController } from "./settings-storages/global-settings-storage";
export
class XcloudInterceptor {
static async #handleLogin(request: RequestInfo | URL, init?: RequestInit) {
export class XcloudInterceptor {
private static readonly SERVER_EMOJIS = {
AustraliaEast: '🇦🇺',
AustraliaSouthEast: '🇦🇺',
BrazilSouth: '🇧🇷',
EastUS: '🇺🇸',
EastUS2: '🇺🇸',
JapanEast: '🇯🇵',
KoreaCentral: '🇰🇷',
MexicoCentral: '🇲🇽',
NorthCentralUs: '🇺🇸',
SouthCentralUS: '🇺🇸',
UKSouth: '🇬🇧',
WestEurope: '🇪🇺',
WestUS: '🇺🇸',
WestUS2: '🇺🇸',
};
private static async handleLogin(request: RequestInfo | URL, init?: RequestInit) {
const bypassServer = getPref(PrefKey.SERVER_BYPASS_RESTRICTION);
if (bypassServer !== 'off') {
const ip = BypassServerIps[bypassServer as keyof typeof BypassServerIps];
@ -35,24 +51,8 @@ class XcloudInterceptor {
RemotePlayManager.getInstance().xcloudToken = obj.gsToken;
// Get server list
const serverEmojis = {
AustraliaEast: '🇦🇺',
AustraliaSouthEast: '🇦🇺',
BrazilSouth: '🇧🇷',
EastUS: '🇺🇸',
EastUS2: '🇺🇸',
JapanEast: '🇯🇵',
KoreaCentral: '🇰🇷',
MexicoCentral: '🇲🇽',
NorthCentralUs: '🇺🇸',
SouthCentralUS: '🇺🇸',
UKSouth: '🇬🇧',
WestEurope: '🇪🇺',
WestUS: '🇺🇸',
WestUS2: '🇺🇸',
};
const serverRegex = /\/\/(\w+)\./;
const serverEmojis = XcloudInterceptor.SERVER_EMOJIS;
for (let region of obj.offeringSettings.regions) {
const regionName = region.name as keyof typeof serverEmojis;
@ -91,7 +91,7 @@ class XcloudInterceptor {
return response;
}
static async #handlePlay(request: RequestInfo | URL, init?: RequestInit) {
private static async handlePlay(request: RequestInfo | URL, init?: RequestInit) {
const PREF_STREAM_TARGET_RESOLUTION = getPref(PrefKey.STREAM_TARGET_RESOLUTION);
const PREF_STREAM_PREFERRED_LOCALE = getPref(PrefKey.STREAM_PREFERRED_LOCALE);
@ -129,7 +129,7 @@ class XcloudInterceptor {
return NATIVE_FETCH(newRequest);
}
static async #handleWaitTime(request: RequestInfo | URL, init?: RequestInit) {
private static async handleWaitTime(request: RequestInfo | URL, init?: RequestInit) {
const response = await NATIVE_FETCH(request, init);
if (getPref(PrefKey.UI_LOADING_SCREEN_WAIT_TIME)) {
@ -143,7 +143,7 @@ class XcloudInterceptor {
return response;
}
static async #handleConfiguration(request: RequestInfo | URL, init?: RequestInit) {
private static async handleConfiguration(request: RequestInfo | URL, init?: RequestInit) {
if ((request as Request).method !== 'GET') {
return NATIVE_FETCH(request, init);
}
@ -213,13 +213,13 @@ class XcloudInterceptor {
// Server list
if (url.endsWith('/v2/login/user')) {
return XcloudInterceptor.#handleLogin(request, init);
return XcloudInterceptor.handleLogin(request, init);
} else if (url.endsWith('/sessions/cloud/play')) { // Get session
return XcloudInterceptor.#handlePlay(request, init);
return XcloudInterceptor.handlePlay(request, init);
} else if (url.includes('xboxlive.com') && url.includes('/waittime/')) {
return XcloudInterceptor.#handleWaitTime(request, init);
return XcloudInterceptor.handleWaitTime(request, init);
} else if (url.endsWith('/configuration')) {
return XcloudInterceptor.#handleConfiguration(request, init);
return XcloudInterceptor.handleConfiguration(request, init);
} else if (url && url.endsWith('/ice') && url.includes('/sessions/') && (request as Request).method === 'GET') {
return patchIceCandidates(request as Request);
}

View File

@ -10,7 +10,7 @@ import type { RemotePlayConsoleAddresses } from "@/types/network";
import { RemotePlayManager } from "@/modules/remote-play-manager";
export class XhomeInterceptor {
static #consoleAddrs: RemotePlayConsoleAddresses = {};
private static consoleAddrs: RemotePlayConsoleAddresses = {};
private static readonly BASE_DEVICE_INFO = {
appInfo: {
@ -52,7 +52,7 @@ export class XhomeInterceptor {
},
};
static async #handleLogin(request: Request) {
private static async handleLogin(request: Request) {
try {
const clone = (request as Request).clone();
@ -74,7 +74,7 @@ export class XhomeInterceptor {
return NATIVE_FETCH(request);
}
static async #handleConfiguration(request: Request | URL) {
private static async handleConfiguration(request: Request | URL) {
const response = await NATIVE_FETCH(request);
const obj = await response.clone().json()
@ -90,15 +90,15 @@ export class XhomeInterceptor {
const serverDetails = obj.serverDetails;
if (serverDetails.ipAddress) {
XhomeInterceptor.#consoleAddrs[serverDetails.ipAddress] = processPorts(serverDetails.port);
XhomeInterceptor.consoleAddrs[serverDetails.ipAddress] = processPorts(serverDetails.port);
}
if (serverDetails.ipV4Address) {
XhomeInterceptor.#consoleAddrs[serverDetails.ipV4Address] = processPorts(serverDetails.ipV4Port);
XhomeInterceptor.consoleAddrs[serverDetails.ipV4Address] = processPorts(serverDetails.ipV4Port);
}
if (serverDetails.ipV6Address) {
XhomeInterceptor.#consoleAddrs[serverDetails.ipV6Address] = processPorts(serverDetails.ipV6Port);
XhomeInterceptor.consoleAddrs[serverDetails.ipV6Address] = processPorts(serverDetails.ipV6Port);
}
response.json = () => Promise.resolve(obj);
@ -107,7 +107,7 @@ export class XhomeInterceptor {
return response;
}
static async #handleInputConfigs(request: Request | URL, opts: {[index: string]: any}) {
private static async handleInputConfigs(request: Request | URL, opts: {[index: string]: any}) {
const response = await NATIVE_FETCH(request);
if (getPref(PrefKey.STREAM_TOUCH_CONTROLLER) !== StreamTouchController.ALL) {
@ -144,7 +144,7 @@ export class XhomeInterceptor {
return response;
}
static async #handleTitles(request: Request) {
private static async handleTitles(request: Request) {
const clone = request.clone();
const headers: {[index: string]: any} = {};
@ -163,7 +163,7 @@ export class XhomeInterceptor {
return NATIVE_FETCH(request);
}
static async #handlePlay(request: RequestInfo | URL) {
private static async handlePlay(request: RequestInfo | URL) {
const clone = (request as Request).clone();
const body = await clone.json();
@ -216,17 +216,17 @@ export class XhomeInterceptor {
// Get console IP
if (url.includes('/configuration')) {
return XhomeInterceptor.#handleConfiguration(request);
return XhomeInterceptor.handleConfiguration(request);
} else if (url.endsWith('/sessions/home/play')) {
return XhomeInterceptor.#handlePlay(request);
return XhomeInterceptor.handlePlay(request);
} else if (url.includes('inputconfigs')) {
return XhomeInterceptor.#handleInputConfigs(request, opts);
return XhomeInterceptor.handleInputConfigs(request, opts);
} else if (url.includes('/login/user')) {
return XhomeInterceptor.#handleLogin(request);
return XhomeInterceptor.handleLogin(request);
} else if (url.endsWith('/titles')) {
return XhomeInterceptor.#handleTitles(request);
return XhomeInterceptor.handleTitles(request);
} else if (url && url.endsWith('/ice') && url.includes('/sessions/') && (request as Request).method === 'GET') {
return patchIceCandidates(request, XhomeInterceptor.#consoleAddrs);
return patchIceCandidates(request, XhomeInterceptor.consoleAddrs);
}
return await NATIVE_FETCH(request);