]> jfr.im git - irc/quakenet/qwebirc.git/blob - js/irc/baseircclient.js
e5fd5d614df27be248a4e3b3471c1a49ae45f0b1
[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-2009 -- " + 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: true, k: true, o: true, l: true, v: true};
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 var d;
266 if(this.pmodes[mode]) {
267 d = [cmode, mode, xargs[carg++]]
268 } else {
269 d = [cmode, mode]
270 }
271
272 data.push(d);
273 }, this);
274
275 this.channelMode(user, target, data, args);
276 }
277
278 return true;
279 },
280 irc_RPL_ISUPPORT: function(prefix, params) {
281 var supported = params.slice(1, -1);
282 var supportedhash = {};
283
284 for(var i=0;i<supported.length;i++) {
285 var l = supported[i].splitMax("=", 2);
286 this.supported(l[0], l[1]);
287 }
288 },
289 irc_RPL_MYINFO: function(prefix, params) {
290 if(params.length < 6)
291 return;
292
293 var pmodes = params[5].split("");
294 this.pmodes = {}
295
296 pmodes.each(function(pmode) {
297 this.pmodes[pmode] = true;
298 }, this);
299 },
300 irc_RPL_NAMREPLY: function(prefix, params) {
301 var channel = params[2];
302 var names = params[3];
303
304 this.channelNames(channel, names.split(" "));
305
306 return true;
307 },
308 irc_RPL_ENDOFNAMES: function(prefix, params) {
309 var channel = params[1];
310
311 this.channelNames(channel, []);
312 return true;
313 },
314 irc_RPL_NOTOPIC: function(prefix, params) {
315 var channel = params[1];
316
317 if(this.channels[channel]) {
318 this.initialTopic(channel, "");
319 return true;
320 }
321 },
322 irc_RPL_TOPIC: function(prefix, params) {
323 var channel = params[1];
324 var topic = params.indexFromEnd(-1);
325
326 if(this.channels[channel]) {
327 this.initialTopic(channel, topic);
328 return true;
329 }
330 },
331 irc_RPL_TOPICWHOTIME: function(prefix, params) {
332 return true;
333 },
334 irc_RPL_WHOISUSER: function(prefix, params) {
335 var nick = params[1];
336 this.whoisNick = nick;
337
338 return this.whois(nick, "user", {ident: params[2], hostname: params[3], realname: params.indexFromEnd(-1)});
339 },
340 irc_RPL_WHOISSERVER: function(prefix, params) {
341 var nick = params[1];
342 var server = params[2];
343 var serverdesc = params.indexFromEnd(-1);
344
345 return this.whois(nick, "server", {server: params[2], serverdesc: params.indexFromEnd(-1)});
346 },
347 irc_RPL_WHOISOPERATOR: function(prefix, params) {
348 var nick = params[1];
349 var text = params.indexFromEnd(-1);
350
351 return this.whois(nick, "oper", {opertext: params.indexFromEnd(-1)});
352 },
353 irc_RPL_WHOISIDLE: function(prefix, params) {
354 var nick = params[1];
355
356 return this.whois(nick, "idle", {idle: params[2], connected: params[3]});
357 },
358 irc_RPL_WHOISCHANNELS: function(prefix, params) {
359 var nick = params[1];
360
361 return this.whois(nick, "channels", {channels: params.indexFromEnd(-1)});
362 },
363 irc_RPL_WHOISACCOUNT: function(prefix, params) {
364 var nick = params[1];
365
366 return this.whois(nick, "account", {account: params[2]});
367 },
368 irc_RPL_WHOISACTUALLY: function(prefix, params) {
369 var nick = params[1];
370
371 return this.whois(nick, "actually", {hostmask: params[2], ip: params[3]});
372 },
373 irc_RPL_WHOISOPERNAME: function(prefix, params) {
374 var nick = params[1];
375 var opername = params[2];
376
377 return this.whois(nick, "opername", {opername: params[2]});
378 },
379 irc_RPL_ENDOFWHOIS: function(prefix, params) {
380 var nick = params[1];
381 var text = params.indexFromEnd(-1);
382 this.whoisNick = null;
383
384 return this.whois(nick, "end", {});
385 },
386 irc_genericError: function(prefix, params) {
387 var target = params[1];
388 var message = params.indexFromEnd(-1);
389
390 this.genericError(target, message);
391 return true;
392 },
393 irc_genericQueryError: function(prefix, params) {
394 var target = params[1];
395 var message = params.indexFromEnd(-1);
396
397 this.genericQueryError(target, message);
398 return true;
399 },
400 setupGenericErrors: function() {
401 this.irc_ERR_CHANOPPRIVSNEEDED = this.irc_ERR_CANNOTSENDTOCHAN = this.irc_genericError;
402 this.irc_ERR_NOSUCHNICK = this.irc_genericQueryError;
403 return true;
404 },
405 irc_RPL_AWAY: function(prefix, params) {
406 var nick = params[1];
407 var text = params.indexFromEnd(-1);
408
409 if(this.whoisNick && (this.whoisNick == nick))
410 return this.whois(nick, "away", {"away": text});
411
412 this.awayMessage(nick, text);
413 return true;
414 },
415 irc_RPL_NOWAWAY: function(prefix, params) {
416 this.awayStatus(true, params.indexFromEnd(-1));
417 return true;
418 },
419 irc_RPL_UNAWAY: function(prefix, params) {
420 this.awayStatus(false, params.indexFromEnd(-1));
421 return true;
422 }
423 });