From 23629cf40d13492393872af24d203480b287f298 Mon Sep 17 00:00:00 2001 From: Johan le stickman Date: Sun, 10 Sep 2023 00:13:29 +0200 Subject: [PATCH] Changement de bcp de choses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Passage d'eslint, correction de typos, changement de domaine, utilisation de nouvelles propriétés Bachero, changement de domaine, dépréciation de "longDescription" et suppression des "onloadMessage" vide --- .../autolink-config.js | 4 +- modules/bachero.module.autolink/autolink.js | 2 +- .../bachero.module.autolink/manifest.jsonc | 4 - modules/bachero.module.botInfo/botinfo.js | 4 +- modules/bachero.module.botInfo/manifest.jsonc | 4 - modules/bachero.module.colorInfo/color.js | 162 ++++----- .../bachero.module.colorInfo/manifest.jsonc | 4 - .../contributeurs.js | 2 +- .../manifest.jsonc | 3 - modules/bachero.module.databaseTest/delete.js | 26 +- modules/bachero.module.databaseTest/get.js | 26 +- modules/bachero.module.databaseTest/getAll.js | 20 +- modules/bachero.module.databaseTest/has.js | 26 +- .../manifest.jsonc | 1 - modules/bachero.module.databaseTest/set.js | 32 +- modules/bachero.module.discordWhois/main.js | 16 +- .../manifest.jsonc | 4 - modules/bachero.module.fake/fake-config.js | 38 +-- modules/bachero.module.fake/fake.js | 104 +++--- modules/bachero.module.fake/manifest.jsonc | 4 - modules/bachero.module.help/help.js | 80 ++--- modules/bachero.module.help/manifest.jsonc | 4 - modules/bachero.module.issue/manifest.jsonc | 4 - modules/bachero.module.issue/report.js | 40 +-- .../bachero.module.level/level-leaderboard.js | 6 +- modules/bachero.module.level/level-manage.js | 2 +- modules/bachero.module.level/manifest.jsonc | 3 - modules/bachero.module.lyrics/lyrics.js | 67 ++-- modules/bachero.module.lyrics/manifest.jsonc | 4 - modules/bachero.module.message/clear.js | 60 ++-- modules/bachero.module.message/embed.js | 186 +++++----- modules/bachero.module.message/first.js | 42 ++- modules/bachero.module.message/manifest.jsonc | 4 - modules/bachero.module.message/say.js | 56 +-- modules/bachero.module.message/slowmode.js | 34 +- .../bachero.module.minecraft/manifest.jsonc | 4 - modules/bachero.module.minecraft/mc-server.js | 72 ++-- .../bachero.module.moduleInfo/manifest.jsonc | 4 - modules/bachero.module.moduleInfo/module.js | 54 +-- modules/bachero.module.pfc/manifest.jsonc | 4 - modules/bachero.module.pfc/pfc.js | 142 ++++---- modules/bachero.module.ping/manifest.jsonc | 6 +- modules/bachero.module.ping/ping.js | 60 ++-- modules/bachero.module.short/manifest.jsonc | 4 - modules/bachero.module.short/short.js | 54 ++- .../bachero.module.showReports/manifest.jsonc | 4 - .../bachero.module.showReports/showInfo.js | 30 +- modules/bachero.module.snipe/manifest.jsonc | 4 - modules/bachero.module.snipe/snipe-config.js | 46 +-- modules/bachero.module.snipe/snipe.js | 141 ++++---- .../bachero.module.textCommand/manifest.jsonc | 4 - .../bachero.module.textCommand/slashtotext.js | 36 +- modules/bachero.module.timer/manifest.jsonc | 4 - modules/bachero.module.timer/timer.js | 233 ++++++------- modules/bachero.module.transports/divia.js | 2 +- modules/bachero.module.transports/fluo.js | 2 +- .../bachero.module.transports/manifest.jsonc | 5 - modules/bachero.module.transports/ratp.js | 322 ++++++++---------- .../bachero.module.typeracer/manifest.jsonc | 4 - modules/bachero.module.typeracer/typeracer.js | 230 ++++++------- modules/bachero.module.unshort/manifest.jsonc | 4 - modules/bachero.module.unshort/unshort.js | 63 ++-- modules/bachero.module.userinfo/avatar.js | 6 +- .../bachero.module.userinfo/manifest.jsonc | 4 - modules/bachero.module.userinfo/userinfo.js | 18 +- modules/el2zay.elbot/manifest.jsonc | 6 +- modules/el2zay.elbot/sondage.js | 4 +- 67 files changed, 1228 insertions(+), 1426 deletions(-) diff --git a/modules/bachero.module.autolink/autolink-config.js b/modules/bachero.module.autolink/autolink-config.js index 0a51573..3d19d2f 100644 --- a/modules/bachero.module.autolink/autolink-config.js +++ b/modules/bachero.module.autolink/autolink-config.js @@ -29,7 +29,7 @@ module.exports = { }) }, - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Vérifier si la fonctionnalité est activée var isEnabled = await bacheroFunctions.database.get(database, `enabled-${interaction.guild.id}`) @@ -37,7 +37,7 @@ module.exports = { // Créer un embed var embed = new EmbedBuilder() .setTitle("Configuration d'AutoLink") - .setColor(bacheroFunctions.config.getValue("bachero", "embedColor")) + .setColor(bacheroFunctions.colors.primary) if(isEnabled) embed.setDescription("La fonctionnalité AutoLink est activée sur l'ensemble de ce serveur.\nCelle-ci détecte les messages envoyés par n'importe qui sur votre serveur et en extrait certains liens, pour afficher des détails dans un embed.\n\n:warning: Les liens ne sont pas vérifiés et peuvent être malicieux.") else embed.setDescription("La fonctionnalité AutoLink est désactivée sur ce serveur.\nLorsqu'elle est activée, elle détecte les messages envoyés par les utilisateurs et en extrait certains liens, pour en afficher des détails simplifiés.\n\n:warning: Les liens ne sont pas vérifiés et peuvent être malicieux, à activer avec prudence.") diff --git a/modules/bachero.module.autolink/autolink.js b/modules/bachero.module.autolink/autolink.js index 1b0e0b9..692adfb 100644 --- a/modules/bachero.module.autolink/autolink.js +++ b/modules/bachero.module.autolink/autolink.js @@ -159,7 +159,7 @@ module.exports = { var embed = new EmbedBuilder() .setTitle(`AutoLink - ${links.length > 1 ? "Des liens ont été détectés" : "Un lien a été détecté"}`) .setDescription(description.join("\n\n").substring(0, 4000)) - .setColor(bacheroFunctions.config.getValue("bachero", "embedColor")) + .setColor(bacheroFunctions.colors.primary) .setFooter({ text: `${description.join("\n\n").length > 2000 ? "Les informations sont tronquées." : "Le contenu de ce message n'est pas vérifié"}. Informations obtenues grâce au message de ${message.author.discriminator == "0" ? message.author.username : message.author.tag} (ID: ${message.author.id}).` }) message.reply({ embeds: [embed] }).catch(err => {}) }) diff --git a/modules/bachero.module.autolink/manifest.jsonc b/modules/bachero.module.autolink/manifest.jsonc index 6b897e2..332fb69 100644 --- a/modules/bachero.module.autolink/manifest.jsonc +++ b/modules/bachero.module.autolink/manifest.jsonc @@ -10,10 +10,6 @@ // Description du module "shortDescription": "Détecte lorsqu'un utilisateur envoie un lien, et affiche des informations sur certains sites lorsque cela peut être utile", - "longDescription": "Détecte les messages contenant un lien, récupère des informations à partir de celui-ci et les envoie via un embed détaillé", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.botInfo/botinfo.js b/modules/bachero.module.botInfo/botinfo.js index a326f8a..a1f72a4 100644 --- a/modules/bachero.module.botInfo/botinfo.js +++ b/modules/bachero.module.botInfo/botinfo.js @@ -52,7 +52,7 @@ module.exports = { .setName("botinfo") .setDescription(`Fournis des informations sur ${bacheroFunctions.config.getValue("bachero", "botName")}`), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Obtenir le client du bot if(!botClient) botClient = bacheroFunctions.botClient.get() @@ -70,7 +70,7 @@ module.exports = { // Créer un embed pour afficher les informations var embed = new EmbedBuilder() .setTitle(`Informations sur ${bacheroFunctions.config.getValue("bachero", "botName")}${bacheroFunctions.config.getValue("bachero", "botName").trim().toLowerCase() == "bachero" ? "" : " *(par Bachero)*"}`) - .setColor(bacheroFunctions.config.getValue("bachero", "embedColor")) + .setColor(bacheroFunctions.colors.primary) var listFields = [ !hideStartTime ? { name: "Dernier démarrage", value: ``, inline: true } : null, cache.guildCount ? { name: "Statistiques Discord", value: `${cache.guildCount?.value} serveurs, ${cache.membersCount?.value} membres`, inline: true } : null, diff --git a/modules/bachero.module.botInfo/manifest.jsonc b/modules/bachero.module.botInfo/manifest.jsonc index d3deb1c..787d19c 100644 --- a/modules/bachero.module.botInfo/manifest.jsonc +++ b/modules/bachero.module.botInfo/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Ce module renvoie des informations sur le robot", - "longDescription": "Ajoute une commande (/botinfo) qui envoie de nombreuses informations sur le robot et son hébergement.", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.colorInfo/color.js b/modules/bachero.module.colorInfo/color.js index 1c0cc44..0808535 100644 --- a/modules/bachero.module.colorInfo/color.js +++ b/modules/bachero.module.colorInfo/color.js @@ -1,13 +1,13 @@ -const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js') -const convert = require('color-convert') +const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js") +const convert = require("color-convert") const cherangi = require("cherangi") // Fonction pour obtenir l'opposé d'une couleur const invertColor = (col) => { col = col.toLowerCase() - const colors = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'] - let inverseColor = '#' - col.replace('#','').split('').forEach(i => { + const colors = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"] + let inverseColor = "#" + col.replace("#", "").split("").forEach(i => { const index = colors.indexOf(i) inverseColor += colors.reverse()[index] }) @@ -18,7 +18,7 @@ const invertColor = (col) => { const getClosestColor = (hex) => { /* https://github.com/zhigang1992/nearestTailwindColor/blob/master/index.js */ // Liste des couleurs TailwindCSS - var colors = { black: '#000', white: '#fff', slate: { 50: '#f8fafc', 100: '#f1f5f9', 200: '#e2e8f0', 300: '#cbd5e1', 400: '#94a3b8', 500: '#64748b', 600: '#475569', 700: '#334155', 800: '#1e293b', 900: '#0f172a' }, gray: { 50: '#f9fafb', 100: '#f3f4f6', 200: '#e5e7eb', 300: '#d1d5db', 400: '#9ca3af', 500: '#6b7280', 600: '#4b5563', 700: '#374151', 800: '#1f2937', 900: '#111827' }, zinc: { 50: '#fafafa', 100: '#f4f4f5', 200: '#e4e4e7', 300: '#d4d4d8', 400: '#a1a1aa', 500: '#71717a', 600: '#52525b', 700: '#3f3f46', 800: '#27272a', 900: '#18181b' }, neutral: { 50: '#fafafa', 100: '#f5f5f5', 200: '#e5e5e5', 300: '#d4d4d4', 400: '#a3a3a3', 500: '#737373', 600: '#525252', 700: '#404040', 800: '#262626', 900: '#171717' }, stone: { 50: '#fafaf9', 100: '#f5f5f4', 200: '#e7e5e4', 300: '#d6d3d1', 400: '#a8a29e', 500: '#78716c', 600: '#57534e', 700: '#44403c', 800: '#292524', 900: '#1c1917' }, red: { 50: '#fef2f2', 100: '#fee2e2', 200: '#fecaca', 300: '#fca5a5', 400: '#f87171', 500: '#ef4444', 600: '#dc2626', 700: '#b91c1c', 800: '#991b1b', 900: '#7f1d1d' }, orange: { 50: '#fff7ed', 100: '#ffedd5', 200: '#fed7aa', 300: '#fdba74', 400: '#fb923c', 500: '#f97316', 600: '#ea580c', 700: '#c2410c', 800: '#9a3412', 900: '#7c2d12' }, amber: { 50: '#fffbeb', 100: '#fef3c7', 200: '#fde68a', 300: '#fcd34d', 400: '#fbbf24', 500: '#f59e0b', 600: '#d97706', 700: '#b45309', 800: '#92400e', 900: '#78350f' }, yellow: { 50: '#fefce8', 100: '#fef9c3', 200: '#fef08a', 300: '#fde047', 400: '#facc15', 500: '#eab308', 600: '#ca8a04', 700: '#a16207', 800: '#854d0e', 900: '#713f12' }, lime: { 50: '#f7fee7', 100: '#ecfccb', 200: '#d9f99d', 300: '#bef264', 400: '#a3e635', 500: '#84cc16', 600: '#65a30d', 700: '#4d7c0f', 800: '#3f6212', 900: '#365314' }, green: { 50: '#f0fdf4', 100: '#dcfce7', 200: '#bbf7d0', 300: '#86efac', 400: '#4ade80', 500: '#22c55e', 600: '#16a34a', 700: '#15803d', 800: '#166534', 900: '#14532d' }, emerald: { 50: '#ecfdf5', 100: '#d1fae5', 200: '#a7f3d0', 300: '#6ee7b7', 400: '#34d399', 500: '#10b981', 600: '#059669', 700: '#047857', 800: '#065f46', 900: '#064e3b' }, teal: { 50: '#f0fdfa', 100: '#ccfbf1', 200: '#99f6e4', 300: '#5eead4', 400: '#2dd4bf', 500: '#14b8a6', 600: '#0d9488', 700: '#0f766e', 800: '#115e59', 900: '#134e4a' }, cyan: { 50: '#ecfeff', 100: '#cffafe', 200: '#a5f3fc', 300: '#67e8f9', 400: '#22d3ee', 500: '#06b6d4', 600: '#0891b2', 700: '#0e7490', 800: '#155e75', 900: '#164e63' }, sky: { 50: '#f0f9ff', 100: '#e0f2fe', 200: '#bae6fd', 300: '#7dd3fc', 400: '#38bdf8', 500: '#0ea5e9', 600: '#0284c7', 700: '#0369a1', 800: '#075985', 900: '#0c4a6e' }, blue: { 50: '#eff6ff', 100: '#dbeafe', 200: '#bfdbfe', 300: '#93c5fd', 400: '#60a5fa', 500: '#3b82f6', 600: '#2563eb', 700: '#1d4ed8', 800: '#1e40af', 900: '#1e3a8a' }, indigo: { 50: '#eef2ff', 100: '#e0e7ff', 200: '#c7d2fe', 300: '#a5b4fc', 400: '#818cf8', 500: '#6366f1', 600: '#4f46e5', 700: '#4338ca', 800: '#3730a3', 900: '#312e81' }, violet: { 50: '#f5f3ff', 100: '#ede9fe', 200: '#ddd6fe', 300: '#c4b5fd', 400: '#a78bfa', 500: '#8b5cf6', 600: '#7c3aed', 700: '#6d28d9', 800: '#5b21b6', 900: '#4c1d95' }, purple: { 50: '#faf5ff', 100: '#f3e8ff', 200: '#e9d5ff', 300: '#d8b4fe', 400: '#c084fc', 500: '#a855f7', 600: '#9333ea', 700: '#7e22ce', 800: '#6b21a8', 900: '#581c87' }, fuchsia: { 50: '#fdf4ff', 100: '#fae8ff', 200: '#f5d0fe', 300: '#f0abfc', 400: '#e879f9', 500: '#d946ef', 600: '#c026d3', 700: '#a21caf', 800: '#86198f', 900: '#701a75' }, pink: { 50: '#fdf2f8', 100: '#fce7f3', 200: '#fbcfe8', 300: '#f9a8d4', 400: '#f472b6', 500: '#ec4899', 600: '#db2777', 700: '#be185d', 800: '#9d174d', 900: '#831843' }, rose: { 50: '#fff1f2', 100: '#ffe4e6', 200: '#fecdd3', 300: '#fda4af', 400: '#fb7185', 500: '#f43f5e', 600: '#e11d48', 700: '#be123c', 800: '#9f1239', 900: '#881337' } } + var colors = { black: "#000", white: "#fff", slate: { 50: "#f8fafc", 100: "#f1f5f9", 200: "#e2e8f0", 300: "#cbd5e1", 400: "#94a3b8", 500: "#64748b", 600: "#475569", 700: "#334155", 800: "#1e293b", 900: "#0f172a" }, gray: { 50: "#f9fafb", 100: "#f3f4f6", 200: "#e5e7eb", 300: "#d1d5db", 400: "#9ca3af", 500: "#6b7280", 600: "#4b5563", 700: "#374151", 800: "#1f2937", 900: "#111827" }, zinc: { 50: "#fafafa", 100: "#f4f4f5", 200: "#e4e4e7", 300: "#d4d4d8", 400: "#a1a1aa", 500: "#71717a", 600: "#52525b", 700: "#3f3f46", 800: "#27272a", 900: "#18181b" }, neutral: { 50: "#fafafa", 100: "#f5f5f5", 200: "#e5e5e5", 300: "#d4d4d4", 400: "#a3a3a3", 500: "#737373", 600: "#525252", 700: "#404040", 800: "#262626", 900: "#171717" }, stone: { 50: "#fafaf9", 100: "#f5f5f4", 200: "#e7e5e4", 300: "#d6d3d1", 400: "#a8a29e", 500: "#78716c", 600: "#57534e", 700: "#44403c", 800: "#292524", 900: "#1c1917" }, red: { 50: "#fef2f2", 100: "#fee2e2", 200: "#fecaca", 300: "#fca5a5", 400: "#f87171", 500: "#ef4444", 600: "#dc2626", 700: "#b91c1c", 800: "#991b1b", 900: "#7f1d1d" }, orange: { 50: "#fff7ed", 100: "#ffedd5", 200: "#fed7aa", 300: "#fdba74", 400: "#fb923c", 500: "#f97316", 600: "#ea580c", 700: "#c2410c", 800: "#9a3412", 900: "#7c2d12" }, amber: { 50: "#fffbeb", 100: "#fef3c7", 200: "#fde68a", 300: "#fcd34d", 400: "#fbbf24", 500: "#f59e0b", 600: "#d97706", 700: "#b45309", 800: "#92400e", 900: "#78350f" }, yellow: { 50: "#fefce8", 100: "#fef9c3", 200: "#fef08a", 300: "#fde047", 400: "#facc15", 500: "#eab308", 600: "#ca8a04", 700: "#a16207", 800: "#854d0e", 900: "#713f12" }, lime: { 50: "#f7fee7", 100: "#ecfccb", 200: "#d9f99d", 300: "#bef264", 400: "#a3e635", 500: "#84cc16", 600: "#65a30d", 700: "#4d7c0f", 800: "#3f6212", 900: "#365314" }, green: { 50: "#f0fdf4", 100: "#dcfce7", 200: "#bbf7d0", 300: "#86efac", 400: "#4ade80", 500: "#22c55e", 600: "#16a34a", 700: "#15803d", 800: "#166534", 900: "#14532d" }, emerald: { 50: "#ecfdf5", 100: "#d1fae5", 200: "#a7f3d0", 300: "#6ee7b7", 400: "#34d399", 500: "#10b981", 600: "#059669", 700: "#047857", 800: "#065f46", 900: "#064e3b" }, teal: { 50: "#f0fdfa", 100: "#ccfbf1", 200: "#99f6e4", 300: "#5eead4", 400: "#2dd4bf", 500: "#14b8a6", 600: "#0d9488", 700: "#0f766e", 800: "#115e59", 900: "#134e4a" }, cyan: { 50: "#ecfeff", 100: "#cffafe", 200: "#a5f3fc", 300: "#67e8f9", 400: "#22d3ee", 500: "#06b6d4", 600: "#0891b2", 700: "#0e7490", 800: "#155e75", 900: "#164e63" }, sky: { 50: "#f0f9ff", 100: "#e0f2fe", 200: "#bae6fd", 300: "#7dd3fc", 400: "#38bdf8", 500: "#0ea5e9", 600: "#0284c7", 700: "#0369a1", 800: "#075985", 900: "#0c4a6e" }, blue: { 50: "#eff6ff", 100: "#dbeafe", 200: "#bfdbfe", 300: "#93c5fd", 400: "#60a5fa", 500: "#3b82f6", 600: "#2563eb", 700: "#1d4ed8", 800: "#1e40af", 900: "#1e3a8a" }, indigo: { 50: "#eef2ff", 100: "#e0e7ff", 200: "#c7d2fe", 300: "#a5b4fc", 400: "#818cf8", 500: "#6366f1", 600: "#4f46e5", 700: "#4338ca", 800: "#3730a3", 900: "#312e81" }, violet: { 50: "#f5f3ff", 100: "#ede9fe", 200: "#ddd6fe", 300: "#c4b5fd", 400: "#a78bfa", 500: "#8b5cf6", 600: "#7c3aed", 700: "#6d28d9", 800: "#5b21b6", 900: "#4c1d95" }, purple: { 50: "#faf5ff", 100: "#f3e8ff", 200: "#e9d5ff", 300: "#d8b4fe", 400: "#c084fc", 500: "#a855f7", 600: "#9333ea", 700: "#7e22ce", 800: "#6b21a8", 900: "#581c87" }, fuchsia: { 50: "#fdf4ff", 100: "#fae8ff", 200: "#f5d0fe", 300: "#f0abfc", 400: "#e879f9", 500: "#d946ef", 600: "#c026d3", 700: "#a21caf", 800: "#86198f", 900: "#701a75" }, pink: { 50: "#fdf2f8", 100: "#fce7f3", 200: "#fbcfe8", 300: "#f9a8d4", 400: "#f472b6", 500: "#ec4899", 600: "#db2777", 700: "#be185d", 800: "#9d174d", 900: "#831843" }, rose: { 50: "#fff1f2", 100: "#ffe4e6", 200: "#fecdd3", 300: "#fda4af", 400: "#fb7185", 500: "#f43f5e", 600: "#e11d48", 700: "#be123c", 800: "#9f1239", 900: "#881337" } } // Obtenir la couleur const flattenedColor = {} @@ -30,112 +30,96 @@ const getClosestColor = (hex) => { } // Retourner la couleur - const nearestColor = require('nearest-color').from(flattenedColor) + const nearestColor = require("nearest-color").from(flattenedColor) return nearestColor(hex) } module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('color') - .setDescription('Affiche des informations sur une couleur') + .setName("color") + .setDescription("Affiche des informations sur une couleur") .addSubcommand((subcommand) => subcommand - .setName('hex') - .setDescription('Affiche des informations sur une couleur hexadécimale') - .addStringOption(option => option.setName('color') + .setName("hex") + .setDescription("Affiche des informations sur une couleur hexadécimale") + .addStringOption(option => option.setName("color") .setDescription("Couleur hexadécimale (avec ou sans le #)") - .setRequired(true) - ) - ) + .setRequired(true))) .addSubcommand((subcommand) => subcommand - .setName('rgb') - .setDescription('Affiche des informations sur une couleur RGB') - .addNumberOption(option => option.setName('r') + .setName("rgb") + .setDescription("Affiche des informations sur une couleur RGB") + .addNumberOption(option => option.setName("r") .setDescription("Valeur de rouge (0-255)") .setRequired(true) .setMinValue(0) - .setMaxValue(255) - ) - .addNumberOption(option => option.setName('g') + .setMaxValue(255)) + .addNumberOption(option => option.setName("g") .setDescription("Valeur de vert (0-255)") .setRequired(true) .setMinValue(0) - .setMaxValue(255) - ) - .addNumberOption(option => option.setName('b') + .setMaxValue(255)) + .addNumberOption(option => option.setName("b") .setDescription("Valeur de bleu (0-255)") .setRequired(true) .setMinValue(0) - .setMaxValue(255) - ) - ) + .setMaxValue(255))) .addSubcommand((subcommand) => subcommand - .setName('hsl') - .setDescription('Affiche des informations sur une couleur HSL') - .addNumberOption(option => option.setName('h') + .setName("hsl") + .setDescription("Affiche des informations sur une couleur HSL") + .addNumberOption(option => option.setName("h") .setDescription("Valeur de teinte (0-360)") .setRequired(true) .setMinValue(0) - .setMaxValue(360) - ) - .addNumberOption(option => option.setName('s') + .setMaxValue(360)) + .addNumberOption(option => option.setName("s") .setDescription("Valeur de saturation (0-100)") .setRequired(true) .setMinValue(0) - .setMaxValue(100) - ) - .addNumberOption(option => option.setName('l') + .setMaxValue(100)) + .addNumberOption(option => option.setName("l") .setDescription("Valeur de luminosité (0-100)") .setRequired(true) .setMinValue(0) - .setMaxValue(100) - ) - ) + .setMaxValue(100))) .addSubcommand((subcommand) => subcommand - .setName('cmyk') - .setDescription('Affiche des informations sur une couleur CMYK') - .addNumberOption(option => option.setName('c') + .setName("cmyk") + .setDescription("Affiche des informations sur une couleur CMYK") + .addNumberOption(option => option.setName("c") .setDescription("Valeur de cyan (0-100)") .setRequired(true) .setMinValue(0) - .setMaxValue(100) - ) - .addNumberOption(option => option.setName('m') + .setMaxValue(100)) + .addNumberOption(option => option.setName("m") .setDescription("Valeur de magenta (0-100)") .setRequired(true) .setMinValue(0) - .setMaxValue(100) - ) - .addNumberOption(option => option.setName('y') + .setMaxValue(100)) + .addNumberOption(option => option.setName("y") .setDescription("Valeur de jaune (0-100)") .setRequired(true) .setMinValue(0) - .setMaxValue(100) - ) - .addNumberOption(option => option.setName('k') + .setMaxValue(100)) + .addNumberOption(option => option.setName("k") .setDescription("Valeur de noir (0-100)") .setRequired(true) .setMinValue(0) - .setMaxValue(100) - ) - ) + .setMaxValue(100))) .addSubcommand((subcommand) => subcommand - .setName('random') - .setDescription('Affiche une couleur aléatoire') - ), + .setName("random") + .setDescription("Affiche une couleur aléatoire")), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Obtenir les arguments var format = interaction.options.getSubcommand() var color - if(format == 'hex') color = interaction.options.getString('color') - if(format == 'rgb') color = [interaction.options.getNumber('r'), interaction.options.getNumber('g'), interaction.options.getNumber('b')] - if(format == 'hsl') color = [interaction.options.getNumber('h'), interaction.options.getNumber('s'), interaction.options.getNumber('l')] - if(format == 'cmyk') color = [interaction.options.getNumber('c'), interaction.options.getNumber('m'), interaction.options.getNumber('y'), interaction.options.getNumber('k')] - if(format == 'random'){ + if(format == "hex") color = interaction.options.getString("color") + if(format == "rgb") color = [interaction.options.getNumber("r"), interaction.options.getNumber("g"), interaction.options.getNumber("b")] + if(format == "hsl") color = [interaction.options.getNumber("h"), interaction.options.getNumber("s"), interaction.options.getNumber("l")] + if(format == "cmyk") color = [interaction.options.getNumber("c"), interaction.options.getNumber("m"), interaction.options.getNumber("y"), interaction.options.getNumber("k")] + if(format == "random"){ color = (Math.floor(Math.random() * 16777215).toString(16)).toUpperCase() - format = 'hex' + format = "hex" } // Liste des couleurs une fois converties @@ -144,10 +128,10 @@ module.exports = { // Convertir dans un maximum de formats if(color && format){ // Convertir en HEX - if(format != 'hex' && format == 'rgb') colors.hex = convert.rgb.hex(color) - if(format != 'hex' && format == 'hsl') colors.hex = convert.hsl.hex(color) - if(format != 'hex' && format == 'cmyk') colors.hex = convert.cmyk.hex(color) - if(format == 'hex'){ + if(format != "hex" && format == "rgb") colors.hex = convert.rgb.hex(color) + if(format != "hex" && format == "hsl") colors.hex = convert.hsl.hex(color) + if(format != "hex" && format == "cmyk") colors.hex = convert.cmyk.hex(color) + if(format == "hex"){ // Convertir en rgb puis en hex, pour que "fff" devienne "FFFFFF" colors.rgb = convert.hex.rgb(color) color = convert.rgb.hex(colors.rgb) @@ -173,32 +157,30 @@ module.exports = { // Créer l'embed var embed = new EmbedBuilder() - .setTitle(colors.name) - .setColor(colors.hex) - .addFields([ - { name: 'Décimale', value: '`' + colors.decimal + '`', inline: true }, - { name: 'Hexadécimale', value: '`#' + colors.hex + '`', inline: true }, - { name: 'Tailwind CSS', value: '`' + colors.tailwindcss + '`', inline: true }, - { name: 'RGB', value: '`' + colors.rgb.join(', ') + '`', inline: true }, - { name: 'HSL', value: '`' + colors.hsl.join(', ') + '`', inline: true }, - { name: 'HSV', value: '`' + colors.hsv.join(', ') + '`', inline: true }, - { name: 'XYZ', value: '`' + colors.xyz.join(', ') + '`', inline: true }, - { name: 'LAB', value: '`' + colors.lab + '`', inline: true }, - { name: 'CMYK', value: '`' + colors.cmyk.join(', ') + '`', inline: true }, - { name: 'HWB', value: '`' + colors.hwb.join(', ') + '`', inline: true }, - { name: 'ANSI 16', value: '`' + colors.ansi16 + '`', inline: true }, - { name: 'ANSI 256', value: '`' + colors.ansi256 + '`', inline: true }, - { name: 'Couleur opposée', value: '`' + colors.opposite.toUpperCase() + '`', inline: true }, - { name: 'Est foncé ?', value: colors.isDark ? 'Oui' : 'Non', inline: true } - ]) + .setTitle(colors.name) + .setColor(colors.hex) + .addFields([ + { name: "Décimale", value: `\`${colors.decimal}\``, inline: true }, + { name: "Hexadécimale", value: `\`#${colors.hex}\``, inline: true }, + { name: "Tailwind CSS", value: `\`${colors.tailwindcss}\``, inline: true }, + { name: "RGB", value: `\`${colors.rgb.join(", ")}\``, inline: true }, + { name: "HSL", value: `\`${colors.hsl.join(", ")}\``, inline: true }, + { name: "HSV", value: `\`${colors.hsv.join(", ")}\``, inline: true }, + { name: "XYZ", value: `\`${colors.xyz.join(", ")}\``, inline: true }, + { name: "LAB", value: `\`${colors.lab}\``, inline: true }, + { name: "CMYK", value: `\`${colors.cmyk.join(", ")}\``, inline: true }, + { name: "HWB", value: `\`${colors.hwb.join(", ")}\``, inline: true }, + { name: "ANSI 16", value: `\`${colors.ansi16}\``, inline: true }, + { name: "ANSI 256", value: `\`${colors.ansi256}\``, inline: true }, + { name: "Couleur opposée", value: `\`${colors.opposite.toUpperCase()}\``, inline: true }, + { name: "Est foncé ?", value: colors.isDark ? "Oui" : "Non", inline: true } + ]) // Créer un bouton - var row = new ActionRowBuilder().addComponents( - new ButtonBuilder() + var row = new ActionRowBuilder().addComponents(new ButtonBuilder() .setURL(`https://parrot.color.pizza/color/${colors.hex}`) .setStyle(ButtonStyle.Link) - .setLabel('Informations sur Color Pizza') - ) + .setLabel("Informations sur Color Pizza")) // Envoyer l'embed interaction.reply({ embeds: [embed], components: [row] }).catch(err => {}) diff --git a/modules/bachero.module.colorInfo/manifest.jsonc b/modules/bachero.module.colorInfo/manifest.jsonc index 1e8fa25..e2b52bd 100644 --- a/modules/bachero.module.colorInfo/manifest.jsonc +++ b/modules/bachero.module.colorInfo/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Ce module vous donne des informations sur une couleur", - "longDescription": "Ce module récupère et vous affiche des informations sur une couleur", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.contributors/contributeurs.js b/modules/bachero.module.contributors/contributeurs.js index 27b74ae..d8e3aef 100644 --- a/modules/bachero.module.contributors/contributeurs.js +++ b/modules/bachero.module.contributors/contributeurs.js @@ -17,7 +17,7 @@ module.exports = { .setName("contributeurs") .setDescription("Liste les personnes ayant le plus contribué au développement de ce robot"), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // On defer l'interaction, si c'est pas une commande texte (on a pas besoin de defer pour les commandes texte car il n'y a pas de timeout) if(interaction.sourceType != "textCommand" && await interaction.deferReply({ ephemeral: true }).catch(err => { return "stop" }) == "stop") return diff --git a/modules/bachero.module.contributors/manifest.jsonc b/modules/bachero.module.contributors/manifest.jsonc index f8b74a9..67a551b 100644 --- a/modules/bachero.module.contributors/manifest.jsonc +++ b/modules/bachero.module.contributors/manifest.jsonc @@ -8,9 +8,6 @@ // Description du module "shortDescription": "Liste les contributeurs du dépôt GitHub de Bachero.", - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", - // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.databaseTest/delete.js b/modules/bachero.module.databaseTest/delete.js index 90b4dfd..34ca87b 100644 --- a/modules/bachero.module.databaseTest/delete.js +++ b/modules/bachero.module.databaseTest/delete.js @@ -1,30 +1,30 @@ -const { SlashCommandBuilder, EmbedBuilder } = require('discord.js') -const bacheroFunctions = require('../../functions') -const database = bacheroFunctions.database.getDatabase('bachero.module.databaseTest') +const { SlashCommandBuilder, EmbedBuilder } = require("discord.js") +const bacheroFunctions = require("../../functions") +const database = bacheroFunctions.database.getDatabase("bachero.module.databaseTest") module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('db-delete') - .setDescription('Effectue une opération sur la BDD : delete') - .addStringOption(option => option.setName('property') - .setDescription('Propriété') + .setName("db-delete") + .setDescription("Effectue une opération sur la BDD : delete") + .addStringOption(option => option.setName("property") + .setDescription("Propriété") .setRequired(true)), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Obtenir la propriété - var property = interaction.options.getString('property') + var property = interaction.options.getString("property") // Supprimer la propriété property = await bacheroFunctions.database.delete(database, property) // Créer un embed var embed = new EmbedBuilder() - .setTitle('Opération effectuée') - .setDescription("```\n" + (property?.toString()?.replace(/`/g, ' `') || property) + "\n```") - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - .setFooter({text:`L'activation du module "bachero.module.databaseTest" est fortement déconseillée`}) + .setTitle("Opération effectuée") + .setDescription(`\`\`\`\n${property?.toString()?.replace(/`/g, " `") || property}\n\`\`\``) + .setColor(bacheroFunctions.colors.primary) + .setFooter({ text: "L'activation du module \"bachero.module.databaseTest\" est fortement déconseillée" }) // Répondre à l'utilisateur interaction.reply({ embeds: [embed] }).catch(err => {}) diff --git a/modules/bachero.module.databaseTest/get.js b/modules/bachero.module.databaseTest/get.js index 1f4149c..40911e6 100644 --- a/modules/bachero.module.databaseTest/get.js +++ b/modules/bachero.module.databaseTest/get.js @@ -1,29 +1,29 @@ -const { SlashCommandBuilder, EmbedBuilder } = require('discord.js') -const bacheroFunctions = require('../../functions') -const database = bacheroFunctions.database.getDatabase('bachero.module.databaseTest') +const { SlashCommandBuilder, EmbedBuilder } = require("discord.js") +const bacheroFunctions = require("../../functions") +const database = bacheroFunctions.database.getDatabase("bachero.module.databaseTest") module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('db-get') - .setDescription('Effectue une opération sur la BDD : get') - .addStringOption(option => option.setName('property') - .setDescription('Propriété') + .setName("db-get") + .setDescription("Effectue une opération sur la BDD : get") + .addStringOption(option => option.setName("property") + .setDescription("Propriété") .setRequired(true)), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Obtenir la propriété - var property = interaction.options.getString('property') + var property = interaction.options.getString("property") property = await bacheroFunctions.database.get(database, property) property = JSON.stringify(property, null, 2) || property // Créer un embed var embed = new EmbedBuilder() - .setTitle('Opération effectuée') - .setDescription("```\n" + (property?.toString()?.replace(/`/g, ' `') || property) + "\n```") - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - .setFooter({text:`L'activation du module "bachero.module.databaseTest" est fortement déconseillée`}) + .setTitle("Opération effectuée") + .setDescription(`\`\`\`\n${property?.toString()?.replace(/`/g, " `") || property}\n\`\`\``) + .setColor(bacheroFunctions.colors.primary) + .setFooter({ text: "L'activation du module \"bachero.module.databaseTest\" est fortement déconseillée" }) // Répondre à l'utilisateur interaction.reply({ embeds: [embed] }).catch(err => {}) diff --git a/modules/bachero.module.databaseTest/getAll.js b/modules/bachero.module.databaseTest/getAll.js index 5c68d23..315b892 100644 --- a/modules/bachero.module.databaseTest/getAll.js +++ b/modules/bachero.module.databaseTest/getAll.js @@ -1,14 +1,14 @@ -const { SlashCommandBuilder, EmbedBuilder } = require('discord.js') -const bacheroFunctions = require('../../functions') -const database = bacheroFunctions.database.getDatabase('bachero.module.databaseTest') +const { SlashCommandBuilder, EmbedBuilder } = require("discord.js") +const bacheroFunctions = require("../../functions") +const database = bacheroFunctions.database.getDatabase("bachero.module.databaseTest") module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('db-getall') - .setDescription('Effectue une opération sur la BDD : getAll'), + .setName("db-getall") + .setDescription("Effectue une opération sur la BDD : getAll"), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Obtenir tout le contenu de la base de données var entireDatabase = await bacheroFunctions.database.getAll(database) @@ -16,10 +16,10 @@ module.exports = { // Créer un embed var embed = new EmbedBuilder() - .setTitle('Opération effectuée') - .setDescription("```\n" + (entireDatabase?.toString()?.replace(/`/g, ' `') || entireDatabase) + "\n```") - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - .setFooter({text:`L'activation du module "bachero.module.databaseTest" est fortement déconseillée`}) + .setTitle("Opération effectuée") + .setDescription(`\`\`\`\n${entireDatabase?.toString()?.replace(/`/g, " `") || entireDatabase}\n\`\`\``) + .setColor(bacheroFunctions.colors.primary) + .setFooter({ text: "L'activation du module \"bachero.module.databaseTest\" est fortement déconseillée" }) // Répondre à l'utilisateur interaction.reply({ embeds: [embed] }).catch(err => {}) diff --git a/modules/bachero.module.databaseTest/has.js b/modules/bachero.module.databaseTest/has.js index df95a35..ec638ad 100644 --- a/modules/bachero.module.databaseTest/has.js +++ b/modules/bachero.module.databaseTest/has.js @@ -1,28 +1,28 @@ -const { SlashCommandBuilder, EmbedBuilder } = require('discord.js') -const bacheroFunctions = require('../../functions') -const database = bacheroFunctions.database.getDatabase('bachero.module.databaseTest') +const { SlashCommandBuilder, EmbedBuilder } = require("discord.js") +const bacheroFunctions = require("../../functions") +const database = bacheroFunctions.database.getDatabase("bachero.module.databaseTest") module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('db-has') - .setDescription('Effectue une opération sur la BDD : has') - .addStringOption(option => option.setName('property') - .setDescription('Propriété') + .setName("db-has") + .setDescription("Effectue une opération sur la BDD : has") + .addStringOption(option => option.setName("property") + .setDescription("Propriété") .setRequired(true)), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Obtenir la propriété - var property = interaction.options.getString('property') + var property = interaction.options.getString("property") property = await bacheroFunctions.database.has(database, property) // Créer un embed var embed = new EmbedBuilder() - .setTitle('Opération effectuée') - .setDescription("```\n" + (property?.toString()?.replace(/`/g, ' `') || property) + "\n```") - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - .setFooter({text:`L'activation du module "bachero.module.databaseTest" est fortement déconseillée`}) + .setTitle("Opération effectuée") + .setDescription(`\`\`\`\n${property?.toString()?.replace(/`/g, " `") || property}\n\`\`\``) + .setColor(bacheroFunctions.colors.primary) + .setFooter({ text: "L'activation du module \"bachero.module.databaseTest\" est fortement déconseillée" }) // Répondre à l'utilisateur interaction.reply({ embeds: [embed] }).catch(err => {}) diff --git a/modules/bachero.module.databaseTest/manifest.jsonc b/modules/bachero.module.databaseTest/manifest.jsonc index 9cc7708..dd53798 100644 --- a/modules/bachero.module.databaseTest/manifest.jsonc +++ b/modules/bachero.module.databaseTest/manifest.jsonc @@ -10,7 +10,6 @@ // Description du module "shortDescription": "Ce module permet de faire des tests sur la base de données", - "longDescription": "Ce module permet de faire des tests sur la base de données, en ajoutant quelques commandes pour faire des opérations", // Message affiché lorsque le module finit de charger (recommandé de laisser vide) "onloadMessage": "ce module n'est pas recommandé, n'importe qui peut accéder à la base de données", diff --git a/modules/bachero.module.databaseTest/set.js b/modules/bachero.module.databaseTest/set.js index 19b9dce..92b9889 100644 --- a/modules/bachero.module.databaseTest/set.js +++ b/modules/bachero.module.databaseTest/set.js @@ -1,24 +1,24 @@ -const { SlashCommandBuilder, EmbedBuilder } = require('discord.js') -const bacheroFunctions = require('../../functions') -const database = bacheroFunctions.database.getDatabase('bachero.module.databaseTest') +const { SlashCommandBuilder, EmbedBuilder } = require("discord.js") +const bacheroFunctions = require("../../functions") +const database = bacheroFunctions.database.getDatabase("bachero.module.databaseTest") module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('db-set') - .setDescription('Effectue une opération sur la BDD : set') - .addStringOption(option => option.setName('property') - .setDescription('Propriété') + .setName("db-set") + .setDescription("Effectue une opération sur la BDD : set") + .addStringOption(option => option.setName("property") + .setDescription("Propriété") .setRequired(true)) - .addStringOption(option => option.setName('value') - .setDescription('Valeur') + .addStringOption(option => option.setName("value") + .setDescription("Valeur") .setRequired(true)), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Obtenir les arguments - var property = interaction.options.getString('property') - var value = interaction.options.getString('value') + var property = interaction.options.getString("property") + var value = interaction.options.getString("value") try { value = JSON.parse(value) } catch (err) {} @@ -28,10 +28,10 @@ module.exports = { // Créer un embed var embed = new EmbedBuilder() - .setTitle('Opération effectuée') - .setDescription("```\n" + (databaseChange?.toString()?.replace(/`/g, ' `') || databaseChange) + "\n```") - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - .setFooter({text:`L'activation du module "bachero.module.databaseTest" est fortement déconseillée`}) + .setTitle("Opération effectuée") + .setDescription(`\`\`\`\n${databaseChange?.toString()?.replace(/`/g, " `") || databaseChange}\n\`\`\``) + .setColor(bacheroFunctions.colors.primary) + .setFooter({ text: "L'activation du module \"bachero.module.databaseTest\" est fortement déconseillée" }) // Répondre à l'utilisateur interaction.reply({ embeds: [embed] }).catch(err => {}) diff --git a/modules/bachero.module.discordWhois/main.js b/modules/bachero.module.discordWhois/main.js index 57ef2ab..678d880 100644 --- a/modules/bachero.module.discordWhois/main.js +++ b/modules/bachero.module.discordWhois/main.js @@ -1,9 +1,9 @@ -const fetch = require('node-fetch') -var CronJob = require('cron').CronJob +const fetch = require("node-fetch") +var CronJob = require("cron").CronJob var botClient // Tout les jours à 4h21 du matin -new CronJob('21 4 * * *', async function() { +new CronJob("21 4 * * *", (async () => { // Si on a pas de client, on annule car c'est censé le définir automatiquement if(!botClient) return @@ -13,7 +13,7 @@ new CronJob('21 4 * * *', async function() { var verifiedGuild = 0 // Obtenir le maximum de personne possible à travers tout les serveurs - var getMembers = new Promise(async (resolve, reject) => { + var getMembers = new Promise((resolve, reject) => { botClient.guilds.cache.forEach(guild => { // A chaque serveur rejoint par le bot guild.members.fetch().then(members => { // Obtenir tout les membres du serveur members.forEach(member => { // A chaque membre du serveur @@ -39,10 +39,10 @@ new CronJob('21 4 * * *', async function() { // Faire une requête vers Discord WhoIs setTimeout(async () => { verified.push(userId) - await fetch(`https://discord-whois.vercel.app/api/getDiscord?discordId=${userId}`, { headers: { 'User-Agent': 'BacheroBot (+https://github.com/bacherobot/bot)' } }).catch(err => {}) + await fetch(`https://discord-whois.vercel.app/api/getDiscord?discordId=${userId}`, { headers: { "User-Agent": "BacheroBot (+https://github.com/bacherobot/bot)" } }).catch(err => {}) }, i * 2000) }) -}).start() +})).start() module.exports = { async getClient(client){ @@ -50,7 +50,7 @@ module.exports = { botClient = client // Quand quelqu'un change d'information sur son compte (event via le client) - botClient.on('userUpdate', async (oldUser, newUser) => { + botClient.on("userUpdate", async (oldUser, newUser) => { // Si on a l'ancien pseudo, et le nouveau, vérifier que ça soit pas les mêmes if( (oldUser.username && newUser.username && oldUser.username == newUser.username) || @@ -59,7 +59,7 @@ module.exports = { ) return // Ajouter dans l'historique WhoIs - if(newUser.id || oldUser.id) await fetch(`https://discord-whois.vercel.app/api/getDiscord?discordId=${newUser.id || oldUser.id}`, { headers: { 'User-Agent': 'BacheroBot (+https://github.com/bacherobot/bot)' } }).catch(err => {}) + if(newUser.id || oldUser.id) await fetch(`https://discord-whois.vercel.app/api/getDiscord?discordId=${newUser.id || oldUser.id}`, { headers: { "User-Agent": "BacheroBot (+https://github.com/bacherobot/bot)" } }).catch(err => {}) }) } } \ No newline at end of file diff --git a/modules/bachero.module.discordWhois/manifest.jsonc b/modules/bachero.module.discordWhois/manifest.jsonc index b23bb76..40b3d71 100644 --- a/modules/bachero.module.discordWhois/manifest.jsonc +++ b/modules/bachero.module.discordWhois/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Ajoute tous les membres des serveurs dans l'historique Discord WhoIs", - "longDescription": "Ce module ajoute tous les membres de tous les serveurs dans l'historique de pseudo Discord WhoIs accessible via https://discord-whois.johanstick.me", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.fake/fake-config.js b/modules/bachero.module.fake/fake-config.js index b626212..db7b1f1 100644 --- a/modules/bachero.module.fake/fake-config.js +++ b/modules/bachero.module.fake/fake-config.js @@ -1,53 +1,51 @@ -const { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js') -const bacheroFunctions = require('../../functions') -const database = bacheroFunctions.database.getDatabase('bachero.module.fake') +const { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js") +const bacheroFunctions = require("../../functions") +const database = bacheroFunctions.database.getDatabase("bachero.module.fake") // Exporter certaines fonctions module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('fake-config') - .setDescription(`Configure la permission requise pour utiliser la commande fake sur ce serveur`) + .setName("fake-config") + .setDescription("Configure la permission requise pour utiliser la commande fake sur ce serveur") .setDefaultMemberPermissions(PermissionFlagsBits.ManageWebhooks) .setDMPermission(false), // Récupérer le listener et savoir lorsque quelqu'un renvoie le bouton async interactionListener(listener){ - listener.on('button', async (interaction) => { + listener.on("button", async (interaction) => { // Vérifier l'identifiant du bouton, puis defer l'interaction - if(interaction.customId != 'fakeConfig-disableForAll' && interaction.customId != 'fakeConfig-enableForAll') return + if(interaction.customId != "fakeConfig-disableForAll" && interaction.customId != "fakeConfig-enableForAll") return if(interaction.user.id != interaction?.message?.interaction?.user?.id && interaction.user.id != interaction?.message?.mentions?.repliedUser?.id) return interaction.reply({ content: "Il semblerait que tu ne sois pas la personne que j'attendais...", ephemeral: true }).catch(err => {}) await interaction.deferReply().catch(err => {}) // Modifier la valeur dans la base de données - if(interaction.customId == 'fakeConfig-disableForAll') await bacheroFunctions.database.delete(database, `everyoneUse-${interaction.guild.id}`) + if(interaction.customId == "fakeConfig-disableForAll") await bacheroFunctions.database.delete(database, `everyoneUse-${interaction.guild.id}`) else await bacheroFunctions.database.set(database, `everyoneUse-${interaction.guild.id}`, true) // Modifier le message d'origine, et supprimer l'interaction await interaction.deleteReply().catch(err => {}) - await interaction.message.edit({ content: `La commande \`fake\` est désormais utilisable ${interaction.customId == 'fakeConfig-disableForAll' ? 'par les modérateurs uniquement' : 'par tout le serveur'}.`, embeds: [], components: [] }).catch(err => {}) + await interaction.message.edit({ content: `La commande \`fake\` est désormais utilisable ${interaction.customId == "fakeConfig-disableForAll" ? "par les modérateurs uniquement" : "par tout le serveur"}.`, embeds: [], components: [] }).catch(err => {}) }) }, - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Vérifier si la commande /fake est activée pour tout le monde var isEnableForAll = await bacheroFunctions.database.get(database, `everyoneUse-${interaction.guild.id}`) // Créer un embed var embed = new EmbedBuilder() - .setTitle('Configuration de la commande fake') - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - if(isEnableForAll != true) embed.setDescription(`La commande \`fake\` permet d'"usurper l'identité" de quelqu'un en envoyant un message sous l'identité de cette personne.\nEn raison des problèmes qu'elle peut poser, elle est désactivée par défaut.`) - else embed.setDescription(`La commande \`fake\` permet d'"usurper l'identité" de quelqu'un en envoyant un message sous l'identité de cette personne.\nEn raison des problèmes qu'elle peut poser, elle est désactivée par défaut mais un membre du staff de ce serveur a tout de même décidé de la rendre disponible pour tous les membres.`) + .setTitle("Configuration de la commande fake") + .setColor(bacheroFunctions.colors.primary) + if(isEnableForAll != true) embed.setDescription("La commande `fake` permet d'\"usurper l'identité\" de quelqu'un en envoyant un message sous l'identité de cette personne.\nEn raison des problèmes qu'elle peut poser, elle est désactivée par défaut.") + else embed.setDescription("La commande `fake` permet d'\"usurper l'identité\" de quelqu'un en envoyant un message sous l'identité de cette personne.\nEn raison des problèmes qu'elle peut poser, elle est désactivée par défaut mais un membre du staff de ce serveur a tout de même décidé de la rendre disponible pour tous les membres.") // Créé un bouton - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setCustomId(isEnableForAll ? `fakeConfig-disableForAll` : `fakeConfig-enableForAll`) - .setLabel(isEnableForAll ? 'Désactiver par défaut' : 'Activer pour tout le monde') - .setStyle(ButtonStyle.Primary), - ) + const row = new ActionRowBuilder().addComponents(new ButtonBuilder() + .setCustomId(isEnableForAll ? "fakeConfig-disableForAll" : "fakeConfig-enableForAll") + .setLabel(isEnableForAll ? "Désactiver par défaut" : "Activer pour tout le monde") + .setStyle(ButtonStyle.Primary),) // Répondre à l'interaction interaction.reply({ embeds: [embed], components: [row] }).catch(err => {}) diff --git a/modules/bachero.module.fake/fake.js b/modules/bachero.module.fake/fake.js index b3ba443..7e27897 100644 --- a/modules/bachero.module.fake/fake.js +++ b/modules/bachero.module.fake/fake.js @@ -1,7 +1,7 @@ -const { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits, WebhookClient, ModalBuilder, TextInputBuilder, TextInputStyle, ActionRowBuilder, ContextMenuCommandBuilder, ApplicationCommandType } = require('discord.js') -const Fuse = require('fuse.js'); -const bacheroFunctions = require('../../functions') -const database = bacheroFunctions.database.getDatabase('bachero.module.fake') +const { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits, WebhookClient, ModalBuilder, TextInputBuilder, TextInputStyle, ActionRowBuilder, ContextMenuCommandBuilder, ApplicationCommandType } = require("discord.js") +const Fuse = require("fuse.js") +const bacheroFunctions = require("../../functions") +const database = bacheroFunctions.database.getDatabase("bachero.module.fake") const modalList = [] // Liste des profils prédéfinis @@ -86,18 +86,18 @@ var fuse = new Fuse(Object.entries(profiles).map(([key, value]) => ({ ...value, threshold: 0.6, keys: [ { - name: 'username', + name: "username", weight: 0.5 }, { - name: 'id', + name: "id", weight: 0.6 } ] }) // Fonction pour obtenir/crée un webhook -async function getWebhook(interaction, forceRecreate=false){ +async function getWebhook(interaction, forceRecreate = false){ // Préparer une variable var webhookClient @@ -106,7 +106,7 @@ async function getWebhook(interaction, forceRecreate=false){ if(forceRecreate != true && webhookInfo?.id && webhookInfo?.token) try { webhookClient = new WebhookClient({ id: webhookInfo.id, token: webhookInfo.token }) } catch(err) { webhookClient = { error: err } } // Si on a pas de webhook, on le crée - if(forceRecreate == true || !webhookClient || webhookClient?.error) var webhookInfo = await interaction.channel.createWebhook({ name: "Bachero Webhook", reason: `Un webhook a été créé par le module "bachero.module.fake" pour pouvoir utiliser la commande` }).catch(err => { return { error: err } }) + if(forceRecreate == true || !webhookClient || webhookClient?.error) var webhookInfo = await interaction.channel.createWebhook({ name: "Bachero Webhook", reason: "Un webhook a été créé par le module \"bachero.module.fake\" pour pouvoir utiliser la commande" }).catch(err => { return { error: err } }) if(webhookInfo.error) return await bacheroFunctions.report.createAndReply("création du webhook Bachero", webhookInfo.error, {}, interaction) bacheroFunctions.database.set(database, `webhook-${interaction.channel.id}`, { id: webhookInfo.id, token: webhookInfo.token, lastUsed: Date.now() }) try { webhookClient = new WebhookClient({ id: webhookInfo.id, token: webhookInfo.token }) } catch(err) { webhookClient = { error: err } } @@ -119,19 +119,19 @@ async function getWebhook(interaction, forceRecreate=false){ // Fonction pour envoyer un message dans un salon async function sendToChannel(interaction, userToFake){ // On defer la réponse pour éviter les erreurs - if(interaction.sourceType != 'textCommand' && await interaction.deferReply({ ephemeral: true }).catch(err => { return 'stop' }) == 'stop') return + if(interaction.sourceType != "textCommand" && await interaction.deferReply({ ephemeral: true }).catch(err => { return "stop" }) == "stop") return // Obtenir l'utilisateur mentionné, et le texte à envoyer var user = userToFake || modalList[interaction.user.id] - var text = await interaction.options?.getString('text') || await interaction?.fields?.getTextInputValue('fakeCommand-text') || "Aucun texte fourni :/" // le "aucun texte fourni" devrais vraiment pas apparaître, c'est surtout AU CAS OU + var text = await interaction.options?.getString("text") || await interaction?.fields?.getTextInputValue("fakeCommand-text") || "Aucun texte fourni :/" // le "aucun texte fourni" devrais vraiment pas apparaître, c'est surtout AU CAS OU // Modifier et vérifier le texte - text = text.replace(/\\n/g, '\n').replace(/%JUMP%/g, '\n').replace(/%DATE%/g, ``) - if(text.length > 1999) return interaction.editReply({ content: 'Votre message dépasse la limite de caractère (2000 caractères)' }).catch(err => {}) + text = text.replace(/\\n/g, "\n").replace(/%JUMP%/g, "\n").replace(/%DATE%/g, ``) + if(text.length > 1999) return interaction.editReply({ content: "Votre message dépasse la limite de caractère (2000 caractères)" }).catch(err => {}) // Obtenir le webhook, et l'utiliser pour envoyer un message var webhook = await getWebhook(interaction) - if(!webhook.send) return; // si on a pas de webhook, on arrête là (ptet que la fonction a retourné un rapport d'erreur) + if(!webhook.send) return // si on a pas de webhook, on arrête là (ptet que la fonction a retourné un rapport d'erreur) await webhook.send({ content: text, username: user?.username, avatarURL: user?.avatarURL }).catch(async err => { // créer un webhookclient avec des informations invalides ne provoque pas d'erreur, donc on vérifie si les informations sont valides au moment d'envoyer le message (qui renvoie une erreur) // Donc si l'envoi a raté, on réessaie mais cette fois-ci en créant un nouveau webhook avant webhook = await getWebhook(interaction, true) @@ -141,48 +141,46 @@ async function sendToChannel(interaction, userToFake){ }) // Si c'est une commande texte, tenter de supprimer le message d'invocation - if(interaction.sourceType == 'textCommand'){ + if(interaction.sourceType == "textCommand"){ try { interaction.delete().catch(err => {}) } catch(err) {} // Le choix de la sécurité } // Répondre à l'interaction - if(interaction.sourceType != 'textCommand') return interaction.editReply({ content: `Message envoyé !` }).catch(err => {}) + if(interaction.sourceType != "textCommand") return interaction.editReply({ content: "Message envoyé !" }).catch(err => {}) } // Exporter certaines fonctions module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('fake') + .setName("fake") .setDescription("Envoie un message sous une autre identité, via un webhook") .setDMPermission(false) .addSubcommand((subcommand) => subcommand - .setName('mention') + .setName("mention") .setDescription("Usurpe l'identité d'un membre du serveur") - .addUserOption(option => option.setName('user') - .setDescription('Membre à usurper') + .addUserOption(option => option.setName("user") + .setDescription("Membre à usurper") .setRequired(true)) - .addStringOption(option => option.setName('text') - .setDescription('Contenu du message à envoyer') + .addStringOption(option => option.setName("text") + .setDescription("Contenu du message à envoyer") .setRequired(false) - .setMaxLength(1999)) - ) + .setMaxLength(1999))) .addSubcommand((subcommand) => subcommand - .setName('custom') + .setName("custom") .setDescription("Usurpe l'identité à partir d'un profil prédéfini") - .addStringOption(option => option.setName('id') + .addStringOption(option => option.setName("id") .setDescription("Identifiant du profil prédéfini, n'entrer aucun argument pour obtenir la liste") .setRequired(false)) - .addStringOption(option => option.setName('text') - .setDescription('Contenu du message à envoyer') + .addStringOption(option => option.setName("text") + .setDescription("Contenu du message à envoyer") .setRequired(false) - .setMaxLength(1999)) - ), + .setMaxLength(1999))), // Définir les infos du menu contextuel contextInfo: new ContextMenuCommandBuilder() - .setName("Usurper cet identité") - .setType(ApplicationCommandType.User), + .setName("Usurper cet identité") + .setType(ApplicationCommandType.User), // Quand le bot est connecté à Discord getClient(){ @@ -199,7 +197,7 @@ module.exports = { if(webhook.lastUsed < Date.now() - 600000){ await bacheroFunctions.database.delete(database, Object.entries(webhooks).find(([key, value]) => value.id == webhook.id)?.[0]) try { var webhookClient = new WebhookClient({ id: webhook.id, token: webhook.token }) } catch(err) { var webhookClient = { error: err } } - if(!webhookClient.error) await webhookClient.delete().catch(err => { return 'stop' }) + if(!webhookClient.error) await webhookClient.delete().catch(err => { return "stop" }) } }) }, 120000) // Vérifier toutes les 2 minutes s'il ne faut pas supprimer un/plusieurs webhooks @@ -207,13 +205,13 @@ module.exports = { // Récupérer le listener et savoir lorsque quelqu'un renvoie le modal async interactionListener(listener){ - listener.on('modal', (interaction) => { - if(interaction.customId != 'fakeCommand-messageInfos') return + listener.on("modal", (interaction) => { + if(interaction.customId != "fakeCommand-messageInfos") return sendToChannel(interaction) }) }, - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Vérifier que l'utilisateur a la permission d'utiliser cette commande, si le serveur n'a pas été configuré pour permettre à tout le monde de l'utiliser if(await bacheroFunctions.database.get(database, `everyoneUse-${interaction.guild.id}`) != true && !interaction.channel.permissionsFor(interaction.user).has(PermissionFlagsBits.ManageWebhooks)) return interaction.reply({ content: ":no_entry_sign: Tu ne sembles pas avoir la permission de gérer les webhooks dans ce salon.", ephemeral: true }) @@ -222,13 +220,13 @@ module.exports = { var userToFake // Si on utilise un profil prédéfini, on vérifie que l'identifiant est valide - var profilId = await interaction.options.getString('id') + var profilId = await interaction.options.getString("id") if(profilId) profilId = profilId.toUpperCase() if(profilId && profiles[profilId]) userToFake = profiles[profilId] // Si on a pas d'utilisateur, alors que la sous commande est "custom" - if(!userToFake && profilId && await interaction.options.getSubcommand() == 'custom'){ - var results = fuse.search(await interaction.options.getString('id')) + if(!userToFake && profilId && await interaction.options.getSubcommand() == "custom"){ + var results = fuse.search(await interaction.options.getString("id")) if(results?.length) results.sort((a, b) => { return a.score - b.score }) userToFake = results[0]?.item } @@ -238,41 +236,37 @@ module.exports = { // Si on a pas d'utilisateur à usurper, on essaye autrement if(!userToFake) userToFake = { - username: (await interaction.options.getUser('user'))?.display_name || (await interaction.options.getUser('user'))?.username, - avatarURL: (await interaction.options.getUser('user'))?.avatarURL({ dynamic: true, size: 512 }) + username: (await interaction.options.getUser("user"))?.display_name || (await interaction.options.getUser("user"))?.username, + avatarURL: (await interaction.options.getUser("user"))?.avatarURL({ dynamic: true, size: 512 }) } // Si on a pas d'utilisateur, on provient forcément de la sous commande "custom" (car la sous commande "mention" a besoin d'un utilisateur) if(!userToFake?.username){ var embed = new EmbedBuilder() - .setTitle("Liste des profils prédéfinis") - .setDescription(Object.entries(profiles).map(([key, value]) => `**${key}** : « ${value.username} »`).join('\n').substring(0, 3900)) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - .setFooter({ text: `${Object.entries(profiles).length} profils ont été trouvés` }) + .setTitle("Liste des profils prédéfinis") + .setDescription(Object.entries(profiles).map(([key, value]) => `**${key}** : « ${value.username} »`).join("\n").substring(0, 3900)) + .setColor(bacheroFunctions.colors.primary) + .setFooter({ text: `${Object.entries(profiles).length} profils ont été trouvés` }) return interaction.reply({ embeds: [embed], ephemeral: true }).catch(err => {}) } // Si on a le contenu du message, on l'envoie - if(await interaction.options.getString('text')) return sendToChannel(interaction, userToFake) + if(await interaction.options.getString("text")) return sendToChannel(interaction, userToFake) // Sinon, on vérifie qu'on peut afficher un modal - if(interaction.sourceType == 'textCommand') return interaction.reply({ content: "L'argument `text` est manquant dans votre commande, vous devez l'ajouter à votre message. Sinon, vous pouvez aussi utiliser une commande slash (/) pour afficher un menu permettant la saisie du texte sans ajouter d'argument à votre message." }).catch(err => {}) + if(interaction.sourceType == "textCommand") return interaction.reply({ content: "L'argument `text` est manquant dans votre commande, vous devez l'ajouter à votre message. Sinon, vous pouvez aussi utiliser une commande slash (/) pour afficher un menu permettant la saisie du texte sans ajouter d'argument à votre message." }).catch(err => {}) // Puis on le crée si c'est bon const modal = new ModalBuilder() - .setCustomId('fakeCommand-messageInfos') - .setTitle('Détail du message') - .addComponents( - new ActionRowBuilder().addComponents( - new TextInputBuilder() - .setCustomId('fakeCommand-text') + .setCustomId("fakeCommand-messageInfos") + .setTitle("Détail du message") + .addComponents(new ActionRowBuilder().addComponents(new TextInputBuilder() + .setCustomId("fakeCommand-text") .setLabel("Contenu") .setPlaceholder("Contenu du message à envoyer") .setStyle(TextInputStyle.Paragraph) .setRequired(true) - .setMaxLength(1999) - ) - ) + .setMaxLength(1999))) // Ajouter dans la liste des modals l'utilisateur mentionné modalList[interaction.user.id] = userToFake diff --git a/modules/bachero.module.fake/manifest.jsonc b/modules/bachero.module.fake/manifest.jsonc index e14faf0..5060883 100644 --- a/modules/bachero.module.fake/manifest.jsonc +++ b/modules/bachero.module.fake/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Envoie un message avec le nom et la photo de profil d'un membre du serveur", - "longDescription": "Créer un webhook sur un serveur, et l'utilise pour envoyer un message avec le nom et la photo de profil d'un membre mentionné sur ce serveur", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.help/help.js b/modules/bachero.module.help/help.js index f156b1d..8c41404 100644 --- a/modules/bachero.module.help/help.js +++ b/modules/bachero.module.help/help.js @@ -1,45 +1,45 @@ -const { SlashCommandBuilder, EmbedBuilder } = require('discord.js') -const bacheroFunctions = require('../../functions') -var botPrefix = bacheroFunctions.config.getValue('bachero', 'prefix') -var botName = bacheroFunctions.config.getValue('bachero', 'botName') -var disableTextCommand = bacheroFunctions.config.getValue('bachero', 'disableTextCommand') +const { SlashCommandBuilder, EmbedBuilder } = require("discord.js") +const bacheroFunctions = require("../../functions") +var botPrefix = bacheroFunctions.config.getValue("bachero", "prefix") +var botName = bacheroFunctions.config.getValue("bachero", "botName") +var disableTextCommand = bacheroFunctions.config.getValue("bachero", "disableTextCommand") var listCommand = [] -var pages = [''] // Faire que le premier élément (0) soit vide, pour que la liste commence à 1 +var pages = [""] // Faire que le premier élément (0) soit vide, pour que la liste commence à 1 module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('help') - .setDescription(`Affiche la liste des commandes disponibles`) - .addStringOption(option => option.setName('commandname') + .setName("help") + .setDescription("Affiche la liste des commandes disponibles") + .addStringOption(option => option.setName("commandname") .setDescription("Affiche l'utilisation d'une commande spécifique") .setRequired(false)) - .addNumberOption(option => option.setName('page') + .addNumberOption(option => option.setName("page") .setDescription("Permet de choisir la page affichée lorsqu'on n'entre pas de nom de commande") .setRequired(false)), // Obtenir le client async getClient(client){ - client.on('messageCreate', async message => { + client.on("messageCreate", async message => { // Si on mentionne le bot, et que le message ne contient que ça if(message.mentions.has(client.user) && (message.content == `<@!${client.user.id}>` || message.content == `<@${client.user.id}>`)){ // Vérifier si les commandes textes sont activés sur ce serveur - if(!disableTextCommand) var isTextCommandDisabledGuild = await bacheroFunctions.database.get(bacheroFunctions.database.getDatabase('textCommandDisabledGuilds'), message.guild.id) + if(!disableTextCommand) var isTextCommandDisabledGuild = await bacheroFunctions.database.get(bacheroFunctions.database.getDatabase("textCommandDisabledGuilds"), message.guild.id) else var isTextCommandDisabledGuild = true // Répondre message.reply({ embeds: [ new EmbedBuilder() - .setTitle("Oh c'est moi") - .setDescription(disableTextCommand ? `${botName} ne fonctionne qu'avec des commandes slash. Tu peux commencer à écrire \`/\` et Discord complétera les commandes pour toi. Sinon, tu peux utiliser la commande \`/help\` !` : `Tu peux utiliser la commande \`/help\` pour obtenir la liste des commandes disponibles, ou l'utiliser via message classique, en envoyant \`${botPrefix} help\`${isTextCommandDisabledGuild ? ".\nNote : la fonctionnalité d'utilisation des commandes via message a été désactivé sur ce serveur par un membre du staff." : ''}`) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) + .setTitle("Oh c'est moi") + .setDescription(disableTextCommand ? `${botName} ne fonctionne qu'avec des commandes slash. Tu peux commencer à écrire \`/\` et Discord complétera les commandes pour toi. Sinon, tu peux utiliser la commande \`/help\` !` : `Tu peux utiliser la commande \`/help\` pour obtenir la liste des commandes disponibles, ou l'utiliser via message classique, en envoyant \`${botPrefix}help\`${isTextCommandDisabledGuild ? ".\nNote : la fonctionnalité d'utilisation des commandes via message a été désactivé sur ce serveur par un membre du staff." : ""}`) + .setColor(bacheroFunctions.colors.primary) ], ephemeral: false }).catch(err => {}) } }) }, - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Si on a pas encore la liste des modules, le définir if(!listCommand?.length){ @@ -56,29 +56,29 @@ module.exports = { if(!pages?.[1]) listCommand.forEach(cmd => { if(commandsMessage.length > 3900){ pages.push(commandsMessage) - commandsMessage = `\n• ${cmd.name} : ${cmd.command.description.replace(/`/g, '')}` - } else commandsMessage += `\n• ${cmd.name} : ${cmd.command.description.replace(/`/g, '')}` + commandsMessage = `\n• ${cmd.name} : ${cmd.command.description.replace(/`/g, "")}` + } else commandsMessage += `\n• ${cmd.name} : ${cmd.command.description.replace(/`/g, "")}` }) if(commandsMessage) pages.push(commandsMessage) // Obtenir le nom de la commande - var commandName = interaction.options.getString('commandname') + var commandName = interaction.options.getString("commandname") // Si aucun nom de commande n'est donné, obtenir la liste complète if(!commandName){ // Créer un embed var embed = new EmbedBuilder() - .setTitle('Liste des commandes') - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) + .setTitle("Liste des commandes") + .setColor(bacheroFunctions.colors.primary) // Si on veut choisir une page à afficher - var currentlyShowedPage = interaction.options.getNumber('page') || 1 - if(currentlyShowedPage > pages?.length - 1) embed.setFooter({ text: `Première page affichée car la valeur que vous avez spécifiée est trop haute` }) - else if(currentlyShowedPage < 1) embed.setFooter({ text: `Première page affichée car la valeur que vous avez spécifiée est trop basse` }) + var currentlyShowedPage = interaction.options.getNumber("page") || 1 + if(currentlyShowedPage > pages?.length - 1) embed.setFooter({ text: "Première page affichée car la valeur que vous avez spécifiée est trop haute" }) + else if(currentlyShowedPage < 1) embed.setFooter({ text: "Première page affichée car la valeur que vous avez spécifiée est trop basse" }) else embed.setFooter({ text: `Affichage de la page ${currentlyShowedPage}/${pages?.length - 1} • ${listCommand?.length} résultats` }) // Ajouter la page dans l'embed - embed.setDescription(pages[currentlyShowedPage] || pages[1] || pages[0] || pages?.join('\n') || pages) // le choix de la sécurité + embed.setDescription(pages[currentlyShowedPage] || pages[1] || pages[0] || pages?.join("\n") || pages) // le choix de la sécurité // Envoyer l'embed interaction.reply({ embeds: [embed] }).catch(err => {}) @@ -86,39 +86,39 @@ module.exports = { // Sinon, obtenir les infos sur la commande else { // Obtenir la commande et en faire un clone - var commandBeforeClone = listCommand.find(m => m.name == (commandName?.split(' ')[0] || commandName)) + var commandBeforeClone = listCommand.find(m => m.name == (commandName?.split(" ")[0] || commandName)) var command = commandBeforeClone ? JSON.parse(JSON.stringify(commandBeforeClone)) : null - if(commandName?.split(' ')[1] && command?.command?.options?.find(m => m.type == 1 && m.name == commandName?.split(' ')[1])){ - var _command = command; - command = command.command.options.find(m => m.name == commandName?.split(' ')[1]); - command.command = _command; - command.module = _command.module; + if(commandName?.split(" ")[1] && command?.command?.options?.find(m => m.type == 1 && m.name == commandName?.split(" ")[1])){ + var _command = command + command = command.command.options.find(m => m.name == commandName?.split(" ")[1]) + command.command = _command + command.module = _command.module } // Si la commande n'existe pas, répondre avec un message d'erreur if(!command){ var embed = new EmbedBuilder() - .setTitle('Commande introuvable') - .setDescription(`Aucune commande avec le nom \`${commandName.replace(/`/g, '')}\` n'a été trouvé. Utiliser la commande d'aide sans arguments pour obtenir la liste complète.`) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) + .setTitle("Commande introuvable") + .setDescription(`Aucune commande avec le nom \`${commandName.replace(/`/g, "")}\` n'a été trouvé. Utiliser la commande d'aide sans arguments pour obtenir la liste complète.`) + .setColor(bacheroFunctions.colors.secondary) return interaction.reply({ embeds: [embed] }).catch(err => {}) } // Liste des sous commandes s'il y en a - if(command?.command?.options?.length && command?.command?.options?.filter(op => op.type == 1)?.length) var subCommandsText = `\nㅤ • ${command?.command?.options?.map(o => `${o.name} : ${o.description}`).join('\nㅤ • ')}` + if(command?.command?.options?.length && command?.command?.options?.filter(op => op.type == 1)?.length) var subCommandsText = `\nㅤ • ${command?.command?.options?.map(o => `${o.name} : ${o.description}`).join("\nㅤ • ")}` if(subCommandsText) subCommandsText = `\n**Sous commandes** : ${subCommandsText}` // Faire une variable qui contiendra les indications sur les arguments if(command.options) command.command.options = command.options - if(command?.command?.options?.length && interaction.sourceType == 'textCommand') var argumentsText = command?.command?.options?.map(o => (o.required ? '<' : '[') + o.name + ':' + o.type?.toString()?.replace('3', 'contenu').replace('4', 'nombre entier').replace('5', 'true/false').replace('6', 'utilisateur').replace('7', 'salon').replace('8', 'rôle').replace('9', 'utilisateur ou rôle').replace('10', 'nombre').replace('11', 'attachement') + (o.required ? '>' : ']')).join('; ') - else if(command?.command?.options?.length) var argumentsText = `\nㅤ • ${command?.command?.options?.map(o => o.name).join('\nㅤ • ')}` + if(command?.command?.options?.length && interaction.sourceType == "textCommand") var argumentsText = command?.command?.options?.map(o => `${(o.required ? "<" : "[") + o.name}:${o.type?.toString()?.replace("3", "contenu").replace("4", "nombre entier").replace("5", "true/false").replace("6", "utilisateur").replace("7", "salon").replace("8", "rôle").replace("9", "utilisateur ou rôle").replace("10", "nombre").replace("11", "attachement")}${o.required ? ">" : "]"}`).join("; ") + else if(command?.command?.options?.length) var argumentsText = `\nㅤ • ${command?.command?.options?.map(o => o.name).join("\nㅤ • ")}` if(argumentsText) argumentsText = `\n**Arguments** : ${argumentsText}` // Sinon, créer un embed pour afficher les infos de la commande var embed = new EmbedBuilder() - .setTitle(command?.name) - .setDescription(`${command?.module?.whitelistedGuildIds?.length && !command?.module?.whitelistedGuildIds?.includes(interaction.guildId) ? '⚠️ Non autorisé sur ce serveur\n' : ''}${(command?.command?.slashToText || command?.command?.command?.slashToText) == false ? '⚠️ Uniquement disponible pour les commandes slash\n' : ''}\n> ${(command.command.description || command.description).replace(/\n/g, ' ').replace(/`/g, '')}\n\n**Provient du module :** ${command.module.packageName}${subCommandsText || argumentsText || ''}`) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) + .setTitle(command?.name) + .setDescription(`${command?.module?.whitelistedGuildIds?.length && !command?.module?.whitelistedGuildIds?.includes(interaction.guildId) ? "⚠️ Non autorisé sur ce serveur\n" : ""}${(command?.command?.slashToText || command?.command?.command?.slashToText) == false ? "⚠️ Uniquement disponible pour les commandes slash\n" : ""}\n> ${(command.command.description || command.description).replace(/\n/g, " ").replace(/`/g, "")}\n\n**Provient du module :** ${command.module.packageName}${subCommandsText || argumentsText || ""}`) + .setColor(bacheroFunctions.colors.primary) // Répondre avec l'embed interaction.reply({ embeds: [embed] }).catch(err => {}) diff --git a/modules/bachero.module.help/manifest.jsonc b/modules/bachero.module.help/manifest.jsonc index 6094fd2..b72608e 100644 --- a/modules/bachero.module.help/manifest.jsonc +++ b/modules/bachero.module.help/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Ce module permet d'obtenir la liste des commandes avec une commande", - "longDescription": "Ajoute une commande (/help) pour obtenir la liste de toutes les commandes disponibles dans les modules installés", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.issue/manifest.jsonc b/modules/bachero.module.issue/manifest.jsonc index 7fc38b4..3b0e75a 100644 --- a/modules/bachero.module.issue/manifest.jsonc +++ b/modules/bachero.module.issue/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Permet de rapporter des problèmes en rapport avec le robot", - "longDescription": "Permet de rapporter des problèmes à l'administrateur de cette instance Bachero, ou au développeur du bot", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.issue/report.js b/modules/bachero.module.issue/report.js index 66a90a6..4bc2cc6 100644 --- a/modules/bachero.module.issue/report.js +++ b/modules/bachero.module.issue/report.js @@ -1,49 +1,49 @@ -const { SlashCommandBuilder, EmbedBuilder, WebhookClient, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js') -const bacheroFunctions = require('../../functions') -const escape = require('markdown-escape') +const { SlashCommandBuilder, EmbedBuilder, WebhookClient, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js") +const bacheroFunctions = require("../../functions") +const escape = require("markdown-escape") // Exporter certaines fonctions module.exports = { // Quand le bot est prêt getClient(){ - if(!bacheroFunctions.config.getValue('bachero.module.issue', 'webhookLink')) return bacheroFunctions.showLog('warn', `Le lien du webhook entré pour le module "bachero.module.issue" n'a pas été défini. Pour recevoir des signalements de la part des utilisateurs en rapport avec votre instance Bachero, veuillez définir un lien de webhook dans le fichier de configuration. Vous pouvez également supprimer ce module.`, id="report-no-webhook") + if(!bacheroFunctions.config.getValue("bachero.module.issue", "webhookLink")) return bacheroFunctions.showLog("warn", "Le lien du webhook entré pour le module \"bachero.module.issue\" n'a pas été défini. Pour recevoir des signalements de la part des utilisateurs en rapport avec votre instance Bachero, veuillez définir un lien de webhook dans le fichier de configuration. Vous pouvez également supprimer ce module.", "report-no-webhook") }, // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('report') - .setDescription(`Signale un problème en rapport avec le robot`) - .addStringOption(option => option.setName('reason') - .setDescription('Raison du signalement') + .setName("report") + .setDescription("Signale un problème en rapport avec le robot") + .addStringOption(option => option.setName("reason") + .setDescription("Raison du signalement") .setRequired(true) .setMaxLength(1000) .setMinLength(12)), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Vérifier et répondre si l'utilisateur est limité, sinon on le limite - var checkAndReply = await bacheroFunctions.cooldown.checkAndReply(interaction, 'createIssueModule') - if(checkAndReply) return; else await bacheroFunctions.cooldown.set('createIssueModule', interaction.user.id, 30000) + var checkAndReply = await bacheroFunctions.cooldown.checkAndReply(interaction, "createIssueModule") + if(checkAndReply) return; else await bacheroFunctions.cooldown.set("createIssueModule", interaction.user.id, 30000) // Mettre la réponse en defer - if(await interaction.deferReply().catch(err => { return 'stop' }) == 'stop') return + if(await interaction.deferReply().catch(err => { return "stop" }) == "stop") return // Obtenir la raison - var reason = interaction.options.getString('reason') || "Impossible d'obtenir la raison" + var reason = interaction.options.getString("reason") || "Impossible d'obtenir la raison" // Créer l'embed var embed = new EmbedBuilder() - .setTitle(`Signalement de ${interaction.user.discriminator == '0' ? escape(interaction.user.username) : escape(interaction.user.tag)}`) - .setDescription(reason) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - .setFooter({ text: `Identifiant : ${interaction.user.id}` }) - .setTimestamp() + .setTitle(`Signalement de ${interaction.user.discriminator == "0" ? escape(interaction.user.username) : escape(interaction.user.tag)}`) + .setDescription(reason) + .setColor(bacheroFunctions.colors.primary) + .setFooter({ text: `Identifiant : ${interaction.user.id}` }) + .setTimestamp() // Envoyer le message avec un webhook, puis confirmer en renvoyant l'interaction try { - var webhook = new WebhookClient({ url: bacheroFunctions.config.getValue('bachero.module.issue', 'webhookLink') }) + var webhook = new WebhookClient({ url: bacheroFunctions.config.getValue("bachero.module.issue", "webhookLink") }) await webhook.send({ embeds: [embed] }) - await interaction.editReply({ content: `Votre signalement a bien été envoyé au propriétaire de cette instance.`, ephemeral: true, components: [new ActionRowBuilder().addComponents(new ButtonBuilder().setURL(`https://contact.johanstick.me`).setStyle(ButtonStyle.Link).setLabel('Contacter le créateur de Bachero'))] }) + await interaction.editReply({ content: "Votre signalement a bien été envoyé au propriétaire de cette instance.", ephemeral: true, components: [new ActionRowBuilder().addComponents(new ButtonBuilder().setURL("https://johanstick.fr/contact").setStyle(ButtonStyle.Link).setLabel("Contacter le créateur de Bachero"))] }) } catch (err) { return await bacheroFunctions.report.createAndReply("envoi d'un signalement via un webhook", err, {}, interaction) } diff --git a/modules/bachero.module.level/level-leaderboard.js b/modules/bachero.module.level/level-leaderboard.js index 4d0aa5c..5a7a769 100644 --- a/modules/bachero.module.level/level-leaderboard.js +++ b/modules/bachero.module.level/level-leaderboard.js @@ -27,7 +27,7 @@ module.exports = { .setName("level-leaderboard") .setDescription("Affiche le classement des niveaux, sur ce serveur et sur tous les serveurs."), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Identifiant du serveur et de l'utilisateur var guildId = interaction?.guild?.id @@ -112,7 +112,7 @@ module.exports = { .setTitle("Classement - interserveur") .setFields(global_leaderboard_embed) .setFooter({ text: `Votre rang : ${global_userRank} / ${global_leaderboard.length} • ${userDb?.global?.level ? `Niveau ${userDb?.global?.level}` : "Aucun niveau"}, avec ${userDb?.global?.xp ? `${addSpaceNumbers(userDb?.global?.xp)} XP` : "Aucune XP"}` }) - .setColor(bacheroFunctions.config.getValue("bachero", "embedColor")) + .setColor(bacheroFunctions.colors.primary) } // On génère l'embed sur ce serveur @@ -132,7 +132,7 @@ module.exports = { .setTitle("Classement - ce serveur") .setFields(server_leaderboard_embed) .setFooter({ text: `Votre rang : ${server_userRank} / ${server_leaderboard.length} • ${userDb?.[`server-${guildId}`]?.level ? `Niveau ${userDb?.[`server-${guildId}`]?.level}` : "Aucun niveau"}, avec ${userDb?.[`server-${guildId}`]?.xp ? `${addSpaceNumbers(userDb?.[`server-${guildId}`]?.xp)} XP` : "Aucune XP"}` }) - .setColor(bacheroFunctions.config.getValue("bachero", "embedColor")) + .setColor(bacheroFunctions.colors.primary) } // On met en cache diff --git a/modules/bachero.module.level/level-manage.js b/modules/bachero.module.level/level-manage.js index df70e31..de33f58 100644 --- a/modules/bachero.module.level/level-manage.js +++ b/modules/bachero.module.level/level-manage.js @@ -166,7 +166,7 @@ module.exports = { }) }, - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Rangée const row = new ActionRowBuilder().addComponents(new StringSelectMenuBuilder() diff --git a/modules/bachero.module.level/manifest.jsonc b/modules/bachero.module.level/manifest.jsonc index e1ccc51..5085804 100644 --- a/modules/bachero.module.level/manifest.jsonc +++ b/modules/bachero.module.level/manifest.jsonc @@ -8,9 +8,6 @@ // Description du module "shortDescription": "Propose un système de niveaux avec points d'XP", - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", - // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.lyrics/lyrics.js b/modules/bachero.module.lyrics/lyrics.js index a684b06..83cc7f4 100644 --- a/modules/bachero.module.lyrics/lyrics.js +++ b/modules/bachero.module.lyrics/lyrics.js @@ -1,49 +1,48 @@ -const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js') -const bacheroFunctions = require('../../functions') -const Genius = require("genius-lyrics"); const GeniusClient = new Genius.Client(); -const escape = require('markdown-escape') +const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js") +const bacheroFunctions = require("../../functions") +const Genius = require("genius-lyrics"); const GeniusClient = new Genius.Client() +const escape = require("markdown-escape") // Fonction pour tenter de "compresser" un texte tout en le gardant lisible pour un humain function compressText(text){ // Remplacer certains caractères par d'autres - text = text.replace(/\.\.\./g, '…') - text = text.replace(/\.\./g, '‥') - text = text.replace(/!!/g, '‼') - text = text.replace(/\?\?/g, '⁇') - text = text.replace(/!\?/g, '⁈') - text = text.replace(/\?!/g, '⁉') - text = text.replace(/--/g, '—') - text = text.replace(/---/g, '——') - text = text.replace(/----/g, '———') - text = text.replace(/-----/g, '———') - + text = text.replace(/\.\.\./g, "…") + text = text.replace(/\.\./g, "‥") + text = text.replace(/!!/g, "‼") + text = text.replace(/\?\?/g, "⁇") + text = text.replace(/!\?/g, "⁈") + text = text.replace(/\?!/g, "⁉") + text = text.replace(/--/g, "—") + text = text.replace(/---/g, "——") + text = text.replace(/----/g, "———") + text = text.replace(/-----/g, "———") + // Enlever les indications de paroles (toute les lignes qui commencent par un [ et fini par un ]) - text = text.replace(/\[.*\]/g, '') + text = text.replace(/\[.*\]/g, "") // Enlever les doubles sauts de ligne - text = text.replace(/\n\n/g, '\n') + text = text.replace(/\n\n/g, "\n") // Retourner le texte - return text.trim() + return escape(text.trim()) } module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('lyrics') - .setDescription('Recherche et obtient les paroles d\'une chanson') - .addStringOption(option => option.setName('search') + .setName("lyrics") + .setDescription("Recherche et obtient les paroles d'une chanson") + .addStringOption(option => option.setName("search") .setDescription("Terme de recherche") - .setRequired(false) - ), + .setRequired(false)), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Mettre la réponse en defer - if(await interaction.deferReply().catch(err => { return 'stop' }) == 'stop') return + if(await interaction.deferReply().catch(err => { return "stop" }) == "stop") return // Obtenir le terme de recherche - var query = interaction.options.getString('search') + var query = interaction.options.getString("search") // Si on a pas de terme de recherche, on va chercher ce que l'utilisateur est en train d'écouter if(!query && interaction.member?.presence?.activities?.length){ @@ -66,19 +65,17 @@ module.exports = { // Créer l'embed var embed = new EmbedBuilder() - .setTitle(searchResult.fullTitle) - .setDescription(lyrics.substring(0, 4094).length < lyrics.length ? lyrics.substring(0, 4094) + '…' : lyrics) - .setThumbnail(searchResult.thumbnail) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - .setFooter({ text: `Paroles récupérées via Genius sous la demande de ${interaction.user.discriminator == '0' ? escape(interaction.user.username) : escape(interaction.user.tag)}` }) + .setTitle(searchResult.fullTitle) + .setDescription(lyrics.substring(0, 4094).length < lyrics.length ? `${lyrics.substring(0, 4094)}…` : lyrics) + .setThumbnail(searchResult.thumbnail) + .setColor(bacheroFunctions.colors.primary) + .setFooter({ text: `Paroles récupérées via Genius sous la demande de ${interaction.user.discriminator == "0" ? interaction.user.username : interaction.user.tag}` }) // Créer un bouton - var row = new ActionRowBuilder().addComponents( - new ButtonBuilder() + var row = new ActionRowBuilder().addComponents(new ButtonBuilder() .setURL(searchResult.url) .setStyle(ButtonStyle.Link) - .setLabel(`Voir ${lyrics.substring(0, 4092).length < lyrics.length ? 'en entier ' : ''}sur Genius`) - ) + .setLabel(`Voir ${lyrics.substring(0, 4092).length < lyrics.length ? "en entier " : ""}sur Genius`)) // Envoyer l'embed interaction.editReply({ embeds: [embed], components: [row] }).catch(err => {}) diff --git a/modules/bachero.module.lyrics/manifest.jsonc b/modules/bachero.module.lyrics/manifest.jsonc index 489dc5e..d584ddf 100644 --- a/modules/bachero.module.lyrics/manifest.jsonc +++ b/modules/bachero.module.lyrics/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Ce module récupère les paroles d'une musique et les affiche via une commande", - "longDescription": "Ce module obtient les paroles d'une chanson via l'API de Genius et les affiche aux membres utilisant la commande dédiée", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.message/clear.js b/modules/bachero.module.message/clear.js index 7591ea9..14f0817 100644 --- a/modules/bachero.module.message/clear.js +++ b/modules/bachero.module.message/clear.js @@ -1,50 +1,50 @@ -const { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, ComponentType } = require('discord.js') -const bacheroFunctions = require('../../functions') -var botName = bacheroFunctions.config.getValue('bachero', 'botName') +const { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, ComponentType } = require("discord.js") +const bacheroFunctions = require("../../functions") +var botName = bacheroFunctions.config.getValue("bachero", "botName") // Exporter certaines fonctions module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('clear') - .setDescription('Supprime des messages dans ce salon') - .addNumberOption(option => option.setName('count') - .setDescription('Nombre de messages à supprimer') + .setName("clear") + .setDescription("Supprime des messages dans ce salon") + .addNumberOption(option => option.setName("count") + .setDescription("Nombre de messages à supprimer") .setRequired(true) .setMinValue(1) .setMaxValue(100)) .setDefaultMemberPermissions(PermissionFlagsBits.ManageChannels | PermissionFlagsBits.ManageMessages) .setDMPermission(false), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Obtenir le nombre de messages à supprimer - var count = interaction.options.getNumber('count') + var count = interaction.options.getNumber("count") // Créé deux boutons pour confirmer qu'on sois sur de vouloir supprimer les messages var date = Date.now() const rowConfirm = new ActionRowBuilder().addComponents( new ButtonBuilder() - .setCustomId(`confirm-askClear-${date}`) - .setLabel('Confirmer') - .setStyle(ButtonStyle.Danger), + .setCustomId(`confirm-askClear-${date}`) + .setLabel("Confirmer") + .setStyle(ButtonStyle.Danger), new ButtonBuilder() - .setCustomId(`cancel-askClear-${date}`) - .setLabel('Finalement non') - .setStyle(ButtonStyle.Success), + .setCustomId(`cancel-askClear-${date}`) + .setLabel("Finalement non") + .setStyle(ButtonStyle.Success), ) // Afficher l'embed de confirmation var embed = new EmbedBuilder() - .setTitle("Suppression des messages") - .setDescription(`T'es vraiment sûr de vouloir supprimer **${count == 1 ? "le dernier message" : "les " + count + " derniers messages"}** ?\n\nCette action est irréversible et ${count == 1 ? "le message ira" : "les messages iront"} dans les backrooms, force à ${count == 1 ? "lui" : "eux"}.`) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) + .setTitle("Suppression des messages") + .setDescription(`T'es vraiment sûr de vouloir supprimer **${count == 1 ? "le dernier message" : `les ${count} derniers messages`}** ?\n\nCette action est irréversible et ${count == 1 ? "le message ira" : "les messages iront"} dans les backrooms, force à ${count == 1 ? "lui" : "eux"}.`) + .setColor(bacheroFunctions.colors.secondary) interaction.reply({ embeds: [embed], components: [rowConfirm] }).catch(err => {}) // Quand quelqu'un clique sur le bouton const filter_confirm = i => i.customId == `confirm-askClear-${date}` || i.customId == `cancel-askClear-${date}` const collector_confirm = interaction.channel.createMessageComponentCollector({ componentType: ComponentType.Button, filter: filter_confirm, time: 999999 }) - collector_confirm.on('collect', async i => { + collector_confirm.on("collect", async i => { // Vérifier que la personne a les permissions de gérer les messages ou de gérer le salon if(!interaction.channel.permissionsFor(i.user).has(PermissionFlagsBits.ManageChannels) && !interaction.channel.permissionsFor(i.user).has(PermissionFlagsBits.ManageMessages)) return i.reply({ content: ":no_entry_sign: Tu ne sembles pas avoir la permission de gérer les messages ou de gérer ce salon.", ephemeral: true }) @@ -57,38 +57,36 @@ module.exports = { // Arrêter le collecteur et dire à la personne de supprimer collector_confirm.stop() - if(await interaction.editReply({ embeds: [], components: [], content: "Veuillez patientez" }).catch(err => { return 'stop' }) == 'stop') return + if(await interaction.editReply({ embeds: [], components: [], content: "Veuillez patientez" }).catch(err => { return "stop" }) == "stop") return // Créé un bouton pour supprimer le message de succès date = Date.now() - const rowDeleteMessageSuccess = new ActionRowBuilder().addComponents( - new ButtonBuilder() + const rowDeleteMessageSuccess = new ActionRowBuilder().addComponents(new ButtonBuilder() .setCustomId(`deleteMessageSuccessClear-${date}`) - .setLabel('Masquer') - .setStyle(ButtonStyle.Primary), - ) + .setLabel("Masquer") + .setStyle(ButtonStyle.Primary),) // Modifier le temps dans le salon var successMessage try { await interaction.channel.bulkDelete(count == 100 ? count : count + 1, true) // ajouter +1 (car on inclus l'interaction) - successMessage = await interaction.channel.send({ content: `Tout est bon <@${interaction.user.id}>, ${count} message${count == 1 ? '' : 's'} devrait avoir été supprimé${count == 1 ? '' : 's'} !` }) + successMessage = await interaction.channel.send({ content: `Tout est bon <@${interaction.user.id}>, ${count} message${count == 1 ? "" : "s"} devrait avoir été supprimé${count == 1 ? "" : "s"} !` }) setTimeout(() => successMessage.edit({ components: [rowDeleteMessageSuccess] }).catch(err => {}), 2000) } catch(err) { // S’il y a eu une erreur // Note : cet embed est assez commun lorsque le bot n'a pas la permission, pour éviter de créer trop de rapports d'erreurs, cette méthode ne sera pas utilisée var embed = new EmbedBuilder() - .setTitle("Impossible de supprimer les messages") - .setDescription("Un problème est survenu lors de la suppression des messages :\n```\n" + (err?.toString()?.replace(/`/g, ' `').replace('Missing Permissions', "Je n'ai pas la permission de gérer ce salon.") || err) + "\n```") - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - .setFooter({ text: `Si vous pensez que ce problème a quelque chose à voir avec ${botName}, n'hésitez pas à le signaler` }) + .setTitle("Impossible de supprimer les messages") + .setDescription(`Un problème est survenu lors de la suppression des messages :\n\`\`\`\n${err?.toString()?.replace(/`/g, " `").replace("Missing Permissions", "Je n'ai pas la permission de gérer ce salon.") || err}\n\`\`\``) + .setColor(bacheroFunctions.colors.secondary) + .setFooter({ text: `Si vous pensez que ce problème a quelque chose à voir avec ${botName}, n'hésitez pas à le signaler` }) interaction.editReply({ embeds: [embed], components: [], content: null }).catch(err => {}) } // Quand quelqu'un clique sur le bouton pour masquer le message de succès const filter_delete = i => i.customId == `deleteMessageSuccessClear-${date}` const collector_delete = interaction.channel.createMessageComponentCollector({ componentType: ComponentType.Button, filter: filter_delete, time: 999999 }) - collector_delete.on('collect', async i => { + collector_delete.on("collect", async i => { // Vérifier que la personne a les permissions de gérer les messages ou de gérer le salon if(!interaction.channel.permissionsFor(i.user).has(PermissionFlagsBits.ManageChannels) && !interaction.channel.permissionsFor(i.user).has(PermissionFlagsBits.ManageMessages)) return i.reply({ content: ":no_entry_sign: Tu ne sembles pas avoir la permission de gérer les messages ou de gérer ce salon.", ephemeral: true }) diff --git a/modules/bachero.module.message/embed.js b/modules/bachero.module.message/embed.js index 7f50af6..31c0154 100644 --- a/modules/bachero.module.message/embed.js +++ b/modules/bachero.module.message/embed.js @@ -1,33 +1,32 @@ -const { SlashCommandBuilder, PermissionFlagsBits, ActionRowBuilder, TextInputBuilder, ModalBuilder, TextInputStyle, EmbedBuilder } = require('discord.js') -const bacheroFunctions = require('../../functions') -const database = bacheroFunctions.database.getDatabase('bachero.module.embed') -var botName = bacheroFunctions.config.getValue('bachero', 'botName') -var embedWithoutPermissions = bacheroFunctions.config.getValue('bachero.module.message', 'embedWithoutPermissions') -var embedShowAuthor = bacheroFunctions.config.getValue('bachero.module.message', 'embedShowAuthor') +const { SlashCommandBuilder, PermissionFlagsBits, ActionRowBuilder, TextInputBuilder, ModalBuilder, TextInputStyle, EmbedBuilder } = require("discord.js") +const bacheroFunctions = require("../../functions") +const database = bacheroFunctions.database.getDatabase("bachero.module.embed") +var botName = bacheroFunctions.config.getValue("bachero", "botName") +var embedWithoutPermissions = bacheroFunctions.config.getValue("bachero.module.message", "embedWithoutPermissions") +var embedShowAuthor = bacheroFunctions.config.getValue("bachero.module.message", "embedShowAuthor") var botClient -const fetch = require('node-fetch') -const escape = require('markdown-escape') -const { customAlphabet } = require('nanoid'), nanoid = customAlphabet('abcdefghiklnoqrstuvyz123456789', 14) +const fetch = require("node-fetch") +const { customAlphabet } = require("nanoid"), nanoid = customAlphabet("abcdefghiklnoqrstuvyz123456789", 14) // Créé la commande slash var slashInfo = new SlashCommandBuilder() -.setName('embed') -.setDescription(`Envoie un embed ${embedShowAuthor ? '' : 'anonymement '}sur le serveur en tant que ${botName}`) -.addStringOption(option => option.setName('source') - .setDescription("Préremplit les informations à partir d'une source (identifiant, hastebin, ...)") - .setRequired(false)) + .setName("embed") + .setDescription(`Envoie un embed ${embedShowAuthor ? "" : "anonymement "}sur le serveur en tant que ${botName}`) + .addStringOption(option => option.setName("source") + .setDescription("Préremplit les informations à partir d'une source (identifiant d'un embed)") + .setRequired(false)) if(!embedWithoutPermissions) slashInfo.setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages) // Fonction pour envoyer un message à partir d'une interaction async function sendToChannel(interaction, embedInfos){ // Mettre la réponse en defer - if(await interaction.deferReply({ ephemeral: true }).catch(err => { return 'stop' }) == 'stop') return + if(await interaction.deferReply({ ephemeral: true }).catch(err => { return "stop" }) == "stop") return // Obtenir toute les options - var title = interaction?.fields?.getTextInputValue('embedCommand-title') || embedInfos?.title - var description = interaction?.fields?.getTextInputValue('embedCommand-description') || embedInfos?.description - var footer = interaction?.fields?.getTextInputValue('embedCommand-footer') || embedInfos?.footer - var color = interaction?.fields?.getTextInputValue('embedCommand-color') || embedInfos?.color + var title = interaction?.fields?.getTextInputValue("embedCommand-title") || embedInfos?.title + var description = interaction?.fields?.getTextInputValue("embedCommand-description") || embedInfos?.description + var footer = interaction?.fields?.getTextInputValue("embedCommand-footer") || embedInfos?.footer + var color = interaction?.fields?.getTextInputValue("embedCommand-color") || embedInfos?.color // Générer un identifiant var uniqueId = nanoid() @@ -39,56 +38,41 @@ async function sendToChannel(interaction, embedInfos){ var notes = [] // Modifier la description - if(description) description = description.replace(/\\n/g, '\n').replace(/%JUMP%/g, '\n').replace(/%DATE%/g, ``) + if(description) description = description.replace(/\\n/g, "\n").replace(/%JUMP%/g, "\n").replace(/%DATE%/g, ``) // Faire quelques vérifications if(!title && !description) return interaction.editReply({ content: "Vous devez entrer un titre ou une description lors de la création d'un embed" }).catch(err => {}) - if((title?.length + description?.length + footer?.length) > 6000) return interaction.editReply({ content: `Un embed ne peut pas dépasser la limite de 6000 caractères (titre, description et footer inclus), cependant votre embed contient un total de ${title.length + description.length + footer.length} caractères.\n${title.length ? '\n**Titre : **' + title.length + ' caractères' : ''}${description.length ? '\n**Description : **' + description.length + ' caractères' : ''}${footer.length ? '\n**Footer : **' + footer.length + ' caractères' : ''}` }).catch(err => {}) + if((title?.length + description?.length + footer?.length) > 6000) return interaction.editReply({ content: `Un embed ne peut pas dépasser la limite de 6000 caractères (titre, description et footer inclus), cependant votre embed contient un total de ${title.length + description.length + footer.length} caractères.\n${title.length ? `\n**Titre : **${title.length} caractères` : ""}${description.length ? `\n**Description : **${description.length} caractères` : ""}${footer.length ? `\n**Footer : **${footer.length} caractères` : ""}` }).catch(err => {}) // Déterminer la couleur à utiliser - // Créé une liste de couleurs - var alreadyDefinedColors = { - 'rouge': 'e00032', - 'vert': '12c700', - 'bleu': '01579b', - 'orange': 'ff6f00', - 'blanc': 'fafafa', - 'noir': '212121', - 'jaune': 'ffff00', - 'violet': '512da8', - 'cyan': '4fc3f7', - 'rose': 'ffafcc', - 'gris': 'f5f5f5', - 'grisfonce': '524b50', - 'marron': '604840', - 'saumon': 'f9906f', - } + // Créé une liste de couleurs + var alreadyDefinedColors = bacheroFunctions.colors || {} - // Si on a pas choisis de couleur, obtenir une au hasard parmis la liste - if(!color) color = Object.keys(alreadyDefinedColors)[Math.floor(Math.random() * Object.keys(alreadyDefinedColors).length)] + // Si on a pas choisis de couleur, obtenir une au hasard parmis la liste + if(!color) color = Object.keys(alreadyDefinedColors)[Math.floor(Math.random() * Object.keys(alreadyDefinedColors).length)] - // Remplacer quelques mots dans la couleur pour une meilleure "compatibilité" - color = color.toLowerCase().replace(/ /g,'').replace('red','rouge').replace('green','vert').replace('blue','bleu').replace('white','blanc').replace('black','noir').replace('yellow','jaune').replace('purple','violet').replace('grey','gris').replace('gray','gris').replace('brown','marron').replace('salmon','saumon').replace('foncé','fonce') + // Remplacer quelques mots dans la couleur pour une meilleure "compatibilité" + color = color.toLowerCase().replace(/ /g, "").replace("red", "rouge").replace("green", "vert").replace("blue", "bleu").replace("white", "blanc").replace("black", "noir").replace("yellow", "jaune").replace("purple", "violet").replace("grey", "gris").replace("gray", "gris").replace("brown", "marron").replace("salmon", "saumon").replace("foncé", "fonce") - // Vérifier si la couleur qu'on a choisis fait parti de la liste - if(alreadyDefinedColors[color]) color = alreadyDefinedColors[color] + // Vérifier si la couleur qu'on a choisis fait parti de la liste + if(alreadyDefinedColors[color]) color = alreadyDefinedColors[color] - // Sinon, vérifier si la couleur est une bonne couleur hexadécimale - else if(!color?.length || (color?.length && !color?.replace('#','')?.match(/^[0-9a-f]{6}$/i))){ - // Définir par une couleur aléatoire de la liste - colorName = Object.keys(alreadyDefinedColors)[Math.floor(Math.random() * Object.keys(alreadyDefinedColors).length)] - color = alreadyDefinedColors[colorName] + // Sinon, vérifier si la couleur est une bonne couleur hexadécimale + else if(!color?.length || (color?.length && !color?.replace("#", "")?.match(/^[0-9a-f]{6}$/i))){ + // Définir par une couleur aléatoire de la liste + var colorName = Object.keys(alreadyDefinedColors)[Math.floor(Math.random() * Object.keys(alreadyDefinedColors).length)] + color = alreadyDefinedColors[colorName] - // Définir une note additionnelle - notes.push(`Cette couleur n'est pas valide, je vais donc utiliser la couleur aléatoire : **${colorName}**.`) - } + // Définir une note additionnelle + notes.push(`Cette couleur n'est pas valide, je vais donc utiliser la couleur aléatoire : **${colorName}**.`) + } // Créer l'embed var embed = new EmbedBuilder() if(title) embed.setTitle(title) if(description) embed.setDescription(description) if(footer) embed.setFooter({ text: footer }) - if(embedShowAuthor) embed.setAuthor({ name: interaction.user.discriminator == '0' ? escape(interaction.user.username) : escape(interaction.user.tag), iconURL: interaction.user.displayAvatarURL() }) + if(embedShowAuthor) embed.setAuthor({ name: interaction.user.discriminator == "0" ? interaction.user.username : interaction.user.tag, iconURL: interaction.user.displayAvatarURL() }) embed.setColor(color) // Obtenir le client du bot @@ -97,16 +81,20 @@ async function sendToChannel(interaction, embedInfos){ // Finir l'exécution try { // Envoyer l'embed - botClient.channels.cache.get(interaction.channelId).send({ embeds: [embed] }).catch(err => {}) + var isFailed = false + await botClient.channels.cache.get(interaction.channelId).send({ embeds: [embed] }).catch(err => { + isFailed = true + return bacheroFunctions.report.createAndReply("envoi du message", err, {}, interaction) + }) // Obtenir une astuce var astucesList = ["Vous pouvez écrire `\\n` pour faire un saut de ligne.", "Pour un message classique, vous pouvez utiliser la commande `/say`.", embedShowAuthor ? null : "Personne ne sait que vous êtes l'auteur de cette commande 🤫", "Certains textes sont automatiquements remplacés par des raccourcis, vous pouvez écrire `%DATE%` pour ajouter la date du jour.", "Il est possible d'ajouter des liens cliquables dans la description : `[texte](lien)`", "Le champ permettant d'ajouter une couleur à l'embed accepte des couleurs hexédécimales"].filter(a => a != null) var randomAstuce = astucesList[Math.floor(Math.random() * astucesList.length)] // Répondre à l'interaction - interaction.editReply({ content: `L'embed a été envoyé avec l'identifiant \`${uniqueId}\` !\n> **Tips :** ${notes.length ? notes.join(',') : randomAstuce}` }).catch(err => {}) + if(!isFailed) interaction.editReply({ content: `L'embed a été envoyé avec l'identifiant \`${uniqueId}\` !\n> **Tips :** ${notes.length ? notes.join(",") : randomAstuce}` }).catch(err => {}) } catch(err) { - return await bacheroFunctions.report.createAndReply("envoi du msesage", err, {}, interaction) + return await bacheroFunctions.report.createAndReply("envoi du message", err, {}, interaction) } } @@ -120,48 +108,48 @@ module.exports = { // Récupérer le listener et savoir lorsque quelqu'un renvoie le modal async interactionListener(listener){ - listener.on('modal', (interaction) => { - if(interaction.customId != 'embedCommand-getEmbedInfos') return + listener.on("modal", (interaction) => { + if(interaction.customId != "embedCommand-getEmbedInfos") return sendToChannel(interaction) }) }, - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Préparer les informations nécessaires pour l'embed var embedInfos = {} // Si on a entré une source - var source = interaction.options.getString('source') + var source = interaction.options.getString("source") if(source){ // Tenter d'obtenir certaines sources source = { all: source } - source.hastebin = source?.all?.match(/hastebin.com\/.{2,99}/g)?.toString()?.replace('hastebin.com/','') - source.text = source?.all?.match(/text.johanstick.me\/v\/\d*-\w*/g)?.toString()?.replace('/v/','/raw/') + // source.hastebin = source?.all?.match(/hastebin.com\/.{2,99}/g)?.toString()?.replace('hastebin.com/','') + source.text = source?.all?.match(/text.johanstick.fr\/v\/\d*-\w*/g)?.toString()?.replace("/v/", "/raw/") // Si on a réussi à obtenir un hastebin, obtenir son contenu // TODO: supporter l'utilisation de clé d'api, qui est forcé depuis quelques jours - if(source?.hastebin){ + // if(source?.hastebin){ + // // Obtenir le contenu + // var content = await fetch(`https://hastebin.com/raw/${source.hastebin}`, { headers: { 'User-Agent': 'BacheroBot (+https://github.com/bacherobot/bot)' } }).then(res => res.text()).catch(err => { return { message: err } }) + + // // Si on arrive à parser en JSON, c'est qu'il y a une erreur + // try { + // content = JSON.parse(content) + // } catch(err){} + // if(typeof content == 'object') return await bacheroFunctions.report.createAndReply("obtention du hastebin", content?.message?.toString() || content, {}, interaction) + + // // Sinon, définir les informations de l'embed + // embedInfos.description = content + // } + + // Si on a réussi à obtenir un texte, obtenir son contenu + if(source?.text){ // Obtenir le contenu - var content = await fetch(`https://hastebin.com/raw/${source.hastebin}`, { headers: { 'User-Agent': 'BacheroBot (+https://github.com/bacherobot/bot)' } }).then(res => res.text()).catch(err => { return { message: err } }) - - // Si on arrive à parser en JSON, c'est qu'il y a une erreur - try { - content = JSON.parse(content) - } catch(err){} - if(typeof content == 'object') return await bacheroFunctions.report.createAndReply("obtention du hastebin", content?.message?.toString() || content, {}, interaction) - - // Sinon, définir les informations de l'embed - embedInfos.description = content - } - - // Si on a réussi à obtenir un hastebin, obtenir son contenu - else if(source?.text){ - // Obtenir le contenu - var content = await fetch(`https://${source.text}`, { headers: { 'User-Agent': 'BacheroBot (+https://github.com/bacherobot/bot)' } }).then(res => res.text()).catch(err => { return `/\\ ERREUR /\\\n\n${err}` }) + var content = await fetch(`https://${source.text}`, { headers: { "User-Agent": "BacheroBot (+https://github.com/bacherobot/bot)" } }).then(res => res.text()).catch(err => { return `/\\ ERREUR /\\\n\n${err}` }) // Si il y a une erreur - if(content?.toString()?.startsWith('/\\ ERREUR /\\')) return await bacheroFunctions.report.createAndReply("obtention du texte", content?.replace('/\\ ERREUR /\\\n\n','')?.toString() || content, {}, interaction) + if(content?.toString()?.startsWith("/\\ ERREUR /\\")) return await bacheroFunctions.report.createAndReply("obtention du texte", content?.replace("/\\ ERREUR /\\\n\n", "")?.toString() || content, {}, interaction) // Sinon, définir les informations de l'embed embedInfos.description = content @@ -171,7 +159,7 @@ module.exports = { else if(source?.all){ // Obtenir le contenu var content = (await bacheroFunctions.database.get(database, `embedId-${source.all}`)) || null - + // Si il existe, définir les informations de l'embed if(content) embedInfos = content } @@ -188,51 +176,43 @@ module.exports = { // Créér un modal const modal = new ModalBuilder() - .setCustomId('embedCommand-getEmbedInfos') - .setTitle('Créer un embed') + .setCustomId("embedCommand-getEmbedInfos") + .setTitle("Créer un embed") // Ajouter des champs dans le modal modal.addComponents( - new ActionRowBuilder().addComponents( - new TextInputBuilder() - .setCustomId('embedCommand-title') + new ActionRowBuilder().addComponents(new TextInputBuilder() + .setCustomId("embedCommand-title") .setLabel("Titre") .setPlaceholder("Titre, affiché tout en haut de l'embed") .setStyle(TextInputStyle.Short) .setRequired(false) .setMaxLength(256) - .setValue(embedInfos.title || '') - ), - new ActionRowBuilder().addComponents( - new TextInputBuilder() - .setCustomId('embedCommand-description') + .setValue(embedInfos.title || "")), + new ActionRowBuilder().addComponents(new TextInputBuilder() + .setCustomId("embedCommand-description") .setLabel("Description") .setPlaceholder("Contenu principal de l'embed, avec une limite de caractère bien plus élevée qu'un message classique") .setStyle(TextInputStyle.Paragraph) .setRequired(false) .setMaxLength(4000) - .setValue(embedInfos.description || '') - ), - new ActionRowBuilder().addComponents( - new TextInputBuilder() - .setCustomId('embedCommand-footer') + .setValue(embedInfos.description || "")), + new ActionRowBuilder().addComponents(new TextInputBuilder() + .setCustomId("embedCommand-footer") .setLabel("Footer") .setPlaceholder("Informations supplémentaires, affiché tout en bas") .setStyle(TextInputStyle.Paragraph) .setRequired(false) .setMaxLength(2048) - .setValue(embedInfos.footer || '') - ), - new ActionRowBuilder().addComponents( - new TextInputBuilder() - .setCustomId('embedCommand-color') + .setValue(embedInfos.footer || "")), + new ActionRowBuilder().addComponents(new TextInputBuilder() + .setCustomId("embedCommand-color") .setLabel("Couleur") .setPlaceholder("Ajoute une couleur via un code hexadécimal, ou parmi: rouge/vert/bleu/orange/blanc/noir/jaune/violet") .setStyle(TextInputStyle.Paragraph) .setRequired(false) .setMaxLength(12) - .setValue(embedInfos.color || '') - ) + .setValue(embedInfos.color || "")) ) // Afficher le modal diff --git a/modules/bachero.module.message/first.js b/modules/bachero.module.message/first.js index 61a40bc..14dc879 100644 --- a/modules/bachero.module.message/first.js +++ b/modules/bachero.module.message/first.js @@ -1,22 +1,22 @@ -const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js') -const bacheroFunctions = require('../../functions') -const escape = require('markdown-escape') +const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js") +const bacheroFunctions = require("../../functions") +const escape = require("markdown-escape") // Exporter certaines fonctions module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('first') - .setDescription('Affiche le premier message dans ce salon'), + .setName("first") + .setDescription("Affiche le premier message dans ce salon"), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Vérifier si l'utilisateur est limité, et si c'est pas le cas, le limiter - var checkAndReply = await bacheroFunctions.cooldown.checkAndReply(interaction, 'firstCommandeUsage') - if(checkAndReply) return; else await bacheroFunctions.cooldown.set('firstCommandeUsage', interaction.user.id, 5000) + var checkAndReply = await bacheroFunctions.cooldown.checkAndReply(interaction, "firstCommandeUsage") + if(checkAndReply) return; else await bacheroFunctions.cooldown.set("firstCommandeUsage", interaction.user.id, 5000) // Mettre la réponse en defer et obtenir la date - if(await interaction.deferReply().catch(err => { return 'stop' }) == 'stop') return + if(await interaction.deferReply().catch(err => { return "stop" }) == "stop") return var date = Date.now() // Obtenir le premier message @@ -28,23 +28,21 @@ module.exports = { // Créer un embed var embed = new EmbedBuilder() - .setTitle(`Premier message${interaction?.channel?.name?.length ? ` dans \`#${interaction.channel.name}\`` : ''}`) - .setDescription(first.content || first?.embeds?.[0]?.description || first.url || "Impossible d'obtenir le contenu") - .addFields( - { name: "Date", value: ``, inline: true }, - { name: "Auteur", value: first.author.discriminator == '0' ? escape(first.author.username) : escape(first.author.tag), inline: true }, - { name: "Identifiant", value: first.id, inline: true } - ) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - .setFooter({ text: `Résultat obtenu en ${Math.round((new Date().getTime() - date))} ms` }) + .setTitle(`Premier message${interaction?.channel?.name?.length ? ` dans \`#${interaction.channel.name}\`` : ""}`) + .setDescription(first.content || first?.embeds?.[0]?.description || first.url || "Impossible d'obtenir le contenu") + .addFields( + { name: "Date", value: ``, inline: true }, + { name: "Auteur", value: first.author.discriminator == "0" ? escape(first.author.username) : escape(first.author.tag), inline: true }, + { name: "Identifiant", value: first.id, inline: true } + ) + .setColor(bacheroFunctions.colors.primary) + .setFooter({ text: `Résultat obtenu en ${Math.round((new Date().getTime() - date))} ms` }) // Créé un bouton - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder() + const row = new ActionRowBuilder().addComponents(new ButtonBuilder() .setURL(first.url || "https://discord.com") // oui parce que si on a pas la valeur du .url, ça crash .setStyle(ButtonStyle.Link) - .setLabel('Accéder au message'), - ) + .setLabel("Accéder au message"),) // Répondre à l'interaction interaction.editReply({ embeds: [embed], components: [row] }).catch(err => {}) diff --git a/modules/bachero.module.message/manifest.jsonc b/modules/bachero.module.message/manifest.jsonc index d52e4f1..70087b3 100644 --- a/modules/bachero.module.message/manifest.jsonc +++ b/modules/bachero.module.message/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Ce module rajoute plusieurs commandes en lien avec la gestion des messages", - "longDescription": "Ce module rajoute plusieurs commandes permettant de gérer les messages des serveurs, pour en supprimer ou en envoyer.", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.message/say.js b/modules/bachero.module.message/say.js index ea969f8..5f4c6b9 100644 --- a/modules/bachero.module.message/say.js +++ b/modules/bachero.module.message/say.js @@ -1,22 +1,22 @@ -const { SlashCommandBuilder, PermissionFlagsBits, AttachmentBuilder } = require('discord.js') -const bacheroFunctions = require('../../functions') -const escape = require('markdown-escape') -var botName = bacheroFunctions.config.getValue('bachero', 'botName') -var sayWithoutPermissions = bacheroFunctions.config.getValue('bachero.module.message', 'sayWithoutPermissions') -var sayShowAuthor = bacheroFunctions.config.getValue('bachero.module.message', 'sayShowAuthor') +const { SlashCommandBuilder, PermissionFlagsBits, AttachmentBuilder } = require("discord.js") +const bacheroFunctions = require("../../functions") +const escape = require("markdown-escape") +var botName = bacheroFunctions.config.getValue("bachero", "botName") +var sayWithoutPermissions = bacheroFunctions.config.getValue("bachero.module.message", "sayWithoutPermissions") +var sayShowAuthor = bacheroFunctions.config.getValue("bachero.module.message", "sayShowAuthor") var botClient // Créé la commande slash var slashInfo = new SlashCommandBuilder() -.setName('say') -.setDescription(`Envoie un message ${sayShowAuthor ? '' : 'anonymement '}sur le serveur en tant que ${botName}`) -.addStringOption(option => option.setName('text') - .setDescription('Contenu du message à envoyer') - .setRequired(true) - .setMaxLength(1999)) -.addAttachmentOption(option => option.setName('attachment') - .setDescription('Permet d\'ajouter un attachement au message') - .setRequired(false)) + .setName("say") + .setDescription(`Envoie un message ${sayShowAuthor ? "" : "anonymement "}sur le serveur en tant que ${botName}`) + .addStringOption(option => option.setName("text") + .setDescription("Contenu du message à envoyer") + .setRequired(true) + .setMaxLength(1999)) + .addAttachmentOption(option => option.setName("attachment") + .setDescription("Permet d'ajouter un attachement au message") + .setRequired(false)) if(!sayWithoutPermissions) slashInfo.setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages) // Exporter certaines fonctions @@ -24,23 +24,23 @@ module.exports = { // Définir les infos de la commande slash slashInfo: slashInfo, - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Mettre la réponse en defer - if(interaction.sourceType !== 'textCommand' && await interaction.deferReply({ ephemeral: true }).catch(err => { return 'stop' }) == 'stop') return + if(interaction.sourceType !== "textCommand" && await interaction.deferReply({ ephemeral: true }).catch(err => { return "stop" }) == "stop") return // Obtenir le texte à envoyer - var text = interaction.options.getString('text') - text = text.replace(/\\n/g, '\n').replace(/%JUMP%/g, '\n').replace(/%DATE%/g, ``) + var text = interaction.options.getString("text") + text = text.replace(/\\n/g, "\n").replace(/%JUMP%/g, "\n").replace(/%DATE%/g, ``) // Rajouter l'auteur - if(sayShowAuthor) text = `\`${interaction.user.discriminator == '0' ? escape(interaction.user.username) : escape(interaction.user.tag)}\`\n${text}` + if(sayShowAuthor) text = `\`${interaction.user.discriminator == "0" ? escape(interaction.user.username) : escape(interaction.user.tag)}\`\n${text}` // Vérifier sa taille - if(text.length > 1999) return interaction.editReply({ content: 'Votre message dépasse la limite de caractère (2000 caractères)' }).catch(err => {}) + if(text.length > 1999) return interaction.editReply({ content: "Votre message dépasse la limite de caractère (2000 caractères)" }).catch(err => {}) // Obtenir l'attachement - var attachment = await interaction.options.getAttachment('attachment') + var attachment = await interaction.options.getAttachment("attachment") if(attachment) attachment = new AttachmentBuilder(attachment.url) // Obtenir le client du bot @@ -51,20 +51,24 @@ module.exports = { // Envoyer le message var messageOption = { content: text } if(attachment) messageOption.files = [attachment] - botClient.channels.cache.get(interaction.channelId).send(messageOption) + var isFailed = false + await botClient.channels.cache.get(interaction.channelId).send(messageOption).catch(err => { + isFailed = true + return bacheroFunctions.report.createAndReply("envoi du message", err, {}, interaction) + }) // Obtenir une astuce var astucesList = ["Vous pouvez écrire `\\n` pour faire un saut de ligne.", "La commande `/embed` permet d'afficher plus d'informations dans vos messages.", sayShowAuthor ? null : "Personne ne sait que vous êtes l'auteur de cette commande 🤫", "Certains textes sont automatiquements remplacés par des raccourcis, vous pouvez écrire `%DATE%` pour ajouter la date du jour."].filter(a => a != null) var randomAstuce = astucesList[Math.floor(Math.random() * astucesList.length)] // Répondre à l'interaction - if(interaction.sourceType !== 'textCommand') interaction.editReply({ content: `Message envoyé !\n> **Tips :** ${randomAstuce}` }).catch(err => {}) + if(interaction.sourceType !== "textCommand" && !isFailed) interaction.editReply({ content: `Message envoyé !\n> **Tips :** ${randomAstuce}` }).catch(err => {}) } catch(err) { - return await bacheroFunctions.report.createAndReply("envoi du msesage", err, {}, interaction) + return await bacheroFunctions.report.createAndReply("envoi du message", err, {}, interaction) } // Si c'est une commande texte, tenter de supprimer le message d'invocation - if(interaction.sourceType == 'textCommand'){ + if(interaction.sourceType == "textCommand"){ try { interaction.delete().catch(err => {}) } catch(err) {} // Le choix de la sécurité } } diff --git a/modules/bachero.module.message/slowmode.js b/modules/bachero.module.message/slowmode.js index c86f56d..fe0e219 100644 --- a/modules/bachero.module.message/slowmode.js +++ b/modules/bachero.module.message/slowmode.js @@ -1,50 +1,50 @@ -const { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder } = require('discord.js') -const bacheroFunctions = require('../../functions') -var botName = bacheroFunctions.config.getValue('bachero', 'botName') +const { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder } = require("discord.js") +const bacheroFunctions = require("../../functions") +var botName = bacheroFunctions.config.getValue("bachero", "botName") // Exporter certaines fonctions module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('slowmode') - .setDescription('Modifie le temps utilisé pour le mode lent dans ce salon') - .addNumberOption(option => option.setName('time') - .setDescription('Temps à définir (en secondes)') + .setName("slowmode") + .setDescription("Modifie le temps utilisé pour le mode lent dans ce salon") + .addNumberOption(option => option.setName("time") + .setDescription("Temps à définir (en secondes)") .setRequired(true) .setMinValue(0) .setMaxValue(21600)) .setDefaultMemberPermissions(PermissionFlagsBits.ManageChannels) .setDMPermission(false), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Mettre la réponse en defer - if(await interaction.deferReply().catch(err => { return 'stop' }) == 'stop') return + if(await interaction.deferReply().catch(err => { return "stop" }) == "stop") return // Obtenir le temps à définir - var nextTime = interaction.options.getNumber('time') + var nextTime = interaction.options.getNumber("time") // Obtenir le temps qui était actuellement défini dans le salon var currentTime = interaction.channel.rateLimitPerUser // Si le type de salon est incorrect - if(interaction.channel.type != 0) return interaction.editReply({ content: `Cette commande ne peut qu'être exécutée dans un salon textuel.` }).catch(err => {}) + if(interaction.channel.type != 0) return interaction.editReply({ content: "Cette commande ne peut qu'être exécutée dans un salon textuel." }).catch(err => {}) // Si le temps à définir est le même que celui actuellement défini if(nextTime == currentTime) return interaction.editReply({ content: `Le mode lent est déjà défini sur ${currentTime} secondes.` }).catch(err => {}) // Modifier le temps dans le salon try { - interaction.channel.setRateLimitPerUser(nextTime, `${interaction.user.discriminator == '0' ? interaction.user.username : interaction.user.tag} (ID : ${interaction.user.id}) a modifié le slowmode via la commande /slowmode`).catch(err => { return err }) - interaction.editReply({ content: `Le temps à attendre entre chaque message est passé de ${currentTime} ${currentTime > 1 ? 'secondes' : 'seconde'} à ${nextTime} ${nextTime > 1 ? 'secondes' : 'seconde'}.` }) + interaction.channel.setRateLimitPerUser(nextTime, `${interaction.user.discriminator == "0" ? interaction.user.username : interaction.user.tag} (ID : ${interaction.user.id}) a modifié le slowmode via la commande /slowmode`).catch(err => { return err }) + interaction.editReply({ content: `Le temps à attendre entre chaque message est passé de ${currentTime} ${currentTime > 1 ? "secondes" : "seconde"} à ${nextTime} ${nextTime > 1 ? "secondes" : "seconde"}.` }) } catch(err) { // S’il y a eu une erreur // Note : cet embed est assez commun lorsque le bot n'a pas la permission, pour éviter de créer trop de rapports d'erreurs, cette méthode ne sera pas utilisée var embed = new EmbedBuilder() - .setTitle("Impossible de modifier le mode lent") - .setDescription("Un problème est survenu lors de la modification des paramètres du salon :\n```\n" + (err?.toString()?.replace(/`/g, ' `').replace('Missing Permissions', "Je n'ai pas la permission de gérer ce salon.") || err) + "\n```") - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - .setFooter({ text: `Si vous pensez que ce problème a quelque chose à voir avec ${botName}, n'hésitez pas à le signaler` }) + .setTitle("Impossible de modifier le mode lent") + .setDescription(`Un problème est survenu lors de la modification des paramètres du salon :\n\`\`\`\n${err?.toString()?.replace(/`/g, " `").replace("Missing Permissions", "Je n'ai pas la permission de gérer ce salon.") || err}\n\`\`\``) + .setColor(bacheroFunctions.colors.secondary) + .setFooter({ text: `Si vous pensez que ce problème a quelque chose à voir avec ${botName}, n'hésitez pas à le signaler` }) interaction.editReply({ embeds: [embed] }).catch(err => {}) } } diff --git a/modules/bachero.module.minecraft/manifest.jsonc b/modules/bachero.module.minecraft/manifest.jsonc index c43e648..ad2188b 100644 --- a/modules/bachero.module.minecraft/manifest.jsonc +++ b/modules/bachero.module.minecraft/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Obtient des informations sur un serveur Minecraft en une commande", - "longDescription": "Rajoute une commande permettant d'obtenir des informations sur un serveur Minecraft, qu'il soit sur l'édition Java ou Bedrock.", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.minecraft/mc-server.js b/modules/bachero.module.minecraft/mc-server.js index 947415f..1ae6be4 100644 --- a/modules/bachero.module.minecraft/mc-server.js +++ b/modules/bachero.module.minecraft/mc-server.js @@ -1,45 +1,41 @@ -const { SlashCommandBuilder, EmbedBuilder } = require('discord.js') -const bacheroFunctions = require('../../functions') -const fetch = require('node-fetch') -const escape = require('markdown-escape') +const { SlashCommandBuilder, EmbedBuilder } = require("discord.js") +const bacheroFunctions = require("../../functions") +const fetch = require("node-fetch") +const escape = require("markdown-escape") module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('mc-server') - .setDescription('Vérifie et renvoie des informations sur un serveur Minecraft') + .setName("mc-server") + .setDescription("Vérifie et renvoie des informations sur un serveur Minecraft") .addSubcommand((subcommand) => subcommand - .setName('java') - .setDescription('Vérifie un serveur pour l\'édition Java') - .addStringOption(option => option.setName('ip') - .setDescription('IP du serveur') + .setName("java") + .setDescription("Vérifie un serveur pour l'édition Java") + .addStringOption(option => option.setName("ip") + .setDescription("IP du serveur") .setMaxLength(320) - .setRequired(true) - ), - ) + .setRequired(true)),) .addSubcommand((subcommand) => subcommand - .setName('bedrock') - .setDescription('Vérifie un serveur pour l\'édition Bedrock') - .addStringOption(option => option.setName('ip') - .setDescription('IP du serveur') + .setName("bedrock") + .setDescription("Vérifie un serveur pour l'édition Bedrock") + .addStringOption(option => option.setName("ip") + .setDescription("IP du serveur") .setMaxLength(320) - .setRequired(true) - ), - ), + .setRequired(true)),), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Mettre la réponse en defer - if(await interaction.deferReply().catch(err => { return 'stop' }) == 'stop') return + if(await interaction.deferReply().catch(err => { return "stop" }) == "stop") return // Obtenir l'adresse IP et l'édition - var ip = interaction.options.getString('ip') + var ip = interaction.options.getString("ip") var edition = interaction.options.getSubcommand() // Obtenir les informations du serveur - var infos = await fetch(`https://api.mcstatus.io/v2/status/${edition || 'java'}/${ip}`, { headers: { 'User-Agent': 'BacheroBot (+https://github.com/bacherobot/bot)' } }).catch(err => { return { message: err } }) - var cache_hit = infos.headers.get('X-Cache-Hit') == 'true' - if(cache_hit) var cache_time_remaining = infos.headers.get('X-Cache-Time-Remaining') // (en secondes) + var infos = await fetch(`https://api.mcstatus.io/v2/status/${edition || "java"}/${ip}`, { headers: { "User-Agent": "BacheroBot (+https://github.com/bacherobot/bot)" } }).catch(err => { return { message: err } }) + var cache_hit = infos.headers.get("X-Cache-Hit") == "true" + if(cache_hit) var cache_time_remaining = infos.headers.get("X-Cache-Time-Remaining") // (en secondes) infos = await infos.json().catch(err => { return { message: err } }) // Si on a une erreur @@ -47,18 +43,18 @@ module.exports = { // Créer l'embed var embed = new EmbedBuilder() - .setTitle("Résultat de la vérification") - .addFields([ - !infos.online ? { name: 'Statut', value: 'Hors ligne', inline: true } : undefined, - infos.host ? { name: 'Domaine', value: escape(infos.host), inline: true } : undefined, - infos.port ? { name: 'Port', value: infos.port.toString(), inline: true } : undefined, - infos.players ? { name: 'Joueurs', value: escape(`${infos?.players?.online}/${infos?.players?.max}${infos?.players?.list?.length ? ' : ' + infos.players.list.map(p => p.name_clean || p.name_raw || p.uuid || p).join(', ') : ''}`.substring(0, 1024)), inline: true } : undefined, - edition == 'java' && infos.version ? { name: 'Version', value: escape((infos.version?.name_clean || infos.version?.name_raw || infos.version?.protocol || infos.version || 'Inconnu').toString()), inline: true } : undefined, - infos?.motd?.clean && infos.motd.clean != 'A Minecraft Server' ? { name: 'MOTD', value: escape(infos?.motd?.clean), inline: true } : undefined, - infos.eula_blocked ? { name: 'Bloqué EULA', value: 'Oui', inline: true } : undefined, - ].filter(Boolean)) - .setColor(infos.online ? bacheroFunctions.config.getValue('bachero', 'embedColor') : bacheroFunctions.config.getValue('bachero', 'secondEmbedColor')) - .setFooter({ text: `Sous la demande de ${interaction.user.discriminator == '0' ? escape(interaction.user.username) : escape(interaction.user.tag)}${cache_hit ? ' • Provient du cache' : ''}${cache_time_remaining ? `, S'actualise dans ${cache_time_remaining} seconde${cache_time_remaining > 1 ? 's' : ''}` : ''}` }) + .setTitle("Résultat de la vérification") + .addFields([ + !infos.online ? { name: "Statut", value: "Hors ligne", inline: true } : undefined, + infos.host ? { name: "Domaine", value: escape(infos.host), inline: true } : undefined, + infos.port ? { name: "Port", value: infos.port.toString(), inline: true } : undefined, + infos.players ? { name: "Joueurs", value: escape(`${infos?.players?.online}/${infos?.players?.max}${infos?.players?.list?.length ? ` : ${infos.players.list.map(p => p.name_clean || p.name_raw || p.uuid || p).join(", ")}` : ""}`.substring(0, 1024)), inline: true } : undefined, + edition == "java" && infos.version ? { name: "Version", value: escape((infos.version?.name_clean || infos.version?.name_raw || infos.version?.protocol || infos.version || "Inconnu").toString()), inline: true } : undefined, + infos?.motd?.clean && infos.motd.clean != "A Minecraft Server" ? { name: "MOTD", value: escape(infos?.motd?.clean), inline: true } : undefined, + infos.eula_blocked ? { name: "Bloqué EULA", value: "Oui", inline: true } : undefined, + ].filter(Boolean)) + .setColor(infos.online ? bacheroFunctions.colors.primary : bacheroFunctions.colors.secondary) + .setFooter({ text: `Sous la demande de ${interaction.user.discriminator == "0" ? interaction.user.username : interaction.user.tag}${cache_hit ? " • Provient du cache" : ""}${cache_time_remaining ? `, S'actualise dans ${cache_time_remaining} seconde${cache_time_remaining > 1 ? "s" : ""}` : ""}` }) // Envoyer l'embed interaction.editReply({ embeds: [embed] }).catch(err => {}) diff --git a/modules/bachero.module.moduleInfo/manifest.jsonc b/modules/bachero.module.moduleInfo/manifest.jsonc index d15f81a..ae42f9d 100644 --- a/modules/bachero.module.moduleInfo/manifest.jsonc +++ b/modules/bachero.module.moduleInfo/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Ce module rajoute la commande /module", - "longDescription": "Ce module rajoute une commande permettant d'obtenir la liste des modules actuellement installés, ou des informations détaillées sur un seul via son nom de packet", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.moduleInfo/module.js b/modules/bachero.module.moduleInfo/module.js index 669e0f4..5206d8c 100644 --- a/modules/bachero.module.moduleInfo/module.js +++ b/modules/bachero.module.moduleInfo/module.js @@ -1,24 +1,24 @@ -const { SlashCommandBuilder, EmbedBuilder } = require('discord.js') -const bacheroFunctions = require('../../functions') -const authorizedIds = bacheroFunctions.config.getValue('bachero.module.moduleInfo', 'authorizedIds') +const { SlashCommandBuilder, EmbedBuilder } = require("discord.js") +const bacheroFunctions = require("../../functions") +const authorizedIds = bacheroFunctions.config.getValue("bachero.module.moduleInfo", "authorizedIds") var allModulesDetails var listModules = [] -var pages = [''] // Faire que le premier élément (0) soit vide, pour que la liste commence à 1 +var pages = [""] // Faire que le premier élément (0) soit vide, pour que la liste commence à 1 module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('module') - .setDescription('Affiche la liste des modules') - .addStringOption(option => option.setName('packagename') - .setDescription('Affiche des informations sur un module en particulier') + .setName("module") + .setDescription("Affiche la liste des modules") + .addStringOption(option => option.setName("packagename") + .setDescription("Affiche des informations sur un module en particulier") .setRequired(false)) - .addNumberOption(option => option.setName('page') + .addNumberOption(option => option.setName("page") .setDescription("Permet de choisir la page affichée lorsqu'on n'entre pas de nom de module") .setRequired(false)), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Vérifier que la personne est autorisé if(authorizedIds?.length && !authorizedIds?.includes(interaction.user.id)) return interaction.reply({ ephemeral: true, content: "Oupsi, tu n'as pas le droit d'utiliser cette commande..." }).catch(err => {}) @@ -27,7 +27,7 @@ module.exports = { if(!allModulesDetails) allModulesDetails = bacheroFunctions.modules.allModulesDetails() // Obtenir le nom de packet - var packageName = interaction.options.getString('packagename') + var packageName = interaction.options.getString("packagename") // Obtenir la liste des modules si elle n'a pas encore été défini if(!listModules?.length) listModules = Object.values(Object.fromEntries(allModulesDetails)) @@ -37,8 +37,8 @@ module.exports = { if(!pages?.[1]) listModules.forEach(mod => { if(modulesMessage.length > 3900){ pages.push(modulesMessage) - modulesMessage = `\n• *${mod.packageName}* : ${mod.shortDescription.replace(/`/g, '')}` - } else modulesMessage += `\n• *${mod.packageName}* : ${mod.shortDescription.replace(/`/g, '')}` + modulesMessage = `\n• *${mod.packageName}* : ${mod.shortDescription.replace(/`/g, "")}` + } else modulesMessage += `\n• *${mod.packageName}* : ${mod.shortDescription.replace(/`/g, "")}` }) if(modulesMessage) pages.push(modulesMessage) @@ -46,17 +46,17 @@ module.exports = { if(!packageName){ // Créér un embed pour afficher la liste des modules var embed = new EmbedBuilder() - .setTitle('Liste des modules') - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) + .setTitle("Liste des modules") + .setColor(bacheroFunctions.colors.primary) // Si on veut choisir une page à afficher - var currentlyShowedPage = interaction.options.getNumber('page') || 1 - if(currentlyShowedPage > pages?.length - 1) embed.setFooter({ text: `Première page affichée car la valeur que vous avez spécifiée est trop haute` }) - else if(currentlyShowedPage < 1) embed.setFooter({ text: `Première page affichée car la valeur que vous avez spécifiée est trop basse` }) + var currentlyShowedPage = interaction.options.getNumber("page") || 1 + if(currentlyShowedPage > pages?.length - 1) embed.setFooter({ text: "Première page affichée car la valeur que vous avez spécifiée est trop haute" }) + else if(currentlyShowedPage < 1) embed.setFooter({ text: "Première page affichée car la valeur que vous avez spécifiée est trop basse" }) else embed.setFooter({ text: `Affichage de la page ${currentlyShowedPage}/${pages?.length - 1} • ${listModules?.length} résultats` }) // Ajouter la page dans l'embed - embed.setDescription(pages[currentlyShowedPage] || pages[1] || pages[0] || pages?.join('\n') || pages) // le choix de la sécurité + embed.setDescription(pages[currentlyShowedPage] || pages[1] || pages[0] || pages?.join("\n") || pages) // le choix de la sécurité // Répondre avec l'embed interaction.reply({ embeds: [embed] }).catch(err => {}) @@ -65,23 +65,23 @@ module.exports = { else { // Obtenir le module var module = listModules.find(m => m.packageName == packageName) - if(!module) var module = listModules.find(m => m.packageName.toLowerCase().replace(/[^a-zA-Z]+/g, '') == packageName.toLowerCase().replace(/[^a-zA-Z]+/g, '')) + if(!module) var module = listModules.find(m => m.packageName.toLowerCase().replace(/[^a-zA-Z]+/g, "") == packageName.toLowerCase().replace(/[^a-zA-Z]+/g, "")) // Si le module n'existe pas, répondre avec un message d'erreur if(!module){ var embed = new EmbedBuilder() - .setTitle('Module introuvable') - .setDescription(`Aucun module avec le nom \`${packageName.replace(/`/g, '')}\` n'a été trouvé. Utiliser la commande sans arguments pour obtenir la liste complète.`) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) + .setTitle("Module introuvable") + .setDescription(`Aucun module avec le nom \`${packageName.replace(/`/g, "")}\` n'a été trouvé. Utiliser la commande sans arguments pour obtenir la liste complète.`) + .setColor(bacheroFunctions.colors.secondary) return interaction.reply({ embeds: [embed] }).catch(err => {}) } // Sinon, créer un embed pour afficher les infos du module var embed = new EmbedBuilder() - .setTitle(module.name) - .setDescription(`> ${module.shortDescription.replace(/\n/g, ' ').replace(/`/g, '')}\n\n**Nom de packet :** ${module.packageName}\n**Auteur${module.authors.length > 1 ? 's' : ''} :** ${module.authors.join(', ')}\n**Commande${module.commands.length > 1 ? 's' : ''} :** ${(module?.commands?.length > 0 ? module.commands : [{name:'Aucune'}]).map(c => c.name).join(', ')}`) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - if(module.source && typeof module.source == 'string') embed.setURL(module.source) + .setTitle(module.name) + .setDescription(`> ${module.shortDescription.replace(/\n/g, " ").replace(/`/g, "")}\n\n**Nom de packet :** ${module.packageName}\n**Auteur${module.authors.length > 1 ? "s" : ""} :** ${module.authors.join(", ")}\n**Commande${module.commands.length > 1 ? "s" : ""} :** ${(module?.commands?.length > 0 ? module.commands : [{ name: "Aucune" }]).map(c => c.name).join(", ")}`) + .setColor(bacheroFunctions.colors.primary) + if(module.source && typeof module.source == "string") embed.setURL(module.source) // Répondre avec l'embed interaction.reply({ embeds: [embed] }).catch(err => {}) diff --git a/modules/bachero.module.pfc/manifest.jsonc b/modules/bachero.module.pfc/manifest.jsonc index 9d5c176..229e160 100644 --- a/modules/bachero.module.pfc/manifest.jsonc +++ b/modules/bachero.module.pfc/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Ce module rajoute une commande pfc", - "longDescription": "Ce module rajoute le jeu du pierre feuille ciseau dans Discord", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.pfc/pfc.js b/modules/bachero.module.pfc/pfc.js index 6c3622b..42d6d3d 100644 --- a/modules/bachero.module.pfc/pfc.js +++ b/modules/bachero.module.pfc/pfc.js @@ -1,21 +1,21 @@ -const { SlashCommandBuilder, EmbedBuilder, ButtonBuilder, ButtonStyle, AttachmentBuilder, ActionRowBuilder, ComponentType } = require('discord.js') -const { rando } = require('@nastyox/rando.js') -var CronJob = require('cron').CronJob -const bacheroFunctions = require('../../functions') -const database = bacheroFunctions.database.getDatabase('bachero.module.pfc') -const disableCooldown = bacheroFunctions.config.getValue('bachero.module.pfc', 'disableCooldown') -const disableAutoResetLeaderboard = bacheroFunctions.config.getValue('bachero.module.pfc', 'disableAutoResetLeaderboard') +const { SlashCommandBuilder, EmbedBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder } = require("discord.js") +const { rando } = require("@nastyox/rando.js") +var CronJob = require("cron").CronJob +const bacheroFunctions = require("../../functions") +const database = bacheroFunctions.database.getDatabase("bachero.module.pfc") +const disableCooldown = bacheroFunctions.config.getValue("bachero.module.pfc", "disableCooldown") +const disableAutoResetLeaderboard = bacheroFunctions.config.getValue("bachero.module.pfc", "disableAutoResetLeaderboard") // Fonction qui permet de déterminer si un joueur a gagné ou perdu function determineWinner(playerChoice, playerWinRatio){ // Enlever le "pfc-" au début du choix du joueur - playerChoice = playerChoice.replace('pfc-', '') + playerChoice = playerChoice.replace("pfc-", "") // Liste des possibilités du bot var botChoices = [ - { name: 'pierre', rate: 50 }, - { name: 'feuille', rate: 50 }, - { name: 'ciseau', rate: 50 } + { name: "pierre", rate: 50 }, + { name: "feuille", rate: 50 }, + { name: "ciseau", rate: 50 } ] botChoices.find(choice => choice.name == playerChoice).rate = 15 // baisser la probabilité que le bot trouve le même résultat que l'utilisateur @@ -28,16 +28,16 @@ function determineWinner(playerChoice, playerWinRatio){ botAnswer = botAnswer.value.name // Déterminer si le joueur a gagné, ou perdu - var winner = '' - if(playerChoice == 'pierre' && botAnswer == 'feuille') winner = 'bot' - if(playerChoice == 'feuille' && botAnswer == 'ciseau') winner = 'bot' - if(playerChoice == 'ciseau' && botAnswer == 'pierre') winner = 'bot' - if(playerChoice == 'pierre' && botAnswer == 'ciseau') winner = 'player' - if(playerChoice == 'feuille' && botAnswer == 'pierre') winner = 'player' - if(playerChoice == 'ciseau' && botAnswer == 'feuille') winner = 'player' - if(playerChoice == 'pierre' && botAnswer == 'pierre') winner = 'draw' - if(playerChoice == 'feuille' && botAnswer == 'feuille') winner = 'draw' - if(playerChoice == 'ciseau' && botAnswer == 'ciseau') winner = 'draw' + var winner = "" + if(playerChoice == "pierre" && botAnswer == "feuille") winner = "bot" + if(playerChoice == "feuille" && botAnswer == "ciseau") winner = "bot" + if(playerChoice == "ciseau" && botAnswer == "pierre") winner = "bot" + if(playerChoice == "pierre" && botAnswer == "ciseau") winner = "player" + if(playerChoice == "feuille" && botAnswer == "pierre") winner = "player" + if(playerChoice == "ciseau" && botAnswer == "feuille") winner = "player" + if(playerChoice == "pierre" && botAnswer == "pierre") winner = "draw" + if(playerChoice == "feuille" && botAnswer == "feuille") winner = "draw" + if(playerChoice == "ciseau" && botAnswer == "ciseau") winner = "draw" // Retourner le résultat return { winner, botAnswer } @@ -46,26 +46,27 @@ function determineWinner(playerChoice, playerWinRatio){ // Fonction pour réinitialiser les scores async function resetScores(){ // Obtenir toute la base de données - var databaseJSON = await bacheroFunctions.database.getAll(database) + var databaseJSON = await bacheroFunctions.database.getAll(database) // Si la dernière fois qu'on a réinitialisé les scores n'était pas il y a plus de 30 jours et 20 heures, ne rien faire var lastReset = databaseJSON.lastReset - if(lastReset && lastReset > Date.now() - (30 * 24 * 60 * 60 * 1000 + 20 * 60 * 60 * 1000)) return; else databaseJSON.lastReset = Date.now() + if(lastReset && lastReset > Date.now() - ((30 * 24 * 60 * 60 * 1000) + (20 * 60 * 60 * 1000))) return; else databaseJSON.lastReset = Date.now() // Réinisialiser les scores de tout le monde for(var key of Object.keys(databaseJSON)){ - if(key.startsWith('winCount-')) bacheroFunctions.database.delete(database, key) - if(key.startsWith('loseCount-')) bacheroFunctions.database.delete(database, key) + if(key.startsWith("winCount-")) bacheroFunctions.database.delete(database, key) + if(key.startsWith("loseCount-")) bacheroFunctions.database.delete(database, key) } // Définir la date de dernière réinisialisation des scores - bacheroFunctions.database.set(database, 'lastReset', Date.now()) + bacheroFunctions.database.set(database, "lastReset", Date.now()) } if(disableAutoResetLeaderboard != true){ // Tous les jours à sept heures, tenter de réinitialiser les scores - new CronJob('0 7 * * *', async function(){ + new CronJob("0 7 * * *", (async () => { resetScores() - }) + })).start() + // Vérifier si on devrait supprimer les scores, au moment où le bot démarre resetScores() } @@ -74,25 +75,25 @@ if(disableAutoResetLeaderboard != true){ module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('pfc') - .setDescription('Permet de jouer au pierre feuille ciseau') - .addBooleanOption(option => option.setName('showleaderboard') - .setDescription('Affiche le classement des joueurs') + .setName("pfc") + .setDescription("Permet de jouer au pierre feuille ciseau") + .addBooleanOption(option => option.setName("showleaderboard") + .setDescription("Affiche le classement des joueurs") .setRequired(false)), // Récupérer le listener bouton (quand quelqu'un clique sur un bouton) async interactionListener(listener){ - listener.on('button', async (interaction) => { + listener.on("button", async (interaction) => { // Vérifier l'identifiant du bouton - if(interaction.customId != 'pfc-pierre' && interaction.customId != 'pfc-feuille' && interaction.customId != 'pfc-ciseau') return + if(interaction.customId != "pfc-pierre" && interaction.customId != "pfc-feuille" && interaction.customId != "pfc-ciseau") return // Vérifier que l'auteur de l'identifiant soit le bon - if(interaction?.message?.interaction?.user?.id != interaction?.user?.id) return interaction.reply({ content: "Il semblerait que tu ne sois pas la personne que j'attendais...", ephemeral: true }) + if((interaction?.message?.interaction?.user?.id && interaction.user.id != interaction?.message?.interaction?.user?.id) || (interaction?.message?.mentions?.repliedUser?.id && interaction.user.id != interaction?.message?.mentions?.repliedUser?.id)) return interaction.reply({ content: "Il semblerait que tu ne sois pas la personne que j'attendais...", ephemeral: true }) // Vérifier si l'utilisateur est limité, et si c'est pas le cas, le limiter if(disableCooldown != true){ - var checkAndReply = await bacheroFunctions.cooldown.checkAndReply(interaction, 'pfcPlay') - if(checkAndReply) return; else await bacheroFunctions.cooldown.set('pfcPlay', interaction.user.id, 1000) + var checkAndReply = await bacheroFunctions.cooldown.checkAndReply(interaction, "pfcPlay") + if(checkAndReply) return; else await bacheroFunctions.cooldown.set("pfcPlay", interaction.user.id, 1000) } // Obtenir le nombre de victoire/défaite @@ -103,11 +104,11 @@ module.exports = { var { winner, botAnswer } = determineWinner(interaction.customId, (winCount / (winCount + loseCount)) * 100) // Le redéfinir - if(winner == 'player'){ + if(winner == "player"){ winCount++ await bacheroFunctions.database.set(database, `winCount-${interaction?.user?.id}`, winCount) } - if(winner == 'bot'){ + if(winner == "bot"){ loseCount++ await bacheroFunctions.database.set(database, `loseCount-${interaction?.user?.id}`, loseCount) } @@ -117,19 +118,20 @@ module.exports = { // Créé un embed à partir de celui du message var embed = new EmbedBuilder(interaction?.message?.embeds[0]?.data) - embed.setDescription(`Tu as choisi **${interaction.customId.replace('pfc-','')}** et j'ai choisi **${botAnswer}**.\n\n${winner == 'draw' ? 'C\'est un match nul !' : winner == 'player' ? 'Bravo, tu as gagné !' : 'Dommage, tu as perdu !'}`) - embed.setFooter({ text: `${winCount} victoire${winCount.length > 1 ? 's' : ''} | ${loseCount} défaite${loseCount.length > 1 ? 's' : ''}${!Math.round(winPercent) ? '' : ` | ${Math.round(winPercent)}% des parties remportées`}` }) + embed.setDescription(`Tu as choisi **${interaction.customId.replace("pfc-", "")}** et j'ai choisi **${botAnswer}**.\n\n${winner == "draw" ? "C'est un match nul !" : winner == "player" ? "Bravo, tu as gagné !" : "Dommage, tu as perdu !"}`) + embed.setFooter({ text: `${winCount} victoire${winCount.length > 1 ? "s" : ""} | ${loseCount} défaite${loseCount.length > 1 ? "s" : ""}${!Math.round(winPercent) ? "" : ` | ${Math.round(winPercent)}% des parties remportées`}` }) + embed.setColor(bacheroFunctions.config.getValue("bachero", winner == "player" ? "successEmbedColor" : winner == "bot" ? "secondEmbedColor" : "embedColor")) interaction.update({ embeds: [embed] }).catch(err => {}) }) }, - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Si on veut obtenir le classement - if(interaction.options.getBoolean('showleaderboard')){ + if(interaction.options.getBoolean("showleaderboard")){ // Vérifier si l'utilisateur est limité, et si c'est pas le cas, le limiter - var checkAndReply = await bacheroFunctions.cooldown.checkAndReply(interaction, 'pfcLeaderboardShow') - if(checkAndReply) return; else await bacheroFunctions.cooldown.set('pfcLeaderboardShow', interaction.user.id, 10000) + var checkAndReply = await bacheroFunctions.cooldown.checkAndReply(interaction, "pfcLeaderboardShow") + if(checkAndReply) return; else await bacheroFunctions.cooldown.set("pfcLeaderboardShow", interaction.user.id, 10000) // Obtenir la base de données entière en JSON const databaseJSON = await bacheroFunctions.database.getAll(database) @@ -140,9 +142,9 @@ module.exports = { // Pour chaque utilisateur de la BDD, ajouter le nom de l'utilisateur à la variable users for(var key of Object.keys(databaseJSON)){ // Si ça commence par "winCount-" - if(key.startsWith('winCount-')){ + if(key.startsWith("winCount-")){ // Obtenir l'identifiant - var id = key.split('-')[1] + var id = key.split("-")[1] // Obtenir le loseCount var loseCount = databaseJSON[`loseCount-${id}`] @@ -163,9 +165,9 @@ module.exports = { // Si on a rien trouvé, on envoie un message d'erreur if(!users.length){ var embed = new EmbedBuilder() - .setTitle('Classement') - .setDescription(`Impossible d'obtenir le classement puisque personne n'y a encore participé. ${databaseJSON.lastReset ? `Le classement a été réinitialisé pour la dernière fois le ` : ''}`) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) + .setTitle("Classement") + .setDescription(`Impossible d'obtenir le classement puisque personne n'y a encore participé. ${databaseJSON.lastReset ? `Le classement a été réinitialisé pour la dernière fois le ` : ""}`) + .setColor(bacheroFunctions.colors.secondary) return interaction.reply({ embeds: [embed] }).catch(err => {}) } @@ -173,11 +175,11 @@ module.exports = { users.sort((a, b) => b.winPercent - a.winPercent) // Créé le contenu du classement - var leaderboardText = '' + var leaderboardText = "" for(var i = 0; i < users.length; i++){ if(i >= 10) break var user = users[i] - leaderboardText += `\n**${i + 1}.** ${await bacheroFunctions.parseUserFromString(user.id, 'mention')} : ${user.winPercent ? `${user.winPercent}%` : '0%'} - ${user.winCount} victoire${user.winCount.length > 1 ? 's' : ''} | ${user.loseCount} défaite${user.loseCount.length > 1 ? 's' : ''}` + leaderboardText += `\n**${i + 1}.** ${await bacheroFunctions.parseUserFromString(user.id, "mention")} : ${user.winPercent ? `${user.winPercent}%` : "0%"} - ${user.winCount} victoire${user.winCount.length > 1 ? "s" : ""} | ${user.loseCount} défaite${user.loseCount.length > 1 ? "s" : ""}` } // Obtenir la position dans le classement @@ -185,13 +187,13 @@ module.exports = { // Créer un embed var embed = new EmbedBuilder() - .setTitle('Classement') - .setDescription(`Voici le classement des joueurs (interserveurs) :\n${leaderboardText}`) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - .setFooter({ text: `Parmis ${users.length} joueurs, ${position == 0 ? "vous n'êtes pas dans le classement" : `vous êtes le ${position}${position == 1 ? "er" : "ème"}`}` }) + .setTitle("Classement - interserveur") + .setDescription(`Voici le classement des joueurs :\n${leaderboardText}`) + .setColor(bacheroFunctions.colors.primary) + .setFooter({ text: `Parmis ${users.length} joueurs, ${position == 0 ? "vous n'êtes pas dans le classement" : `vous êtes le ${position}${position == 1 ? "er" : "ème"}`}` }) // Envoyer l'embed - if(await interaction.reply({ embeds: [embed] }).catch(err => { return 'stop' }) == 'stop') return + await interaction.reply({ embeds: [embed] }).catch(err => {}) } // Sinon, afficher les boutons dans un embed else { @@ -204,27 +206,27 @@ module.exports = { // Créer un embed var embed = new EmbedBuilder() - .setTitle('Pierre feuille ciseau') - .setDescription(`Appuie sur un des boutons en dessous de ce message pour jouer au pierre feuille ciseau`) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - .setFooter({ text: `${winCount} victoire${winCount.length > 1 ? 's' : ''} | ${loseCount} défaite${loseCount.length > 1 ? 's' : ''}${!Math.round(winPercent) ? '' : ` | ${Math.round(winPercent)}% des parties remportées`}` }) + .setTitle("Pierre feuille ciseau") + .setDescription("Appuie sur un des boutons en dessous de ce message pour jouer au pierre feuille ciseau") + .setColor(bacheroFunctions.colors.primary) + .setFooter({ text: `${winCount} victoire${winCount.length > 1 ? "s" : ""} | ${loseCount} défaite${loseCount.length > 1 ? "s" : ""}${!Math.round(winPercent) ? "" : ` | ${Math.round(winPercent)}% des parties remportées`}` }) // Créé des boutons const row = new ActionRowBuilder().addComponents( new ButtonBuilder() - .setCustomId(`pfc-pierre`) - .setStyle(ButtonStyle.Primary) - .setEmoji('🪨'), + .setCustomId("pfc-pierre") + .setStyle(ButtonStyle.Primary) + .setEmoji("🪨"), new ButtonBuilder() - .setCustomId(`pfc-feuille`) - .setStyle(ButtonStyle.Primary) - .setEmoji('🍃'), + .setCustomId("pfc-feuille") + .setStyle(ButtonStyle.Primary) + .setEmoji("🍃"), new ButtonBuilder() - .setCustomId(`pfc-ciseau`) - .setStyle(ButtonStyle.Primary) - .setEmoji('✂️'), + .setCustomId("pfc-ciseau") + .setStyle(ButtonStyle.Primary) + .setEmoji("✂️"), ) // Répondre à l'interaction diff --git a/modules/bachero.module.ping/manifest.jsonc b/modules/bachero.module.ping/manifest.jsonc index aa852cd..9af89f7 100644 --- a/modules/bachero.module.ping/manifest.jsonc +++ b/modules/bachero.module.ping/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Ce module rajoute une commande ping, pour obtenir le temps de latence du bot", - "longDescription": "Ce module rajoute une commande affichant le temps de latence entre Bachero et Discord une fois exécuté", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", @@ -40,7 +36,7 @@ "name": "monitoredByElwatch", "type": "boolean", "default": false, - "description": "Es-ce que Bachero est sous la surveillance d'ElWatch (https://elwatch.johanstick.me) ?" + "description": "Es-ce que Bachero est sous la surveillance d'ElWatch (https://elwatch.johanstick.fr) ?" } ] } \ No newline at end of file diff --git a/modules/bachero.module.ping/ping.js b/modules/bachero.module.ping/ping.js index cf91211..b146752 100644 --- a/modules/bachero.module.ping/ping.js +++ b/modules/bachero.module.ping/ping.js @@ -1,18 +1,18 @@ -const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, ComponentType } = require('discord.js') -const fetch = require('node-fetch') -const { database, config, cooldown, botClient } = require('../../functions') -const db = database.getDatabase('bachero.module.ping') -const showPingFromDatabase = config.getValue('bachero.module.ping', 'showPingFromDatabase') -var botName = config.getValue('bachero', 'botName') +const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, ComponentType } = require("discord.js") +const fetch = require("node-fetch") +const { database, config, cooldown, botClient, colors } = require("../../functions") +const db = database.getDatabase("bachero.module.ping") +const showPingFromDatabase = config.getValue("bachero.module.ping", "showPingFromDatabase") +var botName = config.getValue("bachero", "botName") // Fonction pour obtenir l'historique de latence var latencyHistory = {} async function getLatencyHistory(clientId){ // Si on a déjà enregistrer dans le cache y'a moins de 5 heures, on retourne - if(latencyHistory.content && latencyHistory.lastFetched && latencyHistory.lastFetched > Date.now() - 1000 * 60 * 60 * 5) return latencyHistory.content + if(latencyHistory.content && latencyHistory.lastFetched && latencyHistory.lastFetched > Date.now() - (1000 * 60 * 60 * 5)) return latencyHistory.content // Sinon on fetch, enregistre dans le cache, et retourne - latencyHistory.content = await fetch(`https://api.elwatch.johanstick.me/api/status/${clientId}`).then(res => res.json()).catch(err => { return {} }) + latencyHistory.content = await fetch(`https://api.elwatch.johanstick.fr/api/status/${clientId}`).then(res => res.json()).catch(err => { return {} }) latencyHistory.lastFetched = new Date() latencyHistory.content = latencyHistory?.content?.info?.pingHistory || latencyHistory?.content return latencyHistory.content @@ -21,27 +21,27 @@ async function getLatencyHistory(clientId){ module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('ping') + .setName("ping") .setDescription(`Affiche le temps de latence de ${botName}`), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Vérifier si l'utilisateur est limité, et si c'est pas le cas, le limiter - var checkAndReply = await cooldown.checkAndReply(interaction, 'pingCommandUsage') - if(checkAndReply) return; else await cooldown.set('pingCommandUsage', interaction.user.id, 1000) + var checkAndReply = await cooldown.checkAndReply(interaction, "pingCommandUsage") + if(checkAndReply) return; else await cooldown.set("pingCommandUsage", interaction.user.id, 1000) // Obtenir la date actuelle var date = Date.now() // Mettre la réponse en defer - if(await interaction.deferReply().catch(err => { return 'stop' }) == 'stop') return + if(await interaction.deferReply().catch(err => { return "stop" }) == "stop") return // Récupérer le temps pris var discordLatency = new Date().getTime() - date // Dans la base de données, obtenir l'historique de ping (qui permettra donc d'obtenir le ping de la BDD en lecture) date = new Date().getTime() - var latencyHistory = await database.get(db, 'pingHistory') || {} + var latencyHistory = await database.get(db, "pingHistory") || {} var databaseLatency_read = new Date().getTime() - date // Obtenir la valeur + clé la plus récente par rapport à la date @@ -53,43 +53,41 @@ module.exports = { date = new Date().getTime() latencyHistory[Date.now()] = discordLatency if(latencyHistory_keys.length > 5) latencyHistory = Object.fromEntries(latencyHistory_keys.slice(latencyHistory_keys.length - 5).map(key => [key, latencyHistory[key]])) - await database.set(db, 'pingHistory', latencyHistory) + await database.set(db, "pingHistory", latencyHistory) var databaseLatency_write = new Date().getTime() - date // Créer un embed var embed = new EmbedBuilder() - .setTitle('Pong 🏓') - .setDescription(`Discord : \`${discordLatency}\` ms ${latencyHistory_value ? `(\`${latencyHistory_value}\` ms )` : ''}${showPingFromDatabase == true ? `\nBase de données :\nㅤ • Lecture : \`${databaseLatency_read}\` ms\nㅤ • Ecriture : \`${databaseLatency_write}\` ms` : ''}`) - .setColor(config.getValue('bachero', 'embedColor')) + .setTitle("Pong 🏓") + .setDescription(`Discord : \`${discordLatency}\` ms ${latencyHistory_value ? `(\`${latencyHistory_value}\` ms )` : ""}${showPingFromDatabase == true ? `\nBase de données :\nㅤ • Lecture : \`${databaseLatency_read}\` ms\nㅤ • Ecriture : \`${databaseLatency_write}\` ms` : ""}`) + .setColor(colors.primary) // Créé un bouton - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder() + const row = new ActionRowBuilder().addComponents(new ButtonBuilder() .setCustomId(`pingInfo-${date}`) - .setLabel('En savoir plus') - .setStyle(ButtonStyle.Primary), - ) + .setLabel("En savoir plus") + .setStyle(ButtonStyle.Primary),) // Quand quelqu'un clique sur le bouton const filter = i => i.customId == `pingInfo-${date}` const collector = interaction.channel.createMessageComponentCollector({ componentType: ComponentType.Button, filter, time: 999999 }) - collector.on('collect', async i => { + collector.on("collect", async i => { // Arrêter le collecteur collector.stop() // Obtenir des infos via l'API d'ElWatch var pingHistory = [] - if(config.getValue('bachero.module.ping', 'monitoredByElwatch') == true){ + if(config.getValue("bachero.module.ping", "monitoredByElwatch") == true){ var elwatchStatus = await getLatencyHistory(interaction.client.user.id || botClient.get().user.id) - if(elwatchStatus['6']) pingHistory.push(`6h : \`${elwatchStatus['6']}\` ms`) - if(elwatchStatus['12']) pingHistory.push(`12h : \`${elwatchStatus['12']}\` ms`) - if(elwatchStatus['18']) pingHistory.push(`18h : \`${elwatchStatus['18']}\` ms`) - if(elwatchStatus['23']) pingHistory.push(`23h : \`${elwatchStatus['23']}\` ms`) - embed.data.description += `\nHistorique Discord sur plusieurs heures :\n${pingHistory.map(a => `ㅤ • ${a}`).join('\n')}` + if(elwatchStatus["6"]) pingHistory.push(`6h : \`${elwatchStatus["6"]}\` ms`) + if(elwatchStatus["12"]) pingHistory.push(`12h : \`${elwatchStatus["12"]}\` ms`) + if(elwatchStatus["18"]) pingHistory.push(`18h : \`${elwatchStatus["18"]}\` ms`) + if(elwatchStatus["23"]) pingHistory.push(`23h : \`${elwatchStatus["23"]}\` ms`) + embed.data.description += `\nHistorique Discord sur plusieurs heures :\n${pingHistory.map(a => `ㅤ • ${a}`).join("\n")}` } // Mettre à jour l'embed - embed.setDescription(`${embed.data.description}\n\n> Pour obtenir la latence Discord, ${botName} calcule le temps qu'il prend pour envoyer et recevoir des réponses, ceci inclut le temps que Discord prend à s'exécuter.${config.getValue('bachero.module.ping', 'monitoredByElwatch') ? `\n\n> Également, ce bot est surveillé par ElWatch et supporte la mesure du ping, vous pouvez [cliquer ici](https://elwatch.johanstick.me/status/${interaction.client.user.id || botClient.get().user.id}) pour obtenir la latence obtenue par un tiers.` : ''}`) + embed.setDescription(`${embed.data.description}\n\n> Pour obtenir la latence Discord, ${botName} calcule le temps qu'il prend pour envoyer et recevoir des réponses, ceci inclut le temps que Discord prend à s'exécuter.${config.getValue("bachero.module.ping", "monitoredByElwatch") ? `\n\n> Également, ce bot est surveillé par ElWatch et supporte la mesure du ping, vous pouvez [cliquer ici](https://elwatch.johanstick.fr/status/${interaction.client.user.id || botClient.get().user.id}) pour obtenir la latence obtenue par un tiers.` : ""}`) i.update({ embeds: [embed], components: [] }).catch(err => {}) }) diff --git a/modules/bachero.module.short/manifest.jsonc b/modules/bachero.module.short/manifest.jsonc index 4f7dd60..41acfa3 100644 --- a/modules/bachero.module.short/manifest.jsonc +++ b/modules/bachero.module.short/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Permet de raccourcir n'importe quel lien pour obtenir une URL courte", - "longDescription": "Ajoute une commande permettant de générer une URL plus courte à partir d'un lien.", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.short/short.js b/modules/bachero.module.short/short.js index c73c337..9596246 100644 --- a/modules/bachero.module.short/short.js +++ b/modules/bachero.module.short/short.js @@ -1,42 +1,40 @@ -const { SlashCommandBuilder, EmbedBuilder } = require('discord.js') -const bacheroFunctions = require('../../functions') -const fetch = require('node-fetch') -const escape = require('markdown-escape') -var instance = bacheroFunctions.config.getValue('bachero.module.short', 'defaultInstance') +const { SlashCommandBuilder, EmbedBuilder } = require("discord.js") +const bacheroFunctions = require("../../functions") +const fetch = require("node-fetch") +const escape = require("markdown-escape") +var instance = bacheroFunctions.config.getValue("bachero.module.short", "defaultInstance") module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('short') + .setName("short") .setDescription("Raccourcir une URL") - .addStringOption(option => option.setName('url') + .addStringOption(option => option.setName("url") .setDescription("URL à raccourcir (si non spécifié, le bot va raccourcir le dernier message ou celui en réponse)") - .setRequired(false) - ) - .addStringOption(option => option.setName('password') - .setDescription("Mot de passe pour accéder à l'URL raccourcie") - .setRequired(false) - ), + .setRequired(false)) + .addStringOption(option => option.setName("password") + .setDescription("Mot de passe pour accéder à l'URL raccourcie") + .setRequired(false)), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Mettre la réponse en defer - if(await interaction.deferReply({ ephemeral: interaction.guildId ? true : false }).catch(err => { return 'stop' }) == 'stop') return + if(await interaction.deferReply({ ephemeral: !!interaction.guildId }).catch(err => { return "stop" }) == "stop") return // Si c'est une commande texte, tenter de supprimer le message d'invocation - if(interaction.sourceType == 'textCommand'){ + if(interaction.sourceType == "textCommand"){ try { interaction.delete().catch(err => {}) } catch(err) {} // Le choix de la sécurité } // Obtenir le terme de recherche - let query = interaction.options.getString('url') + let query = interaction.options.getString("url") // Si on a pas de terme de recherche, on va chercher le dernier message ou celui en réponse if(!query){ // Chercher le message auquel on répond if(interaction?.reference?.messageId){ var repliedTo = await interaction.channel.messages.fetch(interaction.reference.messageId).catch(err => {}) - if(repliedTo.content.includes('https://') || repliedTo.content.includes('http://')) query = repliedTo.content + if(repliedTo.content.includes("https://") || repliedTo.content.includes("http://")) query = repliedTo.content } // Sinon, on prend le dernier message @@ -44,16 +42,16 @@ module.exports = { query = await interaction.channel.messages.fetch({ limit: 1, before: interaction.id }).catch(err => {}) query = query.first() query = query.content - if(!query.includes('https://') && !query.includes('http://')) query = undefined + if(!query.includes("https://") && !query.includes("http://")) query = undefined } } // Si on a toujours pas de terme de recherche, on affiche une erreur if(!query) return interaction.editReply("Pour utiliser cette commande, vous devez inclure l'argument `url` dans votre commande, ou répondre à un message contenant un lien (ne fonctionne pas via les commandes slash).").catch(err => {}) - if(!query.includes('https://') && !query.includes('http://')) return interaction.editReply("L'URL obtenu ne semble pas être un lien valide.").catch(err => {}) + if(!query.includes("https://") && !query.includes("http://")) return interaction.editReply("L'URL obtenu ne semble pas être un lien valide.").catch(err => {}) // Raccourcir le lien - let shortened = await fetch(`${instance}api/shorten`, { method: 'POST', body: new URLSearchParams(interaction.options.getString("password") ? { link: query, password: interaction.options.getString("password") } : { link: query }) }).then(res => res.json()).catch(err => { return { fetcherror: err } }) + let shortened = await fetch(`${instance}api/shorten`, { method: "POST", body: new URLSearchParams(interaction.options.getString("password") ? { link: query, password: interaction.options.getString("password") } : { link: query }) }).then(res => res.json()).catch(err => { return { fetcherror: err } }) // Si on a une erreur if(shortened.fetcherror) return await bacheroFunctions.report.createAndReply("requête vers l'API de Quecto", shortened.fetcherror || shortened, {}, interaction) @@ -61,13 +59,13 @@ module.exports = { // Créer et envoyer l'embed var embed = new EmbedBuilder() - .setTitle("Résultat du raccourcissement") - .addFields([ - { name: 'Raccourci', value: escape(shortened?.data?.shorten), inline: true }, - { name: 'Originale', value: escape(shortened?.data?.original || query), inline: true }, - ]) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - .setFooter({ text: `Sous la demande de ${interaction.user.discriminator == '0' ? interaction.user.username : interaction.user.tag}` }) + .setTitle("Résultat du raccourcissement") + .addFields([ + { name: "Raccourci", value: escape(shortened?.data?.shorten), inline: true }, + { name: "Originale", value: escape(shortened?.data?.original || query), inline: true }, + ]) + .setColor(bacheroFunctions.colors.primary) + .setFooter({ text: `Sous la demande de ${interaction.user.discriminator == "0" ? interaction.user.username : interaction.user.tag}` }) interaction.editReply({ embeds: [embed] }).catch(err => {}) } } \ No newline at end of file diff --git a/modules/bachero.module.showReports/manifest.jsonc b/modules/bachero.module.showReports/manifest.jsonc index 77f3bf0..349b42c 100644 --- a/modules/bachero.module.showReports/manifest.jsonc +++ b/modules/bachero.module.showReports/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Permet à l'hébergeur de Bachero d'obtenir des informations sur un rapport d'erreur", - "longDescription": "Ce module permet à la personne hébergeant Bachero d'afficher des rapports d'erreurs via une commande secrète", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.showReports/showInfo.js b/modules/bachero.module.showReports/showInfo.js index 64cd139..d7d0807 100644 --- a/modules/bachero.module.showReports/showInfo.js +++ b/modules/bachero.module.showReports/showInfo.js @@ -1,22 +1,22 @@ -const { codeBlock } = require('discord.js') -const bacheroFunctions = require('../../functions') -if(bacheroFunctions.config.getValue('bachero', 'disableReport') == true) return // si le système de rapports est désactivé, on arrête le chargement du module -const secretPassword = bacheroFunctions.config.getValue('bachero.module.showReports', 'secretPassword') +const { codeBlock } = require("discord.js") +const bacheroFunctions = require("../../functions") +if(bacheroFunctions.config.getValue("bachero", "disableReport") == true) return // si le système de rapports est désactivé, on arrête le chargement du module +const secretPassword = bacheroFunctions.config.getValue("bachero.module.showReports", "secretPassword") module.exports = { async getClient(client){ // Vérifier le mot de passe définit dans le fichier de configuration - if(secretPassword == 'password') bacheroFunctions.showLog('warn', `Le mot de passe entré pour le module "bachero.module.showReports" n'a pas été changé. Pour plus de sécurité, veuillez le changer dans le fichier de configuration associé au module.`, id="showReports-default-password") + if(secretPassword == "password") bacheroFunctions.showLog("warn", "Le mot de passe entré pour le module \"bachero.module.showReports\" n'a pas été changé. Pour plus de sécurité, veuillez le changer dans le fichier de configuration associé au module.", "showReports-default-password") // Quand on reçoit un message - client.on('messageCreate', async (message) => { - if(message.content.startsWith('bachero-send-reports')){ + client.on("messageCreate", async (message) => { + if(message.content.startsWith("bachero-send-reports")){ // Si on est pas en message privé - if(message.channel.type != 1) return message.reply('Vous devez utiliser cette commande en message privé pour plus de sécurité.').catch(err => {}) + if(message.channel.type != 1) return message.reply("Vous devez utiliser cette commande en message privé pour plus de sécurité.").catch(err => {}) // Si il n'y a pas de mot de passe - var password = message.content.split(' ')[1] - if(!password) return message.reply('Vous devez entrer un mot de passe pour utiliser cette commande. Exemple : `bachero-send-reports .`').catch(err => {}) + var password = message.content.split(" ")[1] + if(!password) return message.reply("Vous devez entrer un mot de passe pour utiliser cette commande. Exemple : `bachero-send-reports .`").catch(err => {}) // Si le mot de passe est incorrect if(password != secretPassword) return message.reply("Le mot de passe entré n'est pas celui entré dans le fichier de configuration.").catch(err => {}) @@ -25,20 +25,20 @@ module.exports = { var filter = m => m.author.id == message.author.id var reportId = message.channel.createMessageCollector({ filter, time: 30000 }) var tempAskMessage = await message.reply("Veuillez entrer l'identifiant du rapport que vous souhaitez voir. Vous pouvez également envoyer `cancel` pour annuler la commande, ou patienter 30 secondes.").catch(err => {}) - reportId.on('collect', async m => { + reportId.on("collect", async m => { // Si on annule - if(m.content == 'cancel'){ - reportId.stop('cancel') + if(m.content == "cancel"){ + reportId.stop("cancel") return tempAskMessage.delete().catch(err => {}) } // Sinon, obtenir un rapport avec cet identifiant - reportId.stop('correct') + reportId.stop("correct") var report = await bacheroFunctions.report.get(m.content) // Si le rapport fait moins de 2000 caractères, l'envoyer directement, sinon faire un fichier if(report.length < 2000) message.channel.send(codeBlock(report)).catch(err => {}) - else message.channel.send({ files: [{ attachment: Buffer.from(report), name: 'report.txt' }] }).catch(err => {}) + else message.channel.send({ files: [{ attachment: Buffer.from(report), name: "report.txt" }] }).catch(err => {}) // Supprimer le message temporaire tempAskMessage.delete().catch(err => {}) diff --git a/modules/bachero.module.snipe/manifest.jsonc b/modules/bachero.module.snipe/manifest.jsonc index 73053c0..b0c93fa 100644 --- a/modules/bachero.module.snipe/manifest.jsonc +++ b/modules/bachero.module.snipe/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Enregistre les messages supprimés par les membres de votre serveur, pour les réafficher avec une commande", - "longDescription": "Ce module sert à enregistrer dans une base de données non-persistante tous les messages supprimés par les membres de vos serveurs, les modérateurs auront ensuite la possibilité de les réafficher en utilisant une commande", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.snipe/snipe-config.js b/modules/bachero.module.snipe/snipe-config.js index 8fe6ddb..e2599a3 100644 --- a/modules/bachero.module.snipe/snipe-config.js +++ b/modules/bachero.module.snipe/snipe-config.js @@ -1,70 +1,70 @@ -const { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js') -const bacheroFunctions = require('../../functions') -const database = bacheroFunctions.database.getDatabase('bachero.module.snipe') +const { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js") +const bacheroFunctions = require("../../functions") +const database = bacheroFunctions.database.getDatabase("bachero.module.snipe") // Exporter certaines fonctions module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('snipe-config') - .setDescription(`Configure si les messages supprimés devraient être enregistrés pour ce serveur`) + .setName("snipe-config") + .setDescription("Configure si les messages supprimés devraient être enregistrés pour ce serveur") .setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild) .setDMPermission(false), // Récupérer le listener et savoir lorsque quelqu'un renvoie le bouton async interactionListener(listener){ - listener.on('button', async (interaction) => { + listener.on("button", async (interaction) => { // Si l'identifiant du bouton est "snipeConfig-safety" - if(interaction.customId == 'snipeConfig-safety'){ + if(interaction.customId == "snipeConfig-safety"){ var embed = new EmbedBuilder() - .setTitle("Confidentialité des données avec la fonctionnalité Snipe") - .setDescription(`Nous tenons à la vie privée de nos utilisateurs, nous avons donc mis en place certaines mesures listées ici :\n + .setTitle("Confidentialité des données avec la fonctionnalité Snipe") + .setDescription(`Nous tenons à la vie privée de nos utilisateurs, nous avons donc mis en place certaines mesures listées ici :\n • Les messages supprimés sont enregistrés dans une base de données non persistante : ils sont supprimés à chaque redémarrage de l'infrastructure ou après 24 heures. • Les messages qui ont été envoyés il y a plus de trois jours, ou envoyés par un robot ne sont pas enregistrés. • La fonctionnalité est désactivée par défaut sur tous les serveurs, et doit être activée par un membre ayant la permission de gérer le serveur. • Il est impossible pour un modérateur d'exporter toutes les données enregistrées sur un serveur. • Notre base de données n'inclut que 500 messages par serveur, les anciens messages seront supprimés si le serveur dépasse cette limite. • Seules les informations suivantes sont enregistrées : les identifiants du message, de l'utilisateur et du salon ; le tag de l'auteur ; le contenu du message ; la date de suppression ou de modification ; les attachements.`) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) + .setColor(bacheroFunctions.colors.primary) return interaction.reply({ embeds: [embed], ephemeral: true }).catch(err => {}) } // Vérifier l'identifiant du bouton, puis defer l'interaction - if(interaction.customId != 'snipeConfig-disable' && interaction.customId != 'snipeConfig-enable') return + if(interaction.customId != "snipeConfig-disable" && interaction.customId != "snipeConfig-enable") return if(interaction.user.id != interaction?.message?.interaction?.user?.id && interaction.user.id != interaction?.message?.mentions?.repliedUser?.id) return interaction.reply({ content: "Il semblerait que tu ne sois pas la personne que j'attendais...", ephemeral: true }).catch(err => {}) await interaction.deferReply().catch(err => {}) // Modifier la valeur dans la base de données - if(interaction.customId == 'snipeConfig-disable') await bacheroFunctions.database.delete(database, `enabled-${interaction.guild.id}`) + if(interaction.customId == "snipeConfig-disable") await bacheroFunctions.database.delete(database, `enabled-${interaction.guild.id}`) else await bacheroFunctions.database.set(database, `enabled-${interaction.guild.id}`, true) // Modifier le message d'origine, et supprimer l'interaction await interaction.deleteReply().catch(err => {}) - await interaction.message.edit({ content: `La fonctionnalité Snipe est désormais ${interaction.customId == 'snipeConfig-disable' ? 'désactivée sur ce serveur' : 'activée sur l\'ensemble de ce serveur'}.\nCette modification peut prendre jusqu'à 2 minutes pour s'appliquer.`, embeds: [], components: [] }).catch(err => {}) + await interaction.message.edit({ content: `La fonctionnalité Snipe est désormais ${interaction.customId == "snipeConfig-disable" ? "désactivée sur ce serveur" : "activée sur l'ensemble de ce serveur"}.\nCette modification peut prendre jusqu'à 2 minutes pour s'appliquer.`, embeds: [], components: [] }).catch(err => {}) }) }, - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Vérifier si la fonctionnalité est activée var isEnabled = await bacheroFunctions.database.get(database, `enabled-${interaction.guild.id}`) // Créer un embed var embed = new EmbedBuilder() - .setTitle("Configuration de la fonctionnalité Snipe") - .setDescription(isEnabled ? "La fonctionnalité Snipe est activée sur l'ensemble de ce serveur.\nCelle-ci détecte lorsqu'un utilisateur supprime un message et permet aux modérateurs de l'afficher à nouveau en utilisant la commande `snipe`." : "La fonctionnalité Snipe est désactivée sur ce serveur.\nLorsqu'elle est activée, elle détecte lorsqu'un utilisateur supprime un message sur votre serveur et permet aux modérateurs de l'afficher à nouveau en utilisant la commande `snipe`.") - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) + .setTitle("Configuration de la fonctionnalité Snipe") + .setDescription(isEnabled ? "La fonctionnalité Snipe est activée sur l'ensemble de ce serveur.\nCelle-ci détecte lorsqu'un utilisateur supprime un message et permet aux modérateurs de l'afficher à nouveau en utilisant la commande `snipe`." : "La fonctionnalité Snipe est désactivée sur ce serveur.\nLorsqu'elle est activée, elle détecte lorsqu'un utilisateur supprime un message sur votre serveur et permet aux modérateurs de l'afficher à nouveau en utilisant la commande `snipe`.") + .setColor(bacheroFunctions.colors.primary) // Créé deux boutons const row = new ActionRowBuilder().addComponents( new ButtonBuilder() - .setCustomId(isEnabled ? `snipeConfig-disable` : `snipeConfig-enable`) - .setLabel(isEnabled ? 'Désactiver la fonctionnalité' : 'Activer la fonctionnalité') - .setStyle(ButtonStyle.Primary), + .setCustomId(isEnabled ? "snipeConfig-disable" : "snipeConfig-enable") + .setLabel(isEnabled ? "Désactiver la fonctionnalité" : "Activer la fonctionnalité") + .setStyle(ButtonStyle.Primary), new ButtonBuilder() - .setCustomId(`snipeConfig-safety`) - .setLabel('Comment votre confidentialité reste assurée') - .setStyle(ButtonStyle.Secondary), + .setCustomId("snipeConfig-safety") + .setLabel("Comment votre confidentialité reste assurée") + .setStyle(ButtonStyle.Secondary), ) // Répondre à l'interaction diff --git a/modules/bachero.module.snipe/snipe.js b/modules/bachero.module.snipe/snipe.js index 1ac9239..de76d04 100644 --- a/modules/bachero.module.snipe/snipe.js +++ b/modules/bachero.module.snipe/snipe.js @@ -1,11 +1,11 @@ -const { EmbedBuilder, SlashCommandBuilder, PermissionFlagsBits, ButtonStyle, ButtonBuilder, ActionRowBuilder } = require('discord.js') -const fetch = require('node-fetch') -const escape = require('markdown-escape') -const bacheroFunctions = require('../../functions') -const database = bacheroFunctions.database.getDatabase('bachero.module.snipe') +const { EmbedBuilder, SlashCommandBuilder, PermissionFlagsBits, ButtonStyle, ButtonBuilder, ActionRowBuilder } = require("discord.js") +const fetch = require("node-fetch") +const escape = require("markdown-escape") +const bacheroFunctions = require("../../functions") +const database = bacheroFunctions.database.getDatabase("bachero.module.snipe") const hastebinUrl = process.env.HASTEBIN_URL || "https://hastebin.com" -const hastebinAPI = hastebinUrl + "/documents" -const hastebinTokenRequired = hastebinUrl == 'https://hastebin.com' +const hastebinAPI = `${hastebinUrl}/documents` +const hastebinTokenRequired = hastebinUrl == "https://hastebin.com" // Liste des serveurs où la fonctionnalité est activé (cache), et le client var allGuildStatus = {} @@ -47,18 +47,18 @@ async function addToDb(message, newMessage){ if(!client.snipes) client.snipes = new Map() var snipes = client.snipes.get(message.guildId) || [] if(newMessage) snipes.push({ - type: 'edit', + type: "edit", editTimestamp: Date.now(), channelId: message.channelId, id: message.id, oldContent: message.content, newContent: newMessage.content, - authorId: message.author.id, authorTag: message.author.discriminator == '0' ? escape(message.author.username) : escape(message.author.tag), + authorId: message.author.id, authorTag: message.author.discriminator == "0" ? escape(message.author.username) : escape(message.author.tag), }) else snipes.push({ - type: 'delete', + type: "delete", deletedTimestamp: Date.now(), channelId: message.channelId, id: message.id, content: message.content, attachments: attachments, - authorId: message.author.id, authorTag: message.author.discriminator == '0' ? escape(message.author.username) : escape(message.author.tag), + authorId: message.author.id, authorTag: message.author.discriminator == "0" ? escape(message.author.username) : escape(message.author.tag), }) // Mettre les snipes dans un ordre pour que les plus récents soient en haut @@ -73,26 +73,23 @@ async function addToDb(message, newMessage){ module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('snipe') - .setDescription(`Affiche les dernières modifications et suppressions de messages`) + .setName("snipe") + .setDescription("Affiche les dernières modifications et suppressions de messages") .setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages) .setDMPermission(false) - .addUserOption(option => option.setName('de') + .addUserOption(option => option.setName("de") .setDescription("Filtrer les messages d'un utilisateur") - .setRequired(false) - ) - .addStringOption(option => option.setName('contient') + .setRequired(false)) + .addStringOption(option => option.setName("contient") .setDescription("Filtrer les messages qui contiennent un élément") .setChoices( - { name: 'Lien', value: 'link' }, - { name: 'Attachement', value: 'attachment' } + { name: "Lien", value: "link" }, + { name: "Attachement", value: "attachment" } ) - .setRequired(false) - ) - .addStringOption(option => option.setName('query') + .setRequired(false)) + .addStringOption(option => option.setName("query") .setDescription("Filtrer les messages qui contiennent un certain texte") - .setRequired(false) - ), + .setRequired(false)), // Obtenir le client getClient(_client){ @@ -119,44 +116,44 @@ module.exports = { }, 1000 * 60 * 60 * 24) // Détecter les messages supprimés, ou modifiés - client.on('messageDelete', async message => addToDb(message)) - client.on('messageUpdate', async (oldMessage, newMessage) => addToDb(oldMessage, newMessage)) + client.on("messageDelete", async message => addToDb(message)) + client.on("messageUpdate", async (oldMessage, newMessage) => addToDb(oldMessage, newMessage)) }, - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Mettre la réponse en defer - if(await interaction.deferReply().catch(err => { return 'stop' }) == 'stop') return + if(await interaction.deferReply().catch(err => { return "stop" }) == "stop") return // Obtenir les derniers snipes var snipes = interaction.client?.snipes?.get(interaction.guildId) || [] - if(!snipes?.length) return interaction.editReply({ content: `Aucun message n'a été supprimé ou modifié récemment...` }).catch(err => {}) + if(!snipes?.length) return interaction.editReply({ content: "Aucun message n'a été supprimé ou modifié récemment..." }).catch(err => {}) // Appliquer les filtres - // Obtenir les options - var user = await interaction.options.getUser('de') - var contains = await interaction.options.getString('contient') - var query = await interaction.options.getString('query') - - // Filtrer les snipes - snipes = snipes.filter(snipe => { - // Si on a un utilisateur, on ne garde que les snipes de cet utilisateur - if(user && snipe.authorId != user.id) return false - - // Si on a un type de filtre, on ne garde que les snipes qui correspondent - snipe.globalContent = snipe.content || snipe.oldContent + snipe.newContent || '' - if(contains == 'link' && !snipe.globalContent?.includes('http://') && !snipe.globalContent?.includes('https://')) return false - if(contains == 'attachment' && !snipe.attachments?.length) return false - - // Si on a une requête, on ne garde que les snipes qui correspondent - if(query && !snipe.globalContent?.toLowerCase()?.includes(query.toLowerCase())) return false - - // Sinon, on garde le snipe - return true - }) + // Obtenir les options + var user = await interaction.options.getUser("de") + var contains = await interaction.options.getString("contient") + var query = await interaction.options.getString("query") + + // Filtrer les snipes + snipes = snipes.filter(snipe => { + // Si on a un utilisateur, on ne garde que les snipes de cet utilisateur + if(user && snipe.authorId != user.id) return false + + // Si on a un type de filtre, on ne garde que les snipes qui correspondent + snipe.globalContent = snipe.content || snipe.oldContent + snipe.newContent || "" + if(contains == "link" && !snipe.globalContent?.includes("http://") && !snipe.globalContent?.includes("https://")) return false + if(contains == "attachment" && !snipe.attachments?.length) return false + + // Si on a une requête, on ne garde que les snipes qui correspondent + if(query && !snipe.globalContent?.toLowerCase()?.includes(query.toLowerCase())) return false + + // Sinon, on garde le snipe + return true + }) // Si on a aucun snipe, on annule - if(!snipes?.length) return interaction.editReply({ content: `Aucun snipe ne correspond à ces critères de recherche...` }).catch(err => {}) + if(!snipes?.length) return interaction.editReply({ content: "Aucun snipe ne correspond à ces critères de recherche..." }).catch(err => {}) // Déterminer si certains snipes sont trop longs var isSomeSnipeTooLong = false @@ -164,39 +161,37 @@ module.exports = { // Lister les champs (fields) de l'embed var fields = snipes.slice(0, 13).map(snipe => { // Obtenir le contenu - var content = snipe.type == 'delete' ? snipe.content : `**Avant :** ${snipe.oldContent}\n**Après :** ${snipe.newContent}` + var content = snipe.type == "delete" ? snipe.content : `**Avant :** ${snipe.oldContent}\n**Après :** ${snipe.newContent}` // Obtenir les attachements - var attachments = snipe?.attachments?.map(attachment => { return `[${attachment.filename}](${attachment.url})` })?.join('\n') || '' + var attachments = snipe?.attachments?.map(attachment => { return `[${attachment.filename}](${attachment.url})` })?.join("\n") || "" // Si le contenu ainsi que les attachements sont trop longs, on n'affiche que ce qu'on peut if(`${attachments}\n${content}`.trim().length > 1024){ isSomeSnipeTooLong = true - content = `${attachments}\n${content}`.trim().match(/.{1,1021}/g)[0] + '...' + content = `${`${attachments}\n${content}`.trim().match(/.{1,1021}/g)[0]}...` } else content = `${attachments}\n${content}`.trim() // Retourner le champ return { - name: `${snipe.authorTag} *(ID: ${snipe.authorId})* — ${snipe.type == 'delete' ? 'suppression' : 'modification'} — `, + name: `${snipe.authorTag} *(ID: ${snipe.authorId})* — ${snipe.type == "delete" ? "suppression" : "modification"} — `, value: content, } }) // Créer un embed var embed = new EmbedBuilder() - .setTitle("Fonctionnalité Snipe") - .addFields(fields) - .setDescription(`Affichage ${snipes.length == 1 ? 'de la dernière modification ou suppression de message' : `des **${snipes.slice(0, 13).length}** dernières modifications et suppressions de messages`}.${isSomeSnipeTooLong ? "\n⚠️ Certains snipes sont trop longs pour être affichés ici : ils ont été tronqués..." : ''}`) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) + .setTitle("Fonctionnalité Snipe") + .addFields(fields) + .setDescription(`Affichage ${snipes.length == 1 ? "de la dernière modification ou suppression de message" : `des **${snipes.slice(0, 13).length}** dernières modifications et suppressions de messages`}.${isSomeSnipeTooLong ? "\n⚠️ Certains snipes sont trop longs pour être affichés ici : ils ont été tronqués..." : ""}`) + .setColor(bacheroFunctions.colors.primary) // Ajouter un bouton pour accéder au haste - if(isSomeSnipeTooLong && ((hastebinTokenRequired && process.env.HASTEBIN_TOKEN) || !hastebinTokenRequired)) var row = new ActionRowBuilder().addComponents( - new ButtonBuilder() + if(isSomeSnipeTooLong && ((hastebinTokenRequired && process.env.HASTEBIN_TOKEN) || !hastebinTokenRequired)) var row = new ActionRowBuilder().addComponents(new ButtonBuilder() .setURL(hastebinAPI) - .setLabel('Afficher intégralement') + .setLabel("Afficher intégralement") .setStyle(ButtonStyle.Link) - .setDisabled(true) - ) + .setDisabled(true)) // Répondre à l'interaction if(row) await interaction.editReply({ embeds: [embed], components: [row] }).catch(err => {}) @@ -206,21 +201,21 @@ module.exports = { if(isSomeSnipeTooLong && ((hastebinTokenRequired && process.env.HASTEBIN_TOKEN) || !hastebinTokenRequired)){ // Générer le contenu du haste var content = snipes.slice(0, 13).map(snipe => { - var content = snipe.type == 'delete' ? snipe.content : `* Avant : ${snipe.oldContent}\n* Après : ${snipe.newContent}` - var attachments = snipe?.attachments?.map(attachment => { return `- ${attachment.filename} : ${attachment.url}` })?.join('\n') || '' + var content = snipe.type == "delete" ? snipe.content : `* Avant : ${snipe.oldContent}\n* Après : ${snipe.newContent}` + var attachments = snipe?.attachments?.map(attachment => { return `- ${attachment.filename} : ${attachment.url}` })?.join("\n") || "" content = `${attachments}\n${content}`.trim() - return `${snipe.authorTag} (ID: ${snipe.authorId}) — ${snipe.type == 'delete' ? 'suppression' : 'modification'} — ${new Date(snipe.deletedTimestamp || snipe.editTimestamp).toLocaleString()}\n\n${content}` + return `${snipe.authorTag} (ID: ${snipe.authorId}) — ${snipe.type == "delete" ? "suppression" : "modification"} — ${new Date(snipe.deletedTimestamp || snipe.editTimestamp).toLocaleString()}\n\n${content}` }) - .join('\n\n\n\n\n') + .join("\n\n\n\n\n") // Obtenir les informations de l'utilisateur var haste = await fetch(hastebinAPI, { - method: 'POST', + method: "POST", body: content, headers: { - 'Authorization': `Bearer ${process.env.HASTEBIN_TOKEN}`, - 'Content-Type': 'text/plain', - 'User-Agent': 'BacheroBot (+https://github.com/bacherobot/bot)' + "Authorization": `Bearer ${process.env.HASTEBIN_TOKEN}`, + "Content-Type": "text/plain", + "User-Agent": "BacheroBot (+https://github.com/bacherobot/bot)" } }).then(res => res.json()).catch(err => { return { error: true, message: err } }) @@ -228,7 +223,7 @@ module.exports = { if(haste?.message || !haste?.key) return await bacheroFunctions.report.createAndReply("création d'un haste", haste?.message || haste, { url: hastebinAPI }, interaction) // Modifier le bouton dans l'interaction - row.components[0].setURL(`${hastebinUrl == 'https://hastebin.com' ? `https://hastebin.com/share/${haste?.key}` : `${hastebinUrl}/${haste?.key}`}`).setDisabled(false) + row.components[0].setURL(`${hastebinUrl == "https://hastebin.com" ? `https://hastebin.com/share/${haste?.key}` : `${hastebinUrl}/${haste?.key}`}`).setDisabled(false) await interaction.editReply({ components: [row] }).catch(err => {}) } } diff --git a/modules/bachero.module.textCommand/manifest.jsonc b/modules/bachero.module.textCommand/manifest.jsonc index 8700bab..df39875 100644 --- a/modules/bachero.module.textCommand/manifest.jsonc +++ b/modules/bachero.module.textCommand/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Permet d'activer ou désactiver l'utilisation des commandes textes sur votre serveur", - "longDescription": "Ce module permet de configurer si l'utilisation de commande texte est activée ou non sur un serveur, en modifiant le contenu d'une base de donnée interne", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.textCommand/slashtotext.js b/modules/bachero.module.textCommand/slashtotext.js index 7796b50..d3ec3e3 100644 --- a/modules/bachero.module.textCommand/slashtotext.js +++ b/modules/bachero.module.textCommand/slashtotext.js @@ -1,52 +1,50 @@ -const { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js') -const bacheroFunctions = require('../../functions') -const database = bacheroFunctions.database.getDatabase('textCommandDisabledGuilds') +const { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js") +const bacheroFunctions = require("../../functions") +const database = bacheroFunctions.database.getDatabase("textCommandDisabledGuilds") // Exporter certaines fonctions module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('slash-to-text') - .setDescription(`Configure l'utilisation de commande textes par messages, sans utiliser le préfixe slash (/).`) + .setName("slash-to-text") + .setDescription("Configure l'utilisation de commande textes par messages, sans utiliser le préfixe slash (/).") .setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild) .setDMPermission(false), // Récupérer le listener et savoir lorsque quelqu'un renvoie le bouton async interactionListener(listener){ - listener.on('button', async (interaction) => { + listener.on("button", async (interaction) => { // Vérifier l'identifiant du bouton, puis defer l'interaction - if(interaction.customId != 'textCommand-disable' && interaction.customId != 'textCommand-enable') return + if(interaction.customId != "textCommand-disable" && interaction.customId != "textCommand-enable") return if(interaction.user.id != interaction?.message?.interaction?.user?.id && interaction.user.id != interaction?.message?.mentions?.repliedUser?.id) return interaction.reply({ content: "Il semblerait que tu ne sois pas la personne que j'attendais...", ephemeral: true }).catch(err => {}) await interaction.deferReply().catch(err => {}) // Modifier la valeur dans la base de données - if(interaction.customId == 'textCommand-enable') await bacheroFunctions.database.delete(database, interaction.guild.id) + if(interaction.customId == "textCommand-enable") await bacheroFunctions.database.delete(database, interaction.guild.id) else await bacheroFunctions.database.set(database, interaction.guild.id, true) // Modifier le message d'origine, et supprimer l'interaction await interaction.deleteReply().catch(err => {}) - await interaction.message.edit({ content: `La fonctionnalité d'utilisation des commande slash en message est désormais ${interaction.customId == 'textCommand-disable' ? 'désactivée sur ce serveur' : 'activée sur l\'ensemble de ce serveur'}.`, embeds: [], components: [] }).catch(err => {}) + await interaction.message.edit({ content: `La fonctionnalité d'utilisation des commande slash en message est désormais ${interaction.customId == "textCommand-disable" ? "désactivée sur ce serveur" : "activée sur l'ensemble de ce serveur"}.`, embeds: [], components: [] }).catch(err => {}) }) }, - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Vérifier si la fonctionnalité est désactivée var isDisabled = await bacheroFunctions.database.get(database, interaction.guild.id) // Créer un embed var embed = new EmbedBuilder() - .setTitle("Configuration des commandes textes") - .setDescription(`${isDisabled ? "La fonctionnalité d'utilisation des commandes slash en message est désactivée sur ce serveur." : "La fonctionnalité d'utilisation des commandes slash en message est activée sur l'ensemble de ce serveur."}\nAvec cette fonctionnalité, les commandes slash peuvent être utilisées via un message classique en utilisant le préfixe \`${bacheroFunctions.config.getValue('bachero', 'prefix')}\` au début de votre message.\n\n> Cette fonctionnalité passe outre les permissions et dérogations définies depuis les paramètres de votre serveur Discord.`) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) + .setTitle("Configuration des commandes textes") + .setDescription(`${isDisabled ? "La fonctionnalité d'utilisation des commandes slash en message est désactivée sur ce serveur." : "La fonctionnalité d'utilisation des commandes slash en message est activée sur l'ensemble de ce serveur."}\nAvec cette fonctionnalité, les commandes slash peuvent être utilisées via un message classique en utilisant le préfixe \`${bacheroFunctions.config.getValue("bachero", "prefix")}\` au début de votre message.\n\n> Cette fonctionnalité passe outre les permissions et dérogations définies depuis les paramètres de votre serveur Discord.`) + .setColor(bacheroFunctions.colors.primary) // Créé un bouton - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder() - .setCustomId(isDisabled ? `textCommand-enable` : `textCommand-disable`) - .setLabel(isDisabled ? 'Activer la fonctionnalité' : 'Désactiver la fonctionnalité') - .setStyle(ButtonStyle.Primary) - ) + const row = new ActionRowBuilder().addComponents(new ButtonBuilder() + .setCustomId(isDisabled ? "textCommand-enable" : "textCommand-disable") + .setLabel(isDisabled ? "Activer la fonctionnalité" : "Désactiver la fonctionnalité") + .setStyle(ButtonStyle.Primary)) // Répondre à l'interaction interaction.reply({ embeds: [embed], components: [row] }).catch(err => {}) diff --git a/modules/bachero.module.timer/manifest.jsonc b/modules/bachero.module.timer/manifest.jsonc index a113495..2b5799b 100644 --- a/modules/bachero.module.timer/manifest.jsonc +++ b/modules/bachero.module.timer/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Ce module rajoute la commande /timer", - "longDescription": "Ce module rajoute la possibilité de créer des minuteurs pour être rappeler de certains évènements", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.timer/timer.js b/modules/bachero.module.timer/timer.js index 5d358cf..6393156 100644 --- a/modules/bachero.module.timer/timer.js +++ b/modules/bachero.module.timer/timer.js @@ -1,12 +1,12 @@ -const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js') -const bacheroFunctions = require('../../functions') -const database = bacheroFunctions.database.getDatabase('bachero.module.timer') -const { customAlphabet } = require('nanoid'), nanoid = customAlphabet('abcdefghiklnoqrstuvyz123456789', 14) -var botName = bacheroFunctions.config.getValue('bachero', 'botName') +const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js") +const bacheroFunctions = require("../../functions") +const database = bacheroFunctions.database.getDatabase("bachero.module.timer") +const { customAlphabet } = require("nanoid"), nanoid = customAlphabet("abcdefghiklnoqrstuvyz123456789", 14) +var botName = bacheroFunctions.config.getValue("bachero", "botName") // Préparer des variables qui seront utilisées plus tard -var buttonsIds = []; -var forcedDeletedTimers = []; +var buttonsIds = [] +var forcedDeletedTimers = [] // Fonction pour obtenir les timers en cours async function runningTimers(){ @@ -20,54 +20,45 @@ async function runningTimers(){ module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('timer') - .setDescription('Gérer un minuteur') + .setName("timer") + .setDescription("Gérer un minuteur") .addSubcommand((subcommand) => subcommand - .setName('create') - .setDescription('Permet de créer un minuteur') - .addNumberOption(option => option.setName('duration') + .setName("create") + .setDescription("Permet de créer un minuteur") + .addNumberOption(option => option.setName("duration") .setDescription("Durée avant que le minuteur n'expire") - .setRequired(true) - ) - .addStringOption(option => option.setName('type') + .setRequired(true)) + .addStringOption(option => option.setName("type") .setDescription("Type de minuteur") .setChoices( - { name: 'Milliseconde', value: 'ms' }, - { name: 'Seconde', value: 'sec' }, - { name: 'Minute', value: 'min' }, - { name: 'Heure', value: 'hour' }, - { name: 'Jour', value: 'day' } + { name: "Milliseconde", value: "ms" }, + { name: "Seconde", value: "sec" }, + { name: "Minute", value: "min" }, + { name: "Heure", value: "hour" }, + { name: "Jour", value: "day" } ) - .setRequired(false) - ) - .addStringOption(option => option.setName('reason') - .setDescription('Raison du minuteur') + .setRequired(false)) + .addStringOption(option => option.setName("reason") + .setDescription("Raison du minuteur") .setMaxLength(512) - .setRequired(false) - ), - ) + .setRequired(false)),) .addSubcommand((subcommand) => subcommand - .setName('list') - .setDescription('Affiche la liste des minuteurs en cours') - ) + .setName("list") + .setDescription("Affiche la liste des minuteurs en cours")) .addSubcommand((subcommand) => subcommand - .setName('details') - .setDescription('Affiche les détails sur un minuteur') - .addStringOption(option => option.setName('id') - .setDescription('Identifiant du minuteur') + .setName("details") + .setDescription("Affiche les détails sur un minuteur") + .addStringOption(option => option.setName("id") + .setDescription("Identifiant du minuteur") .setMaxLength(320) - .setRequired(true) - ) - ) + .setRequired(true))) .addSubcommand((subcommand) => subcommand - .setName('delete') - .setDescription('Supprime un minuteur en cours') - .addStringOption(option => option.setName('id') - .setDescription('Identifiant du minuteur') + .setName("delete") + .setDescription("Supprime un minuteur en cours") + .addStringOption(option => option.setName("id") + .setDescription("Identifiant du minuteur") .setMaxLength(320) - .setRequired(true) - ) - ), + .setRequired(true))), // Obtenir le client async getClient(client){ @@ -85,26 +76,24 @@ module.exports = { client.users.fetch(timer.authorId).then(async user => { // Créer un embed var listFields = [ - timer.userDuration ? { name: 'Durée', value: timer.userDuration, inline: true } : null, - timer.startDate ? { name: 'Début', value: ``, inline: true } : null, - timer.reason ? { name: 'Raison', value: timer.reason, inline: true } : null, - timer.timerId ? { name: 'Identifiant', value: `\`${timer.timerId}\``, inline: true } : null, + timer.userDuration ? { name: "Durée", value: timer.userDuration, inline: true } : null, + timer.startDate ? { name: "Début", value: ``, inline: true } : null, + timer.reason ? { name: "Raison", value: timer.reason, inline: true } : null, + timer.timerId ? { name: "Identifiant", value: `\`${timer.timerId}\``, inline: true } : null, ] var timerEndMs = new Date(timer.endDate).getTime() const embed = new EmbedBuilder() - .setTitle('Minuteur terminé') - .setDescription(`C'est l'heure ! Votre minuteur est terminé.${timerEndMs + 5000 < Date.now() ? `\n*En raison d'un problème avec l'hébergement de ${botName}, du retard a pu être causé (${Math.round((Date.now() - timerEndMs) / 1000)} secondes)*` : ''}`) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - .addFields(listFields.filter(field => field != null)) + .setTitle("Minuteur terminé") + .setDescription(`C'est l'heure ! Votre minuteur est terminé.${timerEndMs + 5000 < Date.now() ? `\n*En raison d'un problème avec l'hébergement de ${botName}, du retard a pu être causé (${Math.round((Date.now() - timerEndMs) / 1000)} secondes)*` : ""}`) + .setColor(bacheroFunctions.colors.primary) + .addFields(listFields.filter(field => field != null)) // Ajouter un bouton qui permet de recréer le minuteur var date = Date.now() - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder() + const row = new ActionRowBuilder().addComponents(new ButtonBuilder() .setCustomId(`confirm-createTimer-${date}`) - .setLabel('Recréer le même minuteur') - .setStyle(ButtonStyle.Primary) - ) + .setLabel("Recréer le même minuteur") + .setStyle(ButtonStyle.Primary)) // Ajouter le bouton du minuteur dans la liste des boutons existants et envoyer le message buttonsIds.push({ customId: `confirm-createTimer-${date}`, userDuration: timer.userDuration, duration: timer.duration, startDate: Date.now(), reason: timer.reason, authorId: user.id, timerId: nanoid() }) @@ -118,14 +107,14 @@ module.exports = { // Récupérer le listener bouton (quand quelqu'un clique sur un bouton) async interactionListener(listener){ - listener.on('button', async (interaction) => { + listener.on("button", async (interaction) => { // Si le bouton SEMBLE valide, mais ne l'est pas - if((interaction.customId.startsWith('confirm-createTimer-') || interaction.customId.startsWith('cancel-createTimer-') || interaction.customId.startsWith('confirm-deleteTimer-') || interaction.customId.startsWith('cancel-deleteTimer-')) && !buttonsIds.map(a => a.customId).includes(interaction.customId)){ + if((interaction.customId.startsWith("confirm-createTimer-") || interaction.customId.startsWith("cancel-createTimer-") || interaction.customId.startsWith("confirm-deleteTimer-") || interaction.customId.startsWith("cancel-deleteTimer-")) && !buttonsIds.map(a => a.customId).includes(interaction.customId)){ return interaction.reply({ content: "Impossible de récupérer le contenu de ce bouton, tenter de refaire la commande.", ephemeral: true }).catch(err => {}) } // Si le bouton ne semble pas valide, et qu'il ne l'est pas, on arrête - if(!buttonsIds.map(a => a.customId).includes(interaction.customId)) return; + if(!buttonsIds.map(a => a.customId).includes(interaction.customId)) return // Récupérer les infos du bouton var button = buttonsIds.find(a => a.customId == interaction.customId) @@ -137,12 +126,12 @@ module.exports = { buttonsIds.splice(buttonsIds.indexOf(button), 1) // Si l'action du bouton consiste à annuler la création du minuteur - if(interaction.customId.startsWith('cancel-createTimer-') || interaction.customId.startsWith('cancel-deleteTimer-')){ + if(interaction.customId.startsWith("cancel-createTimer-") || interaction.customId.startsWith("cancel-deleteTimer-")){ return button.interaction.deleteReply().catch(err => {}) } // Si on veut créer un minuteur - if(interaction.customId.startsWith('confirm-createTimer-')){ + if(interaction.customId.startsWith("confirm-createTimer-")){ // Et sinon lets go ajouter les infos du minuteur dans une variable var timerInfo = { duration: button?.duration, @@ -161,8 +150,8 @@ module.exports = { } // Si le temps de faire tout ça, le minuteur s'est déjà terminé - if(timerInfo.endDate < Date.now() && button.interaction) return button.interaction.editReply({ content: `On n'a même pas eu le temps de finir la création du minuteur que.. c'est fini !`, embeds: [], components: [] }).catch(err => {}) - else if(timerInfo.endDate < Date.now()) return interaction.reply({ content: `On n'a même pas eu le temps de finir la création du minuteur que.. c'est fini !`, embeds: [], components: [], ephemeral: true }).catch(err => {}) + if(timerInfo.endDate < Date.now() && button.interaction) return button.interaction.editReply({ content: "On n'a même pas eu le temps de finir la création du minuteur que.. c'est fini !", embeds: [], components: [] }).catch(err => {}) + else if(timerInfo.endDate < Date.now()) return interaction.reply({ content: "On n'a même pas eu le temps de finir la création du minuteur que.. c'est fini !", embeds: [], components: [], ephemeral: true }).catch(err => {}) // On ajoute à la liste des minuteurs bacheroFunctions.database.set(database, timerInfo?.timerId, timerInfo) @@ -173,35 +162,35 @@ module.exports = { } // Si on veut supprimer un minuteur - if(interaction.customId.startsWith('confirm-deleteTimer-')){ + if(interaction.customId.startsWith("confirm-deleteTimer-")){ // On supprimer le minuteur await bacheroFunctions.database.delete(database, button?.timer?.timerId) // On finit par modifier l'interaction de base - button.interaction.editReply({ content: `Le minuteur a été supprimé avec succès !`, embeds: [], components: [] }).catch(err => {}) + button.interaction.editReply({ content: "Le minuteur a été supprimé avec succès !", embeds: [], components: [] }).catch(err => {}) } }) }, - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Si on veut créer un minuteur - if(interaction.options.getSubcommand() == 'create'){ + if(interaction.options.getSubcommand() == "create"){ // Obtenir les options - var duration = interaction.options.getNumber('duration') - var type = interaction.options.getString('type') || 'sec' - var reason = interaction.options.getString('reason') + var duration = interaction.options.getNumber("duration") + var type = interaction.options.getString("type") || "sec" + var reason = interaction.options.getString("reason") // Convertir la durée en millisecondes - userDuration = `${duration} ${type.replace('sec', 'secondes').replace('ms', 'millisecondes').replace('min', 'minutes').replace('hour', 'heures').replace('day', 'jours')}` - if(type == 'sec') duration = duration * 1000 - if(type == 'min') duration = duration * 1000 * 60 - if(type == 'hour') duration = duration * 1000 * 60 * 60 - if(type == 'day') duration = duration * 1000 * 60 * 60 * 24 + var userDuration = `${duration} ${type.replace("sec", "secondes").replace("ms", "millisecondes").replace("min", "minutes").replace("hour", "heures").replace("day", "jours")}` + if(type == "sec") duration = duration * 1000 + if(type == "min") duration = duration * 1000 * 60 + if(type == "hour") duration = duration * 1000 * 60 * 60 + if(type == "day") duration = duration * 1000 * 60 * 60 * 24 // Vérifier que la durée soit valide - if(duration < 1) return interaction.reply({ content: 'La durée doit être supérieure à 0', ephemeral: true }).catch(err => {}) - if(duration > 14 * 86400000) return interaction.reply({ content: 'La durée doit être inférieure à 14 jours', ephemeral: true }).catch(err => {}) + if(duration < 1) return interaction.reply({ content: "La durée doit être supérieure à 0", ephemeral: true }).catch(err => {}) + if(duration > 14 * 86400000) return interaction.reply({ content: "La durée doit être inférieure à 14 jours", ephemeral: true }).catch(err => {}) // Déterminer la date de fin du minuteur var endDate = new Date() @@ -209,21 +198,21 @@ module.exports = { // Créer un embed var embed = new EmbedBuilder() - .setTitle("Création d'un minuteur") - .setDescription(`${type == 'ms' ? '⚠️ Les minuteurs sont précis à la seconde, une durée en millisecondes ne sera pas exacte et aura une seconde de retard maximum\n\n' : ''}Vous vous apprêtez à créer un minuteur qui s'arrêtera ${reason?.length ? ` avec la raison "${reason?.replace(/`/g, '')?.replace(/"/g, '')}"` : ''}.`) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) + .setTitle("Création d'un minuteur") + .setDescription(`${type == "ms" ? "⚠️ Les minuteurs sont précis à la seconde, une durée en millisecondes ne sera pas exacte et aura une seconde de retard maximum\n\n" : ""}Vous vous apprêtez à créer un minuteur qui s'arrêtera ${reason?.length ? ` avec la raison "${reason?.replace(/`/g, "")?.replace(/"/g, "")}"` : ""}.`) + .setColor(bacheroFunctions.colors.primary) // Créé deux boutons pour confirmer qu'on sois sur var date = Date.now() const rowConfirm = new ActionRowBuilder().addComponents( new ButtonBuilder() - .setCustomId(`confirm-createTimer-${date}`) - .setLabel('Confirmer') - .setStyle(ButtonStyle.Success), + .setCustomId(`confirm-createTimer-${date}`) + .setLabel("Confirmer") + .setStyle(ButtonStyle.Success), new ButtonBuilder() - .setCustomId(`cancel-createTimer-${date}`) - .setLabel('Finalement non') - .setStyle(ButtonStyle.Danger), + .setCustomId(`cancel-createTimer-${date}`) + .setLabel("Finalement non") + .setStyle(ButtonStyle.Danger), ) buttonsIds.push({ customId: `confirm-createTimer-${date}`, interaction: interaction, userDuration: userDuration, duration: duration, startDate: Date.now(), endDate: endDate, reason: reason, authorId: interaction.user.id, timerId: nanoid() }, { customId: `cancel-createTimer-${date}`, interaction: interaction, userDuration: userDuration, duration: duration, endDate: endDate, reason: reason, authorId: interaction.user.id, timerId: nanoid() }) @@ -232,55 +221,53 @@ module.exports = { } // Si on veut lister les minuteurs - if(interaction.options.getSubcommand() == 'list'){ + if(interaction.options.getSubcommand() == "list"){ // Obtenir la liste des minuteurs var timers = (await runningTimers()).filter(timer => timer?.authorId == interaction.user.id) timers = timers.sort((a, b) => new Date(a?.endDate).getTime() - new Date(b?.endDate).getTime()) // trier pour afficher en premier ceux qui se finissent en premier // Créer un embed var embed = new EmbedBuilder() - .setTitle("Vos minuteurs") - .setDescription(!timers?.length ? "Vous n'avez aucun minuteur en cours.\n*Note : pour une meilleure gestion interne, certains minuteurs durant moins de 2 minutes ne sont affichés dans cette liste*" : `Vous avez actuellement ${timers?.length} minuteur${timers?.length > 1 ? 's' : ''} en cours :\n${timers?.length > 1 ? '\n' : ''}ㅤ • ${timers?.map(tim => ` (ID : \`${tim?.timerId}\`)${tim?.reason?.length ? `\nㅤ ㅤ « ${tim?.reason.replace(/«/g, '"').replace(/»/g, '"').replace(/`/g, '')} »` : ''}`)?.join('\nㅤ • ')}`.substring(0, 4000)) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) + .setTitle("Vos minuteurs") + .setDescription(!timers?.length ? "Vous n'avez aucun minuteur en cours.\n*Note : pour une meilleure gestion interne, certains minuteurs durant moins de 2 minutes ne sont affichés dans cette liste*" : `Vous avez actuellement ${timers?.length} minuteur${timers?.length > 1 ? "s" : ""} en cours :\n${timers?.length > 1 ? "\n" : ""}ㅤ • ${timers?.map(tim => ` (ID : \`${tim?.timerId}\`)${tim?.reason?.length ? `\nㅤ ㅤ « ${tim?.reason.replace(/«/g, "\"").replace(/»/g, "\"").replace(/`/g, "")} »` : ""}`)?.join("\nㅤ • ")}`.substring(0, 4000)) + .setColor(bacheroFunctions.colors.primary) // L'envoyer interaction.reply({ embeds: [embed], ephemeral: true }).catch(err => {}) } // Si on veut afficher les détails d'un minuteur - if(interaction.options.getSubcommand() == 'details'){ + if(interaction.options.getSubcommand() == "details"){ // Obtenir l'identifiant du minuteur - var timerId = interaction.options.getString('id') + var timerId = interaction.options.getString("id") // Obtenir le minuteur associé à cet identifiant var timer = (await runningTimers()).find(timer => timer?.timerId == timerId) - if(!timer) var timer = (await runningTimers()).find(timer => timer?.timerId?.toLowerCase()?.replace(/_/g,'') == timerId?.toLowerCase()?.replace(/_/g,'')) // deuxième tentative qui laisse plus d'éléments + if(!timer) var timer = (await runningTimers()).find(timer => timer?.timerId?.toLowerCase()?.replace(/_/g, "") == timerId?.toLowerCase()?.replace(/_/g, "")) // deuxième tentative qui laisse plus d'éléments // Si on a pas trouvé de minuteur, ou qu'il n'a pas été créé par l'utilisateur, on arrête - if(!timer) return interaction.reply({ content: `Aucun minuteur n'a été trouvé avec cet identifiant. Vérifier qu'il a bien été écrit, et que vous en êtes le créateur.`, ephemeral: true }).catch(err => {}) - if(timer?.authorId != interaction.user.id) return interaction.reply({ content: `Un minuteur a été trouvé avec cet identifiant mais vous n'en êtes pas son créateur, les informations sont donc indisponibles.`, ephemeral: true }).catch(err => {}) + if(!timer) return interaction.reply({ content: "Aucun minuteur n'a été trouvé avec cet identifiant. Vérifier qu'il a bien été écrit, et que vous en êtes le créateur.", ephemeral: true }).catch(err => {}) + if(timer?.authorId != interaction.user.id) return interaction.reply({ content: "Un minuteur a été trouvé avec cet identifiant mais vous n'en êtes pas son créateur, les informations sont donc indisponibles.", ephemeral: true }).catch(err => {}) // Créer un embed var listFields = [ - timer.userDuration ? { name: 'Durée', value: timer.userDuration, inline: true } : null, - timer.startDate ? { name: 'Date de début', value: ``, inline: true } : null, - timer.endDate ? { name: 'Date de fin', value: ``, inline: true } : null, - timer.reason ? { name: 'Raison', value: timer.reason, inline: true } : null, - timer.timerId ? { name: 'Identifiant', value: `\`${timer.timerId}\``, inline: true } : null, + timer.userDuration ? { name: "Durée", value: timer.userDuration, inline: true } : null, + timer.startDate ? { name: "Date de début", value: ``, inline: true } : null, + timer.endDate ? { name: "Date de fin", value: ``, inline: true } : null, + timer.reason ? { name: "Raison", value: timer.reason, inline: true } : null, + timer.timerId ? { name: "Identifiant", value: `\`${timer.timerId}\``, inline: true } : null, ] var embed = new EmbedBuilder() - .setTitle("Détails du minuteur") - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) - .addFields(listFields.filter(field => field != null)) + .setTitle("Détails du minuteur") + .setColor(bacheroFunctions.colors.primary) + .addFields(listFields.filter(field => field != null)) // Créé un bouton si on veut supprimer var date = Date.now() - const rowConfirm = new ActionRowBuilder().addComponents( - new ButtonBuilder() + const rowConfirm = new ActionRowBuilder().addComponents(new ButtonBuilder() .setCustomId(`confirm-deleteTimer-${date}`) - .setLabel('Supprimer') - .setStyle(ButtonStyle.Danger) - ) + .setLabel("Supprimer") + .setStyle(ButtonStyle.Danger)) buttonsIds.push({ customId: `confirm-deleteTimer-${date}`, interaction: interaction, authorId: interaction.user.id, timer: timer }) // Répondre avec l'embed et les boutons @@ -288,36 +275,36 @@ module.exports = { } // Si on veut supprimer un minuteur - if(interaction.options.getSubcommand() == 'delete'){ + if(interaction.options.getSubcommand() == "delete"){ // Obtenir l'identifiant du minuteur - var timerId = interaction.options.getString('id') + var timerId = interaction.options.getString("id") // Obtenir le minuteur associé à cet identifiant var timer = (await runningTimers()).find(timer => timer?.timerId == timerId && timer?.authorId == interaction.user.id) - if(!timer) var timer = (await runningTimers()).find(timer => timer?.timerId?.toLowerCase()?.replace(/_/g,'') == timerId?.toLowerCase()?.replace(/_/g,'') && timer?.authorId == interaction.user.id) // deuxième tentative qui laisse plus d'éléments, tant que c'est la bonne personne + if(!timer) var timer = (await runningTimers()).find(timer => timer?.timerId?.toLowerCase()?.replace(/_/g, "") == timerId?.toLowerCase()?.replace(/_/g, "") && timer?.authorId == interaction.user.id) // deuxième tentative qui laisse plus d'éléments, tant que c'est la bonne personne // Si on a pas trouvé de minuteur - if(!timer) return interaction.reply({ content: `Aucun minuteur n'a été trouvé avec cet identifiant. Vérifier qu'il a bien été écrit, et que vous en êtes le créateur.`, ephemeral: true }).catch(err => {}) + if(!timer) return interaction.reply({ content: "Aucun minuteur n'a été trouvé avec cet identifiant. Vérifier qu'il a bien été écrit, et que vous en êtes le créateur.", ephemeral: true }).catch(err => {}) // Créer un embed var embed = new EmbedBuilder() - .setTitle("Suppression d'un minuteur") - .setDescription(`Le minuteur avec l'identifiant \`${timer?.timerId}\` qui s'arrête ${timer?.reason?.length ? ` avec la raison "${timer?.reason?.replace(/`/g, '')?.replace(/"/g, '')}"` : ''} va être supprimé.`) - .setColor(bacheroFunctions.config.getValue('bachero', 'embedColor')) + .setTitle("Suppression d'un minuteur") + .setDescription(`Le minuteur avec l'identifiant \`${timer?.timerId}\` qui s'arrête ${timer?.reason?.length ? ` avec la raison "${timer?.reason?.replace(/`/g, "")?.replace(/"/g, "")}"` : ""} va être supprimé.`) + .setColor(bacheroFunctions.colors.secondary) // Créé deux boutons pour confirmer qu'on sois sur var date = Date.now() const rowConfirm = new ActionRowBuilder().addComponents( new ButtonBuilder() - .setCustomId(`confirm-deleteTimer-${date}`) - .setLabel('Confirmer') - .setStyle(ButtonStyle.Success), + .setCustomId(`confirm-deleteTimer-${date}`) + .setLabel("Confirmer") + .setStyle(ButtonStyle.Success), new ButtonBuilder() - .setCustomId(`cancel-deleteTimer-${date}`) - .setLabel('Finalement non') - .setStyle(ButtonStyle.Danger), + .setCustomId(`cancel-deleteTimer-${date}`) + .setLabel("Finalement non") + .setStyle(ButtonStyle.Danger), ) - buttonsIds.push({ customId: `confirm-deleteTimer-${date}`, interaction: interaction, authorId: interaction.user.id, timer: timer }, { customId: `cancel-deleteTimer-${date}`, interaction: interaction, interaction: interaction, authorId: interaction.user.id, timer: timer }) + buttonsIds.push({ customId: `confirm-deleteTimer-${date}`, interaction: interaction, authorId: interaction.user.id, timer: timer }, { customId: `cancel-deleteTimer-${date}`, interaction: interaction, authorId: interaction.user.id, timer: timer }) // Répondre avec l'embed et les boutons interaction.reply({ embeds: [embed], components: [rowConfirm] }).catch(err => {}) diff --git a/modules/bachero.module.transports/divia.js b/modules/bachero.module.transports/divia.js index 9df72f0..3a07296 100644 --- a/modules/bachero.module.transports/divia.js +++ b/modules/bachero.module.transports/divia.js @@ -333,7 +333,7 @@ module.exports = { }) }, - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Vérifier et répondre si l'utilisateur est limité, sinon on le limite var checkAndReply = await bacheroFunctions.cooldown.checkAndReply(interaction, "transportModuleDiviaCmd") diff --git a/modules/bachero.module.transports/fluo.js b/modules/bachero.module.transports/fluo.js index 26459ed..e8a39c9 100644 --- a/modules/bachero.module.transports/fluo.js +++ b/modules/bachero.module.transports/fluo.js @@ -20,7 +20,7 @@ module.exports = { .setDescription("Arrêt à rechercher") .setRequired(true)), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Mettre la réponse en defer if(await interaction.deferReply({ ephemeral: false }).catch(err => { return "stop" }) == "stop") return diff --git a/modules/bachero.module.transports/manifest.jsonc b/modules/bachero.module.transports/manifest.jsonc index d602cce..2e8d0fe 100644 --- a/modules/bachero.module.transports/manifest.jsonc +++ b/modules/bachero.module.transports/manifest.jsonc @@ -1,5 +1,4 @@ { - "disabled": true, // le module marche pas encore à cause de certaines modifs dans le fichier index.js et le fichier functions.js // Nom unique, plusieurs modules ne peuvent pas avoir le même nom "packageName": "bachero.module.transports", @@ -8,10 +7,6 @@ // Description du module "shortDescription": "Récupère et affiche les horaires des passages de différents transports en commun", - "longDescription": "Permet d'obtenir et d'afficher les horaires de passage des transports en commun dans plusieurs régions de France sur Discord.", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.transports/ratp.js b/modules/bachero.module.transports/ratp.js index ed67e80..8977439 100644 --- a/modules/bachero.module.transports/ratp.js +++ b/modules/bachero.module.transports/ratp.js @@ -1,6 +1,6 @@ -const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ModalBuilder, TextInputBuilder, TextInputStyle, ButtonBuilder, ButtonStyle, StringSelectMenuBuilder, StringSelectMenuOptionBuilder } = require('discord.js') -const Fuse = require('fuse.js'); -const bacheroFunctions = require('../../functions') +const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ModalBuilder, TextInputBuilder, TextInputStyle, ButtonBuilder, ButtonStyle, StringSelectMenuBuilder, StringSelectMenuOptionBuilder } = require("discord.js") +const Fuse = require("fuse.js") +const bacheroFunctions = require("../../functions") // Ids d'interactions var interactionIds = [] @@ -12,84 +12,84 @@ var cache_stops = {} // Liste de tous les identifiants de transports const transportIds = { tramway: [ - { name: 'Tramway 1', id: 'LIG:IDFM:C01389' }, - { name: 'Tramway 2', id: 'LIG:IDFM:C01390' }, - { name: 'Tramway 3a', id: 'LIG:IDFM:C01391' }, - { name: 'Tramway 3b', id: 'LIG:IDFM:C01679' }, - { name: 'Tramway 4', id: 'LIG:IDFM:C01843' }, - { name: 'Tramway 5', id: 'LIG:IDFM:C01684' }, - { name: 'Tramway 6', id: 'LIG:IDFM:C01794' }, - { name: 'Tramway 7', id: 'LIG:IDFM:C01774' }, - { name: 'Tramway 8', id: 'LIG:IDFM:C01795' }, - { name: 'Tramway 9', id: 'LIG:IDFM:C02317' }, - { name: 'Tramway 10', id: 'LIG:IDFM:C02528' }, - { name: 'Tramway 11', id: 'LIG:IDFM:C01999' }, - { name: 'Tramway 13', id: 'LIG:IDFM:C02344' }, + { name: "Tramway 1", id: "LIG:IDFM:C01389" }, + { name: "Tramway 2", id: "LIG:IDFM:C01390" }, + { name: "Tramway 3a", id: "LIG:IDFM:C01391" }, + { name: "Tramway 3b", id: "LIG:IDFM:C01679" }, + { name: "Tramway 4", id: "LIG:IDFM:C01843" }, + { name: "Tramway 5", id: "LIG:IDFM:C01684" }, + { name: "Tramway 6", id: "LIG:IDFM:C01794" }, + { name: "Tramway 7", id: "LIG:IDFM:C01774" }, + { name: "Tramway 8", id: "LIG:IDFM:C01795" }, + { name: "Tramway 9", id: "LIG:IDFM:C02317" }, + { name: "Tramway 10", id: "LIG:IDFM:C02528" }, + { name: "Tramway 11", id: "LIG:IDFM:C01999" }, + { name: "Tramway 13", id: "LIG:IDFM:C02344" }, ], rer: [ - { name: 'RER A', id: 'LIG:IDFM:C01742' }, - { name: 'RER B', id: 'LIG:IDFM:C01743' }, - { name: 'RER C', id: 'LIG:IDFM:C01727' }, - { name: 'RER D', id: 'LIG:IDFM:C01728' }, - { name: 'RER E', id: 'LIG:IDFM:C01729' }, + { name: "RER A", id: "LIG:IDFM:C01742" }, + { name: "RER B", id: "LIG:IDFM:C01743" }, + { name: "RER C", id: "LIG:IDFM:C01727" }, + { name: "RER D", id: "LIG:IDFM:C01728" }, + { name: "RER E", id: "LIG:IDFM:C01729" }, ], metro: [ - { name: 'Métro 1', id: 'LIG:IDFM:C01371' }, - { name: 'Métro 2', id: 'LIG:IDFM:C01372' }, - { name: 'Métro 3', id: 'LIG:IDFM:C01373' }, - { name: 'Métro 3 Bis', id: 'LIG:IDFM:C01386' }, - { name: 'Métro 4', id: 'LIG:IDFM:C01374' }, - { name: 'Métro 5', id: 'LIG:IDFM:C01375' }, - { name: 'Métro 6', id: 'LIG:IDFM:C01376' }, - { name: 'Métro 7', id: 'LIG:IDFM:C01377' }, - { name: 'Métro 7 Bis', id: 'LIG:IDFM:C01387' }, - { name: 'Métro 8', id: 'LIG:IDFM:C01378' }, - { name: 'Métro 9', id: 'LIG:IDFM:C01379' }, - { name: 'Métro 10', id: 'LIG:IDFM:C01380' }, - { name: 'Métro 11', id: 'LIG:IDFM:C01381' }, - { name: 'Métro 12', id: 'LIG:IDFM:C01382' }, - { name: 'Métro 13', id: 'LIG:IDFM:C01383' }, - { name: 'Métro 14', id: 'LIG:IDFM:C01384' }, + { name: "Métro 1", id: "LIG:IDFM:C01371" }, + { name: "Métro 2", id: "LIG:IDFM:C01372" }, + { name: "Métro 3", id: "LIG:IDFM:C01373" }, + { name: "Métro 3 Bis", id: "LIG:IDFM:C01386" }, + { name: "Métro 4", id: "LIG:IDFM:C01374" }, + { name: "Métro 5", id: "LIG:IDFM:C01375" }, + { name: "Métro 6", id: "LIG:IDFM:C01376" }, + { name: "Métro 7", id: "LIG:IDFM:C01377" }, + { name: "Métro 7 Bis", id: "LIG:IDFM:C01387" }, + { name: "Métro 8", id: "LIG:IDFM:C01378" }, + { name: "Métro 9", id: "LIG:IDFM:C01379" }, + { name: "Métro 10", id: "LIG:IDFM:C01380" }, + { name: "Métro 11", id: "LIG:IDFM:C01381" }, + { name: "Métro 12", id: "LIG:IDFM:C01382" }, + { name: "Métro 13", id: "LIG:IDFM:C01383" }, + { name: "Métro 14", id: "LIG:IDFM:C01384" }, ], transilien: [ - { name: 'Transilien H', id: 'LIG:IDFM:C01737' }, - { name: 'Transilien J', id: 'LIG:IDFM:C01739' }, - { name: 'Transilien K', id: 'LIG:IDFM:C01738' }, - { name: 'Transilien L', id: 'LIG:IDFM:C01740' }, - { name: 'Transilien N', id: 'LIG:IDFM:C01736' }, - { name: 'Transilien P', id: 'LIG:IDFM:C01730' }, - { name: 'Transilien R', id: 'LIG:IDFM:C01731' }, - { name: 'Transilien U', id: 'LIG:IDFM:C01741' }, + { name: "Transilien H", id: "LIG:IDFM:C01737" }, + { name: "Transilien J", id: "LIG:IDFM:C01739" }, + { name: "Transilien K", id: "LIG:IDFM:C01738" }, + { name: "Transilien L", id: "LIG:IDFM:C01740" }, + { name: "Transilien N", id: "LIG:IDFM:C01736" }, + { name: "Transilien P", id: "LIG:IDFM:C01730" }, + { name: "Transilien R", id: "LIG:IDFM:C01731" }, + { name: "Transilien U", id: "LIG:IDFM:C01741" }, ] } // Fonction utilitaire pour obtenir un nom d'arrêt joli function getStopName(name){ // Modifications simples - name = name.replaceAll(/(? { return p1 + p2.toLowerCase() }) // Remplacer les mots en majuscules par des minuscules sauf pour la première lettre // Certains mots on les remplace par d'autres - name = name.replaceAll(' Rer', ' RER') - name = name.replaceAll(' Du ', ' du ') - name = name.replaceAll('St ', 'Saint ') - name = name.replaceAll('Gare De ', 'Gare de ') - name = name.replaceAll('La Defense', 'La Défense') - name = name.replaceAll('A.france', 'Anatole France') - name = name.replaceAll('Cite', 'Cité') + name = name.replaceAll(" Rer", " RER") + name = name.replaceAll(" Du ", " du ") + name = name.replaceAll("St ", "Saint ") + name = name.replaceAll("Gare De ", "Gare de ") + name = name.replaceAll("La Defense", "La Défense") + name = name.replaceAll("A.france", "Anatole France") + name = name.replaceAll("Cite", "Cité") name = name.replaceAll("D'Italie", "d'Italie") - name = name.replaceAll('Jonchere', 'Jonchère') - name = name.replaceAll('C.charlebourg', 'Colombes Charlebourg') - name = name.replaceAll('Asnieres', 'Asnières') - name = name.replaceAll('Porte d ', "Porte d'") - name = name.replaceAll('Orleans', "Orléans") - name = name.replaceAll('La Cavee', 'La cavée') + name = name.replaceAll("Jonchere", "Jonchère") + name = name.replaceAll("C.charlebourg", "Colombes Charlebourg") + name = name.replaceAll("Asnieres", "Asnières") + name = name.replaceAll("Porte d ", "Porte d'") + name = name.replaceAll("Orleans", "Orléans") + name = name.replaceAll("La Cavee", "La cavée") name = name.replaceAll("A l'arrêt", "À l'arrêt") - name = name.replaceAll(' ....','…') + name = name.replaceAll(" ....", "…") // Enlever si 2/3 espaces se suivent - name = name.replaceAll(' ', ' ') - name = name.replaceAll(' ', ' ') + name = name.replaceAll(" ", " ") + name = name.replaceAll(" ", " ") return name // Retourner le nom } @@ -104,10 +104,10 @@ async function whenLineObtained(interaction, line, isBus){ var _line = line if(cache_lines[line]) line = cache_lines[line] // si on l'a déjà en cache, on l'utilise else if(isBus){ - line = await fetch(`https://www.bonjour-ratp.fr/api/bff/lines/search/`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: line }) }).then(r => r.json()).catch(err => { return { fetcherror: err } }) + line = await fetch("https://www.bonjour-ratp.fr/api/bff/lines/search/", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ text: line }) }).then(r => r.json()).catch(err => { return { fetcherror: err } }) if(line.fetcherror) return await bacheroFunctions.report.createAndReply("requête vers l'API de la RATP (n°1)", line.fetcherror || line, {}, interaction) if(!line?.[0]?.id) return interaction.editReply({ content: "Je n'ai pas trouvé cette ligne de bus..." }).catch(err => {}) - line = { id: line?.[0]?.id, name: 'BUS ' + line?.[0]?.displayCode } + line = { id: line?.[0]?.id, name: `BUS ${line?.[0]?.displayCode}` } } else line = transportIds[Object.keys(transportIds).find(t => transportIds[t].find(l => l.id == line))].find(l => l.id == line) // Obtenir les arrêts sur la ligne @@ -127,33 +127,27 @@ async function whenLineObtained(interaction, line, isBus){ if(stops.length > 25){ // Créer un embed var embed = new EmbedBuilder() - .setTitle(`${stops.length} arrêts trouvés sur ${line.name}`) - .setDescription(stops.map(s => `- **${s.name ? s.name : 'Inconnu (???)'}** ${s.code ? s.code + ' ' : ''}${s.city ? s.city : 'Ville Inconnue'}`).join('\n')) - .setColor(bacheroFunctions.colors.primary) + .setTitle(`${stops.length} arrêts trouvés sur ${line.name}`) + .setDescription(stops.map(s => `- **${s.name ? s.name : "Inconnu (???)"}** ${s.code ? `${s.code} ` : ""}${s.city ? s.city : "Ville Inconnue"}`).join("\n")) + .setColor(bacheroFunctions.colors.primary) // Créer le bouton pour choisir via un modal var id = Date.now() - const row = new ActionRowBuilder().addComponents( - new ButtonBuilder() + const row = new ActionRowBuilder().addComponents(new ButtonBuilder() .setCustomId(`ratpCmd-stop-${id}`) - .setLabel('Choisir un arrêt') - .setStyle(ButtonStyle.Primary) - ) + .setLabel("Choisir un arrêt") + .setStyle(ButtonStyle.Primary)) interactionIds.push({ id: id, line: line, stops: stops }) await interaction.editReply({ embeds: [embed], components: [row] }).catch(err => {}) } else { // Répondre à l'interaction var id = Date.now() - const row = new ActionRowBuilder().addComponents( - new StringSelectMenuBuilder() + const row = new ActionRowBuilder().addComponents(new StringSelectMenuBuilder() .setCustomId(`ratpCmd-stop-${id}`) - .setPlaceholder('Choissisez un arrêt') - .addOptions( - stops.map(s => { - return new StringSelectMenuOptionBuilder().setLabel(`${s.name ? s.name : 'Inconnu (???)'}`).setDescription(`${s.code ? s.code + ' ' : ''}${s.city ? s.city : 'Ville Inconnue'}`).setValue(s.id) - }) - ) - ) + .setPlaceholder("Choissisez un arrêt") + .addOptions(stops.map(s => { + return new StringSelectMenuOptionBuilder().setLabel(`${s.name ? s.name : "Inconnu (???)"}`).setDescription(`${s.code ? `${s.code} ` : ""}${s.city ? s.city : "Ville Inconnue"}`).setValue(s.id) + }))) interactionIds.push({ id: id, line: line, stops: stops }) await interaction.editReply({ components: [row] }).catch(err => {}) } @@ -168,7 +162,7 @@ async function whenStopObtained(interaction, stop, isComplete){ await interaction.deferUpdate().catch(err => { interaction.deferReply().catch(err => {}) }) // On détermine la ligne - var line = interactionIds?.find(i => i.id == interaction.customId.split('-')[2]) + var line = interactionIds?.find(i => i.id == interaction.customId.split("-")[2]) if(!line) return interaction.editReply({ embeds: [], components: [], content: "Commande expirée. Réessayez la commande." }).catch(err => {}) var stops = line.stops line = line.line @@ -176,7 +170,7 @@ async function whenStopObtained(interaction, stop, isComplete){ // Si c'est pas un arrêt complet, on essaye d'obtenir son identifiant if(!isComplete){ // On essaye d'obtenir l'arrêt, limiter à 15 résultats - var search = new Fuse(stops, { keys: ['name', 'code', 'city'], shouldSort: true, distance: 200, threshold: 0.4, ignoreLocation: true }).search(stop) + var search = new Fuse(stops, { keys: ["name", "code", "city"], shouldSort: true, distance: 200, threshold: 0.4, ignoreLocation: true }).search(stop) if(!search?.[0]?.item?.id) return interaction.editReply({ embeds: [], content: "Je n'ai pas trouvé cet arrêt..." }).catch(err => {}) search = search.slice(0, 15) @@ -185,21 +179,17 @@ async function whenStopObtained(interaction, stop, isComplete){ // Sinon on demande à l'utilisateur de préciser else { - const row = new ActionRowBuilder().addComponents( // On crée une action row - new StringSelectMenuBuilder() - .setCustomId('ratpCmd-stop-' + interaction.customId.split('-')[2]) - .setPlaceholder('Choissisez un arrêt') - .addOptions( - search.map(s => { - return new StringSelectMenuOptionBuilder().setLabel(`${s.item.name ? s.item.name : 'Inconnu (???)'}`).setDescription(`${s.item.code ? s.item.code + ' ' : ''}${s.item.city ? s.item.city : 'Ville Inconnue'}`).setValue(s.item.id) - }) - ) - ) + const row = new ActionRowBuilder().addComponents(new StringSelectMenuBuilder() // On crée une action row + .setCustomId(`ratpCmd-stop-${interaction.customId.split("-")[2]}`) + .setPlaceholder("Choissisez un arrêt") + .addOptions(search.map(s => { + return new StringSelectMenuOptionBuilder().setLabel(`${s.item.name ? s.item.name : "Inconnu (???)"}`).setDescription(`${s.item.code ? `${s.item.code} ` : ""}${s.item.city ? s.item.city : "Ville Inconnue"}`).setValue(s.item.id) + }))) await interaction.editReply({ embeds: [], components: [row] }).catch(err => {}) return } } - interactionIds = interactionIds.filter(i => i.id != interaction.customId.split('-')[2]) // On supprime l'interaction de la liste + interactionIds = interactionIds.filter(i => i.id != interaction.customId.split("-")[2]) // On supprime l'interaction de la liste // Obtenir les horaires var times = await fetch(`https://www.bonjour-ratp.fr/api/next-stops/${stop}/preview/`).then(r => r.json()).catch(err => { return { fetcherror: err } }) @@ -212,7 +202,7 @@ async function whenStopObtained(interaction, stop, isComplete){ lineName: t.lineName, situationCriticity: t.situationCriticity, nextStops: t.nextStops.map(s => { - return { name: getStopName(s.destinationName), dateTime: s.dateTime, additionalWaitingTimeNote: s.additionalWaitingTimeNote, wait: s.waitingTimeInMinutes, status: !s.status || (s.status && s.rawFallback && (s.status == 'UNKNOWN' || s.status == 'DEGRADED')) ? getStopName(s.rawFallback.replace('Service Termine', 'Service terminé').replace('Info Indispo ....', 'Infos indisponibles').replace('Pas de Service', 'Pas de service').replace('Service Non Commence', 'Service non commencé').replace('Deviation Arret Non Desservi', 'Arrêt non desservi, déviation').replace('Arret Non Desservi Travaux', 'Arrêt non desservi, travaux')) : s.status.replace('UNAVAILABLE', null).replace('DEGRADED', null) } + return { name: getStopName(s.destinationName), dateTime: s.dateTime, additionalWaitingTimeNote: s.additionalWaitingTimeNote, wait: s.waitingTimeInMinutes, status: !s.status || (s.status && s.rawFallback && (s.status == "UNKNOWN" || s.status == "DEGRADED")) ? getStopName(s.rawFallback.replace("Service Termine", "Service terminé").replace("Info Indispo ....", "Infos indisponibles").replace("Pas de Service", "Pas de service").replace("Service Non Commence", "Service non commencé").replace("Deviation Arret Non Desservi", "Arrêt non desservi, déviation").replace("Arret Non Desservi Travaux", "Arrêt non desservi, travaux")) : s.status.replace("UNAVAILABLE", null).replace("DEGRADED", null) } }) } }) @@ -220,149 +210,139 @@ async function whenStopObtained(interaction, stop, isComplete){ return { lineName: t.lineName, situationCriticity: t.situationCriticity, - nextStops: t.nextStops.filter(s => s.status != "null" && s.status != 'Infos indisponibles' && s.status != 'UNAVAILABLE') + nextStops: t.nextStops.filter(s => s.status != "null" && s.status != "Infos indisponibles" && s.status != "UNAVAILABLE") } }) times = times.filter(t => t.nextStops.length > 0) // On enlève les lignes qui n'ont pas d'horaires // Créer l'embed var embed = new EmbedBuilder() - .setTitle(`Horaires de passage à l'arrêt ${stops.find(s => s.id == stop).name}`) - .setDescription(!times.length ? "Aucun passages n'a pu être trouvé à cet arrêt. Tenter d'utiliser l'appli RATP pour plus de détails, ou réessayer plus tard." : times.map(t => { - return `### ${t.lineName} — ${t?.nextStops?.[0]?.name ? t?.nextStops?.[0]?.name?.substring(0, 106) : ''}${t?.situationCriticity ? '— Potentiels problèmes sur la ligne' : ''}\n${t.nextStops.map(s => { - return `- ${s.status != 'AVAILABLE_WAITING_TIME' && s.status ? s.status.replace('APPROACHING', "**À l'approche**").replace('ATDOCK', "**À quai**") : ''}${s.status != 'AVAILABLE_WAITING_TIME' && s.status && typeof s.wait == 'number' ? ` | ${s.wait} minute${s.wait > 1 ? 's' :''}` : (typeof s.wait == 'number' ? `${s.wait} minute${s.wait > 1 ? 's' :''}` : (s.dateTime ? new Date(s.dateTime).toLocaleString() : ''))}${s.additionalWaitingTimeNote?.length ? ' | ' + s.additionalWaitingTimeNote : ''}` - }).join('\n')}` - }).join('\n')) - .setColor(bacheroFunctions.colors.primary) - .setFooter({ text: 'Données fournies par "Bonjour RATP"' }) + .setTitle(`Horaires de passage à l'arrêt ${stops.find(s => s.id == stop).name}`) + .setDescription(!times.length ? "Aucun passages n'a pu être trouvé à cet arrêt. Tenter d'utiliser l'appli RATP pour plus de détails, ou réessayer plus tard." : times.map(t => { + return `### ${t.lineName} — ${t?.nextStops?.[0]?.name ? t?.nextStops?.[0]?.name?.substring(0, 106) : ""}${t?.situationCriticity ? "— Potentiels problèmes sur la ligne" : ""}\n${t.nextStops.map(s => { + return `- ${s.status != "AVAILABLE_WAITING_TIME" && s.status ? s.status.replace("APPROACHING", "**À l'approche**").replace("ATDOCK", "**À quai**") : ""}${s.status != "AVAILABLE_WAITING_TIME" && s.status && typeof s.wait == "number" ? ` | ${s.wait} minute${s.wait > 1 ? "s" : ""}` : (typeof s.wait == "number" ? `${s.wait} minute${s.wait > 1 ? "s" : ""}` : (s.dateTime ? new Date(s.dateTime).toLocaleString() : ""))}${s.additionalWaitingTimeNote?.length ? ` | ${s.additionalWaitingTimeNote}` : ""}` + }).join("\n")}` + }).join("\n")) + .setColor(bacheroFunctions.colors.primary) + .setFooter({ text: "Données fournies par \"Bonjour RATP\"" }) // Répondre à l'interaction - await interaction.editReply({ embeds: [embed], components: [], content: '' }).catch(err => {}) + await interaction.editReply({ embeds: [embed], components: [], content: "" }).catch(err => {}) } // Exporter certaines fonctions module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('ratp') - .setDescription(`Permet de récupérer les horaires sur le réseau de transport RATP`), + .setName("ratp") + .setDescription("Permet de récupérer les horaires sur le réseau de transport RATP"), // Récupérer le listener et savoir lorsque quelqu'un fait quelque chose async interactionListener(listener){ // Pour les select menu - listener.on('selectMenu', async (interaction) => { + listener.on("selectMenu", async (interaction) => { // Vérifier l'ids - if(interaction.customId != 'ratpCmd-type' && interaction.customId != 'ratpCmd-line' && !interaction.customId.startsWith('ratpCmd-stop-')) return + if(interaction.customId != "ratpCmd-type" && interaction.customId != "ratpCmd-line" && !interaction.customId.startsWith("ratpCmd-stop-")) return // Vérifier l'auteur puis defer l'interaction if((interaction?.message?.interaction?.user?.id && interaction.user.id != interaction?.message?.interaction?.user?.id) || (interaction?.message?.mentions?.repliedUser?.id && interaction.user.id != interaction?.message?.mentions?.repliedUser?.id)) return interaction.reply({ content: "Il semblerait que tu ne sois pas la personne que j'attendais...", ephemeral: true }).catch(err => {}) // Si on a sélectionné le type de transport - if(interaction.customId == 'ratpCmd-type'){ + if(interaction.customId == "ratpCmd-type"){ // Récupérer le type de transport var type = interaction?.values?.[0] - if(!type) return; // en théorie on devrait jamais arriver ici, mais on sait jamais + if(!type) return // en théorie on devrait jamais arriver ici, mais on sait jamais // Si c'est le bus, demander le numéro de la ligne via un modal - if(type == 'bus'){ + if(type == "bus"){ interaction.showModal(new ModalBuilder() - .setCustomId('ratpCmd-modalLine') - .setTitle('Choissisez une ligne') - .addComponents( - new ActionRowBuilder().addComponents(new TextInputBuilder() - .setCustomId('ratpCmd-line') - .setLabel("Ligne de bus") - .setStyle(TextInputStyle.Short) - .setRequired(true) - .setMinLength(1) - .setMaxLength(4)) - )).catch(err => {}) + .setCustomId("ratpCmd-modalLine") + .setTitle("Choissisez une ligne") + .addComponents(new ActionRowBuilder().addComponents(new TextInputBuilder() + .setCustomId("ratpCmd-line") + .setLabel("Ligne de bus") + .setStyle(TextInputStyle.Short) + .setRequired(true) + .setMinLength(1) + .setMaxLength(4)))).catch(err => {}) await interaction.deleteReply().catch(err => {}) } // Sinon else { if(!transportIds[type]) return // en théorie on devrait jamais arriver ici, mais on sait jamais - const row = new ActionRowBuilder().addComponents( - new StringSelectMenuBuilder() - .setCustomId('ratpCmd-line') - .setPlaceholder('Choissisez une ligne') - .addOptions( - transportIds[type].map(t => new StringSelectMenuOptionBuilder().setLabel(t.name).setValue(t.id)) - ) - ) + const row = new ActionRowBuilder().addComponents(new StringSelectMenuBuilder() + .setCustomId("ratpCmd-line") + .setPlaceholder("Choissisez une ligne") + .addOptions(transportIds[type].map(t => new StringSelectMenuOptionBuilder().setLabel(t.name).setValue(t.id)))) await interaction.update({ components: [row] }).catch(err => {}) } } // Si on a choisit une ligne - else if(interaction.customId == 'ratpCmd-line') whenLineObtained(interaction, interaction?.values?.[0], false) + else if(interaction.customId == "ratpCmd-line") whenLineObtained(interaction, interaction?.values?.[0], false) // Si on a choisit un arrêt - else if(interaction.customId.startsWith('ratpCmd-stop-')) whenStopObtained(interaction, interaction?.values?.[0], true) + else if(interaction.customId.startsWith("ratpCmd-stop-")) whenStopObtained(interaction, interaction?.values?.[0], true) }) // Pour les modals - listener.on('modal', async (interaction) => { - if(interaction.customId != 'ratpCmd-modalLine' && !interaction.customId.startsWith('ratpCmd-modalStop')) return + listener.on("modal", async (interaction) => { + if(interaction.customId != "ratpCmd-modalLine" && !interaction.customId.startsWith("ratpCmd-modalStop")) return if((interaction?.message?.interaction?.user?.id && interaction.user.id != interaction?.message?.interaction?.user?.id) || (interaction?.message?.mentions?.repliedUser?.id && interaction.user.id != interaction?.message?.mentions?.repliedUser?.id)) return interaction.reply({ content: "Il semblerait que tu ne sois pas la personne que j'attendais...", ephemeral: true }).catch(err => {}) - if(interaction.customId == 'ratpCmd-modalLine') whenLineObtained(interaction, interaction?.fields?.getTextInputValue('ratpCmd-line'), true) - if(interaction.customId.startsWith('ratpCmd-modalStop')) whenStopObtained(interaction, interaction?.fields?.getTextInputValue('ratpCmd-stop'), false) + if(interaction.customId == "ratpCmd-modalLine") whenLineObtained(interaction, interaction?.fields?.getTextInputValue("ratpCmd-line"), true) + if(interaction.customId.startsWith("ratpCmd-modalStop")) whenStopObtained(interaction, interaction?.fields?.getTextInputValue("ratpCmd-stop"), false) }) // Pour les boutons - listener.on('button', async (interaction) => { - if(!interaction.customId.startsWith('ratpCmd-stop-')) return + listener.on("button", async (interaction) => { + if(!interaction.customId.startsWith("ratpCmd-stop-")) return if((interaction?.message?.interaction?.user?.id && interaction.user.id != interaction?.message?.interaction?.user?.id) || (interaction?.message?.mentions?.repliedUser?.id && interaction.user.id != interaction?.message?.mentions?.repliedUser?.id)) return interaction.reply({ content: "Il semblerait que tu ne sois pas la personne que j'attendais...", ephemeral: true }).catch(err => {}) - if(interaction.customId.startsWith('ratpCmd-stop-')){ - var id = interaction.customId.split('-')[2] + if(interaction.customId.startsWith("ratpCmd-stop-")){ + var id = interaction.customId.split("-")[2] await interaction.showModal(new ModalBuilder() // Créer un modal pour demander le nom de l'arrêt - .setCustomId(`ratpCmd-modalStop-${id}`) - .setTitle('Choissisez un arrêt') - .addComponents( - new ActionRowBuilder().addComponents(new TextInputBuilder() - .setCustomId(`ratpCmd-stop`) // note: ne surtout pas mettre un identifiant ici - .setLabel("Nom de l'arrêt") - .setStyle(TextInputStyle.Short) - .setRequired(true) - .setMinLength(1) - .setMaxLength(50)) - )).catch(err => {}) + .setCustomId(`ratpCmd-modalStop-${id}`) + .setTitle("Choissisez un arrêt") + .addComponents(new ActionRowBuilder().addComponents(new TextInputBuilder() + .setCustomId("ratpCmd-stop") // note: ne surtout pas mettre un identifiant ici + .setLabel("Nom de l'arrêt") + .setStyle(TextInputStyle.Short) + .setRequired(true) + .setMinLength(1) + .setMaxLength(50)))).catch(err => {}) } }) }, - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Vérifier et répondre si l'utilisateur est limité, sinon on le limite - var checkAndReply = await bacheroFunctions.cooldown.checkAndReply(interaction, 'transportModuleRatpCmd') - if(checkAndReply) return; else await bacheroFunctions.cooldown.set('transportModuleRatpCmd', interaction.user.id, 7000) + var checkAndReply = await bacheroFunctions.cooldown.checkAndReply(interaction, "transportModuleRatpCmd") + if(checkAndReply) return; else await bacheroFunctions.cooldown.set("transportModuleRatpCmd", interaction.user.id, 7000) // Demander le type de transport - const row = new ActionRowBuilder().addComponents( - new StringSelectMenuBuilder() - .setCustomId('ratpCmd-type') - .setPlaceholder('Sélectionnez le type de transport') + const row = new ActionRowBuilder().addComponents(new StringSelectMenuBuilder() + .setCustomId("ratpCmd-type") + .setPlaceholder("Sélectionnez le type de transport") .addOptions( new StringSelectMenuOptionBuilder() - .setLabel('BUS') - .setValue('bus'), + .setLabel("BUS") + .setValue("bus"), new StringSelectMenuOptionBuilder() - .setLabel('RER') - .setValue('rer'), + .setLabel("RER") + .setValue("rer"), new StringSelectMenuOptionBuilder() - .setLabel('Métro') - .setValue('metro'), + .setLabel("Métro") + .setValue("metro"), new StringSelectMenuOptionBuilder() - .setLabel('Tramway') - .setValue('tramway'), + .setLabel("Tramway") + .setValue("tramway"), new StringSelectMenuOptionBuilder() - .setLabel('Transilien') - .setValue('transilien'), - ) - ) + .setLabel("Transilien") + .setValue("transilien"), + )) interaction.reply({ components: [row] }).catch(err => {}) } } \ No newline at end of file diff --git a/modules/bachero.module.typeracer/manifest.jsonc b/modules/bachero.module.typeracer/manifest.jsonc index 5e60915..4c1b393 100644 --- a/modules/bachero.module.typeracer/manifest.jsonc +++ b/modules/bachero.module.typeracer/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Lance un duel d'écriture contre un membre de votre serveur", - "longDescription": "Rajoute une commande permettant de lancer un duel d'écriture envers un membre du serveur, le premier à finir d'écrire un texte remporte la partie.", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.typeracer/typeracer.js b/modules/bachero.module.typeracer/typeracer.js index 5edab39..57b3e15 100644 --- a/modules/bachero.module.typeracer/typeracer.js +++ b/modules/bachero.module.typeracer/typeracer.js @@ -1,127 +1,127 @@ -const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, ComponentType, ContextMenuCommandBuilder, ApplicationCommandType } = require('discord.js') -const { rando } = require('@nastyox/rando.js') -const escape = require('markdown-escape') -const { diffWords } = require('diff') -const { config } = require('../../functions') +const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, ComponentType, ContextMenuCommandBuilder, ApplicationCommandType } = require("discord.js") +const { rando } = require("@nastyox/rando.js") +const escape = require("markdown-escape") +const { diffWords } = require("diff") +const { colors } = require("../../functions") const listPhrases = [ - { text: `L'Homme est ci, l'Homme est ça, mais quand il commet l'homicide, l'Homme est sale.`, source: `https://genius.com/Lefa-fils-dadam-lyrics` }, - { text: `C'est bien beau de tourner des clips sur des yachts ou en hélico, ça c'est l'image, mais vos sons ont toujours besoin de soins médicaux.`, source: `https://genius.com/Lefa-plus-ltime-lyrics` }, - { text: `Il y aura du ciment sur mes mains pour bâtir ton avenir. Il y aura du sang sur mes mains si un homme te fait souffrir.`, source: `https://genius.com/Soprano-je-serai-la-lyrics` }, - { text: `Je n'ai pas révélé la moitié de ce que j'ai vu, car je savais qu'on ne me croirait pas...`, source: `https://citation-celebre.leparisien.fr/citations/271852` }, - { text: `Tu étais formidable, j'étais fort minable\nNous étions formidables`, source: `https://genius.com/Stromae-formidable-lyrics` }, - { text: `Cette fois c'était la dernière, tu peux croire que c'est qu'une crise.`, source: `https://genius.com/Stromae-tous-les-memes-lyrics` }, - { text: `Simius n'avait pas entendu, mais ses pensées cheminaient dans la même direction. Ils arrivaient aux premiers tombeaux de la nécropole. La porte sud de la ville.`, source: null }, - { text: `Pourquoi tu veux me mettre un bébé dans les bras ? J'ai déjà du mal à m'occuper de moi.`, source: `https://genius.com/Orelsan-san-lyrics` }, - { text: `Dans ce rap biz\nOn est arrivé les mains dans les poches\nA l'époque c'était "envoie le beat"\nOn fait le truc à l'arrache`, source: `https://genius.com/Sniper-grave-dans-la-roche-lyrics` }, - { text: `Garde le sourire, plus rien n'est grave\nTant qu'il nous reste une seconde de souvenir dans le crâne`, source: `https://genius.com/Lomepal-trop-beau-lyrics` }, - { text: `Ne fais pas ta joie du malheur d'autrui.\nIl n'est pas permis de blesser un ami, même en plaisantant.`, source: null }, - { text: `Je me sentais moins seule quand je ne te connaissais pas encore : j'attendais l'autre. Je ne pensais qu'à sa force et jamais à ma faiblesse.`, source: `https://www.dicocitations.com/citations/citation-25293.php` }, - { text: `Qui dit études dit travail, qui dit taf te dit tes thunes, qui dit argent dit dépenses, qui dit crédit dit créance, qui dit dette te dit huissier.`, source: `https://genius.com/Stromae-alors-on-danse-lyrics` }, - { text: `Et là tu t'dis que c'est fini\nCar pire que ça, ce serait la mort\nQuand tu crois enfin qu'tu t'en sors\nQuand y en a plus, et bah y en a encore`, source: `https://genius.com/Stromae-alors-on-danse-lyrics` }, - { text: `Donnez-moi une suite au Ritz, je n'en veux pas ! Des bijoux de chez Chanel, je n'en veux pas ! Donnez-moi une limousine, j'en ferais quoi ?`, source: `https://genius.com/Zaz-je-veux-lyrics` }, - { text: `Elle m'a aimé de tout son amour, de tout son coeur. Elle m'a donné tout ce qu'elle avait quand je n'étais rien.`, source: `https://genius.com/Kendji-girac-elle-ma-aime-lyrics ` }, - { text: `Ma raison somnolait, ma conscience me conseillait, mon subconscient m'déconseillait, mais mon esprit veut s'envoler.`, source: `https://genius.com/Gims-zombie-lyrics` }, - { text: `J'ai la colère des p'tits à qui on demande de choisir d'un coup leur métier, qui a conseillé la conseillère d'orientation ?`, source: `https://genius.com/Nekfeu-humanoide-lyrics` }, - { text: `Obligé d's'enterrer dans l'son, trouver une putain d'raison d'vivre\nJ'ai frappé dans les murs, mais ça résonne vide`, source: `https://genius.com/Nekfeu-humanoide-lyrics` }, - { text: `Un jour, ils ont commencé à menacer ma mif\nAlors je me suis armé par le biais d'un ami\nMais, Dieu merci, j'm'en suis jamais servi`, source: `https://genius.com/Nekfeu-mauvaise-graine-lyrics` }, - { text: `Aventurier de l'inconnu, avant tu riais de l'inconnu\nAvant tu riais du temps qui passe, et puis le temps est passé`, source: `https://genius.com/Nekfeu-avant-tu-riais-lyrics` }, - { text: `Ils disent que l'amour rend aveugle, mais il t'a redonné la vue\nIl t'a fait muer quand ta rage était sourde, il a fait fredonner la rue\nIl t'a fait retirer le collier de chien qui te servait d'écharpe`, source: `https://genius.com/Nekfeu-avant-tu-riais-lyrics` }, - { text: `Des Hommes de face désormais néfastes\nDes zones désolées, des hommes et des femmes\nTu te sens d'aucun des clans`, source: `https://genius.com/Nekfeu-avant-tu-riais-lyrics` }, - { text: `Ce soir, j'me mets minable, pourquoi j'me fais si mal ?\nJ'ai fait des rêves bizarres où tu changeais d'visage`, source: `https://genius.com/Orelsan-reves-bizarres-lyrics` }, - { text: `Ce soir, on ira faire un tour chez l'épicier ouvert en bas\nEt on parlera d'amour, entassés sur une véranda`, source: `https://genius.com/Nekfeu-on-verra-lyrics` }, - { text: `Combien d'fois j'ai volé par flemme de faire la queue ?`, source: `https://genius.com/Nekfeu-on-verra-lyrics` }, - { text: `Putain, bien sûr que j'me sens banane comme si le paradise m'avait mal accueilli\nJ'aimerais tellement que tu m'appelles juste pour pouvoir te raccrocher à la gueule`, source: `https://genius.com/Lefa-paradise-lyrics` }, - { text: `Le monde est à nous, le monde est à toi et moi`, source: `https://genius.com/Damso-macarena-lyrics` }, - { text: `Il fait le mec mature mais tu sais qu'au lit, plus que lui, j'assure`, source: `https://genius.com/Damso-macarena-lyrics` }, - { text: `Quand t'as démarré, qu't'es allée chez lui ben nan, j'ai rien dit\nPourtant, j'le savais qu'tu baisais pour t'évader, après tout, j''tais là qu'pour dépanner`, source: `https://genius.com/Damso-macarena-lyrics` }, - { text: `J'vais pas trop m'étaler, saigner fallait, blessé j'l'étais, j't'ai remballé, tu m'as remplacé, tu m'as délaissé`, source: `https://genius.com/Damso-macarena-lyrics` }, - { text: `À la base, j'ai commencé la musique juste pour voir\nJ'étais très différent de ceux qui cherchent plus de pouvoir\nJ'm'amusais à tester les plus grands qu'moi juste pour voir`, source: `https://genius.com/Spri-noir-juste-pour-voir-lyrics` }, - { text: `Juste pour voir, viens faire un tour dans nos têtes`, source: `https://genius.com/Spri-noir-juste-pour-voir-lyrics` }, - { text: `Si le monsieur dort dehors, c'est qu'il aime le bruit des voitures\nS'il s'amuse à faire le mort, c'est qu'il joue avec les statues`, source: `https://genius.com/Orelsan-tout-va-bien-lyrics` }, - { text: `Si la voisine crie très fort, c'est qu'elle a pas bien entendu`, source: `https://genius.com/Orelsan-tout-va-bien-lyrics` }, - { text: `Et si, un jour, ils ont disparu, c'est qu'ils s'amusaient tellement bien\nQu'ils sont partis loin faire une ronde, tous en treillis, main dans la main`, source: `https://genius.com/Orelsan-tout-va-bien-lyrics` }, - { text: `On trinque à nos balafres, à nos crochets tous les soirs.`, source: `https://genius.com/Booba-92i-veyron-lyrics` }, - { text: `Il me semble que je sombre depuis quelques mois\nTellement sombre que mon ombre est plus claire que moi`, source: `https://genius.com/Nekfeu-energie-sombre-lyrics` }, - { text: `Toute cette émotion fait que je sombre depuis quelques mois\nTellement sombre que mon ombre est plus claire que moi`, source: `https://genius.com/Nekfeu-energie-sombre-lyrics` }, - { text: `J'te préfère avec une balle dans la tête au moins j't'écouterai plus raconter ta vie`, source: `https://genius.com/Damso-javais-juste-envie-decrire-lyrics` }, - { text: `J'suis tellement loin que même les bruits qui courent se sont arrêtés`, source: `https://genius.com/Damso-javais-juste-envie-decrire-lyrics` }, - { text: `La voix de la sagesse est muette, elle parle en langage des signes`, source: `https://genius.com/Damso-javais-juste-envie-decrire-lyrics` }, - { text: `Sentiments égarés, on sourit pour ne pas pleurer`, source: `https://genius.com/Damso-silence-lyrics` }, - { text: `On s'oublie pour ne plus s'aimer, cherche la perfection pour fuir la réalité`, source: `https://genius.com/Damso-silence-lyrics` }, - { text: `Le vrai problème, c'est qu'à chaque fois qu'c'est le même problème`, source: `https://genius.com/Damso-silence-lyrics` }, - { text: `Je ne vois plus que des clones, ça a commencé à l'école\nÀ qui tu donnes de l'épaule pour t'en sortir ?`, source: `https://genius.com/Nekfeu-nique-les-clones-part-ii-lyrics` }, - { text: `Ici, tout l'monde joue des rôles en rêvant du million d'euros\nEt j'ai poussé comme une rose parmi les orties`, source: `https://genius.com/Nekfeu-nique-les-clones-part-ii-lyrics` }, - { text: `T'es malheureux quand t'as qu'un rêve et que tes parents ne veulent pas`, source: `https://genius.com/Nekfeu-nique-les-clones-part-ii-lyrics` }, - { text: `Non, je n'aime pas quand je me promène et que je vois\nCe petit qui se fait traquer pour des problèmes de poids`, source: `https://genius.com/Nekfeu-nique-les-clones-part-ii-lyrics` }, - { text: `T'as tes propres codes, t'as ta propre mode\nT'es tellement unique et ça c'est tout pour moi`, source: `https://genius.com/Luidji-pour-deux-ames-solitaires-part-1-lyrics` }, - { text: `Tu m'conseilles des séries, tu m'conseilles des films\nMais j'veux plus d'conseils, j'veux qu'on les mate ensemble`, source: `https://genius.com/Luidji-pour-deux-ames-solitaires-part-1-lyrics` }, - { text: `Tu réfléchis comme moi, souvent t'agis comme moi\nJ't'ai vu parler, penser, aimer\nJ't'ai vu rêver comme moi`, source: `https://genius.com/Luidji-pour-deux-ames-solitaires-part-1-lyrics` }, - { text: `Je me pose des questions sur le destin\nJe suis mon psy, ouais, mon propre médecin`, source: `https://genius.com/Luidji-pour-deux-ames-solitaires-part-2-lyrics` }, - { text: `Peut-être qu'elle se sert de moi pour oublier son ex hein\nMais j'me suis servi d'elle pour terminer mon texte hein`, source: `https://genius.com/Luidji-pour-deux-ames-solitaires-part-2-lyrics` }, - { text: `Maintenant j'suis tellement sûr de moi\nChaque fois que j'l'ouvre j'ai l'impression d'me vendre`, source: `https://genius.com/Luidji-pour-deux-ames-solitaires-part-2-lyrics` }, - { text: `J'avais trop de doutes et de questionnements, de motivations, de fréquentations\nMais j'ai médité assez longtemps`, source: `https://genius.com/Luidji-pour-deux-ames-solitaires-part-2-lyrics` }, - { text: `Ton corps m'inspire, fais ta valise, on s'tire`, source: `https://genius.com/Jokair-las-vegas-lyrics` }, - { text: `C'est comme ça, aucune meuf sur terre ne pourra m'changer\nTu n'es pas la première personne à avoir essayé`, source: `https://genius.com/Jokair-las-vegas-lyrics` }, - { text: `Pardonne-moi si j'suis une personne trop dure à aimer`, source: `https://genius.com/Jokair-las-vegas-lyrics` }, - { text: `J'accélère, on a la tête posée sur l'appuie-tête\nToute la nuit, les pneus brûlent sur la route 66`, source: `https://genius.com/Jokair-las-vegas-lyrics` }, - { text: `Au retour, mes draps avaient encore son odeur\nDur d'effacer nos souvenirs de ma tête`, source: `https://genius.com/Jokair-nos-souvenirs-lyrics` }, + { text: "L'Homme est ci, l'Homme est ça, mais quand il commet l'homicide, l'Homme est sale.", source: "https://genius.com/Lefa-fils-dadam-lyrics" }, + { text: "C'est bien beau de tourner des clips sur des yachts ou en hélico, ça c'est l'image, mais vos sons ont toujours besoin de soins médicaux.", source: "https://genius.com/Lefa-plus-ltime-lyrics" }, + { text: "Il y aura du ciment sur mes mains pour bâtir ton avenir. Il y aura du sang sur mes mains si un homme te fait souffrir.", source: "https://genius.com/Soprano-je-serai-la-lyrics" }, + { text: "Je n'ai pas révélé la moitié de ce que j'ai vu, car je savais qu'on ne me croirait pas...", source: "https://citation-celebre.leparisien.fr/citations/271852" }, + { text: "Tu étais formidable, j'étais fort minable\nNous étions formidables", source: "https://genius.com/Stromae-formidable-lyrics" }, + { text: "Cette fois c'était la dernière, tu peux croire que c'est qu'une crise.", source: "https://genius.com/Stromae-tous-les-memes-lyrics" }, + { text: "Simius n'avait pas entendu, mais ses pensées cheminaient dans la même direction. Ils arrivaient aux premiers tombeaux de la nécropole. La porte sud de la ville.", source: null }, + { text: "Pourquoi tu veux me mettre un bébé dans les bras ? J'ai déjà du mal à m'occuper de moi.", source: "https://genius.com/Orelsan-san-lyrics" }, + { text: "Dans ce rap biz\nOn est arrivé les mains dans les poches\nA l'époque c'était \"envoie le beat\"\nOn fait le truc à l'arrache", source: "https://genius.com/Sniper-grave-dans-la-roche-lyrics" }, + { text: "Garde le sourire, plus rien n'est grave\nTant qu'il nous reste une seconde de souvenir dans le crâne", source: "https://genius.com/Lomepal-trop-beau-lyrics" }, + { text: "Ne fais pas ta joie du malheur d'autrui.\nIl n'est pas permis de blesser un ami, même en plaisantant.", source: null }, + { text: "Je me sentais moins seule quand je ne te connaissais pas encore : j'attendais l'autre. Je ne pensais qu'à sa force et jamais à ma faiblesse.", source: "https://www.dicocitations.com/citations/citation-25293.php" }, + { text: "Qui dit études dit travail, qui dit taf te dit tes thunes, qui dit argent dit dépenses, qui dit crédit dit créance, qui dit dette te dit huissier.", source: "https://genius.com/Stromae-alors-on-danse-lyrics" }, + { text: "Et là tu t'dis que c'est fini\nCar pire que ça, ce serait la mort\nQuand tu crois enfin qu'tu t'en sors\nQuand y en a plus, et bah y en a encore", source: "https://genius.com/Stromae-alors-on-danse-lyrics" }, + { text: "Donnez-moi une suite au Ritz, je n'en veux pas ! Des bijoux de chez Chanel, je n'en veux pas ! Donnez-moi une limousine, j'en ferais quoi ?", source: "https://genius.com/Zaz-je-veux-lyrics" }, + { text: "Elle m'a aimé de tout son amour, de tout son coeur. Elle m'a donné tout ce qu'elle avait quand je n'étais rien.", source: "https://genius.com/Kendji-girac-elle-ma-aime-lyrics " }, + { text: "Ma raison somnolait, ma conscience me conseillait, mon subconscient m'déconseillait, mais mon esprit veut s'envoler.", source: "https://genius.com/Gims-zombie-lyrics" }, + { text: "J'ai la colère des p'tits à qui on demande de choisir d'un coup leur métier, qui a conseillé la conseillère d'orientation ?", source: "https://genius.com/Nekfeu-humanoide-lyrics" }, + { text: "Obligé d's'enterrer dans l'son, trouver une putain d'raison d'vivre\nJ'ai frappé dans les murs, mais ça résonne vide", source: "https://genius.com/Nekfeu-humanoide-lyrics" }, + { text: "Un jour, ils ont commencé à menacer ma mif\nAlors je me suis armé par le biais d'un ami\nMais, Dieu merci, j'm'en suis jamais servi", source: "https://genius.com/Nekfeu-mauvaise-graine-lyrics" }, + { text: "Aventurier de l'inconnu, avant tu riais de l'inconnu\nAvant tu riais du temps qui passe, et puis le temps est passé", source: "https://genius.com/Nekfeu-avant-tu-riais-lyrics" }, + { text: "Ils disent que l'amour rend aveugle, mais il t'a redonné la vue\nIl t'a fait muer quand ta rage était sourde, il a fait fredonner la rue\nIl t'a fait retirer le collier de chien qui te servait d'écharpe", source: "https://genius.com/Nekfeu-avant-tu-riais-lyrics" }, + { text: "Des Hommes de face désormais néfastes\nDes zones désolées, des hommes et des femmes\nTu te sens d'aucun des clans", source: "https://genius.com/Nekfeu-avant-tu-riais-lyrics" }, + { text: "Ce soir, j'me mets minable, pourquoi j'me fais si mal ?\nJ'ai fait des rêves bizarres où tu changeais d'visage", source: "https://genius.com/Orelsan-reves-bizarres-lyrics" }, + { text: "Ce soir, on ira faire un tour chez l'épicier ouvert en bas\nEt on parlera d'amour, entassés sur une véranda", source: "https://genius.com/Nekfeu-on-verra-lyrics" }, + { text: "Combien d'fois j'ai volé par flemme de faire la queue ?", source: "https://genius.com/Nekfeu-on-verra-lyrics" }, + { text: "Putain, bien sûr que j'me sens banane comme si le paradise m'avait mal accueilli\nJ'aimerais tellement que tu m'appelles juste pour pouvoir te raccrocher à la gueule", source: "https://genius.com/Lefa-paradise-lyrics" }, + { text: "Le monde est à nous, le monde est à toi et moi", source: "https://genius.com/Damso-macarena-lyrics" }, + { text: "Il fait le mec mature mais tu sais qu'au lit, plus que lui, j'assure", source: "https://genius.com/Damso-macarena-lyrics" }, + { text: "Quand t'as démarré, qu't'es allée chez lui ben nan, j'ai rien dit\nPourtant, j'le savais qu'tu baisais pour t'évader, après tout, j''tais là qu'pour dépanner", source: "https://genius.com/Damso-macarena-lyrics" }, + { text: "J'vais pas trop m'étaler, saigner fallait, blessé j'l'étais, j't'ai remballé, tu m'as remplacé, tu m'as délaissé", source: "https://genius.com/Damso-macarena-lyrics" }, + { text: "À la base, j'ai commencé la musique juste pour voir\nJ'étais très différent de ceux qui cherchent plus de pouvoir\nJ'm'amusais à tester les plus grands qu'moi juste pour voir", source: "https://genius.com/Spri-noir-juste-pour-voir-lyrics" }, + { text: "Juste pour voir, viens faire un tour dans nos têtes", source: "https://genius.com/Spri-noir-juste-pour-voir-lyrics" }, + { text: "Si le monsieur dort dehors, c'est qu'il aime le bruit des voitures\nS'il s'amuse à faire le mort, c'est qu'il joue avec les statues", source: "https://genius.com/Orelsan-tout-va-bien-lyrics" }, + { text: "Si la voisine crie très fort, c'est qu'elle a pas bien entendu", source: "https://genius.com/Orelsan-tout-va-bien-lyrics" }, + { text: "Et si, un jour, ils ont disparu, c'est qu'ils s'amusaient tellement bien\nQu'ils sont partis loin faire une ronde, tous en treillis, main dans la main", source: "https://genius.com/Orelsan-tout-va-bien-lyrics" }, + { text: "On trinque à nos balafres, à nos crochets tous les soirs.", source: "https://genius.com/Booba-92i-veyron-lyrics" }, + { text: "Il me semble que je sombre depuis quelques mois\nTellement sombre que mon ombre est plus claire que moi", source: "https://genius.com/Nekfeu-energie-sombre-lyrics" }, + { text: "Toute cette émotion fait que je sombre depuis quelques mois\nTellement sombre que mon ombre est plus claire que moi", source: "https://genius.com/Nekfeu-energie-sombre-lyrics" }, + { text: "J'te préfère avec une balle dans la tête au moins j't'écouterai plus raconter ta vie", source: "https://genius.com/Damso-javais-juste-envie-decrire-lyrics" }, + { text: "J'suis tellement loin que même les bruits qui courent se sont arrêtés", source: "https://genius.com/Damso-javais-juste-envie-decrire-lyrics" }, + { text: "La voix de la sagesse est muette, elle parle en langage des signes", source: "https://genius.com/Damso-javais-juste-envie-decrire-lyrics" }, + { text: "Sentiments égarés, on sourit pour ne pas pleurer", source: "https://genius.com/Damso-silence-lyrics" }, + { text: "On s'oublie pour ne plus s'aimer, cherche la perfection pour fuir la réalité", source: "https://genius.com/Damso-silence-lyrics" }, + { text: "Le vrai problème, c'est qu'à chaque fois qu'c'est le même problème", source: "https://genius.com/Damso-silence-lyrics" }, + { text: "Je ne vois plus que des clones, ça a commencé à l'école\nÀ qui tu donnes de l'épaule pour t'en sortir ?", source: "https://genius.com/Nekfeu-nique-les-clones-part-ii-lyrics" }, + { text: "Ici, tout l'monde joue des rôles en rêvant du million d'euros\nEt j'ai poussé comme une rose parmi les orties", source: "https://genius.com/Nekfeu-nique-les-clones-part-ii-lyrics" }, + { text: "T'es malheureux quand t'as qu'un rêve et que tes parents ne veulent pas", source: "https://genius.com/Nekfeu-nique-les-clones-part-ii-lyrics" }, + { text: "Non, je n'aime pas quand je me promène et que je vois\nCe petit qui se fait traquer pour des problèmes de poids", source: "https://genius.com/Nekfeu-nique-les-clones-part-ii-lyrics" }, + { text: "T'as tes propres codes, t'as ta propre mode\nT'es tellement unique et ça c'est tout pour moi", source: "https://genius.com/Luidji-pour-deux-ames-solitaires-part-1-lyrics" }, + { text: "Tu m'conseilles des séries, tu m'conseilles des films\nMais j'veux plus d'conseils, j'veux qu'on les mate ensemble", source: "https://genius.com/Luidji-pour-deux-ames-solitaires-part-1-lyrics" }, + { text: "Tu réfléchis comme moi, souvent t'agis comme moi\nJ't'ai vu parler, penser, aimer\nJ't'ai vu rêver comme moi", source: "https://genius.com/Luidji-pour-deux-ames-solitaires-part-1-lyrics" }, + { text: "Je me pose des questions sur le destin\nJe suis mon psy, ouais, mon propre médecin", source: "https://genius.com/Luidji-pour-deux-ames-solitaires-part-2-lyrics" }, + { text: "Peut-être qu'elle se sert de moi pour oublier son ex hein\nMais j'me suis servi d'elle pour terminer mon texte hein", source: "https://genius.com/Luidji-pour-deux-ames-solitaires-part-2-lyrics" }, + { text: "Maintenant j'suis tellement sûr de moi\nChaque fois que j'l'ouvre j'ai l'impression d'me vendre", source: "https://genius.com/Luidji-pour-deux-ames-solitaires-part-2-lyrics" }, + { text: "J'avais trop de doutes et de questionnements, de motivations, de fréquentations\nMais j'ai médité assez longtemps", source: "https://genius.com/Luidji-pour-deux-ames-solitaires-part-2-lyrics" }, + { text: "Ton corps m'inspire, fais ta valise, on s'tire", source: "https://genius.com/Jokair-las-vegas-lyrics" }, + { text: "C'est comme ça, aucune meuf sur terre ne pourra m'changer\nTu n'es pas la première personne à avoir essayé", source: "https://genius.com/Jokair-las-vegas-lyrics" }, + { text: "Pardonne-moi si j'suis une personne trop dure à aimer", source: "https://genius.com/Jokair-las-vegas-lyrics" }, + { text: "J'accélère, on a la tête posée sur l'appuie-tête\nToute la nuit, les pneus brûlent sur la route 66", source: "https://genius.com/Jokair-las-vegas-lyrics" }, + { text: "Au retour, mes draps avaient encore son odeur\nDur d'effacer nos souvenirs de ma tête", source: "https://genius.com/Jokair-nos-souvenirs-lyrics" }, ] // Exporter certaines fonctions module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('typeracer') - .setDescription(`Défie un membre du serveur à un duel d'écriture`) + .setName("typeracer") + .setDescription("Défie un membre du serveur à un duel d'écriture") .setDMPermission(false) - .addUserOption(option => option.setName('user') - .setDescription('Adversaire à défier') + .addUserOption(option => option.setName("user") + .setDescription("Adversaire à défier") .setRequired(true)), // Définir les infos du menu contextuel contextInfo: new ContextMenuCommandBuilder() - .setName("Défier sur typeracer") - .setType(ApplicationCommandType.User), + .setName("Défier sur typeracer") + .setType(ApplicationCommandType.User), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Obtenir l'adversaire - var opponent = await interaction.options.getUser('user') + var opponent = await interaction.options.getUser("user") var opponentMention = `<@${opponent?.id}>` // Empêcher la mention de certains types de personnes - if(!opponent || !opponent.id) return interaction.reply({ content: `Tu dois mentionner un utilisateur valide !`, ephemeral: true }) - if(opponent.bot) return interaction.reply({ content: `Beep boop, il n'est pas possible de défier un robot...`, ephemeral: true }) - if(opponent.id == interaction.user.id) return interaction.reply({ content: `Tu ne peux pas défier toi-même, ça serait trop simple 🙃`, ephemeral: true }) + if(!opponent || !opponent.id) return interaction.reply({ content: "Tu dois mentionner un utilisateur valide !", ephemeral: true }) + if(opponent.bot) return interaction.reply({ content: "Beep boop, il n'est pas possible de défier un robot...", ephemeral: true }) + if(opponent.id == interaction.user.id) return interaction.reply({ content: "Tu ne peux pas défier toi-même, ça serait trop simple 🙃", ephemeral: true }) // Générer un embed const embed = new EmbedBuilder() - .setTitle("Demande de duel d'écriture") - .setDescription(`${opponentMention}, **${interaction.user.discriminator == '0' ? escape(interaction.user.username) : escape(interaction.user.tag)}** vous défie à un duel d'écriture !\n\nUn texte sera envoyé, le premier à le recopier et l'envoyer dans ce salon deviendra vainqueur !`) - .setFooter({ text: "Vous avez 30 secondes pour accepter cette demande" }) - .setColor(config.getValue('bachero', 'embedColor')) + .setTitle("Demande de duel d'écriture") + .setDescription(`${opponentMention}, **${interaction.user.discriminator == "0" ? escape(interaction.user.username) : escape(interaction.user.tag)}** vous défie à un duel d'écriture !\n\nUn texte sera envoyé, le premier à le recopier et l'envoyer dans ce salon deviendra vainqueur !`) + .setFooter({ text: "Vous avez 30 secondes pour accepter cette demande" }) + .setColor(colors.primary) // Créé des boutons var date = Date.now() const row = new ActionRowBuilder().addComponents( new ButtonBuilder() - .setCustomId(`typeracer-accept-${date}`) - .setStyle(ButtonStyle.Success) - .setLabel('Accepter'), + .setCustomId(`typeracer-accept-${date}`) + .setStyle(ButtonStyle.Success) + .setLabel("Accepter"), new ButtonBuilder() - .setCustomId(`typeracer-deny-${date}`) - .setStyle(ButtonStyle.Danger) - .setLabel('Refuser'), + .setCustomId(`typeracer-deny-${date}`) + .setStyle(ButtonStyle.Danger) + .setLabel("Refuser"), ) // Envoyer l'embed - if(await interaction.reply({ embeds: [embed], components: [row] }).catch(err => { return 'stop' }) == 'stop') return + if(await interaction.reply({ embeds: [embed], components: [row] }).catch(err => { return "stop" }) == "stop") return // Quand quelqu'un clique sur le bouton const filter = inte => inte.user.id == opponent.id && (inte.customId == `typeracer-accept-${date}` || inte.customId == `typeracer-deny-${date}`) const collector = interaction.channel.createMessageComponentCollector({ componentType: ComponentType.Button, filter, time: 30000 }) - collector.on('collect', async inte => { + collector.on("collect", async inte => { // Arrêter le collecteur collector.stop() @@ -129,41 +129,41 @@ module.exports = { if(inte.customId == `typeracer-deny-${date}`) return interaction.editReply({ embeds: [embed.setDescription(`La demande de duel a été refusé par ${opponentMention} !`).setFooter({ text: null })], components: [] }).catch(err => {}) // Sinon, on dit que la demande a été accepté - interaction.editReply({ embeds: [embed.setDescription(`Demande de duel accepté, la partie va débuter dans quelques instants...`).setFooter({ text: null })], components: [] }).catch(err => {}) + interaction.editReply({ embeds: [embed.setDescription("Demande de duel accepté, la partie va débuter dans quelques instants...").setFooter({ text: null })], components: [] }).catch(err => {}) // Générer un texte à partir d'une liste var phrase = rando(listPhrases).value - + // Faire une copie du texte avec un caractère invisible tous les deux caractères par mot (ça évite le copier coller) - var phraseAntiCP = '' - var phraseSplited = phrase.text.split('') - var invisibleChars = ['\u200B', '\u200C', '\u200D', '\u2060', '\uFEFF'] + var phraseAntiCP = "" + var phraseSplited = phrase.text.split("") + var invisibleChars = ["\u200B", "\u200C", "\u200D", "\u2060", "\uFEFF"] for(var i = 0; i < phraseSplited.length; i++){ phraseAntiCP += phraseSplited[i] if(i % 2 == 0) phraseAntiCP += rando(invisibleChars).value } // Envoyer le message - await interaction.editReply({ embeds: [embed.setTitle(`${interaction.user.username} VS ${opponent.username}`).setDescription(`> ${phraseAntiCP.replaceAll('\n', '\n> ')}`).setColor(config.getValue('bachero', 'secondEmbedColor'))] }).catch(err => {}) + await interaction.editReply({ embeds: [embed.setTitle(`${interaction.user.username} VS ${opponent.username}`).setDescription(`> ${phraseAntiCP.replaceAll("\n", "\n> ")}`).setColor(colors.secondary)] }).catch(err => {}) var dateStartGame = Date.now() // Attendre une réponse var messageToDelete = [] const filter2 = m => m.author.id == interaction.user.id || m.author.id == opponent.id const collector2 = interaction.channel.createMessageCollector({ filter2, time: 120000 }) - collector2.on('collect', async m => { + collector2.on("collect", async m => { // Si l'auteur de ce message n'avait pas encore répondu if(collector2.collected.filter(msg => msg.author.id == m.author.id).size == 1){ - if(collector2.collected.size == 1) m.react('✅').catch(err => {}) + if(collector2.collected.size == 1) m.react("✅").catch(err => {}) messageToDelete.push(m) } // Si les deux joueurs ont répondus if(collector2.collected.filter(m => m.author.id == interaction.user.id).size > 0 && collector2.collected.filter(m => m.author.id == opponent.id).size > 0) collector2.stop() }) - collector2.on('end', async (collected, reason) => { + collector2.on("end", async (collected, reason) => { // Si le temps est écoulé - if(reason == 'time') interaction.editReply({ embeds: [new EmbedBuilder().setTitle("Duel d'écriture").setDescription(`La partie vient de se terminer après deux minutes en raison d'une inactivité. Aucun vainqueur n'a pu être désigné.`).setColor(config.getValue('bachero', 'embedColor'))] }).catch(err => {}) + if(reason == "time") interaction.editReply({ embeds: [new EmbedBuilder().setTitle("Duel d'écriture").setDescription("La partie vient de se terminer après deux minutes en raison d'une inactivité. Aucun vainqueur n'a pu être désigné.").setColor(colors.primary)] }).catch(err => {}) // Sinon, on calcule la vitesse de chaque joueur else { @@ -176,34 +176,34 @@ module.exports = { var taken2 = parseFloat(((message2.createdTimestamp - dateStartGame) / 1000).toFixed(2)) // Modifier le contenu des messages pour remplacer les caractères invisibles - message1.content = message1.content.replace(/[\u200B\u200C\u200D\u2060\uFEFF]/g, '*') - message2.content = message2.content.replace(/[\u200B\u200C\u200D\u2060\uFEFF]/g, '*') + message1.content = message1.content.replace(/[\u200B\u200C\u200D\u2060\uFEFF]/g, "*") // eslint-disable-line + message2.content = message2.content.replace(/[\u200B\u200C\u200D\u2060\uFEFF]/g, "*") // eslint-disable-line // Déterminer le nombre d'erreurs dans le texte - var errors1 = diffWords(message1.content.replace(/[^a-zA-Z0-9\*', çéêèà]/g, ''), phrase.text.replace(/[^a-zA-Z0-9', çéêèà\*]/g, ''), { ignoreCase: true }).length - 1 - var errors2 = diffWords(message2.content.replace(/[^a-zA-Z0-9\*', çéêèà]/g, ''), phrase.text.replace(/[^a-zA-Z0-9', çéêèà\*]/g, ''), { ignoreCase: true }).length - 1 + var errors1 = diffWords(message1.content.replace(/[^a-zA-Z0-9\*', çéêèà]/g, ""), phrase.text.replace(/[^a-zA-Z0-9', çéêèà\*]/g, ""), { ignoreCase: true }).length - 1 // eslint-disable-line + var errors2 = diffWords(message2.content.replace(/[^a-zA-Z0-9\*', çéêèà]/g, ""), phrase.text.replace(/[^a-zA-Z0-9', çéêèà\*]/g, ""), { ignoreCase: true }).length - 1 // eslint-disable-line // Calculer un score en fonction du temps et du nombre d'erreurs - var score1 = parseFloat((taken1 + errors1 * 2).toFixed(2)) - var score2 = parseFloat((taken2 + errors2 * 2).toFixed(2)) + var score1 = parseFloat((taken1 + (errors1 * 2)).toFixed(2)) + var score2 = parseFloat((taken2 + (errors2 * 2)).toFixed(2)) // Déterminer le vainqueur - var winner = 'personne (égalité)' + var winner = "personne (égalité)" if(score1 < score2) winner = message1.author else if(score2 < score1) winner = message2.author // Construire un embed var embed = new EmbedBuilder() - .setTitle("Duel d'écriture") - .setDescription(`:tada: Victoire de **${winner}** !\n\n• ${message1.author} : ${taken1} secondes, ${errors1} erreur${errors1 > 1 ? 's' : ''}, ${score1} points\n• ${message2.author} : ${taken2} secondes, ${errors2} erreur${errors2 > 1 ? 's' : ''}, ${score2} points.`) - .setColor(config.getValue('bachero', 'embedColor')) - .setFooter({ text: phrase.source ? "Les résultats peuvent différer de la réalité en raison de latence avec Discord" : "Impossible de trouver la source de ce texte" }) + .setTitle("Duel d'écriture") + .setDescription(`:tada: Victoire de **${winner}** !\n\n• ${message1.author} : ${taken1} secondes, ${errors1} erreur${errors1 > 1 ? "s" : ""}, ${score1} points\n• ${message2.author} : ${taken2} secondes, ${errors2} erreur${errors2 > 1 ? "s" : ""}, ${score2} points.`) + .setColor(colors.primary) + .setFooter({ text: phrase.source ? "Les résultats peuvent différer de la réalité en raison de latence avec Discord" : "Impossible de trouver la source de ce texte" }) // Créer un bouton var button = new ButtonBuilder() - .setURL(phrase.source || 'https://bachero.johanstick.me/404') - .setStyle(ButtonStyle.Link) - .setLabel('Source de la citation') + .setURL(phrase.source || "https://bachero.johanstick.fr/404") + .setStyle(ButtonStyle.Link) + .setLabel("Source de la citation") if(!phrase.source) button.setDisabled() // Modifier l'interaction @@ -214,8 +214,8 @@ module.exports = { } }) }) - collector.on('end', async (collected, reason) => { - if(reason == 'time') interaction.editReply({ embeds: [embed.setDescription(`Aucune réponse de la part de ${opponentMention}, la demande de duel a expiré automatiquement.`).setFooter({ text: null })], components: [] }).catch(err => {}) + collector.on("end", async (collected, reason) => { + if(reason == "time") interaction.editReply({ embeds: [embed.setDescription(`Aucune réponse de la part de ${opponentMention}, la demande de duel a expiré automatiquement.`).setFooter({ text: null })], components: [] }).catch(err => {}) }) } } \ No newline at end of file diff --git a/modules/bachero.module.unshort/manifest.jsonc b/modules/bachero.module.unshort/manifest.jsonc index 9b5ce41..3e66462 100644 --- a/modules/bachero.module.unshort/manifest.jsonc +++ b/modules/bachero.module.unshort/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Prélève l'URL originale à partir de n'importe quel lien raccourci", - "longDescription": "Ajoute une commande permettant d'obtenir le lien originel à partir de n'importe quel lien raccourci, y compris Grabify.", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.unshort/unshort.js b/modules/bachero.module.unshort/unshort.js index 23f29cd..d615ea8 100644 --- a/modules/bachero.module.unshort/unshort.js +++ b/modules/bachero.module.unshort/unshort.js @@ -1,37 +1,36 @@ -const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js') -const bacheroFunctions = require('../../functions') -const fetch = require('node-fetch') -const escape = require('markdown-escape') +const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js") +const bacheroFunctions = require("../../functions") +const fetch = require("node-fetch") +const escape = require("markdown-escape") module.exports = { // Définir les infos de la commande slash slashInfo: new SlashCommandBuilder() - .setName('unshort') + .setName("unshort") .setDescription("Obtient l'URL originale d'un lien raccourci") - .addStringOption(option => option.setName('url') + .addStringOption(option => option.setName("url") .setDescription("URL à déracourcir (si non spécifié, le bot va déracourcir le dernier message ou celui en réponse)") - .setRequired(false) - ), + .setRequired(false)), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Mettre la réponse en defer - if(await interaction.deferReply({ ephemeral: interaction.guildId ? true : false }).catch(err => { return 'stop' }) == 'stop') return + if(await interaction.deferReply({ ephemeral: !!interaction.guildId }).catch(err => { return "stop" }) == "stop") return // Si c'est une commande texte, tenter de supprimer le message d'invocation - if(interaction.sourceType == 'textCommand'){ + if(interaction.sourceType == "textCommand"){ try { interaction.delete().catch(err => {}) } catch(err) {} // Le choix de la sécurité } // Obtenir le terme de recherche - var query = interaction.options.getString('url') + var query = interaction.options.getString("url") // Si on a pas de terme de recherche, on va chercher le dernier message ou celui en réponse if(!query){ // Chercher le message auquel on répond if(interaction?.reference?.messageId){ var repliedTo = await interaction.channel.messages.fetch(interaction.reference.messageId).catch(err => {}) - if(repliedTo.content.includes('https://') || repliedTo.content.includes('http://')) query = repliedTo.content + if(repliedTo.content.includes("https://") || repliedTo.content.includes("http://")) query = repliedTo.content } // Sinon, on prend le dernier message @@ -39,49 +38,47 @@ module.exports = { query = await interaction.channel.messages.fetch({ limit: 1, before: interaction.id }).catch(err => {}) query = query.first() query = query.content - if(!query.includes('https://') && !query.includes('http://')) query = undefined + if(!query.includes("https://") && !query.includes("http://")) query = undefined } } // Si on a toujours pas de terme de recherche, on affiche une erreur if(!query) return interaction.editReply("Pour utiliser cette commande, vous devez inclure l'argument `url` dans votre commande, ou répondre à un message contenant un lien (ne fonctionne pas via les commandes slash).").catch(err => {}) - if(!query.includes('https://') && !query.includes('http://')) return interaction.editReply("L'URL obtenu ne semble pas être un lien valide.").catch(err => {}) + if(!query.includes("https://") && !query.includes("http://")) return interaction.editReply("L'URL obtenu ne semble pas être un lien valide.").catch(err => {}) // Obtenir l'URL originale - var unshortened = await fetch('https://unshort-api.vercel.app', { method: 'POST', body: JSON.stringify({ link: query }), headers: { 'User-Agent': 'BacheroBot (+https://github.com/bacherobot/bot)' } }).then(res => res.json()).catch(err => { return { fetcherror: err } }) + var unshortened = await fetch("https://unshort-api.vercel.app", { method: "POST", body: JSON.stringify({ link: query }), headers: { "User-Agent": "BacheroBot (+https://github.com/bacherobot/bot)" } }).then(res => res.json()).catch(err => { return { fetcherror: err } }) // Si on a une erreur if(unshortened.fetcherror) return await bacheroFunctions.report.createAndReply("requête vers l'API d'Unshort", unshortened.fetcherror || unshortened.error || unshortened.message, {}, interaction) else if(unshortened.error || unshortened.statusCode) return interaction.editReply(unshortened.message || unshortened.error || unshortened.statusCode).catch(err => {}) // Obtenir les métadonnées - var meta_title = unshortened?.metadata?.find(a => a.name == 'title')?.content - var meta_description = unshortened?.metadata?.find(a => a.name == 'description')?.content - var meta_image = unshortened?.metadata?.find(a => a.name == 'image')?.content + var meta_title = unshortened?.metadata?.find(a => a.name == "title")?.content + var meta_description = unshortened?.metadata?.find(a => a.name == "description")?.content + var meta_image = unshortened?.metadata?.find(a => a.name == "image")?.content // Créer l'embed var embed = new EmbedBuilder() - .setTitle("Résultat de l'analyse") - .addFields([ - { name: 'Raccourci', value: unshortened.url || query, inline: true }, - { name: 'Originale', value: unshortened.redirected, inline: true }, - meta_title ? { name: 'Titre', value: escape(meta_title) || 'Aucun titre trouvé', inline: true } : undefined, - meta_description ? { name: 'Description', value: escape(meta_description) || 'Aucune description trouvée', inline: true } : undefined, - ].filter(Boolean)) - .setColor(unshortened.safe ? bacheroFunctions.config.getValue('bachero', 'embedColor') : bacheroFunctions.config.getValue('bachero', 'secondEmbedColor')) - .setFooter({ text: `Sous la demande de ${interaction.user.discriminator == '0' ? interaction.user.username : interaction.user.tag}` }) + .setTitle("Résultat de l'analyse") + .addFields([ + { name: "Raccourci", value: escape(unshortened.url || query), inline: true }, + { name: "Originale", value: escape(unshortened.redirected), inline: true }, + meta_title ? { name: "Titre", value: escape(meta_title) || "Aucun titre trouvé", inline: true } : undefined, + meta_description ? { name: "Description", value: escape(meta_description) || "Aucune description trouvée", inline: true } : undefined, + ].filter(Boolean)) + .setColor(unshortened.safe ? bacheroFunctions.colors.primary : bacheroFunctions.colors.secondary) + .setFooter({ text: `Sous la demande de ${interaction.user.discriminator == "0" ? interaction.user.username : interaction.user.tag}` }) // Ajouter quelques éléments - if(!unshortened.safe) embed.setDescription(`⚠️ La [navigation sécurisée](https://transparencyreport.google.com/safe-browsing/search) de Google a détecté que le lien originel n'est pas sécurisé. Soyez vigilant si vous décidez de cliquer sur ce lien.`) + if(!unshortened.safe) embed.setDescription("⚠️ La [navigation sécurisée](https://transparencyreport.google.com/safe-browsing/search) de Google a détecté que le lien originel n'est pas sécurisé. Soyez vigilant si vous décidez de cliquer sur ce lien.") if(meta_image) embed.setImage(meta_image) // Créer un bouton - var row = new ActionRowBuilder().addComponents( - new ButtonBuilder() + var row = new ActionRowBuilder().addComponents(new ButtonBuilder() .setURL(unshortened.redirected) .setStyle(ButtonStyle.Link) - .setLabel(`Visiter la page`) - ) + .setLabel("Visiter la page")) // Envoyer l'embed interaction.editReply({ embeds: [embed], components: [unshortened.safe ? row : undefined].filter(Boolean) }).catch(err => {}) diff --git a/modules/bachero.module.userinfo/avatar.js b/modules/bachero.module.userinfo/avatar.js index 5a59646..4bf3057 100644 --- a/modules/bachero.module.userinfo/avatar.js +++ b/modules/bachero.module.userinfo/avatar.js @@ -1,5 +1,5 @@ const { SlashCommandBuilder, EmbedBuilder, ContextMenuCommandBuilder, ApplicationCommandType } = require("discord.js") -const { config } = require("../../functions") +const { colors } = require("../../functions") const escape = require("markdown-escape") // Exporter certaines fonctions @@ -17,7 +17,7 @@ module.exports = { .setName("Afficher la photo") .setType(ApplicationCommandType.User), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Mettre la réponse en defer if(await interaction.deferReply().catch(err => { return "stop" }) == "stop") return @@ -37,7 +37,7 @@ module.exports = { var embed = new EmbedBuilder() .setTitle(`${user?.globalName ? user.globalName : ""} ${user?.globalName ? "(" : ""}${user?.discriminator == "0" ? `@${user?.username}` : escape(user?.tag)}${user?.globalName ? ")" : ""}`) .setDescription(`[Lien direct vers la photo de profil](${avatar})${user.banner ? `\n[Lien direct vers la bannière](${user.banner})` : ""}`) - .setColor(config.getValue("bachero", "embedColor")) + .setColor(colors.primary) .setFooter({ text: `${!user.avatar ? "Affichage d'un avatar par défaut • " : ""}Identifiant : ${userId}` }) if(user.banner) embed.setThumbnail(avatar); else embed.setImage(avatar) if(user.banner) embed.setImage(user.banner) diff --git a/modules/bachero.module.userinfo/manifest.jsonc b/modules/bachero.module.userinfo/manifest.jsonc index 2a496dc..9114b1c 100644 --- a/modules/bachero.module.userinfo/manifest.jsonc +++ b/modules/bachero.module.userinfo/manifest.jsonc @@ -7,10 +7,6 @@ // Description du module "shortDescription": "Ajoute la possibilité d'obtenir des informations sur un utilisateur", - "longDescription": "Permet d'obtenir des informations sur un utilisateur avec une commande, se sert également d'API externe pour être plus complet", - - // Message affiché lorsque le module finit de charger (recommandé de laisser vide) - "onloadMessage": "", // Source (par exemple, lien du module sur GitHub), "source": "https://github.com/bacherobot/bot", diff --git a/modules/bachero.module.userinfo/userinfo.js b/modules/bachero.module.userinfo/userinfo.js index a5230af..3fee17d 100644 --- a/modules/bachero.module.userinfo/userinfo.js +++ b/modules/bachero.module.userinfo/userinfo.js @@ -1,5 +1,5 @@ const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, ComponentType, ContextMenuCommandBuilder, ApplicationCommandType } = require("discord.js") -const { config, report } = require("../../functions") +const { config, report, colors } = require("../../functions") const alwaysShowMinimal = config.getValue("bachero.module.userinfo", "alwaysShowMinimal") const disableBadges = config.getValue("bachero.module.userinfo", "disableBadges") const fetchPronouns = config.getValue("bachero.module.userinfo", "fetchPronouns") @@ -27,7 +27,7 @@ module.exports = { .setName("Afficher les infos") .setType(ApplicationCommandType.User), - // Code a executer quand la commande est appelée + // Code à exécuter quand la commande est appelée async execute(interaction){ // Mettre la réponse en defer if(await interaction.deferReply().catch(err => { return "stop" }) == "stop") return @@ -50,7 +50,7 @@ module.exports = { userInfo = userInfo?.advancedInfo || userInfo // Si c'est un bot, obtenir des informations venant d'ElWatch - if(!showMinimal && userInfo.bot) var botInfo = await fetch(`https://api.elwatch.johanstick.me/api/status/${userId}`).then(res => res.json()).catch(err => { return {} }); else var botInfo = {} + if(!showMinimal && userInfo.bot) var botInfo = await fetch(`https://api.elwatch.johanstick.fr/api/status/${userId}`).then(res => res.json()).catch(err => { return {} }); else var botInfo = {} if(botInfo?.error) botInfo = {} if(botInfo?.info) botInfo = botInfo?.info if(botInfo?.username == "Inconnu" && botInfo?.discriminator == "0000") botInfo = {} @@ -91,7 +91,7 @@ module.exports = { // Si c'est un bot, et qu'on a eu des informations depuis ElWatch if(userInfo?.bot && botInfo?.username) row.addComponents(new ButtonBuilder() - .setURL(`https://elwatch.johanstick.me/status/${userId}`) + .setURL(`https://elwatch.johanstick.fr/status/${userId}`) .setStyle(ButtonStyle.Link) .setLabel("Voir sur ElWatch")) @@ -142,7 +142,7 @@ module.exports = { if(userInfo?.badges?.replugged_early) badges.push({ from: "replugged", name: "Utilisateur Replugged de la première heure", emoji: "<:UtilisateurRepluggeddelapremireh:1008809329677320303>", link: "https://replugged.dev/" }) if(userInfo?.badges?.replugged_booster) badges.push({ from: "replugged", name: "Replugged Server Booster", emoji: "<:RepluggedServerBooster:1008809313818660864>", link: "https://replugged.dev/" }) if(userInfo?.badges?.aliucord_contributor) badges.push({ from: "aliucord", name: "Contributeur Aliucord", emoji: "<:ContributeurAliucord:1008809283435118624>", link: "https://github.com/Aliucord/Aliucord" }) // ouais il manque le aliucord développeur mais j'ai pas trouvé l'icône :/ - if(userInfo?.badges?.bachero_ogSupporter) badges.push({ from: "bachero", name: "OG Supporter", emoji: "<:BacheroLogo:1046404634023047240>", link: "https://bachero.johanstick.me" }) + if(userInfo?.badges?.bachero_ogSupporter) badges.push({ from: "bachero", name: "OG Supporter", emoji: "<:BacheroLogo:1046404634023047240>", link: "https://bachero.johanstick.fr" }) if(userInfo?.badges?.custom?.emoji && userInfo?.badges?.custom?.name) badges.push({ from: "discord-whois", emoji: userInfo?.badges?.custom?.emoji, name: userInfo?.badges?.custom?.name }) // Fetch le membre du serveur @@ -160,7 +160,7 @@ module.exports = { // Créé un embed contenant toute les informations var embed = new EmbedBuilder() .setTitle(`${userInfo?.global_name || userInfo?.globalName ? userInfo.global_name || userInfo.globalName : ""} ${userInfo?.global_name || userInfo?.globalName ? "(" : ""}${userInfo?.discriminator == "0" ? `@${userInfo?.username}` : escape(`${userInfo.username}#${userInfo.discriminator}`)}${userInfo?.global_name || userInfo?.globalName ? ")" : ""} ${pronouns?.length ? `*(${escape(pronouns)})*` : ""}`) - .setColor(config.getValue("bachero", "embedColor")) + .setColor(colors.primary) if(!showMinimal) embed.setFooter({ text: `Informations obtenues via Discord WhoIs${userInfo?.bot && botInfo?.username ? ", ElWatch" : ""}${pronouns?.length ? ", PronounDB" : ""}` }) if(userInfo.avatar_url) embed.setThumbnail(userInfo.avatar_url) if(userInfo.banner_url) embed.setImage(userInfo.banner_url) @@ -207,13 +207,13 @@ module.exports = { // Créé un embed var embed = new EmbedBuilder() embed.setTitle("Historique de pseudos") - embed.setDescription(`${usernameHistory.map(u => ` | ${escape(u.username)}`).join("\n").slice(0, 3800)}\n\n> L'historique de pseudos se base sur le moment auquel [Discord WhoIs](https://bachero.johanstick.me/blog/discord-whois) a été utilisé pour obtenir les informations de l'utilisateur.\n\n> À chaque fois qu'un utilisateur obtient les informations d'un autre utilisateur, le pseudo sera modifié dans l'historique.`) - embed.setColor(config.getValue("bachero", "embedColor")) + embed.setDescription(`${usernameHistory.map(u => ` | ${escape(u.username)}`).join("\n").slice(0, 3800)}\n\n> L'historique de pseudos se base sur le moment auquel [Discord WhoIs](https://bachero.johanstick.fr/blog/discord-whois) a été utilisé pour obtenir les informations de l'utilisateur.\n\n> À chaque fois qu'un utilisateur obtient les informations d'un autre utilisateur, le pseudo sera modifié dans l'historique.`) + embed.setColor(colors.primary) embed.setFooter({ text: `Informations obtenues via Discord WhoIs${userInfo?.bot && botInfo?.username ? " et ElWatch" : ""}` }) // Répondre et modifier l'ancienne réponse pour enlever le bouton if(await i.editReply({ embeds: [embed] }).catch(err => { return "stop" }) == "stop") return - if(await interaction.editReply({ components: [row] }).catch(err => { return "stop" }) == "stop") return + await interaction.editReply({ components: [row] }).catch(err => { return "stop" }) }) } diff --git a/modules/el2zay.elbot/manifest.jsonc b/modules/el2zay.elbot/manifest.jsonc index 6538e9c..809d81b 100644 --- a/modules/el2zay.elbot/manifest.jsonc +++ b/modules/el2zay.elbot/manifest.jsonc @@ -1,11 +1,8 @@ { - "disabled": true, // le module marche pas encore à cause de certaines modifs dans le fichier index.js et le fichier functions.js "packageName": "el2zay.elbot", "name": "elbot", "shortDescription": "Ce module ajoute plusieurs commandes de elbot.", - "longDescription": "Ce module ajoute les commandes principales de elbot.", - "onloadMessage": "", - "source": "", + "source": "https://github.com/bacherobot/bot", "files": [ // toutes les commandes désactivées sont pas terminées "bingchiling.js", "roulette.js", @@ -33,7 +30,6 @@ "random-dé.js", "random-map-point.js" ], - "authors": [ { "name": "el2zay", diff --git a/modules/el2zay.elbot/sondage.js b/modules/el2zay.elbot/sondage.js index 555b37e..890efba 100644 --- a/modules/el2zay.elbot/sondage.js +++ b/modules/el2zay.elbot/sondage.js @@ -47,7 +47,7 @@ function generateEmbed(sondage, reason) { { name: `2️⃣ ${sondage.option2}`, value: `${choix2} vote${choix2 > 1 ? "s" : ""} (${choix2_percent}%)${trait2.length ? ` | ${trait2}` : ""}` }, { name: "Participants", value: `${choix1 + choix2} vote${choix1 + choix2 > 1 ? "s" : ""}` } ]) - .setColor(bacheroFunctions.config.getValue("bachero", "embedColor")) + .setColor(bacheroFunctions.colors.primary) if (reason != "dm") embed.setAuthor({ name: sondage.username, iconURL: sondage.authorPdp }) if (!reason) embed.setFooter({ text: "Vous pourrez changer votre vote, mais vous ne pourrez pas le retirer • L'auteur ne sait pas qui participe" }) @@ -211,7 +211,7 @@ module.exports = { var embed = new EmbedBuilder() .setTitle("Quelle action voulez-vous faire ?") .setDescription("1️⃣ : Modifier la question\n2️⃣ : Modifier les options\n✅ : Terminer le sondage") - .setColor(bacheroFunctions.config.getValue("bachero", "embedColor")) + .setColor(bacheroFunctions.colors.primary) var row = new ActionRowBuilder().addComponents( new ButtonBuilder()