From da425fefafb4efeca480723945c1787ec165bcde Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Mon, 7 Mar 2016 23:09:42 +0200 Subject: [PATCH 01/46] Start working on moving to irc-framework --- package.json | 1 + src/client.js | 177 +++++++++++++++--------------- src/models/network.js | 4 +- src/models/user.js | 4 + src/plugins/inputs/action.js | 2 +- src/plugins/inputs/msg.js | 2 +- src/plugins/inputs/notice.js | 4 +- src/plugins/irc-events/ctcp.js | 17 +-- src/plugins/irc-events/error.js | 2 +- src/plugins/irc-events/invite.js | 2 +- src/plugins/irc-events/join.js | 10 +- src/plugins/irc-events/kick.js | 8 +- src/plugins/irc-events/link.js | 2 +- src/plugins/irc-events/message.js | 51 ++++----- src/plugins/irc-events/mode.js | 6 +- src/plugins/irc-events/motd.js | 21 +++- src/plugins/irc-events/names.js | 4 +- src/plugins/irc-events/nick.js | 2 +- src/plugins/irc-events/part.js | 2 +- src/plugins/irc-events/topic.js | 2 +- src/plugins/irc-events/welcome.js | 9 +- 21 files changed, 165 insertions(+), 167 deletions(-) diff --git a/package.json b/package.json index 28e0e926..35c97db1 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "event-stream": "3.3.2", "express": "4.13.4", "lodash": "4.6.1", + "irc-framework": "1.0.3", "mkdirp": "0.5.1", "moment": "2.12.0", "read": "1.0.7", diff --git a/src/client.js b/src/client.js index 9e0856e0..5196d078 100644 --- a/src/client.js +++ b/src/client.js @@ -3,11 +3,9 @@ var Chan = require("./models/chan"); var crypto = require("crypto"); var identd = require("./identd"); var log = require("./log"); -var net = require("net"); var Msg = require("./models/msg"); var Network = require("./models/network"); -var slate = require("slate-irc"); -var tls = require("tls"); +var ircFramework = require("irc-framework"); var Helper = require("./helper"); module.exports = Client; @@ -25,7 +23,6 @@ var events = [ "link", "names", "nick", - "notice", "part", "quit", "topic", @@ -33,7 +30,6 @@ var events = [ "whois" ]; var inputs = [ - // These inputs are sorted in order that is most likely to be used "msg", "part", "action", @@ -129,97 +125,69 @@ Client.prototype.connect = function(args) { var config = Helper.getConfig(); var client = this; - if (config.lockNetwork) { - // 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; - } + var nick = args.nick || "lounge-user"; - args.host = config.defaults.host; - args.port = config.defaults.port; - args.tls = config.defaults.tls; - } - - var server = { + var network = new Network({ name: args.name || "", host: args.host || "", 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, password: args.password, - username: username, - realname: realname, + username: args.username || nick.replace(/[^a-zA-Z0-9]/g, ""), + realname: args.realname || "The Lounge User", commands: args.commands }); - network.irc = irc; - client.networks.push(network); client.emit("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) { var path = "./plugins/irc-events/" + plugin; 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 commands = args.commands; if (Array.isArray(commands)) { @@ -242,16 +242,13 @@ Client.prototype.connect = function(args) { delay += 1000; }); } - setTimeout(function() { - irc.write("PING " + network.host); - }, delay); - }); - irc.once("pong", function() { var join = (args.join || ""); if (join) { - join = join.replace(/\,/g, " ").split(/\s+/g); - irc.join(join); + setTimeout(function() { + join = join.replace(/\,/g, " ").split(/\s+/g); + irc.join(join); + }, delay); } }); }; diff --git a/src/models/network.js b/src/models/network.js index 0b641177..5e0200dc 100644 --- a/src/models/network.js +++ b/src/models/network.js @@ -30,7 +30,7 @@ function Network(attr) { } 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"); }; @@ -45,7 +45,7 @@ Network.prototype.export = function() { "realname", "commands" ]); - network.nick = (this.irc || {}).me; + network.nick = (this.irc && this.irc.user.nick) || ""; network.join = _.map( _.filter(this.channels, {type: "channel"}), "name" diff --git a/src/models/user.js b/src/models/user.js index 755e53dd..79c8947d 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -3,6 +3,10 @@ var _ = require("lodash"); module.exports = User; function User(attr) { + // TODO: Remove this + attr.name = attr.nick; + attr.mode = attr.modes[0] || ""; + _.merge(this, _.extend({ mode: "", name: "" diff --git a/src/plugins/inputs/action.js b/src/plugins/inputs/action.js index bdb85d25..cf4b753a 100644 --- a/src/plugins/inputs/action.js +++ b/src/plugins/inputs/action.js @@ -18,7 +18,7 @@ exports.input = function(network, chan, cmd, args) { text ); irc.emit("message", { - from: irc.me, + from: irc.user.nick, to: chan.name, message: "\u0001ACTION " + text }); diff --git a/src/plugins/inputs/msg.js b/src/plugins/inputs/msg.js index 27a27db3..da3edeb3 100644 --- a/src/plugins/inputs/msg.js +++ b/src/plugins/inputs/msg.js @@ -21,7 +21,7 @@ exports.input = function(network, chan, cmd, args) { var channel = _.find(network.channels, {name: target}); if (typeof channel !== "undefined") { irc.emit("message", { - from: irc.me, + from: irc.user.nick, to: channel.name, message: msg }); diff --git a/src/plugins/inputs/notice.js b/src/plugins/inputs/notice.js index 4c5981e5..09445e5c 100644 --- a/src/plugins/inputs/notice.js +++ b/src/plugins/inputs/notice.js @@ -20,8 +20,8 @@ exports.input = function(network, chan, cmd, args) { var msg = new Msg({ type: Msg.Type.NOTICE, - mode: targetChan.getMode(irc.me), - from: irc.me, + mode: targetChan.getMode(irc.user.nick), + from: irc.user.nick, text: message }); targetChan.messages.push(msg); diff --git a/src/plugins/irc-events/ctcp.js b/src/plugins/irc-events/ctcp.js index 42b7fed8..e329a4d3 100644 --- a/src/plugins/irc-events/ctcp.js +++ b/src/plugins/irc-events/ctcp.js @@ -1,22 +1,15 @@ var pkg = require(process.cwd() + "/package.json"); module.exports = function(irc/* , network */) { - irc.on("message", function(data) { - if (data.message.indexOf("\001") !== 0) { - return; - } - var msg = data.message.replace(/\001/g, ""); - var split = msg.split(" "); - switch (split[0]) { + irc.on("ctcp request", function(data) { + switch (data.type) { case "VERSION": - irc.ctcp( - data.from, - "VERSION " + pkg.name + " " + pkg.version - ); + irc.ctcpResponse(data.nick, "VERSION " + pkg.name + " " + pkg.version); break; case "PING": + var split = data.msg.split(" "); if (split.length === 2) { - irc.ctcp(data.from, "PING " + split[1]); + irc.ctcpResponse(data.nick, "PING " + split[1]); } break; } diff --git a/src/plugins/irc-events/error.js b/src/plugins/irc-events/error.js index c56a36cc..020ceeef 100644 --- a/src/plugins/irc-events/error.js +++ b/src/plugins/irc-events/error.js @@ -14,7 +14,7 @@ module.exports = function(irc, network) { }); if (!network.connected) { 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); } } diff --git a/src/plugins/irc-events/invite.js b/src/plugins/irc-events/invite.js index 6bf1e3b7..cc3a4229 100644 --- a/src/plugins/irc-events/invite.js +++ b/src/plugins/irc-events/invite.js @@ -16,7 +16,7 @@ module.exports = function(irc, network) { from: data.from, target: target, text: data.channel, - invitedYou: target.toLowerCase() === irc.me.toLowerCase() + invitedYou: target === irc.user.nick }); chan.messages.push(msg); client.emit("msg", { diff --git a/src/plugins/irc-events/join.js b/src/plugins/irc-events/join.js index 07e0bd0f..4410e9c3 100644 --- a/src/plugins/irc-events/join.js +++ b/src/plugins/irc-events/join.js @@ -18,20 +18,16 @@ module.exports = function(irc, network) { chan: chan }); } - chan.users.push(new User({name: data.nick})); + chan.users.push(new User({nick: data.nick, modes: ""})); chan.sortUsers(); client.emit("users", { chan: chan.id }); - var self = false; - if (data.nick.toLowerCase() === irc.me.toLowerCase()) { - self = true; - } var msg = new Msg({ from: data.nick, - hostmask: data.hostmask.username + "@" + data.hostmask.hostname, + hostmask: data.ident + "@" + data.hostname, type: Msg.Type.JOIN, - self: self + self: data.nick === irc.user.nick }); chan.messages.push(msg); client.emit("msg", { diff --git a/src/plugins/irc-events/kick.js b/src/plugins/irc-events/kick.js index c5bac10d..9e456edb 100644 --- a/src/plugins/irc-events/kick.js +++ b/src/plugins/irc-events/kick.js @@ -12,7 +12,7 @@ module.exports = function(irc, network) { return; } - if (data.client === irc.me) { + if (data.client === irc.user.nick) { chan.users = []; } else { chan.users = _.without(chan.users, _.find(chan.users, {name: data.client})); @@ -22,17 +22,13 @@ module.exports = function(irc, network) { chan: chan.id }); - var self = false; - if (data.nick.toLowerCase() === irc.me.toLowerCase()) { - self = true; - } var msg = new Msg({ type: Msg.Type.KICK, mode: mode, from: from, target: data.client, text: data.message || "", - self: self + self: data.nick === irc.user.nick }); chan.messages.push(msg); client.emit("msg", { diff --git a/src/plugins/irc-events/link.js b/src/plugins/irc-events/link.js index d5317016..37d4e72a 100644 --- a/src/plugins/irc-events/link.js +++ b/src/plugins/irc-events/link.js @@ -27,7 +27,7 @@ module.exports = function(irc, network) { 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}); if (typeof chan === "undefined") { return; diff --git a/src/plugins/irc-events/message.js b/src/plugins/irc-events/message.js index 0894843b..3ac43c86 100644 --- a/src/plugins/irc-events/message.js +++ b/src/plugins/irc-events/message.js @@ -7,22 +7,32 @@ module.exports = function(irc, network) { var client = this; var config = Helper.getConfig(); - irc.on("message", function(data) { - if (data.message.indexOf("\u0001") === 0 && data.message.substring(0, 7) !== "\u0001ACTION") { - // Hide ctcp messages. - return; - } + irc.on("notice", function(data) { + data.type = Msg.Type.NOTICE; + handleMessage(data); + }); - var target = data.to; - if (target.toLowerCase() === irc.me.toLowerCase()) { - target = data.from; + irc.on("action", function(data) { + data.type = Msg.Type.ACTION; + 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}); if (typeof chan === "undefined") { chan = new Chan({ type: Chan.Type.QUERY, - name: data.from + name: data.nick }); network.channels.push(chan); client.emit("join", { @@ -31,19 +41,11 @@ module.exports = function(irc, network) { }); } - var type = Msg.Type.MESSAGE; - 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()); + var self = data.nick === irc.user.nick; // Self messages are never highlighted // 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); }); @@ -55,12 +57,11 @@ module.exports = function(irc, network) { } } - var name = data.from; var msg = new Msg({ - type: type, - mode: chan.getMode(name), - from: name, - text: text, + type: data.type, + mode: chan.getMode(data.nick), + from: data.nick, + text: data.msg, self: self, highlight: highlight }); @@ -74,5 +75,5 @@ module.exports = function(irc, network) { chan: chan.id, msg: msg }); - }); + } }; diff --git a/src/plugins/irc-events/mode.js b/src/plugins/irc-events/mode.js index be4868eb..f6ca2a21 100644 --- a/src/plugins/irc-events/mode.js +++ b/src/plugins/irc-events/mode.js @@ -13,16 +13,12 @@ module.exports = function(irc, network) { if (from.indexOf(".") !== -1) { from = data.target; } - var self = false; - if (from.toLowerCase() === irc.me.toLowerCase()) { - self = true; - } var msg = new Msg({ type: Msg.Type.MODE, mode: chan.getMode(from), from: from, text: data.mode + " " + (data.client || ""), - self: self + self: from === irc.user.nick }); chan.messages.push(msg); client.emit("msg", { diff --git a/src/plugins/irc-events/motd.js b/src/plugins/irc-events/motd.js index 3f7d078a..bb5cd141 100644 --- a/src/plugins/irc-events/motd.js +++ b/src/plugins/irc-events/motd.js @@ -4,16 +4,31 @@ module.exports = function(irc, network) { var client = this; irc.on("motd", function(data) { 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({ type: Msg.Type.MOTD, - text: text + text: data.error }); lobby.messages.push(msg); client.emit("msg", { chan: lobby.id, msg: msg }); - }); + } }); }; diff --git a/src/plugins/irc-events/names.js b/src/plugins/irc-events/names.js index 5f4f7aa9..5612b09f 100644 --- a/src/plugins/irc-events/names.js +++ b/src/plugins/irc-events/names.js @@ -3,13 +3,13 @@ var User = require("../../models/user"); module.exports = function(irc, network) { var client = this; - irc.on("names", function(data) { + irc.on("userlist", function(data) { var chan = _.find(network.channels, {name: data.channel}); if (typeof chan === "undefined") { return; } chan.users = []; - _.each(data.names, function(u) { + _.each(data.users, function(u) { chan.users.push(new User(u)); }); chan.sortUsers(); diff --git a/src/plugins/irc-events/nick.js b/src/plugins/irc-events/nick.js index a77d12a3..ca51bbde 100644 --- a/src/plugins/irc-events/nick.js +++ b/src/plugins/irc-events/nick.js @@ -6,7 +6,7 @@ module.exports = function(irc, network) { irc.on("nick", function(data) { var self = false; var nick = data["new"]; - if (nick === irc.me) { + if (nick === irc.user.nick) { var lobby = network.channels[0]; var msg = new Msg({ text: "You're now known as " + nick, diff --git a/src/plugins/irc-events/part.js b/src/plugins/irc-events/part.js index 89d2364e..2c0600d4 100644 --- a/src/plugins/irc-events/part.js +++ b/src/plugins/irc-events/part.js @@ -9,7 +9,7 @@ module.exports = function(irc, network) { return; } var from = data.nick; - if (from === irc.me) { + if (from === irc.user.nick) { network.channels = _.without(network.channels, chan); client.save(); client.emit("part", { diff --git a/src/plugins/irc-events/topic.js b/src/plugins/irc-events/topic.js index 600780fe..9c746e5b 100644 --- a/src/plugins/irc-events/topic.js +++ b/src/plugins/irc-events/topic.js @@ -17,7 +17,7 @@ module.exports = function(irc, network) { from: from, text: topic, isSetByChan: from === chan.name, - self: (from.toLowerCase() === irc.me.toLowerCase()) + self: from === irc.user.nick }); chan.messages.push(msg); client.emit("msg", { diff --git a/src/plugins/irc-events/welcome.js b/src/plugins/irc-events/welcome.js index 9bac7c6c..23c5f54f 100644 --- a/src/plugins/irc-events/welcome.js +++ b/src/plugins/irc-events/welcome.js @@ -2,13 +2,12 @@ var Msg = require("../../models/msg"); module.exports = function(irc, network) { var client = this; - irc.on("welcome", function(data) { + irc.on("registered", function(data) { network.connected = true; - irc.write("PING " + network.host); + network.nick = data.nick; var lobby = network.channels[0]; - var nick = data; var msg = new Msg({ - text: "You're now known as " + nick + text: "You're now known as " + data.nick }); lobby.messages.push(msg); client.emit("msg", { @@ -18,7 +17,7 @@ module.exports = function(irc, network) { client.save(); client.emit("nick", { network: network.id, - nick: nick + nick: data.nick }); }); }; From e380319400454e288b2a38c240d157cd8612699f Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 8 Mar 2016 11:26:43 +0200 Subject: [PATCH 02/46] Handle parts, quits, topics and topic set by --- client/css/style.css | 3 ++- client/js/lounge.js | 1 + client/views/actions/topic.tpl | 6 ++--- client/views/actions/topic_set_by.tpl | 1 + src/models/msg.js | 1 + src/plugins/irc-events/message.js | 2 +- src/plugins/irc-events/part.js | 6 ++--- src/plugins/irc-events/quit.js | 4 ++-- src/plugins/irc-events/topic.js | 34 ++++++++++++++++++++------- 9 files changed, 40 insertions(+), 18 deletions(-) create mode 100644 client/views/actions/topic_set_by.tpl diff --git a/client/css/style.css b/client/css/style.css index c88a072c..41373540 100644 --- a/client/css/style.css +++ b/client/css/style.css @@ -789,7 +789,8 @@ button, #chat .nick .text, #chat .part .text, #chat .quit .text, -#chat .topic .text { +#chat .topic .text, +#chat .topic_set_by .text { color: #999; } diff --git a/client/js/lounge.js b/client/js/lounge.js index 7dfa56d8..c134eba3 100644 --- a/client/js/lounge.js +++ b/client/js/lounge.js @@ -221,6 +221,7 @@ $(function() { "part", "quit", "topic", + "topic_set_by", "action", "whois", ].indexOf(type) !== -1) { diff --git a/client/views/actions/topic.tpl b/client/views/actions/topic.tpl index 56962794..92fe29ae 100644 --- a/client/views/actions/topic.tpl +++ b/client/views/actions/topic.tpl @@ -1,8 +1,8 @@ -{{#if isSetByChan}} - The topic is: -{{else}} +{{#if from}} {{mode}}{{from}} has changed the topic to: +{{else}} + The topic is: {{/if}} {{{parse text}}} diff --git a/client/views/actions/topic_set_by.tpl b/client/views/actions/topic_set_by.tpl new file mode 100644 index 00000000..87d8ee83 --- /dev/null +++ b/client/views/actions/topic_set_by.tpl @@ -0,0 +1 @@ +Topic set by {{nick}} on {{when}} diff --git a/src/models/msg.js b/src/models/msg.js index d501c4d7..d176c8f5 100644 --- a/src/models/msg.js +++ b/src/models/msg.js @@ -15,6 +15,7 @@ Msg.Type = { QUIT: "quit", TOGGLE: "toggle", TOPIC: "topic", + TOPIC_SET_BY: "topic_set_by", WHOIS: "whois" }; diff --git a/src/plugins/irc-events/message.js b/src/plugins/irc-events/message.js index 3ac43c86..e5a0e38d 100644 --- a/src/plugins/irc-events/message.js +++ b/src/plugins/irc-events/message.js @@ -46,7 +46,7 @@ module.exports = function(irc, network) { // Self messages are never highlighted // Non-self messages are highlighted as soon as the nick is detected var highlight = !self && data.msg.split(" ").some(function(w) { - return (w.replace(/^@/, "").toLowerCase().indexOf(irc.me.toLowerCase()) === 0); + return (w.replace(/^@/, "").toLowerCase().indexOf(irc.user.nick.toLowerCase()) === 0); }); if (chan.id !== client.activeChannel) { diff --git a/src/plugins/irc-events/part.js b/src/plugins/irc-events/part.js index 2c0600d4..7006ac0a 100644 --- a/src/plugins/irc-events/part.js +++ b/src/plugins/irc-events/part.js @@ -4,7 +4,7 @@ var Msg = require("../../models/msg"); module.exports = function(irc, network) { var client = this; irc.on("part", function(data) { - var chan = _.find(network.channels, {name: data.channels[0]}); + var chan = _.find(network.channels, {name: data.channel}); if (typeof chan === "undefined") { return; } @@ -23,9 +23,9 @@ module.exports = function(irc, network) { }); var msg = new Msg({ type: Msg.Type.PART, - mode: chan.getMode(from), + mode: user.mode || "", text: data.message || "", - hostmask:data.hostmask.username + "@" + data.hostmask.hostname, + hostmask: data.ident + "@" + data.hostname, from: from }); chan.messages.push(msg); diff --git a/src/plugins/irc-events/quit.js b/src/plugins/irc-events/quit.js index 59ff5f3b..87dd2eab 100644 --- a/src/plugins/irc-events/quit.js +++ b/src/plugins/irc-events/quit.js @@ -16,9 +16,9 @@ module.exports = function(irc, network) { }); var msg = new Msg({ type: Msg.Type.QUIT, - mode: chan.getMode(from), + mode: user.mode || "", text: data.message || "", - hostmask: data.hostmask.username + "@" + data.hostmask.hostname, + hostmask: data.ident + "@" + data.hostname, from: from }); chan.messages.push(msg); diff --git a/src/plugins/irc-events/topic.js b/src/plugins/irc-events/topic.js index 9c746e5b..abf66fbb 100644 --- a/src/plugins/irc-events/topic.js +++ b/src/plugins/irc-events/topic.js @@ -8,26 +8,44 @@ module.exports = function(irc, network) { if (typeof chan === "undefined") { return; } - var from = data.nick || chan.name; - var topic = data.topic; var msg = new Msg({ type: Msg.Type.TOPIC, - mode: chan.getMode(from), - from: from, - text: topic, - isSetByChan: from === chan.name, - self: from === irc.user.nick + mode: (data.nick && chan.getMode(data.nick)) || "", + from: data.nick, + text: data.topic, + self: data.nick === irc.user.nick }); chan.messages.push(msg); client.emit("msg", { chan: chan.id, msg: msg }); - chan.topic = topic; + + chan.topic = data.topic; client.emit("topic", { chan: chan.id, topic: chan.topic }); }); + + irc.on("topicsetby", function(data) { + var chan = _.find(network.channels, {name: data.channel}); + if (typeof chan === "undefined") { + return; + } + + var msg = new Msg({ + type: Msg.Type.TOPIC_SET_BY, + mode: chan.getMode(data.nick), + nick: data.nick, + when: data.when, + self: data.nick === irc.user.nick + }); + chan.messages.push(msg); + client.emit("msg", { + chan: chan.id, + msg: msg + }); + }); }; From 360563528a5b526ca8d728074d3cf0fd63290f73 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 8 Mar 2016 11:42:38 +0200 Subject: [PATCH 03/46] Handle channel and user modes --- src/plugins/irc-events/mode.js | 38 +++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/plugins/irc-events/mode.js b/src/plugins/irc-events/mode.js index f6ca2a21..d50117a7 100644 --- a/src/plugins/irc-events/mode.js +++ b/src/plugins/irc-events/mode.js @@ -1,28 +1,38 @@ var _ = require("lodash"); +var Chan = require("../../models/chan"); var Msg = require("../../models/msg"); module.exports = function(irc, network) { var client = this; irc.on("mode", function(data) { - var chan = _.find(network.channels, {name: data.target}); - if (typeof chan !== "undefined") { - setTimeout(function() { - irc.write("NAMES " + data.target); - }, 200); - var from = data.nick; - if (from.indexOf(".") !== -1) { - from = data.target; + var targetChan; + + if (data.target === irc.user.nick) { + targetChan = network.channels[0]; + } else { + targetChan = _.find(network.channels, {name: data.target}); + if (typeof targetChan === "undefined") { + return; } + } + + for (var i = 0; i < data.modes.length; i++) { + var mode = data.modes[i]; + var text = mode.mode; + if (mode.param) { + text += " " + mode.param; + } + var msg = new Msg({ type: Msg.Type.MODE, - mode: chan.getMode(from), - from: from, - text: data.mode + " " + (data.client || ""), - self: from === irc.user.nick + mode: (targetChan.type !== Chan.Type.LOBBY && targetChan.getMode(data.nick)) || "", + from: data.nick, + text: text, + self: data.nick === irc.user.nick }); - chan.messages.push(msg); + targetChan.messages.push(msg); client.emit("msg", { - chan: chan.id, + chan: targetChan.id, msg: msg, }); } From 4d986537bc188872d43ea90d7b8e6c6755357bbe Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 8 Mar 2016 11:54:17 +0200 Subject: [PATCH 04/46] Handle error --- src/plugins/irc-events/error.js | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/plugins/irc-events/error.js b/src/plugins/irc-events/error.js index 020ceeef..fd65e494 100644 --- a/src/plugins/irc-events/error.js +++ b/src/plugins/irc-events/error.js @@ -2,21 +2,31 @@ var Msg = require("../../models/msg"); module.exports = function(irc, network) { var client = this; - irc.on("errors", function(data) { + irc.on("irc_error", function(data) { + console.log(data); var lobby = network.channels[0]; var msg = new Msg({ type: Msg.Type.ERROR, - text: data.message, + text: data.error, }); client.emit("msg", { chan: lobby.id, msg: msg }); - if (!network.connected) { - if (data.cmd === "ERR_NICKNAMEINUSE") { - var random = irc.user.nick + Math.floor(10 + (Math.random() * 89)); - irc.nick(random); - } - } + }); + + irc.on("nick in use", function(data) { + var lobby = network.channels[0]; + var msg = new Msg({ + type: Msg.Type.ERROR, + text: "Nickname " + data.nick + " is already in use: " + data.reason, + }); + client.emit("msg", { + chan: lobby.id, + msg: msg + }); + + var random = irc.user.nick + Math.floor(10 + (Math.random() * 89)); + irc.raw("NICK", random); }); }; From 9ab71b25881b9c6d1edfe84a61b06b963a030b69 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 8 Mar 2016 11:58:51 +0200 Subject: [PATCH 05/46] Handle nick --- client/views/actions/nick.tpl | 4 ++-- src/plugins/irc-events/nick.js | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/client/views/actions/nick.tpl b/client/views/actions/nick.tpl index dc6ed133..567aeaa7 100644 --- a/client/views/actions/nick.tpl +++ b/client/views/actions/nick.tpl @@ -1,3 +1,3 @@ -{{mode}}{{from}} +{{mode}}{{nick}} is now known as -{{mode}}{{text}} +{{mode}}{{newnick}} diff --git a/src/plugins/irc-events/nick.js b/src/plugins/irc-events/nick.js index ca51bbde..93926db4 100644 --- a/src/plugins/irc-events/nick.js +++ b/src/plugins/irc-events/nick.js @@ -5,11 +5,10 @@ module.exports = function(irc, network) { var client = this; irc.on("nick", function(data) { var self = false; - var nick = data["new"]; - if (nick === irc.user.nick) { + if (data.nick === irc.user.nick) { var lobby = network.channels[0]; var msg = new Msg({ - text: "You're now known as " + nick, + text: "You're now known as " + data.newnick, }); lobby.messages.push(msg); client.emit("msg", { @@ -20,23 +19,25 @@ module.exports = function(irc, network) { client.save(); client.emit("nick", { network: network.id, - nick: nick + nick: data.newnick }); } + network.channels.forEach(function(chan) { var user = _.find(chan.users, {name: data.nick}); if (typeof user === "undefined") { return; } - user.name = nick; + user.name = data.newnick; chan.sortUsers(); client.emit("users", { chan: chan.id }); var msg = new Msg({ type: Msg.Type.NICK, - from: data.nick, - text: nick, + mode: chan.getMode(data.newnick), + nick: data.nick, + newnick: data.newnick, self: self }); chan.messages.push(msg); From 627b69822161c9d72ddcef16ecc0a853f973fc8b Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 8 Mar 2016 12:13:36 +0200 Subject: [PATCH 06/46] Fix creating duplicate query windows when our nick is not known --- src/plugins/irc-events/message.js | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/plugins/irc-events/message.js b/src/plugins/irc-events/message.js index e5a0e38d..c8677113 100644 --- a/src/plugins/irc-events/message.js +++ b/src/plugins/irc-events/message.js @@ -23,22 +23,23 @@ module.exports = function(irc, network) { }); function handleMessage(data) { - var target = data.target; - if (target.toLowerCase() === irc.user.nick.toLowerCase()) { - target = data.nick; - } - - var chan = _.find(network.channels, {name: target}); + // First, try to find current target + var chan = _.find(network.channels, {name: data.target}); if (typeof chan === "undefined") { - chan = new Chan({ - type: Chan.Type.QUERY, - name: data.nick - }); - network.channels.push(chan); - client.emit("join", { - network: network.id, - chan: chan - }); + // If current target doesn't exist, try to find by nick + chan = _.find(network.channels, {name: data.nick}); + // If neither target or nick channels exist, create one for the nick + if (typeof chan === "undefined") { + chan = new Chan({ + type: Chan.Type.QUERY, + name: data.nick + }); + network.channels.push(chan); + client.emit("join", { + network: network.id, + chan: chan + }); + } } var self = data.nick === irc.user.nick; From 356851c3f2d255faf5eba47dfbe9fda5de4f629b Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 8 Mar 2016 12:16:20 +0200 Subject: [PATCH 07/46] Handle kick --- src/plugins/irc-events/kick.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/plugins/irc-events/kick.js b/src/plugins/irc-events/kick.js index 9e456edb..2fb81fc2 100644 --- a/src/plugins/irc-events/kick.js +++ b/src/plugins/irc-events/kick.js @@ -4,18 +4,15 @@ var Msg = require("../../models/msg"); module.exports = function(irc, network) { var client = this; irc.on("kick", function(data) { - var from = data.nick; var chan = _.find(network.channels, {name: data.channel}); - var mode = chan.getMode(from); - if (typeof chan === "undefined") { return; } - if (data.client === irc.user.nick) { + if (data.kicked === irc.user.nick) { chan.users = []; } else { - chan.users = _.without(chan.users, _.find(chan.users, {name: data.client})); + chan.users = _.without(chan.users, _.find(chan.users, {name: data.kicked})); } client.emit("users", { @@ -24,10 +21,11 @@ module.exports = function(irc, network) { var msg = new Msg({ type: Msg.Type.KICK, - mode: mode, - from: from, - target: data.client, + mode: chan.getMode(data.nick), + from: data.nick, + target: data.kicked, text: data.message || "", + highlight: data.kicked === irc.user.nick, self: data.nick === irc.user.nick }); chan.messages.push(msg); From 82e192cd2c1ed7c29f9909ab8803ce847acabae6 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 8 Mar 2016 12:31:43 +0200 Subject: [PATCH 08/46] Enable link fetcher --- src/plugins/irc-events/link.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/plugins/irc-events/link.js b/src/plugins/irc-events/link.js index 37d4e72a..1f687b73 100644 --- a/src/plugins/irc-events/link.js +++ b/src/plugins/irc-events/link.js @@ -9,7 +9,7 @@ process.setMaxListeners(0); module.exports = function(irc, network) { var client = this; - irc.on("message", function(data) { + irc.on("privmsg", function(data) { var config = Helper.getConfig(); if (!config.prefetch) { return; @@ -27,8 +27,7 @@ module.exports = function(irc, network) { return; } - 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: data.target}); if (typeof chan === "undefined") { return; } From 2244dda56618af046366f2f99122ea83c12f6a48 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 8 Mar 2016 15:36:25 +0200 Subject: [PATCH 09/46] Update commands --- src/plugins/inputs/action.js | 19 +++++++++---------- src/plugins/inputs/invite.js | 4 ++-- src/plugins/inputs/kick.js | 2 +- src/plugins/inputs/mode.js | 7 ++----- src/plugins/inputs/msg.js | 21 ++++++++++++++++----- src/plugins/inputs/notice.js | 15 ++++----------- src/plugins/inputs/raw.js | 2 +- src/plugins/inputs/topic.js | 5 ++--- src/plugins/irc-events/error.js | 2 +- src/plugins/irc-events/part.js | 2 +- 10 files changed, 39 insertions(+), 40 deletions(-) diff --git a/src/plugins/inputs/action.js b/src/plugins/inputs/action.js index cf4b753a..34c8036a 100644 --- a/src/plugins/inputs/action.js +++ b/src/plugins/inputs/action.js @@ -2,25 +2,24 @@ exports.commands = ["slap", "me"]; exports.input = function(network, chan, cmd, args) { var irc = network.irc; + var text; switch (cmd) { case "slap": - var slap = "slaps " + args[0] + " around a bit with a large trout"; + text = "slaps " + args[0] + " around a bit with a large trout"; /* fall through */ case "me": if (args.length === 0) { break; } - var text = slap || args.join(" "); - irc.action( - chan.name, - text - ); - irc.emit("message", { - from: irc.user.nick, - to: chan.name, - message: "\u0001ACTION " + text + text = text || args.join(" "); + + irc.say(chan.name, "\u0001ACTION " + text + "\u0001"); + irc.emit("action", { + nick: irc.user.nick, + target: chan.name, + msg: text }); break; } diff --git a/src/plugins/inputs/invite.js b/src/plugins/inputs/invite.js index b81ae2c8..8eefcbac 100644 --- a/src/plugins/inputs/invite.js +++ b/src/plugins/inputs/invite.js @@ -4,9 +4,9 @@ exports.input = function(network, chan, cmd, args) { var irc = network.irc; if (args.length === 2) { - irc.invite(args[0], args[1]); // Channel provided in the command + irc.raw("INVITE", args[0], args[1]); // Channel provided in the command } else if (args.length === 1 && chan.type === "channel") { - irc.invite(args[0], chan.name); // Current channel + irc.raw("INVITE", args[0], chan.name); // Current channel } return true; diff --git a/src/plugins/inputs/kick.js b/src/plugins/inputs/kick.js index a57d6cd4..47068817 100644 --- a/src/plugins/inputs/kick.js +++ b/src/plugins/inputs/kick.js @@ -3,7 +3,7 @@ exports.commands = ["kick"]; exports.input = function(network, chan, cmd, args) { if (args.length !== 0) { var irc = network.irc; - irc.kick(chan.name, args[0]); + irc.raw("KICK", chan.name, args[0]); } return true; diff --git a/src/plugins/inputs/mode.js b/src/plugins/inputs/mode.js index 5ca106be..b476256d 100644 --- a/src/plugins/inputs/mode.js +++ b/src/plugins/inputs/mode.js @@ -21,12 +21,9 @@ exports.input = function(network, chan, cmd, args) { mode = args[0]; user = args[1]; } + var irc = network.irc; - irc.mode( - chan.name, - mode, - user - ); + irc.raw("MODE", chan.name, mode, user); return true; }; diff --git a/src/plugins/inputs/msg.js b/src/plugins/inputs/msg.js index da3edeb3..4afaa5c4 100644 --- a/src/plugins/inputs/msg.js +++ b/src/plugins/inputs/msg.js @@ -1,11 +1,20 @@ var _ = require("lodash"); +<<<<<<< fbbb3d20d287243d2c3c5525d86801f54f903603 exports.commands = ["msg", "say"]; exports.input = function(network, chan, cmd, args) { +======= +module.exports = function(network, chan, cmd, args) { + if (cmd !== "say" && cmd !== "msg") { + return; + } + +>>>>>>> Update commands if (args.length === 0 || args[0] === "") { return true; } + var irc = network.irc; var target = ""; if (cmd === "msg") { @@ -16,14 +25,16 @@ exports.input = function(network, chan, cmd, args) { } else { target = chan.name; } + var msg = args.join(" "); - irc.send(target, msg); + irc.say(target, msg); + var channel = _.find(network.channels, {name: target}); if (typeof channel !== "undefined") { - irc.emit("message", { - from: irc.user.nick, - to: channel.name, - message: msg + irc.emit("privmsg", { + nick: irc.user.nick, + target: channel.name, + msg: msg }); } diff --git a/src/plugins/inputs/notice.js b/src/plugins/inputs/notice.js index 09445e5c..ca0a5e6c 100644 --- a/src/plugins/inputs/notice.js +++ b/src/plugins/inputs/notice.js @@ -1,5 +1,4 @@ var _ = require("lodash"); -var Msg = require("../../models/msg"); exports.commands = ["notice"]; @@ -18,16 +17,10 @@ exports.input = function(network, chan, cmd, args) { targetChan = chan; } - var msg = new Msg({ - type: Msg.Type.NOTICE, - mode: targetChan.getMode(irc.user.nick), - from: irc.user.nick, - text: message - }); - targetChan.messages.push(msg); - this.emit("msg", { - chan: targetChan.id, - msg: msg + irc.emit("notice", { + nick: irc.user.nick, + target: targetChan.name, + msg: message }); return true; diff --git a/src/plugins/inputs/raw.js b/src/plugins/inputs/raw.js index cab47bd8..b58a993c 100644 --- a/src/plugins/inputs/raw.js +++ b/src/plugins/inputs/raw.js @@ -3,7 +3,7 @@ exports.commands = ["raw", "send", "quote"]; exports.input = function(network, chan, cmd, args) { if (args.length !== 0) { var irc = network.irc; - irc.write(args.join(" ")); + irc.raw(args); } return true; diff --git a/src/plugins/inputs/topic.js b/src/plugins/inputs/topic.js index d342223f..7e9253c0 100644 --- a/src/plugins/inputs/topic.js +++ b/src/plugins/inputs/topic.js @@ -1,12 +1,11 @@ exports.commands = ["topic"]; exports.input = function(network, chan, cmd, args) { - var msg = "TOPIC"; - msg += " " + chan.name; + var msg = chan.name; msg += args[0] ? (" :" + args.join(" ")) : ""; var irc = network.irc; - irc.write(msg); + irc.raw("TOPIC", msg); return true; }; diff --git a/src/plugins/irc-events/error.js b/src/plugins/irc-events/error.js index fd65e494..f26d6836 100644 --- a/src/plugins/irc-events/error.js +++ b/src/plugins/irc-events/error.js @@ -27,6 +27,6 @@ module.exports = function(irc, network) { }); var random = irc.user.nick + Math.floor(10 + (Math.random() * 89)); - irc.raw("NICK", random); + irc.changeNick(random); }); }; diff --git a/src/plugins/irc-events/part.js b/src/plugins/irc-events/part.js index 7006ac0a..ef1e4467 100644 --- a/src/plugins/irc-events/part.js +++ b/src/plugins/irc-events/part.js @@ -23,7 +23,7 @@ module.exports = function(irc, network) { }); var msg = new Msg({ type: Msg.Type.PART, - mode: user.mode || "", + mode: (user && user.mode) || "", text: data.message || "", hostmask: data.ident + "@" + data.hostname, from: from From 470b0a2c4f4afc65f8730fb1d8912daa077eeca0 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 8 Mar 2016 18:01:56 +0200 Subject: [PATCH 10/46] Fix test --- test/plugins/link.js | 2 +- test/util.js | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/plugins/link.js b/test/plugins/link.js index 278a2713..e6ad0a94 100644 --- a/test/plugins/link.js +++ b/test/plugins/link.js @@ -26,7 +26,7 @@ describe("Link plugin", function() { }); this.irc.createMessage({ - message: "http://localhost:9002/basic" + msg: "http://localhost:9002/basic" }); this.irc.once("toggle", function(data) { diff --git a/test/util.js b/test/util.js index cda4a419..07478867 100644 --- a/test/util.js +++ b/test/util.js @@ -4,7 +4,7 @@ var _ = require("lodash"); var express = require("express"); function MockClient(opts) { - this.me = "test-user"; + this.user = {nick: "test-user"}; for (var k in opts) { this[k] = opts[k]; @@ -15,12 +15,12 @@ util.inherits(MockClient, EventEmitter); MockClient.prototype.createMessage = function(opts) { var message = _.extend({ - message: "dummy message", - from: "test-user", - to: "test-channel" + msg: "dummy message", + nick: "test-user", + target: "#test-channel" }, opts); - this.emit("message", message); + this.emit("privmsg", message); }; module.exports = { @@ -30,7 +30,7 @@ module.exports = { createNetwork: function() { return { channels: [{ - name: "test-channel", + name: "#test-channel", messages: [] }] }; From 28ae544b2a08e64709b35f2302ed197a31251a90 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 8 Mar 2016 20:50:48 +0200 Subject: [PATCH 11/46] Move connection events to a separate file, sync PREFIX with frontend --- client/js/lounge.js | 6 +++ src/client.js | 66 ++++++--------------------- src/models/network.js | 4 +- src/plugins/irc-events/connection.js | 68 ++++++++++++++++++++++++++++ src/plugins/irc-events/message.js | 5 ++ src/plugins/irc-events/welcome.js | 1 - 6 files changed, 97 insertions(+), 53 deletions(-) create mode 100644 src/plugins/irc-events/connection.js diff --git a/client/js/lounge.js b/client/js/lounge.js index c134eba3..9335e557 100644 --- a/client/js/lounge.js +++ b/client/js/lounge.js @@ -146,6 +146,7 @@ $(function() { }) ); var channels = $.map(data.networks, function(n) { + sidebar.find("#network-" + n.id).data("options", n.serverOptions); return n.channels; }); chat.html( @@ -294,6 +295,7 @@ $(function() { networks: [data.network] }) ); + sidebar.find("#network-" + data.network.id).data("options", data.network.serverOptions); chat.append( render("chat", { channels: data.network.channels @@ -310,6 +312,10 @@ $(function() { sortable(); }); + socket.on("network_changed", function(data) { + sidebar.find("#network-" + data.network).data("options", data.serverOptions); + }); + socket.on("nick", function(data) { var id = data.network; var nick = data.nick; diff --git a/src/client.js b/src/client.js index 5196d078..284c4901 100644 --- a/src/client.js +++ b/src/client.js @@ -1,7 +1,6 @@ var _ = require("lodash"); var Chan = require("./models/chan"); var crypto = require("crypto"); -var identd = require("./identd"); var log = require("./log"); var Msg = require("./models/msg"); var Network = require("./models/network"); @@ -12,6 +11,7 @@ module.exports = Client; var id = 0; var events = [ + "connection", "ctcp", "error", "invite", @@ -172,8 +172,8 @@ Client.prototype.connect = function(args) { return; } - var irc = new ircFramework.Client(); - irc.connect({ + network.irc = new ircFramework.Client(); + network.irc.connect({ host: network.host, port: network.port, nick: nick, @@ -186,49 +186,7 @@ Client.prototype.connect = function(args) { auto_reconnect: false, // TODO: Enable auto reconnection }); - network.irc = irc; - - events.forEach(function(plugin) { - var path = "./plugins/irc-events/" + plugin; - require(path).apply(client, [ - irc, - network - ]); - }); - - 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() { + network.irc.on("registered", function() { var delay = 1000; var commands = args.commands; if (Array.isArray(commands)) { @@ -247,10 +205,18 @@ Client.prototype.connect = function(args) { if (join) { setTimeout(function() { join = join.replace(/\,/g, " ").split(/\s+/g); - irc.join(join); + network.irc.join(join); }, delay); } }); + + events.forEach(function(plugin) { + var path = "./plugins/irc-events/" + plugin; + require(path).apply(client, [ + network.irc, + network + ]); + }); }; Client.prototype.setPassword = function(hash) { @@ -373,10 +339,8 @@ Client.prototype.quit = function() { } this.networks.forEach(function(network) { var irc = network.irc; - if (network.connected) { - irc.quit(); - } else { - irc.stream.end(); + if (irc.connection) { + irc.connection.end(); } }); }; diff --git a/src/models/network.js b/src/models/network.js index 5e0200dc..cb6d4735 100644 --- a/src/models/network.js +++ b/src/models/network.js @@ -16,9 +16,11 @@ function Network(attr) { username: "", realname: "", channels: [], - connected: false, id: id++, irc: null, + serverOptions: { + PREFIX: [], + }, }, attr)); this.name = attr.name || prettify(attr.host); this.channels.unshift( diff --git a/src/plugins/irc-events/connection.js b/src/plugins/irc-events/connection.js new file mode 100644 index 00000000..44e75714 --- /dev/null +++ b/src/plugins/irc-events/connection.js @@ -0,0 +1,68 @@ +var identd = require("../../identd"); +var Msg = require("../../models/msg"); + +module.exports = function(irc, network) { + var client = this; + + client.emit("msg", { + chan: network.channels[0].id, + msg: new Msg({ + text: "Network created, connecting to " + network.host + ":" + network.port + "..." + }) + }); + + 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({ + text: "Disconnected from the network." + }) + }); + }); + + irc.on("socket error", function(err) { + console.log(err); + client.emit("msg", { + chan: network.channels[0].id, + msg: new Msg({ + type: Msg.Type.ERROR, + text: "Socket error: " + err + }) + }); + }); + + irc.on("reconnecting", function() { + client.emit("msg", { + chan: network.channels[0].id, + msg: new Msg({ + text: "Reconnecting..." + }) + }); + }); + + irc.on("server options", function(data) { + if (network.serverOptions.PREFIX === data.options.PREFIX) { + return; + } + + network.serverOptions.PREFIX = data.options.PREFIX; + + client.emit("network_changed", { + network: network.id, + serverOptions: network.serverOptions + }); + }); +}; diff --git a/src/plugins/irc-events/message.js b/src/plugins/irc-events/message.js index c8677113..467ec2ae 100644 --- a/src/plugins/irc-events/message.js +++ b/src/plugins/irc-events/message.js @@ -42,6 +42,11 @@ module.exports = function(irc, network) { } } + // Server messages go to server window + if (data.from_server) { + chan = network.channels[0]; + } + var self = data.nick === irc.user.nick; // Self messages are never highlighted diff --git a/src/plugins/irc-events/welcome.js b/src/plugins/irc-events/welcome.js index 23c5f54f..ef8de616 100644 --- a/src/plugins/irc-events/welcome.js +++ b/src/plugins/irc-events/welcome.js @@ -3,7 +3,6 @@ var Msg = require("../../models/msg"); module.exports = function(irc, network) { var client = this; irc.on("registered", function(data) { - network.connected = true; network.nick = data.nick; var lobby = network.channels[0]; var msg = new Msg({ From b6993f6e375f042d5b261a7844faca7519ceb69e Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Wed, 9 Mar 2016 10:27:01 +0200 Subject: [PATCH 12/46] Make whois work --- client/views/actions/whois.tpl | 29 +++++++++++++++++++---------- src/plugins/irc-events/whois.js | 27 +++++++++++++++++---------- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/client/views/actions/whois.tpl b/client/views/actions/whois.tpl index 0e17a02c..d890efcf 100644 --- a/client/views/actions/whois.tpl +++ b/client/views/actions/whois.tpl @@ -1,26 +1,35 @@
- {{whois.nickname}} - ({{whois.username}}@{{whois.hostname}}): + {{whois.nick}} + ({{whois.user}}@{{whois.host}}): {{whois.realname}}
+{{#if whois.account}} +
+ {{whois.nick}} + is logged in as {{whois.account}} +
+{{/if}} {{#if whois.channels}}
- {{whois.nickname}} - is on the following channels: - {{#each whois.channels}} - {{{parse this}}} - {{/each}} + {{whois.nick}} + is on the following channels: {{{parse whois.channels}}}
{{/if}} {{#if whois.server}}
- {{whois.nickname}} - is connected to {{whois.server}} + {{whois.nick}} + is connected to {{whois.server}} ({{whois.server_info}}) +
+{{/if}} +{{#if whois.secure}} +
+ {{whois.nick}} + is using a secure connection
{{/if}} {{#if whois.away}}
- {{whois.nickname}} + {{whois.nick}} is away ({{whois.away}})
{{/if}} diff --git a/src/plugins/irc-events/whois.js b/src/plugins/irc-events/whois.js index d4d8374b..d10c7426 100644 --- a/src/plugins/irc-events/whois.js +++ b/src/plugins/irc-events/whois.js @@ -4,15 +4,12 @@ var Msg = require("../../models/msg"); module.exports = function(irc, network) { var client = this; - irc.on("whois", function(err, data) { - if (data === null) { - return; - } - var chan = _.find(network.channels, {name: data.nickname}); + irc.on("whois", function(data) { + var chan = _.find(network.channels, {name: data.nick}); if (typeof chan === "undefined") { chan = new Chan({ type: Chan.Type.QUERY, - name: data.nickname + name: data.nick }); network.channels.push(chan); client.emit("join", { @@ -20,10 +17,20 @@ module.exports = function(irc, network) { chan: chan }); } - var msg = new Msg({ - type: Msg.Type.WHOIS, - whois: data - }); + + var msg; + if (data.error) { + msg = new Msg({ + type: Msg.Type.ERROR, + text: "No such nick: " + data.nick + }); + } else { + msg = new Msg({ + type: Msg.Type.WHOIS, + whois: data + }); + } + chan.messages.push(msg); client.emit("msg", { chan: chan.id, From dff6eb33c56f0b4d248a05f1121cf65934a91982 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Fri, 11 Mar 2016 18:34:50 +0200 Subject: [PATCH 13/46] Maintain backwards compatibility by sending symbols to the client --- src/plugins/irc-events/connection.js | 7 +++++++ src/plugins/irc-events/names.js | 9 ++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/plugins/irc-events/connection.js b/src/plugins/irc-events/connection.js index 44e75714..18ceb3f2 100644 --- a/src/plugins/irc-events/connection.js +++ b/src/plugins/irc-events/connection.js @@ -1,3 +1,4 @@ +var _ = require("lodash"); var identd = require("../../identd"); var Msg = require("../../models/msg"); @@ -58,6 +59,12 @@ module.exports = function(irc, network) { return; } + network.prefixLookup = {}; + + _.each(data.options.PREFIX, function(mode) { + network.prefixLookup[mode.mode] = mode.symbol; + }); + network.serverOptions.PREFIX = data.options.PREFIX; client.emit("network_changed", { diff --git a/src/plugins/irc-events/names.js b/src/plugins/irc-events/names.js index 5612b09f..fb176075 100644 --- a/src/plugins/irc-events/names.js +++ b/src/plugins/irc-events/names.js @@ -10,7 +10,14 @@ module.exports = function(irc, network) { } chan.users = []; _.each(data.users, function(u) { - chan.users.push(new User(u)); + var user = new User(u); + + // irc-framework sets characater mode, but lounge works with symbols + if (user.mode) { + user.mode = network.prefixLookup[user.mode]; + } + + chan.users.push(user); }); chan.sortUsers(); client.emit("users", { From 7baf5f0f81334f4ffa4121970fd4b16d305981b4 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sat, 12 Mar 2016 11:36:27 +0200 Subject: [PATCH 14/46] Remove unused notice event --- src/plugins/irc-events/notice.js | 33 -------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 src/plugins/irc-events/notice.js diff --git a/src/plugins/irc-events/notice.js b/src/plugins/irc-events/notice.js deleted file mode 100644 index 391ebda8..00000000 --- a/src/plugins/irc-events/notice.js +++ /dev/null @@ -1,33 +0,0 @@ -var _ = require("lodash"); -var Msg = require("../../models/msg"); - -module.exports = function(irc, network) { - var client = this; - irc.on("notice", function(data) { - var target = data.to; - if (target.toLowerCase() === irc.me.toLowerCase()) { - target = data.from; - } - - var chan = _.find(network.channels, {name: target}); - if (typeof chan === "undefined") { - chan = network.channels[0]; - } - - var from = data.from || ""; - if (data.to === "*" || data.from.indexOf(".") !== -1) { - from = ""; - } - var msg = new Msg({ - type: Msg.Type.NOTICE, - mode: chan.getMode(from), - from: from, - text: data.message - }); - chan.messages.push(msg); - client.emit("msg", { - chan: chan.id, - msg: msg - }); - }); -}; From 516ccd965fa229ac2238a328c0d1f238036d9472 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sat, 12 Mar 2016 11:36:55 +0200 Subject: [PATCH 15/46] Add support for IRCv3 server-time --- src/models/msg.js | 7 ++++++- src/plugins/irc-events/join.js | 1 + src/plugins/irc-events/kick.js | 1 + src/plugins/irc-events/message.js | 1 + src/plugins/irc-events/mode.js | 1 + src/plugins/irc-events/nick.js | 1 + src/plugins/irc-events/part.js | 1 + src/plugins/irc-events/quit.js | 1 + src/plugins/irc-events/topic.js | 1 + 9 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/models/msg.js b/src/models/msg.js index d176c8f5..d0c8a0db 100644 --- a/src/models/msg.js +++ b/src/models/msg.js @@ -28,8 +28,13 @@ function Msg(attr) { from: "", id: id++, text: "", - time: new Date(), type: Msg.Type.MESSAGE, self: false }, attr)); + + if (attr.time > 0) { + attr.time = new Date(attr.time); + } else { + attr.time = new Date(); + } } diff --git a/src/plugins/irc-events/join.js b/src/plugins/irc-events/join.js index 4410e9c3..a9bacc80 100644 --- a/src/plugins/irc-events/join.js +++ b/src/plugins/irc-events/join.js @@ -24,6 +24,7 @@ module.exports = function(irc, network) { chan: chan.id }); var msg = new Msg({ + time: data.time, from: data.nick, hostmask: data.ident + "@" + data.hostname, type: Msg.Type.JOIN, diff --git a/src/plugins/irc-events/kick.js b/src/plugins/irc-events/kick.js index 2fb81fc2..d1713e19 100644 --- a/src/plugins/irc-events/kick.js +++ b/src/plugins/irc-events/kick.js @@ -21,6 +21,7 @@ module.exports = function(irc, network) { var msg = new Msg({ type: Msg.Type.KICK, + time: data.time, mode: chan.getMode(data.nick), from: data.nick, target: data.kicked, diff --git a/src/plugins/irc-events/message.js b/src/plugins/irc-events/message.js index 467ec2ae..dd20e1fd 100644 --- a/src/plugins/irc-events/message.js +++ b/src/plugins/irc-events/message.js @@ -65,6 +65,7 @@ module.exports = function(irc, network) { var msg = new Msg({ type: data.type, + time: data.time, mode: chan.getMode(data.nick), from: data.nick, text: data.msg, diff --git a/src/plugins/irc-events/mode.js b/src/plugins/irc-events/mode.js index d50117a7..fd734439 100644 --- a/src/plugins/irc-events/mode.js +++ b/src/plugins/irc-events/mode.js @@ -24,6 +24,7 @@ module.exports = function(irc, network) { } var msg = new Msg({ + time: data.time, type: Msg.Type.MODE, mode: (targetChan.type !== Chan.Type.LOBBY && targetChan.getMode(data.nick)) || "", from: data.nick, diff --git a/src/plugins/irc-events/nick.js b/src/plugins/irc-events/nick.js index 93926db4..6a810e80 100644 --- a/src/plugins/irc-events/nick.js +++ b/src/plugins/irc-events/nick.js @@ -34,6 +34,7 @@ module.exports = function(irc, network) { chan: chan.id }); var msg = new Msg({ + time: data.time, type: Msg.Type.NICK, mode: chan.getMode(data.newnick), nick: data.nick, diff --git a/src/plugins/irc-events/part.js b/src/plugins/irc-events/part.js index ef1e4467..8043920a 100644 --- a/src/plugins/irc-events/part.js +++ b/src/plugins/irc-events/part.js @@ -23,6 +23,7 @@ module.exports = function(irc, network) { }); var msg = new Msg({ type: Msg.Type.PART, + time: data.time, mode: (user && user.mode) || "", text: data.message || "", hostmask: data.ident + "@" + data.hostname, diff --git a/src/plugins/irc-events/quit.js b/src/plugins/irc-events/quit.js index 87dd2eab..288135af 100644 --- a/src/plugins/irc-events/quit.js +++ b/src/plugins/irc-events/quit.js @@ -15,6 +15,7 @@ module.exports = function(irc, network) { chan: chan.id }); var msg = new Msg({ + time: data.time, type: Msg.Type.QUIT, mode: user.mode || "", text: data.message || "", diff --git a/src/plugins/irc-events/topic.js b/src/plugins/irc-events/topic.js index abf66fbb..0330d139 100644 --- a/src/plugins/irc-events/topic.js +++ b/src/plugins/irc-events/topic.js @@ -10,6 +10,7 @@ module.exports = function(irc, network) { } var msg = new Msg({ + time: data.time, type: Msg.Type.TOPIC, mode: (data.nick && chan.getMode(data.nick)) || "", from: data.nick, From 071881a9fa8fbdbfcffc64df9593995ee11ff0b8 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Mon, 14 Mar 2016 13:44:06 +0200 Subject: [PATCH 16/46] Sort user list within a single pass, use server provided user modes --- src/models/chan.js | 25 ++++++++++++++----------- src/plugins/irc-events/join.js | 2 +- src/plugins/irc-events/names.js | 2 +- src/plugins/irc-events/nick.js | 2 +- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/models/chan.js b/src/models/chan.js index a3501097..a6f232b8 100644 --- a/src/models/chan.js +++ b/src/models/chan.js @@ -23,18 +23,21 @@ function Chan(attr) { }, attr)); } -Chan.prototype.sortUsers = function() { - this.users = _.sortBy( - this.users, - function(u) { return u.name.toLowerCase(); } - ); +Chan.prototype.sortUsers = function(irc) { + var userModeSortPriority = {}; + irc.network.options.PREFIX.forEach(function(prefix, index) { + userModeSortPriority[prefix.symbol] = index; + }); - ["+", "%", "@", "&", "~"].forEach(function(mode) { - this.users = _.remove( - this.users, - function(u) { return u.mode === mode; } - ).concat(this.users); - }, this); + userModeSortPriority[""] = 99; // No mode is lowest + + this.users = this.users.sort(function(a, b) { + if (a.mode === b.mode) { + return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; + } + + return userModeSortPriority[a.mode] - userModeSortPriority[b.mode]; + }); }; Chan.prototype.getMode = function(name) { diff --git a/src/plugins/irc-events/join.js b/src/plugins/irc-events/join.js index a9bacc80..e447f99e 100644 --- a/src/plugins/irc-events/join.js +++ b/src/plugins/irc-events/join.js @@ -19,7 +19,7 @@ module.exports = function(irc, network) { }); } chan.users.push(new User({nick: data.nick, modes: ""})); - chan.sortUsers(); + chan.sortUsers(irc); client.emit("users", { chan: chan.id }); diff --git a/src/plugins/irc-events/names.js b/src/plugins/irc-events/names.js index fb176075..a41c7541 100644 --- a/src/plugins/irc-events/names.js +++ b/src/plugins/irc-events/names.js @@ -19,7 +19,7 @@ module.exports = function(irc, network) { chan.users.push(user); }); - chan.sortUsers(); + chan.sortUsers(irc); client.emit("users", { chan: chan.id }); diff --git a/src/plugins/irc-events/nick.js b/src/plugins/irc-events/nick.js index 6a810e80..a3719cb8 100644 --- a/src/plugins/irc-events/nick.js +++ b/src/plugins/irc-events/nick.js @@ -29,7 +29,7 @@ module.exports = function(irc, network) { return; } user.name = data.newnick; - chan.sortUsers(); + chan.sortUsers(irc); client.emit("users", { chan: chan.id }); From a01216fa4cacc78fe06734aa49a1fe83f5ef89cc Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 15 Mar 2016 11:41:11 +0200 Subject: [PATCH 17/46] Update irc-framework --- client/views/actions/whois.tpl | 2 +- package.json | 2 +- src/plugins/irc-events/ctcp.js | 2 +- src/plugins/irc-events/message.js | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/views/actions/whois.tpl b/client/views/actions/whois.tpl index d890efcf..9c91d2ac 100644 --- a/client/views/actions/whois.tpl +++ b/client/views/actions/whois.tpl @@ -1,7 +1,7 @@
{{whois.nick}} ({{whois.user}}@{{whois.host}}): - {{whois.realname}} + {{whois.real_name}}
{{#if whois.account}}
diff --git a/package.json b/package.json index 35c97db1..4a70004f 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "event-stream": "3.3.2", "express": "4.13.4", "lodash": "4.6.1", - "irc-framework": "1.0.3", + "irc-framework": "1.0.4", "mkdirp": "0.5.1", "moment": "2.12.0", "read": "1.0.7", diff --git a/src/plugins/irc-events/ctcp.js b/src/plugins/irc-events/ctcp.js index e329a4d3..b2db7973 100644 --- a/src/plugins/irc-events/ctcp.js +++ b/src/plugins/irc-events/ctcp.js @@ -7,7 +7,7 @@ module.exports = function(irc/* , network */) { irc.ctcpResponse(data.nick, "VERSION " + pkg.name + " " + pkg.version); break; case "PING": - var split = data.msg.split(" "); + var split = data.message.split(" "); if (split.length === 2) { irc.ctcpResponse(data.nick, "PING " + split[1]); } diff --git a/src/plugins/irc-events/message.js b/src/plugins/irc-events/message.js index dd20e1fd..b0c1c7fc 100644 --- a/src/plugins/irc-events/message.js +++ b/src/plugins/irc-events/message.js @@ -51,7 +51,7 @@ module.exports = function(irc, network) { // Self messages are never highlighted // Non-self messages are highlighted as soon as the nick is detected - var highlight = !self && data.msg.split(" ").some(function(w) { + var highlight = !self && data.message.split(" ").some(function(w) { return (w.replace(/^@/, "").toLowerCase().indexOf(irc.user.nick.toLowerCase()) === 0); }); @@ -68,7 +68,7 @@ module.exports = function(irc, network) { time: data.time, mode: chan.getMode(data.nick), from: data.nick, - text: data.msg, + text: data.message, self: self, highlight: highlight }); From db5fe00b604611be24b8ce7a930dc43c07bd221d Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 15 Mar 2016 11:59:36 +0200 Subject: [PATCH 18/46] A couple of fixes after rebasing and updating framework --- src/models/msg.js | 6 +++--- src/plugins/inputs/action.js | 2 +- src/plugins/inputs/msg.js | 10 +--------- src/plugins/inputs/notice.js | 2 +- test/plugins/link.js | 2 +- test/util.js | 2 +- 6 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/models/msg.js b/src/models/msg.js index d0c8a0db..00fbf04b 100644 --- a/src/models/msg.js +++ b/src/models/msg.js @@ -32,9 +32,9 @@ function Msg(attr) { self: false }, attr)); - if (attr.time > 0) { - attr.time = new Date(attr.time); + if (this.time > 0) { + this.time = new Date(this.time); } else { - attr.time = new Date(); + this.time = new Date(); } } diff --git a/src/plugins/inputs/action.js b/src/plugins/inputs/action.js index 34c8036a..4f8376ce 100644 --- a/src/plugins/inputs/action.js +++ b/src/plugins/inputs/action.js @@ -19,7 +19,7 @@ exports.input = function(network, chan, cmd, args) { irc.emit("action", { nick: irc.user.nick, target: chan.name, - msg: text + message: text }); break; } diff --git a/src/plugins/inputs/msg.js b/src/plugins/inputs/msg.js index 4afaa5c4..1e98d886 100644 --- a/src/plugins/inputs/msg.js +++ b/src/plugins/inputs/msg.js @@ -1,16 +1,8 @@ var _ = require("lodash"); -<<<<<<< fbbb3d20d287243d2c3c5525d86801f54f903603 exports.commands = ["msg", "say"]; exports.input = function(network, chan, cmd, args) { -======= -module.exports = function(network, chan, cmd, args) { - if (cmd !== "say" && cmd !== "msg") { - return; - } - ->>>>>>> Update commands if (args.length === 0 || args[0] === "") { return true; } @@ -34,7 +26,7 @@ module.exports = function(network, chan, cmd, args) { irc.emit("privmsg", { nick: irc.user.nick, target: channel.name, - msg: msg + message: msg }); } diff --git a/src/plugins/inputs/notice.js b/src/plugins/inputs/notice.js index ca0a5e6c..e16cb74b 100644 --- a/src/plugins/inputs/notice.js +++ b/src/plugins/inputs/notice.js @@ -20,7 +20,7 @@ exports.input = function(network, chan, cmd, args) { irc.emit("notice", { nick: irc.user.nick, target: targetChan.name, - msg: message + message: message }); return true; diff --git a/test/plugins/link.js b/test/plugins/link.js index e6ad0a94..278a2713 100644 --- a/test/plugins/link.js +++ b/test/plugins/link.js @@ -26,7 +26,7 @@ describe("Link plugin", function() { }); this.irc.createMessage({ - msg: "http://localhost:9002/basic" + message: "http://localhost:9002/basic" }); this.irc.once("toggle", function(data) { diff --git a/test/util.js b/test/util.js index 07478867..aea080bb 100644 --- a/test/util.js +++ b/test/util.js @@ -15,7 +15,7 @@ util.inherits(MockClient, EventEmitter); MockClient.prototype.createMessage = function(opts) { var message = _.extend({ - msg: "dummy message", + message: "dummy message", nick: "test-user", target: "#test-channel" }, opts); From 17bcc37b808bcbc9b30861ce449b1bf137989662 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Wed, 16 Mar 2016 22:54:11 +0200 Subject: [PATCH 19/46] Request names on mode change as a temporary measure --- src/plugins/irc-events/error.js | 6 +++++- src/plugins/irc-events/mode.js | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/plugins/irc-events/error.js b/src/plugins/irc-events/error.js index f26d6836..9756c9b5 100644 --- a/src/plugins/irc-events/error.js +++ b/src/plugins/irc-events/error.js @@ -4,10 +4,14 @@ module.exports = function(irc, network) { var client = this; irc.on("irc_error", function(data) { console.log(data); + var text = data.error; + if (data.reason) { + text = data.reason + " (" + text + ")"; + } var lobby = network.channels[0]; var msg = new Msg({ type: Msg.Type.ERROR, - text: data.error, + text: text, }); client.emit("msg", { chan: lobby.id, diff --git a/src/plugins/irc-events/mode.js b/src/plugins/irc-events/mode.js index fd734439..e205c66c 100644 --- a/src/plugins/irc-events/mode.js +++ b/src/plugins/irc-events/mode.js @@ -16,11 +16,18 @@ module.exports = function(irc, network) { } } + var usersUpdated; + for (var i = 0; i < data.modes.length; i++) { var mode = data.modes[i]; var text = mode.mode; if (mode.param) { text += " " + mode.param; + + var user = _.find(targetChan.users, {name: mode.param}); + if (typeof user !== "undefined") { + usersUpdated = true; + } } var msg = new Msg({ @@ -37,5 +44,10 @@ module.exports = function(irc, network) { msg: msg, }); } + + if (usersUpdated) { + // TODO: This is horrible + irc.raw("NAMES", data.target); + } }); }; From b19e79c48f082d4d5dffb05850c4228241ce6515 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Wed, 16 Mar 2016 23:49:45 +0200 Subject: [PATCH 20/46] Fix autojoining and allow autojoing with keys Syntax is like "#a,#b,#c keya,keyb" --- src/client.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client.js b/src/client.js index 284c4901..91a9d120 100644 --- a/src/client.js +++ b/src/client.js @@ -204,8 +204,8 @@ Client.prototype.connect = function(args) { var join = (args.join || ""); if (join) { setTimeout(function() { - join = join.replace(/\,/g, " ").split(/\s+/g); - network.irc.join(join); + join = join.split(/\s+/); + network.irc.join(join[0], join[1]); }, delay); } }); From 54526215a4f06c6df97004a68e10e51ad03e2533 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Thu, 17 Mar 2016 20:55:51 +0200 Subject: [PATCH 21/46] Correctly create new windows for private messages --- src/plugins/irc-events/message.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/plugins/irc-events/message.js b/src/plugins/irc-events/message.js index b0c1c7fc..f9338dee 100644 --- a/src/plugins/irc-events/message.js +++ b/src/plugins/irc-events/message.js @@ -23,16 +23,22 @@ module.exports = function(irc, network) { }); function handleMessage(data) { - // First, try to find current target - var chan = _.find(network.channels, {name: data.target}); - if (typeof chan === "undefined") { - // If current target doesn't exist, try to find by nick - chan = _.find(network.channels, {name: data.nick}); - // If neither target or nick channels exist, create one for the nick + // Server messages go to server window, no questions asked + if (data.from_server) { + chan = network.channels[0]; + } else { + var target = data.target; + + // If the message is targeted at us, use sender as target instead + if (target.toLowerCase() === irc.user.nick.toLowerCase()) { + target = data.nick; + } + + var chan = _.find(network.channels, {name: target}); if (typeof chan === "undefined") { chan = new Chan({ type: Chan.Type.QUERY, - name: data.nick + name: target }); network.channels.push(chan); client.emit("join", { @@ -42,11 +48,6 @@ module.exports = function(irc, network) { } } - // Server messages go to server window - if (data.from_server) { - chan = network.channels[0]; - } - var self = data.nick === irc.user.nick; // Self messages are never highlighted From 40677e32489eae8a2c302761bdab015985bbe6e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Astori?= Date: Fri, 18 Mar 2016 00:52:17 -0400 Subject: [PATCH 22/46] Update tests to match the new irc-framework models --- src/models/user.js | 4 ++-- test/models/chan.js | 24 ++++++++++++++++-------- test/models/network.js | 2 +- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/models/user.js b/src/models/user.js index 79c8947d..68d251d1 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -4,8 +4,8 @@ module.exports = User; function User(attr) { // TODO: Remove this - attr.name = attr.nick; - attr.mode = attr.modes[0] || ""; + attr.name = attr.name || attr.nick; + attr.mode = attr.mode || (attr.modes && attr.modes[0]) || ""; _.merge(this, _.extend({ mode: "", diff --git a/test/models/chan.js b/test/models/chan.js index d6e42714..90f8c609 100644 --- a/test/models/chan.js +++ b/test/models/chan.js @@ -5,8 +5,9 @@ var expect = require("chai").expect; var Chan = require("../../src/models/chan"); var User = require("../../src/models/user"); -function makeUser(name, mode) { - return new User({name: name, mode: mode}); +function makeUser(name) { + // TODO Update/Fix this when User constructor gets reworked (see its TODO) + return new User({nick: name, mode: ""}); } function getUserNames(chan) { @@ -14,13 +15,20 @@ function getUserNames(chan) { } describe("Chan", function() { - describe("#sortUsers()", function() { + describe("#sortUsers(irc)", function() { + var fullNetworkPrefix = [ + {symbol: "~", mode: "q"}, + {symbol: "&", mode: "a"}, + {symbol: "@", mode: "o"}, + {symbol: "%", mode: "h"}, + {symbol: "+", mode: "v"} + ]; it("should sort a simple user list", function() { var chan = new Chan({users: [ "JocelynD", "YaManicKill", "astorije", "xPaw", "Max-P" ].map(makeUser)}); - chan.sortUsers(); + chan.sortUsers({network: {options: {PREFIX: fullNetworkPrefix}}}); expect(getUserNames(chan)).to.deep.equal([ "astorije", "JocelynD", "Max-P", "xPaw", "YaManicKill" @@ -35,7 +43,7 @@ describe("Chan", function() { new User({name: "xPaw", mode: "~"}), new User({name: "Max-P", mode: "@"}), ]}); - chan.sortUsers(); + chan.sortUsers({network: {options: {PREFIX: fullNetworkPrefix}}}); expect(getUserNames(chan)).to.deep.equal([ "xPaw", "JocelynD", "Max-P", "astorije", "YaManicKill" @@ -50,7 +58,7 @@ describe("Chan", function() { new User({name: "xPaw"}), new User({name: "Max-P", mode: "@"}), ]}); - chan.sortUsers(); + chan.sortUsers({network: {options: {PREFIX: fullNetworkPrefix}}}); expect(getUserNames(chan)).to.deep.equal( ["Max-P", "YaManicKill", "astorije", "JocelynD", "xPaw"] @@ -59,7 +67,7 @@ describe("Chan", function() { it("should be case-insensitive", function() { var chan = new Chan({users: ["aB", "Ad", "AA", "ac"].map(makeUser)}); - chan.sortUsers(); + chan.sortUsers({network: {options: {PREFIX: fullNetworkPrefix}}}); expect(getUserNames(chan)).to.deep.equal(["AA", "aB", "ac", "Ad"]); }); @@ -69,7 +77,7 @@ describe("Chan", function() { "[foo", "]foo", "(foo)", "{foo}", "", "_foo", "@foo", "^foo", "&foo", "!foo", "+foo", "Foo" ].map(makeUser)}); - chan.sortUsers(); + chan.sortUsers({network: {options: {PREFIX: fullNetworkPrefix}}}); expect(getUserNames(chan)).to.deep.equal([ "!foo", "&foo", "(foo)", "+foo", "", "@foo", "[foo", "]foo", diff --git a/test/models/network.js b/test/models/network.js index 300e6545..dcd9d92b 100644 --- a/test/models/network.js +++ b/test/models/network.js @@ -22,7 +22,7 @@ describe("Network", function() { username: "", realname: "", commands: [], - nick: undefined, + nick: "", join: "#thelounge,&foobar", }); }); From e0fb454223b22f65b1a112e1aba17b6711dd9bc1 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sun, 20 Mar 2016 16:28:47 +0200 Subject: [PATCH 23/46] Search channel case insensitively --- src/models/network.js | 8 ++++++++ src/plugins/inputs/msg.js | 4 +--- src/plugins/inputs/notice.js | 4 +--- src/plugins/irc-events/invite.js | 3 +-- src/plugins/irc-events/join.js | 3 +-- src/plugins/irc-events/kick.js | 2 +- src/plugins/irc-events/link.js | 2 +- src/plugins/irc-events/message.js | 3 +-- src/plugins/irc-events/mode.js | 2 +- src/plugins/irc-events/names.js | 2 +- src/plugins/irc-events/part.js | 2 +- src/plugins/irc-events/topic.js | 5 ++--- src/plugins/irc-events/whois.js | 3 +-- 13 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/models/network.js b/src/models/network.js index cb6d4735..1df03704 100644 --- a/src/models/network.js +++ b/src/models/network.js @@ -55,6 +55,14 @@ Network.prototype.export = function() { return network; }; +Network.prototype.getChannel = function(name) { + name = name.toLowerCase(); + + return _.find(this.channels, function(that) { + return that.name.toLowerCase() === name; + }); +}; + function prettify(host) { var name = capitalize(host.split(".")[1]); if (!name) { diff --git a/src/plugins/inputs/msg.js b/src/plugins/inputs/msg.js index 1e98d886..a562b607 100644 --- a/src/plugins/inputs/msg.js +++ b/src/plugins/inputs/msg.js @@ -1,5 +1,3 @@ -var _ = require("lodash"); - exports.commands = ["msg", "say"]; exports.input = function(network, chan, cmd, args) { @@ -21,7 +19,7 @@ exports.input = function(network, chan, cmd, args) { var msg = args.join(" "); irc.say(target, msg); - var channel = _.find(network.channels, {name: target}); + var channel = network.getChannel(target); if (typeof channel !== "undefined") { irc.emit("privmsg", { nick: irc.user.nick, diff --git a/src/plugins/inputs/notice.js b/src/plugins/inputs/notice.js index e16cb74b..33aeda00 100644 --- a/src/plugins/inputs/notice.js +++ b/src/plugins/inputs/notice.js @@ -1,5 +1,3 @@ -var _ = require("lodash"); - exports.commands = ["notice"]; exports.input = function(network, chan, cmd, args) { @@ -11,7 +9,7 @@ exports.input = function(network, chan, cmd, args) { var irc = network.irc; irc.notice(args[0], message); - var targetChan = _.find(network.channels, {name: args[0]}); + var targetChan = network.getChannel(args[0]); if (typeof targetChan === "undefined") { message = "{to " + args[0] + "} " + message; targetChan = chan; diff --git a/src/plugins/irc-events/invite.js b/src/plugins/irc-events/invite.js index cc3a4229..0f00e87d 100644 --- a/src/plugins/irc-events/invite.js +++ b/src/plugins/irc-events/invite.js @@ -1,4 +1,3 @@ -var _ = require("lodash"); var Msg = require("../../models/msg"); module.exports = function(irc, network) { @@ -6,7 +5,7 @@ module.exports = function(irc, network) { irc.on("invite", function(data) { var target = data.to; - var chan = _.find(network.channels, {name: data.channel}); + var chan = network.getChannel(data.channel); if (typeof chan === "undefined") { chan = network.channels[0]; } diff --git a/src/plugins/irc-events/join.js b/src/plugins/irc-events/join.js index e447f99e..d2f6496e 100644 --- a/src/plugins/irc-events/join.js +++ b/src/plugins/irc-events/join.js @@ -1,4 +1,3 @@ -var _ = require("lodash"); var Chan = require("../../models/chan"); var Msg = require("../../models/msg"); var User = require("../../models/user"); @@ -6,7 +5,7 @@ var User = require("../../models/user"); module.exports = function(irc, network) { var client = this; irc.on("join", function(data) { - var chan = _.find(network.channels, {name: data.channel}); + var chan = network.getChannel(data.channel); if (typeof chan === "undefined") { chan = new Chan({ name: data.channel diff --git a/src/plugins/irc-events/kick.js b/src/plugins/irc-events/kick.js index d1713e19..8e2522d9 100644 --- a/src/plugins/irc-events/kick.js +++ b/src/plugins/irc-events/kick.js @@ -4,7 +4,7 @@ var Msg = require("../../models/msg"); module.exports = function(irc, network) { var client = this; irc.on("kick", function(data) { - var chan = _.find(network.channels, {name: data.channel}); + var chan = network.getChannel(data.channel); if (typeof chan === "undefined") { return; } diff --git a/src/plugins/irc-events/link.js b/src/plugins/irc-events/link.js index 1f687b73..1f19bba0 100644 --- a/src/plugins/irc-events/link.js +++ b/src/plugins/irc-events/link.js @@ -27,7 +27,7 @@ module.exports = function(irc, network) { return; } - var chan = _.find(network.channels, {name: data.target}); + var chan = network.getChannel(data.target); if (typeof chan === "undefined") { return; } diff --git a/src/plugins/irc-events/message.js b/src/plugins/irc-events/message.js index f9338dee..42a7aa9d 100644 --- a/src/plugins/irc-events/message.js +++ b/src/plugins/irc-events/message.js @@ -1,4 +1,3 @@ -var _ = require("lodash"); var Chan = require("../../models/chan"); var Msg = require("../../models/msg"); var Helper = require("../../helper"); @@ -34,7 +33,7 @@ module.exports = function(irc, network) { target = data.nick; } - var chan = _.find(network.channels, {name: target}); + var chan = network.getChannel(target); if (typeof chan === "undefined") { chan = new Chan({ type: Chan.Type.QUERY, diff --git a/src/plugins/irc-events/mode.js b/src/plugins/irc-events/mode.js index e205c66c..1444720f 100644 --- a/src/plugins/irc-events/mode.js +++ b/src/plugins/irc-events/mode.js @@ -10,7 +10,7 @@ module.exports = function(irc, network) { if (data.target === irc.user.nick) { targetChan = network.channels[0]; } else { - targetChan = _.find(network.channels, {name: data.target}); + targetChan = network.getChannel(data.target); if (typeof targetChan === "undefined") { return; } diff --git a/src/plugins/irc-events/names.js b/src/plugins/irc-events/names.js index a41c7541..4307ff22 100644 --- a/src/plugins/irc-events/names.js +++ b/src/plugins/irc-events/names.js @@ -4,7 +4,7 @@ var User = require("../../models/user"); module.exports = function(irc, network) { var client = this; irc.on("userlist", function(data) { - var chan = _.find(network.channels, {name: data.channel}); + var chan = network.getChannel(data.channel); if (typeof chan === "undefined") { return; } diff --git a/src/plugins/irc-events/part.js b/src/plugins/irc-events/part.js index 8043920a..5aee2c49 100644 --- a/src/plugins/irc-events/part.js +++ b/src/plugins/irc-events/part.js @@ -4,7 +4,7 @@ var Msg = require("../../models/msg"); module.exports = function(irc, network) { var client = this; irc.on("part", function(data) { - var chan = _.find(network.channels, {name: data.channel}); + var chan = network.getChannel(data.channel); if (typeof chan === "undefined") { return; } diff --git a/src/plugins/irc-events/topic.js b/src/plugins/irc-events/topic.js index 0330d139..be63c451 100644 --- a/src/plugins/irc-events/topic.js +++ b/src/plugins/irc-events/topic.js @@ -1,10 +1,9 @@ -var _ = require("lodash"); var Msg = require("../../models/msg"); module.exports = function(irc, network) { var client = this; irc.on("topic", function(data) { - var chan = _.find(network.channels, {name: data.channel}); + var chan = network.getChannel(data.channel); if (typeof chan === "undefined") { return; } @@ -31,7 +30,7 @@ module.exports = function(irc, network) { }); irc.on("topicsetby", function(data) { - var chan = _.find(network.channels, {name: data.channel}); + var chan = network.getChannel(data.channel); if (typeof chan === "undefined") { return; } diff --git a/src/plugins/irc-events/whois.js b/src/plugins/irc-events/whois.js index d10c7426..ea5430d1 100644 --- a/src/plugins/irc-events/whois.js +++ b/src/plugins/irc-events/whois.js @@ -1,11 +1,10 @@ -var _ = require("lodash"); var Chan = require("../../models/chan"); var Msg = require("../../models/msg"); module.exports = function(irc, network) { var client = this; irc.on("whois", function(data) { - var chan = _.find(network.channels, {name: data.nick}); + var chan = network.getChannel(data.nick); if (typeof chan === "undefined") { chan = new Chan({ type: Chan.Type.QUERY, From 4a7fc0544e248404a1b728d3e972b30b114721a5 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sun, 20 Mar 2016 16:39:59 +0200 Subject: [PATCH 24/46] Fix link test not using network model --- test/util.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/util.js b/test/util.js index aea080bb..a0e00172 100644 --- a/test/util.js +++ b/test/util.js @@ -2,6 +2,7 @@ var EventEmitter = require("events").EventEmitter; var util = require("util"); var _ = require("lodash"); var express = require("express"); +var Network = require("../src/models/network"); function MockClient(opts) { this.user = {nick: "test-user"}; @@ -13,7 +14,6 @@ function MockClient(opts) { util.inherits(MockClient, EventEmitter); MockClient.prototype.createMessage = function(opts) { - var message = _.extend({ message: "dummy message", nick: "test-user", @@ -28,12 +28,13 @@ module.exports = { return new MockClient(); }, createNetwork: function() { - return { + return new Network({ + host: "example.com", channels: [{ name: "#test-channel", messages: [] }] - }; + }); }, createWebserver: function() { return express(); From 92cc130e2bcf4522c274c9d5058074ef2dd61d92 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sun, 20 Mar 2016 18:46:08 +0200 Subject: [PATCH 25/46] Always send notices that are not targeted at us into the server window --- src/plugins/irc-events/message.js | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/plugins/irc-events/message.js b/src/plugins/irc-events/message.js index 42a7aa9d..da5c1467 100644 --- a/src/plugins/irc-events/message.js +++ b/src/plugins/irc-events/message.js @@ -7,6 +7,12 @@ module.exports = function(irc, network) { var config = Helper.getConfig(); irc.on("notice", function(data) { + // Some servers send notices without any nickname + if (!data.nick) { + data.from_server = true; + data.nick = network.host; + } + data.type = Msg.Type.NOTICE; handleMessage(data); }); @@ -27,23 +33,30 @@ module.exports = function(irc, network) { chan = network.channels[0]; } else { var target = data.target; + var targetedAtUser = false; // If the message is targeted at us, use sender as target instead if (target.toLowerCase() === irc.user.nick.toLowerCase()) { + targetedAtUser = true; target = data.nick; } var chan = network.getChannel(target); if (typeof chan === "undefined") { - chan = new Chan({ - type: Chan.Type.QUERY, - name: target - }); - network.channels.push(chan); - client.emit("join", { - network: network.id, - chan: chan - }); + // Send notices that are not targeted at us into the server window + if (data.type === Msg.Type.NOTICE && !targetedAtUser) { + chan = network.channels[0]; + } else { + chan = new Chan({ + type: Chan.Type.QUERY, + name: target + }); + network.channels.push(chan); + client.emit("join", { + network: network.id, + chan: chan + }); + } } } From 43f58a80752d3589b836ec987c560114a154ef42 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sun, 20 Mar 2016 19:18:43 +0200 Subject: [PATCH 26/46] Format topic set date --- client/js/libs/handlebars/date.js | 7 +++++++ client/views/actions/topic_set_by.tpl | 2 +- src/plugins/irc-events/topic.js | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 client/js/libs/handlebars/date.js diff --git a/client/js/libs/handlebars/date.js b/client/js/libs/handlebars/date.js new file mode 100644 index 00000000..751e713d --- /dev/null +++ b/client/js/libs/handlebars/date.js @@ -0,0 +1,7 @@ +Handlebars.registerHelper( + "localeDate", function(date) { + date = new Date(date); + + return date.toLocaleString(); + } +); diff --git a/client/views/actions/topic_set_by.tpl b/client/views/actions/topic_set_by.tpl index 87d8ee83..d842fa67 100644 --- a/client/views/actions/topic_set_by.tpl +++ b/client/views/actions/topic_set_by.tpl @@ -1 +1 @@ -Topic set by {{nick}} on {{when}} +Topic set by {{nick}} on {{localeDate when}} diff --git a/src/plugins/irc-events/topic.js b/src/plugins/irc-events/topic.js index be63c451..f341fcd7 100644 --- a/src/plugins/irc-events/topic.js +++ b/src/plugins/irc-events/topic.js @@ -39,7 +39,7 @@ module.exports = function(irc, network) { type: Msg.Type.TOPIC_SET_BY, mode: chan.getMode(data.nick), nick: data.nick, - when: data.when, + when: new Date(data.when * 1000), self: data.nick === irc.user.nick }); chan.messages.push(msg); From 769bd16c8b079d7abd25778f08282f6377ecad9a Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sun, 20 Mar 2016 19:20:07 +0200 Subject: [PATCH 27/46] Fix sending unknown commands --- src/client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client.js b/src/client.js index 91a9d120..4e3f81e3 100644 --- a/src/client.js +++ b/src/client.js @@ -252,7 +252,7 @@ Client.prototype.input = function(data) { if (cmd in inputs) { inputs[cmd].apply(client, [target.network, target.chan, cmd, args]); } else { - target.network.irc.write(text); + target.network.irc.raw(text); } }; From d1da4b338a93ac102aaa386abc513e3a02d97bac Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sun, 20 Mar 2016 20:03:18 +0200 Subject: [PATCH 28/46] Update irc-framework, fixes quitting networks --- package.json | 2 +- src/client.js | 5 +---- src/plugins/irc-events/connection.js | 2 +- src/plugins/irc-events/error.js | 9 ++++++++- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 4a70004f..8b4702fd 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "event-stream": "3.3.2", "express": "4.13.4", "lodash": "4.6.1", - "irc-framework": "1.0.4", + "irc-framework": "1.0.6", "mkdirp": "0.5.1", "moment": "2.12.0", "read": "1.0.7", diff --git a/src/client.js b/src/client.js index 4e3f81e3..3d7a1416 100644 --- a/src/client.js +++ b/src/client.js @@ -338,10 +338,7 @@ Client.prototype.quit = function() { } } this.networks.forEach(function(network) { - var irc = network.irc; - if (irc.connection) { - irc.connection.end(); - } + network.irc.quit("Page closed"); }); }; diff --git a/src/plugins/irc-events/connection.js b/src/plugins/irc-events/connection.js index 18ceb3f2..5635c74a 100644 --- a/src/plugins/irc-events/connection.js +++ b/src/plugins/irc-events/connection.js @@ -13,7 +13,7 @@ module.exports = function(irc, network) { }); irc.on("raw socket connected", function() { - identd.hook(irc.socket, network.username); + identd.hook(irc.connection.socket, network.username); }); irc.on("socket connected", function() { diff --git a/src/plugins/irc-events/error.js b/src/plugins/irc-events/error.js index 9756c9b5..ac01756d 100644 --- a/src/plugins/irc-events/error.js +++ b/src/plugins/irc-events/error.js @@ -2,8 +2,15 @@ var Msg = require("../../models/msg"); module.exports = function(irc, network) { var client = this; + + // TODO: remove later irc.on("irc_error", function(data) { - console.log(data); + console.log("Got an irc_error"); + irc.emit("error", data); + }); + + irc.on("error", function(data) { + console.log("error", data); var text = data.error; if (data.reason) { text = data.reason + " (" + text + ")"; From 6b2ebd790d2f62039ca6dda9980292312508ba7e Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 22 Mar 2016 13:08:10 +0200 Subject: [PATCH 29/46] Always send notices for non existing targets into server window This matches current master behaviour --- src/plugins/irc-events/message.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/plugins/irc-events/message.js b/src/plugins/irc-events/message.js index da5c1467..53cda20b 100644 --- a/src/plugins/irc-events/message.js +++ b/src/plugins/irc-events/message.js @@ -33,18 +33,16 @@ module.exports = function(irc, network) { chan = network.channels[0]; } else { var target = data.target; - var targetedAtUser = false; // If the message is targeted at us, use sender as target instead if (target.toLowerCase() === irc.user.nick.toLowerCase()) { - targetedAtUser = true; target = data.nick; } var chan = network.getChannel(target); if (typeof chan === "undefined") { // Send notices that are not targeted at us into the server window - if (data.type === Msg.Type.NOTICE && !targetedAtUser) { + if (data.type === Msg.Type.NOTICE) { chan = network.channels[0]; } else { chan = new Chan({ From 3fc7036d328fe582bc6cab30944e7c9169d14a57 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Fri, 25 Mar 2016 16:43:30 +0200 Subject: [PATCH 30/46] Don't reset time in link expander and hide time with css --- client/css/style.css | 4 ++++ src/plugins/irc-events/link.js | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/client/css/style.css b/client/css/style.css index 41373540..37e5b08b 100644 --- a/client/css/style.css +++ b/client/css/style.css @@ -868,6 +868,10 @@ button, color: #f00; } +#chat .msg.toggle .time { + visibility: hidden; +} + #chat .toggle-button { background: #f5f5f5; border-radius: 2px; diff --git a/src/plugins/irc-events/link.js b/src/plugins/irc-events/link.js index 1f19bba0..af21a1d4 100644 --- a/src/plugins/irc-events/link.js +++ b/src/plugins/irc-events/link.js @@ -34,7 +34,6 @@ module.exports = function(irc, network) { var msg = new Msg({ type: Msg.Type.TOGGLE, - time: "" }); chan.messages.push(msg); client.emit("msg", { From 142aa85548780b894938624ff89bd2eaff6df01a Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sat, 26 Mar 2016 01:26:53 +0200 Subject: [PATCH 31/46] Handle invites Requires irc-fw update --- client/views/actions/invite.tpl | 4 ++-- src/plugins/irc-events/invite.js | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/client/views/actions/invite.tpl b/client/views/actions/invite.tpl index 6e689ac1..6b9cecac 100644 --- a/client/views/actions/invite.tpl +++ b/client/views/actions/invite.tpl @@ -3,7 +3,7 @@ invited {{#if invitedYou}} you {{else}} - {{target}} + {{invited}} {{/if}} to -{{{parse text}}} +{{{parse channel}}} diff --git a/src/plugins/irc-events/invite.js b/src/plugins/irc-events/invite.js index 0f00e87d..7accbb7c 100644 --- a/src/plugins/irc-events/invite.js +++ b/src/plugins/irc-events/invite.js @@ -3,8 +3,6 @@ var Msg = require("../../models/msg"); module.exports = function(irc, network) { var client = this; irc.on("invite", function(data) { - var target = data.to; - var chan = network.getChannel(data.channel); if (typeof chan === "undefined") { chan = network.channels[0]; @@ -12,10 +10,11 @@ module.exports = function(irc, network) { var msg = new Msg({ type: Msg.Type.INVITE, - from: data.from, - target: target, - text: data.channel, - invitedYou: target === irc.user.nick + time: data.time, + from: data.nick, + invited: data.invited, + channel: data.channel, + invitedYou: data.invited === irc.user.nick }); chan.messages.push(msg); client.emit("msg", { From 829b879f558ae2f91893f6c44e033ebe3b5a61ae Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sat, 26 Mar 2016 11:41:17 +0200 Subject: [PATCH 32/46] Update irc-framework --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8b4702fd..aa1f16b8 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "event-stream": "3.3.2", "express": "4.13.4", "lodash": "4.6.1", - "irc-framework": "1.0.6", + "irc-framework": "1.0.7", "mkdirp": "0.5.1", "moment": "2.12.0", "read": "1.0.7", From 338116a01e5c5882da7e00df5ecdfaf334446b1e Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sat, 26 Mar 2016 22:03:31 +0200 Subject: [PATCH 33/46] Prevent opening query windows for CHANTYPES and PREFIX --- src/plugins/inputs/query.js | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/plugins/inputs/query.js b/src/plugins/inputs/query.js index cb093015..616d1ae9 100644 --- a/src/plugins/inputs/query.js +++ b/src/plugins/inputs/query.js @@ -1,5 +1,6 @@ var _ = require("lodash"); var Chan = require("../../models/chan"); +var Msg = require("../../models/msg"); exports.commands = ["query"]; @@ -14,11 +15,31 @@ exports.input = function(network, chan, cmd, args) { return; } - // If target doesn't start with an allowed character, ignore - if (!/^[a-zA-Z_\\\[\]{}^`|]/.test(target)) { + var char = target[0]; + if (network.irc.network.options.CHANTYPES && network.irc.network.options.CHANTYPES.indexOf(char) !== -1) { + this.emit("msg", { + chan: chan.id, + msg: new Msg({ + type: Msg.Type.ERROR, + text: "You can not open query windows for channels, use /join instead." + }) + }); return; } + for (var i = 0; i < network.irc.network.options.PREFIX.length; i++) { + if (network.irc.network.options.PREFIX[i].symbol === char) { + this.emit("msg", { + chan: chan.id, + msg: new Msg({ + type: Msg.Type.ERROR, + text: "You can not open query windows for names starting with a user prefix." + }) + }); + return; + } + } + var newChan = new Chan({ type: Chan.Type.QUERY, name: target From 6c5ade3fe3fdefe6a14e83f4a0da17d841038967 Mon Sep 17 00:00:00 2001 From: Maxime Poulin Date: Sat, 26 Mar 2016 16:25:02 -0400 Subject: [PATCH 34/46] Fix the /topic command --- src/plugins/inputs/topic.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/plugins/inputs/topic.js b/src/plugins/inputs/topic.js index 7e9253c0..d9e66852 100644 --- a/src/plugins/inputs/topic.js +++ b/src/plugins/inputs/topic.js @@ -1,11 +1,8 @@ exports.commands = ["topic"]; exports.input = function(network, chan, cmd, args) { - var msg = chan.name; - msg += args[0] ? (" :" + args.join(" ")) : ""; - var irc = network.irc; - irc.raw("TOPIC", msg); + irc.raw("TOPIC", chan.name, args.join(" ")); return true; }; From 9cd4c6744cdc858ed63511d9c91248b14b8a813d Mon Sep 17 00:00:00 2001 From: Maxime Poulin Date: Sat, 26 Mar 2016 23:29:59 -0400 Subject: [PATCH 35/46] Support kick message in /kick command --- src/plugins/inputs/kick.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/inputs/kick.js b/src/plugins/inputs/kick.js index 47068817..d0b74802 100644 --- a/src/plugins/inputs/kick.js +++ b/src/plugins/inputs/kick.js @@ -3,7 +3,7 @@ exports.commands = ["kick"]; exports.input = function(network, chan, cmd, args) { if (args.length !== 0) { var irc = network.irc; - irc.raw("KICK", chan.name, args[0]); + irc.raw("KICK", chan.name, args[0], args.slice(1).join(" ")); } return true; From 2a7a93d207016a28bc0714cc5139a8e3859f0224 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sun, 27 Mar 2016 18:57:23 +0300 Subject: [PATCH 36/46] Fix incorrect context menu names in nick, whois and topic set by messages --- client/views/actions/nick.tpl | 4 ++-- client/views/actions/topic_set_by.tpl | 2 +- client/views/actions/whois.tpl | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/client/views/actions/nick.tpl b/client/views/actions/nick.tpl index 567aeaa7..8b7304f4 100644 --- a/client/views/actions/nick.tpl +++ b/client/views/actions/nick.tpl @@ -1,3 +1,3 @@ -{{mode}}{{nick}} +{{mode}}{{nick}} is now known as -{{mode}}{{newnick}} +{{mode}}{{newnick}} diff --git a/client/views/actions/topic_set_by.tpl b/client/views/actions/topic_set_by.tpl index d842fa67..120c757d 100644 --- a/client/views/actions/topic_set_by.tpl +++ b/client/views/actions/topic_set_by.tpl @@ -1 +1 @@ -Topic set by {{nick}} on {{localeDate when}} +Topic set by {{mode}}{{nick}} on {{localeDate when}} diff --git a/client/views/actions/whois.tpl b/client/views/actions/whois.tpl index 9c91d2ac..ced3326b 100644 --- a/client/views/actions/whois.tpl +++ b/client/views/actions/whois.tpl @@ -5,31 +5,31 @@
{{#if whois.account}}
- {{whois.nick}} + {{whois.nick}} is logged in as {{whois.account}}
{{/if}} {{#if whois.channels}}
- {{whois.nick}} + {{whois.nick}} is on the following channels: {{{parse whois.channels}}}
{{/if}} {{#if whois.server}}
- {{whois.nick}} + {{whois.nick}} is connected to {{whois.server}} ({{whois.server_info}})
{{/if}} {{#if whois.secure}}
- {{whois.nick}} + {{whois.nick}} is using a secure connection
{{/if}} {{#if whois.away}}
- {{whois.nick}} + {{whois.nick}} is away ({{whois.away}})
{{/if}} From 16370d8fcc5a4649b877386cb0bf1ed0e0223dbc Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sun, 27 Mar 2016 18:57:59 +0300 Subject: [PATCH 37/46] Add /ctcp command and handle ctcp responses --- client/css/style.css | 5 +++++ client/js/lounge.js | 1 + client/views/actions/ctcp.tpl | 2 ++ src/client.js | 1 + src/models/msg.js | 1 + src/plugins/inputs/ctcp.js | 8 ++++++++ src/plugins/irc-events/ctcp.js | 29 ++++++++++++++++++++++++++--- 7 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 client/views/actions/ctcp.tpl create mode 100644 src/plugins/inputs/ctcp.js diff --git a/client/css/style.css b/client/css/style.css index 37e5b08b..3b9bcf67 100644 --- a/client/css/style.css +++ b/client/css/style.css @@ -827,6 +827,11 @@ button, color: #2ecc40; } +#chat .ctcp .from:before { + font-family: FontAwesome; + content: "\f0f6"; +} + #chat .whois .from:before { font-family: FontAwesome; content: "\f007"; diff --git a/client/js/lounge.js b/client/js/lounge.js index 9335e557..8ecfa8fd 100644 --- a/client/js/lounge.js +++ b/client/js/lounge.js @@ -225,6 +225,7 @@ $(function() { "topic_set_by", "action", "whois", + "ctcp", ].indexOf(type) !== -1) { data.msg.template = "actions/" + type; msg = $(render("msg_action", data.msg)); diff --git a/client/views/actions/ctcp.tpl b/client/views/actions/ctcp.tpl new file mode 100644 index 00000000..30334536 --- /dev/null +++ b/client/views/actions/ctcp.tpl @@ -0,0 +1,2 @@ +{{from}} +{{ctcpType}} {{ctcpMessage}} diff --git a/src/client.js b/src/client.js index 3d7a1416..0349e5dd 100644 --- a/src/client.js +++ b/src/client.js @@ -30,6 +30,7 @@ var events = [ "whois" ]; var inputs = [ + "ctcp", "msg", "part", "action", diff --git a/src/models/msg.js b/src/models/msg.js index 00fbf04b..0f29d5ab 100644 --- a/src/models/msg.js +++ b/src/models/msg.js @@ -14,6 +14,7 @@ Msg.Type = { PART: "part", QUIT: "quit", TOGGLE: "toggle", + CTCP: "ctcp", TOPIC: "topic", TOPIC_SET_BY: "topic_set_by", WHOIS: "whois" diff --git a/src/plugins/inputs/ctcp.js b/src/plugins/inputs/ctcp.js new file mode 100644 index 00000000..75906b79 --- /dev/null +++ b/src/plugins/inputs/ctcp.js @@ -0,0 +1,8 @@ +exports.commands = ["ctcp"]; + +exports.input = function(network, chan, cmd, args) { + if (args.length > 1) { + var irc = network.irc; + irc.ctcpRequest(args[0], args.slice(1).join(" ")); + } +}; diff --git a/src/plugins/irc-events/ctcp.js b/src/plugins/irc-events/ctcp.js index b2db7973..d6cbd1a7 100644 --- a/src/plugins/irc-events/ctcp.js +++ b/src/plugins/irc-events/ctcp.js @@ -1,15 +1,38 @@ var pkg = require(process.cwd() + "/package.json"); +var Msg = require("../../models/msg"); + +module.exports = function(irc, network) { + var client = this; + + irc.on("ctcp response", function(data) { + var chan = network.getChannel(data.nick); + if (typeof chan === "undefined") { + chan = network.channels[0]; + } + + var msg = new Msg({ + type: Msg.Type.CTCP, + time: data.time, + from: data.nick, + ctcpType: data.type, + ctcpMessage: data.message + }); + chan.messages.push(msg); + client.emit("msg", { + chan: chan.id, + msg: msg + }); + }); -module.exports = function(irc/* , network */) { irc.on("ctcp request", function(data) { switch (data.type) { case "VERSION": - irc.ctcpResponse(data.nick, "VERSION " + pkg.name + " " + pkg.version); + irc.ctcpResponse(data.nick, "VERSION", pkg.name + " " + pkg.version); break; case "PING": var split = data.message.split(" "); if (split.length === 2) { - irc.ctcpResponse(data.nick, "PING " + split[1]); + irc.ctcpResponse(data.nick, "PING", split[1]); } break; } From ef0e638a68c7824afb92dee8410737148754252f Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sun, 27 Mar 2016 19:13:50 +0300 Subject: [PATCH 38/46] Update irc-framework --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aa1f16b8..9bdf4bbf 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "event-stream": "3.3.2", "express": "4.13.4", "lodash": "4.6.1", - "irc-framework": "1.0.7", + "irc-framework": "1.0.8", "mkdirp": "0.5.1", "moment": "2.12.0", "read": "1.0.7", From 7d243948149157c9a34b674131ce718a6f059c2c Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 29 Mar 2016 22:09:56 +0300 Subject: [PATCH 39/46] Update irc-framework and fix issue when changing your own nick --- client/views/actions/nick.tpl | 2 +- package.json | 2 +- src/plugins/irc-events/nick.js | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/client/views/actions/nick.tpl b/client/views/actions/nick.tpl index 8b7304f4..2481e914 100644 --- a/client/views/actions/nick.tpl +++ b/client/views/actions/nick.tpl @@ -1,3 +1,3 @@ {{mode}}{{nick}} is now known as -{{mode}}{{newnick}} +{{mode}}{{new_nick}} diff --git a/package.json b/package.json index 9bdf4bbf..5dcb8804 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "event-stream": "3.3.2", "express": "4.13.4", "lodash": "4.6.1", - "irc-framework": "1.0.8", + "irc-framework": "1.0.10", "mkdirp": "0.5.1", "moment": "2.12.0", "read": "1.0.7", diff --git a/src/plugins/irc-events/nick.js b/src/plugins/irc-events/nick.js index a3719cb8..25e2b609 100644 --- a/src/plugins/irc-events/nick.js +++ b/src/plugins/irc-events/nick.js @@ -8,7 +8,7 @@ module.exports = function(irc, network) { if (data.nick === irc.user.nick) { var lobby = network.channels[0]; var msg = new Msg({ - text: "You're now known as " + data.newnick, + text: "You're now known as " + data.new_nick, }); lobby.messages.push(msg); client.emit("msg", { @@ -19,7 +19,7 @@ module.exports = function(irc, network) { client.save(); client.emit("nick", { network: network.id, - nick: data.newnick + nick: data.new_nick }); } @@ -28,7 +28,7 @@ module.exports = function(irc, network) { if (typeof user === "undefined") { return; } - user.name = data.newnick; + user.name = data.new_nick; chan.sortUsers(irc); client.emit("users", { chan: chan.id @@ -36,9 +36,9 @@ module.exports = function(irc, network) { var msg = new Msg({ time: data.time, type: Msg.Type.NICK, - mode: chan.getMode(data.newnick), + mode: chan.getMode(data.new_nick), nick: data.nick, - newnick: data.newnick, + new_nick: data.new_nick, self: self }); chan.messages.push(msg); From 69bb003e458b4b3b76f8217f7891bda1412ce72a Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sun, 3 Apr 2016 12:03:09 +0300 Subject: [PATCH 40/46] Do not try to quit from errored networks --- src/client.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/client.js b/src/client.js index 0349e5dd..3ad82945 100644 --- a/src/client.js +++ b/src/client.js @@ -339,7 +339,9 @@ Client.prototype.quit = function() { } } this.networks.forEach(function(network) { - network.irc.quit("Page closed"); + if (network.irc) { + network.irc.quit("Page closed"); + } }); }; From 40a15b2676dca8f9ffb350fddc01804b99d7222b Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sun, 3 Apr 2016 12:58:59 +0300 Subject: [PATCH 41/46] Whitelist which commands are allowed while not being connected --- src/client.js | 25 +++++++++++++++++++++---- src/plugins/inputs/connect.js | 1 + src/plugins/inputs/part.js | 5 +++-- src/plugins/inputs/quit.js | 5 ++++- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/client.js b/src/client.js index 3ad82945..c0ddd323 100644 --- a/src/client.js +++ b/src/client.js @@ -47,7 +47,7 @@ var inputs = [ var path = "./plugins/inputs/" + name; var plugin = require(path); plugin.commands.forEach(function(command) { - plugins[command] = plugin.input; + plugins[command] = plugin; }); return plugins; }, {}); @@ -250,10 +250,27 @@ Client.prototype.input = function(data) { var args = text.split(" "); var cmd = args.shift().toLowerCase(); + var irc = target.network.irc; + var connected = irc && irc.connection && irc.connection.connected; + if (cmd in inputs) { - inputs[cmd].apply(client, [target.network, target.chan, cmd, args]); - } else { - target.network.irc.raw(text); + var plugin = inputs[cmd]; + if (connected || plugin.allowDisconnected) { + connected = true; + plugin.input.apply(client, [target.network, target.chan, cmd, args]); + } + } else if (connected) { + irc.raw(text); + } + + if (!connected) { + this.emit("msg", { + chan: target.chan.id, + msg: new Msg({ + type: Msg.Type.ERROR, + text: "You are not connected to the IRC network, unable to send your command." + }) + }); } }; diff --git a/src/plugins/inputs/connect.js b/src/plugins/inputs/connect.js index 9aeba2a7..538cd4a2 100644 --- a/src/plugins/inputs/connect.js +++ b/src/plugins/inputs/connect.js @@ -1,4 +1,5 @@ exports.commands = ["connect", "server"]; +exports.allowDisconnected = true; exports.input = function(network, chan, cmd, args) { if (args.length === 0) { diff --git a/src/plugins/inputs/part.js b/src/plugins/inputs/part.js index d8701544..7c2fcf8e 100644 --- a/src/plugins/inputs/part.js +++ b/src/plugins/inputs/part.js @@ -2,6 +2,7 @@ var _ = require("lodash"); var Msg = require("../../models/msg"); exports.commands = ["close", "leave", "part"]; +exports.allowDisconnected = true; exports.input = function(network, chan, cmd, args) { if (chan.type === "lobby") { @@ -15,8 +16,8 @@ exports.input = function(network, chan, cmd, args) { return; } - if (chan.type === "channel") { - var irc = network.irc; + var irc = network.irc; + if (irc && chan.type === "channel") { irc.part(chan.name, args.join(" ")); } diff --git a/src/plugins/inputs/quit.js b/src/plugins/inputs/quit.js index fb208b2f..7f54fccf 100644 --- a/src/plugins/inputs/quit.js +++ b/src/plugins/inputs/quit.js @@ -1,6 +1,7 @@ var _ = require("lodash"); exports.commands = ["quit", "disconnect"]; +exports.allowDisconnected = true; exports.input = function(network, chan, cmd, args) { var client = this; @@ -13,7 +14,9 @@ exports.input = function(network, chan, cmd, args) { network: network.id }); - irc.quit(quitMessage); + if (irc) { + irc.quit(quitMessage); + } return true; }; From 7fdd0e90c164c0e11f81afb8b5ea9e02352f722f Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sun, 3 Apr 2016 13:26:17 +0300 Subject: [PATCH 42/46] Generate a random hexadecimal nickname when servers says current nick is invalid --- src/plugins/irc-events/error.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/plugins/irc-events/error.js b/src/plugins/irc-events/error.js index ac01756d..e579be2c 100644 --- a/src/plugins/irc-events/error.js +++ b/src/plugins/irc-events/error.js @@ -40,4 +40,19 @@ module.exports = function(irc, network) { var random = irc.user.nick + Math.floor(10 + (Math.random() * 89)); irc.changeNick(random); }); + + irc.on("nick invalid", function(data) { + var lobby = network.channels[0]; + var msg = new Msg({ + type: Msg.Type.ERROR, + text: "Nickname " + data.nick + " is invalid: " + data.reason, + }); + client.emit("msg", { + chan: lobby.id, + msg: msg + }); + + var random = "i" + Math.random().toString(36).substr(2, 10); // 'i' so it never begins with a number + irc.changeNick(random); + }); }; From 34af38ff920a21db650a95ef1c7bd0f1c849d7c0 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Mon, 4 Apr 2016 21:32:21 +0300 Subject: [PATCH 43/46] Change how nick errors are displayed --- src/plugins/irc-events/error.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/irc-events/error.js b/src/plugins/irc-events/error.js index e579be2c..abd1f6e4 100644 --- a/src/plugins/irc-events/error.js +++ b/src/plugins/irc-events/error.js @@ -30,14 +30,14 @@ module.exports = function(irc, network) { var lobby = network.channels[0]; var msg = new Msg({ type: Msg.Type.ERROR, - text: "Nickname " + data.nick + " is already in use: " + data.reason, + text: data.nick + ": " + (data.reason || "Nickname is already in use."), }); client.emit("msg", { chan: lobby.id, msg: msg }); - var random = irc.user.nick + Math.floor(10 + (Math.random() * 89)); + var random = (data.nick || irc.user.nick) + Math.floor(10 + (Math.random() * 89)); irc.changeNick(random); }); @@ -45,7 +45,7 @@ module.exports = function(irc, network) { var lobby = network.channels[0]; var msg = new Msg({ type: Msg.Type.ERROR, - text: "Nickname " + data.nick + " is invalid: " + data.reason, + text: data.nick + ": " + (data.reason || "Nickname is invalid."), }); client.emit("msg", { chan: lobby.id, From e799cc493c7071e2ad1fa1c6d0a316f361925f91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Astori?= Date: Sun, 10 Apr 2016 01:03:08 -0400 Subject: [PATCH 44/46] Move the sidebar serverOptions to the according template --- client/js/libs/handlebars/tojson.js | 7 +++++++ client/js/lounge.js | 2 -- client/views/network.tpl | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 client/js/libs/handlebars/tojson.js diff --git a/client/js/libs/handlebars/tojson.js b/client/js/libs/handlebars/tojson.js new file mode 100644 index 00000000..7df32f77 --- /dev/null +++ b/client/js/libs/handlebars/tojson.js @@ -0,0 +1,7 @@ +"use strict"; + +Handlebars.registerHelper( + "toJSON", function(context) { + return JSON.stringify(context); + } +); diff --git a/client/js/lounge.js b/client/js/lounge.js index 8ecfa8fd..eaa4f3dc 100644 --- a/client/js/lounge.js +++ b/client/js/lounge.js @@ -146,7 +146,6 @@ $(function() { }) ); var channels = $.map(data.networks, function(n) { - sidebar.find("#network-" + n.id).data("options", n.serverOptions); return n.channels; }); chat.html( @@ -296,7 +295,6 @@ $(function() { networks: [data.network] }) ); - sidebar.find("#network-" + data.network.id).data("options", data.network.serverOptions); chat.append( render("chat", { channels: data.network.channels diff --git a/client/views/network.tpl b/client/views/network.tpl index feec605d..c10162a0 100644 --- a/client/views/network.tpl +++ b/client/views/network.tpl @@ -1,5 +1,5 @@ {{#each networks}} -
+
{{partial "chan"}}
{{/each}} From 71a4dde7ad954e1e5bc90319f5025532760cbdd2 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sun, 10 Apr 2016 11:55:58 +0300 Subject: [PATCH 45/46] Do not generate random nicks on nick errors if already registered with the network --- src/plugins/irc-events/error.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/plugins/irc-events/error.js b/src/plugins/irc-events/error.js index abd1f6e4..8726b0d3 100644 --- a/src/plugins/irc-events/error.js +++ b/src/plugins/irc-events/error.js @@ -37,8 +37,10 @@ module.exports = function(irc, network) { msg: msg }); - var random = (data.nick || irc.user.nick) + Math.floor(10 + (Math.random() * 89)); - irc.changeNick(random); + if (irc.connection.registered === false) { + var random = (data.nick || irc.user.nick) + Math.floor(10 + (Math.random() * 89)); + irc.changeNick(random); + } }); irc.on("nick invalid", function(data) { @@ -52,7 +54,9 @@ module.exports = function(irc, network) { msg: msg }); - var random = "i" + Math.random().toString(36).substr(2, 10); // 'i' so it never begins with a number - irc.changeNick(random); + if (irc.connection.registered === false) { + var random = "i" + Math.random().toString(36).substr(2, 10); // 'i' so it never begins with a number + irc.changeNick(random); + } }); }; From af2c36e86e2ded8e85df78a02cf341418d4c6cf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Astori?= Date: Mon, 11 Apr 2016 00:56:59 -0400 Subject: [PATCH 46/46] Fix missing channel name from invite notifications --- client/js/lounge.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/js/lounge.js b/client/js/lounge.js index eaa4f3dc..49bb54ae 100644 --- a/client/js/lounge.js +++ b/client/js/lounge.js @@ -775,7 +775,7 @@ $(function() { if (msg.type === "invite") { title = "New channel invite:"; - body = msg.from + " invited you to " + msg.text; + body = msg.from + " invited you to " + msg.channel; } else { title = msg.from; if (!isQuery) {