+qwebirc.irc.PMODE_LIST = 0;
+qwebirc.irc.PMODE_SET_UNSET = 1;
+qwebirc.irc.PMODE_SET_ONLY = 2;
+qwebirc.irc.PMODE_REGULAR_MODE = 3;
+
qwebirc.irc.RegisteredCTCPs = {
"VERSION": function(x) {
- return "qwebirc v" + qwebirc.VERSION + ", copyright (C) Chris Porter 2008-2009 -- " + qwebirc.util.browserVersion();
+ return "qwebirc v" + qwebirc.VERSION + ", copyright (C) 2008-2014 Chris Porter and the qwebirc project -- transport: " + this.connection.transportStatus + " -- " + qwebirc.util.browserVersion();
},
"USERINFO": function(x) { return "qwebirc"; },
- "TIME": function(x) { return qwebirc.irc.IRCTime(new Date()); },
+ "TIME": function(x) { return qwebirc.irc.IRCDate(new Date()); },
"PING": function(x) { return x; },
- "CLIENTINFO": function(x) { return "PING VERSION TIME USERINFO CLIENTINFO"; }
+ "CLIENTINFO": function(x) { return "PING VERSION TIME USERINFO CLIENTINFO WEBSITE"; },
+ "WEBSITE": function(x) { return window == window.top ? "direct" : document.referrer; }
};
qwebirc.irc.BaseIRCClient = new Class({
- Implements: [Options],
+ Implements: [Options, Events],
options: {
nickname: "qwebirc"
},
initialize: function(options) {
this.setOptions(options);
+ this.toIRCLower = qwebirc.irc.RFC1459toIRCLower;
+
this.nickname = this.options.nickname;
-
+ this.lowerNickname = this.toIRCLower(this.nickname);
+
this.__signedOn = false;
- this.pmodes = {b: true, k: true, o: true, l: true, v: true};
- this.channels = {}
- this.nextctcp = 0;
+ this.pmodes = {b: qwebirc.irc.PMODE_LIST, l: qwebirc.irc.PMODE_SET_ONLY, k: qwebirc.irc.PMODE_SET_UNSET, o: qwebirc.irc.PMODE_SET_UNSET, v: qwebirc.irc.PMODE_SET_UNSET};
+ this.channels = {};
+ this.chanPrefixes = {"#": true, "&": true};
+ this.nextctcp = 0;
- this.connection = new qwebirc.irc.IRCConnection({initialNickname: this.nickname, onRecv: this.dispatch.bind(this)});
+ this.connection = new qwebirc.irc.IRCConnection({
+ initialNickname: this.nickname,
+ onRecv: this.dispatch.bind(this),
+ serverPassword: this.options.serverPassword
+ });
this.send = this.connection.send.bind(this.connection);
- this.connect = this.connection.connect.bind(this.connection);
this.disconnect = this.connection.disconnect.bind(this.connection);
-
+
this.setupGenericErrors();
},
+ connect: function() {
+ this.connection.connect.apply(this.connection);
+ },
dispatch: function(data) {
var message = data[0];
if(message == "connect") {
},
isChannel: function(target) {
var c = target.charAt(0);
- return c == '#';
+ return this.chanPrefixes[c] === true;
+ },
+ supported: function(key, value) {
+ if(key == "CASEMAPPING") {
+ if(value == "ascii") {
+ this.toIRCLower = qwebirc.irc.ASCIItoIRCLower;
+ } else if(value == "rfc1459") {
+ /* IGNORE */
+ } else {
+ /* TODO: warn */
+ }
+ this.lowerNickname = this.toIRCLower(this.nickname);
+ } else if(key == "CHANMODES") {
+ var smodes = value.split(",");
+ for(var i=0;i<smodes.length;i++)
+ for(var j=0;j<smodes[i].length;j++)
+ this.pmodes[smodes[i].charAt(j)] = i;
+ } else if(key == "CHANTYPES") {
+ this.chanPrefixes = {};
+ for(var i=0;i<value.length;i++)
+ this.chanPrefixes[value.charAt(i)] = true;
+ } else if(key == "PREFIX") {
+ var l = (value.length - 2) / 2;
+
+ var modeprefixes = value.substr(1, l).split("");
+ modeprefixes.each(function(modeprefix) {
+ this.pmodes[modeprefix] = qwebirc.irc.PMODE_SET_UNSET;
+ }, this);
+ }
},
irc_RPL_WELCOME: function(prefix, params) {
this.nickname = params[0];
-
+ this.lowerNickname = this.toIRCLower(this.nickname);
this.__signedOn = true;
this.signedOn(this.nickname);
},
var oldnick = user.hostToNick();
var newnick = params[0];
- if(this.nickname == oldnick)
+ if(this.nickname == oldnick) {
this.nickname = newnick;
-
+ this.lowerNickname = this.toIRCLower(this.nickname);
+ }
+
this.nickChanged(user, newnick);
return true;
var nick = user.hostToNick();
- if((nick == this.nickname) && this.channels[channel])
- delete this.channels[channel];
+ if((nick == this.nickname) && this.__getChannel(channel))
+ this.__killChannel(channel);
this.userPart(user, channel, message);
return true;
},
+ __getChannel: function(name) {
+ return this.channels[this.toIRCLower(name)];
+ },
+ __killChannel: function(name) {
+ delete this.channels[this.toIRCLower(name)];
+ },
+ __nowOnChannel: function(name) {
+ this.channels[this.toIRCLower(name)] = 1;
+ },
irc_KICK: function(prefix, params) {
var kicker = prefix;
var channel = params[0];
var kickee = params[1];
var message = params[2];
- if((kickee == this.nickname) && this.channels[channel])
- delete this.channels[channel];
+ if((kickee == this.nickname) && this.__getChannel(channel))
+ this.__killChannel(channel);
this.userKicked(kicker, channel, kickee, message);
var nick = user.hostToNick();
if(nick == this.nickname)
- this.channels[channel] = true;
+ this.__nowOnChannel(channel);
this.userJoined(user, channel);
var replyfn = qwebirc.irc.RegisteredCTCPs[type];
if(replyfn) {
var t = new Date().getTime() / 1000;
- if(t > this.nextctcp)
- this.send("NOTICE " + user.hostToNick() + " :\x01" + type + " " + replyfn(ctcp[1]) + "\x01");
- this.nextctcp = t + 5;
+ if(t > this.nextctcp) {
+ this.send("NOTICE " + user.hostToNick() + " :\x01" + type + " " + replyfn.call(this, ctcp[1]) + "\x01");
+ this.nextctcp = t + 10;
+ }
}
if(target == this.nickname) {
}
var d;
- if(this.pmodes[mode]) {
+ var pmode = this.pmodes[mode];
+ if(pmode == qwebirc.irc.PMODE_LIST || pmode == qwebirc.irc.PMODE_SET_UNSET || (cmode == "+" && pmode == qwebirc.irc.PMODE_SET_ONLY)) {
d = [cmode, mode, xargs[carg++]]
} else {
d = [cmode, mode]
},
irc_RPL_ISUPPORT: function(prefix, params) {
var supported = params.slice(1, -1);
- var supportedhash = {};
+ var items = {};
for(var i=0;i<supported.length;i++) {
var l = supported[i].splitMax("=", 2);
- this.supported(l[0], l[1]);
+ items[l[0]] = true;
}
- },
- irc_RPL_MYINFO: function(prefix, params) {
- if(params.length < 6)
- return;
-
- var pmodes = params[5].split("");
- this.pmodes = {}
- pmodes.each(function(pmode) {
- this.pmodes[pmode] = true;
- }, this);
- },
+ if(items.CHANMODES && items.PREFIX) /* nasty hack */
+ this.pmodes = {};
+
+ for(var i=0;i<supported.length;i++) {
+ var l = supported[i].splitMax("=", 2);
+ this.supported(l[0], l[1]);
+ }
+ },
irc_RPL_NAMREPLY: function(prefix, params) {
var channel = params[2];
var names = params[3];
irc_RPL_NOTOPIC: function(prefix, params) {
var channel = params[1];
- if(this.channels[channel]) {
+ if(this.__getChannel(channel)) {
this.initialTopic(channel, "");
return true;
}
var channel = params[1];
var topic = params.indexFromEnd(-1);
- if(this.channels[channel]) {
+ if(this.__getChannel(channel)) {
this.initialTopic(channel, topic);
return true;
}
var opername = params[2];
return this.whois(nick, "opername", {opername: params[2]});
- },
+ },
+ irc_RPL_WHOISGENERICTEXT: function(prefix, params) {
+ var nick = params[1];
+ var text = params.indexFromEnd(-1);
+
+ return this.whois(nick, "generictext", {text: text});
+ },
+ irc_RPL_WHOISWEBIRC: function(prefix, params) {
+ var nick = params[1];
+ var text = params.indexFromEnd(-1);
+
+ return this.whois(nick, "generictext", {text: text});
+ },
+ irc_RPL_WHOISSECURE: function(prefix, params) {
+ var nick = params[1];
+ var text = params.indexFromEnd(-1);
+
+ return this.whois(nick, "generictext", {text: text});
+ },
irc_RPL_ENDOFWHOIS: function(prefix, params) {
var nick = params[1];
var text = params.indexFromEnd(-1);
irc_RPL_UNAWAY: function(prefix, params) {
this.awayStatus(false, params.indexFromEnd(-1));
return true;
+ },
+ irc_WALLOPS: function(prefix, params) {
+ var user = prefix;
+ var text = params.indexFromEnd(-1);
+
+ this.wallops(user, text);
+ return true;
+ },
+ irc_RPL_CREATIONTIME: function(prefix, params) {
+ var channel = params[1];
+ var time = params[2];
+
+ this.channelCreationTime(channel, time);
+ return true;
+ },
+ irc_RPL_CHANNELMODEIS: function(prefix, params) {
+ var channel = params[1];
+ var modes = params.slice(2);
+
+ this.channelModeIs(channel, modes);
+ return true;
}
});