Files
ft/CodexOutput/upserver/B3BatchMigration/M2/M2-CP2A独立方案审查.md
Liubing\LB 6813da149a feat(upserver): 保存M2客户端KV迁移至本人统计写检查点
保存独立KV用户服务、固定会话存档与原业务接线,以及C3d资料缓存和C3e本人统计写。
保留原PF/AGG路线、业务公式和时序;榜单读取、好友资料、公告、匹配及首场景闸仍待完成。

验证:ServiceHost两条件各33组646断言;Unity CLI Loop编译0错误269警告。
包含相关方案、评审裁决、测试及状态文档。未操作服务器、正式账号或打包。
2026-09-30 19:19:05 +08:00

70 lines
4.7 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.
# M2 CP2A独立方案审查:正式登录与原句柄交接
日期:2026-09-29。审查者:ZCode会话(M2全链审查者:修订1/修订2/CP1方案与实施)。本轮只读+hash重算+源码核对;未修改方案/生产源码/共享文档/历史报告。
## 受审hash核对
`M2-CP2A受审基线.json`:**37/37重算全部一致**。
## 总裁决
**通过。CP2A可批准实施**(主会话核hash裁决后)。无P1/P2;P3四条。
## 六项逐条裁决
### 1. 启动分流与PF默认保持:确认
- `AfterAssetUpdateV2`传入config→`RegisterServices`在组件创建前捕获`playfab`/`kv`——**正确的捕获时机**(:91 AddComponent之前);
- KV不创建`PlayFabMgr`——从源头消除旧40秒循环/PlayerPrefs合档风险;
- Editor loop后置`kv-loop`不被误拒(§2.1明确分离);
- AGG KV显式拒绝;
- 运行期配置改不切后端——正确(防半途切换)。
**CP2A可达旧调用检查**:不创建PF组件后,`SetMMTestValue`/`LoginPlayFab`/TapJoy/YinDun均因KV分支不走这些路径而不可达——§2.3逐条排除。
### 2. 账号准入与三传输所有权:完整
- 请求前规范化+仅101/102常量(后续扩员另审);
- 登录后`newCreate=false`+**非空完整Schema验证**(不是只看newCreate)——双层门;
- 三独立handler共享同一CookieContainer——与4A Owner同一模式;
- 正式工厂与验证工厂隔离——§2.2"测试替身不能经Editor permit混入正式运行"。
### 3. 正式实例准入与CP1接口消费:闭合
- 普通PlayFabUserService获一次性正式加载准入(与kvControlledInstance互斥);
- `unstarted`在Apply前复核;
- 第31模块仅在正式加载窗口内允许Reset/Replace;
- **CP1三接口全部有真实消费者**(LoadForGameAsync由UserService调/TryGetCurrentGameHandle由UserService按epoch调一次/TryAcquireGameHandle由Coordinator内部调)——接口闭环。
### 4. KVHandoffReady与双重阶段闸:语义自洽
- 内部`KVHandoffReady(epoch, originalHandle)`≠公开`IsLogin`/`IsAuthorized`——**正确的分层**(公开状态是身份发布问题,留CP2B随首场景评审);
- `PFLoginAct`:KV分支不注册`WaitForAPISvrLogin`(防永远等待)、不初始化Mail/IAP、不Unload——收到内部状态后停在登录阶段;
- `LoginStage.RequestNextAct`**双重阻断**进FishingStage——防后续UI误触发;
- 首场景依赖清单(mail/fetch/Survey×2/排行榜/anti-cheat/friend等旧PF或API调用)因此全部不可达——正确的安全边界。
### 5. CustomServerMgr空路由与关闭:充分
- 正式租约绑定但CP2A API路由集合为**空**——任何`CustomServerPost`在KV模式拒绝——最保守正确;
- 401/旧epoch/Logout同步清内部状态→Revoke→Registry排水;
- Close故障阻断新Context——与4A/CP1合同一致。
### 6. 白名单与矩阵:完整可独立编码
**白名单12项**(2修改Boostrap/SubBoostrap+2新RuntimeSelection/RuntimeLifetime+4修改PlayerData+2修改LoginStage/Bindings+3修改UserService/PFLoginAct/CustomServerMgr)——每项限定到具体方法/入口。禁改清单明确(PlayFabMgr/KVMgr/Guard/AggUserService/FishingStage等)。
**验收矩阵六类**(PF不回归/KV准入/成功交接/竞态关闭/网络/目标编译)覆盖充分——含Editor+Player双目标编译+历史`_cheatingScore`另列。
**CP2A能否独立编码**:可以——它的停止点(不进首场景)使其不依赖FishingStage内的迁移。CP2B首场景是下一独立边界。
## P3清单
- **P3-1**:§2.1的`PlayerKVRuntimeSelection`——建议实现时在类内加XML注释说明"101/102为受审常量,扩员须完整方案审查"——防后续维护者直接改常量。
- **P3-2**:§2.2的"Bindings对正式路径接受明确的本地decoder版本令牌"——建议令牌命名包含创建时间或配置指纹前缀(如`formal-<cfgHash前8字符>`),使不同配置版本可区分。
- **P3-3**:§2.3的"KV加载失败显示失败并要求显式重启或登出"——建议在PFLoginAct中为KV失败路径加一个可区分的错误码(如`PlayerKVGameLoadError`→UI映射),便于CP2B扩展错误提示。
- **P3-4**:§3白名单的`PlayerKVRuntimeLifetime.cs`标注"若现有根对象生命周期没有合适位置"——建议CP2A实施时先评估是否有现有可复用点(如Coordinator的Registry已覆盖排水),避免新增文件成为冗余。
## 结论
**通过CP2A方案。** 主会话核hash(已代验37/37)逐条裁决后按白名单实施。CP2A完成后做批末独立实施复核,其关闭仅表示"正式登录与原handle交接可达",不启用首场景/玩法/公开授权。CP2B首场景为下一独立方案。