require('tinycolor'); var EventEmitter = require('events').EventEmitter; var util = require('util'); var cp = require('child_process'); var IrcClient = require('./irc-client').IrcClient; var Service = require('dynobot/service.js'); var Channel = require('dynobot/channel.js'); var _ = require('underscore'); var rl = require('readline'); /************************************************************/ function FakeSocket(stdin, stdout, msgHandler) { this.stdin = stdin; this.stdout = stdout; this.msgHandler = msgHandler; this.connectHandler = undefined; this.errorHandler = undefined; } FakeSocket.prototype.setEncoding = function(encoding) { this.stdin.setEncoding(encoding); } FakeSocket.prototype.on = function(event, cb) { switch(event) { case 'data': this.stdin.on('data', function(chunk) { cb(chunk.trim() + '\r\n'); }); break; case 'connect': this.connectHandler = cb; break; case 'close': this.stdin.on('exit', cb); break; case 'end': case 'error': break; default: process.exit(1); break; } } FakeSocket.prototype.connect = function(server, port) { this.connectHandler(); } FakeSocket.prototype.write = function(chunk) { this.stdout.write(chunk.red); this.msgHandler && this.msgHandler(chunk); } /************************************************************/ var StdinPipe = function() { EventEmitter.call(this); } util.inherits(StdinPipe, EventEmitter); StdinPipe.prototype.setEncoding = function() {} StdinPipe.prototype.send = function(msg) { console.log(msg.blue); stdinPipe.emit('data', msg + '\r\n'); } /************************************************************/ var stdinPipe = new StdinPipe(); var irc; var nick = 'dynobot'; var realName = 'bots\'r\'us'; var ident = 'ident'; function info(a, b, c) { console.log.apply(null, arguments); } var reallyConnect = true; if(reallyConnect) { var host = 'localhost'; // host = 'irc.freenode.net'; irc = new IrcClient(nick, realName, ident, host, 6667); } else { var msgHandler = function(line) { line = line.trim(); var prefix = ':' + nick + '!' + ident + '@example.org'; var parts = line.split(' '); switch(parts[0]) { case 'JOIN': stdinPipe.send(prefix + ' JOIN ' + parts[1]); } } irc = new IrcClient(nick, realName, ident,new FakeSocket(stdinPipe, process.stdout, msgHandler)); process.stdin.resume(); } var ircService = new Service('irc', irc); irc.setDebugLevel(3); function Plugin(name, script) { this.name = name; this.script = script; this.channel = undefined; } var plugins = [ new Plugin('echo', './echo-bot/index.js') // new Plugin('atom', './atom-bot/index.js') ]; _.each(plugins, function(plugin) { info('Starting ' + plugin.name); // TODO: Resolve plugin.script // TODO: set cwd option to the plugin's directory. var args = []; var options = { silent: true }; var child = cp.fork(plugin.script, args, options); var channel = new Channel(child); ircService.handle(channel); child.on('exit', function() { info(plugin.name + ' exited..'); ircService.release(channel); channel.close(); }); // TODO: set up consumers for child.stdout and color it before // piping to process.stdout }); process.stdin.resume(); var i = rl.createInterface(process.stdin, process.stdout, null); function quit() { i.close(); process.stdin.destroy(); process.exit(0); } function setupRepl() { var from = 'alice!~alice@example.com'; var channel = '#bitraf2'; function updatePrompt() { var prefix = 'from=' + from; prefix += channel ? ', channel=' + channel : ''; prefix += '> '; i.setPrompt(prefix, prefix.length); i.prompt(); } i.on('line', function (cmd) { cmd = cmd.trim(); if(cmd.length == 0) { i.prompt(); return; } var parts = cmd.split(' '); switch(parts[0]) { case '/quit': case '/q': quit(); break; case '/raw': case '/r': parts.shift(); stdinPipe.send(parts.join(' ')); updatePrompt(); break; case '/join': case '/j': channel = parts[1]; updatePrompt(); break; case '/from': case '/f': from = parts[1]; updatePrompt(); break; case '/notice': case '/n': if(channel) { parts.shift(); stdinPipe.send(':' + from + ' NOTICE ' + channel + ' :' + parts.join(' ')); } else { info('You have to /j a channel first'); } break; default: stdinPipe.send(':' + from + ' PRIVMSG ' + channel + ' :' + parts.join(' ')); updatePrompt(); break; } }).on('close', function() { quit(); }); updatePrompt(); } irc.join('#bitraf2', function(name) { info('joined ' + name + ' from dynobot.'); }); info('colors: ' + 'from bot'.red + ', ' + 'to bot'.blue); irc.connect(); setupRepl(i); setTimeout(function() { stdinPipe.send(':irc.foo.bar 001 this :Welcome to Some Internet Relay Chat Network this'); }, 1000);