]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_shun.cpp
Fix the cloaking module on C++98 compilers.
[user/henk/code/inspircd.git] / src / modules / m_shun.cpp
index a62d8369d29dad2a99807f4f73ac9a1e9aee0729..d63b721a0ebe5938c285cbcbbfcfacb948692e58 100644 (file)
@@ -4,18 +4,16 @@
  *   Copyright (C) 2019 Matt Schatz <genius3000@g3k.solutions>
  *   Copyright (C) 2018 linuxdaemon <linuxdaemon.irc@gmail.com>
  *   Copyright (C) 2017-2018 B00mX0r <b00mx0r@aureus.pw>
- *   Copyright (C) 2013, 2017-2018, 2020 Sadie Powell <sadie@witchery.services>
- *   Copyright (C) 2012-2016 Attila Molnar <attilamolnar@hush.com>
- *   Copyright (C) 2012, 2018-2019 Robby <robby@chatbelgie.be>
+ *   Copyright (C) 2013, 2017-2018, 2020-2021 Sadie Powell <sadie@witchery.services>
+ *   Copyright (C) 2012-2013, 2015-2016 Attila Molnar <attilamolnar@hush.com>
+ *   Copyright (C) 2012, 2019 Robby <robby@chatbelgie.be>
  *   Copyright (C) 2012 Jens Voss <DukePyrolator@anope.org>
  *   Copyright (C) 2009 Uli Schlachter <psychon@inspircd.org>
- *   Copyright (C) 2009 Matt Smith <dz@inspircd.org>
- *   Copyright (C) 2009 John Brooks <special@inspircd.org>
  *   Copyright (C) 2009 Dennis Friis <peavey@inspircd.org>
  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
  *   Copyright (C) 2008-2010 Craig Edwards <brain@inspircd.org>
- *   Copyright (C) 2008-2009 Robin Burchell <robin+git@viroteck.net>
  *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
+ *   Copyright (C) 2008 Robin Burchell <robin+git@viroteck.net>
  *
  * This file is part of InspIRCd.  InspIRCd is free software: you can
  * redistribute it and/or modify it under the terms of the GNU General Public
@@ -57,14 +55,13 @@ class ShunFactory : public XLineFactory
        }
 };
 
-//typedef std::vector<Shun> shunlist;
-
 class CommandShun : public Command
 {
  public:
        CommandShun(Module* Creator) : Command(Creator, "SHUN", 1, 3)
        {
-               flags_needed = 'o'; this->syntax = "<nick!user@host> [<duration> :<reason>]";
+               flags_needed = 'o';
+               syntax = "<nick!user@host> [<duration> :<reason>]";
        }
 
        CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE
@@ -152,14 +149,22 @@ class CommandShun : public Command
 
 class ModuleShun : public Module, public Stats::EventListener
 {
+ private:
        CommandShun cmd;
-       ShunFactory f;
-       insp::flat_set<std::string> ShunEnabledCommands;
-       bool NotifyOfShun;
+       ShunFactory shun;
+       insp::flat_set<std::string, irc::insensitive_swo> cleanedcommands;
+       insp::flat_set<std::string, irc::insensitive_swo> enabledcommands;
        bool affectopers;
+       bool allowconnect;
+       bool allowtags;
+       bool notifyuser;
 
        bool IsShunned(LocalUser* user)
        {
+               // Exempt the user if they are not fully connected and allowconnect is enabled.
+               if (allowconnect && user->registered != REG_ALL)
+                       return false;
+
                // Exempt the user from shuns if they are an oper and affectopers is disabled.
                if (!affectopers && user->IsOper())
                        return false;
@@ -181,13 +186,13 @@ class ModuleShun : public Module, public Stats::EventListener
 
        void init() CXX11_OVERRIDE
        {
-               ServerInstance->XLines->RegisterFactory(&f);
+               ServerInstance->XLines->RegisterFactory(&shun);
        }
 
        ~ModuleShun()
        {
                ServerInstance->XLines->DelAll("SHUN");
-               ServerInstance->XLines->UnregisterFactory(&f);
+               ServerInstance->XLines->UnregisterFactory(&shun);
        }
 
        void Prioritize() CXX11_OVERRIDE
@@ -209,16 +214,20 @@ class ModuleShun : public Module, public Stats::EventListener
        {
                ConfigTag* tag = ServerInstance->Config->ConfValue("shun");
 
-               ShunEnabledCommands.clear();
+               cleanedcommands.clear();
+               irc::spacesepstream cleanedcmds(tag->getString("cleanedcommands", "AWAY PART QUIT"));
+               for (std::string cleanedcmd; cleanedcmds.GetToken(cleanedcmd); )
+                       cleanedcommands.insert(cleanedcmd);
+
+               enabledcommands.clear();
                irc::spacesepstream enabledcmds(tag->getString("enabledcommands", "ADMIN OPER PING PONG QUIT", 1));
                for (std::string enabledcmd; enabledcmds.GetToken(enabledcmd); )
-               {
-                       std::transform(enabledcmd.begin(), enabledcmd.end(), enabledcmd.begin(), ::toupper);
-                       ShunEnabledCommands.insert(enabledcmd);
-               }
+                       enabledcommands.insert(enabledcmd);
 
-               NotifyOfShun = tag->getBool("notifyuser", true);
                affectopers = tag->getBool("affectopers", false);
+               allowtags = tag->getBool("allowtags");
+               allowconnect = tag->getBool("allowconnect");
+               notifyuser = tag->getBool("notifyuser", true);
        }
 
        ModResult OnPreCommand(std::string& command, CommandBase::Params& parameters, LocalUser* user, bool validated) CXX11_OVERRIDE
@@ -226,25 +235,45 @@ class ModuleShun : public Module, public Stats::EventListener
                if (validated || !IsShunned(user))
                        return MOD_RES_PASSTHRU;
 
-               if (!ShunEnabledCommands.count(command))
+               if (!enabledcommands.count(command))
                {
-                       if (NotifyOfShun)
-                               user->WriteNotice("*** Command " + command + " not processed, as you have been blocked from issuing commands (SHUN)");
+                       if (notifyuser)
+                               user->WriteNotice("*** " + command + " command not processed as you have been blocked from issuing commands.");
                        return MOD_RES_DENY;
                }
 
-               if (command == "QUIT")
+               if (!allowtags)
                {
-                       /* Allow QUIT but dont show any quit message */
-                       parameters.clear();
+                       // Remove all client tags.
+                       ClientProtocol::TagMap& tags = parameters.GetTags();
+                       for (ClientProtocol::TagMap::iterator tag = tags.begin(); tag != tags.end(); )
+                       {
+                               if (tag->first[0] == '+')
+                                       tag = tags.erase(tag);
+                               else
+                                       tag++;
+                       }
                }
-               else if ((command == "PART") && (parameters.size() > 1))
+
+               if (cleanedcommands.count(command))
                {
-                       /* same for PART */
-                       parameters.pop_back();
+                       if (command == "AWAY" && !parameters.empty())
+                       {
+                               // Allow away but only for unsetting.
+                               parameters.clear();
+                       }
+                       else if (command == "PART" && parameters.size() > 1)
+                       {
+                               // Allow part but strip the message.
+                               parameters.pop_back();
+                       }
+                       else if (command == "QUIT" && !parameters.empty())
+                       {
+                               // Allow quit but strip the message.
+                               parameters.clear();
+                       }
                }
 
-               /* if we're here, allow the command. */
                return MOD_RES_PASSTHRU;
        }