diff options
| author | IRONM00N <64110067+IRONM00N@users.noreply.github.com> | 2021-10-12 20:27:37 -0400 |
|---|---|---|
| committer | IRONM00N <64110067+IRONM00N@users.noreply.github.com> | 2021-10-12 20:27:37 -0400 |
| commit | ba2d7b7db0a627234ed08de9d6bec8cb675404a7 (patch) | |
| tree | 9ade9ed549b52eac3f2966a5cee5478267eca7c4 /src | |
| parent | cac6abf3efd563b83f8f0ce70ce4bcfa5ada1a27 (diff) | |
| download | tanzanite-ba2d7b7db0a627234ed08de9d6bec8cb675404a7.tar.gz tanzanite-ba2d7b7db0a627234ed08de9d6bec8cb675404a7.tar.bz2 tanzanite-ba2d7b7db0a627234ed08de9d6bec8cb675404a7.zip | |
revamp automod, refactoring, fixes
Diffstat (limited to 'src')
| -rw-r--r-- | src/commands/info/botInfo.ts | 2 | ||||
| -rw-r--r-- | src/commands/moderation/ban.ts | 5 | ||||
| -rw-r--r-- | src/commands/moderation/kick.ts | 3 | ||||
| -rw-r--r-- | src/commands/moderation/modlog.ts | 2 | ||||
| -rw-r--r-- | src/commands/moderation/mute.ts | 3 | ||||
| -rw-r--r-- | src/commands/moderation/unmute.ts | 3 | ||||
| -rw-r--r-- | src/commands/moderation/warn.ts | 3 | ||||
| -rw-r--r-- | src/lib/badlinks.ts | 410 | ||||
| -rw-r--r-- | src/lib/badwords.ts | 242 | ||||
| -rw-r--r-- | src/lib/common/autoMod.ts | 236 | ||||
| -rw-r--r-- | src/lib/common/moderation.ts | 181 | ||||
| -rw-r--r-- | src/lib/extensions/discord-akairo/BushClientUtil.ts | 361 | ||||
| -rw-r--r-- | src/lib/extensions/discord.js/BushGuild.ts | 22 | ||||
| -rw-r--r-- | src/lib/extensions/discord.js/BushGuildMember.ts | 25 | ||||
| -rw-r--r-- | src/lib/models/Guild.ts | 25 | ||||
| -rw-r--r-- | src/listeners/client/interactionCreate.ts | 5 | ||||
| -rw-r--r-- | src/listeners/message/automodCreate.ts | 113 | ||||
| -rw-r--r-- | src/listeners/message/automodUpdate.ts | 4 |
18 files changed, 1232 insertions, 413 deletions
diff --git a/src/commands/info/botInfo.ts b/src/commands/info/botInfo.ts index 8f85fe6..257dc90 100644 --- a/src/commands/info/botInfo.ts +++ b/src/commands/info/botInfo.ts @@ -53,7 +53,7 @@ export default class BotInfoCommand extends BushCommand { ) .addField('**CPU Usage**', `${client.stats.cpu}%`, true) .addField('**Platform**', Platform[process.platform], true) - .addField('**Commands Used**', `${client.stats.commandsUsed}`, true) + .addField('**Commands Used**', `${client.stats.commandsUsed.toLocaleString()}`, true) .addField('**Servers**', client.guilds.cache.size.toLocaleString(), true) .addField('**Users**', client.users.cache.size.toLocaleString(), true) .addField('**Discord.js Version**', discordJSVersion, true) diff --git a/src/commands/moderation/ban.ts b/src/commands/moderation/ban.ts index b64330f..4c2b3d3 100644 --- a/src/commands/moderation/ban.ts +++ b/src/commands/moderation/ban.ts @@ -1,5 +1,6 @@ import { AllowedMentions, BushCommand, BushMessage, BushSlashMessage } from '@lib'; import { Snowflake, User } from 'discord.js'; +import { Moderation } from '../../lib/common/moderation'; export default class BanCommand extends BushCommand { public constructor() { @@ -103,9 +104,7 @@ export default class BanCommand extends BushCommand { const useForce = force && message.author.isOwner(); if (!message.member) throw new Error(`message.member is null`); - const canModerateResponse = member - ? await util.moderationPermissionCheck(message.member, member, 'ban', true, useForce) - : true; + const canModerateResponse = member ? await Moderation.permissionCheck(message.member, member, 'ban', true, useForce) : true; if (canModerateResponse !== true) { return await message.util.reply(canModerateResponse); diff --git a/src/commands/moderation/kick.ts b/src/commands/moderation/kick.ts index 07c25ab..715483a 100644 --- a/src/commands/moderation/kick.ts +++ b/src/commands/moderation/kick.ts @@ -1,4 +1,5 @@ import { AllowedMentions, BushCommand, BushGuildMember, BushMessage, BushSlashMessage, BushUser } from '@lib'; +import { Moderation } from '../../lib/common/moderation'; export default class KickCommand extends BushCommand { public constructor() { @@ -67,7 +68,7 @@ export default class KickCommand extends BushCommand { ); if (!message.member) throw new Error(`message.member is null`); const useForce = force && message.author.isOwner(); - const canModerateResponse = await util.moderationPermissionCheck(message.member, member, 'kick', true, useForce); + const canModerateResponse = await Moderation.permissionCheck(message.member, member, 'kick', true, useForce); if (canModerateResponse !== true) { return message.util.reply(canModerateResponse); diff --git a/src/commands/moderation/modlog.ts b/src/commands/moderation/modlog.ts index 0eb7392..d5c6f91 100644 --- a/src/commands/moderation/modlog.ts +++ b/src/commands/moderation/modlog.ts @@ -48,7 +48,7 @@ export default class ModlogCommand extends BushCommand { #generateModlogInfo(log: ModLog, showUser: boolean): string { const trim = (str: string): string => (str.endsWith('\n') ? str.substring(0, str.length - 1).trim() : str.trim()); - const modLog = [`**Case ID**: ${log.id}`, `**Type**: ${log.type.toLowerCase()}`]; + const modLog = [`**Case ID**: ${util.discord.escapeItalic(log.id)}`, `**Type**: ${log.type.toLowerCase()}`]; if (showUser) modLog.push(`**User**: <@!${log.user}>`); modLog.push(`**Moderator**: <@!${log.moderator}>`); if (log.duration) modLog.push(`**Duration**: ${util.humanizeDuration(log.duration)}`); diff --git a/src/commands/moderation/mute.ts b/src/commands/moderation/mute.ts index 9e68d63..942c0b0 100644 --- a/src/commands/moderation/mute.ts +++ b/src/commands/moderation/mute.ts @@ -1,4 +1,5 @@ import { AllowedMentions, BushCommand, BushMessage, BushSlashMessage, BushUser } from '@lib'; +import { Moderation } from '../../lib/common/moderation'; export default class MuteCommand extends BushCommand { public constructor() { @@ -73,7 +74,7 @@ export default class MuteCommand extends BushCommand { if (!message.member) throw new Error(`message.member is null`); const useForce = force && message.author.isOwner(); - const canModerateResponse = await util.moderationPermissionCheck(message.member, member, 'mute', true, useForce); + const canModerateResponse = await Moderation.permissionCheck(message.member, member, 'mute', true, useForce); const victimBoldTag = `**${member.user.tag}**`; if (canModerateResponse !== true) { diff --git a/src/commands/moderation/unmute.ts b/src/commands/moderation/unmute.ts index 680c7ba..3d592b7 100644 --- a/src/commands/moderation/unmute.ts +++ b/src/commands/moderation/unmute.ts @@ -1,4 +1,5 @@ import { AllowedMentions, BushCommand, BushGuildMember, BushMessage, BushSlashMessage, BushUser } from '@lib'; +import { Moderation } from '../../lib/common/moderation'; export default class UnmuteCommand extends BushCommand { public constructor() { @@ -67,7 +68,7 @@ export default class UnmuteCommand extends BushCommand { const useForce = force && message.author.isOwner(); - const canModerateResponse = await util.moderationPermissionCheck(message.member, member, 'unmute', true, useForce); + const canModerateResponse = await Moderation.permissionCheck(message.member, member, 'unmute', true, useForce); const victimBoldTag = `**${member.user.tag}**`; diff --git a/src/commands/moderation/warn.ts b/src/commands/moderation/warn.ts index b4bf74d..3df4b3b 100644 --- a/src/commands/moderation/warn.ts +++ b/src/commands/moderation/warn.ts @@ -1,4 +1,5 @@ import { BushCommand, BushGuildMember, BushMessage, BushSlashMessage, BushUser } from '@lib'; +import { Moderation } from '../../lib/common/moderation'; export default class WarnCommand extends BushCommand { public constructor() { @@ -63,7 +64,7 @@ export default class WarnCommand extends BushCommand { if (!member) return message.util.reply(`${util.emojis.error} I cannot warn users that are not in the server.`); const useForce = force && message.author.isOwner(); if (!message.member) throw new Error(`message.member is null`); - const canModerateResponse = await util.moderationPermissionCheck(message.member, member, 'warn', true, useForce); + const canModerateResponse = await Moderation.permissionCheck(message.member, member, 'warn', true, useForce); const victimBoldTag = `**${member.user.tag}**`; if (canModerateResponse !== true) { diff --git a/src/lib/badlinks.ts b/src/lib/badlinks.ts new file mode 100644 index 0000000..67f9679 --- /dev/null +++ b/src/lib/badlinks.ts @@ -0,0 +1,410 @@ +/* Links in this file are treated as severity 3 offences. + +made in part possible by https://github.com/nacrt/SkyblockClient-REPO/blob/main/files/scamlinks.json */ +export default [ + "acercup.com", + "affix-cup.ru", + "affix-sport.ru", + "airdrops.tips", + "aladdinhub.fun", + "allskinz.xyz", + "ano-skinspin.xyz", + "anomalygiveaways.pro", + "anomalyknifes.xyz", + "anomalyskin.xyz", + "anomalyskinz.xyz", + "anoskinzz.xyz", + "berrygamble.com", + "bit-skins.ru", + "bitknife.xyz", + "bitskines.ru", + "casefire.fun", + "challengeme.in", + "challengeme.vip", + "challengme.ru", + "cloud9team.space", + "cmepure.com", + "cmskillcup.com", + "counterpaid.xyz", + "counterspin.top", + "counterstrikegift.xyz", + "cs-beast.xyz", + "cs-lucky.xyz", + "cs-pill.xyz", + "cs-prizeskins.xyz", + "cs-prizeskinz.xyz", + "cs-simpleroll.xyz", + "cs-skinz.xyz", + "cs-smoke.xyz", + "cs-spinz.xyz", + "cs-victory.xyz", + "csallskin.xyz", + "csbuyskins.in", + "cscoat.eu", + "csgo-analyst.com", + "csgo-cash.eu", + "csgo-gifts.com", + "csgo-market.ru.com", + "csgo-market.ru.com", + "csgo-steamanalyst.net", + "csgo-swapskin.com", + "csgo-trade.net", + "csgo-up.com", + "csgobeats.com", + "csgobelieve.ru", + "csgocase.one", + "csgocashs.com", + "csgocheck.ru.com", + "csgocheck.ru", + "csgocompetive.com", + "csgocupp.ru.com", + "csgocybersport.ru.com", + "csgodetails.info", + "csgodreamer.com", + "csgodrs.com", + "csgoeasywin.ru.com", + "csgoelite.xyz", + "csgoencup.com", + "csgoevent.xyz", + "csgogift49.xyz", + "csgoindex.ru.com", + "csgoindex.ru", + "csgoitemdetails.com", + "csgoitemsprices.com", + "csgoko.tk", + "csgomarble.xyz", + "csgomarketplace.net", + "csgomarkets.net", + "csgoorun.ru", + "csgoprocupgo.com", + "csgorcup.com", + "csgorose.com", + "csgoroyalskins1.com", + "csgoskill.ru", + "csgoskinprices.com", + "csgoskinsinfo.com", + "csgoskinsroll.com", + "csgosteamanalysis.com", + "csgosteamanalyst.ru", + "csgoteammate.gq", + "csgothunby.com", + "csgotrades.net", + "csgovip.ru", + "csgoxgiveaway.ru", + "csgozone.net.in", + "csgunskins.xyz", + "csmoneyskinz.xyz", + "csmvcecup.com", + "csprices.in", + "csskill.com", + "csskillpro.xyz", + "csskinz.xyz", + "cstournament.ru", + "csxrnoney.com", + "cybergamearena.ru", + "d2cups.com", + "d2faceit.com", + "deamonbets.ru", + "demonbets.ru", + "denforapasi.cf", + "diablobets.com", + "dicksod.co", + "dicsord.gifts", + "dicsord.net", + "dicsord.net", + "dirscod.com", + "dirscod.gift", + "discocrd.gift", + "discod.gift", + "discod.info", + "discorb.co", + "discorb.ru.com", + "discorcl-app.com", + "discorcl-gift.xyz", + "discorcl.click", + "discorcl.link", + "discorclapp.com", + "discord-accept.com", + "discord-airdrop.com", + "discord-app.me", + "discord-app.net", + "discord-app.ru.com", + "discord-cpp.com", + "discord-gifts.com", + "discord-give.com", + "discord-halloween.ru", + "discord-nitro.click", + "discord-nitro.gifts", + "discord-nitro.link", + "discord.blog", + "discord.givaewey.com", + "discord.giveawey.com", + "discord.moscow", + "discord.shop", + "discordapp.click", + "discordgift.info", + "discordgift.ru.com", + "discordgivenitro.com", + "discordglfts.com", + "discordnitrogift.ru", + "discords-nitroapp.xyz", + "discordsteams.com", + "discrod.gift", + "discrod.gifts", + "discrodnitro.org", + "diskord.ru.com", + "disrcod.com", + "dlscord-app.com", + "dlscord-nitro.link", + "dlscord.app", + "dlscord.info", + "dlscord.online", + "dlscord.org", + "dlscord.press", + "dlscord.store", + "dlscord.wiki", + "dlscord.world", + "doatgiveaway.top", + "dopeskins.com", + "dota2fight.net", + "dota2fight.ru", + "dota2giveaway.top", + "dota2giveaways.top", + "dotafights.vip", + "dotagiveaway.win", + "dragon-up.online", + "drop-key.ru", + "dsicord.gift", + "earnskinz.xyz", + "emeraldbets.ru", + "eplcups.com", + "esea-mdl.com", + "esportgaming.ru", + "event-games4roll.com", + "exchangeuritems.gq", + "extraskinscs.xyz", + "ezwin24.ru", + "facecup.fun", + "faceiteasyleague.ru", + "fatown.net", + "fineleague.fun", + "fireopencase.com", + "fivetown.net", + "free-nitlross.ru", + "free-nitro.ru", + "free-nitros.ru", + "free-skins.ru", + "freenitroi.ru", + "freenitros.ru", + "g2-give.ru", + "g2-give.ru", + "game4roll.com", + "gameluck.ru", + "gamerich.xyz", + "games-roll.ga", + "games-roll.ml", + "games-roll.ru", + "get-nitro.net", + "gift4keys.com", + "giftsdiscord.ru", + "giveavvay.com", + "giveawayskin.com", + "glets-nitro.com", + "global-skins.gq", + "globalcsskins.xyz", + "globalskins.tk", + "go.rancah.com", + "goldendota.com", + "goodskins.gq", + "gosteamanalyst.com", + "gtakey.ru", + "hellgiveaway.trade", + "hellstores.xyz", + "hltvcsgo.com", + "hltvgames.net", + "iemcup.com", + "keydorp.me", + "keys-loot.com", + "knifespin.top", + "knifespin.top", + "knifespin.xyz", + "knifespins.xyz", + "knifez-roll.xyz", + "knifez-win.xyz", + "league-csgo.com", + "lehatop-01.ru", + "lootxmarket.com", + "loungeztrade.com", + "lucky-skins.xyz", + "made-nitro.com", + "makson-gta.ru", + "maxskins.xyz", + "mvcsgo.com", + "mvpcup.ru", + "mvptournament.com", + "mygames4roll.com", + "naviback.ru", + "night-skins.com", + "nitro-discord.org", + "nitros-gift.com", + "nwgwroqr.ru", + "oligarph.club", + "ownerbets.com", + "playerskinz.xyz", + "pubggift62.xyz", + "rangskins.com", + "rave-new.ru", + "roll-skins.ru", + "roll4knife.xyz", + "roll4tune.com", + "rollknfez.xyz", + "rollskin-simple.xyz", + "rushbskins.xyz", + "rushskins.xyz", + "s1mple-spin.xyz", + "sakuralive.ru.com", + "scale-navi.pp.ru", + "simple-knifez.xyz", + "simple-win.xyz", + "simplegamepro.ru", + "simpleroll-cs.xyz", + "simplespinz.xyz", + "simplewinz.xyz", + "skin-index.com", + "skin888trade.com", + "skincs-spin.top", + "skincs-spin.xyz", + "skinmarkets.net", + "skins-hub.top", + "skins-info.net", + "skins-jungle.xyz", + "skinsboost.ru", + "skinsdatabse.com", + "skinsind.com", + "skinsmind.ru", + "skinspace.ru", + "skinsplane.com", + "skinsplanes.com", + "skinsplanets.com", + "skinxinfo.net", + "skinxmarket.site", + "skinz-spin.top", + "skinz-spin.xyz", + "skinzjar.ru", + "skinzprize.xyz", + "skinzspin-cs.xyz", + "skinzspinz.xyz", + "sleanmconmunltiy.ru", + "spin-games.com", + "spin4skinzcs.top", + "spin4skinzcs.xyz", + "spinforskin.ml", + "sponsored-simple.xyz", + "staemcomnrnunitiy.ru.com", + "staemcomrnunity.store", + "staermcrommunity.me", + "staffstatsgo.com", + "starrygamble.com", + "stat-csgo.ru", + "stats-cs.ru", + "stceamcomminity.com", + "steam-analyst.ru", + "steam-nitro.ru", + "steam-trades.icu", + "steamanalysts.com", + "steamcomcunity.ru", + "steamcomminutiu.ru", + "steamcomminutiy.ru", + "steamcomminuty.com", + "steamcomminytiu.com", + "steamcomminytiu.ru", + "steamcomminytu.ru", + "steamcommnunily.com", + "steamcommnuninty.com", + "steamcommnuntiy.com", + "steamcommrutiny.ru", + "steamcommuniiy.ru", + "steamcommunily.uno", + "steamcommunitiyu.com", + "steamcommunitlu.com", + "steamcommunity.link", + "steamcommunityu.com", + "steamcommunityu.ru", + "steamcommunityw.com", + "steamcommunlty.pro", + "steamcommunrlity.com", + "steamcommunutiy.com", + "steamcommunytiu.ru", + "steamcommunytu.ru", + "steamcommutiny.com", + "steamcommynitu.ru", + "steamcomnmuituy.com", + "steamcomnumity.ru", + "steamcomrnunity.ru", + "steamcomrrnunity.com", + "steamcomrunity.com", + "steamcomuniity.ru.com", + "steamconmunlty.com", + "steamcormmuntiy.com", + "steamcornminuty.com", + "steamgamesroll.ru", + "steamncommuniity.com", + "steamncommunity.com", + "steamnitro.com", + "steamnmcomunnity.co", + "steamoemmunity.com", + "steamsupportpowered.icu", + "steancommunity.link", + "steancommynity.ru.com", + "steancomnunytu.ru", + "steancomunnity.ru", + "steancomunyiti.ru", + "stearmcommunnitty.online", + "stearmmcomunitty.ru", + "stearmmcomunity.ru", + "stearmmcomuunity.ru", + "stearncomminuty.ru", + "stearncommunity.ru", + "stearncommunytiy.ru", + "stearncommuty.com", + "stearncormmunity.com", + "steemcommnunity.ru", + "stemcommunnilty.com", + "stemcornmunity.ru", + "stermccommunitty.ru", + "stermcommuniity.com", + "stermcommunnitty.ru", + "stewie2k-giveaway-150days.pro", + "stiemcommunitty.ru", + "stmeacomunnitty.ru", + "store-stempowered.com", + "streamcommulinty.com", + "streamcommuninnity.com", + "streamcommuunnity.com", + "streamcomnumity.ru", + "streamcomunity.com", + "streammcomunnity.ru", + "streancommunuty.ru", + "streancommunuty.ru", + "strearmcommunity.ru", + "strearmcomunity.ru", + "sunnygamble.com", + "swapskins.live", + "test-domuin2.com", + "test-domuin3.ru", + "test-domuin4.ru", + "test-domuin5.ru", + "tf2market.store", + "tournamentt.com", + "ultimateskins.xyz", + "ultracup.fun", + "uspringcup.com", + "waterbets.ru", + "win-skin.top", + "win-skin.xyz", + "winknifespin.xyz", + "winskin-simple.xyz", + "winskins.top", + "wintheskin.xyz", + "xgamercup.com", +]; diff --git a/src/lib/badwords.ts b/src/lib/badwords.ts new file mode 100644 index 0000000..c5fbf2d --- /dev/null +++ b/src/lib/badwords.ts @@ -0,0 +1,242 @@ +import { BadWords, Severity } from "./common/automod"; + +export default { + /* -------------------------------------------------------------------------- */ + /* Slurs */ + /* -------------------------------------------------------------------------- */ + "faggot": { + severity: Severity.TEMP_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "racial slur", + }, + "nigga": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "racial slur", + }, + "nigger": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "racial slur", + }, + "nigra": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "racial slur", + }, + "retard": { + severity: Severity.TEMP_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "ableist slur", + }, + "retarted": { + severity: Severity.TEMP_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "ableist slur", + }, + "slut": { + severity: Severity.WARN, + ignoreSpaces: false, + ignoreCapitalization: true, + reason: "derogatory term", + }, + "tar baby": { + severity: Severity.TEMP_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "racial slur", + }, + "whore": { + severity: Severity.WARN, + ignoreSpaces: false, + ignoreCapitalization: true, + reason: "derogatory term", + }, + "卍": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "racist symbol", + }, + + /* -------------------------------------------------------------------------- */ + /* Steam Scams */ + /* -------------------------------------------------------------------------- */ + 'Я в тильте, в кс дали статус "Ненадежный"': { + //? I'm on tilt, in the cop they gave the status "Unreliable" + severity: Severity.WARN, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "steam scam phrase", + }, + "hello i am leaving cs:go": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "steam scam phrase", + }, + "hello! I'm done with csgo": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "steam scam phrase", + }, + "hi bro, i'm leaving this fucking game, take my skin": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "steam scam phrase", + }, + "hi friend, today i am leaving this fucking game": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "steam scam phrase", + }, + "hi guys, i'm leaving this fucking game, take my": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "steam scam phrase", + }, + "hi, bro h am leaving cs:go and giving away my skin": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "steam scam phrase", + }, + "hi, bro i am leaving cs:go and giving away my skin": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "steam scam phrase", + }, + "i confirm all exchanges, there won't be enough": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "steam scam phrase", + }, + "i quit csgo": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "steam scam phrase", + }, + "the first three who send a trade": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "steam scam phrase", + }, + "you can choose any skin for yourself": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "steam scam phrase", + }, + + /* -------------------------------------------------------------------------- */ + /* Nitro Scams */ + /* -------------------------------------------------------------------------- */ + "and there is discord hallween's giveaway": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "discord nitro scam phrase", + }, + "discord nitro for free - steam store": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "discord nitro scam phrase", + }, + "free 3 months of discord nitro": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "discord nitro scam phrase", + }, + "free discord nitro airdrop": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "discord nitro scam phrase", + }, + "get 3 months of discord nitro": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "discord nitro scam phrase", + }, + "get discord nitro for free": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "discord nitro scam phrase", + }, + "get free discord nitro from steam": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "discord nitro scam phrase", + }, + "lol, jahjajha free discord nitro for 3 month!!": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "discord nitro scam phrase", + }, + "steam is giving away 3 months of discord nitro for free to all no limited steam users": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "discord nitro scam phrase", + }, + "Лол, бесплатный дискорд нитро на 1 месяц!": { + //? Lol, 1 month free discord nitro! + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "discord nitro scam phrase", + }, + "Airdrop Discord FREE NITRO from Steam —": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "discord nitro scam phrase", + }, + + /* -------------------------------------------------------------------------- */ + /* Misc Scams */ + /* -------------------------------------------------------------------------- */ + "found a cool software that improves the": { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "misc. scam phrase", + }, + "there is a possible chance tomorrow there will be a cyber-attack event where on all social networks including Discord there will be people trying": + { + severity: Severity.WARN, + ignoreSpaces: false, + ignoreCapitalization: true, + reason: "annoying copy pasta", + }, + + /* -------------------------------------------------------------------------- */ + /* Frequently Advertised Discord Severs */ + /* -------------------------------------------------------------------------- */ + "https://discord.gg/7CaCvDXs": { + severity: Severity.TEMP_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: "blacklisted server link", + }, +} as BadWords; diff --git a/src/lib/common/autoMod.ts b/src/lib/common/autoMod.ts new file mode 100644 index 0000000..10bccba --- /dev/null +++ b/src/lib/common/autoMod.ts @@ -0,0 +1,236 @@ +import { Formatters, MessageActionRow, MessageButton, MessageEmbed, TextChannel } from 'discord.js'; +import badLinksArray from '../../lib/badlinks'; +import badLinksSecretArray from '../../lib/badlinks-secret'; // I cannot make this public so just make a new file that export defaults an empty array +import badWords from '../../lib/badwords'; +import { BushButtonInteraction } from '../extensions/discord.js/BushButtonInteraction'; +import { BushMessage } from '../extensions/discord.js/BushMessage'; + +export class AutoMod { + private message: BushMessage; + + public constructor(message: BushMessage) { + this.message = message; + void this.handle(); + } + + private async handle(): Promise<void> { + if (this.message.channel.type === 'DM' || !this.message.guild) return; + if (!(await this.message.guild.hasFeature('automod'))) return; + + const customAutomodPhrases = (await this.message.guild.getSetting('autoModPhases')) ?? {}; + const badLinks: BadWords = {}; + const badLinksSecret: BadWords = {}; + + badLinksArray.forEach((link) => { + badLinks[link] = { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: 'malicious link' + }; + }); + badLinksSecretArray.forEach((link) => { + badLinks[link] = { + severity: Severity.PERM_MUTE, + ignoreSpaces: true, + ignoreCapitalization: true, + reason: 'malicious link' + }; + }); + + const result = { + ...this.checkWords(customAutomodPhrases), + ...this.checkWords((await this.message.guild.hasFeature('excludeDefaultAutomod')) ? {} : badWords), + ...this.checkWords( + (await this.message.guild.hasFeature('excludeAutomodScamLinks')) ? {} : { ...badLinks, ...badLinksSecret } + ) + }; + + if (Object.keys(result).length === 0) return; + + const highestOffence = Object.entries(result) + .map(([key, value]) => ({ word: key, ...value })) + .sort((a, b) => b.severity - a.severity)[0]; + + if (highestOffence.severity === undefined || highestOffence.severity === null) + void this.message.guild.sendLogChannel('error', { + embeds: [ + { + title: 'AutoMod Error', + description: `Unable to find severity information for ${Formatters.inlineCode( + util.discord.escapeInlineCode(highestOffence.word) + )}`, + color: util.colors.error + } + ] + }); + else { + const color = this.punish(highestOffence); + void this.log(highestOffence, color, result); + } + } + + private checkWords(words: BadWords): BadWords { + if (Object.keys(words).length === 0) return {}; + + const matchedWords: BadWords = {}; + for (const word in words) { + const wordOptions = words[word]; + if (this.format(this.message.content, wordOptions) === this.format(word, wordOptions)) { + } + } + return matchedWords; + } + + private format(string: string, wordOptions: BadWordDetails) { + const temp = wordOptions.ignoreCapitalization ? string.toLowerCase() : string; + return wordOptions.ignoreSpaces ? temp.replace(/ /g, '') : temp; + } + + private punish(highestOffence: BadWordDetails & { word: string }) { + let color; + switch (highestOffence.severity) { + case Severity.DELETE: { + color = util.colors.lightGray; + void this.message.delete().catch((e) => deleteError.bind(this, e)); + break; + } + case Severity.WARN: { + color = util.colors.yellow; + void this.message.delete().catch((e) => deleteError.bind(this, e)); + void this.message.member?.warn({ + moderator: this.message.guild!.me!, + reason: `[AutoMod] ${highestOffence.reason}` + }); + break; + } + case Severity.TEMP_MUTE: { + color = util.colors.orange; + void this.message.delete().catch((e) => deleteError.bind(this, e)); + void this.message.member?.mute({ + moderator: this.message.guild!.me!, + reason: `[AutoMod] ${highestOffence.reason}`, + duration: 900_000 // 15 minutes + }); + break; + } + case Severity.PERM_MUTE: { + color = util.colors.red; + void this.message.delete().catch((e) => deleteError.bind(this, e)); + void this.message.member?.mute({ + moderator: this.message.guild!.me!, + reason: `[AutoMod] ${highestOffence.reason}`, + duration: 900_000 // 15 minutes + }); + break; + } + default: { + throw new Error('Invalid severity'); + } + } + + return color; + + async function deleteError(this: AutoMod, e: Error | any) { + this.message.guild?.sendLogChannel('error', { + embeds: [ + { + title: 'AutoMod Error', + description: `Unable to delete triggered message.`, + fields: [{ name: 'Error', value: await util.codeblock(`${e.stack ?? e}`, 1024, 'js', true) }], + color: util.colors.error + } + ] + }); + } + } + + private async log(highestOffence: BadWordDetails & { word: string }, color: `#${string}`, offences: BadWords) { + void client.console.info( + 'autoMod', + `Severity <<${highestOffence.severity}>> action performed on <<${this.message.author.tag}>> (<<${ + this.message.author.id + }>>) in <<#${(this.message.channel as TextChannel).name}>> in <<${this.message.guild!.name}>>` + ); + + return await this.message.guild!.sendLogChannel('automod', { + embeds: [ + new MessageEmbed() + .setTitle(`[Severity ${highestOffence.severity}] Automod Action Performed`) + .setDescription( + `**User:** ${this.message.author} (${this.message.author.tag})\n**Sent From**: <#${ + this.messa |
