2026-07-08 07:05:48 +08:00
|
|
|
|
"use server";
|
|
|
|
|
|
|
|
|
|
|
|
import { modrinthClient, curseforgeClient } from "./clients";
|
2026-07-11 09:23:12 +08:00
|
|
|
|
import { getLoaders, getGameVersions as getModrinthGameVersions } from "@/lib/modrinth";
|
|
|
|
|
|
import { getVersionTypes, getGameVersions, getMinecraftVersions } from "@/lib/curseforge";
|
|
|
|
|
|
import { SemVer } from "@/lib/utils/templates/semver";
|
2026-07-13 09:29:00 +08:00
|
|
|
|
import { Environment, EnvironmentSchema } from "@/types";
|
2026-07-08 07:05:48 +08:00
|
|
|
|
|
2026-07-13 09:29:00 +08:00
|
|
|
|
const ENVIRONMENT_LABELS: Record<Environment, string> = {
|
2026-07-08 07:05:48 +08:00
|
|
|
|
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<string[]> {
|
|
|
|
|
|
const loaders = await getLoaders(modrinthClient);
|
|
|
|
|
|
return loaders.map((l) => l.name);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-11 09:23:12 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 获取 Modrinth 支持的 Minecraft 版本号列表。
|
|
|
|
|
|
* 用于 ConfigModal 中 game_versions 多选下拉框的选项。
|
|
|
|
|
|
*/
|
|
|
|
|
|
export async function getModrinthMcVersions(): Promise<string[]> {
|
|
|
|
|
|
const versions = await getModrinthGameVersions(modrinthClient);
|
|
|
|
|
|
return versions
|
|
|
|
|
|
.filter((v) => v.version_type === "release")
|
|
|
|
|
|
.map((v) => v.version);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-08 07:05:48 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 获取 Modrinth 运行环境枚举值,转为 Ant Design Select 的选项格式。
|
|
|
|
|
|
* 前端使用 OptGroup 分组显示(Client / Server / Both / Other)。
|
|
|
|
|
|
*/
|
2026-07-13 09:29:00 +08:00
|
|
|
|
export async function getModrinthEnvironments() {
|
2026-07-08 07:05:48 +08:00
|
|
|
|
return EnvironmentSchema.options.map((value) => ({
|
|
|
|
|
|
value,
|
2026-07-13 09:29:00 +08:00
|
|
|
|
label: ENVIRONMENT_LABELS[value],
|
2026-07-08 07:05:48 +08:00
|
|
|
|
}));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取 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 };
|
|
|
|
|
|
}
|
2026-07-11 09:23:12 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取 CurseForge 支持的 Minecraft 版本号列表。
|
|
|
|
|
|
* 通过 /v1/minecraft/version 接口获取,
|
|
|
|
|
|
* 并排除 versionString 包含 "preRelease" 的预发布版本。
|
|
|
|
|
|
*/
|
|
|
|
|
|
export async function getCurseForgeMcVersions(): Promise<string[]> {
|
|
|
|
|
|
const versions = await getMinecraftVersions(curseforgeClient);
|
|
|
|
|
|
return versions
|
|
|
|
|
|
.filter((v) => {
|
|
|
|
|
|
const sv = SemVer.parse(v.versionString);
|
|
|
|
|
|
return sv.preRelease === null;
|
|
|
|
|
|
})
|
|
|
|
|
|
.map((v) => v.versionString);
|
|
|
|
|
|
}
|