From e49a832b1bcdc2d932a452caad2109056949fb0b Mon Sep 17 00:00:00 2001 From: brad90four <42116429+brad90four@users.noreply.github.com> Date: Wed, 1 Apr 2026 10:32:31 -0400 Subject: [PATCH 1/5] Multi rule spam handling --- bot/exts/levels/_cog.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bot/exts/levels/_cog.py b/bot/exts/levels/_cog.py index abdd3b1..7a0d4e1 100644 --- a/bot/exts/levels/_cog.py +++ b/bot/exts/levels/_cog.py @@ -223,6 +223,10 @@ async def on_message(self, msg: discord.Message) -> None: if rule_matches != 0: user_id = msg.author.id await self._update_points(user_id, total_points) + elif rule_matches >= 3: + user_id = msg.author.id + total_points -= 5 + await self._update_points(user_id, total_points) @commands.Cog.listener() From e3d410b9e491fe926015422afed4afaf2147ff6a Mon Sep 17 00:00:00 2001 From: brad90four <42116429+brad90four@users.noreply.github.com> Date: Wed, 1 Apr 2026 10:35:57 -0400 Subject: [PATCH 2/5] monty_python rules --- bot/exts/levels/rules/monty_python.toml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/bot/exts/levels/rules/monty_python.toml b/bot/exts/levels/rules/monty_python.toml index 721fb4b..ec74112 100644 --- a/bot/exts/levels/rules/monty_python.toml +++ b/bot/exts/levels/rules/monty_python.toml @@ -17,3 +17,13 @@ points = 3 interaction_type = "message" message_content = '''\b(IDLE|Idle|Cleese|Gilliam|Jones|Chapman|Palin)\b''' points = 1 + +[[rule]] +interaction_type = "message" +message_content = '''\b(\'[Tt]is but a scratch)\b''' +points = 1 + +[[rule]] +interaction_type = "message" +message_content = '''\b([Ff]light [Ss]peed|[Uu]nladen [Ss]wallow|[Aa]frican or [Ee]uropean)\b''' +points = 2 From 4185d4965acbdb494db547f914f65985e73a8bc4 Mon Sep 17 00:00:00 2001 From: brad90four <42116429+brad90four@users.noreply.github.com> Date: Wed, 1 Apr 2026 10:47:17 -0400 Subject: [PATCH 3/5] Discourage spam behavior --- bot/exts/levels/_cog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/levels/_cog.py b/bot/exts/levels/_cog.py index 7a0d4e1..3520223 100644 --- a/bot/exts/levels/_cog.py +++ b/bot/exts/levels/_cog.py @@ -225,7 +225,7 @@ async def on_message(self, msg: discord.Message) -> None: await self._update_points(user_id, total_points) elif rule_matches >= 3: user_id = msg.author.id - total_points -= 5 + total_points = -5 await self._update_points(user_id, total_points) From accd0699d9a29c1891fca78c537ee2072c9e3aa1 Mon Sep 17 00:00:00 2001 From: brad90four <42116429+brad90four@users.noreply.github.com> Date: Wed, 1 Apr 2026 13:34:03 -0400 Subject: [PATCH 4/5] Correct anti-spam and remove existing role --- bot/exts/levels/_cog.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/bot/exts/levels/_cog.py b/bot/exts/levels/_cog.py index 3520223..a1ba81e 100644 --- a/bot/exts/levels/_cog.py +++ b/bot/exts/levels/_cog.py @@ -132,6 +132,10 @@ async def _cycle_rules_task(self) -> None: rule_trigger for rule in self.rules_active for rule_trigger in rule.rule_triggers if rule_trigger.interaction_type=="reaction" ] + self.all_message_rule_triggers = [ + rule_trigger for rule in self.rules_all + for rule_trigger in rule.rule_triggers if rule_trigger.interaction_type=="message" + ] # [rule for rule in self.rules_active if rule.interaction_type=="reaction"] # self.active_message_rule_triggers = [rule for rule in self.rules_active if rule.interaction_type=="message"] @@ -192,6 +196,9 @@ async def _update_role_assignment(self, user_id: int) -> None: guild = self.bot.get_guild(constants.Bot.guild) role = guild.get_role(level_to_assign) user = await members.get_or_fetch_member(guild, user_id) + for user_role in user.roles: + if user_role in LEVEL_ROLES: + await members.handle_role_change(user, user.remove_roles, user_role) if role in user.roles: return logger.debug(f"Assigning {role.name} to {user.name}") @@ -223,10 +230,15 @@ async def on_message(self, msg: discord.Message) -> None: if rule_matches != 0: user_id = msg.author.id await self._update_points(user_id, total_points) - elif rule_matches >= 3: - user_id = msg.author.id - total_points = -5 - await self._update_points(user_id, total_points) + + total_rule_matches = 0 + for rule_trigger in self.all_message_rule_triggers: + re_pattern = rule_trigger.message_content + match = re.search(re_pattern, msg.content) + if match: + total_rule_matches += 1 + if total_rule_matches >= 3: + await self._update_points(user_id, -5) @commands.Cog.listener() From d2341e3a117d6fa8f5be33e8702807639f276a7d Mon Sep 17 00:00:00 2001 From: brad90four <42116429+brad90four@users.noreply.github.com> Date: Wed, 1 Apr 2026 14:00:36 -0400 Subject: [PATCH 5/5] correctly exit early in role check --- bot/exts/levels/_cog.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot/exts/levels/_cog.py b/bot/exts/levels/_cog.py index a1ba81e..9f934de 100644 --- a/bot/exts/levels/_cog.py +++ b/bot/exts/levels/_cog.py @@ -196,11 +196,11 @@ async def _update_role_assignment(self, user_id: int) -> None: guild = self.bot.get_guild(constants.Bot.guild) role = guild.get_role(level_to_assign) user = await members.get_or_fetch_member(guild, user_id) + if role in user.roles: + return for user_role in user.roles: if user_role in LEVEL_ROLES: await members.handle_role_change(user, user.remove_roles, user_role) - if role in user.roles: - return logger.debug(f"Assigning {role.name} to {user.name}") await members.handle_role_change(user, user.add_roles, role)