From: Jack Allnutt Date: Fri, 25 Jan 2013 00:41:29 +0000 (+0000) Subject: Add IrcServer X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=1cc056b8034cdc235aaca999b704bcd8d733f8b3;p=KiwiIRC.git Add IrcServer --- diff --git a/server/irc/commands.js b/server/irc/commands.js index 1f05857..a58355f 100644 --- a/server/irc/commands.js +++ b/server/irc/commands.js @@ -87,7 +87,9 @@ var listeners = { var nick = command.params[0]; this.irc_connection.registered = true; this.cap_negotation = false; - this.client.sendIrcCommand('connect', {server: this.con_num, nick: nick}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':connect', { + nick: nick + }); }, 'RPL_ISUPPORT': function (command) { var options, i, option, matches, j; @@ -114,7 +116,10 @@ var listeners = { } } } - this.client.sendIrcCommand('options', {server: this.con_num, options: this.irc_connection.options, cap: this.irc_connection.cap.enabled}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':options', { + options: this.irc_connection.options, + cap: this.irc_connection.cap.enabled + }); }, 'RPL_ENDOFWHOIS': function (command) { this.irc_connection.emit('user:' + command.params[1] + ':endofwhois', { @@ -168,37 +173,30 @@ var listeners = { }); }, 'RPL_LISTSTART': function (command) { - this.client.sendIrcCommand('list_start', {server: this.con_num}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':list_start', {}); this.client.buffer.list = []; }, 'RPL_LISTEND': function (command) { - if (this.client.buffer.list.length > 0) { - this.client.buffer.list = _.sortBy(this.client.buffer.list, function (channel) { - return channel.num_users; - }); - this.client.sendIrcCommand('list_channel', {server: this.con_num, chans: this.client.buffer.list}); - this.client.buffer.list = []; - } - this.client.sendIrcCommand('list_end', {server: this.con_num}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':list_end', {}); }, 'RPL_LIST': function (command) { - this.client.buffer.list.push({server: this.con_num, channel: command.params[1], num_users: parseInt(command.params[2], 10), topic: command.trailing}); - if (this.client.buffer.list.length > 200){ - this.client.buffer.list = _.sortBy(this.client.buffer.list, function (channel) { - return channel.num_users; + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':list_channel', { + channel: command.params[1], + num_users: parseint(command.params[2], 10), + topic: command.trailing }); - this.client.sendIrcCommand('list_channel', {server: this.con_num, chans: this.client.buffer.list}); - this.client.buffer.list = []; } }, 'RPL_MOTD': function (command) { - this.client.buffer.motd += command.trailing + '\n'; + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':motd', { + motd: command.trailing + '\n'; + }); }, 'RPL_MOTDSTART': function (command) { - this.client.buffer.motd = ''; + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':motd_start', {}); }, 'RPL_ENDOFMOTD': function (command) { - this.client.sendIrcCommand('motd', {server: this.con_num, msg: this.client.buffer.motd}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':motd_end', {}); }, 'RPL_NAMEREPLY': function (command) { var members = command.trailing.split(' '); @@ -561,43 +559,82 @@ var listeners = { // noop }, 'ERROR': function (command) { - this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'error', reason: command.trailing}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':error', { + reason: command.trailing + }); }, ERR_LINKCHANNEL: function (command) { - this.client.sendIrcCommand('channel_redirect', {server: this.con_num, from: command.params[1], to: command.params[2]}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':channel_redirect', { + from: command.params[1], + to: command.params[2] + }); }, ERR_NOSUCHNICK: function (command) { - this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'no_such_nick', nick: command.params[1], reason: command.trailing}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':no_such_nick', { + nick: command.params[1], + reason: command.trailing + }); }, ERR_CANNOTSENDTOCHAN: function (command) { - this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'cannot_send_to_chan', channel: command.params[1], reason: command.trailing}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':cannot_send_to_chan', { + channel: command.params[1], + reason: command.trailing + }); }, ERR_TOOMANYCHANNELS: function (command) { - this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'too_many_channels', channel: command.params[1], reason: command.trailing}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':too_many_channels', { + channel: command.params[1], + reason: command.trailing + }); }, ERR_USERNOTINCHANNEL: function (command) { - this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'user_not_in_channel', nick: command.params[0], channel: command.params[1], reason: command.trailing}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':user_not_in_channel', { + nick: command.params[0], + channel: command.params[1], + reason: command.trailing + }); }, ERR_NOTONCHANNEL: function (command) { - this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'not_on_channel', channel: command.params[1], reason: command.trailing}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':not_on_channel', { + channel: command.params[1], + reason: command.trailing + }); }, ERR_CHANNELISFULL: function (command) { - this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'channel_is_full', channel: command.params[1], reason: command.trailing}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':channel_is_full', { + channel: command.params[1], + reason: command.trailing + }); }, ERR_INVITEONLYCHAN: function (command) { - this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'invite_only_channel', channel: command.params[1], reason: command.trailing}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':invite_only_channel', { + channel: command.params[1], + reason: command.trailing + }); }, ERR_BANNEDFROMCHAN: function (command) { - this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'banned_from_channel', channel: command.params[1], reason: command.trailing}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':banned_from_channel', { + channel: command.params[1], + reason: command.trailing + }); }, ERR_BADCHANNELKEY: function (command) { - this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'bad_channel_key', channel: command.params[1], reason: command.trailing}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':bad_channel_key', { + channel: command.params[1], + reason: command.trailing + }); }, ERR_CHANOPRIVSNEEDED: function (command) { - this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'chanop_privs_needed', channel: command.params[1], reason: command.trailing}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':chanop_privs_needed', { + channel: command.params[1], + reason: command.trailing + }); }, ERR_NICKNAMEINUSE: function (command) { - this.client.sendIrcCommand('irc_error', {server: this.con_num, error: 'nickname_in_use', nick: command.params[1], reason: command.trailing}); + this.irc_connection.emit('server:' + this.irc_connection.irc_host.hostname + ':nickname_in_use', { + nick: command.params[1], + reason: command.trailing + }); }, ERR_NOTREGISTERED: function (command) { }, diff --git a/server/irc/server.js b/server/irc/server.js new file mode 100755 index 0000000..ee469c0 --- /dev/null +++ b/server/irc/server.js @@ -0,0 +1,228 @@ +var IrcServer = function (irc_connection, host, port) { + this.irc_connection = irc_connection; + this.host = host; + this.port = port; + + this.list_buffer = []; + this.motd_buffer = ''; +}; + +module.exports = IrcServer; + +IrcServer.prototype.bindEvents = function () { + var that = this; + + // If we havent generated an event listing yet, do so now + if (!this.irc_events) { + this.irc_events = { + connect: onConnect, + options: onOptions, + list_start: onListStart, + list_channel: onListChannel, + list_end: onListEnd, + motd_start: onMotdStart, + motd: onMotd, + motd_end: onMotdEnd, + error: onError, + channel_redirect: onChannelRedirect, + no_such_nick: onNoSuchNick, + cannot_send_to_channel: onChannotSendToChan, + too_many_channels: onTooManyChannels, + user_not_in_channel: onUserNotInChannel, + not_on_channel: onNotOnChannel, + channel_is_full: onChannelisFull, + invite_only_channel: onInviteOnlyChannel, + banned_from_channel: onBannedFromChannel, + bad_channel_key: onBadChannelKey, + chanop_privs_needed: onChanopPrivsNeeded, + nickname_in_use: onNicknameInUse + }; + } + + this.irc_events.forEach(function (fn, event_name, irc_events) { + // Bind the event to `that` context, storing it with the event listing + if (!irc_events[event_name].bound_fn) { + irc_events[event_name].bound_fn = fn.bind(that); + } + + this.irc_connection.on('server:' + this.host + ':' + event_name, irc_events[event_name].bound_fn); + }); +}; + + +IrcServer.prototype.unbindEvents = function () { + this.irc_events.forEach(function(fn, event_name, irc_events) { + if (irc_events[event_name].bound_fn) { + this.irc_connection.removeListener('server:' + this.host + ':' + event_name, irc_events[event_name].bound_fn); + } + }); +}; + +function onConnect(event) { + this.irc_connection.clientEvent('connect', { + nick: event.nick + }); +}; + +function onOptions(event) { + this.irc_connection.clientEvent('options', { + options: event.options, + cap: event.cap + }); +}; + +function onListStart(event) { + this.irc_connection.clientEvent('list_start', {}); +}; + +function onListChannel(event) { + var buf; + this.list_buffer.push({ + channel: event.channel, + num_users: event.num_users, + topic: event.topic + }); + + if (this.list_buffer.length > 200) { + buf = _.sortBy(this.list_buffer, function (channel) { + // sortBy sorts in ascending order, we want to sort by descending, hence using 0 - num_users. + return 0 - channel.num_users; + }); + this.irc_connection.clientEvent('list_channel', { + chans: buf + }); + this.list_buffer = []; + }; +}; + +function onListEnd(event) { + if (this.list_buffer.length > 200) { + buf = _.sortBy(this.list_buffer, function (channel) { + // sortBy sorts in ascending order, we want to sort by descending, hence using 0 - num_users. + return 0 - channel.num_users; + }); + this.irc_connection.clientEvent('list_channel', { + chans: buf + }); + this.list_buffer = []; + }; + + this.irc_connection.clientEvent('list_end', {}); +}; + +function onMotdStart(event) { + this.motd_buffer = ''; +}; + +function onMotd(event) { + this.motd_buffer += event.motd; +}; + +function onMotdEnd(event) { + this.irc_connection.clientEvent('motd', { + msg: this.motd_buffer + }); +}; + +function onError(event) { + this.irc_connection.clientEvent('irc_error', { + error: 'error', + reason: event.reason + }); +}; + +function onChannelRedirect(event) { + this.irc_connection.clientEvent('channel_redirect', { + from: event.from, + to: event.to + }); +}; + +function onNoSuchNick(event) { + this.irc_connection.clientEvent('irc_error', { + error: 'no_such_nick', + nick: event.nick, + reason: event.reason + }); +}; + +function onCannotSendToChan(event) { + this.irc_connection.clientEvent('irc_error', { + error: 'cannot_send_to_chan', + channel: event.channel, + reason: event.reason + }); +}; + +function onTooManyChannels(event) { + this.irc_connection.clientEvent('irc_error', { + error: 'too_many_channels', + channel: event.channel, + reason: event.reason + }); +}; + +function onUserNotInChannel(event) { + this.irc_connection.clientEvent('irc_error', { + error: 'user_not_in_channel', + nick: event.nick, + channel: event.channel, + reason: event.reason + }); +}; + +function onNotOnChannel(event) { + this.irc_connection.clientEvent('irc_error', { + error: 'not_on_channel', + channel: event.channel, + reason: event.reason + }); +}; + +function onChannelIsFull(event) { + this.irc_connection.clientEvent('irc_error', { + error: 'channel_is_full', + channel: event.channel, + reason: event.reason + }); +}; + +function onInviteOnlyChannel(event) { + this.irc_connection.clientEvent('irc_error', { + error: 'invite_only_channel', + channel: event.channel, + reason: event.reason + }); +}; + +function onBannedFromChannel(event) { + this.irc_connection.clientEvent('irc_error', { + error: 'banned_from_channel', + channel: event.channel, + reason: event.reason + }); +}; + +function onBadChannelKey(event) { + this.irc_connection.clientEvent('irc_error', { + error: 'bad_channel_key', + channel: event.channel, + reason: event.reason + }); +}; + +function onChanopPrivsNeeded(event) { + this.irc_connection.clientEvent('irc_error', { + error: 'chanop_privs_needed', + channel: event.channel, + reason: event.reason + }); +}; + +function onNicknameInUse(event) { + this.irc_connection.clientEvent('irc_error', { + error: 'nickname_in_use', + nick: event.nick, + reason: event.reason + }); +};