diff --git a/CHANGELOG.md b/CHANGELOG.md index 365b3b8..9143bfd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ This file is the source of truth for release notes. The newest entry must match the version in `WandEnhancer/Properties/AssemblyInfo.cs`. +## [1.0.8.4] - 2026-06-10 + +### Fixes + +- Fixed QR code issues on the latest Wand version. +- Fixed application hang that occurred after Wand updates with pending patches. + ## [1.0.8.3] - 2026-06-06 ### Fixes diff --git a/WandEnhancer/Core/EnhancerConfig.cs b/WandEnhancer/Core/EnhancerConfig.cs index d2c8ee7..ec8d985 100644 --- a/WandEnhancer/Core/EnhancerConfig.cs +++ b/WandEnhancer/Core/EnhancerConfig.cs @@ -7,9 +7,6 @@ namespace WandEnhancer.Core { public static class EnhancerConfig { - private const int RemoteWebPanelDefaultPort = 3223; - private static readonly string RemoteWebPanelFallbackUrl = $"http://localhost:{RemoteWebPanelDefaultPort}/remote/"; - public class ResolveContext { public string Placeholder { get; set; } @@ -227,29 +224,6 @@ namespace WandEnhancer.Core SearchHints = new[] { "client-value-changed" }, Target = new Regex(@"#ct\(e,t\)\{t\.push\(e\.onValueSet\(e=>\{this\.status===i\.Connected&&e\.source!==g\.kL\.Remote&&this\.#Me\?\.send\(""client-value-changed"",\{instanceId:this\.#Pe,name:e\.name,value:e\.value,cheatId:e\.cheatId\}\)\}\)\),this\.#Be\(\)\}"), Patch = "#ct(e,t){t.push(e.onValueSet(e=>{this.status===i.Connected&&e.source!==g.kL.Remote&&this.#Me?.send(\"client-value-changed\",{instanceId:this.#Pe,name:e.name,value:e.value,cheatId:e.cheatId}),this.__wandRemoteBridge?.valueChanged({trainerId:this.#ke,target:e.name,value:e.value,oldValue:e.oldValue,source:String(e.source??\"desktop\"),cheatId:e.cheatId})})),this.#Be()}" - }, - new PatchEntry - { - Name = "remoteTooltipPreviewUrl", - SearchHints = new[] { "remote_tooltip.scan_the_qr_code_or_visit_the_site", "remote_tooltip.connect_to_wand_remote" }, - Target = new Regex(@"remoteUrl=""wemodwebsite://remote"""), - Patch = "remoteUrl=globalThis.__wandRemoteBridgeUrl||\"" + RemoteWebPanelFallbackUrl + "\"" - }, - new PatchEntry - { - Name = "remoteQrPreviewUrl", - SearchHints = new[] { "resources/elements/remote-qr-code" }, - Resolver = new ResolveContext - { - Handler = (matchContent) => - { - var match = Regex.Match(matchContent, @"this\.canvasElement&&(\w+)\.mo"); - return match.Success ? match.Groups[1].Value : null; - }, - Placeholder = "" - }, - Target = new Regex(@"this\.canvasElement&&\w+\.mo\(this\.canvasElement,`\$\{\w+\.A\.wemodWebsiteUrl\}/remote`,this\.options\)"), - Patch = "this.canvasElement&&.mo(this.canvasElement,globalThis.__wandRemoteBridgeUrl||\"" + RemoteWebPanelFallbackUrl + "\",this.options)" } } } diff --git a/WandEnhancer/Properties/AssemblyInfo.cs b/WandEnhancer/Properties/AssemblyInfo.cs index 24d5bef..fcb2d6b 100644 --- a/WandEnhancer/Properties/AssemblyInfo.cs +++ b/WandEnhancer/Properties/AssemblyInfo.cs @@ -51,5 +51,5 @@ using System.Windows; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.8.3")] -[assembly: AssemblyFileVersion("1.0.8.3")] \ No newline at end of file +[assembly: AssemblyVersion("1.0.8.4")] +[assembly: AssemblyFileVersion("1.0.8.4")] \ No newline at end of file diff --git a/web-panel/bridge/scripts/default/remote-popup-cleanup.js b/web-panel/bridge/scripts/default/remote-popup-cleanup.js index 0c0e4b8..a4a8ad2 100644 --- a/web-panel/bridge/scripts/default/remote-popup-cleanup.js +++ b/web-panel/bridge/scripts/default/remote-popup-cleanup.js @@ -1,3 +1,8 @@ +import { + getWebpackRequire, + isRecord, +} from "./installed-apps-sync/runtime.js" + ;(function installRemotePopupCleanup(WandEnhancer) { if (globalThis.__wandRemotePopupCleanupInstalled) { return @@ -8,14 +13,13 @@ const style = document.createElement("style") style.id = "wand-remote-popup-cleanup-style" style.textContent = ` - .pro-onboarding-card--remote { + article.pro-onboarding-card--remote { display: none !important; } remote-tooltip .remote-tooltip .top-wrapper, remote-tooltip .remote-tooltip .remote-tooltip-section-divider, remote-tooltip .remote-tooltip .instructions .header, - remote-tooltip .remote-tooltip .instructions .content .text, remote-tooltip .remote-tooltip .instructions .platforms { display: none !important; } @@ -29,15 +33,15 @@ remote-tooltip .remote-tooltip .instructions, remote-tooltip .remote-tooltip .instructions .content { display: flex !important; + flex-direction: column !important; align-items: center !important; justify-content: center !important; padding: 0 !important; - gap: 0 !important; + gap: 12px !important; } remote-tooltip .remote-tooltip .instructions remote-qr-code { - all: unset !important; - --wand-qr-size: clamp(220px, 100vw, 300px); + --wand-qr-size: clamp(180px, 70vw, 240px); width: var(--wand-qr-size) !important; height: var(--wand-qr-size) !important; min-width: var(--wand-qr-size) !important; @@ -53,6 +57,12 @@ box-shadow: 0 18px 48px rgba(0, 0, 0, 0.35) !important; } + remote-tooltip .remote-tooltip .instructions .content .text { + display: block !important; + max-width: 250px !important; + overflow-wrap: anywhere !important; + } + remote-tooltip .remote-tooltip .instructions remote-qr-code canvas { width: 100% !important; height: 100% !important; @@ -64,6 +74,8 @@ transform: none !important; } ` + let qrRenderer = null + let refreshScheduled = false const installStyle = () => { if (!document.getElementById(style.id)) { @@ -71,9 +83,31 @@ } } - const updateLinks = () => { - const remoteUrl = - globalThis.__wandRemoteBridgeUrl || WandEnhancer?.remoteUrl + const getRemoteUrl = () => + globalThis.__wandRemoteBridgeUrl || WandEnhancer?.remoteUrl + + const resolveQrRenderer = () => { + if (qrRenderer) { + return qrRenderer + } + + const webpackRequire = getWebpackRequire() + for (const record of Object.values(webpackRequire?.c || {})) { + const exports = record?.exports + if ( + isRecord(exports) && + typeof exports.create === "function" && + typeof exports.mo === "function" + ) { + qrRenderer = exports.mo + return qrRenderer + } + } + + return null + } + + const updateLinks = (remoteUrl) => { if (!remoteUrl) { return } @@ -84,13 +118,48 @@ } } - installStyle() - updateLinks() + const updateQrCodes = async (remoteUrl) => { + const renderQr = remoteUrl && resolveQrRenderer() + if (!renderQr) { + return + } - const observer = new MutationObserver(() => { + for (const canvas of document.querySelectorAll("remote-qr-code canvas")) { + if (canvas.dataset.wandRemoteUrl === remoteUrl) { + continue + } + + try { + await renderQr(canvas, remoteUrl) + canvas.dataset.wandRemoteUrl = remoteUrl + } catch (error) { + WandEnhancer?.log("Failed to render local remote QR code", error) + } + } + } + + const refresh = () => { + const remoteUrl = getRemoteUrl() installStyle() - updateLinks() - }) + updateLinks(remoteUrl) + void updateQrCodes(remoteUrl) + } + + const scheduleRefresh = () => { + if (refreshScheduled) { + return + } + + refreshScheduled = true + setTimeout(() => { + refreshScheduled = false + refresh() + }, 0) + } + + refresh() + + const observer = new MutationObserver(scheduleRefresh) observer.observe(document.documentElement, { childList: true,