// DTOs of the public read API, shared by backend and web. export type Unit = 'hours' | 'count' | 'km' | 'blocks'; export type Period = 'all' | '30d' | '7d'; export type ItemCategory = 'mined' | 'crafted' | 'used' | 'picked_up'; export const ITEM_CATEGORIES: ItemCategory[] = ['mined', 'crafted', 'used', 'picked_up']; export interface OverviewDto { online: number; totalPlayers: number; totalPlayHours: number; totalDeaths: number; totalMobKills: number; questsCompleted: number; advancements: number; lastUpdate: number | null; } export interface OnlinePlayerDto { uuid: string; name: string | null; since: number; dimension: string | null; } export interface OnlineDto { players: OnlinePlayerDto[]; } export interface BoardMetaDto { id: string; title: string; description: string; unit: Unit; } export interface LeaderboardEntryDto { rank: number; uuid: string; name: string | null; value: number; } export interface LeaderboardsDto { boards: (BoardMetaDto & { top: LeaderboardEntryDto[] })[]; } export interface LeaderboardDto { board: BoardMetaDto; period: Period; entries: LeaderboardEntryDto[]; } export interface PlayerListItemDto { uuid: string; name: string | null; lastSeen: number | null; playHours: number; online: boolean; } export interface PlayerListDto { players: PlayerListItemDto[]; total: number; } export interface PlayerQuestsDto { teamId: string; teamName: string | null; completed: number; total: number | null; chapters: { chapterId: string; title: string | null; completed: number; total: number }[]; /** last completed quests that have a title in the quest config (newest first, max. 10) */ recent: { questId: string; title: string; chapterTitle: string | null; at: number }[]; } export interface PlayerProfileDto { uuid: string; name: string | null; firstSeen: number; lastSeen: number | null; online: boolean; playHours: number; sessions: number; ranks: Record; /** minecraft:custom counters except distances (raw values; play_time in ticks) */ general: Record; /** distances in cm by key (minecraft:walk_one_cm …) */ movement: Record; deathsByCause: { cause: string; count: number }[]; killedBy: { entity: string; count: number }[]; killsByType: { entity: string; count: number }[]; bossKills: { entity: string; at: number }[]; dimensions: { dimension: string; firstAt: number }[]; advancements: { id: string; title: string | null; at: number }[]; quests: PlayerQuestsDto; /** minutes online per [weekday 0=Mon..6=Sun][hour 0..23], last 90 days, server time zone */ activityHeatmap: number[][]; } export interface HistoryDto { metric: string; unit: Unit; points: { t: number; v: number }[]; } export interface ItemsDto { category: ItemCategory; mods: { namespace: string; total: number; items: { key: string; value: number }[] }[]; } export interface ServerInfoDto { startedAt: number; mcVersion: string; neoforgeVersion: string; javaVersion: string; modCount: number; } export interface ModsDto { server: ServerInfoDto | null; mods: { id: string; name: string; version: string; activity: number; category: string | null }[]; /** activity per category (tech/magic/farming/other) across all visible players */ categories: { category: string; activity: number }[]; } export interface QuestsDto { defsKnown: boolean; chapters: { chapterId: string; title: string | null; total: number; maxCompleted: number; teamsFinished: number }[]; teams: { teamId: string; name: string | null; members: { uuid: string; name: string | null }[]; completed: number }[]; } export interface HealthPointDto { t: number; msptAvg: number; msptP95: number; tps: number; players: number; heapUsedMb: number; heapMaxMb: number; } export interface ServerDto { info: ServerInfoDto | null; health: HealthPointDto[]; } export interface SourcesDto { push: { lastEventAt: number | null; lastServerStart: number | null; reachable: boolean }; sftp: { enabled: boolean; lastSyncAt: number | null; lastError: string | null }; limitations: string[]; } export type LiveKind = 'online' | 'death' | 'advancement' | 'quest' | 'counters'; export interface LiveEvent { id: number; kind: LiveKind; data: Record; }