var fs = require('fs'), _ = require('underscore')._, jsbot = require('./jsbot/jsbot'), DatabaseDriver = require('./database').DatabaseDriver, async = require('async'); require('./snippets'); var DBot = function() { /*** Load the DB ***/ if(fs.existsSync('db.json')) { try { this.db = JSON.parse(fs.readFileSync('db.json', 'utf-8')); } catch(err) { console.log('Error loading db.json. Stopping: ' + err); process.exit(); } } else { this.db = {}; } this.reloadConfig(); /*** Load the fancy DB ***/ this.ddb = new DatabaseDriver(this.config); /*** Load main strings ***/ try { this.strings = JSON.parse(fs.readFileSync('strings.json', 'utf-8')); } catch(err) { console.log('Probably a syntax error in strings.json: ' + err); this.strings = {}; } // Initialise run-time resources this.usage = {}; this.status = {}; this.sessionData = {}; // Populate bot properties with config data // Create JSBot and connect to each server this.instance = jsbot.createJSBot(this.config.name); _.each(this.config.servers, function(server, name) { this.instance.addConnection(name, server.server, server.port, this.config.admin, function(event) { var server = this.config.servers[event.server]; _.each(server.channels, function(channel) { this.instance.join(event, channel); }, this); }.bind(this), server.nickserv, server.password); }, this); // Load the modules and connect to the server this.reloadModules(); this.instance.connectAll(); }; DBot.prototype.reloadConfig = function() { this.config = {}; if(!fs.existsSync('config.json')) { console.log('Error: config.json file does not exist. Stopping'); process.exit(); } try { var configFile = fs.readFileSync('config.json', 'utf-8'); this.config = JSON.parse(configFile); this.customConfig = JSON.parse(configFile); } catch(err) { console.log('Config file is invalid. Stopping: ' + err); process.exit(); } try { var defaultConfig = JSON.parse(fs.readFileSync('config.json.sample', 'utf-8')); } catch(err) { console.log('Error loading sample config. Bugger off this should not even be edited. Stopping.'); process.exit(); } // Load missing config directives from sample file if(!_.has(this.customConfig, 'modules')) { this.customConfig.modules = {}; this.config.modules = {}; } _.defaults(this.config, defaultConfig); }; // Say something in a channel DBot.prototype.say = function(server, channel, message) { this.instance.say(server, channel, message); }; // Format given stored string in config language DBot.prototype.t = function(string, formatData) { var formattedString = 'String not found. Something has gone screwy. Maybe.'; if(_.has(this.strings, string)) { var lang = this.config.language; if(!_.has(this.strings[string], lang)) { lang = "en"; } if(_.has(this.strings[string], lang)) { var module = this.stringMap[string]; formattedString = this.strings[string][lang].format(formatData); if(this.config.modules[module] && this.config.modules[module].outputPrefix) { formattedString = '[' + this.config.modules[module].outputPrefix + '] ' + formattedString; } } } return formattedString; }; /*DBot.prototype.act = function(channel, data) { this.instance.send('PRIVMSG', channel, ':\001ACTION ' + data + '\001'); }*/ // Save the database file DBot.prototype.save = function() { fs.writeFileSync('db.json', JSON.stringify(this.db, null, ' ')); }; // Hot-reload module files. DBot.prototype.reloadModules = function() { this.save(); if(this.modules) { // Run 'onDestroy' code for each module if it exists. _.each(this.modules, function(module) { if(module.onDestroy) { module.onDestroy(); } }); } this.rawModules = []; this.pages = {}; this.status = {}; this.modules = {}; this.commands = {}; this.api = {}; this.stringMap = {}; this.usage = {}; this.reloadConfig(); this.ddb.createDB(name, this.config.dbType, {}, function(db) {}); try { this.strings = JSON.parse(fs.readFileSync('strings.json', 'utf-8')); } catch(err) { this.strings = {}; } var moduleNames = this.config.moduleNames; // Enforce having command. it can still be reloaded, but dbot _will not_ // function without it, so not having it should be impossible if(!_.include(moduleNames, 'command')) { moduleNames.push("command"); } // Reload Javascript snippets var path = require.resolve('./snippets'); delete require.cache[path]; require('./snippets'); // Clear JSBot listeners and hooks this.instance.removeListeners(); this.instance.clearHooks(); var name, moduleDir, config; for(i=0;i