瀏覽代碼

Adding URL spam cog. Fixing joinraid cog.

tags/1.0.1
Rocketsoup 4 年之前
父節點
當前提交
0d09d27221
共有 5 個文件被更改,包括 85 次插入25 次删除
  1. 1
    0
      cogs/basecog.py
  2. 3
    25
      cogs/joinraidcog.py
  3. 75
    0
      cogs/urlspamcog.py
  4. 4
    0
      config.py.sample
  5. 2
    0
      rocketbot.py

+ 1
- 0
cogs/basecog.py 查看文件

@@ -2,6 +2,7 @@ from discord import Guild, Message, PartialEmoji, RawReactionActionEvent, TextCh
2 2
 from discord.ext import commands
3 3
 from datetime import timedelta
4 4
 
5
+from config import CONFIG
5 6
 from rscollections import AgeBoundDict
6 7
 from storage import ConfigKey, Storage
7 8
 import json

+ 3
- 25
cogs/joinraidcog.py 查看文件

@@ -162,35 +162,10 @@ class GuildContext:
162 162
 	"""
163 163
 	def __init__(self, guild_id: int):
164 164
 		self.guild_id = guild_id
165
-		self.join_warning_count = self.get_cog_default('warning_count')
166
-		self.join_warning_seconds = self.get_cog_default('warning_seconds')
167 165
 		# Non-persisted runtime state
168 166
 		self.current_raid = JoinRaidRecord()
169 167
 		self.all_raids = [ self.current_raid ] # periodically culled of old ones
170 168
 
171
-	# Events
172
-
173
-	async def handle_join(self, member: Member) -> None:
174
-		"""
175
-		Event handler for all joins to this guild.
176
-		"""
177
-		now = member.joined_at
178
-		raid = self.current_raid
179
-		raid.handle_join(
180
-			member,
181
-			now=now,
182
-			max_age_seconds = self.join_warning_seconds,
183
-			max_join_count = self.join_warning_count)
184
-		self.__trace(f'raid phase: {raid.phase}')
185
-		if raid.phase == RaidPhase.JUST_STARTED:
186
-			await self.__on_join_raid_begin(raid)
187
-		elif raid.phase == RaidPhase.CONTINUING:
188
-			await self.__on_join_raid_updated(raid)
189
-		elif raid.phase == RaidPhase.ENDED:
190
-			self.__start_new_raid(member)
191
-			await self.__on_join_raid_end(raid)
192
-		self.__cull_old_raids(now)
193
-
194 169
 	def reset_raid(self, now: datetime):
195 170
 		"""
196 171
 		Retires self.current_raid and creates a new empty one.
@@ -467,6 +442,9 @@ class JoinRaidCog(BaseCog):
467 442
 		if gc is not None:
468 443
 			return gc
469 444
 		gc = GuildContext(guild.id)
445
+		gc.join_warning_count = self.get_cog_default('warning_count')
446
+		gc.join_warning_seconds = self.get_cog_default('warning_seconds')
447
+
470 448
 		self.guild_id_to_context[guild.id] = gc
471 449
 		return gc
472 450
 

+ 75
- 0
cogs/urlspamcog.py 查看文件

@@ -0,0 +1,75 @@
1
+from discord import Guild, Message
2
+from discord.ext import commands
3
+import re
4
+from datetime import timedelta
5
+
6
+from cogs.basecog import BaseCog
7
+from config import CONFIG
8
+from storage import Storage
9
+
10
+class URLSpamCog(BaseCog):
11
+	CONFIG_KEY_EARLY_URL_TIMEOUT = "urlspam_early_url_timeout"
12
+	CONFIG_KEY_EARLY_URL_ACTION = "urlspam_early_url_action"
13
+
14
+	def __init__(self, bot):
15
+		super().__init__(bot)
16
+
17
+	def __early_url_timeout(self, guild: Guild) -> int:
18
+		return Storage.get_config_value(guild, self.CONFIG_KEY_EARLY_URL_TIMEOUT) or \
19
+			self.get_cog_default('early_url_timeout')
20
+
21
+	def __early_url_action(self, guild: Guild) -> str:
22
+		return Storage.get_config_value(guild, self.CONFIG_KEY_EARLY_URL_ACTION) or \
23
+			self.get_cog_default('early_url_action')
24
+
25
+	@commands.Cog.listener()
26
+	async def on_message(self, message: Message):
27
+		if message.guild is None or message.channel is None:
28
+			# DM or something
29
+			return
30
+		action = self.__early_url_action(message.guild)
31
+		if action == 'nothing':
32
+			return
33
+		if message.author.permissions_in(message.channel).ban_members:
34
+			# Mods are exempt
35
+			return
36
+		if not self.__contains_url(message.content):
37
+			return
38
+		join_age = message.created_at - message.author.joined_at
39
+		join_age_str = self.__format_timedelta(join_age)
40
+		if join_age.total_seconds() < self.__early_url_timeout(message.guild):
41
+			if action == 'modwarn':
42
+				await self.warn(message.guild, f'User {message.author.mention} ' +
43
+					f'posted a URL {join_age_str} after joining.\n\n> {message.content}')
44
+				# TODO: Emoji actions
45
+			elif action == 'delete':
46
+				await message.delete()
47
+				# TODO: Info to mods
48
+			elif action == 'kick':
49
+				await message.author.kick(reason=f'User posted a link {join_age_str} after joining')
50
+				# TODO: Info to mods
51
+			elif action == 'ban':
52
+				await message.author.ban(reason=f'User posted a link {join_age_str} after joining', delete_message_days=1)
53
+				# TODO: Info to mods
54
+
55
+	def __contains_url(self, text: str) -> bool:
56
+		p = re.compile(r'http[^\s]*')
57
+		return p.search(text) is not None
58
+
59
+	def __format_timedelta(self, timespan: timedelta) -> str:
60
+		parts = []
61
+		d = timespan.days
62
+		h = timespan.seconds // 3600
63
+		m = (timespan.seconds // 60) % 60
64
+		s = timespan.seconds % 60
65
+		if d > 0:
66
+			parts.append(f'{d}d')
67
+		if d > 0 or h > 0:
68
+			parts.append(f'{h}h')
69
+		if d > 0 or h > 0 or m > 0:
70
+			parts.append(f'{m}m')
71
+		parts.append(f'{s}s')
72
+		# Limit the precision to the two most significant elements
73
+		while len(parts) > 2:
74
+			parts.pop(-1)
75
+		return ' '.join(parts)

+ 4
- 0
config.py.sample 查看文件

@@ -22,5 +22,9 @@ CONFIG = {
22 22
 			'time_window_seconds': 120,
23 23
 			'min_message_length': 0,
24 24
 		},
25
+		'URLSpamCog': {
26
+			'early_url_timeout': 900,  # Should be > 10m due to Discord-imposed waiting period
27
+			'early_url_action': 'modwarn', # "nothing" | "modwarn" | "delete" | "kick" | "ban"
28
+		},
25 29
 	},
26 30
 }

+ 2
- 0
rocketbot.py 查看文件

@@ -13,6 +13,7 @@ from cogs.configcog import ConfigCog
13 13
 from cogs.crosspostcog import CrossPostCog
14 14
 from cogs.generalcog import GeneralCog
15 15
 from cogs.joinraidcog import JoinRaidCog
16
+# from cogs.urlspamcog import URLSpamCog
16 17
 
17 18
 CURRENT_CONFIG_VERSION = 1
18 19
 if (CONFIG.get('__config_version') or 0) < CURRENT_CONFIG_VERSION:
@@ -32,5 +33,6 @@ bot.add_cog(GeneralCog(bot))
32 33
 bot.add_cog(ConfigCog(bot))
33 34
 bot.add_cog(JoinRaidCog(bot))
34 35
 bot.add_cog(CrossPostCog(bot))
36
+# bot.add_cog(URLSpamCog(bot))
35 37
 bot.run(CONFIG['client_token'], bot=True, reconnect=True)
36 38
 print('\nBot aborted')

Loading…
取消
儲存