aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIRONM00N <64110067+IRONM00N@users.noreply.github.com>2022-01-08 20:08:16 -0500
committerIRONM00N <64110067+IRONM00N@users.noreply.github.com>2022-01-08 20:08:16 -0500
commite0531157a745ac6178d55cc159b5932fa36ff20f (patch)
treea8de340d0c48269619e9bfde536932eb08556593
parent0e160ae77477f0986a02746e84158329299f438f (diff)
downloadtanzanite-e0531157a745ac6178d55cc159b5932fa36ff20f.tar.gz
tanzanite-e0531157a745ac6178d55cc159b5932fa36ff20f.tar.bz2
tanzanite-e0531157a745ac6178d55cc159b5932fa36ff20f.zip
database migrations - use jsonb over text + JSON.parse, refactor bad word & automod - store word in shared db
closes: #53
-rw-r--r--src/commands/config/config.ts2
-rw-r--r--src/commands/dev/eval.ts18
-rw-r--r--src/commands/dev/test.ts10
-rw-r--r--src/lib/badlinks.ts15
-rw-r--r--src/lib/badwords.ts1006
-rw-r--r--src/lib/common/AutoMod.ts86
-rw-r--r--src/lib/extensions/discord-akairo/BushClient.ts8
-rw-r--r--src/lib/extensions/discord-akairo/BushClientUtil.ts4
-rw-r--r--src/lib/models/Global.ts9
-rw-r--r--src/lib/models/Guild.ts42
-rw-r--r--src/lib/models/ModLog.ts5
-rw-r--r--src/lib/models/Shared.ts42
-rw-r--r--src/lib/models/Stat.ts13
-rw-r--r--src/lib/models/StickyRole.ts3
-rw-r--r--src/lib/models/__helpers.ts65
-rw-r--r--src/lib/utils/BushCache.ts9
16 files changed, 710 insertions, 627 deletions
diff --git a/src/commands/config/config.ts b/src/commands/config/config.ts
index 9d8ba60..b7b3f0e 100644
--- a/src/commands/config/config.ts
+++ b/src/commands/config/config.ts
@@ -324,7 +324,7 @@ export default class ConfigCommand extends BushCommand {
return Array.isArray(feat)
? feat.length
- ? feat.map(func).join('\n')
+ ? (<string[]>feat).map(func).join('\n')
: '[Empty Array]'
: feat !== null
? func(feat)
diff --git a/src/commands/dev/eval.ts b/src/commands/dev/eval.ts
index 5b2f27a..4eb25dc 100644
--- a/src/commands/dev/eval.ts
+++ b/src/commands/dev/eval.ts
@@ -8,6 +8,7 @@ import {
Guild,
Level,
ModLog,
+ Shared,
StickyRole,
type ArgType
} from '#lib';
@@ -132,6 +133,15 @@ export default class EvalCommand extends BushCommand {
prompt: 'Would you like to inspect the prototype chain to find methods?',
slashType: 'BOOLEAN',
optional: true
+ },
+ {
+ id: 'async',
+ description: 'Whether or not to wrap the code in an async function.',
+ match: 'flag',
+ flag: '--async',
+ prompt: 'Would you like to wrap the code in an async function?',
+ slashType: 'BOOLEAN',
+ optional: true
}
],
slash: true,
@@ -144,8 +154,8 @@ export default class EvalCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
args: {
- sel_depth: ArgType<'integer'>;
code: ArgType<'string'>;
+ sel_depth: ArgType<'integer'>;
sudo: ArgType<'boolean'>;
silent: ArgType<'boolean'>;
deleteMSG: ArgType<'boolean'>;
@@ -153,6 +163,7 @@ export default class EvalCommand extends BushCommand {
hidden: ArgType<'boolean'>;
show_proto: ArgType<'boolean'>;
show_methods: ArgType<'boolean'>;
+ async: ArgType<'boolean'>;
}
) {
if (!message.author.isOwner())
@@ -161,7 +172,8 @@ export default class EvalCommand extends BushCommand {
await message.interaction.deferReply({ ephemeral: args.silent });
}
const isTypescript = args.typescript || args.code.includes('```ts');
- const rawCode = args.code.replace(/[“”]/g, '"').replace(/```*(?:js|ts)?/g, '');
+ let rawCode = args.code.replace(/[“”]/g, '"').replace(/```*(?:js|ts)?/g, '');
+ if (args.async) rawCode = `(async () => {${rawCode}})()`;
const code: { ts: string | null; js: string; lang: 'ts' | 'js' } = {
ts: isTypescript ? rawCode : null,
@@ -237,4 +249,4 @@ export default class EvalCommand extends BushCommand {
}
}
-/** @typedef {ActivePunishment|Global|Guild|Level|ModLog|StickyRole|ButtonInteraction|Collection|Collector|CommandInteraction|ContextMenuInteraction|DMChannel|Emoji|Interaction|InteractionCollector|Message|MessageActionRow|MessageAttachment|MessageButton|MessageCollector|MessageSelectMenu|ReactionCollector|Util|Canvas} VSCodePleaseDontRemove */
+/** @typedef {ActivePunishment|Global|Guild|Level|ModLog|StickyRole|ButtonInteraction|Collection|Collector|CommandInteraction|ContextMenuInteraction|DMChannel|Emoji|Interaction|InteractionCollector|Message|MessageActionRow|MessageAttachment|MessageButton|MessageCollector|MessageSelectMenu|ReactionCollector|Util|Canvas|Shared} VSCodePleaseDontRemove */
diff --git a/src/commands/dev/test.ts b/src/commands/dev/test.ts
index 2c4e34d..50532f8 100644
--- a/src/commands/dev/test.ts
+++ b/src/commands/dev/test.ts
@@ -1,6 +1,8 @@
-import { BushCommand, ButtonPaginator, type BushMessage } from '#lib';
+import { BushCommand, ButtonPaginator, Shared, type BushMessage } from '#lib';
import { MessageActionRow, MessageButton, MessageEmbed, type ApplicationCommand, type Collection } from 'discord.js';
import { MessageButtonStyles } from 'discord.js/typings/enums';
+import badLinksSecretArray from '../../lib/badlinks-secret.js';
+import badLinksArray from '../../lib/badlinks.js';
export default class TestCommand extends BushCommand {
public constructor() {
@@ -148,6 +150,12 @@ export default class TestCommand extends BushCommand {
return await message.util.reply(`${util.emojis.success} Removed guild commands and global commands.`);
} else if (['drop down', 'drop downs', 'select menu', 'select menus'].includes(args?.feature?.toLowerCase())) {
+ } else if (['sync links'].includes(args?.feature?.toLowerCase())) {
+ const row = (await Shared.findByPk(0))!;
+ row.badLinks = badLinksArray;
+ row.badLinksSecret = badLinksSecretArray;
+ await row.save();
+ return await message.util.reply(`${util.emojis.success} Updated bad links.`);
}
return await message.util.reply(responses[Math.floor(Math.random() * responses.length)]);
}
diff --git a/src/lib/badlinks.ts b/src/lib/badlinks.ts
index 6cabd65..3a5b171 100644
--- a/src/lib/badlinks.ts
+++ b/src/lib/badlinks.ts
@@ -628,6 +628,7 @@ export default [
"discardapp.fun",
"disccor.com",
"disccord-apps.com",
+ "disccord-appss.ru",
"disccord-club.com",
"disccord-gift.com",
"disccord.gg",
@@ -638,8 +639,10 @@ export default [
"disccords.com",
"disccrd.gifts",
"discford.com",
+ "dischrd.com",
"discird.gg",
"discird.me",
+ "discjrd.com",
"disckordapp.com",
"disclord.com",
"disclrd.com",
@@ -688,6 +691,7 @@ export default [
"disconrd.com",
"discontro.ru",
"discoogs.com",
+ "discoord-apps.com",
"discoord-nitro.com",
"discoord.space",
"discor-dnitro.fun",
@@ -1024,6 +1028,7 @@ export default [
"discord-tech.com",
"discord-tester.com",
"discord-to.com",
+ "discord-true.com",
"discord-trustandsafety.com",
"discord-up.ru",
"discord-verif.ga",
@@ -1033,6 +1038,7 @@ export default [
"discord-verify.com",
"discord-verify.ru",
"discord-vetify.com",
+ "discord-web.co",
"discord-xnitro.com",
"discord.1nitro.club",
"discord.ac",
@@ -1167,6 +1173,7 @@ export default [
"discorddiscord.com",
"discorddrop.com",
"discorde-gift.com",
+ "discorde-gifte.com",
"discorde-nitro.com",
"discorde.gift",
"discorde.xyz",
@@ -1496,6 +1503,8 @@ export default [
"disordnitros.gifts",
"disordnitros.xyz",
"disordnltro.xyz",
+ "disordnltros.com",
+ "disordnltros.com",
"disordnltros.gifts",
"disordsnitro.gifts",
"disordsnitros.gifts",
@@ -1680,6 +1689,7 @@ export default [
"dlscrod.ru.com",
"dlscrodapp.ru",
"dlsordnitro.gifts",
+ "dlsordnltros.gifts",
"dmarkef.com",
"dmarket-place.pp.ua",
"dmcordsteamnitro.de",
@@ -2128,6 +2138,8 @@ export default [
"ggnavincere.xyz",
"ggtour.ru",
"ghostgame.ru",
+ "gif-discord.com",
+ "gife-discorde.com",
"gift-discord.online",
"gift-discord.ru",
"gift-discord.shop",
@@ -3987,7 +3999,6 @@ export default [
"steamcommunity.cloud",
"steamcommunity.cn",
"steamcommunity.co.ua",
- // "steamcommunity.co",
"steamcommunity.com-id-k4tushatwitchbabydota.ru",
"steamcommunity.com.ru",
"steamcommunity.comlappl251490lrust.ru",
@@ -4703,6 +4714,7 @@ export default [
"steamnconmunity.work",
"steamnconnmunity.com",
"steamnitro.com",
+ "steamnitrol.com",
"steamnitros.com",
"steamnitros.ru",
"steamnltro.com",
@@ -6879,4 +6891,5 @@ export default [
"zipsetgo.com",
"zonewarco.org.ru",
"zonewarco.org.ru",
+ // "steamcommunity.co",
];
diff --git a/src/lib/badwords.ts b/src/lib/badwords.ts
index 90f5a64..326e4b8 100644
--- a/src/lib/badwords.ts
+++ b/src/lib/badwords.ts
@@ -4,488 +4,572 @@ export default {
/* -------------------------------------------------------------------------- */
/* Slurs */
/* -------------------------------------------------------------------------- */
- "faggot": {
- severity: Severity.TEMP_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "racial slur",
- regex: false,
- },
- "nigga": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "racial slur",
- regex: false,
- },
- "nigger": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "racial slur",
- regex: false,
- },
- "nigra": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "racial slur",
- regex: false,
- },
- "retard": {
- severity: Severity.TEMP_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "ableist slur",
- regex: false,
- },
- "retarted": {
- severity: Severity.TEMP_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "ableist slur",
- regex: false,
- },
- "slut": {
- severity: Severity.WARN,
- ignoreSpaces: false,
- ignoreCapitalization: true,
- reason: "derogatory term",
- regex: false,
- },
- "tar baby": {
- severity: Severity.TEMP_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "racial slur",
- regex: false,
- },
- "whore": {
- severity: Severity.WARN,
- ignoreSpaces: false,
- ignoreCapitalization: true,
- reason: "derogatory term",
- regex: false,
- },
- "卍": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "racist symbol",
- regex: false,
- },
- "space movie 1992": {
- //? N word
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "racial slur",
- regex: false,
- },
+ "Slurs": [
+ {
+ match: "faggot",
+ severity: Severity.TEMP_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "racial slur",
+ regex: false,
+ },
+ {
+ match: "nigga",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "racial slur",
+ regex: false,
+ },
+ {
+ match: "nigger",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "racial slur",
+ regex: false,
+ },
+ {
+ match: "nigra",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "racial slur",
+ regex: false,
+ },
+ {
+ match: "retard",
+ severity: Severity.TEMP_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "ableist slur",
+ regex: false,
+ },
+ {
+ match: "retarted",
+ severity: Severity.TEMP_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "ableist slur",
+ regex: false,
+ },
+ {
+ match: "slut",
+ severity: Severity.WARN,
+ ignoreSpaces: false,
+ ignoreCapitalization: true,
+ reason: "derogatory term",
+ regex: false,
+ },
+ {
+ match: "tar baby",
+ severity: Severity.TEMP_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "racial slur",
+ regex: false,
+ },
+ {
+ match: "whore",
+ severity: Severity.WARN,
+ ignoreSpaces: false,
+ ignoreCapitalization: true,
+ reason: "derogatory term",
+ regex: false,
+ },
+ {
+ match: "卍",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "racist symbol",
+ regex: false,
+ },
+ {
+ //? N word
+ match: "space movie 1992",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "racial slur",
+ regex: false,
+ },
+ ],
/* -------------------------------------------------------------------------- */
/* 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",
- regex: false,
- },
- "hello i am leaving cs:go": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "steam scam phrase",
- regex: false,
- },
- "hello! I'm done with csgo": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "steam scam phrase",
- regex: false,
- },
- "hi bro, i'm leaving this fucking game, take my skin": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "steam scam phrase",
- regex: false,
- },
- "hi friend, today i am leaving this fucking game": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "steam scam phrase",
- regex: false,
- },
- "hi guys, i'm leaving this fucking game, take my": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "steam scam phrase",
- regex: false,
- },
- "hi, bro h am leaving cs:go and giving away my skin": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "steam scam phrase",
- regex: false,
- },
- "hi, bro i am leaving cs:go and giving away my skin": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "steam scam phrase",
- regex: false,
- },
- "i confirm all exchanges, there won't be enough": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "steam scam phrase",
- regex: false,
- },
- "i quit csgo": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "steam scam phrase",
- regex: false,
- },
- "the first three who send a trade": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "steam scam phrase",
- regex: false,
- },
- "you can choose any skin for yourself": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "steam scam phrase",
- regex: false,
- },
- "Hey, I'm leaving for the army and giving the skins": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "steam scam phrase",
- regex: false,
- },
- "fuck this trash called CS:GO, deleted,": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "steam scam phrase",
- regex: false,
- },
+ "Steam Scams": [
+ {
+ //? I'm on tilt, in the cop they gave the status "Unreliable"
+ match: 'Я в тильте, в кс дали статус "Ненадежный"',
+ severity: Severity.WARN,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "steam scam phrase",
+ regex: false,
+ },
+ {
+ match: "hello i am leaving cs:go",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "steam scam phrase",
+ regex: false,
+ },
+ {
+ match: "hello! I'm done with csgo",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "steam scam phrase",
+ regex: false,
+ },
+ {
+ match: "hi bro, i'm leaving this fucking game, take my skin",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "steam scam phrase",
+ regex: false,
+ },
+ {
+ match: "hi friend, today i am leaving this fucking game",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "steam scam phrase",
+ regex: false,
+ },
+ {
+ match: "hi guys, i'm leaving this fucking game, take my",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "steam scam phrase",
+ regex: false,
+ },
+ {
+ match: "hi, bro h am leaving cs:go and giving away my skin",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "steam scam phrase",
+ regex: false,
+ },
+ {
+ match: "hi, bro i am leaving cs:go and giving away my skin",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "steam scam phrase",
+ regex: false,
+ },
+ {
+ match: "i confirm all exchanges, there won't be enough",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "steam scam phrase",
+ regex: false,
+ },
+ {
+ match: "i quit csgo",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "steam scam phrase",
+ regex: false,
+ },
+ {
+ match: "the first three who send a trade",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "steam scam phrase",
+ regex: false,
+ },
+ {
+ match: "you can choose any skin for yourself",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "steam scam phrase",
+ regex: false,
+ },
+ {
+ match: "Hey, I'm leaving for the army and giving the skins",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "steam scam phrase",
+ regex: false,
+ },
+ {
+ match: "fuck this trash called CS:GO, deleted,",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "steam scam phrase",
+ regex: false,
+ },
+ ],
/* -------------------------------------------------------------------------- */
/* Nitro Scams */
/* -------------------------------------------------------------------------- */
- "and there is discord hallween's giveaway": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "discord nitro for free - steam store": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "free 3 months of discord nitro": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "free discord nitro airdrop": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "get 3 months of discord nitro": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "get discord nitro for free": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "get free discord nitro from steam": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "lol, jahjajha free discord nitro for 3 month!!": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "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",
- regex: false,
- },
- "Лол, бесплатный дискорд нитро на 1 месяц!": {
- //? Lol, 1 month free discord nitro!
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "Airdrop Discord FREE NITRO from Steam —": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "take nitro faster, it's already running out": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: false,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "only the first 10 people will have time to take nitro": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: false,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "Discord is giving away nitro!": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: false,
- ignoreCapitalization: false,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "Free gift discord nitro for 1 month!": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: false,
- ignoreCapitalization: false,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "Hi i claim this nitro for free 3 months lol!": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "bro watch this, working nitro gen": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: false,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "Free distribution of discord nitro for 3 months from steam!": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "Get 3 Months of Discord Nitro. Personalize your profile, screen share in HD, upgrade your emojis, and more!": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "Steam is giving away free discord nitro, have time to pick up at my link": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "Airdrop Discord NITRO with": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "Check this lol, there nitro is handed out for free, take it until everything is sorted out": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "A free Discord Nitro | Steam Store Discord Nitro Distribution.": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "Xbox gives away discord nitro for free": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "airdrop discord nitro by steam": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "3 месяца нитро бесплатно от стима, забирайте тоже": {
- //? 3 months nitro free from steam, take too
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "Free distributiοn of discοrd nitrο for 3 months from steаm!": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "Free discord nitro for 1 month!": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "I got some nitro left over here": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "Hey, steam gived nitro": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "nitro giveaway by steam, take it": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "3 months nitro from styme,": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "XBOX and DISCORD are giving away free NITRO FULL for a month.": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "Hi,take the Discord Nitro for free": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "Дискорд нитро получил бесплатно,забирай пока не поздно": {
- //? Discord nitro got free, take it before it's too late
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "1 month nitro for free": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "Gifts for the new year, nitro for 3 months": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
- "1 month nitro from steam, take it guys": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "discord nitro scam phrase",
- regex: false,
- },
+ "Nitro Scams": [
+ {
+ match: "and there is discord hallween's giveaway",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "discord nitro for free - steam store",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "free 3 months of discord nitro",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "free discord nitro airdrop",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "get 3 months of discord nitro",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "get discord nitro for free",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "get free discord nitro from steam",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "lol, jahjajha free discord nitro for 3 month!!",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "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",
+ regex: false,
+ },
+ {
+ //? Lol, 1 month free discord nitro!
+ match: "Лол, бесплатный дискорд нитро на 1 месяц!",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "Airdrop Discord FREE NITRO from Steam —",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "take nitro faster, it's already running out",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: false,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "only the first 10 people will have time to take nitro",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: false,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "Discord is giving away nitro!",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: false,
+ ignoreCapitalization: false,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "Free gift discord nitro for 1 month!",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: false,
+ ignoreCapitalization: false,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "Hi i claim this nitro for free 3 months lol!",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "bro watch this, working nitro gen",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: false,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "Free distribution of discord nitro for 3 months from steam!",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "Get 3 Months of Discord Nitro. Personalize your profile, screen share in HD, upgrade your emojis, and more!",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "Steam is giving away free discord nitro, have time to pick up at my link",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "Airdrop Discord NITRO with",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "Check this lol, there nitro is handed out for free, take it until everything is sorted out",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "A free Discord Nitro | Steam Store Discord Nitro Distribution.",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "Xbox gives away discord nitro for free",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "airdrop discord nitro by steam",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ //? 3 months nitro free from steam, take too
+ match: "3 месяца нитро бесплатно от стима, забирайте тоже",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "Free distributiοn of discοrd nitrο for 3 months from steаm!",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "Free discord nitro for 1 month!",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "I got some nitro left over here",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "Hey, steam gived nitro",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "nitro giveaway by steam, take it",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "3 months nitro from styme,",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "XBOX and DISCORD are giving away free NITRO FULL for a month.",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "Hi,take the Discord Nitro for free",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ //? Discord nitro got free, take it before it's too late
+ match: "Дискорд нитро получил бесплатно,забирай пока не поздно",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "1 month nitro for free",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "Gifts for the new year, nitro for 3 months",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "1 month nitro from steam, take it guys",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ {
+ match: "Hello, discord and steam are giving away nitro, take it away",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "discord nitro scam phrase",
+ regex: false,
+ },
+ ],
/* -------------------------------------------------------------------------- */
/* Misc Scams */
/* -------------------------------------------------------------------------- */
- "found a cool software that improves the": {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "misc. scam phrase",
- regex: false,
- },
- "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":
+ "Misc Scams": [
{
+ match: "found a cool software that improves the",
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "misc. scam phrase",
+ regex: false,
+ },
+ {
+ match:
+ "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",
regex: false,
},
+ ],
/* -------------------------------------------------------------------------- */
/* Frequently Advertised Discord Severs */
/* -------------------------------------------------------------------------- */
- "https://discord.gg/7CaCvDXs": {
- severity: Severity.TEMP_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: "blacklisted server link",
- regex: false,
- },
+ "Frequently Advertised Discord Severs": [
+ {
+ match: "https://discord.gg/7CaCvDXs",
+ severity: Severity.TEMP_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: "blacklisted server link",
+ regex: false,
+ },
+ ],
} as BadWords;
diff --git a/src/lib/common/AutoMod.ts b/src/lib/common/AutoMod.ts
index 1bc26fb..595f025 100644
--- a/src/lib/common/AutoMod.ts
+++ b/src/lib/common/AutoMod.ts
@@ -1,8 +1,5 @@
import { Moderation, type BushButtonInteraction, type BushMessage } from '#lib';
import { GuildMember, MessageActionRow, MessageButton, MessageEmbed, type TextChannel } from 'discord.js';
-import badLinksSecretArray from '../badlinks-secret.js'; // I cannot make this public so just make a new file that export defaults an empty array
-import badLinksArray from '../badlinks.js';
-import badWords from '../badwords.js';
/**
* Handles auto moderation functionality.
@@ -36,39 +33,40 @@ export class AutoMod {
if (this.message.author.bot) return;
if (this.message.author.isOwner()) return;
- const customAutomodPhrases = (await this.message.guild.getSetting('autoModPhases')) ?? {};
- const badLinks: BadWords = {};
+ const badLinksArray = util.getShared('badLinks');
+ const badLinksSecretArray = util.getShared('badLinksSecret');
+ const badWordsRaw = util.getShared('badWords');
+ const customAutomodPhrases = (await this.message.guild.getSetting('autoModPhases')) ?? [];
const uniqueLinks = [...new Set([...badLinksArray, ...badLinksSecretArray])];
- uniqueLinks.forEach((link) => {
- badLinks[link] = {
- severity: Severity.PERM_MUTE,
- ignoreSpaces: true,
- ignoreCapitalization: true,
- reason: 'malicious link',
- regex: false
- };
- });
+ const badLinks: BadWordDetails[] = uniqueLinks.map((link) => ({
+ match: link,
+ severity: Severity.PERM_MUTE,
+ ignoreSpaces: true,
+ ignoreCapitalization: true,
+ reason: 'malicious link',
+ regex: false
+ }));
+
+ const parsedBadWords = Object.values(badWordsRaw).flat();
const result = {
...this.checkWords(customAutomodPhrases),
- ...this.checkWords((await this.message.guild.hasFeature('excludeDefaultAutomod')) ? {} : badWords),
- ...this.checkWords((await this.message.guild.hasFeature('excludeAutomodScamLinks')) ? {} : badLinks)
+ ...this.checkWords((await this.message.guild.hasFeature('excludeDefaultAutomod')) ? [] : parsedBadWords),
+ ...this.checkWords((await this.message.guild.hasFeature('excludeAutomodScamLinks')) ? [] : badLinks)
};
- if (Object.keys(result).length === 0) return;
+ if (result.length === 0) return;
- const highestOffence = Object.entries(result)
- .map(([key, value]) => ({ word: key, ...value }))
- .sort((a, b) => b.severity - a.severity)[0];
+ const highestOffence = result.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 ${util.format.inlineCode(highestOffence.word)}`,
+ description: `Unable to find severity information for ${util.format.inlineCode(highestOffence.match)}`,
color: util.colors.error
}
]
@@ -86,19 +84,18 @@ export class AutoMod {
* @param words The words to check for
* @returns The blacklisted words found in the message
*/
- 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 (wordOptions.regex) {
- if (new RegExp(word).test(this.format(word, wordOptions))) {
- matchedWords[word] = wordOptions;
+ private checkWords(words: BadWordDetails[]): BadWordDetails[] {
+ if (words.length === 0) return [];
+
+ const matchedWords: BadWordDetails[] = [];
+ for (const word of words) {
+ if (word.regex) {
+ if (new RegExp(word.match).test(this.format(word.match, word))) {
+ matchedWords.push(word);
}
} else {
- if (this.format(this.message.content, wordOptions).includes(this.format(word, wordOptions))) {
- matchedWords[word] = wordOptions;
+ if (this.format(this.message.content, word).includes(this.format(word.match, word))) {
+ matchedWords.push(word);
}
}
}
@@ -130,7 +127,7 @@ export class AutoMod {
includes('check this lol') ||
includes('airdrop')
) {
- const color = this.punish({ severity: Severity.TEMP_MUTE, reason: 'everyone mention and scam phrase' } as HighestOffence);
+ const color = this.punish({ severity: Severity.TEMP_MUTE, reason: 'everyone mention and scam phrase' } as BadWordDetails);
void this.message.guild!.sendLogChannel('automod', {
embeds: [
new MessageEmbed()
@@ -173,7 +170,7 @@ export class AutoMod {
* @param highestOffence The highest offence to punish the user for
* @returns The color of the embed that the log should, based on the severity of the offence
*/
- private punish(highestOffence: HighestOffence) {
+ private punish(highestOffence: BadWordDetails) {
let color;
switch (highestOffence.severity) {
case Severity.DELETE: {
@@ -241,7 +238,7 @@ export class AutoMod {
* @param color The color that the log embed should be (based on the severity)
* @param offences The other offences that were also matched in the message
*/
- private async log(highestOffence: HighestOffence, color: `#${string}`, offences: BadWords) {
+ private async log(highestOffence: BadWordDetails, color: `#${string}`, offences: BadWordDetails[]) {
void client.console.info(
'autoMod',
`Severity <<${highestOffence.severity}>> action performed on <<${this.message.author.tag}>> (<<${
@@ -360,7 +357,12 @@ export const enum Severity {
/**
* Details about a blacklisted word
*/
-interface BadWordDetails {
+export interface BadWordDetails {
+ /**
+ * The word that is blacklisted
+ */
+ match: string;
+
/**
* The severity of the word
*/
@@ -387,19 +389,9 @@ interface BadWordDetails {
regex: boolean;
}
-interface HighestOffence extends BadWordDetails {
- /**
- * The word that is blacklisted
- */
- word: string;
-}
-
/**
* Blacklisted words mapped to their details
*/
export interface BadWords {
- /**
- * The blacklisted word
- */
- [key: string]: BadWordDetails;
+ [category: string]: BadWordDetails[];
}
diff --git a/src/lib/extensions/discord-akairo/BushClient.ts b/src/lib/extensions/discord-akairo/BushClient.ts
index 65b60eb..cb1e50b 100644
--- a/src/lib/extensions/discord-akairo/BushClient.ts
+++ b/src/lib/extensions/discord-akairo/BushClient.ts
@@ -419,7 +419,11 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re
Stat.initModel(this.sharedDB);
Global.initModel(this.sharedDB);
Shared.initModel(this.sharedDB);
- await this.sharedDB.sync({ alter: true }); // Sync all tables to fix everything if updated
+ await this.sharedDB.sync({
+ // Sync all tables to fix everything if updated
+ // if another instance restarts we don't want to overwrite new changes made in development
+ alter: this.config.isDevelopment ? true : false
+ });
await this.console.success('startup', `Successfully connected to <<shared database>>.`, false);
} catch (e) {
await this.console.error(
@@ -473,7 +477,7 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re
public override isSuperUser(user: BushUserResolvable): boolean {
const userID = this.users.resolveId(user)!;
- return !!client.cache.shared.superUsers.includes(userID) || this.config.owners.includes(userID);
+ return client.cache.shared.superUsers.includes(userID) || this.config.owners.includes(userID);
}
}
diff --git a/src/lib/extensions/discord-akairo/BushClientUtil.ts b/src/lib/extensions/discord-akairo/BushClientUtil.ts
index cdb883d..3e066c8 100644
--- a/src/lib/extensions/discord-akairo/BushClientUtil.ts
+++ b/src/lib/extensions/discord-akairo/BushClientUtil.ts
@@ -476,7 +476,7 @@ export class BushClientUtil extends ClientUtil {
* @param key The key of the element in the shared cache to update.
* @param value The value to add/remove from the array.
*/
- public async insertOrRemoveFromShared<K extends keyof typeof client['cache']['shared']>(
+ public async insertOrRemoveFromShared<K extends Exclude<keyof typeof client['cache']['shared'], 'badWords'>>(
action: 'add' | 'remove',
key: K,
value: typeof client['cache']['shared'][K][0]
@@ -510,7 +510,7 @@ export class BushClientUtil extends ClientUtil {
* @param key The key in the shared cache to update.
* @param value The value to set the key to.
*/
- public async setShared<K extends keyof typeof client['cache']['shared']>(
+ public async setShared<K extends Exclude<keyof typeof client['cache']['shared'], 'badWords'>>(
key: K,
value: typeof client['cache']['shared'][K]
): Promise<Shared | void> {
diff --git a/src/lib/models/Global.ts b/src/lib/models/Global.ts
index 1deb090..8e467f6 100644
--- a/src/lib/models/Global.ts
+++ b/src/lib/models/Global.ts
@@ -1,7 +1,6 @@
import { type Snowflake } from 'discord.js';
import { type Sequelize } from 'sequelize';
import { BaseModel } from './BaseModel.js';
-import { jsonArray } from './__helpers.js';
const { DataTypes } = (await import('sequelize')).default;
export interface GlobalModel {
@@ -54,10 +53,10 @@ export class Global extends BaseModel<GlobalModel, GlobalModelCreationAttributes
Global.init(
{
environment: { type: DataTypes.STRING, primaryKey: true },
- disabledCommands: jsonArray('disabledCommands'),
- blacklistedUsers: jsonArray('blacklistedUsers'),
- blacklistedGuilds: jsonArray('blacklistedGuilds'),
- blacklistedChannels: jsonArray('blacklistedChannels')
+ disabledCommands: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ blacklistedUsers: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ blacklistedGuilds: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ blacklistedChannels: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] }
},
{ sequelize }
);
diff --git a/src/lib/models/Guild.ts b/src/lib/models/Guild.ts
index 80bd119..34f6747 100644
--- a/src/lib/models/Guild.ts
+++ b/src/lib/models/Guild.ts
@@ -1,10 +1,9 @@
import { ExcludeEnum, type Snowflake } from 'discord.js';
import { ChannelTypes } from 'discord.js/typings/enums';
import { type Sequelize } from 'sequelize';
-import { type BadWords } from '../common/AutoMod.js';
+import { BadWordDetails } from '../common/AutoMod.js';
import { type BushClient } from '../extensions/discord-akairo/BushClient.js';
import { BaseModel } from './BaseModel.js';
-import { jsonArray, jsonObject } from './__helpers.js';
const { DataTypes } = (await import('sequelize')).default;
export interface GuildModel {
@@ -18,7 +17,7 @@ export interface GuildModel {
punishmentEnding: string;
disabledCommands: string[];
lockdownChannels: Snowflake[];
- autoModPhases: BadWords;
+ autoModPhases: BadWordDetails[];
enabledFeatures: GuildFeatures[];
joinRoles: Snowflake[];
logChannels: LogChannelDB;
@@ -39,7 +38,7 @@ export interface GuildModelCreationAttributes {
punishmentEnding?: string;
disabledCommands?: string[];
lockdownChannels?: Snowflake[];
- autoModPhases?: BadWords;
+ autoModPhases?: BadWordDetails[];
enabledFeatures?: GuildFeatures[];
joinRoles?: Snowflake[];
logChannels?: LogChannelDB;
@@ -103,7 +102,7 @@ export class Guild extends BaseModel<GuildModel, GuildModelCreationAttributes> i
/**
* Custom automod phases
*/
- public declare autoModPhases: BadWords;
+ public declare autoModPhases: BadWordDetails[];
/**
* The features enabled in a guild
@@ -149,24 +148,27 @@ export class Guild extends BaseModel<GuildModel, GuildModelCreationAttributes> i
{
id: { type: DataTypes.STRING, primaryKey: true },
prefix: { type: DataTypes.TEXT, allowNull: false, defaultValue: client.config.prefix },
- autoPublishChannels: jsonArray('autoPublishChannels'),
- blacklistedChannels: jsonArray('blacklistedChannels'),
- blacklistedUsers: jsonArray('blacklistedChannels'),
+ autoPublishChannels: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ blacklistedChannels: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ blacklistedUsers: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
welcomeChannel: { type: DataTypes.STRING, allowNull: true },
muteRole: { type: DataTypes.STRING, allowNull: true },
punishmentEnding: { type: DataTypes.TEXT, allowNull: true },
- disabledCommands: jsonArray('disabledCommands'),
- lockdownChannels: jsonArray('lockdownChannels'),
- autoModPhases: jsonObject('autoModPhases'),
- enabledFeatures: jsonArray(
- 'enabledFeatures',
- Object.keys(guildFeaturesObj).filter((key) => guildFeaturesObj[key as keyof typeof guildFeaturesObj].default)
- ),
- joinRoles: jsonArray('joinRoles'),
- logChannels: jsonObject('logChannels'),
- bypassChannelBlacklist: jsonArray('bypassChannelBlacklist'),
- noXpChannels: jsonArray('noXpChannels'),
- levelRoles: jsonObject('levelRoles'),
+ disabledCommands: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ lockdownChannels: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ autoModPhases: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ enabledFeatures: {
+ type: DataTypes.JSONB,
+ allowNull: false,
+ defaultValue: Object.keys(guildFeaturesObj).filter(
+ (key) => guildFeaturesObj[key as keyof typeof guildFeaturesObj].default
+ )
+ },
+ joinRoles: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ logChannels: { type: DataTypes.JSONB, allowNull: false, defaultValue: {} },
+ bypassChannelBlacklist: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ noXpChannels: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ levelRoles: { type: DataTypes.JSONB, allowNull: false, defaultValue: {} },
levelUpChannel: { type: DataTypes.STRING, allowNull: true }
},
{ sequelize }
diff --git a/src/lib/models/ModLog.ts b/src/lib/models/ModLog.ts
index 7ddd64c..8d6a08c 100644
--- a/src/lib/models/ModLog.ts
+++ b/src/lib/models/ModLog.ts
@@ -2,7 +2,6 @@ import { type Snowflake } from 'discord.js';
import { nanoid } from 'nanoid';
import { type Sequelize } from 'sequelize';
import { BaseModel } from './BaseModel.js';
-import { jsonBoolean } from './__helpers.js';
const { DataTypes } = (await import('sequelize')).default;
export enum ModLogType {
@@ -116,8 +115,8 @@ export class ModLog extends BaseModel<ModLogModel, ModLogModelCreationAttributes
reason: { type: DataTypes.TEXT, allowNull: true },
guild: { type: DataTypes.STRING, references: { model: 'Guilds', key: 'id' } },
evidence: { type: DataTypes.TEXT, allowNull: true },
- pseudo: jsonBoolean('pseudo'),
- hidden: jsonBoolean('hidden')
+ pseudo: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false },
+ hidden: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false }
},
{ sequelize }
);
diff --git a/src/lib/models/Shared.ts b/src/lib/models/Shared.ts
index dd7682b..a240ef9 100644
--- a/src/lib/models/Shared.ts
+++ b/src/lib/models/Shared.ts
@@ -1,18 +1,25 @@
-import { type Sequelize } from 'sequelize';
+import { Snowflake } from 'discord.js';
+import type { Sequelize } from 'sequelize';
+import type { BadWords } from '../common/AutoMod.js';
import { BaseModel } from './BaseModel.js';
-import { jsonArray } from './__helpers.js';
const { DataTypes } = (await import('sequelize')).default;
export interface SharedModel {
primaryKey: 0;
- superUsers: string[];
+ superUsers: Snowflake[];
+ privilegedUsers: Snowflake[];
+ badLinksSecret: string[];
badLinks: string[];
+ badWords: BadWords;
}
export interface SharedModelCreationAttributes {
primaryKey?: 0;
- superUsers?: string[];
+ superUsers?: Snowflake[];
+ privilegedUsers?: Snowflake[];
+ badLinksSecret?: string[];
badLinks?: string[];
+ badWords?: BadWords;
}
export class Shared extends BaseModel<SharedModel, SharedModelCreationAttributes> implements SharedModel {
@@ -24,15 +31,29 @@ export class Shared extends BaseModel<SharedModel, SharedModelCreationAttributes
/**
* Trusted users.
*/
- public declare superUsers: string[];
+ public declare superUsers: Snowflake[];
- //todo
/**
- * Bad links.
+ * Users that have all permissions that devs have except eval.
+ */
+ public declare privilegedUsers: Snowflake[];
+
+ /**
+ * Non-public bad links.
+ */
+ public declare badLinksSecret: string[];
+
+ /**
+ * Public Bad links.
*/
public declare badLinks: string[];
/**
+ * Bad words.
+ */
+ public declare badWords: BadWords;
+
+ /**
* Initializes the model.
* @param sequelize The sequelize instance.
*/
@@ -40,8 +61,11 @@ export class Shared extends BaseModel<SharedModel, SharedModelCreationAttributes
Shared.init(
{
primaryKey: { type: DataTypes.INTEGER, primaryKey: true, validate: { min: 0, max: 0 } },
- superUsers: jsonArray('superUsers'),
- badLinks: jsonArray('badLinks')
+ superUsers: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ privilegedUsers: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ badLinksSecret: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ badLinks: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
+ badWords: { type: DataTypes.JSONB, allowNull: false, defaultValue: {} }
},
{ sequelize, freezeTableName: true }
);
diff --git a/src/lib/models/Stat.ts b/src/lib/models/Stat.ts
index 06ee21f..8f90724 100644
--- a/src/lib/models/Stat.ts
+++ b/src/lib/models/Stat.ts
@@ -1,6 +1,5 @@
import { type Sequelize } from 'sequelize';
import { BaseModel } from './BaseModel.js';
-import { jsonBigint } from './__helpers.js';
const { DataTypes } = (await import('sequelize')).default;
type Environment = 'production' | 'development' | 'beta';
@@ -34,7 +33,17 @@ export class Stat extends BaseModel<StatModel, StatModelCreationAttributes> impl
Stat.init(
{
environment: { type: DataTypes.STRING, primaryKey: true },
- commandsUsed: jsonBigint('commandsUsed')
+ commandsUsed: {
+ type: DataTypes.TEXT,
+ get: function (): bigint {
+ return BigInt(this.getDataValue('commandsUsed'));
+ },
+ set: function (val: bigint) {
+ return this.setDataValue('commandsUsed', <any>`${val}`);
+ },
+ allowNull: false,
+ defaultValue: `${0n}`
+ }
},
{ sequelize }
);
diff --git a/src/lib/models/StickyRole.ts b/src/lib/models/StickyRole.ts
index bbe81ae..4beb4cf 100644
--- a/src/lib/models/StickyRole.ts
+++ b/src/lib/models/StickyRole.ts
@@ -1,7 +1,6 @@
import { type Snowflake } from 'discord.js';
import { type Sequelize } from 'sequelize';
import { BaseModel } from './BaseModel.js';
-import { jsonArray } from './__helpers.js';
const { DataTypes } = (await import('sequelize')).default;
export interface StickyRoleModel {
@@ -47,7 +46,7 @@ export class StickyRole extends BaseModel<StickyRoleModel, StickyRoleModelCreati
{
user: { type: DataTypes.STRING, allowNull: false },
guild: { type: DataTypes.STRING, allowNull: false },
- roles: jsonArray('roles'),
+ roles: { type: DataTypes.JSONB, allowNull: false, defaultValue: [] },
nickname: { type: DataTypes.STRING, allowNull: true }
},
{ sequelize }
diff --git a/src/lib/models/__helpers.ts b/src/lib/models/__helpers.ts
deleted file mode 100644
index bbfe328..0000000
--- a/src/lib/models/__helpers.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import { type Model } from 'sequelize';
-const { DataTypes } = (await import('sequelize')).default;
-
-export function jsonParseGet(this: Model, key: string): any {
- return JSON.parse(this.getDataValue(key));
-}
-export function jsonParseSet(this: Model, key: string, value: any): any {
- return this.setDataValue(key, JSON.stringify(value));
-}
-
-export function jsonObject(key: string): any {
- return {
- type: DataTypes.TEXT,
- get: function (): Record<string, unknown> {
- return jsonParseGet.call(this, key);
- },
- set: function (val: Record<string, unknown>) {
- return jsonParseSet.call(this, key, val);
- },
- allowNull: false,
- defaultValue: '{}'
- };
-}
-
-export function jsonArray(key: string, defaultValue: string[] = []): any {
- return {
- type: DataTypes.TEXT,
- get: function (): string[] {
- return jsonParseGet.call(this, key);
- },
- set: function (val: string[]) {
- return jsonParseSet.call(this, key, val);
- },
- allowNull: false,
- defaultValue: JSON.stringify(defaultValue)
- };
-}
-
-export function jsonBoolean(key: string, defaultVal = false): any {
- return {
- type: DataTypes.STRING,
- get: function (): boolean {
- return jsonParseGet.call(this, key);
- },
- set: function (val: boolean) {
- return jsonParseSet.call(this, key, val);
- },
- allowNull: false,
- defaultValue: `${defaultVal}`
- };
-}
-
-export function jsonBigint(key: string, defaultVal = 0n): any {
- return {
- type: DataTypes.TEXT,
- get: function (): bigint {
- return BigInt(this.getDataValue(key));
- },
- set: function (val: bigint) {
- return this.setDataValue(key, `${val}`);
- },
- allowNull: false,
- defaultValue: `${defaultVal}`
- };
-}
diff --git a/src/lib/utils/BushCache.ts b/src/lib/utils/BushCache.ts
index 5654495..1f50fba 100644
--- a/src/lib/utils/BushCache.ts
+++ b/src/lib/utils/BushCache.ts
@@ -1,4 +1,4 @@
-import { type Guild } from '#lib';
+import { BadWords, GlobalModel, SharedModel, type Guild } from '#lib';
import { Collection, type Snowflake } from 'discord.js';
export class BushCache {
@@ -7,16 +7,19 @@ export class BushCache {
public guilds = new GuildCache();
}
-export class GlobalCache {
+export class GlobalCache implements Omit<GlobalModel, 'environment'> {
public disabledCommands: string[] = [];
public blacklistedChannels: Snowflake[] = [];
public blacklistedGuilds: Snowflake[] = [];
public blacklistedUsers: Snowflake[] = [];
}
-export class SharedCache {
+export class SharedCache implements Omit<SharedModel, 'primaryKey'> {
public superUsers: Snowflake[] = [];
+ public privilegedUsers: Snowflake[] = [];
+ public badLinksSecret: string[] = [];
public badLinks: string[] = [];
+ public badWords: BadWords = {};
}
export class GuildCache extends Collection<Snowflake, Guild> {}