From: Jack Allnutt Date: Wed, 16 Nov 2011 13:24:56 +0000 (+0000) Subject: Allow for IRC command handlers to be rebound on recode X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=f52d8543ad2e027b8b479d7d5bdac02a007912c7;p=KiwiIRC.git Allow for IRC command handlers to be rebound on recode --- diff --git a/server/app.js b/server/app.js index b2f99bb..ea1c1ff 100644 --- a/server/app.js +++ b/server/app.js @@ -120,10 +120,12 @@ var ircNumerics = { this.bindIRCCommands = function (irc_connection, websocket) { + var boundEvents = []; irc_connection.on('irc_PING', function (msg) { websocket.sendServerLine('PONG ' + msg.trailing); }); + boundEvents.push('irc_PING'); irc_connection.on('irc_' + ircNumerics.RPL_WELCOME, function (msg) { if (irc_connection.IRC.CAP.negotiating) { @@ -135,6 +137,7 @@ this.bindIRCCommands = function (irc_connection, websocket) { var nick = msg.params.split(' ')[0]; websocket.sendClientEvent('connect', {connected: true, host: null, nick: nick}); }); + boundEvents.push('irc_' + ircNumerics.RPL_WELCOME); irc_connection.on('irc_' + ircNumerics.RPL_ISUPPORT, function (msg) { var opts = msg.params.split(" "), @@ -167,35 +170,43 @@ this.bindIRCCommands = function (irc_connection, websocket) { websocket.sendClientEvent('options', {server: '', "options": irc_connection.IRC.options}); }); + boundEvents.push('irc_' + ircNumerics.RPL_ISUPPORT); irc_connection.on('irc_' + ircNumerics.RPL_ENDOFWHOIS, function (msg) { websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: true}); }); + boundEvents.push('irc_' + ircNumerics.RPL_ENDOFWHOIS); irc_connection.on('irc_' + ircNumerics.RPL_WHOISUSER, function (msg) { websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: false}); }); + boundEvents.push('irc_' + ircNumerics.RPL_WHOISUSER); irc_connection.on('irc_' + ircNumerics.RPL_WHOISSERVER, function (msg) { websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: false}); }); + boundEvents.push('irc_' + ircNumerics.RPL_WHOISSERVER); irc_connection.on('irc_' + ircNumerics.RPL_WHOISOPERATOR, function (msg) { websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: false}); }); + boundEvents.push('irc_' + ircNumerics.RPL_WHOISOPERATOR); irc_connection.on('irc_' + ircNumerics.RPL_WHOISCHANNELS, function (msg) { websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: false}); }); + boundEvents.push('irc_' + ircNumerics.RPL_WHOISCHANNELS); irc_connection.on('irc_' + ircNumerics.RPL_WHOISMODES, function (msg) { websocket.sendClientEvent('whois', {server: '', nick: msg.params.split(" ", 3)[1], "msg": msg.trailing, end: false}); }); + boundEvents.push('irc_' + ircNumerics.RPL_WHOISMODES); irc_connection.on('irc_' + ircNumerics.RPL_LISTSTART, function (msg) { websocket.sendClientEvent('list_start', {server: ''}); websocket.kiwi.buffer.list = []; }); + boundEvents.push('irc_' + ircNumerics.RPL_LISTSTART); irc_connection.on('irc_' + ircNumerics.RPL_LISTEND, function (msg) { if (websocket.kiwi.buffer.list.length > 0) { @@ -207,6 +218,7 @@ this.bindIRCCommands = function (irc_connection, websocket) { } websocket.sendClientEvent('list_end', {server: ''}); }); + boundEvents.push('irc_' + ircNumerics.RPL_LISTEND); irc_connection.on('irc_' + ircNumerics.RPL_LIST, function (msg) { var parts, channel, num_users, topic; @@ -233,6 +245,7 @@ this.bindIRCCommands = function (irc_connection, websocket) { websocket.kiwi.buffer.list = []; } }); + boundEvents.push('irc_' + ircNumerics.RPL_LIST); irc_connection.on('irc_' + ircNumerics.RPL_WHOISIDLE, function (msg) { var params = msg.params.split(" ", 4), @@ -242,18 +255,22 @@ this.bindIRCCommands = function (irc_connection, websocket) { } websocket.sendClientEvent('whois', rtn); }); + boundEvents.push('irc_' + ircNumerics.RPL_WHOISIDLE); irc_connection.on('irc_' + ircNumerics.RPL_MOTD, function (msg) { websocket.kiwi.buffer.motd += msg.trailing + '\n'; }); + boundEvents.push('irc_' + ircNumerics.RPL_MOTD); irc_connection.on('irc_' + ircNumerics.RPL_MOTDSTART, function (msg) { websocket.kiwi.buffer.motd = ''; }); + boundEvents.push('irc_' + ircNumerics.RPL_MOTDSTART); irc_connection.on('irc_' + ircNumerics.RPL_ENDOFMOTD, function (msg) { websocket.sendClientEvent('motd', {server: '', 'msg': websocket.kiwi.buffer.motd}); }); + boundEvents.push('irc_' + ircNumerics.RPL_ENDOFMOTD); irc_connection.on('irc_' + ircNumerics.RPL_NAMEREPLY, function (msg) { var params = msg.params.split(" "), @@ -284,29 +301,35 @@ this.bindIRCCommands = function (irc_connection, websocket) { kiwi.log("oops"); } }); + boundEvents.push('irc_' + ircNumerics.RPL_NAMEREPLY); irc_connection.on('irc_' + ircNumerics.RPL_ENDOFNAMES, function (msg) { websocket.sendClientEvent('userlist_end', {server: '', channel: msg.params.split(" ")[1]}); }); + boundEvents.push('irc_' + ircNumerics.RPL_ENDOFNAMES); irc_connection.on('irc_' + ircNumerics.ERR_LINKCHANNEL, function (msg) { var params = msg.params.split(" "); websocket.sendClientEvent('channel_redirect', {from: params[1], to: params[2]}); }); + boundEvents.push('irc_' + ircNumerics.ERR_LINKCHANNEL); irc_connection.on('irc_' + ircNumerics.ERR_NOSUCHNICK, function (msg) { websocket.sendClientEvent('irc_error', {error: 'no_such_nick', nick: msg.params.split(" ")[1], reason: msg.trailing}); }); + boundEvents.push('irc_' + ircNumerics.ERR_NOSUCHNICK); irc_connection.on('irc_' + ircNumerics.RPL_BANLIST, function (msg) { var params = msg.params.split(" "); kiwi.log(params); websocket.sendClientEvent('banlist', {server: '', channel: params[1], banned: params[2], banned_by: params[3], banned_at: params[4]}); }); + boundEvents.push('irc_' + ircNumerics.RPL_BANLIST); irc_connection.on('irc_' + ircNumerics.RPL_ENDOFBANLIST, function (msg) { websocket.sendClientEvent('banlist_end', {server: '', channel: msg.params.split(" ")[1]}); }); + boundEvents.push('irc_' + ircNumerics.RPL_ENDOFBANLIST); irc_connection.on('irc_JOIN', function (msg) { var channel; @@ -324,19 +347,23 @@ this.bindIRCCommands = function (irc_connection, websocket) { websocket.sendServerLine('NAMES ' + msg.trailing); } }); + boundEvents.push('irc_JOIN'); irc_connection.on('irc_PART', function (msg) { websocket.sendClientEvent('part', {nick: msg.nick, ident: msg.ident, hostname: msg.hostname, channel: msg.params.trim(), message: msg.trailing}); }); + boundEvents.push('irc_PART'); irc_connection.on('irc_KICK', function (msg) { var params = msg.params.split(" "); websocket.sendClientEvent('kick', {kicked: params[1], nick: msg.nick, ident: msg.ident, hostname: msg.hostname, channel: params[0].trim(), message: msg.trailing}); }); + boundEvents.push('irc_KICK'); irc_connection.on('irc_QUIT', function (msg) { websocket.sendClientEvent('quit', {nick: msg.nick, ident: msg.ident, hostname: msg.hostname, message: msg.trailing}); }); + boundEvents.push('irc_QUIT'); irc_connection.on('irc_NOTICE', function (msg) { if ((msg.trailing.charAt(0) === String.fromCharCode(1)) && (msg.trailing.charAt(msg.trailing.length - 1) === String.fromCharCode(1))) { @@ -346,25 +373,30 @@ this.bindIRCCommands = function (irc_connection, websocket) { websocket.sendClientEvent('notice', {nick: msg.nick, ident: msg.ident, hostname: msg.hostname, target: msg.params.trim(), msg: msg.trailing}); } }); + boundEvents.push('irc_NOTICE'); irc_connection.on('irc_NICK', function (msg) { websocket.sendClientEvent('nick', {nick: msg.nick, ident: msg.ident, hostname: msg.hostname, newnick: msg.trailing}); }); + boundEvents.push('irc_NICK'); irc_connection.on('irc_TOPIC', function (msg) { var obj = {nick: msg.nick, channel: msg.params, topic: msg.trailing}; websocket.sendClientEvent('topic', obj); }); + boundEvents.push('irc_TOPIC'); irc_connection.on('irc_' + ircNumerics.RPL_TOPIC, function (msg) { var obj = {nick: '', channel: msg.params.split(" ")[1], topic: msg.trailing}; websocket.sendClientEvent('topic', obj); }); + boundEvents.push('irc_' + ircNumerics.RPL_TOPIC); irc_connection.on('irc_' + ircNumerics.RPL_NOTOPIC, function (msg) { var obj = {nick: '', channel: msg.params.split(" ")[1], topic: ''}; websocket.sendClientEvent('topic', obj); }); + boundEvents.push('irc_' + ircNumerics.RPL_NOTOPIC); irc_connection.on('irc_' + ircNumerics.RPL_TOPICWHOTIME, function (msg) { var parts = msg.params.split(' '), @@ -374,6 +406,7 @@ this.bindIRCCommands = function (irc_connection, websocket) { obj = {nick: nick, channel: channel, when: when}; websocket.sendClientEvent('topicsetby', obj); }); + boundEvents.push('irc_' + ircNumerics.RPL_TOPICWHOTIME); irc_connection.on('irc_MODE', function (msg) { var opts = msg.params.split(" "), @@ -396,6 +429,7 @@ this.bindIRCCommands = function (irc_connection, websocket) { } websocket.sendClientEvent('mode', params); }); + boundEvents.push('irc_MODE'); irc_connection.on('irc_PRIVMSG', function (msg) { var tmp, namespace, obj; @@ -418,6 +452,7 @@ this.bindIRCCommands = function (irc_connection, websocket) { websocket.sendClientEvent('msg', obj); } }); + boundEvents.push('irc_PRIVMSG'); irc_connection.on('irc_CAP', function (msg) { var caps = kiwi.config.cap_options, @@ -462,6 +497,7 @@ this.bindIRCCommands = function (irc_connection, websocket) { break; } }); + boundEvents.push('irc_CAP'); /*case ircNumerics.RPL_STARTTLS: try { IRC = ircSocket.IRC; @@ -485,55 +521,77 @@ this.bindIRCCommands = function (irc_connection, websocket) { irc_connection.on('irc_' + ircNumerics.ERR_CANNOTSENDTOCHAN, function (msg) { websocket.sendClientEvent('irc_error', {error: 'cannot_send_to_chan', channel: msg.params.split(" ")[1], reason: msg.trailing}); }); + boundEvents.push('irc_' + ircNumerics.ERR_CANNOTSENDTOCHAN); irc_connection.on('irc_' + ircNumerics.ERR_TOOMANYCHANNELS, function (msg) { websocket.sendClientEvent('irc_error', {error: 'too_many_channels', channel: msg.params.split(" ")[1], reason: msg.trailing}); }); + boundEvents.push('irc_' + ircNumerics.ERR_TOOMANYCHANNELS); irc_connection.on('irc_' + ircNumerics.ERR_USERNOTINCHANNEL, function (msg) { var params = msg.params.split(" "); websocket.sendClientEvent('irc_error', {error: 'user_not_in_channel', nick: params[0], channel: params[1], reason: msg.trainling}); }); + boundEvents.push('irc_' + ircNumerics.ERR_USERNOTINCHANNEL); irc_connection.on('irc_' + ircNumerics.ERR_NOTONCHANNEL, function (msg) { websocket.sendClientEvent('irc_error', {error: 'not_on_channel', channel: msg.params.split(" ")[1], reason: msg.trailing}); }); + boundEvents.push('irc_' + ircNumerics.ERR_NOTONCHANNEL); irc_connection.on('irc_' + ircNumerics.ERR_CHANNELISFULL, function (msg) { websocket.sendClientEvent('irc_error', {error: 'channel_is_full', channel: msg.params.split(" ")[1], reason: msg.trailing}); }); + boundEvents.push('irc_' + ircNumerics.ERR_CHANNELISFULL); irc_connection.on('irc_' + ircNumerics.ERR_INVITEONLYCHAN, function (msg) { websocket.sendClientEvent('irc_error', {error: 'invite_only_channel', channel: msg.params.split(" ")[1], reason: msg.trailing}); }); + boundEvents.push('irc_' + ircNumerics.ERR_INVITEONLYCHAN); irc_connection.on('irc_' + ircNumerics.ERR_BANNEDFROMCHAN, function (msg) { websocket.sendClientEvent('irc_error', {error: 'banned_from_channel', channel: msg.params.split(" ")[1], reason: msg.trailing}); }); + boundEvents.push('irc_' + ircNumerics.ERR_BANNEDFROMCHAN); irc_connection.on('irc_' + ircNumerics.ERR_BADCHANNELKEY, function (msg) { websocket.sendClientEvent('irc_error', {error: 'bad_channel_key', channel: msg.params.split(" ")[1], reason: msg.trailing}); }); + boundEvents.push('irc_' + ircNumerics.ERR_BADCHANNELKEY); irc_connection.on('irc_' + ircNumerics.ERR_CHANOPRIVSNEEDED, function (msg) { websocket.sendClientEvent('irc_error', {error: 'chanop_privs_needed', channel: msg.params.split(" ")[1], reason: msg.trailing}); }); + boundEvents.push('irc_' + ircNumerics.ERR_CHANOPRIVSNEEDED); irc_connection.on('irc_' + ircNumerics.ERR_NICKNAMEINUSE, function (msg) { websocket.sendClientEvent('irc_error', {error: 'nickname_in_use', nick: _.last(msg.params.split(" ")), reason: msg.trailing}); }); + boundEvents.push('irc_' + ircNumerics.ERR_NICKNAMEINUSE); irc_connection.on('irc_ERROR', function (msg) { irc_connection.end(); websocket.sendClientEvent('irc_error', {error: 'error', reason: msg.trailing}); websocket.disconnect(); }); + boundEvents.push('irc_ERROR'); irc_connection.on('irc_' + ircNumerics.ERR_NOTREGISTERED, function (msg) { if (irc_connection.IRC.registered) { kiwi.log('Kiwi thinks user is registered, but the IRC server thinks differently'); } }); + boundEvents.push('irc_' + ircNumerics.ERR_NOTREGISTERED); + + return boundEvents; +}; + +this.rebindIRCCommands = function () { + _.each(kiwi.connections, function (con) { + _.each(con.sockets, function (sock) { + sock.ircConnection.rebindIRCCommands(); + }); + }); }; @@ -829,10 +887,11 @@ this.IRCConnection = function (websocket, nick, host, port, ssl, password, callb var ircSocket, that = this, regex, - onConnectHandler; + onConnectHandler, + boundEvents; events.EventEmitter.call(this); - + onConnectHandler = function () { that.IRC.nick = nick; // Send the login data @@ -848,13 +907,10 @@ this.IRCConnection = function (websocket, nick, host, port, ssl, password, callb websocket.sendServerLine('NICK ' + nick); websocket.sendServerLine('USER kiwi_' + nick.replace(/[^0-9a-zA-Z\-_.]/, '') + ' 0 0 :' + nick); - if ((callback) && (typeof (callback) === 'function')) { - //callback(); - } + that.emit('connect'); }); - }; - + if (!ssl) { ircSocket = net.createConnection(port, host); ircSocket.on('connect', onConnectHandler); @@ -876,11 +932,11 @@ this.IRCConnection = function (websocket, nick, host, port, ssl, password, callb ircSocket.on('error', function (e) { that.emit('error', e); }); - - ircSocket.on('connect', function () { - that.emit('connect'); - }); - + + if (typeof callback === 'function') { + this.on('connect', callback); + } + regex = /^(?::(?:([a-z0-9\x5B-\x60\x7B-\x7D\.\-]+)|([a-z0-9\x5B-\x60\x7B-\x7D\.\-]+)!([a-z0-9~\.\-_|]+)@?([a-z0-9\.\-:\/]+)?) )?(\S+)(?: (?!:)(.+?))?(?: :(.+))?$/i; ircSocket.holdLast = false; ircSocket.held = ''; @@ -941,7 +997,7 @@ this.IRCConnection = function (websocket, nick, host, port, ssl, password, callb ircSocket.destroy(); that.emit('error', {message: 'Connection timed out'}); }); - + this.write = function (data, encoding, callback) { ircSocket.write(data, encoding, callback); }; @@ -953,12 +1009,19 @@ this.IRCConnection = function (websocket, nick, host, port, ssl, password, callb this.destroySoon = function () { ircSocket.destroySoon(); }; - kiwi.bindIRCCommands(this, websocket); + boundEvents = kiwi.bindIRCCommands(this, websocket); + + this.rebindIRCCommands = function () { + _.each(boundEvents, function (event) { + that.removeAllListeners(event); + }); + boundEvents = kiwi.bindIRCCommands(that, websocket); + }; }; util.inherits(this.IRCConnection, events.EventEmitter); -this.IRCConnection.prototype = events.EventEmitter; +//this.IRCConnection.prototype = events.EventEmitter; this.websocketMessage = function (websocket, msg, callback) { diff --git a/server/kiwi.js b/server/kiwi.js index cae8fff..99f5ca5 100644 --- a/server/kiwi.js +++ b/server/kiwi.js @@ -98,6 +98,7 @@ this.recode = function () { var objs = {tls:tls, net:net, http:http, https:https, fs:fs, url:url, dns:dns, crypto:crypto, events:events, util:util, ws:ws, jsp:jsp, pro:pro, _:_, starttls:starttls}; app.init(objs); + app.rebindIRCCommands(); return true; } @@ -175,10 +176,13 @@ this.IRCConnection = function (websocket, nick, host, port, ssl, password, callb return app.IRCConnection.call(this, websocket, nick, host, port, ssl, password, callback); } util.inherits(this.IRCConnection, events.EventEmitter); + this.bindIRCCommands = function (irc_connection, websocket) { return app.bindIRCCommands.call(this, irc_connection, websocket); } - +this.rebindIRCCommands = function () { + return app.bindIRCCommands.call(this); +}