From 8e0c8fdc90620931ab76f88d91d1d54014b2a3ba Mon Sep 17 00:00:00 2001 From: Joywayer Date: Thu, 27 Aug 2026 22:06:53 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=8C=E4=B8=83=E7=8E=8B=EF=BC=9A=E6=8E=A5?= =?UTF-8?q?=E4=B8=8A=20SubGameHooks.DeskInfo=EF=BC=88=E4=B8=AD=E9=80=94?= =?UTF-8?q?=E8=BF=9B=E6=A1=8C=EF=BC=89=EF=BC=8C=E5=A4=8D=E7=94=A8=E9=87=8D?= =?UTF-8?q?=E8=BF=9E=E7=9A=84=E9=87=8D=E7=94=BB=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 平台 07_Desk.js 在「牌局已开始 + 走加入房间而非重连」时调 Game_Modify.DeskInfo(_msg.data.deskinfo), 该 hook 此前只有注释占位,整份 deskinfo 被 02 转发壳静默丢弃、界面全空且不报错。 裁剪核实(读平台源码):两条路径的 deskinfo 都出自 server_room/class.return.js—— 进房走 self_join_room 的 get_deskinfo(o_room, o_player.gameinfo.seat), 登录走 self_login 的 get_deskinfo(o_player.gameinfo.o_room, o_player.gameinfo.seat), 同一个函数、同一个「本人座位」入参。底牌/埋牌底牌只给庄家、亮牌只给闲家、mustcard 只给轮到那家 等可见性裁剪对中途进桌一样生效,不存在「拿到别人视角」的问题,接线安全。 test_hooks 新增 4 条断言,含「同一份 deskinfo 分别喂 DeskInfo 与 Reconnect,snapshot 逐字段相同」。 Co-Authored-By: Claude Opus 5 (1M context) --- client/js/01_SubGame/codes/SubGameHooks.js | 20 ++++++++++++++++++-- client/tests/test_hooks.js | 19 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/client/js/01_SubGame/codes/SubGameHooks.js b/client/js/01_SubGame/codes/SubGameHooks.js index 63a751a..a4f1134 100644 --- a/client/js/01_SubGame/codes/SubGameHooks.js +++ b/client/js/01_SubGame/codes/SubGameHooks.js @@ -122,8 +122,7 @@ SubGameHooks.gamemydraw = function (gameid, spid, times, timelong, no2, no3, no4 // [A] Free(_msg):投票解散确认回调。 // SubGameHooks.Free = function (_msg) { /* ... */ }; -// [A] DeskInfo(_msg):未开战状态下加入牌桌的数据同步。 -// SubGameHooks.DeskInfo = function (_msg) { /* ... */ }; +// [A] DeskInfo(_msg):牌局已开始时加入牌桌的数据同步(实现见文末「网络与对局」一段)。 // [A] breakRoom():开局后自己退出房间触发。 // SubGameHooks.breakRoom = function () { /* ... */ }; @@ -295,6 +294,23 @@ SubGameHooks.Reconnect = function (_deskinfo) { EQW_ResyncHandler.handleDeskinfo(_deskinfo); }; +// 中途进桌:牌局【已经开始】,但自己走的是「加入房间」而非「重连」这条路径。 +// 平台 07_Desk.js 在 self_join_room 且 battlestate==1 时走 Game_Modify.DeskInfo(_msg.data.deskinfo), +// 与 self_login 的 Game_Modify.Reconnect(_msg.data.deskinfo) 是两条并列分支—— +// 不接这个 hook,整份 deskinfo 会被 02 转发壳静默丢弃(无 hook 即 no-op),界面全空且不报错。 +// +// 【入参与 Reconnect 完全同源、且已按【自己的】座位裁剪】: +// 两条路径的 deskinfo 都出自服务端 server/youle/server_room/class.return.js —— 进房走 +// self_join_room 的 get_deskinfo(o_room, o_player.gameinfo.seat),登录走 self_login 的 +// get_deskinfo(o_player.gameinfo.o_room, o_player.gameinfo.seat),同一个函数、同一个 +// 「本人座位」入参。get_deskinfo 内部的可见性裁剪(底牌/埋牌底牌只给庄家、亮牌只给闲家、 +// mustcard 只给轮到的那家)因此对中途进桌一样生效,不会把别人的视角发过来。 +// 故直接复用同一条重画路径(前端 04 §3「重连 = 重画」),不为它单写一套渲染。 +SubGameHooks.DeskInfo = function (_deskinfo) { + SubGameHooks._syncMySeat(); + EQW_ResyncHandler.handleDeskinfo(_deskinfo); +}; + // 重连但未开战:没有牌局数据,无需重画对局 SubGameHooks.ReconnectNoMakewar = function () { SubGameHooks._syncMySeat(); diff --git a/client/tests/test_hooks.js b/client/tests/test_hooks.js index 6088219..c53df31 100644 --- a/client/tests/test_hooks.js +++ b/client/tests/test_hooks.js @@ -39,6 +39,24 @@ SubGameHooks.Reconnect({ count: 6, idx: 3, PlayerInfo: [0,0,0], step: 1, MyCards t.eq('Reconnect 填状态', S.my.cards, [5,6]); t.eq('Reconnect 填局数', S.room.asetIdx, 3); +// ---- DeskInfo(中途进桌)---- +// 平台 07_Desk.js 在「牌局已开始 + 走加入房间而非重连」时调 Game_Modify.DeskInfo(_msg.data.deskinfo)。 +// 入参结构与 Reconnect 完全一致(服务端两条路径都是 get_deskinfo(o_room, 本人座位)), +// 故必须走同一条重画路径;不接线的话整份 deskinfo 被转发壳静默丢弃、界面空白且不报错。 +const MIDJOIN = { count: 6, idx: 2, PlayerInfo: [3,-1,-2], step: 5, MyCards: [10,11], + PushCards: { banker: 1, call: 60, multiple: 3, flower: 2, grade: 25, + curmultiple: -1, baozhu: 0, countdown: 30, + playproc: { round: 4, start: 1, currseat: 2, cards: [null,[12],null] } } }; +S.reset(); S.room.mySeat = 2; +SubGameHooks.DeskInfo(MIDJOIN); +t.eq('DeskInfo 已接线(不再静默丢包)', S.my.cards, [10,11]); +t.eq('DeskInfo 复用重连的重画路径(阶段)', S.aset.step, 5); +t.eq('DeskInfo 复用重连的重画路径(控制权读 playproc.currseat)', S.turn.seat, 2); +t.eq('DeskInfo 与 Reconnect 落地结果逐字段相同', + (function () { const a = JSON.stringify(EQW_GameState.snapshot()); + S.reset(); S.room.mySeat = 2; SubGameHooks.Reconnect(MIDJOIN); + return a === JSON.stringify(EQW_GameState.snapshot()); })(), true); + // ---- 畸形入参一律不崩 ---- boom = false; try { @@ -46,6 +64,7 @@ try { SubGameHooks._ReceiveData({}); SubGameHooks.StartWar(null); SubGameHooks.Reconnect(null); + SubGameHooks.DeskInfo(null); SubGameHooks.setRoomDes(); } catch (e) { boom = true; } t.eq('畸形入参不崩', boom, false);