const { Client, GatewayIntentBits, Collection, ActivityType, REST, Routes } = require("discord.js") const fs = require("node:fs") const path = require("path") const { Manager } = require("erela.js") const { __glob } = require("./global-variables") const { LogType } = require("loguix") const { List } = require("./sub-list") const nodeFinder = require("./nodes-finder") const metric = require("webmetrik") const client = new Client({ intents:[GatewayIntentBits.Guilds, GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.GuildMembers], }) var membersVoices = new Map() module.exports.getClient = function () { return client } module.exports.getMemberVoices = function () { return membersVoices } module.exports.DiscordBot = class { constructor(config, dlog) { dlog.step.init("d_init", "Démarrage du Bot Discord") init(dlog, config) } } function init(dlog, config) { client.commands = new Collection() client.dictator = false; dlog.step.init("d_get_commands", "Récupération des commandes en local depuis : " + __glob.COMMANDS) const commands = []; // Grab all the command files from the commands directory you created earlier const commandsPath = __glob.COMMANDS const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js')); for (const file of commandFiles) { const command = require(commandsPath + path.sep + file); client.commands.set(command.data.name, command) commands.push(command.data.toJSON()); } dlog.step.end("d_get_commands") const rest = new REST().setToken(config.token); (async () => { try { dlog.step.init("d_commands_refresh", `Refreshing ${commands.length} application (/) commands.`); // The put method is used to fully refresh all commands in the guild with the current set const data = await rest.put( Routes.applicationGuildCommands("1094727789682380922", "137291455336022018"), { body: commands }, ); dlog.log("COMMANDS : Sended to Discord [" + data.length + "]") dlog.step.end("d_commands_refresh") } catch (error) { // And of course, make sure you catch and log any errors! dlog.error(error) } })(); rest.on("rateLimited", (datawarn) => { dlog.warn("REST - Limite de requête atteinte ! TimeToReset : " + datawarn.timeToReset); }) client.once("ready", () => { dlog.log("Connexion au Bot Discord réussi ! Connecté à : " + client.user.username + "#" + client.user.discriminator) client.user.setPresence({ activities: [{ name: `toutes les musiques possible !`, type: ActivityType.Listening }], status: 'online', }); client.manager.init(client.user.id); const commandManager = client.application.commands; if (!commandManager) { dlog.error('Command manager not available.'); } else { commandManager.set([]); } dlog.step.end("d_init") }) client.on("interactionCreate", (interaction) => { if(!interaction.isCommand()) return; var numberOfCommands = new metric.Metric("numberOfCommands", "Nombre de commandes éxécutées") numberOfCommands.setValue(numberOfCommands.getValue() + 1) const command = client.commands.get(interaction.commandName) try { // Create a metric to count the number of commands executed by each user const userCommand = new metric.Metric("userCommand_" + interaction.member.user.username, "Nombre de commandes éxécutées par l'utilisateur : " + interaction.member.user.username) userCommand.setValue(userCommand.getValue() + 1) dlog.log(interaction.member.user.username + "-> /" + interaction.commandName) command.execute(client, interaction) } catch(error) { dlog.error(interaction.member.user.username + "-> /" + interaction.commandName + " : ERREUR RENCONTRE") dlog.error(error) interaction.reply({content:"Erreur lors de l'éxécution de la commande !", ephemeral: true}) } }) startErelaManager(dlog, config) client.login(config.token) } function startErelaManager(dlog, config) { const elog = new LogType("Lavalink-Manager") const nodes = nodeFinder.getNodes() client.manager = new Manager({ // The nodes to connect to, optional if using default lavalink options nodes, // Method to send voice data to Discord send: (id, payload) => { const guild = client.guilds.cache.get(id); // NOTE: FOR ERIS YOU NEED JSON.stringify() THE PAYLOAD if (guild) guild.shard.send(payload); } }); const plog = new LogType("Lavalink-Player") client.on("voiceStateUpdate", (oldMember, newMember) => { membersVoices.set(newMember.id, newMember.channelId) /* SECURITY DISABLED let player = client.manager.players.get(oldMember.guild.id) if(player) { client.channels.fetch(player.options.voiceChannel).then(channel => { if(channel.members.size <= 1) { player.destroy() plog.log("[Automatic Task] Player supprimé dans : " + channel.name) } }) }*/ }) const list = new List() client.manager.on("playerCreate", async (player) => { await client.channels.fetch(player.options.voiceChannel).then(channel => { plog.log("Nouveau Player instancié dans : " + channel.name) }) process.emit("MUSIC_UPDATE_STATE") }) client.manager.on("playerDestroy",async (player) => { await list.destroy() await client.channels.fetch(player.options.voiceChannel).then(channel => { plog.log("Player supprimé dans : " + channel.name) }) process.emit("MUSIC_UPDATE_STATE") }) client.manager.on("trackStart", async (player) => { // Create a metric to count the number of songs played const songPlayed = new metric.Metric("songPlayed", "Nombre de musiques jouées") songPlayed.setValue(songPlayed.getValue() + 1) if(player) { plog.log("Lecture de '" + player.queue.current.title + "' de '" + player.queue.current.author + "'") // Create a metric to count the number of minutes played by the bot using player.queue.current.duration which is in ms (milliseconds) and verify if it's not a livestream if(player.queue.current.duration && player.queue.current.duration != 9223372036854776000) { const songDuration = new metric.Metric("songDuration", "Durée totale des musiques jouées en secondes") songDuration.setValue(songDuration.getValue() + (player.queue.current.duration / 1000)) } await list.setCurrent(player) await player.seek(0) process.emit("MUSIC_UPDATE_STATE") } }) client.manager.on("queueEnd", async () => { let player = await client.manager.players.get("137291455336022018") if(player) { await list.addCurrentToPrevious() if(await list.haveSongs()) { await player.play(list.next()) console.log("Lecture de la musique suivante") } } process.emit("MUSIC_UPDATE_STATE") }) // Emitted whenever a node connects client.manager.on("nodeConnect", node => { elog.log(`Connecté au serveur Lavalink : "${node.options.identifier}"` ) nodeFinder.setNodeState(node.options.identifier, true) }) // Emitted whenever a node encountered an error client.manager.on("nodeError", (node, error) => { elog.warn(`Node "${node.options.identifier}" encountered an error: ${error.message}.`) }) client.manager.on("nodeDisconnect", (node) => { nodeFinder.setNodeState(node.options.identifier, false) }) // THIS IS REQUIRED. Send raw events to Erela.js client.on("raw", d => client.manager.updateVoiceState(d)); }