Start working on moving to irc-framework

This commit is contained in:
Pavel Djundik 2016-03-07 23:09:42 +02:00 committed by Maxime Poulin
parent ab95419c89
commit da425fefaf
21 changed files with 165 additions and 167 deletions

View file

@ -33,6 +33,7 @@
"event-stream": "3.3.2", "event-stream": "3.3.2",
"express": "4.13.4", "express": "4.13.4",
"lodash": "4.6.1", "lodash": "4.6.1",
"irc-framework": "1.0.3",
"mkdirp": "0.5.1", "mkdirp": "0.5.1",
"moment": "2.12.0", "moment": "2.12.0",
"read": "1.0.7", "read": "1.0.7",

View file

@ -3,11 +3,9 @@ var Chan = require("./models/chan");
var crypto = require("crypto"); var crypto = require("crypto");
var identd = require("./identd"); var identd = require("./identd");
var log = require("./log"); var log = require("./log");
var net = require("net");
var Msg = require("./models/msg"); var Msg = require("./models/msg");
var Network = require("./models/network"); var Network = require("./models/network");
var slate = require("slate-irc"); var ircFramework = require("irc-framework");
var tls = require("tls");
var Helper = require("./helper"); var Helper = require("./helper");
module.exports = Client; module.exports = Client;
@ -25,7 +23,6 @@ var events = [
"link", "link",
"names", "names",
"nick", "nick",
"notice",
"part", "part",
"quit", "quit",
"topic", "topic",
@ -33,7 +30,6 @@ var events = [
"whois" "whois"
]; ];
var inputs = [ var inputs = [
// These inputs are sorted in order that is most likely to be used
"msg", "msg",
"part", "part",
"action", "action",
@ -129,97 +125,69 @@ Client.prototype.connect = function(args) {
var config = Helper.getConfig(); var config = Helper.getConfig();
var client = this; var client = this;
if (config.lockNetwork) { var nick = args.nick || "lounge-user";
// This check is needed to prevent invalid user configurations
if (args.host && args.host.length > 0 && args.host !== config.defaults.host) {
var invalidHostnameMsg = new Msg({
type: Msg.Type.ERROR,
text: "Hostname you specified is not allowed."
});
client.emit("msg", {
msg: invalidHostnameMsg
});
return;
}
args.host = config.defaults.host; var network = new Network({
args.port = config.defaults.port;
args.tls = config.defaults.tls;
}
var server = {
name: args.name || "", name: args.name || "",
host: args.host || "", host: args.host || "",
port: parseInt(args.port, 10) || (args.tls ? 6697 : 6667), port: parseInt(args.port, 10) || (args.tls ? 6697 : 6667),
rejectUnauthorized: false
};
if (server.host.length === 0) {
var emptyHostnameMsg = new Msg({
type: Msg.Type.ERROR,
text: "You must specify a hostname to connect."
});
client.emit("msg", {
msg: emptyHostnameMsg
});
return;
}
if (config.bind) {
server.localAddress = config.bind;
if (args.tls) {
var socket = net.connect(server);
server.socket = socket;
}
}
var stream = args.tls ? tls.connect(server) : net.connect(server);
stream.on("error", function(e) {
console.log("Client#connect():\n" + e);
stream.end();
var msg = new Msg({
type: Msg.Type.ERROR,
text: "Connection error."
});
client.emit("msg", {
msg: msg
});
});
var nick = args.nick || "lounge-user";
var username = args.username || nick.replace(/[^a-zA-Z0-9]/g, "");
var realname = args.realname || "The Lounge User";
var irc = slate(stream);
identd.hook(stream, username);
if (args.password) {
irc.pass(args.password);
}
irc.me = nick;
irc.nick(nick);
irc.user(username, realname);
var network = new Network({
name: server.name,
host: server.host,
port: server.port,
tls: !!args.tls, tls: !!args.tls,
password: args.password, password: args.password,
username: username, username: args.username || nick.replace(/[^a-zA-Z0-9]/g, ""),
realname: realname, realname: args.realname || "The Lounge User",
commands: args.commands commands: args.commands
}); });
network.irc = irc;
client.networks.push(network); client.networks.push(network);
client.emit("network", { client.emit("network", {
network: network network: network
}); });
if (config.lockNetwork) {
// This check is needed to prevent invalid user configurations
if (args.host && args.host.length > 0 && args.host !== config.defaults.host) {
client.emit("msg", {
chan: network.channels[0].id,
msg: new Msg({
type: Msg.Type.ERROR,
text: "Hostname you specified is not allowed."
})
});
return;
}
network.host = config.defaults.host;
network.port = config.defaults.port;
network.tls = config.defaults.tls;
}
if (network.host.length === 0) {
client.emit("msg", {
chan: network.channels[0].id,
msg: new Msg({
type: Msg.Type.ERROR,
text: "You must specify a hostname to connect."
})
});
return;
}
var irc = new ircFramework.Client();
irc.connect({
host: network.host,
port: network.port,
nick: nick,
username: network.username,
gecos: network.realname,
password: network.password,
tls: network.tls,
localAddress: config.bind,
rejectUnauthorized: false,
auto_reconnect: false, // TODO: Enable auto reconnection
});
network.irc = irc;
events.forEach(function(plugin) { events.forEach(function(plugin) {
var path = "./plugins/irc-events/" + plugin; var path = "./plugins/irc-events/" + plugin;
require(path).apply(client, [ require(path).apply(client, [
@ -228,7 +196,39 @@ Client.prototype.connect = function(args) {
]); ]);
}); });
irc.once("welcome", function() { irc.on("raw socket connected", function() {
identd.hook(irc.socket, network.username);
});
irc.on("socket connected", function() {
client.emit("msg", {
chan: network.channels[0].id,
msg: new Msg({
text: "Connected to the network."
})
});
});
irc.on("socket close", function() {
client.emit("msg", {
chan: network.channels[0].id,
msg: new Msg({
type: Msg.Type.ERROR,
text: "Disconnected from the network."
})
});
});
irc.on("reconnecting", function() {
client.emit("msg", {
chan: network.channels[0].id,
msg: new Msg({
text: "Reconnecting..."
})
});
});
irc.on("registered", function() {
var delay = 1000; var delay = 1000;
var commands = args.commands; var commands = args.commands;
if (Array.isArray(commands)) { if (Array.isArray(commands)) {
@ -242,16 +242,13 @@ Client.prototype.connect = function(args) {
delay += 1000; delay += 1000;
}); });
} }
setTimeout(function() {
irc.write("PING " + network.host);
}, delay);
});
irc.once("pong", function() {
var join = (args.join || ""); var join = (args.join || "");
if (join) { if (join) {
join = join.replace(/\,/g, " ").split(/\s+/g); setTimeout(function() {
irc.join(join); join = join.replace(/\,/g, " ").split(/\s+/g);
irc.join(join);
}, delay);
} }
}); });
}; };

View file

@ -30,7 +30,7 @@ function Network(attr) {
} }
Network.prototype.toJSON = function() { Network.prototype.toJSON = function() {
var json = _.extend(this, {nick: (this.irc || {}).me || ""}); var json = _.extend(this, {nick: (this.irc && this.irc.user.nick) || ""});
return _.omit(json, "irc", "password"); return _.omit(json, "irc", "password");
}; };
@ -45,7 +45,7 @@ Network.prototype.export = function() {
"realname", "realname",
"commands" "commands"
]); ]);
network.nick = (this.irc || {}).me; network.nick = (this.irc && this.irc.user.nick) || "";
network.join = _.map( network.join = _.map(
_.filter(this.channels, {type: "channel"}), _.filter(this.channels, {type: "channel"}),
"name" "name"

View file

@ -3,6 +3,10 @@ var _ = require("lodash");
module.exports = User; module.exports = User;
function User(attr) { function User(attr) {
// TODO: Remove this
attr.name = attr.nick;
attr.mode = attr.modes[0] || "";
_.merge(this, _.extend({ _.merge(this, _.extend({
mode: "", mode: "",
name: "" name: ""

View file

@ -18,7 +18,7 @@ exports.input = function(network, chan, cmd, args) {
text text
); );
irc.emit("message", { irc.emit("message", {
from: irc.me, from: irc.user.nick,
to: chan.name, to: chan.name,
message: "\u0001ACTION " + text message: "\u0001ACTION " + text
}); });

View file

@ -21,7 +21,7 @@ exports.input = function(network, chan, cmd, args) {
var channel = _.find(network.channels, {name: target}); var channel = _.find(network.channels, {name: target});
if (typeof channel !== "undefined") { if (typeof channel !== "undefined") {
irc.emit("message", { irc.emit("message", {
from: irc.me, from: irc.user.nick,
to: channel.name, to: channel.name,
message: msg message: msg
}); });

View file

@ -20,8 +20,8 @@ exports.input = function(network, chan, cmd, args) {
var msg = new Msg({ var msg = new Msg({
type: Msg.Type.NOTICE, type: Msg.Type.NOTICE,
mode: targetChan.getMode(irc.me), mode: targetChan.getMode(irc.user.nick),
from: irc.me, from: irc.user.nick,
text: message text: message
}); });
targetChan.messages.push(msg); targetChan.messages.push(msg);

View file

@ -1,22 +1,15 @@
var pkg = require(process.cwd() + "/package.json"); var pkg = require(process.cwd() + "/package.json");
module.exports = function(irc/* , network */) { module.exports = function(irc/* , network */) {
irc.on("message", function(data) { irc.on("ctcp request", function(data) {
if (data.message.indexOf("\001") !== 0) { switch (data.type) {
return;
}
var msg = data.message.replace(/\001/g, "");
var split = msg.split(" ");
switch (split[0]) {
case "VERSION": case "VERSION":
irc.ctcp( irc.ctcpResponse(data.nick, "VERSION " + pkg.name + " " + pkg.version);
data.from,
"VERSION " + pkg.name + " " + pkg.version
);
break; break;
case "PING": case "PING":
var split = data.msg.split(" ");
if (split.length === 2) { if (split.length === 2) {
irc.ctcp(data.from, "PING " + split[1]); irc.ctcpResponse(data.nick, "PING " + split[1]);
} }
break; break;
} }

View file

@ -14,7 +14,7 @@ module.exports = function(irc, network) {
}); });
if (!network.connected) { if (!network.connected) {
if (data.cmd === "ERR_NICKNAMEINUSE") { if (data.cmd === "ERR_NICKNAMEINUSE") {
var random = irc.me + Math.floor(10 + (Math.random() * 89)); var random = irc.user.nick + Math.floor(10 + (Math.random() * 89));
irc.nick(random); irc.nick(random);
} }
} }

View file

@ -16,7 +16,7 @@ module.exports = function(irc, network) {
from: data.from, from: data.from,
target: target, target: target,
text: data.channel, text: data.channel,
invitedYou: target.toLowerCase() === irc.me.toLowerCase() invitedYou: target === irc.user.nick
}); });
chan.messages.push(msg); chan.messages.push(msg);
client.emit("msg", { client.emit("msg", {

View file

@ -18,20 +18,16 @@ module.exports = function(irc, network) {
chan: chan chan: chan
}); });
} }
chan.users.push(new User({name: data.nick})); chan.users.push(new User({nick: data.nick, modes: ""}));
chan.sortUsers(); chan.sortUsers();
client.emit("users", { client.emit("users", {
chan: chan.id chan: chan.id
}); });
var self = false;
if (data.nick.toLowerCase() === irc.me.toLowerCase()) {
self = true;
}
var msg = new Msg({ var msg = new Msg({
from: data.nick, from: data.nick,
hostmask: data.hostmask.username + "@" + data.hostmask.hostname, hostmask: data.ident + "@" + data.hostname,
type: Msg.Type.JOIN, type: Msg.Type.JOIN,
self: self self: data.nick === irc.user.nick
}); });
chan.messages.push(msg); chan.messages.push(msg);
client.emit("msg", { client.emit("msg", {

View file

@ -12,7 +12,7 @@ module.exports = function(irc, network) {
return; return;
} }
if (data.client === irc.me) { if (data.client === irc.user.nick) {
chan.users = []; chan.users = [];
} else { } else {
chan.users = _.without(chan.users, _.find(chan.users, {name: data.client})); chan.users = _.without(chan.users, _.find(chan.users, {name: data.client}));
@ -22,17 +22,13 @@ module.exports = function(irc, network) {
chan: chan.id chan: chan.id
}); });
var self = false;
if (data.nick.toLowerCase() === irc.me.toLowerCase()) {
self = true;
}
var msg = new Msg({ var msg = new Msg({
type: Msg.Type.KICK, type: Msg.Type.KICK,
mode: mode, mode: mode,
from: from, from: from,
target: data.client, target: data.client,
text: data.message || "", text: data.message || "",
self: self self: data.nick === irc.user.nick
}); });
chan.messages.push(msg); chan.messages.push(msg);
client.emit("msg", { client.emit("msg", {

View file

@ -27,7 +27,7 @@ module.exports = function(irc, network) {
return; return;
} }
var self = data.to.toLowerCase() === irc.me.toLowerCase(); var self = data.to.toLowerCase() === irc.user.nick.toLowerCase();
var chan = _.find(network.channels, {name: self ? data.from : data.to}); var chan = _.find(network.channels, {name: self ? data.from : data.to});
if (typeof chan === "undefined") { if (typeof chan === "undefined") {
return; return;

View file

@ -7,22 +7,32 @@ module.exports = function(irc, network) {
var client = this; var client = this;
var config = Helper.getConfig(); var config = Helper.getConfig();
irc.on("message", function(data) { irc.on("notice", function(data) {
if (data.message.indexOf("\u0001") === 0 && data.message.substring(0, 7) !== "\u0001ACTION") { data.type = Msg.Type.NOTICE;
// Hide ctcp messages. handleMessage(data);
return; });
}
var target = data.to; irc.on("action", function(data) {
if (target.toLowerCase() === irc.me.toLowerCase()) { data.type = Msg.Type.ACTION;
target = data.from; handleMessage(data);
});
irc.on("privmsg", function(data) {
data.type = Msg.Type.MESSAGE;
handleMessage(data);
});
function handleMessage(data) {
var target = data.target;
if (target.toLowerCase() === irc.user.nick.toLowerCase()) {
target = data.nick;
} }
var chan = _.find(network.channels, {name: target}); var chan = _.find(network.channels, {name: target});
if (typeof chan === "undefined") { if (typeof chan === "undefined") {
chan = new Chan({ chan = new Chan({
type: Chan.Type.QUERY, type: Chan.Type.QUERY,
name: data.from name: data.nick
}); });
network.channels.push(chan); network.channels.push(chan);
client.emit("join", { client.emit("join", {
@ -31,19 +41,11 @@ module.exports = function(irc, network) {
}); });
} }
var type = Msg.Type.MESSAGE; var self = data.nick === irc.user.nick;
var text = data.message;
var textSplit = text.split(" ");
if (textSplit[0] === "\u0001ACTION") {
type = Msg.Type.ACTION;
text = text.replace(/^\u0001ACTION|\u0001$/g, "");
}
var self = (data.from.toLowerCase() === irc.me.toLowerCase());
// Self messages are never highlighted // Self messages are never highlighted
// Non-self messages are highlighted as soon as the nick is detected // Non-self messages are highlighted as soon as the nick is detected
var highlight = !self && textSplit.some(function(w) { var highlight = !self && data.msg.split(" ").some(function(w) {
return (w.replace(/^@/, "").toLowerCase().indexOf(irc.me.toLowerCase()) === 0); return (w.replace(/^@/, "").toLowerCase().indexOf(irc.me.toLowerCase()) === 0);
}); });
@ -55,12 +57,11 @@ module.exports = function(irc, network) {
} }
} }
var name = data.from;
var msg = new Msg({ var msg = new Msg({
type: type, type: data.type,
mode: chan.getMode(name), mode: chan.getMode(data.nick),
from: name, from: data.nick,
text: text, text: data.msg,
self: self, self: self,
highlight: highlight highlight: highlight
}); });
@ -74,5 +75,5 @@ module.exports = function(irc, network) {
chan: chan.id, chan: chan.id,
msg: msg msg: msg
}); });
}); }
}; };

View file

@ -13,16 +13,12 @@ module.exports = function(irc, network) {
if (from.indexOf(".") !== -1) { if (from.indexOf(".") !== -1) {
from = data.target; from = data.target;
} }
var self = false;
if (from.toLowerCase() === irc.me.toLowerCase()) {
self = true;
}
var msg = new Msg({ var msg = new Msg({
type: Msg.Type.MODE, type: Msg.Type.MODE,
mode: chan.getMode(from), mode: chan.getMode(from),
from: from, from: from,
text: data.mode + " " + (data.client || ""), text: data.mode + " " + (data.client || ""),
self: self self: from === irc.user.nick
}); });
chan.messages.push(msg); chan.messages.push(msg);
client.emit("msg", { client.emit("msg", {

View file

@ -4,16 +4,31 @@ module.exports = function(irc, network) {
var client = this; var client = this;
irc.on("motd", function(data) { irc.on("motd", function(data) {
var lobby = network.channels[0]; var lobby = network.channels[0];
data.motd.forEach(function(text) {
if (data.motd) {
data.motd.split("\n").forEach(function(text) {
var msg = new Msg({
type: Msg.Type.MOTD,
text: text
});
lobby.messages.push(msg);
client.emit("msg", {
chan: lobby.id,
msg: msg
});
});
}
if (data.error) {
var msg = new Msg({ var msg = new Msg({
type: Msg.Type.MOTD, type: Msg.Type.MOTD,
text: text text: data.error
}); });
lobby.messages.push(msg); lobby.messages.push(msg);
client.emit("msg", { client.emit("msg", {
chan: lobby.id, chan: lobby.id,
msg: msg msg: msg
}); });
}); }
}); });
}; };

View file

@ -3,13 +3,13 @@ var User = require("../../models/user");
module.exports = function(irc, network) { module.exports = function(irc, network) {
var client = this; var client = this;
irc.on("names", function(data) { irc.on("userlist", function(data) {
var chan = _.find(network.channels, {name: data.channel}); var chan = _.find(network.channels, {name: data.channel});
if (typeof chan === "undefined") { if (typeof chan === "undefined") {
return; return;
} }
chan.users = []; chan.users = [];
_.each(data.names, function(u) { _.each(data.users, function(u) {
chan.users.push(new User(u)); chan.users.push(new User(u));
}); });
chan.sortUsers(); chan.sortUsers();

View file

@ -6,7 +6,7 @@ module.exports = function(irc, network) {
irc.on("nick", function(data) { irc.on("nick", function(data) {
var self = false; var self = false;
var nick = data["new"]; var nick = data["new"];
if (nick === irc.me) { if (nick === irc.user.nick) {
var lobby = network.channels[0]; var lobby = network.channels[0];
var msg = new Msg({ var msg = new Msg({
text: "You're now known as " + nick, text: "You're now known as " + nick,

View file

@ -9,7 +9,7 @@ module.exports = function(irc, network) {
return; return;
} }
var from = data.nick; var from = data.nick;
if (from === irc.me) { if (from === irc.user.nick) {
network.channels = _.without(network.channels, chan); network.channels = _.without(network.channels, chan);
client.save(); client.save();
client.emit("part", { client.emit("part", {

View file

@ -17,7 +17,7 @@ module.exports = function(irc, network) {
from: from, from: from,
text: topic, text: topic,
isSetByChan: from === chan.name, isSetByChan: from === chan.name,
self: (from.toLowerCase() === irc.me.toLowerCase()) self: from === irc.user.nick
}); });
chan.messages.push(msg); chan.messages.push(msg);
client.emit("msg", { client.emit("msg", {

View file

@ -2,13 +2,12 @@ var Msg = require("../../models/msg");
module.exports = function(irc, network) { module.exports = function(irc, network) {
var client = this; var client = this;
irc.on("welcome", function(data) { irc.on("registered", function(data) {
network.connected = true; network.connected = true;
irc.write("PING " + network.host); network.nick = data.nick;
var lobby = network.channels[0]; var lobby = network.channels[0];
var nick = data;
var msg = new Msg({ var msg = new Msg({
text: "You're now known as " + nick text: "You're now known as " + data.nick
}); });
lobby.messages.push(msg); lobby.messages.push(msg);
client.emit("msg", { client.emit("msg", {
@ -18,7 +17,7 @@ module.exports = function(irc, network) {
client.save(); client.save();
client.emit("nick", { client.emit("nick", {
network: network.id, network: network.id,
nick: nick nick: data.nick
}); });
}); });
}; };