mirror of
https://github.com/inspircd/inspircd.git
synced 2025-03-10 02:59:01 -04:00
Allow hiding silenced users messages instead of blocking.
Implements part 1 of #1606.
This commit is contained in:
parent
68480cee67
commit
470805acf6
@ -156,7 +156,7 @@ the specified argument is a hex encoded IP address then respond with
|
|||||||
the equivalent raw IP address.
|
the equivalent raw IP address.
|
||||||
">
|
">
|
||||||
|
|
||||||
<helptopic key="silence" title="/SILENCE [(+|-)<mask> [CcdiNnPpTtx]]" value="
|
<helptopic key="silence" title="/SILENCE [(+|-)<mask> [CcdiHNnPpTtx]]" value="
|
||||||
A server-side ignore of the given n!u@h mask. If the optional flags field is
|
A server-side ignore of the given n!u@h mask. If the optional flags field is
|
||||||
specified then it must contain one or more flags which specify what kind of
|
specified then it must contain one or more flags which specify what kind of
|
||||||
messages should be blocked and how they should be blocked.
|
messages should be blocked and how they should be blocked.
|
||||||
@ -170,6 +170,7 @@ Valid SILENCE Flags
|
|||||||
C Matches a CTCP targeted at a user.
|
C Matches a CTCP targeted at a user.
|
||||||
c Matches a CTCP targeted at a channel.
|
c Matches a CTCP targeted at a channel.
|
||||||
d Default behaviour; equivalent to CciNnPpTt.
|
d Default behaviour; equivalent to CciNnPpTt.
|
||||||
|
H Hide the contents of messages instead of blocking.
|
||||||
i Matches an invite to a channel.
|
i Matches an invite to a channel.
|
||||||
N Matches a NOTICE targeted at a user.
|
N Matches a NOTICE targeted at a user.
|
||||||
n Matches a NOTICE targeted at a channel.
|
n Matches a NOTICE targeted at a channel.
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "inspircd.h"
|
#include "inspircd.h"
|
||||||
|
#include "clientprotocolmsg.h"
|
||||||
#include "modules/ctctags.h"
|
#include "modules/ctctags.h"
|
||||||
#include "modules/isupport.h"
|
#include "modules/isupport.h"
|
||||||
|
|
||||||
@ -46,7 +47,10 @@ public:
|
|||||||
// Exclude users who match this flags ("x").
|
// Exclude users who match this flags ("x").
|
||||||
SF_EXEMPT = 1,
|
SF_EXEMPT = 1,
|
||||||
|
|
||||||
// 2, 4, 8, 16 are reserved for future use.
|
// Hide the contents of the message when sent to the silencer ("H").
|
||||||
|
SF_HIDE_SILENCER = 2,
|
||||||
|
|
||||||
|
// 4, 8, 16 are reserved for future use.
|
||||||
|
|
||||||
// Matches a NOTICE targeted at a channel ("n").
|
// Matches a NOTICE targeted at a channel ("n").
|
||||||
SF_NOTICE_CHANNEL = 32,
|
SF_NOTICE_CHANNEL = 32,
|
||||||
@ -122,6 +126,9 @@ public:
|
|||||||
case 'd':
|
case 'd':
|
||||||
out |= SF_DEFAULT;
|
out |= SF_DEFAULT;
|
||||||
break;
|
break;
|
||||||
|
case 'H':
|
||||||
|
out |= SF_HIDE_SILENCER;
|
||||||
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
out |= SF_INVITE;
|
out |= SF_INVITE;
|
||||||
break;
|
break;
|
||||||
@ -164,6 +171,8 @@ public:
|
|||||||
out.push_back('C');
|
out.push_back('C');
|
||||||
if (flags & SF_CTCP_CHANNEL)
|
if (flags & SF_CTCP_CHANNEL)
|
||||||
out.push_back('c');
|
out.push_back('c');
|
||||||
|
if (flags & SF_HIDE_SILENCER)
|
||||||
|
out.push_back('H');
|
||||||
if (flags & SF_INVITE)
|
if (flags & SF_INVITE)
|
||||||
out.push_back('i');
|
out.push_back('i');
|
||||||
if (flags & SF_NOTICE_USER)
|
if (flags & SF_NOTICE_USER)
|
||||||
@ -411,17 +420,21 @@ private:
|
|||||||
bool exemptservice;
|
bool exemptservice;
|
||||||
CommandSilence cmd;
|
CommandSilence cmd;
|
||||||
|
|
||||||
ModResult BuildChannelExempts(User* source, Channel* channel, SilenceEntry::SilenceFlags flag, CUList& exemptions)
|
void BuildChannelExempts(User* source, Channel* channel, SilenceEntry::SilenceFlags flag, CUList& exemptions, CUList& hides)
|
||||||
{
|
{
|
||||||
for (const auto& [user, _] : channel->GetUsers())
|
for (const auto& [user, _] : channel->GetUsers())
|
||||||
{
|
{
|
||||||
if (!CanReceiveMessage(source, user, flag))
|
uint32_t flags;
|
||||||
|
if (!CanReceiveMessage(source, user, flag, &flags))
|
||||||
|
{
|
||||||
exemptions.insert(user);
|
exemptions.insert(user);
|
||||||
|
if (user != source && flags & SilenceEntry::SF_HIDE_SILENCER)
|
||||||
|
hides.insert(user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return MOD_RES_PASSTHRU;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanReceiveMessage(User* source, User* target, SilenceEntry::SilenceFlags flag)
|
bool CanReceiveMessage(User* source, User* target, SilenceEntry::SilenceFlags flag, uint32_t* flags = nullptr)
|
||||||
{
|
{
|
||||||
// Servers handle their own clients.
|
// Servers handle their own clients.
|
||||||
if (!IS_LOCAL(target))
|
if (!IS_LOCAL(target))
|
||||||
@ -440,12 +453,23 @@ private:
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (InspIRCd::Match(source->GetMask(), entry.mask))
|
if (InspIRCd::Match(source->GetMask(), entry.mask))
|
||||||
|
{
|
||||||
|
if (flags)
|
||||||
|
*flags = entry.flags;
|
||||||
|
|
||||||
return entry.flags & SilenceEntry::SF_EXEMPT;
|
return entry.flags & SilenceEntry::SF_EXEMPT;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HideMessage(std::string& message)
|
||||||
|
{
|
||||||
|
InspIRCd::StripColor(message);
|
||||||
|
message.insert(0, "\x1DSilenced\x1D: \00315,15");
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ModuleSilence()
|
ModuleSilence()
|
||||||
: Module(VF_VENDOR | VF_OPTCOMMON, "Adds the /SILENCE command which allows users to ignore other users on server-side.")
|
: Module(VF_VENDOR | VF_OPTCOMMON, "Adds the /SILENCE command which allows users to ignore other users on server-side.")
|
||||||
@ -490,7 +514,20 @@ public:
|
|||||||
else if (details.type == MessageType::PRIVMSG)
|
else if (details.type == MessageType::PRIVMSG)
|
||||||
flag = SilenceEntry::SF_PRIVMSG_CHANNEL;
|
flag = SilenceEntry::SF_PRIVMSG_CHANNEL;
|
||||||
|
|
||||||
return BuildChannelExempts(user, target.Get<Channel>(), flag, details.exemptions);
|
CUList hides;
|
||||||
|
BuildChannelExempts(user, target.Get<Channel>(), flag, details.exemptions, hides);
|
||||||
|
if (!hides.empty())
|
||||||
|
{
|
||||||
|
// In this mode we just strip formatting and hide the message.
|
||||||
|
std::string message = details.text;
|
||||||
|
HideMessage(message);
|
||||||
|
|
||||||
|
// Servers handle their own users so this cast will always work.
|
||||||
|
ClientProtocol::Messages::Privmsg msg(user, target.Get<Channel>(), message, details.type, target.status);
|
||||||
|
for (auto* hideuser : hides)
|
||||||
|
static_cast<LocalUser*>(hideuser)->Send(ServerInstance->GetRFCEvents().privmsg, msg);
|
||||||
|
}
|
||||||
|
return MOD_RES_PASSTHRU;
|
||||||
}
|
}
|
||||||
case MessageTarget::TYPE_USER:
|
case MessageTarget::TYPE_USER:
|
||||||
{
|
{
|
||||||
@ -501,9 +538,16 @@ public:
|
|||||||
else if (details.type == MessageType::PRIVMSG)
|
else if (details.type == MessageType::PRIVMSG)
|
||||||
flag = SilenceEntry::SF_PRIVMSG_USER;
|
flag = SilenceEntry::SF_PRIVMSG_USER;
|
||||||
|
|
||||||
if (!CanReceiveMessage(user, target.Get<User>(), flag))
|
uint32_t flags;
|
||||||
|
if (!CanReceiveMessage(user, target.Get<User>(), flag, &flags))
|
||||||
{
|
{
|
||||||
details.echo_original = true;
|
details.echo_original = true;
|
||||||
|
if (flags & SilenceEntry::SF_HIDE_SILENCER)
|
||||||
|
{
|
||||||
|
// In this mode we just strip formatting and hide the message.
|
||||||
|
HideMessage(details.text);
|
||||||
|
break;
|
||||||
|
}
|
||||||
return MOD_RES_DENY;
|
return MOD_RES_DENY;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -518,7 +562,11 @@ public:
|
|||||||
ModResult OnUserPreTagMessage(User* user, const MessageTarget& target, CTCTags::TagMessageDetails& details) override
|
ModResult OnUserPreTagMessage(User* user, const MessageTarget& target, CTCTags::TagMessageDetails& details) override
|
||||||
{
|
{
|
||||||
if (target.type == MessageTarget::TYPE_CHANNEL)
|
if (target.type == MessageTarget::TYPE_CHANNEL)
|
||||||
return BuildChannelExempts(user, target.Get<Channel>(), SilenceEntry::SF_TAGMSG_CHANNEL, details.exemptions);
|
{
|
||||||
|
CUList unused;
|
||||||
|
BuildChannelExempts(user, target.Get<Channel>(), SilenceEntry::SF_TAGMSG_CHANNEL, details.exemptions, unused);
|
||||||
|
return MOD_RES_PASSTHRU;
|
||||||
|
}
|
||||||
|
|
||||||
if (target.type == MessageTarget::TYPE_USER && !CanReceiveMessage(user, target.Get<User>(), SilenceEntry::SF_TAGMSG_USER))
|
if (target.type == MessageTarget::TYPE_USER && !CanReceiveMessage(user, target.Get<User>(), SilenceEntry::SF_TAGMSG_USER))
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user