Files
TankIC/3DTank/docs/StateMap.md
T
TermiNexus 61b57a3d11 docs(3dtank): 架构逆向:模块依赖图、6 条运行链路、TOState↔reducer 映射
names/module-graph.json:126 模块的 Kind/职责/依赖/导出/锚点,533 条依赖边,入口 13431(出度 46,依赖链深 17 层)。docs/ArchitectureModules.md:依赖图摘要 + 40 个游戏模块逐条 + 依赖分层(由数据生成)。docs/ArchitectureRuntime.md:启动引导/网络层/Redux/UI 系统/资源与渲染/空间与对象模型 6 条链路,64 条关键函数([证据] 77 / [推断] 15)。names/tostate-map.json + docs/StateMap.md:TOState 实为 89 字段(非估计的 60),89/89 由「toString 字段→槽位」与「根 reducer v8 的实参顺序→ntb 形参→w8 字段顺序」两条独立链路交叉验证,唯一未映射的是只读的 launchParams。
2026-09-18 09:30:30 +08:00

293 lines
26 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TOState 字段 ↔ reducer 映射表
本文是 `names/tostate-map.json` 的人类可读版,用途:**重写客户端时对照根状态的每个分片该由哪个 reducer / 哪些 action 驱动**。
## 1. TOState 是什么
- **根状态类**:`TOState`,即 `module_10032.js` 里的类 `w8`;其 `toString` 以 `"TOState(user="` 开头,定义在 **`module_10032.js:43519`**(`vd(w8).toString`)。
- **字段数**:**89 个**(每个字段在源码里是 `this.<槽位>_1`,形如 `app_1` / `bpp_1` … `kps_1`)。
- **根 reducer**:`module_10032.js:14307-15449` 的函数 **`v8(action, state)`**(`[证据]`:`module_10849:91` 的 Store 构造把 `v8` 作为 reducer 传入,见 `ArchitectureRuntime.md` 第 3 节)。它把 89 个分片逐一委派给各自的分片 reducer,最后用 `state.ntb(...)`(`vd(w8).ntb`,定义 `module_10032.js:42968`,方法体就是一串 `return new w8(参数…)`)合成新 `TOState`。
- **store / dispatch**:`module_10032.js:52887` 的 `$_$.w1r` 创建 store(被 `module_13431:1408` 调用);`dispatch` 即 `module_10849:320` 的 `qao`。无 saga/effect,只有 thunk + ConsoleDebug 中间件。
- **action 形态**:Kotlin 数据类实例,`new XxxAction(...)`,经 `store.qao(action)` 分发;分片 reducer 内部用 `if (t instanceof XxxAction)` 长链分派。
> 一致性交叉验证:`v8` 末尾 `return state.ntb(i, r, N, s, o, e, u, _, c, $, q, h, a, …)` 的**实参顺序**与 `TOState` 的**字段顺序**逐位对齐(第 1 位 `i`=`app_1`=`user`,第 2 位 `r`=`bpp_1`=`screen`,…),且每一位实参本身调用的 reducer 恰好读取同一个槽位。两套独立证据吻合,故下表映射记为 `证据`。
## 2. 主表(全部 89 个字段)
「reducer 函数」列 = `v8` 中处理该槽位的调用式(源码形态);「位置」= 该调用在根 reducer 中的行;「相关 action」见第 3 节分组表。
| 业务域 | 字段 | 槽位 | reducer 函数 | 位置 | 可信度 |
|---|---|---|---|---|---|
| 登录与账号 | `user` | `app_1` | `T6().bt7` | module_10032.js:14308 | 证据 |
| UI/面板 | `screen` | `bpp_1` | `cY().wry` | module_10032.js:14309 | 证据 |
| UI/面板 | `modalScreen` | `cpp_1` | `Us.wru` | module_10032.js:14342 | 证据 |
| 战斗 | `battleStatistics` | `dpp_1` | `rr.tqk` | module_10032.js:14312 | 证据 |
| 战斗 | `battleTutorial` | `epp_1` | `Q.uq2` | module_10032.js:14313 | 证据 |
| 车库与物品 | `garage` | `fpp_1` | `sF` | module_10032.js:14310 | 证据 |
| 车库与物品 | `garagePreview` | `gpp_1` | `ls.rrn` | module_10032.js:14311 | 证据 |
| 任务与内容 | `challenges` | `hpp_1` | `ta.tsc` | module_10032.js:14314 | 证据 |
| 登录与账号 | `loginByPassword` | `ipp_1` | `nu.qqz` | module_10032.js:14317 | 证据 |
| 登录与账号 | `register` | `jpp_1` | `fw.dta` | module_10032.js:14330 | 证据 |
| 登录与账号 | `migrationState` | `kpp_1` | `Gv.cta` | module_10032.js:14329 | 证据 |
| 登录与账号 | `inviteState` | `lpp_1` | `Ke.sqy` | module_10032.js:14316 | 证据 |
| 登录与账号 | `captchaState` | `mpp_1` | `hr.wqm` | module_10032.js:14315 | 证据 |
| 登录与账号 | `passwordChangeState` | `npp_1` | `uu.dr0` | module_10032.js:14341 | 证据 |
| 网络/系统 | `system` | `opp_1` | `l4().jt3` | module_10032.js:14318 | 证据 |
| 任务与内容 | `quests` | `ppp_1` | `(null == qw && new Vrt(), qw).zt9` | module_10032.js:14321 | 证据 |
| 聊天/社交 | `chatState` | `qpp_1` | `jr.kqp` | module_10032.js:14322 | 证据 |
| 聊天/社交 | `clanChatState` | `rpp_1` | `xv.bta` | module_10032.js:14323 | 证据 |
| 聊天/社交 | `clan` | `spp_1` | `pe.vqt` | module_10032.js:14325 | 证据 |
| 聊天/社交 | `clansStorage` | `tpp_1` | `me.jqv` | module_10032.js:14326 | 证据 |
| UI/面板 | `tipsState` | `upp_1` | `Vp.gtb` | module_10032.js:15348 | 证据 |
| UI/面板 | `news` | `vpp_1` | `C_.ms6` | module_10032.js:14327 | 证据 |
| 设置 | `settings` | `wpp_1` | `Sp.wt9` | module_10032.js:14319 | 证据 |
| 设置 | `accountSettings` | `xpp_1` | `Uw.xt9` | module_10032.js:14320 | 证据 |
| 车库与物品 | `lootBoxes` | `ypp_1` | `ws.jrp` | module_10032.js:14328 | 证据 |
| UI/面板 | `notifications` | `zpp_1` | `L_.us7` | module_10032.js:14331 | 证据 |
| 聊天/社交 | `friends` | `apq_1` | `AL().qr2` | module_10032.js:14332 | 证据 |
| 网络/系统 | `remoteUserDataStorage` | `bpq_1` | `fa.use` | module_10032.js:14333 | 证据 |
| 空间与场景 | `battlesSelect` | `cpq_1` | `Oi.wqe` | module_10032.js:14334 | 证据 |
| 空间与场景 | `maps` | `dpq_1` | `Mi.gqf` | module_10032.js:14335 | 证据 |
| 空间与场景 | `matchmaking` | `epq_1` | `WH().drr` | module_10032.js:14336 | 证据 |
| 空间与场景 | `battleCreateState` | `fpq_1` | `Uf.eta` | module_10032.js:14338 | 证据 |
| 空间与场景 | `battleSearchState` | `gpq_1` | `Gtt().gta` | module_10032.js:14339 | 证据 |
| UI/面板 | `lobbyLoader` | `hpq_1` | `Ls.rru` | module_10032.js:14340 | 证据 |
| 战斗 | `battleResult` | `ipq_1` | `Fi.oqi` | module_10032.js:14343 | 证据 |
| 战斗 | `battleUsers` | `jpq_1` | `sr.vql` | module_10032.js:14344 | 证据 |
| 战斗 | `suppliesState` | `kpq_1` | `jt.hq3` | module_10032.js:15249 | 证据 |
| 空间与场景 | `matchmakingGroup` | `lpq_1` | `TW().vrt` | module_10032.js:14337 | 证据 |
| 车库与物品 | `shop` | `mpq_1` | `(inline IIFE)@module_10032.js:14345` | module_10032.js:14345 | 证据 |
| 战斗 | `battlePauseState` | `npq_1` | `RT().oq6` | module_10032.js:15251 | 证据 |
| 战斗 | `battleViewState` | `opq_1` | `(null == jn && new eI(), jn).lq7` | module_10032.js:15250 | 证据 |
| 战斗 | `rankUpDialogState` | `ppq_1` | `Se.pqw` | module_10032.js:15252 | 证据 |
| 聊天/社交 | `clanUserInfo` | `qpq_1` | `de.uqu` | module_10032.js:14324 | 证据 |
| 战斗 | `tankActionsLogState` | `rpq_1` | `pi.iq8` | module_10032.js:15253 | 证据 |
| 战斗 | `battleMessage` | `spq_1` | `lT().tq5` | module_10032.js:15254 | 证据 |
| 聊天/社交 | `battleChat` | `tpq_1` | `Kf.hta` | module_10032.js:15255 | 证据 |
| 战斗 | `droppableGold` | `upq_1` | `Kw.vta` | module_10032.js:15271 | 证据 |
| UI/面板 | `home` | `vpq_1` | `(inline IIFE)@module_10032.js:15256` | module_10032.js:15256 | 证据 |
| 战斗 | `localBattleUserState` | `wpq_1` | `(inline IIFE)@module_10032.js:15265` | module_10032.js:15265 | 证据 |
| 设置 | `soundSettings` | `xpq_1` | `Get().uta` | module_10032.js:15268 | 证据 |
| 设置 | `gameSettings` | `ypq_1` | `v2().osm` | module_10032.js:15270 | 证据 |
| 设置 | `battleSettings` | `zpq_1` | `W0().tsj` | module_10032.js:15269 | 证据 |
| 设置 | `graphicsSettings` | `apr_1` | `lc.wsn` | module_10032.js:15272 | 证据 |
| 设置 | `controlSettings` | `bpr_1` | `e2().tsl` | module_10032.js:15273 | 证据 |
| 设置 | `securitySettings` | `cpr_1` | `wc.dsp` | module_10032.js:15275 | 证据 |
| 车库与物品 | `purchaseDialogState` | `dpr_1` | `ze.iqw` | module_10032.js:15276 | 证据 |
| 战斗 | `battleInviteState` | `epr_1` | `Itt().yta` | module_10032.js:15277 | 证据 |
| 设置 | `keyboardSettings` | `fpr_1` | `$p.zta` | module_10032.js:15278 | 证据 |
| 设置 | `touchscreenHudSettings` | `gpr_1` | `I7().ksp` | module_10032.js:15274 | 证据 |
| 任务与内容 | `mainQuest` | `hpr_1` | `na.nsd` | module_10032.js:15279 | 证据 |
| 设置 | `language` | `ipr_1` | `f8().ut9` | module_10032.js:15330 | 证据 |
| 登录与账号 | `partner` | `kpr_1` | `(inline IIFE)@module_10032.js:15280` | module_10032.js:15280 | 证据 |
| UI/面板 | `entrance` | `lpr_1` | `Fv.atb` | module_10032.js:15331 | 证据 |
| 登录与账号 | `antiAddiction` | `mpr_1` | `W.kq2` | module_10032.js:15332 | 证据 |
| 战斗 | `spectator` | `npr_1` | `Li.xqf` | module_10032.js:15334 | 证据 |
| 登录与账号 | `moderation` | `opr_1` | `Ei.qqb` | module_10032.js:15333 | 证据 |
| 登录与账号 | `rulesUpdated` | `ppr_1` | `Sa.psf` | module_10032.js:15335 | 证据 |
| UI/面板 | `announcement` | `qpr_1` | `AC().tpz` | module_10032.js:15336 | 证据 |
| UI/面板 | `notificationByCountry` | `rpr_1` | `A_.es7` | module_10032.js:15337 | 证据 |
| 登录与账号 | `userRenameState` | `spr_1` | `Af.at8` | module_10032.js:15338 | 证据 |
| 车库与物品 | `eventGoods` | `tpr_1` | `Wc.rsq` | module_10032.js:15339 | 证据 |
| 任务与内容 | `creatorTagState` | `upr_1` | `ke.sqv` | module_10032.js:15340 | 证据 |
| 登录与账号 | `twoStepVerificationState` | `vpr_1` | `_f.mt4` | module_10032.js:15341 | 证据 |
| 任务与内容 | `rewardedVideosState` | `wpr_1` | `ja.lsf` | module_10032.js:15342 | 证据 |
| 任务与内容 | `twitchState` | `xpr_1` | `uf.st3` | module_10032.js:15343 | 证据 |
| UI/面板 | `icons` | `ypr_1` | `fs.xrn` | module_10032.js:15344 | 证据 |
| UI/面板 | `itemNotifications` | `zpr_1` | `C1().ssh` | module_10032.js:15345 | 证据 |
| 战斗 | `contextTutorial` | `aps_1` | `Yst().etb` | module_10032.js:15346 | 证据 |
| 战斗 | `suppliesTutorial` | `bps_1` | `Gp.ftb` | module_10032.js:15347 | 证据 |
| 任务与内容 | `questCategories` | `cps_1` | `Q_.xsa` | module_10032.js:15349 | 证据 |
| 空间与场景 | `proBattle` | `dps_1` | `_v.htb` | module_10032.js:15350 | 证据 |
| 空间与场景 | `availabilityByRank` | `eps_1` | `zw.itb` | module_10032.js:15351 | 证据 |
| 登录与账号 | `userReportsState` | `fps_1` | `(null == _d && new kot(), _d).ktb` | module_10032.js:15352 | 证据 |
| 车库与物品 | `tankBuilderState` | `gps_1` | `gw.ltb` | module_10032.js:15353 | 证据 |
| 任务与内容 | `contractState` | `hps_1` | `Sv.mtb` | module_10032.js:15354 | 证据 |
| 任务与内容 | `promoCode` | `ips_1` | `Z_.ksa` | module_10032.js:15355 | 证据 |
| 任务与内容 | `referralEvent` | `jps_1` | `ca.ase` | module_10032.js:15356 | 证据 |
| 登录与账号 | `supportUrl` | `kps_1` | `Yl.ot0` | module_10032.js:15357 | 证据 |
| 网络/系统 | `launchParams` | `jpr_1` | —(透传,无 reducer) | module_10032.js:15328 | 未映射 |
## 3. 按业务域分组
每组给出字段 → reducer 函数(`(inline IIFE)@…` 表示根 reducer 内联的匿名 reducer,其函数体直接写在 `v8` 里,没有独立函数名)。相关 action 见 `names/tostate-map.json` 各 entry 的 `Actions`;下表为高频代表。
### 3.1 登录与账号(15 字段)
- `user`→`T6().bt7`、`loginByPassword`→`nu.qqz`、`register`→`fw.dta`、`migrationState`→`Gv.cta`、`inviteState`→`Ke.sqy`、`captchaState`→`hr.wqm`、`passwordChangeState`→`uu.dr0`、`userRenameState`→`Af.at8`、`twoStepVerificationState`→`_f.mt4`、`antiAddiction`→`W.kq2`、`moderation`→`Ei.qqb`、`rulesUpdated`→`Sa.psf`、`partner`→`(inline IIFE)@15280`、`supportUrl`→`Yl.ot0`、`userReportsState`→`(null == _d && new kot(), _d).ktb`
| 字段 | reducer | 相关 action(代表) |
|---|---|---|
| `user` | `T6().bt7` @14308 | SetClanInfo, UpdateCrystals, SpendCrystals, AddCoins, SetCoins, SpendCoins, SetHasTemporaryCash, AddRubies …(共 27 个) |
| `loginByPassword` | `nu.qqz` @14317 | SetLogin, SetPassword, SetRememberMe, SetStatus, IncorrectLogin2FA …(共 9 个) |
| `register` | `fw.dta` @14330 | SetUid, ForceSetUid, SetPassword, EnteredUidIsBusy …(共 19 个) |
| `migrationState` | `Gv.cta` @14329 | SetUid, ForceSetUid, SetPassword …(共 11 个) |
| `inviteState` | `Ke.sqy` @14316 | SetInviteNeed, SetInviteStatus, ApplyInvite |
| `captchaState` | `hr.wqm` @14315 | SetLocations, LocationsUpdated |
| `passwordChangeState` | `uu.dr0` @14341 | SetPasswordChangeHash |
| `userRenameState` | `Af.at8` @15338 | ChangeUidInputState, SetValidationStatus, SetRubiesForRename, ResponseDelivered …(共 11 个) |
| `twoStepVerificationState` | `_f.mt4` @15341 | SetUse2FA, ActivationStatus2FA, SetSecretAndQRCode, VerificationStatus, Enable2FaRequest |
| `antiAddiction` | `W.kq2` @15332 | SetRealNameAndIdNumber, SetValidateAntiAddictionUserDataStatus |
| `moderation` | `Ei.qqb` @15333 | …(共 13 个) |
| `rulesUpdated` | `Sa.psf` @15335 | UpdateRules |
| `partner` | `(inline IIFE)@15280` | SetPartnerId, SetLoginParams, SetPartnerParameters, InitPartnerInviteAction, SetLoginStatusForBinding …(共 11 个) |
| `supportUrl` | `Yl.ot0` @15357 | SetUrl |
| `userReportsState` | `(…, _d).ktb` @15352 | SetAvailableReports, SetAvailableGameReports, ReportProBattleName, ReportLobbyChatMessage, ReportBattleChatMessage |
### 3.2 UI/面板(12 字段)
- `screen`→`cY().wry`、`modalScreen`→`Us.wru`、`home`→`(inline IIFE)@15256`、`lobbyLoader`→`Ls.rru`、`tipsState`→`Vp.gtb`、`news`→`C_.ms6`、`notifications`→`L_.us7`、`announcement`→`AC().tpz`、`notificationByCountry`→`A_.es7`、`icons`→`fs.xrn`、`itemNotifications`→`C1().ssh`、`entrance`→`Fv.atb`
| 字段 | reducer | 相关 action(代表) |
|---|---|---|
| `screen` | `cY().wry` @14309 | GoTo, PressedAnyButton, DisplayMainEntranceScreen, DisplayReauthorizationMessage …(共 15 个) |
| `modalScreen` | `Us.wru` @14342 | AddModal, RemoveModal, RemoveCurrentByName |
| `home` | `(inline IIFE)@15256` | (3 个:`i1`/`n1`/`r1`) |
| `lobbyLoader` | `Ls.rru` @14340 | (2 个) |
| `tipsState` | `Vp.gtb` @15348 | UpdateTips |
| `news` | `C_.ms6` @14327 | SetNewsItemAction, AddNewsItemAction, RemoveNewsItemAction, SetUnreadNewsCounter |
| `notifications` | `L_.us7` @14331 | InitNotificationSound, AddNotification |
| `announcement` | `AC().tpz` @15336 | Init, SetSkipNextPromotedAnnounce |
| `notificationByCountry` | `A_.es7` @15337 | (2 个) |
| `icons` | `fs.xrn` @15344 | SetIcons |
| `itemNotifications` | `C1().ssh` @15345 | AddItemNotifications |
| `entrance` | `Fv.atb` @15331 | SetAgeWarnShow …(共 7 个) |
### 3.3 空间与场景(8 字段)
- `battlesSelect`→`Oi.wqe`、`maps`→`Mi.gqf`、`matchmaking`→`WH().drr`、`matchmakingGroup`→`TW().vrt`、`battleCreateState`→`Uf.eta`、`battleSearchState`→`Gtt().gta`、`proBattle`→`_v.htb`、`availabilityByRank`→`zw.itb`
| 字段 | reducer | 相关 action(代表) |
|---|---|---|
| `battlesSelect` | `Oi.wqe` @14334 | RoundStarted, SwapTeam, RoundFinish, RemoveBattle, ChangeName …(共 20 个) |
| `maps` | `Mi.gqf` @14335 | AddMap |
| `matchmaking` | `WH().drr` @14336 | SelectMatchmakingMode, WasRegistered, EnterToBattleApply …(共 9 个) |
| `matchmakingGroup` | `TW().vrt` @14337 | InitMatchmakingGroup, SetAllowedFromFriends, AddUser, UserRemoved, Invite, AcceptedInviteToGroup …(共 13 个) |
| `battleCreateState` | `Uf.eta` @14338 | Configure, SetName, SetMode, SetMaxPeopleInTeam, SetScoreLimit, SetSearch, SetRanks, SetAvailableRanks …(共 17 个) |
| `battleSearchState` | `Gtt().gta` @14339 | SetFilter, SetSearch, SetSuspiciousFilter, Fight, EnterToBattle, SelectBattle, SelectBattleFormat, RemoveBattle …(共 9 个) |
| `proBattle` | `_v.htb` @15350 | Fight, SetPassword |
| `availabilityByRank` | `zw.itb` @15351 | SetLoadedData |
> 注意:`battleCreateState` 的 reducer `Uf.eta(t, n.fpq_1, n.dpq_1, n.app_1)` 是**三槽位联合 reducer**(同时读 `maps`、`user`),重写时不可只传自身分片。
### 3.4 车库与物品(7 字段)
- `garage`→`sF`、`garagePreview`→`ls.rrn`、`shop`→`(inline IIFE)@14345`、`lootBoxes`→`ws.jrp`、`eventGoods`→`Wc.rsq`、`purchaseDialogState`→`ze.iqw`、`tankBuilderState`→`gw.ltb`
| 字段 | reducer | 相关 action(代表) |
|---|---|---|
| `garage` | `sF` @14310 | SetGarageSkinsAction …(共 60 个;`sF` 是读整个 state 的跨分片 reducer,见 `module_10032.js:6455`,内部取 `n.fpp_1`) |
| `garagePreview` | `ls.rrn` @14311 | UpdatePreviewSettings, InitGarageResources, SetExpectedItemId, AddRequestedItem …(共 22 个) |
| `shop` | `(inline IIFE)@14345` | SetCoinPaymentProviderUrl, PaymentUrlReceived, SetBraintreeToken, SetStripeIntentParams, BraintreeLoadingInterrupt …(共 69 个,是全表 action 最多的分片) |
| `lootBoxes` | `ws.jrp` @14328 | SetPossibleRewards, SetCurrentContainer, SetKeys, AddKeys, SetGoToGarage, SetRewards …(共 18 个) |
| `eventGoods` | `Wc.rsq` @15339 | InitEventGoods |
| `purchaseDialogState` | `ze.iqw` @15276 | ChangeEmailStatus …(共 3 个) |
| `tankBuilderState` | `gw.ltb` @15353 | SetKode, SetParts, SetPartsInfo |
### 3.5 战斗(16 字段)
- `battleStatistics`→`rr.tqk`、`battleTutorial`→`Q.uq2`、`battleResult`→`Fi.oqi`、`battleUsers`→`sr.vql`、`suppliesState`→`jt.hq3`、`battlePauseState`→`RT().oq6`、`battleViewState`→`(…, jn).lq7`、`rankUpDialogState`→`Se.pqw`、`tankActionsLogState`→`pi.iq8`、`battleMessage`→`lT().tq5`、`droppableGold`→`Kw.vta`、`localBattleUserState`→`(inline IIFE)@15265`、`battleInviteState`→`Itt().yta`、`spectator`→`Li.xqf`、`contextTutorial`→`Yst().etb`、`suppliesTutorial`→`Gp.ftb`
| 字段 | reducer | 相关 action(代表) |
|---|---|---|
| `battleStatistics` | `rr.tqk` @14312 | SetDisplayClientInfo, SetBattleMode, SetReArmor, SetRankRange, UpdateScore, UpdateFund …(共 22 个) |
| `battleTutorial` | `Q.uq2` @14313 | ShowMessage, SetFragsCount |
| `battleResult` | `Fi.oqi` @14343 | SetRewards, SetHasBattleResult |
| `battleUsers` | `sr.vql` @14344 | UpdateUserRank, UpdateUsersClanTag, UpdateUserScoreKillsAndDeaths, SetGearScore …(共 18 个) |
| `suppliesState` | `jt.hq3` @15249 | (`kE`) |
| `battlePauseState` | `RT().oq6` @15251 | OnPauseMode, SetIdleKickPeriod |
| `battleViewState` | `(…, jn).lq7` @15250 | SetVisibility, SetElementsVisibility …(共 14 个) |
| `rankUpDialogState` | `Se.pqw` @15252 | ShowAvailableItems |
| `tankActionsLogState` | `pi.iq8` @15253 | OnUserJoinTheBattle, OnUserLeaveTheBattle, UpdateLog |
| `battleMessage` | `lT().tq5` @15254 | HideMessage, RemoveMessage |
| `droppableGold` | `Kw.vta` @15271 | (2 个) |
| `localBattleUserState` | `(inline IIFE)@15265` | SetLocalWeaponResistanceProperty, SetReArmorTemporaryDisabled |
| `battleInviteState` | `Itt().yta` @15277 | SelectUserToInvite, RemoveUserFromInvited, EnableSetBattleInviteNotifications |
| `spectator` | `Li.xqf` @15334 | SetSpectator, UpdateHudLayout |
| `contextTutorial` | `Yst().etb` @15346 | LoadCurrentElement, SetUnViewedElements, MarkElementAsViewed, SetLoadedElements, SetMissionToElement |
| `suppliesTutorial` | `Gp.ftb` @15347 | ActivatedInCurrentBattle, SetLoadedElement |
### 3.6 聊天/社交(7 字段)
- `chatState`→`jr.kqp`、`clanChatState`→`xv.bta`、`clan`→`pe.vqt`、`clansStorage`→`me.jqv`、`clanUserInfo`→`de.uqu`、`friends`→`AL().qr2`、`battleChat`→`Kf.hta`
| 字段 | reducer | 相关 action(代表) |
|---|---|---|
| `chatState` | `jr.kqp` @14322 | Configure, ChangeChannel, SaveChatMessage, SetMessages, CleanUsersMessage, UpdateUsers …(共 24 个) |
| `clanChatState` | `xv.bta` @14323 | Configure, DoAddMessages |
| `clan` | `pe.vqt` @14325 | AddUsersToAccepted, RemoveUserFromAccepted, SetMinRankForCreate, MembersFetched, ClanInfoLoaded, IncomingAdded …(共 43 个) |
| `clansStorage` | `me.jqv` @14326 | ClanLoaded, ClanUnloaded, MinimalRankChanged, RecruitmentChanged, AddUser, RemoveUser …(共 13 个) |
| `clanUserInfo` | `de.uqu` @14324 | Loaded |
| `friends` | `AL().qr2` @14332 | ChangeFriendAddFindState, SetLimits, AddUsersToAccepted, RemoveUserFromAccepted ≥ …(共 13 个) |
| `battleChat` | `Kf.hta` @15255 | AddMessage …(共 6 个) |
### 3.7 设置(11 字段)
- `settings`→`Sp.wt9`、`accountSettings`→`Uw.xt9`、`soundSettings`→`Get().uta`、`gameSettings`→`v2().osm`、`battleSettings`→`W0().tsj`、`graphicsSettings`→`lc.wsn`、`controlSettings`→`e2().tsl`、`securitySettings`→`wc.dsp`、`keyboardSettings`→`$p.zta`、`touchscreenHudSettings`→`I7().ksp`、`language`→`f8().ut9`
| 字段 | reducer | 相关 action(代表) |
|---|---|---|
| `settings` | `Sp.wt9` @14319 | (2 个) |
| `accountSettings` | `Uw.xt9` @14320 | …(共 13 个) |
| `soundSettings` | `Get().uta` @15268 | UpdateSettings, SetEntranceSoundEnabled |
| `gameSettings` | `v2().osm` @15270 | UpdateSettings |
| `battleSettings` | `W0().tsj` @15269 | UpdateSettings |
| `graphicsSettings` | `lc.wsn` @15272 | UpdateSettings |
| `controlSettings` | `e2().tsl` @15273 | UpdateSettings |
| `securitySettings` | `wc.dsp` @15275 | SetProfileBlockStatus |
| `keyboardSettings` | `$p.zta` @15278 | RemoveAction, ResetAction |
| `touchscreenHudSettings` | `I7().ksp` @15274 | UpdateSettings |
| `language` | `f8().ut9` @15330 | (`c8`) |
> 各 `*Settings` 分片共用同一个 `UpdateSettings` 类 action,靠 reducer 内部区分目标分片;重写时不要把它当成单一 store。
### 3.8 任务与内容(10 字段)
- `challenges`→`ta.tsc`、`quests`→`(…, qw).zt9`、`mainQuest`→`na.nsd`、`questCategories`→`Q_.xsa`、`contractState`→`Sv.mtb`、`promoCode`→`Z_.ksa`、`referralEvent`→`ca.ase`、`rewardedVideosState`→`ja.lsf`、`twitchState`→`uf.st3`、`creatorTagState`→`ke.sqv`
| 字段 | reducer | 相关 action(代表) |
|---|---|---|
| `challenges` | `ta.tsc` @14314 | UpdateStars, SetChallenge, RemoveChallenge, SetBattlePass, SetRewardForDialog, SetBattlePassPackages, SetTakenFreeRewardIndex …(共 9 个) |
| `quests` | `(…, qw).zt9` @14321 | SetCurrentCategory, GoTo, QuestCategory |
| `mainQuest` | `na.nsd` @15279 | QuestsLoaded, SetQuests, UpdateQuests, AddRewardedQuest, SetEventPassShopItemId, SetBattleUpdatedQuests |
| `questCategories` | `Q_.xsa` @15349 | SetQuestCategories, RemoveQuestCategory, RequestQuestCategoriesStatistic, SetQuestCategoriesStatistic |
| `contractState` | `Sv.mtb` @15354 | SetActiveContract, SetContract, UpdateProgress, SetBattleProgress, GetReward |
| `promoCode` | `Z_.ksa` @15355 | ActivatePromoCode, SetCodeValidateStatus |
| `referralEvent` | `ca.ase` @15356 | SetReferralEventData, SetPromoCode, SetReferrals, SetReferrer |
| `rewardedVideosState` | `ja.lsf` @15342 | SetDisplayState |
| `twitchState` | `uf.st3` @15343 | SetTwitchEnabled, SetAccount, SetDaysForNextLinking |
| `creatorTagState` | `ke.sqv` @15340 | SetCreatorTags, SetCreatorTag, SetAttachedCreatorTag |
### 3.9 网络/系统(2 字段 + 1 未映射)
- `system`→`l4().jt3`、`remoteUserDataStorage`→`fa.use`(`launchParams` 未映射,见第 4 节)
| 字段 | reducer | 相关 action(代表) |
|---|---|---|
| `system` | `l4().jt3` @14318 | DoShowMessage, SetFatalError |
| `remoteUserDataStorage` | `fa.use` @14333 | UpdateUids, UpdateRanks, UpdatePremiumStatus, UpdateClanTags, UpdateOnlineStatus, UserEnterBattle, UserLeaveBattle, UserLeaveGroup |
## 4. 未映射字段
| 字段 | 槽位 | 原因 |
|---|---|---|
| `launchParams` | `jpr_1` | 根 reducer `v8` 在 `module_10032.js:15328` 用 `ht = n.jpr_1` **原样透传**:没有分片 reducer,也没有任何 `instanceof` 分支写它。该字段只在初始化(`module_10032.js:52909` `new w8().vt9(...)`)时被写入,之后不可变。重写时按只读启动参数处理即可。 |
其余 88 个字段全部定位到分片 reducer(`Stats`: 证据 88 / 推断 0 / 未映射 1)。
## 5. 方法说明(如何把 TOState 字段与根 reducer 分支对上)
**关键难点**:`v8` 是 1143 行的巨型函数,且不以 `if (t instanceof …)` 长链覆盖全部字段 —— 前 38 行是「直线式委派」,其余散落在 14345–15357 的续行里,且**顺序与 `TOState` 字段顺序完全不同**(例如 `battlePauseState` 在 15341、`modalScreen` 在 14342)。因此不能靠"读顺序"对齐,必须做双向锚定。
实际用到的四步与锚点:
1. **抽出字段→槽位表**。定位 `module_10032.js:43519` 的 `vd(w8).toString`,用正则
`/([A-Za-z][A-Za-z0-9]*)="\s*\+\s*(?:this\.([A-Za-z0-9_]+)|qd\(this\.([A-Za-z0-9_]+)\))/g`
在 `"TOState(user="` 到 `hashCode` 之间的片段上匹配,得到 89 组 `字段名 → this.<槽位>`。注意字段名在 `="` 之前(形如 `..., screen=" + this.bpp_1 ...`),直接抓 `"name="` 会失败。
2. **抽出 `v8` 的委派语句**。定位 `function v8(t, n)`,用花括号配对取出函数体;再以「括号深度 0 处的逗号」切分变量声明链(`var i = ..., r = ..., e = ...;`),得到 89 条 `变量 = 表达式`。每条记录其起始偏移,换算成文件行号(注意函数体第一个换行导致 **+1 修正**——行号在起草稿时曾整体偏 −1,已校准)。
3. **把变量接到字段上(主锚点)**。`v8` 末尾 `return n.ntb(...)` 调用 `vd(w8).ntb`(`module_10032.js:42968`),而 `ntb` 的形参顺序 = `new w8(...)` 的实参顺序 = `TOState` 字段顺序(`app_1, bpp_1, cpp_1, …`)。于是**第 k 个实参 ↔ 第 k 个字段**。同时每个实参变量(如第 1 个 `i = T6().bt7(t, n.app_1)`)自身读取的槽位又是 `app_1` —— 两个方向的独立结果逐位一致(89/89),故此映射可直接标 `证据`,无需 `推断`。
4. **抽 action 类名**。对每个分片 reducer 取方法名(如 `bt7`),在 `module_10032.js` 里找 `.bt7 = function` / `function bt7(` 定义点,花括号配对取出函数体,用 `/\binstanceof\s+([A-Za-z_$][A-Za-z0-9_$]*)/g` 收集分支上的类名,再用 `names/evidence.json` 的 `byModule.10032.classNames`(混淆名→真名,如 `E6→State`)翻译成可读 action 名。分片状态类同理取自定义点的 `vd(<Class>).<method>`。
- 内联匿名 reducer(`shop`/`home`/`localBattleUserState`/`partner`)无独立函数名,直接从 `v8` 内的 IIFE 函数体取 `instanceof` 链。
- 特殊形态 `(null == qw && new Vrt(), qw).zt9(t, n.ppp_1)`(惰性单例)需要从 `(…, <名字>).<方法>` 里剥出方法名,普通 `^X.y(t` 正则会漏掉。
**复现命令**(只读,无临时文件):对 `module_10032.js` 用 `node -e` 跑上述四步的正则/配对逻辑即可重建 `names/tostate-map.json`;`Stats` 与 `Entries` 应逐条一致。
**已知不确定点**:
- `SliceClass` 有 5 项为空(`garage` 由顶层函数 `sF` 处理而非类方法;`shop`/`home`/`localBattleUserState`/`partner` 是内联 IIFE),其分片状态类名未在本模块内定位。
- `Actions` 中部分仍是混淆名(如 `c6`/`p6`/`S6`),因为 `evidence.json` 的 `classNames` 未覆盖这些类;它们**确实是**能改该字段的 action 类,只是真名缺失。
- `garage` 的 reducer `sF` 读整个 state(`n.fpp_1` 等)而非仅自身分片,属跨分片 reducer;`battleCreateState` 的 `Uf.eta` 显式接收 `maps`/`user` 两个额外槽位。重写时这两个是重点。