tAdd login key in app to show personal badge collection - scoreboard - Interactive scoreboard for CTF-like games
(HTM) git clone git://git.z3bra.org/scoreboard.git
(DIR) Log
(DIR) Files
(DIR) Refs
---
(DIR) commit cb97cb5f224a91c0f4b47db43fae0f37f6e1a079
(DIR) parent f77371dc092804946f8d32c60dbdf1a10b9516da
(HTM) Author: Willy Goiffon <contact@z3bra.org>
Date: Fri, 27 Sep 2024 18:08:23 +0200
Add login key in app to show personal badge collection
Diffstat:
M main.go | 28 +++++++++++-----------------
M player.go | 8 ++++++--
M ui.go | 40 +++++++++++++++++++++++++-------
3 files changed, 49 insertions(+), 27 deletions(-)
---
(DIR) diff --git a/main.go b/main.go
t@@ -120,7 +120,13 @@ func main() {
scoreboard.app = tview.NewApplication()
scoreboard.pages = tview.NewPages()
scoreboard.board = tview.NewFlex()
- scoreboard.player = &Player{ db: scoreboard.db }
+ scoreboard.player = &Player{
+ db: scoreboard.db,
+ flag: 0,
+ score: 0,
+ ts: time.Now().Unix(),
+ token: "",
+ }
scoreboard.pages.SetBackgroundColor(tcell.ColorDefault)
t@@ -145,22 +151,11 @@ func main() {
os.Exit(0)
case "register":
- scoreboard.player.flag = 0
- scoreboard.player.score = 0
- scoreboard.player.ts = time.Now().Unix()
-
rank, _ := db_count_players(scoreboard.db)
scoreboard.NewPlayer(rank + 1)
scoreboard.pages.SwitchToPage("board")
reminder = true
- case "badges":
- badgepage := scoreboard.Token(func () {
- scoreboard.app.Stop()
- fmt.Printf("Collection: %d/%d\n\n%s", scoreboard.player.flag, len(scoreboard.flag_ref), scoreboard.player.BadgeStr())
- })
- scoreboard.pages.AddAndSwitchToPage("badge", badgepage, true)
-
/* anything not a command is treated as a flag */
default:
scoreboard.flag, err = db_get_flag(scoreboard.db, args[0])
t@@ -169,19 +164,18 @@ func main() {
return
}
- submitpage := scoreboard.Token(func () {
+ page := scoreboard.Token(func () {
err = scoreboard.player.Submit(scoreboard.flag)
if err != nil {
scoreboard.Fatal(err)
return
}
scoreboard.HighlightBoard(scoreboard.player.ScoreRank() + 1)
- scoreboard.pages.RemovePage("submit")
- scoreboard.pages.ShowPage("board")
+ scoreboard.pages.RemovePage("token")
scoreboard.GenerateHTML()
})
- scoreboard.pages.AddAndSwitchToPage("submit", submitpage, true)
+ scoreboard.pages.AddAndSwitchToPage("token", page, true)
}
}
t@@ -192,7 +186,7 @@ func main() {
}
/* Print a token reminder on exit in case one has been generated or provided */
- if reminder {
+ if reminder && scoreboard.player.token != "" {
fmt.Printf(TOKEN_REMINDER, scoreboard.player.name, scoreboard.player.token)
}
}
(DIR) diff --git a/player.go b/player.go
t@@ -147,7 +147,7 @@ func (p *Player) FlagStr() string {
return fmt.Sprintf("%2d/%d", p.flag, len(scoreboard.flag_ref))
}
-func (p *Player) BadgeStr() string {
+func (p *Player) BadgeStr(full bool) string {
var badges strings.Builder
query := `SELECT
t@@ -168,7 +168,11 @@ func (p *Player) BadgeStr() string {
if err != nil {
return ""
}
- badges.WriteString(fmt.Sprintf("%s %s (%d pts)\n", b, v, s))
+ if full {
+ badges.WriteString(fmt.Sprintf("%s %s\n", b, v))
+ } else {
+ badges.WriteString(b)
+ }
}
return badges.String();
(DIR) diff --git a/ui.go b/ui.go
t@@ -58,6 +58,19 @@ func RankTable(offset, limit, rank int, fill bool) *tview.Table {
t.SetCell(i, 3, newcell(scorestr))
}
+ t.SetSelectedFunc(func (row, col int) {
+ var player Player
+ col = 1
+ player.name = t.GetCell(row, col).Text
+ player.db = scoreboard.db
+ player.Fetch()
+ if scoreboard.player.name == player.name {
+ scoreboard.Message(player.name, player.BadgeStr(true))
+ } else {
+ scoreboard.Popup(player.name, player.BadgeStr(false))
+ }
+ })
+
if fill == true {
bsize := int(math.Max(float64(BOARD_HEIGHT), float64(limit)))
for i:=t.GetRowCount(); i<bsize; i++ {
t@@ -85,6 +98,7 @@ func (a *Application) SetupFrame() {
grid.AddItem(a.board, 1, 0, 1, 1, BOARD_HEIGHT, BOARD_WIDTH, true)
a.frame = tview.NewFrame(grid)
+ a.frame.AddText(fmt.Sprintf("press 'l' to login"), false, tview.AlignCenter, 0)
}
func (a *Application) DrawBoard() {
t@@ -98,6 +112,13 @@ func (a *Application) DrawBoard() {
a.app.Stop()
return nil
}
+ if event.Rune() == 'l' && a.player.token == "" {
+ page := a.Token(func () {
+ a.pages.RemovePage("token")
+ a.HighlightBoard(a.player.ScoreRank() + 1)
+ })
+ a.pages.AddAndSwitchToPage("token", page, true)
+ }
return event
})
}
t@@ -108,7 +129,8 @@ func (a *Application) HighlightBoard(line int) {
AddItem(RankTable(0, -1, 0, true).Select(line - 1, 0), BOARD_HEIGHT, 1, true)
a.app.SetFocus(a.board)
- a.frame.AddText(fmt.Sprintf(" 🔑%s", a.player.token), false, tview.AlignCenter, 0)
+ a.frame.Clear()
+ a.frame.AddText(fmt.Sprintf("🔑%s", a.player.token), false, tview.AlignCenter, 0)
}
func (a *Application) NewPlayer(rank int) {
t@@ -150,7 +172,7 @@ func popup(title, text string, w, h int, callback func(key tcell.Key)) tview.Pri
}
func (a *Application) Message(title, text string) {
- p := popup(title, text, 64, 19, func(key tcell.Key) {
+ p := popup(title, text, 72, 19, func(key tcell.Key) {
a.pages.RemovePage("popup")
})
t@@ -200,18 +222,20 @@ func (a *Application) Token(callback func()) tview.Primitive {
token := input.GetText()
if len(token) != 24 {
- scoreboard.Popup("ERROR", "Invalid token format")
+ a.Popup("ERROR", "Invalid token format")
return
}
- err := scoreboard.player.FromToken(token)
+ err := a.player.FromToken(token)
if err != nil {
- scoreboard.Fatal(err)
+ a.Fatal(err)
return
}
- scoreboard.player.token = token;
- scoreboard.player.Fetch()
- scoreboard.pages.RemovePage("token");
+ a.player.Fetch()
+ a.player.token = token;
+ a.pages.RemovePage("token");
+ a.frame.Clear()
+ a.frame.AddText(fmt.Sprintf("🔑%s", a.player.token), false, tview.AlignCenter, 0)
callback()
})