Add "Enable microphone on game launch" setting (#89)

* Add "Enable microphone on game launch" setting

* Stream menu: clone the second last button instead of the first one (usually the mic button)

* Close the HUD when clicking clicking on the Video Settings button

* Use a different CSS for the Stream Stats button when it's ON
This commit is contained in:
redphx 2023-08-12 14:52:27 +07:00 committed by GitHub
parent 8315cee7ec
commit 43b932f5d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -477,7 +477,7 @@ class StreamStats {
static #quickGlanceObserver; static #quickGlanceObserver;
static start(glancing=false) { static start(glancing=false) {
if (!StreamStats.isHidden() || (glancing && StreamStats.#isGlancing())) { if (!StreamStats.isHidden() || (glancing && StreamStats.isGlancing())) {
return; return;
} }
@ -488,7 +488,7 @@ class StreamStats {
} }
static stop(glancing=false) { static stop(glancing=false) {
if (glancing && !StreamStats.#isGlancing()) { if (glancing && !StreamStats.isGlancing()) {
return; return;
} }
@ -501,7 +501,7 @@ class StreamStats {
} }
static toggle() { static toggle() {
if (StreamStats.#isGlancing()) { if (StreamStats.isGlancing()) {
StreamStats.#$container.setAttribute('data-display', 'fixed'); StreamStats.#$container.setAttribute('data-display', 'fixed');
} else { } else {
StreamStats.isHidden() ? StreamStats.start() : StreamStats.stop(); StreamStats.isHidden() ? StreamStats.start() : StreamStats.stop();
@ -515,7 +515,7 @@ class StreamStats {
} }
static isHidden = () => StreamStats.#$container.classList.contains('better-xcloud-gone'); static isHidden = () => StreamStats.#$container.classList.contains('better-xcloud-gone');
static #isGlancing = () => StreamStats.#$container.getAttribute('data-display') === 'glancing'; static isGlancing = () => StreamStats.#$container.getAttribute('data-display') === 'glancing';
static quickGlanceSetup() { static quickGlanceSetup() {
if (StreamStats.#quickGlanceObserver) { if (StreamStats.#quickGlanceObserver) {
@ -623,7 +623,7 @@ class StreamStats {
static hideSettingsUi() { static hideSettingsUi() {
StreamStats.#$settings.style.display = 'none'; StreamStats.#$settings.style.display = 'none';
if (StreamStats.#isGlancing() && !PREFS.get(Preferences.STATS_QUICK_GLANCE)) { if (StreamStats.isGlancing() && !PREFS.get(Preferences.STATS_QUICK_GLANCE)) {
StreamStats.stop(); StreamStats.stop();
} }
} }
@ -835,6 +835,8 @@ class Preferences {
static get VIDEO_CONTRAST() { return 'video_contrast'; } static get VIDEO_CONTRAST() { return 'video_contrast'; }
static get VIDEO_SATURATION() { return 'video_saturation'; } static get VIDEO_SATURATION() { return 'video_saturation'; }
static get AUDIO_MIC_ON_PLAYING() { return 'audio_mic_on_playing'; }
static get STATS_SHOW_WHEN_PLAYING() { return 'stats_show_when_playing'; } static get STATS_SHOW_WHEN_PLAYING() { return 'stats_show_when_playing'; }
static get STATS_QUICK_GLANCE() { return 'stats_quick_glance'; } static get STATS_QUICK_GLANCE() { return 'stats_quick_glance'; }
static get STATS_POSITION() { return 'stats_position'; } static get STATS_POSITION() { return 'stats_position'; }
@ -975,6 +977,9 @@ class Preferences {
'min': 0, 'min': 0,
'max': 150, 'max': 150,
}, },
[Preferences.AUDIO_MIC_ON_PLAYING]: {
'default': false,
},
[Preferences.STATS_SHOW_WHEN_PLAYING]: { [Preferences.STATS_SHOW_WHEN_PLAYING]: {
'default': false, 'default': false,
}, },
@ -1601,6 +1606,12 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
font-family: Consolas, "Courier New", Courier, monospace; font-family: Consolas, "Courier New", Courier, monospace;
} }
.better-xcloud-stream-menu-button-on {
fill: #000 !important;
background-color: #fff !important;
color: #000 !important;
}
#better-xcloud-touch-controller-bar { #better-xcloud-touch-controller-bar {
display: none; display: none;
opacity: 0; opacity: 0;
@ -1851,9 +1862,12 @@ function interceptHttpRequests() {
const PREF_PREFER_IPV6_SERVER = PREFS.get(Preferences.PREFER_IPV6_SERVER); const PREF_PREFER_IPV6_SERVER = PREFS.get(Preferences.PREFER_IPV6_SERVER);
const PREF_STREAM_TARGET_RESOLUTION = PREFS.get(Preferences.STREAM_TARGET_RESOLUTION); const PREF_STREAM_TARGET_RESOLUTION = PREFS.get(Preferences.STREAM_TARGET_RESOLUTION);
const PREF_STREAM_PREFERRED_LOCALE = PREFS.get(Preferences.STREAM_PREFERRED_LOCALE); const PREF_STREAM_PREFERRED_LOCALE = PREFS.get(Preferences.STREAM_PREFERRED_LOCALE);
const PREF_STREAM_TOUCH_CONTROLLER = PREFS.get(Preferences.STREAM_TOUCH_CONTROLLER);
const PREF_USE_DESKTOP_CODEC = PREFS.get(Preferences.USE_DESKTOP_CODEC); const PREF_USE_DESKTOP_CODEC = PREFS.get(Preferences.USE_DESKTOP_CODEC);
const PREF_STREAM_TOUCH_CONTROLLER = PREFS.get(Preferences.STREAM_TOUCH_CONTROLLER);
const PREF_AUDIO_MIC_ON_PLAYING = PREFS.get(Preferences.AUDIO_MIC_ON_PLAYING);
const PREF_OVERRIDE_CONFIGURATION = PREF_AUDIO_MIC_ON_PLAYING || PREF_STREAM_TOUCH_CONTROLLER === 'all';
const orgFetch = window.fetch; const orgFetch = window.fetch;
window.fetch = async (...arg) => { window.fetch = async (...arg) => {
const request = arg[0]; const request = arg[0];
@ -1933,8 +1947,13 @@ function interceptHttpRequests() {
return orgFetch(...arg); return orgFetch(...arg);
} }
if (PREF_STREAM_TOUCH_CONTROLLER === 'all' && url.endsWith('/configuration') && url.includes('/sessions/cloud/') && request.method === 'GET') { if (PREF_OVERRIDE_CONFIGURATION && url.endsWith('/configuration') && url.includes('/sessions/cloud/') && request.method === 'GET') {
const promise = orgFetch(...arg);
// Touch controller for all games
if (PREF_STREAM_TOUCH_CONTROLLER === 'all') {
TouchController.disable(); TouchController.disable();
// Get game ID from window.location // Get game ID from window.location
const match = window.location.pathname.match(/\/launch\/[^\/]+\/([\w\d]+)/); const match = window.location.pathname.match(/\/launch\/[^\/]+\/([\w\d]+)/);
// Check touch support // Check touch support
@ -1942,12 +1961,13 @@ function interceptHttpRequests() {
TouchController.enable(); TouchController.enable();
} }
const promise = orgFetch(...arg); // If both settings are invalid -> return promise
if (!TouchController.isEnabled()) { if (!PREF_AUDIO_MIC_ON_PLAYING && !TouchController.isEnabled()) {
return promise; return promise;
} }
}
// Intercept result to make xCloud show the touch controller // Intercept configurations
return promise.then(response => { return promise.then(response => {
return response.clone().text().then(text => { return response.clone().text().then(text => {
if (!text.length) { if (!text.length) {
@ -1957,9 +1977,18 @@ function interceptHttpRequests() {
const obj = JSON.parse(text); const obj = JSON.parse(text);
let overrides = JSON.parse(obj.clientStreamingConfigOverrides || '{}') || {}; let overrides = JSON.parse(obj.clientStreamingConfigOverrides || '{}') || {};
// Enable touch controller
if (TouchController.isEnabled()) {
overrides.inputConfiguration = overrides.inputConfiguration || {}; overrides.inputConfiguration = overrides.inputConfiguration || {};
overrides.inputConfiguration.enableTouchInput = true; overrides.inputConfiguration.enableTouchInput = true;
overrides.inputConfiguration.maxTouchPoints = 10; overrides.inputConfiguration.maxTouchPoints = 10;
}
// Enable mic
if (PREF_AUDIO_MIC_ON_PLAYING) {
overrides.audioConfiguration = overrides.audioConfiguration || {};
overrides.audioConfiguration.enableMicrophone = true;
}
obj.clientStreamingConfigOverrides = JSON.stringify(overrides); obj.clientStreamingConfigOverrides = JSON.stringify(overrides);
@ -2085,10 +2114,11 @@ function injectSettingsButton($parent) {
[Preferences.STREAM_PREFERRED_LOCALE]: 'Preferred game\'s language', [Preferences.STREAM_PREFERRED_LOCALE]: 'Preferred game\'s language',
[Preferences.PREFER_IPV6_SERVER]: 'Prefer IPv6 server', [Preferences.PREFER_IPV6_SERVER]: 'Prefer IPv6 server',
}, },
'Stream quality': { 'Video/Audio': {
[Preferences.STREAM_TARGET_RESOLUTION]: 'Target resolution', [Preferences.STREAM_TARGET_RESOLUTION]: 'Target resolution',
[Preferences.USE_DESKTOP_CODEC]: 'Force high-quality codec', [Preferences.USE_DESKTOP_CODEC]: 'Force high-quality codec',
[Preferences.DISABLE_BANDWIDTH_CHECKING]: 'Disable bandwidth checking', [Preferences.DISABLE_BANDWIDTH_CHECKING]: 'Disable bandwidth checking',
[Preferences.AUDIO_MIC_ON_PLAYING]: 'Enable microphone on game launch',
}, },
'Controller': { 'Controller': {
[Preferences.STREAM_TOUCH_CONTROLLER]: 'Touch controller', [Preferences.STREAM_TOUCH_CONTROLLER]: 'Touch controller',
@ -2306,7 +2336,7 @@ function cloneStreamMenuButton($orgButton, label, svg_icon) {
} }
function injectVideoSettingsButton() { function injectStreamMenuButtons() {
const $screen = document.querySelector('#PageContent section[class*=PureScreens]'); const $screen = document.querySelector('#PageContent section[class*=PureScreens]');
if (!$screen) { if (!$screen) {
return; return;
@ -2348,7 +2378,8 @@ function injectVideoSettingsButton() {
return; return;
} }
const $orgButton = node.querySelector('div > div > button'); // Get the second last button
const $orgButton = node.querySelector('div > div > button:nth-last-child(2)');
if (!$orgButton) { if (!$orgButton) {
return; return;
} }
@ -2359,6 +2390,9 @@ function injectVideoSettingsButton() {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
// Close HUD
$btnCloseHud.click();
// Show Quick settings bar // Show Quick settings bar
$quickBar.style.display = 'flex'; $quickBar.style.display = 'flex';
@ -2390,6 +2424,9 @@ function injectVideoSettingsButton() {
StreamStats.toggle(); StreamStats.toggle();
}); });
const btnStreamStatsOn = (!StreamStats.isHidden() && !StreamStats.isGlancing());
$btnStreamStats.classList.toggle('better-xcloud-stream-menu-button-on', btnStreamStatsOn);
// Insert after Video Settings button // Insert after Video Settings button
$orgButton.parentElement.insertBefore($btnStreamStats, $btnVideoSettings); $orgButton.parentElement.insertBefore($btnStreamStats, $btnVideoSettings);
@ -2461,7 +2498,7 @@ function patchVideoApi() {
} }
this.addEventListener('playing', showFunc); this.addEventListener('playing', showFunc);
injectVideoSettingsButton(); injectStreamMenuButtons();
return this.orgPlay.apply(this); return this.orgPlay.apply(this);
}; };