const Discord = require('discord.js'); const client = new Discord.Client(); const { Sequelize, Model, DataTypes } = require('sequelize'); const sequelize = new Sequelize({ dialect: 'sqlite', storage: './database.sqlite' }); const format = require('util').format; var ADMIN_ROLENAME = "Cadre du Parti"; var MEMBER_ROLENAME = "Membre du Parti"; var MEMBER_CHANNEL_NAME = "annonces-au-peuple"; var EVERYONE_CHANNEL_NAME = "general"; client.login('token'); class Partie extends Model { } Partie.init({ date_partie: { type: DataTypes.DATE, primaryKey: true, }, date_fin_exclu: DataTypes.DATE, max_joueurs: DataTypes.INTEGER }, { sequelize, modelName: 'Partie' }); class Joueur extends Model { } Joueur.init({ discord_id: { type: DataTypes.STRING, primaryKey: true } }, { sequelize, modelName: 'Joueur' }); class Joueur_Partie extends Model { } Joueur_Partie.init({ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true }, participe: { type: DataTypes.BOOLEAN, defaultValue: false }, membre: { type: DataTypes.BOOLEAN, defaultValue: false }, barbeque: { type: DataTypes.BOOLEAN, defaultValue: false }, location: { type: DataTypes.BOOLEAN, defaultValue: false }, envoi_dm: { type: DataTypes.BOOLEAN, defaultValue: false }, date_inscription: { type: DataTypes.DATE }, partie_date_partie: { type: DataTypes.DATE }, joueur_discord_id: { type: DataTypes.STRING }, }, { sequelize, modelName: 'Joueur_Partie' }); Partie.sync({ alter: true }); Joueur.sync({ alter: true }); Joueur_Partie.sync({ alter: true }); function adjust_date(date) { const today = new Date(); const base_date = new Date( today.getFullYear(), date[2].startsWith('0') ? date[2].substring(1, 2) - 1 : date[2] - 1, date[1].startsWith('0') ? date[1].substring(1, 2) : date[1] ); if (today < base_date) { return base_date; } else { return new Date( base_date.getFullYear() + 1, base_date.getMonth(), base_date.getDay() ); } } client.on('ready', () => { console.log(`Logged in as ${client.user.tag}!`); }); client.on('message', async function(msg) { if(msg.guild == undefined) return; // Pour que les DM trigger pas les call const admin_role = msg.guild.roles.cache.find(r => (r.name == ADMIN_ROLENAME)); const member_role = msg.guild.roles.cache.find(r => (r.name == MEMBER_ROLENAME)); const member_channel = msg.guild.channels.cache.find(r => (r.name == MEMBER_CHANNEL_NAME)); const is_admin = msg.member.roles.cache.find(r => (r == admin_role)); if (msg.content.startsWith('/organiser ') && is_admin) { const args = msg.content.split(/(\s+)/).filter(e => (e.trim().length > 0)); const parser = /^(\d{2})\/(\d{2})$/; const date_de_partie = adjust_date(args[1].match(parser)).toISOString(); const date_fin_exclu = adjust_date(args[2].match(parser)).toISOString(); const nb_joueurs = parseInt(args[3].match(parser)); const partie = Partie.build({ date_partie: date_de_partie, date_fin_exclu: date_fin_exclu, max_joueurs: nb_joueurs }); partie.save(); const message = await member_channel.send(format( ` Une partie est organisée le %s! Réagissez avec 👍 pour recevoir le formulaire d'inscription! ` , args[1])); message.react('👍'); const collector = message.createReactionCollector(v => (true), {}); collector.on('collect', async function(m) { try{ m.users.cache.forEach(async function(user, _) { const member = await msg.guild.members.fetch(user.id); console.log(user.id); const is_member = member.roles.cache.find(r => (r == member_role)); console.log(user); if(user.id == client.user.id) return; const j = await Joueur.findOrCreate({where: {discord_id: user.id}, default: {discord_id: user.id}}); var [p, _] = await Joueur_Partie.findOrCreate({ where: {joueur_discord_id: user.id, partie_date_partie: partie.date_partie}, default: {joueur_discord_id: user.id, partie_date_partie: partie.date_partie} }); if(!p.envoi_dm) { const discord_user = await client.users.fetch(user.id); const dms = await discord_user.createDM(); if(is_member || date_fin_exclu <= new Date()) { const sent_dm = await dms.send( format(` Pour vous inscrire à la partie du %s, réagissez à ce message avec l'émote appropriée: 🔫: Participe à la partie 🍴: Participe au repas 🥺: Loue une réplique ⚠️: Ce bot n'as pas encore de fonctionalité pour annuler votre inscription, en cas d'annulation, prévenez @asitiglutama#1025 `, args[1])); await p.save(); await sent_dm.react('🔫'); await sent_dm.react('🍴'); await sent_dm.react('🥺'); const personal_collector = sent_dm.createReactionCollector(v => (true), {}); personal_collector.on('collect', async function(m) { try { console.log(m._emoji.name); for(var [user, rest] of m.users.cache) { if(user != client.user.id) { var element = await Joueur_Partie.findOne({where: {joueur_discord_id: user, partie_date_partie: date_de_partie}}); if(m._emoji.name == '🔫') { const partie = await Partie.findOne({where: {date_partie: date_de_partie}}); const participants = await Joueur_Partie.count({where: {partie_date_partie: date_de_partie, participe: true}}); if(participants >= nb_joueurs) { const sent_dm = await dms.send("Impossible de vous inscrire, la partie est pleine"); } else { element.participe = true; element.date_inscription = new Date(); await element.save(); } } else if(m._emoji.name == '🍴') { element.barbeque = true; await element.save(); } else if(m._emoji.name =='🥺') { element.location = true; await element.save(); } } } } catch (ex) { } }); p.envoi_dm = true; await p.save(); } else { const sent_dm = await dms.send( format(` Pour vous inscrire à la partie du %s, vous devez être membre de la NvA ou attendre la fin de l'exclusivité le %s! `, args[1], args[2])); } } }); } catch(ex) { console.log(ex); } }) } else if (msg.content.startsWith('/liste ') && msg.member.roles.cache.find(r => (r == admin_role))) { const args = msg.content.split(/(\s+)/).filter(e => (e.trim().length > 0)); const parser = /^(\d{2})\/(\d{2})$/; const date_de_partie = adjust_date(args[1].match(parser)).toISOString(); const liste = await Joueur_Partie.findAll({where: {partie_date_partie: date_de_partie}}); const dm = await msg.author.createDM(); const participants = await Joueur_Partie.count({where: {partie_date_partie: date_de_partie, participe: true}}); const repas = await Joueur_Partie.count({where: {partie_date_partie: date_de_partie, barbeque: true}}); const loca = await Joueur_Partie.count({where: {partie_date_partie: date_de_partie, location: true}}); await dm.send(format("Liste de la partie du %s\ninscrits=%i\nrepas=%i\nloca=%i", args[1], participants, repas, loca)); for(const element of liste) { const inscrit = await client.users.fetch(element.joueur_discord_id); await dm.send(format(inscrit.username)+" "+(inscrit.participe ? "🔫" : "")+(inscrit.barbeque ? "🍴" : "")+(inscrit.location ? "🥺" : "")); } } });