From: Jack Allnutt Date: Thu, 1 Nov 2012 20:12:19 +0000 (+0000) Subject: Implement the capabilities negotiation and multi-prefix extensions X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=eec8c71e92bdacc02571c25747d48c9a059115cf;p=KiwiIRC.git Implement the capabilities negotiation and multi-prefix extensions Issues #107 and #108 --- diff --git a/server/irc/commands.js b/server/irc/commands.js index afeb4ed..a47cb19 100644 --- a/server/irc/commands.js +++ b/server/irc/commands.js @@ -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'; diff --git a/server/irc/connection.js b/server/irc/connection.js index c68637d..9a344ff 100644 --- a/server/irc/connection.js +++ b/server/irc/connection.js @@ -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);