NON-PRODUCTION
Dragon Tiger — tài liệu ghép client
Cược Dragon / Tiger / Tie (+ Big/Small từng cửa). Mỗi bên 1 lá. Envelope lobby game_event; payload bàn proto dragontiger_event. Frame binary protobuf.
1. Tổng quan
Mục Giá trị
Connect GET /ws?access_token=<JWT> trên domain game
Lobby internal/proto/game-event · package game_event
Gameplay package dragontiger_event trong data_send.data
Card id rank * 4 + suit. So sánh rank; hòa → cửa Tie
1 user Một connection. Duplicate → lobby 102
Side enum
Giá trị Cửa
0 Dragon Lá rồng cao hơn
1 Tiger Lá hổ cao hơn
2 Tie Hòa rank
3 DragonBig Dragon rank lớn (side bet)
4 DragonSmall Dragon rank nhỏ
5 TigerBig Tiger rank lớn
6 TigerSmall Tiger rank nhỏ
State: Pending · Countdown · DealTime · ShowdownTime · BetTime · PreShowdownTime. Tỷ lệ lấy room_state.side_list (vd Tie 10:1).
Cược chỉ trong BetTime sau start_bet. multiple_bet để đặt Dragon + Tie một lúc.
2. Demo Dragon vs Tiger
Viền vàng = win_sides chứa Dragon. Lật 2 lá theo finish.dragon_card / tiger_card. Rank K > 7 → Dragon thắng; Tie nếu hai rank bằng nhau.
Card id
id = rank * 4 + suit. Rank 0=A … 12=K (tuỳ enum gamecard). Suit 0–3. Ví dụ K♥ ≈ 44, 7♠ ≈ 20 — lấy đúng field int32, client map sprite.
Không dùng công thức điểm Baccarat (mod 10). Cửa chính so rank; Big/Small là side bet theo ngưỡng rank trong side_list.
3. WS envelope (đầy đủ)
Frame binary protobuf , không JSON. Handshake: 0 closed · 1 other device playing · 2 too many conn · 4 token expired · 5 banned.
GET /ws?access_token=<JWT> // domain game dragontiger
game_event.Request.data_send { room_id: 11 data: <bytes dragontiger_event.Request> }
game_event.Response.game_message { room_id: 11 data: <bytes dragontiger_event.Response> }
Ngoài data: user_joined / user_left / start_countdown / start_game / reset_game / auto_leave.
4. Lobby C→S / S→C
C→S Field
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
inviteroom_id, password, user_id
free_users_listbet
send_chat_messageroom_id, message, to[], is_private_chat
data_sendbytes game hoặc auto_leave
S→C Field
room_config / room_listsảnh / bàn
game_messagepayload bàn
errorcode + tag
chat_messagechat
invite / someone_invited_youmời
5. Gameplay proto dragontiger_event
C→S Request (oneof)
Message Field Ghi chú
bet TagBet=1side, bet_amount, count[{bet, count}]Một cửa + chip animate
multiple_betbets[]Nhiều cửa
cheatdragon_card, tiger_cardNon-prod
Request { bet { side: Dragon bet_amount: 1000 count { bet: 1000 count: 1 } } }
Request { multiple_bet { bets { side: Dragon bet_amount: 500 } bets { side: Tie bet_amount: 100 } } }
S→C Response (oneof)
Message Field
room_statestate, timers, bet, players[], dragon_card, tiger_card, dragon_score, tiger_score, side_list[], winning_sides[], bets[], history[{sides, dragon_card, tiger_card}], max_bet, max_bet_by_vip, is_registered_leave
start_betdelay_millis
bet / multiple_betuser_id, side, bet_amount, side_total_bet, seat, player_total_bet, count[]
dealrỗng
pre_showdownresult[{user_id, amount, user_money}], bet_sides[] — sync chip đã trừ
finishdragon_card, tiger_card, win_sides[], sides_win_amount[], players_sides_win_amount[], dragon_score, tiger_score
errorcode + tag=1 RequestBet
Response { start_bet { delay_millis: 30000 } }
Response { finish {
dragon_card: 44
tiger_card: 20
win_sides: [Dragon, DragonBig]
dragon_score: 13
tiger_score: 7
sides_win_amount { side: Dragon win_amount: 80000 }
players_sides_win_amount {
user_id: 1001 total_amount: 1000 user_money: 501000
sides_win_amount { side: Dragon win_amount: 1000 }
}
} }
room_state — restore
Field Client
state, count_down_millis, state_start_time, state_end_timeĐồng hồ
players[]user_id, name, chip, avatar, seat, disconnected, state, bet_sides[], level, vip
dragon_card, tiger_card, dragon_score, tiger_scoreCó khi đang Deal/Showdown
side_list[], bets[], winning_sides[]Paytable + chip + cửa thắng
history[]sides[], dragon_card, tiger_card — bead road
max_bet, max_bet_by_vip, is_registered_leaveChặn cược / tự kick
Response { bet {
user_id: 1001 side: Dragon bet_amount: 1000
side_total_bet: 22000 seat: 0 player_total_bet: 1000
count { bet: 1000 count: 1 }
} }
Response { pre_showdown {
result { user_id: 1001 amount: -1000 user_money: 499000 }
bet_sides { side: Dragon bet_amount: 22000 }
} }
Optimistic chip lúc tap. pre_showdown ghi đè nếu lệch. Win lấy players_sides_win_amount.user_money. Score là rank lá (không mod 10 như baccarat).
Lobby payload mẫu
Request { room_config {} }
Request { join_room { room_id: 11 password: "" is_viewer: false } }
Request { data_send { room_id: 11 data: <dragontiger_event.Request bet> } }
Big/Small là side bet theo rank lá (không phải tổng điểm). Multiplier mặc định Tie 10:1; đọc side_list chứ đừng hardcode. Cheat dragon_card/tiger_card chỉ non-prod.
6. Luồng ghép
Connect /ws
room_config
join_room
start_bet
bet / multiple_bet
deal → pre_showdown → finish
Connect JWT. Close 1/2/4/5 → dừng.
room_config rồi join. Restore felt từ room_state.
start_bet mở cửa. Gửi bet Tag=1 (hoặc multiple_bet).
deal khóa. pre_showdown sync money. finish lật 2 lá, highlight win_sides.
7. Error codes
Handshake 0 closed · 1 other device playing · 2 too many conn · 4 token expired · 5 banned
Lobby 100 missing payload · 102 duplicated login · 103 room not found · 108 bad password · 113 room full · 114 in other room · 115 bet not found · 120 not enough money
Gameplay tag=1 1 NotBetTime · 2 InvalidBet · 3 NotEnoughChip · 4 SideBetNotAllowed · 5 UserNotFound · 6 ActionNotAllowed
Khi nào chip đổi
Event Chip
Tap bet (optimistic) Client trừ tạm; server chưa confirm
pre_showdownGhi đè result[].user_money
finish+total_amount từng user; source of truth = user_money
8. Checklist client
Binary protobuf, domain game, một socket / user.
Bàn = data_send.data bytes dragontiger_event.Request.
Decode card id = rank×4+suit. So sánh rank, không phải điểm baccarat.
Side bet Big/Small theo side_list — đừng hardcode multiplier.
Money: pre_showdown + finish. Cheat chỉ non-prod.
Restore: nếu room_state đã có dragon_card/tiger_card thì lật sẵn, đừng chờ finish.
Tie thường trả side bet Dragon/Tiger = 0 (push/mất tùy room_config) — tin win_sides.
Không gửi bet khi không phải BetTime (gameplay error 1).
count[] chỉ để animate chip stack — server tính theo bet_amount.
Dragon Tiger game server · tài liệu client · GET /dragontiger