import { EmbedBuilder, SlashCommandBuilder } from "discord.js"; import fs from "fs/promises"; import { t, getLang } from "../util/i18n.js"; export default { name: "top", description: "Zeigt die meistgeladenen/bestbewerteten beobachteten Plugins", aliases: [], guild: ["all"], nsfw: false, user_permissions: [], bot_permissions: [], args_required: 0, args_usage: "[-r] -r = nach Bewertung sortieren", cooldown: 10, data: new SlashCommandBuilder() .setName("top") .setDescription("Shows the top watched plugins by downloads or rating") .addStringOption((opt) => opt .setName("sortierung") .setDescription("Sortierung") .setRequired(false) .addChoices( { name: "⬇️ Downloads", value: "downloads" }, { name: "⭐ Bewertung", value: "rating" } ) ), async execute(client, ctx, args) { const guildID = ctx.guild.id; const filePath = `./serverdata/${guildID}.json`; let saveData; try { const raw = await fs.readFile(filePath, "utf8"); saveData = JSON.parse(raw); } catch { return ctx.reply("Dieser Server hat keine beobachteten Ressourcen."); } const lang = getLang(saveData); const sortBy = ctx.isSlash ? (ctx.interaction.options.getString("sortierung") ?? "downloads") : (args.includes("-r") ? "rating" : "downloads"); const watched = saveData.watchedResources; if (!watched || watched.length === 0) { return ctx.reply(t(lang, "top.noData")); } // Fetch stats for all watched resources const results = []; for (const w of watched) { try { const res = await fetch(`https://api.spiget.org/v2/resources/${w.resourceID}`); if (!res.ok) continue; const data = await res.json(); results.push({ id: w.resourceID, name: data.name ?? w.resourceName ?? w.resourceID, downloads: data.downloads ?? 0, rating: data.rating?.average ?? 0, version: w.lastCheckedVersion ?? "?", channelID: w.channelID, }); await new Promise((r) => setTimeout(r, 300)); } catch { /* Plugin überspringen */ } } if (results.length === 0) { return ctx.reply(t(lang, "error.apiDown")); } // Sort results.sort((a, b) => sortBy === "rating" ? b.rating - a.rating : b.downloads - a.downloads ); const sortLabel = t(lang, sortBy === "rating" ? "top.rating" : "top.downloads"); const medal = ["🥇", "🥈", "🥉"]; const list = results.map((r, i) => { const icon = medal[i] ?? `${i + 1}.`; const dl = r.downloads.toLocaleString("de-DE"); const stars = r.rating > 0 ? `⭐ ${r.rating.toFixed(1)}` : "⭐ –"; return `${icon} **${r.name}** (v${r.version})\n⬇️ ${dl} ${stars} 🆔 \`${r.id}\``; }).join("\n\n"); const embed = new EmbedBuilder() .setColor(ctx.guild.members.me.displayHexColor) .setTitle(t(lang, "top.title", { sort: sortLabel })) .setDescription(list) .setFooter({ text: `${results.length} Plugins • ${client.config.prefix}plugin [id] für Details` }) .setTimestamp(); return ctx.reply({ embeds: [embed] }); }, };