Experimental Discord bot written in Python
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

crosspostcog.py 2.0KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. from discord import Guild, Message
  2. from cogs.basecog import BaseCog
  3. class CrossPostCog(BaseCog):
  4. class SpamContext:
  5. def __init__(self, member):
  6. self.member = member
  7. self.is_warned = False
  8. STATE_KEY_RECENT_MESSAGES = "crosspost_recent_messages"
  9. STATE_KEY_SPAM_CONTEXT = "crosspost_spam_context"
  10. def __init__(self, bot):
  11. super().__init__(bot)
  12. self.max_recent_messages = 20
  13. self.messages_per_user = 3
  14. self.min_message_length = 10
  15. def __record_message(self, message: Message) -> None:
  16. recent_messages = Storage.get_state_value(message.guild, self.STATE_KEY_RECENT_MESSAGES) or []
  17. recent_messages.append(message)
  18. while len(recent_messages) > self.max_recent_messages:
  19. recent_messages.pop(0)
  20. Storage.set_state_value(message.guild, self.STATE_KEY_RECENT_MESSAGES, recent_messages)
  21. def __check_for_spam(self, guild: Guild) -> None:
  22. recent_messages = Storage.get_state_value(guild, self.STATE_KEY_RECENT_MESSAGES)
  23. if recent_messages is None:
  24. return
  25. user_id_to_count = {}
  26. spamming_members = set()
  27. for message in recent_messages:
  28. content = message.content
  29. if len(content) < self.min_message_length:
  30. continue
  31. key = str(message.author.id) + '|' + hash(content)
  32. count = (user_id_to_count.get(key) or 0) + 1
  33. user_id_to_count[key] = count
  34. if count >= self.messages_per_user:
  35. spamming_members.add(message.author)
  36. for member in spamming_members:
  37. context = self.__spam_context_for_user(member)
  38. def __spam_context_for_user(self,
  39. member: Member,
  40. create_if_missing: bool = False) -> SpamContext:
  41. spam_lookup = Storage.get_state_value(member.guild, self.STATE_KEY_SPAM_CONTEXT) or {}
  42. context = spam_lookup.get(member.id)
  43. if context:
  44. return context
  45. if not create_if_missing:
  46. return None
  47. context = SpamContext(member)
  48. spam_lookup[member.id] = context
  49. Storage.set_state_value(member.guild, self.STATE_KEY_SPAM_CONTEXT, spam_lookup)
  50. return context
  51. @commands.Cog.listener()
  52. def on_message(self, message: Message):
  53. self.__record_message(message)
  54. self.__check_for_spam(message.guild)