Exclude round one records from match history and statistics
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
// Reset/abandoned games at round 1 do not qualify as gameplay records.
|
||||
export const MIN_RECORDED_ROUND = 2;
|
||||
|
||||
export interface ServerMatch {
|
||||
id: number;
|
||||
server: string;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { BetaPlan, RequirementProgress } from '../../beta-plan.js';
|
||||
import type { GameEvent } from '../../telemetry.js';
|
||||
import { MIN_RECORDED_ROUND } from '../../match-history.js';
|
||||
|
||||
export interface MatchEvidence {
|
||||
map: string;
|
||||
@@ -46,6 +47,7 @@ export function applyGameEvent(plan: BetaPlan, metrics: TestMetrics, event: Game
|
||||
if (r.kind === 'round') metrics.values[r.id] = Math.max(current, event.round);
|
||||
}
|
||||
if (event.event === 'game_end' && r.kind === 'matches'
|
||||
&& event.round >= MIN_RECORDED_ROUND
|
||||
&& (match.rounds[r.id] ?? -1) >= r.minRound
|
||||
&& (r.minMinutes === 0 || (match.started !== undefined && now - match.started >= r.minMinutes * 60_000))) {
|
||||
metrics.values[r.id] = current + 1;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { db } from '../db/index.js';
|
||||
import { MIN_RECORDED_ROUND } from '../../match-history.js';
|
||||
import { leaderboardMetrics, type LeaderboardEntry, type LeaderboardMap, type LeaderboardMetric,
|
||||
type LeaderboardOptions, type LeaderboardResponse } from '../../leaderboard.js';
|
||||
|
||||
@@ -15,7 +16,8 @@ export function getLeaderboard(options: LeaderboardOptions = {}): LeaderboardRes
|
||||
const metric = options.metric && isLeaderboardMetric(options.metric) ? options.metric : 'highestRound';
|
||||
const limit = Number.isSafeInteger(options.limit) ? Math.min(100, Math.max(1, options.limit!)) : 50;
|
||||
const offset = Number.isSafeInteger(options.offset) ? Math.min(MAX_LEADERBOARD_OFFSET, Math.max(0, options.offset!)) : 0;
|
||||
const conditions = ['mp.has_stats = 1'];
|
||||
const conditions = ['mp.has_stats = 1', `m.highest_round >= ${MIN_RECORDED_ROUND}`,
|
||||
`mp.highest_round >= ${MIN_RECORDED_ROUND}`];
|
||||
const parameters: string[] = [];
|
||||
if (options.game) { conditions.push('m.game = ?'); parameters.push(options.game); }
|
||||
if (options.map) { conditions.push('m.map_key = ?'); parameters.push(options.map); }
|
||||
@@ -48,9 +50,9 @@ export function getLeaderboard(options: LeaderboardOptions = {}): LeaderboardRes
|
||||
COALESCE(MAX(mp.highest_round), 0) AS highestRound,
|
||||
MIN(m.started_at) AS firstTrackedAt, MAX(m.last_received_at) AS updatedAt
|
||||
${scoped}`).get(...parameters, ...parameters) as LeaderboardResponse['summary'];
|
||||
// Keep all recorded map variants available, even after their server is removed.
|
||||
// Keep qualifying map variants available, even after their server is removed.
|
||||
const maps = handle.prepare(`SELECT map_key AS key, game, map, map_name AS name
|
||||
FROM leaderboard_matches ${options.game ? 'WHERE game = ?' : ''}
|
||||
FROM leaderboard_matches WHERE highest_round >= ${MIN_RECORDED_ROUND}${options.game ? ' AND game = ?' : ''}
|
||||
GROUP BY game, map_key HAVING id = MAX(id)
|
||||
ORDER BY game, name COLLATE NOCASE, map_key`)
|
||||
.all(...(options.game ? [options.game] : [])) as LeaderboardMap[];
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { db } from '../db/index.js';
|
||||
import type { ServerMatch } from '../../match-history.js';
|
||||
import { MIN_RECORDED_ROUND, type ServerMatch } from '../../match-history.js';
|
||||
|
||||
export function serverMatchHistory(server?: string, limit = 25): { matches: ServerMatch[]; total: number } {
|
||||
const handle = db();
|
||||
const where = server === undefined ? '' : 'WHERE m.server = ?';
|
||||
const where = `WHERE m.highest_round >= ${MIN_RECORDED_ROUND}${server === undefined ? '' : ' AND m.server = ?'}`;
|
||||
const parameters = server === undefined ? [] : [server];
|
||||
const total = (handle.prepare(`SELECT COUNT(*) AS total FROM leaderboard_matches m ${where}`).get(...parameters) as { total: number }).total;
|
||||
const matches = handle.prepare(`SELECT m.id, m.server, m.map_name AS map, m.started_at AS startedAt, m.status,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { db } from '../db/index.js';
|
||||
import { MIN_RECORDED_ROUND } from '../../match-history.js';
|
||||
import type { PlayerProfile, PlayerStats, PlayerMapRecord, PlayerMatch } from '../../leaderboard.js';
|
||||
|
||||
const totals = `MAX(mp.highest_round) AS highestRound, SUM(mp.kills) AS kills,
|
||||
@@ -6,7 +7,8 @@ const totals = `MAX(mp.highest_round) AS highestRound, SUM(mp.kills) AS kills,
|
||||
SUM(mp.revives) AS revives, SUM(mp.downs) AS downs, COUNT(*) AS gamesPlayed,
|
||||
SUM(mp.completed) AS gamesCompleted, MAX(mp.kills) AS bestKills, MAX(mp.best_score) AS bestScore`;
|
||||
const scope = `FROM leaderboard_match_players mp JOIN leaderboard_matches m ON m.id = mp.match_id
|
||||
WHERE m.game = ? AND mp.guid = ? AND mp.has_stats = 1`;
|
||||
WHERE m.game = ? AND mp.guid = ? AND mp.has_stats = 1
|
||||
AND m.highest_round >= ${MIN_RECORDED_ROUND} AND mp.highest_round >= ${MIN_RECORDED_ROUND}`;
|
||||
|
||||
export function getPlayerProfile(game: string, guid: string, requestedOffset = 0): PlayerProfile | null {
|
||||
const handle = db();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { db } from '../db/index.js';
|
||||
import type { GameTelemetry } from '../../telemetry.js';
|
||||
import { MIN_RECORDED_ROUND } from '../../match-history.js';
|
||||
import { recordLeaderboardTelemetry } from './leaderboard-ingest.js';
|
||||
|
||||
export function listTelemetry(): GameTelemetry[] {
|
||||
@@ -36,7 +37,7 @@ export function saveTelemetry(report: GameTelemetry): GameTelemetry {
|
||||
} else if (report.event === 'game_end') {
|
||||
handle.prepare('UPDATE servers SET game_ended_at = ? WHERE name = ?').run(report.receivedAt, report.server);
|
||||
// Legacy betas also take match completion directly from the script.
|
||||
handle.prepare(`UPDATE beta_servers SET match_seen_at = ? WHERE server = ? AND stage = 'awaiting-match'
|
||||
if (report.round >= MIN_RECORDED_ROUND) handle.prepare(`UPDATE beta_servers SET match_seen_at = ? WHERE server = ? AND stage = 'awaiting-match'
|
||||
AND healthy_at <= ? AND beta_id IN (SELECT id FROM betas WHERE state = 'running')`)
|
||||
.run(report.receivedAt, report.server, report.receivedAt);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user