]> jfr.im git - irc/quakenet/qwebirc.git/blob - js/irc/baseircclient.js
c329ec822e2e53c407182b1a60fe17fc3e1a9bdc
[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 -- user agent: " + Browser.Engine.name + " (" + Browser.Platform.name + ")";
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.chatAt(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 if(this.__signedOn)
79 return;
80
81 var newnick = params[1] + "_";
82 if(newnick == this.lastnick)
83 newnick = "webchat" + Math.floor(Math.random() * 1024 * 1024);
84
85 this.send("NICK " + newnick);
86 this.lastnick = newnick;
87 },
88 irc_NICK: function(prefix, params) {
89 var user = prefix;
90 var oldnick = user.hostToNick();
91 var newnick = params[0];
92
93 if(this.nickname == oldnick)
94 this.nickname = newnick;
95
96 this.nickChanged(user, newnick);
97
98 return true;
99 },
100 irc_QUIT: function(prefix, params) {
101 var user = prefix;
102
103 var message = params.indexFromEnd(-1);
104
105 this.userQuit(user, message);
106
107 return true;
108 },
109 irc_PART: function(prefix, params) {
110 var user = prefix;
111 var channel = params[0];
112 var message = params[1];
113
114 var nick = user.hostToNick();
115
116 if((nick == this.nickname) && this.channels[channel])
117 delete this.channels[channel];
118
119 this.userPart(user, channel, message);
120
121 return true;
122 },
123 irc_KICK: function(prefix, params) {
124 var kicker = prefix;
125 var channel = params[0];
126 var kickee = params[1];
127 var message = params[2];
128
129 if((kickee == this.nickname) && this.channels[channel])
130 delete this.channels[channel];
131
132 this.userKicked(kicker, channel, kickee, message);
133
134 return true;
135 },
136 irc_PING: function(prefix, params) {
137 this.send("PONG :" + params.indexFromEnd(-1));
138
139 return true;
140 },
141 irc_JOIN: function(prefix, params) {
142 var channel = params[0];
143 var user = prefix;
144 var nick = user.hostToNick();
145
146 if(nick == this.nickname)
147 this.channels[channel] = true;
148
149 this.userJoined(user, channel);
150
151 return true;
152 },
153 irc_TOPIC: function(prefix, params) {
154 var user = prefix;
155 var channel = params[0];
156 var topic = params.indexFromEnd(-1);
157
158 this.channelTopic(user, channel, topic);
159
160 return true;
161 },
162 processCTCP: function(message) {
163 if(message.charAt(0) != "\x01")
164 return;
165
166 if(message.charAt(message.length - 1) == "\x01") {
167 message = message.substr(1, message.length - 2);
168 } else {
169 message = message.substr(1);
170 }
171 return message.splitMax(" ", 2);
172 },
173 irc_PRIVMSG: function(prefix, params) {
174 var user = prefix;
175 var target = params[0];
176 var message = params.indexFromEnd(-1);
177
178 var ctcp = this.processCTCP(message);
179 if(ctcp) {
180 var type = ctcp[0].toUpperCase();
181
182 var replyfn = qwebirc.irc.RegisteredCTCPs[type];
183 if(replyfn) {
184 var t = new Date().getTime() / 1000;
185 if(t > this.nextctcp)
186 this.send("NOTICE " + user.hostToNick() + " :\x01" + type + " " + replyfn(ctcp[1]) + "\x01");
187 this.nextctcp = t + 5;
188 }
189
190 if(target == this.nickname) {
191 this.userCTCP(user, type, ctcp[1]);
192 } else {
193 this.channelCTCP(user, target, type, ctcp[1]);
194 }
195 } else {
196 if(target == this.nickname) {
197 this.userPrivmsg(user, message);
198 } else {
199 this.channelPrivmsg(user, target, message);
200 }
201 }
202
203 return true;
204 },
205 irc_NOTICE: function(prefix, params) {
206 var user = prefix;
207 var target = params[0];
208 var message = params.indexFromEnd(-1);
209
210 if(user == "") {
211 this.serverNotice(message);
212 } else if(target == this.nickname) {
213 var ctcp = this.processCTCP(message);
214 if(ctcp) {
215 this.userCTCPReply(user, ctcp[0], ctcp[1]);
216 } else {
217 this.userNotice(user, message);
218 }
219 } else {
220 this.channelNotice(user, target, message);
221 }
222
223 return true;
224 },
225 irc_INVITE: function(prefix, params) {
226 var user = prefix;
227 var channel = params.indexFromEnd(-1);
228
229 this.userInvite(user, channel);
230
231 return true;
232 },
233 irc_ERROR: function(prefix, params) {
234 var message = params.indexFromEnd(-1);
235
236 this.serverError(message);
237
238 return true;
239 },
240 irc_MODE: function(prefix, params) {
241 var user = prefix;
242 var target = params[0];
243 var args = params.slice(1);
244
245 if(target == this.nickname) {
246 this.userMode(args);
247 } else {
248 var modes = args[0].split("");
249 var xargs = args.slice(1);
250
251 var data = []
252 var carg = 0;
253 var pos = 0;
254 var cmode = "+";
255
256 modes.each(function(mode) {
257 if((mode == "+") || (mode == "-")) {
258 cmode = mode;
259 return;
260 }
261
262 if(this.pmodes[mode]) {
263 d = [cmode, mode, xargs[carg++]]
264 } else {
265 d = [cmode, mode]
266 }
267
268 data.push(d);
269 }, this);
270
271 this.channelMode(user, target, data, args);
272 }
273
274 return true;
275 },
276 irc_RPL_ISUPPORT: function(prefix, params) {
277 var supported = params.slice(1, -1);
278 var supportedhash = {};
279
280 for(var i=0;i<supported.length;i++) {
281 var l = supported[i].splitMax("=", 2);
282 this.supported(l[0], l[1]);
283 }
284 },
285 irc_RPL_MYINFO: function(prefix, params) {
286 var pmodes = params[5].split("");
287 this.pmodes = {}
288
289 pmodes.each(function(pmode) {
290 this.pmodes[pmode] = true;
291 }, this);
292 },
293 irc_RPL_NAMREPLY: function(prefix, params) {
294 var channel = params[2];
295 var names = params[3];
296
297 this.channelNames(channel, names.split(" "));
298
299 return true;
300 },
301 irc_RPL_ENDOFNAMES: function(prefix, params) {
302 var channel = params[1];
303
304 this.channelNames(channel, []);
305 return true;
306 },
307 irc_RPL_NOTOPIC: function(prefix, params) {
308 var channel = params[1];
309
310 if(this.channels[channel]) {
311 this.initialTopic(channel, "");
312 return true;
313 }
314 },
315 irc_RPL_TOPIC: function(prefix, params) {
316 var channel = params[1];
317 var topic = params.indexFromEnd(-1);
318
319 if(this.channels[channel]) {
320 this.initialTopic(channel, topic);
321 return true;
322 }
323 },
324 irc_RPL_TOPICWHOTIME: function(prefix, params) {
325 return true;
326 },
327 irc_RPL_WHOISUSER: function(prefix, params) {
328 var nick = params[1];
329 this.whoisNick = nick;
330
331 return this.whois(nick, "user", {ident: params[2], hostname: params[3], realname: params.indexFromEnd(-1)});
332 },
333 irc_RPL_WHOISSERVER: function(prefix, params) {
334 var nick = params[1];
335 var server = params[2];
336 var serverdesc = params.indexFromEnd(-1);
337
338 return this.whois(nick, "server", {server: params[2], serverdesc: params.indexFromEnd(-1)});
339 },
340 irc_RPL_WHOISOPERATOR: function(prefix, params) {
341 var nick = params[1];
342 var text = params.indexFromEnd(-1);
343
344 return this.whois(nick, "oper", {opertext: params.indexFromEnd(-1)});
345 },
346 irc_RPL_WHOISIDLE: function(prefix, params) {
347 var nick = params[1];
348
349 return this.whois(nick, "idle", {idle: params[2], connected: params[3]});
350 },
351 irc_RPL_WHOISCHANNELS: function(prefix, params) {
352 var nick = params[1];
353
354 return this.whois(nick, "channels", {channels: params.indexFromEnd(-1)});
355 },
356 irc_RPL_WHOISACCOUNT: function(prefix, params) {
357 var nick = params[1];
358
359 return this.whois(nick, "account", {account: params[2]});
360 },
361 irc_RPL_WHOISACTUALLY: function(prefix, params) {
362 var nick = params[1];
363
364 return this.whois(nick, "actually", {hostmask: params[2], ip: params[3]});
365 },
366 irc_RPL_WHOISOPERNAME: function(prefix, params) {
367 var nick = params[1];
368 var opername = params[2];
369
370 return this.whois(nick, "opername", {opername: params[2]});
371 },
372 irc_RPL_ENDOFWHOIS: function(prefix, params) {
373 var nick = params[1];
374 var text = params.indexFromEnd(-1);
375 this.whoisNick = null;
376
377 return this.whois(nick, "end", {});
378 },
379 irc_genericError: function(prefix, params) {
380 var target = params[1];
381 var message = params.indexFromEnd(-1);
382
383 this.genericError(target, message);
384 return true;
385 },
386 setupGenericErrors: function() {
387 this.irc_ERR_CHANOPPRIVSNEEDED = this.irc_ERR_NOSUCHNICK = this.irc_ERR_CANNOTSENDTOCHAN = this.irc_genericError;
388 return true;
389 },
390 irc_RPL_AWAY: function(prefix, params) {
391 var nick = params[1];
392 var text = params.indexFromEnd(-1);
393
394 if(this.whoisNick && (this.whoisNick == nick))
395 return this.whois(nick, "away", {"away": text});
396
397 this.awayMessage(nick, text);
398 return true;
399 },
400 irc_RPL_NOWAWAY: function(prefix, params) {
401 this.awayStatus(true, params.indexFromEnd(-1));
402 return true;
403 },
404 irc_RPL_UNAWAY: function(prefix, params) {
405 this.awayStatus(false, params.indexFromEnd(-1));
406 return true;
407 }
408 });