circl
Version:
Concise IRC client library
108 lines (100 loc) • 2.96 kB
JavaScript
var net = require("net"),
fs = require("fs"),
eh = require("./event.js");
function IRCClient (nick, mode, channels, host, port, log) {
"use strict";
this.nick = nick;
this.mode = mode;
this.channels = channels;
this.host = host;
this.port = port;
this.log = log;
this.socket = this.newIRCSocket();
this.handler = new eh.EventHandler();
this.timeout = 120;
this.triggers = this.handler.triggers;
this.serverReady = false;
this.isPinging = false;
this.addDefaultTriggers();
}
IRCClient.prototype = {
newIRCSocket: function () {
var self = this,
socket = new net.Socket();
socket.on("data", function (data) {
self.onData(data, self.log);
});
socket.on("connect", function () {
self.onConnect(self.nick, self.mode);
});
socket.on("disconnect", function () {
self.onDisconnect();
});
socket.on("end", function () {
self.onDisconnect();
});
socket.on("timeout", function () {
self.onTimeout();
});
socket.setTimeout(this.timeout * 1000, this.connect);
socket.setEncoding("utf8");
socket.setNoDelay();
return socket;
},
addDefaultTriggers: function () {
var self = this;
if (this.channels.length) {
this.addTrigger(/^[^ ]+ 001/, function () {
self.serverReady = true;
self.send(["JOIN", self.channels.join()].join(" "));
});
}
this.addTrigger(/^PING (.+)/, function (groups) {
self.send(["PONG", groups[1]].join(" "));
});
},
connect: function (socket) {
socket.connect(this.port, this.host);
},
send: function (data) {
this.socket.write(data + "\n", "utf8", function () {
if (this.log) {
process.stderr.write(data + "\n");
}
}.bind(this));
},
addTrigger: function (trigger, callback) {
this.triggers.push([trigger, callback]);
},
onConnect: function (nick, mode) {
this.send(["NICK", nick].join(" "));
this.send(["USER", nick, mode, "*", ":"].join(" ") + nick);
this.startPinging();
},
onDisconnect: function () {
this.serverReady = false;
this.socket = this.newIRCSocket();
this.connect(this.socket);
},
onTimeout: function () {
this.socket.end();
this.onDisconnect();
},
onData: function (data, log) {
if (log) {
console.log(data);
}
this.handler.handle(data);
},
ping: function () {
if (this.serverReady) {
this.send("PING :foo");
}
},
startPinging: function () {
if (!this.isPinging) {
setInterval(this.ping, this.timeout * 1000 / 2);
}
}
};
exports.IRCClient = IRCClient;