diff --git a/.gitignore b/.gitignore index bbb3670c..5c23c14a 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ report*.json config.json command-leaderboard.json command-last-run.json +blacklist.json # Tesseract Trained Data *.traineddata diff --git a/Xiao.js b/Xiao.js index dec5c945..2e10ab56 100644 --- a/Xiao.js +++ b/Xiao.js @@ -86,6 +86,14 @@ client.on('ready', async () => { }, client.memePoster.postInterval); } + // Import blacklist + try { + const results = client.importBlacklist(); + if (!results) client.logger.error('[BLACKLIST] blacklist.json is not formatted correctly.'); + } catch (err) { + client.logger.error(`[BLACKLIST] Could not parse blacklist.json:\n${err.stack}`); + } + // Import command-leaderboard.json try { const results = client.importCommandLeaderboard(); @@ -138,6 +146,10 @@ client.on('message', async msg => { }); client.on('guildCreate', async guild => { + if (client.blacklist.guild.includes(guild.id) || client.blacklist.user.includes(guild.ownerID)) { + guild.leave(); + return; + } if (guild.systemChannel && guild.systemChannel.permissionsFor(client.user).has('SEND_MESSAGES')) { try { const usage = client.registry.commands.get('help').usage(); @@ -207,6 +219,12 @@ client.on('commandRun', command => { command.lastRun = new Date(); }); +client.dispatcher.addInhibitor(msg => { + if (client.blacklist.user.includes(msg.author.id)) return 'blacklisted'; + if (client.blacklist.guild.includes(msg.guild.id)) return 'blacklisted'; + return false; +}); + client.on('commandError', (command, err) => client.logger.error(`[COMMAND:${command.name}]\n${err.stack}`)); client.login(XIAO_TOKEN); diff --git a/commands/util-public/report.js b/commands/util-public/report.js index 8e545bc5..c77bfbbb 100644 --- a/commands/util-public/report.js +++ b/commands/util-public/report.js @@ -1,15 +1,15 @@ const Command = require('../../structures/Command'); const { MessageEmbed } = require('discord.js'); const { list } = require('../../util/Util'); -const reasons = ['bug', 'feedback', 'suggestion']; -const reasonColors = ['RED', 'GREEN', 'YELLOW']; -const displayReasons = ['🐛 Bug Report', '📬 Feedback', '❓ Suggestion']; +const reasons = ['bug', 'feedback', 'suggestion', 'abuse']; +const reasonColors = ['RED', 'GREEN', 'YELLOW', 'ORANGE']; +const displayReasons = ['🐛 Bug Report', '📬 Feedback', '❓ Suggestion', '⚠️ Abuse']; module.exports = class ReportCommand extends Command { constructor(client) { super(client, { name: 'report', - aliases: ['bug', 'report-bug', 'feedback', 'contact', 'suggest', 'suggestion'], + aliases: ['bug', 'report-bug', 'feedback', 'contact', 'suggest', 'suggestion', 'abuse', 'report-abuse'], group: 'util-public', memberName: 'report', description: 'Reports something to the bot owner(s).', @@ -24,7 +24,7 @@ module.exports = class ReportCommand extends Command { }, { key: 'message', - prompt: 'What is the message of your report?', + prompt: 'What is the message of your report? If you are reporting abuse, be sure to include IDs.', type: 'string' } ] diff --git a/commands/util/blacklist.js b/commands/util/blacklist.js new file mode 100644 index 00000000..8042889d --- /dev/null +++ b/commands/util/blacklist.js @@ -0,0 +1,37 @@ +const Command = require('../../structures/Command'); +const { list } = require('../../util/Util'); +const types = ['user', 'guild']; + +module.exports = class BlacklistCommand extends Command { + constructor(client) { + super(client, { + name: 'blacklist', + group: 'util', + memberName: 'blacklist', + description: 'Blacklists a user or server.', + details: 'Only the bot owner(s) may use this command.', + ownerOnly: true, + guarded: true, + args: [ + { + key: 'type', + prompt: `What type do you want to blacklist? Either ${list(types, 'or')}.`, + type: 'string', + oneOf: types, + parse: type => type.toLowerCase() + }, + { + key: 'target', + prompt: 'What do you want to blacklist? Use the ID.', + type: 'string' + } + ] + }); + } + + run(msg, { type, target }) { + this.client.blacklist[type].push(target); + this.client.exportBlacklist(); + return msg.say(`🔨 Blacklisted ${type} \`${target}\`.`); + } +}; diff --git a/package.json b/package.json index 9892e514..f81ebfac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiao", - "version": "129.6.0", + "version": "129.7.0", "description": "Your personal server companion.", "main": "Xiao.js", "scripts": { diff --git a/structures/Client.js b/structures/Client.js index 9a8d6b75..04272aa2 100644 --- a/structures/Client.js +++ b/structures/Client.js @@ -35,6 +35,7 @@ module.exports = class XiaoClient extends CommandoClient { this.redis = Redis ? Redis.db : null; this.webhook = new WebhookClient(XIAO_WEBHOOK_ID, XIAO_WEBHOOK_TOKEN, { disableMentions: 'everyone' }); this.timers = new TimerManager(this); + this.blacklist = { guild: [], user: [] }; this.pokemon = new PokemonStore(); this.memePoster = POSTER_ID && POSTER_TOKEN ? new MemePosterClient(POSTER_ID, POSTER_TOKEN, { subreddits, @@ -62,6 +63,39 @@ module.exports = class XiaoClient extends CommandoClient { || (origin.guild && origin.topic.includes(``)); } + importBlacklist() { + const read = fs.readFileSync(path.join(__dirname, '..', 'blacklist.json'), { encoding: 'utf8' }); + const file = JSON.parse(read); + if (typeof file !== 'object' || Array.isArray(file)) return null; + if (!file.guild || !file.user) return null; + for (const id of file.guild) { + if (typeof value !== 'string') continue; + this.blacklist.guild.push(id); + } + for (const id of file.user) { + if (typeof value !== 'string') continue; + this.blacklist.user.push(id); + } + return file; + } + + exportBlacklist() { + let text = '{\n "guild": [\n '; + for (const id of this.blacklist.guild) { + text += `"${id}",`; + } + text = text.slice(0, -1); + text += '\n ]\n },\n "user": [\n '; + for (const id of this.blacklist.user) { + text += `"${id}",`; + } + text = text.slice(0, -1); + text += '\n ]\n }\n}\n'; + const buf = Buffer.from(text); + fs.writeFileSync(path.join(__dirname, '..', 'blacklist.json'), buf, { encoding: 'utf8' }); + return buf; + } + importCommandLeaderboard() { const read = fs.readFileSync(path.join(__dirname, '..', 'command-leaderboard.json'), { encoding: 'utf8'