fix: update match configuration to bestOf 5 and scoringType to score_v2

This commit is contained in:
2026-02-28 06:38:05 +01:00
parent e99444b157
commit fb9140a03f
555 changed files with 124715 additions and 1 deletions

View File

@@ -0,0 +1,100 @@
import { d as db, m as mappool, a as mappoolSlot } from "../../../../../chunks/index2.js";
import { eq, and } from "drizzle-orm";
import { redirect, error } from "@sveltejs/kit";
import { g as getBeatmap } from "../../../../../chunks/api.js";
const load = async ({ params, locals }) => {
if (!locals.user) redirect(302, "/");
const pool = await db.query.mappool.findFirst({
where: eq(mappool.id, params.id),
with: {
slots: {
orderBy: (s, { asc }) => [asc(s.category), asc(s.orderInCategory)]
}
}
});
if (!pool) error(404, "Mappool not found");
const slotsWithBeatmaps = await Promise.all(
pool.slots.map(async (slot) => {
try {
const beatmap = await getBeatmap(slot.beatmapId);
return {
...slot,
beatmap: {
title: beatmap.beatmapset.title,
artist: beatmap.beatmapset.artist,
version: beatmap.version,
starRating: beatmap.difficulty_rating,
bpm: beatmap.bpm,
totalLength: beatmap.total_length,
coverUrl: beatmap.beatmapset.covers["card@2x"],
url: beatmap.url
}
};
} catch {
return {
...slot,
beatmap: null
};
}
})
);
return {
pool: { ...pool, slots: slotsWithBeatmaps }
};
};
const actions = {
addSlot: async ({ params, request, locals }) => {
if (!locals.user) redirect(302, "/");
const form = await request.formData();
let beatmapId = form.get("beatmapId")?.toString()?.trim();
const category = form.get("category")?.toString()?.trim()?.toUpperCase();
if (!beatmapId || !category) {
return { error: "Beatmap ID and category are required" };
}
const urlMatch = beatmapId.match(/beatmaps\/(\d+)/);
const setMatch = beatmapId.match(/beatmapsets\/\d+#\w+\/(\d+)/);
if (urlMatch) beatmapId = urlMatch[1];
else if (setMatch) beatmapId = setMatch[1];
if (!/^\d+$/.test(beatmapId)) {
return { error: "Invalid beatmap ID" };
}
let beatmap;
try {
beatmap = await getBeatmap(beatmapId);
} catch {
return { error: "Beatmap not found on osu!" };
}
const existing = await db.query.mappoolSlot.findMany({
where: and(
eq(mappoolSlot.mappoolId, params.id),
eq(mappoolSlot.category, category)
)
});
await db.insert(mappoolSlot).values({
mappoolId: params.id,
beatmapId,
category,
orderInCategory: existing.length + 1,
starRating: beatmap.difficulty_rating,
mods: category === "NM" || category === "TB" || category === "FM" ? [] : [category]
});
return { success: true };
},
removeSlot: async ({ request, locals }) => {
if (!locals.user) redirect(302, "/");
const form = await request.formData();
const slotId = form.get("slotId")?.toString();
if (!slotId) return { error: "Missing slot ID" };
await db.delete(mappoolSlot).where(eq(mappoolSlot.id, slotId));
return { success: true };
},
deletePool: async ({ params, locals }) => {
if (!locals.user) redirect(302, "/");
await db.delete(mappool).where(eq(mappool.id, params.id));
redirect(303, "/mappools");
}
};
export {
actions,
load
};

View File

@@ -0,0 +1,98 @@
import { e as escape_html, a as ensure_array_like, b as attr, c as attr_class, d as derived, s as stringify } from "../../../../../chunks/index3.js";
import "@sveltejs/kit/internal";
import "../../../../../chunks/url.js";
import "../../../../../chunks/utils.js";
import "@sveltejs/kit/internal/server";
import "../../../../../chunks/root.js";
import "../../../../../chunks/exports.js";
import "../../../../../chunks/state.svelte.js";
function _page($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let { data } = $$props;
const categories = ["NM", "HD", "HR", "DT", "FM", "TB"];
let addingCategory = "NM";
let beatmapInput = "";
const grouped = derived(() => () => {
const groups = {};
for (const cat of categories) {
const slots = data.pool.slots.filter((s) => s.category === cat);
if (slots.length > 0) groups[cat] = slots;
}
return groups;
});
function formatLength(seconds) {
const m = Math.floor(seconds / 60);
const s = seconds % 60;
return `${m}:${s.toString().padStart(2, "0")}`;
}
const categoryColors = {
NM: "bg-blue-500/20 text-blue-400 border-blue-500/30",
HD: "bg-yellow-500/20 text-yellow-400 border-yellow-500/30",
HR: "bg-red-500/20 text-red-400 border-red-500/30",
DT: "bg-purple-500/20 text-purple-400 border-purple-500/30",
FM: "bg-green-500/20 text-green-400 border-green-500/30",
TB: "bg-pink-500/20 text-pink-400 border-pink-500/30"
};
$$renderer2.push(`<div class="mx-auto max-w-4xl"><div class="flex items-center justify-between"><div class="flex items-center gap-3"><a href="/mappools" class="text-text-secondary transition-colors hover:text-text-primary">←</a> <div><h1 class="text-2xl font-700 tracking-tight">${escape_html(data.pool.name)}</h1> <p class="mt-1 text-sm text-text-secondary">${escape_html(data.pool.slots.length)} map${escape_html(data.pool.slots.length !== 1 ? "s" : "")}</p></div></div> <form method="post" action="?/deletePool"><button type="submit" class="rounded-md border border-red-500/30 px-3 py-1.5 text-sm text-red-400 transition-colors hover:bg-red-500/10">Delete Pool</button></form></div> <form method="post" action="?/addSlot" class="mt-6 rounded-lg border border-border bg-surface-800 p-4"><h2 class="text-sm font-600">Add Map</h2> <div class="mt-3 flex gap-3">`);
$$renderer2.select(
{
name: "category",
value: addingCategory,
class: "rounded-md border border-border bg-surface-700 px-3 py-2 text-sm text-text-primary focus:border-accent focus:outline-none"
},
($$renderer3) => {
$$renderer3.push(`<!--[-->`);
const each_array = ensure_array_like(categories);
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
let cat = each_array[$$index];
$$renderer3.option({ value: cat }, ($$renderer4) => {
$$renderer4.push(`${escape_html(cat)}`);
});
}
$$renderer3.push(`<!--]-->`);
}
);
$$renderer2.push(` <input type="text" name="beatmapId"${attr("value", beatmapInput)} placeholder="Beatmap ID or URL (e.g. 75 or https://osu.ppy.sh/beatmaps/75)" class="flex-1 rounded-md border border-border bg-surface-700 px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary/50 focus:border-accent focus:outline-none"/> <button type="submit"${attr("disabled", !beatmapInput.trim(), true)} class="rounded-md bg-accent px-4 py-2 text-sm font-600 text-surface-900 transition-colors hover:bg-accent-hover disabled:opacity-50">${escape_html("Add")}</button></div> `);
{
$$renderer2.push("<!--[!-->");
}
$$renderer2.push(`<!--]--></form> <div class="mt-6 flex flex-col gap-6">`);
const each_array_1 = ensure_array_like(Object.entries(grouped()()));
if (each_array_1.length !== 0) {
$$renderer2.push("<!--[-->");
for (let $$index_2 = 0, $$length = each_array_1.length; $$index_2 < $$length; $$index_2++) {
let [category, slots] = each_array_1[$$index_2];
$$renderer2.push(`<div><div class="mb-2 flex items-center gap-2"><span${attr_class(`rounded border px-2 py-0.5 text-xs font-600 ${stringify(categoryColors[category] ?? "bg-surface-600 text-text-secondary border-border")}`)}>${escape_html(category)}</span> <span class="text-xs text-text-secondary">${escape_html(slots.length)} map${escape_html(slots.length !== 1 ? "s" : "")}</span></div> <div class="flex flex-col gap-2"><!--[-->`);
const each_array_2 = ensure_array_like(slots);
for (let i = 0, $$length2 = each_array_2.length; i < $$length2; i++) {
let slot = each_array_2[i];
$$renderer2.push(`<div class="group flex items-center gap-3 rounded-lg border border-border bg-surface-800 p-2 transition-colors hover:border-accent/30">`);
if (slot.beatmap?.coverUrl) {
$$renderer2.push("<!--[-->");
$$renderer2.push(`<img${attr("src", slot.beatmap.coverUrl)} alt="" class="h-12 w-24 rounded object-cover"/>`);
} else {
$$renderer2.push("<!--[!-->");
$$renderer2.push(`<div class="flex h-12 w-24 items-center justify-center rounded bg-surface-700 text-xs text-text-secondary">No cover</div>`);
}
$$renderer2.push(`<!--]--> <div class="min-w-0 flex-1">`);
if (slot.beatmap) {
$$renderer2.push("<!--[-->");
$$renderer2.push(`<a${attr("href", slot.beatmap.url)} target="_blank" rel="noopener" class="truncate text-sm font-500 hover:text-accent">${escape_html(slot.beatmap.artist)} - ${escape_html(slot.beatmap.title)}</a> <div class="mt-0.5 flex items-center gap-3 text-xs text-text-secondary"><span>[${escape_html(slot.beatmap.version)}]</span> <span>★ ${escape_html(slot.beatmap.starRating.toFixed(2))}</span> <span>${escape_html(slot.beatmap.bpm)} BPM</span> <span>${escape_html(formatLength(slot.beatmap.totalLength))}</span></div>`);
} else {
$$renderer2.push("<!--[!-->");
$$renderer2.push(`<p class="text-sm text-text-secondary">Beatmap #${escape_html(slot.beatmapId)}</p>`);
}
$$renderer2.push(`<!--]--></div> <span class="text-xs font-600 text-text-secondary">${escape_html(category)}${escape_html(i + 1)}</span> <form method="post" action="?/removeSlot"><input type="hidden" name="slotId"${attr("value", slot.id)}/> <button type="submit" class="rounded p-1 text-text-secondary opacity-0 transition-all hover:bg-red-500/10 hover:text-red-400 group-hover:opacity-100">✕</button></form></div>`);
}
$$renderer2.push(`<!--]--></div></div>`);
}
} else {
$$renderer2.push("<!--[!-->");
$$renderer2.push(`<div class="rounded-lg border border-dashed border-border py-12 text-center"><p class="text-sm text-text-secondary">No maps yet. Add your first map above.</p></div>`);
}
$$renderer2.push(`<!--]--></div></div>`);
});
}
export {
_page as default
};

View File

@@ -0,0 +1,24 @@
import { d as db, m as mappool } from "../../../../chunks/index2.js";
import { redirect } from "@sveltejs/kit";
const load = async ({ locals }) => {
if (!locals.user) redirect(302, "/");
const mappools = await db.query.mappool.findMany({
with: { slots: true },
orderBy: (m, { desc }) => [desc(m.createdAt)]
});
return { mappools };
};
const actions = {
create: async ({ request, locals }) => {
if (!locals.user) redirect(302, "/");
const form = await request.formData();
const name = form.get("name")?.toString()?.trim();
if (!name) return { error: "Name is required" };
const [created] = await db.insert(mappool).values({ name, createdBy: locals.user.id }).returning();
redirect(303, `/mappools/${created.id}`);
}
};
export {
actions,
load
};

View File

@@ -0,0 +1,34 @@
import { e as escape_html, a as ensure_array_like, b as attr, s as stringify } from "../../../../chunks/index3.js";
import "@sveltejs/kit/internal";
import "../../../../chunks/url.js";
import "../../../../chunks/utils.js";
import "@sveltejs/kit/internal/server";
import "../../../../chunks/root.js";
import "../../../../chunks/exports.js";
import "../../../../chunks/state.svelte.js";
function _page($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let { data } = $$props;
$$renderer2.push(`<div class="mx-auto max-w-4xl"><div class="flex items-center justify-between"><div><h1 class="text-2xl font-700 tracking-tight">Mappools</h1> <p class="mt-1 text-sm text-text-secondary">Create and manage your beatmap pools</p></div> <button class="rounded-md bg-accent px-4 py-2 text-sm font-600 text-surface-900 transition-colors hover:bg-accent-hover">${escape_html("New Pool")}</button></div> `);
{
$$renderer2.push("<!--[!-->");
}
$$renderer2.push(`<!--]--> <div class="mt-6 flex flex-col gap-3">`);
const each_array = ensure_array_like(data.mappools);
if (each_array.length !== 0) {
$$renderer2.push("<!--[-->");
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
let pool = each_array[$$index];
$$renderer2.push(`<a${attr("href", `/mappools/${stringify(pool.id)}`)} class="group flex items-center justify-between rounded-lg border border-border bg-surface-800 p-4 transition-colors hover:border-accent/40 hover:bg-surface-700"><div><h2 class="text-sm font-600">${escape_html(pool.name)}</h2> <p class="mt-1 text-xs text-text-secondary">${escape_html(pool.slots.length)} map${escape_html(pool.slots.length !== 1 ? "s" : "")}
· Created ${escape_html(new Date(pool.createdAt).toLocaleDateString())}</p></div> <span class="text-text-secondary transition-colors group-hover:text-accent">→</span></a>`);
}
} else {
$$renderer2.push("<!--[!-->");
$$renderer2.push(`<div class="rounded-lg border border-dashed border-border py-12 text-center"><p class="text-sm text-text-secondary">No mappools yet. Create one to get started.</p></div>`);
}
$$renderer2.push(`<!--]--></div></div>`);
});
}
export {
_page as default
};