平台 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>
73 lines
3.4 KiB
JavaScript
73 lines
3.4 KiB
JavaScript
// 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);
|