Compare commits

...

4 Commits

Author SHA1 Message Date
cc9a644a5e Bump version to 1.15.1 2023-09-08 17:24:05 +07:00
a77db68afb Bump version to 1.15.1 2023-09-08 17:23:46 +07:00
cd7a7c92c7 Validate settings when getting its values 2023-09-08 17:16:38 +07:00
651402a6b4 Restore stretch to full screen feature 2023-09-08 17:15:45 +07:00
2 changed files with 76 additions and 57 deletions

View File

@ -1,5 +1,5 @@
// ==UserScript==
// @name Better xCloud
// @namespace https://github.com/redphx
// @version 1.15
// @version 1.15.1
// ==/UserScript==

View File

@ -1,7 +1,7 @@
// ==UserScript==
// @name Better xCloud
// @namespace https://github.com/redphx
// @version 1.15
// @version 1.15.1
// @description Improve Xbox Cloud Gaming (xCloud) experience
// @author redphx
// @license MIT
@ -13,7 +13,7 @@
// ==/UserScript==
'use strict';
const SCRIPT_VERSION = '1.15';
const SCRIPT_VERSION = '1.15.1';
const SCRIPT_HOME = 'https://github.com/redphx/better-xcloud';
console.log(`[Better xCloud] readyState: ${document.readyState}`);
@ -1314,24 +1314,30 @@ class Preferences {
'max': 5,
},
[Preferences.VIDEO_RATIO]: {
'default': 16,
'min': 16,
'max': 21,
'steps': 1,
'default': '16:9',
'options': {
'16:9': '16:9',
'21:9': '21:9',
'16:10': '16:10',
'4:3': '4:3',
'fill': 'Stretch',
'cover': 'Cover',
},
},
[Preferences.VIDEO_SATURATION]: {
'default': 100,
'min': 0,
'min': 50,
'max': 150,
},
[Preferences.VIDEO_CONTRAST]: {
'default': 100,
'min': 0,
'min': 50,
'max': 150,
},
[Preferences.VIDEO_BRIGHTNESS]: {
'default': 100,
'min': 0,
'min': 50,
'max': 150,
},
[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') {
debugger;
return;
@ -1422,46 +1464,14 @@ class Preferences {
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;
}
if (defaultValue !== null) {
return defaultValue;
}
// Return default value
return Preferences.SETTINGS[key].default;
return value;
}
set(key, value) {
const config = Preferences.SETTINGS[key];
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;
}
}
}
value = this.#validateValue(key, value);
this._prefs[key] = value;
this._update_storage();
@ -1643,8 +1653,8 @@ const PREFS = new Preferences();
function checkForUpdate() {
const CHECK_INTERVAL_SECONDS = 4 * 3600; // check every 4 hours
const currentVersion = PREFS.get(Preferences.CURRENT_VERSION, '');
const lastCheck = PREFS.get(Preferences.LAST_UPDATE_CHECK, 0);
const currentVersion = PREFS.get(Preferences.CURRENT_VERSION);
const lastCheck = PREFS.get(Preferences.LAST_UPDATE_CHECK);
const now = Math.round((+new Date) / 1000);
if (currentVersion === SCRIPT_VERSION && now - lastCheck < CHECK_INTERVAL_SECONDS) {
@ -2663,7 +2673,7 @@ function injectSettingsButton($parent) {
const CE = createElement;
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
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);
if (PREF_RATIO) {
const minRatio = 16 / 9;
let maxRatio = window.innerWidth / window.innerHeight;
const ratio = Math.min(maxRatio, PREF_RATIO / 9);
if (ratio > minRatio) {
videoCss += `aspect-ratio: ${ratio}; width: auto !important; object-fit: unset !important;`;
if (PREF_RATIO && PREF_RATIO !== '16:9') {
if (PREF_RATIO.includes(':')) {
videoCss += `aspect-ratio: ${PREF_RATIO.replace(':', '/')}; object-fit: unset !important;`;
const tmp = PREF_RATIO.split(':');
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 {
margin: 0 auto;
align-self: center;
${videoCss}
}
`;
@ -3243,7 +3262,7 @@ function setupVideoSettingsBar() {
const $wrapper = CE('div', {'class': 'better-xcloud-quick-settings-bar'},
CE('div', {},
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('label', {}, 'Clarity'),
PREFS.toNumberStepper(Preferences.VIDEO_CLARITY, onChange, '', isSafari)), // disable this feature in Safari