Introducing plugins

This commit is contained in:
Mattias Erming 2014-06-19 17:28:53 +02:00
parent 227e7837ed
commit e42e118262
15 changed files with 437 additions and 379 deletions

20
lib/plugins/errors.js Normal file
View File

@ -0,0 +1,20 @@
var Msg = require("../models/msg");
module.exports = function(client, sockets) {
var network = this;
client.on("errors", function(data) {
sockets.in("chat").emit("msg", {
msg: new Msg({
type: "error",
from: "-!-",
text: data.message,
}),
});
if (!network.connected) {
if (data.cmd == "ERR_NICKNAMEINUSE") {
var random = config.defaults.nick + Math.floor(10 + (Math.random() * 89));
client.nick(random);
}
}
});
};

29
lib/plugins/join.js Normal file
View File

@ -0,0 +1,29 @@
var _ = require("lodash");
var Chan = require("../models/chan");
var Msg = require("../models/msg");
module.exports = function(client, sockets) {
var network = this;
client.on("join", function(data) {
var chan = _.findWhere(network.channels, {name: data.channel});
if (typeof chan === "undefined") {
chan = new Chan({
name: data.channel,
});
network.addChan(chan);
sockets.in("chat").emit("join", {
id: network.id,
chan: chan,
});
}
var msg = new Msg({
from: data.nick,
type: "join",
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
});
};

32
lib/plugins/kick.js Normal file
View File

@ -0,0 +1,32 @@
var _ = require("lodash");
var Chan = require("../models/chan");
var Msg = require("../models/msg");
module.exports = function(client, sockets) {
var network = this;
client.on("kick", function(data) {
var chan = _.findWhere(network.channels, {name: data.channel});
if (typeof chan === "undefined") {
return;
}
if (data.client == client.me) {
chan.users = [];
} else {
chan.users = _.without(chan.users, _.findWhere(chan.users, {name: data.client}));
}
sockets.in("chat").emit("users", {
id: chan.id,
users: chan.users,
});
var msg = new Msg({
type: "kick",
from: data.nick,
text: data.client,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
});
};

42
lib/plugins/message.js Normal file
View File

@ -0,0 +1,42 @@
var _ = require("lodash");
var Chan = require("../models/chan");
var Msg = require("../models/msg");
var Network = require("../models/network");
module.exports = function(client, sockets) {
var network = this;
client.on("message", function(data) {
var target = data.to;
var chan = _.findWhere(network.channels, {name: target.charAt(0) == "#" ? target : data.from});
if (typeof chan === "undefined") {
chan = new Chan({
name: data.from,
type: "query",
});
network.addChan(chan);
sockets.in("chat").emit("join", {
id: network.id,
chan: chan,
});
}
var type = "";
var text = data.message;
if (text.split(" ")[0] === "\u0001ACTION") {
type = "action";
text = text.replace(/\u0001|ACTION/g, "");
}
text.split(' ').forEach(function(w) {
if (w.indexOf(client.me) == 0) type += " highlight";
});
var msg = new Msg({
type: type || "normal",
from: data.from,
text: text,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
});
};

31
lib/plugins/mode.js Normal file
View File

@ -0,0 +1,31 @@
var _ = require("lodash");
var Chan = require("../models/chan");
var Msg = require("../models/msg");
module.exports = function(client, sockets) {
var network = this;
var timer = null;
client.on("mode", function(data) {
var chan = _.findWhere(network.channels, {name: data.target});
if (typeof chan !== "undefined") {
clearTimeout(timer);
timer = setTimeout(function() {
client.write("NAMES " + data.target);
}, 200);
var nick = data.nick;
if (nick.indexOf(".") !== -1) {
nick = data.target;
}
var msg = new Msg({
type: "mode",
from: nick,
text: data.mode + " " + data.client,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
}
});
};

22
lib/plugins/motd.js Normal file
View File

@ -0,0 +1,22 @@
var Chan = require("../models/chan");
var Msg = require("../models/msg");
module.exports = function(client, sockets) {
var network = this;
client.on("motd", function(data) {
var rows = data.motd;
var chan = network.channels[0];
rows.forEach(function(text) {
var msg = new Msg({
type: "motd",
from: "-!-",
text: text,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
});
});
};

22
lib/plugins/names.js Normal file
View File

@ -0,0 +1,22 @@
var _ = require("lodash");
var Chan = require("../models/chan");
var User = require("../models/user");
module.exports = function(client, sockets) {
var network = this;
client.on("names", function(data) {
var chan = _.findWhere(network.channels, {name: data.channel});
if (typeof chan === "undefined") {
return;
}
chan.users = [];
_.each(data.names, function(n) {
chan.addUser(new User(n));
});
chan.sortUsers();
sockets.in("chat").emit("users", {
id: chan.id,
users: chan.users,
});
});
};

43
lib/plugins/nick.js Normal file
View File

@ -0,0 +1,43 @@
var _ = require("lodash");
var Chan = require("../models/chan");
var Msg = require("../models/msg");
module.exports = function(client, sockets) {
var network = this;
client.on("nick", function(data) {
if (data["new"] == client.me) {
var chan = network.channels[0];
var msg = new Msg({
from: "-!-",
text: "You're now known as " + data["new"],
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
}
network.channels.forEach(function(chan) {
var user = _.findWhere(chan.users, {name: data.nick});
if (!user) {
return;
}
user.name = data["new"];
chan.sortUsers();
sockets.in("chat").emit("users", {
id: chan.id,
users: chan.users,
});
var msg = new Msg({
type: "nick",
from: data.nick,
text: data["new"],
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
});
});
};

23
lib/plugins/notice.js Normal file
View File

@ -0,0 +1,23 @@
var Chan = require("../models/chan");
var Msg = require("../models/msg");
module.exports = function(client, sockets) {
var network = this;
client.on("notice", function(data) {
var chan = network.channels[0];
var from = data.from || "-!-";
if (data.to == "*" || data.from.indexOf(".") !== -1) {
from = "-!-";
}
var msg = new Msg({
type: "notice",
from: from,
text: data.message,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
});
};

34
lib/plugins/part.js Normal file
View File

@ -0,0 +1,34 @@
var _ = require("lodash");
var Chan = require("../models/chan");
var Msg = require("../models/msg");
module.exports = function(client, sockets) {
var network = this;
client.on("part", function(data) {
var chan = _.findWhere(network.channels, {name: data.channels[0]});
if (typeof chan === "undefined") {
return;
}
if (data.nick == client.me) {
network.channels = _.without(network.channels, chan);
sockets.in("chat").emit("part", {
id: chan.id,
});
} else {
chan.users = _.without(chan.users, _.findWhere(chan.users, {name: data.nick}));
sockets.in("chat").emit("users", {
id: chan.id,
users: chan.users,
});
var msg = new Msg({
type: "part",
from: data.nick,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
}
});
};

29
lib/plugins/quit.js Normal file
View File

@ -0,0 +1,29 @@
var _ = require("lodash");
var Chan = require("../models/chan");
var Msg = require("../models/msg");
module.exports = function(client, sockets) {
var network = this;
client.on("quit", function(data) {
network.channels.forEach(function(chan) {
var user = _.findWhere(chan.users, {name: data.nick});
if (!user) {
return;
}
chan.users = _.without(chan.users, user);
sockets.in("chat").emit("users", {
id: chan.id,
users: chan.users,
});
var msg = new Msg({
type: "quit",
from: data.nick,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
});
});
};

24
lib/plugins/topic.js Normal file
View File

@ -0,0 +1,24 @@
var _ = require("lodash");
var Chan = require("../models/chan");
var Msg = require("../models/msg");
module.exports = function(client, sockets) {
var network = this;
client.on("topic", function(data) {
var chan = _.findWhere(network.channels, {name: data.channel});
if (typeof chan === "undefined") {
return;
}
var from = data.nick || chan.name;
var msg = new Msg({
type: "topic",
from: from,
text: data.topic,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
});
};

19
lib/plugins/welcome.js Normal file
View File

@ -0,0 +1,19 @@
var Chan = require("../models/chan");
var Msg = require("../models/msg");
module.exports = function(client, sockets) {
var network = this;
client.on("welcome", function(data) {
network.connected = true;
var chan = network.channels[0];
var msg = new Msg({
from: "-!-",
text: "You're now known as " + data,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
});
};

57
lib/plugins/whois.js Normal file
View File

@ -0,0 +1,57 @@
var _ = require("lodash");
var Chan = require("../models/chan");
var Msg = require("../models/msg");
module.exports = function(client, sockets) {
var network = this;
client.on("whois", function(err, data) {
if (!data) {
return;
}
var chan = _.findWhere(network.channels, {name: data.nickname});
if (typeof chan === "undefined") {
chan = new Chan({
type: "query",
name: data.nickname,
});
network.addChan(chan);
sockets.in("chat").emit("join", {
id: network.id,
chan: chan,
});
}
var prefix = {
hostname: "from",
realname: "is",
channels: "on",
server: "using",
};
var i = 0;
for (var k in data) {
var key = prefix[k];
if (!key || data[k].toString() == "") {
continue;
}
var msg = new Msg({
type: "whois",
from: data.nickname,
text: key + " " + data[k],
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
}
var msg = new Msg({
type: "whois",
from: data.nickname,
text: "End of /WHOIS list.",
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
});
};

View File

@ -7,17 +7,13 @@ var irc = require("slate-irc");
var net = require("net");
var tls = require("tls");
// Models
var Chan = require("./models/chan");
var Msg = require("./models/msg");
var Network = require("./models/network");
var User = require("./models/user");
var sockets = null;
var networks = [];
var events = [
var plugins = [
"errors",
"join",
"kick",
@ -34,9 +30,7 @@ var events = [
"whois",
];
module.exports = listen;
function listen() {
module.exports = function listen() {
var port = config.port || 9000;
var app = http()
.use(index)
@ -73,7 +67,7 @@ function init(login) {
function index(req, res, next) {
if (req.url != "/") return next();
fs.readFile("client/index.html", function(err, file) {
return fs.readFile("client/index.html", function(err, file) {
var data = _.merge(
require("../package.json"),
config
@ -116,10 +110,8 @@ function connect(params) {
client.nick(params.nick);
client.user(params.nick, params.realname);
events.forEach(function(e) {
client.on(e, function() {
event.apply(network, [e, arguments]);
});
plugins.forEach(function(plugin) {
require("./plugins/" + plugin).apply(network, [client, sockets]);
});
if (!params.onConnect) {
@ -127,20 +119,20 @@ function connect(params) {
}
client.once("welcome", function() {
(params.onConnect.join || []).forEach(function(chan) {
client.write("PING " + network.host);
var channels = params.onConnect.join || [];
channels.forEach(function(chan) {
client.join.apply(
client,
chan.split(' ')
);
});
// Trigger 'PONG' response.
client.write("PING " + network.host);
});
client.once("pong", function() {
var delay = 1000;
(params.onConnect.commands || []).forEach(function(cmd) {
var commands = params.onConnect.commands || [];
commands.forEach(function(cmd) {
setTimeout(function() {
input({
id: network.channels[0].id,
@ -397,7 +389,6 @@ function input(data) {
}
break;
// Send raw IRC messages.
case "raw":
case "send":
if (client) {
@ -423,366 +414,6 @@ function fetch(data) {
});
}
function event(e, data) {
var data = _.last(data);
var network = this;
switch (e) {
case "errors":
sockets.in("chat").emit("msg", {
msg: new Msg({
type: "error",
from: "-!-",
text: data.message,
}),
});
if (!this.connected) {
if (data.cmd == "ERR_NICKNAMEINUSE") {
var random = config.defaults.nick + Math.floor(10 + (Math.random() * 89));
this.client.nick(random);
}
}
break;
case "join":
var chan = _.findWhere(this.channels, {name: data.channel});
if (typeof chan === "undefined") {
chan = new Chan({
name: data.channel,
});
this.addChan(chan);
sockets.in("chat").emit("join", {
id: this.id,
chan: chan,
});
}
var users = chan.users;
users.push(new User({name: data.nick}));
chan.sortUsers();
sockets.in("chat").emit("users", {
id: chan.id,
users: users,
});
var msg = new Msg({
from: data.nick,
type: "join",
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
break;
case "kick":
var chan = _.findWhere(this.channels, {name: data.channel});
if (typeof chan === "undefined") {
break;
}
if (data.client == this.client.me) {
chan.users = [];
} else {
chan.users = _.without(chan.users, _.findWhere(chan.users, {name: data.client}));
}
sockets.in("chat").emit("users", {
id: chan.id,
users: chan.users,
});
var msg = new Msg({
type: "kick",
from: data.nick,
text: data.client,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
break;
case "mode":
var chan = _.findWhere(this.channels, {name: data.target});
if (typeof chan !== "undefined") {
clearTimeout(this.timer);
this.timer = setTimeout((function() {
this.client.write("NAMES " + data.target);
}).bind(this), 200);
var nick = data.nick;
if (nick.indexOf(".") !== -1) {
nick = data.target;
}
var msg = new Msg({
type: "mode",
from: nick,
text: data.mode + " " + data.client,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
}
break;
case "motd":
var chan = this.channels[0];
data.motd.forEach(function(m) {
var msg = new Msg({
type: "motd",
from: "-!-",
text: m,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
});
break;
case "message":
var target = data.to;
var chan = _.findWhere(this.channels, {name: target.charAt(0) == "#" ? target : data.from});
if (typeof chan === "undefined") {
chan = new Chan({
name: data.from,
type: "query",
});
this.addChan(chan);
sockets.in("chat").emit("join", {
id: this.id,
chan: chan,
});
}
var type = "";
var text = data.message;
if (text.split(" ")[0] === "\u0001ACTION") {
type = "action";
text = text.replace(/\u0001|ACTION/g, "");
}
var network = this;
text.split(' ').forEach(function(w) {
if (w.indexOf(network.client.me) == 0) type += " highlight";
});
var msg = new Msg({
type: type || "normal",
from: data.from,
text: text,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
break;
case "names":
var chan = _.findWhere(this.channels, {name: data.channel});
if (typeof chan === "undefined") {
break;
}
chan.users = [];
_.each(data.names, function(n) {
chan.addUser(new User(n));
});
chan.sortUsers();
sockets.in("chat").emit("users", {
id: chan.id,
users: chan.users,
});
break;
case "nick":
if (data["new"] == this.client.me) {
var chan = this.channels[0];
var msg = new Msg({
from: "-!-",
text: "You're now known as " + data["new"],
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
}
this.channels.forEach(function(chan) {
var user = _.findWhere(chan.users, {name: data.nick});
if (!user) {
return;
}
user.name = data["new"];
chan.sortUsers();
sockets.in("chat").emit("users", {
id: chan.id,
users: chan.users,
});
var msg = new Msg({
type: "nick",
from: data.nick,
text: data["new"],
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
});
break;
case "notice":
var chan = this.channels[0];
var from = data.from || "-!-";
if (data.to == "*" || data.from.indexOf(".") !== -1) {
from = "-!-";
}
var msg = new Msg({
type: "notice",
from: from,
text: data.message,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
break;
case "part":
var chan = _.findWhere(this.channels, {name: data.channels[0]});
if (typeof chan === "undefined") {
break;
}
if (data.nick == this.client.me) {
remove(chan.id);
sockets.in("chat").emit("part", {
id: chan.id,
});
} else {
chan.users = _.without(chan.users, _.findWhere(chan.users, {name: data.nick}));
sockets.in("chat").emit("users", {
id: chan.id,
users: chan.users,
});
var msg = new Msg({
type: "part",
from: data.nick,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
}
break;
case "quit":
this.channels.forEach(function(chan) {
var user = _.findWhere(chan.users, {name: data.nick});
if (!user) {
return;
}
chan.users = _.without(chan.users, user);
sockets.in("chat").emit("users", {
id: chan.id,
users: chan.users,
});
var msg = new Msg({
type: "quit",
from: data.nick,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
});
break;
case "topic":
var chan = _.findWhere(this.channels, {name: data.channel});
if (typeof chan === "undefined") {
break;
}
var from = data.nick || chan.name;
var msg = new Msg({
type: "topic",
from: from,
text: data.topic,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
break;
case "welcome":
this.connected = true;
var chan = this.channels[0];
var msg = new Msg({
from: "-!-",
text: "You're now known as " + data,
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
break;
case "whois":
if (!data) {
break;
}
var chan = _.findWhere(this.channels, {name: data.nickname});
if (typeof chan === "undefined") {
chan = new Chan({
type: "query",
name: data.nickname,
});
this.addChan(chan);
sockets.in("chat").emit("join", {
id: this.id,
chan: chan,
});
}
var prefix = {
hostname: "from",
realname: "is",
channels: "on",
server: "using",
};
var i = 0;
for (var k in data) {
var key = prefix[k];
if (!key || data[k].toString() == "") {
continue;
}
var msg = new Msg({
type: "whois",
from: data.nickname,
text: key + " " + data[k],
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
}
var msg = new Msg({
type: "whois",
from: data.nickname,
text: "End of /WHOIS list.",
});
chan.addMsg(msg);
sockets.in("chat").emit("msg", {
id: chan.id,
msg: msg,
});
break;
}
}
function find(id) {
for (var i = 0; i < networks.length; i++) {
var result = {