From 6d63fc5db3eec09f14f461758408fc0dd0963e8e Mon Sep 17 00:00:00 2001 From: Trevor Slocum Date: Tue, 19 Dec 2023 18:43:50 -0800 Subject: [PATCH] Serve matches via URL --- pkg/server/database.go | 23 +++++++++++++++++++++++ pkg/server/database_disabled.go | 4 ++++ pkg/server/server.go | 19 +++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/pkg/server/database.go b/pkg/server/database.go index cd7e294..83cd3b8 100644 --- a/pkg/server/database.go +++ b/pkg/server/database.go @@ -437,6 +437,29 @@ func recordGameResult(g *bgammon.Game, winType int, account1 int, account2 int, return err } +func matchInfo(id int) (timestamp int64, player1 string, player2 string, replay []byte, err error) { + dbLock.Lock() + defer dbLock.Unlock() + + if db == nil { + return 0, "", "", nil, err + } else if id <= 0 { + return 0, "", "", nil, fmt.Errorf("please specify an id") + } + + tx, err := begin() + if err != nil { + return 0, "", "", nil, err + } + defer tx.Commit(context.Background()) + + err = tx.QueryRow(context.Background(), "SELECT started, player1, player2, replay FROM game WHERE id = $1 AND replay != ''", id).Scan(×tamp, &player1, &player2, &replay) + if err != nil { + return 0, "", "", nil, err + } + return timestamp, player1, player2, replay, nil +} + func replayByID(id int) ([]byte, error) { dbLock.Lock() defer dbLock.Unlock() diff --git a/pkg/server/database_disabled.go b/pkg/server/database_disabled.go index c068925..861fcac 100644 --- a/pkg/server/database_disabled.go +++ b/pkg/server/database_disabled.go @@ -43,6 +43,10 @@ func setAccountSetting(id int, name string, value int) error { return nil } +func matchInfo(id int) (timestamp int64, player1 string, player2 string, replay []byte, err error) { + return 0, "", "", nil, nil +} + func replayByID(id int) ([]byte, error) { return nil, nil } diff --git a/pkg/server/server.go b/pkg/server/server.go index 65e315e..5dc3f59 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -161,6 +161,24 @@ func (s *server) handleResetPassword(w http.ResponseWriter, r *http.Request) { w.Write([]byte(`

Your bgammon.org password has been reset.

Your new password is ` + newPassword + ``)) } +func (s *server) handleMatch(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + id, err := strconv.Atoi(vars["id"]) + if err != nil || id <= 0 { + return + } + + timestamp, player1, player2, replay, err := matchInfo(id) + if err != nil || len(replay) == 0 { + log.Printf("failed to retrieve match: %s", err) + return + } + + w.Header().Set("Content-Type", "text/plain") + w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%d_%s_%s.match"`, timestamp, player1, player2)) + w.Write(replay) +} + func (s *server) handleListMatches(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.Write(s.cachedMatches()) @@ -250,6 +268,7 @@ func (s *server) listenWebSocket(address string) { m := mux.NewRouter() m.HandleFunc("/reset/{id:[0-9]+}/{key:[A-Za-z0-9]+}", s.handleResetPassword) + m.HandleFunc("/match/{id:[0-9]+}", s.handleMatch) m.HandleFunc("/matches", s.handleListMatches) m.HandleFunc("/stats", s.handlePrintDailyStats) m.HandleFunc("/stats-total", s.handlePrintCumulativeStats)