package handlers import ( "fmt" "gralias/models" "sync" "time" ) type roomTimer struct { ticker *time.Ticker done chan bool } var ( timers = make(map[string]*roomTimer) mu sync.Mutex ) func StartTurnTimer(roomID string, duration time.Duration) { mu.Lock() defer mu.Unlock() if _, exists := timers[roomID]; exists { return // Timer already running } ticker := time.NewTicker(1 * time.Second) done := make(chan bool) timers[roomID] = &roomTimer{ticker: ticker, done: done} go func() { for { select { case <-done: return case <-ticker.C: room, err := getRoomByID(roomID) if err != nil { log.Error("failed to get room by id", "error", err) StopTurnTimer(roomID) return } if room.Settings.TurnSecondsLeft <= 0 { log.Info("turn time is over", "room_id", roomID) room.ChangeTurn() room.MimeDone = false if err := saveRoom(room); err != nil { log.Error("failed to save room", "error", err) } notify(models.NotifyTurnTimerPrefix+room.ID, fmt.Sprintf("%d", room.Settings.TurnSecondsLeft)) notifyBotIfNeeded(room) StopTurnTimer(roomID) return } room.Settings.TurnSecondsLeft-- if err := saveRoom(room); err != nil { log.Error("failed to save room", "error", err) } notify(models.NotifyRoomUpdatePrefix+room.ID, "") } } }() } func StopTurnTimer(roomID string) { mu.Lock() defer mu.Unlock() if timer, exists := timers[roomID]; exists { timer.ticker.Stop() close(timer.done) delete(timers, roomID) } }