Files
ft/CodexOutput/upserver/B3BatchMigration/M2/M2-先存KV后联调的阶段移植方案-2026-09-30.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

68 lines
7.5 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 先存KV、后联调的阶段移植方案
日期:2026-09-30。
用户最新方向:可以先在KV保存对应数据,优先完成PlayFab→KV客户端移植,等与服务器真正联调时再确定最终接口修改,并将阶段移植方案保存到文档。
**本文件记录已确定的阶段方向及候选实施边界。本轮仅文档落盘,尚未新增生产代码或正式KV数据,不将方向确认写成实现已完成。** 本增量并入现有C3c集中裁决,不另拆一轮逐字段审核;修改代码前仍按根AGENTS完成完整方案评审和明确边界。
## 1. 阶段目标与范围
把“客户端已知数据如何存入KV”和“服务器如何批量查询并返回跨玩家数据”分开推进。后者的最终方案不再反复阻断已可定义、已审通过的客户端存储替换。
本次临时保存范围是此前讨论的LevelB与登录时间。好友关系、全服/地区排名、公告及匹配结果不能凭本人KV快照生成;不扩大为任意存一份假结果后删除SDK调用。
保留原玩家等级、建筑等级、排序、同步/异步方式和UI流程;使用认证返回的UserID与固定原handle。PF/AGG分支仍在使用的实现继续保留。固定http://s101.local:18080/,Unity只用CLI Loop,不使用UnitySkills,暂不打包,不修改服务器源码。
## 2. 先保存的数据
| 数据 | 临时KV方案 | 值与时点 | 状态 |
|---|---|---|---|
| LevelB | 候选新增本人KV键LevelB,存十进制分数字符串 | 原SetLvData计算出的值;玩家等级×100000+建筑等级,原等级上限和建筑上限不变;原统计更新触发点保存 | 待本增量完整裁决后实施 |
| 地区等级统计 | 已有合法地区时,若原更新同时包含地区统计,候选按原地区统计名保存同一分数;不新增地区来源 | 沿已审地区缺失边界,未知地区不编造前缀,也不当作全球榜替代 | 随LevelB接线在同一方案落实,不新增独立地区开关 |
| LastLogin | 复用已存在的KV键LastLoginTimeUtc,不另加内容相同的LastLogin键 | 已有KVUserService.LoginTime取登录响应服务器时间;FishingStage先完成每日初始化,再按现有顺序保存UTC往返格式O | 客户端读写代码已有;正式101/102本次读取时尚无该键,不能称已落正式档 |
LevelB是迁移期分数快照,源仍是原玩家等级和建筑数据;不让它反向覆盖玩家等级,不新增第二套等级计算。名字暂时保留原统计名,PlayerKV类名也按先前要求留到整个迁移完成后处理。
**本次用户方向允许讨论暂存LevelB,覆盖之前“优先不新增LevelB冗余存档”的建议,但不自动改写原已封存方案或hash。** 原规则的目的仍保留:必须登记临时快照、固定计算来源,联调后确认保留或收回,不能长期无说明地维护两套独立真值。
## 3. 客户端接线候选边界
1. 复用现有IPlayerSaveStore与KVMgr/原handle完成KV写入,不新增管理器、泛化Provider、缓存层、开关或服务器依赖。
2. `DataCenter.LeadboardData.cs`:在原统计更新位置按现有提供方分流。KV保存对应统计快照;PF保留原UpdatePlayerStatisticsAsync。SetLvData分数计算、async void入口、调用者顺序及UI不重构。确认/拒绝/Unknown沿现有store合同,不用空成功假装已同步。
3. `KVUserService.cs`、`FishingStage.cs`:本轮登录时间优先复用当前实现,不新增一个登录时提前写同名时间的分支。特别不能在跨日初始化消费旧值之前把它覆盖为当前时间。
4. 测试沿现有ServiceHost、离线存档测试与CLI Loop;同批验证目标账号、两个统计值、原分数上限、保存/读回、换号不串档、失败结果、KV分支PF调用计数0及原PF路线保持。
5. 本候选只解决本人存储,不把GetLeadboardData直接改成本人单项列表,也不把所有好友时间写成自己的时间。跨玩家读取的最终DTO/字段映射留在下节联调待办,未明确前不编造路由。
## 4. 服务端联调时再定的内容
- 好友列表继续一次返回各好友资料。线上friend/GetFriendsList与101/102非空样例已存在,无须再次询问是否有接口;当前项仅ID、昵称、头像、普通Level,缺LevelB/LastLogin。
- LevelB最终由服务器从KV等级/建筑字段计算,还是直接读取这次暂存的分数键,联调时决定。保持与原配置上限和更新时点一致。普通Level仍是普通等级,不能替换成复合分数。
- LastLogin最终读取KV的LastLoginTimeUtc,还是复用账号服务已有DBPlayer.LastLoginTime,由联调决定。两者写入阶段不同:KV当前在首场景初始化后确认;账号数据库时间在认证登录时更新。选择时明确语义,不悄悄更改每日刷新流程。
- 旧账号无时间键的处理、服务器原有资料缓存刷新、好友Level与真实KV等级不一致一起核对。不得用当前查询时间伪造历史登录时间。
- 榜单聚合、公开资料、公告、匹配仍是迁移内待完成项;记录准确读写映射后接线,不因暂存方案宣布完成或默认砍掉功能。
当前证据:101/102已互加,KV现代存档等级为62/60,好友接口Level均1;源KV还没有LastLoginTimeUtc。参考服务器代码已记录数据库登录时间,但本地参考版本不等于线上部署版本。已有源码与线上证据继续保留,不凭此再猜服务器状态。
## 5. 临时项登记与最终关闭条件
| 临时项/未完成项 | 最终必须处理 |
|---|---|
| 新增LevelB及可能的地区分数KV快照 | 联调后确定是否成为正式接口数据;若无消费者,移除本次新增的闲置写入/读取实现。若保留,明确唯一计算和写入来源。正式历史KV键的清理按最终方案执行,不直接删除用户数据 |
| KV登录时间与服务器登录元数据候选来源 | 确定好友查询唯一来源;保留业务意义不同的每日刷新状态,不维持两条互相覆盖的好友时间写入路径 |
| 双登录阶段闸、KV匹配暂时结束、其他开发冻结/忽略路径 | 全部登记待恢复;最终通关前必须放开并验证,不能用保持冻结替代移植完成 |
| 已落KV但尚未接通跨账号读取 | 状态只记“本人存储接线完成/跨玩家查询待联调”,不能记全链通过 |
| 临时测试脚本、适配实现及DTO | 删除迁移造成且确无消费者的实现;原有效功能、PF/AGG分支保留,不夹带重构 |
最终验证须覆盖真实非空好友、等级/建筑/时间正确、原伙伴邀请/排名流程、保存退出后恢复,以及KV运行路径无PF SDK调用。整个迁移完成后才处理此前登记的原缺陷、优化及统一命名。
## 6. 当前执行顺序
- [x] 用户阶段方向已记录,临时项、真实线上事实与最终清理条件已登记。
- [ ] 将本人统计快照写入范围、地区缺失行为及测试边界并入C3c完整裁决;已有登录时间实现不重复设计。
- [ ] 裁决范围内连续实施和验证客户端KV存储替换,不逐模块停下来送审。
- [ ] 在服务端联调阶段确定最终数据来源和返回字段,完成所有跨玩家能力。
- [ ] 恢复开发临时路径、清理闲置实现,完成同批最终复核。
本轮没有修改客户端生产/测试源码或服务器源码,没有新增线上请求或KV写入。此前已经批准的101/102好友关系和必要时103–110测试权限保持;当前客户端正式准入开关不因测试账号授权自动扩大。