Files
ft/CodexOutput/upserver/B3BatchMigration/M2/M2-正式接线依赖补审方案-修订2-待评审.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

7.4 KiB
Raw Blame History

M2正式接线依赖补审方案(修订2,待评审)

日期:2026-09-29。继承修订1主方案的“先移植后优化”目标、旧成员映射与CP3–CP5,不回写受审原件。依据修订1独立报告的P2-1以及主会话逐项裁决,修正“CP1–CP2约30–50行即可进正式玩法”的漏项。本方案仍不批准任何生产代码;独立复审后再明确批准边界。

1. 真正依赖顺序

flowchart TD
  A[已关闭:B02四入口/4B2受控验证] --> B[CP1:合成环境中验证正式加载交接合同]
  B --> C[CP2:真实启动/认证/网络/31模块注册接线]
  C --> D[CP3:业务域调用迁移]
  D --> E[CP4:旧Mgr运行引用和自动执行归零]
  E --> F[CP5:证据驱动清理Guard及无用代码]
  X[SubBoostrap总创建PF组件] --> C
  Y[kv配置被拒/登录走PF] --> C
  Z[网络借用仅验证路由] --> C
  W[Bindings仅Editor] --> C

CP1只验证可复用的加载→释放Guard→原handle交接语义,不宣称普通客户端已能登录;CP2才是正式路径。这样不会为绕过启动阻断而复制Editor许可循环或把PF SDK挪进KVMgr。用户要求业务批较大,CP1/CP2是两个不同的系统边界,不按单函数审批。CP1的新增接口在CP2必须实际使用;若CP2评审认为不适用,应在合并前删掉,不保留闲置迁移框架。

2. CP1精确合同(申请独立复审后批准)

  1. PlayerKVLoginContext增加仅 internal 的 TryAcquireGameHandle(long expectedEpoch, out PlayerKVGameSessionHandle handle):在同一Context的prepared==1、未closing/revoked、IsCurrent且handle.Epoch==expectedEpoch时返回现存原对象;不创建新Owner、不公开Cookie;Close前后和旧epoch均失败。取得句柄不代表公布可写状态,最终发布由协调器做。实现不得在Context自身的gate内调用可能重入的外部身份回调。
  2. PlayerKVGameLoadCoordinator保留现有LoadAsync与LoadedForValidation完整语义;新增LoadForGameAsync(string id, PlayerKVGameLoadCapability capability, CancellationToken token, Func<bool> identityCurrent),共用现有Prepare/Decode/Apply主体,不复制200行流程。成功分支在transaction.Apply(...)返回None、notify完成且最终token/context/epoch/Violations复核通过之后取得原handle,随后释放该次Guard,最后发布内部GameLoaded状态。任何一步失败继续走原Revoke/Close;不得仅使KVMgr忽略Guard。返回值必须与LoadedForValidation可区分;历史失败结果不携可用handle。
  3. 协调器增加TryGetCurrentGameHandle(long expectedEpoch, out PlayerKVGameSessionHandle handle),只有正式成功状态、相同epoch、Context当前有效、未closing且Guard已释放才返回;Revoke在关闭异步排水之前同步清除内部可发布引用/状态。调用方捕获该原对象,后续旧回调不得重新查询“当前账号”换Owner。Close并发时即使调用方曾取得对象,也由现有Handle/Slot撤销机制拒绝其操作。具体Guard释放、状态发布与Revoke并发锁顺序列入实施测试,不在锁内await。
  4. CP1不新增通用存档facade、全局handle、PF同名转发、第二套缓存/定时器。PlayerKVGameLoadGuard.cs及KVMgr.cs四入口方法体原样保持。CP1白名单:仅PlayerKVLoginContext.cs、PlayerKVGameLoadCoordinator.cs和直接验证上述时序的既有/新增合成测试宿主;若实际编译确需结果类型在同一协调器文件中增GameLoaded枚举状态,仍属该白名单。不得修改SubBoostrap、UserService、CustomServerMgr或真实账号配置。验证包括原4B2加载回归、B02四入口/Guard、成功交接后合成读写、Apply/notify失败、同账号新epoch、关闭竞态。

CP1只解决原协调器能否产生可写的固定handle。它不是正式运行功能,因此不把Player编译、真实会话登录或B01正式接线记为已通过。只有复审明确认可此拆分及白名单,主会话核hash裁决后才能编码。

3. CP2正式接线必须完整评审的范围(当前不申请编码)

源码入口 当前阻断 CP2所需设计证据
SubBoostrap.cs + PlayFabMgr.Awake 普通启动无条件创建PF组件并启动旧40秒同步;CP1不能要求“PF未启动”同时又沿用普通启动 按启动时捕获的backend分流创建旧组件,PF默认不变;KV模式不建立旧缓冲/定时器。配置变更只影响下一次完整启动,不在半途把已运行PF组件转KV。停用前核Unity生命周期/Prefab调用。
UserService.KVLoad.cs、UserService.cs、AggUserService.cs kv配置拒绝;普通登录PF先行;授权状态和渠道路径依赖PF 精确小写KV分支的单次S101认证、错误码、IsLogin/IsAuthorized/Logout、API身份发布与渠道身份映射;PF分支无改;不得从受控验证工厂/Editor permit偷接正式入口。
PlayerKVControlledLoadCapability.cs + PlayerKVLoginContext.cs 只有UNITY_EDITOR验证工厂;生产配置/三条transport未定 独立正式工厂,固定API地址来自已捕获配置且必须等于s101.local:18080,同一CookieContainer、三条不同拥有者的handler、CacheRoot和表快照来源;不共享/转移验证能力。
PlayerKVGameplayBindings.cs + LoginStage.cs 31模块Bind整文件只在Editor;Player对象注册/静止点未核 只提升实际相同的Snapshot/Bind源码进入Player编译,逐模块核容器注册、登录时序与Apply前静止条件;失败不得以空对象替代。
CustomServerMgr.cs + PlayerKVAccountLease KV借用只允两条验证路由,普通API在kvOnly抛错 以单会话租约承接正式业务API,请求路由/Method白名单、SessionVersion/401/Close隔离、被撤销请求丢弃;不能改回旧Cookie替换。需按即将启用的业务域列真实API调用,不能全开放网络能力。

CP2精确源码白名单、路由清单、账号/历史档策略、Editor/Player编译与真实闭环验收矩阵尚待完整设计审查。其范围显著超过修订1独立报告估计的30–50行。CP1实施时不得擅改CP2文件作为“顺手接线”;CP2完成后才可称正式可运行。Player构建的历史_cheatingScore错误可以单列来源,但正式交付不得把有编译错误的构建算通过。

4. P3归档与停止条件

  • P3-1:Guard当前方法调用按主会话核证为20处/5文件,另有类型/字段引用;本轮只记录用途,不随CP1移动Guard。CP5另判断是否从正式KVMgr调用链移除,并删除最终无用代码。
  • P3-2:CP3每个业务域记PF旧缓冲/40秒/暂停退出触发与KV实际行为差异,CP4停止旧组件前必须对账。
  • P3-3:CP1合成验证可以明确“未声称Player构建通过”;CP2正式可运行要求Player目标0错误。历史错误若需最小修复,先列单独白名单与回归,不混入KVMgr迁移逻辑。

若复审核实CP1接口一经加入就必然要求改普通启动、验证路径无法保持原行为、或Guard释放与Revoke并发无法用现有锁/Handle撤销保证,则不批准CP1编码,退回合并CP1/CP2完整方案。所有检查点继续更新开发日志,默认PF保持原状;无正式账号写入、无打包。