import assert from 'assert' import * as mc from 'minecraft-protocol' import { default as pino } from 'pino' import moduleList from './modules' import Module, { IModuleType } from './utils/Module' import Client from './modules/Connection' interface IConfig { /** Minecraft protocol options */ client: mc.ClientOptions, /** Logger options */ log: pino.LoggerOptions, /** Modules to load and options */ modules: { [name: string]: object } } /** Modules manager */ export default class Cubbot { private logger: pino.Logger private _client?: mc.Client public get client() { return this._client } private _registeredModules = new Map(moduleList.map(m => [m.name, m])) private _modules?: Map> public get modules() { return this._modules } constructor(private readonly config: IConfig) { this.logger = pino(this.config.log) this.logger.warn('Cubbot') assert.ok(this.config.client) } /** Add addition module */ public registerModule(module: IModuleType, name?: string) { const n: string = name || module.name if (this._registeredModules.has(n)) { this.logger.warn({ msg: 'Overriding module', value: n }) } this._registeredModules.set(n, module) } public getModule>(module: IModuleType, load: boolean): T | undefined { return this.getModuleByName(module.name, load) as T | undefined } public getModuleByName(name: string, load: boolean) { if (this.modules!.has(name)) { return this.modules!.get(name)! } if (load) { this.logger.debug('Loading module %s', name) assert.ok(this._registeredModules.has(name), `Unknown module ${name}`) const mType = this._registeredModules.get(name)! const conf: { log?: string } = this.config.modules[name] || {} const mLogger = this.logger.child({ name, level: conf.log }) mLogger.trace('Logger created') const module = new mType(this.client!, mLogger, conf, this.getModule.bind(this)) this._modules!.set(name, module) return module } } /** Start bot */ public mount() { if (!this.client) { this.logger.debug('Creating client') this._client = mc.createClient(this.config.client) this.logger.debug('Loading modules') this._modules = new Map>() this.getModule(Client, true)!.setEngine(this) Object.keys(this.config.modules).forEach(m => this.getModuleByName(m, true)) } } /** Stop bot */ public umount(exit: boolean = false) { if (this.client) { this.logger.debug('Unloading modules') this.modules!.forEach(m => m.umount()) this._modules = undefined this.logger.debug('Removing client') //TODO: disconnect this._client = undefined if (exit) { this.logger.warn('Stopped') this.logger.flush() setTimeout(process.exit, 100) } } } }