Files
ft/CodexOutput/upserver/客户端与服务端对比分析.md

81 lines
8.9 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.
# 客户端与 N3-Server-CN 对比分析
更新说明:服务端 a3d3faa 已补齐通用玩家 KV Get/Set/Delete,本文未找到KV的结论已过期;最新接口及兼容差异见《KV更新复核.md》。
进一步核查修正:friend/GetHomePage仅返回社交列表,不能作为本人资料恢复接口。当前开发方案、资料来源限制及评审裁决见《客户端迁移详细修改方案.md》。
日期:2026-09-15。客户端 feat/upserver / f40a816cc,加已批准的 SignalR 选项修改;服务端本地 main / 696fc8c。分析以当前源码为准,不代表远端部署版本已经核对。此次只分析及更新文档。
## 一、结论
服务端已实现渠道十进制身份、Cookie 登录、自建 SignalR 和好友列表;它尚不能在当前检出中完整替代客户端使用的全部 PlayFab 功能。优先打通账号和实时连接,再补齐 KV 契约及外围依赖,最后删除 SDK。
## 二、核心接口对照
| 项目 | 客户端当前实现 | 服务端当前实现 | 差异与处理 |
| --- | --- | --- | --- |
| API 地址 | DebugConfig 和 CustomServerMgr 缺省指向旧 IP:5292;本地配置可覆盖 | 用户指定 s101.local:18080,根路径/时间接口已可达 | 地址及生效配置仍需修改;本次仅 SignalR 选项已改 |
| 身份来源 | AggUserService 将渠道 ID 放在 CustomId;随后 PlayFab 登录生成 hex UserId | PlayerIdUtil 使用 long.Parse,拒绝负值 | UserId 应来自渠道 ID;不能对旧 hex 做进制转换代替身份迁移 |
| 登录路由 | POST account/Login,发送 playerId/playerProfile | 同一路由;playerProfile 可选 | 路由基本一致,主要差异是身份语义与初始化数据 |
| 登录返回 | 只读 state/internalId,LoginApiServer 为 async void | 成功返回 state=0、internalId、createTime、svrTime、newCreate,签发 Cookie | await 业务登录,失败不返回 Done;专用 DTO 接收并映射时间/新账号标志 |
| 登录附带资料 | PlayFab 返回 UserData、昵称、头像、地区、创建/上次登录时间、EntityToken | LoginResp 无 KV、昵称头像、地区、上次登录时间和实体令牌 | 逐项指定新来源;不能删掉 PlayFab 调用后用空值继续初始化 |
| KV 读取 | PlayFab 登录 InfoResultPayload.UserData,CompareDatas 后 LoadPlayerData | 当前检出未找到通用 KV 读取路由,登录也不带存档 | 需要确定 KV 服务/分支;不能用服务器 players 表代替游戏存档 |
| KV 写入 | UpdateUserData,字符串键值、LastUpdated、本地缓存、批量及立即同步 | 当前检出未找到等价通用写入路由 | 定义批量读写、时间/版本、失败重试、跨玩家读取权限后实施 |
| SignalR | /gamehub,业务登录事件触发,复用 CookieContainer | /gamehub RequireAuthorization,用户标识来自 Cookie | 认证与路径一致,已添加 SkipNegotiation+WebSockets;仍需实际登录验证 |
注:服务端模型属性 InternalId/CreateTime 采用默认 MVC JSON 命名策略;客户端的 internalId 不能仅凭 C# 属性大小写判为不兼容。最终用真实响应或契约测试确认。
## 三、登录顺序必须调整
旧顺序:渠道身份 → PlayFab 登录/资料/KV → 初始化玩法 → 异步发业务登录 → 提前返回 Done。
建议新顺序:渠道身份 → 等待 account/Login 并确认 state → 保存会话/内部 ID/服务时间 → 获取完整玩家资料与 KV → 初始化玩法 → 返回 Done。
API 授权成功事件与游戏数据就绪要明确分开:SignalR 可以在拿到 Cookie 后建立连接,但消费玩法消息的代码需要在数据就绪后执行,或在此期间缓存消息。实施方案需核查所有 EvtAPISvrLoginSuccess 订阅者再确定事件时序。
首次登录建议不上传尚未恢复的等级/昵称等默认资料:服务端 AccountService 每次登录都会把非空 playerProfile 写回 DBPlayer,客户端默认数据可能覆盖已有资料。先取资料/存档,再按明确字段更新。服务端 GetHomePage 可作为资料查询候选,需核对响应是否覆盖登录初始化所需字段。
## 四、KV 需要的契约
PlayFabMgr 不只是本地缓存。它负责远端记录与本地值合并,再供大量玩法加载;服务端的 DBPlayer 只有账号资料,Redis 的玩法状态也不能证明存在可供客户端调用的通用 KV API。
必须明确:
1. 读写路径、鉴权方式、全量/指定 key 读取及响应模型。
2. 空存档与请求失败的区分;字符串值、每 key 更新时间/版本。
3. 并发策略、写入确认与重试、批量大小限制。
4. 当前 Public UserData 中哪些允许其他玩家读取,哪些只能当前账号访问。
5. 全新区服是否沿用服务端文档“不迁移旧 PlayFab 存量”决策;本地旧缓存也不能混入新渠道账号。
现有队列还有可靠性缺口:SyncData 在请求确认前轮换缓冲,失败仅记日志;改造时应保留未确认批次并防止旧重试覆盖新值。立即同步与批量同步也必须有明确先后规则。
## 五、删除 SDK 的外围依赖
| 功能 | 客户端依赖 | 服务端可用能力 | 判断 |
| --- | --- | --- | --- |
| 好友列表 | PlayFab GetFriendsList,读取 Profile.Statistics/LastLogin | POST friend/GetFriendsList;Friends 为每项已序列化的 JSON 字符串 | 可适配,需两层解析;PlayerInfo 给 Level,不给 Statistics/LastLogin,在线时长展示需另定来源 |
| 玩家资料 | GetPlayerProfile、UpdateAvatarUrl、UpdateUserTitleDisplayName | account/UpdateProfile、friend/GetHomePage | 有候选;需核对读取/失败语义,不能保持原“先 PlayFab 后业务”双写 |
| 地区与语言 | PlayFab Locations、SetProfileLanguage | 登录响应未提供 | 明确渠道/本地设置/服务端字段的责任,不编造地区 |
| 等级/地区排行榜 | UpdatePlayerStatistics、GetLeaderboard,LevelB 等统计名 | event/GetLeaderboards、event/UpdateScore | 已有的是活动排行榜,不能直接当作全球/地区等级榜替代 |
| 公告 | GetTitleNews | 本次控制器检索未找到等价公告端点 | 契约缺口;不能用空列表假装迁移完成 |
| 对战匹配 | Create/Get/CancelMatchmakingTicket、GetMatch,依赖 EntityKey | duel/DuelRT 负责对战实时请求 | 对战同步不等于票据匹配,需要等价匹配服务或经评审的玩法切换 |
| 账号工具 | PlayFabTools 用渠道 ID 再登录 PlayFab 查资料 | 服务端渠道身份/玩家查询 | 删除这条旧映射,具体替代查询需核实 |
## 六、易遗漏的客户端兼容问题
- FriendService.cs:375:邀请码把 ID 当 hex 转整数;应核对编码和解码的整个链路。
- SurveyService.cs:56:用户尾号筛选按 hex 转换,会改变十进制渠道用户分组。
- DinggingSceneData.cs:94:随机种子按 hex 转换;迁移后需要明确可复现规则,避免既有玩法结果突变。
- UserService.cs:140:默认名使用 id[0..5];服务端允许较短数字 ID,不能默认长度至少为 5。
- RTService:连接前注册的订阅进入 _cachedEvents,但刷新仅挂在 Reconnected;首次 StartAsync 成功没有刷新调用。从控制流看存在首连漏订阅风险,需回归测试验证,不属于已批准的两项选项修改。
- Logout 当前只清 PlayFab 凭据和字段,业务 Cookie 生命周期需在迁移方案中一并处理。
## 七、建议实施顺序与评审裁决
1. API 地址与现有本地覆盖项修改,验证实际生效;SignalR 两项配置已经落地。
2. 完成十进制账号登录方案:响应 DTO、await、时间/资料来源、Cookie、失败处理和所有 ID 依赖点。
3. 确认 KV 契约;无契约前不替换存档初始化,不直接删除 SDK。
4. 迁移好友等有明确替代接口的功能;逐项解决公告、排行、匹配缺口。
5. 清理 SDK 包、类型、程序集和热更新引用,执行编译及回归。
6. 用专用账号验证登录、KV 写后读与重新登录、SignalR 无 negotiate 且可调用 Test/接收推送/重连。
裁决:SignalR 选项子集实现与服务端方向一致;全量去 SDK 方案仍有 KV 和外围能力缺口,暂不放行。地址/登录可分别形成限定边界的开发批次,但账号登录成功不能冒充完整游戏登录验收。
## 源码入口
- 客户端:Client/Assets/Scripts/Services/{UserService,AggUserService,FriendService,RTService,SurveyService,TileNewsManager}.cs
- 客户端:Client/Assets/Scripts/Core/PlayFabMgr.cs、Client/Assets/Scripts/DataCenter/DataCenter.LeadboardData.cs、Client/Assets/Scripts/Duel/UI/EventFishingDuelPanel.cs
- 服务端:LeaderboardAPI/Controllers/{AccountApi,FriendApi,EventLeaderboardApi,DuelApi}.cs、LeaderboardAPI/Program.cs
- 服务端:LeaderboardBLL/Models/AccountModel.cs、LeaderboardBLL/Utils/PlayerIdUtil.cs、LeaderboardBLL/Services/PlayerInfo/{AccountService,PlayerInfoCacheService}.cs、LeaderboardBLL/Services/Friend/NewFriendService.cs