mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-06-30 19:31:44 +02:00
Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
adf689d61d | |||
086385fbfb | |||
705446ffb9 | |||
e366cb73e4 | |||
d148fc708e | |||
f75e22b5f6 | |||
0f7ac4c372 | |||
a4874c76db | |||
397b3baa9b | |||
0330d0d811 | |||
f8e035d98f | |||
1e7bc366ca |
@ -1,5 +1,5 @@
|
||||
// ==UserScript==
|
||||
// @name Better xCloud
|
||||
// @namespace https://github.com/redphx
|
||||
// @version 3.2.2
|
||||
// @version 3.2.3
|
||||
// ==/UserScript==
|
||||
|
@ -1,7 +1,7 @@
|
||||
// ==UserScript==
|
||||
// @name Better xCloud
|
||||
// @namespace https://github.com/redphx
|
||||
// @version 3.2.2
|
||||
// @version 3.2.3
|
||||
// @description Improve Xbox Cloud Gaming (xCloud) experience
|
||||
// @author redphx
|
||||
// @license MIT
|
||||
@ -14,7 +14,7 @@
|
||||
// ==/UserScript==
|
||||
'use strict';
|
||||
|
||||
const SCRIPT_VERSION = '3.2.2';
|
||||
const SCRIPT_VERSION = '3.2.3';
|
||||
const SCRIPT_HOME = 'https://github.com/redphx/better-xcloud';
|
||||
|
||||
const ENABLE_XCLOUD_LOGGER = false;
|
||||
@ -675,6 +675,22 @@ const Translations = {
|
||||
"Bạn có muốn kết nối lại stream không?",
|
||||
"您想要刷新吗?",
|
||||
],
|
||||
"connected": [
|
||||
,
|
||||
"Connected",
|
||||
"Conectado",
|
||||
,
|
||||
,
|
||||
"接続済み",
|
||||
,
|
||||
"Połączony",
|
||||
,
|
||||
"Подключен",
|
||||
"Bağlı",
|
||||
"Під’єднано",
|
||||
"Đã kết nối",
|
||||
"已连接",
|
||||
],
|
||||
"console-connect": [
|
||||
"Verbinden",
|
||||
"Connect",
|
||||
@ -963,6 +979,22 @@ const Translations = {
|
||||
"Đã tắt",
|
||||
"禁用",
|
||||
],
|
||||
"disconnected": [
|
||||
,
|
||||
"Disconnected",
|
||||
"Desconectado",
|
||||
,
|
||||
,
|
||||
"切断",
|
||||
,
|
||||
"Rozłączony",
|
||||
,
|
||||
"Отключен",
|
||||
"Bağlı değil",
|
||||
"Роз’єднано",
|
||||
"Đã ngắt kết nối",
|
||||
"已断开连接",
|
||||
],
|
||||
"edit": [
|
||||
"Bearbeiten",
|
||||
"Edit",
|
||||
@ -1045,18 +1077,18 @@ const Translations = {
|
||||
],
|
||||
"enable-mkb": [
|
||||
"Maus- und Tastaturunterstützung aktivieren",
|
||||
"Enable Mouse & Keyboard support",
|
||||
"Habilitar soporte para ratón y teclado",
|
||||
"Emulate controller with Mouse & Keyboard",
|
||||
"Emular mandos con teclado y ratón",
|
||||
,
|
||||
"Abilitare il supporto di mouse e tastiera",
|
||||
"マウス&キーボードのサポートを有効化",
|
||||
"マウス&キーボード操作をコントローラー化",
|
||||
"마우스 & 키보드 활성화",
|
||||
"Włącz obsługę myszy i klawiatury",
|
||||
"Habilitar suporte ao Mouse & Teclado",
|
||||
"Включить поддержку мыши и клавиатуры",
|
||||
"Эмулировать контроллер с помощью мыши и клавиатуры",
|
||||
"Klavye ve fare desteğini aktive et",
|
||||
"Увімкнути підтримку миші та клавіатури",
|
||||
"Kích hoạt hỗ trợ Chuột & Bàn phím",
|
||||
"Емуляція контролера за допомогою миші та клавіатури",
|
||||
"Giả lập tay cầm bằng Chuột và Bàn phím",
|
||||
"启用鼠标和键盘支持",
|
||||
],
|
||||
"enable-quick-glance-mode": [
|
||||
@ -2636,8 +2668,8 @@ const Translations = {
|
||||
"コントローラー接続時に無効化",
|
||||
,
|
||||
"Wyłącz, gdy kontroler zostanie znaleziony",
|
||||
,
|
||||
,
|
||||
"Desligar toque quando o controle estiver conectado",
|
||||
"Выключить, когда контроллер найден",
|
||||
"Başka bir kumanda bağlandığında kapat",
|
||||
"Вимкнено, коли контролер знайдено",
|
||||
"Tắt khi sử dụng tay cầm",
|
||||
@ -4063,14 +4095,39 @@ class Toast {
|
||||
static #$wrapper;
|
||||
static #$msg;
|
||||
static #$status;
|
||||
static #stack = [];
|
||||
static #isShowing = false;
|
||||
|
||||
static #timeout;
|
||||
static #DURATION = 3000;
|
||||
|
||||
static show(msg, status) {
|
||||
static show(msg, status, options) {
|
||||
options = options || {};
|
||||
|
||||
if (options.instant) {
|
||||
// Clear stack
|
||||
Toast.#stack = [arguments];
|
||||
Toast.#showNext();
|
||||
} else {
|
||||
Toast.#stack.push(arguments);
|
||||
!Toast.#isShowing && Toast.#showNext();
|
||||
}
|
||||
}
|
||||
|
||||
static #showNext() {
|
||||
if (!Toast.#stack.length) {
|
||||
Toast.#isShowing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Toast.#isShowing = true;
|
||||
|
||||
Toast.#timeout && clearTimeout(Toast.#timeout);
|
||||
Toast.#timeout = setTimeout(Toast.#hide, Toast.#DURATION);
|
||||
|
||||
// Get values from item
|
||||
const [msg, status, options] = Toast.#stack.shift();
|
||||
|
||||
Toast.#$msg.textContent = msg;
|
||||
|
||||
if (status) {
|
||||
@ -4103,6 +4160,8 @@ class Toast {
|
||||
if (classList.contains('bx-hide')) {
|
||||
classList.remove('bx-offscreen', 'bx-hide');
|
||||
classList.add('bx-offscreen');
|
||||
|
||||
Toast.#showNext();
|
||||
}
|
||||
});
|
||||
|
||||
@ -4847,7 +4906,7 @@ class MkbHandler {
|
||||
static get MAXIMUM_STICK_RANGE() { return 1.1; }
|
||||
|
||||
#VIRTUAL_GAMEPAD = {
|
||||
id: 'Xbox 360 Controller (XInput STANDARD GAMEPAD)',
|
||||
id: 'Xbox 360 Controller',
|
||||
index: 3,
|
||||
connected: false,
|
||||
hapticActuators: null,
|
||||
@ -6802,18 +6861,18 @@ class Preferences {
|
||||
'options': {
|
||||
'de-DE': 'Deutsch',
|
||||
'en-US': 'English (United States)',
|
||||
'es-ES': 'espa\xf1ol (Espa\xf1a)',
|
||||
'fr-FR': 'fran\xe7ais',
|
||||
'es-ES': 'español (España)',
|
||||
'fr-FR': 'français',
|
||||
'it-IT': 'italiano',
|
||||
'ja-JP': '\u65e5\u672c\u8a9e',
|
||||
'ko-KR': '\ud55c\uad6d\uc5b4',
|
||||
'ja-JP': '日本語',
|
||||
'ko-KR': '한국어',
|
||||
'pl-PL': 'polski',
|
||||
'pt-BR': 'portugu\xeas (Brasil)',
|
||||
'ru-RU': '\u0440\u0443\u0441\u0441\u043a\u0438\u0439',
|
||||
'tr-TR': 'T\xfcrk\xe7e',
|
||||
'pt-BR': 'português (Brasil)',
|
||||
'ru-RU': 'русский',
|
||||
'tr-TR': 'Türkçe',
|
||||
'uk-UA': 'українська',
|
||||
'vi-VN': 'Tiếng Việt',
|
||||
'zh-CN': '\u4e2d\u6587(\u7b80\u4f53)',
|
||||
'zh-CN': '中文(简体)',
|
||||
},
|
||||
},
|
||||
[Preferences.SERVER_REGION]: {
|
||||
@ -6823,37 +6882,37 @@ class Preferences {
|
||||
'default': 'default',
|
||||
'options': {
|
||||
'default': t('default'),
|
||||
'ar-SA': '\u0627\u0644\u0639\u0631\u0628\u064a\u0629',
|
||||
'cs-CZ': '\u010de\u0161tina',
|
||||
'ar-SA': 'العربية',
|
||||
'cs-CZ': 'čeština',
|
||||
'da-DK': 'dansk',
|
||||
'de-DE': 'Deutsch',
|
||||
'el-GR': '\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac',
|
||||
'el-GR': 'Ελληνικά',
|
||||
'en-GB': 'English (United Kingdom)',
|
||||
'en-US': 'English (United States)',
|
||||
'es-ES': 'espa\xf1ol (Espa\xf1a)',
|
||||
'es-MX': 'espa\xf1ol (Latinoam\xe9rica)',
|
||||
'es-ES': 'español (España)',
|
||||
'es-MX': 'español (Latinoamérica)',
|
||||
'fi-FI': 'suomi',
|
||||
'fr-FR': 'fran\xe7ais',
|
||||
'he-IL': '\u05e2\u05d1\u05e8\u05d9\u05ea',
|
||||
'fr-FR': 'français',
|
||||
'he-IL': 'עברית',
|
||||
'hu-HU': 'magyar',
|
||||
'it-IT': 'italiano',
|
||||
'ja-JP': '\u65e5\u672c\u8a9e',
|
||||
'ko-KR': '\ud55c\uad6d\uc5b4',
|
||||
'nb-NO': 'norsk bokm\xe5l',
|
||||
'ja-JP': '日本語',
|
||||
'ko-KR': '한국어',
|
||||
'nb-NO': 'norsk bokmål',
|
||||
'nl-NL': 'Nederlands',
|
||||
'pl-PL': 'polski',
|
||||
'pt-BR': 'portugu\xeas (Brasil)',
|
||||
'pt-PT': 'portugu\xeas (Portugal)',
|
||||
'ru-RU': '\u0440\u0443\u0441\u0441\u043a\u0438\u0439',
|
||||
'sk-SK': 'sloven\u010dina',
|
||||
'pt-BR': 'português (Brasil)',
|
||||
'pt-PT': 'português (Portugal)',
|
||||
'ru-RU': 'русский',
|
||||
'sk-SK': 'slovenčina',
|
||||
'sv-SE': 'svenska',
|
||||
'tr-TR': 'T\xfcrk\xe7e',
|
||||
'zh-CN': '\u4e2d\u6587(\u7b80\u4f53)',
|
||||
'zh-TW': '\u4e2d\u6587 (\u7e41\u9ad4)',
|
||||
'tr-TR': 'Türkçe',
|
||||
'zh-CN': '中文(简体)',
|
||||
'zh-TW': '中文 (繁體)',
|
||||
},
|
||||
},
|
||||
[Preferences.STREAM_TARGET_RESOLUTION]: {
|
||||
'default': '1080p',
|
||||
'default': 'auto',
|
||||
'options': {
|
||||
'auto': t('default'),
|
||||
'1080p': '1080p',
|
||||
@ -8207,7 +8266,7 @@ a.bx-button {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.better_xcloud_settings {
|
||||
.bx-settings-container {
|
||||
background-color: #151515;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
@ -8511,9 +8570,15 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.bx-stats-bar[data-display=glancing]::before {
|
||||
content: '👀 ';
|
||||
.bx-stats-bar::before {
|
||||
display: none;
|
||||
content: '👀';
|
||||
vertical-align: middle;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.bx-stats-bar[data-display=glancing]::before {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.bx-stats-bar[data-position=top-left] {
|
||||
@ -8922,6 +8987,7 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
|
||||
-webkit-appearance: none;
|
||||
background: transparent;
|
||||
text-align-last: right;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.bx-mkb-pointer-lock-msg {
|
||||
@ -9912,7 +9978,7 @@ function injectSettingsButton($parent) {
|
||||
label: PREF_PREFERRED_REGION,
|
||||
style: ButtonStyle.GHOST | ButtonStyle.FOCUSABLE | ButtonStyle.FULL_HEIGHT,
|
||||
onClick: e => {
|
||||
const $settings = document.querySelector('.better_xcloud_settings');
|
||||
const $settings = document.querySelector('.bx-settings-container');
|
||||
$settings.classList.toggle('bx-gone');
|
||||
$settings.scrollIntoView();
|
||||
document.activeElement && document.activeElement.blur();
|
||||
@ -9926,12 +9992,16 @@ function injectSettingsButton($parent) {
|
||||
|
||||
// Add the Settings button to the web page
|
||||
$headerFragment.appendChild($settingsBtn);
|
||||
|
||||
$parent.appendChild($headerFragment);
|
||||
|
||||
// Avoid rendering the Settings multiple times
|
||||
if (document.querySelector('.bx-settings-container')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup Settings UI
|
||||
const $container = CE('div', {
|
||||
'class': 'better_xcloud_settings bx-gone',
|
||||
'class': 'bx-settings-container bx-gone',
|
||||
});
|
||||
|
||||
let $updateAvailable;
|
||||
@ -10773,14 +10843,8 @@ function setupQuickSettingsBar() {
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
HAS_TOUCH_SUPPORT && {
|
||||
icon: Icon.HAND_TAP,
|
||||
group: 'touch-controller',
|
||||
items: [
|
||||
{
|
||||
HAS_TOUCH_SUPPORT && {
|
||||
group: 'touch-controller',
|
||||
label: t('touch-controller'),
|
||||
items: [
|
||||
@ -10939,6 +11003,10 @@ function setupQuickSettingsBar() {
|
||||
const $group = CE('div', {'data-group': settingTab.group, 'class': 'bx-gone'});
|
||||
|
||||
for (const settingGroup of settingTab.items) {
|
||||
if (!settingGroup) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$group.appendChild(CE('h2', {},
|
||||
CE('span', {}, settingGroup.label),
|
||||
settingGroup.help_url && createButton({
|
||||
@ -11096,7 +11164,7 @@ function onHistoryChanged(e) {
|
||||
|
||||
setTimeout(RemotePlay.detect, 10);
|
||||
|
||||
const $settings = document.querySelector('.better_xcloud_settings');
|
||||
const $settings = document.querySelector('.bx-settings-container');
|
||||
if ($settings) {
|
||||
$settings.classList.add('bx-gone');
|
||||
}
|
||||
@ -11211,7 +11279,7 @@ window.addEventListener(BxEvent.STREAM_STOPPED, e => {
|
||||
IS_PLAYING = false;
|
||||
|
||||
// Stop MKB listeners
|
||||
MkbHandler.INSTANCE.destroy();
|
||||
getPref(Preferences.MKB_ENABLED) && MkbHandler.INSTANCE.destroy();
|
||||
|
||||
const $quickBar = document.querySelector('.bx-quick-settings-bar');
|
||||
if ($quickBar) {
|
||||
@ -11337,3 +11405,22 @@ RemotePlay.detect();
|
||||
StreamBadges.setupEvents();
|
||||
StreamStats.setupEvents();
|
||||
MkbHandler.setupEvents();
|
||||
|
||||
// Show a toast when connecting/disconecting controller
|
||||
function showGamepadToast(gamepad) {
|
||||
let text = '🎮';
|
||||
|
||||
if (getPref(Preferences.LOCAL_CO_OP_ENABLED)) {
|
||||
text += ` #${gamepad.index + 1}`;
|
||||
}
|
||||
|
||||
// Remove "(STANDARD GAMEPAD Vendor: xxx Product: xxx)" from ID
|
||||
const gamepadId = gamepad.id.replace(/ \(.* Vendor: \w+ Product: \w+\)$/, '');
|
||||
text += ` - ${gamepadId}`;
|
||||
const status = gamepad.connected ? t('connected') : t('disconnected');
|
||||
|
||||
Toast.show(text, status, {instant: false});
|
||||
}
|
||||
|
||||
window.addEventListener('gamepadconnected', e => showGamepadToast(e.gamepad));
|
||||
window.addEventListener('gamepaddisconnected', e => showGamepadToast(e.gamepad));
|
||||
|
Reference in New Issue
Block a user