fix: honor Komodo health and prefer fresh telemetry across fleet status

This commit is contained in:
2026-09-27 15:34:30 -04:00
parent 46a89ea4b0
commit 8ea696417f
27 changed files with 488 additions and 315 deletions
+12 -6
View File
@@ -70,6 +70,10 @@
status?: { players: number; map: string | null; gametype: string | null; roster: RosterPlayer[] };
}
interface Server {
telemetry_after?: string | null;
status_source?: 'telemetry' | 'rcon' | null;
rcon_status?: import('$lib/server-observation.js').GameObservation;
telemetry?: import('$lib/telemetry.js').GameTelemetry;
name: string;
komodo_type: string; komodo_name: string; komodo_server: string | null;
game_port: number | null; rcon_host: string | null;
@@ -145,10 +149,11 @@
let effectivePlayers = $derived(fresh ? server?.last_players ?? null : null);
let effectiveMap = $derived(server?.last_map ?? null);
let effectiveGametype = $derived(server?.last_gametype ?? null);
const scoreboard = $derived($telemetryByServer.get(name));
const scoreboard = $derived(server?.telemetry ?? $telemetryByServer.get(name));
let effectiveHealth = $derived<Health>(server?.health === 'online' && !fresh ? 'stale' : server?.health ?? 'offline');
let effectiveSeen = $derived(server?.last_seen_at ?? null);
let effectiveErr = $derived(server?.last_error ?? null);
let effectiveErr = $derived(effectiveHealth === 'starting' || effectiveHealth === 'provisioning'
? null : server?.rcon_status?.last_error ?? server?.last_error ?? null);
let effectiveEndpoint = $derived<RconEndpoint | null>(server?.endpoint ?? null);
let decoded = $derived(decodeRconError(effectiveErr));
let effectiveReason = $derived<RconFailure | null>(decoded?.reason ?? null);
@@ -217,7 +222,7 @@
}
// Tab config — Diagnostics gets a warning badge when there's an issue.
let tabs = $derived([
{ id: 'scoreboard', label: 'Scoreboard', badge: scoreboard?.players.length ?? null },
{ id: 'scoreboard', label: 'Scoreboard', badge: null },
{ id: 'chat', label: 'Chat' },
{ id: 'matches', label: 'Matches' },
{ id: 'logs', label: 'Logs' },
@@ -296,7 +301,7 @@
{/if}
</div>
{#if effectiveHealth !== 'starting' && effectiveHealth !== 'provisioning'}<RoundTelemetry {name} />{/if}
{#if effectiveHealth === 'online'}<RoundTelemetry {name} report={scoreboard} since={server?.telemetry_after ?? null} />{/if}
</Card>
@@ -315,7 +320,7 @@
{#if tabError}<div class="ui-error" role="alert">{tabError}<Button size="sm" onclick={() => loadTab(name, activeTab)}>Retry</Button></div>{/if}
{#if activeTab === 'scoreboard'}
<Card padding="lg">
{#key name}<PlayerScoreboard game={fleetIdentity(server).game} report={scoreboard} mapLabel={scoreboard ? fleetIdentity({ ...server, last_map: scoreboard.map }).map : undefined} />{/key}
{#key name}<PlayerScoreboard current={fresh} after={server?.telemetry_after ?? null} game={fleetIdentity(server).game} report={scoreboard} mapLabel={scoreboard ? fleetIdentity({ ...server, last_map: scoreboard.map }).map : undefined} />{/key}
</Card>
{:else if activeTab === 'chat'}
<Card padding="lg">
@@ -373,6 +378,7 @@
{/if}
</div>
<p class="sub">Current player count: {server.status_source === 'telemetry' ? 'game telemetry' : server.status_source === 'rcon' ? 'RCON' : 'unavailable'}. RCON probes below show that connection's separate results.</p>
{#if integrations}
<div class="diag-grid">
<div class="kv"><span class="k">Endpoint</span><span class="v mono">{endpointLabel(effectiveEndpoint)}</span></div>
@@ -422,7 +428,7 @@
<div class="alert alert-ok">
<Badge variant="online" uppercase>Connected</Badge>
<span class="alert-detail">
{rconProbe.status?.players ?? '?'} players
RCON: {rconProbe.status?.players ?? '?'} players
{#if rconProbe.status?.map} · map <strong>{rconProbe.status.map}</strong>{/if}
{#if rconProbe.status?.gametype} · {rconProbe.status.gametype}{/if}
</span>