UNPKG

coffea

Version:

event based and extensible nodejs irc client library with multi-network support

237 lines (211 loc) 8.65 kB
/*jslint node: true*/ "use strict"; var utils = require('../utils'); module.exports = function () { return function (irc) { irc.whoisCallbacks = {}; /** * WHOIS plugin to query for whois info and\or emit "whois" events * * client.whois('cmilhench'); * * client.whois('cmilhench', 'testnet'); * * client.on('whois', function(err, data){ ... }); * * client.whois('cmilhench', function(err, data){ * console.log(names); * }); * * client.whois('cmilhench', 'testnet', function(err, data){ * console.log(names); * }); * * @return {Function} * @api public */ irc.whois = function ircWhois(target, network, fn) { // if network is the callback, then it wasn't defined either if (typeof(network) === 'function') { fn = network; network = undefined; } if (!network) { network = utils.extractNetwork(target); } this.write('WHOIS ' + utils.targetString(target), network); if (fn) { var _this = this; this.whoisCallbacks[(network ? network + '_' : '') + target] = function (err, data) { delete _this.whoisCallbacks[(network ? network + '_' : '') + target]; fn(err, data); }; } }; var map = {}; irc.on('data', function (err, msg) { var network = msg.network; var params, target, cb, user; switch (msg.command) { case 'RPL_WHOISUSER': params = msg.params.split(' '); target = params[1]; user = irc.getUser(target, network); map[target] = map[target] || {}; map[target].nick = target; //reset to default values map[target].away = null; map[target].oper = false; map[target].account = null; map[target].registered = false; map[target].secure = false; map[target].username = params[2]; user.username = params[2]; map[target].hostname = params[3]; user.hostname = params[3]; map[target].realname = msg.trailing; user.realname = msg.trailing; break; case 'RPL_WHOISCHANNELS': params = msg.params.split(' '); target = params[1]; user = irc.getUser(target, network); map[target] = map[target] || {}; map[target].channels = {}; msg.trailing.split(' ').forEach(function (channelName) { var m = channelName.match(/^((!|~|&|@|%|\+)*)(.*)$/); map[target].channels[m[3]] = m[1].split(''); }); user.channels = map[target].channels; break; case 'RPL_WHOISSERVER': params = msg.params.split(' '); target = params[1]; user = irc.getUser(target, network); map[target] = map[target] || {}; map[target].server = params[2]; user.server = params[2]; map[target].serverInfo = msg.trailing; user.serverInfo = msg.trailing; break; case 'RPL_AWAY': params = msg.params.split(' '); target = params[1]; if (map[target]) { user = irc.getUser(target, network); user.away = msg.trailing; map[target].away = msg.trailing; } break; case 'RPL_WHOISOPERATOR': params = msg.params.split(' '); target = params[1]; user = irc.getUser(target, network); map[target] = map[target] || {}; map[target].oper = true; user.oper = true; break; case 'RPL_WHOISIDLE': params = msg.params.split(' '); target = params[1]; user = irc.getUser(target, network); map[target] = map[target] || {}; map[target].idle = parseInt(params[2], 10); user.idle = parseInt(params[2], 10); map[target].signon = new Date(parseInt(params[3], 10) * 1000); user.signon = new Date(parseInt(params[3], 10) * 1000); break; case '330': params = msg.params.split(' '); target = params[1]; user = irc.getUser(target, network); if (msg.trailing.toLowerCase() === 'is logged in as' || msg.trailing.toLowerCase() === 'is authed as') { map[target] = map[target] || {}; user.account = params[2]; map[target].account = params[2]; user.registered = true; map[target].registered = true; } break; case '307': params = msg.params.split(' '); target = params[1]; user = irc.getUser(target, network); if (msg.trailing.toLowerCase() === 'is a registered nick' || msg.trailing.toLowerCase() === 'is identified for this nick') { map[target] = map[target] || {}; user.registered = true; map[target].registered = true; } break; case '671': params = msg.params.split(' '); target = params[1]; user = irc.getUser(target, network); if (msg.trailing.toLowerCase() === 'is using a secure connection') { map[target] = map[target] || {}; user.secure = true; map[target].secure = true; } break; case 'RPL_ENDOFWHOIS': params = msg.params.split(' '); target = params[1]; if (!map[target]) { return; } cb = irc.whoisCallbacks[network + '_' + target]; if (!cb) { cb = irc.whoisCallbacks[target]; // try single network mode } if (cb) { cb(null, map[target]); } else { utils.emit(irc, network, 'whois', {user: map[target]}); } break; case 'ERR_NEEDMOREPARAMS': params = msg.params.split(' '); target = params[1]; if (target !== 'WHOIS') { return; } cb = irc.whoisCallbacks[network + '_' + target]; if (!cb) { cb = irc.whoisCallbacks[target]; // try single network mode } if (cb) { cb('Not enough parameters', null); } else { utils.emit(irc, network, 'whois', new Error("Not enough parameters")); } break; case 'ERR_NOSUCHSERVER': params = msg.params.split(' '); target = params[1]; cb = irc.whoisCallbacks[network + '_' + target]; if (!cb) { cb = irc.whoisCallbacks[target]; // try single network mode } if (cb) { cb("No such server: " + target, null); } else { utils.emit(irc, network, 'whois', new Error("No such server: " + target)); } break; case 'ERR_NOSUCHNICK': params = msg.params.split(' '); target = params[1]; cb = irc.whoisCallbacks[network + '_' + target]; if (!cb) { cb = irc.whoisCallbacks[target]; // try single network mode } if (cb) { cb("No such nick/channel: " + target, null); } else { utils.emit(irc, network, 'whois', new Error("No such nick/channel: " + target)); } break; } }); }; };