mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-06-06 07:37:19 +02:00
Update better-xcloud.user.js
This commit is contained in:
parent
dcbae39042
commit
18027ed1c5
190
dist/better-xcloud.user.js
vendored
190
dist/better-xcloud.user.js
vendored
@ -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";
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user