Shuo/lib/server.js

398 lines
7.4 KiB
JavaScript
Raw Normal View History

2014-04-05 22:01:19 +00:00
var models = require(__dirname + "/models.js");
var config = require(__dirname + "/../config.js");
2014-03-24 15:47:29 +00:00
var http = require("connect");
var io = require("socket.io");
var irc = require("slate-irc");
var net = require("net");
var _ = require("lodash");
2014-03-06 15:11:25 +00:00
2014-03-24 16:47:14 +00:00
var sockets = null;
2014-03-24 13:44:41 +00:00
var networks = new models.Networks;
2014-03-06 15:11:25 +00:00
2014-03-24 15:47:29 +00:00
var events = [
"join",
"kick",
2014-04-07 22:03:21 +00:00
"mode",
2014-04-03 20:55:51 +00:00
"motd",
2014-03-30 03:12:29 +00:00
"message",
2014-03-24 15:47:29 +00:00
"names",
"nick",
"notice",
"part",
"quit",
"topic",
"welcome",
2014-04-05 22:01:19 +00:00
"whois",
2014-03-24 15:47:29 +00:00
];
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);
2014-04-19 21:40:36 +00:00
sockets.emit("network", {
data: networks,
});
2014-03-13 17:50:02 +00:00
});
2014-03-24 13:44:41 +00:00
2014-03-24 15:47:29 +00:00
networks.on("all", function() {
sockets.emit.apply(sockets, arguments);
2014-03-13 17:50:02 +00:00
});
2014-04-05 22:01:19 +00:00
config.servers.forEach(function(s) {
connect(s);
});
2014-03-13 17:50:02 +00:00
};
2014-04-05 22:01:19 +00:00
function connect(params) {
params = _.extend(
config.defaults,
params
);
var host = params.host;
var port = params.port || 6667;
2014-03-24 15:47:29 +00:00
var stream = net.connect({
2014-04-05 22:01:19 +00:00
port: port,
2014-03-24 15:47:29 +00:00
host: host,
});
stream.on("error", function(e) {
console.log(e);
});
var client = irc(stream);
2014-03-29 23:59:28 +00:00
var network = networks.add({
host: host,
client: client,
}, {silent: true});
2014-04-21 11:20:20 +00:00
networks.trigger("network", {data: networks});
2014-03-24 15:47:29 +00:00
2014-04-05 22:01:19 +00:00
client.nick(params.nick);
client.user(params.nick, params.realname);
client.once("welcome", function() {
params.channels.forEach(function(c) {
client.join(c);
});
});
2014-03-24 15:47:29 +00:00
events.forEach(function(e) {
2014-04-02 15:24:33 +00:00
client.on(e, function() {
event.apply(network, [e, arguments]);
2014-03-24 15:47:29 +00:00
});
});
2014-03-24 13:44:41 +00:00
}
2014-03-24 15:47:29 +00:00
function input(json) {
2014-03-24 13:44:41 +00:00
var target = networks.find(json.id);
2014-03-09 21:22:37 +00:00
if (!target) {
return;
}
2014-03-13 15:25:01 +00:00
var network = target.network;
var channel = target.channel;
2014-03-24 13:44:41 +00:00
2014-03-30 03:12:29 +00:00
var client = network.get("client");
2014-03-24 13:44:41 +00:00
var id = json.id;
var text = json.text;
var args = text.replace(/^\//, '').split(" ");
var cmd = text.charAt(0) == "/" ? args[0].toLowerCase() : "";
2014-03-09 21:22:37 +00:00
switch (cmd) {
2014-03-24 13:44:41 +00:00
case "":
args.unshift(
"msg",
2014-03-13 15:25:01 +00:00
channel.get("name")
);
2014-03-29 15:36:12 +00:00
case "msg":
2014-03-30 03:12:29 +00:00
var user;
var message = _.tail(args, 2).join(" ");
if (client) {
user = client.me;
client.send(args[1], message);
}
2014-04-19 21:40:36 +00:00
channel.get("messages").add({
2014-03-30 03:12:29 +00:00
from: user,
2014-04-20 22:12:07 +00:00
text: message,
2014-03-29 15:36:12 +00:00
});
2014-03-24 13:44:41 +00:00
break;
case "server":
case "connect":
2014-03-24 15:47:29 +00:00
if (args[1]) {
2014-04-05 22:01:19 +00:00
connect({host: args[1]});
2014-03-14 15:12:01 +00:00
}
2014-03-12 18:06:08 +00:00
break;
2014-03-24 13:44:41 +00:00
2014-03-29 23:59:28 +00:00
case "join":
2014-03-30 03:12:29 +00:00
case "nick":
if (client && args[1]) {
2014-04-06 15:46:42 +00:00
client[cmd].apply(client, args.slice(1));
2014-03-29 23:59:28 +00:00
}
break;
2014-04-06 20:53:07 +00:00
case "leave":
case "part":
if (channel.get("type") == "query") {
network.get("channels").remove(channel);
} else if (client) {
client.part(channel.get("name"));
}
break;
2014-03-30 03:12:29 +00:00
case "topic":
2014-04-06 18:04:11 +00:00
var chan = channel.get("name");
if (client) {
var str = "TOPIC " + chan;
if (args[1]) {
str += " :" + args.slice(1).join(" ");
2014-03-30 03:12:29 +00:00
}
client.write(str);
2014-03-29 23:59:28 +00:00
}
break;
2014-04-02 15:24:33 +00:00
case "query":
case "whois":
if (client && args[1]) {
2014-04-06 15:46:42 +00:00
client.whois(args[1]);
2014-04-02 15:24:33 +00:00
}
break;
case "kick":
2014-04-06 15:46:42 +00:00
if (client && args[1]) {
client.kick(channel.get("name"), args[1]);
}
break;
2014-04-07 22:03:21 +00:00
case "op":
case "deop":
case "voice":
case "devoice":
2014-04-06 15:46:42 +00:00
case "mode":
2014-04-07 22:03:21 +00:00
if (!client || !args[1]) {
break;
}
var mode;
var user;
if (cmd != "mode") {
user = args[1];
mode = {
"op": "+o",
"deop": "-o",
"voice": "+v",
"devoice": "-v",
}[cmd];
} else if (!args[2]) {
break;
} else {
mode = args[1];
user = args[2];
}
client.mode(
channel.get("name"),
mode,
user
);
2014-04-02 15:24:33 +00:00
break;
2014-03-30 03:12:29 +00:00
case "quit":
case "disconnect":
networks.remove(network);
2014-04-21 11:20:20 +00:00
networks.trigger("network", {data: networks});
2014-03-30 03:12:29 +00:00
break;
2014-03-12 15:09:37 +00:00
}
2014-03-24 15:47:29 +00:00
}
function event(event, data) {
2014-03-29 23:59:28 +00:00
var channels = this.get("channels");
2014-03-24 15:47:29 +00:00
switch (event) {
case "join":
2014-04-02 15:24:33 +00:00
var chan = channels.findWhere({name: data[0].channel}) || channels.add({name: data[0].channel});
2014-04-09 22:35:04 +00:00
var users = chan.get("users");
2014-04-19 21:40:36 +00:00
users.add({name: data[0].nick}, {silent: true});
if (data[0].nick != this.get("client").me) {
users.sort();
}
chan.get("messages").add({
2014-04-02 15:24:33 +00:00
from: data[0].nick,
2014-03-29 23:59:28 +00:00
type: "join",
2014-04-06 15:46:42 +00:00
});
break;
2014-03-24 15:47:29 +00:00
case "kick":
2014-04-06 15:46:42 +00:00
var chan = channels.findWhere({name: data[0].channel});
var users = chan.get("users");
2014-04-06 20:53:07 +00:00
if (data[0].client != this.get("client").me) {
users.remove(users.findWhere({name: data[0].client}));
2014-04-06 15:46:42 +00:00
} else {
2014-04-06 20:53:07 +00:00
users.reset();
2014-04-06 15:46:42 +00:00
}
2014-04-19 21:40:36 +00:00
chan.get("messages").add({
2014-04-06 15:46:42 +00:00
from: data[0].nick,
2014-04-20 22:12:07 +00:00
text: data[0].client,
2014-04-06 15:46:42 +00:00
type: "kick",
});
2014-04-03 20:55:51 +00:00
break;
2014-04-07 22:03:21 +00:00
case "mode":
var chan = channels.findWhere({name: data[0].target});
if (typeof chan !== "undefined") {
2014-04-19 21:40:36 +00:00
chan.get("messages").add({
2014-04-07 22:03:21 +00:00
from: data[0].nick,
2014-04-20 22:12:07 +00:00
text: data[0].mode + " " + data[0].client,
2014-04-07 22:03:21 +00:00
type: "mode",
});
}
break;
2014-04-03 20:55:51 +00:00
case "motd":
var messages = data[0].motd;
messages.forEach(function(msg) {
2014-04-20 22:12:07 +00:00
channels.first().get("messages").add({text: msg});
2014-04-03 20:55:51 +00:00
});
2014-03-24 15:47:29 +00:00
break;
2014-03-30 03:12:29 +00:00
case "message":
2014-04-02 15:24:33 +00:00
var chan = channels.findWhere({name: data[0].to}) || channels.add({type: "query", name: data[0].from});
2014-04-21 15:08:57 +00:00
var type = "";
var text = data[0].message;
var network = this;
text.split(" ").forEach(function(w) {
if (w == network.get("client").me) type = "highlight";
});
2014-04-19 21:40:36 +00:00
chan.get("messages").add({
2014-04-21 15:08:57 +00:00
type: type,
2014-04-02 15:24:33 +00:00
from: data[0].from,
2014-04-21 15:08:57 +00:00
text: text,
2014-03-30 03:12:29 +00:00
});
break;
2014-03-24 15:47:29 +00:00
case "names":
2014-04-02 15:24:33 +00:00
var chan = channels.findWhere({name: data[0].channel});
2014-04-09 22:35:04 +00:00
var users = chan.get("users");
users.reset(
_.map(data[0].names, function(n) { return {name: n}; }),
{silent: true}
2014-04-02 15:24:33 +00:00
);
2014-04-09 22:35:04 +00:00
users.sort();
2014-03-24 15:47:29 +00:00
break;
case "nick":
2014-04-02 15:24:33 +00:00
if (data[0].new == this.get("client").me) {
2014-04-19 21:40:36 +00:00
channels.first().get("messages").add({
2014-04-20 22:12:07 +00:00
text: "You're now known as " + data[0]["new"],
2014-04-02 15:24:33 +00:00
});
}
2014-03-30 03:12:29 +00:00
channels.each(function(chan) {
var users = chan.get("users");
2014-04-02 15:24:33 +00:00
var user = users.findWhere({name: data[0].nick});
2014-03-30 03:12:29 +00:00
if (!user) {
return;
}
2014-04-02 15:24:33 +00:00
user.set("name", data[0]["new"]);
2014-04-09 22:35:04 +00:00
users.sort();
2014-03-30 03:12:29 +00:00
2014-04-19 21:40:36 +00:00
chan.get("messages").add({
2014-04-02 15:24:33 +00:00
from: data[0].nick,
2014-04-20 22:12:07 +00:00
text: data[0]["new"],
2014-03-30 03:12:29 +00:00
type: "nick",
});
});
2014-03-24 15:47:29 +00:00
break;
2014-04-20 22:12:07 +00:00
case "notice":
2014-04-02 15:24:33 +00:00
if (data[0].to = "*") {
data[0].from = "-!-";
}
2014-04-20 22:12:07 +00:00
channels.first().get("messages").add({
type: "notice",
from: data[0].from,
text: data[0].message,
});
2014-03-24 15:47:29 +00:00
break;
2014-04-07 21:19:20 +00:00
case "part":
var chan = channels.findWhere({name: data[0].channels[0]});
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}));
2014-04-09 22:35:04 +00:00
users.sort();
2014-04-19 21:40:36 +00:00
chan.get("messages").add({
2014-04-07 21:19:20 +00:00
from: data[0].nick,
type: "part",
});
break;
2014-03-24 15:47:29 +00:00
case "quit":
2014-03-30 03:12:29 +00:00
channels.each(function(chan) {
var users = chan.get("users");
2014-04-02 15:24:33 +00:00
var user = users.findWhere({name: data[0].nick});
2014-03-30 03:12:29 +00:00
if (user) {
users.remove(user);
2014-04-09 22:35:04 +00:00
users.sort();
2014-04-19 21:40:36 +00:00
chan.get("messages").add({
2014-04-02 15:24:33 +00:00
from: data[0].nick,
2014-03-30 03:12:29 +00:00
type: "quit",
});
}
});
2014-03-24 15:47:29 +00:00
break;
case "topic":
2014-04-02 15:24:33 +00:00
var chan = channels.findWhere({name: data[0].channel});
2014-04-06 18:04:11 +00:00
var from = data[0].nick || chan.get("name");
2014-04-19 21:40:36 +00:00
chan.get("messages").add({
2014-03-30 03:12:29 +00:00
from: from,
2014-04-20 22:12:07 +00:00
text: data[0].topic,
2014-03-30 03:12:29 +00:00
type: "topic",
});
2014-03-24 15:47:29 +00:00
break;
case "welcome":
2014-04-19 21:40:36 +00:00
channels.first().get("messages").add([
2014-04-20 22:12:07 +00:00
{text: "You're now connected to " + this.get("host")},
{text: "You're now known as " + data[0]}
2014-04-02 15:24:33 +00:00
]);
2014-03-24 15:47:29 +00:00
break;
case "whois":
2014-04-02 15:24:33 +00:00
if (data[1] == null) {
2014-04-19 21:40:36 +00:00
channels.first().get("messages").add({
2014-04-02 15:24:33 +00:00
type: "error",
2014-04-20 22:12:07 +00:00
text: data[0]
2014-04-02 15:24:33 +00:00
});
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;
2014-04-19 21:40:36 +00:00
chan.get("messages").add({
2014-04-20 22:12:07 +00:00
text: k + ": " + data[1][k]
2014-04-02 15:24:33 +00:00
});
}
2014-03-24 15:47:29 +00:00
break;
}
2014-04-02 15:24:33 +00:00
}