const fs = require('fs/promises') const path = require('path') const readline = require('readline') const json5 = require('json5') const matrix = require('matrix-js-sdk') const createBot = require('./bot.js') const fileExists = require('./util/file_exists') const Console = require('./util/console') async function main () { // config loading const configPath = process.argv[2] ?? 'config.json5' if (!await fileExists(configPath)) { await fs.copyFile(path.join(__dirname, 'default.json5'), configPath) console.info('No config file was found, so a default one was created') } const config = json5.parse(await fs.readFile(configPath, 'utf-8')) // logging const logdir = config.paths.logs ?? 'logs' if (!await fileExists(logdir)) await fs.mkdir(logdir) const rl = readline.createInterface({ input: process.stdin, output: process.stdout, prefix: '> ' }) const console = new Console({ readline: rl }) await console.createLogFile(logdir) const matrixClients = {} for (const key in config.matrixClients) { const client = matrix.createClient(config.matrixClients[key]) matrixClients[key] = client client.startClient() } const bots = [] for (const options of config.bots) { const mergedOptions = { console, paths: config.paths, ...(config.all ?? {}), ...options } if (mergedOptions.matrix && typeof mergedOptions.matrix.client !== 'object') mergedOptions.matrix.client = matrixClients[mergedOptions.matrix.client] const bot = createBot(mergedOptions) bots.push(bot) bot.bots = bots bot.on('error', error => bot.console.error(error.stack)) } process.on('uncaughtException', error => { if (error.stack.includes('protodef') || error.code === 'Z_BUF_ERROR') { console.error('Uncaught protodef exception!\n' + error.stack) return // Ignore protodef-related errors (packet-related) } console.error(error) process.exit(1) }) } main()