import { EmbedBuilder, SlashCommandBuilder } from "discord.js"; import fs from "fs"; import { t, getLang } from "../util/i18n.js"; import { generateResourceIconURL } from "../util/helpers.js"; import { Spiget } from "spiget"; const spiget = new Spiget("Viper-Network"); export default { name: "compare", description: "Vergleicht zwei Plugins nebeneinander", aliases: ["cmp"], guild: ["all"], nsfw: false, user_permissions: [], bot_permissions: [], args_required: 2, args_usage: "[id1] [id2] Beispiel: vn!compare 72678 34315", cooldown: 10, data: new SlashCommandBuilder() .setName("compare") .setDescription("Compares two plugins side by side") .addStringOption((opt) => opt.setName("id1").setDescription("Erste Ressourcen-ID").setRequired(true) ) .addStringOption((opt) => opt.setName("id2").setDescription("Zweite Ressourcen-ID").setRequired(true) ), async execute(client, ctx, args) { const lang = loadLang(ctx.guild.id); const id1 = ctx.isSlash ? ctx.interaction.options.getString("id1") : args[0]; const id2 = ctx.isSlash ? ctx.interaction.options.getString("id2") : args[1]; // Fetch both resources in parallel let [dataA, dataB] = await Promise.all([ fetchResource(id1), fetchResource(id2), ]); if (!dataA) return ctx.reply(t(lang, "error.invalidID", { id: id1 })); if (!dataB) return ctx.reply(t(lang, "error.invalidID", { id: id2 })); // Fetch latest versions const [verA, verB] = await Promise.all([ fetchVersion(id1), fetchVersion(id2), ]); dataA.latestVersion = verA; dataB.latestVersion = verB; // Helper: format a stat with winner indicator const win = (valA, valB, higherIsBetter = true) => { if (valA === valB) return ["–", "–"]; const aWins = higherIsBetter ? valA > valB : valA < valB; return aWins ? ["🏆", ""] : ["", "🏆"]; }; const [dlWinA, dlWinB] = win(dataA.downloads, dataB.downloads); const [rtWinA, rtWinB] = win(dataA.rating?.average ?? 0, dataB.rating?.average ?? 0); const dateA = dataA.updateDate ? new Date(dataA.updateDate * 1000).toLocaleDateString("de-DE") : "?"; const dateB = dataB.updateDate ? new Date(dataB.updateDate * 1000).toLocaleDateString("de-DE") : "?"; const [dtWinA, dtWinB] = win(dataA.updateDate ?? 0, dataB.updateDate ?? 0); const dlA = (dataA.downloads ?? 0).toLocaleString("de-DE"); const dlB = (dataB.downloads ?? 0).toLocaleString("de-DE"); const rtA = dataA.rating?.average?.toFixed(1) ?? "–"; const rtB = dataB.rating?.average?.toFixed(1) ?? "–"; const embed = new EmbedBuilder() .setColor(ctx.guild.members.me.displayHexColor) .setTitle(t(lang, "compare.title")) .addFields([ // Header row { name: "📦 Plugin", value: `**${dataA.name}**`, inline: true }, { name: "\u200b", value: "**vs**", inline: true }, { name: "\u200b", value: `**${dataB.name}**`, inline: true }, // Downloads { name: t(lang, "compare.downloads"), value: `${dlWinA} ${dlA}`, inline: true }, { name: "\u200b", value: "⬇️", inline: true }, { name: "\u200b", value: `${dlWinB} ${dlB}`, inline: true }, // Rating { name: t(lang, "compare.rating"), value: `${rtWinA} ⭐ ${rtA}`, inline: true }, { name: "\u200b", value: "⭐", inline: true }, { name: "\u200b", value: `${rtWinB} ⭐ ${rtB}`, inline: true }, // Version { name: t(lang, "compare.version"), value: `v${verA ?? "?"}`, inline: true }, { name: "\u200b", value: "📦", inline: true }, { name: "\u200b", value: `v${verB ?? "?"}`, inline: true }, // Last update { name: t(lang, "compare.updated"), value: `${dtWinA} ${dateA}`, inline: true }, { name: "\u200b", value: "🕐", inline: true }, { name: "\u200b", value: `${dtWinB} ${dateB}`, inline: true }, // Links { name: "🔗 Link", value: `[SpigotMC](https://spigotmc.org/resources/.${id1}/)`, inline: true }, { name: "\u200b", value: "\u200b", inline: true }, { name: "\u200b", value: `[SpigotMC](https://spigotmc.org/resources/.${id2}/)`, inline: true }, ]) .setFooter({ text: `IDs: ${id1} vs ${id2}` }) .setTimestamp(); return ctx.reply({ embeds: [embed] }); }, }; async function fetchResource(id) { try { const res = await fetch(`https://api.spiget.org/v2/resources/${id}`); if (!res.ok) return null; return await res.json(); } catch { return null; } } async function fetchVersion(id) { try { const res = await fetch(`https://api.spigotmc.org/legacy/update.php?resource=${id}`); if (!res.ok) return null; return (await res.text()).trim(); } catch { return null; } } function loadLang(guildID) { try { const data = JSON.parse(fs.readFileSync(`./serverdata/${guildID}.json`, "utf8")); return getLang(data); } catch { return "de"; } }