NON-PRODUCTION

Baccarat — tài liệu ghép client

Cược Player / Banker / Tie + side bet. Envelope lobby game_event; payload bàn là bytes proto baccarat_event. Frame WS là binary, không JSON.

1. Tổng quan

MụcGiá trị
ConnectGET /ws?access_token=<JWT> trên domain game (không phải docs)
Lobbyinternal/proto/game-event · package game_event
Gameplaypackage baccarat_event. C→S bọc trong Request.data_send.data
Card idrank * 4 + suit. Điểm cửa = tổng rank mod 10 (10/J/Q/K = 0, A = 1)
1 userMột connection. Duplicate login → lobby 102

Side enum

Giá trịCửa
0 PlayerNhà con, trái
1 BankerNhà cái, phải (thường 0.95:1)
2 TieHòa
3 PlayerPairPlayer có đôi
4 BankerPairBanker có đôi
5 BigKhoảng cách điểm 5–6
6 SmallKhoảng cách điểm 4
7 PerfectPairĐôi cùng chất
8 EitherPairMột trong hai cửa có đôi

State enum

Pending=0 · Countdown=1 · DealTime=2 · ShowdownTime=3 · BetTime=4 · PreShowdownTime=5. Chỉ cược khi BetTime (sau start_bet).

2. Demo felt

PLAYER
0 · P8
TIE
2
BANKER
1 · B6

Viền vàng = cửa win (win_sides). Side bet (Pair/Big/Small) vẽ chip quanh felt; tỷ lệ lấy room_state.side_list.

3. WS envelope (đầy đủ)

Mọi frame là binary protobuf, không JSON. Handshake close code: 0 closed · 1 other device playing · 2 too many conn · 4 token expired · 5 banned.

GET /ws?access_token=<JWT>     // domain game, ví dụ wss://baccarat.example/ws

Gameplay bytes: client marshal baccarat_event.Request → nhét vào lobby:

game_event.Request.data_send {
  room_id: 42
  data: <bytes baccarat_event.Request>
}

Server đẩy bàn qua:

game_event.Response.game_message {
  room_id: 42
  data: <bytes baccarat_event.Response>
}
Ngoài data, game_message còn user_joined / user_left / start_countdown / start_game / reset_game / auto_leave.

4. Lobby C→S / S→C

C→S (game_event.Request)Field
room_configrỗng → Response.room_config (room_types, play_now, best_choice, disable_*)
get_room_listbet
create_roombet, password, max_players, name
join_roomroom_id, password, is_viewer
join_any_roombet, max_players
leave_roomroom_id
find_roomroom_id → is_private
inviteroom_id, password, user_id
free_users_listbet
send_chat_messageroom_id, message, to[], is_private_chat
data_sendroom_id + data (bytes game) hoặc auto_leave
S→C (game_event.Response)Field
room_config / room_listconfig sảnh, danh sách bàn
game_messagepayload bàn (bytes hoặc join/left/countdown)
errorcode + tag (xem mục 7)
chat_messageroom_id, user_id, message, name, vip
invite / someone_invited_youlời mời

5. Gameplay proto baccarat_event

C→S Request (oneof) — gửi trong data_send.data

MessageFieldGhi chú
bet TagBet=1side, bet_amount, count[{bet, count}]Một cửa. count = số chip từng mệnh giá để animate
multiple_betbets[] = repeated RequestBetNhiều cửa một lúc
cheatplayer_cards[], banker_cards[]Non-prod / cheater
// C→S bet Player 1000
Request { bet { side: Player  bet_amount: 1000  count { bet: 1000  count: 1 } } }

// C→S multiple_bet
Request { multiple_bet { bets { side: Banker bet_amount: 500 } bets { side: Tie bet_amount: 100 } } }

S→C Response (oneof) — nhận từ game_message.data

MessageField chính
room_statestate, count_down_millis, state_start_time, state_end_time, bet, players[], player_cards[], banker_cards[], player_score, banker_score, side_list[{side,multiplier,total_bet}], winning_sides[], logs[], bets[], is_registered_leave, max_bet, max_bet_by_vip
start_betdelay_millis — mở cửa cược
bet / multiple_betecho: user_id, side, bet_amount, side_total_bet, seat, player_total_bet, count[]
dealrỗng — bắt đầu chia bài
pre_showdownresult[{user_id, amount, user_money}], bet_sides[{side, bet_amount}] — sync chip sau khi trừ cược
finishplayer_cards[], banker_cards[], win_sides[], player_score, banker_score, sides_win_amount[{side,win_amount}], players_sides_win_amount[{user_id, sides_win_amount, avatar, name, total_amount, user_money}]
errorcode + tag (tag=1 RequestBet)
// S→C start_bet
Response { start_bet { delay_millis: 20000 } }

// S→C finish (Banker thắng)
Response { finish {
  player_cards: [4, 20]
  banker_cards: [8, 16, 1]
  win_sides: [Banker]
  player_score: 8
  banker_score: 6
  sides_win_amount { side: Banker  win_amount: 95000 }
  players_sides_win_amount {
    user_id: 1001  total_amount: 950  user_money: 500950
    sides_win_amount { side: Banker win_amount: 950 }
  }
} }

room_state — restore khi join giữa ván

FieldTypeClient
stateStateKhóa/mở chip. Chỉ BetTime mới gửi bet
count_down_millis / state_end_timeint32Đồng hồ. Ưu tiên end_time unix
players[]PlayerInfouser_id, name, chip, avatar, seat, disconnected, state (0 view / 1 play), bet_sides[], level, vip
player_cards / banker_cardsint32[]Có khi đang Deal/Showdown
side_listSideMultiplier[]Paytable thật — multiplier + total_bet từng cửa
betsint64[]Mệnh giá chip hợp lệ
max_bet / max_bet_by_vipint64Chặn cược / banner nạp
logsGameResult[]Bead road: player_score, banker_score, win_sides
// C→S echo bet (S→C)
Response { bet {
  user_id: 1001  side: Player  bet_amount: 1000
  side_total_bet: 48000  seat: 2  player_total_bet: 1000
  count { bet: 1000 count: 1 }
} }
// pre_showdown — trừ cược, ghi đè chip nếu UI lệch
Response { pre_showdown {
  result { user_id: 1001  amount: -1000  user_money: 499000 }
  bet_sides { side: Player  bet_amount: 48000 }
} }
Chip UI lúc tap cược là optimistic. Khi pre_showdown lệch thì ghi đè user_money. Win thật lấy từ finish.players_sides_win_amount.

6. Luồng ghép

Connect /ws
room_config
join_room / join_any
start_bet
bet / multiple_bet
deal → pre_showdown → finish
  1. WS connect JWT. Nhận close 1/2/4/5 thì dừng, hiện lý do.
  2. Gửi room_config rồi join_any_room / create_room / join_room.
  3. Nhận room_state — restore felt, chip, cửa đang mở.
  4. Khi start_bet: đếm delay_millis, enable chip.
  5. Gửi bet (Tag=1). Echo cập nhật total cửa.
  6. deal khóa cược. pre_showdown sync money. finish lật bài, highlight win_sides, cộng chip.

7. Error codes

HandshakeÝ nghĩa
0 / 1 / 2 / 4 / 5closed · other device playing · too many conn · token expired · banned
LobbyÝ nghĩa
100missing payload
102duplicated login
103room not found
108bad password
113room full
114in other room
115bet not found
120not enough money
Gameplay (tag RequestBet=1)Ý nghĩa
1 NotBetTimeKhông phải cửa cược
2 InvalidBetMức cược không tồn tại
3 NotEnoughChipKhông đủ chip
4 SideBetNotAllowedCửa không hợp lệ
5 UserNotFoundKhông tìm thấy user
6 ActionNotAllowedAction không hợp lệ

8. Checklist client