]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_cap.cpp
Update the cloaks of connected users when their IP address changes.
[user/henk/code/inspircd.git] / src / modules / m_cap.cpp
index 868294fe4d6fb436a2a3189231e7bfc70bae026f..922061757306b878c418dc3c23a322fd48c5c9be 100644 (file)
 #include "modules/reload.h"
 #include "modules/cap.h"
 
+enum
+{
+       // From IRCv3 capability-negotiation-3.1.
+       ERR_INVALIDCAPCMD = 410
+};
+
 namespace Cap
 {
        class ManagerImpl;
@@ -335,16 +341,35 @@ void Cap::ExtItem::unserialize(SerializeFormat format, Extensible* container, co
        managerimpl->HandleReq(user, caplist);
 }
 
+class CapMessage : public Cap::MessageBase
+{
+ public:
+       CapMessage(LocalUser* user, const std::string& subcmd, const std::string& result)
+               : Cap::MessageBase(subcmd)
+       {
+               SetUser(user);
+               PushParamRef(result);
+       }
+};
+
 class CommandCap : public SplitCommand
 {
        Events::ModuleEventProvider evprov;
        Cap::ManagerImpl manager;
+       ClientProtocol::EventProvider protoevprov;
 
-       static void DisplayResult(LocalUser* user, std::string& result)
+       void DisplayResult(LocalUser* user, const std::string& subcmd, std::string& result)
        {
                if (*result.rbegin() == ' ')
                        result.erase(result.end()-1);
-               user->WriteCommand("CAP", result);
+               DisplayResult2(user, subcmd, result);
+       }
+
+       void DisplayResult2(LocalUser* user, const std::string& subcmd, const std::string& result)
+       {
+               CapMessage msg(user, subcmd, result);
+               ClientProtocol::Event ev(protoevprov, msg);
+               user->Send(ev);
        }
 
  public:
@@ -354,12 +379,13 @@ class CommandCap : public SplitCommand
                : SplitCommand(mod, "CAP", 1)
                , evprov(mod, "event/cap")
                , manager(mod, evprov)
+               , protoevprov(mod, name)
                , holdext("cap_hold", ExtensionItem::EXT_USER, mod)
        {
                works_before_reg = true;
        }
 
-       CmdResult HandleLocal(const std::vector<std::string>& parameters, LocalUser* user) CXX11_OVERRIDE
+       CmdResult HandleLocal(LocalUser* user, const Params& parameters) CXX11_OVERRIDE
        {
                if (user->registered != REG_ALL)
                        holdext.set(user, 1);
@@ -372,9 +398,8 @@ class CommandCap : public SplitCommand
                        if (parameters.size() < 2)
                                return CMD_FAILURE;
 
-                       std::string result = (manager.HandleReq(user, parameters[1]) ? "ACK :" : "NAK :");
-                       result.append(parameters[1]);
-                       user->WriteCommand("CAP", result);
+                       const std::string replysubcmd = (manager.HandleReq(user, parameters[1]) ? "ACK" : "NAK");
+                       DisplayResult2(user, replysubcmd, parameters[1]);
                }
                else if (subcommand == "END")
                {
@@ -386,20 +411,20 @@ class CommandCap : public SplitCommand
                        if ((is_ls) && (parameters.size() > 1) && (parameters[1] == "302"))
                                manager.Set302Protocol(user);
 
-                       std::string result = subcommand + " :";
+                       std::string result;
                        // Show values only if supports v3.2 and doing LS
                        manager.HandleList(result, user, is_ls, ((is_ls) && (manager.GetProtocol(user) != Cap::CAP_LEGACY)));
-                       DisplayResult(user, result);
+                       DisplayResult(user, subcommand, result);
                }
                else if ((subcommand == "CLEAR") && (manager.GetProtocol(user) == Cap::CAP_LEGACY))
                {
-                       std::string result = "ACK :";
+                       std::string result;
                        manager.HandleClear(user, result);
-                       DisplayResult(user, result);
+                       DisplayResult(user, "ACK", result);
                }
                else
                {
-                       user->WriteNumeric(ERR_INVALIDCAPSUBCOMMAND, subcommand, "Invalid CAP subcommand");
+                       user->WriteNumeric(ERR_INVALIDCAPCMD, subcommand.empty() ? "*" : subcommand, "Invalid CAP subcommand");
                        return CMD_FAILURE;
                }