games: automatic CS2 / PUBG / R6 match history — games.matches, match_players, seasons, snapshots, accounts; in-app poller (Leetify, FACEIT, Steam share codes, PUBG API, Ubisoft) every 20 min plus scripts/games-ingest.ts for backfills; match history, stats, maps and seasons on the per-game pages
All checks were successful
Deploy production / deploy (push) Successful in 1m6s

This commit is contained in:
2026-10-25 16:00:48 +00:00
parent 9114b5433b
commit 80803ef5ac
24 changed files with 30747 additions and 5 deletions

View File

@@ -2,11 +2,15 @@ import { error } from '@sveltejs/kit';
import { eq, inArray } from 'drizzle-orm';
import { db } from '#lib/server/db/index.js';
import { gameLibrary, hardwareSensitivities } from '#lib/server/db/schema/index.js';
import { isOwner } from '#lib/server/owner.js';
import { isAutoTracked, loadHistory } from '#lib/server/games/history.js';
import type { PageServerLoad } from './$types';
// One game from games.library, plus its mouse sensitivity (hardware.sensitivities, matched by
// name, short name or alias) when there is one.
export const load: PageServerLoad = async ({ params }) => {
// name, short name or alias) when there is one. CS2, PUBG and R6 also get their automatic
// match history (games.matches, filled by the in-app poller).
export const load: PageServerLoad = async (event) => {
const { params } = event;
const [game] = await db.select().from(gameLibrary).where(eq(gameLibrary.slug, params.slug));
if (!game) error(404, 'Not Found');
const names = [game.name, game.shortName, ...game.aliases];
@@ -37,6 +41,7 @@ export const load: PageServerLoad = async ({ params }) => {
notes: game.notes
},
sensitivity: sensitivity ?? null,
history: isAutoTracked(game.slug) ? await loadHistory(game.slug, isOwner(event)) : null,
seo: {
title: `${game.name} · Games`,
description: `${game.name} on Stan Runge’s game tracker${game.status === 'main' ? ': my main game right now' : ''}.`

View File

@@ -3,6 +3,7 @@
import ArrowLeft from 'lucide-svelte/icons/arrow-left';
import ArrowRight from 'lucide-svelte/icons/arrow-right';
import TrackerIcon from '#lib/components/TrackerIcon.svelte';
import MatchHistory from '#lib/game-tracker/MatchHistory.svelte';
import { gameTrackers } from '#lib/projects.js';
import type { PageProps } from './$types';
@@ -74,6 +75,10 @@
</ul>
{/if}
{#if data.history}
<MatchHistory history={data.history} game={game.slug as 'cs2' | 'pubg' | 'r6'} />
{/if}
{#if game.notes}
<p class="mb-8 max-w-2xl whitespace-pre-line text-[var(--site-muted)]">{game.notes}</p>
{/if}
@@ -87,7 +92,7 @@
</span>
<ArrowRight size={18} aria-hidden="true" class="ml-4 text-[var(--site-muted)]" />
</a>
{:else if !hasStats && !game.notes}
{:else if !hasStats && !game.notes && !data.history}
<p class="empty rounded-xl p-6 text-[var(--site-muted)]">
Nothing tracked for {game.shortName} yet. Stats, ranks and notes show up here once I add them.
</p>