保存独立KV用户服务、固定会话存档与原业务接线,以及C3d资料缓存和C3e本人统计写。 保留原PF/AGG路线、业务公式和时序;榜单读取、好友资料、公告、匹配及首场景闸仍待完成。 验证:ServiceHost两条件各33组646断言;Unity CLI Loop编译0错误269警告。 包含相关方案、评审裁决、测试及状态文档。未操作服务器、正式账号或打包。
12 KiB
M2 C3c 剩余 SDK 接线集中差异与待审方案
状态:已到必要的集中差异审查点,尚未批准本增量编码。 本文不是已完成的实现方案:第3节缺失的调用映射必须由审查结论补齐,不能由实施者临时猜测。既有C2d/C3b结论继续有效。
执行方式:当前客户端主会话实施,同批连续开发;不创建并行开发端,不逐功能送审。
目标:KV模式从KV及其既有业务接线取得原SDK提供的数据,业务逻辑保持原样,PF/AGG有效路线保留。
架构:复用KVUserService、IPlayerSaveStore和CustomServerMgr的现有身份/会话。本人存档由原handle操作;跨账号、榜单、好友关系和匹配按其真实服务能力接入。不为这一批新增泛化Provider、管理器、工厂或新开关,不让底层KVMgr依赖好友/UI/榜单业务。
技术:现有Unity C#、Newtonsoft.Json、Unity CLI Loop与ServiceHost离线宿主。
依据:范围重申与调用清单、已审正式方案、根AGENTS及用户纯平移裁决。
1. 本次继续执行得出的新结论
- 历史文档不是完全没有候选接口:
CodexOutput/upserver/服务端契约核查.md:19记录POST friend/GetFriendsList;《客户端与服务端对比分析.md:50》记录Friends为JSON字符串数组。它们是历史本地版本分析,不是当前线上契约证据;本次没有读取服务器源码。旧集中问题单里“尚不知有无好友路由”的描述应改为“已有历史候选,字段等价性待核”。 friend/SearchFriend已经有客户端调用与DTO,C3b已验证新ID传递。SearchFriendReq.PlayFabId填对方UserID;SearchFriendResp包含Code、Msg、Info,Info为BFriendInfo(PlayFabId、DisplayName、AvatarUrl、Level)。可作为对方资料读取候选,不需要另造URL。原搜索UI按Code > 0消费。但历史分析提示可能返回Unknown默认资料;C3b响应是合成夹具,不能证明正式响应源自KV或资料具有权威性。friend/GetHomePage返回邀请/推荐列表;不拿它当本人/他人完整档案接口。活动event/GetLeaderboards也不能当全球/地区等级榜。- 公告本次加入同一增量:TileNewsManager有SDK调用,NoticePopupPanel有实际事件发布。其源文件不在原候选白名单中,需要一次纳入明确边界。
2. 已证实不能直接机械替换的差异
| 编号 | 客户端原语义与证据 | 机械替换会造成什么 | 本次裁决 |
|---|---|---|---|
| D1 好友等级 | FriendService:169-185从Statistics取LevelB;SocialFriends:106-107将value除以/模100000;伙伴邀请:360也除100000 | 普通Level=12直接填value会在好友UI显示等级0;只乘100000又会丢建筑等级及原排序 | 必须拿到等价LevelB,或真实Lv与建筑等级后按原clamp算法计算。历史方案“Level直接映射”不能继续采用 |
| D2 好友时间 | FriendService:186存LastLogin;EventPartnerInvitationPanel:361无HasValue检查直接读.Value并按时间排序 |
缺时间填null可令符合筛选条件的好友在伙伴邀请列表触发异常;填当前时间/MinValue会改变排序 | 需真实等价时间来源,不能靠更改消费者过滤/默认时间解决。GetActiveFriendCount也使用该字段,但全Scripts检索未发现其调用者,不夸大为已执行链 |
| D3 他人资料 | UserService:849-892原GetPlayInfo同步返回同一占位对象,异步更新对象并发布GetClubPlayInfoEvent;GetPlayLv按目标ID取Lv | KV当前缓存未命中返回null/异常,并不等价;直接换成等待网络后显示又改变原时序 | 候选在KVUserService中恢复原占位对象、缓存更新与事件路径;只替换数据读取。先裁决SearchFriend的结果有效性和失败映射 |
| D4 等级榜 | 原SetLvData编码等级和建筑等级;GetLeadboardData返回全局/地区前50、位置与资料 | 仅保存本人Lv无法生成其他玩家榜;把活动榜接过来改变业务 | 沿用已审“不新增LevelB冗余键”,补准确的KV聚合读取及原统计更新时点映射,不能简单删除Update统计调用 |
| D5 公告/匹配 | 公告读取标题/正文/时间及首项;匹配有创建/3秒轮询/取消/结果 | 空公告或直接MachingEnd(null)只是停用;普通KV写键不能替代多人票据匹配 | 补真实调用映射,保留现有UI和轮询时序;本增量不顺带修原公告异步显示或匹配竞态 |
3. 集中审查需要产出的最小裁决
这不是重新询问迁移方向、新ID或邮件流程,也不要求客户端读取服务器源码。审查侧先查已有资料;能直接指出已有调用方式的就给文件/段落,缺事实才列一次外部沟通项。
| 能力 | 已有可用输入 | 需补的准确映射/事实 |
|---|---|---|
| 他人资料 | 现有SearchFriend请求/DTO、新UserID与同会话FriendRequest | 能否按目标UserID读到KV来源的真实Lv/昵称/头像;Unknown/不存在/请求失败的区分;Info.PlayFabId是否为目标ID。若可复用,给出原GetPlayInfo/GetPlayLv失败形态对应关系 |
| 好友列表 | 历史POST friend/GetFriendsList,Cookie身份、Friends字符串数组 | 现行请求体与完整单项格式、成功/失败Code;等价LevelB或Lv+建筑等级、LastLogin的来源。不可批准“Level直接映射”或用假时间补齐 |
| 等级榜 | 本人KV已有Lv/InfiniteBuildingData/ContinentCode;原分数算法 | 已有聚合路由/输入/结果(统计名、地区、StartPosition、MaxResultsCount、UserID、分数、位置、资料);聚合读取如何与原更新时点对应,未知地区如何沿已审边界处理 |
| 公告 | 原消费者Title/Body/Timestamp和首项选择已定位 | 公告属于全局内容,给实际KV作用域、键或读取入口及发布/排序格式,不能凭名称猜一个私有KV键 |
| 匹配 | 原QueueName、GiveUpAfterSeconds、Tier/Map/Group/Details | 新UserID的创建/查询/取消/读结果调用;TicketId、Status、MatchId、成员UserID/属性的对应。保留3秒轮询和原5秒Ready检查,不用伪EntityKey |
只有旧本地文档或成功合成响应时,明确写“候选/待实测”,不要升级为当前线上已确认。用户已允许必要功能测试;已知原普通路由无需逐条再索要审批。缺的是上述数据语义和新调用映射,不是对测试方向的授权。
4. 候选最小文件边界与实施顺序
确定接口后沿当前主会话按下列顺序实施,不拆新批,不更改既有业务消费者:
| 文件(Client/Assets/Scripts下) | 仅允许的迁移变化 |
|---|---|
| Services/KVUserService.cs | GetPlayInfo/GetPlayLv的目标玩家读取、原缓存对象更新和原事件;本人KV资料及认证流程不改 |
| Services/FriendService.cs | GetFriendList的KV数据取得及映射,保留async void、过滤、排序、发布顺序和原PF分支 |
| Services/FriendModel.cs(新增白名单候选) | 只有现有DTO确实缺少已确认响应字段时补DTO;不重命名现有字段 |
| DataCenter/DataCenter.LeadboardData.cs | KV统计/聚合调用及结果映射,保留原分数计算、展示和活动榜 |
| Services/TileNewsManager.cs(新增白名单候选) | KV公告读取及原TitleNewsItem结果映射,UI消费者零修改 |
| Duel/UI/EventFishingDuelPanel.cs | 同一匹配流程按既有提供方选择接线,KV移除开发性结束路径,PF路线保留 |
| CodexOutput/upserver/KVGameLoadTests/ServiceHost/下现有宿主及新增C3RemainingSdkTests.cs | 链接真实生产类,协议夹具和SDK计数;不得把只测夹具当真实生产覆盖 |
不新增生产接口抽象;若实际签名迫使新增层次,必须给具体调用者和复用现有实现不足的理由,由同一次审查裁决。Core/KVMgr、KV底层协议/Guard、HomePanel、场景资产、服务端代码不在本增量边界。未来需要新增URL分类时先审准确路由,不能开放任意请求。
- 完成客户端与历史接口资料核查、具体差异及消费者核对。
- 建立本增量受审hash与静态核查记录;不重写原C2d/C3b封存。
- 审查逐项补齐第3节映射,明确哪些可立即实施;没有依据的项保持未裁决,不能给空泛整包PASS。
- 主会话核受审hash、逐条裁决并补全可执行签名/响应映射后,在同批先写对应失败用例,再接线至通过。
- 两种ServiceHost条件测试及Unity CLI Loop编译;原PF对照和KV零SDK调用计数同时验证。
- 用正式允许的账号101/102检验已知调用的数据/ID语义,保留脱敏失败供服务端侧处理。正式写入/Play范围按当时明确裁决执行,不混入付费或打包。
- 全链就绪后恢复已登记冻结,最后一次C4实施复核。
5. 验证要求(随实现执行,本次未运行)
- 101查102、反向查询及旧会话撤销:结果必须属于目标账号;PF调用计数KV为0,PF对照仍走原实现。
- 好友Lv=12、建筑=34时原value=1200034;旧好友UI解码12/34、排序不变。缺少建筑/LastLogin不能因解析默认值而伪装测试通过;包含真实伙伴邀请消费者验证时间读取。
- 他人资料缓存未命中:同步占位返回对象保持引用;异步更新和GetClubPlayInfoEvent遵循原行为。接口失败、不存在、Unknown分别按裁决验证,不写回假资料。
- 榜单空榜/50人/同分/地区缺失、更新后读取;公告多项顺序、Timestamp、原红点/显示流程,不能拿内存拼榜冒充聚合。
- 匹配创建失败、等待、Matched、Canceled、取消后的返回;3秒轮询及成员属性解析保持,不顺带加强原竞态行为。
命令:dotnet run --project CodexOutput/upserver/KVGameLoadTests/ServiceHost/ServiceHost.csproj --no-restore;另一条件增加-p:AndroidProbe=true。Unity只运行uloop compile --project-path C:/projects/ft/Client --wait-for-domain-reload true及已核隔离验证。测试需覆盖真实接线,合成HTTP不证明线上KV来源。
6. 给原ZCode的一次性审查指令
先核同目录M2-C3c剩余SDK差异受审hash.json的所有项;读取本文及引用方案,只读客户端和已归档文档,禁止读取/改动本地或远程服务器源码。不要重审C2d/C3b已批准同合同内容。
按D1-D5逐条给出:事实是否成立、已有映射文档位置、客户端最小实现裁决与允许文件、仍缺的具体事实。重点反证“Level直接映射”和“LastLogin置空”是否能保留原流程;若不能,禁止以UI修复规避。
报告写M2-C3c剩余SDK接线独立差异审查-2026-09-30.md,注明受审清单SHA256、逐项核验数量及仅静态/实际测试的区别。不能用用户已批准KV方向代替对新增接口映射的审查;也不反过来要求用户重答方向问题。报告落盘后由主会话核hash、逐项裁决;一次批准范围内连续执行。
7. 当前停止原因与边界
根AGENTS规定:“修改代码前完成相关方案的完整评审,记录裁决和开发边界。”原正式审查只批准原白名单与方案§2–§7的明确行为;尚未给出这些剩余能力的完整映射,公告及必要DTO又增加文件边界。现在直接编码只能猜字段、丢数据或改业务,违反用户纯平移要求,因此在本增量编码前停在集中审查点。
本次未改生产/测试/配置,未发线上请求,未Play/打包,未向其他会话或人员发送消息。当前需要审查侧给出上述具体裁决,不等于已证明服务器必须新增全部能力。
封存前只读核验:原受审基线叠加C2d后2122项Client文件全部一致;C3b的4项交付与8项证据全部一致,0漂移。见M2-C3c只读核查记录.json。本轮没有重跑业务测试;等级除法示例仅用于反证错误映射,不是线上或Unity运行证据。