130 lines
3.4 KiB
TypeScript
130 lines
3.4 KiB
TypeScript
import { efficiencyMetrics, type EfficiencyMetric } from './leaderboard-efficiency.js';
|
|
|
|
export const playerStatMetrics = [
|
|
{ key: 'highestRound', label: 'Highest round' },
|
|
{ key: 'kills', label: 'Total kills' },
|
|
{ key: 'roundsSurvived', label: 'Total rounds' },
|
|
{ key: 'headshots', label: 'Headshots' },
|
|
{ key: 'revives', label: 'Revives' },
|
|
{ key: 'downs', label: 'Downs' },
|
|
{ key: 'gamesPlayed', label: 'Games played' },
|
|
{ key: 'gamesCompleted', label: 'Games completed' },
|
|
{ key: 'bestKills', label: 'Best game kills' },
|
|
{ key: 'bestScore', label: 'Highest reported score' }
|
|
] as const;
|
|
|
|
export const leaderboardMetrics = [...playerStatMetrics, ...efficiencyMetrics] as const;
|
|
export type LeaderboardMetric = typeof leaderboardMetrics[number]['key'];
|
|
export type PlayerStatMetric = typeof playerStatMetrics[number]['key'];
|
|
|
|
export type PlayerStats = Record<PlayerStatMetric, number>;
|
|
export type PersonalBestMetric = 'highestRound' | 'bestKills' | 'bestScore';
|
|
export interface RecordEvidence {
|
|
matchId: number;
|
|
game: string;
|
|
mapKey: string;
|
|
mapName: string;
|
|
server: string;
|
|
startedAt: string;
|
|
endedAt: string | null;
|
|
startObserved: boolean;
|
|
presentAtStart: boolean | null;
|
|
firstObservedRound: number | null;
|
|
value: number;
|
|
}
|
|
export type PersonalBestRecords = Record<PersonalBestMetric, RecordEvidence>;
|
|
export interface PlayerMapRecord extends PlayerStats {
|
|
game: string;
|
|
key: string;
|
|
name: string;
|
|
lastSeen: string;
|
|
records: PersonalBestRecords;
|
|
}
|
|
export interface PlayerMatch {
|
|
id: number;
|
|
game: string;
|
|
server: string;
|
|
server_deleted_at?: string | null;
|
|
mapName: string;
|
|
startedAt: string;
|
|
lastSeen: string;
|
|
status: 'active' | 'completed' | 'interrupted';
|
|
completed: number;
|
|
highestRound: number;
|
|
roundsSurvived: number;
|
|
kills: number;
|
|
headshots: number;
|
|
revives: number;
|
|
downs: number;
|
|
bestScore: number;
|
|
}
|
|
export interface PlayerProfile {
|
|
guid: string;
|
|
name: string;
|
|
firstSeen: string;
|
|
lastSeen: string;
|
|
stats: PlayerStats;
|
|
records: PersonalBestRecords;
|
|
maps: PlayerMapRecord[];
|
|
matches: PlayerMatch[];
|
|
matchesTotal: number;
|
|
offset: number;
|
|
limit: number;
|
|
}
|
|
|
|
export function playerProfileHref(guid: string): string {
|
|
return `/leaderboard/players/${encodeURIComponent(guid)}`;
|
|
}
|
|
|
|
export interface LeaderboardEntry extends Record<EfficiencyMetric, number | null> {
|
|
rank: number;
|
|
guid: string;
|
|
name: string;
|
|
highestRound: number;
|
|
kills: number;
|
|
roundsSurvived: number;
|
|
headshots: number;
|
|
revives: number;
|
|
downs: number;
|
|
gamesPlayed: number;
|
|
gamesCompleted: number;
|
|
bestKills: number;
|
|
bestScore: number;
|
|
lastSeen: string;
|
|
records: PersonalBestRecords;
|
|
}
|
|
|
|
export interface LeaderboardMap {
|
|
key: string;
|
|
game: string;
|
|
map: string;
|
|
name: string;
|
|
}
|
|
|
|
export interface LeaderboardOptions {
|
|
game?: string;
|
|
map?: string;
|
|
metric?: LeaderboardMetric;
|
|
q?: string;
|
|
limit?: number;
|
|
offset?: number;
|
|
}
|
|
|
|
export interface LeaderboardResponse {
|
|
entries: LeaderboardEntry[];
|
|
maps: LeaderboardMap[];
|
|
total: number;
|
|
limit: number;
|
|
offset: number;
|
|
metric: LeaderboardMetric;
|
|
summary: {
|
|
players: number;
|
|
matches: number;
|
|
kills: number;
|
|
roundsSurvived: number;
|
|
highestRound: number;
|
|
firstTrackedAt: string | null;
|
|
updatedAt: string | null;
|
|
};
|
|
}
|