A discord bot for the Nouvelle Aube Airsoft Association
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 

232 lignes
9.2 KiB

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 ? "🥺" : ""));
}
}
});