diff --git a/components/room.html b/components/room.html
index 9feab4f..207e242 100644
--- a/components/room.html
+++ b/components/room.html
@@ -25,6 +25,7 @@
{{if .Room.IsRunning}}
Turn of the {{.Room.TeamTurn}} team
+{{template "turntimer" .Room}}
{{if .Room.MimeDone}}
Waiting for guessers
Given Clue: "{{.Room.FetchLastClueWord}}"
diff --git a/components/turntimer.html b/components/turntimer.html
new file mode 100644
index 0000000..791571d
--- /dev/null
+++ b/components/turntimer.html
@@ -0,0 +1,5 @@
+{{define "turntimer"}}
+
+ Timer: {{.Settings.TurnSecondsLeft}}
+
+{{end}}
diff --git a/handlers/actions.go b/handlers/actions.go
index 30e439f..7d56390 100644
--- a/handlers/actions.go
+++ b/handlers/actions.go
@@ -84,8 +84,8 @@ func saveFullInfo(fi *models.FullInfo) error {
return nil
}
-func notifyBotIfNeeded(fi *models.FullInfo) {
- if botName := fi.Room.WhichBotToMove(); botName != "" {
+func notifyBotIfNeeded(room *models.Room) {
+ if botName := room.WhichBotToMove(); botName != "" {
log.Debug("got botname", "name", botName, "channel_len", len(llmapi.SignalChanMap[botName]))
llmapi.SignalChanMap[botName] <- true
log.Debug("after sending signal", "name", botName)
diff --git a/handlers/elements.go b/handlers/elements.go
index 201a792..96821f4 100644
--- a/handlers/elements.go
+++ b/handlers/elements.go
@@ -159,7 +159,7 @@ func HandleShowColor(w http.ResponseWriter, r *http.Request) {
return
}
// get mime bot for opp team and notify it
- notifyBotIfNeeded(fi)
+ notifyBotIfNeeded(fi.Room)
notify(models.NotifyRoomUpdatePrefix+fi.Room.ID, "")
if err := tmpl.ExecuteTemplate(w, "cardword", cardword); err != nil {
log.Error("failed to execute cardword template", "error", err)
diff --git a/handlers/game.go b/handlers/game.go
index df76741..57648df 100644
--- a/handlers/game.go
+++ b/handlers/game.go
@@ -9,6 +9,7 @@ import (
"net/http"
"strconv"
"strings"
+ "time"
)
func HandleCreateRoom(w http.ResponseWriter, r *http.Request) {
@@ -122,6 +123,7 @@ func HandleEndTurn(w http.ResponseWriter, r *http.Request) {
}
fi.Room.ChangeTurn()
fi.Room.MimeDone = false
+ StopTurnTimer(fi.Room.ID)
if err := saveFullInfo(fi); err != nil {
abortWithError(w, err.Error())
return
@@ -132,7 +134,7 @@ func HandleEndTurn(w http.ResponseWriter, r *http.Request) {
abortWithError(w, err.Error())
return
}
- notifyBotIfNeeded(fi)
+ notifyBotIfNeeded(fi.Room)
notify(models.NotifyRoomUpdatePrefix+fi.Room.ID, "")
if err := tmpl.ExecuteTemplate(w, "base", fi); err != nil {
log.Error("failed to execute base template", "error", err)
@@ -181,7 +183,7 @@ func HandleStartGame(w http.ResponseWriter, r *http.Request) {
abortWithError(w, err.Error())
return
}
- notifyBotIfNeeded(fi)
+ notifyBotIfNeeded(fi.Room)
// to update only the room that should be updated
notify(models.NotifyRoomUpdatePrefix+fi.Room.ID, "")
// notify(models.NotifyBacklogPrefix+fi.Room.ID, "game started")
@@ -283,9 +285,11 @@ func HandleGiveClue(w http.ResponseWriter, r *http.Request) {
fi.Room.ThisTurnLimit = 9
}
fi.Room.OpenedThisTurn = 0
+ fi.Room.Settings.TurnSecondsLeft = fi.Room.Settings.RoundTime
+ StartTurnTimer(fi.Room.ID, time.Duration(fi.Room.Settings.RoundTime)*time.Second)
log.Debug("given clue", "clue", clue, "limit", fi.Room.ThisTurnLimit)
notify(models.NotifyBacklogPrefix+fi.Room.ID, clue+num)
- notifyBotIfNeeded(fi)
+ notifyBotIfNeeded(fi.Room)
if err := saveFullInfo(fi); err != nil {
abortWithError(w, err.Error())
return
@@ -298,5 +302,5 @@ func HandleRenotifyBot(w http.ResponseWriter, r *http.Request) {
abortWithError(w, err.Error())
return
}
- notifyBotIfNeeded(fi)
+ notifyBotIfNeeded(fi.Room)
}
diff --git a/handlers/timer.go b/handlers/timer.go
new file mode 100644
index 0000000..f188616
--- /dev/null
+++ b/handlers/timer.go
@@ -0,0 +1,60 @@
+package handlers
+
+import (
+ "gralias/models"
+ "sync"
+ "time"
+)
+
+var (
+ timers = make(map[string]*time.Ticker)
+ 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)
+ timers[roomID] = ticker
+ go func() {
+ for range 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.NotifyRoomUpdatePrefix+room.ID, "")
+ 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 ticker, exists := timers[roomID]; exists {
+ ticker.Stop()
+ delete(timers, roomID)
+ }
+}
diff --git a/models/main.go b/models/main.go
index 3d8580a..9346c3b 100644
--- a/models/main.go
+++ b/models/main.go
@@ -325,10 +325,10 @@ type WordCard struct {
}
type GameSettings struct {
- Language string `json:"language" example:"en" form:"language"`
- RoomPass string `json:"room_pass"`
- TurnSeconds uint32
- RoundTime uint32
+ Language string `json:"language" example:"en" form:"language"`
+ RoomPass string `json:"room_pass"`
+ TurnSecondsLeft uint32
+ RoundTime uint32
}
// =====