import {Client, Guild} from "discord.js"; import { Config } from "./lib/utils/Config"; import { DefaultConfig } from "./lib/utils/DefaultConfig"; import * as path from "path"; import * as fsx from "fs-extra"; import * as yaml from "js-yaml"; import {BotLogger} from "./lib/utils/BotLogger"; import {DataHandler} from "./lib/DataHandler"; import {GuildHandler} from "./lib/GuildHandler"; const configFile = "config.yaml"; /** * The main class of the bot. */ export class Bot { public readonly client: Client; public readonly config: Config; public readonly logger: BotLogger; public readonly dataHandler: DataHandler; private guildHandlers: any = {}; /** * constructor */ constructor() { this.config = Bot.loadConfig(); this.logger = new BotLogger(this.config.logging.directory, this.config.logging.level); this.client = new Client(); this.dataHandler = new DataHandler(this); } /** * Starts the bot. */ public async start(): Promise { await this.dataHandler.init(); this.logger.debug(`Config is ${JSON.stringify(this.config)}`); await this.client.login(this.config.botToken); this.logger.info(`Logged in as ${this.client.user.tag}`); this.registerEvents(); } /** * Loads the config file or creates one if none exists. */ private static loadConfig(): Config { const configPath: string = path.join(__dirname, "../", configFile); if (!fsx.existsSync(configPath)) { const configString: string = yaml.safeDump(new DefaultConfig()); fsx.writeFileSync(configPath, configString); // tslint:disable-next-line:no-console console.log("-----------------"); // tslint:disable-next-line:no-console console.log("Please edit the config before starting the bot."); process.exit(0); } else { const configString = fsx.readFileSync(configPath, "utf-8"); return Object.assign(new DefaultConfig(), yaml.safeLoad(configString)); } } /** * Registers all events the bot needs. */ private registerEvents(): void { this.client.on("message", async (message) => { if (message.author !== this.client.user) { if (message.guild) { const handler = await this.getGuildHandler(message.guild); await handler.onMessage(message); } } }); } /** * Returns the guild handler for a guild and creates one if it doesn't exist. * @param guild */ private async getGuildHandler(guild: Guild): Promise { let handler = this.guildHandlers[guild.id]; if (!handler) { handler = new GuildHandler(this, guild) as GuildHandler; await handler.init(); this.guildHandlers[guild.id] = handler; } return handler; } }