This repository has been archived on 2022-11-26. You can view files and clone it, but cannot push or open issues or pull requests.
teemant-old/server/teemant_irc/irc.js

550 lines
17 KiB
JavaScript
Raw Normal View History

2016-12-15 21:30:55 +00:00
const EventEmitter = require('events').EventEmitter;
const net = require('net');
const tls = require('tls');
const parse = require(__dirname+'/parser');
2016-09-23 21:38:09 +00:00
class IRCConnectionHandler {
constructor(connection) {
this.conn = connection;
}
2016-09-23 22:35:30 +00:00
handleUserLine(data) {
2016-09-24 16:09:03 +00:00
switch(data.command) {
2016-12-15 21:30:55 +00:00
case 'topic':
2016-09-27 15:13:24 +00:00
this.conn.write(('{0} {1}'+(data.message != '' ? ' :'+data.message : '')).format(data.command.toUpperCase(), data.arguments[0]));
break;
2016-12-15 21:30:55 +00:00
case 'kick':
2016-09-27 15:13:24 +00:00
this.conn.write('{0} {1} :{2}'.format(data.command.toUpperCase(), data.arguments.join(' '), data.message));
break;
2016-12-15 21:30:55 +00:00
case 'part':
2016-09-24 16:09:03 +00:00
this.conn.write('{0} {1} :{2}'.format(data.command.toUpperCase(), data.arguments[0], data.message));
break;
2016-12-15 21:30:55 +00:00
case 'nick':
case 'whois':
case 'who':
case 'names':
case 'join':
2016-09-24 16:09:03 +00:00
this.conn.write('{0} {1}'.format(data.command.toUpperCase(), data.arguments[0]));
break;
2016-12-15 21:30:55 +00:00
case 'quit':
2016-10-02 12:08:36 +00:00
this.conn.write('{0} :{1}'.format(data.command.toUpperCase(), (data.message == '' ?
this.conn.globalConfig.default_quit_msg : data.message)));
2016-09-24 16:09:03 +00:00
break;
2016-12-15 21:30:55 +00:00
case 'privmsg':
2016-09-24 16:09:03 +00:00
this.conn.write('PRIVMSG {0} :{1}'.format(data.arguments[0], data.message));
2016-12-15 21:30:55 +00:00
this.conn.emit('pass_to_client', {type: 'message', messageType: 'privmsg', to: data.arguments[0],
2016-09-24 16:09:03 +00:00
user: {nickname: this.conn.config.nickname}, message: data.message, server: data.server});
break;
2016-12-15 21:30:55 +00:00
case 'notice':
2016-09-24 16:09:03 +00:00
this.conn.write('NOTICE {0} :{1}'.format(data.arguments[0], data.message));
2016-12-15 21:30:55 +00:00
this.conn.emit('pass_to_client', {type: 'message', messageType: 'notice', to: data.arguments[0],
2016-09-24 16:09:03 +00:00
user: {nickname: this.conn.config.nickname}, message: data.message, server: data.server});
break;
2016-12-15 21:30:55 +00:00
case 'list':
2016-09-24 16:09:03 +00:00
this.conn.write(data.command.toUpperCase());
break;
2016-12-15 21:30:55 +00:00
case 'ctcp':
2016-10-01 19:42:17 +00:00
let ctcpmsg = '';
if(data.arguments[1].toLowerCase() == 'ping')
ctcpmsg = 'PING '+Math.floor(Date.now()/1000);
else
ctcpmsg = data.message;
this.conn.write('PRIVMSG {0} :\x01{1}\x01'.format(data.arguments[0], ctcpmsg));
2016-12-15 21:30:55 +00:00
this.conn.emit('pass_to_client', {type: 'message', messageType: 'ctcp_request', to: this.conn.config.nickname,
2016-10-01 19:42:17 +00:00
user: {nickname: data.arguments[0]}, message: ctcpmsg, server: data.server});
break;
2016-09-24 16:09:03 +00:00
default:
this.conn.write(data.command.toUpperCase()+' '+data.message);
}
2016-12-15 21:30:55 +00:00
if(data.targetType == 'channel' || data.targetType == 'message') {
2016-09-24 16:09:03 +00:00
this.conn.write('PRIVMSG {0} :{1}'.format(data.target, data.message));
2016-12-15 21:30:55 +00:00
this.conn.emit('pass_to_client', {type: 'message', messageType: 'privmsg', to: data.target,
2016-09-23 22:35:30 +00:00
user: {nickname: this.conn.config.nickname}, message: data.message, server: data.server});
}
}
2016-09-24 16:09:03 +00:00
whoisManage(whom, list) {
if(!this.conn.queue.whois)
this.conn.queue.whois = {};
if(!this.conn.queue.whois[whom])
this.conn.queue.whois[whom] = list;
else
for(let a in list)
this.conn.queue.whois[whom][a] = list[a];
}
2016-09-30 10:37:35 +00:00
ctcpManage(data) {
let line = data.trailing.replace(/\x01/g, '').trim().split(' ');
2016-10-02 12:08:36 +00:00
2016-09-30 10:37:35 +00:00
if(!line[0]) return;
2016-10-02 12:08:36 +00:00
line[0] = line[0].toUpperCase();
2016-09-30 10:37:35 +00:00
2016-12-15 21:30:55 +00:00
let resp = '\x01'+line[0]+' {0}\x01';
2016-09-30 10:37:35 +00:00
2016-12-15 21:30:55 +00:00
if(line[0] == 'PING' && line[1] != null && line[1] != '') {
2016-10-02 12:08:36 +00:00
resp = resp.format(line.slice(1).join(' '));
2016-12-15 21:30:55 +00:00
} else if(line[0] == 'CLIENTINFO') {
resp = resp.format('CLIENTINFO PING '+Object.keys(this.conn.extras.ctcps).join(' '));
2016-10-02 12:08:36 +00:00
} else if(this.conn.extras.ctcps && this.conn.extras.ctcps[line[0]] != null) {
resp = resp.format(this.conn.extras.ctcps[line[0]](data, this.conn));
} else {
resp = null;
2016-09-30 10:37:35 +00:00
}
if (resp != null)
2016-12-15 21:30:55 +00:00
this.conn.write('NOTICE {0} :{1}'.format(data.user.nickname, resp));
2016-09-30 10:37:35 +00:00
return resp != null;
}
2016-09-23 21:38:09 +00:00
handleServerLine(line) {
2016-12-15 21:30:55 +00:00
if(this.conn.queue['supportsmsg'] && line.command != '005') {
2016-09-23 21:38:09 +00:00
2016-12-15 21:30:55 +00:00
delete this.conn.queue['supportsmsg'];
2016-09-23 21:38:09 +00:00
if(this.conn.config.autojoin.length > 0)
for(let t in this.conn.config.autojoin)
2016-09-24 16:09:03 +00:00
this.conn.write('JOIN '+this.conn.config.autojoin[t]);
2016-09-23 21:38:09 +00:00
this.conn.emit('authenticated', {});
}
let serverName = this.conn.config.server;
let realServerName = this.conn.data.actualServer;
2016-09-24 17:30:39 +00:00
if(line.user.nickname == '')
realServerName = line.user.hostname;
2016-09-23 21:38:09 +00:00
2016-09-24 16:09:03 +00:00
let list = null;
2016-09-23 21:38:09 +00:00
switch(line.command) {
2016-12-15 21:30:55 +00:00
case 'error':
this.conn.emit('connerror', {type: 'irc_error', raw: line.raw});
2016-09-23 21:38:09 +00:00
break;
2016-12-15 21:30:55 +00:00
case '001':
2016-09-23 22:35:30 +00:00
this.conn.data.actualServer = line.user.hostname;
2016-12-15 21:30:55 +00:00
break;
case '005':
if(!this.conn.queue['supportsmsg'])
this.conn.queue['supportsmsg'] = true;
2016-09-23 21:38:09 +00:00
2016-09-23 22:35:30 +00:00
this.conn.authenticated = true;
2016-09-23 21:38:09 +00:00
let argv = line.arguments.slice(1);
for(let a in argv) {
let t = argv[a];
if(t.indexOf('=') != -1) {
t = t.split('=');
if(t[0] === 'PREFIX') {
let d = t[1].match(/\((\w+)\)(.*)/);
let r = d[1].split('');
let aa = d[2].split('');
for(let b in r)
this.conn.data.supportedModes[r[b]] = aa[b];
} else if(t[0] === 'NETWORK') {
this.conn.data.network = t[1];
2016-09-24 16:09:03 +00:00
} else if(t[0] === 'CHANNELLEN') {
this.conn.data.max_channel_length = parseInt(t[1]);
2016-09-23 21:38:09 +00:00
}
this.conn.data.serverSupports[t[0]] = t[1];
} else {
this.conn.data.serverSupports[t] = true;
}
}
break;
2016-12-15 21:30:55 +00:00
case 'JOIN':
2016-11-14 15:20:27 +00:00
if(line.trailing) {
2016-12-15 21:30:55 +00:00
this.conn.emit('pass_to_client', {type: 'event_join_channel', user: line.user, channel: line.trailing, server: serverName });
2016-11-14 15:20:27 +00:00
} else {
for(let i in line.arguments) {
2016-12-15 21:30:55 +00:00
this.conn.emit('pass_to_client', {type: 'event_join_channel', user: line.user, channel: line.arguments[i], server: serverName });
2016-11-14 15:20:27 +00:00
}
}
2016-09-23 21:38:09 +00:00
break;
2016-12-15 21:30:55 +00:00
case 'PART':
this.conn.emit('pass_to_client', {type: 'event_part_channel', user: line.user, channel: line.arguments[0], reason: line.trailing, server: serverName });
2016-09-23 21:38:09 +00:00
break;
2016-12-15 21:30:55 +00:00
case 'QUIT':
this.conn.emit('pass_to_client', {type: 'event_quit', user: line.user, reason: line.trailing, server: serverName });
2016-09-23 21:38:09 +00:00
break;
2016-12-15 21:30:55 +00:00
case '353':
if(!this.conn.queue['names'])
2016-09-23 21:38:09 +00:00
this.conn.queue['names'] = {};
let splittrail = line.trailing.split(' ');
for(let a in splittrail) {
let nick = splittrail[a];
2016-12-15 21:30:55 +00:00
if(nick.trim() == '') continue;
if(this.conn.queue['names'][line.arguments[2]])
this.conn.queue['names'][line.arguments[2]].push(nick);
2016-09-23 21:38:09 +00:00
else
2016-12-15 21:30:55 +00:00
this.conn.queue['names'][line.arguments[2]] = [nick];
2016-09-23 21:38:09 +00:00
}
break;
2016-12-15 21:30:55 +00:00
case '366':
if(!this.conn.queue['names']) break;
if(this.conn.queue['names'][line.arguments[1]]) {
this.conn.emit('pass_to_client', {type: 'channel_nicks', channel: line.arguments[1], nicks: this.conn.queue['names'][line.arguments[1]], server: serverName});
delete this.conn.queue['names'][line.arguments[1]];
2016-09-23 21:38:09 +00:00
}
2016-12-15 21:30:55 +00:00
if(Object.keys(this.conn.queue['names']).length == 0)
delete this.conn.queue['names'];
2016-11-14 15:20:27 +00:00
2016-09-23 21:38:09 +00:00
break;
2016-12-15 21:30:55 +00:00
case 'PRIVMSG':
2016-09-30 10:37:35 +00:00
if(line.trailing.indexOf('\x01') == 0 && line.trailing.indexOf('\x01ACTION') != 0)
return this.ctcpManage(line);
2016-09-23 21:38:09 +00:00
2016-12-15 21:30:55 +00:00
if(line.user.nickname != '')
this.conn.emit('pass_to_client', {type: 'message', messageType: 'privmsg', to: line.arguments[0],
2016-09-23 21:38:09 +00:00
user: line.user, message: line.trailing, server: serverName});
else
2016-12-15 21:30:55 +00:00
this.conn.emit('pass_to_client', {type: 'server_message', messageType: 'privmsg', message: line.trailing, server: serverName, from: realServerName});
2016-09-23 21:38:09 +00:00
break;
2016-12-15 21:30:55 +00:00
case 'NOTICE':
2016-10-01 19:42:17 +00:00
if(line.trailing.indexOf('\x01') == 0 && line.trailing.indexOf('\x01ACTION') != 0) {
2016-12-15 21:30:55 +00:00
let composethis = line.trailing.replace(/\x01/g,'').trim().split(' ');
2016-10-01 19:42:17 +00:00
composethis[0] = composethis[0].toUpperCase();
2016-12-15 21:30:55 +00:00
let message = composethis.join(' ');
2016-10-01 19:42:17 +00:00
if(composethis[0] == 'PING')
2016-12-15 21:30:55 +00:00
message = Math.floor(Date.now()/1000) - composethis[1]+'s';
2016-10-01 19:42:17 +00:00
2016-12-15 21:30:55 +00:00
this.conn.emit('pass_to_client', {type: 'message', messageType: 'ctcp_response', to: line.arguments[0],
2016-10-01 19:42:17 +00:00
user: line.user, message: message, server: serverName});
return;
}
2016-12-15 21:30:55 +00:00
if(line.user.nickname != '')
this.conn.emit('pass_to_client', {type: 'message', messageType: 'notice', to: line.arguments[0],
2016-09-25 14:13:14 +00:00
user: line.user, message: line.trailing, server: serverName});
2016-09-23 21:38:09 +00:00
else
2016-12-15 21:30:55 +00:00
this.conn.emit('pass_to_client', {type: 'server_message', messageType: 'notice', message: line.trailing, server: serverName, from: realServerName});
2016-09-23 21:38:09 +00:00
break;
2016-12-15 21:30:55 +00:00
case 'NICK':
2016-09-24 16:09:03 +00:00
if(line.user.nickname == this.conn.config.nickname)
this.conn.config.nickname = line.arguments[0];
2016-12-15 21:30:55 +00:00
this.conn.emit('pass_to_client', {type: 'nick_change', nick: line.user.nickname, newNick: line.arguments[0], server: serverName});
break;
case 'KICK':
this.conn.emit('pass_to_client', {type: 'event_kick_channel', user: line.user, channel: line.arguments[0], reason: line.trailing, kickee: line.arguments[1], server: serverName});
break;
case 'TOPIC':
this.conn.emit('pass_to_client', {type: 'channel_topic', channel: line.arguments[0], set_by: line.user.nickname, topic: line.trailing, server: serverName});
break;
case '332':
this.conn.emit('pass_to_client', {type: 'channel_topic', channel: line.arguments[1], topic: line.trailing, server: serverName});
break;
case '333':
this.conn.emit('pass_to_client', {type: 'channel_topic', channel: line.arguments[1], set_by: line.arguments[2], time: line.arguments[3], server: serverName});
break;
case '375':
case '372':
case '376':
this.conn.emit('pass_to_client', {type: 'server_message', messageType: 'motd', message: line.trailing, server: serverName, from: realServerName});
break;
case '006':
case '007':
case '251':
case '255':
case '270':
case '290':
case '292':
case '323':
case '351':
case '381':
this.conn.emit('pass_to_client', {type: 'server_message', messageType: 'regular', message: line.trailing, server: serverName, from: realServerName});
break;
case '252':
case '254':
case '396':
case '042':
this.conn.emit('pass_to_client', {type: 'server_message', messageType: 'regular', message: line.arguments[1] +' '+ line.trailing, server: serverName, from: realServerName});
break;
case '501':
case '401':
case '402':
case '421':
case '482':
case '331':
case '432':
this.conn.emit('pass_to_client', {type: 'message', to: null, message: line.arguments[1]+': '+line.trailing,
server: serverName, user: {nickname: realServerName}, messageType: 'error'});
break;
case 'MODE':
2016-09-24 12:25:47 +00:00
let isChannelMode = false;
let method = '+';
if(line.arguments[0].indexOf('#') != -1)
isChannelMode = true;
let modes = line.arguments[1];
if(!modes && line.trailing != '')
modes = line.trailing;
let sender = line.user.nickname;
if(sender == '')
sender = line.user.hostname;
2016-09-24 12:25:47 +00:00
method = modes.substring(0, 1);
modes = modes.substring(1).split('');
let pass = [];
if(isChannelMode) {
for(let i in modes) {
let mode = modes[i];
if(this.conn.data.supportedModes[mode])
2016-12-15 21:30:55 +00:00
this.conn.emit('pass_to_client', {type: 'mode_'+(method=='+'?'add':'del'), target: line.arguments[0], mode: mode,
modeTarget: line.arguments[2+parseInt(i)], server: serverName, user: {nickname: sender}});
2016-09-24 12:25:47 +00:00
else
pass.push(mode);
}
} else {
pass = modes;
}
if(pass.length > 0)
2016-12-15 21:30:55 +00:00
this.conn.emit('pass_to_client', {type: 'mode', target: line.arguments[0], message: method+pass.join(''),
server: serverName, user: {nickname: sender}});
2016-09-24 12:25:47 +00:00
break;
2016-12-15 21:30:55 +00:00
case '433':
let newNick = this.conn.config.nickname + '_';
2016-09-24 16:09:03 +00:00
this.conn.write('NICK '+newNick);
this.conn.config.nickname = newNick;
break;
2016-12-15 21:30:55 +00:00
case '311':
2016-09-24 16:09:03 +00:00
// start whois queue
list = {
nickname: line.arguments[1],
2016-12-15 21:30:55 +00:00
hostmask: '{0}!{1}@{2}'.format(line.arguments[1], line.arguments[2], line.arguments[3]),
realname: line.trailing || ''
2016-09-24 16:09:03 +00:00
};
this.whoisManage(line.arguments[1], list);
break;
2016-12-15 21:30:55 +00:00
case '319':
2016-09-24 16:09:03 +00:00
// whois: channels
list = {
2016-12-15 21:30:55 +00:00
channels: line.trailing.split(' '),
2016-09-24 16:09:03 +00:00
};
this.whoisManage(line.arguments[1], list);
break;
2016-12-15 21:30:55 +00:00
case '378':
2016-09-25 13:22:20 +00:00
list = {
connectingFrom: line.trailing,
};
this.whoisManage(line.arguments[1], list);
break;
2016-12-15 21:30:55 +00:00
case '379':
2016-09-25 13:22:20 +00:00
list = {
usingModes: line.trailing,
};
this.whoisManage(line.arguments[1], list);
break;
2016-12-15 21:30:55 +00:00
case '312':
2016-09-24 16:09:03 +00:00
list = {
server: line.arguments[2],
2016-12-15 21:30:55 +00:00
server_name: line.trailing || ''
};
2016-09-24 16:09:03 +00:00
this.whoisManage(line.arguments[1], list);
break;
2016-12-15 21:30:55 +00:00
case '313':
2016-09-24 16:09:03 +00:00
list = {
title: line.trailing
2016-12-15 21:30:55 +00:00
};
2016-09-24 16:09:03 +00:00
this.whoisManage(line.arguments[1], list);
break;
2016-12-15 21:30:55 +00:00
case '330':
2016-09-24 16:09:03 +00:00
list = {
loggedIn: line.trailing+' '+line.arguments[2]
2016-12-15 21:30:55 +00:00
};
2016-09-24 16:09:03 +00:00
this.whoisManage(line.arguments[1], list);
break;
2016-12-15 21:30:55 +00:00
case '335':
2016-09-24 16:09:03 +00:00
list = {
bot: true
2016-12-15 21:30:55 +00:00
};
2016-09-24 16:09:03 +00:00
this.whoisManage(line.arguments[1], list);
break;
2016-12-15 21:30:55 +00:00
case '307':
2016-09-24 16:09:03 +00:00
list = {
registered: line.trailing
2016-12-15 21:30:55 +00:00
};
2016-09-24 16:09:03 +00:00
this.whoisManage(line.arguments[1], list);
break;
2016-12-15 21:30:55 +00:00
case '671':
2016-09-24 16:09:03 +00:00
list = {
secure: true
2016-12-15 21:30:55 +00:00
};
2016-09-24 16:09:03 +00:00
this.whoisManage(line.arguments[1], list);
break;
2016-12-15 21:30:55 +00:00
case '317':
2016-09-24 16:09:03 +00:00
list = {
signonTime: line.arguments[3],
idleSeconds: line.arguments[2]
2016-12-15 21:30:55 +00:00
};
2016-09-24 16:09:03 +00:00
this.whoisManage(line.arguments[1], list);
break;
2016-12-15 21:30:55 +00:00
case '318':
2016-09-24 16:09:03 +00:00
if(!this.conn.queue.whois || !this.conn.queue.whois[line.arguments[1]])
return;
2016-11-14 15:20:27 +00:00
2016-12-15 21:30:55 +00:00
this.conn.emit('pass_to_client', {type: 'whoisResponse', whois: this.conn.queue.whois[line.arguments[1]],
2016-09-24 16:09:03 +00:00
server: serverName, from: realServerName});
2016-11-14 15:20:27 +00:00
2016-09-24 16:09:03 +00:00
delete this.conn.queue.whois[line.arguments[1]];
break;
2016-12-15 21:30:55 +00:00
case '321':
this.conn.emit('pass_to_client', {type: 'listedchan', channel: 'Channel', users: 'Users', topic: 'Topic',
2016-09-24 16:09:03 +00:00
server: serverName, from: realServerName});
break;
2016-12-15 21:30:55 +00:00
case '322':
this.conn.emit('pass_to_client', {type: 'listedchan', channel: line.arguments[1], users: line.arguments[2], topic: line.trailing,
2016-09-24 16:09:03 +00:00
server: serverName, from: realServerName});
break;
2016-12-15 21:30:55 +00:00
case 'CAP':
2016-10-01 19:42:17 +00:00
// might come in the future, who knows
2016-12-15 21:30:55 +00:00
this.conn.write('CAP END');
2016-10-01 19:42:17 +00:00
break;
2016-09-23 21:38:09 +00:00
}
}
}
class IRCConnection extends EventEmitter {
2016-10-02 12:08:36 +00:00
constructor(providedInfo, globalConfig, extras) {
2016-09-23 21:38:09 +00:00
super();
2016-10-02 12:08:36 +00:00
this.globalConfig = globalConfig;
this.extras = extras || { authenticationSteps: [], ctcps: {} };
2016-09-24 13:24:55 +00:00
this.config = {
2016-12-15 21:30:55 +00:00
nickname: 'teemant',
2016-10-02 12:08:36 +00:00
username: globalConfig.username,
realname: globalConfig.realname,
2016-12-15 21:30:55 +00:00
server: 'localhost',
2016-09-24 13:24:55 +00:00
port: 6667,
autojoin: [],
2016-10-02 12:08:36 +00:00
secure: globalConfig.secure_by_default,
2016-12-15 21:30:55 +00:00
password: '',
address: '0.0.0.0',
2016-10-02 12:08:36 +00:00
rejectUnauthorized: globalConfig.rejectUnauthorizedCertificates
2016-09-24 13:24:55 +00:00
};
for(let a in providedInfo) {
this.config[a] = providedInfo[a];
}
2016-09-23 21:38:09 +00:00
this.socket = null;
this.connected = false;
this.authenticated = false;
this.handler = new IRCConnectionHandler(this);
this.data = {
serverSupports: {},
network: this.config.server,
actualServer: this.config.server,
2016-09-24 16:09:03 +00:00
max_channel_length: 64,
2016-09-23 21:38:09 +00:00
supportedModes: {}
};
2016-09-25 14:13:14 +00:00
this.authorizationError = '';
2016-09-23 21:38:09 +00:00
this.queue = {};
}
on(...args) {
2016-12-15 21:30:55 +00:00
return super.on(...args);
2016-09-23 21:38:09 +00:00
}
emit(...args) {
return super.emit(...args);
}
connect() {
2016-09-25 14:13:14 +00:00
this.socket = (this.config.secure ? tls : net).connect({port: this.config.port, host: this.config.server,
rejectUnauthorized: this.config.rejectUnauthorized}, () => {
2016-09-23 21:38:09 +00:00
this.connected = true;
this.authenticate();
});
2016-10-02 12:08:36 +00:00
this.socket.setEncoding(this.globalConfig.encoding);
this.socket.setTimeout(this.globalConfig.timeout);
2016-09-23 21:38:09 +00:00
this.socket.on('error', (data) => {
2016-12-15 21:30:55 +00:00
this.emit('connerror', {type: 'sock_error', message: 'A socket error occured.', raw: data});
2016-09-23 21:38:09 +00:00
});
this.socket.on('lookup', (err, address, family, host) => {
if(err) {
2016-12-15 21:30:55 +00:00
this.emit('connerror', {type: 'resolve_error', message: 'Failed to resolve host.'});
2016-09-23 21:38:09 +00:00
} else {
this.emit('lookup', {address: address, family: address, host: host});
this.config.address = address;
}
});
2016-12-15 21:30:55 +00:00
let buffer = '';
2016-09-23 21:38:09 +00:00
this.socket.on('data', (chunk) => {
buffer += chunk;
let data = buffer.split('\r\n');
buffer = data.pop();
data.forEach((line) => {
if(line.indexOf('PING') === 0) {
this.socket.write('PONG'+line.substring(4)+'\r\n');
2016-12-15 21:30:55 +00:00
return;
2016-09-23 21:38:09 +00:00
}
this.emit('raw', line);
let parsed = parse(line);
this.emit('line', parsed);
this.handler.handleServerLine(parsed);
});
});
this.socket.on('close', (data) => {
2016-09-23 22:35:30 +00:00
if(!this.queue['close'])
2016-12-15 21:30:55 +00:00
this.emit('closed', {type: 'sock_closed', raw: data, message: 'Connection closed.'});
2016-09-23 21:38:09 +00:00
this.connected = false;
this.authenticated = false;
2016-12-15 21:30:55 +00:00
});
2016-09-23 21:38:09 +00:00
}
authenticate() {
if (this.config.password)
this.socket.write('PASS {0}\r\n'.format(this.config.password));
2016-10-02 12:08:36 +00:00
if(this.extras.authenticationSteps) {
for(let i in this.extras.authenticationSteps) {
let step = this.extras.authenticationSteps[i];
step.authenticate(this);
}
}
2016-09-25 13:09:55 +00:00
2016-09-23 21:38:09 +00:00
this.socket.write('USER {0} 8 * :{1}\r\n'.format(this.config.username, this.config.realname));
this.socket.write('NICK {0}\r\n'.format(this.config.nickname));
}
disconnect(message) {
if(!this.connected) {
2016-12-15 21:30:55 +00:00
this.emit('connerror', {type: 'sock_closed', message: 'Connection already closed.'});
2016-09-23 21:38:09 +00:00
return;
}
this.queue['close'] = true;
2016-10-02 12:08:36 +00:00
this.socket.write('QUIT :{0}\r\n'.format(message != null ? message : this.globalConfig.default_quit_msg));
2016-09-23 21:38:09 +00:00
}
2016-09-24 16:09:03 +00:00
write(message) {
if(!this.connected) {
2016-12-15 21:30:55 +00:00
this.emit('connerror', {type: 'sock_closed', message: 'Connection is closed.'});
2016-09-24 16:09:03 +00:00
return;
}
this.socket.write(message+'\r\n');
}
2016-09-23 21:38:09 +00:00
}
module.exports = IRCConnection;