]> jfr.im git - irc/quakenet/qwebirc.git/blobdiff - js/irc/baseircclient.js
Merge.
[irc/quakenet/qwebirc.git] / js / irc / baseircclient.js
index e5fd5d614df27be248a4e3b3471c1a49ae45f0b1..45a13928d322b85687695e97c7c4a5366181ab9e 100644 (file)
@@ -1,36 +1,52 @@
+qwebirc.irc.PMODE_LIST = 0;
+qwebirc.irc.PMODE_SET_UNSET = 1;
+qwebirc.irc.PMODE_SET_ONLY = 2;
+qwebirc.irc.PMODE_REGULAR_MODE = 3;
+
 qwebirc.irc.RegisteredCTCPs = {
   "VERSION": function(x) {
-    return "qwebirc v" + qwebirc.VERSION + ", copyright (C) Chris Porter 2008-2009 -- " + qwebirc.util.browserVersion();
+    return "qwebirc v" + qwebirc.VERSION + ", copyright (C) 2008-2014 Chris Porter and the qwebirc project -- transport: " + this.connection.transportStatus + " -- " + qwebirc.util.browserVersion();
   },
   "USERINFO": function(x) { return "qwebirc"; },
-  "TIME": function(x) { return qwebirc.irc.IRCTime(new Date()); },
+  "TIME": function(x) { return qwebirc.irc.IRCDate(new Date()); },
   "PING": function(x) { return x; },
-  "CLIENTINFO": function(x) { return "PING VERSION TIME USERINFO CLIENTINFO"; }
+  "CLIENTINFO": function(x) { return "PING VERSION TIME USERINFO CLIENTINFO WEBSITE"; },
+  "WEBSITE": function(x) { return window == window.top ? "direct" : document.referrer; }
 };
 
 qwebirc.irc.BaseIRCClient = new Class({
-  Implements: [Options],
+  Implements: [Options, Events],
   options: {
     nickname: "qwebirc"
   },
   initialize: function(options) {
     this.setOptions(options);
 
+    this.toIRCLower = qwebirc.irc.RFC1459toIRCLower;
+
     this.nickname = this.options.nickname;
-    
+    this.lowerNickname = this.toIRCLower(this.nickname);    
+
     this.__signedOn = false;
-    this.pmodes = {b: true, k: true, o: true, l: true, v: true};
-    this.channels = {}
-    this.nextctcp = 0;    
+    this.pmodes = {b: qwebirc.irc.PMODE_LIST, l: qwebirc.irc.PMODE_SET_ONLY, k: qwebirc.irc.PMODE_SET_UNSET, o: qwebirc.irc.PMODE_SET_UNSET, v: qwebirc.irc.PMODE_SET_UNSET};
+    this.channels = {};
+    this.chanPrefixes = {"#": true, "&": true};
+    this.nextctcp = 0;
 
-    this.connection = new qwebirc.irc.IRCConnection({initialNickname: this.nickname, onRecv: this.dispatch.bind(this)});
+    this.connection = new qwebirc.irc.IRCConnection({
+      initialNickname: this.nickname,
+      onRecv: this.dispatch.bind(this),
+      serverPassword: this.options.serverPassword
+    });
   
     this.send = this.connection.send.bind(this.connection);
-    this.connect = this.connection.connect.bind(this.connection);
     this.disconnect = this.connection.disconnect.bind(this.connection);
-    
+
     this.setupGenericErrors();
   },
+  connect: function() {
+    this.connection.connect.apply(this.connection);
+  },
   dispatch: function(data) {
     var message = data[0];
     if(message == "connect") {
@@ -66,11 +82,39 @@ qwebirc.irc.BaseIRCClient = new Class({
   },
   isChannel: function(target) {
     var c = target.charAt(0);
-    return c == '#';
+    return this.chanPrefixes[c] === true;
+  },
+  supported: function(key, value) {
+    if(key == "CASEMAPPING") {
+      if(value == "ascii") {
+        this.toIRCLower = qwebirc.irc.ASCIItoIRCLower;
+      } else if(value == "rfc1459") {
+        /* IGNORE */
+      } else {
+        /* TODO: warn */
+      }
+      this.lowerNickname = this.toIRCLower(this.nickname);
+    } else if(key == "CHANMODES") {
+      var smodes = value.split(",");
+      for(var i=0;i<smodes.length;i++)
+        for(var j=0;j<smodes[i].length;j++)
+          this.pmodes[smodes[i].charAt(j)] = i;
+    } else if(key == "CHANTYPES") {
+      this.chanPrefixes = {};
+      for(var i=0;i<value.length;i++)
+        this.chanPrefixes[value.charAt(i)] = true;
+    } else if(key == "PREFIX") {
+      var l = (value.length - 2) / 2;
+      
+      var modeprefixes = value.substr(1, l).split("");
+      modeprefixes.each(function(modeprefix) {
+        this.pmodes[modeprefix] = qwebirc.irc.PMODE_SET_UNSET;
+      }, this);
+    }
   },
   irc_RPL_WELCOME: function(prefix, params) {
     this.nickname = params[0];
-    
+    this.lowerNickname = this.toIRCLower(this.nickname);
     this.__signedOn = true;
     this.signedOn(this.nickname);
   },
@@ -93,9 +137,11 @@ qwebirc.irc.BaseIRCClient = new Class({
     var oldnick = user.hostToNick();
     var newnick = params[0];
     
-    if(this.nickname == oldnick)
+    if(this.nickname == oldnick) {
       this.nickname = newnick;
-      
+      this.lowerNickname = this.toIRCLower(this.nickname);
+    }
+    
     this.nickChanged(user, newnick);
     
     return true;
@@ -116,21 +162,30 @@ qwebirc.irc.BaseIRCClient = new Class({
 
     var nick = user.hostToNick();
     
-    if((nick == this.nickname) && this.channels[channel])
-      delete this.channels[channel];
+    if((nick == this.nickname) && this.__getChannel(channel))
+      this.__killChannel(channel);
       
     this.userPart(user, channel, message);
     
     return true;
   },
+  __getChannel: function(name) {
+    return this.channels[this.toIRCLower(name)];
+  },
+  __killChannel: function(name) {
+    delete this.channels[this.toIRCLower(name)];
+  },
+  __nowOnChannel: function(name) {
+    this.channels[this.toIRCLower(name)] = 1;
+  },
   irc_KICK: function(prefix, params) {
     var kicker = prefix;
     var channel = params[0];
     var kickee = params[1];
     var message = params[2];
     
-    if((kickee == this.nickname) && this.channels[channel])
-      delete this.channels[channel];
+    if((kickee == this.nickname) && this.__getChannel(channel))
+      this.__killChannel(channel);
       
     this.userKicked(kicker, channel, kickee, message);
     
@@ -147,7 +202,7 @@ qwebirc.irc.BaseIRCClient = new Class({
     var nick = user.hostToNick();
         
     if(nick == this.nickname)
-      this.channels[channel] = true;
+      this.__nowOnChannel(channel);
 
     this.userJoined(user, channel);
     
@@ -185,9 +240,10 @@ qwebirc.irc.BaseIRCClient = new Class({
       var replyfn = qwebirc.irc.RegisteredCTCPs[type];
       if(replyfn) {
         var t = new Date().getTime() / 1000;
-        if(t > this.nextctcp)
-          this.send("NOTICE " + user.hostToNick() + " :\x01" + type + " " + replyfn(ctcp[1]) + "\x01");
-        this.nextctcp = t + 5;
+        if(t > this.nextctcp) {
+          this.send("NOTICE " + user.hostToNick() + " :\x01" + type + " " + replyfn.call(this, ctcp[1]) + "\x01");
+          this.nextctcp = t + 10;
+        }
       }
       
       if(target == this.nickname) {
@@ -263,7 +319,8 @@ qwebirc.irc.BaseIRCClient = new Class({
         }
 
         var d;
-        if(this.pmodes[mode]) { 
+        var pmode = this.pmodes[mode];
+        if(pmode == qwebirc.irc.PMODE_LIST || pmode == qwebirc.irc.PMODE_SET_UNSET || (cmode == "+" && pmode == qwebirc.irc.PMODE_SET_ONLY)) { 
           d = [cmode, mode, xargs[carg++]]
         } else {
           d = [cmode, mode]
@@ -279,24 +336,21 @@ qwebirc.irc.BaseIRCClient = new Class({
   },  
   irc_RPL_ISUPPORT: function(prefix, params) {
     var supported = params.slice(1, -1);
-    var supportedhash = {};
     
+    var items = {};
     for(var i=0;i<supported.length;i++) {
       var l = supported[i].splitMax("=", 2);
-      this.supported(l[0], l[1]);
+      items[l[0]] = true;
     }
-  },  
-  irc_RPL_MYINFO: function(prefix, params) {
-    if(params.length < 6)
-      return;
-
-    var pmodes = params[5].split("");
-    this.pmodes = {}
     
-    pmodes.each(function(pmode) {
-      this.pmodes[pmode] = true;
-    }, this);
-  },  
+    if(items.CHANMODES && items.PREFIX) /* nasty hack */
+      this.pmodes = {};
+    
+    for(var i=0;i<supported.length;i++) {
+      var l = supported[i].splitMax("=", 2);
+      this.supported(l[0], l[1]);
+    }
+  },
   irc_RPL_NAMREPLY: function(prefix, params) {
     var channel = params[2];    
     var names = params[3];
@@ -314,7 +368,7 @@ qwebirc.irc.BaseIRCClient = new Class({
   irc_RPL_NOTOPIC: function(prefix, params) {
     var channel = params[1];
 
-    if(this.channels[channel]) {
+    if(this.__getChannel(channel)) {
       this.initialTopic(channel, "");
       return true;
     }
@@ -323,7 +377,7 @@ qwebirc.irc.BaseIRCClient = new Class({
     var channel = params[1];
     var topic = params.indexFromEnd(-1);
     
-    if(this.channels[channel]) {
+    if(this.__getChannel(channel)) {
       this.initialTopic(channel, topic);
       return true;
     }
@@ -375,7 +429,25 @@ qwebirc.irc.BaseIRCClient = new Class({
     var opername = params[2];
 
     return this.whois(nick, "opername", {opername: params[2]});
-  },  
+  },
+  irc_RPL_WHOISGENERICTEXT: function(prefix, params) {
+    var nick = params[1];
+    var text = params.indexFromEnd(-1);
+    
+    return this.whois(nick, "generictext", {text: text});
+  },
+  irc_RPL_WHOISWEBIRC: function(prefix, params) {
+    var nick = params[1];
+    var text = params.indexFromEnd(-1);
+
+    return this.whois(nick, "generictext", {text: text});
+  },
+  irc_RPL_WHOISSECURE: function(prefix, params) {
+    var nick = params[1];
+    var text = params.indexFromEnd(-1);
+
+    return this.whois(nick, "generictext", {text: text});
+  },
   irc_RPL_ENDOFWHOIS: function(prefix, params) {
     var nick = params[1];
     var text = params.indexFromEnd(-1);
@@ -419,5 +491,26 @@ qwebirc.irc.BaseIRCClient = new Class({
   irc_RPL_UNAWAY: function(prefix, params) {
     this.awayStatus(false, params.indexFromEnd(-1));
     return true;
+  },
+  irc_WALLOPS: function(prefix, params) {
+    var user = prefix;
+    var text = params.indexFromEnd(-1);
+    
+    this.wallops(user, text);
+    return true;
+  },
+  irc_RPL_CREATIONTIME: function(prefix, params) {
+    var channel = params[1];
+    var time = params[2];
+
+    this.channelCreationTime(channel, time);    
+    return true;
+  },
+  irc_RPL_CHANNELMODEIS: function(prefix, params) {
+    var channel = params[1];
+    var modes = params.slice(2);
+
+    this.channelModeIs(channel, modes);
+    return true;
   }
 });