Files
joywayerandClaude Opus 5 8e0c8fdc90 二七王:接上 SubGameHooks.DeskInfo(中途进桌),复用重连的重画路径
平台 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) <noreply@anthropic.com>
2026-08-27 22:06:53 +08:00

73 lines
3.4 KiB
JavaScript
Raw Permalink 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.
// SubGameHooks 接线:平台入口 → 新架构
const { load } = require('./_load');
const t = require('./_assert')();
global.window = global; // 转发壳用 window.SubGameHooks 判定
load('client/js/gameabc-framework/system/EventBus.js');
load('client/js/gameabc-framework/system/SpriteEventController.js');
load('client/js/01_SubGame/codes/state/Events.js');
load('client/js/01_SubGame/codes/state/GameState.js');
load('client/js/01_SubGame/codes/state/RoomOptions.js');
['DealHandler','CallHandler','MainHandler','BuryHandler','PlayHandler',
'QueryHandler','ReadyHandler','ResultHandler','ResyncHandler','FailHandler']
.forEach(h => load('client/js/01_SubGame/codes/net/handlers/' + h + '.js'));
load('client/js/01_SubGame/codes/net/Dispatcher.js');
load('client/js/01_SubGame/codes/SubGameHooks.js');
const S = EQW_GameState;
// ---- _ReceiveData:完整包 → 分发 ----
S.reset(); S.room.mySeat = 0;
SubGameHooks._ReceiveData({ app: 'youle', route: 'erqiwang', rpc: 'fapai',
data: { success: true, asetidx: 1, asetcount: 6,
cards: [1,2], seat: 0, countdown: 15 } });
t.eq('_ReceiveData 分发到 handler', S.my.cards, [1,2]);
// ---- setRoomDes ----
SubGameHooks.setRoomDes(123, 12, '00010');
t.eq('setRoomDes 解析选项', S.room.options.climb, 1);
// ---- Free:null 不崩 ----
let boom = false;
try { SubGameHooks.Free(null); } catch (e) { boom = true; }
t.eq('Free(null) 不崩', boom, false);
// ---- Reconnect ----
S.reset(); S.room.mySeat = 1;
SubGameHooks.Reconnect({ count: 6, idx: 3, PlayerInfo: [0,0,0], step: 1, MyCards: [5,6] });
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 {
SubGameHooks._ReceiveData(null);
SubGameHooks._ReceiveData({});
SubGameHooks.StartWar(null);
SubGameHooks.Reconnect(null);
SubGameHooks.DeskInfo(null);
SubGameHooks.setRoomDes();
} catch (e) { boom = true; }
t.eq('畸形入参不崩', boom, false);
process.exit(t.done('hooks') ? 0 : 1);