import eris from 'eris'; import pluris from 'pluris'; import mongoose from 'mongoose'; import { promises as fs } from 'fs'; import { Collection, Command, LocalStorage, Util, ServerManagement, Event } from '.'; import { File, FileInterface, Member, MemberInterface, Moderation, ModerationInterface, Note, NoteInterface, PagerNumber, PagerNumberInterface, Rank, RankInterface, Redirect, RedirectInterface, Stat, StatInterface } from '../models'; import { Config } from '../../types'; // eslint-disable-line pluris(eris); export default class Client extends eris.Client { public config: Config; public commands: Collection; public events: Collection; public intervals: Collection; public util: Util; public serverManagement: ServerManagement; public db: { File: mongoose.Model, Member: mongoose.Model, Moderation: mongoose.Model, Note: mongoose.Model, PagerNumber: mongoose.Model, Rank: mongoose.Model, Redirect: mongoose.Model, Stat: mongoose.Model, local: { muted: LocalStorage } }; constructor(token: string, options?: eris.ClientOptions) { super(token, options); this.commands = new Collection(); this.events = new Collection(); this.intervals = new Collection(); this.db = { File, Member, Moderation, Note, PagerNumber, Rank, Redirect, Stat, local: { muted: new LocalStorage('muted') } }; } public async loadDatabase() { await mongoose.connect(this.config.mongoDB, { useNewUrlParser: true, useUnifiedTopology: true, poolSize: 50 }); const statMessages = await this.db.Stat.findOne({ name: 'messages' }); const statCommands = await this.db.Stat.findOne({ name: 'commands' }); const statPages = await this.db.Stat.findOne({ name: 'pages' }); const statRequests = await this.db.Stat.findOne({ name: 'requests' }); if (!statMessages) { await (new this.db.Stat({ name: 'messages', value: 0 }).save()); } if (!statCommands) { await (new this.db.Stat({ name: 'commands', value: 0 }).save()); } if (!statPages) { await (new this.db.Stat({ name: 'pages', value: 0 }).save()); } if (!statRequests) { await (new this.db.Stat({ name: 'requests', value: 0 }).save()); } } public loadPlugins() { this.util = new Util(this); this.serverManagement = new ServerManagement(this); } public async loadIntervals() { const intervalFiles = await fs.readdir(`${__dirname}/../intervals`); intervalFiles.forEach((file) => { const intervalName = file.split('.')[0]; if (file === 'index.js') return; const interval: NodeJS.Timeout = (require(`${__dirname}/../intervals/${file}`).default)(this); this.intervals.add(intervalName, interval); this.util.signale.success(`Successfully loaded interval: ${intervalName}`); }); } public async loadEvents(eventFiles: { [s: string]: typeof Event; } | ArrayLike) { const evtFiles = Object.entries(eventFiles); for (const [name, Ev] of evtFiles) { const event = new Ev(this); this.events.add(event.event, event); this.on(event.event, event.run); this.util.signale.success(`Successfully loaded event: ${name}`); delete require.cache[require.resolve(`${__dirname}/../events/${name}`)]; } } public async loadCommands(commandFiles: { [s: string]: typeof Command; } | ArrayLike) { const cmdFiles = Object.values(commandFiles); for (const Cmd of cmdFiles) { const command = new Cmd(this); this.commands.add(command.name, command); this.util.signale.success(`Successfully loaded command: ${command.name}`); } } }