1 var net
= require('net'),
3 events
= require('events'),
4 util
= require('util'),
7 var IrcConnection = function (hostname
, port
, ssl
, nick
, user
, pass
) {
9 events
.EventEmitter
.call(this);
12 this.socket
= tls
.connect({
15 rejectUnauthorized
: global
.config
.reject_unauthorised_certificates
17 connect_handler
.apply(that
, arguments
);
20 this.socket
= net
.createConnection(port
, hostname
);
21 this.socket
.on('connect', function () {
22 connect_handler
.apply(that
, arguments
);
26 this.socket
.on('error', function (event
) {
27 that
.emit('error', event
);
30 this.socket
.setEncoding('utf-8');
32 this.socket
.on('data', function () {
33 parse
.apply(that
, arguments
);
36 this.socket
.on('close', function () {
40 this.connected
= false;
41 this.registered
= false;
42 this.cap_negotiation
= true;
45 this.username
= this.nick
.replace(/[^0-9a-zA-Z\-_.]/, ''),
46 this.irc_host
= {hostname
: hostname
, port
: port
};
48 this.options
= Object
.create(null);
49 this.cap
= {requested
: [], enabled
: []};
53 this.hold_last
= false;
56 util
.inherits(IrcConnection
, events
.EventEmitter
);
58 module
.exports
.IrcConnection
= IrcConnection
;
61 IrcConnection
.prototype.write = function (data
, callback
) {
62 write
.call(this, data
+ '\r\n', 'utf-8', callback
);
65 IrcConnection
.prototype.end = function (data
, callback
) {
66 end
.call(this, data
+ '\r\n', 'utf-8', callback
);
69 IrcConnection
.prototype.dispose = function () {
70 this.removeAllListeners();
74 var write = function (data
, encoding
, callback
) {
75 this.socket
.write(data
, encoding
, callback
);
78 var end = function (data
, encoding
, callback
) {
79 this.socket
.end(data
, encoding
, callback
);
83 var connect_handler = function () {
87 // Build up data to be used for webirc/etc detection
91 realname
: '[www.kiwiirc.com] ' + this.nick
,
92 username
: this.username
,
93 irc_host
: this.irc_host
96 // Let the webirc/etc detection modify any required parameters
97 connect_data
= findWebIrc
.call(this, connect_data
);
99 // Send any initial data for webirc/etc
100 if (connect_data
.prepend_data
) {
101 _
.each(connect_data
.prepend_data
, function(data
) {
106 this.write('CAP LS');
109 this.write('PASS ' + this.password
);
111 this.write('NICK ' + this.nick
);
112 this.write('USER ' + this.username
+ ' 0 0 :' + '[www.kiwiirc.com] ' + this.nick
);
114 this.connected
= true;
115 this.emit('connected');
119 function findWebIrc(connect_data
) {
120 var webirc_pass
= global
.config
.webirc_pass
;
121 var ip_as_username
= global
.config
.ip_as_username
;
124 // Do we have a WEBIRC password for this?
125 if (webirc_pass
&& webirc_pass
[connect_data
.irc_host
.hostname
]) {
126 tmp
= 'WEBIRC ' + webirc_pass
[connect_data
.irc_host
.hostname
] + ' KiwiIRC ';
127 tmp
+= connect_data
.user
.hostname
+ ' ' + connect_data
.user
.address
;
128 connect_data
.prepend_data
= [tmp
];
132 // Check if we need to pass the users IP as its username/ident
133 if (ip_as_username
&& ip_as_username
.indexOf(connect_data
.irc_host
.hostname
) > -1) {
134 // Get a hex value of the clients IP
135 this.username
= connect_data
.user
.address
.split('.').map(function(i
, idx
){
136 return parseInt(i
, 10).toString(16);
146 parse_regex
= /^(?:(?:(?:(@[^ ]+) )?):(?:([a-z0-9\x5B-\x60\x7B-\x7D\.\-]+)|([a-z0-9\x5B-\x60\x7B-\x7D\.\-]+)!([a-z0-9~\.\-_|]+)@?([a-z0-9\.\-:\/]+)?) )?(\S+)(?: (?!:)(.+?))?(?: :(.+))?$/i;
147 var parse = function (data
) {
156 if ((this.hold_last
) && (this.held_data
!== '')) {
157 data
= this.held_data
+ data
;
158 this.hold_last
= false;
161 if (data
.substr(-1) !== '\n') {
162 this.hold_last
= true;
164 data
= data
.split("\n");
165 for (i
= 0; i
< data
.length
; i
++) {
167 if ((this.hold_last
) && (i
=== data
.length
- 1)) {
168 this.held_data
= data
[i
];
172 // We have a complete line of data, parse it!
173 msg
= parse_regex
.exec(data
[i
].replace(/^\r+|\r+$/, ''));
176 tags
= msg
[1].split(';');
177 for (j
= 0; j
< tags
.length
; j
++) {
178 tag
= tags
[j
].split('=');
179 tags
[j
] = {tag
: tag
[0], value
: tag
[1]};
187 hostname
: msg
[5] || '',
189 params
: msg
[7] || '',
190 trailing
: (msg
[8]) ? msg
[8].trim() : ''
192 msg
.params
= msg
.params
.split(' ');
194 this.emit('irc_' + msg
.command
.toUpperCase(), msg
);
196 console
.log("Malformed IRC line: " + data
[i
].replace(/^\r+|\r+$/, ''));