X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_silence.cpp;h=e7271e68fc71262339f85a6990515ca4adeef618;hb=HEAD;hp=3b32097eabb7da9419977609f42011e3bac30409;hpb=e57d1b19ff4823b7885eb7f4d3b37c84d2edca0e;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_silence.cpp b/src/modules/m_silence.cpp index 3b32097ea..e7271e68f 100644 --- a/src/modules/m_silence.cpp +++ b/src/modules/m_silence.cpp @@ -1,7 +1,10 @@ /* * InspIRCd -- Internet Relay Chat Daemon * - * Copyright (C) 2019 Peter Powell + * Copyright (C) 2019 linuxdaemon + * Copyright (C) 2019 iwalkalone + * Copyright (C) 2019 Sadie Powell + * Copyright (C) 2019 Robby * * 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 @@ -180,6 +183,84 @@ class SilenceEntry typedef insp::flat_set SilenceList; +class SilenceExtItem : public SimpleExtItem +{ + public: + unsigned int maxsilence; + + SilenceExtItem(Module* Creator) + : SimpleExtItem("silence_list", ExtensionItem::EXT_USER, Creator) + { + } + + void FromInternal(Extensible* container, const std::string& value) CXX11_OVERRIDE + { + LocalUser* user = IS_LOCAL(static_cast(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(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 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 = "[(+|-) [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& tokens) CXX11_OVERRIDE { tokens["ESILENCE"] = "CcdiNnPpTtx"; - tokens["SILENCE"] = ConvToStr(cmd.maxsilence); + 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(), 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(), 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(), 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(), 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); } };