@ -1,7 +1,7 @@
// ==UserScript==
// @name Better xCloud
// @namespace https://github.com/redphx
// @version 2.0
// @version 2.0.2
// @description Improve Xbox Cloud Gaming (xCloud) experience
// @author redphx
// @license MIT
@ -13,7 +13,7 @@
// ==/UserScript==
'use strict' ;
const SCRIPT _VERSION = '2.0' ;
const SCRIPT _VERSION = '2.0.2 ' ;
const SCRIPT _HOME = 'https://github.com/redphx/better-xcloud' ;
const ENABLE _MKB = false ;
@ -311,6 +311,7 @@ const Translations = {
"can-stream-xbox-360-games" : {
"de-DE" : "Kann Xbox 360 Spiele streamen" ,
"en-US" : "Can stream Xbox 360 games" ,
"es-ES" : "Puede transmitir juegos de Xbox 360" ,
"it-IT" : "Puoi riprodurre i giochi Xbox 360" ,
"ja-JP" : "Xbox 360ゲームのストリーミング可能" ,
"pl-PL" : "Można strumieniować gry Xbox 360" ,
@ -321,6 +322,7 @@ const Translations = {
"cant-stream-xbox-360-games" : {
"de-DE" : "Kann Xbox 360 Spiele nicht streamen" ,
"en-US" : "Can't stream Xbox 360 games" ,
"es-ES" : "No puede transmitir juegos de Xbox 360" ,
"it-IT" : "Impossibile riprodurre i giochi Xbox 360" ,
"ja-JP" : "Xbox 360ゲームのストリーミング不可" ,
"pl-PL" : "Nie można strumieniować gier Xbox 360" ,
@ -406,6 +408,7 @@ const Translations = {
"console-connect" : {
"de-DE" : "Verbinden" ,
"en-US" : "Connect" ,
"es-ES" : "Conectar" ,
"it-IT" : "Connetti" ,
"ja-JP" : "本体に接続" ,
"pl-PL" : "Połącz" ,
@ -432,6 +435,7 @@ const Translations = {
"controller" : {
"de-DE" : "Controller" ,
"en-US" : "Controller" ,
"es-ES" : "Joystick" ,
"it-IT" : "Controller" ,
"ja-JP" : "コントローラー" ,
"pl-PL" : "Kontroler" ,
@ -441,8 +445,11 @@ const Translations = {
"zh-CN" : "手柄" ,
} ,
"controller-polling-rate" : {
"de-DE" : "Controller-Abfragerate" ,
"en-US" : "Controller polling rate" ,
"es-ES" : "Tasa de sondeo del Joystick" ,
"ja-JP" : "コントローラーポーリングレート" ,
"pl-PL" : "Częstotliwości raportowania kontrolera" ,
"pt-BR" : "Taxa de consulta do controle" ,
"tr-TR" : "Oyun kumandası işlem hı zı " ,
"vi-VN" : "Tần suất cập nhật của bộ điều khiển" ,
@ -568,6 +575,7 @@ const Translations = {
"enable-controller-shortcuts" : {
"de-DE" : "Controller-Shortcuts aktivieren" ,
"en-US" : "Enable controller shortcuts" ,
"es-ES" : "Habilitar accesos directos del Joystick" ,
"it-IT" : "Consenti scorciatoie da controller" ,
"ja-JP" : "コントローラーショートカットを有効化" ,
"pl-PL" : "Włącz skróty kontrolera" ,
@ -592,8 +600,12 @@ const Translations = {
"zh-CN" : "游戏启动时打开麦克风" ,
} ,
"enable-mkb" : {
"de-DE" : "Maus- und Tastaturunterstützung aktivieren" ,
"en-US" : "Enable Mouse & Keyboard support" ,
"es-ES" : "Habilitar soporte para ratón y teclado" ,
"ja-JP" : "マウス&キーボードのサポートを有効化" ,
"pl-PL" : "Włącz obsługę myszy i klawiatury" ,
"pt-BR" : "Habilitar suporte ao Mouse & Teclado" ,
"tr-TR" : "Klavye ve fare desteğini aktive et" ,
"vi-VN" : "Kích hoạt hỗ trợ Chuột & Bàn phím" ,
} ,
@ -612,6 +624,16 @@ const Translations = {
"vi-VN" : "Bật chế độ \"Xem nhanh\"" ,
"zh-CN" : "仅在打开设置时显示统计信息" ,
} ,
"enable-remote-play-feature" : {
"de-DE" : "\"Remote Play\" Funktion aktivieren" ,
"en-US" : "Enable the \"Remote Play\" feature" ,
"es-ES" : "Activar la función \"Reproducción remota\"" ,
"ja-JP" : "リモートプレイ機能を有効化" ,
"pl-PL" : "Włącz funkcję \"Gra zdalna\"" ,
"pt-BR" : "Ativar o recurso \"Reprodução Remota\"" ,
"tr-TR" : "\"Uzaktan Oynama\" özelliğini aktive et" ,
"vi-VN" : "Bật tính năng \"Chơi từ xa\"" ,
} ,
"enable-volume-control" : {
"de-DE" : "Lautstärkeregelung aktivieren" ,
"en-US" : "Enable volume control feature" ,
@ -627,14 +649,19 @@ const Translations = {
"zh-CN" : "启用音量控制" ,
} ,
"fast" : {
"de-DE" : "Schnell" ,
"en-US" : "Fast" ,
"es-ES" : "Rápido" ,
"ja-JP" : "高速" ,
"pl-PL" : "Szybko" ,
"pt-BR" : "Rápido" ,
"tr-TR" : "Hı zlı " ,
"vi-VN" : "Nhanh" ,
} ,
"getting-consoles-list" : {
"de-DE" : "Rufe Liste der Konsolen ab..." ,
"en-US" : "Getting the list of consoles..." ,
"es-ES" : "Obteniendo la lista de consolas..." ,
"it-IT" : "Ottenere la lista delle consoles..." ,
"ja-JP" : "本体のリストを取得中..." ,
"pl-PL" : "Pobieranie listy konsoli..." ,
@ -703,8 +730,11 @@ const Translations = {
"zh-CN" : "大" ,
} ,
"layout" : {
"de-DE" : "Layout" ,
"en-US" : "Layout" ,
"es-ES" : "Diseño" ,
"ja-JP" : "レイアウト" ,
"pl-PL" : "Układ" ,
"pt-BR" : "Layout" ,
"tr-TR" : "Arayüz Görünümü" ,
"vi-VN" : "Bố cục" ,
@ -725,14 +755,22 @@ const Translations = {
"zh-CN" : "载入画面" ,
} ,
"max-bitrate" : {
"de-DE" : "Max. Bitrate" ,
"en-US" : "Max bitrate" ,
"es-ES" : "Tasa de bits máxima" ,
"ja-JP" : "最大ビットレート" ,
"pl-PL" : "Maksymalny bitrate" ,
"pt-BR" : "Taxa máxima dos bits" ,
"tr-TR" : "Maksimum bithı zı " ,
"vi-VN" : "Bitrate tối đa" ,
} ,
"may-not-work-properly" : {
"de-DE" : "Funktioniert evtl. nicht fehlerfrei!" ,
"en-US" : "May not work properly!" ,
"es-ES" : "¡Puede que no funcione correctamente!" ,
"ja-JP" : "正常に動作しない場合があります!" ,
"pl-PL" : "Może nie działać poprawnie!" ,
"pt-BR" : "Pode não funcionar corretamente!" ,
"tr-TR" : "Düzgün çalı şmayabilir!" ,
"vi-VN" : "Có thể không hoạt động!" ,
} ,
@ -769,6 +807,7 @@ const Translations = {
"microphone" : {
"de-DE" : "Mikrofon" ,
"en-US" : "Microphone" ,
"es-ES" : "Micrófono" ,
"it-IT" : "Microfono" ,
"ja-JP" : "マイク" ,
"pl-PL" : "Mikrofon" ,
@ -778,14 +817,19 @@ const Translations = {
"zh-CN" : "麦克风" ,
} ,
"mouse-and-keyboard" : {
"de-DE" : "Maus & Tastatur" ,
"en-US" : "Mouse & Keyboard" ,
"es-ES" : "Ratón y teclado" ,
"ja-JP" : "マウス&キーボード" ,
"pl-PL" : "Mysz i klawiatura" ,
"pt-BR" : "Mouse e Teclado" ,
"tr-TR" : "Klavye ve Fare" ,
"vi-VN" : "Chuột và Bàn phím" ,
} ,
"muted" : {
"de-DE" : "Stumm" ,
"en-US" : "Muted" ,
"es-ES" : "Silenciado" ,
"it-IT" : "Microfono disattivato" ,
"ja-JP" : "ミュート" ,
"pl-PL" : "Wyciszony" ,
@ -797,6 +841,7 @@ const Translations = {
"no-consoles-found" : {
"de-DE" : "Keine Konsolen gefunden" ,
"en-US" : "No consoles found" ,
"es-ES" : "No se encontraron consolas" ,
"it-IT" : "Nessuna console trovata" ,
"ja-JP" : "本体が見つかりません" ,
"pl-PL" : "Nie znaleziono konsoli" ,
@ -838,6 +883,7 @@ const Translations = {
"on" : {
"de-DE" : "An" ,
"en-US" : "On" ,
"es-ES" : "Activado" ,
"it-IT" : "Attivo" ,
"ja-JP" : "オン" ,
"pl-PL" : "Włącz" ,
@ -846,9 +892,13 @@ const Translations = {
"vi-VN" : "Bật" ,
"zh-CN" : "开启" ,
} ,
"only-support-some-games" : {
"en-US " : "Only support some games " ,
"only-supports -some-games" : {
"de-DE " : "Unterstützt nur einige Spiele " ,
"en-US" : "Only supports some games" ,
"es-ES" : "Sólo soporta algunos juegos" ,
"ja-JP" : "一部のゲームのみサポート" ,
"pl-PL" : "Wspiera tylko niektóre gry" ,
"pt-BR" : "Suporta apenas alguns jogos" ,
"tr-TR" : "Yalnı zca belli oyunlar destekleniyor" ,
"vi-VN" : "Chỉ hỗ trợ một vài game" ,
} ,
@ -900,8 +950,9 @@ const Translations = {
"powered-off" : {
"de-DE" : "Ausgeschaltet" ,
"en-US" : "Powered off" ,
"es-ES" : "Desactivado" ,
"it-IT" : "Spento" ,
"ja-JP" : "電源 オフ" ,
"ja-JP" : "本体 オフ" ,
"pl-PL" : "Zasilanie wyłączone" ,
"pt-BR" : "Desligado" ,
"tr-TR" : "Kapalı " ,
@ -911,8 +962,9 @@ const Translations = {
"powered-on" : {
"de-DE" : "Eingeschaltet" ,
"en-US" : "Powered on" ,
"es-ES" : "Activado" ,
"it-IT" : "Acceso" ,
"ja-JP" : "電源 オン" ,
"ja-JP" : "本体 オン" ,
"pl-PL" : "Zasilanie włączone" ,
"pt-BR" : "Ligado" ,
"tr-TR" : "Açı k" ,
@ -997,6 +1049,7 @@ const Translations = {
"remote-play" : {
"de-DE" : "Remote Play" ,
"en-US" : "Remote Play" ,
"es-ES" : "Reproducción remota" ,
"it-IT" : "Riproduzione Remota" ,
"ja-JP" : "リモートプレイ" ,
"pl-PL" : "Gra zdalna" ,
@ -1231,8 +1284,12 @@ const Translations = {
"zh-CN" : "跳过 Xbox 启动动画" ,
} ,
"slow" : {
"de-DE" : "Langsam" ,
"en-US" : "Slow" ,
"es-ES" : "Lento" ,
"ja-JP" : "低速" ,
"pl-PL" : "Wolno" ,
"pt-BR" : "Lento" ,
"tr-TR" : "Yavaş" ,
"vi-VN" : "Chậm" ,
} ,
@ -1252,8 +1309,11 @@ const Translations = {
"zh-CN" : "小" ,
} ,
"smart-tv" : {
"de-DE" : "Smart TV" ,
"en-US" : "Smart TV" ,
"es-ES" : "Smart TV" ,
"ja-JP" : "スマートTV" ,
"pl-PL" : "Smart TV" ,
"pt-BR" : "Smart TV" ,
"tr-TR" : "Akı llı TV" ,
"vi-VN" : "TV thông minh" ,
@ -1261,6 +1321,7 @@ const Translations = {
"sound" : {
"de-DE" : "Ton" ,
"en-US" : "Sound" ,
"es-ES" : "Sonido" ,
"it-IT" : "Suoni" ,
"ja-JP" : "サウンド" ,
"pl-PL" : "Dźwięk" ,
@ -1272,6 +1333,7 @@ const Translations = {
"standby" : {
"de-DE" : "Standby" ,
"en-US" : "Standby" ,
"es-ES" : "Modo de espera" ,
"it-IT" : "Sospendi" ,
"ja-JP" : "スタンバイ" ,
"pl-PL" : "Stan czuwania" ,
@ -1643,6 +1705,7 @@ const Translations = {
"unknown" : {
"de-DE" : "Unbekannt" ,
"en-US" : "Unknown" ,
"es-ES" : "Desconocido" ,
"it-IT" : "Sconosciuto" ,
"ja-JP" : "不明" ,
"pl-PL" : "Nieznane" ,
@ -1652,14 +1715,19 @@ const Translations = {
"zh-CN" : "未知" ,
} ,
"unlimited" : {
"de-DE" : "Unbegrenzt" ,
"en-US" : "Unlimited" ,
"es-ES" : "Ilimitado" ,
"ja-JP" : "無制限" ,
"pl-PL" : "Bez ograniczeń" ,
"pt-BR" : "Ilimitado" ,
"tr-TR" : "Limitsiz" ,
"vi-VN" : "Không giới hạn" ,
} ,
"unmuted" : {
"de-DE" : "Ton an" ,
"en-US" : "Unmuted" ,
"es-ES" : "Activar sonido" ,
"it-IT" : "Microfono attivato" ,
"ja-JP" : "ミュート解除" ,
"pl-PL" : "Wyciszenie wyłączone" ,
@ -1669,8 +1737,12 @@ const Translations = {
"zh-CN" : "已取消静音" ,
} ,
"use-mouse-absolute-position" : {
"de-DE" : "Absolute Position der Maus verwenden" ,
"en-US" : "Use mouse's absolute position" ,
"es-ES" : "Usar la posición absoluta del ratón" ,
"ja-JP" : "マウスの絶対座標を使用" ,
"pl-PL" : "Użyj pozycji bezwzględnej myszy" ,
"pt-BR" : "Usar posição absoluta do mouse" ,
"tr-TR" : "Farenin mutlak pozisyonunu baz al" ,
"vi-VN" : "Sử dụng vị trí tuyệt đối của chuột" ,
} ,
@ -2047,13 +2119,12 @@ class RemotePlay {
$connectButton = CE ( 'button' , { 'class' : 'bx-primary-button bx-no-margin' } , _ _ ( 'console-connect' ) ) ,
) ;
REMOTE _PLAY _CONFIG = {
serverId : con . serverId ,
} ;
$connectButton . addEventListener ( 'click' , e => {
const url = window . location . href . substring ( 0 , 31 ) + '/launch/starfield/9NCJSXWZTP88#remote-play' ;
// const url = '/play';
REMOTE _PLAY _CONFIG = {
serverId : con . serverId ,
} ;
const url = window . location . href . substring ( 0 , 31 ) + '/launch/fortnite/BT5P2X999VH2#remote-play' ;
const $pageContent = document . getElementById ( 'PageContent' ) ;
const $anchor = CE ( 'a' , { href : url , class : 'bx-hidden' , style : 'position:absolute;top:-9990px;left:-9999px' } , '' ) ;
@ -2074,18 +2145,11 @@ class RemotePlay {
RemotePlay . # $content . parentElement . replaceChild ( $fragment , RemotePlay . # $content ) ;
}
static # onLoad ( ) {
const CE = createElement ;
const $ui = CE ( 'div' , { 'class' : 'bx-container' } ,
CE ( 'h2' , { } , _ _ ( 'remote-play' ) ) ,
CE ( 'div' , { 'id' : 'bxUi' } , _ _ ( 'getting-consoles-list' ) ) ,
) ;
const $landingPageHeader = document . querySelector ( 'h2[class*=LandingPage-module__header]' ) ;
$landingPageHeader . parentElement . insertBefore ( $ui , $landingPageHeader ) ;
}
static detect ( ) {
if ( ! PREFS . get ( Preferences . REMOTE _PLAY _ENABLED ) ) {
return ;
}
IS _REMOTE _PLAYING = window . location . pathname . includes ( '/launch/' ) && window . location . hash . startsWith ( '#remote-play' ) ;
if ( IS _REMOTE _PLAYING ) {
window . BX _REMOTE _PLAY _CONFIG = REMOTE _PLAY _CONFIG ;
@ -3276,7 +3340,7 @@ class PreloadedState {
return this . _state ;
} ,
set : ( state ) => {
set : state => {
this . _state = state ;
APP _CONTEXT = structuredClone ( state . appContext ) ;
@ -3322,7 +3386,6 @@ class Preferences {
static get STREAM _DISABLE _FEEDBACK _DIALOG ( ) { return 'stream_disable_feedback_dialog' ; }
static get CONTROLLER _ENABLE _SHORTCUTS ( ) { return 'controller_enable_shortcuts' ; }
static get CONTROLLER _POLLING _RATE ( ) { return 'controller_polling_rate' ; }
static get MKB _ENABLED ( ) { return 'mkb_enabled' ; }
static get MKB _ABSOLUTE _MOUSE ( ) { return 'mkb_absolute_mouse' ; }
@ -3360,6 +3423,7 @@ class Preferences {
static get STATS _OPACITY ( ) { return 'stats_opacity' ; }
static get STATS _CONDITIONAL _FORMATTING ( ) { return 'stats_conditional_formatting' ; }
static get REMOTE _PLAY _ENABLED ( ) { return 'xhome_enabled' ; }
static get REMOTE _PLAY _RESOLUTION ( ) { return 'xhome_resolution' ; }
// Deprecated
@ -3553,15 +3617,6 @@ class Preferences {
[ Preferences . CONTROLLER _ENABLE _SHORTCUTS ] : {
'default' : false ,
} ,
[ Preferences . CONTROLLER _POLLING _RATE ] : {
'type' : 'number' ,
'default' : 50 ,
'options' : {
16 : '62.5 Hz (16ms)' ,
32 : '31.25 Hz (32ms)' ,
50 : ` 20 Hz (50ms - ${ _ _ ( 'default' ) } ) ` ,
} ,
} ,
[ Preferences . MKB _ENABLED ] : {
'default' : false ,
@ -3707,6 +3762,10 @@ class Preferences {
'default' : false ,
} ,
[ Preferences . REMOTE _PLAY _ENABLED ] : {
'default' : false ,
} ,
[ Preferences . REMOTE _PLAY _RESOLUTION ] : {
'default' : 1080 ,
'options' : {
@ -4033,36 +4092,24 @@ const PREFS = new Preferences();
class Patcher {
static # PATCHES = {
// Modify controller polling rate
controllerPollingRate : ( PREFS . get ( Preferences . CONTROLLER _POLLING _RATE ) !== 50 ) && function ( funcStr ) {
const text = '.startGamepadPolling=()' ;
const index = funcStr . indexOf ( text ) ;
if ( index === - 1 ) {
return false ;
}
const patchedStr = funcStr . substring ( index , index + 100 ) . replace ( /setInterval\((\w+),(\d+)\)/ , ` setInterval( $ 1, ${ PREFS . get ( Preferences . CONTROLLER _POLLING _RATE ) } ) ` ) ;
return funcStr . substring ( 0 , index ) + patchedStr + funcStr . substring ( index + 100 ) ;
} ,
// Enable Remote Play feature
c onnectMode: function ( funcStr ) {
remotePlayC onnectMode: PREFS . get ( Preferences . REMOTE _PLAY _ENABLED ) && function ( funcStr ) {
const text = 'connectMode:"cloud-connect"' ;
if ( ! funcStr . includes ( text ) ) {
return false ;
}
return funcStr . replace ( text , ` connectMode:window.BX_REMOTE_PLAY_CONFIG?"xhome-connect":"cloud-connect",remotePlayServerId:window.BX_REMOTE_PLAY_CONFIG&&window.BX_REMOTE_PLAY_CONFIG.serverId||'' ` ) ;
return funcStr . replace ( text , ` connectMode:window.BX_REMOTE_PLAY_CONFIG?"xhome-connect":"cloud-connect",remotePlayServerId:( window.BX_REMOTE_PLAY_CONFIG&&window.BX_REMOTE_PLAY_CONFIG.serverId) ||'' ` ) ;
} ,
// Replace "/direct-connect" with "/play"
d irectConnectUrl: function ( funcStr ) {
remotePlayD irectConnectUrl: PREFS . get ( Preferences . REMOTE _PLAY _ENABLED ) && function ( funcStr ) {
const index = funcStr . indexOf ( '/direct-connect' ) ;
if ( index === - 1 ) {
return false ;
}
return funcStr . replace ( funcStr . substring ( index - 9 , index + 15 ) , '/play' ) ;
return funcStr . replace ( funcStr . substring ( index - 9 , index + 15 ) , 'https://www.xbox.com /play' ) ;
} ,
// Set disableTelemetry() to true
@ -4085,6 +4132,31 @@ class Patcher {
return funcStr . replace ( text , 'this.trackEvent=e=>{},this.uwuwu=' ) ;
} ,
// Disable ApplicationInsights.track() function
disableAiTrack : PREFS . get ( Preferences . BLOCK _TRACKING ) && function ( funcStr ) {
const text = '.track=function(' ;
const index = funcStr . indexOf ( text ) ;
if ( index === - 1 ) {
return false ;
}
if ( funcStr . substring ( 0 , index + 200 ) . includes ( '"AppInsightsCore' ) ) {
return false ;
}
return funcStr . substring ( 0 , index ) + '.track=function(e){},!!function(' + funcStr . substring ( index + text . length ) ;
} ,
// Block WebRTC stats collector
blockWebRtcStatsCollector : PREFS . get ( Preferences . BLOCK _TRACKING ) && function ( funcStr ) {
const text = 'this.intervalMs=0,' ;
if ( ! funcStr . includes ( text ) ) {
return false ;
}
return funcStr . replace ( text , 'false,' + text ) ;
} ,
// Set TV layout
tvLayout : PREFS . get ( Preferences . UI _LAYOUT ) === 'tv' && function ( funcStr ) {
const text = '?"tv":"default"' ;
@ -4107,7 +4179,7 @@ class Patcher {
}
return funcStr ;
}
} ,
} ;
static # patchFunctionBind ( ) {
@ -5341,9 +5413,6 @@ function interceptHttpRequests() {
try {
const clone = request . clone ( ) ;
const resp = ( await ( await orgFetch ( ... arg ) ) . json ( ) ) ;
RemotePlay . XCLOUD _TOKEN = resp . gsToken ;
const obj = await clone . json ( ) ;
obj . offeringId = 'xhome' ;
@ -5424,6 +5493,9 @@ function interceptHttpRequests() {
return promise . then ( response => {
return response . clone ( ) . json ( ) . then ( obj => {
// Store xCloud token
RemotePlay . XCLOUD _TOKEN = obj . gsToken ;
// Get server list
if ( ! Object . keys ( SERVER _REGIONS ) . length ) {
for ( let region of obj . offeringSettings . regions ) {
@ -5620,6 +5692,7 @@ function injectSettingsButton($parent) {
const CE = createElement ;
const PREF _PREFERRED _REGION = getPreferredServerRegion ( ) ;
const PREF _LATEST _VERSION = PREFS . get ( Preferences . LATEST _VERSION ) ;
const PREF _REMOTE _PLAY _ENABLED = PREFS . get ( Preferences . REMOTE _PLAY _ENABLED ) ;
// Setup Settings button
const $button = CE ( 'button' , { 'class' : 'bx-settings-button' } , PREF _PREFERRED _REGION ) ;
@ -5643,7 +5716,7 @@ function injectSettingsButton($parent) {
} ) ;
let $updateAvailable ;
let $remotePlayLink ;
let $remotePlayBtn ;
const $wrapper = CE ( 'div' , { 'class' : 'bx-settings-wrapper' } ,
CE ( 'div' , { 'class' : 'bx-settings-title-wrapper' } ,
CE ( 'a' , {
@ -5651,7 +5724,7 @@ function injectSettingsButton($parent) {
'href' : SCRIPT _HOME ,
'target' : '_blank' ,
} , 'Better xCloud ' + SCRIPT _VERSION ) ,
$remotePlayLink = CE ( 'button' , { 'class' : 'bx-primary-button bx-no-margin' } , _ _ ( 'remote-play' ) ) ,
$remotePlayBtn = CE ( 'button' , { 'class' : 'bx-primary-button bx-no-margin' } , _ _ ( 'remote-play' ) ) ,
)
) ;
$updateAvailable = CE ( 'a' , {
@ -5660,12 +5733,17 @@ function injectSettingsButton($parent) {
'target' : '_blank' ,
} ) ;
$remotePlayLink . addEventListener ( 'click' , e => {
R emotePlay. showDialog ( ) ;
if ( PREF _REMOTE _PLAY _ENABLED ) {
$r emotePlayBtn . addEventListener ( 'click' , e => {
RemotePlay . showDialog ( ) ;
// Hide Settings
$container . classList . add ( 'bx-gone' ) ;
} ) ;
} else {
$remotePlayBtn . classList . add ( 'bx-gone' ) ;
}
// Hide Settings
$container . classList . add ( 'bx-gone' ) ;
} ) ;
$wrapper . appendChild ( $updateAvailable ) ;
// Show new version indicator
@ -5678,6 +5756,7 @@ function injectSettingsButton($parent) {
const SETTINGS _UI = {
'Better xCloud' : {
[ Preferences . BETTER _XCLOUD _LOCALE ] : _ _ ( 'language' ) ,
[ Preferences . REMOTE _PLAY _ENABLED ] : _ _ ( 'enable-remote-play-feature' ) ,
} ,
[ _ _ ( 'server' ) ] : {
[ Preferences . SERVER _REGION ] : _ _ ( 'region' ) ,
@ -5694,7 +5773,6 @@ function injectSettingsButton($parent) {
[ Preferences . STREAM _DISABLE _FEEDBACK _DIALOG ] : _ _ ( 'disable-post-stream-feedback-dialog' ) ,
} ,
[ _ _ ( 'controller' ) ] : {
[ Preferences . CONTROLLER _POLLING _RATE ] : _ _ ( 'controller-polling-rate' ) ,
[ Preferences . CONTROLLER _ENABLE _SHORTCUTS ] : _ _ ( 'enable-controller-shortcuts' ) ,
} ,
[ _ _ ( 'touch-controller' ) ] : {
@ -5705,7 +5783,7 @@ function injectSettingsButton($parent) {
[ _ _ ( 'mouse-and-keyboard' ) ] : {
'_note' : '⚠️ ' + _ _ ( 'may-not-work-properly' ) ,
[ Preferences . MKB _ENABLED ] : [ _ _ ( 'enable-mkb' ) , _ _ ( 'only-support-some-games' ) ] ,
[ Preferences . MKB _ENABLED ] : [ _ _ ( 'enable-mkb' ) , _ _ ( 'only-supports -some-games' ) ] ,
[ Preferences . MKB _ABSOLUTE _MOUSE ] : _ _ ( 'use-mouse-absolute-position' ) ,
} ,
@ -6623,4 +6701,5 @@ if (PREFS.get(Preferences.CONTROLLER_ENABLE_SHORTCUTS)) {
}
Patcher . initialize ( ) ;
RemotePlay . detect ( ) ;