Playtime stats between players only; no ping; page-wide grid

K/D, headshot %, kills and deaths (drawer, Top players, staff session
lists) now come from pt_events, so kills of bots and deaths to bots don't
count, as in Records; damage per round and MVPs are gone, since only the
game's counters have them and those include bots. Average ping and the
record count footnote are no longer shown. The server header's grid now
runs behind the whole page.
This commit is contained in:
Astra 2026-10-04 22:41:12 +01:00
parent c7fbff0e43
commit 2516759fa9
6 changed files with 120 additions and 81 deletions

View file

@ -116,18 +116,20 @@ func TestPlaytimeDB(t *testing.T) {
// Events: Alpha plants twice (once 10 days ago), defuses once and knifes a player and a bot;
// Bravo gets a Zeus kill and a headshot.
event := func(id uint64, kind int, at time.Time, weapon any, hs any, bot any) {
// Kills say who died (nil for a bot) and the killer's session.
event := func(id uint64, sess string, kind int, at time.Time, weapon any, hs any, victim any, bot any) {
t.Helper()
exec(`INSERT INTO pt_events (event_key, server_id, steamid64, kind, at, map, team, weapon, headshot, victim_bot)
VALUES (REPLACE(UUID(), '-', ''), 1, ?, ?, ?, 'de_mirage', 2, ?, ?, ?)`, id, kind, at, weapon, hs, bot)
exec(`INSERT INTO pt_events (event_key, server_id, session_key, steamid64, kind, at, map, team, weapon, headshot,
victim_steamid64, victim_bot)
VALUES (REPLACE(UUID(), '-', ''), 1, NULLIF(?, ''), ?, ?, ?, 'de_mirage', 2, ?, ?, ?, ?)`, sess, id, kind, at, weapon, hs, victim, bot)
}
event(a, EventPlanted, ago(2*time.Hour), nil, nil, nil)
event(a, EventPlanted, ago(10*24*time.Hour), nil, nil, nil)
event(a, EventDefused, ago(2*time.Hour), nil, nil, nil)
event(a, EventKill, ago(2*time.Hour), "knife_karambit", 0, 0)
event(a, EventKill, ago(2*time.Hour), "knife", 1, 1) // a bot: doesn't count, not even as a headshot
event(b, EventKill, ago(20*time.Minute), "taser", 0, 0)
event(b, EventKill, ago(20*time.Minute), "ak47", 1, 0)
event(a, "", EventPlanted, ago(10*24*time.Hour), nil, nil, nil, nil)
event(a, "a1", EventPlanted, ago(2*time.Hour), nil, nil, nil, nil)
event(a, "a1", EventDefused, ago(2*time.Hour), nil, nil, nil, nil)
event(a, "a1", EventKill, ago(2*time.Hour), "knife_karambit", 0, b, 0)
event(a, "a1", EventKill, ago(2*time.Hour), "knife", 1, nil, 1) // a bot: doesn't count, not even as a headshot
event(b, "b2", EventKill, ago(20*time.Minute), "taser", 0, a, 0)
event(b, "b2", EventKill, ago(20*time.Minute), "ak47", 1, a, 0)
if ok, data, err := st.State(ctx); err != nil || !ok || !data || !st.HasEvents() {
t.Fatalf("State with data: %v, %v, %v (events %v)", ok, data, err, st.HasEvents())
@ -194,13 +196,13 @@ func TestPlaytimeDB(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if len(leaders) != 1 || leaders[0].Name != "Alpha" || leaders[0].T != 1 || leaders[0].CT != 0.5 || leaders[0].Kills != 10 || leaders[0].Deaths != 5 {
if len(leaders) != 1 || leaders[0].Name != "Alpha" || leaders[0].T != 1 || leaders[0].CT != 0.5 || leaders[0].Kills != 1 || leaders[0].Deaths != 2 {
t.Fatalf("leaders this week %+v", leaders)
}
if leaders, err = st.Leaders(ctx, nil, 10); err != nil {
t.Fatal(err)
}
if len(leaders) != 2 || leaders[0].Name != "Bravo" || leaders[0].Kills != 3 {
if len(leaders) != 2 || leaders[0].Name != "Bravo" || leaders[0].Kills != 2 || leaders[0].Deaths != 1 {
t.Fatalf("leaders all time %+v", leaders)
}
@ -212,19 +214,23 @@ func TestPlaytimeDB(t *testing.T) {
for _, d := range p.Days {
days += d.Hours
}
if p.T != 1 || p.CT != 0.5 || p.Spec != 0.5 || p.Stats.Kills != 10 || p.Stats.Rounds != 10 || days != 1.5 || len(p.Maps) != 1 {
if p.T != 1 || p.CT != 0.5 || p.Spec != 0.5 || p.Stats == nil || *p.Stats != (Stats{Kills: 1, Deaths: 2}) || days != 1.5 || len(p.Maps) != 1 {
t.Fatalf("player %+v, %.1f h in days", p, days)
}
if p, err := st.Player(ctx, 76561198000009999, now, london); err != nil || p != nil {
t.Fatalf("unknown player: %v, %v", p, err)
}
ps, err := st.PlayerStaff(ctx, a, now)
ps, err := st.PlayerStaff(ctx, a)
if err != nil {
t.Fatal(err)
}
// Alpha's knife kill was in a1; Bravo killed Alpha twice, but after a1 ended.
if r := ps.Recent; len(r) != 1 || r[0].Kills == nil || *r[0].Kills != 1 || r[0].Deaths == nil || *r[0].Deaths != 0 {
t.Fatalf("recent session kills and deaths %+v", ps.Recent)
}
if len(ps.Names) != 2 || ps.Names[0].Name != "Alpha" || len(ps.Recent) != 1 || ps.Recent[0].Seconds != 7200 ||
ps.Recent[0].Reason != "NETWORK_DISCONNECT_DISCONNECT_BY_USER" || ps.Country != "GB" || ps.City != "London" || ps.Ping == nil || *ps.Ping != 20 {
ps.Recent[0].Reason != "NETWORK_DISCONNECT_DISCONNECT_BY_USER" || ps.Country != "GB" || ps.City != "London" {
t.Fatalf("staff %+v", ps)
}