]> jfr.im git - irc/quakenet/qwebirc.git/blob - js/irc/baseircclient.js
Add notice redirection to message window option.
[irc/quakenet/qwebirc.git] / js / irc / baseircclient.js
1 qwebirc.irc.RegisteredCTCPs = {
2 "VERSION": function(x) {
3 return "qwebirc v" + qwebirc.VERSION + ", copyright (C) Chris Porter 2008 -- " + qwebirc.util.browserVersion();
4 },
5 "USERINFO": function(x) { return "qwebirc"; },
6 "TIME": function(x) { return qwebirc.irc.IRCTime(new Date()); },
7 "PING": function(x) { return x; },
8 "CLIENTINFO": function(x) { return "PING VERSION TIME USERINFO CLIENTINFO"; }
9 };
10
11 qwebirc.irc.BaseIRCClient = new Class({
12 Implements: [Options],
13 options: {
14 nickname: "qwebirc"
15 },
16 initialize: function(options) {
17 this.setOptions(options);
18
19 this.nickname = this.options.nickname;
20
21 this.__signedOn = false;
22 this.pmodes = ["b", "k,", "o", "l", "v"];
23 this.channels = {}
24 this.nextctcp = 0;
25
26 this.connection = new qwebirc.irc.IRCConnection({initialNickname: this.nickname, onRecv: this.dispatch.bind(this)});
27
28 this.send = this.connection.send.bind(this.connection);
29 this.connect = this.connection.connect.bind(this.connection);
30 this.disconnect = this.connection.disconnect.bind(this.connection);
31
32 this.setupGenericErrors();
33 },
34 dispatch: function(data) {
35 var message = data[0];
36 if(message == "connect") {
37 this.connected();
38 } else if(message == "disconnect") {
39 if(data.length == 0) {
40 this.disconnected("No error!");
41 } else {
42 this.disconnected(data[1]);
43 }
44 this.disconnect();
45 } else if(message == "c") {
46 var command = data[1].toUpperCase();
47
48 var prefix = data[2];
49 var sl = data[3];
50 var n = qwebirc.irc.Numerics[command];
51
52 var x = n;
53 if(!n)
54 n = command;
55
56 var o = this["irc_" + n];
57
58 if(o) {
59 var r = o.run([prefix, sl], this);
60 if(!r)
61 this.rawNumeric(command, prefix, sl);
62 } else {
63 this.rawNumeric(command, prefix, sl);
64 }
65 }
66 },
67 isChannel: function(target) {
68 var c = target.charAt(0);
69 return c == '#';
70 },
71 irc_RPL_WELCOME: function(prefix, params) {
72 this.nickname = params[0];
73
74 this.__signedOn = true;
75 this.signedOn(this.nickname);
76 },
77 irc_ERR_NICKNAMEINUSE: function(prefix, params) {
78 this.genericError(params[1], params.indexFromEnd(-1).replace("in use.", "in use"));
79
80 if(this.__signedOn)
81 return true;
82
83 var newnick = params[1] + "_";
84 if(newnick == this.lastnick)
85 newnick = "qwebirc" + Math.floor(Math.random() * 1024 * 1024);
86
87 this.send("NICK " + newnick);
88 this.lastnick = newnick;
89 return true;
90 },
91 irc_NICK: function(prefix, params) {
92 var user = prefix;
93 var oldnick = user.hostToNick();
94 var newnick = params[0];
95
96 if(this.nickname == oldnick)
97 this.nickname = newnick;
98
99 this.nickChanged(user, newnick);
100
101 return true;
102 },
103 irc_QUIT: function(prefix, params) {
104 var user = prefix;
105
106 var message = params.indexFromEnd(-1);
107
108 this.userQuit(user, message);
109
110 return true;
111 },
112 irc_PART: function(prefix, params) {
113 var user = prefix;
114 var channel = params[0];
115 var message = params[1];
116
117 var nick = user.hostToNick();
118
119 if((nick == this.nickname) && this.channels[channel])
120 delete this.channels[channel];
121
122 this.userPart(user, channel, message);
123
124 return true;
125 },
126 irc_KICK: function(prefix, params) {
127 var kicker = prefix;
128 var channel = params[0];
129 var kickee = params[1];
130 var message = params[2];
131
132 if((kickee == this.nickname) && this.channels[channel])
133 delete this.channels[channel];
134
135 this.userKicked(kicker, channel, kickee, message);
136
137 return true;
138 },
139 irc_PING: function(prefix, params) {
140 this.send("PONG :" + params.indexFromEnd(-1));
141
142 return true;
143 },
144 irc_JOIN: function(prefix, params) {
145 var channel = params[0];
146 var user = prefix;
147 var nick = user.hostToNick();
148
149 if(nick == this.nickname)
150 this.channels[channel] = true;
151
152 this.userJoined(user, channel);
153
154 return true;
155 },
156 irc_TOPIC: function(prefix, params) {
157 var user = prefix;
158 var channel = params[0];
159 var topic = params.indexFromEnd(-1);
160
161 this.channelTopic(user, channel, topic);
162
163 return true;
164 },
165 processCTCP: function(message) {
166 if(message.charAt(0) != "\x01")
167 return;
168
169 if(message.charAt(message.length - 1) == "\x01") {
170 message = message.substr(1, message.length - 2);
171 } else {
172 message = message.substr(1);
173 }
174 return message.splitMax(" ", 2);
175 },
176 irc_PRIVMSG: function(prefix, params) {
177 var user = prefix;
178 var target = params[0];
179 var message = params.indexFromEnd(-1);
180
181 var ctcp = this.processCTCP(message);
182 if(ctcp) {
183 var type = ctcp[0].toUpperCase();
184
185 var replyfn = qwebirc.irc.RegisteredCTCPs[type];
186 if(replyfn) {
187 var t = new Date().getTime() / 1000;
188 if(t > this.nextctcp)
189 this.send("NOTICE " + user.hostToNick() + " :\x01" + type + " " + replyfn(ctcp[1]) + "\x01");
190 this.nextctcp = t + 5;
191 }
192
193 if(target == this.nickname) {
194 this.userCTCP(user, type, ctcp[1]);
195 } else {
196 this.channelCTCP(user, target, type, ctcp[1]);
197 }
198 } else {
199 if(target == this.nickname) {
200 this.userPrivmsg(user, message);
201 } else {
202 this.channelPrivmsg(user, target, message);
203 }
204 }
205
206 return true;
207 },
208 irc_NOTICE: function(prefix, params) {
209 var user = prefix;
210 var target = params[0];
211 var message = params.indexFromEnd(-1);
212
213 if((user == "") || (user.indexOf("!") == -1)) {
214 this.serverNotice(user, message);
215 } else if(target == this.nickname) {
216 var ctcp = this.processCTCP(message);
217 if(ctcp) {
218 this.userCTCPReply(user, ctcp[0], ctcp[1]);
219 } else {
220 this.userNotice(user, message);
221 }
222 } else {
223 this.channelNotice(user, target, message);
224 }
225
226 return true;
227 },
228 irc_INVITE: function(prefix, params) {
229 var user = prefix;
230 var channel = params.indexFromEnd(-1);
231
232 this.userInvite(user, channel);
233
234 return true;
235 },
236 irc_ERROR: function(prefix, params) {
237 var message = params.indexFromEnd(-1);
238
239 this.serverError(message);
240
241 return true;
242 },
243 irc_MODE: function(prefix, params) {
244 var user = prefix;
245 var target = params[0];
246 var args = params.slice(1);
247
248 if(target == this.nickname) {
249 this.userMode(args);
250 } else {
251 var modes = args[0].split("");
252 var xargs = args.slice(1);
253
254 var data = []
255 var carg = 0;
256 var pos = 0;
257 var cmode = "+";
258
259 modes.each(function(mode) {
260 if((mode == "+") || (mode == "-")) {
261 cmode = mode;
262 return;
263 }
264
265 if(this.pmodes[mode]) {
266 d = [cmode, mode, xargs[carg++]]
267 } else {
268 d = [cmode, mode]
269 }
270
271 data.push(d);
272 }, this);
273
274 this.channelMode(user, target, data, args);
275 }
276
277 return true;
278 },
279 irc_RPL_ISUPPORT: function(prefix, params) {
280 var supported = params.slice(1, -1);
281 var supportedhash = {};
282
283 for(var i=0;i<supported.length;i++) {
284 var l = supported[i].splitMax("=", 2);
285 this.supported(l[0], l[1]);
286 }
287 },
288 irc_RPL_MYINFO: function(prefix, params) {
289 var pmodes = params[5].split("");
290 this.pmodes = {}
291
292 pmodes.each(function(pmode) {
293 this.pmodes[pmode] = true;
294 }, this);
295 },
296 irc_RPL_NAMREPLY: function(prefix, params) {
297 var channel = params[2];
298 var names = params[3];
299
300 this.channelNames(channel, names.split(" "));
301
302 return true;
303 },
304 irc_RPL_ENDOFNAMES: function(prefix, params) {
305 var channel = params[1];
306
307 this.channelNames(channel, []);
308 return true;
309 },
310 irc_RPL_NOTOPIC: function(prefix, params) {
311 var channel = params[1];
312
313 if(this.channels[channel]) {
314 this.initialTopic(channel, "");
315 return true;
316 }
317 },
318 irc_RPL_TOPIC: function(prefix, params) {
319 var channel = params[1];
320 var topic = params.indexFromEnd(-1);
321
322 if(this.channels[channel]) {
323 this.initialTopic(channel, topic);
324 return true;
325 }
326 },
327 irc_RPL_TOPICWHOTIME: function(prefix, params) {
328 return true;
329 },
330 irc_RPL_WHOISUSER: function(prefix, params) {
331 var nick = params[1];
332 this.whoisNick = nick;
333
334 return this.whois(nick, "user", {ident: params[2], hostname: params[3], realname: params.indexFromEnd(-1)});
335 },
336 irc_RPL_WHOISSERVER: function(prefix, params) {
337 var nick = params[1];
338 var server = params[2];
339 var serverdesc = params.indexFromEnd(-1);
340
341 return this.whois(nick, "server", {server: params[2], serverdesc: params.indexFromEnd(-1)});
342 },
343 irc_RPL_WHOISOPERATOR: function(prefix, params) {
344 var nick = params[1];
345 var text = params.indexFromEnd(-1);
346
347 return this.whois(nick, "oper", {opertext: params.indexFromEnd(-1)});
348 },
349 irc_RPL_WHOISIDLE: function(prefix, params) {
350 var nick = params[1];
351
352 return this.whois(nick, "idle", {idle: params[2], connected: params[3]});
353 },
354 irc_RPL_WHOISCHANNELS: function(prefix, params) {
355 var nick = params[1];
356
357 return this.whois(nick, "channels", {channels: params.indexFromEnd(-1)});
358 },
359 irc_RPL_WHOISACCOUNT: function(prefix, params) {
360 var nick = params[1];
361
362 return this.whois(nick, "account", {account: params[2]});
363 },
364 irc_RPL_WHOISACTUALLY: function(prefix, params) {
365 var nick = params[1];
366
367 return this.whois(nick, "actually", {hostmask: params[2], ip: params[3]});
368 },
369 irc_RPL_WHOISOPERNAME: function(prefix, params) {
370 var nick = params[1];
371 var opername = params[2];
372
373 return this.whois(nick, "opername", {opername: params[2]});
374 },
375 irc_RPL_ENDOFWHOIS: function(prefix, params) {
376 var nick = params[1];
377 var text = params.indexFromEnd(-1);
378 this.whoisNick = null;
379
380 return this.whois(nick, "end", {});
381 },
382 irc_genericError: function(prefix, params) {
383 var target = params[1];
384 var message = params.indexFromEnd(-1);
385
386 this.genericError(target, message);
387 return true;
388 },
389 irc_genericQueryError: function(prefix, params) {
390 var target = params[1];
391 var message = params.indexFromEnd(-1);
392
393 this.genericQueryError(target, message);
394 return true;
395 },
396 setupGenericErrors: function() {
397 this.irc_ERR_CHANOPPRIVSNEEDED = this.irc_ERR_CANNOTSENDTOCHAN = this.irc_genericError;
398 this.irc_ERR_NOSUCHNICK = this.irc_genericQueryError;
399 return true;
400 },
401 irc_RPL_AWAY: function(prefix, params) {
402 var nick = params[1];
403 var text = params.indexFromEnd(-1);
404
405 if(this.whoisNick && (this.whoisNick == nick))
406 return this.whois(nick, "away", {"away": text});
407
408 this.awayMessage(nick, text);
409 return true;
410 },
411 irc_RPL_NOWAWAY: function(prefix, params) {
412 this.awayStatus(true, params.indexFromEnd(-1));
413 return true;
414 },
415 irc_RPL_UNAWAY: function(prefix, params) {
416 this.awayStatus(false, params.indexFromEnd(-1));
417 return true;
418 }
419 });