X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=server%2Firc%2Fconnection.js;h=ce24ece4a75d54eb8fd2c98286e887ab4705229c;hb=bf6d219be77fc4427f76e0b223f8c5b84d28ad00;hp=0d927c22ab6861639c07596583c6f2c1598e9791;hpb=b09157de7df850222786c5f8ea7950c46408b143;p=KiwiIRC.git diff --git a/server/irc/connection.js b/server/irc/connection.js index 0d927c2..ce24ece 100644 --- a/server/irc/connection.js +++ b/server/irc/connection.js @@ -1,13 +1,22 @@ -var net = require('net'), - tls = require('tls'), - events = require('events'), - util = require('util'), - _ = require('lodash'); +var net = require('net'), + tls = require('tls'), + util = require('util'), + _ = require('lodash'), + EventEmitter2 = require('eventemitter2').EventEmitter2, + EventBinder = require('./eventbinder.js'), + IrcServer = require('./server.js'), + IrcChannel = require('./channel.js'), + IrcUser = require('./user.js'); var IrcConnection = function (hostname, port, ssl, nick, user, pass, state) { var that = this; - events.EventEmitter.call(this); + + EventEmitter2.call(this,{ + wildcard: true, + delimiter: ':' + }); + this.setMaxListeners(0); // Socket state this.connected = false; @@ -26,6 +35,15 @@ var IrcConnection = function (hostname, port, ssl, nick, user, pass, state) { // State object this.state = state; + + // IrcServer object + this.server = new IrcServer(this, hostname, port); + + // IrcUser objects + this.irc_users = Object.create(null); + + // IrcChannel objects + this.irc_channels = Object.create(null); // IRC connection information this.irc_host = {hostname: hostname, port: port}; @@ -42,6 +60,7 @@ var IrcConnection = function (hostname, port, ssl, nick, user, pass, state) { this.hold_last = false; this.held_data = ''; + this.applyIrcEvents(); // Call any modules before making the connection global.modules.emit('irc:connecting', {connection: this}) @@ -49,12 +68,29 @@ var IrcConnection = function (hostname, port, ssl, nick, user, pass, state) { that.connect(); }); }; -util.inherits(IrcConnection, events.EventEmitter); +util.inherits(IrcConnection, EventEmitter2); module.exports.IrcConnection = IrcConnection; +IrcConnection.prototype.applyIrcEvents = function () { + // Listen for events on the IRC connection + this.irc_events = { + 'server:*:connect': onServerConnect, + 'channel:*:join': onChannelJoin, + + // TODO: uncomment when using an IrcUser per nick + //'user:*:privmsg': onUserPrivmsg, + 'user:*:nick': onUserNick, + 'channel:*:part': onUserParts, + 'channel:*:quit': onUserParts, + 'channel:*:kick': onUserParts + }; + + EventBinder.bindIrcEvents('', this.irc_events, this, this); +}; + /** * Start the connection to the IRCd @@ -111,7 +147,13 @@ IrcConnection.prototype.connect = function () { }); }; - +/** + * Send an event to the client + */ +IrcConnection.prototype.clientEvent = function (event_name, data, callback) { + data.server = this.con_num; + this.state.sendIrcCommand(event_name, data, callback); +}; /** * Write a line of data to the IRCd @@ -138,6 +180,20 @@ IrcConnection.prototype.end = function (data, callback) { * Clean up this IrcConnection instance and any sockets */ IrcConnection.prototype.dispose = function () { + _.each(this.irc_users, function (user) { + user.dispose(); + }); + _.each(this.irc_channels, function (chan) { + chan.dispose(); + }); + this.irc_users = undefined; + this.irc_channels = undefined; + + this.server.dispose(); + this.server = undefined; + + EventBinder.unbindIrcEvents('', this.irc_events, this); + this.disposeSocket(); this.removeAllListeners(); }; @@ -149,6 +205,7 @@ IrcConnection.prototype.dispose = function () { */ IrcConnection.prototype.disposeSocket = function () { if (this.socket) { + this.socket.end(); this.socket.removeAllListeners(); this.socket = null; } @@ -156,6 +213,73 @@ IrcConnection.prototype.disposeSocket = function () { +function onChannelJoin(event) { + var chan; + + // Only deal with ourselves joining a channel + if (event.nick !== this.nick) + return; + + // We should only ever get a JOIN command for a channel + // we're not already a member of.. but check we don't + // have this channel in case something went wrong somewhere + // at an earlier point + if (!this.irc_channels[event.channel]) { + chan = new IrcChannel(this, event.channel); + this.irc_channels[event.channel] = chan; + chan.irc_events.join.call(chan, event); + } +} + + +function onServerConnect(event) { + this.nick = event.nick; + + // TODO: use `event.nick` instead of `'*'` when using an IrcUser per nick + this.irc_users[event.nick] = new IrcUser(this, '*'); +} + + +function onUserPrivmsg(event) { + var user; + + // Only deal with messages targetted to us + if (event.channel !== this.nick) + return; + + if (!this.irc_users[event.nick]) { + user = new IrcUser(this, event.nick); + this.irc_users[event.nick] = user; + user.irc_events.privmsg.call(user, event); + } +} + + +function onUserNick(event) { + var user; + + // Only deal with messages targetted to us + if (event.nick !== this.nick) + return; + + this.nick = event.newnick; +} + + +function onUserParts(event) { + // Only deal with ourselves leaving a channel + if (event.nick !== this.nick) + return; + + if (this.irc_channels[event.channel]) { + this.irc_channels[event.channel].dispose(); + delete this.irc_channels[event.channel]; + } +} + + + + /** * Handle the socket connect event, starting the IRCd registration */