From c096d8fac0dfdb27d4fdca7100e5c2253910b358 Mon Sep 17 00:00:00 2001 From: bdistin Date: Fri, 10 Nov 2017 12:47:36 -0600 Subject: [PATCH] Command handler improvements (#81) * Command Handler Speed Improvments startsWith is slower than regex.test with a ^, and especially so when cached, instead of recreated every time a message is run (also eliminates regex.exec to get the prefix length) * forgot to save * yeah duh --- src/lib/Client.js | 2 -- src/monitors/commandHandler.js | 29 +++++++++++++++++++++++------ typings/index.d.ts | 1 - 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/lib/Client.js b/src/lib/Client.js index a8b2291776..201070d2e9 100644 --- a/src/lib/Client.js +++ b/src/lib/Client.js @@ -37,7 +37,6 @@ class KlasaClient extends Discord.Client { * @property {KlasaConsoleEvents} [consoleEvents={}] Config options to pass to the client console * @property {boolean} [ignoreBots=true] Whether or not this bot should ignore other bots * @property {boolean} [ignoreSelf=true] Whether or not this bot should ignore itself - * @property {RegExp} [prefixMention] The prefix mention for your bot (Automatically Generated) * @property {boolean} [cmdPrompt=false] Whether the bot should prompt missing parameters * @property {boolean} [cmdEditing=false] Whether the bot should update responses if the command is edited * @property {boolean} [cmdLogging=false] Whether the bot should log command usage @@ -382,7 +381,6 @@ class KlasaClient extends Discord.Client { * @private */ async _ready() { - this.config.prefixMention = new RegExp(`^<@!?${this.user.id}>`); if (this.config.ignoreBots === undefined) this.config.ignoreBots = true; if (this.config.ignoreSelf === undefined) this.config.ignoreSelf = this.user.bot; if (this.user.bot) this.application = await super.fetchApplication(); diff --git a/src/monitors/commandHandler.js b/src/monitors/commandHandler.js index a975805146..0042fbae0b 100644 --- a/src/monitors/commandHandler.js +++ b/src/monitors/commandHandler.js @@ -2,6 +2,14 @@ const { Monitor, CommandMessage, Stopwatch, util: { regExpEsc, newError } } = re module.exports = class extends Monitor { + constructor(...args) { + super(...args); + this.prefixes = new Map(); + this.prefixMention = null; + this.prefixMentionLength = null; + this.nick = new RegExp('^<@!'); + } + async run(msg) { // Ignore other users if selfbot if (!this.client.user.bot && msg.author.id !== this.client.user.id) return; @@ -23,9 +31,8 @@ module.exports = class extends Monitor { } parseCommand(msg) { - const prefix = this.getPrefix(msg); + const { regex: prefix, length: prefixLength } = this.getPrefix(msg); if (!prefix) return { command: false }; - const prefixLength = prefix.exec(msg.content)[0].length; return { command: msg.content.slice(prefixLength).trim().split(' ')[0].toLowerCase(), prefix, @@ -34,18 +41,26 @@ module.exports = class extends Monitor { } getPrefix(msg) { - if (this.client.config.prefixMention.test(msg.content)) return this.client.config.prefixMention; + if (this.prefixMention.test(msg.content)) return { length: this.nick.test(msg.content) ? this.prefixMentionLength + 1 : this.prefixMentionLength, regex: this.prefixMention }; const prefix = msg.guildSettings.prefix || this.client.config.prefix; if (prefix instanceof Array) { for (let i = prefix.length - 1; i >= 0; i--) { - if (msg.content.startsWith(prefix[i])) return new RegExp(`^${regExpEsc(prefix[i])}`); + const testingPrefix = this.prefixes.get(prefix[i]) || this.generateNewPrefix(prefix[i]); + if (testingPrefix.regex.test(msg.content)) return testingPrefix; } - } else if (prefix && msg.content.startsWith(prefix)) { - return new RegExp(`^${regExpEsc(prefix)}`); + } else if (prefix) { + const testingPrefix = this.prefixes.get(prefix) || this.generateNewPrefix(prefix); + if (testingPrefix.regex.test(msg.content)) return testingPrefix; } return false; } + generateNewPrefix(prefix) { + const prefixObject = { length: prefix.length, regex: new RegExp(`^${regExpEsc(prefix)}`) }; + this.prefixes.set(prefix, prefixObject); + return prefixObject; + } + makeProxy(msg, cmdMsg) { return new Proxy(msg, { get: function handler(target, param) { @@ -100,6 +115,8 @@ module.exports = class extends Monitor { init() { this.ignoreSelf = this.client.user.bot; + this.prefixMention = new RegExp(`^<@!?${this.client.user.id}>`); + this.prefixMentionLength = this.client.user.id.length + 3; } }; diff --git a/typings/index.d.ts b/typings/index.d.ts index 4fbdece361..0864d7dfca 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -959,7 +959,6 @@ declare module 'klasa' { consoleEvents?: KlasaConsoleEvents; ignoreBots?: boolean; ignoreSelf?: boolean; - prefixMention?: RegExp; cmdPrompt?: boolean; cmdEditing?: boolean; cmdLogging?: boolean;