Add persistent player leaderboards from game telemetry
This commit is contained in:
@@ -5,6 +5,7 @@ import { config } from '../config.js';
|
||||
import schemaSql from './schema.sql?raw';
|
||||
import { requirement, type BetaPlan, type BetaRequirement } from '../../beta-plan.js';
|
||||
import { emptyMetrics } from '../fleet/beta-evaluation.js';
|
||||
import { backfillLeaderboard } from '../fleet/leaderboard-ingest.js';
|
||||
|
||||
let _db: Database.Database | null = null;
|
||||
|
||||
@@ -259,6 +260,7 @@ export function db(): Database.Database {
|
||||
backfillMultiScriptJoins(handle);
|
||||
assertSnapshotSchemeSafe(handle);
|
||||
migrateGameTelemetry(handle);
|
||||
backfillLeaderboard(handle);
|
||||
} catch (err) {
|
||||
handle.close();
|
||||
throw err;
|
||||
|
||||
@@ -6,6 +6,56 @@
|
||||
PRAGMA journal_mode = WAL;
|
||||
PRAGMA foreign_keys = ON;
|
||||
|
||||
-- Historical gameplay deliberately has no FK to servers: destroying a server
|
||||
-- must not erase records. Each player's counters are high-water marks per match.
|
||||
CREATE TABLE IF NOT EXISTS leaderboard_matches (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
server TEXT NOT NULL,
|
||||
game TEXT NOT NULL,
|
||||
map TEXT NOT NULL,
|
||||
map_key TEXT NOT NULL,
|
||||
map_name TEXT NOT NULL,
|
||||
started_at TEXT NOT NULL,
|
||||
ended_at TEXT,
|
||||
last_received_at TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active', -- active | completed | interrupted
|
||||
start_observed INTEGER NOT NULL DEFAULT 0,
|
||||
highest_round INTEGER NOT NULL DEFAULT 0,
|
||||
last_event TEXT NOT NULL,
|
||||
last_fingerprint TEXT NOT NULL
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_leaderboard_server ON leaderboard_matches(server, id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_leaderboard_map ON leaderboard_matches(game, map_key);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS leaderboard_players (
|
||||
game TEXT NOT NULL,
|
||||
guid TEXT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
first_seen_at TEXT NOT NULL,
|
||||
last_seen_at TEXT NOT NULL,
|
||||
PRIMARY KEY (game, guid)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS leaderboard_match_players (
|
||||
match_id INTEGER NOT NULL REFERENCES leaderboard_matches(id) ON DELETE CASCADE,
|
||||
guid TEXT NOT NULL,
|
||||
highest_round INTEGER NOT NULL DEFAULT 0,
|
||||
rounds_survived INTEGER NOT NULL DEFAULT 0,
|
||||
kills INTEGER NOT NULL DEFAULT 0,
|
||||
headshots INTEGER NOT NULL DEFAULT 0,
|
||||
downs INTEGER NOT NULL DEFAULT 0,
|
||||
revives INTEGER NOT NULL DEFAULT 0,
|
||||
best_score INTEGER NOT NULL DEFAULT 0,
|
||||
last_round INTEGER NOT NULL DEFAULT 0,
|
||||
present INTEGER NOT NULL DEFAULT 1,
|
||||
has_stats INTEGER NOT NULL DEFAULT 0,
|
||||
completed INTEGER NOT NULL DEFAULT 0,
|
||||
first_seen_at TEXT NOT NULL,
|
||||
last_seen_at TEXT NOT NULL,
|
||||
PRIMARY KEY (match_id, guid)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_leaderboard_player_matches ON leaderboard_match_players(guid, match_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS servers (
|
||||
name TEXT PRIMARY KEY,
|
||||
komodo_type TEXT NOT NULL DEFAULT 'deployment', -- deployment|stack|container
|
||||
|
||||
Reference in New Issue
Block a user