aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIRONM00N <64110067+IRONM00N@users.noreply.github.com>2021-10-12 20:27:37 -0400
committerIRONM00N <64110067+IRONM00N@users.noreply.github.com>2021-10-12 20:27:37 -0400
commitba2d7b7db0a627234ed08de9d6bec8cb675404a7 (patch)
tree9ade9ed549b52eac3f2966a5cee5478267eca7c4 /src
parentcac6abf3efd563b83f8f0ce70ce4bcfa5ada1a27 (diff)
downloadtanzanite-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.ts2
-rw-r--r--src/commands/moderation/ban.ts5
-rw-r--r--src/commands/moderation/kick.ts3
-rw-r--r--src/commands/moderation/modlog.ts2
-rw-r--r--src/commands/moderation/mute.ts3
-rw-r--r--src/commands/moderation/unmute.ts3
-rw-r--r--src/commands/moderation/warn.ts3
-rw-r--r--src/lib/badlinks.ts410
-rw-r--r--src/lib/badwords.ts242
-rw-r--r--src/lib/common/autoMod.ts236
-rw-r--r--src/lib/common/moderation.ts181
-rw-r--r--src/lib/extensions/discord-akairo/BushClientUtil.ts361
-rw-r--r--src/lib/extensions/discord.js/BushGuild.ts22
-rw-r--r--src/lib/extensions/discord.js/BushGuildMember.ts25
-rw-r--r--src/lib/models/Guild.ts25
-rw-r--r--src/listeners/client/interactionCreate.ts5
-rw-r--r--src/listeners/message/automodCreate.ts113
-rw-r--r--src/listeners/message/automodUpdate.ts4
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