mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-07-08 23:31:43 +02:00
Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
8ca6a9e08c | |||
344b6bb2c9 | |||
8b56ae218d | |||
3d2b887859 | |||
370fc7b2c2 | |||
5f4a1c24f0 | |||
382cd1aa51 | |||
d929a958ff | |||
a81c6621a8 | |||
edc11b3b48 | |||
c333fffab7 | |||
8c904897b8 | |||
683709f980 | |||
4562ef8f19 |
1
build.ts
1
build.ts
@ -27,6 +27,7 @@ const postProcess = (str: string): string => {
|
|||||||
|
|
||||||
// Remove enum's inlining comments
|
// Remove enum's inlining comments
|
||||||
str = str.replaceAll(/ \/\* [A-Z0-9_]+ \*\//g, '');
|
str = str.replaceAll(/ \/\* [A-Z0-9_]+ \*\//g, '');
|
||||||
|
str = str.replaceAll('/* @__PURE__ */ ', '');
|
||||||
|
|
||||||
// Remove comments from import
|
// Remove comments from import
|
||||||
str = str.replaceAll(/\/\/ src.*\n/g, '');
|
str = str.replaceAll(/\/\/ src.*\n/g, '');
|
||||||
|
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 5.5.3
|
// @version 5.5.5
|
||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
|
65
dist/better-xcloud.user.js
vendored
65
dist/better-xcloud.user.js
vendored
File diff suppressed because one or more lines are too long
@ -10,9 +10,9 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "^1.1.6",
|
"@types/bun": "^1.1.6",
|
||||||
"@types/node": "^20.14.12",
|
"@types/node": "^20.14.15",
|
||||||
"@types/stylus": "^0.48.42",
|
"@types/stylus": "^0.48.42",
|
||||||
"eslint": "^9.8.0",
|
"eslint": "^9.9.0",
|
||||||
"eslint-plugin-compat": "^6.0.0",
|
"eslint-plugin-compat": "^6.0.0",
|
||||||
"stylus": "^0.63.0"
|
"stylus": "^0.63.0"
|
||||||
},
|
},
|
||||||
|
@ -152,8 +152,8 @@
|
|||||||
bottom: offset;
|
bottom: offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
body[data-input-mode=Touch] &,
|
html[data-active-input=touch] &,
|
||||||
body[data-input-mode=Mouse] & {
|
html[data-active-input=mouse] & {
|
||||||
&:focus::after {
|
&:focus::after {
|
||||||
border-color: transparent !important;
|
border-color: transparent !important;
|
||||||
}
|
}
|
||||||
|
@ -245,10 +245,10 @@
|
|||||||
.bx-settings-row {
|
.bx-settings-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
border-bottom: 1px solid #2c2c2e;
|
padding: 16px 10px;
|
||||||
padding: 16px 8px;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border-left: 2px solid transparent;
|
background: #2a2a2a;
|
||||||
|
border-bottom: 1px solid #343434;
|
||||||
|
|
||||||
&:hover, &:focus-within {
|
&:hover, &:focus-within {
|
||||||
background-color: #242424;
|
background-color: #242424;
|
||||||
@ -265,9 +265,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
&:has(input:focus), &:has(select:focus), &:has(button:focus) {
|
&:has(input:focus), &:has(select:focus), &:has(button:focus) {
|
||||||
border-left-color: white;
|
border-left-color: white;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
> span.bx-settings-label {
|
> span.bx-settings-label {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@ -379,3 +381,26 @@
|
|||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
color: #828282;
|
color: #828282;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bx-settings-tab-contents {
|
||||||
|
> div {
|
||||||
|
// Label at the beginning
|
||||||
|
*:not(.bx-settings-row):has(+ .bx-settings-row) + .bx-settings-row:has(+ .bx-settings-row) {
|
||||||
|
border-top-left-radius: 10px;
|
||||||
|
border-top-right-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Label at the end
|
||||||
|
.bx-settings-row:not(:has(+ .bx-settings-row)) {
|
||||||
|
border: none;
|
||||||
|
border-bottom-left-radius: 10px;
|
||||||
|
border-bottom-right-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Single label
|
||||||
|
*:not(.bx-settings-row):has(+ .bx-settings-row) + .bx-settings-row:not(:has(+ .bx-settings-row)) {
|
||||||
|
border: none;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,12 +3,14 @@ import { t } from "@/utils/translation"
|
|||||||
export const BypassServers = {
|
export const BypassServers = {
|
||||||
'br': t('brazil'),
|
'br': t('brazil'),
|
||||||
'jp': t('japan'),
|
'jp': t('japan'),
|
||||||
|
'kr': t('korea'),
|
||||||
'pl': t('poland'),
|
'pl': t('poland'),
|
||||||
'us': t('united-states'),
|
'us': t('united-states'),
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BypassServerIps = {
|
export const BypassServerIps: Record<keyof typeof BypassServers, string> = {
|
||||||
'br': '169.150.198.66',
|
'br': '169.150.198.66',
|
||||||
|
'kr': '121.125.60.151',
|
||||||
'jp': '138.199.21.239',
|
'jp': '138.199.21.239',
|
||||||
'pl': '45.134.212.66',
|
'pl': '45.134.212.66',
|
||||||
'us': '143.244.47.65',
|
'us': '143.244.47.65',
|
||||||
|
@ -119,7 +119,7 @@ document.addEventListener('readystatechange', e => {
|
|||||||
getPref(PrefKey.REMOTE_PLAY_ENABLED) && RemotePlay.preload();
|
getPref(PrefKey.REMOTE_PLAY_ENABLED) && RemotePlay.preload();
|
||||||
} else {
|
} else {
|
||||||
// Show Settings button in the header when not signed in
|
// Show Settings button in the header when not signed in
|
||||||
HeaderSection.watchHeader();
|
window.setTimeout(HeaderSection.watchHeader, 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide "Play with Friends" skeleton section
|
// Hide "Play with Friends" skeleton section
|
||||||
@ -153,7 +153,7 @@ window.addEventListener(BxEvent.XCLOUD_SERVERS_UNAVAILABLE, e => {
|
|||||||
|
|
||||||
window.addEventListener(BxEvent.XCLOUD_SERVERS_READY, e => {
|
window.addEventListener(BxEvent.XCLOUD_SERVERS_READY, e => {
|
||||||
STATES.isSignedIn = true;
|
STATES.isSignedIn = true;
|
||||||
HeaderSection.watchHeader();
|
window.setTimeout(HeaderSection.watchHeader, 2000);
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener(BxEvent.STREAM_LOADING, e => {
|
window.addEventListener(BxEvent.STREAM_LOADING, e => {
|
||||||
|
@ -392,9 +392,11 @@ if (window.BX_EXPOSED.stopTakRendering) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let remotePlayCode = '';
|
let autoOffCode = '';
|
||||||
if (getPref(PrefKey.STREAM_TOUCH_CONTROLLER) !== 'off' && getPref(PrefKey.STREAM_TOUCH_CONTROLLER_AUTO_OFF)) {
|
if (getPref(PrefKey.STREAM_TOUCH_CONTROLLER) === 'off') {
|
||||||
remotePlayCode = `
|
autoOffCode = 'return;';
|
||||||
|
} else if (getPref(PrefKey.STREAM_TOUCH_CONTROLLER_AUTO_OFF)) {
|
||||||
|
autoOffCode = `
|
||||||
const gamepads = window.navigator.getGamepads();
|
const gamepads = window.navigator.getGamepads();
|
||||||
let gamepadFound = false;
|
let gamepadFound = false;
|
||||||
|
|
||||||
@ -412,13 +414,11 @@ if (gamepadFound) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const newCode = `
|
const newCode = `
|
||||||
if (!!window.BX_REMOTE_PLAY_CONFIG) {
|
${autoOffCode}
|
||||||
${remotePlayCode}
|
|
||||||
} else {
|
const titleInfo = window.BX_EXPOSED.getTitleInfo();
|
||||||
const titleInfo = window.BX_EXPOSED.getTitleInfo();
|
if (titleInfo && !titleInfo.details.hasTouchSupport && !titleInfo.details.hasFakeTouchSupport) {
|
||||||
if (titleInfo && !titleInfo.details.hasTouchSupport && !titleInfo.details.hasFakeTouchSupport) {
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ export class StreamUiHandler {
|
|||||||
$dotsButton.parentElement!.insertBefore($dotsButton, $dotsButton.parentElement!.firstElementChild);
|
$dotsButton.parentElement!.insertBefore($dotsButton, $dotsButton.parentElement!.firstElementChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static reset() {
|
static reset() {
|
||||||
StreamUiHandler.$btnStreamSettings = undefined;
|
StreamUiHandler.$btnStreamSettings = undefined;
|
||||||
StreamUiHandler.$btnStreamStats = undefined;
|
StreamUiHandler.$btnStreamStats = undefined;
|
||||||
StreamUiHandler.$btnRefresh = undefined;
|
StreamUiHandler.$btnRefresh = undefined;
|
||||||
@ -273,5 +273,6 @@ export class StreamUiHandler {
|
|||||||
});
|
});
|
||||||
|
|
||||||
observer.observe($screen, {subtree: true, childList: true});
|
observer.observe($screen, {subtree: true, childList: true});
|
||||||
|
StreamUiHandler.observer = observer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import { GamepadKey } from "@/enums/mkb";
|
|||||||
import { EmulatedMkbHandler } from "@/modules/mkb/mkb-handler";
|
import { EmulatedMkbHandler } from "@/modules/mkb/mkb-handler";
|
||||||
import { BxEvent } from "@/utils/bx-event";
|
import { BxEvent } from "@/utils/bx-event";
|
||||||
import { STATES } from "@/utils/global";
|
import { STATES } from "@/utils/global";
|
||||||
import { CE } from "@/utils/html";
|
import { CE, isElementVisible } from "@/utils/html";
|
||||||
import { setNearby } from "@/utils/navigation-utils";
|
import { setNearby } from "@/utils/navigation-utils";
|
||||||
|
|
||||||
export enum NavigationDirection {
|
export enum NavigationDirection {
|
||||||
@ -519,11 +519,8 @@ export class NavigationDialogManager {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rect = $elm.getBoundingClientRect();
|
|
||||||
const isVisible = !!rect.width && !!rect.height;
|
|
||||||
|
|
||||||
// Ignore hidden element
|
// Ignore hidden element
|
||||||
if (!isVisible) {
|
if (!isElementVisible($elm)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { SCRIPT_VERSION } from "@utils/global";
|
import { SCRIPT_VERSION } from "@utils/global";
|
||||||
import { createButton, ButtonStyle, CE } from "@utils/html";
|
import { createButton, ButtonStyle, CE, isElementVisible } from "@utils/html";
|
||||||
import { BxIcon } from "@utils/bx-icon";
|
import { BxIcon } from "@utils/bx-icon";
|
||||||
import { getPreferredServerRegion } from "@utils/region";
|
import { getPreferredServerRegion } from "@utils/region";
|
||||||
import { RemotePlay } from "@modules/remote-play";
|
import { RemotePlay } from "@modules/remote-play";
|
||||||
@ -44,12 +44,16 @@ export class HeaderSection {
|
|||||||
const PREF_LATEST_VERSION = getPref(PrefKey.LATEST_VERSION);
|
const PREF_LATEST_VERSION = getPref(PrefKey.LATEST_VERSION);
|
||||||
|
|
||||||
// Setup Settings button
|
// Setup Settings button
|
||||||
const $settingsBtn = HeaderSection.#$settingsBtn;
|
const $btnSettings = HeaderSection.#$settingsBtn;
|
||||||
$settingsBtn.querySelector('span')!.textContent = getPreferredServerRegion(true) || t('better-xcloud');
|
if (isElementVisible(HeaderSection.#$buttonsWrapper)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$btnSettings.querySelector('span')!.textContent = getPreferredServerRegion(true) || t('better-xcloud');
|
||||||
|
|
||||||
// Show new update status
|
// Show new update status
|
||||||
if (!SCRIPT_VERSION.includes('beta') && PREF_LATEST_VERSION && PREF_LATEST_VERSION !== SCRIPT_VERSION) {
|
if (!SCRIPT_VERSION.includes('beta') && PREF_LATEST_VERSION && PREF_LATEST_VERSION !== SCRIPT_VERSION) {
|
||||||
$settingsBtn.setAttribute('data-update-available', 'true');
|
$btnSettings.setAttribute('data-update-available', 'true');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the Settings button to the web page
|
// Add the Settings button to the web page
|
||||||
@ -75,6 +79,9 @@ export class HeaderSection {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HeaderSection.#timeout && clearTimeout(HeaderSection.#timeout);
|
||||||
|
HeaderSection.#timeout = null;
|
||||||
|
|
||||||
HeaderSection.#observer && HeaderSection.#observer.disconnect();
|
HeaderSection.#observer && HeaderSection.#observer.disconnect();
|
||||||
HeaderSection.#observer = new MutationObserver(mutationList => {
|
HeaderSection.#observer = new MutationObserver(mutationList => {
|
||||||
HeaderSection.#timeout && clearTimeout(HeaderSection.#timeout);
|
HeaderSection.#timeout && clearTimeout(HeaderSection.#timeout);
|
||||||
|
@ -128,6 +128,18 @@ export const BxExposed = {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dict = {
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true,
|
||||||
|
key: 'XF86Back',
|
||||||
|
code: 'XF86Back',
|
||||||
|
keyCode: 4,
|
||||||
|
which: 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
document.body.dispatchEvent(new KeyboardEvent('keydown', dict));
|
||||||
|
document.body.dispatchEvent(new KeyboardEvent('keyup', dict));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -146,5 +146,10 @@ export function escapeHtml(html: string): string {
|
|||||||
return $span.innerHTML;
|
return $span.innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isElementVisible($elm: HTMLElement): boolean {
|
||||||
|
const rect = $elm.getBoundingClientRect();
|
||||||
|
return !!rect.width && !!rect.height;
|
||||||
|
}
|
||||||
|
|
||||||
export const CTN = document.createTextNode.bind(document);
|
export const CTN = document.createTextNode.bind(document);
|
||||||
window.BX_CE = createElement;
|
window.BX_CE = createElement;
|
||||||
|
@ -129,6 +129,7 @@ const Texts = {
|
|||||||
"install-android": "Better xCloud app for Android",
|
"install-android": "Better xCloud app for Android",
|
||||||
"japan": "Japan",
|
"japan": "Japan",
|
||||||
"keyboard-shortcuts": "Keyboard shortcuts",
|
"keyboard-shortcuts": "Keyboard shortcuts",
|
||||||
|
"korea": "Korea",
|
||||||
"language": "Language",
|
"language": "Language",
|
||||||
"large": "Large",
|
"large": "Large",
|
||||||
"layout": "Layout",
|
"layout": "Layout",
|
||||||
|
Reference in New Issue
Block a user