二七王:B 设计修正发包路由与解散入口

两处对着平台代码核实后修正:

发包必须用 RpcHelper.sendRpc('youle','erqiwang',...),不能用 sendGameRpc
——后者预设 route="room",包会被路由到平台房间模块、永远到不了子游戏 mod.js,且不报错。

解散结算根本进不了 _ReceiveData:平台按 route 分流,room 路由交给 Net[rpc],
只有子游戏路由才转 _ReceiveData。平台另有专门入口 Game_Modify.Free(Desk.deskfree),
取值路径因此比协议文档少一层(deskfree.data.aset),且参数可能为 null 需容忍。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-27 17:05:11 +08:00
co-authored by Claude Opus 5
parent f63de40229
commit d4de34c951
@@ -31,7 +31,7 @@
```
点击(C–E 阶段的组件)
└─ Rpc.sendXxx(意图) 语义化发包,只带「做什么 + 目标标识」
└─ RpcHelper.sendGameRpc 框架基座,自动注入平台字段
└─ RpcHelper.sendRpc('youle','erqiwang') 框架基座,自动注入平台字段
└─ 引擎发送
服务端推送
@@ -61,7 +61,7 @@ client/js/01_SubGame/codes/
BuryHandler.js maipai
PlayHandler.js chupai1 / chupai2 / chupai3
QueryHandler.js mingpai / tishi
ResultHandler.js jiesuan / free_room(解散结算)
ResultHandler.js jiesuan / Free(解散结算,走平台 Game_Modify.Free 入口)
ReadyHandler.js zhunbei
ResyncHandler.js deskinfo(重连)+ StartWar(开局)
FailHandler.js 失败回包(与请求同名的 rpc)
@@ -191,9 +191,14 @@ var _handlers = {
**判定顺序**:`dispatch` 先看 `data.success`——为 `false` 一律交给 `FailHandler`(emit `RPC_FAILED`,带 rpc 与 errcode),不进业务 handler。这样每个业务 handler 都可以假定自己拿到的是成功包。
**② 解散结算走平台路由。** 协议 §14.1:它不是子游戏发的包——`route` 是平台的 `room`、`rpc` 是 `free_room`,子游戏的结算数据嵌在 `data.deskfree.data` 里(**多一层包装**),外层 `data.success` 由平台填写。且解散若发生在首局发牌前,`get_disbandRoom` 返回 `null`,**整个 `deskfree` 缺失**——前端必须容忍。
**② 解散结算走另一个平台入口。** 它**根本进不了 `_ReceiveData`**——平台 `12_Logic.js:258` 按 `_msg.route` 分流,`platform`/`agent`/`room` 三个路由交给 `Net[rpc]`,**只有子游戏路由**(`erqiwang`)才转给 `Game_Modify._ReceiveData`。而解散包的 `route` 是 `room`。
这条不走 `_ReceiveData` 的子游戏分发表,需要在平台入口侧单独识别。
平台为此提供了专门入口:`07_Desk.js:875` 的 `Game_Modify.Free(Desk.deskfree)` → `SubGameHooks.Free(deskfree)`。
两个要点:
- **取值路径比协议文档少一层**:协议 §14.1 描述的是原始下发包(`data.deskfree.data.aset`),但平台已经把 `deskfree` 取出来作为参数传入,所以子游戏侧是 **`deskfree.data.aset`** / `deskfree.data.account`。
- **参数可能是 `null`**:`Desk.deskfree` 初值为 `null`,解散若发生在开战后、首局发牌前,服务端 `get_disbandRoom` 返回 `null`、平台走「不带 `deskfree`」分支——`Free(null)` 必须容忍,只做房间收尾、不弹结算。
**③ `countdown` 只是展示用的秒数。** 协议 §0.3:服务端**没有**对应定时器,归零不会自动叫分/选主/埋牌/出牌,也不判负、不跳过。轮到谁而谁不操作,牌局就停在那一直等。
@@ -205,6 +210,10 @@ var _handlers = {
### 5.1 语义化方法
**必须用 `RpcHelper.sendRpc('youle', 'erqiwang', rpc, data)`,不能用 `sendGameRpc`**——后者预设 `route = "room"`(平台房间模块),而二七王的 route 是 `erqiwang`。用错了包会被平台路由到房间模块、永远到不了子游戏的 `mod.js`,且不会有任何报错。
`RpcHelper` 已自动注入 `agentid` / `gameid` / `playerid` / `roomcode` 四个平台字段,`Rpc.js` 只需补 `seat` 与业务字段。
`Rpc.js` 一个操作一个方法,`seat` 从 `GameState.room.mySeat` 自动带上(协议要求包内 `seat` 供服务端做一致性校验,但**身份由连接反查**,前端填的 seat 不作身份依据):
```js