itPrompt players for token to update their score - 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 2dcf67e2ab0f8c6918133d3a5bcb3c1dee86db98 /scm/scoreboard/commit/2dcf67e2ab0f8c6918133d3a5bcb3c1dee86db98.gph z3bra.org 70 1parent e74b632684c58ebb06b40f395409f7759a3ca9fb /scm/scoreboard/commit/e74b632684c58ebb06b40f395409f7759a3ca9fb.gph z3bra.org 70 hAuthor: Willy Goiffon URL:mailto:contact@z3bra.org z3bra.org 70 iDate: Mon, 5 Dec 2022 18:18:27 +0100 Err z3bra.org 70 i Err z3bra.org 70 iPrompt players for token to update their score Err z3bra.org 70 i Err z3bra.org 70 iDiffstat: Err z3bra.org 70 i M db.go | 107 ++++++++++++++----------------- Err z3bra.org 70 i M main.go | 93 ++++++++++++++++++++++--------- Err z3bra.org 70 i M mkfile | 3 ++- Err z3bra.org 70 i M playerbox.go | 8 ++++---- Err z3bra.org 70 i M ui.go | 13 ++++++++----- Err z3bra.org 70 i Err z3bra.org 70 i5 files changed, 130 insertions(+), 94 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@@ -26,104 +26,120 @@ const ( Err z3bra.org 70 i ` Err z3bra.org 70 i DB_FILL string = ` Err z3bra.org 70 i DELETE FROM score; Err z3bra.org 70 i- INSERT INTO score(name,token,flag,score,ts) VALUES ('WGS', 'token0', 3, 600, 10); Err z3bra.org 70 i- INSERT INTO score(name,token,flag,score,ts) VALUES ('DQK', 'token1', 5, 1337, 1); Err z3bra.org 70 i- INSERT INTO score(name,token,flag,score,ts) VALUES ('VNM', 'token2', 5, 1000, 100); Err z3bra.org 70 i- INSERT INTO score(name,token,flag,score,ts) VALUES ('PLR', 'token3', 5, 1000, 300); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('WGS', 'token0', 3, 302, 2); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('DQK', 'token1', 5, 1337, 20); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('VNM', 'token2', 5, 1000, 3); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('PLR', 'token3', 5, 1000, 2); Err z3bra.org 70 i INSERT INTO score(name,token,flag,score,ts) VALUES ('UKN', 'token4', 2, 200, 200); Err z3bra.org 70 i- INSERT INTO score(name,token,flag,score,ts) VALUES ('JFK', 'token5', 3, 600, 200); Err z3bra.org 70 i- INSERT INTO score(name,token,flag,score,ts) VALUES ('NTM', 'token6', 4, 800, 100); Err z3bra.org 70 i- INSERT INTO score(name,token,flag,score,ts) VALUES ('BOB', 'token7', 1, 200, 25); Err z3bra.org 70 i- INSERT INTO score(name,token,flag,score,ts) VALUES ('AAA', 'token8', 1, 100, 13); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('JFK', 'token5', 3, 300, 200); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('AAA', 'token6', 1, 130, 1670260535); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('BBB', 'token7', 4, 400, 1670260535); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('CCC', 'token8', 4, 400, 1670260535); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('DDD', 'token9', 4, 407, 1670260535); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('EEE', 'tokenA', 4, 405, 1670260535); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('FFF', 'tokenB', 4, 401, 1670260535); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('GGG', 'tokenC', 4, 406, 1670260535); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('HHH', 'tokenD', 4, 408, 1670260445); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('III', 'tokenE', 4, 409, 1670260435); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('JJJ', 'tokenF', 4, 402, 1670260535); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('KKK', 'tokenG', 4, 400, 1670260535); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('LLL', 'tokenH', 4, 404, 1670260535); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('MMM', 'tokenI', 4, 403, 1670260535); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('NNN', 'tokenJ', 4, 400, 1670260535); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('OOO', 'tokenK', 4, 400, 1670260535); Err z3bra.org 70 i+ INSERT INTO score(name,token,flag,score,ts) VALUES ('PPP', 'tokenL', 4, 400, 1670260535); Err z3bra.org 70 i ` Err z3bra.org 70 i ) Err z3bra.org 70 i Err z3bra.org 70 i Err z3bra.org 70 i-func (a *Application) db_init(file string) error { Err z3bra.org 70 i+func db_init(file string) (*sql.DB, error) { Err z3bra.org 70 i var err error Err z3bra.org 70 i+ var db *sql.DB 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+ 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+ return nil, 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+ _, err = db.Exec(DB_CREATE) Err z3bra.org 70 i if err != nil { Err z3bra.org 70 i- return err Err z3bra.org 70 i+ return nil, 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+ _, err = 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+ return db, 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+func db_count(db *sql.DB) 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 := a.db.QueryRow(query) Err z3bra.org 70 i+ row := 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 (a *Application) db_count_flag(flag int) int { Err z3bra.org 70 i+func db_score_count(db *sql.DB, score, ts 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+ score >= ? AND Err z3bra.org 70 i+ ts => ? 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 := db.QueryRow(query, score, ts) 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_checkname(nick string) bool { Err z3bra.org 70 i+func db_flag_count(db *sql.DB, 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- name = ? Err z3bra.org 70 i+ flag >= ? Err z3bra.org 70 i ;` Err z3bra.org 70 i Err z3bra.org 70 i- row := a.db.QueryRow(query, nick) Err z3bra.org 70 i+ row := db.QueryRow(query, flag) Err z3bra.org 70 i row.Scan(&count) Err z3bra.org 70 i- return (count > 0) 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_rank(score int, ts int64) int { Err z3bra.org 70 i- var rank int Err z3bra.org 70 i+func db_id(db *sql.DB, nick string) bool { 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- score >= ? Err z3bra.org 70 i+ name = ? Err z3bra.org 70 i ;` Err z3bra.org 70 i 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+ row := db.QueryRow(query, nick) 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 (a *Application) db_ranked(offset, limit int) ([]Player, error) { Err z3bra.org 70 i+func db_ranked_players(db *sql.DB, 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 i ORDER BY Err z3bra.org 70 i score DESC, Err z3bra.org 70 i+ flag DESC, Err z3bra.org 70 i ts ASC Err z3bra.org 70 i LIMIT ? Err z3bra.org 70 i OFFSET ? Err z3bra.org 70 i ;` Err z3bra.org 70 i Err z3bra.org 70 i- rows, err := a.db.Query(query, limit, offset) Err z3bra.org 70 i+ rows, err := 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@@ -131,7 +147,7 @@ func (a *Application) db_ranked(offset, limit int) ([]Player, error) { Err z3bra.org 70 i players := make([]Player, 0) Err z3bra.org 70 i for rows.Next() { Err z3bra.org 70 i var p Player Err z3bra.org 70 i- err := rows.Scan(&p.id, &p.name, &p.token, &p.flags, &p.score) Err z3bra.org 70 i+ err := rows.Scan(&p.id, &p.name, &p.token, &p.flag, &p.score) 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@@ -140,28 +156,3 @@ func (a *Application) db_ranked(offset, limit int) ([]Player, error) { Err z3bra.org 70 i Err z3bra.org 70 i return players, nil Err z3bra.org 70 i } Err z3bra.org 70 i- 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 := 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 i- } Err z3bra.org 70 i- Err z3bra.org 70 i- return &p Err z3bra.org 70 i-} Err z3bra.org 70 i- 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 := 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 i- Err z3bra.org 70 i- id, _ := r.LastInsertId() Err z3bra.org 70 i- Err z3bra.org 70 i- return id 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@@ -34,16 +34,8 @@ const ( Err z3bra.org 70 i DB string = "leaderboard.db" Err z3bra.org 70 i ) Err z3bra.org 70 i Err z3bra.org 70 i-type Player struct { Err z3bra.org 70 i- id int Err z3bra.org 70 i- name string Err z3bra.org 70 i- token string Err z3bra.org 70 i- flags int Err z3bra.org 70 i- score int Err z3bra.org 70 i- ts int64 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 db *sql.DB Err z3bra.org 70 i app *tview.Application Err z3bra.org 70 i pages *tview.Pages Err z3bra.org 70 it@@ -54,11 +46,15 @@ type Application struct { Err z3bra.org 70 i Err z3bra.org 70 i var flag_sha256 = [...]string { Err z3bra.org 70 i "A", Err z3bra.org 70 i+ "B", Err z3bra.org 70 i+ "C", Err z3bra.org 70 i+ "D", Err z3bra.org 70 i+ "E"} Err z3bra.org 70 i //"A6322C6522FB49959242670BC62E85A29ED7EB8CFCD87BE91521F0CA5EEBD198", // cookie.png Err z3bra.org 70 i- "AFE502310D1EE1494770A46DEEED25CABB4B0CA70EFD0571C249C6BAA3728B46", // onion.png + zip Err z3bra.org 70 i- "AC899E9F52E7194933E64D26800A609A83FF01826347FEA5ECDB2E420CAF1F43", // cream.png Err z3bra.org 70 i- "8CB250A66D4301244699186CA723E11AFA806C64466789AB14B7027A2F928BF8", // egg.png Err z3bra.org 70 i- "F6A4071C9C0DDCCB53FC1CDCA38E32CF10551F75AA48996A9341842A7EF2591B"} // salt.png Err z3bra.org 70 i+ //"AFE502310D1EE1494770A46DEEED25CABB4B0CA70EFD0571C249C6BAA3728B46", // onion.png + zip Err z3bra.org 70 i+ //"AC899E9F52E7194933E64D26800A609A83FF01826347FEA5ECDB2E420CAF1F43", // cream.png 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 Err z3bra.org 70 i var cyboard = Application{ Err z3bra.org 70 it@@ -88,18 +84,57 @@ func pageFlag() tview.Primitive { Err z3bra.org 70 i return matched Err z3bra.org 70 i }) Err z3bra.org 70 i input.SetDoneFunc(func(key tcell.Key) { Err z3bra.org 70 i- switch flagid(input.GetText()) { Err z3bra.org 70 i- case 0,1,2,3,4: Err z3bra.org 70 i+ if cyboard.flag == 1 { Err z3bra.org 70 i cyboard.pages.SwitchToPage("score") Err z3bra.org 70 i- default: Err z3bra.org 70 i- cyboard.app.Stop() Err z3bra.org 70 i- fmt.Println("Incorrect flag") Err z3bra.org 70 i } Err z3bra.org 70 i }) Err z3bra.org 70 i Err z3bra.org 70 i return center(40, 1, input) Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i+func pageToken() tview.Primitive { Err z3bra.org 70 i+ input := tview.NewInputField(). Err z3bra.org 70 i+ SetLabel("TOKEN "). Err z3bra.org 70 i+ SetPlaceholder(""). Err z3bra.org 70 i+ SetFieldStyle(tcell.StyleDefault.Reverse(true)). Err z3bra.org 70 i+ SetFieldWidth(28) Err z3bra.org 70 i+ Err z3bra.org 70 i+ input.SetAcceptanceFunc(func(text string, ch rune) bool { Err z3bra.org 70 i+ matched, err := regexp.Match(`^[a-zA-Z0-9]+$`, []byte(text)) 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+ return matched Err z3bra.org 70 i+ }) Err z3bra.org 70 i+ input.SetDoneFunc(func(key tcell.Key) { Err z3bra.org 70 i+ _, err := cyboard.player.FromToken(input.GetText()) Err z3bra.org 70 i+ if err != nil { Err z3bra.org 70 i+ cyboard.Popup("Error", "Invalid Token") Err z3bra.org 70 i+ return Err z3bra.org 70 i+ } Err z3bra.org 70 i+ Err z3bra.org 70 i+ if cyboard.player.flag >= cyboard.flag { Err z3bra.org 70 i+ cyboard.Popup("Error", "Flag already submitted") Err z3bra.org 70 i+ return Err z3bra.org 70 i+ } Err z3bra.org 70 i+ Err z3bra.org 70 i+ cyboard.player.ts = time.Now().Unix() Err z3bra.org 70 i+ cyboard.player.flag = cyboard.flag Err z3bra.org 70 i+ cyboard.player.score += 100 Err z3bra.org 70 i+ Err z3bra.org 70 i+ n := cyboard.player.FlagRank() Err z3bra.org 70 i+ if n < 10 { Err z3bra.org 70 i+ cyboard.player.score += 10 - n Err z3bra.org 70 i+ } Err z3bra.org 70 i+ Err z3bra.org 70 i+ cyboard.player.Update() Err z3bra.org 70 i+ cyboard.HighlightBoard(cyboard.player.ScoreRank()) Err z3bra.org 70 i+ cyboard.pages.SwitchToPage("board") Err z3bra.org 70 i+ }) Err z3bra.org 70 i+ Err z3bra.org 70 i+ return center(40, 1, input) Err z3bra.org 70 i+} Err z3bra.org 70 i+ Err z3bra.org 70 i func pageBoard() tview.Primitive { Err z3bra.org 70 i cyboard.SetupFrame() Err z3bra.org 70 i cyboard.DrawBoard() Err z3bra.org 70 it@@ -108,6 +143,7 @@ func pageBoard() tview.Primitive { Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i func main() { Err z3bra.org 70 i+ var err error Err z3bra.org 70 i cmd := "board" Err z3bra.org 70 i Err z3bra.org 70 i flag.Parse() Err z3bra.org 70 it@@ -131,12 +167,17 @@ func main() { Err z3bra.org 70 i tview.Styles.GraphicsColor = tcell.ColorDefault Err z3bra.org 70 i tview.Styles.PrimaryTextColor = tcell.ColorDefault Err z3bra.org 70 i Err z3bra.org 70 i- cyboard.db_init(DB) Err z3bra.org 70 i+ cyboard.db, err = db_init(DB) 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+ cyboard.player.db = cyboard.db Err z3bra.org 70 i defer cyboard.db.Close() Err z3bra.org 70 i Err z3bra.org 70 i cyboard.pages.SetBackgroundColor(tcell.ColorDefault) Err z3bra.org 70 i Err z3bra.org 70 i cyboard.pages.AddPage("flag", pageFlag(), true, false) Err z3bra.org 70 i+ cyboard.pages.AddPage("token", pageToken(), true, false) Err z3bra.org 70 i cyboard.pages.AddPage("board", pageBoard(), true, false) Err z3bra.org 70 i Err z3bra.org 70 i switch cmd { Err z3bra.org 70 it@@ -144,24 +185,24 @@ func main() { Err z3bra.org 70 i if (len(args) < 2) { Err z3bra.org 70 i usage() Err z3bra.org 70 i } Err z3bra.org 70 i- switch flagid(args[1]) { Err z3bra.org 70 i- case 0: Err z3bra.org 70 i- cyboard.player.flags = 1 Err z3bra.org 70 i+ switch cyboard.flag = flagid(args[1]) + 1; cyboard.flag { Err z3bra.org 70 i+ case 1: Err z3bra.org 70 i+ cyboard.player.flag = cyboard.flag Err z3bra.org 70 i cyboard.player.score = 100 Err z3bra.org 70 i cyboard.player.ts = time.Now().Unix() Err z3bra.org 70 i Err z3bra.org 70 i /* Bonus points for the first 10 players to get first flag */ Err z3bra.org 70 i- n := cyboard.db_count_flag(1) Err z3bra.org 70 i+ n := cyboard.player.FlagRank() Err z3bra.org 70 i if n < 10 { Err z3bra.org 70 i cyboard.player.score += 10 - n Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i- rank := cyboard.db_rank(cyboard.player.score, cyboard.player.ts) Err z3bra.org 70 i+ rank := cyboard.player.ScoreRank() + 1 Err z3bra.org 70 i Err z3bra.org 70 i cyboard.NewPlayer(rank) Err z3bra.org 70 i cyboard.pages.SwitchToPage("board") Err z3bra.org 70 i- //case 1,2,3,4: Err z3bra.org 70 i- // pages.ShowPage("token") Err z3bra.org 70 i+ case 2,3,4,5: Err z3bra.org 70 i+ cyboard.pages.ShowPage("token") Err z3bra.org 70 i default: Err z3bra.org 70 i fmt.Println("Incorrect flag") Err z3bra.org 70 i } Err z3bra.org 70 1diff --git a/mkfile b/mkfile /scm/scoreboard/file/mkfile.gph z3bra.org 70 it@@ -1,4 +1,5 @@ Err z3bra.org 70 i GO = go Err z3bra.org 70 i+SRC = `{find . -name '*.go'} Err z3bra.org 70 i Err z3bra.org 70 i-scoreboard: main.go db.go playerbox.go util.go ui.go Err z3bra.org 70 i+scoreboard: ${SRC} Err z3bra.org 70 i ${GO} build Err z3bra.org 70 1diff --git a/playerbox.go b/playerbox.go /scm/scoreboard/file/playerbox.go.gph z3bra.org 70 it@@ -46,7 +46,7 @@ func manipulatebox(event *tcell.EventKey) *tcell.EventKey { Err z3bra.org 70 i } Err z3bra.org 70 i case tcell.KeyUp: Err z3bra.org 70 i playerbox.char[playerbox.cur]++ Err z3bra.org 70 i- if playerbox.char[playerbox.cur] > len(charlist) { Err z3bra.org 70 i+ if playerbox.char[playerbox.cur] >= len(charlist) { Err z3bra.org 70 i playerbox.char[playerbox.cur] = 0 Err z3bra.org 70 i } Err z3bra.org 70 i case tcell.KeyDown: Err z3bra.org 70 it@@ -70,8 +70,8 @@ func PlayerBoxName(p Player) *tview.TextView { Err z3bra.org 70 i SetDoneFunc(func(key tcell.Key) { Err z3bra.org 70 i if key == tcell.KeyEnter { Err z3bra.org 70 i p.name = fmt.Sprintf("%3s", playerbox.name) Err z3bra.org 70 i- if cyboard.db_checkname(p.name) == false { Err z3bra.org 70 i- cyboard.db_save(p) Err z3bra.org 70 i+ if ! p.Exists() { Err z3bra.org 70 i+ p.Register() Err z3bra.org 70 i cyboard.DrawBoard() Err z3bra.org 70 i } else { Err z3bra.org 70 i cyboard.Popup("Error", "Name already registered\nPlease pick another one") Err z3bra.org 70 it@@ -109,7 +109,7 @@ func PlayerBoxGrid(p Player, rank int) *tview.Grid { Err z3bra.org 70 i SetRows(1). Err z3bra.org 70 i AddItem(gridcell(rankstr), 0, 0, 1, 1, 0, 0, false). Err z3bra.org 70 i AddItem(box, 0, 1, 1, 1, 0, 0, true). Err z3bra.org 70 i- AddItem(gridcell(flag2str(p.flags)), 0, 2, 1, 1, 0, 0, false). Err z3bra.org 70 i+ AddItem(gridcell(flag2str(p.flag)), 0, 2, 1, 1, 0, 0, false). Err z3bra.org 70 i AddItem(playerbox.score, 0, 3, 1, 1, 0, 0, false) Err z3bra.org 70 i Err z3bra.org 70 i return grid Err z3bra.org 70 1diff --git a/ui.go b/ui.go /scm/scoreboard/file/ui.go.gph z3bra.org 70 it@@ -17,10 +17,7 @@ func BoardHeader() *tview.TextView { Err z3bra.org 70 i Err z3bra.org 70 i func RankTable(offset, limit, rank int, fill bool) *tview.Table { Err z3bra.org 70 i t := tview.NewTable() Err z3bra.org 70 i- if limit < 0 { Err z3bra.org 70 i- limit = cyboard.db_count() Err z3bra.org 70 i- } Err z3bra.org 70 i- players, err := cyboard.db_ranked(offset, limit) Err z3bra.org 70 i+ players, err := db_ranked_players(cyboard.db, 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 it@@ -31,7 +28,7 @@ func RankTable(offset, limit, rank int, fill bool) *tview.Table { 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 + 1)) Err z3bra.org 70 i- flagstr := flag2str(p.flags) Err z3bra.org 70 i+ flagstr := flag2str(p.flag) 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 it@@ -72,6 +69,12 @@ func (a *Application) DrawBoard() { Err z3bra.org 70 i AddItem(RankTable(0, -1, 0, true), BOARD_HEIGHT, 1, true) Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i+func (a *Application) HighlightBoard(line int) { Err z3bra.org 70 i+ cyboard.board.Clear(). Err z3bra.org 70 i+ SetDirection(tview.FlexRow). Err z3bra.org 70 i+ AddItem(RankTable(0, -1, 0, true).Select(line - 1, 0), BOARD_HEIGHT, 1, true) 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 i t1 := RankTable(0, BOARD_HEIGHT, 0, false).SetSelectable(false, false) Err z3bra.org 70 i t2 := RankTable(rank - 1, BOARD_HEIGHT, rank, true).SetSelectable(false, false) Err z3bra.org 70 .