Fix active and match timer drift between status polls
Persist occupancy transitions with telemetry and carry timer anchors through live updates. Cover delayed polling, lobby rejoining, and lifecycle boundaries with regression tests. Fixes #47
This commit is contained in:
@@ -50,14 +50,22 @@ export function selectServerObservation<T extends ServerObservation>(server: T,
|
||||
const containerFresh = server.container_state === 'running' && freshStatusTimestamp(checked ?? null, now);
|
||||
if (containerFresh && report?.server === server.name && freshTelemetry(report, now, server.telemetry_after)) {
|
||||
const players = report.players.length;
|
||||
// New reports carry persisted anchors through both SSE and HTTP. Keep
|
||||
// the fallback for telemetry saved before server timing was included.
|
||||
const timing = report.timing?.server ?? {
|
||||
activeSince: server.active_since ?? report.receivedAt,
|
||||
inactiveSince: server.inactive_since ?? report.receivedAt,
|
||||
gameStartedAt: report.event === 'game_start' ? report.receivedAt : server.game_started_at,
|
||||
gameEndedAt: report.event === 'game_start' ? null : report.event === 'game_end' ? report.receivedAt : server.game_ended_at
|
||||
};
|
||||
return { ...result, health: 'online', status_source: 'telemetry', last_players: players,
|
||||
last_map: report.map, last_seen_at: report.receivedAt, last_error: null,
|
||||
roster: report.players.map(player => ({ num: null, score: 'score' in player ? player.score : null,
|
||||
ping: null, guid: player.guid, name: player.name })),
|
||||
active_since: players > 0 ? server.active_since ?? report.receivedAt : null,
|
||||
inactive_since: players === 0 ? server.inactive_since ?? report.receivedAt : null,
|
||||
game_started_at: players === 0 ? null : report.event === 'game_start' ? report.receivedAt : server.game_started_at,
|
||||
game_ended_at: players === 0 || report.event === 'game_start' ? null : report.event === 'game_end' ? report.receivedAt : server.game_ended_at };
|
||||
active_since: players > 0 ? timing.activeSince : null,
|
||||
inactive_since: players === 0 ? timing.inactiveSince : null,
|
||||
game_started_at: players === 0 ? null : timing.gameStartedAt,
|
||||
game_ended_at: players === 0 ? null : timing.gameEndedAt };
|
||||
}
|
||||
const after = !server.telemetry_after || Date.parse(raw.last_seen_at ?? '') > Date.parse(server.telemetry_after);
|
||||
const fresh = after && freshStatusTimestamp(raw.last_seen_at, now) && !raw.last_error;
|
||||
|
||||
Reference in New Issue
Block a user