itMake board editable in-place - 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 7689f88f24595ca9afe38cecab41bfc4e3c29473 /scm/scoreboard/commit/7689f88f24595ca9afe38cecab41bfc4e3c29473.gph z3bra.org 70 1parent 54deea3d092677422021864f23df5cb091f0a0ec /scm/scoreboard/commit/54deea3d092677422021864f23df5cb091f0a0ec.gph z3bra.org 70 hAuthor: Willy Goiffon URL:mailto:contact@z3bra.org z3bra.org 70 iDate: Mon, 5 Dec 2022 13:11:10 +0100 Err z3bra.org 70 i Err z3bra.org 70 iMake board editable in-place Err z3bra.org 70 i Err z3bra.org 70 iDiffstat: Err z3bra.org 70 i M db.go | 58 +++++++++++++++++++++++++------ Err z3bra.org 70 i M main.go | 173 +++++++------------------------ Err z3bra.org 70 i M mkfile | 2 +- Err z3bra.org 70 i M playerbox.go | 12 ++++++------ Err z3bra.org 70 i A ui.go | 86 ++++++++++++++++++++++++++++++ Err z3bra.org 70 i M util.go | 2 +- Err z3bra.org 70 i Err z3bra.org 70 i6 files changed, 178 insertions(+), 155 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@@ -38,15 +38,39 @@ const ( Err z3bra.org 70 i ` Err z3bra.org 70 i ) Err z3bra.org 70 i Err z3bra.org 70 i-func db_count() int { Err z3bra.org 70 i+ Err z3bra.org 70 i+func (a *Application) db_init(file string) error { Err z3bra.org 70 i+ var err error Err z3bra.org 70 i+ Err z3bra.org 70 i+ // open database Err z3bra.org 70 i+ a.db, err = sql.Open("sqlite", file) 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+ // create schema if needed Err z3bra.org 70 i+ _, err = a.db.Exec(DB_CREATE) 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 = a.db.Exec(DB_FILL) Err z3bra.org 70 i+ if err != nil { Err z3bra.org 70 i+ panic(err) Err z3bra.org 70 i+ } Err z3bra.org 70 i+ //*/ Err z3bra.org 70 i+ return nil Err z3bra.org 70 i+} Err z3bra.org 70 i+ Err z3bra.org 70 i+func (a *Application) db_count() int { Err z3bra.org 70 i var count int Err z3bra.org 70 i query := `SELECT count(id) FROM score;` Err z3bra.org 70 i- row := db.QueryRow(query) Err z3bra.org 70 i+ row := a.db.QueryRow(query) Err z3bra.org 70 i row.Scan(&count) Err z3bra.org 70 i return count Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i-func db_rank(score int, ts int64) int { Err z3bra.org 70 i+func (a *Application) db_rank(score int, ts int64) int { Err z3bra.org 70 i var rank int Err z3bra.org 70 i query := `SELECT Err z3bra.org 70 i count(id) Err z3bra.org 70 it@@ -55,12 +79,26 @@ func db_rank(score int, ts int64) int { Err z3bra.org 70 i score >= ? Err z3bra.org 70 i ;` Err z3bra.org 70 i Err z3bra.org 70 i- row := db.QueryRow(query, score) Err z3bra.org 70 i+ row := a.db.QueryRow(query, score) Err z3bra.org 70 i row.Scan(&rank) Err z3bra.org 70 i return rank + 1 Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i-func db_ranked(offset, limit int) ([]Player, error) { Err z3bra.org 70 i+func (a *Application) db_count_flag(flag int) int { Err z3bra.org 70 i+ var count int Err z3bra.org 70 i+ query := `SELECT Err z3bra.org 70 i+ count(id) Err z3bra.org 70 i+ FROM score Err z3bra.org 70 i+ WHERE Err z3bra.org 70 i+ flags >= ? Err z3bra.org 70 i+ ;` Err z3bra.org 70 i+ Err z3bra.org 70 i+ row := a.db.QueryRow(query, flag) Err z3bra.org 70 i+ row.Scan(&count) Err z3bra.org 70 i+ return count Err z3bra.org 70 i+} Err z3bra.org 70 i+ Err z3bra.org 70 i+func (a *Application) db_ranked(offset, limit int) ([]Player, error) { Err z3bra.org 70 i query := `SELECT Err z3bra.org 70 i id,name,token,flag,score Err z3bra.org 70 i FROM score Err z3bra.org 70 it@@ -71,7 +109,7 @@ func db_ranked(offset, limit int) ([]Player, error) { Err z3bra.org 70 i OFFSET ? Err z3bra.org 70 i ;` Err z3bra.org 70 i Err z3bra.org 70 i- rows, err := db.Query(query, limit, offset) Err z3bra.org 70 i+ rows, err := a.db.Query(query, limit, offset) Err z3bra.org 70 i if err != nil { Err z3bra.org 70 i return nil, err Err z3bra.org 70 i } Err z3bra.org 70 it@@ -89,11 +127,11 @@ func db_ranked(offset, limit int) ([]Player, error) { Err z3bra.org 70 i return players, nil Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i-func db_player(id int) *Player { Err z3bra.org 70 i+func (a *Application) db_player(id int) *Player { Err z3bra.org 70 i var p Player Err z3bra.org 70 i query := `SELECT id,name,token,flag,score,ts FROM score WHERE id = ?` Err z3bra.org 70 i Err z3bra.org 70 i- row := db.QueryRow(query, p.id) Err z3bra.org 70 i+ row := a.db.QueryRow(query, p.id) Err z3bra.org 70 i err := row.Scan(&p.id, &p.name, &p.token, &p.flags, &p.score) Err z3bra.org 70 i if err == sql.ErrNoRows { Err z3bra.org 70 i return nil Err z3bra.org 70 it@@ -102,9 +140,9 @@ func db_player(id int) *Player { Err z3bra.org 70 i return &p Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i-func db_save(p Player) int64 { Err z3bra.org 70 i+func (a *Application) db_save(p Player) int64 { Err z3bra.org 70 i query := `INSERT INTO score(name,token,flag,score,ts) VALUES(?,?,?,?,?);` Err z3bra.org 70 i- r, err := db.Exec(query, p.name, p.token, p.flags, p.score, p.ts) Err z3bra.org 70 i+ r, err := a.db.Exec(query, p.name, p.token, p.flags, p.score, p.ts) Err z3bra.org 70 i if err != nil { Err z3bra.org 70 i panic(err) 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@@ -17,21 +17,20 @@ package main Err z3bra.org 70 i import ( Err z3bra.org 70 i "flag" Err z3bra.org 70 i "fmt" Err z3bra.org 70 i- "math" Err z3bra.org 70 i "os" Err z3bra.org 70 i "regexp" Err z3bra.org 70 i "time" 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 //"golang.org/x/crypto/argon2" Err z3bra.org 70 i Err z3bra.org 70 i _ "modernc.org/sqlite" Err z3bra.org 70 i ) Err z3bra.org 70 i Err z3bra.org 70 i const ( Err z3bra.org 70 i- BOARD_SIZE int = 15 Err z3bra.org 70 i+ BOARD_WIDTH int = 26 Err z3bra.org 70 i+ BOARD_HEIGHT int = 15 Err z3bra.org 70 i DB string = "leaderboard.db" Err z3bra.org 70 i ) Err z3bra.org 70 i Err z3bra.org 70 it@@ -45,10 +44,12 @@ type Player struct { Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i type Application struct { Err z3bra.org 70 i+ db *sql.DB Err z3bra.org 70 i app *tview.Application Err z3bra.org 70 i pages *tview.Pages Err z3bra.org 70 i frame *tview.Grid Err z3bra.org 70 i- board *tview.Grid Err z3bra.org 70 i+ board *tview.Flex Err z3bra.org 70 i+ player Player Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i var flag_sha256 = [...]string { Err z3bra.org 70 it@@ -59,20 +60,12 @@ var flag_sha256 = [...]string { Err z3bra.org 70 i "8CB250A66D4301244699186CA723E11AFA806C64466789AB14B7027A2F928BF8", // egg.png Err z3bra.org 70 i "F6A4071C9C0DDCCB53FC1CDCA38E32CF10551F75AA48996A9341842A7EF2591B"} // salt.png Err z3bra.org 70 i Err z3bra.org 70 i-//var Application { Err z3bra.org 70 i-// app: tview.NewApplication(), Err z3bra.org 70 i-// frame: BoardFrame(26, 15), Err z3bra.org 70 i-// pages: tview.NewPages(), Err z3bra.org 70 i-// board: tview.NewTable(), Err z3bra.org 70 i-//} Err z3bra.org 70 i Err z3bra.org 70 i-var app = tview.NewApplication() Err z3bra.org 70 i-var pages = tview.NewPages() Err z3bra.org 70 i-var db *sql.DB Err z3bra.org 70 i-var player = Player{ Err z3bra.org 70 i- score: 100, Err z3bra.org 70 i- flags: 1, Err z3bra.org 70 i- ts: time.Now().Unix(), Err z3bra.org 70 i+var cyboard = Application{ Err z3bra.org 70 i+ app: tview.NewApplication(), Err z3bra.org 70 i+ pages: tview.NewPages(), Err z3bra.org 70 i+ frame: tview.NewGrid(), Err z3bra.org 70 i+ board: tview.NewFlex(), Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i func usage() { Err z3bra.org 70 it@@ -80,41 +73,6 @@ func usage() { Err z3bra.org 70 i os.Exit(0) Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i-func RankTable(t *tview.Table, offset, limit, rank int, fill bool) (*tview.Table) { Err z3bra.org 70 i- players, err := db_ranked(offset, limit) Err z3bra.org 70 i- if err != nil { Err z3bra.org 70 i- panic(err) Err z3bra.org 70 i- } Err z3bra.org 70 i- Err z3bra.org 70 i- t.SetSelectable(true, false). Err z3bra.org 70 i- SetSelectedStyle(tcell.StyleDefault.Reverse(true)) Err z3bra.org 70 i- Err z3bra.org 70 i- for i := 0; i < len(players); i++ { Err z3bra.org 70 i- p := players[i] Err z3bra.org 70 i- rankstr := fmt.Sprintf("%4s", humanize.Ordinal(rank + i)) Err z3bra.org 70 i- flagstr := flag2str(p.flags) Err z3bra.org 70 i- scorestr := fmt.Sprintf("%4d", p.score) Err z3bra.org 70 i- t.SetCell(i, 0, newcell(rankstr)) Err z3bra.org 70 i- t.SetCell(i, 1, newcell(p.name)) Err z3bra.org 70 i- t.SetCell(i, 2, newcell(flagstr)) Err z3bra.org 70 i- t.SetCell(i, 3, newcell(scorestr)) Err z3bra.org 70 i- } Err z3bra.org 70 i- Err z3bra.org 70 i- if fill == true { Err z3bra.org 70 i- for i:=t.GetRowCount(); i