NON-PRODUCTION

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

4 hạt (đỏ/trắng). Cược even / odd / pattern. Envelope lobby game_event; payload bàn proto sesku_event. Frame binary, không JSON.

1. Tổng quan

MụcGiá trị
ConnectGET /ws?access_token=<JWT> trên domain game
Lobbyinternal/proto/game-event · package game_event
Gameplaypackage sesku_event trong data_send.data
Seedsrepeated bool length 4. true = đỏ, false = trắng
Even / OddSố hạt đỏ chẵn / lẻ
1 userMột connection. Duplicate → lobby 102

Side enum

Giá trịCửaĐiều kiện
0 EvenChẵn0 / 2 / 4 hạt đỏ
1 OddLẻ1 / 3 hạt đỏ
2 FourRed4 đỏpattern
3 FourWhite4 trắngpattern
4 ThreeWhiteOneRed3 trắng 1 đỏpattern
5 ThreeRedOneWhite3 đỏ 1 trắngpattern

State: Pending · Countdown · DealTime · ShowdownTime · BetTime · PreShowdownTime. Multiplier mặc định [1, 1, 14, 14, 3, 3] — luôn đọc side_list.

2. Demo 4 hạt

seeds = [true, false, true, true] · 3 đỏ → Odd + ThreeRedOneWhite

ODD EVEN 4 RED 4 WHITE 3W1R 3R1W

Highlight theo finish.win_sides. Pattern và even/odd có thể thắng cùng lúc.

3. WS envelope (đầy đủ)

Frame binary protobuf. Handshake: 0 closed · 1 other device playing · 2 too many conn · 4 token expired · 5 banned.

GET /ws?access_token=<JWT>     // domain game sesku
game_event.Request.data_send { room_id: 5  data: <bytes sesku_event.Request> }
game_event.Response.game_message { room_id: 5  data: <bytes sesku_event.Response> }

Ngoài data: user_joined / user_left / start_countdown / start_game / reset_game / auto_leave.

4. Lobby C→S / S→C

C→SField
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→CField
room_config / room_listsảnh / bàn
game_messagepayload bàn
errorcode + tag
chat_messagechat
invite / someone_invited_youmời

5. Gameplay proto sesku_event

C→S Request (oneof)

MessageFieldGhi chú
bet TagBet=1side, bet_amount, count[{bet, count}]Một cửa
multiple_betbets[]Even + pattern cùng lúc
cheatseeds[] bool×4Non-prod
Request { bet { side: Odd  bet_amount: 1000  count { bet: 1000 count: 1 } } }
Request { multiple_bet {
  bets { side: Odd bet_amount: 1000 }
  bets { side: ThreeRedOneWhite bet_amount: 200 }
} }

S→C Response (oneof)

MessageField
room_statestate, timers, bet, players[], seeds[] (4 bool), side_list[], winning_sides[], bets[], history[{win_sides, seeds}], 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 — bắt đầu lắc hạt
pre_showdownresult[{user_id, amount, user_money}], bet_sides[]
finishseeds[], win_sides[], sides_win_amount[], players_sides_win_amount[{user_id, sides_win_amount, avatar, name, total_amount, user_money}]
errorcode + tag=1 RequestBet
Response { start_bet { delay_millis: 30000 } }
Response { finish {
  seeds: [true, false, true, true]
  win_sides: [Odd, ThreeRedOneWhite]
  sides_win_amount { side: Odd win_amount: 40000 }
  sides_win_amount { side: ThreeRedOneWhite win_amount: 12000 }
  players_sides_win_amount {
    user_id: 1001  total_amount: 1600  user_money: 501600
    sides_win_amount { side: Odd win_amount: 1000 }
    sides_win_amount { side: ThreeRedOneWhite win_amount: 600 }
  }
} }

room_state — restore

FieldClient
state + timersChỉ cược khi BetTime
players[]user_id, name, chip, avatar, seat, state, bet_sides[], vip, level
seeds[]4 bool — hiện nếu đang Deal/Showdown
side_list[]Even/Odd ~1:1; FourRed/FourWhite ~14; 3+1 ~3
bets[], winning_sides[], history[]Chip + bead road (win_sides + seeds)
max_bet, max_bet_by_vip, is_registered_leaveTrần cược / tự kick
Response { bet {
  user_id: 1001  side: Odd  bet_amount: 1000
  side_total_bet: 9000  seat: 0  player_total_bet: 1000
  count { bet: 1000 count: 1 }
} }
Response { pre_showdown {
  result { user_id: 1001  amount: -1200  user_money: 498800 }
  bet_sides { side: Odd bet_amount: 9000 }
  bet_sides { side: ThreeRedOneWhite bet_amount: 200 }
} }
Animate 4 hạt theo seeds (true=đỏ). Đếm đỏ: 0/2/4 → Even; 1/3 → Odd. Pattern overlay cùng ván. Chip cuối = user_money trên finish.

Lobby payload mẫu

Request { room_config {} }
Request { join_room { room_id: 5  password: ""  is_viewer: false } }
Request { data_send { room_id: 5  data: <sesku_event.Request multiple_bet> } }

Cheat seeds: [true,true,true,true] → FourRed (non-prod). 2 đỏ 2 trắng → Even, không trúng pattern 3+1 / 4.

6. Luồng ghép

Connect /ws
room_config
join_room
start_bet
bet / multiple_bet
deal → pre_showdown → finish
  1. Connect JWT. Close 1/2/4/5 → dừng.
  2. Join. Restore 4 hạt nếu room_state đang showdown.
  3. start_bet: enable Even/Odd + 4 pattern. Gửi bet Tag=1.
  4. deal khóa. pre_showdown sync chip. finish lật hạt, highlight win_sides, cộng tiền.

7. Error codes

Handshake0 closed · 1 other device playing · 2 too many conn · 4 token expired · 5 banned
Lobby100 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=11 NotBetTime · 2 InvalidBet · 3 NotEnoughChip · 4 SideBetNotAllowed · 5 UserNotFound · 6 ActionNotAllowed

Khi nào chip đổi

EventChip
Tap bet / multiple_betOptimistic trừ tổng các cửa
pre_showdownGhi đè result[].user_money
finishCộng mọi sides_win_amount; tin user_money

8. Checklist client