1 qwebirc
.irc
.RegisteredCTCPs
= {
2 "VERSION": function(x
) {
3 return "qwebirc v" + qwebirc
.VERSION
+ ", copyright (C) Chris Porter 2008-2009 -- " + qwebirc
.util
.browserVersion();
5 "USERINFO": function(x
) { return "qwebirc"; },
6 "TIME": function(x
) { return qwebirc
.irc
.IRCDate(new Date()); },
7 "PING": function(x
) { return x
; },
8 "CLIENTINFO": function(x
) { return "PING VERSION TIME USERINFO CLIENTINFO"; },
9 "WEBSITE": function(x
) { return window
== window
.top
? "direct" : document
.referrer
; }
12 qwebirc
.irc
.BaseIRCClient
= new Class({
13 Implements: [Options
],
17 initialize: function(options
) {
18 this.setOptions(options
);
20 this.toIRCLower
= qwebirc
.irc
.RFC1459toIRCLower
;
22 this.nickname
= this.options
.nickname
;
23 this.lowerNickname
= this.toIRCLower(this.nickname
);
25 this.__signedOn
= false;
26 this.pmodes
= {b: true, k: true, o: true, l: true, v: true};
30 this.connection
= new qwebirc
.irc
.IRCConnection({
31 initialNickname: this.nickname
,
32 onRecv: this.dispatch
.bind(this),
33 serverPassword: this.options
.serverPassword
36 this.send
= this.connection
.send
.bind(this.connection
);
37 this.connect
= this.connection
.connect
.bind(this.connection
);
38 this.disconnect
= this.connection
.disconnect
.bind(this.connection
);
40 this.setupGenericErrors();
42 dispatch: function(data
) {
43 var message
= data
[0];
44 if(message
== "connect") {
46 } else if(message
== "disconnect") {
47 if(data
.length
== 0) {
48 this.disconnected("No error!");
50 this.disconnected(data
[1]);
53 } else if(message
== "c") {
54 var command
= data
[1].toUpperCase();
58 var n
= qwebirc
.irc
.Numerics
[command
];
64 var o
= this["irc_" + n
];
67 var r
= o
.run([prefix
, sl
], this);
69 this.rawNumeric(command
, prefix
, sl
);
71 this.rawNumeric(command
, prefix
, sl
);
75 isChannel: function(target
) {
76 var c
= target
.charAt(0);
79 supported: function(key
, value
) {
80 if(key
== "CASEMAPPING") {
81 if(value
== "ascii") {
82 this.toIRCLower
= qwebirc
.irc
.ASCIItoIRCLower
;
83 } else if(value
== "rfc1459") {
89 this.lowerNickname
= this.toIRCLower(this.nickname
);
91 irc_RPL_WELCOME: function(prefix
, params
) {
92 this.nickname
= params
[0];
93 this.lowerNickname
= this.toIRCLower(this.nickname
);
94 this.__signedOn
= true;
95 this.signedOn(this.nickname
);
97 irc_ERR_NICKNAMEINUSE: function(prefix
, params
) {
98 this.genericError(params
[1], params
.indexFromEnd(-1).replace("in use.", "in use"));
103 var newnick
= params
[1] + "_";
104 if(newnick
== this.lastnick
)
105 newnick
= "qwebirc" + Math
.floor(Math
.random() * 1024 * 1024);
107 this.send("NICK " + newnick
);
108 this.lastnick
= newnick
;
111 irc_NICK: function(prefix
, params
) {
113 var oldnick
= user
.hostToNick();
114 var newnick
= params
[0];
116 if(this.nickname
== oldnick
) {
117 this.nickname
= newnick
;
118 this.lowerNickname
= this.toIRCLower(this.nickname
);
121 this.nickChanged(user
, newnick
);
125 irc_QUIT: function(prefix
, params
) {
128 var message
= params
.indexFromEnd(-1);
130 this.userQuit(user
, message
);
134 irc_PART: function(prefix
, params
) {
136 var channel
= params
[0];
137 var message
= params
[1];
139 var nick
= user
.hostToNick();
141 if((nick
== this.nickname
) && this.__getChannel(channel
))
142 this.__killChannel(channel
);
144 this.userPart(user
, channel
, message
);
148 __getChannel: function(name
) {
149 return this.channels
[this.toIRCLower(name
)];
151 __killChannel: function(name
) {
152 delete this.channels
[this.toIRCLower(name
)];
154 __nowOnChannel: function(name
) {
155 this.channels
[this.toIRCLower(name
)] = 1;
157 irc_KICK: function(prefix
, params
) {
159 var channel
= params
[0];
160 var kickee
= params
[1];
161 var message
= params
[2];
163 if((kickee
== this.nickname
) && this.__getChannel(channel
))
164 this.__killChannel(channel
);
166 this.userKicked(kicker
, channel
, kickee
, message
);
170 irc_PING: function(prefix
, params
) {
171 this.send("PONG :" + params
.indexFromEnd(-1));
175 irc_JOIN: function(prefix
, params
) {
176 var channel
= params
[0];
178 var nick
= user
.hostToNick();
180 if(nick
== this.nickname
)
181 this.__nowOnChannel(channel
);
183 this.userJoined(user
, channel
);
187 irc_TOPIC: function(prefix
, params
) {
189 var channel
= params
[0];
190 var topic
= params
.indexFromEnd(-1);
192 this.channelTopic(user
, channel
, topic
);
196 processCTCP: function(message
) {
197 if(message
.charAt(0) != "\x01")
200 if(message
.charAt(message
.length
- 1) == "\x01") {
201 message
= message
.substr(1, message
.length
- 2);
203 message
= message
.substr(1);
205 return message
.splitMax(" ", 2);
207 irc_PRIVMSG: function(prefix
, params
) {
209 var target
= params
[0];
210 var message
= params
.indexFromEnd(-1);
212 var ctcp
= this.processCTCP(message
);
214 var type
= ctcp
[0].toUpperCase();
216 var replyfn
= qwebirc
.irc
.RegisteredCTCPs
[type
];
218 var t
= new Date().getTime() / 1000;
219 if(t
> this.nextctcp
)
220 this.send("NOTICE " + user
.hostToNick() + " :\x01" + type
+ " " + replyfn(ctcp
[1]) + "\x01");
221 this.nextctcp
= t
+ 5;
224 if(target
== this.nickname
) {
225 this.userCTCP(user
, type
, ctcp
[1]);
227 this.channelCTCP(user
, target
, type
, ctcp
[1]);
230 if(target
== this.nickname
) {
231 this.userPrivmsg(user
, message
);
233 this.channelPrivmsg(user
, target
, message
);
239 irc_NOTICE: function(prefix
, params
) {
241 var target
= params
[0];
242 var message
= params
.indexFromEnd(-1);
244 if((user
== "") || (user
.indexOf("!") == -1)) {
245 this.serverNotice(user
, message
);
246 } else if(target
== this.nickname
) {
247 var ctcp
= this.processCTCP(message
);
249 this.userCTCPReply(user
, ctcp
[0], ctcp
[1]);
251 this.userNotice(user
, message
);
254 this.channelNotice(user
, target
, message
);
259 irc_INVITE: function(prefix
, params
) {
261 var channel
= params
.indexFromEnd(-1);
263 this.userInvite(user
, channel
);
267 irc_ERROR: function(prefix
, params
) {
268 var message
= params
.indexFromEnd(-1);
270 this.serverError(message
);
274 irc_MODE: function(prefix
, params
) {
276 var target
= params
[0];
277 var args
= params
.slice(1);
279 if(target
== this.nickname
) {
282 var modes
= args
[0].split("");
283 var xargs
= args
.slice(1);
290 modes
.each(function(mode
) {
291 if((mode
== "+") || (mode
== "-")) {
297 if(this.pmodes
[mode
]) {
298 d
= [cmode
, mode
, xargs
[carg
++]]
306 this.channelMode(user
, target
, data
, args
);
311 irc_RPL_ISUPPORT: function(prefix
, params
) {
312 var supported
= params
.slice(1, -1);
313 var supportedhash
= {};
315 for(var i
=0;i
<supported
.length
;i
++) {
316 var l
= supported
[i
].splitMax("=", 2);
317 this.supported(l
[0], l
[1]);
320 irc_RPL_MYINFO: function(prefix
, params
) {
321 if(params
.length
< 6)
324 var pmodes
= params
[5].split("");
327 pmodes
.each(function(pmode
) {
328 this.pmodes
[pmode
] = true;
331 irc_RPL_NAMREPLY: function(prefix
, params
) {
332 var channel
= params
[2];
333 var names
= params
[3];
335 this.channelNames(channel
, names
.split(" "));
339 irc_RPL_ENDOFNAMES: function(prefix
, params
) {
340 var channel
= params
[1];
342 this.channelNames(channel
, []);
345 irc_RPL_NOTOPIC: function(prefix
, params
) {
346 var channel
= params
[1];
348 if(this.__getChannel(channel
)) {
349 this.initialTopic(channel
, "");
353 irc_RPL_TOPIC: function(prefix
, params
) {
354 var channel
= params
[1];
355 var topic
= params
.indexFromEnd(-1);
357 if(this.__getChannel(channel
)) {
358 this.initialTopic(channel
, topic
);
362 irc_RPL_TOPICWHOTIME: function(prefix
, params
) {
365 irc_RPL_WHOISUSER: function(prefix
, params
) {
366 var nick
= params
[1];
367 this.whoisNick
= nick
;
369 return this.whois(nick
, "user", {ident: params
[2], hostname: params
[3], realname: params
.indexFromEnd(-1)});
371 irc_RPL_WHOISSERVER: function(prefix
, params
) {
372 var nick
= params
[1];
373 var server
= params
[2];
374 var serverdesc
= params
.indexFromEnd(-1);
376 return this.whois(nick
, "server", {server: params
[2], serverdesc: params
.indexFromEnd(-1)});
378 irc_RPL_WHOISOPERATOR: function(prefix
, params
) {
379 var nick
= params
[1];
380 var text
= params
.indexFromEnd(-1);
382 return this.whois(nick
, "oper", {opertext: params
.indexFromEnd(-1)});
384 irc_RPL_WHOISIDLE: function(prefix
, params
) {
385 var nick
= params
[1];
387 return this.whois(nick
, "idle", {idle: params
[2], connected: params
[3]});
389 irc_RPL_WHOISCHANNELS: function(prefix
, params
) {
390 var nick
= params
[1];
392 return this.whois(nick
, "channels", {channels: params
.indexFromEnd(-1)});
394 irc_RPL_WHOISACCOUNT: function(prefix
, params
) {
395 var nick
= params
[1];
397 return this.whois(nick
, "account", {account: params
[2]});
399 irc_RPL_WHOISACTUALLY: function(prefix
, params
) {
400 var nick
= params
[1];
402 return this.whois(nick
, "actually", {hostmask: params
[2], ip: params
[3]});
404 irc_RPL_WHOISOPERNAME: function(prefix
, params
) {
405 var nick
= params
[1];
406 var opername
= params
[2];
408 return this.whois(nick
, "opername", {opername: params
[2]});
410 irc_RPL_WHOISGENERICTEXT: function(prefix
, params
) {
411 var nick
= params
[1];
412 var text
= params
.indexFromEnd(-1);
414 return this.whois(nick
, "generictext", {text: text
});
416 irc_RPL_WHOISWEBIRC: function(prefix
, params
) {
417 var nick
= params
[1];
418 var text
= params
.indexFromEnd(-1);
420 return this.whois(nick
, "generictext", {text: text
});
422 irc_RPL_WHOISSECURE: function(prefix
, params
) {
423 var nick
= params
[1];
424 var text
= params
.indexFromEnd(-1);
426 return this.whois(nick
, "generictext", {text: text
});
428 irc_RPL_ENDOFWHOIS: function(prefix
, params
) {
429 var nick
= params
[1];
430 var text
= params
.indexFromEnd(-1);
431 this.whoisNick
= null;
433 return this.whois(nick
, "end", {});
435 irc_genericError: function(prefix
, params
) {
436 var target
= params
[1];
437 var message
= params
.indexFromEnd(-1);
439 this.genericError(target
, message
);
442 irc_genericQueryError: function(prefix
, params
) {
443 var target
= params
[1];
444 var message
= params
.indexFromEnd(-1);
446 this.genericQueryError(target
, message
);
449 setupGenericErrors: function() {
450 this.irc_ERR_CHANOPPRIVSNEEDED
= this.irc_ERR_CANNOTSENDTOCHAN
= this.irc_genericError
;
451 this.irc_ERR_NOSUCHNICK
= this.irc_genericQueryError
;
454 irc_RPL_AWAY: function(prefix
, params
) {
455 var nick
= params
[1];
456 var text
= params
.indexFromEnd(-1);
458 if(this.whoisNick
&& (this.whoisNick
== nick
))
459 return this.whois(nick
, "away", {"away": text
});
461 this.awayMessage(nick
, text
);
464 irc_RPL_NOWAWAY: function(prefix
, params
) {
465 this.awayStatus(true, params
.indexFromEnd(-1));
468 irc_RPL_UNAWAY: function(prefix
, params
) {
469 this.awayStatus(false, params
.indexFromEnd(-1));
472 irc_WALLOPS: function(prefix
, params
) {
474 var text
= params
.indexFromEnd(-1);
476 this.wallops(user
, text
);
479 irc_RPL_CREATIONTIME: function(prefix
, params
) {
480 var channel
= params
[1];
481 var time
= params
[2];
483 this.channelCreationTime(channel
, time
);
486 irc_RPL_CHANNELMODEIS: function(prefix
, params
) {
487 var channel
= params
[1];
488 var modes
= params
.slice(2);
490 this.channelModeIs(channel
, modes
);