itFix flag submission - scoreboard - Interactive scoreboard for CTF-like games Err z3bra.org 70 hgit clone git://git.z3bra.org/scoreboard.git URL:git://git.z3bra.org/scoreboard.git z3bra.org 70 1Log /scm/scoreboard/log.gph z3bra.org 70 1Files /scm/scoreboard/files.gph z3bra.org 70 1Refs /scm/scoreboard/refs.gph z3bra.org 70 i--- Err z3bra.org 70 1commit 307cde02b7be14d34c37e7f02eeaea907d1c0d84 /scm/scoreboard/commit/307cde02b7be14d34c37e7f02eeaea907d1c0d84.gph z3bra.org 70 1parent cc20e9fc44c4a724943a4eb8d8a1edb741ecbb39 /scm/scoreboard/commit/cc20e9fc44c4a724943a4eb8d8a1edb741ecbb39.gph z3bra.org 70 hAuthor: Willy Goiffon URL:mailto:contact@z3bra.org z3bra.org 70 iDate: Thu, 26 Sep 2024 00:11:35 +0200 Err z3bra.org 70 i Err z3bra.org 70 iFix flag submission Err z3bra.org 70 i Err z3bra.org 70 iDiffstat: Err z3bra.org 70 i M db.go | 26 ++++++++++++++++++++++++++ Err z3bra.org 70 i M main.go | 28 +++++++++++++++------------- Err z3bra.org 70 i M player.go | 46 ++++++++++++++++++++++--------- Err z3bra.org 70 i M ui.go | 4 +--- Err z3bra.org 70 i Err z3bra.org 70 i4 files changed, 75 insertions(+), 29 deletions(-) Err z3bra.org 70 i--- Err z3bra.org 70 1diff --git a/db.go b/db.go /scm/scoreboard/file/db.go.gph z3bra.org 70 it@@ -74,6 +74,32 @@ func db_count_players(db *sql.DB) (int, error) { Err z3bra.org 70 i return count, err Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i+func db_count_user_flags(db *sql.DB, name string) (int, error) { Err z3bra.org 70 i+ var count int Err z3bra.org 70 i+ Err z3bra.org 70 i+ query := `SELECT count(*) FROM score WHERE name = ?;` Err z3bra.org 70 i+ Err z3bra.org 70 i+ row := db.QueryRow(query, name) Err z3bra.org 70 i+ err := row.Scan(&count) Err z3bra.org 70 i+ Err z3bra.org 70 i+ return count, err Err z3bra.org 70 i+} Err z3bra.org 70 i+ Err z3bra.org 70 i+func db_calculate_user_score(db *sql.DB, name string) (int, error) { Err z3bra.org 70 i+ var count int Err z3bra.org 70 i+ Err z3bra.org 70 i+ query := `SELECT Err z3bra.org 70 i+ sum(flag.score) Err z3bra.org 70 i+ FROM flag Err z3bra.org 70 i+ INNER JOIN score ON score.flag = flag.value Err z3bra.org 70 i+ WHERE score.name = ?;` Err z3bra.org 70 i+ Err z3bra.org 70 i+ row := db.QueryRow(query, name) Err z3bra.org 70 i+ err := row.Scan(&count) Err z3bra.org 70 i+ Err z3bra.org 70 i+ return count, err Err z3bra.org 70 i+} Err z3bra.org 70 i+ Err z3bra.org 70 i func db_get_flags(db *sql.DB) ([]Flag, error) { Err z3bra.org 70 i query := `SELECT rowid,value,badge,score FROM flag ORDER BY score;` Err z3bra.org 70 i Err z3bra.org 70 1diff --git a/main.go b/main.go /scm/scoreboard/file/main.go.gph z3bra.org 70 it@@ -24,7 +24,6 @@ import ( Err z3bra.org 70 i "database/sql" Err z3bra.org 70 i "github.com/gdamore/tcell/v2" Err z3bra.org 70 i "github.com/rivo/tview" Err z3bra.org 70 i- "github.com/dustin/go-humanize" Err z3bra.org 70 i Err z3bra.org 70 i _ "modernc.org/sqlite" Err z3bra.org 70 i ) Err z3bra.org 70 it@@ -34,7 +33,7 @@ const ( Err z3bra.org 70 i BOARD_HEIGHT int = 15 Err z3bra.org 70 i HTML string = "score.html" Err z3bra.org 70 i DB string = "score.db" Err z3bra.org 70 i- TOKEN_REMINDER string = `%s, use the token below to submit your %s flag. Err z3bra.org 70 i+ TOKEN_REMINDER string = `%s, use the token below to submit your next flag. Err z3bra.org 70 i Save it carefully, do not share it. Err z3bra.org 70 i Err z3bra.org 70 i 🔑%s Err z3bra.org 70 it@@ -49,7 +48,7 @@ type Flag struct { Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i type Application struct { Err z3bra.org 70 i- flag int Err z3bra.org 70 i+ flag string Err z3bra.org 70 i flag_ref []Flag Err z3bra.org 70 i db *sql.DB Err z3bra.org 70 i app *tview.Application Err z3bra.org 70 it@@ -101,22 +100,26 @@ func pageToken() tview.Primitive { Err z3bra.org 70 i return Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i- if len(input.GetText()) != 24 { Err z3bra.org 70 i+ token := input.GetText() Err z3bra.org 70 i+ Err z3bra.org 70 i+ if len(token) != 24 { Err z3bra.org 70 i scoreboard.Popup("ERROR", "Invalid token format") Err z3bra.org 70 i return Err z3bra.org 70 i } Err z3bra.org 70 i- err := scoreboard.player.FromToken(input.GetText()) Err z3bra.org 70 i+ err := scoreboard.player.FromToken(token) Err z3bra.org 70 i if err != nil { Err z3bra.org 70 i scoreboard.Fatal(err) Err z3bra.org 70 i return Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i+ scoreboard.player.token = token; Err z3bra.org 70 i+ Err z3bra.org 70 i err = scoreboard.player.Submit(scoreboard.flag) Err z3bra.org 70 i if err != nil { Err z3bra.org 70 i scoreboard.Fatal(err) Err z3bra.org 70 i return Err z3bra.org 70 i } Err z3bra.org 70 i- scoreboard.HighlightBoard(scoreboard.player.ScoreRank()) Err z3bra.org 70 i+ scoreboard.HighlightBoard(scoreboard.player.ScoreRank() + 1) Err z3bra.org 70 i scoreboard.pages.SwitchToPage("board") Err z3bra.org 70 i scoreboard.GenerateHTML() Err z3bra.org 70 i }) Err z3bra.org 70 it@@ -163,7 +166,7 @@ func main() { Err z3bra.org 70 i Err z3bra.org 70 i scoreboard.flag_ref, err = db_get_flags(scoreboard.db) Err z3bra.org 70 i Err z3bra.org 70 i- scoreboard.flag = 0 Err z3bra.org 70 i+ scoreboard.flag = "" Err z3bra.org 70 i scoreboard.html = *html Err z3bra.org 70 i scoreboard.app = tview.NewApplication() Err z3bra.org 70 i scoreboard.pages = tview.NewPages() Err z3bra.org 70 it@@ -196,13 +199,12 @@ func main() { Err z3bra.org 70 i scoreboard.NewPlayer(rank + 1) Err z3bra.org 70 i scoreboard.pages.SwitchToPage("board") Err z3bra.org 70 i } else { Err z3bra.org 70 i- switch scoreboard.flag = flagid(args[0]) + 1; scoreboard.flag { Err z3bra.org 70 i- case 0: Err z3bra.org 70 i+ if flagid(args[0]) < 0 { Err z3bra.org 70 i fmt.Println("Incorrect flag") Err z3bra.org 70 i return Err z3bra.org 70 i- default: Err z3bra.org 70 i- scoreboard.pages.SwitchToPage("token") Err z3bra.org 70 i } Err z3bra.org 70 i+ scoreboard.flag = args[0] Err z3bra.org 70 i+ scoreboard.pages.SwitchToPage("token") Err z3bra.org 70 i } Err z3bra.org 70 i } else { Err z3bra.org 70 i scoreboard.pages.SwitchToPage("board") Err z3bra.org 70 it@@ -214,7 +216,7 @@ func main() { Err z3bra.org 70 i os.Exit(1) Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i- if scoreboard.player.token != "" && scoreboard.flag < 7 { Err z3bra.org 70 i- fmt.Printf(TOKEN_REMINDER, scoreboard.player.name, humanize.Ordinal(scoreboard.flag + 1), scoreboard.player.token) Err z3bra.org 70 i+ if scoreboard.player.token != "" { Err z3bra.org 70 i+ fmt.Printf(TOKEN_REMINDER, scoreboard.player.name, scoreboard.player.token) Err z3bra.org 70 i } Err z3bra.org 70 i } Err z3bra.org 70 1diff --git a/player.go b/player.go /scm/scoreboard/file/player.go.gph z3bra.org 70 it@@ -76,7 +76,7 @@ func (p *Player) Register() error { Err z3bra.org 70 i return err Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i- query := `INSERT INTO score(name,hash,ts) VALUES(?,?,?);` Err z3bra.org 70 i+ query := `INSERT INTO user(name,hash,score,flag,ts) VALUES(?,?,0,0,?);` Err z3bra.org 70 i _, err = p.db.Exec(query, p.name, hash, p.ts) Err z3bra.org 70 i if err != nil { Err z3bra.org 70 i return err Err z3bra.org 70 it@@ -104,11 +104,21 @@ func (p *Player) Fetch() error { Err z3bra.org 70 i return nil Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i-func (p *Player) Refresh(score int, flag int, ts int64) error { Err z3bra.org 70 i+func (p *Player) Refresh(ts int64) error { Err z3bra.org 70 i var err error Err z3bra.org 70 i Err z3bra.org 70 i+ p.flag, err = db_count_user_flags(p.db, p.name) Err z3bra.org 70 i+ if err != nil { Err z3bra.org 70 i+ return err Err z3bra.org 70 i+ } Err z3bra.org 70 i+ Err z3bra.org 70 i+ p.score, err = db_calculate_user_score(p.db, p.name) Err z3bra.org 70 i+ if err != nil { Err z3bra.org 70 i+ return err Err z3bra.org 70 i+ } Err z3bra.org 70 i+ Err z3bra.org 70 i query := `UPDATE user SET score = ?, flag = ?, ts = ? WHERE name = ?;` Err z3bra.org 70 i- _, err = p.db.Exec(query, score, flag, ts, p.name) Err z3bra.org 70 i+ _, err = p.db.Exec(query, p.score, p.flag, ts, p.name) Err z3bra.org 70 i if err != nil { Err z3bra.org 70 i return err Err z3bra.org 70 i } Err z3bra.org 70 it@@ -161,20 +171,30 @@ func (p *Player) Exists() bool { Err z3bra.org 70 i return (count > 0) Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i-func (p *Player) Submit(flag int) error { Err z3bra.org 70 i+func (p *Player) HasFlag(flag string) bool { Err z3bra.org 70 i+ var count int Err z3bra.org 70 i+ query := `SELECT count(*) FROM score WHERE name = ? AND flag = ?;` Err z3bra.org 70 i+ row := p.db.QueryRow(query, p.name, flag) Err z3bra.org 70 i+ row.Scan(&count) Err z3bra.org 70 i+ return (count > 0) Err z3bra.org 70 i+} Err z3bra.org 70 i+ Err z3bra.org 70 i+func (p *Player) Submit(flag string) error { Err z3bra.org 70 i+ var err error Err z3bra.org 70 i var ts int64 Err z3bra.org 70 i- var score int Err z3bra.org 70 i- var flags int Err z3bra.org 70 i Err z3bra.org 70 i- // TODO: check flag existence Err z3bra.org 70 i- // TODO: check flag already submitted Err z3bra.org 70 i- // TODO: retrieve flag score Err z3bra.org 70 i- ts = time.Now().Unix() Err z3bra.org 70 i- score = p.score // + flag_score Err z3bra.org 70 i- flags = p.flag + 1 Err z3bra.org 70 i+ if p.HasFlag(flag) { Err z3bra.org 70 i+ return errors.New("Flag already submitted") Err z3bra.org 70 i+ } else { Err z3bra.org 70 i+ query := `INSERT INTO score(name,flag) VALUES(?,?);` Err z3bra.org 70 i+ _, err = p.db.Exec(query, p.name, flag) Err z3bra.org 70 i+ if err != nil { Err z3bra.org 70 i+ return err Err z3bra.org 70 i+ } Err z3bra.org 70 i+ } Err z3bra.org 70 i Err z3bra.org 70 i // update user status in database Err z3bra.org 70 i- err := p.Refresh(score, flags, ts) Err z3bra.org 70 i+ err = p.Refresh(ts) Err z3bra.org 70 i if err != nil { Err z3bra.org 70 i return err Err z3bra.org 70 i } Err z3bra.org 70 1diff --git a/ui.go b/ui.go /scm/scoreboard/file/ui.go.gph z3bra.org 70 it@@ -107,9 +107,7 @@ func (a *Application) HighlightBoard(line int) { Err z3bra.org 70 i AddItem(RankTable(0, -1, 0, true).Select(line - 1, 0), BOARD_HEIGHT, 1, true) Err z3bra.org 70 i a.app.SetFocus(a.board) Err z3bra.org 70 i Err z3bra.org 70 i- if (a.flag < 7) { Err z3bra.org 70 i- a.frame.AddText(fmt.Sprintf(" 🔑%s", a.player.token), false, tview.AlignCenter, 0) Err z3bra.org 70 i- } Err z3bra.org 70 i+ a.frame.AddText(fmt.Sprintf(" 🔑%s", a.player.token), false, tview.AlignCenter, 0) Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i func (a *Application) NewPlayer(rank int) { Err z3bra.org 70 .