6.8 KiB
独立审查记录:迁移交接与后续开发
日期:2026-09-21。审查人:独立审查 agent handoff_review。本轮只读核查生产源码、既有验收记录与交接方案,仅新增本文件;未运行测试、未连接正式服务、未写玩家数据。审查不构成新增运行验收。
裁决
交接材料有条件通过。 当前状态基本准确:用户已确认实际登录;PlayFab 存档仍在使用;新 KV 适配未实现;SignalR 配置不等于首连/重连已验收。历史测试与本轮静态核查已正确分开。
- A 可开始调用盘点、契约分类、模拟测试设计。 本人/目标玩家 ID 分类与具体改动文件清单落盘复核后,才实施该批接口修正。身份生命周期修改必须先补充下文 P1-2/P1-3 的方案与测试边界。
- B 可开始协议模型、参数/响应测试及独立传输层设计。 现有方案第 B2 条尚未决定生产会话桥接,不能据此直接把 KV 接到可换号的全局 manager。桥接方案明确并完成评审后才能实现相应绑定。
- C 不放行。 需 A 中相关身份/生命周期和 B 读写隔离验收通过,并完成缓存/同步专项设计评审;当前不切换游戏存档。
- D 不放行。 需各外围功能替代契约及回归证据,不能凭登录成功删除 PlayFab。
这些条件是对方案完整性的审查结论,接手 agent 可以补充技术方案并再次审查,不代表必须再次向用户索取已经给出的测试账号授权。
发现与开发阻塞项
P1-1:仍有新服务器请求使用 PlayFab 身份(已知,未修复)
证据:Client/Assets/Scripts/Services/UserService.cs:425 将 loginResult.PlayFabId 赋给 UserId;ClubService.cs:229,291,352,433,474,494,504,515,529,542,591 的自身 playerId 仍来自 userService.UserId。ClubService.cs:308 还以旧 ID 填充 internalIdToPlayerId,不能仅修改请求对象后宣称该服务身份清理完成。
影响:旧十六进制 ID 仍可能发往十进制服务,产生解析错误;映射缓存和目标 ID 也可能继续传播旧身份。未证明服务器已产生错误写入。
要求:A 的清单必须包含缓存映射、聊天载荷、目标玩家来源;将“本人 ID”与“目标 ID”分开。不能直接把 applyId、appointId 等改成登录本人。完成清单和测试后逐批修改;不是把整个 UserId 全局改成涂游 ID。
P1-2:HTTP 业务请求和未授权事件没有会话代际(C 阻塞)
证据:CustomServerMgr.cs 的 ReplaceTransport 只 Dispose 旧客户端并替换 Cookie;CustomServerPost / GetStringAsync 不验证请求完成时所属账号,401/403 发布无账号信息的 EvtAPISvrUnauthorized。UserService.cs:150 的订阅会清空当前 InternalId 并按当前 CustomId 自动重登。登录函数有 generation 校验,普通业务请求没有。
影响:旧请求若已完成传输、延后处理,仍可能返回给新会话调用方;旧 401 可能影响当前账号。Dispose 旧客户端不能代替应用层响应归属检查。这是源码风险,不是已复现的数据串号事故。
要求:在实现会话共用前明确不可变账号+环境标识、会话代际、取消机制、旧响应丢弃及未授权事件归属;覆盖“101 请求发出→切102→101响应/401到达”。B 必须绑定固定会话,过期会话不能改用新 Cookie 执行旧写入。
P1-3:SignalR 首连事件与旧连接生命周期未完成(实时验收阻塞)
证据:RTService.cs:125 的 OnHubConnected 只挂在 Reconnected;Connect 的 StartAsync 成功后没有处理 _cachedEvents,而 OnEvent<T> 在未连接时会缓存。Reset / Release 未等待 StopAsync / DisposeAsync;WaitForAPISvrLogin 不保存/释放订阅;UserService.Logout 仅清 HTTP 状态。QuitAct.cs:42 确实调用 Release,因此不能误写为“退出完全不释放 Hub”,但当前释放为异步未等待。
影响:首次连接成功可能收不到之前注册的业务事件;重登/退出期间旧连接及迟到回调缺少确定的隔离边界。仅看到 Connected 日志不足以验收。
要求:集成人单独评审并实现可等待的连接替换/释放、订阅生命周期与代际检查;首连建立业务事件绑定;测试首次收事件、断线重连、重登、退出后迟到事件。完成前不宣称实时阶段通过。
P1-4:KV 会话桥接需要具体设计(B 生产绑定阻塞)
证据:S101AccountSession.cs 自有 private HttpClient;CustomServerMgr.UseAccountSession 新建另一 HttpClient 并共享原 CookieContainer;后续方案 B2 要求注入由调用者拥有的 HttpClient,但还没有明确谁创建/释放、怎样获取固定会话及失效通知。
要求:先落盘具体接口及所有权:API 基址、账号、代际、Cookie 与 HttpClient 的创建/释放者、换号何时拒绝新请求、在途写入结果如何标识。禁止把 CustomServerPost 直接当完整 KV 传输适配:其 null 会合并多种失败且编辑器/错误日志会打印请求体,不满足错误分类和存档值不记录要求。
P2-1:服务端无版本条件更新,客户端冲突策略能力有限
证据:C:/projects/N3-Server-CN/LeaderboardBLL/Services/PlayerKV/PlayerKVService.cs,Get 只返回字符串字典;Set 查询已有行后添加/覆盖并 SaveChanges,无 revision/CAS。PlayerDataApi.cs 按 Cookie NameIdentifier 取账号,Set/Delete 返回空 Ok。
裁决:方案对契约和限制描述正确。三方比较能发现部分冲突,不能封闭读取与写入之间的竞争窗口。C 的验收及产品策略必须保留这一限制;“无重试”也不代表超时请求一定未写入,需要允许结果未知并读回核对。
P2-2:接手编译复现仍依赖本地生成物
证据:新增《验证入口.md》明确 RuntimeCompile.rsp 被忽略、需要重新生成;既有 RuntimeCompile.log 是历史证据。25 项测试和用户登录反馈不能当成整个 Unity 项目的新版本验收。
建议:接手首个验证任务保存生成命令/脚本及实际结果,或者使用 Unity 完整导入编译记录;文件边界与测试结果一起记录。当前足够理解状态,但不能仅复制旧 DLL/RSP 就宣布新改动通过。
高频落盘与交接建议
认可接手入口规定的“小任务即保存、持续开发每 15 分钟检查点、阶段变化先记裁决”。每个检查点至少写:准确文件、账号/环境边界、已执行命令与结果、未执行项、阻塞与下一动作。多 agent 各写独立日志,集成人维护共享状态。
本轮没有执行任何代码修改和生产数据操作。上述问题多数已被总体方案提及;本审查将其转换为明确证据和阶段门,不重复宣称已修复。