feat: add time for heart beat

This commit is contained in:
2026-06-19 02:29:00 +03:30
parent 0827858752
commit 32f0406e63
4 changed files with 38 additions and 23 deletions
+24 -14
View File
@@ -54,22 +54,25 @@ type Room struct {
actions chan roomAction
ended bool
turnGen int
timer *time.Timer // تایمر فعال (نوبت یا جمع‌آوری)؛ فقط goroutine میز به آن دست می‌زند
turnTimeout time.Duration
botDelay time.Duration
trickHold time.Duration
timer *time.Timer // تایمر فعال (نوبت یا جمع‌آوری)؛ فقط goroutine میز به آن دست می‌زند
turnTimeout time.Duration
botDelay time.Duration
trickHold time.Duration
firstHandDelay time.Duration
handStart time.Time // زمانِ شروعِ هَندِ جاری (برای پنجره‌ی بُر زدن)
}
func newRoom(id string, seats [4]*seatInfo, hub *Hub) *Room {
return &Room{
ID: id,
hub: hub,
settler: hub.settler,
seats: seats,
actions: make(chan roomAction, 64),
turnTimeout: hub.turnTimeout,
botDelay: hub.botDelay,
trickHold: hub.trickHold,
ID: id,
hub: hub,
settler: hub.settler,
seats: seats,
actions: make(chan roomAction, 64),
turnTimeout: hub.turnTimeout,
botDelay: hub.botDelay,
trickHold: hub.trickHold,
firstHandDelay: hub.firstHandDelay,
}
}
@@ -108,6 +111,7 @@ func (r *Room) start() {
target = targetScore
}
r.game = game.NewGame(target, game.FirstHakem())
r.handStart = time.Now()
for seat, s := range r.seats {
if s.client != nil {
s.client.trySend(mustJSON(r.matchedFor(seat)))
@@ -142,6 +146,7 @@ func (r *Room) react() {
r.endRoom()
return
}
r.handStart = time.Now() // شروعِ هَندِ جدید ⇒ پنجره‌ی بُر زدن
r.broadcastState()
r.armTimer()
case game.PhaseGameOver:
@@ -206,6 +211,11 @@ func (r *Room) armTimer() {
delay := r.turnTimeout
if r.seats[actor].auto() {
delay = r.botDelay
// در پنجره‌ی ابتدای هَند (انیمیشنِ بُر زدنِ کلاینت)، حرکتِ خودکار را عقب
// می‌اندازیم تا کارت‌ها وسطِ بُر زدن روی میز نیفتند. نوبتِ انسان دست‌نخورده می‌ماند.
if grace := r.firstHandDelay - time.Since(r.handStart); grace > delay {
delay = grace
}
}
r.timer = time.AfterFunc(delay, func() {
select {
@@ -386,7 +396,7 @@ func (r *Room) handleReconnect(seat int, client *Client) {
r.broadcast(mustJSON(playerStatusMsg{Type: "player_reconnected", Seat: 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() // مهلت نوبت برای انسانِ بازگشته دوباره بلند می‌شود
}
@@ -476,7 +486,7 @@ func (r *Room) broadcastState() {
players := r.playersInfo()
for seat, s := range r.seats {
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()))))
}
}
}