From 0652a1d1c4d50f1d71299d7c8b9bb35caa90906e Mon Sep 17 00:00:00 2001 From: Pandraghon Date: Thu, 18 May 2017 20:32:20 +0200 Subject: [PATCH 01/14] Base files --- app.js | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 15 +++++++ 2 files changed, 136 insertions(+) create mode 100644 app.js create mode 100644 package.json diff --git a/app.js b/app.js new file mode 100644 index 0000000..41b404c --- /dev/null +++ b/app.js @@ -0,0 +1,121 @@ +const Discord = require('discord.js'); +const client = new Discord.Client(); +const settings = require('./settings.json'); +const Emoji = require("discord-emoji"); + +client.on('ready', () => { + console.log('I am ready!'); +}); + +client.on('message', message => { + let matches; + if (/^ping$/i.test(message.content) /*&& !/^(?:236198969019990018|220333308569976834)$/.test(message.author.id)*/) { + message.channel.send('pong', {tts: true}); + } + if (/my avatar/i.test(message.content)) { + message.reply(message.author.avatarURL); + } + if (/(?:^| )ch?ats?(?: |$)/i.test(message.content)) { + message.react(Emoji.nature.cat); + } + if (/(?:^| )(?:chien|dog)s?(?: |$)/i.test(message.content)) { + message.react(Emoji.nature.dog); + } + if (/\(\╯\°\□\°\)\╯\︵\ \┻\━\┻/.test(message.content)) { + message.reply('PUT. THE. TABLE. BACK.'); + } + if ((matches = message.content.match(/^([a-zA-Z0-9])$/))) { + let c = message.content.charCodeAt(0); + switch(c){ + case 'Z': c = 'A'; + case 'z': c = 'a'; + default: c = String.fromCharCode(++c); + } + message.reply(c); + } + + if (message.content.startsWith(settings.command_prefix.admin) && message.member.roles.some(role => ['admin', 'superadmin'].includes(role.name) )) { + const command = message.content.substring(settings.command_prefix.admin.length); + if (command.startsWith(`purge`)) { + message.channel.fetchMessages() + .then(messages => message.channel.bulkDelete(messages)) + .catch(error => { + const channel = message.guild.channels.find('name', settings.logs); + if (!channel) return; + channel.send(`Error while purging ${message.channel} : \`${error}\``); + }); + } + } + + if (message.content.startsWith(settings.command_prefix.user) && message.member.roles.some(role => ['girl', 'boy', 'bot'].includes(role.name) )) { + const command = message.content.substring(settings.command_prefix.user.length); + if ((matches = command.match(/^poll \[(.*)\] ?(?:\((.*)\))?/))) { + const title = matches[1]; + const options = matches[2] ? matches[2].split(' ;; ') : []; + let msg = `**${title}**`; + for (let option in options) { + msg += `\n **${Number(option) + 1}**. \`${options[option]}\``; + } + message.channel.send(msg) + .then(msg => { + const emojiList = { + 1: 'one', + 2: 'two', + 3: 'three', + 4: 'four', + 5: 'five', + 6: 'six', + 7: 'seven', + 8: 'eight', + 9: 'nine' + }; + if (options.length > 0) { + let promise = msg.react(Emoji.symbols[emojiList[1]]); + for (let option in options) { + promise = promise.then(react => react.message.react(Emoji.symbols[emojiList[Number(option) + 2]])); + } + } + }) + .catch(error => { + const channel = message.guild.channels.find('name', settings.logs); + if (!channel) return; + channel.send(`Error while creating poll in ${message.channel} : \`${error}\`\nCommand : \`${message.content}\``); + }); + } + } +}); + +client.on('guildMemberAdd', member => { + member.guild.defaultChannel.send(`${member} nous a rejoint !`).then(message => { + message.react('😊'); + }); + + const channel = member.guild.channels.find('name', settings.logs); + if (!channel) return; + channel.send(`added member : ${member}`); +}); + +client.on('guildMemberRemove', member => { + member.guild.defaultChannel.send(`${member} nous a quitté !`).then(message => { + message.react('😭'); + }); + + const channel = member.guild.channels.find('name', settings.logs); + if (!channel) return; + channel.send(`removed member : ${member}`); +}); + +client.on('guildMemberUpdate', (oldMember, newMember) => { + const channel = newMember.guild.channels.find('name', settings.logs); + if (!channel) return; + const newRoles = newMember.roles.filter(role => !oldMember.roles.has(role.id)).map(role => role.name); + const removedRoles = oldMember.roles.filter(role => !newMember.roles.has(role.id)).map(role => role.name); + + let message = `${oldMember} changed :`; + if (newRoles.length > 0) message += `\n - New roles : \`${newRoles.join('\`, \`')}\``; + if (removedRoles.length > 0) message += `\n - Removed roles : \`${removedRoles.join('\`, \`')}\``; + + channel.send(message); +}); + +client.login(settings.token); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..81079df --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "noobeater", + "version": "0.0.1", + "description": "Bot for Glaucus Pocus Discord", + "main": "app.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Pandraghon", + "license": "MIT", + "dependencies": { + "discord-emoji": "^1.1.1", + "discord.js": "^11.1.0" + } +} From 9164e0bcb763e412ff9d22128d6d5319a0f60ef4 Mon Sep 17 00:00:00 2001 From: Pandraghon Date: Thu, 18 May 2017 20:52:39 +0200 Subject: [PATCH 02/14] Separate secret config --- .gitignore | 2 ++ app.js | 3 ++- settings.json | 8 ++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 settings.json diff --git a/.gitignore b/.gitignore index 00cbbdf..c853c35 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,5 @@ typings/ # dotenv environment variables file .env + +secret\.json diff --git a/app.js b/app.js index 41b404c..a433b44 100644 --- a/app.js +++ b/app.js @@ -1,6 +1,7 @@ const Discord = require('discord.js'); const client = new Discord.Client(); const settings = require('./settings.json'); +const secret = require('./secret.json'); const Emoji = require("discord-emoji"); client.on('ready', () => { @@ -118,4 +119,4 @@ client.on('guildMemberUpdate', (oldMember, newMember) => { channel.send(message); }); -client.login(settings.token); \ No newline at end of file +client.login(secret.token); \ No newline at end of file diff --git a/settings.json b/settings.json new file mode 100644 index 0000000..d17958c --- /dev/null +++ b/settings.json @@ -0,0 +1,8 @@ +{ + "logs": "logs", + "command_prefix": { + "base": "!", + "admin": "a!", + "user": "u!" + } +} \ No newline at end of file From bdd2209e7986a6bf4003110d7a00aab2509b3f25 Mon Sep 17 00:00:00 2001 From: Pandraghon Date: Sat, 20 May 2017 00:16:46 +0200 Subject: [PATCH 03/14] Add Sqlite + Exp for users --- app.js | 183 ++++++++++++++++++++++++++++++--------------------- package.json | 3 +- 2 files changed, 109 insertions(+), 77 deletions(-) diff --git a/app.js b/app.js index a433b44..e8c466a 100644 --- a/app.js +++ b/app.js @@ -3,87 +3,118 @@ const client = new Discord.Client(); const settings = require('./settings.json'); const secret = require('./secret.json'); const Emoji = require("discord-emoji"); +const sql = require('sqlite'); + +sql.open('./db.sqlite'); client.on('ready', () => { - console.log('I am ready!'); + console.log('I am ready!'); }); +const updateUserXP = (points, userId) => { + sql.get(`SELECT xp, level FROM users WHERE id = '${userId}'`).then(row => { + if (!row) { + sql.run('INSERT INTO users (id, xp, level) VALUES (?, ?, ?)', [userId, 1, 0]); + } else { + sql.run(`UPDATE users SET xp = ${row.xp + points} WHERE id = ${userId}`) + } + }).catch(() => { + console.error; + sql.run('CREATE TABLE IF NOT EXISTS users (id TEXT, xp INTEGER, level INTEGER)').then(() => { + sql.run('INSERT INTO users (id, xp, level) VALUES (?, ?, ?)', [userId, 1, 0]); + }); + }); +}; + client.on('message', message => { let matches; - if (/^ping$/i.test(message.content) /*&& !/^(?:236198969019990018|220333308569976834)$/.test(message.author.id)*/) { - message.channel.send('pong', {tts: true}); - } - if (/my avatar/i.test(message.content)) { - message.reply(message.author.avatarURL); - } - if (/(?:^| )ch?ats?(?: |$)/i.test(message.content)) { - message.react(Emoji.nature.cat); - } - if (/(?:^| )(?:chien|dog)s?(?: |$)/i.test(message.content)) { - message.react(Emoji.nature.dog); - } - if (/\(\╯\°\□\°\)\╯\︵\ \┻\━\┻/.test(message.content)) { - message.reply('PUT. THE. TABLE. BACK.'); - } - if ((matches = message.content.match(/^([a-zA-Z0-9])$/))) { - let c = message.content.charCodeAt(0); - switch(c){ - case 'Z': c = 'A'; - case 'z': c = 'a'; - default: c = String.fromCharCode(++c); - } - message.reply(c); - } - if (message.content.startsWith(settings.command_prefix.admin) && message.member.roles.some(role => ['admin', 'superadmin'].includes(role.name) )) { - const command = message.content.substring(settings.command_prefix.admin.length); - if (command.startsWith(`purge`)) { - message.channel.fetchMessages() - .then(messages => message.channel.bulkDelete(messages)) - .catch(error => { - const channel = message.guild.channels.find('name', settings.logs); - if (!channel) return; - channel.send(`Error while purging ${message.channel} : \`${error}\``); - }); - } - } + if (message.channel.type === 'text') { + updateUserXP(1, message.author.id); + } - if (message.content.startsWith(settings.command_prefix.user) && message.member.roles.some(role => ['girl', 'boy', 'bot'].includes(role.name) )) { - const command = message.content.substring(settings.command_prefix.user.length); - if ((matches = command.match(/^poll \[(.*)\] ?(?:\((.*)\))?/))) { - const title = matches[1]; - const options = matches[2] ? matches[2].split(' ;; ') : []; - let msg = `**${title}**`; - for (let option in options) { - msg += `\n **${Number(option) + 1}**. \`${options[option]}\``; + if (/^ping$/i.test(message.content) /*&& !/^(?:236198969019990018|220333308569976834)$/.test(message.author.id)*/ ) { + message.channel.send('pong', { tts: true }); + } + if (/my avatar/i.test(message.content)) { + message.reply(message.author.avatarURL); + } + if (/(?:^| )ch?ats?(?: |$)/i.test(message.content)) { + message.react(Emoji.nature.cat); + } + if (/(?:^| )(?:chien|dog)s?(?: |$)/i.test(message.content)) { + message.react(Emoji.nature.dog); + } + if (/\(\╯\°\□\°\)\╯\︵\ \┻\━\┻/.test(message.content)) { + message.reply('PUT. THE. TABLE. BACK.'); + } + if ((matches = message.content.match(/^([a-zA-Z0-9])$/))) { + let c = message.content.charCodeAt(0); + switch (c) { + case 'Z': + c = 'A'; + case 'z': + c = 'a'; + default: + c = String.fromCharCode(++c); } - message.channel.send(msg) - .then(msg => { - const emojiList = { - 1: 'one', - 2: 'two', - 3: 'three', - 4: 'four', - 5: 'five', - 6: 'six', - 7: 'seven', - 8: 'eight', - 9: 'nine' - }; - if (options.length > 0) { - let promise = msg.react(Emoji.symbols[emojiList[1]]); - for (let option in options) { - promise = promise.then(react => react.message.react(Emoji.symbols[emojiList[Number(option) + 2]])); + message.reply(c); + } + + if (message.content.startsWith(settings.command_prefix.admin) && message.member.roles.some(role => ['admin', 'superadmin'].includes(role.name))) { + const command = message.content.substring(settings.command_prefix.admin.length); + if (command.startsWith(`purge`)) { + message.channel.fetchMessages() + .then(messages => message.channel.bulkDelete(messages)) + .catch(error => { + const channel = message.guild.channels.find('name', settings.logs); + if (!channel) return; + channel.send(`Error while purging ${message.channel} : \`${error}\``); + }); + } + } + + if (message.content.startsWith(settings.command_prefix.user) && message.member.roles.some(role => ['girl', 'boy', 'bot'].includes(role.name))) { + const command = message.content.substring(settings.command_prefix.user.length); + if ((matches = command.match(/^poll \[(.*)\] ?(?:\((.*)\))?/))) { + const title = matches[1]; + const options = matches[2] ? matches[2].split(' ;; ') : []; + let msg = `**${title}**`; + for (let option in options) { + msg += `\n **${Number(option) + 1}**. \`${options[option]}\``; + } + message.channel.send(msg) + .then(msg => { + const emojiList = { + 1: 'one', + 2: 'two', + 3: 'three', + 4: 'four', + 5: 'five', + 6: 'six', + 7: 'seven', + 8: 'eight', + 9: 'nine' + }; + if (options.length > 0) { + let promise = msg.react(Emoji.symbols[emojiList[1]]); + for (let option in options) { + promise = promise.then(react => react.message.react(Emoji.symbols[emojiList[Number(option) + 2]])); + } } - } - }) - .catch(error => { - const channel = message.guild.channels.find('name', settings.logs); - if (!channel) return; - channel.send(`Error while creating poll in ${message.channel} : \`${error}\`\nCommand : \`${message.content}\``); + }) + .catch(error => { + const channel = message.guild.channels.find('name', settings.logs); + if (!channel) return; + channel.send(`Error while creating poll in ${message.channel} : \`${error}\`\nCommand : \`${message.content}\``); + }); + } else if (command === 'lvl') { + sql.get(`SELECT xp, level FROM users WHERE id = '${message.author.id}'`).then(row => { + if (!row) return message.reply('Ton niveau actuel est ... 0.'); + message.reply(`Ton niveau actuel est ${row.level} [${row.xp}]`); }); - } - } + } + } }); client.on('guildMemberAdd', member => { @@ -107,13 +138,13 @@ client.on('guildMemberRemove', member => { }); client.on('guildMemberUpdate', (oldMember, newMember) => { - const channel = newMember.guild.channels.find('name', settings.logs); - if (!channel) return; - const newRoles = newMember.roles.filter(role => !oldMember.roles.has(role.id)).map(role => role.name); - const removedRoles = oldMember.roles.filter(role => !newMember.roles.has(role.id)).map(role => role.name); + const channel = newMember.guild.channels.find('name', settings.logs); + if (!channel) return; + const newRoles = newMember.roles.filter(role => !oldMember.roles.has(role.id)).map(role => role.name); + const removedRoles = oldMember.roles.filter(role => !newMember.roles.has(role.id)).map(role => role.name); - let message = `${oldMember} changed :`; - if (newRoles.length > 0) message += `\n - New roles : \`${newRoles.join('\`, \`')}\``; + let message = `${oldMember} changed :`; + if (newRoles.length > 0) message += `\n - New roles : \`${newRoles.join('\`, \`')}\``; if (removedRoles.length > 0) message += `\n - Removed roles : \`${removedRoles.join('\`, \`')}\``; channel.send(message); diff --git a/package.json b/package.json index 81079df..c6ad31d 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "license": "MIT", "dependencies": { "discord-emoji": "^1.1.1", - "discord.js": "^11.1.0" + "discord.js": "^11.1.0", + "sqlite": "^2.7.0" } } From 771b5fe8f8c8d7a333c3241c3003c9a735d299d3 Mon Sep 17 00:00:00 2001 From: Pandraghon Date: Sat, 20 May 2017 00:55:07 +0200 Subject: [PATCH 04/14] Event Handler Separate each event handler in its own file in the /events/ folder --- app.js | 43 +++++++------------------------------ events/guildMemberAdd.js | 11 ++++++++++ events/guildMemberRemove.js | 11 ++++++++++ events/guildMemberUpdate.js | 14 ++++++++++++ events/ready.js | 3 +++ 5 files changed, 47 insertions(+), 35 deletions(-) create mode 100644 events/guildMemberAdd.js create mode 100644 events/guildMemberRemove.js create mode 100644 events/guildMemberUpdate.js create mode 100644 events/ready.js diff --git a/app.js b/app.js index e8c466a..6c9269d 100644 --- a/app.js +++ b/app.js @@ -4,11 +4,17 @@ const settings = require('./settings.json'); const secret = require('./secret.json'); const Emoji = require("discord-emoji"); const sql = require('sqlite'); +const fs = require('fs'); sql.open('./db.sqlite'); -client.on('ready', () => { - console.log('I am ready!'); +fs.readdir('./events/', (err, files) => { + if (err) return console.error(err); + files.forEach(file => { + const eventFunction = require(`./events/${file}`); + const eventName = file.split('.')[0]; + client.on(eventName, (...args) => eventFunction.run(client, ...args)); + }); }); const updateUserXP = (points, userId) => { @@ -117,37 +123,4 @@ client.on('message', message => { } }); -client.on('guildMemberAdd', member => { - member.guild.defaultChannel.send(`${member} nous a rejoint !`).then(message => { - message.react('😊'); - }); - - const channel = member.guild.channels.find('name', settings.logs); - if (!channel) return; - channel.send(`added member : ${member}`); -}); - -client.on('guildMemberRemove', member => { - member.guild.defaultChannel.send(`${member} nous a quitté !`).then(message => { - message.react('😭'); - }); - - const channel = member.guild.channels.find('name', settings.logs); - if (!channel) return; - channel.send(`removed member : ${member}`); -}); - -client.on('guildMemberUpdate', (oldMember, newMember) => { - const channel = newMember.guild.channels.find('name', settings.logs); - if (!channel) return; - const newRoles = newMember.roles.filter(role => !oldMember.roles.has(role.id)).map(role => role.name); - const removedRoles = oldMember.roles.filter(role => !newMember.roles.has(role.id)).map(role => role.name); - - let message = `${oldMember} changed :`; - if (newRoles.length > 0) message += `\n - New roles : \`${newRoles.join('\`, \`')}\``; - if (removedRoles.length > 0) message += `\n - Removed roles : \`${removedRoles.join('\`, \`')}\``; - - channel.send(message); -}); - client.login(secret.token); \ No newline at end of file diff --git a/events/guildMemberAdd.js b/events/guildMemberAdd.js new file mode 100644 index 0000000..97ccc87 --- /dev/null +++ b/events/guildMemberAdd.js @@ -0,0 +1,11 @@ +const settings = require('../settings.json'); + +exports.run = (client, member) => { + member.guild.defaultChannel.send(`${member} nous a rejoint !`).then(message => { + message.react('😊'); + }); + + const channel = member.guild.channels.find('name', settings.logs); + if (!channel) return; + channel.send(`added member : ${member}`); +}; \ No newline at end of file diff --git a/events/guildMemberRemove.js b/events/guildMemberRemove.js new file mode 100644 index 0000000..57b08c4 --- /dev/null +++ b/events/guildMemberRemove.js @@ -0,0 +1,11 @@ +const settings = require('../settings.json'); + +exports.run = (client, member) => { + member.guild.defaultChannel.send(`${member} nous a quitté !`).then(message => { + message.react('😭'); + }); + + const channel = member.guild.channels.find('name', settings.logs); + if (!channel) return; + channel.send(`removed member : ${member}`); +}; \ No newline at end of file diff --git a/events/guildMemberUpdate.js b/events/guildMemberUpdate.js new file mode 100644 index 0000000..f2582b6 --- /dev/null +++ b/events/guildMemberUpdate.js @@ -0,0 +1,14 @@ +const settings = require('../settings.json'); + +exports.run = (client, oldMember, newMember) => { + const channel = newMember.guild.channels.find('name', settings.logs); + if (!channel) return; + const newRoles = newMember.roles.filter(role => !oldMember.roles.has(role.id)).map(role => role.name); + const removedRoles = oldMember.roles.filter(role => !newMember.roles.has(role.id)).map(role => role.name); + + let message = `${oldMember} changed :`; + if (newRoles.length > 0) message += `\n - New roles : \`${newRoles.join('\`, \`')}\``; + if (removedRoles.length > 0) message += `\n - Removed roles : \`${removedRoles.join('\`, \`')}\``; + + channel.send(message); +}; \ No newline at end of file diff --git a/events/ready.js b/events/ready.js new file mode 100644 index 0000000..cac6bdb --- /dev/null +++ b/events/ready.js @@ -0,0 +1,3 @@ +exports.run = (client) => { + console.log(`Ready to server in ${client.channels.size} channels on ${client.guilds.size} servers, for a total of ${client.users.size} users.`); +}; \ No newline at end of file From 630c1062ca85681a559196ccc9dca3532b384d40 Mon Sep 17 00:00:00 2001 From: Pandraghon Date: Sun, 21 May 2017 20:28:31 +0200 Subject: [PATCH 05/14] Command Handler Separate commands in other files, for more flexibility --- app.js | 76 ++++++++++++++--------------------------- commands/admin/kick.js | 15 ++++++++ commands/admin/purge.js | 11 ++++++ commands/user/poll.js | 45 ++++++++++++++++++++++++ settings.json | 17 ++++++--- 5 files changed, 109 insertions(+), 55 deletions(-) create mode 100644 commands/admin/kick.js create mode 100644 commands/admin/purge.js create mode 100644 commands/user/poll.js diff --git a/app.js b/app.js index 6c9269d..d81374c 100644 --- a/app.js +++ b/app.js @@ -54,7 +54,7 @@ client.on('message', message => { if (/\(\╯\°\□\°\)\╯\︵\ \┻\━\┻/.test(message.content)) { message.reply('PUT. THE. TABLE. BACK.'); } - if ((matches = message.content.match(/^([a-zA-Z0-9])$/))) { + if ((matches = message.content.match(/^([a-zA-Z])$/))) { let c = message.content.charCodeAt(0); switch (c) { case 'Z': @@ -66,59 +66,33 @@ client.on('message', message => { } message.reply(c); } - - if (message.content.startsWith(settings.command_prefix.admin) && message.member.roles.some(role => ['admin', 'superadmin'].includes(role.name))) { - const command = message.content.substring(settings.command_prefix.admin.length); - if (command.startsWith(`purge`)) { - message.channel.fetchMessages() - .then(messages => message.channel.bulkDelete(messages)) - .catch(error => { - const channel = message.guild.channels.find('name', settings.logs); - if (!channel) return; - channel.send(`Error while purging ${message.channel} : \`${error}\``); - }); - } + if ((matches = message.content.match(/^([0-9]{1,15})$/))) { + message.reply(Number(matches[1]) + 1); } - if (message.content.startsWith(settings.command_prefix.user) && message.member.roles.some(role => ['girl', 'boy', 'bot'].includes(role.name))) { - const command = message.content.substring(settings.command_prefix.user.length); - if ((matches = command.match(/^poll \[(.*)\] ?(?:\((.*)\))?/))) { - const title = matches[1]; - const options = matches[2] ? matches[2].split(' ;; ') : []; - let msg = `**${title}**`; - for (let option in options) { - msg += `\n **${Number(option) + 1}**. \`${options[option]}\``; + const keys = Object.keys(settings.commands); + for (let key of keys) { + const commandGroup = settings.commands[key]; + if (message.content.startsWith(commandGroup.prefix)) { + if (!message.member.roles.some(role => settings.commands[key].roles.includes(role.name))) { + message.reply('tu n\'es pas autorisée à faire ça, bitch'); + } else { + const command = message.content.split(' ')[0].slice(commandGroup.prefix.length); + const args = message.content.slice(commandGroup.prefix.length + command.length + 1); + + if (/\.\./.test(command)) { + message.reply('Tu y as vraiment cru ?'); + break; + } + + try { + const commandFile = require(`./commands/${key}/${command}.js`); + commandFile.run(client, message, args); + } catch (err) { + console.error(err); + } } - message.channel.send(msg) - .then(msg => { - const emojiList = { - 1: 'one', - 2: 'two', - 3: 'three', - 4: 'four', - 5: 'five', - 6: 'six', - 7: 'seven', - 8: 'eight', - 9: 'nine' - }; - if (options.length > 0) { - let promise = msg.react(Emoji.symbols[emojiList[1]]); - for (let option in options) { - promise = promise.then(react => react.message.react(Emoji.symbols[emojiList[Number(option) + 2]])); - } - } - }) - .catch(error => { - const channel = message.guild.channels.find('name', settings.logs); - if (!channel) return; - channel.send(`Error while creating poll in ${message.channel} : \`${error}\`\nCommand : \`${message.content}\``); - }); - } else if (command === 'lvl') { - sql.get(`SELECT xp, level FROM users WHERE id = '${message.author.id}'`).then(row => { - if (!row) return message.reply('Ton niveau actuel est ... 0.'); - message.reply(`Ton niveau actuel est ${row.level} [${row.xp}]`); - }); + break; } } }); diff --git a/commands/admin/kick.js b/commands/admin/kick.js new file mode 100644 index 0000000..9786bda --- /dev/null +++ b/commands/admin/kick.js @@ -0,0 +1,15 @@ +exports.run = (client, message, args) => { + if (message.mentions.users.size === 0) { + return message.reply('T\'as pas dit qui qu\'tu veux kick').catch(console.error); + } + const kickMember = message.guild.member(message.mentions.users.first()); + if (!kickMember) { + return message.reply('Hum, c\'est qui ? Connais pas.'); + } + if (!message.guild.member(client.user).hasPermission('KICK_MEMBERS')) { + return message.reply('Je peux pas.').catch(console.error); + } + kickMember.kick().then(member => { + message.reply(`${member.user.username} a dégagé.`).catch(console.error); + }).catch(console.error) +} \ No newline at end of file diff --git a/commands/admin/purge.js b/commands/admin/purge.js new file mode 100644 index 0000000..0ecfcbb --- /dev/null +++ b/commands/admin/purge.js @@ -0,0 +1,11 @@ +const settings = require('../../settings.json'); + +exports.run = (client, message, args) => { + message.channel.fetchMessages() + .then(messages => message.channel.bulkDelete(messages)) + .catch(error => { + const channel = message.guild.channels.find('name', settings.logs); + if (!channel) return; + channel.send(`Error while purging ${message.channel} : \`${error}\``); + }); +} \ No newline at end of file diff --git a/commands/user/poll.js b/commands/user/poll.js new file mode 100644 index 0000000..2405e54 --- /dev/null +++ b/commands/user/poll.js @@ -0,0 +1,45 @@ +const settings = require('../../settings.json'); +const Emoji = require("discord-emoji"); + +exports.run = (client, message, args) => { + let matches; + if ((matches = args.match(/^\[(.*)\] ?(?:\((.*)\))?/))) { + const title = matches[1]; + const options = matches[2] ? matches[2].split(' ;; ') : []; + let msg = `**${title}**`; + for (let option in options) { + msg += `\n **${Number(option) + 1}**. \`${options[option]}\``; + } + message.channel.send(msg) + .then(msg => { + const emojiList = { + 1: 'one', + 2: 'two', + 3: 'three', + 4: 'four', + 5: 'five', + 6: 'six', + 7: 'seven', + 8: 'eight', + 9: 'nine' + }; + if (options.length > 0) { + let promise = false; + for (let option in options) { + if (promise) { + promise = promise.then(react => react.message.react(Emoji.symbols[emojiList[Number(option) + 1]])); + } else { + promise = msg.react(Emoji.symbols[emojiList[1]]); + } + } + } + }) + .catch(error => { + const channel = message.guild.channels.find('name', settings.logs); + if (!channel) return; + channel.send(`Error while creating poll in ${message.channel} : \`${error}\`\nCommand : \`${message.content}\``); + }); + } else { + message.channel.send('Pas comme ça qu\'ça s\'écrit !'); + } +} \ No newline at end of file diff --git a/settings.json b/settings.json index d17958c..934f85a 100644 --- a/settings.json +++ b/settings.json @@ -1,8 +1,17 @@ { "logs": "logs", - "command_prefix": { - "base": "!", - "admin": "a!", - "user": "u!" + "commands": { + "base": { + "prefix": "!", + "roles": ["girl", "boy", "bot"] + }, + "admin": { + "prefix": "a!", + "roles": ["admin", "superadmin"] + }, + "user": { + "prefix": "u!", + "roles": ["girl", "boy", "bot"] + } } } \ No newline at end of file From 71de260eee7d78ef3728dcfc7f6b4e93e3cac4b4 Mon Sep 17 00:00:00 2001 From: Pandraghon Date: Mon, 22 May 2017 23:08:27 +0200 Subject: [PATCH 06/14] Add mute and deafen commands --- commands/admin/deafen.js | 17 +++++++++++++++++ commands/admin/mute.js | 17 +++++++++++++++++ commands/admin/purge.js | 14 +++++++------- commands/admin/undeafen.js | 17 +++++++++++++++++ commands/admin/unmute.js | 17 +++++++++++++++++ 5 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 commands/admin/deafen.js create mode 100644 commands/admin/mute.js create mode 100644 commands/admin/undeafen.js create mode 100644 commands/admin/unmute.js diff --git a/commands/admin/deafen.js b/commands/admin/deafen.js new file mode 100644 index 0000000..d8ef2d6 --- /dev/null +++ b/commands/admin/deafen.js @@ -0,0 +1,17 @@ +exports.run = (client, message, args) => { + if (message.mentions.users.size === 0 && message.mentions.roles.size === 0) { + return message.reply('T\'as pas dit qui qu\'tu veux deafen').catch(console.error); + } + if (!message.guild.member(client.user).hasPermission('DEAFEN_MEMBERS')) { + return message.reply('Je peux pas.').catch(console.error); + } + + const deafenMember = (member) => { + if (!member || !member.voiceChannel) return; + if (member.serverDeaf) return message.channel.send(`${member} est déjà deaf`); + member.setDeaf(true).catch(console.error); + }; + + message.mentions.users.forEach(user => { deafenMember(message.guild.member(user)); }); + message.mentions.roles.forEach(role => { role.members.forEach(member => { deafenMember(member); }); }); +} \ No newline at end of file diff --git a/commands/admin/mute.js b/commands/admin/mute.js new file mode 100644 index 0000000..9c061c3 --- /dev/null +++ b/commands/admin/mute.js @@ -0,0 +1,17 @@ +exports.run = (client, message, args) => { + if (message.mentions.users.size === 0 && message.mentions.roles.size === 0) { + return message.reply('t\'as pas dit qui qu\'tu veux mute').catch(console.error); + } + if (!message.guild.member(client.user).hasPermission('MUTE_MEMBERS')) { + return message.reply('je peux pas.').catch(console.error); + } + + const muteMember = (member) => { + if (!member || !member.voiceChannel) return; + if (member.serverMute) return message.channel.send(`${member} est déjà mute`); + member.setMute(true).catch(console.error); + }; + + message.mentions.users.forEach(user => { muteMember(message.guild.member(user)); }); + message.mentions.roles.forEach(role => { role.members.forEach(member => { muteMember(member); }); }); +} \ No newline at end of file diff --git a/commands/admin/purge.js b/commands/admin/purge.js index 0ecfcbb..976adf1 100644 --- a/commands/admin/purge.js +++ b/commands/admin/purge.js @@ -1,11 +1,11 @@ const settings = require('../../settings.json'); exports.run = (client, message, args) => { - message.channel.fetchMessages() - .then(messages => message.channel.bulkDelete(messages)) - .catch(error => { - const channel = message.guild.channels.find('name', settings.logs); - if (!channel) return; - channel.send(`Error while purging ${message.channel} : \`${error}\``); - }); + message.channel.messages.deleteAll().forEach(msg => { + msg.catch(error => { + const channel = message.guild.channels.find('name', settings.logs); + if (!channel) return; + channel.send(`Error while purging ${message.channel} : \`${error}\``); + }); + }); } \ No newline at end of file diff --git a/commands/admin/undeafen.js b/commands/admin/undeafen.js new file mode 100644 index 0000000..c4b163d --- /dev/null +++ b/commands/admin/undeafen.js @@ -0,0 +1,17 @@ +exports.run = (client, message, args) => { + if (message.mentions.users.size === 0 && message.mentions.roles.size === 0) { + return message.reply('T\'as pas dit qui qu\'tu veux undeafen').catch(console.error); + } + if (!message.guild.member(client.user).hasPermission('DEAFEN_MEMBERS')) { + return message.reply('Je peux pas.').catch(console.error); + } + + const undeafenMember = (member) => { + if (!member || !member.voiceChannel) return; + if (!member.serverDeaf) return message.channel.send(`${member} n'est pas deaf`); + member.setDeaf(false).catch(console.error); + }; + + message.mentions.users.forEach(user => { undeafenMember(message.guild.member(user)); }); + message.mentions.roles.forEach(role => { role.members.forEach(member => { undeafenMember(member); }); }); +} \ No newline at end of file diff --git a/commands/admin/unmute.js b/commands/admin/unmute.js new file mode 100644 index 0000000..54b87a0 --- /dev/null +++ b/commands/admin/unmute.js @@ -0,0 +1,17 @@ +exports.run = (client, message, args) => { + if (message.mentions.users.size === 0 && message.mentions.roles.size === 0) { + return message.reply('t\'as pas dit qui qu\'tu veux unmute').catch(console.error); + } + if (!message.guild.member(client.user).hasPermission('MUTE_MEMBERS')) { + return message.reply('je peux pas.').catch(console.error); + } + + const unmuteMember = (member) => { + if (!member || !member.voiceChannel) return; + if (!member.serverMute) return message.channel.send(`${member} n'est pas mute`); + member.setMute(false).catch(console.error); + }; + + message.mentions.users.forEach(user => { unmuteMember(message.guild.member(user)); }); + message.mentions.roles.forEach(role => { role.members.forEach(member => { unmuteMember(member); }); }); +} \ No newline at end of file From fbb5bcb1c3c843546794d6e30adfbbda814769a9 Mon Sep 17 00:00:00 2001 From: Pandraghon Date: Wed, 24 May 2017 00:06:39 +0200 Subject: [PATCH 07/14] Add roll command --- commands/user/roll.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 commands/user/roll.js diff --git a/commands/user/roll.js b/commands/user/roll.js new file mode 100644 index 0000000..1b1447d --- /dev/null +++ b/commands/user/roll.js @@ -0,0 +1,23 @@ +exports.run = (client, message, args) => { + const rolls = {}; + let str = args.replace(/(\d*)d(\d+)/gi, (match, $1, $2) => { + $1 = $1 || 1; + const val = []; + for (let i = 0 ; i < $1 ; ++i) { + val.push(Math.floor((Math.random() * $2) + 1)); + } + return `(${val.join(' + ')})`; + }); + if (/[^\(\)\d\s\=\-\+\\\*]/.test(str)) { + return message.reply('je sais pas ce que tu essayes de faire ...') + } + + let val; + try { + val = new Function(`return ${str}`)(); + } catch(err) { + console.error(err); + return message.reply('je sais pas ce que tu essayes de faire ...') + } + message.reply(`${val}. Détail : ${str}`).catch(console.error); +} \ No newline at end of file From b9ebf3b6585a92001f6761fca1cafb2b11535129 Mon Sep 17 00:00:00 2001 From: Pandraghon Date: Fri, 26 May 2017 00:14:22 +0200 Subject: [PATCH 08/14] Update command handler and files structure --- app.js | 117 +++++++++---------------------- commands/admin/purge.js | 11 --- commands/cat.js | 29 ++++++++ commands/{admin => }/deafen.js | 16 ++++- commands/{admin => }/kick.js | 16 ++++- commands/{admin => }/mute.js | 16 ++++- commands/{user => }/poll.js | 18 ++++- commands/purge.js | 22 ++++++ commands/{user => }/roll.js | 16 ++++- commands/{admin => }/undeafen.js | 16 ++++- commands/{admin => }/unmute.js | 16 ++++- events/guildBanAdd.js | 12 ++++ events/guildBanRemove.js | 12 ++++ events/guildMemberUpdate.js | 41 ++++++++--- events/message.js | 107 ++++++++++++++++++++++++++++ package.json | 4 ++ settings.json | 2 + utils/log.js | 14 ++++ 18 files changed, 372 insertions(+), 113 deletions(-) delete mode 100644 commands/admin/purge.js create mode 100644 commands/cat.js rename commands/{admin => }/deafen.js (77%) rename commands/{admin => }/kick.js (75%) rename commands/{admin => }/mute.js (77%) rename commands/{user => }/poll.js (85%) create mode 100644 commands/purge.js rename commands/{user => }/roll.js (78%) rename commands/{admin => }/undeafen.js (77%) rename commands/{admin => }/unmute.js (77%) create mode 100644 events/guildBanAdd.js create mode 100644 events/guildBanRemove.js create mode 100644 events/message.js create mode 100644 utils/log.js diff --git a/app.js b/app.js index d81374c..b7c92b1 100644 --- a/app.js +++ b/app.js @@ -1,15 +1,28 @@ const Discord = require('discord.js'); const client = new Discord.Client(); -const settings = require('./settings.json'); -const secret = require('./secret.json'); -const Emoji = require("discord-emoji"); -const sql = require('sqlite'); const fs = require('fs'); +const settings = require('./settings.json'); +const token = require('./secret.json').token; +const Log = require('./utils/log.js'); -sql.open('./db.sqlite'); +client.commands = new Discord.Collection(); +client.aliases = new Discord.Collection(); + +fs.readdir('./commands/', (err, files) => { + if (err) return Log.error(err); + Log.info(`Loading a total of ${files.length} commands.`); + files.forEach(file => { + const props = require(`./commands/${file}`); + Log.info(`Loading command: ${props.help.name}.`); + client.commands.set(props.help.name, props); + props.conf.aliases.forEach(alias => { + client.aliases.set(alias, props.help.name); + }); + }); +}); fs.readdir('./events/', (err, files) => { - if (err) return console.error(err); + if (err) return Log.error(err); files.forEach(file => { const eventFunction = require(`./events/${file}`); const eventName = file.split('.')[0]; @@ -17,84 +30,18 @@ fs.readdir('./events/', (err, files) => { }); }); -const updateUserXP = (points, userId) => { - sql.get(`SELECT xp, level FROM users WHERE id = '${userId}'`).then(row => { - if (!row) { - sql.run('INSERT INTO users (id, xp, level) VALUES (?, ?, ?)', [userId, 1, 0]); - } else { - sql.run(`UPDATE users SET xp = ${row.xp + points} WHERE id = ${userId}`) - } - }).catch(() => { - console.error; - sql.run('CREATE TABLE IF NOT EXISTS users (id TEXT, xp INTEGER, level INTEGER)').then(() => { - sql.run('INSERT INTO users (id, xp, level) VALUES (?, ?, ?)', [userId, 1, 0]); - }); - }); +client.elevation = (message) => { + let level; + const role = message.member.highestRole; + switch (role.name) { + case 'superadmin': level = 10; break; + case 'admin': level = 5; break; + case 'bot': case 'dev': level = 3; break; + case 'boy': case 'girl': level = 2; break; + default: level = 0; + } + if (message.author.id === settings.ownerid) level = 90; + return level; }; -client.on('message', message => { - let matches; - - if (message.channel.type === 'text') { - updateUserXP(1, message.author.id); - } - - if (/^ping$/i.test(message.content) /*&& !/^(?:236198969019990018|220333308569976834)$/.test(message.author.id)*/ ) { - message.channel.send('pong', { tts: true }); - } - if (/my avatar/i.test(message.content)) { - message.reply(message.author.avatarURL); - } - if (/(?:^| )ch?ats?(?: |$)/i.test(message.content)) { - message.react(Emoji.nature.cat); - } - if (/(?:^| )(?:chien|dog)s?(?: |$)/i.test(message.content)) { - message.react(Emoji.nature.dog); - } - if (/\(\╯\°\□\°\)\╯\︵\ \┻\━\┻/.test(message.content)) { - message.reply('PUT. THE. TABLE. BACK.'); - } - if ((matches = message.content.match(/^([a-zA-Z])$/))) { - let c = message.content.charCodeAt(0); - switch (c) { - case 'Z': - c = 'A'; - case 'z': - c = 'a'; - default: - c = String.fromCharCode(++c); - } - message.reply(c); - } - if ((matches = message.content.match(/^([0-9]{1,15})$/))) { - message.reply(Number(matches[1]) + 1); - } - - const keys = Object.keys(settings.commands); - for (let key of keys) { - const commandGroup = settings.commands[key]; - if (message.content.startsWith(commandGroup.prefix)) { - if (!message.member.roles.some(role => settings.commands[key].roles.includes(role.name))) { - message.reply('tu n\'es pas autorisée à faire ça, bitch'); - } else { - const command = message.content.split(' ')[0].slice(commandGroup.prefix.length); - const args = message.content.slice(commandGroup.prefix.length + command.length + 1); - - if (/\.\./.test(command)) { - message.reply('Tu y as vraiment cru ?'); - break; - } - - try { - const commandFile = require(`./commands/${key}/${command}.js`); - commandFile.run(client, message, args); - } catch (err) { - console.error(err); - } - } - break; - } - } -}); - -client.login(secret.token); \ No newline at end of file +client.login(token); \ No newline at end of file diff --git a/commands/admin/purge.js b/commands/admin/purge.js deleted file mode 100644 index 976adf1..0000000 --- a/commands/admin/purge.js +++ /dev/null @@ -1,11 +0,0 @@ -const settings = require('../../settings.json'); - -exports.run = (client, message, args) => { - message.channel.messages.deleteAll().forEach(msg => { - msg.catch(error => { - const channel = message.guild.channels.find('name', settings.logs); - if (!channel) return; - channel.send(`Error while purging ${message.channel} : \`${error}\``); - }); - }); -} \ No newline at end of file diff --git a/commands/cat.js b/commands/cat.js new file mode 100644 index 0000000..5b42eca --- /dev/null +++ b/commands/cat.js @@ -0,0 +1,29 @@ +const request = require('request'); +const RichEmbed = require('discord.js').RichEmbed; +const Log = require('../utils/log.js'); + +exports.run = (client, message, args) => { + request('http://random.cat/meow', (err, resp, body) => { + if (err) return Log.error(err); + if (resp.statusCode === 200) { + message.channel.send({embed: new RichEmbed() + .setColor('DARK_RED') + .setImage(JSON.parse(body).file) + }).catch(console.error); + } + }) +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: ['pussy'], + permLevel: 2, + nsfw: false +}; + +exports.help = { + name: 'cat', + description: 'Moew.', + usage: 'cat' +}; \ No newline at end of file diff --git a/commands/admin/deafen.js b/commands/deafen.js similarity index 77% rename from commands/admin/deafen.js rename to commands/deafen.js index d8ef2d6..c5daf88 100644 --- a/commands/admin/deafen.js +++ b/commands/deafen.js @@ -14,4 +14,18 @@ exports.run = (client, message, args) => { message.mentions.users.forEach(user => { deafenMember(message.guild.member(user)); }); message.mentions.roles.forEach(role => { role.members.forEach(member => { deafenMember(member); }); }); -} \ No newline at end of file +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: ['+d'], + permLevel: 5, + nsfw: false +}; + +exports.help = { + name: 'deafen', + description: 'Deafens a member or a group', + usage: 'deafen ' +}; \ No newline at end of file diff --git a/commands/admin/kick.js b/commands/kick.js similarity index 75% rename from commands/admin/kick.js rename to commands/kick.js index 9786bda..bef0ce4 100644 --- a/commands/admin/kick.js +++ b/commands/kick.js @@ -12,4 +12,18 @@ exports.run = (client, message, args) => { kickMember.kick().then(member => { message.reply(`${member.user.username} a dégagé.`).catch(console.error); }).catch(console.error) -} \ No newline at end of file +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: [], + permLevel: 5, + nsfw: false +}; + +exports.help = { + name: 'kick', + description: 'Kicks a member', + usage: 'kick ' +}; \ No newline at end of file diff --git a/commands/admin/mute.js b/commands/mute.js similarity index 77% rename from commands/admin/mute.js rename to commands/mute.js index 9c061c3..75c04ff 100644 --- a/commands/admin/mute.js +++ b/commands/mute.js @@ -14,4 +14,18 @@ exports.run = (client, message, args) => { message.mentions.users.forEach(user => { muteMember(message.guild.member(user)); }); message.mentions.roles.forEach(role => { role.members.forEach(member => { muteMember(member); }); }); -} \ No newline at end of file +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: ['+m'], + permLevel: 5, + nsfw: false +}; + +exports.help = { + name: 'mute', + description: 'Mutes a member or a group', + usage: 'mute ' +}; \ No newline at end of file diff --git a/commands/user/poll.js b/commands/poll.js similarity index 85% rename from commands/user/poll.js rename to commands/poll.js index 2405e54..89209e9 100644 --- a/commands/user/poll.js +++ b/commands/poll.js @@ -1,4 +1,4 @@ -const settings = require('../../settings.json'); +const settings = require('../settings.json'); const Emoji = require("discord-emoji"); exports.run = (client, message, args) => { @@ -42,4 +42,18 @@ exports.run = (client, message, args) => { } else { message.channel.send('Pas comme ça qu\'ça s\'écrit !'); } -} \ No newline at end of file +}; + +exports.conf = { + enabled: true, + guildOnly: false, + aliases: ['p?'], + permLevel: 2, + nsfw: false +}; + +exports.help = { + name: 'poll', + description: 'Creates a poll', + usage: 'poll [] ()' +}; \ No newline at end of file diff --git a/commands/purge.js b/commands/purge.js new file mode 100644 index 0000000..7941a53 --- /dev/null +++ b/commands/purge.js @@ -0,0 +1,22 @@ +const settings = require('../settings.json'); + +exports.run = (client, message, args) => { + const messageCount = parseInt(args) || 50; + const logs = message.guild.channels.find('name', settings.logs); + const channel = message.channel; + channel.fetchMessages({ limit: messageCount }).then(messages => messages.deleteAll()); +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: ['clear'], + permLevel: 5, + nsfw: false +}; + +exports.help = { + name: 'purge', + description: 'Purges a channel', + usage: 'purge ' +}; \ No newline at end of file diff --git a/commands/user/roll.js b/commands/roll.js similarity index 78% rename from commands/user/roll.js rename to commands/roll.js index 1b1447d..43986ce 100644 --- a/commands/user/roll.js +++ b/commands/roll.js @@ -20,4 +20,18 @@ exports.run = (client, message, args) => { return message.reply('je sais pas ce que tu essayes de faire ...') } message.reply(`${val}. Détail : ${str}`).catch(console.error); -} \ No newline at end of file +}; + +exports.conf = { + enabled: true, + guildOnly: false, + aliases: [], + permLevel: 2, + nsfw: false +}; + +exports.help = { + name: 'roll', + description: 'Rolls some dice', + usage: 'roll ' +}; \ No newline at end of file diff --git a/commands/admin/undeafen.js b/commands/undeafen.js similarity index 77% rename from commands/admin/undeafen.js rename to commands/undeafen.js index c4b163d..62689ff 100644 --- a/commands/admin/undeafen.js +++ b/commands/undeafen.js @@ -14,4 +14,18 @@ exports.run = (client, message, args) => { message.mentions.users.forEach(user => { undeafenMember(message.guild.member(user)); }); message.mentions.roles.forEach(role => { role.members.forEach(member => { undeafenMember(member); }); }); -} \ No newline at end of file +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: ['-d'], + permLevel: 5, + nsfw: false +}; + +exports.help = { + name: 'undeafen', + description: 'Undeafens a member or a group', + usage: 'undeafen ' +}; \ No newline at end of file diff --git a/commands/admin/unmute.js b/commands/unmute.js similarity index 77% rename from commands/admin/unmute.js rename to commands/unmute.js index 54b87a0..26b3244 100644 --- a/commands/admin/unmute.js +++ b/commands/unmute.js @@ -14,4 +14,18 @@ exports.run = (client, message, args) => { message.mentions.users.forEach(user => { unmuteMember(message.guild.member(user)); }); message.mentions.roles.forEach(role => { role.members.forEach(member => { unmuteMember(member); }); }); -} \ No newline at end of file +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: ['-m'], + permLevel: 5, + nsfw: false +}; + +exports.help = { + name: 'unmute', + description: 'Unmutes a member or a group', + usage: 'unmute ' +}; \ No newline at end of file diff --git a/events/guildBanAdd.js b/events/guildBanAdd.js new file mode 100644 index 0000000..28c4321 --- /dev/null +++ b/events/guildBanAdd.js @@ -0,0 +1,12 @@ +const settings = require('../settings.json'); +const Emoji = require("discord-emoji"); + +exports.run = (client, member) => { + member.guild.defaultChannel.send(`${member} est maintenant banni !`).then(message => { + message.react(Emoji.people.smiling_imp); + }); + + const channel = member.guild.channels.find('name', settings.logs); + if (!channel) return; + channel.send(`banned member : ${member}`); +}; \ No newline at end of file diff --git a/events/guildBanRemove.js b/events/guildBanRemove.js new file mode 100644 index 0000000..1c5201b --- /dev/null +++ b/events/guildBanRemove.js @@ -0,0 +1,12 @@ +const settings = require('../settings.json'); +const Emoji = require("discord-emoji"); + +exports.run = (client, member) => { + member.guild.defaultChannel.send(`${member} n'est plus banni !`).then(message => { + message.react(Emoji.people.innocent); + }); + + const channel = member.guild.channels.find('name', settings.logs); + if (!channel) return; + channel.send(`unbanned member : ${member}`); +}; \ No newline at end of file diff --git a/events/guildMemberUpdate.js b/events/guildMemberUpdate.js index f2582b6..4e1a2e6 100644 --- a/events/guildMemberUpdate.js +++ b/events/guildMemberUpdate.js @@ -1,14 +1,37 @@ const settings = require('../settings.json'); +const ddiff = require('deep-diff').diff; exports.run = (client, oldMember, newMember) => { - const channel = newMember.guild.channels.find('name', settings.logs); - if (!channel) return; - const newRoles = newMember.roles.filter(role => !oldMember.roles.has(role.id)).map(role => role.name); - const removedRoles = oldMember.roles.filter(role => !newMember.roles.has(role.id)).map(role => role.name); - - let message = `${oldMember} changed :`; - if (newRoles.length > 0) message += `\n - New roles : \`${newRoles.join('\`, \`')}\``; - if (removedRoles.length > 0) message += `\n - Removed roles : \`${removedRoles.join('\`, \`')}\``; - + const channel = newMember.guild.channels.find('name', settings.logs); + if (!channel) return; + + const differences = ddiff(oldMember, newMember); + const getData = (el, obj, data) => { + if (el.path[0] === '_roles') { + data = obj.guild.roles.get(data); + } + return data; + }; + const translateDiff = (el) => { + const name = el.path && el.path.join('.') || ''; + switch (el.kind) { + case 'N': + return `added : ${name} (${getData(el, newMember, el.rhs)})`; + case 'D': + return `removed : ${name} (${getData(el, oldMember, el.lhs)})`; + case 'E': + return `edited : ${name} (${getData(el, oldMember, el.lhs)} => ${getData(el, newMember, el.rhs)})`; + case 'A': + el = Object.assign({}, el, el.item); + el.path.push(el.index); + return translateDiff(el); + } + }; + + let message = `${oldMember} changed :`; + for (let d of differences) { + message += `\n - ${translateDiff(d)}`; + } + channel.send(message); }; \ No newline at end of file diff --git a/events/message.js b/events/message.js new file mode 100644 index 0000000..3e212cf --- /dev/null +++ b/events/message.js @@ -0,0 +1,107 @@ +const sql = require('sqlite'); +const Emoji = require("discord-emoji"); +const settings = require('../settings.json'); + +sql.open('./db.sqlite'); + +const updateUserXP = (points, userId) => { + sql.get(`SELECT xp, level FROM users WHERE id = '${userId}'`).then(row => { + if (!row) { + sql.run('INSERT INTO users (id, xp, level) VALUES (?, ?, ?)', [userId, 1, 0]); + } else { + sql.run(`UPDATE users SET xp = ${row.xp + points} WHERE id = ${userId}`) + } + }).catch(() => { + console.error; + sql.run('CREATE TABLE IF NOT EXISTS users (id TEXT, xp INTEGER, level INTEGER)').then(() => { + sql.run('INSERT INTO users (id, xp, level) VALUES (?, ?, ?)', [userId, 1, 0]); + }); + }); +}; + +exports.run = (client, message) => { + let matches; + + if (message.channel.type === 'text') { + updateUserXP(1, message.author.id); + } + + if (/^ping$/i.test(message.content) /*&& !/^(?:236198969019990018|220333308569976834)$/.test(message.author.id)*/ ) { + message.channel.send('pong', { tts: true }); + } + if (/my avatar/i.test(message.content)) { + message.reply(message.author.avatarURL); + } + if (/(?:^| )ch?ats?(?: |$)/i.test(message.content)) { + message.react(Emoji.nature.cat); + } + if (/(?:^| )(?:chien|dog)s?(?: |$)/i.test(message.content)) { + message.react(Emoji.nature.dog); + } + if (/\(\╯\°\□\°\)\╯\︵\ \┻\━\┻/.test(message.content)) { + message.reply('PUT. THE. TABLE. BACK.'); + } + if ((matches = message.content.match(/^([a-zA-Z])$/))) { + let c = message.content.charCodeAt(0); + switch (c) { + case 'Z': + c = 'A'; + case 'z': + c = 'a'; + default: + c = String.fromCharCode(++c); + } + message.reply(c); + } + if ((matches = message.content.match(/^([0-9]{1,15})$/))) { + message.reply(Number(matches[1]) + 1); + } + + if (message.content.startsWith(settings.prefix)) { + const command = message.content.slice(settings.prefix.length).split(' ')[0]; + const args = message.content.slice(settings.prefix.length + command.length + 1); + const perms = client.elevation(message); + let cmd; + + if (client.commands.has(command)) { + cmd = client.commands.get(command); + } else if (client.aliases.has(command)) { + cmd = client.commands.get(client.aliases.get(command)); + } + + if (cmd) { + if (perms < cmd.conf.permLevel) return; + try { + cmd.run(client, message, args); + } catch (err) { + console.error(err); + } + } + } + + /*const keys = Object.keys(settings.commands); + for (let key of keys) { + const commandGroup = settings.commands[key]; + if (message.content.startsWith(commandGroup.prefix)) { + if (!message.member.roles.some(role => settings.commands[key].roles.includes(role.name))) { + message.reply('tu n\'es pas autorisée à faire ça, bitch'); + } else { + const command = message.content.split(' ')[0].slice(commandGroup.prefix.length); + const args = message.content.slice(commandGroup.prefix.length + command.length + 1); + + if (/\.\./.test(command)) { + message.reply('Tu y as vraiment cru ?'); + break; + } + + try { + const commandFile = require(`../commands/${key}/${command}.js`); + commandFile.run(client, message, args); + } catch (err) { + console.error(err); + } + } + break; + } + }*/ +}; \ No newline at end of file diff --git a/package.json b/package.json index c6ad31d..97945a9 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,12 @@ "author": "Pandraghon", "license": "MIT", "dependencies": { + "deep-diff": "^0.3.8", "discord-emoji": "^1.1.1", "discord.js": "^11.1.0", + "moment": "^2.18.1", + "node-opus": "^0.2.6", + "request": "^2.81.0", "sqlite": "^2.7.0" } } diff --git a/settings.json b/settings.json index 934f85a..4986cf7 100644 --- a/settings.json +++ b/settings.json @@ -1,5 +1,7 @@ { "logs": "logs", + "ownerid": "235515918879293440", + "prefix": "hal ", "commands": { "base": { "prefix": "!", diff --git a/utils/log.js b/utils/log.js new file mode 100644 index 0000000..307e153 --- /dev/null +++ b/utils/log.js @@ -0,0 +1,14 @@ +const moment = require('moment'); + +exports.log = (msg) => { + console.log(`[${moment().format('YYYY-MM-DD HH:mm:ss')}] `, msg); +}; +exports.warn = (msg) => { + console.warn(`[${moment().format('YYYY-MM-DD HH:mm:ss')}] `, msg); +}; +exports.error = (msg) => { + console.error(`[${moment().format('YYYY-MM-DD HH:mm:ss')}] `, msg); +}; +exports.info = (msg) => { + console.info(`[${moment().format('YYYY-MM-DD HH:mm:ss')}] `, msg); +}; \ No newline at end of file From 57ac349288ee7951d54f0420788107a633d66bd5 Mon Sep 17 00:00:00 2001 From: Pandraghon Date: Fri, 26 May 2017 00:15:10 +0200 Subject: [PATCH 09/14] Add help and misc command --- commands/ass.js | 32 ++++++++++++++++++++++++++++++++ commands/boobs.js | 32 ++++++++++++++++++++++++++++++++ commands/help.js | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 commands/ass.js create mode 100644 commands/boobs.js create mode 100644 commands/help.js diff --git a/commands/ass.js b/commands/ass.js new file mode 100644 index 0000000..7d907dc --- /dev/null +++ b/commands/ass.js @@ -0,0 +1,32 @@ +const request = require('request'); +const RichEmbed = require('discord.js').RichEmbed; +const Log = require('../utils/log.js'); + +exports.run = (client, message, args) => { + if (!message.channel.nsfw) { + return message.reply('Grossier personnage !').catch(console.error); + } + request('http://api.obutts.ru/butts/0/1/random', (err, resp, body) => { + if (err) return Log.error(err); + if (resp.statusCode === 200) { + message.channel.send({embed: new RichEmbed() + .setColor('DARK_RED') + .setImage(`http://media.obutts.ru/${JSON.parse(body)[0].preview}`) + }).catch(console.error); + } + }) +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: ['butt'], + permLevel: 2, + nsfw: true +}; + +exports.help = { + name: 'ass', + description: 'Writes some poem.', + usage: 'ass' +}; \ No newline at end of file diff --git a/commands/boobs.js b/commands/boobs.js new file mode 100644 index 0000000..4632518 --- /dev/null +++ b/commands/boobs.js @@ -0,0 +1,32 @@ +const request = require('request'); +const RichEmbed = require('discord.js').RichEmbed; +const Log = require('../utils/log.js'); + +exports.run = (client, message, args) => { + if (!message.channel.nsfw) { + return message.reply('Grossier personnage !').catch(console.error); + } + request('http://api.oboobs.ru/boobs/0/1/random', (err, resp, body) => { + if (err) return Log.error(err); + if (resp.statusCode === 200) { + message.channel.send({embed: new RichEmbed() + .setColor('DARK_RED') + .setImage(`http://media.oboobs.ru/${JSON.parse(body)[0].preview}`) + }).catch(console.error); + } + }) +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: ['boobies'], + permLevel: 2, + nsfw: true +}; + +exports.help = { + name: 'boobs', + description: 'Writes some poem.', + usage: 'boobs' +}; \ No newline at end of file diff --git a/commands/help.js b/commands/help.js new file mode 100644 index 0000000..1b4a800 --- /dev/null +++ b/commands/help.js @@ -0,0 +1,35 @@ +const settings = require('../settings.json'); + +exports.run = (client, message, args) => { + if (!args) { + let commands = client.commands; + const perms = client.elevation(message); + commands = commands.filter(cmd => perms >= cmd.conf.permLevel); + if (!message.channel.nsfw) commands = commands.filter(cmd => !cmd.conf.nsfw); + const commandNames = Array.from(commands.keys()); + const longest = commandNames.reduce((long, str) => Math.max(long, str.length), 0); + let msg = `Command List\n\n[Use '${settings.prefix}${exports.help.name} ' for details]\n\n`; + msg += commands.map(cmd => `${settings.prefix}${cmd.help.name}${' '.repeat(longest - cmd.help.name.length)} > ${cmd.help.description}`).join('\n'); + message.channel.send(msg, {code: 'asciidoc'}); + } else { + if (client.commands.has(args)) { + const command = client.commands.get(args); + const msg = `${command.help.name}\n${command.help.description}\nusage: ${command.help.usage}`; + message.channel.send(msg, {code: 'asciidoc'}); + } + } +}; + +exports.conf = { + enabled: true, + guildOnly: false, + aliases: ['h'], + permLevel: 0, + nsfw: false +}; + +exports.help = { + name: 'help', + description: 'Displays all available commands for your permission level.', + usage: 'help [command]' +}; \ No newline at end of file From 8c4ed1304e454cffb5d4ec90fe46856e22d4f34d Mon Sep 17 00:00:00 2001 From: Pandraghon Date: Sat, 27 May 2017 15:03:41 +0200 Subject: [PATCH 10/14] Add dog command and command feedbacks --- app.js | 13 +++++++++++++ commands/ass.js | 3 --- commands/boobs.js | 3 --- commands/cat.js | 2 +- commands/dog.js | 29 +++++++++++++++++++++++++++++ events/message.js | 9 ++++++++- 6 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 commands/dog.js diff --git a/app.js b/app.js index b7c92b1..7a27fd6 100644 --- a/app.js +++ b/app.js @@ -1,10 +1,23 @@ const Discord = require('discord.js'); +const Emoji = require("discord-emoji"); const client = new Discord.Client(); const fs = require('fs'); const settings = require('./settings.json'); const token = require('./secret.json').token; const Log = require('./utils/log.js'); +Discord.Message.prototype.markAsDone = function() { + this.react(Emoji.symbols.o).catch(Log.error); +}; + +Discord.Message.prototype.markAsError = function() { + this.react(Emoji.symbols.x).catch(Log.error); +}; + +Discord.Message.prototype.markAsQuestion = function() { + this.react(Emoji.symbols.question).catch(Log.error); +}; + client.commands = new Discord.Collection(); client.aliases = new Discord.Collection(); diff --git a/commands/ass.js b/commands/ass.js index 7d907dc..6a392f8 100644 --- a/commands/ass.js +++ b/commands/ass.js @@ -3,9 +3,6 @@ const RichEmbed = require('discord.js').RichEmbed; const Log = require('../utils/log.js'); exports.run = (client, message, args) => { - if (!message.channel.nsfw) { - return message.reply('Grossier personnage !').catch(console.error); - } request('http://api.obutts.ru/butts/0/1/random', (err, resp, body) => { if (err) return Log.error(err); if (resp.statusCode === 200) { diff --git a/commands/boobs.js b/commands/boobs.js index 4632518..2cb2ba4 100644 --- a/commands/boobs.js +++ b/commands/boobs.js @@ -3,9 +3,6 @@ const RichEmbed = require('discord.js').RichEmbed; const Log = require('../utils/log.js'); exports.run = (client, message, args) => { - if (!message.channel.nsfw) { - return message.reply('Grossier personnage !').catch(console.error); - } request('http://api.oboobs.ru/boobs/0/1/random', (err, resp, body) => { if (err) return Log.error(err); if (resp.statusCode === 200) { diff --git a/commands/cat.js b/commands/cat.js index 5b42eca..fc562c1 100644 --- a/commands/cat.js +++ b/commands/cat.js @@ -17,7 +17,7 @@ exports.run = (client, message, args) => { exports.conf = { enabled: true, guildOnly: true, - aliases: ['pussy'], + aliases: ['pussy', 'moew'], permLevel: 2, nsfw: false }; diff --git a/commands/dog.js b/commands/dog.js new file mode 100644 index 0000000..34435e3 --- /dev/null +++ b/commands/dog.js @@ -0,0 +1,29 @@ +const request = require('request'); +const RichEmbed = require('discord.js').RichEmbed; +const Log = require('../utils/log.js'); + +exports.run = (client, message, args) => { + request('https://random.dog/woof.json', (err, resp, body) => { + if (err) return Log.error(err); + if (resp.statusCode === 200) { + message.channel.send({embed: new RichEmbed() + .setColor('DARK_RED') + .setImage(JSON.parse(body).url) + }).catch(console.error); + } + }) +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: ['bitch', 'woof'], + permLevel: 2, + nsfw: false +}; + +exports.help = { + name: 'dog', + description: 'Woof.', + usage: 'dog' +}; \ No newline at end of file diff --git a/events/message.js b/events/message.js index 3e212cf..4ad61b5 100644 --- a/events/message.js +++ b/events/message.js @@ -70,7 +70,14 @@ exports.run = (client, message) => { } if (cmd) { - if (perms < cmd.conf.permLevel) return; + if (perms < cmd.conf.permLevel) { + message.markAsError(); + return message.reply('tu n\'es pas autorisé à faire ça.'); + } + if (cmd.conf.nsfw && !message.channel.nsfw) { + message.markAsError(); + return message.reply('Grossier personnage !').catch(console.error); + } try { cmd.run(client, message, args); } catch (err) { From 975185a492029699b5a267322e44efd24b6823b3 Mon Sep 17 00:00:00 2001 From: Pandraghon Date: Sun, 28 May 2017 22:30:46 +0200 Subject: [PATCH 11/14] Conf for guild only commands --- commands/help.js | 2 +- commands/poll.js | 2 +- events/message.js | 11 +++++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/commands/help.js b/commands/help.js index 1b4a800..c922069 100644 --- a/commands/help.js +++ b/commands/help.js @@ -22,7 +22,7 @@ exports.run = (client, message, args) => { exports.conf = { enabled: true, - guildOnly: false, + guildOnly: true, aliases: ['h'], permLevel: 0, nsfw: false diff --git a/commands/poll.js b/commands/poll.js index 89209e9..3c04a7f 100644 --- a/commands/poll.js +++ b/commands/poll.js @@ -46,7 +46,7 @@ exports.run = (client, message, args) => { exports.conf = { enabled: true, - guildOnly: false, + guildOnly: true, aliases: ['p?'], permLevel: 2, nsfw: false diff --git a/events/message.js b/events/message.js index 4ad61b5..507e46c 100644 --- a/events/message.js +++ b/events/message.js @@ -60,7 +60,6 @@ exports.run = (client, message) => { if (message.content.startsWith(settings.prefix)) { const command = message.content.slice(settings.prefix.length).split(' ')[0]; const args = message.content.slice(settings.prefix.length + command.length + 1); - const perms = client.elevation(message); let cmd; if (client.commands.has(command)) { @@ -70,13 +69,17 @@ exports.run = (client, message) => { } if (cmd) { - if (perms < cmd.conf.permLevel) { + if (cmd.conf.guildOnly && !message.guild) { message.markAsError(); - return message.reply('tu n\'es pas autorisé à faire ça.'); + return message.reply('you have to be in a guild channel.').catch(console.error); + } + if (client.elevation(message) < cmd.conf.permLevel) { + message.markAsError(); + return message.reply('you are not allowed to do that.').catch(console.error); } if (cmd.conf.nsfw && !message.channel.nsfw) { message.markAsError(); - return message.reply('Grossier personnage !').catch(console.error); + return message.reply('you are way too pervert for this channel !').catch(console.error); } try { cmd.run(client, message, args); From d237cac921a8b94cb4413c55153b20218926bcfe Mon Sep 17 00:00:00 2001 From: Pandraghon Date: Mon, 12 Jun 2017 18:30:21 +0200 Subject: [PATCH 12/14] Adding Travis CI --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..99d549f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +language: node_js +node_js: + - "node" + +cache: + directories: + - node_modules \ No newline at end of file From 6279a10f3fc6763d7aaab88e82732f381beb64fd Mon Sep 17 00:00:00 2001 From: Pandraghon Date: Mon, 12 Jun 2017 18:39:41 +0200 Subject: [PATCH 13/14] Update .travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 99d549f..1aee2d4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: node_js node_js: - "node" - +install: npm install cache: directories: - - node_modules \ No newline at end of file + - node_modules From 44d9dcb6c492a5bea4147d1cf7a475c774a68f36 Mon Sep 17 00:00:00 2001 From: Pandraghon Date: Mon, 12 Jun 2017 18:41:47 +0200 Subject: [PATCH 14/14] Create .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1aee2d4..ae9615c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - "node" + - "7" install: npm install cache: directories: