]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_silence.cpp
Fix the cloaking module on C++98 compilers.
[user/henk/code/inspircd.git] / src / modules / m_silence.cpp
index 36d024ba52b0be7d22dbc93bdafb4f5cf6fd25d1..e7271e68fc71262339f85a6990515ca4adeef618 100644 (file)
@@ -1,7 +1,10 @@
 /*
  * InspIRCd -- Internet Relay Chat Daemon
  *
- *   Copyright (C) 2019 Peter Powell <petpow@saberuk.com>
+ *   Copyright (C) 2019 linuxdaemon <linuxdaemon.irc@gmail.com>
+ *   Copyright (C) 2019 iwalkalone <iwalkalone69@gmail.com>
+ *   Copyright (C) 2019 Sadie Powell <sadie@witchery.services>
+ *   Copyright (C) 2019 Robby <robby@chatbelgie.be>
  *
  * 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
@@ -41,7 +44,7 @@ class SilenceEntry
 
                // Exclude users who match this flags ("x").
                SF_EXEMPT = 1,
-       
+
                // 2, 4, 8, 16 are reserved for future use.
 
                // Matches a NOTICE targeted at a channel ("n").
@@ -180,6 +183,84 @@ class SilenceEntry
 
 typedef insp::flat_set<SilenceEntry> SilenceList;
 
+class SilenceExtItem : public SimpleExtItem<SilenceList>
+{
+ public:
+       unsigned int maxsilence;
+
+       SilenceExtItem(Module* Creator)
+               : SimpleExtItem<SilenceList>("silence_list", ExtensionItem::EXT_USER, Creator)
+       {
+       }
+
+       void FromInternal(Extensible* container, const std::string& value) CXX11_OVERRIDE
+       {
+               LocalUser* user = IS_LOCAL(static_cast<User*>(container));
+               if (!user)
+                       return;
+
+               // Remove the old list and create a new one.
+               unset(user);
+               SilenceList* list = new SilenceList();
+
+               irc::spacesepstream ts(value);
+               while (!ts.StreamEnd())
+               {
+                       // Check we have space for another entry.
+                       if (list->size() >= maxsilence)
+                       {
+                               ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Oversized silence list received for %s: %s",
+                                       user->uuid.c_str(), value.c_str());
+                               delete list;
+                               return;
+                       }
+
+                       // Extract the mask and the flags.
+                       std::string mask;
+                       std::string flagstr;
+                       if (!ts.GetToken(mask) || !ts.GetToken(flagstr))
+                       {
+                               ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Malformed silence list received for %s: %s",
+                                       user->uuid.c_str(), value.c_str());
+                               delete list;
+                               return;
+                       }
+
+                       // Try to parse the flags.
+                       uint32_t flags;
+                       if (!SilenceEntry::FlagsToBits(flagstr, flags))
+                       {
+                               ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Malformed silence flags received for %s: %s",
+                                       user->uuid.c_str(), flagstr.c_str());
+                               delete list;
+                               return;
+                       }
+
+                       // Store the silence entry.
+                       list->insert(SilenceEntry(flags, mask));
+               }
+
+               // The value was well formed.
+               set(user, list);
+       }
+
+       std::string ToInternal(const Extensible* container, void* item) const CXX11_OVERRIDE
+       {
+               SilenceList* list = static_cast<SilenceList*>(item);
+               std::string buf;
+               for (SilenceList::const_iterator iter = list->begin(); iter != list->end(); ++iter)
+               {
+                       if (iter != list->begin())
+                               buf.push_back(' ');
+
+                       buf.append(iter->mask);
+                       buf.push_back(' ');
+                       buf.append(SilenceEntry::BitsToFlags(iter->flags));
+               }
+               return buf;
+       }
+};
+
 class SilenceMessage : public ClientProtocol::Message
 {
  public:
@@ -187,7 +268,7 @@ class SilenceMessage : public ClientProtocol::Message
                : ClientProtocol::Message("SILENCE")
        {
                PushParam(mask);
-               PushParamRef(flags);
+               PushParam(flags);
        }
 };
 
@@ -199,9 +280,9 @@ class CommandSilence : public SplitCommand
        CmdResult AddSilence(LocalUser* user, const std::string& mask, uint32_t flags)
        {
                SilenceList* list = ext.get(user);
-               if (list && list->size() > maxsilence)
+               if (list && list->size() > ext.maxsilence)
                {
-                       user->WriteNumeric(ERR_SILELISTFULL, mask, SilenceEntry::BitsToFlags(flags), "Your silence list is full");
+                       user->WriteNumeric(ERR_SILELISTFULL, mask, SilenceEntry::BitsToFlags(flags), "Your SILENCE list is full");
                        return CMD_FAILURE;
                }
                else if (!list)
@@ -213,7 +294,7 @@ class CommandSilence : public SplitCommand
 
                if (!list->insert(SilenceEntry(flags, mask)).second)
                {
-                       user->WriteNumeric(ERR_SILENCE, mask, SilenceEntry::BitsToFlags(flags), "The silence entry you specified already exists");
+                       user->WriteNumeric(ERR_SILENCE, mask, SilenceEntry::BitsToFlags(flags), "The SILENCE entry you specified already exists");
                        return CMD_FAILURE;
                }
 
@@ -239,7 +320,7 @@ class CommandSilence : public SplitCommand
                        }
                }
 
-               user->WriteNumeric(ERR_SILENCE, mask, SilenceEntry::BitsToFlags(flags), "The silence entry you specified could not be found");
+               user->WriteNumeric(ERR_SILENCE, mask, SilenceEntry::BitsToFlags(flags), "The SILENCE entry you specified could not be found");
                return CMD_FAILURE;
        }
 
@@ -253,18 +334,17 @@ class CommandSilence : public SplitCommand
                                user->WriteNumeric(RPL_SILELIST, iter->mask, SilenceEntry::BitsToFlags(iter->flags));
                        }
                }
-               user->WriteNumeric(RPL_ENDOFSILELIST, "End of silence list");
+               user->WriteNumeric(RPL_ENDOFSILELIST, "End of SILENCE list");
                return CMD_SUCCESS;
        }
 
  public:
-       SimpleExtItem<SilenceList> ext;
-       unsigned int maxsilence;
+       SilenceExtItem ext;
 
        CommandSilence(Module* Creator)
                : SplitCommand(Creator, "SILENCE")
                , msgprov(Creator, "SILENCE")
-               , ext("silence_list", ExtensionItem::EXT_USER, Creator)
+               , ext(Creator)
        {
                allow_empty_last_param = false;
                syntax = "[(+|-)<mask> [CcdiNnPpTtx]]";
@@ -282,7 +362,7 @@ class CommandSilence : public SplitCommand
                std::string mask = parameters[0];
                if (mask[0] == '-' || mask[0] == '+')
                {
-                       mask.erase(0);
+                       mask.erase(0, 1);
                        if (mask.empty())
                                mask.assign("*");
                        ModeParser::CleanMask(mask);
@@ -364,13 +444,13 @@ class ModuleSilence
        {
                ConfigTag* tag = ServerInstance->Config->ConfValue("silence");
                exemptuline = tag->getBool("exemptuline", true);
-               cmd.maxsilence = tag->getUInt("maxentries", 32, 1);
+               cmd.ext.maxsilence = tag->getUInt("maxentries", 32, 1);
        }
 
        void On005Numeric(std::map<std::string, std::string>& tokens) CXX11_OVERRIDE
        {
-               tokens["ESILENCE"] = "CcdiNnPpsTtx";
-               tokens["SILENCE"] = ConvToStr(cmd.maxsilence);
+               tokens["ESILENCE"] = "CcdiNnPpTtx";
+               tokens["SILENCE"] = ConvToStr(cmd.ext.maxsilence);
        }
 
        ModResult OnUserPreInvite(User* source, User* dest, Channel* channel, time_t timeout) CXX11_OVERRIDE
@@ -384,32 +464,37 @@ class ModuleSilence
                bool is_ctcp = details.IsCTCP(ctcpname) && !irc::equals(ctcpname, "ACTION");
 
                SilenceEntry::SilenceFlags flag = SilenceEntry::SF_NONE;
-               if (target.type == MessageTarget::TYPE_CHANNEL)
+               switch (target.type)
                {
-                       if (is_ctcp)
-                               flag = SilenceEntry::SF_CTCP_CHANNEL;
-                       else if (details.type == MSG_NOTICE)
-                               flag = SilenceEntry::SF_NOTICE_CHANNEL;
-                       else if (details.type == MSG_PRIVMSG)
-                               flag = SilenceEntry::SF_PRIVMSG_CHANNEL;
-
-                       return BuildChannelExempts(user, target.Get<Channel>(), flag, details.exemptions);
-               }
-
-               if (target.type == MessageTarget::TYPE_USER)
-               {
-                       if (is_ctcp)
-                               flag = SilenceEntry::SF_CTCP_USER;
-                       else if (details.type == MSG_NOTICE)
-                               flag = SilenceEntry::SF_NOTICE_USER;
-                       else if (details.type == MSG_PRIVMSG)
-                               flag = SilenceEntry::SF_PRIVMSG_USER;
-
-                       if (!CanReceiveMessage(user, target.Get<User>(), flag))
+                       case MessageTarget::TYPE_CHANNEL:
+                       {
+                               if (is_ctcp)
+                                       flag = SilenceEntry::SF_CTCP_CHANNEL;
+                               else if (details.type == MSG_NOTICE)
+                                       flag = SilenceEntry::SF_NOTICE_CHANNEL;
+                               else if (details.type == MSG_PRIVMSG)
+                                       flag = SilenceEntry::SF_PRIVMSG_CHANNEL;
+
+                               return BuildChannelExempts(user, target.Get<Channel>(), flag, details.exemptions);
+                       }
+                       case MessageTarget::TYPE_USER:
                        {
-                               details.echo_original = true;
-                               return MOD_RES_DENY;
+                               if (is_ctcp)
+                                       flag = SilenceEntry::SF_CTCP_USER;
+                               else if (details.type == MSG_NOTICE)
+                                       flag = SilenceEntry::SF_NOTICE_USER;
+                               else if (details.type == MSG_PRIVMSG)
+                                       flag = SilenceEntry::SF_PRIVMSG_USER;
+
+                               if (!CanReceiveMessage(user, target.Get<User>(), flag))
+                               {
+                                       details.echo_original = true;
+                                       return MOD_RES_DENY;
+                               }
+                               break;
                        }
+                       case MessageTarget::TYPE_SERVER:
+                               break;
                }
 
                return MOD_RES_PASSTHRU;
@@ -431,7 +516,7 @@ class ModuleSilence
 
        Version GetVersion() CXX11_OVERRIDE
        {
-               return Version("Provides support for blocking users with the /SILENCE command", VF_OPTCOMMON | VF_VENDOR);
+               return Version("Adds the /SILENCE command which allows users to ignore other users on server-side.", VF_OPTCOMMON | VF_VENDOR);
        }
 };