首页 / 横向专题 / 协议总索引
协议总索引
八大模块涉及的全部协议,号码全部核对自 Src/Core/Define/Net/NetDefine.ts。
拿到一个陌生协议号先来这里查。
284
SCNotify
252
CSReq
1
CSPush
537
合计
1. 命名与编号规律
| 后缀 | 方向 | 客户端 API | 说明 |
|---|---|---|---|
| XxxSCNotify | S → C | Net.Register / Net.UnRegister | 单向通知,服务器主动推 |
| XxxCSReq | C → S | Net.Call / Net.CallAsync | 请求,必有对应 SCRsp |
| XxxSCRsp | S → C | 作为 Call 的回调参数 | 不用单独 Register,Net 层已做请求-响应一对一映射 |
| XxxCSPush | C → S | Net.Push | 单向推送,不等回包。全工程只有 1 条 |
Req / Rsp 号码是连号的
看到偶数号的 Rsp,减 1 就是它的 Req。 排查时如果只看到 Req 没看到 Rsp,说明服务器没回或者被超时丢了。
WorldEnterDungeonCSReq = 20503 → WorldEnterDungeonSCRsp = 20504WorldClientSameSceneLoadDoneCSReq = 14716 → SCRsp = 14717看到偶数号的 Rsp,减 1 就是它的 Req。 排查时如果只看到 Req 没看到 Rsp,说明服务器没回或者被超时丢了。
1.1 号段分布
| 号段 | 数量 | 业务归属 |
|---|---|---|
| 10xxx / 11xxx | 42 | 登录、玩家基础数据 |
| 13xxx | 34 | 战斗 |
| 14xxx | 139 | 关卡玩法(最大的一段)。坠落重生、LoadDone、场景加载都在这 |
| 15xxx | 17 | 行为树 + 传送/移动同步 |
| 20xxx | 31 | 副本(进出、结算、爬塔星级) |
| 23xxx | 55 | 地图与传送点(解锁、标记、追踪) |
| 26xxx | 60 | 背包、道具 |
| 29xxx | 111 | 组队、社交 |
| 30xxx | 62 | 任务 |
| 37xxx | 12 | 爬塔局外 |
号段不完全等于模块
所以号段只能缩小范围,精确归属还得查下面的表。
15xxx 里前半段(15002-15016)是行为树,后半段(15508-15512)才是传送。
同样 14xxx 是个大杂烩,涵盖整个关卡玩法。所以号段只能缩小范围,精确归属还得查下面的表。
2. 传送
| 号 | 协议名 | 方向 | 作用 |
|---|---|---|---|
| 15512 | WorldTeleportSelfSCNotify | S→C | 传送入口。携带目标坐标 + reason + serverMoveVersion,reason 决定走哪条分支 |
| 14716 | WorldClientSameSceneLoadDoneCSReq | C→S | LoadDone 多人栅栏。「本端准备好了」+ 重置服务端「不可主控」标记。靠 serverMoveVersion 幂等去重,5 次退避重试 |
| 14717 | WorldClientSameSceneLoadDoneSCRsp | S→C | LoadDone 回包。收到即结束重试 |
| 15509 | WorldTeleportEnterSCNotify | S→C | 进入传送体积/区域 |
| 15510 | WorldTeleportLeaveSCNotify | S→C | 离开传送体积 |
| 15511 | WorldServerEntityMoveSCNotify | S→C | 服务器驱动的实体位移 |
| 15508 | WorldEntityMoveBatchErrorSCNotify | S→C | 批量移动错误通知 |
| 14596 | WorldSyncDirPosSCNotify | S→C | 朝向与位置同步,TeleportController 也监听 |
| 14525 | WorldClientLoadDoneCSReq | C→S | 跨场景加载完成(和 14716 的同场景版区分开) |
| 14564 | WorldClientEnterLevelDoneCSReq | C→S | 进入关卡完成 |
| 14572 | WorldClientSceneLoadAnimDoneCSReq | C→S | 场景加载动画播完。没有 Seq3 时必须显式 emit 关闸,否则只能等 20s 兜底 |
14716 vs 14525:同场景 vs 跨场景
用错会导致服务器状态机对不上,表现为「传送完了但服务器认为你还没到」。 改传送代码时先确认当前是哪条路径。
SameSceneLoadDone(14716) 用于同图同步瞬移;
ClientLoadDone(14525) 用于跨图传送走完整 Loading 的那条路。用错会导致服务器状态机对不上,表现为「传送完了但服务器认为你还没到」。 改传送代码时先确认当前是哪条路径。
已删除的历史协议
但
15504 / 15505 / 15506(PreServerMove 三件套)已在 0.7.0 清理,
连同 moveComp 的两个字段一并删除。但
Protocol.d.ts 是 proto 自动生成的,
需要协调服务器同步删 .proto,否则下次生成会写回。
在老日志里看到这三个号是正常的。
3. 传送点与地图
| 号 | 协议名 | 方向 | 作用 |
|---|---|---|---|
| 23707 | WorldTeleportCSReq | C→S | 请求传送到某传送点。传送点模块的核心请求 |
| 23705 | WorldUnlockTeleportSCNotify | S→C | 传送点解锁通知。首次靠近解锁后落存档 |
| 23701 | WorldMapFullDataSCNotify | S→C | 地图全量数据(登录/进图时) |
| 23702 | WorldMapUpdateSCNotify | S→C | 地图增量更新 |
| 23703 | WorldMapDataCSReq | C→S | 主动拉取地图数据 |
| 23706 | WorldUnlockMapMarkSCNotify | S→C | 地图标记解锁 |
| 23714 | WorldUnlockMapFogSCNotify | S→C | 迷雾解锁 |
| 23709 / 23711 | WorldTraceMapMarkCSReq / StopTrace | C→S | 追踪/取消追踪地图标记 |
| 23713 | WorldClearTraceMapMarkSCNotify | S→C | 清除追踪 |
| 23715 / 23717 / 23719 | Save / Update / Delete CustomerMapMark | C→S | 自定义标记的增改删 |
| 23721 | WorldCustomerMapMarkChangedSCNotify | S→C | 自定义标记变更通知 |
| 23722 / 23724 | Start / Stop TraceCustomerMapMark | C→S | 追踪自定义标记 |
| 23726 | WorldTraceCustomerMapMarkChangedSCNotify | S→C | 自定义标记追踪变更 |
| 23727 | WorldTraceRoleInfoSCNotify | S→C | 追踪玩家信息 |
| 23728 / 23729 | RedNameMonster Appear / Disappear | S→C | 红名怪出现/消失 |
| 23730 / 23732 | Trace / StopTrace RedNameMonster | C→S | 追踪红名怪 |
4. 副本(含结算)
| 号 | 协议名 | 方向 | 作用 |
|---|---|---|---|
| 20528 | WorldDungeonSettleSCNotify | S→C | 副本结算数据下发。整个结算三阶段的起点 |
| 20501 | WorldDungeonFullDataSCNotify | S→C | 副本全量数据 |
| 20502 | WorldDungeonUpdateSCNotify | S→C | 副本增量更新 |
| 20503 / 20504 | WorldEnterDungeon Req/Rsp | 双向 | 进入副本 |
| 20505 / 20506 | WorldReEnterDungeon Req/Rsp | 双向 | 重进副本 |
| 20507 / 20508 | WorldLeaveDungeon Req/Rsp | 双向 | 退出副本。ShowInfo 参数从这里透传 |
| 20512 | WorldDungeonRewardSCNotify | S→C | 副本奖励 |
| 20513 / 20514 | Dungeon Enter/Leave CloseArea | S→C | 进入/离开封闭区域 |
| 20516 / 20517 | DungeonTeleportCloseArea Req/Rsp | 双向 | 封闭区域内传送 |
| 20518 | WorldDungeonDefeatSCNotify | S→C | 副本失败 |
| 20520 | WorldDungeonMatchFlagSCNotify | S→C | 匹配标记 |
| 20522 | WorldDungeonClientLoadDoneSCNotify | S→C | 副本内客户端加载完成广播 |
| 20523 | WorldDungeonStateUpdateSCNotify | S→C | 副本状态更新 |
| 20525 / 20527 | DungeonClickLike Req / Notify | 双向 | 结算点赞 |
| 20529 / 20531 | DungeonStatistics Update / Enable | 双向 | 副本统计数据(结算面板数值来源) |
5. 爬塔
5.1 局内(副本内实时 HUD)
| 号 | 协议名 | 方向 | 作用 |
|---|---|---|---|
| 20532 | WorldDungeonTowerStarStartSCNotify | S→C | 星级监听开启 + 全量下发。带 starList 和 starsMask。主控树上必须放「开启星级监听」节点才会发 |
| 20533 | WorldDungeonTowerStarUpdateSCNotify | S→C | 单档增量更新。只带变化的那一档,不刷整体 mask,客户端需双源 OR 反算 |
5.2 局外(存档与排行)
| 号 | 协议名 | 方向 | 作用 |
|---|---|---|---|
| 37501 | WorldTowerClimbDataSCNotify | S→C | 爬塔总数据 |
| 37502 | WorldTowerClimbTaskSCNotify | S→C | 塔任务更新 |
| 37503 | WorldTowerClimbBestRecordSCNotify | S→C | 最佳记录(星级落存档)。局内打完的星级最终落在这 |
| 37504 / 37505 | TowerClimbTaskList Req/Rsp | 双向 | 拉取任务列表 |
| 37506 / 37507 | TowerClimbTaskTakeReward Req/Rsp | 双向 | 领取任务奖励 |
| 37508 / 37509 | TowerClimbSelfRankList Req/Rsp | 双向 | 拉取自己的排行信息 |
| 37510 | WorldTowerClimbSelfRankListSCNotify | S→C | 排行信息推送。存 Map 时读写 key 不一致是已知 bug |
6. 关卡玩法(重生 / 计时器 / 子弹)
| 号 | 协议名 | 方向 | 作用 |
|---|---|---|---|
| 14710 | WorldFallingRebornCSReq | C→S | 坠落重生请求。客户端检测到 Z 低于 SafeDepth 后发起 |
| 15016 | WorldBehaviorTreeTimerParameterSCNotify | S→C | 计时器玩法数据。带 status(Running/Paused/Stopped)+ 时间戳,只有 Running 才叠加 timeDiff |
| 14523 | WorldReviveSCNotify | S→C | 复活通知 |
| 14522 | WorldForbidReviveSCNotify | S→C | 禁止复活 |
| 14718 | WorldSuicideCSReq | C→S | 自杀(GM/卡死自救) |
| 14712 | WorldLevelSwitchVolumeCSReq | C→S | 关卡切换体积 |
| 14584 | WorldLevelPlayerPositionSCNotify | S→C | 关卡内玩家位置广播 |
| 14585 | WorldLevelAiSpawnerInfoUpdateSCNotify | S→C | 刷怪器信息更新 |
| 15002-15016 | WorldBehaviorTree* | S→C | 行为树节点/变量更新。关卡玩法的驱动核心,计时器也挂在这套上 |
关卡子弹没有专属协议
子弹走的是环境怪(EnvMonster)中转,复用怪物系统的创建/销毁协议,
再靠 15 位 TypeId 编码子弹类型。
所以排查子弹问题不要去 grep「Bullet」协议,找不到的—— 要看环境怪的实体创建流程。
所以排查子弹问题不要去 grep「Bullet」协议,找不到的—— 要看环境怪的实体创建流程。
7. 场景加载与流送
| 号 | 协议名 | 方向 | 作用 |
|---|---|---|---|
| 14528 | WorldSetLayerTaskSCNotify | S→C | 服务器下发子关卡列表。带 layerTaskNameList,落进 ServerLayerTasks 后与旧集合求差集开关 DataLayerRuntime_SubMap_* |
| 14504 | WorldEnterLevelSCNotify | S→C | 进入关卡。场景加载链的常规触发源 |
| 14503 | WorldLeaveLevelSCNotify | S→C | 离开关卡,对应卸载链 |
| 14525 | WorldClientLoadDoneCSReq | C→S | 跨场景加载完成(同场景版是 14716) |
| 14526 | WorldClientLoadDoneSCRsp | S→C | 上面的回包 |
| 14564 / 14565 | WorldClientEnterLevelDoneCSReq / SCRsp | C→S / S→C | 进入关卡完成上报与回包 |
| 14572 / 14573 | WorldClientSceneLoadAnimDoneCSReq / SCRsp | C→S / S→C | 加载动画播完。对应主链 ⑲ SceneLoadingAnimDownCmd |
| 14580 / 14578 / 14579 | WorldDestructScene* | 双向 | 场景破坏物同步 |
DataLayer 本身不走协议
服务器只下发子关卡名字列表(14528),
拼成
所以「某个 DataLayer 没开」不要先怀疑协议—— 先用
DataLayerRuntime_SubMap_{name} 和实际开关都是客户端做的。
另一批 DataLayerRuntime_EntityLevel_{levelId} 更是纯客户端按当前关卡 Id 推导,
完全没有对应协议。所以「某个 DataLayer 没开」不要先怀疑协议—— 先用
WhereAmI 看客户端算出来的状态。
8. 使用规范
8.1 注册与注销必须配对
protected override OnRegisterNetEvent(): void {
Net.Register(ENotifyMessageId.WorldDungeonTowerStarStartSCNotify, this.OnTowerStarStart);
Net.Register(ENotifyMessageId.WorldDungeonTowerStarUpdateSCNotify, this.OnTowerStarUpdate);
}
protected override OnUnRegisterNetEvent(): void {
Net.UnRegister(ENotifyMessageId.WorldDungeonTowerStarStartSCNotify);
Net.UnRegister(ENotifyMessageId.WorldDungeonTowerStarUpdateSCNotify);
}
注意 UnRegister 只要消息号,不要 handler
因为一个消息号只能有一个 handler(不是列表)。
两个模块 Register 同一个号,后注册的会覆盖前一个——
「协议明明发了但回调没触发」时查这个。
8.2 int64 必须转换
// ❌ protobuf 的 int64 是 Long 对象,直接算得 NaN
const t = progress.condition.waitTimeData.endTimeMs;
// ✅
const t = MathUtils.LongToNumber(progress.condition?.waitTimeData?.endTimeMs ?? 0);
时间戳、uid、大数值属性都要转。这是「数值算出来是 NaN」的头号原因。
8.3 收包端的四条防御
| 防御 | 为什么 |
|---|---|
| Model 可能还没装载 | ModelManager.XxxModel?. 用可选链,协议可能早于 Model 初始化到达 |
| 字段全部可选 | proto3 里所有字段都是 optional,notify.info?.starList ?? [] |
| 增量按主键有则更新无则插入 | findIndex 找到就改、找不到就 push,不要假设顺序 |
| 处理完必须 Emit | 中途提前 return 会导致 UI 不刷新,「首档不亮」就是这么来的 |
8.4 增删协议的正确姿势
1
先和服务器约定号码和字段
号码从对应模块的号段里取,Req/Rsp 连号
2
服务器改 .proto 并同步生成
Protocol.d.ts 是自动生成的,客户端不要手改3
在 NetDefine.ts 加枚举项 + 类型映射
枚举、
TNotifyProtocol 映射、MsgConfig 路由三处都要加4
删协议时必须双边同步
只删客户端不删
.proto,下次生成会全部写回——
看起来「删干净了、编译过了」,几天后又冒出来