From 796af0531e0f5eb5fa2b800370338ede120a867d Mon Sep 17 00:00:00 2001
From: Florent Le Coz <louiz@louiz.org>
Date: Tue, 27 May 2014 02:17:25 +0200
Subject: Add support for CHANTYPES isupport element, to know the prefixes of
 channels

---
 src/irc/irc_client.cpp | 15 ++++++++++++---
 src/irc/irc_client.hpp |  6 ++++++
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp
index cea08f2..03402e7 100644
--- a/src/irc/irc_client.cpp
+++ b/src/irc/irc_client.cpp
@@ -20,7 +20,8 @@ IrcClient::IrcClient(std::shared_ptr<Poller> poller, const std::string& hostname
   current_nick(username),
   bridge(bridge),
   welcomed(false),
-  chanmodes({"", "", "", ""})
+  chanmodes({"", "", "", ""}),
+  chantypes({'#', '&'})
 {
   this->dummy_channel.topic = "This is a virtual channel provided for "
                               "convenience by biboumi, it is not connected "
@@ -279,6 +280,15 @@ void IrcClient::on_isupport_message(const IrcMessage& message)
             this->prefix_to_mode[token[j++]] = token[i++];
           }
       }
+    else if (token.substr(0, 10) == "CHANTYPES=")
+      {
+        // Remove the default types, they apply only if no other value is
+        // specified.
+        this->chantypes.clear();
+        size_t i = 11;
+        while (i < token.size())
+          this->chantypes.insert(token[i++]);
+      }
   }
 }
 
@@ -564,8 +574,7 @@ void IrcClient::on_kick(const IrcMessage& message)
 void IrcClient::on_mode(const IrcMessage& message)
 {
   const std::string target = message.arguments[0];
-  if (target[0] == '&' || target[0] == '#' ||
-      target[0] == '!' || target[0] == '+')
+  if (this->chantypes.find(target[0]) != this->chantypes.end())
     this->on_channel_mode(message);
   else
     this->on_user_mode(message);
diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp
index e70ee33..e6fb393 100644
--- a/src/irc/irc_client.hpp
+++ b/src/irc/irc_client.hpp
@@ -12,6 +12,7 @@
 #include <vector>
 #include <string>
 #include <map>
+#include <set>
 
 class Bridge;
 
@@ -257,6 +258,11 @@ private:
    * chanmodes[0] contains modes of type A, [1] of type B etc
    */
   std::vector<std::string> chanmodes;
+  /**
+   * See http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt
+   * section 3.5
+   */
+  std::set<char> chantypes;
   /**
    * Each motd line received is appended to this string, which we send when
    * the motd is completely received
-- 
cgit v1.2.3