always sort scores on win condition
This commit is contained in:
@@ -110,7 +110,7 @@
|
|||||||
{ href: '/mappools', label: 'Mappools', icon: 'mappools' },
|
{ href: '/mappools', label: 'Mappools', icon: 'mappools' },
|
||||||
// { href: '/teams', label: 'Teams', icon: 'teams' },
|
// { href: '/teams', label: 'Teams', icon: 'teams' },
|
||||||
{ href: '/leaderboard', label: 'Leaderboard', icon: 'leaderboard' },
|
{ href: '/leaderboard', label: 'Leaderboard', icon: 'leaderboard' },
|
||||||
] as item}
|
] as item (item.href)}
|
||||||
<a
|
<a
|
||||||
href={item.href}
|
href={item.href}
|
||||||
class="font-500 flex items-center gap-3 rounded-md px-3 py-2 text-sm transition-colors {isActive(item.href)
|
class="font-500 flex items-center gap-3 rounded-md px-3 py-2 text-sm transition-colors {isActive(item.href)
|
||||||
|
|||||||
@@ -668,7 +668,8 @@ export async function getMatchFull(matchId: string) {
|
|||||||
with: {
|
with: {
|
||||||
slot: true,
|
slot: true,
|
||||||
scores: {
|
scores: {
|
||||||
with: { player: true }
|
with: { player: true },
|
||||||
|
orderBy: (s, { desc }) => [desc(s.score)]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
orderBy: (g, { asc }) => [asc(g.gameNumber)]
|
orderBy: (g, { asc }) => [asc(g.gameNumber)]
|
||||||
|
|||||||
@@ -24,6 +24,18 @@ export const load: PageServerLoad = async ({ params, locals }) => {
|
|||||||
error(404, 'Match not found');
|
error(404, 'Match not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort game scores by the match win condition so clients always receive sorted data
|
||||||
|
const scoringType = (m.config as MatchConfig).scoringType;
|
||||||
|
for (const game of m.games) {
|
||||||
|
if (game.scores?.length > 1) {
|
||||||
|
game.scores.sort((a, b) => {
|
||||||
|
if (scoringType === 'accuracy') return b.accuracy - a.accuracy;
|
||||||
|
if (scoringType === 'combo') return b.maxCombo - a.maxCombo;
|
||||||
|
return b.score - a.score;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Build beatmap metadata cache — prefer DB-stored R2 URLs, fall back to API
|
// Build beatmap metadata cache — prefer DB-stored R2 URLs, fall back to API
|
||||||
const beatmapCache: Record<string, any> = {};
|
const beatmapCache: Record<string, any> = {};
|
||||||
if (m.mappool?.slots) {
|
if (m.mappool?.slots) {
|
||||||
|
|||||||
@@ -544,12 +544,7 @@
|
|||||||
<!-- Per-player score breakdown -->
|
<!-- Per-player score breakdown -->
|
||||||
{#if game.state === 'FINISHED' && game.scores?.length > 0}
|
{#if game.state === 'FINISHED' && game.scores?.length > 0}
|
||||||
<div class="mt-1.5 flex flex-col gap-1">
|
<div class="mt-1.5 flex flex-col gap-1">
|
||||||
{#each [...game.scores].sort((a: any, b: any) => {
|
{#each game.scores as s}
|
||||||
if (config.scoringType === 'accuracy') return b.accuracy - a.accuracy;
|
|
||||||
if (config.scoringType === 'combo') return b.maxCombo - a.maxCombo;
|
|
||||||
if (config.scoringType === 'pp') return (b.pp ?? 0) - (a.pp ?? 0);
|
|
||||||
return b.score - a.score;
|
|
||||||
}) as s}
|
|
||||||
{@const username = playerNames[s.player?.userId]}
|
{@const username = playerNames[s.player?.userId]}
|
||||||
<div class="flex flex-wrap items-center gap-x-3 gap-y-0.5 rounded bg-surface-900 px-3 py-1.5 text-xs">
|
<div class="flex flex-wrap items-center gap-x-3 gap-y-0.5 rounded bg-surface-900 px-3 py-1.5 text-xs">
|
||||||
<span class="w-24 truncate font-500">{username ?? s.player?.userId ?? '?'}</span>
|
<span class="w-24 truncate font-500">{username ?? s.player?.userId ?? '?'}</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user