]> jfr.im git - irc/quakenet/qwebirc.git/blob - js/irc/baseircclient.js
f8b0e072a726dd3944cd9a143ee3bd226b5896a8
[irc/quakenet/qwebirc.git] / js / irc / baseircclient.js
1 qwebirc.irc.Numerics = {"001": "RPL_WELCOME", "433": "ERR_NICKNAMEINUSE", "004": "RPL_MYINFO", "005": "RPL_ISUPPORT", "353": "RPL_NAMREPLY", "366": "RPL_ENDOFNAMES", "331": "RPL_NOTOPIC", "332": "RPL_TOPIC", "333": "RPL_TOPICWHOTIME"};
2
3 qwebirc.irc.RegisteredCTCPs = {
4 "VERSION": function(x) {
5 return "qwebirc v" + qwebirc.VERSION + ", copyright (C) Chris Porter 2008 -- user agent: " + Browser.Engine.name + " (" + Browser.Platform.name + ")";
6 },
7 "USERINFO": function(x) { return "qwebirc"; },
8 "TIME": function(x) { return qwebirc.irc.IRCTime(new Date()); },
9 "PING": function(x) { return x; },
10 "CLIENTINFO": function(x) { return "PING VERSION TIME USERINFO CLIENTINFO"; }
11 };
12
13 qwebirc.irc.BaseIRCClient = new Class({
14 Implements: [Options],
15 options: {
16 nickname: "qwebirc"
17 },
18 initialize: function(options) {
19 this.setOptions(options);
20
21 this.nickname = this.options.nickname;
22
23 this.__signedOn = false;
24 this.pmodes = ["b", "k,", "o", "l", "v"];
25 this.channels = {}
26 this.nextctcp = 0;
27
28 this.connection = new qwebirc.irc.IRCConnection({initialNickname: this.nickname, onRecv: this.dispatch.bind(this)});
29
30 this.send = this.connection.send.bind(this.connection);
31 this.connect = this.connection.connect.bind(this.connection);
32 this.disconnect = this.connection.disconnect.bind(this.connection);
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.attempt([prefix, sl], this);
60 if(!r)
61 this.rawNumeric(command, prefix, sl);
62 } else {
63 this.rawNumeric(command, prefix, sl);
64 }
65 }
66 },
67
68 irc_RPL_WELCOME: function(prefix, params) {
69 this.nickname = params[0];
70
71 this.__signedOn = true;
72 this.signedOn(this.nickname);
73 },
74 irc_ERR_NICKNAMEINUSE: function(prefix, params) {
75 if(this.__signedOn)
76 return;
77
78 var newnick = params[1] + "_";
79 if(newnick == this.lastnick)
80 newnick = "webchat" + Math.floor(Math.random() * 1024 * 1024);
81
82 this.send("NICK " + newnick);
83 this.lastnick = newnick;
84 },
85 irc_NICK: function(prefix, params) {
86 var user = prefix;
87 var oldnick = user.hostToNick();
88 var newnick = params[0];
89
90 if(this.nickname == oldnick)
91 this.nickname = newnick;
92
93 this.nickChanged(user, newnick);
94
95 return true;
96 },
97 irc_QUIT: function(prefix, params) {
98 var user = prefix;
99
100 var message = params.indexFromEnd(-1);
101
102 this.userQuit(user, message);
103
104 return true;
105 },
106 irc_PART: function(prefix, params) {
107 var user = prefix;
108 var channel = params[0];
109 var message = params[1];
110
111 var nick = user.hostToNick();
112
113 if((nick == this.nickname) && this.channels[channel])
114 delete this.channels[channel];
115
116 this.userPart(user, channel, message);
117
118 return true;
119 },
120 irc_KICK: function(prefix, params) {
121 var kicker = prefix;
122 var channel = params[0];
123 var kickee = params[1];
124 var message = params[2];
125
126 if((kickee == this.nickname) && this.channels[channel])
127 delete this.channels[channel];
128
129 this.userKicked(kicker, channel, kickee, message);
130
131 return true;
132 },
133 irc_PING: function(prefix, params) {
134 this.send("PONG :" + params.indexFromEnd(-1));
135
136 return true;
137 },
138 irc_JOIN: function(prefix, params) {
139 var channel = params[0];
140 var user = prefix;
141 var nick = user.hostToNick();
142
143 if(nick == this.nickname)
144 this.channels[channel] = true;
145
146 this.userJoined(user, channel);
147
148 return true;
149 },
150 irc_TOPIC: function(prefix, params) {
151 var user = prefix;
152 var channel = params[0];
153 var topic = params.indexFromEnd(-1);
154
155 this.channelTopic(user, channel, topic);
156
157 return true;
158 },
159 processCTCP: function(message) {
160 if(message.charAt(0) != "\x01")
161 return;
162
163 if(message.charAt(message.length - 1) == "\x01") {
164 message = message.substr(1, message.length - 2);
165 } else {
166 message = message.substr(1);
167 }
168 return message.splitMax(" ", 2);
169 },
170 irc_PRIVMSG: function(prefix, params) {
171 var user = prefix;
172 var target = params[0];
173 var message = params.indexFromEnd(-1);
174
175 var ctcp = this.processCTCP(message);
176 if(ctcp) {
177 var type = ctcp[0].toUpperCase();
178
179 var replyfn = qwebirc.irc.RegisteredCTCPs[type];
180 if(replyfn) {
181 var t = new Date().getTime() / 1000;
182 if(t > this.nextctcp)
183 this.send("NOTICE " + user.hostToNick() + " :\x01" + type + " " + replyfn(ctcp[1]) + "\x01");
184 this.nextctcp = t + 5;
185 }
186
187 if(target == this.nickname) {
188 this.userCTCP(user, type, ctcp[1]);
189 } else {
190 this.channelCTCP(user, target, type, ctcp[1]);
191 }
192 } else {
193 if(target == this.nickname) {
194 this.userPrivmsg(user, message);
195 } else {
196 this.channelPrivmsg(user, target, message);
197 }
198 }
199
200 return true;
201 },
202 irc_NOTICE: function(prefix, params) {
203 var user = prefix;
204 var target = params[0];
205 var message = params.indexFromEnd(-1);
206
207 if(user == "") {
208 this.serverNotice(message);
209 } else if(target == this.nickname) {
210 var ctcp = this.processCTCP(message);
211 if(ctcp) {
212 this.userCTCPReply(user, ctcp[0], ctcp[1]);
213 } else {
214 this.userNotice(user, message);
215 }
216 } else {
217 this.channelNotice(user, target, message);
218 }
219
220 return true;
221 },
222 irc_INVITE: function(prefix, params) {
223 var user = prefix;
224 var channel = params.indexFromEnd(-1);
225
226 this.userInvite(user, channel);
227
228 return true;
229 },
230 irc_ERROR: function(prefix, params) {
231 var message = params.indexFromEnd(-1);
232
233 this.serverError(message);
234
235 return true;
236 },
237 irc_MODE: function(prefix, params) {
238 var user = prefix;
239 var target = params[0];
240 var args = params.slice(1);
241
242 if(target == this.nickname) {
243 this.userMode(args);
244 } else {
245 var modes = args[0].split("");
246 var xargs = args.slice(1);
247
248 var data = []
249 var carg = 0;
250 var pos = 0;
251 var cmode = "+";
252
253 modes.each(function(mode) {
254 if((mode == "+") || (mode == "-")) {
255 cmode = mode;
256 return;
257 }
258
259 if(this.pmodes[mode]) {
260 d = [cmode, mode, xargs[carg++]]
261 } else {
262 d = [cmode, mode]
263 }
264
265 data.push(d);
266 }, this);
267
268 this.channelMode(user, target, data, args);
269 }
270
271 return true;
272 },
273 irc_RPL_ISUPPORT: function(prefix, params) {
274 var supported = params.slice(1, -1);
275 var supportedhash = {};
276
277 for(var i=0;i<supported.length;i++) {
278 var l = supported[i].splitMax("=", 2);
279 this.supported(l[0], l[1]);
280 }
281 },
282 irc_RPL_MYINFO: function(prefix, params) {
283 var pmodes = params[5].split("");
284 this.pmodes = {}
285
286 pmodes.each(function(pmode) {
287 this.pmodes[pmode] = true;
288 }, this);
289 },
290 irc_RPL_NAMREPLY: function(prefix, params) {
291 var channel = params[2];
292 var names = params[3];
293
294 this.channelNames(channel, names.split(" "));
295
296 return true;
297 },
298 irc_RPL_ENDOFNAMES: function(prefix, params) {
299 var channel = params[1];
300
301 this.channelNames(channel, []);
302 return true;
303 },
304 irc_RPL_NOTOPIC: function(prefix, params) {
305 var channel = params[1];
306
307 if(this.channels[channel]) {
308 this.initialTopic(channel, "");
309 return true;
310 }
311 },
312 irc_RPL_TOPIC: function(prefix, params) {
313 var channel = params[1];
314 var topic = params.indexFromEnd(-1);
315
316 if(this.channels[channel]) {
317 this.initialTopic(channel, topic);
318 return true;
319 }
320 },
321 irc_RPL_TOPICWHOTIME: function(prefix, params) {
322 return true;
323 }
324 });