Update better-xcloud.user.js

This commit is contained in:
redphx 2024-05-25 09:52:25 +07:00
parent dcbae39042
commit 18027ed1c5

View File

@ -149,6 +149,7 @@ var BxEvent;
BxEvent2["GAME_BAR_ACTION_ACTIVATED"] = "bx-game-bar-action-activated";
BxEvent2["MICROPHONE_STATE_CHANGED"] = "bx-microphone-state-changed";
BxEvent2["CAPTURE_SCREENSHOT"] = "bx-capture-screenshot";
BxEvent2["GAINNODE_VOLUME_CHANGED"] = "bx-gainnode-volume-changed";
})(BxEvent || (BxEvent = {}));
var XcloudEvent;
(function(XcloudEvent2) {
@ -504,6 +505,8 @@ var Texts = {
contrast: "Contrast",
controller: "Controller",
"controller-shortcuts": "Controller shortcuts",
"controller-shortcuts-connect-note": "Connect a controller to use this feature",
"controller-shortcuts-xbox-note": "The Xbox button is the one that opens the Guide menu",
"controller-vibration": "Controller vibration",
copy: "Copy",
custom: "Custom",
@ -565,7 +568,6 @@ var Texts = {
"mkb-click-to-activate": "Click to activate",
"mkb-disclaimer": "Using this feature when playing online could be viewed as cheating",
"mouse-and-keyboard": "Mouse & Keyboard",
"mute-unmute-sound": "Mute/unmute sound",
muted: "Muted",
name: "Name",
new: "New",
@ -667,8 +669,6 @@ var Texts = {
"tc-standard-layout-style": "Standard layout's button style",
"text-size": "Text size",
toggle: "Toggle",
"toggle-microphone": "Toggle microphone",
"toggle-stream-stats": "Toggle stream stats",
"top-center": "Top-center",
"top-left": "Top-left",
"top-right": "Top-right",
@ -932,7 +932,7 @@ class SettingElement {
$range.addEventListener("input", (e) => {
value = parseInt(e.target.value);
$text.textContent = renderTextValue(value);
onChange && onChange(e, value);
!e.ignoreOnChange && onChange && onChange(e, value);
});
$wrapper.appendChild($range);
if (options.ticks || options.exactTicks) {
@ -2270,6 +2270,7 @@ class Preferences {
value = this.#validateValue(key, value);
this.#prefs[key] = value;
this.#updateStorage();
return value;
}
#updateStorage() {
this.#storage.setItem(this.#key, JSON.stringify(this.#prefs));
@ -2340,7 +2341,7 @@ class Toast {
Toast.#timeout && clearTimeout(Toast.#timeout);
Toast.#timeout = window.setTimeout(Toast.#hide, Toast.#DURATION);
const [msg, status, options] = Toast.#stack.shift();
if (options.html) {
if (options && options.html) {
Toast.#$msg.innerHTML = msg;
} else {
Toast.#$msg.textContent = msg;
@ -3167,13 +3168,22 @@ class MkbHandler {
}
// src/modules/shortcuts/shortcut-microphone.ts
var MicrophoneState;
(function(MicrophoneState2) {
MicrophoneState2["REQUESTED"] = "Requested";
MicrophoneState2["ENABLED"] = "Enabled";
MicrophoneState2["MUTED"] = "Muted";
MicrophoneState2["NOT_ALLOWED"] = "NotAllowed";
MicrophoneState2["NOT_FOUND"] = "NotFound";
})(MicrophoneState || (MicrophoneState = {}));
class MicrophoneShortcut {
static toggle(showToast = true) {
if (!window.BX_EXPOSED.streamSession) {
return false;
}
const state = window.BX_EXPOSED.streamSession._microphoneState;
const enableMic = state === "Enabled" ? false : true;
const enableMic = state === MicrophoneState.ENABLED ? false : true;
try {
window.BX_EXPOSED.streamSession.tryEnableChatAsync(enableMic);
showToast && Toast.show(t("microphone"), t(enableMic ? "unmuted" : "muted"), { instant: true });
@ -3192,6 +3202,96 @@ class StreamUiShortcut {
}
}
// src/utils/utils.ts
function checkForUpdate() {
const CHECK_INTERVAL_SECONDS = 7200;
const currentVersion = getPref(PrefKey.CURRENT_VERSION);
const lastCheck = getPref(PrefKey.LAST_UPDATE_CHECK);
const now = Math.round(+new Date / 1000);
if (currentVersion === SCRIPT_VERSION && now - lastCheck < CHECK_INTERVAL_SECONDS) {
return;
}
setPref(PrefKey.LAST_UPDATE_CHECK, now);
fetch("https://api.github.com/repos/redphx/better-xcloud/releases/latest").then((response) => response.json()).then((json) => {
setPref(PrefKey.LATEST_VERSION, json.tag_name.substring(1));
setPref(PrefKey.CURRENT_VERSION, SCRIPT_VERSION);
});
Translations.updateTranslations(true);
}
function disablePwa() {
const userAgent2 = (window.navigator.orgUserAgent || window.navigator.userAgent || "").toLowerCase();
if (!userAgent2) {
return;
}
if (!!AppInterface || UserAgent.isSafari(true)) {
Object.defineProperty(window.navigator, "standalone", {
value: true
});
}
}
function hashCode(str2) {
let hash = 0;
for (let i = 0, len = str2.length;i < len; i++) {
const chr = str2.charCodeAt(i);
hash = (hash << 5) - hash + chr;
hash |= 0;
}
return hash;
}
function renderString(str2, obj) {
return str2.replace(/\$\{.+?\}/g, (match) => {
const key = match.substring(2, match.length - 1);
if (key in obj) {
return obj[key];
}
return match;
});
}
function ceilToNearest(value, interval) {
return Math.ceil(value / interval) * interval;
}
function floorToNearest(value, interval) {
return Math.floor(value / interval) * interval;
}
// src/modules/shortcuts/shortcut-sound.ts
class SoundShortcut {
static increaseGainNodeVolume(amount) {
SoundShortcut.#adjustGainNodeVolume(amount);
}
static decreaseGainNodeVolume(amount) {
SoundShortcut.#adjustGainNodeVolume(-1 * Math.abs(amount));
}
static #adjustGainNodeVolume(amount) {
if (!getPref(PrefKey.AUDIO_ENABLE_VOLUME_CONTROL)) {
return 0;
}
const currentValue = getPref(PrefKey.AUDIO_VOLUME);
let nearestValue;
if (amount > 0) {
nearestValue = ceilToNearest(currentValue, amount);
} else {
nearestValue = floorToNearest(currentValue, -1 * amount);
}
let newValue;
if (currentValue !== nearestValue) {
newValue = nearestValue;
} else {
newValue = currentValue + amount;
}
newValue = setPref(PrefKey.AUDIO_VOLUME, newValue);
SoundShortcut.setGainNodeVolume(newValue);
Toast.show(`${t("stream")} ${t("volume")}`, newValue + "%", { instant: true });
BxEvent.dispatch(window, BxEvent.GAINNODE_VOLUME_CHANGED, {
volume: newValue
});
return newValue;
}
static setGainNodeVolume(value) {
STATES.currentStream.audioGainNode && (STATES.currentStream.audioGainNode.gain.value = value / 100);
}
}
// src/modules/controller-shortcut.ts
var ShortcutAction;
(function(ShortcutAction2) {
@ -3256,6 +3356,12 @@ class ControllerShortcut {
case ShortcutAction.STREAM_MENU_TOGGLE:
StreamUiShortcut.showHideStreamMenu();
break;
case ShortcutAction.STREAM_VOLUME_INC:
SoundShortcut.increaseGainNodeVolume(10);
break;
case ShortcutAction.STREAM_VOLUME_DEC:
SoundShortcut.decreaseGainNodeVolume(10);
break;
}
}
static #updateAction(profile, button, action) {
@ -3349,7 +3455,9 @@ class ControllerShortcut {
[ShortcutAction.STREAM_SCREENSHOT_CAPTURE]: [t("stream"), t("take-screenshot")],
[ShortcutAction.STREAM_STATS_TOGGLE]: [t("stream"), t("stats"), t("show-hide")],
[ShortcutAction.STREAM_MICROPHONE_TOGGLE]: [t("stream"), t("microphone"), t("toggle")],
[ShortcutAction.STREAM_MENU_TOGGLE]: [t("stream"), t("menu"), t("show")]
[ShortcutAction.STREAM_MENU_TOGGLE]: [t("stream"), t("menu"), t("show")],
[ShortcutAction.STREAM_VOLUME_INC]: getPref(PrefKey.AUDIO_ENABLE_VOLUME_CONTROL) && [t("stream"), t("volume"), t("increase")],
[ShortcutAction.STREAM_VOLUME_DEC]: getPref(PrefKey.AUDIO_ENABLE_VOLUME_CONTROL) && [t("stream"), t("volume"), t("decrease")]
}
};
const $baseSelect = CE("select", { autocomplete: "off" }, CE("option", { value: "" }, "---"));
@ -3365,7 +3473,7 @@ class ControllerShortcut {
continue;
}
if (Array.isArray(label)) {
label = label.join(" > ");
label = label.join(" ");
}
const $option = CE("option", { value: action }, label);
$optGroup.appendChild($option);
@ -3705,15 +3813,6 @@ class TouchControlAction extends BaseGameBarAction {
}
// src/modules/game-bar/action-microphone.ts
var MicrophoneState;
(function(MicrophoneState2) {
MicrophoneState2["REQUESTED"] = "Requested";
MicrophoneState2["ENABLED"] = "Enabled";
MicrophoneState2["MUTED"] = "Muted";
MicrophoneState2["NOT_ALLOWED"] = "NotAllowed";
MicrophoneState2["NOT_FOUND"] = "NotFound";
})(MicrophoneState || (MicrophoneState = {}));
class MicrophoneAction extends BaseGameBarAction {
$content;
visible = false;
@ -4680,10 +4779,19 @@ var setupQuickSettingsBar = function() {
pref: PrefKey.AUDIO_VOLUME,
label: t("volume"),
onChange: (e, value) => {
STATES.currentStream.audioGainNode && (STATES.currentStream.audioGainNode.gain.value = value / 100);
SoundShortcut.setGainNodeVolume(value);
},
params: {
disabled: !getPref(PrefKey.AUDIO_ENABLE_VOLUME_CONTROL)
},
onMounted: ($elm) => {
const $range = $elm.querySelector("input[type=range");
window.addEventListener(BxEvent.GAINNODE_VOLUME_CHANGED, (e) => {
$range.value = e.volume;
BxEvent.dispatch($range, "input", {
ignoreOnChange: true
});
});
}
}
]
@ -7135,52 +7243,6 @@ class MouseCursorHider {
}
}
// src/utils/utils.ts
function checkForUpdate() {
const CHECK_INTERVAL_SECONDS = 7200;
const currentVersion = getPref(PrefKey.CURRENT_VERSION);
const lastCheck = getPref(PrefKey.LAST_UPDATE_CHECK);
const now = Math.round(+new Date / 1000);
if (currentVersion === SCRIPT_VERSION && now - lastCheck < CHECK_INTERVAL_SECONDS) {
return;
}
setPref(PrefKey.LAST_UPDATE_CHECK, now);
fetch("https://api.github.com/repos/redphx/better-xcloud/releases/latest").then((response) => response.json()).then((json) => {
setPref(PrefKey.LATEST_VERSION, json.tag_name.substring(1));
setPref(PrefKey.CURRENT_VERSION, SCRIPT_VERSION);
});
Translations.updateTranslations(true);
}
function disablePwa() {
const userAgent2 = (window.navigator.orgUserAgent || window.navigator.userAgent || "").toLowerCase();
if (!userAgent2) {
return;
}
if (!!AppInterface || UserAgent.isSafari(true)) {
Object.defineProperty(window.navigator, "standalone", {
value: true
});
}
}
function hashCode(str2) {
let hash = 0;
for (let i = 0, len = str2.length;i < len; i++) {
const chr = str2.charCodeAt(i);
hash = (hash << 5) - hash + chr;
hash |= 0;
}
return hash;
}
function renderString(str2, obj) {
return str2.replace(/\$\{.+?\}/g, (match) => {
const key = match.substring(2, match.length - 1);
if (key in obj) {
return obj[key];
}
return match;
});
}
// src/modules/patches/controller-shortcuts.js
var controller_shortcuts_default = "const currentGamepad = ${gamepadVar};\n\n// Share button on XS controller\nif (currentGamepad.buttons[17] && currentGamepad.buttons[17].value === 1) {\n window.dispatchEvent(new Event(BxEvent.CAPTURE_SCREENSHOT));\n}\n\nconst btnHome = currentGamepad.buttons[16];\nif (btnHome) {\n if (!this.bxHomeStates) {\n this.bxHomeStates = {};\n }\n\n if (btnHome.pressed) {\n this.gamepadIsIdle.set(currentGamepad.index, false);\n\n if (this.bxHomeStates[currentGamepad.index]) {\n const lastTimestamp = this.bxHomeStates[currentGamepad.index].timestamp;\n\n if (currentGamepad.timestamp !== lastTimestamp) {\n this.bxHomeStates[currentGamepad.index].timestamp = currentGamepad.timestamp;\n\n const handled = window.BX_EXPOSED.handleControllerShortcut(currentGamepad);\n if (handled) {\n this.bxHomeStates[currentGamepad.index].shortcutPressed += 1;\n }\n }\n } else {\n // First time pressing > save current timestamp\n window.BX_EXPOSED.resetControllerShortcut(currentGamepad.index);\n this.bxHomeStates[currentGamepad.index] = {\n shortcutPressed: 0,\n timestamp: currentGamepad.timestamp,\n };\n }\n\n // Listen to next button press\n const intervalMs = 50;\n this.inputConfiguration.useIntervalWorkerThreadForInput && this.intervalWorker ? this.intervalWorker.scheduleTimer(intervalMs) : this.pollGamepadssetTimeoutTimerID = setTimeout(this.pollGamepads, intervalMs);\n\n // Hijack this button\n return;\n } else if (this.bxHomeStates[currentGamepad.index]) {\n const info = structuredClone(this.bxHomeStates[currentGamepad.index]);\n\n // Home button released\n this.bxHomeStates[currentGamepad.index] = null;\n\n if (info.shortcutPressed === 0) {\n const fakeGamepadMappings = [{\n GamepadIndex: currentGamepad.index,\n A: 0,\n B: 0,\n X: 0,\n Y: 0,\n LeftShoulder: 0,\n RightShoulder: 0,\n LeftTrigger: 0,\n RightTrigger: 0,\n View: 0,\n Menu: 0,\n LeftThumb: 0,\n RightThumb: 0,\n DPadUp: 0,\n DPadDown: 0,\n DPadLeft: 0,\n DPadRight: 0,\n Nexus: 1,\n LeftThumbXAxis: 0,\n LeftThumbYAxis: 0,\n RightThumbXAxis: 0,\n RightThumbYAxis: 0,\n PhysicalPhysicality: 0,\n VirtualPhysicality: 0,\n Dirty: true,\n Virtual: false,\n }];\n\n const isLongPress = (currentGamepad.timestamp - info.timestamp) >= 500;\n const intervalMs = isLongPress ? 500 : 100;\n\n this.inputSink.onGamepadInput(performance.now() - intervalMs, fakeGamepadMappings);\n this.inputConfiguration.useIntervalWorkerThreadForInput && this.intervalWorker ? this.intervalWorker.scheduleTimer(intervalMs) : this.pollGamepadssetTimeoutTimerID = setTimeout(this.pollGamepads, intervalMs);\n return;\n }\n }\n}\n";