import { EmbedBuilder, SlashCommandBuilder } from "discord.js"; import fs from "fs"; import { t, getLang } from "../util/i18n.js"; import { generateAvatarLink, generateAuthorURL, generateResourceIconURL, } from "../util/helpers.js"; import { Spiget } from "spiget"; const spiget = new Spiget("Viper-Network"); export default { name: "check", description: "Prüft ob ein Plugin mit einer Minecraft-Version kompatibel ist", aliases: [], guild: ["all"], nsfw: false, user_permissions: [], bot_permissions: [], args_required: 1, args_usage: "[ressourcen_id] [mc-version] Beispiel: vn!check 72678 1.21", cooldown: 5, data: new SlashCommandBuilder() .setName("check") .setDescription("Checks if a plugin is compatible with a Minecraft version") .addStringOption((opt) => opt.setName("ressourcen_id").setDescription("Spiget Ressourcen-ID").setRequired(true) ) .addStringOption((opt) => opt .setName("mc_version") .setDescription("Minecraft-Version (z.B. 1.21) – leer = aktuellste prüfen") .setRequired(false) ), async execute(client, ctx, args) { const guildID = ctx.guild.id; const lang = loadLang(guildID); const resourceID = ctx.isSlash ? ctx.interaction.options.getString("ressourcen_id") : args[0]; const mcVersion = ctx.isSlash ? (ctx.interaction.options.getString("mc_version") ?? null) : (args[1] ?? null); // Fetch resource details from Spiget let resource, author; try { resource = await spiget.getResource(resourceID); author = await resource.getAuthor(); } catch { return ctx.reply(t(lang, "error.invalidID", { id: resourceID })); } // Fetch full resource data for tested versions let data; try { const res = await fetch(`https://api.spiget.org/v2/resources/${resourceID}`); if (!res.ok) throw new Error(); data = await res.json(); } catch { return ctx.reply(t(lang, "error.apiDown")); } // testedVersions is a string like "1.8 - 1.21" or array const testedRaw = data.testedVersions ?? []; const tested = Array.isArray(testedRaw) ? testedRaw : [testedRaw]; // Supported versions from tags/description often contains "1.x" const supportedVersions = tested.length > 0 ? tested.join(", ") : "Keine Angabe"; // Determine compatibility for requested version let compatStatus; let compatColor; if (mcVersion) { const matches = tested.some((v) => { // Handle ranges like "1.8-1.21" or "1.8 - 1.21" const rangeMatch = v.match(/(\d+\.\d+)\s*[-–]\s*(\d+\.\d+)/); if (rangeMatch) { const [, from, to] = rangeMatch; return compareVersions(mcVersion, from) >= 0 && compareVersions(mcVersion, to) <= 0; } // Exact match or starts-with return v.trim().startsWith(mcVersion.trim()); }); if (tested.length === 0) { compatStatus = t(lang, "check.unknown"); compatColor = "#FFA500"; } else if (matches) { compatStatus = t(lang, "check.compatible"); compatColor = "#00FF00"; } else { compatStatus = t(lang, "check.incompatible"); compatColor = "#FF0000"; } } else { compatStatus = tested.length > 0 ? `${t(lang, "check.compatible")} (${supportedVersions})` : t(lang, "check.unknown"); compatColor = tested.length > 0 ? "#00FF00" : "#FFA500"; } const authorURL = generateAuthorURL(author.name, author.id); const authorAvatarURL = generateAvatarLink(author.id); const resourceIconURL = generateResourceIconURL(resource); const resourceURL = `https://spigotmc.org/resources/.${resourceID}/`; const fields = [ { name: t(lang, "check.supportedVersions"), value: supportedVersions, inline: false, }, ]; if (mcVersion) { fields.unshift({ name: `Minecraft ${mcVersion}`, value: compatStatus, inline: false, }); } fields.push( { name: "📦 Version", value: data.version?.id ?? "?", inline: true }, { name: "⬇️ Download", value: resourceURL, inline: true } ); const embed = new EmbedBuilder() .setAuthor({ name: t(lang, "general.author", { name: author.name }), iconURL: authorAvatarURL, url: authorURL }) .setColor(compatColor) .setTitle(t(lang, "check.title", { name: resource.name })) .setDescription(resource.tag) .addFields(fields) .setThumbnail(resourceIconURL) .setTimestamp(); return ctx.reply({ embeds: [embed] }); }, }; /** Vergleicht zwei Versions-Strings (z.B. "1.8" und "1.21") */ function compareVersions(a, b) { const pa = a.split(".").map(Number); const pb = b.split(".").map(Number); for (let i = 0; i < Math.max(pa.length, pb.length); i++) { const diff = (pa[i] ?? 0) - (pb[i] ?? 0); if (diff !== 0) return diff; } return 0; } function loadLang(guildID) { try { const data = JSON.parse(fs.readFileSync(`./serverdata/${guildID}.json`, "utf8")); return getLang(data); } catch { return "de"; } }