diff --git a/handlers/auth.go b/handlers/auth.go index c987885..f622771 100644 --- a/handlers/auth.go +++ b/handlers/auth.go @@ -9,6 +9,7 @@ import ( "gralias/models" "gralias/utils" "html/template" + "log/slog" "net/http" "strings" "time" @@ -89,7 +90,6 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) { // userstate, err := loadState(cleanName) userstate, err := repo.PlayerGetByName(r.Context(), cleanName) if err != nil || userstate == nil { - userstate = models.InitPlayer(cleanName) makeplayer = true } @@ -181,7 +181,12 @@ func makeCookie(username string, remote string) (*http.Cookie, error) { cookie.Secure = false log.Info("changing cookie domain", "domain", cookie.Domain) } - // set ctx? + // make player first, since username is fk to players table + player := models.InitPlayer(username) + if err := repo.PlayerAdd(context.Background(), player); err != nil { + slog.Error("failed to create player", "username", username) + return nil, err + } if err := repo.SessionCreate(context.Background(), session); err != nil { return nil, err } diff --git a/handlers/game.go b/handlers/game.go index 3a54281..ae0a25b 100644 --- a/handlers/game.go +++ b/handlers/game.go @@ -40,22 +40,11 @@ func HandleCreateRoom(w http.ResponseWriter, r *http.Request) { } fi.State.RoomID = &room.ID fi.Room = room - // if err := repo.RoomCreate(r.Context(), room); err != nil { - // log.Error("failed to create a room", "error", err) - // abortWithError(w, err.Error()) - // return - // } - if err := repo.PlayerSetRoomID(r.Context(), fi.State.Username, room.ID); err != nil { + if err := repo.PlayerSetRoomID(r.Context(), room.ID, fi.State.Username); err != nil { log.Error("failed to set room id", "error", err) abortWithError(w, err.Error()) return } - // if err := saveFullInfo(r.Context(), fi); err != nil { - // msg := "failed to set current room to session" - // log.Error(msg, "error", err) - // abortWithError(w, msg) - // return - // } notify(models.NotifyRoomListUpdate, "") tmpl, err := template.ParseGlob("components/*.html") if err != nil { @@ -348,7 +337,6 @@ 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) diff --git a/handlers/timer.go b/handlers/timer.go index fca39f2..9040184 100644 --- a/handlers/timer.go +++ b/handlers/timer.go @@ -28,39 +28,31 @@ func StartTurnTimer(roomID string, duration time.Duration) { done := make(chan bool) timers[roomID] = &roomTimer{ticker: ticker, done: done} go func() { - settings, err := repo.SettingsGetByRoomID(context.Background(), roomID) + room, err := repo.RoomGetByID(context.Background(), roomID) if err != nil { - log.Error("failed to get settings by room id", "error", err) + log.Error("failed to get room by id", "error", err) StopTurnTimer(roomID) return } + timeLeft := room.Settings.RoundTime for { select { case <-done: return case <-ticker.C: - if settings.TurnSecondsLeft <= 0 { + if timeLeft <= 0 { log.Info("turn time is over", "room_id", roomID) - room, err := repo.RoomGetByID(context.Background(), roomID) - if err != nil { - log.Error("failed to get room by id", "error", err) - StopTurnTimer(roomID) - return - } room.ChangeTurn() room.MimeDone = false if err := repo.RoomUpdate(context.Background(), room); err != nil { log.Error("failed to save room", "error", err) } - notify(models.NotifyTurnTimerPrefix+room.ID, strconv.FormatUint(uint64(room.Settings.TurnSecondsLeft), 10)) + notify(models.NotifyTurnTimerPrefix+room.ID, strconv.FormatUint(uint64(room.Settings.RoundTime), 10)) notifyBotIfNeeded(room) StopTurnTimer(roomID) return } - settings.TurnSecondsLeft-- - if err := repo.SettingsUpdate(context.Background(), settings); err != nil { - log.Error("failed to update settings", "error", err) - } + timeLeft-- notify(models.NotifyRoomUpdatePrefix+roomID, "") } } diff --git a/models/main.go b/models/main.go index 9e0a41e..52d5fd8 100644 --- a/models/main.go +++ b/models/main.go @@ -390,7 +390,7 @@ type GameSettings struct { RoomID string `db:"room_id"` Language string `json:"language" example:"en" form:"language" db:"language"` RoomPass string `json:"room_pass" db:"room_pass"` - TurnSecondsLeft uint32 `db:"turn_seconds_left"` + RoundTime uint32 `json:"round_time" db:"turn_time"` CreatedAt time.Time `db:"created_at"` } diff --git a/repos/players.go b/repos/players.go index 9a8dd7e..7c4ee49 100644 --- a/repos/players.go +++ b/repos/players.go @@ -13,7 +13,7 @@ type PlayersRepo interface { PlayerAdd(ctx context.Context, player *models.Player) error PlayerUpdate(ctx context.Context, player *models.Player) error PlayerDelete(ctx context.Context, roomID, username string) error - PlayerSetRoomID(ctx context.Context, username, roomID string) error + PlayerSetRoomID(ctx context.Context, roomID, username string) error PlayerExitRoom(ctx context.Context, username string) error PlayerListNames(ctx context.Context) ([]string, error) PlayerList(ctx context.Context, isBot bool) ([]models.Player, error) diff --git a/repos/rooms.go b/repos/rooms.go index 9a26647..ea56a78 100644 --- a/repos/rooms.go +++ b/repos/rooms.go @@ -47,7 +47,7 @@ func (p *RepoProvider) RoomCreate(ctx context.Context, r *models.Room) error { if err != nil { return err } - _, err = db.ExecContext(ctx, `INSERT INTO settings (room_id, language, room_pass, turn_time, turn_seconds_left) VALUES (?, ?, ?, ?, ?)`, r.ID, r.Settings.Language, r.Settings.RoomPass, r.Settings.RoundTime, r.Settings.TurnSecondsLeft) + _, err = db.ExecContext(ctx, `INSERT INTO settings (room_id, language, room_pass, turn_time) VALUES (?, ?, ?, ?)`, r.ID, r.Settings.Language, r.Settings.RoomPass, r.Settings.RoundTime) return err } @@ -63,7 +63,7 @@ func (p *RepoProvider) RoomUpdate(ctx context.Context, r *models.Room) error { if err != nil { return err } - _, err = db.ExecContext(ctx, `UPDATE settings SET language = ?, room_pass = ?, turn_time = ?, turn_seconds_left = ? WHERE room_id = ?`, r.Settings.Language, r.Settings.RoomPass, r.Settings.RoundTime, r.Settings.TurnSecondsLeft, r.ID) + _, err = db.ExecContext(ctx, `UPDATE settings SET language = ?, room_pass = ?, turn_time = ?, WHERE room_id = ?`, r.Settings.Language, r.Settings.RoomPass, r.Settings.RoundTime, r.ID) return err } diff --git a/repos/rooms_test.go b/repos/rooms_test.go index 096bd1f..8b04348 100644 --- a/repos/rooms_test.go +++ b/repos/rooms_test.go @@ -84,7 +84,6 @@ func setupTestDB(t *testing.T) (*sqlx.DB, func()) { language TEXT NOT NULL DEFAULT 'en', room_pass TEXT NOT NULL DEFAULT '', turn_time INTEGER NOT NULL DEFAULT 60, - turn_seconds_left INTEGER NOT NULL DEFAULT 0, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE ); @@ -145,12 +144,12 @@ func TestRoomsRepo_CreateRoom(t *testing.T) { assert.Equal(t, room.CreatorName, retrievedRoom.CreatorName) var retrievedSettings models.GameSettings - err = db.Get(&retrievedSettings, "SELECT id, language, room_pass, turn_time, turn_seconds_left FROM settings WHERE room_id = ?", room.ID) + err = db.Get(&retrievedSettings, "SELECT id, language, room_pass, turn_time FROM settings WHERE room_id = ?", room.ID) assert.NoError(t, err) assert.Equal(t, room.Settings.Language, retrievedSettings.Language) assert.Equal(t, room.Settings.RoundTime, retrievedSettings.RoundTime) assert.Equal(t, room.Settings.RoomPass, retrievedSettings.RoomPass) - assert.Equal(t, room.Settings.TurnSecondsLeft, retrievedSettings.TurnSecondsLeft) + assert.Equal(t, room.Settings.RoundTime, retrievedSettings.RoundTime) } func TestRoomsRepo_GetRoomByID(t *testing.T) { @@ -182,9 +181,9 @@ func TestRoomsRepo_GetRoomByID(t *testing.T) { } // Insert a room directly into the database for testing GetRoomByID - _, err := db.Exec(`INSERT INTO rooms (id, created_at, creator_name, team_turn, this_turn_limit, opened_this_turn, blue_counter, red_counter, red_turn, mime_done, is_running, is_over, team_won, room_link) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, room.ID, room.CreatedAt, room.CreatorName, room.TeamTurn, room.ThisTurnLimit, room.OpenedThisTurn, room.BlueCounter, room.RedCounter, room.RedTurn, room.MimeDone, room.IsRunning, room.IsOver, room.TeamWon, room.RoomLink) + _, err = db.Exec(`INSERT INTO rooms (id, created_at, creator_name, team_turn, this_turn_limit, opened_this_turn, blue_counter, red_counter, red_turn, mime_done, is_running, is_over, team_won, room_link) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, room.ID, room.CreatedAt, room.CreatorName, room.TeamTurn, room.ThisTurnLimit, room.OpenedThisTurn, room.BlueCounter, room.RedCounter, room.RedTurn, room.MimeDone, room.IsRunning, room.IsOver, room.TeamWon, room.RoomLink) assert.NoError(t, err) - _, err = db.Exec(`INSERT INTO settings (room_id, language, room_pass, turn_time, turn_seconds_left) VALUES (?, ?, ?, ?, ?)`, room.ID, room.Settings.Language, room.Settings.RoomPass, room.Settings.RoundTime, room.Settings.TurnSecondsLeft) + _, err = db.Exec(`INSERT INTO settings (room_id, language, room_pass, turn_time) VALUES (?, ?, ?, ?)`, room.ID, room.Settings.Language, room.Settings.RoomPass, room.Settings.RoundTime) assert.NoError(t, err) retrievedRoom, err := repo.RoomGetByID(context.Background(), room.ID) @@ -246,12 +245,12 @@ func TestRoomsRepo_ListRooms(t *testing.T) { _, err := db.Exec(`INSERT INTO rooms (id, created_at, creator_name, team_turn, this_turn_limit, opened_this_turn, blue_counter, red_counter, red_turn, mime_done, is_running, is_over, team_won, room_link) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, room1.ID, room1.CreatedAt, room1.CreatorName, room1.TeamTurn, room1.ThisTurnLimit, room1.OpenedThisTurn, room1.BlueCounter, room1.RedCounter, room1.RedTurn, room1.MimeDone, room1.IsRunning, room1.IsOver, room1.TeamWon, room1.RoomLink) assert.NoError(t, err) - _, err = db.Exec(`INSERT INTO settings (room_id, language, room_pass, turn_time, turn_seconds_left) VALUES (?, ?, ?, ?, ?)`, room1.ID, room1.Settings.Language, room1.Settings.RoomPass, room1.Settings.RoundTime, room1.Settings.TurnSecondsLeft) + _, err = db.Exec(`INSERT INTO settings (room_id, language, room_pass, turn_time) VALUES (?, ?, ?, ?)`, room1.ID, room1.Settings.Language, room1.Settings.RoomPass, room1.Settings.RoundTime) assert.NoError(t, err) _, err = db.Exec(`INSERT INTO rooms (id, created_at, creator_name, team_turn, this_turn_limit, opened_this_turn, blue_counter, red_counter, red_turn, mime_done, is_running, is_over, team_won, room_link) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, room2.ID, room2.CreatedAt, room2.CreatorName, room2.TeamTurn, room2.ThisTurnLimit, room2.OpenedThisTurn, room2.BlueCounter, room2.RedCounter, room2.RedTurn, room2.MimeDone, room2.IsRunning, room2.IsOver, room2.TeamWon, room2.RoomLink) assert.NoError(t, err) - _, err = db.Exec(`INSERT INTO settings (room_id, language, room_pass, turn_time, turn_seconds_left) VALUES (?, ?, ?, ?, ?)`, room2.ID, room2.Settings.Language, room2.Settings.RoomPass, room2.Settings.RoundTime, room2.Settings.TurnSecondsLeft) + _, err = db.Exec(`INSERT INTO settings (room_id, language, room_pass, turn_time) VALUES (?, ?, ?, ?)`, room2.ID, room2.Settings.Language, room2.Settings.RoomPass, room2.Settings.RoundTime) assert.NoError(t, err) rooms, err := repo.RoomList(context.Background()) @@ -289,7 +288,7 @@ func TestRoomsRepo_DeleteRoomByID(t *testing.T) { _, err := db.Exec(`INSERT INTO rooms (id, created_at, creator_name, team_turn, this_turn_limit, opened_this_turn, blue_counter, red_counter, red_turn, mime_done, is_running, is_over, team_won, room_link) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, room.ID, room.CreatedAt, room.CreatorName, room.TeamTurn, room.ThisTurnLimit, room.OpenedThisTurn, room.BlueCounter, room.RedCounter, room.RedTurn, room.MimeDone, room.IsRunning, room.IsOver, room.TeamWon, room.RoomLink) assert.NoError(t, err) - _, err = db.Exec(`INSERT INTO settings (room_id, language, room_pass, turn_time, turn_seconds_left) VALUES (?, ?, ?, ?, ?)`, room.ID, room.Settings.Language, room.Settings.RoomPass, room.Settings.RoundTime, room.Settings.TurnSecondsLeft) + _, err = db.Exec(`INSERT INTO settings (room_id, language, room_pass, turn_time) VALUES (?, ?, ?, ?, ?)`, room.ID, room.Settings.Language, room.Settings.RoomPass, room.Settings.RoundTime, room.Settings.TurnSecondsLeft) assert.NoError(t, err) // Insert a word card for the room @@ -350,13 +349,13 @@ func TestRoomsRepo_UpdateRoom(t *testing.T) { _, err := db.Exec(`INSERT INTO rooms (id, created_at, creator_name, team_turn, this_turn_limit, opened_this_turn, blue_counter, red_counter, red_turn, mime_done, is_running, is_over, team_won, room_link) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, room.ID, room.CreatedAt, room.CreatorName, room.TeamTurn, room.ThisTurnLimit, room.OpenedThisTurn, room.BlueCounter, room.RedCounter, room.RedTurn, room.MimeDone, room.IsRunning, room.IsOver, room.TeamWon, room.RoomLink) assert.NoError(t, err) - _, err = db.Exec(`INSERT INTO settings (room_id, language, room_pass, turn_time, turn_seconds_left) VALUES (?, ?, ?, ?, ?)`, room.ID, room.Settings.Language, room.Settings.RoomPass, room.Settings.RoundTime, room.Settings.TurnSecondsLeft) + _, err = db.Exec(`INSERT INTO settings (room_id, language, room_pass, turn_time) VALUES (?, ?, ?, ?, ?)`, room.ID, room.Settings.Language, room.Settings.RoomPass, room.Settings.RoundTime, room.Settings.TurnSecondsLeft) assert.NoError(t, err) room.TeamTurn = "red" room.BlueCounter = 10 room.Settings.RoundTime = 120 - room.Settings.TurnSecondsLeft = 30 // Set a value for turn_seconds_left + err = repo.RoomUpdate(context.Background(), room) assert.NoError(t, err) diff --git a/repos/settings.go b/repos/settings.go index 2249ce0..0807add 100644 --- a/repos/settings.go +++ b/repos/settings.go @@ -24,7 +24,7 @@ func (p *RepoProvider) SettingsGetByRoomID(ctx context.Context, roomID string) ( func (p *RepoProvider) SettingsUpdate(ctx context.Context, s *models.GameSettings) error { db := getDB(ctx, p.DB) - _, err := db.ExecContext(ctx, `UPDATE settings SET language = ?, room_pass = ?, turn_time = ?, turn_seconds_left = ? WHERE room_id = ?`, s.Language, s.RoomPass, s.RoundTime, s.TurnSecondsLeft, s.RoomID) + _, err := db.ExecContext(ctx, `UPDATE settings SET language = ?, room_pass = ?, turn_time = ? WHERE room_id = ?`, s.Language, s.RoomPass, s.RoundTime, s.RoomID) return err } diff --git a/repos/settings_test.go b/repos/settings_test.go index 4818ff5..b354609 100644 --- a/repos/settings_test.go +++ b/repos/settings_test.go @@ -30,17 +30,17 @@ func TestSettingsRepo_SettingsUpdate(t *testing.T) { Language: "en", RoomPass: "pass123", RoundTime: 60, - TurnSecondsLeft: 60, + CreatedAt: time.Now(), } // Insert initial settings - _, err = db.Exec(`INSERT INTO settings (room_id, language, room_pass, turn_time, turn_seconds_left, created_at) VALUES (?, ?, ?, ?, ?, ?)`, settings.RoomID, settings.Language, settings.RoomPass, settings.RoundTime, settings.TurnSecondsLeft, settings.CreatedAt) + _, err = db.Exec(`INSERT INTO settings (room_id, language, room_pass, turn_time, created_at) VALUES (?, ?, ?, ?, ?)`, settings.RoomID, settings.Language, settings.RoomPass, settings.RoundTime, settings.CreatedAt) assert.NoError(t, err) // Update settings settings.RoundTime = 120 - settings.TurnSecondsLeft = 30 + settings.Language = "ru" err = repo.SettingsUpdate(context.Background(), settings) @@ -52,6 +52,6 @@ func TestSettingsRepo_SettingsUpdate(t *testing.T) { assert.NoError(t, err) assert.Equal(t, uint32(120), updatedSettings.RoundTime) - assert.Equal(t, uint32(30), updatedSettings.TurnSecondsLeft) + assert.Equal(t, "ru", updatedSettings.Language) } diff --git a/todos.md b/todos.md index d3ee429..afb0ad5 100644 --- a/todos.md +++ b/todos.md @@ -66,5 +66,9 @@ - name check does not work; - game did not end when all blue cards were open; - bot ends a turn after guessing one word only; - - sync writing to json cache; what happens now: timer (or other side routine) overwrites old room, while mime making clue; +----------------- +- instant timer over; +- bot does not react; +{"time":"2025-07-04T16:01:57.755750352+03:00","level":"INFO","source":{"function":"gralias/handlers.StartTurnTimer.func1","file":"/home/grail/projects/web/gralias/handlers/timer.go","line":43},"msg":"turn time is over","room_id":"d1jt16sg3nfp9p4thgl0"} +looking for bot to move team-turn: red mime-done: false bot-map: map[] is_running: true blueMime: redMime: