Files
ft/CodexOutput/upserver/B3BatchMigration/M2/M2-C3c纯平移统一审查入口-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

108 lines
13 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 C3c 纯平移统一审查入口
日期:2026-09-30。用途:交审核 AI 做本次集中审查。**本文件是当前审查入口,取代旧暂存方案的执行优先级;不是生产编码批准。**
## 1. 用户已确定的要求
客户端将原 PlayFab 能力平移给 KV 管理器及其接线,保留原业务方案。LevelB、榜单、好友资料和匹配均属于原有能力,不是新增需求。原来何时写、写什么、如何读、失败后怎样继续,都应保持;仅替换迁移必要的存储、身份和接口。
不得为了分段开发、便于测试或方便接口设计,另做临时副本方案、重构、优化、额外业务修复、客户端拼榜、改变排序、虚构默认资料或冻结功能。确实无法等价替换的差异列出源码、前后行为和影响,再讨论,不自行改业务。
KV身份为认证返回的PlayerId,即新UserID。旧请求字段名playFabId可保留,值用新UserID;不再讨论是否存KV、另选玩家ID或更改原邮件流程。PF/AGG仍在用的路线保留,KV运行链不应调用PF SDK。
固定正式地址 `http://s101.local:18080/`;Unity仅CLI Loop,不用UnitySkills,暂不打包。保留现有工作树;客户端Agent不修改本地或远程服务器代码。审查默认使用本包客户端源码与归档证据,不需要重新操作正式账号。
## 2. 文档优先级与撤回项
阅读顺序:本文件 → `M2-LevelB保持PlayFab原语义裁决-2026-09-30.md` → 原 `M2-C3c剩余SDK接线集中差异与待审方案-2026-09-30.md` 的未解决项 → 本包源码和事实证据。根AGENTS与用户最新裁决优先于历史方案。
| 历史文档/提议 | 当前处理 |
|---|---|
| M2-C3c本人统计KV暂存实施增量及其增量hash | **整个实施候选已撤回**。通用store逐键Write+Flush不是当前待批准方案;hash仅证明历史内容,不能当白名单 |
| M2-先存KV后联调的阶段移植方案 | 用户允许优先推进客户端这一方向保留;把LevelB解释成“可回收临时个人快照”的部分撤回 |
| M2-LevelB与LastLogin服务器只读核查及建议 §5 | 已核源码事实保留;“查询时从lv/建筑派生LevelB、不持久化统计值”的建议不再默认采用,可能改变原上报时点。LastLogin来源意见仍是候选,未批准更改现有每日刷新时序 |
| 原合批正式方案等级榜条目“不新增LevelB冗余键” | 不能把这条历史实现限制解释成取消原统计更新,或授权查询时随意重算。审核需按最新用户裁决核其兼容性;存储容器/键属于实现细节,判断标准是原统计语义能否保持 |
| 原C3c“好友无线上样例”一类历史描述 | 已被101/102双向非空实测覆盖;路由存在、响应类型已知,不再要求重复找接口或样例 |
原受审文档和hash原字节保留,不改写历史。尚未实现被撤回的LevelB提议,也没有相关正式KV写入需要回滚。不要为了撤回该提议再开独立审核轮。
## 3. PlayFab原行为基线(本轮已对照源码)
下列路径相对 `C:/projects/ft/`;行号供定位,最终以hash锁定的文件内容为准。
| 环节 | 源码 | 原行为及不允许改变的部分 |
|---|---|---|
| 首次上报 | Client/Assets/Scripts/Stages/FishingStage.cs:249 | 原位置调用SetLvData,调用者不await这个async void入口;不额外阻断场景流程 |
| 普通升级触发 | Client/Assets/Scripts/DataCenter/DataCenter.PlayerData.cs:378–395 | SetLv完成原事件、OnLvChange、SavePlayerData后调用AwaitSetLvData;不调整先后顺序 |
| 建筑升级触发 | Client/Assets/Scripts/InfiniteBuilding/InfiniteBuildingAct.cs:664–668 | UpdateData后,deltaLvl>0发布原事件并调用AwaitSetLvData;条件不改 |
| 延迟更新 | Client/Assets/Scripts/DataCenter/DataCenter.LeadboardData.cs:209–217 | 已刷新中则返回,否则设置标志,等待原300秒,再SetLvData;不顺手修原并发/调度行为 |
| 分数生成 | 同文件:189–206 | TryParse建筑值;>=100000压到99999;lv超过TbMapData最后项上限则按原逻辑回写;分数lv×100000+建筑值。原异常、负值等缺陷不在迁移中修正 |
| 提交统计 | 同文件:158–169、205 | 一次UpdatePlayerStatisticsAsync请求含LevelB和ContinentCode+LevelB,值相同;await后按原流程复位。客户端一次请求本身**不能证明PF后端事务原子性**,不凭空增加事务要求 |
| 更新失败 | Client/LocalPackages/asap.playfab.async/Runtime/Gen/PlayFabClientAsyncAPI.cs:2430 | 错误回调Debug.LogError后SetResult(null),调用者忽略返回值并结束等待。不要把已知服务失败改成抛异常卡住isRefreshing |
| 全球/地区榜读取 | LeadboardData.cs:171–186、220–254 | 按统计名读StartPosition=0、默认MaxResultsCount=50,要求头像/地区/昵称;沿原条件更新列表及发布PFRankDataEvent。不得自行修改空榜处理 |
| 排名映射 | Client/Assets/Scripts/UI/Social/SocialLeadboardItem.cs:91–99 | PlayerId、Position、Position+1、StatValue、资料及LastLogin映射到原item;不重新给全服结果本地排名 |
| 好友读取 | Client/Assets/Scripts/Services/FriendService.cs:133–216 | 请求头像/昵称/Statistics/LastLogin;沿原过滤,取名为LevelB的Value,按值降序排序,赋position/rank,更新列表和事件/AGG计数 |
| 查询失败 | PlayFabClientAsyncAPI.cs:494、510 | 好友/榜单错误均log后返回null;沿消费者原null条件,不强行改为空成功、清缓存或新增重试 |
| UI解码 | Client/Assets/Scripts/UI/Social/SocialFriends.cs:106–107;SocialLeadboardItem.cs:63–64 | 分数除100000为等级、模100000为建筑等级;不能把普通Level塞入value |
| 伙伴邀请 | Client/Assets/Scripts/UI/PartnerFishBowl/EventPartnerInvitationPanel.cs:360–362 | 使用好友value解码等级,读取LastLogin.Value并按时间排序;不通过过滤好友或伪造时间改变行为 |
例:等级12、建筑34对应1200034;这个值才是原LevelB。地区来源沿现有KVUserService已校验ContinentCode及已审未知地区边界,不增加新来源或开关。
## 4. 当前KV能力与事实,不扩大结论
1. `Core/KVMgr.cs`现有四入口是固定本人handle的ReadKV/WriteKV/FlushKVAsync/WaitForKVTicketAsync;`IPlayerSaveStore`是现有个人存档合同。它们的存在证明本人KV读写能力,单凭这四入口不能证明已有跨玩家统计聚合或好友资料投影。
2. `CustomServerMgr.FriendRequest`等业务请求和新UserID接线已有。不能因KVMgr暂未包装某方法就断言线上不支持该能力;也不能凭猜测新增URL。优先核既有能力和协议映射。
3. 正式`friend/GetFriendsList`已在101/102互加后成功,双方各有1项。每项是JSON字符串,当前实测只有PlayFabId、DisplayName、AvatarUrl、Level;Level均1,无LevelB/Statistics/建筑等级/LastLogin。
4. 同期KV现代档中101等级62、102等级60,来自NewPlayerDataDic.newData第0槽;本次未执行原UpdateProfile路径。不得断言等级差异一定由PF或服务器实现错误造成。普通Level既不能直接用作LevelB,也不能仅乘100000伪装建筑分数正确。
5. 同期两账号KV均未取得LastLoginTimeUtc;当前客户端已有在首场景每日初始化后写该键的实现。它不自动等价于PF资料的LastLogin,也不授权提前覆盖每日刷新使用的旧时间。
6. 已授权只读参考的`D:/ft/server/N3-Server`中,登录服务维护DBPlayer.LastLoginTime,公开缓存仅四字段。参考版本仍有旧PF/十六进制ID路径且缺线上已存在的GetFriendsList action,**不是已核实的线上版本**。本次审查可读取归档报告,不需要改动服务器或推断线上内部实现。
证据:`M2-C3c正式互加好友结果与字段差异-2026-09-30.md`、`M2-C3c正式互加好友实测-final-2026-09-30.json`、`M2-LevelB与LastLogin服务器只读核查及建议-2026-09-30.md`。其中“建议”不具有实现批准效力。
## 5. 请审核AI一次完成的裁决
按下表分别给结论,不要求用户再次确认既定产品方向。能从现有能力找到映射的,给准确源码/文档/协议证据;证据不足则说明尚未证实,不能编造签名或给整包空泛PASS。
| 编号 | 核查问题 | 必须给出的结果 |
|---|---|---|
| R1 原业务保持 | 第3节原链路是否准确,是否遗漏实际写入/读取消费者 | 更正点及具体源码;确认原计算、更新时点、顺序、返回/异常和UI边界 |
| R2 KV统计更新 | 现有KV及业务接口怎样承接原统计更新,是否能保持原触发点和全局/地区含义 | 可复用的实际调用、请求/结果及失败映射;准确列出差异。未找到接口证据不等于要求新增泛化管理器;不要复活已撤回的通用Flush临时方案 |
| R3 榜单与好友读取 | 怎样读取原时点已更新的LevelB用于排名和好友资料 | 数据来源、统计名、玩家UserID、分数、位置、资料字段与null/失败映射。若建议查询时重算,必须指出如何保证与原更新时间等价,不能默认视为机械替换 |
| R4 LastLogin | 实际好友读取能否提供原语义的时间,同时保留现有每日刷新流程 | 使用可核实来源,说明缺值与缓存行为;未确认时保持未裁决,不填假时间或改UI |
| R5 原C3c其余项 | 他人公开资料、公告、匹配的映射是否已有足够证据 | 沿原C3c D3/D5集中结论;已明确部分可以单独批准在同批连续执行,未定义部分不默认延期或移出迁移目标 |
| R6 最小开发范围 | 哪些改动真正是存储/身份/接口平移,哪些是额外设计 | 对每个允许文件、方法和测试给边界;新增抽象须给具体调用点及现有实现为何不足。不得把“更方便开发”作为改业务的理由 |
报告请区分:①证据充分可实施;②有具体合同差异需裁决;③缺少真实接口证据。未验证的线上能力不能写成“不存在”;有明确缺口时,把最小接口问题及源码依据合并在报告末尾,供用户与服务端开发沟通。
已明确方向及原业务边界不反复送审。需要进一步沟通时,只问无法由现有证据确定的具体差异。报告不授权客户端Agent修改服务器。
## 6. 文件范围与验证要求
当前**没有新增编码许可**。供审查确定的最小候选:
- `DataCenter/DataCenter.LeadboardData.cs`:统计更新/查询提供方接线与必要结果映射。
- `Services/FriendService.cs`、必要时`Services/FriendModel.cs`:原好友数据取得与DTO映射。
- 原C3c其他候选`Services/KVUserService.cs`、`Services/TileNewsManager.cs`、`Duel/UI/EventFishingDuelPanel.cs`:只按准确映射批准相关方法,文件入表不代表允许任意修改。
- `CodexOutput/upserver/KVGameLoadTests/ServiceHost/`的既有宿主/新增用例:准确范围由对应接线确定。已撤回暂存方案中的“五测试文件”不自动继承为许可。
生产路径前缀均为`Client/Assets/Scripts/`。UI消费者、升级/建筑业务调用者、HomePanel、配置和场景不因接口替换而修改。现有底层会话/Guard不增加高层业务依赖;不得预先批准无消费者接口或新的管理器。
通过后验证至少覆盖:
1. 原分数上限、有效/坏建筑字符串、统计名/分数与触发顺序;不顺手修负数、溢出等原缺陷。
2. 原同步/异步返回、错误log/null行为、列表及事件先后;无额外等待、重试、防重入或异常修正。
3. KV统计更新后,榜单和好友读出同义分数,包含地区、非空多玩家、名次及资料;对同分顺序/版本策略等源码不能证明的后端行为不凭空添加规则。
4. 原UI解码与伙伴邀请真实消费者,不能只测复制算法或模拟返回对象而声称全链通过。
5. 原handle与UserID归属、注销/换号隔离;KV路径PF调用计数0,PF/AGG对照不变。
6. ServiceHost两条件及Unity CLI Loop编译。合成网络验证与正式联调结果分开记录;本轮只编制文档,没有新测试通过结论。
7. 全流程通关前恢复所有开发冻结/忽略路径,清理仅由迁移造成且已无消费者的实现;统一命名和原业务优化留全迁移结束后另行授权。
## 7. 审查交付与执行衔接
1. 核同目录`M2-C3c纯平移统一审查基线.json`的SHA256、字节数及全部items;该清单引用原C3c清单,原清单也须核验。最新用户裁决覆盖冲突的旧设计,不以旧hash恢复被撤回方案。
2. 不需要重复跑正式互加好友脚本;它有写操作。默认本次为只读审查,若运行离线测试,在报告注明具体命令、条件、结果及证据范围。
3. 继续交付原约定文件`M2-C3c剩余SDK接线独立差异审查-2026-09-30.md`,无需另开LevelB/LastLogin/地区三份报告。报告注明本清单hash、核验项数、R1–R6逐条结论、准确允许范围及未解决项;若追加已有报告,保留旧结论并注明本次增量。
4. 主会话收到后先核受审hash,再逐条裁决。批准范围内连续测试、编码、验证并更新检查点;没有新合同差异不逐功能停下来送审。未批准部分不猜测实现,也不把它们当作移出迁移范围。
本检查点只整理审查文件与入口,未改生产、测试、服务器、配置或正式KV数据,未Play/打包;原工作树保持。此次文档完成不等于整个M2迁移完成。