import Logger, { levels } from './logger.js'; import { filename, getPerms, hasPerms } from './utils.js'; export class Command { init(ctx, log) { this.log = log; } log; name = 'DEFAULT'; description = 'No description'; helptext = 'No helptext'; aliases = ''; whitelist = false; perms = 0; func() {} } export class Event { event = 'NONE'; func(...args) {} } export class CommandInitializer { ctx; log; commands = []; aliases = {}; uninitialized = []; events = {}; initialize(ctx) { this.ctx = ctx; this.log = new Logger('parser', ctx.log_level); for (const index in this.uninitialized) { this.initCommand(this.uninitialized[index], ctx); delete this.uninitialized[index]; } } initCommand(cmd, ctx) { cmd.init(ctx, new Logger(`cmd.${cmd.name}`, ctx.log_level)); this.commands.push(cmd); for (const alias of cmd.aliases) { this.aliases[alias] = cmd.name; } } addCommand(cmd) { this.uninitialized.push(cmd); } addEvent(handler) { console.log(handler); const event = handler.event; if (!this.events[event]) { this.events[event] = []; } this.events[event].push(handler); } getCommands() { return this.commands; } getAliases() { return this.aliases; } getEvents() { console.log(this.events); return this.events; } } export default class CommandParser { constructor(ctx, prefix = ';') { this.log = new Logger(filename(import.meta.url), ctx.log_level); this.prefix = prefix ? prefix : this.prefix || ';'; } log; prefix; commands = []; aliases = {}; addCommand(cmd) { this.log.trace(`cmd to add: ${JSON.stringify(cmd)}`); if (this.isCmd(cmd)) { this.commands.push(cmd); } } addAliases(aliases) { this.log.debug('added ' + Object.keys(aliases).length + ' aliases'); this.aliases = { ...this.aliases, ...aliases, }; } hasCmd(str) { if (this.aliases && this.aliases[str] != undefined) { str = this.aliases[str]; } const results = this.commands.filter((c) => c.name == str); return results.length ? results[0] : undefined; } isCmd(cmd) { return typeof cmd == 'object' && cmd instanceof Command; } getArgsList(split) { const parsed_args = []; let join_index = -1; let add = true; for (let index in split) { if (split[index].startsWith('```')) { join_index = index; add = false; } if (add) { parsed_args.push(split[index]); } if (split[index].endsWith('```') && join_index != -1) { let joined = split .slice(join_index, index + 1) .join(' ') .replace(/```/g, ''); parsed_args.push(joined); add = true; join_index = -1; } } return parsed_args; } parseMsg(msg, ctx) { if (msg.author.bot) { return; } this.log.trace(msg.content); this.log.trace(msg.content.startsWith(this.prefix)); this.log.trace(msg.content[0]); this.log.trace(this.prefix); if (msg.content.startsWith(this.prefix)) { if (msg.channel.guild && !ctx.whitelist.guild(msg.channel.guild)) { msg.channel.createMessage('guild not whitelisted'); return; } const snip = msg.content.slice(this.prefix.length); const unsep = snip.split(' '); const res = this.hasCmd(unsep[0]); const args = this.getArgsList(unsep.slice(1)); this.log.trace(snip); this.log.trace(res); this.log.trace(args); if (res != undefined) { this.log.debug(`execute function ${res.name}`); const perms = msg.channel.guild.members.get(msg.author.id).permissions; const resolvedPerms = res.perms.toString(); this.log.trace(resolvedPerms); this.log.trace(perms); if (res.whitelist && !ctx.whitelist.user(msg.author)) { msg.channel.createMessage('not whitelisted'); } else if (resolvedPerms && !hasPerms(perms, resolvedPerms)) { const required = getPerms(perms.allow.toString() & res.perms).join(', '); msg.channel.createMessage('not enough permissions.').then((sent) => { if (required.length <= 1000) { sent.edit('not enough permissions. needs: `' + required + '`'); } }); } else { res.func(msg, args, ctx); } } } } }