|
@@ -1,114 +0,0 @@
|
|
-import path from "path";
|
|
|
|
-import fs from "fs";
|
|
|
|
-import { isCommandSet, ICommand, IBotCommand, ActionType, BotAction } from "./model/command";
|
|
|
|
-import { getNumberEnums, assertOk } from "./util";
|
|
|
|
-import { Message } from "discord.js";
|
|
|
|
-
|
|
|
|
-interface IDocumentationData {
|
|
|
|
- name: string;
|
|
|
|
- doc?: string;
|
|
|
|
- example?: string;
|
|
|
|
- auth: boolean;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-type BotEventCollection = { [event in ActionType]: BotAction[] };
|
|
|
|
-
|
|
|
|
-export class CommandManager {
|
|
|
|
- private commandSets: ICommand[] = [];
|
|
|
|
- private botCommands: IBotCommand[] = [];
|
|
|
|
- private botEvents: BotEventCollection = getNumberEnums(ActionType).reduce((p, c) => { p[c as ActionType] = []; return p; }, {} as BotEventCollection);
|
|
|
|
- private startActions: Array<() => void | Promise<void>> = [];
|
|
|
|
-
|
|
|
|
- constructor(private cmdPath: string) {
|
|
|
|
- this.init();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private init(): void {
|
|
|
|
- const files = fs.readdirSync(this.cmdPath);
|
|
|
|
-
|
|
|
|
- for (const file of files) {
|
|
|
|
- const ext = path.extname(file);
|
|
|
|
- if (ext != ".js")
|
|
|
|
- continue;
|
|
|
|
-
|
|
|
|
- // eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
|
|
- this.loadCommand(require(path.resolve(this.cmdPath, file)));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private loadCommand(mod: Record<string, unknown>) {
|
|
|
|
- for (const i in mod) {
|
|
|
|
- if (!Object.prototype.hasOwnProperty.call(mod, i))
|
|
|
|
- continue;
|
|
|
|
-
|
|
|
|
- const commandClass = mod[i] as unknown;
|
|
|
|
- // Ensure this is indeed a command class
|
|
|
|
- if (!isCommandSet(commandClass))
|
|
|
|
- continue;
|
|
|
|
-
|
|
|
|
- const cmd = new commandClass();
|
|
|
|
- this.commandSets.push(cmd);
|
|
|
|
-
|
|
|
|
- if (cmd._botCommands)
|
|
|
|
- this.botCommands.push(...cmd._botCommands.map(c => ({ ...c, action: c.action.bind(cmd) })));
|
|
|
|
-
|
|
|
|
- if (cmd._botEvents)
|
|
|
|
- for (const [i, event] of Object.entries(cmd._botEvents)) {
|
|
|
|
- this.botEvents[+i as ActionType].push((event as BotAction).bind(cmd));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (cmd.onStart)
|
|
|
|
- this.startActions.push(cmd.onStart.bind(cmd));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- get documentation(): IDocumentationData[] {
|
|
|
|
- return this.botCommands.filter(m => m.documentation !== undefined).map(m => ({
|
|
|
|
- name: m.pattern.toString(),
|
|
|
|
- doc: m.documentation?.description,
|
|
|
|
- example: m.documentation?.example,
|
|
|
|
- auth: m.auth || false
|
|
|
|
- }));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- async onStart(): Promise<void> {
|
|
|
|
- for (let i = 0; i < this.startActions.length; i++) {
|
|
|
|
- const action = this.startActions[i];
|
|
|
|
- const val = action();
|
|
|
|
- if (val instanceof Promise)
|
|
|
|
- await assertOk(val);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- async trigger(type: ActionType, ...params: unknown[]): Promise<boolean> {
|
|
|
|
- let actionDone = false;
|
|
|
|
- const actions = this.botEvents[type];
|
|
|
|
- for (let i = 0; i < actions.length; i++) {
|
|
|
|
- const action = actions[i] as (...args: unknown[]) => boolean | Promise<boolean>;
|
|
|
|
- const actionResult = action(actionDone, ...params);
|
|
|
|
- if (actionResult instanceof Promise)
|
|
|
|
- actionDone = (await assertOk(actionResult)) || actionDone;
|
|
|
|
- else
|
|
|
|
- actionDone = actionResult || actionDone;
|
|
|
|
- }
|
|
|
|
- return actionDone;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- runCommand(m: Message, content: string): boolean {
|
|
|
|
- const lowerCaseContent = content.toLowerCase();
|
|
|
|
- for (const c of this.botCommands) {
|
|
|
|
- if (typeof (c.pattern) == "string" && lowerCaseContent.startsWith(c.pattern)) {
|
|
|
|
- c.action(m, content);
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- else if (c.pattern instanceof RegExp) {
|
|
|
|
- const result = c.pattern.exec(content);
|
|
|
|
- if (result != null) {
|
|
|
|
- c.action(m, content, result);
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-}
|
|
|