-var IRCClient = new Class({\r
- Extends: BaseIRCClient,\r
- options: {\r
- nickname: "WCunset",\r
- autojoin: "",\r
- },\r
- initialize: function(options, ui) {\r
- this.parent(options);\r
-\r
- this.ui = ui;\r
-\r
- this.prefixes = "@+";\r
- this.modeprefixes = "ov";\r
- this.windows = {};\r
- \r
- this.commandparser = new CommandParser(this);\r
- this.exec = this.commandparser.dispatch.bind(this.commandparser);\r
-\r
- this.statusWindow = this.ui.newClient(this);\r
- },\r
- newLine: function(window, type, data) {\r
- if(!data)\r
- data = {};\r
- \r
- var w = this.getWindow(window);\r
- if(w) {\r
- w.addLine(type, data);\r
- } else {\r
- this.statusWindow.addLine(type, data);\r
- }\r
- },\r
- newChanLine: function(channel, type, user, extra) {\r
- if(!extra)\r
- extra = {};\r
-\r
- extra["n"] = user.hostToNick();\r
- extra["h"] = user.hostToHost();\r
- extra["c"] = channel;\r
- extra["-"] = this.nickname;\r
- \r
- this.newLine(channel, type, extra);\r
- },\r
- newServerLine: function(type, data) {\r
- this.statusWindow.addLine(type, data);\r
- },\r
- newActiveLine: function(type, data) {\r
- this.ui.getActiveWindow().addLine(type, data);\r
- },\r
- updateNickList: function(channel) {\r
- var n1 = this.tracker.getChannel(channel);\r
- var names = new Array();\r
- var tff = String.fromCharCode(255);\r
- var nh = {}\r
- \r
- /* MEGAHACK */\r
- for(var n in n1) {\r
- var nc = n1[n];\r
- var nx;\r
- \r
- if(nc.prefixes.length > 0) {\r
- var c = nc.prefixes.charAt(0);\r
- nx = String.fromCharCode(this.prefixes.indexOf(c)) + n.toIRCLower();\r
- nh[nx] = c + n;\r
- } else {\r
- nx = tff + n.toIRCLower();\r
- nh[nx] = n;\r
- }\r
- names.push(nx);\r
- };\r
- \r
- names.sort();\r
- \r
- var sortednames = new Array();\r
- names.each(function(name) {\r
- sortednames.push(nh[name]);\r
- });\r
- \r
- var w = this.getWindow(channel);\r
- if(w)\r
- w.updateNickList(sortednames);\r
- },\r
- getWindow: function(name) {\r
- return this.windows[name];\r
- },\r
- newWindow: function(name, type, select) {\r
- var w = this.getWindow(name);\r
- if(!w) {\r
- w = this.windows[name] = this.ui.newWindow(this, type, name);\r
- \r
- w.addEvent("close", function(w) {\r
- delete this.windows[name];\r
- }.bind(this));\r
- }\r
- \r
- if(select)\r
- this.ui.selectWindow(w);\r
- \r
- return w;\r
- },\r
- getActiveWindow: function() {\r
- return this.ui.getActiveWindow();\r
- },\r
- getNickname: function() {\r
- return this.nickname;\r
- },\r
- addPrefix: function(nickchanentry, prefix) {\r
- var ncp = nickchanentry.prefixes + prefix;\r
- var prefixes = [];\r
- \r
- /* O(n^2) */\r
- for(var i=0;i<this.prefixes.length;i++) {\r
- var pc = this.prefixes.charAt(i);\r
- var index = ncp.indexOf(pc);\r
- if(index != -1)\r
- prefixes.push(pc);\r
- }\r
- \r
- nickchanentry.prefixes = prefixes.join("");\r
- },\r
- removePrefix: function(nickchanentry, prefix) {\r
- nickchanentry.prefixes = nickchanentry.prefixes.replaceAll(prefix, "");\r
- },\r
- \r
- /* from here down are events */\r
- rawNumeric: function(numeric, prefix, params) {\r
- this.newServerLine("RAW", {"n": "numeric", "m": params.slice(1).join(" ")});\r
- },\r
- signedOn: function(nickname) {\r
- this.tracker = new IRCTracker();\r
- this.nickname = nickname;\r
- this.newServerLine("SIGNON");\r
- \r
- if(this.autojoin)\r
- this.send("JOIN " + this.autojoin);\r
- },\r
- userJoined: function(user, channel) {\r
- var nick = user.hostToNick();\r
- var host = user.hostToHost();\r
- \r
- if((nick == this.nickname) && !this.getWindow(channel))\r
- this.newWindow(channel, WINDOW_CHANNEL, true);\r
- this.tracker.addNickToChannel(nick, channel);\r
-\r
- this.newChanLine(channel, "JOIN", user);\r
- this.updateNickList(channel);\r
- },\r
- userPart: function(user, channel, message) {\r
- var nick = user.hostToNick();\r
- var host = user.hostToHost();\r
- \r
- if(nick == this.nickname) {\r
- this.tracker.removeChannel(channel);\r
- } else {\r
- this.tracker.removeNickFromChannel(nick, channel);\r
- this.newChanLine(channel, "PART", user, {"m": message});\r
- }\r
- \r
- this.updateNickList(channel);\r
- \r
- var w = this.getWindow(channel)\r
- if(w)\r
- w.close();\r
- },\r
- userKicked: function(kicker, channel, kickee, message) {\r
- if(kickee == this.nickname) {\r
- this.tracker.removeChannel(channel);\r
- this.getWindow(channel).close();\r
- } else {\r
- this.tracker.removeNickFromChannel(kickee, channel);\r
- this.updateNickList(channel);\r
- }\r
- \r
- this.newChanLine(channel, "KICK", kicker, {"v": kickee, "m": message});\r
- },\r
- channelMode: function(user, channel, modes, raw) {\r
- modes.each(function(mo) {\r
- var direction = mo[0];\r
- var mode = mo[1];\r
-\r
- var prefixindex = this.modeprefixes.indexOf(mode);\r
- if(prefixindex == -1)\r
- return;\r
- \r
- var nick = mo[2];\r
- var prefixchar = this.prefixes.charAt(prefixindex);\r
-\r
- var nc = this.tracker.getOrCreateNickOnChannel(nick, channel);\r
- if(direction == "-") {\r
- this.removePrefix(nc, prefixchar);\r
- } else {\r
- this.addPrefix(nc, prefixchar);\r
- }\r
- }, this);\r
-\r
- this.newChanLine(channel, "MODE", user, {"m": raw.join(" ")});\r
- \r
- this.updateNickList(channel);\r
- },\r
- userQuit: function(user, message) {\r
- var nick = user.hostToNick();\r
- \r
- var channels = this.tracker.getNick(nick);\r
- \r
- var clist = [];\r
- for(var c in channels) {\r
- clist.push(c);\r
- this.newChanLine(c, "QUIT", user, {"m": message});\r
- }\r
- \r
- this.tracker.removeNick(nick);\r
- \r
- clist.each(function(cli) {\r
- this.updateNickList(cli);\r
- }, this);\r
- },\r
- nickChanged: function(user, newnick) {\r
- var oldnick = user.hostToNick();\r
- \r
- if(oldnick == this.nickname)\r
- this.nickname = newnick;\r
- \r
- this.tracker.renameNick(oldnick, newnick);\r
-\r
- var channels = this.tracker.getNick(newnick);\r
- \r
- for(var c in channels) {\r
- this.newChanLine(c, "NICK", user, {"w": newnick});\r
- /* TODO: rename queries */\r
- this.updateNickList(c);\r
- }\r
- },\r
- channelTopic: function(user, channel, topic) {\r
- this.newChanLine(channel, "TOPIC", user, {"m": topic});\r
- this.getWindow(channel).updateTopic(topic);\r
- },\r
- initialTopic: function(channel, topic) {\r
- this.getWindow(channel).updateTopic(topic);\r
- },\r
- channelCTCP: function(user, channel, type, args) {\r
- if(args == undefined)\r
- args = "";\r
-\r
- if(type == "ACTION") {\r
- this.newChanLine(channel, "CHANACTION", user, {"m": args, "c": channel});\r
- return;\r
- }\r
- \r
- this.newChanLine(channel, "CHANCTCP", user, {"x": type, "m": args, "c": channel});\r
- },\r
- userCTCP: function(user, type, args) {\r
- var nick = user.hostToNick();\r
- var host = user.hostToHost();\r
- if(args == undefined)\r
- args = "";\r
- \r
- if(type == "ACTION") { \r
- this.newWindow(nick, WINDOW_QUERY);\r
- this.newLine(nick, "PRIVACTION", {"m": args, "x": type, "h": host, "n": nick});\r
- return;\r
- }\r
- \r
- if(this.getWindow(nick)) {\r
- this.newLine(nick, "PRIVCTCP", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});\r
- } else {\r
- this.newActiveLine("PRIVCTCP", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});\r
- }\r
- },\r
- userCTCPReply: function(user, type, args) {\r
- var nick = user.hostToNick();\r
- var host = user.hostToHost();\r
- if(args == undefined)\r
- args = "";\r
- \r
- if(this.getWindow(nick)) {\r
- this.newLine(nick, "CTCPREPLY", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});\r
- } else {\r
- this.newActiveLine("CTCPREPLY", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});\r
- }\r
- },\r
- channelPrivmsg: function(user, channel, message) {\r
- this.newChanLine(channel, "CHANMSG", user, {"m": message});\r
- },\r
- channelNotice: function(user, channel, message) {\r
- this.newChanLine(channel, "CHANNOTICE", user, {"m": message});\r
- },\r
- userPrivmsg: function(user, message) {\r
- var nick = user.hostToNick();\r
- var host = user.hostToHost();\r
- \r
- this.newWindow(nick, WINDOW_QUERY);\r
- \r
- this.newLine(nick, "PRIVMSG", {"m": message, "h": host, "n": nick});\r
- },\r
- serverNotice: function(message) {\r
- this.newServerLine("SERVERNOTICE", {"m": message});\r
- },\r
- userNotice: function(user, message) {\r
- var nick = user.hostToNick();\r
- var host = user.hostToHost();\r
-\r
- if(this.getWindow(nick)) {\r
- this.newLine(nick, "PRIVNOTICE", {"m": message, "h": host, "n": nick});\r
- } else {\r
- this.newActiveLine("PRIVNOTICE", {"m": message, "h": host, "n": nick});\r
- }\r
- },\r
- userInvite: function(user, channel) {\r
- var nick = user.hostToNick();\r
- var host = user.hostToHost();\r
-\r
- this.newServerLine("INVITE", {"c": channel, "h": host, "n": nick});\r
- },\r
- userMode: function(modes) {\r
- this.newServerLine("UMODE", {"m": modes, "n": this.nickname});\r
- },\r
- channelNames: function(channel, names) {\r
- if(names.length == 0) {\r
- this.updateNickList(channel);\r
- return;\r
- }\r
- \r
- names.each(function(nick) {\r
- var prefixes = [];\r
- var splitnick = nick.split("");\r
- \r
- splitnick.every(function(c, i) {\r
- if(this.prefixes.indexOf(c) == -1) {\r
- nick = nick.substr(i);\r
- return false;\r
- }\r
- \r
- prefixes.push(c);\r
- return true;\r
- }, this);\r
-\r
- var nc = this.tracker.addNickToChannel(nick, channel);\r
- prefixes.each(function(p) {\r
- this.addPrefix(nc, p);\r
- }, this);\r
- }, this);\r
- },\r
- disconnected: function() {\r
- for(var x in this.parent.channels)\r
- this.ui.closeWindow(x);\r
-\r
- this.tracker = undefined;\r
- \r
- this.newServerLine("DISCONNECT");\r
- },\r
- supported: function(key, value) {\r
- if(key == "PREFIX") {\r
- var l = (value.length - 2) / 2;\r
-\r
- this.modeprefixes = value.substr(1, l);\r
- this.prefixes = value.substr(l + 2, l);\r
- }\r
- },\r
- connected: function() {\r
- this.newServerLine("CONNECT");\r
- },\r
- serverError: function(message) {\r
- this.newServerLine("ERROR", {"m": message});\r
- }\r
-});\r
+var IRCClient = new Class({
+ Extends: BaseIRCClient,
+ options: {
+ nickname: "WCunset",
+ autojoin: "",
+ },
+ initialize: function(options, ui) {
+ this.parent(options);
+
+ this.ui = ui;
+
+ this.prefixes = "@+";
+ this.modeprefixes = "ov";
+ this.windows = {};
+
+ this.commandparser = new CommandParser(this);
+ this.exec = this.commandparser.dispatch.bind(this.commandparser);
+
+ this.statusWindow = this.ui.newClient(this);
+ },
+ newLine: function(window, type, data) {
+ if(!data)
+ data = {};
+
+ var w = this.getWindow(window);
+ if(w) {
+ w.addLine(type, data);
+ } else {
+ this.statusWindow.addLine(type, data);
+ }
+ },
+ newChanLine: function(channel, type, user, extra) {
+ if(!extra)
+ extra = {};
+
+ extra["n"] = user.hostToNick();
+ extra["h"] = user.hostToHost();
+ extra["c"] = channel;
+ extra["-"] = this.nickname;
+
+ this.newLine(channel, type, extra);
+ },
+ newServerLine: function(type, data) {
+ this.statusWindow.addLine(type, data);
+ },
+ newActiveLine: function(type, data) {
+ this.ui.getActiveWindow().addLine(type, data);
+ },
+ updateNickList: function(channel) {
+ var n1 = this.tracker.getChannel(channel);
+ var names = new Array();
+ var tff = String.fromCharCode(255);
+ var nh = {}
+
+ /* MEGAHACK */
+ for(var n in n1) {
+ var nc = n1[n];
+ var nx;
+
+ if(nc.prefixes.length > 0) {
+ var c = nc.prefixes.charAt(0);
+ nx = String.fromCharCode(this.prefixes.indexOf(c)) + n.toIRCLower();
+ nh[nx] = c + n;
+ } else {
+ nx = tff + n.toIRCLower();
+ nh[nx] = n;
+ }
+ names.push(nx);
+ };
+
+ names.sort();
+
+ var sortednames = new Array();
+ names.each(function(name) {
+ sortednames.push(nh[name]);
+ });
+
+ var w = this.getWindow(channel);
+ if(w)
+ w.updateNickList(sortednames);
+ },
+ getWindow: function(name) {
+ return this.windows[name];
+ },
+ newWindow: function(name, type, select) {
+ var w = this.getWindow(name);
+ if(!w) {
+ w = this.windows[name] = this.ui.newWindow(this, type, name);
+
+ w.addEvent("close", function(w) {
+ delete this.windows[name];
+ }.bind(this));
+ }
+
+ if(select)
+ this.ui.selectWindow(w);
+
+ return w;
+ },
+ getActiveWindow: function() {
+ return this.ui.getActiveWindow();
+ },
+ getNickname: function() {
+ return this.nickname;
+ },
+ addPrefix: function(nickchanentry, prefix) {
+ var ncp = nickchanentry.prefixes + prefix;
+ var prefixes = [];
+
+ /* O(n^2) */
+ for(var i=0;i<this.prefixes.length;i++) {
+ var pc = this.prefixes.charAt(i);
+ var index = ncp.indexOf(pc);
+ if(index != -1)
+ prefixes.push(pc);
+ }
+
+ nickchanentry.prefixes = prefixes.join("");
+ },
+ removePrefix: function(nickchanentry, prefix) {
+ nickchanentry.prefixes = nickchanentry.prefixes.replaceAll(prefix, "");
+ },
+
+ /* from here down are events */
+ rawNumeric: function(numeric, prefix, params) {
+ this.newServerLine("RAW", {"n": "numeric", "m": params.slice(1).join(" ")});
+ },
+ signedOn: function(nickname) {
+ this.tracker = new IRCTracker();
+ this.nickname = nickname;
+ this.newServerLine("SIGNON");
+
+ if(this.autojoin)
+ this.send("JOIN " + this.autojoin);
+ },
+ userJoined: function(user, channel) {
+ var nick = user.hostToNick();
+ var host = user.hostToHost();
+
+ if((nick == this.nickname) && !this.getWindow(channel))
+ this.newWindow(channel, WINDOW_CHANNEL, true);
+ this.tracker.addNickToChannel(nick, channel);
+
+ this.newChanLine(channel, "JOIN", user);
+ this.updateNickList(channel);
+ },
+ userPart: function(user, channel, message) {
+ var nick = user.hostToNick();
+ var host = user.hostToHost();
+
+ if(nick == this.nickname) {
+ this.tracker.removeChannel(channel);
+ } else {
+ this.tracker.removeNickFromChannel(nick, channel);
+ this.newChanLine(channel, "PART", user, {"m": message});
+ }
+
+ this.updateNickList(channel);
+
+ var w = this.getWindow(channel)
+ if(w)
+ w.close();
+ },
+ userKicked: function(kicker, channel, kickee, message) {
+ if(kickee == this.nickname) {
+ this.tracker.removeChannel(channel);
+ this.getWindow(channel).close();
+ } else {
+ this.tracker.removeNickFromChannel(kickee, channel);
+ this.updateNickList(channel);
+ }
+
+ this.newChanLine(channel, "KICK", kicker, {"v": kickee, "m": message});
+ },
+ channelMode: function(user, channel, modes, raw) {
+ modes.each(function(mo) {
+ var direction = mo[0];
+ var mode = mo[1];
+
+ var prefixindex = this.modeprefixes.indexOf(mode);
+ if(prefixindex == -1)
+ return;
+
+ var nick = mo[2];
+ var prefixchar = this.prefixes.charAt(prefixindex);
+
+ var nc = this.tracker.getOrCreateNickOnChannel(nick, channel);
+ if(direction == "-") {
+ this.removePrefix(nc, prefixchar);
+ } else {
+ this.addPrefix(nc, prefixchar);
+ }
+ }, this);
+
+ this.newChanLine(channel, "MODE", user, {"m": raw.join(" ")});
+
+ this.updateNickList(channel);
+ },
+ userQuit: function(user, message) {
+ var nick = user.hostToNick();
+
+ var channels = this.tracker.getNick(nick);
+
+ var clist = [];
+ for(var c in channels) {
+ clist.push(c);
+ this.newChanLine(c, "QUIT", user, {"m": message});
+ }
+
+ this.tracker.removeNick(nick);
+
+ clist.each(function(cli) {
+ this.updateNickList(cli);
+ }, this);
+ },
+ nickChanged: function(user, newnick) {
+ var oldnick = user.hostToNick();
+
+ if(oldnick == this.nickname)
+ this.nickname = newnick;
+
+ this.tracker.renameNick(oldnick, newnick);
+
+ var channels = this.tracker.getNick(newnick);
+
+ for(var c in channels) {
+ this.newChanLine(c, "NICK", user, {"w": newnick});
+ /* TODO: rename queries */
+ this.updateNickList(c);
+ }
+ },
+ channelTopic: function(user, channel, topic) {
+ this.newChanLine(channel, "TOPIC", user, {"m": topic});
+ this.getWindow(channel).updateTopic(topic);
+ },
+ initialTopic: function(channel, topic) {
+ this.getWindow(channel).updateTopic(topic);
+ },
+ channelCTCP: function(user, channel, type, args) {
+ if(args == undefined)
+ args = "";
+
+ if(type == "ACTION") {
+ this.newChanLine(channel, "CHANACTION", user, {"m": args, "c": channel});
+ return;
+ }
+
+ this.newChanLine(channel, "CHANCTCP", user, {"x": type, "m": args, "c": channel});
+ },
+ userCTCP: function(user, type, args) {
+ var nick = user.hostToNick();
+ var host = user.hostToHost();
+ if(args == undefined)
+ args = "";
+
+ if(type == "ACTION") {
+ this.newWindow(nick, WINDOW_QUERY);
+ this.newLine(nick, "PRIVACTION", {"m": args, "x": type, "h": host, "n": nick});
+ return;
+ }
+
+ if(this.getWindow(nick)) {
+ this.newLine(nick, "PRIVCTCP", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});
+ } else {
+ this.newActiveLine("PRIVCTCP", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});
+ }
+ },
+ userCTCPReply: function(user, type, args) {
+ var nick = user.hostToNick();
+ var host = user.hostToHost();
+ if(args == undefined)
+ args = "";
+
+ if(this.getWindow(nick)) {
+ this.newLine(nick, "CTCPREPLY", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});
+ } else {
+ this.newActiveLine("CTCPREPLY", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});
+ }
+ },
+ channelPrivmsg: function(user, channel, message) {
+ this.newChanLine(channel, "CHANMSG", user, {"m": message});
+ },
+ channelNotice: function(user, channel, message) {
+ this.newChanLine(channel, "CHANNOTICE", user, {"m": message});
+ },
+ userPrivmsg: function(user, message) {
+ var nick = user.hostToNick();
+ var host = user.hostToHost();
+
+ this.newWindow(nick, WINDOW_QUERY);
+
+ this.newLine(nick, "PRIVMSG", {"m": message, "h": host, "n": nick});
+ },
+ serverNotice: function(message) {
+ this.newServerLine("SERVERNOTICE", {"m": message});
+ },
+ userNotice: function(user, message) {
+ var nick = user.hostToNick();
+ var host = user.hostToHost();
+
+ if(this.getWindow(nick)) {
+ this.newLine(nick, "PRIVNOTICE", {"m": message, "h": host, "n": nick});
+ } else {
+ this.newActiveLine("PRIVNOTICE", {"m": message, "h": host, "n": nick});
+ }
+ },
+ userInvite: function(user, channel) {
+ var nick = user.hostToNick();
+ var host = user.hostToHost();
+
+ this.newServerLine("INVITE", {"c": channel, "h": host, "n": nick});
+ },
+ userMode: function(modes) {
+ this.newServerLine("UMODE", {"m": modes, "n": this.nickname});
+ },
+ channelNames: function(channel, names) {
+ if(names.length == 0) {
+ this.updateNickList(channel);
+ return;
+ }
+
+ names.each(function(nick) {
+ var prefixes = [];
+ var splitnick = nick.split("");
+
+ splitnick.every(function(c, i) {
+ if(this.prefixes.indexOf(c) == -1) {
+ nick = nick.substr(i);
+ return false;
+ }
+
+ prefixes.push(c);
+ return true;
+ }, this);
+
+ var nc = this.tracker.addNickToChannel(nick, channel);
+ prefixes.each(function(p) {
+ this.addPrefix(nc, p);
+ }, this);
+ }, this);
+ },
+ disconnected: function() {
+ for(var x in this.parent.channels)
+ this.ui.closeWindow(x);
+
+ this.tracker = undefined;
+
+ this.newServerLine("DISCONNECT");
+ },
+ supported: function(key, value) {
+ if(key == "PREFIX") {
+ var l = (value.length - 2) / 2;
+
+ this.modeprefixes = value.substr(1, l);
+ this.prefixes = value.substr(l + 2, l);
+ }
+ },
+ connected: function() {
+ this.newServerLine("CONNECT");
+ },
+ serverError: function(message) {
+ this.newServerLine("ERROR", {"m": message});
+ }
+});