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