mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-07-18 04:01:42 +02:00
Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
cc9a644a5e | |||
a77db68afb | |||
cd7a7c92c7 | |||
651402a6b4 |
@ -1,5 +1,5 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name Better xCloud
|
// @name Better xCloud
|
||||||
// @namespace https://github.com/redphx
|
// @namespace https://github.com/redphx
|
||||||
// @version 1.15
|
// @version 1.15.1
|
||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name Better xCloud
|
// @name Better xCloud
|
||||||
// @namespace https://github.com/redphx
|
// @namespace https://github.com/redphx
|
||||||
// @version 1.15
|
// @version 1.15.1
|
||||||
// @description Improve Xbox Cloud Gaming (xCloud) experience
|
// @description Improve Xbox Cloud Gaming (xCloud) experience
|
||||||
// @author redphx
|
// @author redphx
|
||||||
// @license MIT
|
// @license MIT
|
||||||
@ -13,7 +13,7 @@
|
|||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const SCRIPT_VERSION = '1.15';
|
const SCRIPT_VERSION = '1.15.1';
|
||||||
const SCRIPT_HOME = 'https://github.com/redphx/better-xcloud';
|
const SCRIPT_HOME = 'https://github.com/redphx/better-xcloud';
|
||||||
|
|
||||||
console.log(`[Better xCloud] readyState: ${document.readyState}`);
|
console.log(`[Better xCloud] readyState: ${document.readyState}`);
|
||||||
@ -1314,24 +1314,30 @@ class Preferences {
|
|||||||
'max': 5,
|
'max': 5,
|
||||||
},
|
},
|
||||||
[Preferences.VIDEO_RATIO]: {
|
[Preferences.VIDEO_RATIO]: {
|
||||||
'default': 16,
|
'default': '16:9',
|
||||||
'min': 16,
|
'options': {
|
||||||
'max': 21,
|
'16:9': '16:9',
|
||||||
'steps': 1,
|
'21:9': '21:9',
|
||||||
|
'16:10': '16:10',
|
||||||
|
'4:3': '4:3',
|
||||||
|
|
||||||
|
'fill': 'Stretch',
|
||||||
|
'cover': 'Cover',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
[Preferences.VIDEO_SATURATION]: {
|
[Preferences.VIDEO_SATURATION]: {
|
||||||
'default': 100,
|
'default': 100,
|
||||||
'min': 0,
|
'min': 50,
|
||||||
'max': 150,
|
'max': 150,
|
||||||
},
|
},
|
||||||
[Preferences.VIDEO_CONTRAST]: {
|
[Preferences.VIDEO_CONTRAST]: {
|
||||||
'default': 100,
|
'default': 100,
|
||||||
'min': 0,
|
'min': 50,
|
||||||
'max': 150,
|
'max': 150,
|
||||||
},
|
},
|
||||||
[Preferences.VIDEO_BRIGHTNESS]: {
|
[Preferences.VIDEO_BRIGHTNESS]: {
|
||||||
'default': 100,
|
'default': 100,
|
||||||
'min': 0,
|
'min': 50,
|
||||||
'max': 150,
|
'max': 150,
|
||||||
},
|
},
|
||||||
[Preferences.AUDIO_MIC_ON_PLAYING]: {
|
[Preferences.AUDIO_MIC_ON_PLAYING]: {
|
||||||
@ -1411,7 +1417,43 @@ class Preferences {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get(key, defaultValue=null) {
|
#validateValue(key, value) {
|
||||||
|
const config = Preferences.SETTINGS[key];
|
||||||
|
if (!config) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof value === 'undefined' || value === null) {
|
||||||
|
value = config.default;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('min' in config) {
|
||||||
|
value = Math.max(config.min, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('max' in config) {
|
||||||
|
value = Math.min(config.max, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('options' in config && !(value in config.options)) {
|
||||||
|
value = config.default;
|
||||||
|
} else if ('multiple_options' in config) {
|
||||||
|
if (value.length) {
|
||||||
|
const validOptions = Object.keys(config.multiple_options);
|
||||||
|
value.forEach((item, idx) => {
|
||||||
|
(validOptions.indexOf(item) === -1) && value.splice(idx, 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!value.length) {
|
||||||
|
value = config.default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get(key) {
|
||||||
if (typeof key === 'undefined') {
|
if (typeof key === 'undefined') {
|
||||||
debugger;
|
debugger;
|
||||||
return;
|
return;
|
||||||
@ -1422,46 +1464,14 @@ class Preferences {
|
|||||||
return 'default';
|
return 'default';
|
||||||
}
|
}
|
||||||
|
|
||||||
const value = this._prefs[key];
|
let value = this._prefs[key];
|
||||||
|
value = this.#validateValue(key, value);
|
||||||
|
|
||||||
if (typeof value !== 'undefined' && value !== null && value !== '') {
|
return value;
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (defaultValue !== null) {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return default value
|
|
||||||
return Preferences.SETTINGS[key].default;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set(key, value) {
|
set(key, value) {
|
||||||
const config = Preferences.SETTINGS[key];
|
value = this.#validateValue(key, value);
|
||||||
if (config) {
|
|
||||||
if ('min' in config) {
|
|
||||||
value = Math.max(config.min, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('max' in config) {
|
|
||||||
value = Math.min(config.max, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('options' in config && !(value in config.options)) {
|
|
||||||
value = config.default;
|
|
||||||
} else if ('multiple_options' in config) {
|
|
||||||
if (value.length) {
|
|
||||||
const validOptions = Object.keys(config.multiple_options);
|
|
||||||
value.forEach((item, idx) => {
|
|
||||||
(validOptions.indexOf(item) === -1) && value.splice(idx, 1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!value.length) {
|
|
||||||
value = config.default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this._prefs[key] = value;
|
this._prefs[key] = value;
|
||||||
this._update_storage();
|
this._update_storage();
|
||||||
@ -1643,8 +1653,8 @@ const PREFS = new Preferences();
|
|||||||
function checkForUpdate() {
|
function checkForUpdate() {
|
||||||
const CHECK_INTERVAL_SECONDS = 4 * 3600; // check every 4 hours
|
const CHECK_INTERVAL_SECONDS = 4 * 3600; // check every 4 hours
|
||||||
|
|
||||||
const currentVersion = PREFS.get(Preferences.CURRENT_VERSION, '');
|
const currentVersion = PREFS.get(Preferences.CURRENT_VERSION);
|
||||||
const lastCheck = PREFS.get(Preferences.LAST_UPDATE_CHECK, 0);
|
const lastCheck = PREFS.get(Preferences.LAST_UPDATE_CHECK);
|
||||||
const now = Math.round((+new Date) / 1000);
|
const now = Math.round((+new Date) / 1000);
|
||||||
|
|
||||||
if (currentVersion === SCRIPT_VERSION && now - lastCheck < CHECK_INTERVAL_SECONDS) {
|
if (currentVersion === SCRIPT_VERSION && now - lastCheck < CHECK_INTERVAL_SECONDS) {
|
||||||
@ -2663,7 +2673,7 @@ function injectSettingsButton($parent) {
|
|||||||
|
|
||||||
const CE = createElement;
|
const CE = createElement;
|
||||||
const PREF_PREFERRED_REGION = getPreferredServerRegion();
|
const PREF_PREFERRED_REGION = getPreferredServerRegion();
|
||||||
const PREF_LATEST_VERSION = PREFS.get(Preferences.LATEST_VERSION, null);
|
const PREF_LATEST_VERSION = PREFS.get(Preferences.LATEST_VERSION);
|
||||||
|
|
||||||
// Setup Settings button
|
// Setup Settings button
|
||||||
const $button = CE('button', {'class': 'better-xcloud-settings-button'}, PREF_PREFERRED_REGION);
|
const $button = CE('button', {'class': 'better-xcloud-settings-button'}, PREF_PREFERRED_REGION);
|
||||||
@ -2924,12 +2934,20 @@ function updateVideoPlayerCss() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const PREF_RATIO = PREFS.get(Preferences.VIDEO_RATIO);
|
const PREF_RATIO = PREFS.get(Preferences.VIDEO_RATIO);
|
||||||
if (PREF_RATIO) {
|
if (PREF_RATIO && PREF_RATIO !== '16:9') {
|
||||||
const minRatio = 16 / 9;
|
if (PREF_RATIO.includes(':')) {
|
||||||
let maxRatio = window.innerWidth / window.innerHeight;
|
videoCss += `aspect-ratio: ${PREF_RATIO.replace(':', '/')}; object-fit: unset !important;`;
|
||||||
const ratio = Math.min(maxRatio, PREF_RATIO / 9);
|
|
||||||
if (ratio > minRatio) {
|
const tmp = PREF_RATIO.split(':');
|
||||||
videoCss += `aspect-ratio: ${ratio}; width: auto !important; object-fit: unset !important;`;
|
const ratio = parseFloat(tmp[0]) / parseFloat(tmp[1]);
|
||||||
|
const maxRatio = window.innerWidth / window.innerHeight;
|
||||||
|
if (ratio < maxRatio) {
|
||||||
|
videoCss += 'width: fit-content !important;'
|
||||||
|
} else {
|
||||||
|
videoCss += 'height: fit-content !important;'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
videoCss += `object-fit: ${PREF_RATIO} !important;`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2942,6 +2960,7 @@ div[data-testid="media-container"] {
|
|||||||
|
|
||||||
#game-stream video {
|
#game-stream video {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
align-self: center;
|
||||||
${videoCss}
|
${videoCss}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
@ -3243,7 +3262,7 @@ function setupVideoSettingsBar() {
|
|||||||
const $wrapper = CE('div', {'class': 'better-xcloud-quick-settings-bar'},
|
const $wrapper = CE('div', {'class': 'better-xcloud-quick-settings-bar'},
|
||||||
CE('div', {},
|
CE('div', {},
|
||||||
CE('label', {'for': 'better-xcloud-quick-setting-stretch'}, 'Video Ratio'),
|
CE('label', {'for': 'better-xcloud-quick-setting-stretch'}, 'Video Ratio'),
|
||||||
PREFS.toNumberStepper(Preferences.VIDEO_RATIO, onChange, ':9')),
|
PREFS.toElement(Preferences.VIDEO_RATIO, onChange, ':9')),
|
||||||
CE('div', {},
|
CE('div', {},
|
||||||
CE('label', {}, 'Clarity'),
|
CE('label', {}, 'Clarity'),
|
||||||
PREFS.toNumberStepper(Preferences.VIDEO_CLARITY, onChange, '', isSafari)), // disable this feature in Safari
|
PREFS.toNumberStepper(Preferences.VIDEO_CLARITY, onChange, '', isSafari)), // disable this feature in Safari
|
||||||
|
Reference in New Issue
Block a user