Compare commits

..

4 Commits

Author SHA1 Message Date
kitbyte a7f0eae670 fix: Assignment to constant variable error in the enhancer patcher, bump version to 1.0.9.1 2026-06-24 22:13:57 +03:00
k1tbyte 1c9a8fb780 Merge pull request #110 from Kava-4/fix/pro-account-reducer-guard
fix(pro): guard ACTION_SET_ACCOUNT reducer against subscription loss
2026-06-24 21:52:36 +03:00
kava4 ec07dc63f0 fix(pro): guard ACTION_SET_ACCOUNT reducer against subscription loss
Periodic refreshAccount and other store writes could replace the account without subscription, causing Pro to drop after a day or two (#106).
2026-06-24 18:00:42 +03:00
kitbyte 88556ec70f feat(funding): add funding options to README and create FUNDING.yml 2026-06-16 18:00:18 +03:00
6 changed files with 51 additions and 5 deletions
+8
View File
@@ -0,0 +1,8 @@
patreon: kitbyte
custom: [
"https://www.patreon.com/kitbyte/gift",
"https://tronscan.org/#/address/TQdvau8pAy5Tg1Aa588tTcPCFgbcHtuoxc",
"https://www.blockchain.com/explorer/addresses/btc/1EZKDcyU8REm9JW5xwXJqSpn5Xaq5yAWWX",
"https://etherscan.io/address/0xd904d9d0557f88bbb1c4ab3582b4ca0d8a730e8d"
]
+1 -1
View File
@@ -22,7 +22,7 @@ This repository patches the Wand Electron app from a .NET Framework WPF desktop
- The websocket `hello` snapshot must still send cached `installed_apps` and `game_status` even when no trainer snapshot is active yet; do not reintroduce a handshake path that returns early after `trainer_changed`.
- Remote Play/Stop uses the websocket `remote_command` message. The bridge forwards it over `wand-remote-command` / `wand-remote-command-response`, and `installed-apps-sync.js` resolves Wand's trainer API + trainer service to launch a trainer for a `gameId` or end the current trainer.
- Remote Play must construct Wand's real trainer launch request class (`69482.vO`) before calling `trainerService.launch(...)`. Passing a plain object launches the game process but breaks Wand's `getMetadata(vO)`-based trainer state, causing missing status, disappearing play/close buttons, and stuck loading behavior.
- Pro activation is a C# asar patch (`EPatchType.ActivatePro`, independent of the remote panel / bridge). It rewrites three account-returning service methods to inject `subscription:{period:"yearly",state:"active"}` into the response before it reaches the store: `getUserAccount` and `setAccountWandBrandExperience` (Resolver-style, service field via `<service_name>` placeholder) and `setAccountLanguage` (`BuildSetAccountLanguagePatch` PatchFactory — captures the real param names + the original `post("/v3/account/language",{...})` expr and wraps `.then`). Pro is `am(account) = !!account.subscription` (flags/512 are irrelevant). `setAccountLanguage` is the one the original two patches missed, which is why Pro dropped on language change. If a future Wand build changes these method bodies, re-derive the regexes against the live `app-*.bundle.js` (do NOT trust `.source/new` — it is a different version).
- Pro activation is a C# asar patch (`EPatchType.ActivatePro`, independent of the remote panel / bridge). It rewrites three account-returning service methods to inject `subscription:{period:"yearly",state:"active"}` into the response before it reaches the store: `getUserAccount` and `setAccountWandBrandExperience` (Resolver-style, service field via `<service_name>` placeholder) and `setAccountLanguage` (`BuildSetAccountLanguagePatch` PatchFactory — captures the real param names + the original `post("/v3/account/language",{...})` expr and wraps `.then`). A fourth patch (`setAccountReducer`) rewrites the `ACTION_SET_ACCOUNT` store reducer so any account write (periodic `refreshAccount`, push/profile updates, etc.) keeps Pro even when it bypasses those API methods. Pro is `am(account) = !!account.subscription` (flags/512 are irrelevant). `setAccountLanguage` is the one the original two patches missed, which is why Pro dropped on language change. If a future Wand build changes these method bodies, re-derive the regexes against the live `app-*.bundle.js` (do NOT trust `.source/new` — it is a different version).
## ASAR Patch Pipeline
+8 -1
View File
@@ -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.9.1] - 2026-06-24
### Fixes
- Fixed Pro features disappearing after a day or two when Wand refreshed account data in the background; account store updates now preserve the patched active subscription by @Kava-4 in #110. Related issue #106
- Fixed the new Pro account reducer guard so normal account updates do not fail while keeping Pro active.
## [1.0.9.0] - 2026-06-15
### Features
@@ -154,4 +161,4 @@ The newest entry must match the version in `WandEnhancer/Properties/AssemblyInfo
### Changes
- Basic ElectronJS wrapper over the original script.
- Basic ElectronJS wrapper over the original script.
+8 -1
View File
@@ -129,7 +129,14 @@ This project is licensed under the Apache-2.0 - see the [LICENSE](LICENSE.md) fi
---
## ❤️ Support
[![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/kitbyte)
If you find this project useful, you can support its development using any of the options below 🙌
[![Patreon](https://img.shields.io/badge/Patreon-donate-f96854.svg?logo=patreon)](https://www.patreon.com/kitbyte/gift)
[![USDT TRC20](https://img.shields.io/badge/USDT--TRC20-donate-26a17b.svg?logo=tether)](https://tronscan.org/#/address/TQdvau8pAy5Tg1Aa588tTcPCFgbcHtuoxc)
[![BTC](https://img.shields.io/badge/BTC-donate-f7931a.svg?logo=bitcoin)](https://www.blockchain.com/explorer/addresses/btc/1EZKDcyU8REm9JW5xwXJqSpn5Xaq5yAWWX)
[![ETH](https://img.shields.io/badge/ETH-donate-3c3c3d.svg?logo=ethereum)](https://etherscan.io/address/0xd904d9d0557f88bbb1c4ab3582b4ca0d8a730e8d)
---
+24
View File
@@ -50,6 +50,17 @@ namespace WandEnhancer.Core
return $"setAccountLanguage({parameters}){{return ({expr}).then(response=>{{response&&\"object\"==typeof response&&(response.subscription={{period:\"yearly\",state:\"active\"}});return response;}})}}";
}
private static string BuildSetAccountReducerPatch(Match match)
{
var decl = RequireGroup(match, "decl", "setAccountReducer");
var fn = RequireGroup(match, "fn", "setAccountReducer");
var parameters = RequireGroup(match, "params", "setAccountReducer");
var state = RequireGroup(match, "state", "setAccountReducer");
var account = RequireGroup(match, "account", "setAccountReducer");
return
$"const {decl}=\"ACTION_SET_ACCOUNT\";function {fn}({parameters}){{const a={account}&&\"object\"==typeof {account}?{{...{account},subscription:{{period:\"yearly\",state:\"active\"}}}}:{account};return{{...{state},account:a}}}}";
}
private static string BuildRemoteBridgeResetPatch(Match match)
{
var source = match.Value;
@@ -143,6 +154,19 @@ namespace WandEnhancer.Core
@"setAccountLanguage\((?<params>[^)]*)\)\{\s*return\s+(?<expr>this\.#\w+\.post\(""/v3/account/language"",\{[^}]*\}\))\s*;?\s*\}",
RegexOptions.Singleline),
PatchFactory = BuildSetAccountLanguagePatch
},
new PatchEntry
{
// Last-resort guard: any code path that dispatches ACTION_SET_ACCOUNT
// (periodic refreshAccount, push updates, profile edits, etc.) must keep
// subscription on the store object even when it bypasses the account API
// service methods patched above.
Name = "setAccountReducer",
SearchHints = new[] { "ACTION_SET_ACCOUNT" },
Target = new Regex(
@"const (?<decl>\w+)=""ACTION_SET_ACCOUNT"";function (?<fn>\w+)\((?<params>[^)]*)\)\{return\{\.\.\.(?<state>\w+),account:(?<account>\w+)\}\}",
RegexOptions.Singleline),
PatchFactory = BuildSetAccountReducerPatch
}
}
},
+2 -2
View File
@@ -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.9.0")]
[assembly: AssemblyFileVersion("1.0.9.0")]
[assembly: AssemblyVersion("1.0.9.1")]
[assembly: AssemblyFileVersion("1.0.9.1")]