"use server"; import { modrinthClient, curseforgeClient } from "./clients"; import { getLoaders, getGameVersions as getModrinthGameVersions } from "@/lib/modrinth"; import { getVersionTypes, getGameVersions, getMinecraftVersions } from "@/lib/curseforge"; import { SemVer } from "@/lib/utils/templates/semver"; import { EnvironmentSchema } from "@/types"; const ENVIRONMENT_LABELS: Record = { unknown: "Unknown environment", client_only: "Client-side only", server_only: "Server-side only (singleplayer compatible)", dedicated_server_only: "Dedicated server only", client_and_server: "Required on both", server_only_client_optional: "Optional on client", client_only_server_optional: "Optional on server", client_or_server_prefers_both: "Optional on both (prefers both)", client_or_server: "Optional on both (either side)", singleplayer_only: "Singleplayer only", }; /** * 获取 Modrinth 支持的加载器名称列表。 * 用于 ConfigModal 中 loaders 多选下拉框的选项。 */ export async function getModrinthLoaders(): Promise { const loaders = await getLoaders(modrinthClient); return loaders.map((l) => l.name); } /** * 获取 Modrinth 支持的 Minecraft 版本号列表。 * 用于 ConfigModal 中 game_versions 多选下拉框的选项。 */ export async function getModrinthMcVersions(): Promise { const versions = await getModrinthGameVersions(modrinthClient); return versions .filter((v) => v.version_type === "release") .map((v) => v.version); } /** * 获取 Modrinth 运行环境枚举值,转为 Ant Design Select 的选项格式。 * 前端使用 OptGroup 分组显示(Client / Server / Both / Other)。 */ export async function getModrinthEnvironments(): Promise< { value: string; label: string }[] > { return EnvironmentSchema.options.map((value) => ({ value, label: ENVIRONMENT_LABELS[value] ?? value, })); } /** * 获取 CurseForge 的运行环境和加载器选项。 * 从 Game Version Types 中找到 Environment / Modloader 分类 ID, * 再从 Game Versions 中按 gameVersionTypeID 过滤出对应值。 */ export async function getCurseForgeMeta(): Promise<{ environments: string[]; loaders: string[]; }> { const [versionTypes, gameVersions] = await Promise.all([ getVersionTypes(curseforgeClient), getGameVersions(curseforgeClient), ]); const environmentTypeId = versionTypes.find( (t) => t.name === "Environment", )?.id; const modloaderTypeId = versionTypes.find( (t) => t.name === "Modloader", )?.id; const environments = environmentTypeId != null ? gameVersions .filter((v) => v.gameVersionTypeID === environmentTypeId) .map((v) => v.name) : []; const loaders = modloaderTypeId != null ? gameVersions .filter((v) => v.gameVersionTypeID === modloaderTypeId) .map((v) => v.name) : []; return { environments, loaders }; } /** * 获取 CurseForge 支持的 Minecraft 版本号列表。 * 通过 /v1/minecraft/version 接口获取, * 并排除 versionString 包含 "preRelease" 的预发布版本。 */ export async function getCurseForgeMcVersions(): Promise { const versions = await getMinecraftVersions(curseforgeClient); return versions .filter((v) => { const sv = SemVer.parse(v.versionString); return sv.preRelease === null; }) .map((v) => v.versionString); }