167 lines
4.3 KiB
TypeScript
Executable File
167 lines
4.3 KiB
TypeScript
Executable File
// const low = require('lowdb');
|
|
// const FileSync = require('lowdb/adapters/FileSync');
|
|
|
|
// import { MongoClient, Db } from 'mongodb';
|
|
import Mongoose from 'mongoose';
|
|
import * as Discord from 'discord.js';
|
|
|
|
// import {BotConf} from './BotConf';
|
|
// import {BotStorage} from './BotStorage';
|
|
// import {Database} from './Database';
|
|
|
|
import LevelPlugin from './Plugin/Level/LevelPlugin';
|
|
import VoiceChatPlugin from './Plugin/VoiceChat/VoiceChatPlugin';
|
|
|
|
// import {ChatChannels} from './Modules/ChatChannels';
|
|
|
|
import { Command, CommandFn } from './Commands/Command';
|
|
import Help from './Commands/Help';
|
|
// import {Level} from './Commands/Level';
|
|
// import {Haystack} from './Commands/Haystack';
|
|
// import {Leaderboard} from './Commands/Leaderboard';
|
|
|
|
import log4js from 'log4js';
|
|
|
|
const logger = log4js.getLogger();
|
|
|
|
export interface BotConfig {
|
|
auth: {
|
|
discord: string;
|
|
mongo_url: string;
|
|
mongo_db: string;
|
|
};
|
|
|
|
options: {
|
|
status: string
|
|
prefix: string;
|
|
delete_triggers: boolean;
|
|
}
|
|
|
|
plugin: {
|
|
level?: {
|
|
please_and_thank_you: boolean;
|
|
message: {
|
|
cooldown: number;
|
|
min_length: number;
|
|
},
|
|
levels: {
|
|
[num: string]: {
|
|
name: string;
|
|
experience: number;
|
|
role: number;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export default class Bot {
|
|
private config: BotConfig;
|
|
private client: Discord.Client;
|
|
// private db: ;
|
|
// storage: BotStorage;
|
|
|
|
// chatChannels: ChatChannels;
|
|
// leveller: Leveller;
|
|
|
|
private plugins: any[] = [];
|
|
private commands: { [command: string]: Command | CommandFn } = {};
|
|
|
|
constructor(config: BotConfig) {
|
|
this.config = config;
|
|
this.client = new Discord.Client();
|
|
// this.storage = new BotStorage(config);
|
|
|
|
// const adapter = new FileSync('./data/db.json');
|
|
// this.storage.db = new Database(low(adapter));
|
|
}
|
|
|
|
|
|
/**
|
|
* Initializes the connection to discord, and binds a shutdown handler.
|
|
*
|
|
* @returns the bot, once initialization is complete.
|
|
*/
|
|
|
|
async init(): Promise<this> {
|
|
await this.connect();
|
|
await this.bind();
|
|
|
|
process.on('SIGINT', () => this.onInterrupt().then(() => process.exit()));
|
|
|
|
return this;
|
|
}
|
|
|
|
|
|
/**
|
|
* Attempts to connect the client to discord, and sets its status to online.
|
|
*
|
|
* @returns a promise indicating the success state of the connection.
|
|
*/
|
|
|
|
private async connect() {
|
|
await new Promise((resolve, reject) => {
|
|
Mongoose.connect(this.config.auth.mongo_url, { useNewUrlParser: true, useUnifiedTopology: true });
|
|
Mongoose.set('useFindAndModify', false);
|
|
Mongoose.connection.on('error', reject);
|
|
Mongoose.connection.once('open', resolve);
|
|
});
|
|
|
|
await new Promise((resolve, reject) => {
|
|
this.client.login(this.config.auth.discord);
|
|
this.client.on('error', reject);
|
|
this.client.once('ready', () => {
|
|
const user = this.client.user as Discord.ClientUser;
|
|
user.setPresence({
|
|
status: 'online',
|
|
activity: { name: this.config.options.status, type: 'CUSTOM_STATUS' }
|
|
});
|
|
logger.info('Successfully connected as %s.', user.tag);
|
|
resolve(this);
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
/**
|
|
* Binds plugins to the bot.
|
|
*/
|
|
|
|
private bind() {
|
|
this.plugins.push(new LevelPlugin(this.config as any, this.client, this.commands));
|
|
this.plugins.push(new VoiceChatPlugin(this.config as any, this.client));
|
|
|
|
this.commands.help = Help;
|
|
|
|
// this.chatChannels = new ChatChannels(this.client, this.storage);
|
|
// this.leveller = new Leveller(this.client, this.storage);
|
|
// this.commands.push(new Haystack(this.client, this.storage));
|
|
// this.commands.push(new Leaderboard(this.client, this.storage));
|
|
|
|
this.client.on('message', (msg) => {
|
|
if (!msg.content.startsWith(this.config.options.prefix + ' ')) return;
|
|
const full = msg.content.substr(this.config.options.prefix.length + 1).trim();
|
|
const command = full.substr(0, full.indexOf(' ') === -1 ? full.length : full.indexOf(' ')).toLowerCase().trimLeft();
|
|
const args = command.substr(command.length).trimLeft().split(' ');
|
|
const cmd = this.commands[command];
|
|
if (typeof cmd === 'function') cmd(msg, command, args);
|
|
else if (typeof cmd === 'object') cmd.trigger(msg, command, args);
|
|
});
|
|
}
|
|
|
|
|
|
/**
|
|
* Performs cleanup activities. Bound to SIGINT after the bot has been set up.
|
|
*/
|
|
|
|
private async onInterrupt() {
|
|
try {
|
|
await Promise.all(this.plugins.map(async p => p.cleanup?.()));
|
|
logger.info('Shut down successfully.');
|
|
}
|
|
catch (e) {
|
|
logger.fatal('Error shutting down k9:\n%s', e);
|
|
}
|
|
}
|
|
}
|