var http = require("connect"); var io = require("socket.io"); var irc = require("slate-irc"); var models = require(__dirname + "/models"); var net = require("net"); var _ = require("lodash"); var sockets = null; var networks = new models.Networks; var events = [ "join", "kick", "motd", "message", "names", "nick", "notice", "part", "quit", "topic", "welcome", "whois" ]; module.exports = function listen() { var app = http() .use(http.static("client")) .listen(9000); sockets = io.listen(app, {log: 0}).sockets.on("connection", function(s) { s.on("input", input); sockets.emit("network", networks); }); networks.on("all", function() { sockets.emit.apply(sockets, arguments); }); }; function connect(host) { var stream = net.connect({ port: 6667, host: host, }); stream.on("error", function(e) { console.log(e); }); var client = irc(stream); var network = networks.add({ host: host, client: client, }, {silent: true}); networks.trigger("network", networks); client.nick("t_user"); client.user("t_user", "temp user"); events.forEach(function(e) { client.on(e, function() { event.apply(network, [e, arguments]); }); }); } function input(json) { var target = networks.find(json.id); if (!target) { return; } var network = target.network; var channel = target.channel; var client = network.get("client"); var id = json.id; var text = json.text; var args = text.replace(/^\//, '').split(" "); var cmd = text.charAt(0) == "/" ? args[0].toLowerCase() : ""; switch (cmd) { case "": args.unshift( "msg", channel.get("name") ); case "msg": var user; var message = _.tail(args, 2).join(" "); if (client) { user = client.me; client.send(args[1], message); } channel.addMessage({ from: user, message: message, }); break; case "server": case "connect": if (args[1]) { connect(args[1]); } break; case "join": case "part": case "nick": if (client && args[1]) { client[cmd](args[1]); } break; case "topic": if (client && args[1]) { var str = "TOPIC " + args[1]; if (args[2]) { str += " :" + args.slice(2).join(" "); } client.write(str); } break; case "query": case "whois": if (client && args[1]) { client["whois"](args[1]); } break; case "kick": break; case "quit": case "disconnect": networks.remove(network); networks.trigger("network", networks); break; } } function event(event, data) { var channels = this.get("channels"); switch (event) { case "join": var chan = channels.findWhere({name: data[0].channel}) || channels.add({name: data[0].channel}); chan.addUser({name: data[0].nick}); chan.addMessage({ from: data[0].nick, type: "join", }); break; case "kick": break; case "motd": var messages = data[0].motd; messages.forEach(function(msg) { channels.first().addMessage({message: msg}); }); break; case "message": var chan = channels.findWhere({name: data[0].to}) || channels.add({type: "query", name: data[0].from}); chan.addMessage({ from: data[0].from, message: data[0].message }); break; case "names": var chan = channels.findWhere({name: data[0].channel}); chan.get("users").reset( _.map(data[0].names, function(n) { return {name: n}; }) ); break; case "nick": if (data[0].new == this.get("client").me) { channels.first().addMessage({ message: "You're now known as " + data[0]["new"], }); } channels.each(function(chan) { var users = chan.get("users"); var user = users.findWhere({name: data[0].nick}); if (!user) { return; } user.set("name", data[0]["new"]); users.trigger("change", {}, users); chan.addMessage({ from: data[0].nick, message: data[0]["new"], type: "nick", }); }); break; case "notice": if (data[0].to = "*") { data[0].from = "-!-"; } channels.first().addMessage(data[0]); break; case "part": var i = data[0].channels.length; while (i--) { var chan = channels.findWhere({name: data[0].channels[i]}); if (data[0].nick == this.get("client").me) { channels.remove(chan); return; } var users = chan.get("users"); users.remove(users.findWhere({name: data[0].nick})); chan.addMessage({ from: data[0].nick, type: "part", }); } break; case "quit": channels.each(function(chan) { var users = chan.get("users"); var user = users.findWhere({name: data[0].nick}); if (user) { users.remove(user); chan.addMessage({ from: data[0].nick, type: "quit", }); } }); break; case "topic": var chan = channels.findWhere({name: data[0].channel}); var from = data[0].nick; if (from == this.get("client").me) { from = data[0].channel; } chan.addMessage({ from: from, message: data[0].topic, type: "topic", }); break; case "welcome": channels.first().addMessage([ {message: "You're now connected to " + this.get("host")}, {message: "You're now known as " + data[0]} ]); break; case "whois": // If this value is null, an error has occured. if (data[1] == null) { channels.first().addMessage({ type: "error", message: data[0] }); break; } var name = data[1].nickname; var chan = channels.findWhere({name: name}) || channels.add({type: "query", name: name}); var i = 0; for (var k in data[1]) { if (i++ == 5) break; chan.addMessage({ message: k + ": " + data[1][k] }); } break; } // Debug console.log(event); console.log(data); }