From 968b835d0e6fe960c3d7ab915ef6d9cecec4ab7f Mon Sep 17 00:00:00 2001
From: nsfisis <nsfisis@gmail.com>
Date: Mon, 5 Aug 2024 02:33:54 +0900
Subject: feat(backend): allow to edit `game_type` in admin page

---
 backend/query.sql | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

(limited to 'backend/query.sql')

diff --git a/backend/query.sql b/backend/query.sql
index 886f96c..39b0b21 100644
--- a/backend/query.sql
+++ b/backend/query.sql
@@ -41,9 +41,10 @@ LIMIT 1;
 -- name: UpdateGame :exec
 UPDATE games
 SET
-    state = $2,
-    display_name = $3,
-    duration_seconds = $4,
-    started_at = $5,
-    problem_id = $6
+    game_type = $2,
+    state = $3,
+    display_name = $4,
+    duration_seconds = $5,
+    started_at = $6,
+    problem_id = $7
 WHERE game_id = $1;
-- 
cgit v1.3.1


From 498ad23eaaae1e856c71f44ad0bf3912a6d7e5b7 Mon Sep 17 00:00:00 2001
From: nsfisis <nsfisis@gmail.com>
Date: Mon, 5 Aug 2024 03:00:48 +0900
Subject: feat(backend): wait for all players to enter

---
 backend/db/query.sql.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 backend/game/hub.go     | 10 ++++++++--
 backend/game/models.go  |  1 +
 backend/query.sql       |  5 +++++
 4 files changed, 60 insertions(+), 2 deletions(-)

(limited to 'backend/query.sql')

diff --git a/backend/db/query.sql.go b/backend/db/query.sql.go
index c574ca8..8df3bf5 100644
--- a/backend/db/query.sql.go
+++ b/backend/db/query.sql.go
@@ -109,6 +109,52 @@ func (q *Queries) GetUserByID(ctx context.Context, userID int32) (User, error) {
 	return i, err
 }
 
+const listGamePlayers = `-- name: ListGamePlayers :many
+SELECT game_id, game_players.user_id, users.user_id, username, display_name, icon_path, is_admin, created_at FROM game_players
+LEFT JOIN users ON game_players.user_id = users.user_id
+WHERE game_players.game_id = $1
+`
+
+type ListGamePlayersRow struct {
+	GameID      int32
+	UserID      int32
+	UserID_2    *int32
+	Username    *string
+	DisplayName *string
+	IconPath    *string
+	IsAdmin     *bool
+	CreatedAt   pgtype.Timestamp
+}
+
+func (q *Queries) ListGamePlayers(ctx context.Context, gameID int32) ([]ListGamePlayersRow, error) {
+	rows, err := q.db.Query(ctx, listGamePlayers, gameID)
+	if err != nil {
+		return nil, err
+	}
+	defer rows.Close()
+	var items []ListGamePlayersRow
+	for rows.Next() {
+		var i ListGamePlayersRow
+		if err := rows.Scan(
+			&i.GameID,
+			&i.UserID,
+			&i.UserID_2,
+			&i.Username,
+			&i.DisplayName,
+			&i.IconPath,
+			&i.IsAdmin,
+			&i.CreatedAt,
+		); err != nil {
+			return nil, err
+		}
+		items = append(items, i)
+	}
+	if err := rows.Err(); err != nil {
+		return nil, err
+	}
+	return items, nil
+}
+
 const listGames = `-- name: ListGames :many
 SELECT game_id, game_type, state, display_name, duration_seconds, created_at, started_at, games.problem_id, problems.problem_id, title, description FROM games
 LEFT JOIN problems ON games.problem_id = problems.problem_id
diff --git a/backend/game/hub.go b/backend/game/hub.go
index 239f5da..70bf71f 100644
--- a/backend/game/hub.go
+++ b/backend/game/hub.go
@@ -81,7 +81,7 @@ func (hub *gameHub) run() {
 						entriedPlayerCount++
 					}
 				}
-				if entriedPlayerCount == 2 {
+				if entriedPlayerCount == hub.game.playerCount {
 					err := hub.q.UpdateGameState(hub.ctx, db.UpdateGameStateParams{
 						GameID: int32(hub.game.gameID),
 						State:  string(gameStateWaitingStart),
@@ -101,7 +101,7 @@ func (hub *gameHub) run() {
 						readyPlayerCount++
 					}
 				}
-				if readyPlayerCount == 2 {
+				if readyPlayerCount == hub.game.playerCount {
 					startAt := time.Now().Add(11 * time.Second).UTC()
 					for player := range hub.players {
 						player.s2cMessages <- &playerMessageS2CStart{
@@ -300,6 +300,11 @@ func (hubs *GameHubs) RestoreFromDB(ctx context.Context) error {
 				description: *row.Description,
 			}
 		}
+		// TODO: N+1
+		playerRows, err := hubs.q.ListGamePlayers(ctx, int32(row.GameID))
+		if err != nil {
+			return err
+		}
 		hubs.hubs[int(row.GameID)] = newGameHub(ctx, &game{
 			gameID:          int(row.GameID),
 			durationSeconds: int(row.DurationSeconds),
@@ -307,6 +312,7 @@ func (hubs *GameHubs) RestoreFromDB(ctx context.Context) error {
 			displayName:     row.DisplayName,
 			startedAt:       startedAt,
 			problem:         problem_,
+			playerCount:     len(playerRows),
 		}, hubs.q)
 	}
 	return nil
diff --git a/backend/game/models.go b/backend/game/models.go
index e96184a..4080482 100644
--- a/backend/game/models.go
+++ b/backend/game/models.go
@@ -30,6 +30,7 @@ type game struct {
 	durationSeconds int
 	startedAt       *time.Time
 	problem         *problem
+	playerCount     int
 }
 
 type problem struct {
diff --git a/backend/query.sql b/backend/query.sql
index 39b0b21..245d5cf 100644
--- a/backend/query.sql
+++ b/backend/query.sql
@@ -38,6 +38,11 @@ LEFT JOIN problems ON games.problem_id = problems.problem_id
 WHERE games.game_id = $1
 LIMIT 1;
 
+-- name: ListGamePlayers :many
+SELECT * FROM game_players
+LEFT JOIN users ON game_players.user_id = users.user_id
+WHERE game_players.game_id = $1;
+
 -- name: UpdateGame :exec
 UPDATE games
 SET
-- 
cgit v1.3.1

