Add community map records and telemetry API; record Workshop 0.0.126
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
CREATE TABLE servers (
|
||||
server_id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
token_hash TEXT NOT NULL,
|
||||
active INTEGER NOT NULL DEFAULT 1 CHECK (active IN (0, 1)),
|
||||
created_at INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE events (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
server_id TEXT NOT NULL REFERENCES servers(server_id),
|
||||
event_id TEXT NOT NULL,
|
||||
mission_id TEXT NOT NULL,
|
||||
received_at INTEGER NOT NULL,
|
||||
payload_hash TEXT NOT NULL,
|
||||
payload TEXT NOT NULL CHECK (json_valid(payload)),
|
||||
UNIQUE (server_id, event_id)
|
||||
);
|
||||
CREATE INDEX events_mission ON events(server_id, mission_id, id);
|
||||
|
||||
CREATE TABLE missions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
server_id TEXT NOT NULL REFERENCES servers(server_id),
|
||||
mission_id TEXT NOT NULL,
|
||||
event_id TEXT NOT NULL,
|
||||
terminal INTEGER NOT NULL,
|
||||
outcome TEXT NOT NULL,
|
||||
elapsed_seconds INTEGER NOT NULL,
|
||||
occurred_at INTEGER NOT NULL,
|
||||
received_at INTEGER NOT NULL,
|
||||
partial INTEGER NOT NULL,
|
||||
peak_players INTEGER NOT NULL,
|
||||
dropped_events INTEGER NOT NULL,
|
||||
payload TEXT NOT NULL,
|
||||
UNIQUE (server_id, mission_id)
|
||||
);
|
||||
CREATE INDEX missions_server_page ON missions(server_id, id DESC);
|
||||
CREATE INDEX missions_outcome ON missions(outcome, server_id);
|
||||
|
||||
-- An event and its mission projection commit together. Duplicate inserts never
|
||||
-- fire this trigger. First terminal snapshot wins; late starts/heartbeats cannot
|
||||
-- reopen a mission. Elapsed mission time takes precedence over wall-clock skew.
|
||||
CREATE TRIGGER project_mission AFTER INSERT ON events BEGIN
|
||||
INSERT INTO missions (
|
||||
server_id, mission_id, event_id, terminal, outcome, elapsed_seconds,
|
||||
occurred_at, received_at, partial, peak_players, dropped_events, payload
|
||||
) VALUES (
|
||||
NEW.server_id, NEW.mission_id, NEW.event_id,
|
||||
json_extract(NEW.payload, '$.type') = 'mission_finished',
|
||||
json_extract(NEW.payload, '$.outcome'),
|
||||
json_extract(NEW.payload, '$.elapsedSeconds'),
|
||||
json_extract(NEW.payload, '$.occurredAt'), NEW.received_at,
|
||||
json_extract(NEW.payload, '$.partial'), json_extract(NEW.payload, '$.peakPlayers'),
|
||||
json_extract(NEW.payload, '$.droppedEvents'), NEW.payload
|
||||
) ON CONFLICT(server_id, mission_id) DO UPDATE SET
|
||||
event_id = excluded.event_id, terminal = excluded.terminal,
|
||||
outcome = excluded.outcome, elapsed_seconds = excluded.elapsed_seconds,
|
||||
occurred_at = excluded.occurred_at, received_at = excluded.received_at,
|
||||
partial = MAX(missions.partial, excluded.partial),
|
||||
peak_players = MAX(missions.peak_players, excluded.peak_players),
|
||||
dropped_events = MAX(missions.dropped_events, excluded.dropped_events),
|
||||
payload = excluded.payload
|
||||
WHERE missions.terminal = 0 AND (
|
||||
excluded.terminal = 1 OR excluded.elapsed_seconds > missions.elapsed_seconds OR
|
||||
(excluded.elapsed_seconds = missions.elapsed_seconds AND excluded.occurred_at >= missions.occurred_at)
|
||||
);
|
||||
END;
|
||||
|
||||
-- Final snapshots alone feed rankings: spectator and temporary connection IDs
|
||||
-- never become global player records. Missing legacy counters remain NULL.
|
||||
CREATE VIEW final_players AS
|
||||
SELECT m.server_id, m.mission_id, m.outcome, m.elapsed_seconds,
|
||||
m.partial, json_extract(m.payload, '$.playersTruncated') AS players_truncated,
|
||||
json_extract(p.value, '$.id') AS player_id,
|
||||
json_extract(p.value, '$.name') AS name,
|
||||
json_extract(p.value, '$.escaped') AS escaped,
|
||||
json_extract(p.value, '$.connected') AS connected,
|
||||
json_extract(p.value, '$.connectedSeconds') AS connected_seconds,
|
||||
json_extract(p.value, '$.kills') AS kills,
|
||||
json_extract(p.value, '$.friendlyKills') AS friendly_kills,
|
||||
json_extract(p.value, '$.deaths') AS deaths,
|
||||
json_extract(p.value, '$.downed') AS downed,
|
||||
json_extract(p.value, '$.recoveries') AS recoveries
|
||||
FROM missions m, json_each(m.payload, '$.players') p
|
||||
WHERE m.terminal = 1 AND m.outcome IN ('victory', 'defeat')
|
||||
AND json_extract(p.value, '$.authenticated') = 1
|
||||
AND json_extract(p.value, '$.participated') = 1;
|
||||
@@ -0,0 +1,3 @@
|
||||
-- Preserve existing operator-managed credentials and label public enrollment.
|
||||
ALTER TABLE servers ADD COLUMN registration TEXT NOT NULL DEFAULT 'managed'
|
||||
CHECK (registration IN ('managed', 'automatic'));
|
||||
Reference in New Issue
Block a user