mirror of
https://github.com/k1tbyte/Wand-Enhancer.git
synced 2026-08-28 17:01:04 +00:00
fix: bump version to 1.0.9.3 and update changelog with recent fixes
This commit is contained in:
@@ -10,13 +10,13 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v4
|
- uses: pnpm/action-setup@v5
|
||||||
with:
|
with:
|
||||||
version: 10
|
version: 10
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v5
|
||||||
with:
|
with:
|
||||||
node-version: 22
|
node-version: 22
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
@@ -27,7 +27,7 @@ jobs:
|
|||||||
run: ./build.ps1 -Configuration Release
|
run: ./build.ps1 -Configuration Release
|
||||||
|
|
||||||
- name: Upload unsigned executable
|
- name: Upload unsigned executable
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: WandEnhancer-unsigned
|
name: WandEnhancer-unsigned
|
||||||
path: WandEnhancer/bin/Release/WandEnhancer.exe
|
path: WandEnhancer/bin/Release/WandEnhancer.exe
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ jobs:
|
|||||||
mirror:
|
mirror:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
|
|||||||
@@ -16,15 +16,15 @@ jobs:
|
|||||||
RELEASE_VERSION: ${{ github.ref_name }}
|
RELEASE_VERSION: ${{ github.ref_name }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v4
|
- uses: pnpm/action-setup@v5
|
||||||
with:
|
with:
|
||||||
version: 10
|
version: 10
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v5
|
||||||
with:
|
with:
|
||||||
node-version: 22
|
node-version: 22
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ jobs:
|
|||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Validate version and changelog sync
|
- name: Validate version and changelog sync
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
|
|||||||
@@ -3,6 +3,13 @@
|
|||||||
This file is the source of truth for release notes.
|
This file is the source of truth for release notes.
|
||||||
The newest entry must match the version in `WandEnhancer/Properties/AssemblyInfo.cs`.
|
The newest entry must match the version in `WandEnhancer/Properties/AssemblyInfo.cs`.
|
||||||
|
|
||||||
|
## [1.0.9.3] - 2026-07-04
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
- Fixed the Remote Web Panel no longer applying on newer Wand builds and reporting "unsupported version". The remote bridge patches now resolve Wand's minified internal names dynamically instead of relying on hardcoded ones that broke on Wand updates. #118 #123 #124 #126
|
||||||
|
- Fixed Pro reverting to Free (with random sign-outs and the return of ads and the time limit) after linking a phone with Wand's mobile activation code. That native pairing triggers a server-side sign-out on a patched client, so the patcher now disables it; use the built-in Remote Web Panel to control Wand from another device instead. #120
|
||||||
|
|
||||||
## [1.0.9.2] - 2026-06-28
|
## [1.0.9.2] - 2026-06-28
|
||||||
|
|
||||||
### Important
|
### Important
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ This repository does not publish official compiled binaries. Build your own exec
|
|||||||
|
|
||||||
*Here how you do it:*
|
*Here how you do it:*
|
||||||
|
|
||||||
https://github.com/user-attachments/assets/b03eeed4-ceb8-45c0-b09c-2b64cf098c64
|
https://github.com/user-attachments/assets/7966cabe-0aa6-424d-8c2f-981ad91e0f91
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -167,6 +167,20 @@ namespace WandEnhancer.Core
|
|||||||
@"const (?<decl>\w+)=""ACTION_SET_ACCOUNT"";function (?<fn>\w+)\((?<params>[^)]*)\)\{return\{\.\.\.(?<state>\w+),account:(?<account>\w+)\}\}",
|
@"const (?<decl>\w+)=""ACTION_SET_ACCOUNT"";function (?<fn>\w+)\((?<params>[^)]*)\)\{return\{\.\.\.(?<state>\w+),account:(?<account>\w+)\}\}",
|
||||||
RegexOptions.Singleline),
|
RegexOptions.Singleline),
|
||||||
PatchFactory = BuildSetAccountReducerPatch
|
PatchFactory = BuildSetAccountReducerPatch
|
||||||
|
},
|
||||||
|
new PatchEntry
|
||||||
|
{
|
||||||
|
// Wand's native "connect phone" pairing (POST /v3/auth/remote_code)
|
||||||
|
// triggers a server-side device handoff that deauthorizes this desktop
|
||||||
|
// session - the reported "entered the mobile activation key and got
|
||||||
|
// signed out" bug. Neutralize the code issuer so native pairing can
|
||||||
|
// never start. The injected remote panel is independent of this flow
|
||||||
|
// (IPC bridge, not Wand's Pusher pairing) and keeps working. The
|
||||||
|
// rejection is swallowed by the caller's try/catch (renders no code).
|
||||||
|
Name = "disableNativeRemotePairing",
|
||||||
|
SearchHints = new[] { "requestRemoteAuthCode", "/v3/auth/remote_code" },
|
||||||
|
Target = new Regex(@"requestRemoteAuthCode\(\)\{return this\.#[\w$]+\.post\(""/v3/auth/remote_code""\)\}"),
|
||||||
|
Patch = "requestRemoteAuthCode(){return Promise.reject(new Error(\"wand-enhancer: native mobile pairing disabled\"))}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -237,17 +251,28 @@ namespace WandEnhancer.Core
|
|||||||
},
|
},
|
||||||
new PatchEntry
|
new PatchEntry
|
||||||
{
|
{
|
||||||
|
// Inject the bridge init + setHandler right after the method's opening
|
||||||
|
// brace; the rest of setCurrentTrainer is left untouched. Only `${trainer}`
|
||||||
|
// (active-trainer field) and `${remoteSource}` (value-source enum, taken
|
||||||
|
// via lookahead from the sole `e.source!==` site) vary between builds and
|
||||||
|
// are resolved from the match — nothing is hardcoded.
|
||||||
Name = "remoteBridgeBindHandler",
|
Name = "remoteBridgeBindHandler",
|
||||||
SearchHints = new[] { "client-state" },
|
SearchHints = new[] { "client-state" },
|
||||||
Target = new Regex(@"setCurrentTrainer\(e,t=null\)\{const s=e\?\.trainerId\|\|null,i=\(s\?e\?\.gameId:null\)\|\|null,n=\(s\?e\?\.supportedVersions:null\)\|\|\[];if\(s===this\.#ke&&t===this\.#Ee\)return;"),
|
Target = new Regex(@"(?<head>setCurrentTrainer\(e,t=null\)\{)(?=const s=e\?\.trainerId\|\|null,i=\(s\?e\?\.gameId:null\)\|\|null,n=\(s\?e\?\.supportedVersions:null\)\|\|\[\];if\(s===this\.#[\w$]+&&t===this\.(?<trainer>#[\w$]+)\)return;)(?=.*?e\.source!==(?<remoteSource>[\w$]+\.[\w$]+\.Remote))",
|
||||||
Patch = "setCurrentTrainer(e,t=null){this.__wandRemoteBridge||(this.__wandRemoteBridge=(()=>{try{const r=globalThis.require||require;const{ipcRenderer:c}=r(\"electron\");try{c.invoke(\"wand-remote-url\").then((u=>{u&&(globalThis.__wandRemoteBridgeUrl=u)}))}catch(e){}const send=(ch,p)=>{try{return c.invoke(ch,p&&JSON.parse(JSON.stringify(p)))}catch(e){}};return{sync:(s)=>send(\"wand-remote-sync\",s),valueChanged:(s)=>send(\"wand-remote-value-changed\",s),setHandler:(h)=>{if(this.__wandRemoteBridgeBound)return;this.__wandRemoteBridgeBound=true;try{c.invoke(\"wand-remote-set-handler-bind\")}catch(e){}c.on(\"wand-remote-set-value\",(_e,req)=>{try{h(req)}catch(e){}})}}}catch(e){try{const r=globalThis.require||require,fs=r(\"node:fs\"),os=r(\"node:os\"),p=r(\"node:path\");fs.appendFileSync(p.join(os.tmpdir(),\"wand-remote-bridge.log\"),\"[\"+new Date().toISOString()+\"] [renderer-bind-error] \"+(e&&e.stack||e)+\"\\n\");}catch(_){}return null}})());this.__wandRemoteBridge?.setHandler((e=>{if(!this.#Ee||!e?.target)return!1;return this.#Ee.isActive()?this.#Ee.setValue(e.target,e.value,g.kL.Remote,e.cheatId):!1}));this.__wandRemoteTrainerInfo=e??null;const s=e?.trainerId||null,i=(s?e?.gameId:null)||null,n=(s?e?.supportedVersions:null)||[];if(s===this.#ke&&t===this.#Ee)return;"
|
RegexOptions.Singleline),
|
||||||
|
Patch = "${head}this.__wandRemoteBridge||(this.__wandRemoteBridge=(()=>{try{const r=globalThis.require||require;const{ipcRenderer:c}=r(\"electron\");try{c.invoke(\"wand-remote-url\").then((u=>{u&&(globalThis.__wandRemoteBridgeUrl=u)}))}catch(e){}const send=(ch,p)=>{try{return c.invoke(ch,p&&JSON.parse(JSON.stringify(p)))}catch(e){}};return{sync:(s)=>send(\"wand-remote-sync\",s),valueChanged:(s)=>send(\"wand-remote-value-changed\",s),setHandler:(h)=>{if(this.__wandRemoteBridgeBound)return;this.__wandRemoteBridgeBound=true;try{c.invoke(\"wand-remote-set-handler-bind\")}catch(e){}c.on(\"wand-remote-set-value\",(_e,req)=>{try{h(req)}catch(e){}})}}}catch(e){try{const r=globalThis.require||require,fs=r(\"node:fs\"),os=r(\"node:os\"),p=r(\"node:path\");fs.appendFileSync(p.join(os.tmpdir(),\"wand-remote-bridge.log\"),\"[\"+new Date().toISOString()+\"] [renderer-bind-error] \"+(e&&e.stack||e)+\"\\n\");}catch(_){}return null}})());this.__wandRemoteBridge?.setHandler((e=>{if(!this.${trainer}||!e?.target)return!1;return this.${trainer}.isActive()?this.${trainer}.setValue(e.target,e.value,${remoteSource},e.cheatId):!1}));this.__wandRemoteTrainerInfo=e??null;"
|
||||||
},
|
},
|
||||||
new PatchEntry
|
new PatchEntry
|
||||||
{
|
{
|
||||||
|
// Pure insertion: splice one `valueChanged` bridge call in after the
|
||||||
|
// existing `client-value-changed` send, before the onValueSet callback
|
||||||
|
// closes. Resolves no private names — `${head}`/`${tail}` carry the
|
||||||
|
// original text verbatim. trainerId is omitted from the payload;
|
||||||
|
// bridge-state falls back to the active snapshot trainer.
|
||||||
Name = "remoteBridgeValueDelta",
|
Name = "remoteBridgeValueDelta",
|
||||||
SearchHints = new[] { "client-value-changed" },
|
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\(\)\}"),
|
Target = new Regex(@"(?<head>#[\w$]+\(e,t\)\{t\.push\(e\.onValueSet\(e=>\{this\.status===[\w$]+\.Connected&&e\.source!==[\w$]+\.[\w$]+\.Remote&&this\.#[\w$]+\?\.send\(""client-value-changed"",\{instanceId:this\.#[\w$]+,name:e\.name,value:e\.value,cheatId:e\.cheatId\}\))(?<tail>\}\)\),this\.#[\w$]+\(\)\})"),
|
||||||
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()}"
|
Patch = "${head},this.__wandRemoteBridge?.valueChanged({target:e.name,value:e.value,oldValue:e.oldValue,source:String(e.source??\"desktop\"),cheatId:e.cheatId})${tail}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,5 +51,5 @@ using System.Windows;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.0.9.2")]
|
[assembly: AssemblyVersion("1.0.9.3")]
|
||||||
[assembly: AssemblyFileVersion("1.0.9.2")]
|
[assembly: AssemblyFileVersion("1.0.9.3")]
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user