191 lines
5.3 KiB
JavaScript
191 lines
5.3 KiB
JavaScript
const { CommandManager, defaultParameterTypes, TypeConversionError, IParameter, ICommandConfig } = require("knub-command-manager");
|
|
const Eris = require("eris");
|
|
const config = require("./cfg");
|
|
const utils = require("./utils");
|
|
const threads = require("./data/threads");
|
|
const Thread = require("./data/Thread");
|
|
|
|
/**
|
|
* @callback CommandFn
|
|
* @param {Eris.Message} msg
|
|
* @param {object} args
|
|
*/
|
|
|
|
/**
|
|
* @callback InboxServerCommandHandler
|
|
* @param {Eris.Message} msg
|
|
* @param {object} args
|
|
* @param {Thread} [thread]
|
|
*/
|
|
|
|
/**
|
|
* @callback InboxThreadCommandHandler
|
|
* @param {Eris.Message} msg
|
|
* @param {object} args
|
|
* @param {Thread} thread
|
|
*/
|
|
|
|
/**
|
|
* @callback AddGlobalCommandFn
|
|
* @param {string} trigger
|
|
* @param {string} parameters
|
|
* @param {CommandFn} handler
|
|
* @param {ICommandConfig} commandConfig
|
|
*/
|
|
|
|
/**
|
|
* @callback AddInboxServerCommandFn
|
|
* @param {string} trigger
|
|
* @param {string} parameters
|
|
* @param {InboxServerCommandHandler} handler
|
|
* @param {ICommandConfig} commandConfig
|
|
*/
|
|
|
|
/**
|
|
* @callback AddInboxThreadCommandFn
|
|
* Add a command that can only be invoked in a thread on the inbox server
|
|
*
|
|
* @param {string} trigger
|
|
* @param {string} parameters
|
|
* @param {InboxThreadCommandHandler} handler
|
|
* @param {ICommandConfig} commandConfig
|
|
*/
|
|
|
|
/**
|
|
* @callback AddAliasFn
|
|
* @param {string} originalCmd
|
|
* @param {string} alias
|
|
*/
|
|
|
|
module.exports = {
|
|
createCommandManager(bot) {
|
|
const manager = new CommandManager({
|
|
prefix: config.prefix,
|
|
types: Object.assign({}, defaultParameterTypes, {
|
|
userId(value) {
|
|
const userId = utils.getUserMention(value);
|
|
if (! userId) throw new TypeConversionError();
|
|
return userId;
|
|
},
|
|
|
|
delay(value) {
|
|
const ms = utils.convertDelayStringToMS(value);
|
|
if (ms === null) throw new TypeConversionError();
|
|
return ms;
|
|
}
|
|
})
|
|
});
|
|
|
|
const handlers = {};
|
|
const aliasMap = new Map();
|
|
|
|
bot.on("messageCreate", async msg => {
|
|
if (msg.author.bot) return;
|
|
if (msg.author.id === bot.user.id) return;
|
|
if (! msg.content) return;
|
|
|
|
const matchedCommand = await manager.findMatchingCommand(msg.content, { msg });
|
|
if (matchedCommand === null) return;
|
|
if (matchedCommand.error !== undefined) {
|
|
utils.postError(msg.channel, matchedCommand.error);
|
|
return;
|
|
}
|
|
|
|
const allArgs = {};
|
|
for (const [name, arg] of Object.entries(matchedCommand.args)) {
|
|
allArgs[name] = arg.value;
|
|
}
|
|
for (const [name, opt] of Object.entries(matchedCommand.opts)) {
|
|
allArgs[name] = opt.value;
|
|
}
|
|
|
|
handlers[matchedCommand.id](msg, allArgs);
|
|
});
|
|
|
|
/**
|
|
* Add a command that can be invoked anywhere
|
|
* @type {AddGlobalCommandFn}
|
|
*/
|
|
const addGlobalCommand = (trigger, parameters, handler, commandConfig = {}) => {
|
|
let aliases = aliasMap.has(trigger) ? [...aliasMap.get(trigger)] : [];
|
|
if (commandConfig.aliases) aliases.push(...commandConfig.aliases);
|
|
|
|
const cmd = manager.add(trigger, parameters, { ...commandConfig, aliases });
|
|
handlers[cmd.id] = handler;
|
|
};
|
|
|
|
/**
|
|
* Add a command that can only be invoked on the inbox server
|
|
* @type {AddInboxServerCommandFn}
|
|
*/
|
|
const addInboxServerCommand = (trigger, parameters, handler, commandConfig = {}) => {
|
|
const aliases = aliasMap.has(trigger) ? [...aliasMap.get(trigger)] : [];
|
|
if (commandConfig.aliases) aliases.push(...commandConfig.aliases);
|
|
|
|
const cmd = manager.add(trigger, parameters, {
|
|
...commandConfig,
|
|
aliases,
|
|
preFilters: [
|
|
(_, context) => {
|
|
if (! utils.messageIsOnInboxServer(context.msg)) return false;
|
|
if (! utils.isStaff(context.msg.member)) return false;
|
|
return true;
|
|
}
|
|
]
|
|
});
|
|
|
|
handlers[cmd.id] = async (msg, args) => {
|
|
const thread = await threads.findOpenThreadByChannelId(msg.channel.id);
|
|
handler(msg, args, thread);
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Add a command that can only be invoked in a thread on the inbox server
|
|
* @type {AddInboxThreadCommandFn}
|
|
*/
|
|
const addInboxThreadCommand = (trigger, parameters, handler, commandConfig = {}) => {
|
|
const aliases = aliasMap.has(trigger) ? [...aliasMap.get(trigger)] : [];
|
|
if (commandConfig.aliases) aliases.push(...commandConfig.aliases);
|
|
|
|
let thread;
|
|
const cmd = manager.add(trigger, parameters, {
|
|
...commandConfig,
|
|
aliases,
|
|
preFilters: [
|
|
async (_, context) => {
|
|
if (! utils.messageIsOnInboxServer(context.msg)) return false;
|
|
if (! utils.isStaff(context.msg.member)) return false;
|
|
thread = await threads.findOpenThreadByChannelId(context.msg.channel.id);
|
|
if (! thread) return false;
|
|
return true;
|
|
}
|
|
]
|
|
});
|
|
|
|
handlers[cmd.id] = async (msg, args) => {
|
|
handler(msg, args, thread);
|
|
};
|
|
};
|
|
|
|
/**
|
|
* @type {AddAliasFn}
|
|
*/
|
|
const addAlias = (originalCmd, alias) => {
|
|
if (! aliasMap.has(originalCmd)) {
|
|
aliasMap.set(originalCmd, new Set());
|
|
}
|
|
|
|
aliasMap.get(originalCmd).add(alias);
|
|
};
|
|
|
|
return {
|
|
manager,
|
|
addGlobalCommand,
|
|
addInboxServerCommand,
|
|
addInboxThreadCommand,
|
|
addAlias,
|
|
};
|
|
}
|
|
};
|