-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;
// 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};
this.hold_last = false;
this.held_data = '';
+ this.applyIrcEvents();
// Call any modules before making the connection
global.modules.emit('irc:connecting', {connection: this})
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
});
};
-
+/**
+ * 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
* 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();
};
*/
IrcConnection.prototype.disposeSocket = function () {
if (this.socket) {
+ this.socket.end();
this.socket.removeAllListeners();
this.socket = null;
}
+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
*/