import type { PoolClient } from 'pg'; /** * Upserts a player. A non-null name replaces the stored one only if it was observed at least as late as the * current name (late replays never revert a rename) and is recorded in name_history; * `seen` updates last_seen (only for events proving the player was online). */ export async function ensurePlayer(c: PoolClient, uuid: string, name: string | null, ts: number, seen: boolean): Promise { await c.query( `INSERT INTO players(uuid, name, name_seen_at, first_seen, last_seen) VALUES ($1, $2, CASE WHEN $2::text IS NOT NULL THEN to_timestamp($3 / 1000.0) END, to_timestamp($3 / 1000.0), CASE WHEN $4 THEN to_timestamp($3 / 1000.0) END) ON CONFLICT (uuid) DO UPDATE SET name = CASE WHEN EXCLUDED.name IS NOT NULL AND (players.name_seen_at IS NULL OR EXCLUDED.name_seen_at >= players.name_seen_at) THEN EXCLUDED.name ELSE players.name END, name_seen_at = CASE WHEN EXCLUDED.name IS NOT NULL AND (players.name_seen_at IS NULL OR EXCLUDED.name_seen_at >= players.name_seen_at) THEN EXCLUDED.name_seen_at ELSE players.name_seen_at END, first_seen = LEAST(players.first_seen, EXCLUDED.first_seen), last_seen = CASE WHEN $4 THEN GREATEST(players.last_seen, EXCLUDED.last_seen) ELSE players.last_seen END`, [uuid, name, ts, seen], ); if (name) { await c.query( `INSERT INTO name_history(uuid, name, seen_at) VALUES ($1, $2, to_timestamp($3 / 1000.0)) ON CONFLICT (uuid, name) DO UPDATE SET seen_at = GREATEST(name_history.seen_at, EXCLUDED.seen_at)`, [uuid, name, ts], ); } }