Billy/commands/wordwar.js

215 lines
9.5 KiB
JavaScript

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 wrdwar 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);
const commandReply = getRegistered(wwRole.name,wwdelay,wwtimer);
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é.e pour cette wordwar', i, wwRole);
} else if (ongoingww.has(i.user.id)) {
OnlyReply('Vous êtes déjà enregistré.e dans la wordwar ' + ongoingww.get(i.user.id), i, wwRole);
} else {
i.member.roles.add(wwRole);
ongoingww.set(i.user.id, wwRole.name);
i.message.edit(getRegistered(wwRole.name, wwdelay, wwtimer));
i.deferUpdate();
}
});
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 {
i.member.roles.remove(wwRole);
ongoingww.delete(i.user.id);
console.log(ongoingww);
i.deferUpdate();
// 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;
}else{
i.message.edit(getRegistered(wwRole.name, wwdelay, wwtimer));
}
}
});
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();
}
}
function getRegistered(ww,d, t) {
var str = "";
ongoingww.forEach(async (value, key) => {
if (value == ww){
str += userMention(key) + ' ';
}
});
return "la " + ww + " a été initiée. Elle commencera dans " + d + " minutes et durera " + t + " minutes.\nInscrits : " + str;
}