feat(state): 迁移 entrance 切片(8 字段 / 7 臂)
This commit is contained in:
1 parent
435cd3191e
commit
77a90fdfff
8 files changed
+255
-29
No files matched your search
@@ -143,7 +143,7 @@
|
||||
`names/root_wiring.json` + `TankiOffline/.../App/State/RootState.kt`、`RootWiring.kt`。
|
||||
- 根状态 `z6`(`TOState`)的 **89 个槽位**全部入表;字段顺序取 `toString`,槽位取构造函数 `<名>_1`。
|
||||
- 根 reducer `k6` 的逐切片委派记全:reducer 引用、委派表达式、顶层 `instanceof` 动作名。
|
||||
- 已迁移切片 **11/89**:
|
||||
- 已迁移切片 **12/89**:
|
||||
- `inviteState` → `aD` / `pD.er5`(`InviteReducer.kt`)
|
||||
- `loginByPassword` → `gD` / `MD.cr6`(`LoginReducer.kt`,含 `SetLogin`/`SetPassword` 把 status 打回 `NONE` 的原语义)
|
||||
- `twitchState` → `g9` / `y9.gta`(`TwitchReducer.kt`;`SetAccount` 是 Twitch 账号,不是 UID)
|
||||
@@ -181,12 +181,17 @@
|
||||
`TankPartData` / `TankPreviewSettings` / `HullEngineType` / `TurretMechanism` 见 `GaragePreviewModels.kt`;
|
||||
12 个匿名动作按效果定名(`BG`→`CaptureScreenshot` … `tH`→`ClearDroneData`),
|
||||
3 个单例臂定名 `ClearGaragePreviewParams` / `ShowGaragePreview` / `HideGaragePreview`,不在 `Actions` 表里。
|
||||
- `entrance` → `hD` / `Bv.pth`(`EntranceReducer.kt`):8 个布尔字段,7 个 `instanceof` 臂。
|
||||
`showSocialNetworks` 缺省 true,其余 false;`HideSocialNetworks` 置 false,
|
||||
`SetControlsForChina` / `SetRunningInChinaDataCenter` / `SetRunningInChinaPartners` /
|
||||
`SetAuthorizedByChinaSdkToken` / `SetClassic` 各置一个 true,`SetAgeWarnShow` 写入 `isAgeWarnShow`。
|
||||
原 reducer 用 `ur4` 的 `cd` 参数保留其余字段;`authorizedByClassicEarlyAccessToken` 没有写入臂。
|
||||
- `launchParams` → `(pass-through)`:原根 reducer 对 `hpx_1` 没有调用,缺省是 `ag()` 空 Map;
|
||||
`RootState.LaunchParams` 收口为 `LaunchParamsStateSlice = Map<String, String>`,不新增 reducer/动作。
|
||||
- `App/State/RootReducer.kt`:`ReduceRoot(State0, Action)` 归约上述 10 个有 reducer 的切片,
|
||||
`launchParams` 与其余 **78 个字段原样透传**;
|
||||
迁移进度用 `RootReducer.Coverage`(`已迁移 11/89`)与 `RootWiring.Unmigrated` 暴露。
|
||||
- 自检:`TankiOffline/tools/RunStateTest.ps1` **280 项全绿**,含 89 槽位完整性、10 个归约切片一次归约互不串片、未迁移字段透传,
|
||||
- `App/State/RootReducer.kt`:`ReduceRoot(State0, Action)` 归约上述 11 个有 reducer 的切片,
|
||||
`launchParams` 与其余 **77 个字段原样透传**;
|
||||
迁移进度用 `RootReducer.Coverage`(`已迁移 12/89`)与 `RootWiring.Unmigrated` 暴露。
|
||||
- 自检:`TankiOffline/tools/RunStateTest.ps1` **294 项全绿**,含 89 槽位完整性、11 个归约切片一次归约互不串片、未迁移字段透传,
|
||||
以及用 `action_trace_merged.json` 真实派发的两条商店动作(`SetCoinPaymentProviderUrl` / `ToggleShopActivity`)回放。
|
||||
- 委派表里的已知形态:`shop` / `home` / `localBattleUserState` / `partner` 是内联 IIFE,
|
||||
已按字段具名为 `(inline@<field>)` 并从函数体抓到顶层动作名(69 / 1 / 2 / 11 个);
|
||||
@@ -195,7 +200,8 @@
|
||||
`o1` → `ShowShopDiscountNotification`(`$_$.gl` 单例,由 module_18334 的 `Qx.qge` 派发;
|
||||
效果是把 `HomeScreen.shopDiscountNotification` 置 true,对应主菜单商店项的折扣提示);
|
||||
shop 的 17 个匿名类按 reducer 效果定名并登记(`Yut`→`ShopLoaded`、`F5`→`ResetShop` 等);
|
||||
screen 的 9 个、lootBoxes 的 6 个、garage 的 25 个、garagePreview 的 15 个匿名类同样按效果定名并登记。
|
||||
screen 的 9 个、lootBoxes 的 6 个、garage 的 25 个、garagePreview 的 15 个、
|
||||
entrance 的 6 个匿名类同样按效果定名并登记。
|
||||
|
||||
### S4 引擎核心
|
||||
- 模块:32088(3D 数学)、92980(渲染)、61378(ECS)、55088(物理)、36659 + 71105(资源)、36734(音频)、3569(输入)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"generatedAt": "2026-10-23T07:24:48.002Z",
|
||||
"generatedAt": "2026-10-23T07:37:58.358Z",
|
||||
"module": "module_10032.js",
|
||||
"RootState": {
|
||||
"Class": "z6",
|
||||
@@ -17,6 +17,7 @@
|
||||
"lootBoxes",
|
||||
"garage",
|
||||
"garagePreview",
|
||||
"entrance",
|
||||
"launchParams"
|
||||
],
|
||||
"AnonymousActions": [
|
||||
@@ -458,6 +459,42 @@
|
||||
"Name": "HideGaragePreview",
|
||||
"DispatchedAt": "未在 action_trace_merged.json 中出现;按 reducer 分支效果定名",
|
||||
"Effect": "isVisible = false(`n.trs(!1)`)"
|
||||
},
|
||||
{
|
||||
"Local": "eit",
|
||||
"Name": "HideSocialNetworks",
|
||||
"DispatchedAt": "未在 action_trace_merged.json 中出现;按 reducer 分支效果定名",
|
||||
"Effect": "showSocialNetworks = false(`n.ur4(!1)`)"
|
||||
},
|
||||
{
|
||||
"Local": "uit",
|
||||
"Name": "SetControlsForChina",
|
||||
"DispatchedAt": "未在 action_trace_merged.json 中出现;按 reducer 分支效果定名",
|
||||
"Effect": "controlsForChina = true(`n.ur4(cd, !0)`)"
|
||||
},
|
||||
{
|
||||
"Local": "sit",
|
||||
"Name": "SetRunningInChinaDataCenter",
|
||||
"DispatchedAt": "未在 action_trace_merged.json 中出现;按 reducer 分支效果定名",
|
||||
"Effect": "isRunningInChinaDataCenter = true(`n.ur4(cd, cd, !0)`)"
|
||||
},
|
||||
{
|
||||
"Local": "oit",
|
||||
"Name": "SetRunningInChinaPartners",
|
||||
"DispatchedAt": "未在 action_trace_merged.json 中出现;按 reducer 分支效果定名",
|
||||
"Effect": "isRunningInChinaPartners = true(`n.ur4(cd, cd, cd, !0)`)"
|
||||
},
|
||||
{
|
||||
"Local": "lit",
|
||||
"Name": "SetAuthorizedByChinaSdkToken",
|
||||
"DispatchedAt": "未在 action_trace_merged.json 中出现;按 reducer 分支效果定名",
|
||||
"Effect": "authorizedByChinaSdkToken = true(`n.ur4(cd, cd, cd, cd, cd, !0)`)"
|
||||
},
|
||||
{
|
||||
"Local": "fit",
|
||||
"Name": "SetClassic",
|
||||
"DispatchedAt": "未在 action_trace_merged.json 中出现;按 reducer 分支效果定名",
|
||||
"Effect": "isClassic = true(`n.ur4(cd, cd, cd, cd, cd, cd, !0)`)"
|
||||
}
|
||||
],
|
||||
"Markers": [
|
||||
@@ -1813,16 +1850,16 @@
|
||||
"Reducer": "Bv.pth",
|
||||
"Delegate": "Bv.pth(t, n.jpx_1)",
|
||||
"Actions": [
|
||||
"?eit",
|
||||
"?fit",
|
||||
"?lit",
|
||||
"?oit",
|
||||
"?sit",
|
||||
"?uit",
|
||||
"SetAgeWarnShow"
|
||||
"HideSocialNetworks",
|
||||
"SetAgeWarnShow",
|
||||
"SetAuthorizedByChinaSdkToken",
|
||||
"SetClassic",
|
||||
"SetControlsForChina",
|
||||
"SetRunningInChinaDataCenter",
|
||||
"SetRunningInChinaPartners"
|
||||
],
|
||||
"Default": "new hD()",
|
||||
"Migrated": false
|
||||
"Migrated": true
|
||||
},
|
||||
{
|
||||
"Field": "antiAddiction",
|
||||
|
||||
@@ -119,6 +119,14 @@ const AnonymousActionNames = new Map([
|
||||
['is', 'ClearGaragePreviewParams'],
|
||||
['es', 'ShowGaragePreview'],
|
||||
['rs', 'HideGaragePreview'],
|
||||
// entrance 切片(hD / Bv.pth):6 个没有 toString / 不在 action_inventory 的类。
|
||||
// 括号里是原 reducer 的效果;实现见 EntranceReducer.kt。
|
||||
['eit', 'HideSocialNetworks'],
|
||||
['uit', 'SetControlsForChina'],
|
||||
['sit', 'SetRunningInChinaDataCenter'],
|
||||
['oit', 'SetRunningInChinaPartners'],
|
||||
['lit', 'SetAuthorizedByChinaSdkToken'],
|
||||
['fit', 'SetClassic'],
|
||||
]);
|
||||
|
||||
// 非动作的 `instanceof`:屏幕标识类,用于 GoTo 分支判断(不是 dispatch 的动作)。
|
||||
@@ -489,6 +497,7 @@ const Migrated = {
|
||||
lootBoxes: { Type: 'LootBoxesStateSlice', Reduce: 'ReduceLootBoxes' },
|
||||
garage: { Type: 'GarageStateSlice', Reduce: 'ReduceGarage' },
|
||||
garagePreview: { Type: 'GaragePreviewStateSlice', Reduce: 'ReduceGaragePreview' },
|
||||
entrance: { Type: 'EntranceStateSlice', Reduce: 'ReduceEntrance' },
|
||||
// 原根 reducer 对这一片没有调用,只有默认值 `ag()`(空 Map);这里仅做类型收口。
|
||||
launchParams: {
|
||||
Type: 'LaunchParamsStateSlice',
|
||||
@@ -608,6 +617,16 @@ const GaragePreviewAnonymousEffects = {
|
||||
rs: 'isVisible = false(`n.trs(!1)`)',
|
||||
};
|
||||
|
||||
// entrance 切片(hD / Bv.pth):没有 toString / 不在 action_inventory 的类,按 reducer 分支效果定名。
|
||||
const EntranceAnonymousEffects = {
|
||||
eit: 'showSocialNetworks = false(`n.ur4(!1)`)',
|
||||
uit: 'controlsForChina = true(`n.ur4(cd, !0)`)',
|
||||
sit: 'isRunningInChinaDataCenter = true(`n.ur4(cd, cd, !0)`)',
|
||||
oit: 'isRunningInChinaPartners = true(`n.ur4(cd, cd, cd, !0)`)',
|
||||
lit: 'authorizedByChinaSdkToken = true(`n.ur4(cd, cd, cd, cd, cd, !0)`)',
|
||||
fit: 'isClassic = true(`n.ur4(cd, cd, cd, cd, cd, cd, !0)`)',
|
||||
};
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(P, 'names', 'root_wiring.json'),
|
||||
JSON.stringify(
|
||||
@@ -654,6 +673,12 @@ fs.writeFileSync(
|
||||
DispatchedAt: '未在 action_trace_merged.json 中出现;按 reducer 分支效果定名',
|
||||
Effect,
|
||||
})),
|
||||
...Object.entries(EntranceAnonymousEffects).map(([Local, Effect]) => ({
|
||||
Local,
|
||||
Name: AnonymousActionNames.get(Local),
|
||||
DispatchedAt: '未在 action_trace_merged.json 中出现;按 reducer 分支效果定名',
|
||||
Effect,
|
||||
})),
|
||||
],
|
||||
Markers: [
|
||||
{
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// EntranceReducer.kt —— 启动入口切片(对应 module_10032 的 hD 状态 + Bv.pth reducer)
|
||||
//
|
||||
// 证据链:
|
||||
// 状态类 hD:`function hD(t, n, i, r, e, u, s, o)`,8 个布尔字段,
|
||||
// toString 名为 `EntranceState(showSocialNetworks=…, …, authorizedByClassicEarlyAccessToken=…)`。
|
||||
// 默认值:showSocialNetworks = true(`t = t === cd || t`),其余 7 个都是 false
|
||||
// (`x = x !== cd && x`)。
|
||||
//
|
||||
// 根委派:`Bv.pth(t, n.jpx_1)`。pth 有 7 个 instanceof 臂 + 默认透传:
|
||||
// eit → showSocialNetworks = false
|
||||
// uit → controlsForChina = true
|
||||
// sit → isRunningInChinaDataCenter = true
|
||||
// oit → isRunningInChinaPartners = true
|
||||
// _it → isAgeWarnShow = action.isShow(SetAgeWarnShow)
|
||||
// lit → authorizedByChinaSdkToken = true
|
||||
// fit → isClassic = true
|
||||
// 所有臂都走 `ur4`:参数为 `cd` 时保留原值,所以每次只改一个字段。
|
||||
// `authorizedByClassicEarlyAccessToken` 在原 reducer 里没有写入臂,保持默认 false。
|
||||
//
|
||||
// 6 个匿名动作没有 toString / 不在 action_inventory,按 reducer 效果定名;
|
||||
// `_it` 在 action_inventory 里已有名字,直接复用生成的 SetAgeWarnShow。
|
||||
package App.State.Reducers
|
||||
|
||||
import App.State.SetAgeWarnShow
|
||||
|
||||
/* ------------------------------------------------------------------ 匿名动作 */
|
||||
class HideSocialNetworks
|
||||
class SetControlsForChina
|
||||
class SetRunningInChinaDataCenter
|
||||
class SetRunningInChinaPartners
|
||||
class SetAuthorizedByChinaSdkToken
|
||||
class SetClassic
|
||||
|
||||
/* ------------------------------------------------------------------ 状态 */
|
||||
|
||||
data class EntranceStateSlice(
|
||||
val ShowSocialNetworks: Boolean = true,
|
||||
val ControlsForChina: Boolean = false,
|
||||
val IsRunningInChinaDataCenter: Boolean = false,
|
||||
val IsRunningInChinaPartners: Boolean = false,
|
||||
val IsAgeWarnShow: Boolean = false,
|
||||
val AuthorizedByChinaSdkToken: Boolean = false,
|
||||
val IsClassic: Boolean = false,
|
||||
val AuthorizedByClassicEarlyAccessToken: Boolean = false,
|
||||
)
|
||||
|
||||
/* ------------------------------------------------------------------ reducer */
|
||||
|
||||
fun ReduceEntrance(State0: EntranceStateSlice, Action: Any): EntranceStateSlice = when (Action) {
|
||||
is HideSocialNetworks -> State0.copy(ShowSocialNetworks = false)
|
||||
is SetControlsForChina -> State0.copy(ControlsForChina = true)
|
||||
is SetRunningInChinaDataCenter -> State0.copy(IsRunningInChinaDataCenter = true)
|
||||
is SetRunningInChinaPartners -> State0.copy(IsRunningInChinaPartners = true)
|
||||
is SetAgeWarnShow -> State0.copy(IsAgeWarnShow = Action.isShow)
|
||||
is SetAuthorizedByChinaSdkToken -> State0.copy(AuthorizedByChinaSdkToken = true)
|
||||
is SetClassic -> State0.copy(IsClassic = true)
|
||||
else -> State0
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// RootReducer.kt —— 根 reducer 骨架(对应 module_10032 的根状态 z6 / TOState 与根 reducer k6)
|
||||
//
|
||||
// 原包 k6 对 89 个切片逐个调用各自的 reducer,再 `return n.cti(...)`(copy 出新状态)。
|
||||
// 这里采用同一形状。已迁移的 11 个切片里,10 个真正调用 reducer,launchParams 只做类型收口:
|
||||
// 这里采用同一形状。已迁移的 12 个切片里,11 个真正调用 reducer,launchParams 只做类型收口:
|
||||
//
|
||||
// inviteState → ReduceInvite(aD / pD.er5)
|
||||
// loginByPassword → ReduceLoginByPassword(gD / MD.cr6)
|
||||
@@ -13,13 +13,15 @@
|
||||
// lootBoxes → ReduceLootBoxes(aH / EH.wrv)
|
||||
// garage → ReduceGarage(UB / hF,根委派 `i = hF(t, n)`)
|
||||
// garagePreview → ReduceGaragePreview(IG / fs.eru,根委派 `fs.eru(t, n.epv_1)`)
|
||||
// entrance → ReduceEntrance(hD / Bv.pth,根委派 `Bv.pth(t, n.jpx_1)`)
|
||||
// launchParams → 无 reducer(原根 reducer 原样透传;默认 `ag()` = emptyMap())
|
||||
//
|
||||
// 其余 78 个字段按原样透传(defaultValue 取原构造)。每个切片 reducer 对无关动作都返回原状态,
|
||||
// 其余 77 个字段按原样透传(defaultValue 取原构造)。每个切片 reducer 对无关动作都返回原状态,
|
||||
// 所以一次 copy 里串起全部已迁移 reducer,与按动作路由再归约的结果一致。
|
||||
// 迁移进度与每个字段的证据见生成物 RootWiring.kt(不要手改)。
|
||||
package App.State
|
||||
|
||||
import App.State.Reducers.ReduceEntrance
|
||||
import App.State.Reducers.ReduceGarage
|
||||
import App.State.Reducers.ReduceGaragePreview
|
||||
import App.State.Reducers.ReduceHome
|
||||
@@ -54,6 +56,7 @@ object RootReducer {
|
||||
LootBoxes = ReduceLootBoxes(State0.LootBoxes, Action),
|
||||
Garage = ReduceGarage(State0.Garage, Action),
|
||||
GaragePreview = ReduceGaragePreview(State0.GaragePreview, Action),
|
||||
Entrance = ReduceEntrance(State0.Entrance, Action),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// 已迁移的切片用强类型;其余保持 Any?(原样透传),迁移一个改一个再重新生成。
|
||||
package App.State
|
||||
|
||||
import App.State.Reducers.EntranceStateSlice
|
||||
import App.State.Reducers.GarageStateSlice
|
||||
import App.State.Reducers.GaragePreviewStateSlice
|
||||
import App.State.Reducers.HomeStateSlice
|
||||
@@ -146,8 +147,8 @@ data class RootState(
|
||||
val LaunchParams: LaunchParamsStateSlice = emptyMap(),
|
||||
/** 原 partner(UJ / (inline@partner))。未迁移:原样透传。 */
|
||||
val Partner: Any? = null,
|
||||
/** 原 entrance(hD / Bv.pth)。未迁移:原样透传。 */
|
||||
val Entrance: Any? = null,
|
||||
/** 原 entrance(hD / Bv.pth)。已迁移。 */
|
||||
val Entrance: EntranceStateSlice = EntranceStateSlice(),
|
||||
/** 原 antiAddiction(UC / W.iq8)。未迁移:原样透传。 */
|
||||
val AntiAddiction: Any? = null,
|
||||
/** 原 spectator(HA / Li.jqm)。未迁移:原样透传。 */
|
||||
|
||||
@@ -77,7 +77,7 @@ object RootWiring {
|
||||
SliceWiring("language", "gpx_1", "?", "m6().jtg", "m6().jtg(t, n.gpx_1)", listOf("?d6")),
|
||||
SliceWiring("launchParams", "hpx_1", "?", "(pass-through)", "n.hpx_1", listOf()),
|
||||
SliceWiring("partner", "ipx_1", "UJ", "(inline@partner)", "(function (t, n) { var i; if (t instanceof VJ) i = n.osf(t.rsf_1, cd, cd, cd, cd, cd, cd, cd, cd, cd, t.ssf_1); else if (t instanceof nZ) { var r = t.bsg_1, e = t.csg_1, u = t.dsg_1, s = t.esg_1, o = t.fsg_1, _ = t.gsg_1; i = n.osf(cd, cd, cd, r, e, u, cd, cd, o, _, s); } else i = t instanceof iZ ? n.osf(cd, t.hsg_1) : t instanceof uZ ? n.osf(cd, cd, t.ksg_1) : t instanceof eZ ? n.osf(cd, cd, cd, cd, cd, cd, cd, t.jsg_1) : t instanceof _Z ? n.osf(cd, cd, cd, cd, cd, cd, t.osg_1) : t instanceof X …", listOf("?JJ", "?_Z", "?hZ", "?tZ", "InitPartnerInviteAction", "InitSocialNetworkParameters", "SetLoginParams", "SetLoginStatusForBinding", "SetPartnerId", "SetPartnerParameters", "SetPartnerReady")),
|
||||
SliceWiring("entrance", "jpx_1", "hD", "Bv.pth", "Bv.pth(t, n.jpx_1)", listOf("?eit", "?fit", "?lit", "?oit", "?sit", "?uit", "SetAgeWarnShow")),
|
||||
SliceWiring("entrance", "jpx_1", "hD", "Bv.pth", "Bv.pth(t, n.jpx_1)", listOf("HideSocialNetworks", "SetAgeWarnShow", "SetAuthorizedByChinaSdkToken", "SetClassic", "SetControlsForChina", "SetRunningInChinaDataCenter", "SetRunningInChinaPartners")),
|
||||
SliceWiring("antiAddiction", "kpx_1", "UC", "W.iq8", "W.iq8(t, n.kpx_1)", listOf("?FC", "?XC", "?YC", "SetRealNameAndIdNumber", "SetValidateAntiAddictionUserDataStatus")),
|
||||
SliceWiring("spectator", "lpx_1", "HA", "Li.jqm", "Li.jqm(t, n.lpx_1)", listOf("?JA", "?XA", "?YA", "?ZA", "SetSpectator", "UpdateHudLayout")),
|
||||
SliceWiring("moderation", "mpx_1", "NI", "Ei.oqh", "Ei.oqh(t, n.mpx_1)", listOf("?FI", "?GI", "?JI", "?KI", "?QI", "?UI", "?WI", "?XI", "?YI", "?ZI", "?nA", "?tA", "?uA")),
|
||||
@@ -106,7 +106,7 @@ object RootWiring {
|
||||
)
|
||||
|
||||
/** 已迁移(强类型;launchParams 为透传,不调用 reducer)的字段。 */
|
||||
val Migrated: Set<String> = setOf("inviteState", "loginByPassword", "twitchState", "home", "localBattleUserState", "shop", "screen", "lootBoxes", "garage", "garagePreview", "launchParams")
|
||||
val Migrated: Set<String> = setOf("inviteState", "loginByPassword", "twitchState", "home", "localBattleUserState", "shop", "screen", "lootBoxes", "garage", "garagePreview", "entrance", "launchParams")
|
||||
|
||||
/** 未迁移字段:归约时原样透传,作为后续迁移清单。 */
|
||||
val Unmigrated: List<SliceWiring> get() = All.filter { it.Field !in Migrated }
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
// ⑥ 动作目录:816 个类与 138 个真实派发名对齐
|
||||
// ⑦ 回放:真实 toString 样例的类/字段/类型校验
|
||||
// ⑧ 全目录动作类都能按 KClass 路由
|
||||
// ⑨~㉑ 切片 reducer:InviteState / LoginByPasswordState / TwitchState / HomeScreen / LocalBattleUserState /
|
||||
// Shop(含 U7 类别表与 w3 物品表两个子 reducer)/ Screen / LootBoxes / Garage / GaragePreview;
|
||||
// ⑨~㉒ 切片 reducer:InviteState / LoginByPasswordState / TwitchState / HomeScreen / LocalBattleUserState /
|
||||
// Shop(含 U7 类别表与 w3 物品表两个子 reducer)/ Screen / LootBoxes / Garage / GaragePreview / Entrance;
|
||||
// ㉑ launchParams 是纯透传切片(无 reducer/动作),只做 Map 类型收口;⑭ 根 reducer 的 89 槽位委派
|
||||
//
|
||||
// 用法:$env:TANKIOFFLINE_STATE_TEST='1'; node …(见 TankiOffline/tools/RunStateTest.ps1)
|
||||
@@ -217,6 +217,7 @@ import App.State.GaragePreviewModelCC
|
||||
import App.State.HullEngineType
|
||||
import App.State.InitGarageResources
|
||||
import App.State.ResetItem3dModelActionCache
|
||||
import App.State.SetAgeWarnShow
|
||||
import App.State.SetCaptureActions
|
||||
import App.State.SetDrone
|
||||
import App.State.SetExpectedItemId
|
||||
@@ -255,8 +256,16 @@ import App.State.Reducers.PreviewHullCategory
|
||||
import App.State.Reducers.PreviewPaintCategory
|
||||
import App.State.Reducers.PreviewWeaponCategory
|
||||
import App.State.Reducers.ReduceGarage
|
||||
import App.State.Reducers.EntranceStateSlice
|
||||
import App.State.Reducers.HideSocialNetworks
|
||||
import App.State.Reducers.ReduceEntrance
|
||||
import App.State.Reducers.ReduceGaragePreview
|
||||
import App.State.Reducers.RemoveNewItem
|
||||
import App.State.Reducers.SetAuthorizedByChinaSdkToken
|
||||
import App.State.Reducers.SetClassic
|
||||
import App.State.Reducers.SetControlsForChina
|
||||
import App.State.Reducers.SetRunningInChinaDataCenter
|
||||
import App.State.Reducers.SetRunningInChinaPartners
|
||||
import App.State.Reducers.RemoveWaitServerItemMount
|
||||
import App.State.Reducers.ResetGarage
|
||||
import App.State.Reducers.ResetMountDelay
|
||||
@@ -653,7 +662,7 @@ object StateCheck {
|
||||
Check("切片 LocalBattleUser:接 Store 派发后状态已归约", Store.State.IsReArmorTemporaryDisabled)
|
||||
}
|
||||
|
||||
// ⑭ 根 reducer:89 个槽位的委派表 + 11 个已迁移切片(10 归约 + launchParams 透传)
|
||||
// ⑭ 根 reducer:89 个槽位的委派表 + 12 个已迁移切片(11 归约 + launchParams 透传)
|
||||
run {
|
||||
Check("根:根状态 89 个切片槽位", RootWiring.All.size == 89)
|
||||
Check(
|
||||
@@ -717,17 +726,17 @@ object StateCheck {
|
||||
LocalBattleW.Reducer == "(inline@localBattleUserState)"
|
||||
)
|
||||
Check(
|
||||
"根:迁移表 = 11 个已迁移字段,其余 78 个待迁",
|
||||
"根:迁移表 = 12 个已迁移字段,其余 77 个待迁",
|
||||
RootReducer.Migrated ==
|
||||
setOf(
|
||||
"inviteState", "loginByPassword", "twitchState", "home",
|
||||
"localBattleUserState", "shop", "screen", "lootBoxes", "garage",
|
||||
"garagePreview", "launchParams",
|
||||
"garagePreview", "entrance", "launchParams",
|
||||
) &&
|
||||
RootWiring.Unmigrated.size == 78
|
||||
RootWiring.Unmigrated.size == 77
|
||||
)
|
||||
|
||||
// 一次 ReduceRoot 里八个切片各归约自己的动作,互不串片
|
||||
// 一次 ReduceRoot 里多个切片各归约自己的动作,互不串片
|
||||
val S0 = RootState(User = "user-1", Screen = ScreenStateSlice(Current = NamedScreen("Preloader")))
|
||||
val S1 = ReduceRoot(S0, ApplyInvite("uid-1"))
|
||||
Check(
|
||||
@@ -780,7 +789,7 @@ object StateCheck {
|
||||
S5.User == "user-1" && S5.Screen.Current == NamedScreen("Preloader")
|
||||
)
|
||||
Check("根:无关动作返回等值状态", ReduceRoot(S5, AddFrags(1)) == S5)
|
||||
Check("根:Coverage 文本", RootReducer.Coverage == "已迁移 11/89")
|
||||
Check("根:Coverage 文本", RootReducer.Coverage == "已迁移 12/89")
|
||||
|
||||
val Store = ReduxStore(RootState(), { S, A -> ReduceRoot(S, A) })
|
||||
Store.Dispatch(SetStatus("LOGGING_IN"))
|
||||
@@ -2329,6 +2338,93 @@ object StateCheck {
|
||||
)
|
||||
}
|
||||
|
||||
// ㉒ 切片 reducer:Entrance(原 module_10032 的 hD / Bv.pth,8 字段;7 个 instanceof 臂)
|
||||
run {
|
||||
val S0 = EntranceStateSlice()
|
||||
Check(
|
||||
"切片 Entrance:默认值与原构造一致(showSocialNetworks 缺省 true,其余 false)",
|
||||
S0.ShowSocialNetworks && !S0.ControlsForChina &&
|
||||
!S0.IsRunningInChinaDataCenter && !S0.IsRunningInChinaPartners &&
|
||||
!S0.IsAgeWarnShow && !S0.AuthorizedByChinaSdkToken &&
|
||||
!S0.IsClassic && !S0.AuthorizedByClassicEarlyAccessToken
|
||||
)
|
||||
|
||||
Check(
|
||||
"切片 Entrance:HideSocialNetworks 置 showSocialNetworks=false",
|
||||
!ReduceEntrance(S0, HideSocialNetworks()).ShowSocialNetworks
|
||||
)
|
||||
Check(
|
||||
"切片 Entrance:SetControlsForChina 置 controlsForChina=true",
|
||||
ReduceEntrance(S0, SetControlsForChina()).ControlsForChina
|
||||
)
|
||||
Check(
|
||||
"切片 Entrance:SetRunningInChinaDataCenter 置对应字段",
|
||||
ReduceEntrance(S0, SetRunningInChinaDataCenter()).IsRunningInChinaDataCenter
|
||||
)
|
||||
Check(
|
||||
"切片 Entrance:SetRunningInChinaPartners 置对应字段",
|
||||
ReduceEntrance(S0, SetRunningInChinaPartners()).IsRunningInChinaPartners
|
||||
)
|
||||
Check(
|
||||
"切片 Entrance:SetAgeWarnShow 写入 isAgeWarnShow",
|
||||
ReduceEntrance(S0, SetAgeWarnShow(true)).IsAgeWarnShow &&
|
||||
!ReduceEntrance(S0.copy(IsAgeWarnShow = true), SetAgeWarnShow(false)).IsAgeWarnShow
|
||||
)
|
||||
Check(
|
||||
"切片 Entrance:SetAuthorizedByChinaSdkToken 置对应字段",
|
||||
ReduceEntrance(S0, SetAuthorizedByChinaSdkToken()).AuthorizedByChinaSdkToken
|
||||
)
|
||||
Check(
|
||||
"切片 Entrance:SetClassic 置 isClassic",
|
||||
ReduceEntrance(S0, SetClassic()).IsClassic
|
||||
)
|
||||
|
||||
val All = listOf(
|
||||
HideSocialNetworks(),
|
||||
SetControlsForChina(),
|
||||
SetRunningInChinaDataCenter(),
|
||||
SetRunningInChinaPartners(),
|
||||
SetAgeWarnShow(true),
|
||||
SetAuthorizedByChinaSdkToken(),
|
||||
SetClassic(),
|
||||
).fold(S0) { S, A -> ReduceEntrance(S, A) }
|
||||
Check(
|
||||
"切片 Entrance:七个动作依次归约后只改对应字段",
|
||||
!All.ShowSocialNetworks && All.ControlsForChina &&
|
||||
All.IsRunningInChinaDataCenter && All.IsRunningInChinaPartners &&
|
||||
All.IsAgeWarnShow && All.AuthorizedByChinaSdkToken &&
|
||||
All.IsClassic && !All.AuthorizedByClassicEarlyAccessToken
|
||||
)
|
||||
Check("切片 Entrance:无关动作不改状态", ReduceEntrance(All, AddFrags(1)) == All)
|
||||
|
||||
val Root0 = RootState()
|
||||
val Root1 = ReduceRoot(Root0, SetClassic())
|
||||
Check(
|
||||
"根:SetClassic 只动 entrance",
|
||||
Root1.Entrance.IsClassic && Root1.LoginByPassword == Root0.LoginByPassword &&
|
||||
Root1.GaragePreview == Root0.GaragePreview && Root1.Garage == Root0.Garage
|
||||
)
|
||||
Check(
|
||||
"根:entrance 无关动作保留前一次归约",
|
||||
ReduceRoot(Root1, AddFrags(1)).Entrance == Root1.Entrance
|
||||
)
|
||||
|
||||
val W = RootWiring.ByField("entrance")!!
|
||||
Check(
|
||||
"根:entrance 委派到 hD / Bv.pth 且 7 个动作全部具名",
|
||||
W.SliceClass == "hD" && W.Reducer == "Bv.pth" && W.Actions.size == 7 &&
|
||||
W.Actions.none { it.startsWith("?") }
|
||||
)
|
||||
Check(
|
||||
"根:entrance 的动作名覆盖 7 个 instanceof 臂",
|
||||
listOf(
|
||||
"HideSocialNetworks", "SetAgeWarnShow", "SetAuthorizedByChinaSdkToken",
|
||||
"SetClassic", "SetControlsForChina", "SetRunningInChinaDataCenter",
|
||||
"SetRunningInChinaPartners",
|
||||
).all { it in W.Actions }
|
||||
)
|
||||
}
|
||||
|
||||
val Failed = Results.filter { !it.second }
|
||||
println("TankiOffline 状态层自检:${Results.size} 项")
|
||||
for ((Name, Ok) in Results) println((if (Ok) " ✓ " else " ✗ ") + Name)
|
||||
|
||||
Reference in new issue
Block a user