const { Client } = require('discord.js'); const options = require('../../options.json'); const Registry = require('./Registry.js'); const EventHooker = require('./EventHooker.js'); const Dispatcher = require('./Dispatcher.js'); const Resolver = require('./Resolver.js'); const Logger = require('./Logger.js'); const TransactionHandler = require('./TransactionHandler.js'); const LocaleLoader = require('../../language/LocaleLoader.js'); const ModerationManager = require('../moderation/ModerationManager.js'); const RateLimiter = require('./RateLimiter.js'); const { Guild, GuildMember, User, Message } = require('../../structure/extensions/'); //eslint-disable-line no-unused-vars const { Command, Observer, Inhibitor, Setting } = require('../../structure/interfaces/'); const { DefaultGuild } = require('../../util/defaults/'); class DiscordClient extends Client { constructor(options) { super(options.bot.clientOptions); this.registry = new Registry(this); this.eventHooker = new EventHooker(this); this.dispatcher = new Dispatcher(this); this.resolver = new Resolver(this); this.logger = new Logger(this); this.transactionHandler = new TransactionHandler(this); this.localeLoader = new LocaleLoader(this); this.rateLimiter = new RateLimiter(this); this.moderationManager = new ModerationManager(this); this._options = options; this._built = false; this._defaultConfig = null; process.on('message', this._handleMessage.bind(this)); } async _handleMessage(message) { if(message._storage) this.transactionHandler._receive(message); } async build() { if(this._built) return undefined; await super.login(this._options.bot.token); this.localeLoader.loadLanguages(); await this.registry.loadComponents('components/inhibitors/', Inhibitor); await this.registry.loadComponents('components/commands/', Command); await this.registry.loadComponents('components/observers/', Observer); await this.registry.loadComponents('components/settings/', Setting); await this.moderationManager.initialize(); await this.dispatcher.dispatch(); this._built = true; return this._built; } format(language, index, parameters = { }, code = false) { parameters.prefix = this.guild?.prefix; let template = this.localeLoader.template(language, index); //.languages[language][index]; for(const emoji of Object.keys(Emojis)) { parameters[`emoji_${emoji}`] = Emojis[emoji]; } if(!template) { return `**Missing language index \`${language} [${index}]\` in languages. Contact a bot developer about this.**`; } for (const [param, val] of Object.entries(parameters)) { template = template.replace(new RegExp(`{${escapeRegex(param.toLowerCase())}}`, 'gi'), val); } if(code) { try { template = eval(template); } catch(error) { this.client.logger.error(`Error in locale ${language}:${index} while executing code.\n${error.stack || error}`); } } return template; } get defaultConfig() { if(this._defaultConfig) return this._defaultConfig; const settings = this.registry.components.filter((c) => c.type === 'setting' && c.resolve === 'GUILD'); let def = DefaultGuild; for(const setting of settings.values()) { if(setting.default !== null) { def = { ...def, ...setting.default }; } } this._defaultConfig = def; return def; } } module.exports = DiscordClient; const client = new DiscordClient(options); client.build(); process.on("unhandledRejection", (error) => { console.error("Unhandled promise rejection:", error); //eslint-disable-line no-console });