diff options
| -rw-r--r-- | bot/cogs/antispam.py | 8 | ||||
| -rw-r--r-- | bot/rules/newlines.py | 23 | ||||
| -rw-r--r-- | config-default.yml | 1 | 
3 files changed, 27 insertions, 5 deletions
| diff --git a/bot/cogs/antispam.py b/bot/cogs/antispam.py index 800700a50..0d1c7c1e9 100644 --- a/bot/cogs/antispam.py +++ b/bot/cogs/antispam.py @@ -97,13 +97,13 @@ class AntiSpam:                      # Fire it off as a background task to ensure                      # that the sleep doesn't block further tasks                      self.bot.loop.create_task( -                        self.punish(message, member, full_reason, relevant_messages) +                        self.punish(message, member, full_reason, relevant_messages, rule_name)                      )                  await self.maybe_delete_messages(message.channel, relevant_messages)                  break -    async def punish(self, msg: Message, member: Member, reason: str, messages: List[Message]): +    async def punish(self, msg: Message, member: Member, reason: str, messages: List[Message], rule_name: str):          # Sanity check to ensure we're not lagging behind          if self.muted_role not in member.roles:              remove_role_after = AntiSpamConfig.punishment['remove_after'] @@ -114,8 +114,8 @@ class AntiSpam:                  f"**Reason:** {reason}\n"              ) -            # For multiple messages, use the logs API -            if len(messages) > 1: +            # For multiple messages or those with excessive newlines, use the logs API +            if len(messages) > 1 or rule_name == 'newlines':                  url = await self.mod_log.upload_log(messages)                  mod_alert_message += f"A complete log of the offending messages can be found [here]({url})"              else: diff --git a/bot/rules/newlines.py b/bot/rules/newlines.py index a6a1a52d0..fdad6ffd3 100644 --- a/bot/rules/newlines.py +++ b/bot/rules/newlines.py @@ -1,5 +1,6 @@  """Detects total newlines exceeding the set limit sent by a single user.""" +import re  from typing import Dict, Iterable, List, Optional, Tuple  from discord import Member, Message @@ -17,12 +18,32 @@ async def apply(          if msg.author == last_message.author      ) -    total_recent_newlines = sum(msg.content.count('\n') for msg in relevant_messages) +    # Identify groups of newline characters and get group & total counts +    exp = r"(\n+)" +    newline_counts = [] +    for msg in relevant_messages: +        newline_counts += [len(group) for group in re.findall(exp, msg.content)] +    total_recent_newlines = sum(newline_counts) +    # Get maximum newline group size +    if newline_counts: +        max_newline_group = max(newline_counts) +    else: +        # If no newlines are found, newline_counts will be an empty list, which will error out max() +        max_newline_group = 0 + +    # Check first for total newlines, if this passes then check for large groupings      if total_recent_newlines > config['max']:          return (              f"sent {total_recent_newlines} newlines in {config['interval']}s",              (last_message.author,),              relevant_messages          ) +    elif max_newline_group > config['max_consecutive']: +        return ( +            f"sent {max_newline_group} consecutive newlines in {config['interval']}s", +            (last_message.author,), +            relevant_messages +        ) +      return None diff --git a/config-default.yml b/config-default.yml index d0df50605..3ce01916e 100644 --- a/config-default.yml +++ b/config-default.yml @@ -318,6 +318,7 @@ anti_spam:          newlines:              interval: 10              max: 100 +            max_consecutive: 10          role_mentions:              interval: 10 | 
