mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 03:08:55 -05:00
* Mention spam addition Adjust code to allow for warning and kicking in mention spam automoderation. Added new subcommand group, mentionspam. Which will display settings of warn, kick, ban, mentionspam when called. Adjust config to account for this. * Condense config + removal of comments Condense config into one variable to make one call. Removed unneeded comments I left. * Add warning casetype Copied over from warnings cog * Update strings + change function names * Changed prints and logs. Account for showsettings, removed blocking. If this style breaks, blame draper... * Black format...still blaming draper. * Adding period at end of description Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com> * config migration * Fix TypeError, add default information. * Max_mention wording change Thanks to @zephyrkul for suggesting the word changes. * Require argument for max_mention * Fix warn modlog case creation * Fix casetype conflict maaaaaaaaaagicccccccccc timeeeeeeeeeeeeeeeeeeeeeeeee Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com> Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
181 lines
6.7 KiB
Python
181 lines
6.7 KiB
Python
import logging
|
|
from datetime import datetime
|
|
from collections import defaultdict, deque
|
|
|
|
import discord
|
|
from redbot.core import i18n, modlog, commands
|
|
from redbot.core.utils.mod import is_mod_or_superior
|
|
from .abc import MixinMeta
|
|
|
|
_ = i18n.Translator("Mod", __file__)
|
|
log = logging.getLogger("red.mod")
|
|
|
|
|
|
class Events(MixinMeta):
|
|
"""
|
|
This is a mixin for the core mod cog
|
|
Has a bunch of things split off to here.
|
|
"""
|
|
|
|
async def check_duplicates(self, message):
|
|
guild = message.guild
|
|
author = message.author
|
|
|
|
guild_cache = self.cache.get(guild.id, None)
|
|
if guild_cache is None:
|
|
repeats = await self.config.guild(guild).delete_repeats()
|
|
if repeats == -1:
|
|
return False
|
|
guild_cache = self.cache[guild.id] = defaultdict(lambda: deque(maxlen=repeats))
|
|
|
|
if not message.content:
|
|
return False
|
|
|
|
guild_cache[author].append(message.content)
|
|
msgs = guild_cache[author]
|
|
if len(msgs) == msgs.maxlen and len(set(msgs)) == 1:
|
|
try:
|
|
await message.delete()
|
|
return True
|
|
except discord.HTTPException:
|
|
pass
|
|
return False
|
|
|
|
async def check_mention_spam(self, message):
|
|
guild, author = message.guild, message.author
|
|
mention_spam = await self.config.guild(guild).mention_spam.all()
|
|
|
|
mentions = set(message.mentions)
|
|
if mention_spam["ban"]:
|
|
if len(mentions) >= mention_spam["ban"]:
|
|
try:
|
|
await guild.ban(author, reason=_("Mention spam (Autoban)"))
|
|
except discord.HTTPException:
|
|
log.warning(
|
|
"Failed to ban a member ({member}) for mention spam in server {guild}.".format(
|
|
member=author.id, guild=guild.id
|
|
)
|
|
)
|
|
else:
|
|
await modlog.create_case(
|
|
self.bot,
|
|
guild,
|
|
message.created_at,
|
|
"ban",
|
|
author,
|
|
guild.me,
|
|
_("Mention spam (Autoban)"),
|
|
until=None,
|
|
channel=None,
|
|
)
|
|
return True
|
|
|
|
if mention_spam["kick"]:
|
|
if len(mentions) >= mention_spam["kick"]:
|
|
try:
|
|
await guild.kick(author, reason=_("Mention Spam (Autokick)"))
|
|
except discord.HTTPException:
|
|
log.warning(
|
|
"Failed to kick a member ({member}) for mention spam in server {guild}".format(
|
|
member=author.id, guild=guild.id
|
|
)
|
|
)
|
|
else:
|
|
await modlog.create_case(
|
|
self.bot,
|
|
guild,
|
|
message.created_at,
|
|
"kick",
|
|
author,
|
|
guild.me,
|
|
_("Mention spam (Autokick)"),
|
|
until=None,
|
|
channel=None,
|
|
)
|
|
return True
|
|
|
|
if mention_spam["warn"]:
|
|
if len(mentions) >= mention_spam["warn"]:
|
|
try:
|
|
await author.send(_("Please do not mass mention people!"))
|
|
except (discord.HTTPException, discord.Forbidden):
|
|
try:
|
|
await message.channel.send(
|
|
_("{member}, Please do not mass mention people!").format(
|
|
member=author.mention
|
|
)
|
|
)
|
|
except (discord.HTTPException, discord.Forbidden):
|
|
log.warning(
|
|
"Failed to warn a member ({member}) for mention spam in server {guild}".format(
|
|
member=author.id, guild=guild.id
|
|
)
|
|
)
|
|
return False
|
|
|
|
await modlog.create_case(
|
|
self.bot,
|
|
guild,
|
|
message.created_at,
|
|
"warning",
|
|
author,
|
|
guild.me,
|
|
_("Mention spam (Autowarn)"),
|
|
until=None,
|
|
channel=None,
|
|
)
|
|
return True
|
|
return False
|
|
|
|
@commands.Cog.listener()
|
|
async def on_message(self, message):
|
|
author = message.author
|
|
if message.guild is None or self.bot.user == author:
|
|
return
|
|
|
|
if await self.bot.cog_disabled_in_guild(self, message.guild):
|
|
return
|
|
|
|
valid_user = isinstance(author, discord.Member) and not author.bot
|
|
if not valid_user:
|
|
return
|
|
|
|
# Bots and mods or superior are ignored from the filter
|
|
mod_or_superior = await is_mod_or_superior(self.bot, obj=author)
|
|
if mod_or_superior:
|
|
return
|
|
# As are anyone configured to be
|
|
if await self.bot.is_automod_immune(message):
|
|
return
|
|
deleted = await self.check_duplicates(message)
|
|
if not deleted:
|
|
await self.check_mention_spam(message)
|
|
|
|
@commands.Cog.listener()
|
|
async def on_user_update(self, before: discord.User, after: discord.User):
|
|
if before.name != after.name:
|
|
async with self.config.user(before).past_names() as name_list:
|
|
while None in name_list: # clean out null entries from a bug
|
|
name_list.remove(None)
|
|
if after.name in name_list:
|
|
# Ensure order is maintained without duplicates occurring
|
|
name_list.remove(after.name)
|
|
name_list.append(after.name)
|
|
while len(name_list) > 20:
|
|
name_list.pop(0)
|
|
|
|
@commands.Cog.listener()
|
|
async def on_member_update(self, before: discord.Member, after: discord.Member):
|
|
if before.nick != after.nick and after.nick is not None:
|
|
guild = after.guild
|
|
if (not guild) or await self.bot.cog_disabled_in_guild(self, guild):
|
|
return
|
|
async with self.config.member(before).past_nicks() as nick_list:
|
|
while None in nick_list: # clean out null entries from a bug
|
|
nick_list.remove(None)
|
|
if after.nick in nick_list:
|
|
nick_list.remove(after.nick)
|
|
nick_list.append(after.nick)
|
|
while len(nick_list) > 20:
|
|
nick_list.pop(0)
|