]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_namedmodes.cpp
Add support for blocking tag messages with the deaf mode.
[user/henk/code/inspircd.git] / src / modules / m_namedmodes.cpp
index 4004db00e93d488301a58b30088ab897a4a4c2ad..f25cc219ca18a455bbea93f0ba1dbdcd8a6f9947 100644 (file)
@@ -1,6 +1,11 @@
 /*
  * InspIRCd -- Internet Relay Chat Daemon
  *
+ *   Copyright (C) 2017 B00mX0r <b00mx0r@aureus.pw>
+ *   Copyright (C) 2013-2016 Attila Molnar <attilamolnar@hush.com>
+ *   Copyright (C) 2013, 2017-2019 Sadie Powell <sadie@witchery.services>
+ *   Copyright (C) 2012, 2019 Robby <robby@chatbelgie.be>
+ *   Copyright (C) 2010 Craig Edwards <brain@inspircd.org>
  *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
  *
  * This file is part of InspIRCd.  InspIRCd is free software: you can
 
 #include "inspircd.h"
 
-static void DisplayList(User* user, Channel* channel)
+enum
 {
-       std::stringstream items;
+       // InspIRCd-specific.
+       RPL_ENDOFPROPLIST = 960,
+       RPL_PROPLIST = 961
+};
+
+static void DisplayList(LocalUser* user, Channel* channel)
+{
+       Numeric::ParamBuilder<1> numeric(user, RPL_PROPLIST);
+       numeric.AddStatic(channel->name);
+
        const ModeParser::ModeHandlerMap& mhs = ServerInstance->Modes->GetModes(MODETYPE_CHANNEL);
        for (ModeParser::ModeHandlerMap::const_iterator i = mhs.begin(); i != mhs.end(); ++i)
        {
                ModeHandler* mh = i->second;
                if (!channel->IsModeSet(mh))
                        continue;
-               items << " +" << mh->name;
-               if (mh->GetNumParams(true))
-                       items << " " << channel->GetModeParameter(mh);
+               numeric.Add("+" + mh->name);
+               ParamModeBase* pm = mh->IsParameterMode();
+               if (pm)
+               {
+                       if ((pm->IsParameterSecret()) && (!channel->HasUser(user)) && (!user->HasPrivPermission("channels/auspex")))
+                               numeric.Add("<" + mh->name + ">");
+                       else
+                               numeric.Add(channel->GetModeParameter(mh));
+               }
        }
-       const std::string line = ":" + ServerInstance->Config->ServerName + " 961 " + user->nick + " " + channel->name;
-       user->SendText(line, items);
-       user->WriteNumeric(960, "%s :End of mode list", channel->name.c_str());
+       numeric.Flush();
+       user->WriteNumeric(RPL_ENDOFPROPLIST, channel->name, "End of mode list");
 }
 
-class CommandProp : public Command
+class CommandProp : public SplitCommand
 {
  public:
-       CommandProp(Module* parent) : Command(parent, "PROP", 1)
+       CommandProp(Module* parent)
+               : SplitCommand(parent, "PROP", 1)
        {
-               syntax = "<user|channel> {[+-]<mode> [<value>]}*";
+               syntax = "<channel> [[(+|-)]<mode> [<value>]]";
        }
 
-       CmdResult Handle(const std::vector<std::string> &parameters, User *src)
+       CmdResult HandleLocal(LocalUser* src, const Params& parameters) CXX11_OVERRIDE
        {
+               Channel* const chan = ServerInstance->FindChan(parameters[0]);
+               if (!chan)
+               {
+                       src->WriteNumeric(Numerics::NoSuchChannel(parameters[0]));
+                       return CMD_FAILURE;
+               }
+
                if (parameters.size() == 1)
                {
-                       Channel* chan = ServerInstance->FindChan(parameters[0]);
-                       if (chan)
-                               DisplayList(src, chan);
+                       DisplayList(src, chan);
                        return CMD_SUCCESS;
                }
                unsigned int i = 1;
-               std::vector<std::string> modes;
-               modes.push_back(parameters[0]);
-               modes.push_back("");
+               Modes::ChangeList modes;
                while (i < parameters.size())
                {
                        std::string prop = parameters[i++];
+                       if (prop.empty())
+                               continue;
                        bool plus = prop[0] != '-';
                        if (prop[0] == '+' || prop[0] == '-')
                                prop.erase(prop.begin());
@@ -68,16 +93,16 @@ class CommandProp : public Command
                        ModeHandler* mh = ServerInstance->Modes->FindMode(prop, MODETYPE_CHANNEL);
                        if (mh)
                        {
-                               modes[1].push_back(plus ? '+' : '-');
-                               modes[1].push_back(mh->GetModeChar());
-                               if (mh->GetNumParams(plus))
+                               if (mh->NeedsParam(plus))
                                {
                                        if (i != parameters.size())
-                                               modes.push_back(parameters[i++]);
+                                               modes.push(mh, plus, parameters[i++]);
                                }
+                               else
+                                       modes.push(mh, plus);
                        }
                }
-               ServerInstance->Modes->Process(modes, src);
+               ServerInstance->Modes->ProcessSingle(src, chan, NULL, modes, ModeParser::MODE_CHECKACCESS);
                return CMD_SUCCESS;
        }
 };
@@ -91,9 +116,11 @@ class DummyZ : public ModeHandler
        }
 
        // Handle /MODE #chan Z
-       void DisplayList(User* user, Channel* chan)
+       void DisplayList(User* user, Channel* chan) CXX11_OVERRIDE
        {
-               ::DisplayList(user, chan);
+               LocalUser* luser = IS_LOCAL(user);
+               if (luser)
+                       ::DisplayList(luser, chan);
        }
 };
 
@@ -108,10 +135,10 @@ class ModuleNamedModes : public Module
 
        Version GetVersion() CXX11_OVERRIDE
        {
-               return Version("Provides the ability to manipulate modes via long names.",VF_VENDOR);
+               return Version("Provides support for adding and removing modes via their long names.", VF_VENDOR);
        }
 
-       void Prioritize()
+       void Prioritize() CXX11_OVERRIDE
        {
                ServerInstance->Modules->SetPriority(this, I_OnPreMode, PRIORITY_FIRST);
        }
@@ -135,8 +162,8 @@ class ModuleNamedModes : public Module
                                std::string::size_type eq = name.find('=');
                                if (eq != std::string::npos)
                                {
-                                       value = name.substr(eq + 1);
-                                       name = name.substr(0, eq);
+                                       value.assign(name, eq + 1, std::string::npos);
+                                       name.erase(eq);
                                }
 
                                ModeHandler* mh = ServerInstance->Modes->FindMode(name, MODETYPE_CHANNEL);
@@ -148,7 +175,7 @@ class ModuleNamedModes : public Module
                                }
 
                                curr.param.clear();
-                               if (mh->GetNumParams(curr.adding))
+                               if (mh->NeedsParam(curr.adding))
                                {
                                        if (value.empty())
                                        {