feat: add time for heart beat
This commit is contained in:
+7
-4
@@ -12,10 +12,11 @@ import (
|
|||||||
|
|
||||||
// مقادیر پیشفرض مقاومسازی (قابل بازنویسی در تست).
|
// مقادیر پیشفرض مقاومسازی (قابل بازنویسی در تست).
|
||||||
const (
|
const (
|
||||||
defaultTurnTimeout = 20 * time.Second // مهلت نوبت بازیکنِ انسان
|
defaultTurnTimeout = 30 * time.Second // مهلت نوبت بازیکنِ انسان
|
||||||
defaultBotDelay = 800 * time.Millisecond // تأخیر حرکت بات/قطعشده (حس طبیعی + فرصت بازگشت)
|
defaultBotDelay = 800 * time.Millisecond // تأخیر حرکت بات/قطعشده (حس طبیعی + فرصت بازگشت)
|
||||||
defaultMatchWait = 12 * time.Second // مهلت پر شدن میز با انسان پیش از افزودن بات
|
defaultMatchWait = 6 * time.Second // مهلت پر شدن میز با انسان پیش از افزودن بات
|
||||||
defaultTrickHold = 1200 * time.Millisecond // مدت نمایش دستِ کامل پیش از جمعآوری
|
defaultTrickHold = 1200 * time.Millisecond // مدت نمایش دستِ کامل پیش از جمعآوری
|
||||||
|
defaultFirstHandDelay = 3000 * time.Millisecond // تأخیر اولین حرکتِ بات تا پایانِ اینترو+بُر زدنِ کلاینت
|
||||||
)
|
)
|
||||||
|
|
||||||
// AuthFunc توکن را تأیید کرده و (شناسه کاربر، نام نمایشی) را برمیگرداند.
|
// AuthFunc توکن را تأیید کرده و (شناسه کاربر، نام نمایشی) را برمیگرداند.
|
||||||
@@ -69,6 +70,7 @@ type Hub struct {
|
|||||||
botDelay time.Duration
|
botDelay time.Duration
|
||||||
matchWait time.Duration
|
matchWait time.Duration
|
||||||
trickHold time.Duration
|
trickHold time.Duration
|
||||||
|
firstHandDelay time.Duration // تأخیر اولین حرکتِ بات (هماهنگ با انیمیشنِ بُر زدنِ کلاینت)
|
||||||
countdownDelay time.Duration // مهلت شمارش معکوسِ میز خصوصی پیش از شروع
|
countdownDelay time.Duration // مهلت شمارش معکوسِ میز خصوصی پیش از شروع
|
||||||
|
|
||||||
register chan *Client
|
register chan *Client
|
||||||
@@ -98,6 +100,7 @@ func NewHub(auth AuthFunc) *Hub {
|
|||||||
botDelay: defaultBotDelay,
|
botDelay: defaultBotDelay,
|
||||||
matchWait: defaultMatchWait,
|
matchWait: defaultMatchWait,
|
||||||
trickHold: defaultTrickHold,
|
trickHold: defaultTrickHold,
|
||||||
|
firstHandDelay: defaultFirstHandDelay,
|
||||||
countdownDelay: 3 * time.Second,
|
countdownDelay: 3 * time.Second,
|
||||||
register: make(chan *Client),
|
register: make(chan *Client),
|
||||||
unregister: make(chan *Client),
|
unregister: make(chan *Client),
|
||||||
|
|||||||
@@ -76,10 +76,11 @@ type stateMsg struct {
|
|||||||
HandCounts [4]int `json:"hand_counts"`
|
HandCounts [4]int `json:"hand_counts"`
|
||||||
Trick []trickView `json:"trick"`
|
Trick []trickView `json:"trick"`
|
||||||
LeadSuit string `json:"lead_suit,omitempty"`
|
LeadSuit string `json:"lead_suit,omitempty"`
|
||||||
TricksWon [2]int `json:"tricks_won"`
|
TricksWon [2]int `json:"tricks_won"`
|
||||||
Scores [2]int `json:"scores"`
|
Scores [2]int `json:"scores"`
|
||||||
TargetScore int `json:"target_score"`
|
TargetScore int `json:"target_score"`
|
||||||
Players []PlayerInfo `json:"players"`
|
TurnTimeoutMs int `json:"turn_timeout_ms"` // مهلتِ نوبتِ انسان (برای شمارندهی کلاینت)
|
||||||
|
Players []PlayerInfo `json:"players"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// handOverMsg نتیجه یک هَند.
|
// handOverMsg نتیجه یک هَند.
|
||||||
@@ -118,7 +119,7 @@ type playerStatusMsg struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// buildState نمای بازی را برای جایگاه seat میسازد (کارت بقیه مخفی میماند).
|
// buildState نمای بازی را برای جایگاه seat میسازد (کارت بقیه مخفی میماند).
|
||||||
func buildState(g *game.Game, roomID string, seat int, players []PlayerInfo) stateMsg {
|
func buildState(g *game.Game, roomID string, seat int, players []PlayerInfo, turnTimeoutMs int) stateMsg {
|
||||||
hand := g.Hand(seat)
|
hand := g.Hand(seat)
|
||||||
handStr := make([]string, len(hand))
|
handStr := make([]string, len(hand))
|
||||||
for i, c := range hand {
|
for i, c := range hand {
|
||||||
|
|||||||
+24
-14
@@ -54,22 +54,25 @@ type Room struct {
|
|||||||
actions chan roomAction
|
actions chan roomAction
|
||||||
ended bool
|
ended bool
|
||||||
turnGen int
|
turnGen int
|
||||||
timer *time.Timer // تایمر فعال (نوبت یا جمعآوری)؛ فقط goroutine میز به آن دست میزند
|
timer *time.Timer // تایمر فعال (نوبت یا جمعآوری)؛ فقط goroutine میز به آن دست میزند
|
||||||
turnTimeout time.Duration
|
turnTimeout time.Duration
|
||||||
botDelay time.Duration
|
botDelay time.Duration
|
||||||
trickHold time.Duration
|
trickHold time.Duration
|
||||||
|
firstHandDelay time.Duration
|
||||||
|
handStart time.Time // زمانِ شروعِ هَندِ جاری (برای پنجرهی بُر زدن)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRoom(id string, seats [4]*seatInfo, hub *Hub) *Room {
|
func newRoom(id string, seats [4]*seatInfo, hub *Hub) *Room {
|
||||||
return &Room{
|
return &Room{
|
||||||
ID: id,
|
ID: id,
|
||||||
hub: hub,
|
hub: hub,
|
||||||
settler: hub.settler,
|
settler: hub.settler,
|
||||||
seats: seats,
|
seats: seats,
|
||||||
actions: make(chan roomAction, 64),
|
actions: make(chan roomAction, 64),
|
||||||
turnTimeout: hub.turnTimeout,
|
turnTimeout: hub.turnTimeout,
|
||||||
botDelay: hub.botDelay,
|
botDelay: hub.botDelay,
|
||||||
trickHold: hub.trickHold,
|
trickHold: hub.trickHold,
|
||||||
|
firstHandDelay: hub.firstHandDelay,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,6 +111,7 @@ func (r *Room) start() {
|
|||||||
target = targetScore
|
target = targetScore
|
||||||
}
|
}
|
||||||
r.game = game.NewGame(target, game.FirstHakem())
|
r.game = game.NewGame(target, game.FirstHakem())
|
||||||
|
r.handStart = time.Now()
|
||||||
for seat, s := range r.seats {
|
for seat, s := range r.seats {
|
||||||
if s.client != nil {
|
if s.client != nil {
|
||||||
s.client.trySend(mustJSON(r.matchedFor(seat)))
|
s.client.trySend(mustJSON(r.matchedFor(seat)))
|
||||||
@@ -142,6 +146,7 @@ func (r *Room) react() {
|
|||||||
r.endRoom()
|
r.endRoom()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
r.handStart = time.Now() // شروعِ هَندِ جدید ⇒ پنجرهی بُر زدن
|
||||||
r.broadcastState()
|
r.broadcastState()
|
||||||
r.armTimer()
|
r.armTimer()
|
||||||
case game.PhaseGameOver:
|
case game.PhaseGameOver:
|
||||||
@@ -206,6 +211,11 @@ func (r *Room) armTimer() {
|
|||||||
delay := r.turnTimeout
|
delay := r.turnTimeout
|
||||||
if r.seats[actor].auto() {
|
if r.seats[actor].auto() {
|
||||||
delay = r.botDelay
|
delay = r.botDelay
|
||||||
|
// در پنجرهی ابتدای هَند (انیمیشنِ بُر زدنِ کلاینت)، حرکتِ خودکار را عقب
|
||||||
|
// میاندازیم تا کارتها وسطِ بُر زدن روی میز نیفتند. نوبتِ انسان دستنخورده میماند.
|
||||||
|
if grace := r.firstHandDelay - time.Since(r.handStart); grace > delay {
|
||||||
|
delay = grace
|
||||||
|
}
|
||||||
}
|
}
|
||||||
r.timer = time.AfterFunc(delay, func() {
|
r.timer = time.AfterFunc(delay, func() {
|
||||||
select {
|
select {
|
||||||
@@ -386,7 +396,7 @@ func (r *Room) handleReconnect(seat int, client *Client) {
|
|||||||
r.broadcast(mustJSON(playerStatusMsg{Type: "player_reconnected", Seat: seat}))
|
r.broadcast(mustJSON(playerStatusMsg{Type: "player_reconnected", Seat: seat}))
|
||||||
// وضعیت کامل را برای بازیکن بازگشته بفرست
|
// وضعیت کامل را برای بازیکن بازگشته بفرست
|
||||||
client.trySend(mustJSON(r.matchedFor(seat)))
|
client.trySend(mustJSON(r.matchedFor(seat)))
|
||||||
client.trySend(mustJSON(buildState(r.game, r.ID, seat, r.playersInfo())))
|
client.trySend(mustJSON(buildState(r.game, r.ID, seat, r.playersInfo(), int(r.turnTimeout.Milliseconds()))))
|
||||||
r.armTimer() // مهلت نوبت برای انسانِ بازگشته دوباره بلند میشود
|
r.armTimer() // مهلت نوبت برای انسانِ بازگشته دوباره بلند میشود
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,7 +486,7 @@ func (r *Room) broadcastState() {
|
|||||||
players := r.playersInfo()
|
players := r.playersInfo()
|
||||||
for seat, s := range r.seats {
|
for seat, s := range r.seats {
|
||||||
if s.client != nil {
|
if s.client != nil {
|
||||||
s.client.trySend(mustJSON(buildState(r.game, r.ID, seat, players)))
|
s.client.trySend(mustJSON(buildState(r.game, r.ID, seat, players, int(r.turnTimeout.Milliseconds()))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ func testHub() *Hub {
|
|||||||
hub.botDelay = 8 * time.Millisecond
|
hub.botDelay = 8 * time.Millisecond
|
||||||
hub.matchWait = 300 * time.Millisecond
|
hub.matchWait = 300 * time.Millisecond
|
||||||
hub.trickHold = 5 * time.Millisecond
|
hub.trickHold = 5 * time.Millisecond
|
||||||
|
hub.firstHandDelay = 0
|
||||||
hub.countdownDelay = 20 * time.Millisecond
|
hub.countdownDelay = 20 * time.Millisecond
|
||||||
go hub.Run()
|
go hub.Run()
|
||||||
return hub
|
return hub
|
||||||
|
|||||||
Reference in New Issue
Block a user