diff --git a/src/client.ts b/src/client.ts index 3060658..a37e197 100644 --- a/src/client.ts +++ b/src/client.ts @@ -6,6 +6,12 @@ interface IRepeatedMessages { timeout:NodeJS.Timeout; } } +interface ICrosspostSpam { + [key:string]: { + message:string; + channelId:string[]; + } +} import Discord from 'discord.js'; import ConfigHelper from './helpers/ConfigHelper.js'; import {readdirSync} from 'node:fs'; @@ -36,6 +42,7 @@ export default class TClient extends Discord.Client { public tags: TagSystemSvc = new TagSystemSvc(); public ytChannels: YouTubeChannelsSvc = new YouTubeChannelsSvc(); public repeatedMessages: IRepeatedMessages = {}; + public crosspostSpam: ICrosspostSpam = {}; constructor() { super({ diff --git a/src/components/Automod.ts b/src/components/Automod.ts index 2bcc5cf..278660d 100644 --- a/src/components/Automod.ts +++ b/src/components/Automod.ts @@ -35,6 +35,24 @@ export default class Automoderator { clearTimeout(data.timeout); data.timeout = setTimeout(()=>delete client.repeatedMessages[message.author.id], thresholdTime); } + }// Explanation: If spammer sends same message 5 or more times in every channel, they will be served a rotten fish and chips for dinner. + static async crosspostSpam(client:TClient, message:Discord.Message, reason:string) { + if (!client.crosspostSpam[message.author.id]) client.crosspostSpam[message.author.id] = {message: message.content, channelId: [message.channelId]}; + else if (!client.crosspostSpam[message.author.id].channelId.includes(message.channelId)) client.crosspostSpam[message.author.id].channelId.push(message.channelId); + + if (client.crosspostSpam[message.author.id].channelId.length >= 5) { + if (!this.lockQuery.has(message.author.id)) { + this.lockQuery.add(message.author.id); + Logger.console('log', 'AUTOMOD', `Lock acquired for ${message.author.tag} with reason: ${reason}`); + await client.punishments.punishmentAdd('ban', {}, client.user.id, `AUTOMOD:${reason}`, message.author, message.member as Discord.GuildMember); + setTimeout(()=>{ + this.lockQuery.delete(message.author.id); + Logger.console('log', 'AUTOMOD', `Lock released for ${message.author.tag}`); + }, 5000); // Wait 5 seconds before releasing the lock. + } + delete client.crosspostSpam[message.author.id]; + } + setTimeout(()=>delete client.crosspostSpam[message.author.id], 180000); // Delete the data after 3 minutes. } static async imageOnly(message:Discord.Message) { const io_channels = ['468896467688620032']; diff --git a/src/events/messageCreate.ts b/src/events/messageCreate.ts index ee2fe45..16f3a6d 100644 --- a/src/events/messageCreate.ts +++ b/src/events/messageCreate.ts @@ -25,7 +25,7 @@ export default class MessageCreate { } }, discordInvite: { - check: async()=>message.content.toLowerCase().includes('discord.gg/') && !MessageTool.isStaff(message.member as Discord.GuildMember), + check: ()=>message.content.toLowerCase().includes('discord.gg/') && !MessageTool.isStaff(message.member as Discord.GuildMember), action: async()=>{ const validInvite = await client.fetchInvite(message.content.split(' ').find(x=>x.includes('discord.gg/'))).catch(()=>null); if (validInvite && validInvite.guild?.id !== client.config.dcServer.id) { @@ -37,19 +37,22 @@ export default class MessageCreate { } }, imageOnly: { - check: async()=>!MessageTool.isStaff(message.member as Discord.GuildMember), + check: ()=>!MessageTool.isStaff(message.member as Discord.GuildMember), action: async()=>await Automoderator.imageOnly(message) + }, + crosspost: { + check: ()=>!MessageTool.isStaff(message.member as Discord.GuildMember) && message.content.toLowerCase(), + action: async()=>{ + automodded = true; + await Automoderator.crosspostSpam(client, message, 'Crosspost spam'); + } } }; for (const rule of Object.values(automodRules)) { - if (await rule.check()) { - await rule.action(); - break; - } + if (await rule.check()) await rule.action(); } }; - if (message.guildId === client.config.dcServer.id && !automodded) client.userLevels.messageIncremental(message.author.id); // Mop gifs from banned channels without admins having to mop them. // const bannedChannels = []