Implement the capabilities negotiation and multi-prefix extensions
authorJack Allnutt <m2ys4u@Gmail.com>
Thu, 1 Nov 2012 20:12:19 +0000 (20:12 +0000)
committerJack Allnutt <m2ys4u@Gmail.com>
Thu, 1 Nov 2012 20:12:19 +0000 (20:12 +0000)
Issues #107 and #108

server/irc/commands.js
server/irc/connection.js

index afeb4ed2d724887dab11e8183b39461afb1437f7..a47cb192459e503a661250458185b2f099cdf7c8 100644 (file)
@@ -73,6 +73,8 @@ var listeners = {
     'RPL_WELCOME':            function (command) {
                 var nick =  command.params[0];
                 this.irc_connection.registered = true;
+                this.cap_negotation = false;
+                console.log(this.irc_connection.cap.enabled);
                 this.client.sendIrcCommand('connect', {server: this.con_num, nick: nick});
             },
     'RPL_ISUPPORT':           function (command) {
@@ -95,7 +97,7 @@ var listeners = {
                                                        this.irc_connection.options.CHANTYPES = this.irc_connection.options.CHANTYPES.split('');
                                                } else if (option[0] === 'CHANMODES') {
                                                        this.irc_connection.options.CHANMODES = option[1].split(',');
-                        } else if (option[0] === 'NAMESX') {
+                        } else if ((option[0] === 'NAMESX') && (!_.contains(this.irc_connection.cap.enabled, 'multi-prefix'))) {
                             this.irc_connection.write('PROTOCTL NAMESX');
                         }
                     }
@@ -430,6 +432,48 @@ var listeners = {
                     this.client.sendIrcCommand('msg', {server: this.con_num, nick: command.nick, ident: command.ident, hostname: command.hostname, channel: command.params[0], msg: command.trailing});
                 }
             },
+    'CAP':                  function (command) {
+                // TODO: capability modifiers
+                // i.e. - for disable, ~ for requires ACK, = for sticky
+                var capabilities = command.trailing.replace(/[\-~=]/, '').split(' ');
+                var want = ['multi-prefix'];
+                var request;
+                
+                switch (command.params[1]) {
+                    case 'LS':
+                        request = _.intersection(capabilities, want);
+                        if (request.length > 0) {
+                            this.irc_connection.cap.requested = request;
+                            this.irc_connection.write('CAP REQ :' + request.join(' '));
+                        } else {
+                            this.irc_connection.write('CAP END');
+                            this.irc_connection.cap_negotation = false;
+                        }
+                        break;
+                    case 'ACK':
+                        if (capabilities.length > 0) {
+                            this.irc_connection.cap.enabled = capabilities;
+                            this.irc_connection.cap.requested = _.difference(this.irc_connection.cap.requested, capabilities);
+                        }
+                        if (this.irc_connection.cap.requested.length > 0) {
+                            this.irc_connection.write('CAP END');
+                            this.irc_connection.cap_negotation = false;
+                        }
+                        break;
+                    case 'NAK':
+                        if (capabilities.length > 0) {
+                            this.irc_connection.cap.requested = _.difference(this.irc_connection.cap.requested, capabilities);
+                        }
+                        if (this.irc_connection.cap.requested.length > 0) {
+                            this.irc_connection.write('CAP END');
+                            this.irc_connection.cap_negotation = false;
+                        }
+                        break;
+                    case 'LIST':
+                        // should we do anything here?
+                        break;
+                }
+            },
     'ERROR':                function (command) {
                                /*command.server = this.con_num;
                                command.command = 'ERROR';
index c68637d4e25a62a048c69ad28cfdd9facd5a108b..9a344fff7ea732afec1dfe0938dc243069f63fec 100644 (file)
@@ -33,11 +33,13 @@ var IrcConnection = function (hostname, port, ssl, nick, user, pass) {
     
     this.connected = false;
     this.registered = false;
+    this.cap_negotiation = true;
     this.nick = nick;
     this.user = user;
     this.irc_host = {hostname: hostname, port: port};
     this.ssl = !(!ssl);
     this.options = Object.create(null);
+    this.cap = {requested: [], enabled: []};
     
     this.password = pass;
     this.hold_last = false;
@@ -97,6 +99,7 @@ var connect_handler = function () {
         this.write('PASS ' + this.password);
     }
     
+    this.write('CAP LS');
     this.write('NICK ' + connect_data.nick);
     this.write('USER ' + connect_data.username + ' 0 0 :' + connect_data.realname);