coffea
Version:
event based and extensible nodejs irc client library with multi-network support
137 lines (113 loc) • 3.9 kB
JavaScript
/*jslint node: true, nomen: true*/
"use strict";
var _ = require('lodash');
var Channel = function (name, client, network) {
this.name = name;
this.client = client;
this.network = network;
this.topic = {};
this.names = {};
// hide `client` property
Object.defineProperty(this, 'client', {
enumerable: false,
writable: true
});
};
Channel.prototype.toString = function () {
return this.name;
};
Channel.prototype.getName = function () {
return this.name;
};
Channel.prototype.getTopic = function () {
return this.topic;
};
Channel.prototype.getNames = function () {
return this.names; // {'nick': ['~']}
};
Channel.prototype.getNetwork = function () {
return this.network;
};
Channel.prototype.userHasMode = function (user, mode) {
user = typeof user === "string" ? user : user.getNick();
if (this.names.hasOwnProperty(user)) {
return this.names[user].indexOf(mode) > -1;
}
return false;
};
Channel.prototype.isUserInChannel = function (user) {
user = typeof user === "string" ? user : user.getNick();
return this.names.hasOwnProperty(user);
};
Channel.prototype.notice = function (msg) {
this.client.notice(this.getName(), msg, this.network);
};
Channel.prototype.say = function (msg) {
this.client.send(this.getName(), msg, this.network);
};
Channel.prototype.reply = function (user, msg) {
user = typeof user === "string" ? user : user.getNick();
this.say(user + ': ' + msg);
};
Channel.prototype.kick = function (user, reason) {
user = typeof user === "string" ? user : user.getNick();
this.client.kick(this.getName(), user, reason, this.network);
};
Channel.prototype._changeBan = function _changeBan(deleting, mask) {
var mode;
if (deleting) {
mode = ' -b ';
} else {
mode = ' +b ';
}
this.client.write('MODE ' + this.getName() + mode + mask, this.network);
};
Channel.prototype.ban = function (mask) {
this.changeBan(false, mask);
};
Channel.prototype.unban = function (mask) {
this.changeBan(true, mask);
};
module.exports = function () {
var channelCache = {},
channelList = {};
return function (irc) {
irc.getChannelList = function (network) {
if (network) {
if (!channelList[network]) channelList[network] = [];
return channelList[network];
} else return channelList;
};
irc.getChannel = function (name, network) {
var channel = _.find(channelCache[network], function (chan) {
if (network) { return (chan.getName() === name) && (chan.getNetwork() === network); }
else { return chan.getName() === name; }
});
if (channel === undefined) {
channel = new Channel(name, irc, network);
if (!channelCache[network]) channelCache[network] = [];
channelCache[network].push(channel);
}
return channel;
};
irc.isChannel = function (channel) {
return channel instanceof Channel;
};
// add channel to list if we joined
irc.on('join', function (event) {
if (irc.isMe(event.user)) {
if (!channelList[event.network]) channelList[event.network] = [];
channelList[event.network].push(event.channel.getName());
channelList[event.network] = _.uniq(channelList[event.network]);
}
});
// remove channel from list if we parted/got kicked
function _removeChannel(event) {
if (irc.isMe(event.user)) {
channelList[event.network] = _.without(channelList[event.network], event.channel.getName());
}
}
irc.on('part', _removeChannel);
irc.on('kick', _removeChannel);
};
};