Add persistent match history to server pages
This commit is contained in:
@@ -260,6 +260,7 @@ export function db(): Database.Database {
|
||||
backfillMultiScriptJoins(handle);
|
||||
assertSnapshotSchemeSafe(handle);
|
||||
migrateGameTelemetry(handle);
|
||||
migrateTable(handle, 'leaderboard_matches', [{ name: 'start_players', ddl: 'ALTER TABLE leaderboard_matches ADD COLUMN start_players INTEGER' }]);
|
||||
backfillLeaderboard(handle);
|
||||
} catch (err) {
|
||||
handle.close();
|
||||
|
||||
@@ -20,6 +20,7 @@ CREATE TABLE IF NOT EXISTS leaderboard_matches (
|
||||
last_received_at TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active', -- active | completed | interrupted
|
||||
start_observed INTEGER NOT NULL DEFAULT 0,
|
||||
start_players INTEGER,
|
||||
highest_round INTEGER NOT NULL DEFAULT 0,
|
||||
last_event TEXT NOT NULL,
|
||||
last_fingerprint TEXT NOT NULL
|
||||
|
||||
@@ -77,6 +77,11 @@ export function recordLeaderboardTelemetry(handle: Database.Database, report: Ga
|
||||
}
|
||||
if (!match) return;
|
||||
|
||||
if (isStart) {
|
||||
handle.prepare('UPDATE leaderboard_matches SET start_players = COALESCE(start_players, ?) WHERE id = ?')
|
||||
.run(report.players.length, match.id);
|
||||
}
|
||||
|
||||
const previous = new Map((handle.prepare('SELECT guid, last_round, present FROM leaderboard_match_players WHERE match_id = ?')
|
||||
.all(match.id) as Participation[]).map(player => [player.guid, player]));
|
||||
handle.prepare('UPDATE leaderboard_match_players SET present = 0 WHERE match_id = ?').run(match.id);
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import { db } from '../db/index.js';
|
||||
import type { ServerMatch } from '../../match-history.js';
|
||||
|
||||
export function serverMatchHistory(server: string, limit = 25): { matches: ServerMatch[]; total: number } {
|
||||
const handle = db();
|
||||
const total = (handle.prepare('SELECT COUNT(*) AS total FROM leaderboard_matches WHERE server = ?').get(server) as { total: number }).total;
|
||||
const matches = handle.prepare(`SELECT m.id, m.map_name AS map, m.started_at AS startedAt, m.status,
|
||||
m.start_players AS startPlayers,
|
||||
(SELECT COUNT(*) FROM leaderboard_match_players p WHERE p.match_id = m.id) AS uniquePlayers,
|
||||
CASE WHEN m.status = 'completed' THEN
|
||||
(SELECT COUNT(*) FROM leaderboard_match_players p WHERE p.match_id = m.id AND p.present = 1)
|
||||
END AS endPlayers,
|
||||
CASE WHEN m.status = 'completed' AND m.start_observed = 1 THEN
|
||||
MAX(0, ROUND((julianday(m.ended_at) - julianday(m.started_at)) * 86400000)) END AS durationMs,
|
||||
CASE WHEN m.status = 'completed' THEN m.highest_round END AS finalRound
|
||||
FROM leaderboard_matches m WHERE m.server = ? ORDER BY m.id DESC LIMIT ?`)
|
||||
.all(server, limit) as ServerMatch[];
|
||||
return { matches, total };
|
||||
}
|
||||
Reference in New Issue
Block a user