Fix keyed telemetry match attribution (Refs #144)
CI / checks (push) Successful in 5m26s

This commit is contained in:
2026-10-12 00:58:05 -04:00
parent 4ea291d305
commit 785cc4616b
24 changed files with 1115 additions and 112 deletions
+7 -5
View File
@@ -2,7 +2,7 @@ import { jsonBody } from '$lib/server/request-body.js';
import { isHttpError, json } from '@sveltejs/kit';
import { parseGameEvent, type GameTelemetry } from '$lib/telemetry.js';
import { getServer } from '$lib/server/fleet/servers.js';
import { saveTelemetry } from '$lib/server/fleet/telemetry.js';
import { saveTelemetryWithOutcome } from '$lib/server/fleet/telemetry.js';
import { recordTelemetryRequest } from '$lib/server/fleet/telemetry-requests.js';
import { recordGameEvent } from '$lib/server/fleet/beta-tests.js';
import { db } from '$lib/server/db/index.js';
@@ -60,11 +60,13 @@ export async function POST({ request }: { request: Request }) {
const server = getServer(telemetry.server);
if (!server || server.destroyed_at)
return reject(404, 'Server is not registered or has been destroyed');
db().transaction(() => {
telemetry = saveTelemetry(telemetry);
recordGameEvent(telemetry);
const current = db().transaction(() => {
const saved = saveTelemetryWithOutcome(telemetry);
telemetry = saved.telemetry;
if (saved.current) recordGameEvent(telemetry);
return saved.current;
})();
emit({ type: 'server-telemetry', entries: [telemetry] });
if (current) emit({ type: 'server-telemetry', entries: [telemetry] });
} catch (error) {
console.error('Could not process telemetry', error);
log(
+7 -6
View File
@@ -605,12 +605,13 @@
appears here and on the player's profile, regardless of filters.
</p>
<p>
Only completed games contribute to records. Games in progress and interrupted games
stay out of totals and rankings. Players who left a completed game keep their
recorded stats. Game, map, and starting squad-size filters choose which matches
contribute; player search preserves ranks. Player totals count each GUID once. The
top stats cover all recorded players in the selected game and map; player search and
ranking qualification do not change those totals.
Only games with a received end report contribute to records. Games in progress,
interrupted games, and games missing their end report stay out of totals and
rankings. Players who left a completed game keep their recorded stats. Game, map,
and starting squad-size filters choose which matches contribute; player search
preserves ranks. Player totals count each GUID once. The top stats cover all
recorded players in the selected game and map; player search and ranking
qualification do not change those totals.
</p>
<p>
Highest round includes mid-game joins. Total rounds counts round progression during
@@ -159,7 +159,7 @@
{#if !profile.records}
<EmptyState
title="No qualifying match history yet"
description="Stats appear after a recorded game ends, provided this player was observed at round 2 or later. Games in progress and interrupted games do not contribute."
description="Stats appear after a game's end report arrives, provided this player was observed at round 2 or later. Games without an end report do not contribute."
/>
{/if}
<nav class="jump-links" aria-label="Player sections">
@@ -394,10 +394,10 @@
><span>Last seen <RelativeTime value={profile.lastSeen} /></span>
</div>
<p>
Lifetime stats combine completed games from Black Ops I and Black Ops II. Games in
progress and interrupted games do not contribute. Highest round includes mid-game joins;
total rounds counts observed progression. Kills, headshots, revives and downs use each
match's highest reported counters.
Lifetime stats combine completed games from Black Ops I and Black Ops II. Games without
an end report do not contribute. Highest round includes mid-game joins; total rounds
counts observed progression. Kills, headshots, revives and downs use each match's
highest reported counters.
</p>
<p>
Highest reported score is the largest observed points balance, not total points earned.