# TOState 字段 ↔ reducer 映射表 > **版本说明(2026-10)**:本文依据旧版 `names/tostate-map.json`(根状态 `w8` / 根 reducer `v8`、 > 槽位 `app_1` / `bpp_1`)写成,与当前 `src/module_10032.js`(根状态 `z6` / `TOState`、根 reducer `k6`、 > 槽位 `<名>_1`)符号名不同,**只用于交叉验证动作归属**。当前源码口径以 `3DTank/tools/gen_root_wiring.js` > 现场解析出的 `names/root_wiring.json` 与 Kotlin 侧 `App/State/RootWiring.kt` 为准。 本文是 `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().`。 - 内联匿名 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` 两个额外槽位。重写时这两个是重点。