diff --git a/simplecommands/plugin.ts b/simplecommands/plugin.ts index db0f847..7d5f91e 100644 --- a/simplecommands/plugin.ts +++ b/simplecommands/plugin.ts @@ -11,8 +11,9 @@ import { EMessageType, IMessage, IMessageTarget } from '@squeebot/core/lib/types import { fullIDMatcher } from '@squeebot/core/lib/common'; import { logger } from '@squeebot/core/lib/core'; +import { IChannel } from '@squeebot/core/lib/channel'; -declare type Matcher = (msg: IMessage) => boolean; +declare type Matcher = (msg: IMessage) => any; interface CommandSpec { name: string; @@ -26,6 +27,7 @@ interface CommandSpec { match?: string | Matcher; hidden?: boolean; permissions?: string[]; + tempargv?: any[]; execute(msg: IMessage, command: CommandSpec, prefix: string, ...args: any[]): Promise; } @@ -48,6 +50,7 @@ const rates: {[key: string]: Rate} = {}; }, keywords: ['squeebot'], rateLimits: [], + channelMatching: false, }) class SqueebotCommandsAPIPlugin extends Plugin { private commands: CommandSpec[] = []; @@ -153,8 +156,8 @@ class SqueebotCommandsAPIPlugin extends Plugin { return permitted; } - public async handlePrefix(msg: IMessage, prefix: string): Promise { - const text = msg.data.text ? msg.data.text : msg.data; + public async handlePrefix(msg: IMessage, prefix: string, plugins: string[]): Promise { + const text = msg.text; const separate = text.split(' '); if (separate[0].indexOf(prefix) === 0) { separate[0] = separate[0].substring(prefix.length); @@ -163,6 +166,10 @@ class SqueebotCommandsAPIPlugin extends Plugin { // Iteration 1: Resolve commands by name and by aliases const withAliases = []; for (const spec of this.commands) { + if (plugins.length && plugins.indexOf(spec.plugin) === -1) { + continue; + } + if (spec.aliases && spec.aliases.indexOf(separate[0]) !== -1) { const copy = Object.assign({}, spec); copy.alias = spec.name; @@ -208,6 +215,12 @@ class SqueebotCommandsAPIPlugin extends Plugin { // Start executing for (const spec of permitted) { + // Help command needs access to plugin list in the channel + // Very dirty + if (spec.name === 'help') { + spec.tempargv = plugins; + } + const success = await spec.execute(msg, spec, prefix, ...separate.slice(1)); if (success) { break; @@ -217,8 +230,8 @@ class SqueebotCommandsAPIPlugin extends Plugin { // Done } - public async handleKeywords(msg: IMessage, keyword: string): Promise { - const text = msg.data.text ? msg.data.text : msg.data; + public async handleKeywords(msg: IMessage, keyword: string, plugins: string[]): Promise { + const text = msg.text.toLowerCase(); // Only pass command specs which have `match` and match rooms let matching = []; @@ -227,16 +240,24 @@ class SqueebotCommandsAPIPlugin extends Plugin { continue; } + if (plugins.length && plugins.indexOf(spec.plugin) === -1) { + continue; + } + if (typeof spec.match === 'function') { try { - if (!spec.match(msg)) { + const match = spec.match(msg); + if (match == null) { continue; } + spec.tempargv = match; } catch (e) {} } else { - if (!text.match(spec.match)) { + const rgx = text.match(spec.match); + if (rgx == null) { continue; } + spec.tempargv = rgx.slice(1); } matching.push(spec); @@ -272,7 +293,8 @@ class SqueebotCommandsAPIPlugin extends Plugin { // Start executing for (const spec of permitted) { - const success = await spec.execute(msg, spec, keyword); + const success = await spec.execute(msg, spec, keyword, + ...(spec.tempargv ? spec.tempargv : [])); if (success) { break; } @@ -282,20 +304,25 @@ class SqueebotCommandsAPIPlugin extends Plugin { } @EventListener('message') - public digest(msg: IMessage): void { + public digest(msg: IMessage, chan: IChannel): void { if (msg.type !== EMessageType.message) { return; } + let allowedPlugins: string[] = []; + if (chan && this.config.get('channelMatching', false) === true) { + allowedPlugins = chan.plugins; + } + const text = msg.data.text ? msg.data.text : msg.data; const prefixes = this.config.config.prefix; const keywords = this.config.config.keywords; // Attempt to match keywords - if (!keywords && !keywords.length) { + if (keywords && keywords.length) { for (const kw of keywords) { - if (text.match(kw)) { - this.handleKeywords(msg, kw).catch(e => + if (text.toLowerCase().match(kw) != null) { + this.handleKeywords(msg, kw, allowedPlugins).catch(e => logger.error('[%s] Command handler threw an error:', this.name, e.stack)); return; } @@ -329,7 +356,7 @@ class SqueebotCommandsAPIPlugin extends Plugin { return; } - this.handlePrefix(msg, prefix).catch(e => + this.handlePrefix(msg, prefix, allowedPlugins).catch(e => logger.error('[%s] Command handler threw an error:', this.name, e.stack)); } @@ -389,10 +416,14 @@ class SqueebotCommandsAPIPlugin extends Plugin { } } - private helpCommand(msg: IMessage, prefix: string): void { + private helpCommand(msg: IMessage, prefix: string, plugins: string[]): void { // Iteration 1: Resolve commands by name and by aliases const withAliases = []; for (const spec of this.commands) { + if (plugins.length && plugins.indexOf(spec.plugin) === -1) { + continue; + } + if (spec.aliases && spec.aliases.length) { for (const alias of spec.aliases) { const copy = Object.assign({}, spec); @@ -462,7 +493,7 @@ class SqueebotCommandsAPIPlugin extends Plugin { usage: '[]', description: 'Show command usage or list all commands', execute: async (msg: IMessage, spec: CommandSpec, prefix: string): Promise => { - this.helpCommand(msg, prefix); + this.helpCommand(msg, prefix, spec.tempargv as string[]); return true; } });