diff --git a/bot.js b/bot.js index 850ec24..371d57f 100644 --- a/bot.js +++ b/bot.js @@ -22,6 +22,7 @@ class Bot { this.maindb = null; this.presences = []; this.guildHandlers = []; + this.userRates = {}; logger.verbose('Verifying config'); @@ -294,13 +295,24 @@ class Bot { logger.verbose(`ME: ${msg.content}`); return; } - logger.verbose(`<${msg.author.tag}>: ${msg.content}`); - if (!msg.guild) { - let reply = cmd.parseMessage(msg); - this.answerMessage(msg, reply); - } else { - let gh = await this.getGuildHandler(msg.guild, prefix); - await gh.handleMessage(msg); + if (this.checkRate(msg.author.tag)) { + logger.verbose(`<${msg.author.tag}>: ${msg.content}`); + if (!msg.guild) { + let reply = cmd.parseMessage(msg); + await this.answerMessage(msg, reply); + } else { + let gh = await this.getGuildHandler(msg.guild, prefix); + await gh.handleMessage(msg); + } + if (((Date.now() - this.userRates[msg.author.tag].last)/1000) > (config.rateLimitTime || 10)) + this.userRates[msg.author.tag].count = 0; + else + this.userRates[msg.author.tag].count++; + this.userRates[msg.author.tag].last = Date.now(); + this.userRates[msg.author.tag].reached = false; + } else if (!this.userRates[msg.author.tag].reached) { + logger.verbose(`${msg.author.tag} reached it's rate limit.`); + this.userRates[msg.author.tag].reached = true; } } catch (err) { logger.error(err.message); @@ -320,6 +332,18 @@ class Bot { }); } + /** + * Returns true if the user has not reached it's rate limit. + * @param usertag + * @returns {boolean} + */ + checkRate(usertag) { + if (!this.userRates[usertag]) + this.userRates[usertag] = {last: Date.now(), count: 0}; + return ((Date.now() - this.userRates[usertag].last)/1000) > (config.rateLimitTime || 10) || + this.userRates[usertag].count < (config.rateLimitCount || 5); + } + /** * Sends the answer recieved from the commands callback. * Handles the sending differently depending on the type of the callback return diff --git a/commands/servercommands.json b/commands/servercommands.json index 3fc3886..e83b393 100644 --- a/commands/servercommands.json +++ b/commands/servercommands.json @@ -12,7 +12,8 @@ "description": "Saves a sequence of commands under a new name. ~save [cmdsequence] [cmdname]. Semicoli must be escaped with \\ (Backslash)", "category": "Utility", "response": { - "no_recursion": "You are **not** allowed to execute another saved command in this sequence. This is a safety measure to avoid endlessly recursive calls." + "no_recursion": "You are **not** allowed to execute another saved command in this sequence. This is a safety measure to avoid endlessly recursive calls.", + "sequence_too_long": "This command sequence is too long!" } }, "savedcmd": { diff --git a/lib/cmd.js b/lib/cmd.js index 508ff95..697834e 100644 --- a/lib/cmd.js +++ b/lib/cmd.js @@ -155,7 +155,7 @@ exports.Servant = class { let commands = content.split(/(? x.replace(/^ +/, '')); if (commands.length === 1) { return this.processCommand(msg, globResult, content); - } else { + } else if (commands.length < (config.maxCmdSequenceLength || 5)) { let answers = []; let previousCommand = (commands[0].match(/^.\w+/) || [])[0];; for (let i = 0; i < commands.length; i++) { @@ -166,6 +166,8 @@ exports.Servant = class { } return answers; + } else { + return 'This command sequence is too long!'; } } @@ -272,7 +274,7 @@ function parseGlobalCommand(msg) { return false; logger.debug(`Permission <${cmd.role}> granted for command ${command} for user <${msg.author.tag}>`); return processCommand(cmd, msg, content); - } else { + } else if (commands.length < (config.maxCmdSequenceLength || 5)) { let answers = []; let previousCommand = ''; for (let commandPart of commands) { @@ -296,6 +298,8 @@ function parseGlobalCommand(msg) { } } return answers; + } else { + return 'This command sequence is too long!'; } } diff --git a/lib/guilding.js b/lib/guilding.js index 33a8033..0af2aa2 100644 --- a/lib/guilding.js +++ b/lib/guilding.js @@ -304,16 +304,18 @@ exports.GuildHandler = class { // savecmd - saves a command sequence with a name this.servant.createCommand(servercmd.utils.savecmd, async (msg, kwargs, argv) => { let saveName = argv.pop(); + let cmdsequence = argv.join(' ').replace(/\\/g, ''); if (argv.includes(this.prefix + servercmd.utils.execute.name)) { return servercmd.utils.savecmd.response.no_recursion; - } else { - let cmdsequence = argv.join(' ').replace(/\\/g, ''); + } else if (cmdsequence.split(';').length < (config.maxCmdSequenceLength || 5)){ let row = await this.db.get('SELECT COUNT(*) count FROM commands WHERE name = ?', [saveName]); if (!row || row.count === 0) await this.db.run('INSERT INTO commands (name, command) VALUES (?, ?)', [saveName, cmdsequence]); else await this.db.run('UPDATE commands SET sequence = ? WHERE name = ?', [cmdsequence, saveName]); return `saved command sequence as ${saveName}`; + } else { + return servercmd.utils.savecmd.response.sequence_too_long; } });