Simplify Patcher's logs

This commit is contained in:
redphx 2025-02-07 17:10:18 +07:00
parent 4b06d9fcff
commit 85339f09da
3 changed files with 9 additions and 6 deletions

View File

@ -5830,17 +5830,17 @@ class Patcher {
if (cachedPatches) patchesToCheck = cachedPatches.slice(0), patchesToCheck.push(...PATCH_ORDERS);
else patchesToCheck = PATCH_ORDERS.slice(0);
if (!patchesToCheck.length) continue;
let func = chunkData[chunkId], funcStr = func.toString(), patchedFuncStr = funcStr, modified = !1;
let func = chunkData[chunkId], funcStr = func.toString(), patchedFuncStr = funcStr, modified = !1, chunkAppliedPatches = [];
for (let patchIndex = 0;patchIndex < patchesToCheck.length; patchIndex++) {
let patchName = patchesToCheck[patchIndex];
if (appliedPatches.indexOf(patchName) > -1) continue;
if (!PATCHES[patchName]) continue;
let tmpStr = PATCHES[patchName].call(null, patchedFuncStr);
if (!tmpStr) continue;
modified = !0, patchedFuncStr = tmpStr, BxLogger.info(LOG_TAG2, `${patchName}`), appliedPatches.push(patchName), patchesToCheck.splice(patchIndex, 1), patchIndex--, PATCH_ORDERS = PATCH_ORDERS.filter((item2) => item2 != patchName), BxLogger.info(LOG_TAG2, "Remaining patches", PATCH_ORDERS);
modified = !0, patchedFuncStr = tmpStr, appliedPatches.push(patchName), chunkAppliedPatches.push(patchName), patchesToCheck.splice(patchIndex, 1), patchIndex--, PATCH_ORDERS = PATCH_ORDERS.filter((item2) => item2 != patchName);
}
if (modified) {
BX_FLAGS.Debug && console.time(LOG_TAG2);
BxLogger.info(LOG_TAG2, `✅ [${chunkId}] ${chunkAppliedPatches.join(", ")}`), PATCH_ORDERS.length && BxLogger.info(LOG_TAG2, "Remaining patches", PATCH_ORDERS), BX_FLAGS.Debug && console.time(LOG_TAG2);
try {
chunkData[chunkId] = eval(patchedFuncStr);
} catch (e) {

View File

@ -250,7 +250,7 @@ ${subsVar} = subs;
]), STREAM_PAGE_PATCH_ORDERS = PatcherUtils.filterPatches(["exposeInputChannel","patchXcloudTitleInfo","disableGamepadDisconnectedScreen","patchStreamHud","playVibration","alwaysShowStreamHud",getGlobalPref("audio.volume.booster.enabled") && !getGlobalPref("stream.video.combineAudio") && "patchAudioMediaStream",getGlobalPref("audio.volume.booster.enabled") && getGlobalPref("stream.video.combineAudio") && "patchCombinedAudioVideoMediaStream",getGlobalPref("ui.feedbackDialog.disabled") && "skipFeedbackDialog",...STATES.userAgent.capabilities.touch ? [getGlobalPref("touchController.mode") === "all" && "patchShowSensorControls",getGlobalPref("touchController.mode") === "all" && "exposeTouchLayoutManager",(getGlobalPref("touchController.mode") === "off" || getGlobalPref("touchController.autoOff")) && "disableTakRenderer",getGlobalPref("touchController.opacity.default") !== 100 && "patchTouchControlDefaultOpacity",getGlobalPref("touchController.mode") !== "off" && (getGlobalPref("mkb.enabled") || getGlobalPref("nativeMkb.mode") === "on") && "patchBabylonRendererClass"] : [],BX_FLAGS.EnableXcloudLogging && "enableConsoleLogging","patchPollGamepads",getGlobalPref("stream.video.combineAudio") && "streamCombineSources",...getGlobalPref("xhome.enabled") ? ["patchRemotePlayMkb","remotePlayConnectMode"] : [],...AppInterface && getGlobalPref("nativeMkb.mode") === "on" ? ["patchMouseAndKeyboardEnabled","disableNativeRequestPointerLock"] : []
]), PRODUCT_DETAIL_PAGE_PATCH_ORDERS = PatcherUtils.filterPatches(["detectProductDetailPage"
]), ALL_PATCHES = [...PATCH_ORDERS, ...HOME_PAGE_PATCH_ORDERS, ...STREAM_PAGE_PATCH_ORDERS, ...PRODUCT_DETAIL_PAGE_PATCH_ORDERS];
class Patcher {static remainingPatches = {home: HOME_PAGE_PATCH_ORDERS,stream: STREAM_PAGE_PATCH_ORDERS,"product-detail": PRODUCT_DETAIL_PAGE_PATCH_ORDERS};static patchPage(page) {let remaining = Patcher.remainingPatches[page];if (!remaining) return;PATCH_ORDERS = PATCH_ORDERS.concat(remaining), delete Patcher.remainingPatches[page];}static patchNativeBind() {let nativeBind = Function.prototype.bind;Function.prototype.bind = function() {let valid = !1;if (this.name.length <= 2 && arguments.length === 2 && arguments[0] === null) {if (arguments[1] === 0 || typeof arguments[1] === "function") valid = !0;}if (!valid) return nativeBind.apply(this, arguments);if (typeof arguments[1] === "function") BxLogger.info(LOG_TAG2, "Restored Function.prototype.bind()"), Function.prototype.bind = nativeBind;let orgFunc = this, newFunc = (a, item2) => {Patcher.checkChunks(item2), orgFunc(a, item2);};return nativeBind.apply(newFunc, arguments);};}static checkChunks(item) {let patchesToCheck, appliedPatches, chunkData = item[1], patchesMap = {}, patcherCache = PatcherCache.getInstance();for (let chunkId in chunkData) {appliedPatches = [];let cachedPatches = patcherCache.getPatches(chunkId);if (cachedPatches) patchesToCheck = cachedPatches.slice(0), patchesToCheck.push(...PATCH_ORDERS);else patchesToCheck = PATCH_ORDERS.slice(0);if (!patchesToCheck.length) continue;let func = chunkData[chunkId], funcStr = func.toString(), patchedFuncStr = funcStr, modified = !1;for (let patchIndex = 0;patchIndex < patchesToCheck.length; patchIndex++) {let patchName = patchesToCheck[patchIndex];if (appliedPatches.indexOf(patchName) > -1) continue;if (!PATCHES[patchName]) continue;let tmpStr = PATCHES[patchName].call(null, patchedFuncStr);if (!tmpStr) continue;modified = !0, patchedFuncStr = tmpStr, BxLogger.info(LOG_TAG2, `${patchName}`), appliedPatches.push(patchName), patchesToCheck.splice(patchIndex, 1), patchIndex--, PATCH_ORDERS = PATCH_ORDERS.filter((item2) => item2 != patchName), BxLogger.info(LOG_TAG2, "Remaining patches", PATCH_ORDERS);}if (modified) {BX_FLAGS.Debug && console.time(LOG_TAG2);try {chunkData[chunkId] = eval(patchedFuncStr);} catch (e) {if (e instanceof Error) BxLogger.error(LOG_TAG2, "Error", appliedPatches, e.message, patchedFuncStr);}BX_FLAGS.Debug && console.timeEnd(LOG_TAG2);}if (appliedPatches.length) patchesMap[chunkId] = appliedPatches;}if (Object.keys(patchesMap).length) patcherCache.saveToCache(patchesMap);}static init() {Patcher.patchNativeBind();}}
class Patcher {static remainingPatches = {home: HOME_PAGE_PATCH_ORDERS,stream: STREAM_PAGE_PATCH_ORDERS,"product-detail": PRODUCT_DETAIL_PAGE_PATCH_ORDERS};static patchPage(page) {let remaining = Patcher.remainingPatches[page];if (!remaining) return;PATCH_ORDERS = PATCH_ORDERS.concat(remaining), delete Patcher.remainingPatches[page];}static patchNativeBind() {let nativeBind = Function.prototype.bind;Function.prototype.bind = function() {let valid = !1;if (this.name.length <= 2 && arguments.length === 2 && arguments[0] === null) {if (arguments[1] === 0 || typeof arguments[1] === "function") valid = !0;}if (!valid) return nativeBind.apply(this, arguments);if (typeof arguments[1] === "function") BxLogger.info(LOG_TAG2, "Restored Function.prototype.bind()"), Function.prototype.bind = nativeBind;let orgFunc = this, newFunc = (a, item2) => {Patcher.checkChunks(item2), orgFunc(a, item2);};return nativeBind.apply(newFunc, arguments);};}static checkChunks(item) {let patchesToCheck, appliedPatches, chunkData = item[1], patchesMap = {}, patcherCache = PatcherCache.getInstance();for (let chunkId in chunkData) {appliedPatches = [];let cachedPatches = patcherCache.getPatches(chunkId);if (cachedPatches) patchesToCheck = cachedPatches.slice(0), patchesToCheck.push(...PATCH_ORDERS);else patchesToCheck = PATCH_ORDERS.slice(0);if (!patchesToCheck.length) continue;let func = chunkData[chunkId], funcStr = func.toString(), patchedFuncStr = funcStr, modified = !1, chunkAppliedPatches = [];for (let patchIndex = 0;patchIndex < patchesToCheck.length; patchIndex++) {let patchName = patchesToCheck[patchIndex];if (appliedPatches.indexOf(patchName) > -1) continue;if (!PATCHES[patchName]) continue;let tmpStr = PATCHES[patchName].call(null, patchedFuncStr);if (!tmpStr) continue;modified = !0, patchedFuncStr = tmpStr, appliedPatches.push(patchName), chunkAppliedPatches.push(patchName), patchesToCheck.splice(patchIndex, 1), patchIndex--, PATCH_ORDERS = PATCH_ORDERS.filter((item2) => item2 != patchName);}if (modified) {BxLogger.info(LOG_TAG2, `✅ [${chunkId}] ${chunkAppliedPatches.join(", ")}`), PATCH_ORDERS.length && BxLogger.info(LOG_TAG2, "Remaining patches", PATCH_ORDERS), BX_FLAGS.Debug && console.time(LOG_TAG2);try {chunkData[chunkId] = eval(patchedFuncStr);} catch (e) {if (e instanceof Error) BxLogger.error(LOG_TAG2, "Error", appliedPatches, e.message, patchedFuncStr);}BX_FLAGS.Debug && console.timeEnd(LOG_TAG2);}if (appliedPatches.length) patchesMap[chunkId] = appliedPatches;}if (Object.keys(patchesMap).length) patcherCache.saveToCache(patchesMap);}static init() {Patcher.patchNativeBind();}}
class PatcherCache {static instance;static getInstance = () => PatcherCache.instance ?? (PatcherCache.instance = new PatcherCache);KEY_CACHE = "BetterXcloud.Patches.Cache";KEY_SIGNATURE = "BetterXcloud.Patches.Cache.Signature";CACHE;constructor() {this.checkSignature(), this.CACHE = JSON.parse(window.localStorage.getItem(this.KEY_CACHE) || "{}"), BxLogger.info(LOG_TAG2, "Cache", this.CACHE);let pathName = window.location.pathname;if (pathName.includes("/play/launch/")) Patcher.patchPage("stream");else if (pathName.includes("/play/games/")) Patcher.patchPage("product-detail");else if (pathName.endsWith("/play") || pathName.endsWith("/play/")) Patcher.patchPage("home");PATCH_ORDERS = this.cleanupPatches(PATCH_ORDERS), STREAM_PAGE_PATCH_ORDERS = this.cleanupPatches(STREAM_PAGE_PATCH_ORDERS), PRODUCT_DETAIL_PAGE_PATCH_ORDERS = this.cleanupPatches(PRODUCT_DETAIL_PAGE_PATCH_ORDERS), BxLogger.info(LOG_TAG2, "PATCH_ORDERS", PATCH_ORDERS.slice(0));}getSignature() {let scriptVersion = SCRIPT_VERSION, patches = JSON.stringify(ALL_PATCHES), webVersion = "", $link = document.querySelector('link[data-chunk="client"][href*="/client."]');if ($link) {let match = /\/client\.([^\.]+)\.js/.exec($link.href);match && (webVersion = match[1]);} else webVersion = document.querySelector("meta[name=gamepass-app-version]")?.content ?? "";return hashCode(scriptVersion + webVersion + patches);}clear() {window.localStorage.removeItem(this.KEY_CACHE), this.CACHE = {};}checkSignature() {let storedSig = window.localStorage.getItem(this.KEY_SIGNATURE) || 0, currentSig = this.getSignature();if (currentSig !== parseInt(storedSig)) BxLogger.warning(LOG_TAG2, "Signature changed"), window.localStorage.setItem(this.KEY_SIGNATURE, currentSig.toString()), this.clear();else BxLogger.info(LOG_TAG2, "Signature unchanged");}cleanupPatches(patches) {return patches.filter((item2) => {for (let id in this.CACHE)if (this.CACHE[id].includes(item2)) return !1;return !0;});}getPatches(id) {return this.CACHE[id];}saveToCache(subCache) {for (let id in subCache) {let patchNames = subCache[id], data = this.CACHE[id];if (!data) this.CACHE[id] = patchNames;else for (let patchName of patchNames)if (!data.includes(patchName)) data.push(patchName);}window.localStorage.setItem(this.KEY_CACHE, JSON.stringify(this.CACHE));}}
class FullscreenText {static instance;static getInstance = () => FullscreenText.instance ?? (FullscreenText.instance = new FullscreenText);LOG_TAG = "FullscreenText";$text;constructor() {BxLogger.info(this.LOG_TAG, "constructor()"), this.$text = CE("div", {class: "bx-fullscreen-text bx-gone"}), document.documentElement.appendChild(this.$text);}show(msg) {document.body.classList.add("bx-no-scroll"), this.$text.classList.remove("bx-gone"), this.$text.textContent = msg;}hide() {document.body.classList.remove("bx-no-scroll"), this.$text.classList.add("bx-gone");}}
class BaseProfileManagerDialog extends NavigationDialog {$container;title;presetsDb;allPresets;currentPresetId = null;activatedPresetId = null;$presets;$header;$defaultNote;$content;$btnRename;$btnDelete;constructor(title, presetsDb) {super();this.title = title, this.presetsDb = presetsDb;}async renderSummary(presetId) {return null;}updateButtonStates() {let isDefaultPreset = this.currentPresetId === null || this.currentPresetId <= 0;this.$btnRename.disabled = isDefaultPreset, this.$btnDelete.disabled = isDefaultPreset, this.$defaultNote.classList.toggle("bx-gone", !isDefaultPreset);}async renderPresetsList() {if (this.allPresets = await this.presetsDb.getPresets(), this.currentPresetId === null) this.currentPresetId = this.allPresets.default[0];renderPresetsList(this.$presets, this.allPresets, this.activatedPresetId, { selectedIndicator: !0 });}promptNewName(action, value = "") {let newName = "";while (!newName) {if (newName = prompt(`[${action}] ${t("prompt-preset-name")}`, value), newName === null) return !1;newName = newName.trim();}return newName ? newName : !1;}async renderDialog() {this.$presets = CE("select", {class: "bx-full-width",tabindex: -1});let $select = BxSelectElement.create(this.$presets);$select.addEventListener("input", (e) => {this.switchPreset(parseInt($select.value));});let $header = CE("div", {class: "bx-dialog-preset-tools",_nearby: {orientation: "horizontal",focus: $select}}, $select, this.$btnRename = createButton({title: t("rename"),icon: BxIcon.CURSOR_TEXT,style: 64,onClick: async () => {let preset = this.allPresets.data[this.currentPresetId], newName = this.promptNewName(t("rename"), preset.name);if (!newName) return;preset.name = newName, await this.presetsDb.updatePreset(preset), await this.refresh();}}), this.$btnDelete = createButton({icon: BxIcon.TRASH,title: t("delete"),style: 4 | 64,onClick: async (e) => {if (!confirm(t("confirm-delete-preset"))) return;await this.presetsDb.deletePreset(this.currentPresetId), delete this.allPresets.data[this.currentPresetId], this.currentPresetId = parseInt(Object.keys(this.allPresets.data)[0]), await this.refresh();}}), createButton({icon: BxIcon.NEW,title: t("new"),style: 64 | 1,onClick: async (e) => {let newName = this.promptNewName(t("new"));if (!newName) return;let newId = await this.presetsDb.newPreset(newName, this.presetsDb.BLANK_PRESET_DATA);this.currentPresetId = newId, await this.refresh();}}), createButton({icon: BxIcon.COPY,title: t("copy"),style: 64 | 1,onClick: async (e) => {let preset = this.allPresets.data[this.currentPresetId], newName = this.promptNewName(t("copy"), `${preset.name} (2)`);if (!newName) return;let newId = await this.presetsDb.newPreset(newName, preset.data);this.currentPresetId = newId, await this.refresh();}}));this.$header = $header, this.$container = CE("div", { class: "bx-centered-dialog" }, CE("div", { class: "bx-dialog-title" }, CE("p", !1, this.title), createButton({icon: BxIcon.CLOSE,style: 64 | 2048 | 8,onClick: (e) => this.hide()})), CE("div", !1, $header, this.$defaultNote = CE("div", { class: "bx-default-preset-note bx-gone" }, t("default-preset-note"))), CE("div", { class: "bx-dialog-content" }, this.$content));}async refresh() {await this.renderPresetsList(), this.$presets.value = this.currentPresetId.toString(), BxEvent.dispatch(this.$presets, "input", { manualTrigger: !0 });}async onBeforeMount(configs = {}) {await this.renderPresetsList();let valid = !1;if (typeof configs?.id === "number") {if (configs.id in this.allPresets.data) this.currentPresetId = configs.id, this.activatedPresetId = configs.id, valid = !0;}if (!valid) this.currentPresetId = this.allPresets.default[0], this.activatedPresetId = null;this.refresh();}getDialog() {return this;}getContent() {if (!this.$container) this.renderDialog();return this.$container;}focusIfNeeded() {this.dialogManager.focus(this.$header);}}

View File

@ -1393,6 +1393,7 @@ export class Patcher {
let patchedFuncStr = funcStr;
let modified = false;
const chunkAppliedPatches = [];
for (let patchIndex = 0; patchIndex < patchesToCheck.length; patchIndex++) {
const patchName = patchesToCheck[patchIndex];
@ -1415,18 +1416,20 @@ export class Patcher {
modified = true;
patchedFuncStr = tmpStr;
BxLogger.info(LOG_TAG, `${patchName}`);
appliedPatches.push(patchName);
chunkAppliedPatches.push(patchName);
// Remove patch
patchesToCheck.splice(patchIndex, 1);
patchIndex--;
PATCH_ORDERS = PATCH_ORDERS.filter(item => item != patchName);
BxLogger.info(LOG_TAG, 'Remaining patches', PATCH_ORDERS);
}
// Apply patched functions
if (modified) {
BxLogger.info(LOG_TAG, `✅ [${chunkId}] ${chunkAppliedPatches.join(', ')}`);
PATCH_ORDERS.length && BxLogger.info(LOG_TAG, 'Remaining patches', PATCH_ORDERS);
BX_FLAGS.Debug && console.time(LOG_TAG);
try {
chunkData[chunkId] = eval(patchedFuncStr);