1 qwebirc
.irc
.PMODE_LIST
= 0;
2 qwebirc
.irc
.PMODE_SET_UNSET
= 1;
3 qwebirc
.irc
.PMODE_SET_ONLY
= 2;
4 qwebirc
.irc
.PMODE_REGULAR_MODE
= 3;
6 qwebirc
.irc
.RegisteredCTCPs
= {
7 "VERSION": function(x
) {
8 return "qwebirc v" + qwebirc
.VERSION
+ ", copyright (C) 2008-2012 Chris Porter and the qwebirc project -- " + qwebirc
.util
.browserVersion();
10 "USERINFO": function(x
) { return "qwebirc"; },
11 "TIME": function(x
) { return qwebirc
.irc
.IRCDate(new Date()); },
12 "PING": function(x
) { return x
; },
13 "CLIENTINFO": function(x
) { return "PING VERSION TIME USERINFO CLIENTINFO WEBSITE"; },
14 "WEBSITE": function(x
) { return window
== window
.top
? "direct" : document
.referrer
; }
17 qwebirc
.irc
.BaseIRCClient
= new Class({
18 Implements: [Options
],
22 initialize: function(options
) {
23 this.setOptions(options
);
25 this.toIRCLower
= qwebirc
.irc
.RFC1459toIRCLower
;
27 this.nickname
= this.options
.nickname
;
28 this.lowerNickname
= this.toIRCLower(this.nickname
);
30 this.__signedOn
= false;
31 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
};
35 this.connection
= new qwebirc
.irc
.IRCConnection({
36 initialNickname: this.nickname
,
37 onRecv: this.dispatch
.bind(this),
38 serverPassword: this.options
.serverPassword
41 this.send
= this.connection
.send
.bind(this.connection
);
42 this.connect
= this.connection
.connect
.bind(this.connection
);
43 this.disconnect
= this.connection
.disconnect
.bind(this.connection
);
45 this.setupGenericErrors();
47 dispatch: function(data
) {
48 var message
= data
[0];
49 if(message
== "connect") {
51 } else if(message
== "disconnect") {
52 if(data
.length
== 0) {
53 this.disconnected("No error!");
55 this.disconnected(data
[1]);
58 } else if(message
== "c") {
59 var command
= data
[1].toUpperCase();
63 var n
= qwebirc
.irc
.Numerics
[command
];
69 var o
= this["irc_" + n
];
72 var r
= o
.run([prefix
, sl
], this);
74 this.rawNumeric(command
, prefix
, sl
);
76 this.rawNumeric(command
, prefix
, sl
);
80 isChannel: function(target
) {
81 var c
= target
.charAt(0);
84 supported: function(key
, value
) {
85 if(key
== "CASEMAPPING") {
86 if(value
== "ascii") {
87 this.toIRCLower
= qwebirc
.irc
.ASCIItoIRCLower
;
88 } else if(value
== "rfc1459") {
93 this.lowerNickname
= this.toIRCLower(this.nickname
);
94 } else if(key
== "CHANMODES") {
95 var smodes
= value
.split(",");
96 for(var i
=0;i
<smodes
.length
;i
++)
97 for(var j
=0;j
<smodes
[i
].length
;j
++)
98 this.pmodes
[smodes
[i
].charAt(j
)] = i
;
99 } else if(key
== "PREFIX") {
100 var l
= (value
.length
- 2) / 2;
102 var modeprefixes
= value
.substr(1, l
).split("");
103 modeprefixes
.each(function(modeprefix
) {
104 this.pmodes
[modeprefix
] = qwebirc
.irc
.PMODE_SET_UNSET
;
108 irc_RPL_WELCOME: function(prefix
, params
) {
109 this.nickname
= params
[0];
110 this.lowerNickname
= this.toIRCLower(this.nickname
);
111 this.__signedOn
= true;
112 this.signedOn(this.nickname
);
114 irc_ERR_NICKNAMEINUSE: function(prefix
, params
) {
115 this.genericError(params
[1], params
.indexFromEnd(-1).replace("in use.", "in use"));
120 var newnick
= params
[1] + "_";
121 if(newnick
== this.lastnick
)
122 newnick
= "qwebirc" + Math
.floor(Math
.random() * 1024 * 1024);
124 this.send("NICK " + newnick
);
125 this.lastnick
= newnick
;
128 irc_NICK: function(prefix
, params
) {
130 var oldnick
= user
.hostToNick();
131 var newnick
= params
[0];
133 if(this.nickname
== oldnick
) {
134 this.nickname
= newnick
;
135 this.lowerNickname
= this.toIRCLower(this.nickname
);
138 this.nickChanged(user
, newnick
);
142 irc_QUIT: function(prefix
, params
) {
145 var message
= params
.indexFromEnd(-1);
147 this.userQuit(user
, message
);
151 irc_PART: function(prefix
, params
) {
153 var channel
= params
[0];
154 var message
= params
[1];
156 var nick
= user
.hostToNick();
158 if((nick
== this.nickname
) && this.__getChannel(channel
))
159 this.__killChannel(channel
);
161 this.userPart(user
, channel
, message
);
165 __getChannel: function(name
) {
166 return this.channels
[this.toIRCLower(name
)];
168 __killChannel: function(name
) {
169 delete this.channels
[this.toIRCLower(name
)];
171 __nowOnChannel: function(name
) {
172 this.channels
[this.toIRCLower(name
)] = 1;
174 irc_KICK: function(prefix
, params
) {
176 var channel
= params
[0];
177 var kickee
= params
[1];
178 var message
= params
[2];
180 if((kickee
== this.nickname
) && this.__getChannel(channel
))
181 this.__killChannel(channel
);
183 this.userKicked(kicker
, channel
, kickee
, message
);
187 irc_PING: function(prefix
, params
) {
188 this.send("PONG :" + params
.indexFromEnd(-1));
192 irc_JOIN: function(prefix
, params
) {
193 var channel
= params
[0];
195 var nick
= user
.hostToNick();
197 if(nick
== this.nickname
)
198 this.__nowOnChannel(channel
);
200 this.userJoined(user
, channel
);
204 irc_TOPIC: function(prefix
, params
) {
206 var channel
= params
[0];
207 var topic
= params
.indexFromEnd(-1);
209 this.channelTopic(user
, channel
, topic
);
213 processCTCP: function(message
) {
214 if(message
.charAt(0) != "\x01")
217 if(message
.charAt(message
.length
- 1) == "\x01") {
218 message
= message
.substr(1, message
.length
- 2);
220 message
= message
.substr(1);
222 return message
.splitMax(" ", 2);
224 irc_PRIVMSG: function(prefix
, params
) {
226 var target
= params
[0];
227 var message
= params
.indexFromEnd(-1);
229 var ctcp
= this.processCTCP(message
);
231 var type
= ctcp
[0].toUpperCase();
233 var replyfn
= qwebirc
.irc
.RegisteredCTCPs
[type
];
235 var t
= new Date().getTime() / 1000;
236 if(t
> this.nextctcp
)
237 this.send("NOTICE " + user
.hostToNick() + " :\x01" + type
+ " " + replyfn(ctcp
[1]) + "\x01");
238 this.nextctcp
= t
+ 5;
241 if(target
== this.nickname
) {
242 this.userCTCP(user
, type
, ctcp
[1]);
244 this.channelCTCP(user
, target
, type
, ctcp
[1]);
247 if(target
== this.nickname
) {
248 this.userPrivmsg(user
, message
);
250 this.channelPrivmsg(user
, target
, message
);
256 irc_NOTICE: function(prefix
, params
) {
258 var target
= params
[0];
259 var message
= params
.indexFromEnd(-1);
261 if((user
== "") || (user
.indexOf("!") == -1)) {
262 this.serverNotice(user
, message
);
263 } else if(target
== this.nickname
) {
264 var ctcp
= this.processCTCP(message
);
266 this.userCTCPReply(user
, ctcp
[0], ctcp
[1]);
268 this.userNotice(user
, message
);
271 this.channelNotice(user
, target
, message
);
276 irc_INVITE: function(prefix
, params
) {
278 var channel
= params
.indexFromEnd(-1);
280 this.userInvite(user
, channel
);
284 irc_ERROR: function(prefix
, params
) {
285 var message
= params
.indexFromEnd(-1);
287 this.serverError(message
);
291 irc_MODE: function(prefix
, params
) {
293 var target
= params
[0];
294 var args
= params
.slice(1);
296 if(target
== this.nickname
) {
299 var modes
= args
[0].split("");
300 var xargs
= args
.slice(1);
307 modes
.each(function(mode
) {
308 if((mode
== "+") || (mode
== "-")) {
314 var pmode
= this.pmodes
[mode
];
315 if(pmode
== qwebirc
.irc
.PMODE_LIST
|| pmode
== qwebirc
.irc
.PMODE_SET_UNSET
|| (cmode
== "+" && pmode
== qwebirc
.irc
.PMODE_SET_ONLY
)) {
316 d
= [cmode
, mode
, xargs
[carg
++]]
324 this.channelMode(user
, target
, data
, args
);
329 irc_RPL_ISUPPORT: function(prefix
, params
) {
330 var supported
= params
.slice(1, -1);
333 for(var i
=0;i
<supported
.length
;i
++) {
334 var l
= supported
[i
].splitMax("=", 2);
338 if(items
.CHANMODES
&& items
.PREFIX
) /* nasty hack */
341 for(var i
=0;i
<supported
.length
;i
++) {
342 var l
= supported
[i
].splitMax("=", 2);
343 this.supported(l
[0], l
[1]);
346 irc_RPL_NAMREPLY: function(prefix
, params
) {
347 var channel
= params
[2];
348 var names
= params
[3];
350 this.channelNames(channel
, names
.split(" "));
354 irc_RPL_ENDOFNAMES: function(prefix
, params
) {
355 var channel
= params
[1];
357 this.channelNames(channel
, []);
360 irc_RPL_NOTOPIC: function(prefix
, params
) {
361 var channel
= params
[1];
363 if(this.__getChannel(channel
)) {
364 this.initialTopic(channel
, "");
368 irc_RPL_TOPIC: function(prefix
, params
) {
369 var channel
= params
[1];
370 var topic
= params
.indexFromEnd(-1);
372 if(this.__getChannel(channel
)) {
373 this.initialTopic(channel
, topic
);
377 irc_RPL_TOPICWHOTIME: function(prefix
, params
) {
380 irc_RPL_WHOISUSER: function(prefix
, params
) {
381 var nick
= params
[1];
382 this.whoisNick
= nick
;
384 return this.whois(nick
, "user", {ident: params
[2], hostname: params
[3], realname: params
.indexFromEnd(-1)});
386 irc_RPL_WHOISSERVER: function(prefix
, params
) {
387 var nick
= params
[1];
388 var server
= params
[2];
389 var serverdesc
= params
.indexFromEnd(-1);
391 return this.whois(nick
, "server", {server: params
[2], serverdesc: params
.indexFromEnd(-1)});
393 irc_RPL_WHOISOPERATOR: function(prefix
, params
) {
394 var nick
= params
[1];
395 var text
= params
.indexFromEnd(-1);
397 return this.whois(nick
, "oper", {opertext: params
.indexFromEnd(-1)});
399 irc_RPL_WHOISIDLE: function(prefix
, params
) {
400 var nick
= params
[1];
402 return this.whois(nick
, "idle", {idle: params
[2], connected: params
[3]});
404 irc_RPL_WHOISCHANNELS: function(prefix
, params
) {
405 var nick
= params
[1];
407 return this.whois(nick
, "channels", {channels: params
.indexFromEnd(-1)});
409 irc_RPL_WHOISACCOUNT: function(prefix
, params
) {
410 var nick
= params
[1];
412 return this.whois(nick
, "account", {account: params
[2]});
414 irc_RPL_WHOISACTUALLY: function(prefix
, params
) {
415 var nick
= params
[1];
417 return this.whois(nick
, "actually", {hostmask: params
[2], ip: params
[3]});
419 irc_RPL_WHOISOPERNAME: function(prefix
, params
) {
420 var nick
= params
[1];
421 var opername
= params
[2];
423 return this.whois(nick
, "opername", {opername: params
[2]});
425 irc_RPL_WHOISGENERICTEXT: function(prefix
, params
) {
426 var nick
= params
[1];
427 var text
= params
.indexFromEnd(-1);
429 return this.whois(nick
, "generictext", {text: text
});
431 irc_RPL_WHOISWEBIRC: function(prefix
, params
) {
432 var nick
= params
[1];
433 var text
= params
.indexFromEnd(-1);
435 return this.whois(nick
, "generictext", {text: text
});
437 irc_RPL_WHOISSECURE: function(prefix
, params
) {
438 var nick
= params
[1];
439 var text
= params
.indexFromEnd(-1);
441 return this.whois(nick
, "generictext", {text: text
});
443 irc_RPL_ENDOFWHOIS: function(prefix
, params
) {
444 var nick
= params
[1];
445 var text
= params
.indexFromEnd(-1);
446 this.whoisNick
= null;
448 return this.whois(nick
, "end", {});
450 irc_genericError: function(prefix
, params
) {
451 var target
= params
[1];
452 var message
= params
.indexFromEnd(-1);
454 this.genericError(target
, message
);
457 irc_genericQueryError: function(prefix
, params
) {
458 var target
= params
[1];
459 var message
= params
.indexFromEnd(-1);
461 this.genericQueryError(target
, message
);
464 setupGenericErrors: function() {
465 this.irc_ERR_CHANOPPRIVSNEEDED
= this.irc_ERR_CANNOTSENDTOCHAN
= this.irc_genericError
;
466 this.irc_ERR_NOSUCHNICK
= this.irc_genericQueryError
;
469 irc_RPL_AWAY: function(prefix
, params
) {
470 var nick
= params
[1];
471 var text
= params
.indexFromEnd(-1);
473 if(this.whoisNick
&& (this.whoisNick
== nick
))
474 return this.whois(nick
, "away", {"away": text
});
476 this.awayMessage(nick
, text
);
479 irc_RPL_NOWAWAY: function(prefix
, params
) {
480 this.awayStatus(true, params
.indexFromEnd(-1));
483 irc_RPL_UNAWAY: function(prefix
, params
) {
484 this.awayStatus(false, params
.indexFromEnd(-1));
487 irc_WALLOPS: function(prefix
, params
) {
489 var text
= params
.indexFromEnd(-1);
491 this.wallops(user
, text
);
494 irc_RPL_CREATIONTIME: function(prefix
, params
) {
495 var channel
= params
[1];
496 var time
= params
[2];
498 this.channelCreationTime(channel
, time
);
501 irc_RPL_CHANNELMODEIS: function(prefix
, params
) {
502 var channel
= params
[1];
503 var modes
= params
.slice(2);
505 this.channelModeIs(channel
, modes
);
508 irc_QWEBIRCIMAGE: function(prefix
, params
) {
509 var target
= params
[0];
510 var url
= params
.indexFromEnd(-1);
511 return this.qwebircImage(target
, url
);