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' 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('Overriding module %s', n) } this._registeredModules.set(n, module) } public loadModule>(module: IModuleType): T { return this.loadModuleByName(module.name) as T } public loadModuleByName(name: string) { if (this.modules!.has(name)) { return this.modules!.get(name)! } 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.loadModule.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>() Object.keys(this.config.modules).forEach(this.loadModuleByName.bind(this)) } } /** Stop bot */ public umount() { 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 this.logger.warn('Stopped') this.logger.flush() } } }