aboutsummaryrefslogtreecommitdiff
path: root/modules/anticaps.cpp
diff options
context:
space:
mode:
authorGravatar Sadie Powell2024-09-30 17:12:11 +0100
committerGravatar Sadie Powell2024-09-30 17:15:12 +0100
commitd40740062154ae21d1ee0369ae07adafac1c91ea (patch)
tree51ba556a197b5911e0cf32707b861d8918e8e390 /modules/anticaps.cpp
parentFix some warnings when building with Clang. (diff)
parentImplement ldap_initialize on Windows using InternetCrackUrlA. (diff)
Merge branch 'insp4' into master.
Diffstat (limited to 'modules/anticaps.cpp')
-rw-r--r--modules/anticaps.cpp78
1 files changed, 50 insertions, 28 deletions
diff --git a/modules/anticaps.cpp b/modules/anticaps.cpp
index 29f42aa86..48f1d7b8b 100644
--- a/modules/anticaps.cpp
+++ b/modules/anticaps.cpp
@@ -36,8 +36,24 @@ enum class AntiCapsMethod
class AntiCapsSettings final
{
-private:
- bool ParseMethod(irc::sepstream& stream)
+public:
+ const AntiCapsMethod method;
+ const uint16_t minlen;
+ const uint8_t percent;
+
+ AntiCapsSettings(const AntiCapsMethod& m, uint16_t ml, uint8_t p)
+ : method(m)
+ , minlen(ml)
+ , percent(p)
+ {
+ }
+
+ static bool Parse(irc::sepstream& stream, AntiCapsMethod& method, uint16_t& minlen, uint8_t& percent)
+ {
+ return ParseMethod(stream, method) && ParseMinimumLength(stream, minlen) && ParsePercent(stream, percent);
+ }
+
+ static bool ParseMethod(irc::sepstream& stream, AntiCapsMethod& method)
{
std::string methodstr;
if (!stream.GetToken(methodstr))
@@ -59,7 +75,7 @@ private:
return true;
}
- bool ParseMinimumLength(irc::sepstream& stream)
+ static bool ParseMinimumLength(irc::sepstream& stream, uint16_t& minlen)
{
std::string minlenstr;
if (!stream.GetToken(minlenstr))
@@ -73,7 +89,7 @@ private:
return true;
}
- bool ParsePercent(irc::sepstream& stream)
+ static bool ParsePercent(irc::sepstream& stream, uint8_t& percent)
{
std::string percentstr;
if (!stream.GetToken(percentstr))
@@ -86,17 +102,6 @@ private:
percent = result;
return true;
}
-
-public:
- AntiCapsMethod method = AntiCapsMethod::BLOCK;
- uint16_t minlen = 0;
- uint8_t percent = 0;
-
- bool Parse(const std::string& str)
- {
- irc::sepstream stream(str, ':');
- return ParseMethod(stream) && ParseMinimumLength(stream) && ParsePercent(stream);
- }
};
class AntiCapsMode final
@@ -111,14 +116,19 @@ public:
bool OnSet(User* source, Channel* channel, std::string& parameter) override
{
- AntiCapsSettings settings;
- if (!settings.Parse(parameter))
+ irc::sepstream stream(parameter, ':');
+ AntiCapsMethod method;
+ uint16_t minlen;
+ uint8_t percent;
+
+ // Attempt to parse the settings.
+ if (!AntiCapsSettings::Parse(stream, method, minlen, percent))
{
source->WriteNumeric(Numerics::InvalidModeParameter(channel, this, parameter));
return false;
}
- ext.Set(channel, settings);
+ ext.SetFwd(channel, method, minlen, percent);
return true;
}
@@ -158,6 +168,7 @@ private:
CharState uppercase;
CharState lowercase;
AntiCapsMode mode;
+ std::string message;
void CreateBan(Channel* channel, User* user, bool mute)
{
@@ -171,9 +182,9 @@ private:
ServerInstance->Modes.Process(ServerInstance->FakeClient, channel, nullptr, changelist);
}
- static void InformUser(Channel* channel, User* user, const std::string& message)
+ static void InformUser(Channel* channel, User* user, const std::string& msg)
{
- user->WriteNumeric(Numerics::CannotSendTo(channel, message + " and was blocked."));
+ user->WriteNumeric(Numerics::CannotSendTo(channel, msg));
}
public:
@@ -196,6 +207,8 @@ public:
lowercase.reset();
for (const auto chr : tag->getString("lowercase", "abcdefghijklmnopqrstuvwxyz", 1))
lowercase.set(static_cast<unsigned char>(chr));
+
+ message = tag->getString("message", "Your message exceeded the %percent%%% upper case character threshold for %channel%", 1);
}
ModResult OnUserPreMessage(User* user, MessageTarget& target, MessageDetails& details) override
@@ -245,11 +258,14 @@ public:
// Count the characters to see how many upper case and
// ignored (non upper or lower) characters there are.
size_t upper = 0;
+ size_t lower = 0;
for (const auto chr : msgbody)
{
if (uppercase.test(static_cast<unsigned char>(chr)))
upper += 1;
- else if (!lowercase.test(static_cast<unsigned char>(chr)))
+ else if (lowercase.test(static_cast<unsigned char>(chr)))
+ lower += 1;
+ else
length -= 1;
}
@@ -263,32 +279,38 @@ public:
if (percent < config->percent)
return MOD_RES_PASSTHRU;
- const std::string message = FMT::format("Your message exceeded the {}% upper case character threshold for {}",
- config->percent, channel->name);
+ const auto msg = Template::Replace(message, {
+ { "channel", channel->name },
+ { "lower", ConvToStr(lower) },
+ { "minlen", ConvToStr(config->minlen) },
+ { "percent", ConvToStr<uint16_t>(config->percent) },
+ { "punctuation", ConvToStr(msgbody.length() - upper - lower) },
+ { "upper", ConvToStr(upper) },
+ });
switch (config->method)
{
case AntiCapsMethod::BAN:
- InformUser(channel, user, message);
+ InformUser(channel, user, msg);
CreateBan(channel, user, false);
break;
case AntiCapsMethod::BLOCK:
- InformUser(channel, user, message);
+ InformUser(channel, user, msg);
break;
case AntiCapsMethod::MUTE:
- InformUser(channel, user, message);
+ InformUser(channel, user, msg);
CreateBan(channel, user, true);
break;
case AntiCapsMethod::KICK:
- channel->KickUser(ServerInstance->FakeClient, user, message);
+ channel->KickUser(ServerInstance->FakeClient, user, msg);
break;
case AntiCapsMethod::KICK_BAN:
CreateBan(channel, user, false);
- channel->KickUser(ServerInstance->FakeClient, user, message);
+ channel->KickUser(ServerInstance->FakeClient, user, msg);
break;
}
return MOD_RES_DENY;