const { SlashCommandBuilder, blockQuote, userMention, roleMention } = require('@discordjs/builders'); const { MessageActionRow, MessageButton, Collection } = require('discord.js'); const ongoingww = new Collection(); const intTable = new Collection(); var wwId = 1; /** * This function aims to do word wars inside a discord channel. * Someone launches a wordwar and other people can join in by clicking on the react icon. * First argument is the time of duration of the wordwar. * Second argument is the waiting time before the wordwar. **/ module.exports = { data: new SlashCommandBuilder() .setName('wordwar') .setDescription('Pour faire des WordWar comme au NaNoWriMo') .addStringOption(option => option.setName('duree') .setDescription('Durée de la wordwar. Par défaut 20min, max 30min.') .setRequired(false) ) .addStringOption(option => option.setName('attente') .setDescription('Attente avant la wordwar. Par défaut 2min, max 15min.') .setRequired(false) ), async execute(interaction) { // Vérifie que l'utilisateur ne participe pas déjà à une ww en regardant ses rôles if (ongoingww.has(interaction.user.id)) { interaction.reply({ content: "Vous avez déjà une wordwar en cours.", ephemeral: true }); return; } // On vérifie que la commande a correctement été entrée var wwtimer; var wwdelay; if (interaction.options.get('duree') == null) { wwtimer = 20; } else { wwtimer = interaction.options.get('duree').value; if (isNormalInteger(wwtimer)) { if (wwtimer > 30) { interaction.reply({ content: "Le temps d'une wordwar ne peux pas excéder **30 minutes** sur ce channel. Merci de réessayer !", ephemeral: true }); return; } else if (wwtimer < 1) { return; } } else { interaction.reply({ content: "Le temps d'une wordwar doit être un entier positif compris entre **1 minute** et **30 minutes**. Merci de réessayer !", ephemeral: true }); return; } // && Number.isInteger(args[1]) } if (interaction.options.get('attente') == null) { wwdelay = 2; } else { wwdelay = interaction.options.get('attente').value; if (isNormalInteger(wwdelay)) { if (wwdelay > 15) { interaction.reply({ content: "Le temps d'attente d'une wordwar ne peux pas excéder **15 minutes** sur ce channel. Merci de réessayer !", ephemeral: true }); return; } else if (wwdelay < 1) { interaction.reply({ content: "Le temps d'attente d'une wordwar ne peux pas être inférieur à **1 minute** sur ce channel. Merci de réessayer !", ephemeral: true }); return; } } else { interaction.reply({ content: "Le temps d'attente d'une wordwar doit être un entier positif compris entre **1 minute** et **15 minutes**. Merci de réessayer !", ephemeral: true }); return; } } //Si la commande a bien été entrée, on continue //Create a role with a specific ID for this ww var newRole = { name: "WordWar#" + wwId, color: "RANDOM", mentionable: true, reason: "Rôle temporaire pour les wordwar" }; var wwRole = await interaction.guild.roles.create(newRole); wwId++; ongoingww.set(interaction.user.id, wwRole.name); interaction.member.roles.add(wwRole.id); commandReply = "Une wordwar a été initiée. Elle commencera dans " + wwdelay + " minutes et durera " + wwtimer + " minutes."; const row = new MessageActionRow() .addComponents( new MessageButton() .setCustomId('primary') .setLabel('Participer') .setStyle('SUCCESS') ) .addComponents( new MessageButton() .setCustomId('secondary') .setLabel('Annuler') .setStyle('DANGER') ); interaction.reply({ content: commandReply, components: [row] }) .then(() => { var publicReplies = undefined; const filterParticipate = (btnInt) => btnInt.customId === 'primary'; const collectorParticipate = interaction.channel.createMessageComponentCollector({ filter: filterParticipate, }); collectorParticipate.on('collect', async i => { if (i.member.roles.cache.has(wwRole.id)) { OnlyReply('Vous êtes déjà enregistré pour cette wordwar', i, wwRole); } else if (ongoingww.has(i.user.id)) { OnlyReply('Vous êtes déjà enregistré dans la wordwar ' + ongoingww.get(i.user.id), i, wwRole); } else { i.member.roles.add(wwRole); ongoingww.set(i.user.ida, wwRole); OnlyReply('Participation est enregistrée', i, wwRole); } }); const filterCancel = (btnInt) => btnInt.customId === 'secondary'; const collectorCancel = interaction.channel.createMessageComponentCollector({ filter: filterCancel, }); collectorCancel.on('collect', async i => { if (!i.member.roles.cache.has(wwRole.id)) { OnlyReply('Vous n\'êtes pas enregistré pour cette wordwar', i, wwRole); } else { OnlyReply('Participation est annulée', i, wwRole); i.member.roles.remove(wwRole); ongoingww.delete(i.user.id); // Si l'utilisateur qui annule est le dernier dans cette wordwar if (typeof ongoingww.find(wordWar => wordWar == wwRole.name) == "undefined") { row.components.forEach(element => { element.setDisabled(true); }); i.message.edit({ content: "La " + wwRole.name + " a été annulée par manque de participants.", components: [row] }); wwRole.delete(); collectorCancel.stop(); collectorParticipate.stop(); if (publicReplies != undefined) { publicReplies.delete(); } console.log(wwRole.name + ' canceled'); return; } } }); setTimeout(async () => { if (wwRole.deleted != true) { console.log(wwRole.name + ' launched'); var participantStart = '\nLa ' + wwRole.name + ' commence. Vous pouvez toujours la rejoindre si vous le désirez. Bonne chance à tou.te.s !! ' + roleMention(wwRole.id) + '\n'; publicReplies = await interaction.channel.send({ content: participantStart, fetchReply: true }); setTimeout(async () => { if (wwRole.deleted != true) { console.log(wwRole.name + ' ended'); var participantEnd = 'La ' + wwRole.name + ' est maintenant terminée, merci d\'y avoir participé \! ' + roleMention(wwRole.id) + '\n'; await interaction.channel.send({ content: participantEnd, fetchReply: true }); ongoingww.forEach((value,key,ongoingww) => { if (value == wwRole.name) { ongoingww.delete(key); } collectorCancel.stop(); collectorParticipate.stop(); }); setTimeout(() => { wwRole.delete(); }, 30 * 1000); // Wait 30 seconds to delete the role } }, wwtimer * 60000); } }, wwdelay * 60000); }); /* } */ } } function isNormalInteger(str) { var n = Math.floor(Number(str)); return n !== Infinity && String(n) === str && n >= 0; } function OnlyReply(str, int, ww) { if (!intTable.has(ww.name + int.user.id)) { intTable.set(ww.name + int.user.id, int); int.reply({ content: str, ephemeral: true }); } else { intTable.get(ww.name + int.user.id).editReply({ content: str, ephemeral: true, fetchReply: true }); int.deferUpdate(); } }