Skip to content

事件与数据模型 ​

事件信封 ​

json
{
  "v": 1,
  "type": "round.open",
  "table": "B001",
  "seq": 1532,
  "prev": 1531,
  "ts": "2026-09-24T03:00:30.000Z",
  "game": "baccarat",
  "shoe": "260924-03",
  "round": 12,
  "roundKey": "B001-260924-03-12",
  "data": {}
}
字段类型必填说明
vint是协定主版本,目前为 1;更大的版本回 UNSUPPORTED_VERSION
typestring是事件类型(见下表);本平台还不认得的类型会 ack 后忽略
tablestring是来源桌号,[A-Za-z0-9_.:-]{1,64}
seqint是视频流内严格递增,≥ 1,可以不连号
prevint是同视频流上一笔事件的 seq;第一笔为 0;必须小于 seq
tsstring是来源端事件时间,UTC ISO-8601 含毫秒(2026-09-24T03:00:30.000Z),且必须是存在的日期。来源主机必须以 NTP 校时
gamestring已知类型必填baccarat、dragontiger 或 niuniu
shoestring靴、局事件必填来源靴号,[A-Za-z0-9_.:-]{1,64};同一张桌内永久不重复(建议含日期)。牛牛没有靴,这里是场次(见牛牛)
roundint局事件必填本靴(牛牛为本场次)第几局,1–100000
roundKeystring局事件必填同一张桌内永久唯一,[A-Za-z0-9_.:-]{1,128};同一局的修正与作废沿用
dataobject是依类型而定
  • 未知的字段一律忽略;添加字段属于兼容变更,不升主版本。
  • 「靴事件」:shoe.start、shoe.end;「局事件」:round.open、round.close、card、reveal、round.result、round.correct、round.cancel(局事件也需要 shoe)。

事件目录 ​

type时机data
table.info连接后每桌送一次;内容变更时再送{name, game, decks?, dealer?, video?[], capabilities: {cardByCard, countdown, snapshot}}
table.status状态改变{status: "open"|"paused"|"maintenance"|"closed", reason?}
table.snapshot无法重送时,或重连后主动对齐{status, phase: "idle"|"betting"|"closed"|"result", shoe?, round?, roundKey?, closesAt?, history: [{round, result}], gap}
shoe.start新靴开始{decks?}
shoe.end靴结束(选用){rounds}
round.open开放下注{closesAt?, betSeconds?, lastInShoe?, dealer?}
round.close停止下注{}
card发出一张牌(选用,需 cardByCard 能力){pos, card, faceDown?}
reveal牛牛逐家开牌(选用){hands: ["P1"]}
round.result开牌结果(第一版){rev: 1, complete, result}
round.correct修正已发布的结果{rev: n+1, complete, result, reason}
round.cancel本局作废{reason: "misdeal"|"dealer_error"|"device_error"|"table_closed"|"other", note?}
dealer.change换荷官{dealer: {id, name, photoUrl?}}

本平台的处理:

type处理
table.info更新桌台目录;未绑定的来源桌列为「已发现、未绑定」
table.status非 open 时立即停止收注
table.snapshot以快照重建状态与本靴路单
shoe.start清空路单、通知玩家换靴
round.open开局并计算停止下注时间(见时间与下注时窗);lastInShoe: true 让游戏提示「本局后换靴」
round.close立即停止下注
card若仍在下注中立即停止下注;推播开牌动画。牛牛带 faceDown: true 的牌不公开牌面,只通知玩家「发了一张到这个牌位」
reveal公开这几家暗发的牌(前台逐家翻牌);只用于牛牛
round.result验证后结算
round.correct依来源信任等级与护栏自动重算,或维持原结果并列为争议局(见信任等级)
round.cancel结算前:全额退款;结算后:规则同 round.correct
dealer.change显示在游戏画面

字段限制:name 1–128 字符;decks 1–16;betSeconds 1–600;dealer.id 1–64 字符、dealer.name 1–128 字符、dealer.photoUrl 必须是 https://;video 最多 8 笔,每笔 {protocol: "webrtc"|"flv"|"hls"|"agora"|"whep", url?, quality?: "sd"|"hd", auth: "none"|"token"|"referer"};reason、note 最多 500 字符;history 最多 200 笔;closesAt 为含毫秒的 UTC 时间;faceDown 为布尔值;reveal 的 hands 为 1–4 个不重复的 B、P1、P2、P3。

补充规则:

  • 同一个 roundKey 在下注中再送一次 round.open,视为更新倒数(例如荷官重设计时);停止下注后才送达就忽略。
  • 没有 round.open 就直接收到结果(例如来源中途接上)时,只更新路单,该局不接受下注。
  • 不能以第二个 round.result 修改结果:必须用 round.correct 并递增 rev(round.result 的 rev 固定为 1,round.correct 的 rev ≥ 2,而且必须有 reason)。同一个 rev 送出不同的结果时,本平台维持原结果并记录为冲突。

游戏数据模型 ​

牌面编码 ​

<点数><花色>:点数 A 2 3 4 5 6 7 8 9 10 J Q K,花色 S 黑桃、H 红心、D 方块、C 梅花。例如 AS、10H、QD。

百家乐 result ​

json
{
  "cards": { "P1": "2C", "B1": "4H", "P2": "3D", "B2": "2S", "P3": "10S" },
  "player": 5,
  "banker": 6,
  "winner": "B",
  "playerPair": false,
  "bankerPair": false
}
  • 发牌位置 P1 B1 P2 B2 P3 B3,未发的牌省略。
  • player、banker 为点数 0–9;winner 为 P、B、T(和)。
  • complete: true 时必须有完整牌面(至少 P1 B1 P2 B2)。本平台会重算点数、输赢、对子,并检查补牌规则,不一致时回 RESULT_INCONSISTENT,再依信任等级处理。
  • complete: false 时可以只给 player、banker、winner、playerPair、bankerPair,选填 cardCount(两家合计张数 4–6)。
  • 上例是庄 6 点胜:闲 2+3=5 补 10 仍为 5;庄 4+2=6,闲第三张为 0,庄不补。

龙虎 result ​

json
{ "cards": { "D": "KH", "T": "9S" }, "winner": "D" }
  • winner:D 龙、T 虎、TIE 和。
  • 点数由牌面决定:A=1 … K=13(A 最小),不比花色;点数相同且花色相同为同花和。
  • complete: false 时可以只给 winner;这种情况下同花和与大小单双(看各方的牌)无法判定,这些注会退款。先前已送过的 card 事件仍会用来判定。
  • card 事件的位置为 D、T。

牛牛 result ​

json
{
  "cards": {
    "F": "7H",
    "B-1": "KS", "B-2": "QD", "B-3": "10C", "B-4": "3S", "B-5": "5H",
    "P1-1": "4C", "P1-2": "6D", "P1-3": "JS", "P1-4": "9C", "P1-5": "KH",
    "P2-1": "2D", "P2-2": "8S", "P2-3": "QC", "P2-4": "AH", "P2-5": "2C",
    "P3-1": "7D", "P3-2": "3H", "P3-3": "KD", "P3-4": "5C", "P3-5": "5D"
  },
  "hands": { "B": 8, "P1": 9, "P2": 3, "P3": 10 },
  "winners": { "P1": "P", "P2": "B", "P3": "P" }
}
  • 牌位:头牌 F;庄 B-1~B-5;闲一 P1-1~P1-5,闲二 P2-1~P2-5,闲三 P3-1~P3-5(-n 是发到那一家的第几张)。
  • hands:各家牌型代码,0 无牛、1–9 牛几、10 牛牛、11 五花牛、12 炸弹、13 五小牛(11–13 只在打开特殊牌型的桌使用)。winners:P1、P2、P3 各自对庄,P 闲赢、B 庄赢(没有和局)。牌型与比牌规则见桌台与局结果。
  • complete: true 时必须有 21 张(头牌+四家各 5 张),hands 可以省略。
  • complete: false 时至少要有 winners(平倍就能结算)。翻倍要有赢的那一手的牌型才能结算,所以请尽量附上 hands,没有时翻倍的注退款。先前已送过的 card 事件仍会用来判定。
  • 本平台一律依牌面重算牌型与输赢,来源声明的 hands、winners 只拿来比对。检查项目:21 张不重复(一局一副牌)、牌型与输赢符合牌面(特殊牌型关闭的桌出现 11–13 也算不符);逐张送 card 时另外检查头牌最先发、之后第 n 张的牌位照头牌决定的顺序、同一个牌位不重发、结果的牌与已发出的牌相同。任何一项不符都视为 RESULT_INCONSISTENT,依信任等级处理。
  • 发牌顺序:头牌点数 A 5 9 K 从庄先发、2 6 10 从闲一、3 7 J 从闲二、4 8 Q 从闲三,之后照 庄 → 闲一 → 闲二 → 闲三 轮流,每家 5 张。上例头牌 7♥,所以依序发到 P2-1、P3-1、B-1、P1-1、P2-2…;庄牛8,闲一牛9 赢、闲二牛3 输、闲三牛牛 赢。
  • 场次:每局一副新牌、没有靴,以 shoe 当场次(例如每 60 局或换荷官时送 shoe.start 换一场),round 是本场次第几局;table.info 的 decks 建议填 1。

发牌与开牌的事件(建议逐张送,table.info 的 capabilities.cardByCard 为 true):

  1. round.open → round.close(第一张牌送达时也会立即停止下注)。
  2. 头牌:card {"pos": "F", "card": "7H"}。头牌一律是明牌,F 不能带 faceDown: true。
  3. 20 张依头牌决定的顺序发出,面朝下的牌带 faceDown: true:card {"pos": "P2-1", "card": "2D", "faceDown": true}。本平台收下牌面但不公开,只通知玩家「发了一张到闲二」;不带 faceDown 的牌就是明牌,照常显示。
  4. 逐家开牌:reveal {"hands": ["P1"]},建议依 闲一 → 闲二 → 闲三 → 庄 各送一次(一次也可以开好几家);本平台公开这几家的牌。reveal 只用于牛牛(其他游戏回 INVALID_EVENT),和其他局事件一样需要 shoe、round、roundKey。
  5. round.result(complete: true,21 张)。还没开的家,本平台会依 闲一 → 闲二 → 闲三 → 庄 补开后再公开结果。

时间与下注时窗 ​

  • 来源的 closesAt 是权威的下注截止时间。本平台实际停止下注的时间取下列三者最早的一个,再提前约 1 秒(吸收玩家端延迟):
    • closesAt 加上时钟偏移估计
    • 收到 round.open 的时间加上桌设置的最长下注秒数
    • 收到 round.close 或第一张 card 的时间
  • 来源没有 countdown 能力时,以 betSeconds 或桌设置的秒数计时。
  • 时钟同步:心跳带来源时间,本平台据此估算时钟偏移并监控延迟。停止下注的时间依赖正确的时钟,请务必以 NTP 校时。

elite 租户集成 API v1