保存独立KV用户服务、固定会话存档与原业务接线,以及C3d资料缓存和C3e本人统计写。 保留原PF/AGG路线、业务公式和时序;榜单读取、好友资料、公告、匹配及首场景闸仍待完成。 验证:ServiceHost两条件各33组646断言;Unity CLI Loop编译0错误269警告。 包含相关方案、评审裁决、测试及状态文档。未操作服务器、正式账号或打包。
6.4 KiB
6.4 KiB
M2 合批工作稿(修订版)独立复核
日期:2026-09-29。审查人:原 ZCode(独立侧)。对象:合批工作稿修订版(17:47,21140 字节)及预审主会话裁决。性质同前:只读事实/问题吸收,不是 hash 门控正式前审,不触发编码许可。未改生产/测试/服务器代码,未调用正式 101/102,未打包。
总裁决:承接完整,事实声明抽验全部属实;余 3 项 P3 修正,无 P1/P2
1. 裁决承接核对(预审七项 → 修订版落点)
| 预审输入 | 修订版落点 | 核对 |
|---|---|---|
| ① IUserService 成员三分表按新 PlayerId 重写 | "IUserService 成员责任与身份时序"全表(18 行成员逐项)+ 固定发布顺序段落 | ✓ 完整 |
| ② 中立面机制定死 | "生命周期窄契约含 KVHandoffReady/KVLastError/CloseKVAsync/ObserveKVQuitAsync,消费者只有 PFLoginAct/QuitAct";模式判断只读冻结 RuntimeSelection | ✓(成员命名见 §3-P3b) |
| ③ 测试迁移与签名耦合核验 | "候选修改文件"表 formal 合成宿主行(Program/Stubs/csproj)+ "不改但必须回归"行(KVGameplayLoop/AggUserService/EditorValidationHost 三文件签名兼容) | ✓ 完整 |
| ④ 身份发布硬断言 + 两个 IsLogin 消费者 | "身份发布顺序固定为…→同步发布→发布一次 EvtAPISvrLoginSuccess→Login 返回 Done→场景切换前再次确认";"FishingStage KV 入口需硬检查…不得依赖 5 秒软等待";OnApplicationResumedAsync/AutoRestart 分别限定 | ✓ 完整 |
| ⑤ 首场景最短链逐项边界 | "首场景请求与直接 KV 调用边界"表(Mail/AntiCheat/Friend/Club/Survey/等级榜/AIHelp/AutoRestart 逐行失败边界) | ✓ 完整 |
| ⑥ 等级榜 | 个人分按原算法推导、地区码未知不混入全局、聚合入口交服务端、活动榜沿用 event 请求 | ✓ 完整 |
| ⑦ SaveBackend 再读取 | "正式 KV 登录只信启动冻结选择,不再从 config 重读"(选消除路线) | ✓ 已定死 |
2. 新增源码事实声明抽验(全部属实)
| 声明 | 源码证据 |
|---|---|
| BattlePass 链:UpdateTaskData→SaveBattleTask→SaveBattlePassRecordTask→组合值单键 | BattlePassData.cs:256,734(订阅 ConditionTypeEvent);:113-122(SaveBattleTask→SaveBattlePassRecordTask);:117(UpdateUserDataValue("BattlePassRecordTask", battlePass+"#"+battleTask) 单组合键) |
| Achievement 只改内存、直接写已注释、经 PlayerData 合档 | AchievementDataManager.cs:127,150(订阅+UpdateData);:200(//PlayFabMgr...UpdateUserDataValue("AchievementData"...) 注释);DataCenter.PlayerData.cs:35(NewPlayerDataDic 合档事实源) |
MiniBP:provider.SetMiniBattlePassRecord→MiniBPKeyNew |
MiniBattlePassDataProvider.cs:58,168,990 |
LuckyTask:ILuckyTaskGetData.SaveTaskData() 接口多模型 |
LuckyTaskData.cs:18-31,320;EventLuckyGameModel.cs:12、EventLuckMagicData.cs:13 均实现("不把接口名当已穷尽写入点"的表述与多实现一致) |
| TimeRefreshManager 已有 nullable 读取入口、缺失走首次登录分支 | TimeRefreshManager.cs:106-108(DateTime? GetLastLoginTime());:73-75(!lastLoginTime.HasValue 分支) |
Survey TailNumberList 存在,%10 尾数可映射 |
SurveyService.cs:69(surveyDataTable[i].TailNumberList.Contains(tailNumber)) |
IUserService.entityKey 直接使用 PlayFab DTO,与"新类零 PF 类型引用"不可同时成立 |
UserService.cs:6,66(using PlayFab.ClientModels + EntityKey entityKey { get; })——裁决"把 PF 专属身份移出共用契约"是必要而非可选,Duel 三处访问(EventFishingDuelPanel.cs:634-635,748)须同批迁移 |
| CreateTimeUtc/ServerTimeUtc 进入 AccountDescriptor | PlayerKVLoginContext.cs:198,319-330 |
补充事实(支持修订版发布顺序的正确性):EvtAPISvrLoginSuccess 现有订阅者恰三处——ChatService.cs:189、InGameMailHandler.cs:165(触发 FetchMail)、RTService.cs:52(触发连接)。三者分别依赖会话 Cookie、普通请求租约与登录态,修订版"绑定提示服务和同租约普通请求→…→发布事件"的先后顺序与这三个消费者吻合;正式 KV 现状从不发布该事件,修订版补上单次发布是开首场景的必要条件。
3. 待修正(均 P3,不阻塞方案完善)
- P3a「CustomId 增加 setter」表述失准:
IUserService.CustomId已声明get; set;(UserService.cs:70),PlayFabUserService亦已实现(:131)。无需任何接口变更——PFLoginAct.cs:88,167-170的修复就是直接改用userService.CustomId去掉下转。按 AGENTS.md 不应记录一个并不需要的接口修改;该句应改为"直接使用既有 setter"。 - P3b 生命周期契约出现第三个关闭名:既有
CloseKVForValidationAsync(旧类,UserService.KVLoad.cs:193)与StopKVGameplayLoopAsync(kv-loop),契约又引入CloseKVAsync。最终方案须定死契约成员与既有方法的关系(复用改名或明确映射),避免同一关闭动作出现平行 API 面。 - P3c 跨账号公开资料读取未入集中问题单:成员表把"他人 GetPlayInfo/GetPlayLv 的其余跨账号公开资料读取"记为实现依赖,但集中问题单只含新 ID 兼容确认与等级榜聚合两项。PF 模式的他人资料来自 PlayFab 公开档案(
UserService.cs:881-899GetPlayerProfile),KV 模式无此通道;首场景链内 Club 自身响应已含成员资料、不受影响,但后续社交/成员列表 UI 依赖它。应在问题单补第三项(服务端是否提供按新 ID 的跨账号公开资料读取入口),或在最终方案明确这些 UI 的延期产品边界——二选一,不能只留在成员表脚注。
4. 结论
修订版把预审七项、主会话逐项裁决(含 EntityKey DTO 泄漏的处理方向、GetDefaultName/Survey 算法、地区码不拼全局名、身份时序)全部落入正文,且新增声明经抽验无失实。工作稿自认的剩余缺口(奖励写入边界、首场景动态存档链按可达动作展开、跨账号资料消费者)与实际相符。P3 三项修正后,下一步即可编制受审 hash 基线与一次性提示词进入正式前审;本复核不改变"未送审、未获白名单"状态。