You've already forked AstralRinth
forked from didirus/AstralRinth
Add support for snapshots with Modrinth Servers (#3570)
* Add support for snapshots with Modrinth Servers * Fix snapshots without dots * Fix loader version not resetting when no longer valid * Fix collapsing margins on Report page
This commit is contained in:
@@ -53,7 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex w-full flex-col gap-2 rounded-2xl bg-table-alternateRow p-4">
|
<div class="flex w-full flex-col gap-2 rounded-2xl bg-table-alternateRow p-4">
|
||||||
<div class="text-sm font-bold text-contrast">Minecraft version</div>
|
<div class="text-lg font-bold text-contrast">Minecraft version</div>
|
||||||
<UiServersTeleportDropdownMenu
|
<UiServersTeleportDropdownMenu
|
||||||
v-model="selectedMCVersion"
|
v-model="selectedMCVersion"
|
||||||
name="mcVersion"
|
name="mcVersion"
|
||||||
@@ -61,6 +61,20 @@
|
|||||||
class="w-full max-w-[100%]"
|
class="w-full max-w-[100%]"
|
||||||
placeholder="Select Minecraft version..."
|
placeholder="Select Minecraft version..."
|
||||||
/>
|
/>
|
||||||
|
<div class="mt-2 flex items-center justify-between gap-2">
|
||||||
|
<label for="toggle-snapshots" class="font-semibold"> Show snapshot versions </label>
|
||||||
|
<div
|
||||||
|
v-tooltip="
|
||||||
|
isSnapshotSelected ? 'A snapshot version is currently selected.' : undefined
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<Toggle
|
||||||
|
id="toggle-snapshots"
|
||||||
|
v-model="showSnapshots"
|
||||||
|
:disabled="isSnapshotSelected"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -74,7 +88,7 @@
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<div class="text-sm font-bold text-contrast">{{ selectedLoader }} version</div>
|
<div class="text-lg font-bold text-contrast">{{ selectedLoader }} version</div>
|
||||||
|
|
||||||
<template v-if="!selectedMCVersion">
|
<template v-if="!selectedMCVersion">
|
||||||
<div
|
<div
|
||||||
@@ -177,8 +191,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { BackupWarning, ButtonStyled, NewModal } from "@modrinth/ui";
|
import { BackupWarning, ButtonStyled, NewModal, Toggle } from "@modrinth/ui";
|
||||||
import { RightArrowIcon, XIcon, ServerIcon, DropdownIcon } from "@modrinth/assets";
|
import { DropdownIcon, RightArrowIcon, ServerIcon, XIcon } from "@modrinth/assets";
|
||||||
|
import { $fetch } from "ofetch";
|
||||||
import type { Server } from "~/composables/pyroServers";
|
import type { Server } from "~/composables/pyroServers";
|
||||||
import type { Loaders } from "~/types/servers";
|
import type { Loaders } from "~/types/servers";
|
||||||
import type { BackupInProgressReason } from "~/pages/servers/manage/[id].vue";
|
import type { BackupInProgressReason } from "~/pages/servers/manage/[id].vue";
|
||||||
@@ -214,6 +229,7 @@ const hardReset = ref(false);
|
|||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
const loadingServerCheck = ref(false);
|
const loadingServerCheck = ref(false);
|
||||||
const serverCheckError = ref("");
|
const serverCheckError = ref("");
|
||||||
|
const showSnapshots = ref(false);
|
||||||
|
|
||||||
const selectedLoader = ref<Loaders>("Vanilla");
|
const selectedLoader = ref<Loaders>("Vanilla");
|
||||||
const selectedMCVersion = ref("");
|
const selectedMCVersion = ref("");
|
||||||
@@ -226,6 +242,22 @@ const cachedVersions = ref<VersionCache>({});
|
|||||||
|
|
||||||
const versionStrings = ["forge", "fabric", "quilt", "neo"] as const;
|
const versionStrings = ["forge", "fabric", "quilt", "neo"] as const;
|
||||||
|
|
||||||
|
const isSnapshotSelected = computed(() => {
|
||||||
|
if (selectedMCVersion.value) {
|
||||||
|
const selected = tags.value.gameVersions.find((x) => x.version === selectedMCVersion.value);
|
||||||
|
if (selected?.version_type !== "release") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
const getLoaderVersions = async (loader: string) => {
|
||||||
|
return await $fetch(
|
||||||
|
`https://launcher-meta.modrinth.com/${loader?.toLowerCase()}/v0/manifest.json`,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const fetchLoaderVersions = async () => {
|
const fetchLoaderVersions = async () => {
|
||||||
const versions = await Promise.all(
|
const versions = await Promise.all(
|
||||||
versionStrings.map(async (loader) => {
|
versionStrings.map(async (loader) => {
|
||||||
@@ -234,7 +266,7 @@ const fetchLoaderVersions = async () => {
|
|||||||
throw new Error("Failed to fetch loader versions");
|
throw new Error("Failed to fetch loader versions");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const res = await $fetch(`/loader-versions?loader=${loader}`);
|
const res = await getLoaderVersions(loader);
|
||||||
return { [loader]: (res as any).gameVersions };
|
return { [loader]: (res as any).gameVersions };
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
@@ -277,11 +309,11 @@ const fetchPurpurVersions = async (mcVersion: string) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectedLoaderVersions = computed(() => {
|
const selectedLoaderVersions = computed<string[]>(() => {
|
||||||
const loader = selectedLoader.value.toLowerCase();
|
const loader = selectedLoader.value.toLowerCase();
|
||||||
|
|
||||||
if (loader === "paper") {
|
if (loader === "paper") {
|
||||||
return paperVersions.value[selectedMCVersion.value] || [];
|
return paperVersions.value[selectedMCVersion.value].map((x) => `${x}`) || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loader === "purpur") {
|
if (loader === "purpur") {
|
||||||
@@ -325,13 +357,22 @@ watch(selectedLoader, async () => {
|
|||||||
watch(
|
watch(
|
||||||
selectedLoaderVersions,
|
selectedLoaderVersions,
|
||||||
(newVersions) => {
|
(newVersions) => {
|
||||||
if (newVersions.length > 0 && !selectedLoaderVersion.value) {
|
if (
|
||||||
|
newVersions.length > 0 &&
|
||||||
|
(!selectedLoaderVersion.value || !newVersions.includes(selectedLoaderVersion.value))
|
||||||
|
) {
|
||||||
selectedLoaderVersion.value = String(newVersions[0]);
|
selectedLoaderVersion.value = String(newVersions[0]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const getLoaderVersion = async (loader: string, version: string) => {
|
||||||
|
return await $fetch(
|
||||||
|
`https://launcher-meta.modrinth.com/${loader?.toLowerCase()}/v0/versions/${version}.json`,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const checkVersionAvailability = async (version: string) => {
|
const checkVersionAvailability = async (version: string) => {
|
||||||
if (!version || version.trim().length < 3) return;
|
if (!version || version.trim().length < 3) return;
|
||||||
|
|
||||||
@@ -339,9 +380,7 @@ const checkVersionAvailability = async (version: string) => {
|
|||||||
loadingServerCheck.value = true;
|
loadingServerCheck.value = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const mcRes =
|
const mcRes = cachedVersions.value[version] || (await getLoaderVersion("minecraft", version));
|
||||||
cachedVersions.value[version] ||
|
|
||||||
(await $fetch(`/loader-versions?loader=minecraft&version=${version}`));
|
|
||||||
|
|
||||||
cachedVersions.value[version] = mcRes;
|
cachedVersions.value[version] = mcRes;
|
||||||
|
|
||||||
@@ -377,13 +416,15 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const tags = useTags();
|
const tags = useTags();
|
||||||
const mcVersions = tags.value.gameVersions
|
const mcVersions = computed(() =>
|
||||||
.filter((x) => x.version_type === "release")
|
tags.value.gameVersions
|
||||||
.map((x) => x.version)
|
.filter((x) =>
|
||||||
.filter((x) => {
|
showSnapshots.value
|
||||||
const segment = parseInt(x.split(".")[1], 10);
|
? x.version_type === "snapshot" || x.version_type === "release"
|
||||||
return !isNaN(segment) && segment > 2;
|
: x.version_type === "release",
|
||||||
});
|
)
|
||||||
|
.map((x) => x.version),
|
||||||
|
);
|
||||||
|
|
||||||
const isDangerous = computed(() => hardReset.value);
|
const isDangerous = computed(() => hardReset.value);
|
||||||
const canInstall = computed(() => {
|
const canInstall = computed(() => {
|
||||||
@@ -448,6 +489,9 @@ const handleReinstall = async () => {
|
|||||||
|
|
||||||
const onShow = () => {
|
const onShow = () => {
|
||||||
selectedMCVersion.value = props.server.general?.mc_version || "";
|
selectedMCVersion.value = props.server.general?.mc_version || "";
|
||||||
|
if (isSnapshotSelected.value) {
|
||||||
|
showSnapshots.value = true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onHide = () => {
|
const onHide = () => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<div class="experimental-styles-within flex flex-col gap-2">
|
<div class="experimental-styles-within flex flex-col gap-2">
|
||||||
<RadialHeader class="top-box mb-2 text-center" color="orange">
|
<RadialHeader class="top-box mb-2 flex flex-col items-center justify-center" color="orange">
|
||||||
<ScaleIcon class="h-12 w-12 text-brand-orange" />
|
<ScaleIcon class="h-12 w-12 text-brand-orange" />
|
||||||
<h1 class="m-3 gap-2 text-3xl font-extrabold">
|
<h1 class="m-3 gap-2 text-3xl font-extrabold">
|
||||||
{{
|
{{
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
const getLoaderVersions = async (loader: string) => {
|
|
||||||
const loaderVersions = await fetch(
|
|
||||||
`https://launcher-meta.modrinth.com/${loader?.toLowerCase()}/v0/manifest.json`,
|
|
||||||
);
|
|
||||||
return loaderVersions.json();
|
|
||||||
};
|
|
||||||
|
|
||||||
const getLoaderVersion = async (loader: string, version: string) => {
|
|
||||||
const loaderVersion = await fetch(
|
|
||||||
`https://launcher-meta.modrinth.com/${loader?.toLowerCase()}/v0/versions/${version}.json`,
|
|
||||||
);
|
|
||||||
return loaderVersion.json();
|
|
||||||
};
|
|
||||||
|
|
||||||
export default defineEventHandler(async (e) => {
|
|
||||||
const params = new URLSearchParams(e._path?.split("?")[1] ?? "");
|
|
||||||
if (!params.has("loader"))
|
|
||||||
return new Response(
|
|
||||||
JSON.stringify({
|
|
||||||
error: "Missing loader",
|
|
||||||
}),
|
|
||||||
{ status: 400, headers: { "Content-Type": "application/json" } },
|
|
||||||
);
|
|
||||||
const loader = params.get("loader");
|
|
||||||
const version = params.get("version");
|
|
||||||
if (version) {
|
|
||||||
const loaderVersion = await getLoaderVersion(loader!, version);
|
|
||||||
return new Response(JSON.stringify(loaderVersion), {
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const loaderVersions = await getLoaderVersions(loader!);
|
|
||||||
return new Response(JSON.stringify(loaderVersions), {
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user