Fix global vars

This commit is contained in:
redphx 2024-04-24 16:50:59 +07:00
parent 9446e39eb0
commit 9d0f4c380b
30 changed files with 87 additions and 69 deletions

View File

@ -14,10 +14,11 @@
// ==/UserScript==
'use strict';
import "./utils/global";
import { BxEvent } from "./modules/bx-event";
import { BX_FLAGS } from "./modules/bx-flags";
import { BxExposed } from "./modules/bx-exposed";
import { getLocale, t } from "./modules/translation";
import { t } from "./modules/translation";
import { CE } from "./utils/html";
import { showGamepadToast } from "./utils/gamepad";
import { MkbHandler } from "./modules/mkb/mkb-handler";
@ -26,7 +27,7 @@ import { StreamStats } from "./modules/stream/stream-stats";
import { addCss } from "./utils/css";
import { Toast } from "./utils/toast";
import { setupBxUi, updateVideoPlayerCss } from "./modules/ui/ui";
import { PrefKey, Preferences, getPref } from "./modules/preferences";
import { PrefKey, getPref } from "./modules/preferences";
import { LoadingScreen } from "./modules/loading-screen";
import { MouseCursorHider } from "./modules/mkb/mouse-cursor-hider";
import { TouchController } from "./modules/touch-controller";
@ -39,25 +40,7 @@ import { VibrationManager } from "./modules/vibration-manager";
import { PreloadedState } from "./utils/titles-info";
import { patchAudioContext, patchRtcCodecs, patchRtcPeerConnection, patchVideoApi } from "./utils/monkey-patches";
import { interceptHttpRequests } from "./utils/network";
globalThis.SCRIPT_VERSION = '3.5.3';
globalThis.SCRIPT_HOME = 'https://github.com/redphx/better-xcloud';
globalThis.NATIVE_FETCH = window.fetch;
globalThis.LOCALE = getLocale();
globalThis.AppInterface = window.AppInterface;
globalThis.States = {
isPlaying: false,
appContext: {},
serverRegions: {},
hasTouchSupport: ('ontouchstart' in window || navigator.maxTouchPoints > 0),
currentStream: {},
remotePlay: {},
};
import { States } from "./utils/global";
/* ADDITIONAL CODE */

View File

@ -1,3 +1,5 @@
import { AppInterface } from "../utils/global";
export enum BxEvent {
JUMP_BACK_IN_READY = 'bx-jump-back-in-ready',
POPSTATE = 'bx-popstate',

View File

@ -1,3 +1,5 @@
import { States } from "../utils/global";
export const BxExposed = {
onPollingModeChanged: (mode: 'All' | 'None') => {
if (!States.isPlaying) {

View File

@ -1,7 +1,7 @@
import { CE } from "../utils/html";
import { getPreferredServerRegion } from "../utils/region";
import { TitlesInfo } from "../utils/titles-info";
import { PrefKey, Preferences, getPref } from "./preferences";
import { PrefKey, getPref } from "./preferences";
import { t } from "./translation";
export class LoadingScreen {
@ -112,8 +112,6 @@ export class LoadingScreen {
endDateStr = endDateStr.substring(0, 10) + ' ' + endDateStr.substring(11, 19);
endDateStr += ` (${LoadingScreen.#secondsToString(waitTime)})`;
let estimatedWaitTime = LoadingScreen.#secondsToString(waitTime);
let $waitTimeBox = LoadingScreen.#$waitTimeBox;
if (!$waitTimeBox) {
$waitTimeBox = CE<HTMLElement>('div', {'class': 'bx-wait-time-box'},

View File

@ -126,7 +126,7 @@ export class MkbHandler {
const virtualGamepad = this.#getVirtualGamepad();
if (buttonIndex >= 100) {
let [valueArr, axisIndex, fullValue] = this.#STICK_MAP[buttonIndex];
let [valueArr, axisIndex] = this.#STICK_MAP[buttonIndex];
valueArr = valueArr as number[];
axisIndex = axisIndex as number;
@ -232,7 +232,6 @@ export class MkbHandler {
const analog = mouseMapTo === MouseMapTo.LS ? GamepadStick.LEFT : GamepadStick.RIGHT;
const virtualGamepad = this.#getVirtualGamepad();
let { x, y } = this.#getStickAxes(analog);
const length = this.#vectorLength(x, y);
@ -258,7 +257,7 @@ export class MkbHandler {
}
}
#onMouseStopped = (e: MouseEvent) => {
#onMouseStopped = () => {
this.#allowStickDecaying = true;
requestAnimationFrame(this.#decayStick);
}
@ -273,7 +272,7 @@ export class MkbHandler {
this.#allowStickDecaying = false;
this.#detectMouseStoppedTimeout && clearTimeout(this.#detectMouseStoppedTimeout);
this.#detectMouseStoppedTimeout = setTimeout(this.#onMouseStopped.bind(this, e), 100);
this.#detectMouseStoppedTimeout = setTimeout(this.#onMouseStopped.bind(this), 100);
const deltaX = e.movementX;
const deltaY = e.movementY;
@ -326,7 +325,7 @@ export class MkbHandler {
});
}
#onPointerLockChange = (e: Event) => {
#onPointerLockChange = () => {
if (this.#enabled && !document.pointerLockElement) {
this.stop();
this.#waitForPointerLock(true);
@ -458,7 +457,7 @@ export class MkbHandler {
}
static setupEvents() {
window.addEventListener(BxEvent.STREAM_PLAYING, e => {
window.addEventListener(BxEvent.STREAM_PLAYING, () => {
// Enable MKB
if (getPref(PrefKey.MKB_ENABLED)) {
console.log('Emulate MKB');

View File

@ -10,7 +10,7 @@ import { MkbHandler } from "./mkb-handler";
import { LocalDb } from "../../utils/local-db";
import { Icon } from "../../utils/html";
import { SettingElement } from "../settings";
import type { MkbConvertedPresetData, MkbPresetData, MkbStoredPresets } from "../../types/mkb";
import type { MkbPresetData, MkbStoredPresets } from "../../types/mkb";
type MkbRemapperElements = {

View File

@ -1,5 +1,6 @@
import { States } from "../utils/global";
import { BX_FLAGS } from "./bx-flags";
import { getPref, Preferences, PrefKey } from "./preferences";
import { getPref, PrefKey } from "./preferences";
import { VibrationManager } from "./vibration-manager";
const PATCHES = {
@ -492,7 +493,6 @@ export class Patcher {
static patch(item: any) {
// console.log('patch', '-----');
let patchName;
let appliedPatches;
for (let id in item[1]) {

View File

@ -3,7 +3,8 @@ import { t } from "./translation";
import { SettingElement, SettingElementType } from "./settings";
import { UserAgentProfile } from "../utils/user-agent";
import { StreamStat } from "./stream/stream-stats";
import type { PreferenceSetting, PreferenceSettings } from "../types/preferences";
import type { PreferenceSettings } from "../types/preferences";
import { States } from "../utils/global";
export enum PrefKey {
LAST_UPDATE_CHECK = 'version_last_check',

View File

@ -1,7 +1,8 @@
import { States, AppInterface } from "../utils/global";
import { CE, createButton, ButtonStyle, Icon } from "../utils/html";
import { Toast } from "../utils/toast";
import { BxEvent } from "./bx-event";
import { getPref, Preferences, PrefKey, setPref } from "./preferences";
import { getPref, PrefKey, setPref } from "./preferences";
import { t } from "./translation";
import { localRedirect } from "./ui/ui";
@ -82,7 +83,6 @@ export class RemotePlay {
};
static #$content: HTMLElement;
static #$consoles: HTMLElement;
static #initialize() {
if (RemotePlay.#$content) {

View File

@ -1,3 +1,4 @@
import { States, AppInterface } from "../utils/global";
import { CE } from "../utils/html";
export function takeScreenshot(callback: any) {

View File

@ -1,5 +1,5 @@
import type { PreferenceSetting } from "../types/preferences";
import { CE } from "../utils/html";
import type { PreferenceSetting } from "./preferences";
type MultipleOptionsParams = {
size?: number;
@ -53,8 +53,8 @@ export class SettingElement {
$control.setAttribute('size', params.size.toString());
}
for (let value in setting.multiple_options) {
const label = setting.multiple_options[value];
for (let value in setting.multipleOptions) {
const label = setting.multipleOptions[value];
const $option = CE<HTMLOptionElement>('option', {value: value}, label) as HTMLOptionElement;
$option.selected = currentValue.indexOf(value) > -1;

View File

@ -1,6 +1,7 @@
import { t } from "../translation";
import { BxEvent } from "../bx-event";
import { CE } from "../../utils/html";
import { States } from "../../utils/global";
enum StreamBadge {
PLAYTIME = 'playtime',
@ -85,7 +86,7 @@ export class StreamBadges {
} catch(e) {}
}
const stats = await STREAM_WEBRTC.getStats();
const stats = await States.currentStream.peerConnection?.getStats()!;
let totalIn = 0;
let totalOut = 0;
stats.forEach(stat => {

View File

@ -1,9 +1,10 @@
import { PrefKey, Preferences } from "../preferences"
import { PrefKey } from "../preferences"
import { BxEvent } from "../bx-event"
import { getPref } from "../preferences"
import { StreamBadges } from "./stream-badges"
import { CE } from "../../utils/html"
import { t } from "../translation"
import { States } from "../../utils/global"
export enum StreamStat {
PING = 'ping',
@ -105,13 +106,13 @@ export class StreamStats {
}
static update() {
if (StreamStats.isHidden() || !STREAM_WEBRTC) {
if (StreamStats.isHidden() || !States.currentStream.peerConnection) {
StreamStats.onStoppedPlaying();
return;
}
const PREF_STATS_CONDITIONAL_FORMATTING = getPref(PrefKey.STATS_CONDITIONAL_FORMATTING);
STREAM_WEBRTC.getStats().then(stats => {
States.currentStream.peerConnection.getStats().then(stats => {
stats.forEach(stat => {
let grade = '';
if (stat.type === 'inbound-rtp' && stat.kind === 'video') {
@ -213,7 +214,7 @@ export class StreamStats {
}
static getServerStats() {
STREAM_WEBRTC && STREAM_WEBRTC.getStats().then(stats => {
States.currentStream.peerConnection && States.currentStream.peerConnection.getStats().then(stats => {
const allVideoCodecs: {[index: string]: RTCBasicStat} = {};
let videoCodecId;

View File

@ -1,3 +1,4 @@
import { States } from "../../utils/global";
import { Icon } from "../../utils/html";
import { BxEvent } from "../bx-event";
import { PrefKey, getPref } from "../preferences";
@ -44,6 +45,7 @@ class MouseHoldEvent {
this.#$elm.addEventListener('touchend', this.#onMouseUp.bind(this));
}
/*
#clearEventLiseners = () => {
this.#$elm.removeEventListener('mousedown', this.#onMouseDown);
this.#$elm.removeEventListener('click', this.#onMouseUp);
@ -51,6 +53,7 @@ class MouseHoldEvent {
this.#$elm.removeEventListener('touchstart', this.#onMouseDown);
this.#$elm.removeEventListener('touchend', this.#onMouseUp);
}
*/
constructor($elm: HTMLElement, callback: any, duration=1000) {
this.#$elm = $elm;

View File

@ -1,8 +1,9 @@
import { NATIVE_FETCH, States } from "../utils/global";
import { CE } from "../utils/html";
import { Toast } from "../utils/toast";
import { BxEvent } from "./bx-event";
import { BX_FLAGS } from "./bx-flags";
import { getPref, Preferences, PrefKey } from "./preferences";
import { getPref, PrefKey } from "./preferences";
import { t } from "./translation";
export class TouchController {
@ -11,10 +12,12 @@ export class TouchController {
origin: 'better-xcloud',
});
/*
static readonly #EVENT_HIDE_CONTROLLER = new MessageEvent('message', {
data: '{"content":"","target":"/streaming/touchcontrols/hide","type":"Message"}',
origin: 'better-xcloud',
});
*/
static #$bar: HTMLElement;
static #$style: HTMLStyleElement;

View File

@ -1,3 +1,5 @@
import { LOCALE } from "../utils/global";
const Translations = {
enUS: -1,

View File

@ -1,8 +1,9 @@
import { States, AppInterface, SCRIPT_HOME, SCRIPT_VERSION } from "../../utils/global";
import { CE, createButton, Icon, ButtonStyle } from "../../utils/html";
import { getPreferredServerRegion } from "../../utils/region";
import { UserAgent, UserAgentProfile } from "../../utils/user-agent";
import { getPref, Preferences, PrefKey, setPref, toPrefElement } from "../preferences";
import { getLocale, t } from "../translation";
import { t } from "../translation";
const SETTINGS_UI = {
'Better xCloud': {
@ -159,7 +160,7 @@ export function setupSettingsUi() {
if ((e.target as HTMLElement).id === 'bx_setting_' + PrefKey.BETTER_XCLOUD_LOCALE) {
// Update locale
LOCALE = getLocale();
refreshLocale();
const $btn = $reloadBtnWrapper.firstElementChild! as HTMLButtonElement;
$btn.textContent = t('settings-reloading');
@ -345,3 +346,6 @@ export function setupSettingsUi() {
const $pageContent = document.getElementById('PageContent');
$pageContent?.parentNode?.insertBefore($container, $pageContent);
}
function refreshLocale() {
throw new Error("Function not implemented.");
}

View File

@ -1,3 +1,4 @@
import { SCRIPT_VERSION } from "../../utils/global";
import { createButton, Icon, ButtonStyle } from "../../utils/html";
import { getPreferredServerRegion } from "../../utils/region";
import { PrefKey, getPref } from "../preferences";

View File

@ -1,8 +1,9 @@
import { States } from "../../utils/global";
import { Icon, CE, createButton, ButtonStyle } from "../../utils/html";
import { UserAgent } from "../../utils/user-agent";
import { BxEvent } from "../bx-event";
import { MkbRemapper } from "../mkb/mkb-remapper";
import { getPref, Preferences, PrefKey, toPrefElement } from "../preferences";
import { getPref, PrefKey, toPrefElement } from "../preferences";
import { setupScreenshotButton } from "../screenshot";
import { StreamStats } from "../stream/stream-stats";
import { TouchController } from "../touch-controller";

View File

@ -1,3 +1,4 @@
import { AppInterface } from "../utils/global";
import { BxEvent } from "./bx-event";
import { PrefKey, getPref } from "./preferences";

View File

@ -50,12 +50,3 @@ type BxStates = {
}
type DualEnum = {[index: string]: number} & {[index: number]: string};
declare var SCRIPT_VERSION: string;
declare var window: Window & typeof globalThis;
declare var AppInterface: any;
declare var STREAM_WEBRTC: RTCPeerConnection;
declare var States: BxStates;
declare var NATIVE_FETCH: typeof window.fetch;
declare var SCRIPT_HOME: string;
declare var LOCALE: number;

View File

@ -1,7 +1,7 @@
export type PreferenceSetting = {
default: any;
options?: {[index: string]: string};
multiplOptions?: {[index: string]: string};
multipleOptions?: {[index: string]: string};
unsupported?: string | boolean;
note?: string | HTMLElement;
type?: SettingElementType;

View File

@ -1,5 +1,5 @@
import { CE, Icon } from "./html";
import { Preferences, getPref } from "../modules/preferences";
import { PrefKey, getPref } from "../modules/preferences";
export function addCss() {
@ -1273,7 +1273,7 @@ div[class*=NotFocusedDialog] {
`;
// Hide "Play with friends" section
if (getPref(Preferences.BLOCK_SOCIAL_FEATURES)) {
if (getPref(PrefKey.BLOCK_SOCIAL_FEATURES)) {
css += `
div[class^=HomePage-module__bottomSpacing]:has(button[class*=SocialEmptyCard]),
button[class*=SocialEmptyCard] {
@ -1283,7 +1283,7 @@ button[class*=SocialEmptyCard] {
}
// Reduce animations
if (getPref(Preferences.REDUCE_ANIMATIONS)) {
if (getPref(PrefKey.REDUCE_ANIMATIONS)) {
css += `
div[class*=GameCard-module__gameTitleInnerWrapper],
div[class*=GameCard-module__card],
@ -1294,7 +1294,7 @@ div[class*=ScrollArrows-module] {
}
// Hide the top-left dots icon while playing
if (getPref(Preferences.HIDE_DOTS_ICON)) {
if (getPref(PrefKey.HIDE_DOTS_ICON)) {
css += `
div[class*=Grip-module__container] {
visibility: hidden;
@ -1326,7 +1326,7 @@ div[class*=StreamMenu-module__menu] {
min-width: 100vw !important;
}
`;
if (getPref(Preferences.STREAM_SIMPLIFY_MENU)) {
if (getPref(PrefKey.STREAM_SIMPLIFY_MENU)) {
css += `
div[class*=Menu-module__scrollable] {
--bxStreamMenuItemSize: 80px;
@ -1386,7 +1386,7 @@ body:not([data-media-type=tv]) div[class*=MenuItem-module__label] {
}
// Hide scrollbar
if (getPref(Preferences.UI_SCROLLBAR_HIDE)) {
if (getPref(PrefKey.UI_SCROLLBAR_HIDE)) {
css += `
html {
scrollbar-width: none;

22
src/utils/global.ts Normal file
View File

@ -0,0 +1,22 @@
import { getLocale } from "../modules/translation";
export const AppInterface = window.AppInterface;
export const NATIVE_FETCH = window.fetch;
export const States: BxStates = {
isPlaying: false,
appContext: {},
serverRegions: {},
hasTouchSupport: ('ontouchstart' in window || navigator.maxTouchPoints > 0),
currentStream: {},
remotePlay: {},
};
export const SCRIPT_VERSION = '3.5.3';
export const SCRIPT_HOME = 'https://github.com/redphx/better-xcloud';
export var LOCALE = getLocale();
export const refreshLocale = () => {
LOCALE = getLocale();
}

View File

@ -1,5 +1,6 @@
import { BxEvent } from "../modules/bx-event";
import { getPref, PrefKey } from "../modules/preferences";
import { States } from "./global";
import { UserAgent } from "./user-agent";
export function patchVideoApi() {

View File

@ -1,11 +1,11 @@
import { BxEvent } from "../modules/bx-event";
import { BX_FLAGS } from "../modules/bx-flags";
import { LoadingScreen } from "../modules/loading-screen";
import { MouseCursorHider } from "../modules/mkb/mouse-cursor-hider";
import { PrefKey, getPref } from "../modules/preferences";
import { RemotePlay } from "../modules/remote-play";
import { StreamBadges } from "../modules/stream/stream-badges";
import { TouchController } from "../modules/touch-controller";
import { NATIVE_FETCH, States } from "./global";
import { getPreferredServerRegion } from "./region";
import { TitlesInfo } from "./titles-info";
@ -549,8 +549,6 @@ export function interceptHttpRequests() {
return nativeXhrSend.apply(this, arguments);
};
const PREF_UI_LOADING_SCREEN_GAME_ART = getPref(PrefKey.UI_LOADING_SCREEN_GAME_ART);
window.fetch = async (request: RequestInfo | URL, init?: RequestInit): Promise<Response> => {
let url = (typeof request === 'string') ? request : (request as Request).url;

View File

@ -1,4 +1,5 @@
import { getPref, Preferences, PrefKey } from "../modules/preferences";
import { getPref, PrefKey } from "../modules/preferences";
import { States } from "./global";
export function getPreferredServerRegion(shortName = false) {

View File

@ -1,5 +1,6 @@
import { PrefKey } from "../modules/preferences";
import { getPref } from "../modules/preferences";
import { States } from "./global";
import { UserAgent } from "./user-agent";
export class TitlesInfo {

View File

@ -1,4 +1,4 @@
import { PrefKey, Preferences, getPref } from "../modules/preferences";
import { PrefKey, getPref } from "../modules/preferences";
export enum UserAgentProfile {
EDGE_WINDOWS = 'edge-windows',

View File

@ -1,4 +1,5 @@
import { PrefKey, getPref, setPref } from "../modules/preferences";
import { SCRIPT_VERSION } from "./global";
import { UserAgent } from "./user-agent";
export function checkForUpdate() {