二七王:下发面 multiple 按房间「爬坡」开关取值

arith.get_multiple_bycall 写死 get_base_bycall(call, false),被
mod.jiaofen(jiaofen/shangzhuang 两个包)与 export.get_deskinfo
的叫分/选主/埋牌/出牌四个阶段共 6 处使用,且都不传 roomtype。

后果:爬坡房里对局全程界面显示的是常规算子子数,与结算包
aset.multiple 不符。例如叫 45 分,界面显示 6 个子、结算按
design §7.3.1 实际是 7 个子。违反 server dev-guide「服务器权威 +
每个下发包必须携带前端界面所需的全部核心数据」与 engineering
SSOT(同一业务数据只有一个计算处)。

移除 get_multiple_bycall 这层写死 climb=false 的兼容包装,全部
改为直接调 get_base_bycall(call, cfg.climb),cfg 由
class.config.parse(o_room.roomtype) 得到——与结算处
get_paiju_account 用的是同一个取值入口。get_deskinfo 内顺带复用
同一份 cfg,去掉 PushCards 分支里重复解析 roomtype 的调用。

test_rpc 新增 7 项:叫 45 分在常规房/爬坡房分别驱动到上庄,断言
上庄包与重连 ChooseMain 的 multiple 为 6/7,并与结算包
aset.multiple 逐一对齐。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-12 04:16:42 +08:00
co-authored by Claude Opus 5
parent c2a375eef5
commit 20b5425a65
4 changed files with 39 additions and 12 deletions
-5
View File
@@ -59,11 +59,6 @@ var cls_youle_erqiwang_arith = cls_youle_erqiwang_arith || {
return 40; return 40;
}, },
//(兼容)叫分对应的基础子数,供叫分阶段展示,默认按常规算子取值
get_multiple_bycall: function(callgrade){
return cls_youle_erqiwang_arith.get_base_bycall(callgrade, false);
},
//牌id转花色 //牌id转花色
id_to_flower: function(cardid){ id_to_flower: function(cardid){
if (cardid == 52 || cardid == 106){ if (cardid == 52 || cardid == 106){
+8 -5
View File
@@ -63,6 +63,9 @@ var cls_youle_erqiwang_export = cls_youle_erqiwang_export || {
return null; return null;
} }
var paiju = o_room.o_desk.method.curr_paiju(); var paiju = o_room.o_desk.method.curr_paiju();
//本局房间可选规则:爬坡改变「叫分 → 基础子数」的取值(design §7.3.1),
//各阶段下发的 multiple 必须与结算包 aset.multiple 用同一套规则
var cfg = cls_youle_erqiwang_config.parse(o_room.roomtype);
var deskinfo = {}; var deskinfo = {};
deskinfo.count = o_room.asetcount; //总局数 deskinfo.count = o_room.asetcount; //总局数
deskinfo.idx = paiju.idx; //当前局数 deskinfo.idx = paiju.idx; //当前局数
@@ -82,7 +85,7 @@ var cls_youle_erqiwang_export = cls_youle_erqiwang_export || {
//当前叫分 //当前叫分
deskinfo.CallRun.nowcall = paiju.method.get_callgrade_value(); deskinfo.CallRun.nowcall = paiju.method.get_callgrade_value();
//当前叫分倍数 //当前叫分倍数
deskinfo.CallRun.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(deskinfo.CallRun.nowcall); deskinfo.CallRun.multiple = cls_youle_erqiwang_arith.get_base_bycall(deskinfo.CallRun.nowcall, cfg.climb);
//所有玩家的叫分情况 //所有玩家的叫分情况
deskinfo.CallRun.call = [null, null, null]; deskinfo.CallRun.call = [null, null, null];
deskinfo.CallRun.call[0] = paiju.method.get_seat_callgrade(0); deskinfo.CallRun.call[0] = paiju.method.get_seat_callgrade(0);
@@ -96,7 +99,7 @@ var cls_youle_erqiwang_export = cls_youle_erqiwang_export || {
//庄家叫分 //庄家叫分
deskinfo.ChooseMain.call = paiju.call; deskinfo.ChooseMain.call = paiju.call;
//庄家叫分倍数 //庄家叫分倍数
deskinfo.ChooseMain.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(paiju.call); deskinfo.ChooseMain.multiple = cls_youle_erqiwang_arith.get_base_bycall(paiju.call, cfg.climb);
//选主倒计时 //选主倒计时
deskinfo.ChooseMain.countdown = o_room.o_desk.method.get_countdown_xuanzhu(); deskinfo.ChooseMain.countdown = o_room.o_desk.method.get_countdown_xuanzhu();
//底牌:暗牌只有庄家可见(70分的3秒亮牌是上庄时的一次性事件,重连不重放) //底牌:暗牌只有庄家可见(70分的3秒亮牌是上庄时的一次性事件,重连不重放)
@@ -117,7 +120,7 @@ var cls_youle_erqiwang_export = cls_youle_erqiwang_export || {
//庄家叫分 //庄家叫分
deskinfo.BuryCards.call = paiju.call; deskinfo.BuryCards.call = paiju.call;
//庄家叫分倍数 //庄家叫分倍数
deskinfo.BuryCards.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(paiju.call); deskinfo.BuryCards.multiple = cls_youle_erqiwang_arith.get_base_bycall(paiju.call, cfg.climb);
//埋牌倒计时 //埋牌倒计时
deskinfo.BuryCards.countdown = o_room.o_desk.method.get_countdown_maipai(); deskinfo.BuryCards.countdown = o_room.o_desk.method.get_countdown_maipai();
//底牌:暗牌只有庄家可见 //底牌:暗牌只有庄家可见
@@ -135,7 +138,7 @@ var cls_youle_erqiwang_export = cls_youle_erqiwang_export || {
//庄家叫分 //庄家叫分
deskinfo.PushCards.call = paiju.call; deskinfo.PushCards.call = paiju.call;
//庄家叫分倍数 //庄家叫分倍数
deskinfo.PushCards.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(paiju.call); deskinfo.PushCards.multiple = cls_youle_erqiwang_arith.get_base_bycall(paiju.call, cfg.climb);
//出牌倒计时 //出牌倒计时
deskinfo.PushCards.countdown = o_room.o_desk.method.get_countdown_chupai(); deskinfo.PushCards.countdown = o_room.o_desk.method.get_countdown_chupai();
//主牌花色 //主牌花色
@@ -154,7 +157,7 @@ var cls_youle_erqiwang_export = cls_youle_erqiwang_export || {
//当前的出牌情况 //当前的出牌情况
deskinfo.PushCards.playproc = paiju.playproc; deskinfo.PushCards.playproc = paiju.playproc;
//座位列表(报副统计)与亮牌:仅可查牌模式下展示(§9/§8.2) //座位列表(报副统计)与亮牌:仅可查牌模式下展示(§9/§8.2)
if (!cls_youle_erqiwang_config.parse(o_room.roomtype).nocheck){ if (!cfg.nocheck){
deskinfo.PushCards.seatlist = paiju.seatlist; deskinfo.PushCards.seatlist = paiju.seatlist;
if (seat != paiju.banker){ if (seat != paiju.banker){
var _lp = paiju.method.get_liangpai(); var _lp = paiju.method.get_liangpai();
+6 -2
View File
@@ -111,6 +111,10 @@ youle_erqiwang.jiaofen = function(pack){
return; return;
} }
//本局房间可选规则:爬坡改变「叫分 → 基础子数」的取值(design §7.3.1),
//下发面的 multiple 必须与结算包 aset.multiple 用同一套规则,否则界面与结算不符
var _cfg = cls_youle_erqiwang_config.parse(o_room.roomtype);
//叫分成功 //叫分成功
o_paiju.method.do_callgrade(call); o_paiju.method.do_callgrade(call);
@@ -126,7 +130,7 @@ youle_erqiwang.jiaofen = function(pack){
msg.data.seat = seat; msg.data.seat = seat;
msg.data.call = call; msg.data.call = call;
msg.data.currcall = o_paiju.method.get_callgrade_value(); msg.data.currcall = o_paiju.method.get_callgrade_value();
msg.data.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(msg.data.currcall); msg.data.multiple = cls_youle_erqiwang_arith.get_base_bycall(msg.data.currcall, _cfg.climb);
msg.data.nextseat = o_paiju.method.get_callgrade_seat(); msg.data.nextseat = o_paiju.method.get_callgrade_seat();
msg.data.countdown = o_desk.method.get_countdown_jiaofen(); msg.data.countdown = o_desk.method.get_countdown_jiaofen();
o_room.method.sendpack_toother(msg, -1); o_room.method.sendpack_toother(msg, -1);
@@ -144,7 +148,7 @@ youle_erqiwang.jiaofen = function(pack){
msg.data.call = call; msg.data.call = call;
msg.data.banker = o_paiju.banker; msg.data.banker = o_paiju.banker;
msg.data.grade = o_paiju.call; msg.data.grade = o_paiju.call;
msg.data.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(msg.data.grade); msg.data.multiple = cls_youle_erqiwang_arith.get_base_bycall(msg.data.grade, _cfg.climb);
msg.data.countdown = o_desk.method.get_countdown_xuanzhu(); msg.data.countdown = o_desk.method.get_countdown_xuanzhu();
if (o_paiju.call != 70){ if (o_paiju.call != 70){
msg.data.touxiang = 0; msg.data.touxiang = 0;
+25
View File
@@ -130,6 +130,31 @@ t.eq('埋牌 不查牌 闲家无liangpai', mpXian && mpXian.data.liangpai, undef
t.eq('重连 可查牌 PushCards有seatlist', E.get_deskinfo(e.o_room, 1).PushCards.seatlist !== undefined, true); t.eq('重连 可查牌 PushCards有seatlist', E.get_deskinfo(e.o_room, 1).PushCards.seatlist !== undefined, true);
t.eq('重连 不查牌 PushCards无seatlist', E.get_deskinfo(en.o_room, 1).PushCards.seatlist, undefined); t.eq('重连 不查牌 PushCards无seatlist', E.get_deskinfo(en.o_room, 1).PushCards.seatlist, undefined);
// ===================== §7.3 下发面 multiple 必须随「爬坡」开关取值(与结算 aset.multiple 同源)=====================
// 叫 45 分:常规算子基础子数 6(design §7.1「50 及以下统一 6」),爬坡 7(design §7.3.1)
const A = require('../class.arith.js');
function driveUp45(roomtype) {
const pj = P.new({ paiju_list: [] }, 0);
const c = setup(roomtype, pj);
mod.jiaofen(pack(0, { call: 45 })); mod.jiaofen(pack(1, { call: 0 })); mod.jiaofen(pack(2, { call: 0 }));
return { pj, c };
}
t.eq('算子 常规房 get_base_bycall(45,false)=6', A.get_base_bycall(45, false), 6);
t.eq('算子 爬坡房 get_base_bycall(45,true)=7', A.get_base_bycall(45, true), 7);
const n45 = driveUp45("00000"); // 常规算子
const p45 = driveUp45("00010"); // 位3=1 爬坡
const szm = c => c.sent.filter(m => m.rpc === 'shangzhuang')[0].data.multiple;
t.eq('上庄包 常规房 multiple=6', szm(n45.c), 6);
t.eq('上庄包 爬坡房 multiple=7', szm(p45.c), 7);
// 重连各阶段同源:选主阶段(step2) ChooseMain.multiple
t.eq('重连 常规房 ChooseMain.multiple=6', E.get_deskinfo(n45.c.o_room, 0).ChooseMain.multiple, 6);
t.eq('重连 爬坡房 ChooseMain.multiple=7', E.get_deskinfo(p45.c.o_room, 0).ChooseMain.multiple, 7);
// 与结算包 aset.multiple 一致(同一 call 同一房间规则)
const aset45 = P.get_paiju_account(
{ call: 45, banker: 0, flower: 1, cards: [], idx: 1, endtime: null, result: null, o_desk: { seatlist: [[0, []], [0, []], [0, []]], o_room: { roomtype: "00010", asetcount: 6 }, method: { get_desk_account: m => m } } },
0, {}).data.aset.multiple;
t.eq('爬坡房 下发面 multiple 与结算 aset.multiple 一致', szm(p45.c), aset45);
// ===================== §11 闲家出牌提示 tishi(只转发给对家,不校验)===================== // ===================== §11 闲家出牌提示 tishi(只转发给对家,不校验)=====================
const mkTip = (step, banker) => ({ step, banker }); const mkTip = (step, banker) => ({ step, banker });
// 闲家1 发"踩"(tip=1),banker=0 → 对家=2;默认 seatlist fromid==座位号 // 闲家1 发"踩"(tip=1),banker=0 → 对家=2;默认 seatlist fromid==座位号