aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIRONM00N <64110067+IRONM00N@users.noreply.github.com>2021-09-05 20:24:50 -0400
committerIRONM00N <64110067+IRONM00N@users.noreply.github.com>2021-09-05 20:24:50 -0400
commitc4c1d9ffeb179e208792c88dd099caea5030581b (patch)
treedc075bda115de5f6cec925c398f3c9547d1bad55 /src
parentc238b0279c7686ca45506b0909e376f241cf0e30 (diff)
downloadtanzanite-c4c1d9ffeb179e208792c88dd099caea5030581b.tar.gz
tanzanite-c4c1d9ffeb179e208792c88dd099caea5030581b.tar.bz2
tanzanite-c4c1d9ffeb179e208792c88dd099caea5030581b.zip
add moderation logging, fixes, hide modlog, jank
Diffstat (limited to 'src')
-rw-r--r--src/commands/_fake-command/ironmoon.ts2
-rw-r--r--src/commands/config/log.ts2
-rw-r--r--src/commands/info/help.ts4
-rw-r--r--src/commands/moderation/ban.ts2
-rw-r--r--src/commands/moderation/hideCase.ts50
-rw-r--r--src/commands/moderation/modlog.ts45
-rw-r--r--src/commands/moderation/purge.ts9
-rw-r--r--src/commands/moderation/unban.ts2
-rw-r--r--src/commands/moulberry-bush/report.ts11
-rw-r--r--src/lib/extensions/discord-akairo/BushClient.ts46
-rw-r--r--src/lib/extensions/discord-akairo/BushClientUtil.ts9
-rw-r--r--src/lib/extensions/discord-akairo/BushCommand.ts8
-rw-r--r--src/lib/extensions/discord.js/BushClientEvents.d.ts139
-rw-r--r--src/lib/extensions/discord.js/BushGuild.ts171
-rw-r--r--src/lib/extensions/discord.js/BushGuildMember.ts454
-rw-r--r--src/lib/models/Guild.ts2
-rw-r--r--src/lib/models/ModLog.ts48
-rw-r--r--src/lib/utils/BushConstants.ts6
-rw-r--r--src/listeners/custom/bushBan.ts34
-rw-r--r--src/listeners/custom/bushKick.ts33
-rw-r--r--src/listeners/custom/bushMute.ts34
-rw-r--r--src/listeners/custom/bushPunishRole.ts33
-rw-r--r--src/listeners/custom/bushPunishRoleRemove.ts34
-rw-r--r--src/listeners/custom/bushPurge.ts43
-rw-r--r--src/listeners/custom/bushUnban.ts33
-rw-r--r--src/listeners/custom/bushUnmute.ts33
-rw-r--r--src/listeners/custom/bushWarn.ts33
-rw-r--r--src/listeners/message/automodCreate.ts11
-rw-r--r--src/listeners/other/promiseRejection.ts7
-rw-r--r--src/tasks/removeExpiredPunishements.ts2
30 files changed, 1024 insertions, 316 deletions
diff --git a/src/commands/_fake-command/ironmoon.ts b/src/commands/_fake-command/ironmoon.ts
index 8ca1f5b..ddc6ced 100644
--- a/src/commands/_fake-command/ironmoon.ts
+++ b/src/commands/_fake-command/ironmoon.ts
@@ -5,7 +5,7 @@ export default class IronmoonCommand extends BushCommand {
super('ironmoon', {
category: 'fake-commands',
description: { content: '', examples: '', usage: '' },
- completelyHide: true
+ pseudo: true
});
}
public override condition(message: BushMessage): boolean {
diff --git a/src/commands/config/log.ts b/src/commands/config/log.ts
index 592f700..0bc2189 100644
--- a/src/commands/config/log.ts
+++ b/src/commands/config/log.ts
@@ -79,7 +79,7 @@ export default class LogCommand extends BushCommand {
? `${util.emojis.success} Successfully ${oldChannel ? 'changed' : 'set'}`
: `${util.emojis.error} Unable to ${oldChannel ? 'change' : 'set'}`
} ${
- oldChannel ? ` the \`${args.log_type}\` log channel from <#${oldChannel}>` : ` the \`${args.log_type}\` log channel`
+ oldChannel ? ` the **${args.log_type}** log channel from <#${oldChannel}>` : ` the \`${args.log_type}\` log channel`
} to ${args.channel ? `<#${args.channel.id}>` : '`disabled`'}`
);
}
diff --git a/src/commands/info/help.ts b/src/commands/info/help.ts
index ad4e00f..1338f8a 100644
--- a/src/commands/info/help.ts
+++ b/src/commands/info/help.ts
@@ -90,14 +90,14 @@ export default class HelpCommand extends BushCommand {
: args.command
: null;
if (!isOwner) args.showHidden = false;
- if (!command || command.completelyHide) {
+ if (!command || command.pseudo) {
const embed = new MessageEmbed().setColor(util.colors.default).setTimestamp();
if (message.guild) {
embed.setFooter(`For more information about a command use ${prefix}help <command>`);
}
for (const [, category] of this.handler.categories) {
const categoryFilter = category.filter((command) => {
- if (command.completelyHide) return false;
+ if (command.pseudo) return false;
if (command.hidden && !args.showHidden) return false;
if (command.channel == 'guild' && !message.guild && !args.showHidden) return false;
if (command.ownerOnly && !isOwner) return false;
diff --git a/src/commands/moderation/ban.ts b/src/commands/moderation/ban.ts
index 5a1b5d9..812d7ca 100644
--- a/src/commands/moderation/ban.ts
+++ b/src/commands/moderation/ban.ts
@@ -126,7 +126,7 @@ export default class BanCommand extends BushCommand {
duration: time! ?? 0,
deleteDays: days ?? 0
})
- : await message.guild.ban({
+ : await message.guild.bushBan({
user,
reason: parsedReason,
moderator: message.author,
diff --git a/src/commands/moderation/hideCase.ts b/src/commands/moderation/hideCase.ts
new file mode 100644
index 0000000..1d8dea6
--- /dev/null
+++ b/src/commands/moderation/hideCase.ts
@@ -0,0 +1,50 @@
+import { BushCommand, BushMessage, BushSlashMessage, ModLog } from '@lib';
+
+export default class HideCaseCommand extends BushCommand {
+ public constructor() {
+ super('hideCase', {
+ aliases: ['hidecase', 'hide_case', 'showcase', 'show_case', 'coverupmodabuse', 'cover_up_mod_abuse'],
+ category: 'moderation',
+ description: {
+ content: 'Hide a particular modlog case from the modlog command unless the `--hidden` flag is specified',
+ usage: 'hideCase <caseID>',
+ examples: ['hideCase 9210b1ea-91f5-4ea2-801b-02b394469c77']
+ },
+ args: [
+ {
+ id: 'case',
+ type: 'string',
+ prompt: {
+ start: 'What modlog case would you like to hide?',
+ retry: '{error} Choose a valid case id.'
+ }
+ }
+ ],
+ userPermissions: ['MANAGE_MESSAGES'],
+ slash: true,
+ slashOptions: [
+ {
+ name: 'case',
+ description: 'What modlog case would you like to hide?',
+ type: 'STRING',
+ required: true
+ }
+ ],
+ channel: 'guild'
+ });
+ }
+
+ public override async exec(message: BushMessage | BushSlashMessage, { case: caseID }: { case: string }): Promise<unknown> {
+ if (message.author.id === '496409778822709251')
+ return await message.util.reply(`${util.emojis.error} This command is Bestower proof.`);
+ const entry = await ModLog.findByPk(caseID);
+ if (!entry || entry.pseudo) return message.util.send(`${util.emojis.error} Invalid entry.`);
+ if (entry.guild !== message.guild!.id)
+ return message.util.reply(`${util.emojis.error} This modlog is from another server.`);
+ const action = entry.hidden ? 'now hidden' : 'no longer hidden';
+ entry.hidden = !entry.hidden;
+ await entry.save();
+
+ return await message.util.reply(`${util.emojis.success} CaseID \`${caseID}\` is ${action}.`);
+ }
+}
diff --git a/src/commands/moderation/modlog.ts b/src/commands/moderation/modlog.ts
index fd53ea7..0be6971 100644
--- a/src/commands/moderation/modlog.ts
+++ b/src/commands/moderation/modlog.ts
@@ -1,5 +1,5 @@
import { BushCommand, BushMessage, BushSlashMessage, BushUser, ModLog } from '@lib';
-import { MessageEmbed, User } from 'discord.js';
+import { User } from 'discord.js';
export default class ModlogCommand extends BushCommand {
public constructor() {
@@ -8,7 +8,7 @@ export default class ModlogCommand extends BushCommand {
category: 'moderation',
description: {
content: "View a user's modlogs, or view a specific case.",
- usage: 'modlogs <search>',
+ usage: 'modlogs <search> [--hidden]',
examples: ['modlogs @Tyman']
},
args: [
@@ -19,6 +19,12 @@ export default class ModlogCommand extends BushCommand {
start: 'What case id or user would you like to see?',
retry: '{error} Choose a valid case id or user.'
}
+ },
+ {
+ id: 'hidden',
+ match: 'flag',
+ flags: ['--hidden', '-h'],
+ default: false
}
],
userPermissions: ['MANAGE_MESSAGES'],
@@ -29,6 +35,12 @@ export default class ModlogCommand extends BushCommand {
description: 'What case id or user would you like to see?',
type: 'STRING',
required: true
+ },
+ {
+ name: 'hidden',
+ description: 'Would you like to see hidden modlogs?',
+ type: 'BOOLEAN',
+ required: false
}
]
});
@@ -50,7 +62,7 @@ export default class ModlogCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- { search }: { search: BushUser | string }
+ { search, hidden }: { search: BushUser | string; hidden: boolean }
): Promise<unknown> {
const foundUser = search instanceof User ? search : await util.resolveUserAsync(search);
if (foundUser) {
@@ -62,28 +74,25 @@ export default class ModlogCommand extends BushCommand {
order: [['createdAt', 'ASC']]
});
if (!logs.length) return message.util.reply(`${util.emojis.error} **${foundUser.tag}** does not have any modlogs.`);
- const niceLogs: string[] = [];
- for (const log of logs) {
- niceLogs.push(this.#generateModlogInfo(log));
- }
+ const niceLogs = logs.filter((log) => !log.pseudo && !log.hidden && !hidden).map((log) => this.#generateModlogInfo(log));
const chunked: string[][] = util.chunk(niceLogs, 3);
- const embedPages = chunked.map(
- (chunk) =>
- new MessageEmbed({
- title: `${foundUser.tag}'s Mod Logs`,
- description: chunk.join('\n━━━━━━━━━━━━━━━\n'),
- color: util.colors.default
- })
- );
+ const embedPages = chunked.map((chunk) => ({
+ title: `${foundUser.tag}'s Mod Logs`,
+ description: chunk.join('\n━━━━━━━━━━━━━━━\n'),
+ color: util.colors.default
+ }));
return await util.buttonPaginate(message, embedPages, undefined, true);
} else if (search) {
const entry = await ModLog.findByPk(search as string);
- if (!entry) return message.util.send(`${util.emojis.error} That modlog does not exist.`);
- const embed = new MessageEmbed({
+ if (!entry || entry.pseudo || (entry.hidden && !hidden))
+ return message.util.send(`${util.emojis.error} That modlog does not exist.`);
+ if (entry.guild !== message.guild!.id)
+ return message.util.reply(`${util.emojis.error} This modlog is from another server.`);
+ const embed = {
title: `Case ${entry.id}`,
description: this.#generateModlogInfo(entry),
color: util.colors.default
- });
+ };
return await util.buttonPaginate(message, [embed]);
}
}
diff --git a/src/commands/moderation/purge.ts b/src/commands/moderation/purge.ts
index b391ff6..4ed1ee7 100644
--- a/src/commands/moderation/purge.ts
+++ b/src/commands/moderation/purge.ts
@@ -47,18 +47,19 @@ export default class PurgeCommand extends BushCommand {
if (message.channel.type === 'DM') return message.util.reply(`${util.emojis.error} You cannot run this command in dms.`);
if (args.amount > 100 || args.amount < 1) return message.util.reply(`${util.emojis.error} `);
- const messages = (await message.channel.messages.fetch({ limit: args.amount })).filter((message) => filter(message));
- const filter = (filterMessage: BushMessage): boolean => {
+ const messageFilter = (filterMessage: BushMessage): boolean => {
const shouldFilter = new Array<boolean>();
if (args.bot) {
shouldFilter.push(filterMessage.author.bot);
}
return shouldFilter.filter((bool) => bool === false).length === 0;
};
+ const messages = (await message.channel.messages.fetch({ limit: args.amount })).filter((message) => messageFilter(message));
- const purged = await message.channel.bulkDelete(messages, true).catch(() => {});
- if (!purged) return message.util.reply(`${util.emojis.error} Failed to purge messages.`).catch(() => {});
+ const purged = await message.channel.bulkDelete(messages, true).catch(() => null);
+ if (!purged) return message.util.reply(`${util.emojis.error} Failed to purge messages.`).catch(() => null);
else {
+ client.emit('bushPurge', message.author, message.guild!, message.channel, messages);
await message.util
.send(`${util.emojis.success} Successfully purged **${purged.size}** messages.`)
.then(async (purgeMessage) => {
diff --git a/src/commands/moderation/unban.ts b/src/commands/moderation/unban.ts
index 3436da6..5025ede 100644
--- a/src/commands/moderation/unban.ts
+++ b/src/commands/moderation/unban.ts
@@ -59,7 +59,7 @@ export default class UnbanCommand extends BushCommand {
user = util.resolveUser(user, client.users.cache) as BushUser;
}
- const responseCode = await message.guild!.unban({
+ const responseCode = await message.guild!.bushUnban({
user,
moderator: message.author,
reason
diff --git a/src/commands/moulberry-bush/report.ts b/src/commands/moulberry-bush/report.ts
index e387e7d..a5c4cb2 100644
--- a/src/commands/moulberry-bush/report.ts
+++ b/src/commands/moulberry-bush/report.ts
@@ -1,6 +1,6 @@
import { GuildMember, MessageEmbed } from 'discord.js';
import moment from 'moment';
-import { AllowedMentions, BushCommand, BushMessage, BushTextChannel } from '../../lib';
+import { AllowedMentions, BushCommand, BushMessage } from '../../lib';
export default class ReportCommand extends BushCommand {
public constructor() {
@@ -71,9 +71,11 @@ export default class ReportCommand extends BushCommand {
if (member.user.bot)
return await message.util.reply(`${util.emojis.error} You cannot report a bot <:WeirdChamp:756283321301860382>.`);
- const reportChannelId = (await message.guild.getSetting('logChannels')).report;
- if (!reportChannelId)
- return await message.util.reply(`${util.emojis.error} This server has not setup a report logging channel.`);
+ const reportChannel = await message.guild.getLogChannel('report');
+ if (!reportChannel)
+ return await message.util.reply(
+ `${util.emojis.error} This server has not setup a report logging channel or the channel no longer exists.`
+ );
//The formatting of the report is mostly copied from carl since it is pretty good when it actually works
const reportEmbed = new MessageEmbed()
@@ -109,7 +111,6 @@ export default class ReportCommand extends BushCommand {
reportEmbed.addField('Attachment', message.attachments.first()!.url);
}
}
- const reportChannel = client.channels.cache.get(reportChannelId) as unknown as BushTextChannel;
await reportChannel.send({ embeds: [reportEmbed] }).then(async (ReportMessage) => {
try {
await ReportMessage.react(util.emojis.check);
diff --git a/src/lib/extensions/discord-akairo/BushClient.ts b/src/lib/extensions/discord-akairo/BushClient.ts
index 5c1cb35..59c4df8 100644
--- a/src/lib/extensions/discord-akairo/BushClient.ts
+++ b/src/lib/extensions/discord-akairo/BushClient.ts
@@ -1,6 +1,7 @@
import chalk from 'chalk';
import { AkairoClient, ContextMenuCommandHandler } from 'discord-akairo';
import {
+ Awaited,
Collection,
Intents,
InteractionReplyOptions,
@@ -48,6 +49,7 @@ import { BushButtonInteraction } from '../discord.js/BushButtonInteraction';
import { BushCategoryChannel } from '../discord.js/BushCategoryChannel';
import { BushChannel } from '../discord.js/BushChannel';
import { BushChannelManager } from '../discord.js/BushChannelManager';
+import { BushClientEvents } from '../discord.js/BushClientEvents';
import { BushClientUser } from '../discord.js/BushClientUser';
import { BushCommandInteraction } from '../discord.js/BushCommandInteraction';
import { BushDMChannel } from '../discord.js/BushDMChannel';
@@ -159,6 +161,50 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re
public logger = BushLogger;
public constants = BushConstants;
public cache = BushCache;
+
+ public override on<K extends keyof BushClientEvents>(
+ event: K,
+ listener: (...args: BushClientEvents[K]) => Awaited<void>
+ ): this;
+ public override on<S extends string | symbol>(
+ event: Exclude<S, keyof BushClientEvents>,
+ listener: (...args: any[]) => Awaited<void>
+ ): this {
+ return super.on(event as any, listener);
+ }
+
+ public override once<K extends keyof BushClientEvents>(
+ event: K,
+ listener: (...args: BushClientEvents[K]) => Awaited<void>
+ ): this;
+ public override once<S extends string | symbol>(
+ event: Exclude<S, keyof BushClientEvents>,
+ listener: (...args: any[]) => Awaited<void>
+ ): this {
+ return super.once(event as any, listener);
+ }
+
+ public override emit<K extends keyof BushClientEvents>(event: K, ...args: BushClientEvents[K]): boolean;
+ public override emit<S extends string | symbol>(event: Exclude<S, keyof BushClientEvents>, ...args: unknown[]): boolean {
+ return super.emit(event as any, ...args);
+ }
+
+ public override off<K extends keyof BushClientEvents>(
+ event: K,
+ listener: (...args: BushClientEvents[K]) => Awaited<void>
+ ): this;
+ public override off<S extends string | symbol>(
+ event: Exclude<S, keyof BushClientEvents>,
+ listener: (...args: any[]) => Awaited<void>
+ ): this {
+ return super.off(event as any, listener);
+ }
+
+ public override removeAllListeners<K extends keyof BushClientEvents>(event?: K): this;
+ public override removeAllListeners<S extends string | symbol>(event?: Exclude<S, keyof BushClientEvents>): this {
+ return super.removeAllListeners(event as any);
+ }
+
public constructor(config: Config) {
super({
ownerID: config.owners,
diff --git a/src/lib/extensions/discord-akairo/BushClientUtil.ts b/src/lib/extensions/discord-akairo/BushClientUtil.ts
index 3f9e0b6..fec0174 100644
--- a/src/lib/extensions/discord-akairo/BushClientUtil.ts
+++ b/src/lib/extensions/discord-akairo/BushClientUtil.ts
@@ -8,6 +8,7 @@ import {
BushGuildResolvable,
BushMessage,
BushSlashMessage,
+ BushUser,
Global,
Guild,
ModLog,
@@ -576,7 +577,7 @@ export class BushClientUtil extends ClientUtil {
if (content.length > 400_000 && !substr) {
void this.handleError('haste', new Error(`content over 400,000 characters (${content.length.toLocaleString()})`));
return { error: 'content too long' };
- } else {
+ } else if (content.length > 400_000) {
content = content.substr(0, 400_000);
isSubstr = true;
}
@@ -876,7 +877,7 @@ export class BushClientUtil extends ClientUtil {
const haste = await this.haste(code, substr);
hasteOut = `Too large to display. ${
haste.url
- ? `Hastebin: ${haste.url}${haste.error ? `(${haste.error})` : ''}`
+ ? `Hastebin: ${haste.url}${haste.error ? ` - ${haste.error}` : ''}`
: `${this.emojis.error} Hastebin: ${haste.error}`
}`;
}
@@ -969,7 +970,7 @@ export class BushClientUtil extends ClientUtil {
public async inspectCleanRedactHaste(input: any, inspectOptions?: BushInspectOptions) {
input = typeof input !== 'string' ? this.inspect(input, inspectOptions ?? undefined) : input;
input = this.redact(input);
- return this.haste(input);
+ return this.haste(input, true);
}
public inspectAndRedact(input: any, inspectOptions?: BushInspectOptions) {
@@ -1413,7 +1414,7 @@ export class BushClientUtil extends ClientUtil {
});
}
- public async resolveNonCachedUser(user: UserResolvable | undefined | null): Promise<User | undefined> {
+ public async resolveNonCachedUser(user: UserResolvable | undefined | null): Promise<BushUser | undefined> {
if (!user) return undefined;
const id =
user instanceof User || user instanceof GuildMember || user instanceof ThreadMember
diff --git a/src/lib/extensions/discord-akairo/BushCommand.ts b/src/lib/extensions/discord-akairo/BushCommand.ts
index 495a454..1c8ea5b 100644
--- a/src/lib/extensions/discord-akairo/BushCommand.ts
+++ b/src/lib/extensions/discord-akairo/BushCommand.ts
@@ -147,7 +147,7 @@ export interface BushCommandOptions extends CommandOptions {
};
args?: BushArgumentOptions[] & CustomBushArgumentOptions[];
category: string;
- completelyHide?: boolean;
+ pseudo?: boolean;
}
export class BushCommand extends Command {
@@ -166,8 +166,8 @@ export class BushCommand extends Command {
/** Whether the command is hidden from the help command. */
public hidden: boolean;
- /** Completely hide this command from the help command. */
- public completelyHide: boolean;
+ /** A fake command, completely hidden from the help command. */
+ public pseudo: boolean;
public constructor(id: string, options: BushCommandOptions) {
if (options.args && typeof options.args !== 'function') {
@@ -184,7 +184,7 @@ export class BushCommand extends Command {
this.hidden = options.hidden ?? false;
this.restrictedChannels = options.restrictedChannels!;
this.restrictedGuilds = options.restrictedGuilds!;
- this.completelyHide = options.completelyHide!;
+ this.pseudo = options.pseudo!;
}
public override exec(message: BushMessage, args: any): any;
diff --git a/src/lib/extensions/discord.js/BushClientEvents.d.ts b/src/lib/extensions/discord.js/BushClientEvents.d.ts
index ae9b186..8695e7a 100644
--- a/src/lib/extensions/discord.js/BushClientEvents.d.ts
+++ b/src/lib/extensions/discord.js/BushClientEvents.d.ts
@@ -9,7 +9,10 @@ import {
Sticker,
Typing
} from 'discord.js';
-import { BushClient, BushTextBasedChannels } from '../discord-akairo/BushClient';
+import {
+ BushClient,
+ BushTextBasedChannels
+} from '../discord-akairo/BushClient';
import { BushApplicationCommand } from './BushApplicationCommand';
import { BushDMChannel } from './BushDMChannel';
import { BushGuild } from './BushGuild';
@@ -18,7 +21,11 @@ import { BushGuildChannel } from './BushGuildChannel';
import { BushGuildEmoji } from './BushGuildEmoji';
import { BushGuildMember, PartialBushGuildMember } from './BushGuildMember';
import { BushMessage, PartialBushMessage } from './BushMessage';
-import { BushMessageReaction, PartialBushMessageReaction } from './BushMessageReaction';
+import {
+ BushMessageReaction,
+ PartialBushMessageReaction
+} from './BushMessageReaction';
+import { BushNewsChannel } from './BushNewsChannel';
import { BushPresence } from './BushPresence';
import { BushRole } from './BushRole';
import { BushStageInstance } from './BushStageInstance';
@@ -31,11 +38,17 @@ import { BushVoiceState } from './BushVoiceState';
export interface BushClientEvents extends ClientEvents {
applicationCommandCreate: [command: BushApplicationCommand];
applicationCommandDelete: [command: BushApplicationCommand];
- applicationCommandUpdate: [oldCommand: BushApplicationCommand | null, newCommand: BushApplicationCommand];
+ applicationCommandUpdate: [
+ oldCommand: BushApplicationCommand | null,
+ newCommand: BushApplicationCommand
+ ];
channelCreate: [channel: BushGuildChannel];
channelDelete: [channel: BushDMChannel | BushGuildChannel];
channelPinsUpdate: [channel: BushTextBasedChannels, date: Date];
- channelUpdate: [oldChannel: BushDMChannel | BushGuildChannel, newChannel: BushDMChannel | BushGuildChannel];
+ channelUpdate: [
+ oldChannel: BushDMChannel | BushGuildChannel,
+ newChannel: BushDMChannel | BushGuildChannel
+ ];
debug: [message: string];
warn: [message: string];
emojiCreate: [emoji: BushGuildEmoji];
@@ -54,20 +67,40 @@ export interface BushClientEvents extends ClientEvents {
guildMembersChunk: [
members: Collection<Snowflake, BushGuildMember>,
guild: BushGuild,
- data: { count: number; index: number; nonce: string | undefined }
+ data: {
+ count: number;
+ index: number;
+ nonce: string | undefined;
+ }
+ ];
+ guildMemberUpdate: [
+ oldMember: BushGuildMember | PartialBushGuildMember,
+ newMember: BushGuildMember
];
- guildMemberUpdate: [oldMember: BushGuildMember | PartialBushGuildMember, newMember: BushGuildMember];
guildUpdate: [oldGuild: BushGuild, newGuild: BushGuild];
inviteCreate: [invite: Invite];
inviteDelete: [invite: Invite];
messageCreate: [message: BushMessage];
messageDelete: [message: BushMessage | PartialBushMessage];
messageReactionRemoveAll: [message: BushMessage | PartialBushMessage];
- messageReactionRemoveEmoji: [reaction: BushMessageReaction | PartialBushMessageReaction];
- messageDeleteBulk: [messages: Collection<Snowflake, BushMessage | PartialBushMessage>];
- messageReactionAdd: [reaction: BushMessageReaction | PartialBushMessageReaction, user: BushUser | PartialBushUser];
- messageReactionRemove: [reaction: BushMessageReaction | PartialBushMessageReaction, user: BushUser | PartialBushUser];
- messageUpdate: [oldMessage: BushMessage | PartialBushMessage, newMessage: BushMessage | PartialBushMessage];
+ messageReactionRemoveEmoji: [
+ reaction: BushMessageReaction | PartialBushMessageReaction
+ ];
+ messageDeleteBulk: [
+ messages: Collection<Snowflake, BushMessage | PartialBushMessage>
+ ];
+ messageReactionAdd: [
+ reaction: BushMessageReaction | PartialBushMessageReaction,
+ user: BushUser | PartialBushUser
+ ];
+ messageReactionRemove: [
+ reaction: BushMessageReaction | PartialBushMessageReaction,
+ user: BushUser | PartialBushUser
+ ];
+ messageUpdate: [
+ oldMessage: BushMessage | PartialBushMessage,
+ newMessage: BushMessage | PartialBushMessage
+ ];
presenceUpdate: [oldPresence: BushPresence | null, newPresence: BushPresence];
rateLimit: [rateLimitData: RateLimitData];
invalidRequestWarning: [invalidRequestWarningData: InvalidRequestWarningData];
@@ -79,7 +112,10 @@ export interface BushClientEvents extends ClientEvents {
threadCreate: [thread: BushThreadChannel];
threadDelete: [thread: BushThreadChannel];
threadListSync: [threads: Collection<Snowflake, BushThreadChannel>];
- threadMemberUpdate: [oldMember: BushThreadMember, newMember: BushThreadMember];
+ threadMemberUpdate: [
+ oldMember: BushThreadMember,
+ newMember: BushThreadMember
+ ];
threadMembersUpdate: [
oldMembers: Collection<Snowflake, BushThreadMember>,
mewMembers: Collection<Snowflake, BushThreadMember>
@@ -95,9 +131,86 @@ export interface BushClientEvents extends ClientEvents {
shardReconnecting: [shardId: number];
shardResume: [shardId: number, replayedEvents: number];
stageInstanceCreate: [stageInstance: BushStageInstance];
- stageInstanceUpdate: [oldStageInstance: BushStageInstance | null, newStageInstance: BushStageInstance];
+ stageInstanceUpdate: [
+ oldStageInstance: BushStageInstance | null,
+ newStageInstance: BushStageInstance
+ ];
stageInstanceDelete: [stageInstance: BushStageInstance];
stickerCreate: [sticker: Sticker];
stickerDelete: [sticker: Sticker];
stickerUpdate: [oldSticker: Sticker, newSticker: Sticker];
+ /* Custom */
+ bushBan: [
+ victim: BushGuildMember | BushUser,
+ moderator: BushUser,
+ guild: BushGuild,
+ reason: string | undefined,
+ caseID: string,
+ duration: number,
+ dmSuccess?: boolean
+ ];
+ bushKick: [
+ victim: BushGuildMember,
+ moderator: BushUser,
+ guild: BushGuild,
+ reason: string | undefined,
+ caseID: string,
+ dmSuccess: boolean
+ ];
+ bushMute: [
+ victim: BushGuildMember,
+ moderator: BushUser,
+ guild: BushGuild,
+ reason: string | undefined,
+ caseID: string,
+ duration: number,
+ dmSuccess: boolean
+ ];
+ bushPunishRole: [
+ victim: BushGuildMember,
+ moderator: BushUser,
+ guild: BushGuild,
+ reason: string | undefined,
+ caseID: string,
+ duration: number,
+ role: BushRole
+ ];
+ bushPunishRoleRemove: [
+ victim: BushGuildMember,
+ moderator: BushUser,
+ guild: BushGuild,
+ caseID: string,
+ reason: string | undefined,
+ role: BushRole
+ ];
+ bushPurge: [
+ moderator: BushUser,
+ guild: BushGuild,
+ channel: BushTextChannel | BushNewsChannel | BushThreadChannel,
+ messages: Collection<Snowflake, BushMessage>
+ ];
+ bushUnban: [
+ victim: BushUser,
+ moderator: BushUser,
+ guild: BushGuild,
+ reason: string | undefined,
+ caseID: string,
+ dmSuccess: boolean
+ ];
+ bushUnmute: [
+ victim: BushGuildMember,
+ moderator: BushUser,
+ guild: BushGuild,
+ reason: string | undefined,
+ caseID: string,
+ dmSuccess: boolean
+ ];
+ bushWarn: [
+ victim: BushGuildMember,
+ moderator: BushUser,
+ guild: BushGuild,
+ reason: string | undefined,
+ caseID: string,
+ dmSuccess: boolean
+ ];
}
diff --git a/src/lib/extensions/discord.js/BushGuild.ts b/src/lib/extensions/discord.js/BushGuild.ts
index efecdcd..18f6542 100644
--- a/src/lib/extensions/discord.js/BushGuild.ts
+++ b/src/lib/extensions/discord.js/BushGuild.ts
@@ -1,10 +1,11 @@
import { Guild, UserResolvable } from 'discord.js';
import { RawGuildData } from 'discord.js/typings/rawDataTypes';
-import { Guild as GuildDB, GuildFeatures, GuildModel } from '../../models/Guild';
+import { Guild as GuildDB, GuildFeatures, GuildLogType, GuildModel } from '../../models/Guild';
import { ModLogType } from '../../models/ModLog';
import { BushClient, BushUserResolvable } from '../discord-akairo/BushClient';
import { BushGuildMember } from './BushGuildMember';
import { BushGuildMemberManager } from './BushGuildMemberManager';
+import { BushTextChannel } from './BushTextChannel';
import { BushUser } from './BushUser';
export class BushGuild extends Guild {
@@ -50,7 +51,17 @@ export class BushGuild extends Guild {
return await row.save();
}
- public async ban(options: {
+ public async getLogChannel(logType: GuildLogType): Promise<BushTextChannel | undefined> {
+ const channelId = (await this.getSetting('logChannels'))[logType];
+ if (!channelId) return undefined;
+ return (
+ (this.channels.cache.get(channelId) as BushTextChannel | undefined) ??
+ ((await this.channels.fetch(channelId)) as BushTextChannel | null) ??
+ undefined
+ );
+ }
+
+ public async bushBan(options: {
user: BushUserResolvable | UserResolvable;
reason?: string | null;
moderator?: BushUserResolvable;
@@ -62,42 +73,51 @@ export class BushGuild extends Guild {
// checks
if (!this.me!.permissions.has('BAN_MEMBERS')) return 'missing permissions';
+ let caseID: string | undefined = undefined;
+ const user = (await util.resolveNonCachedUser(options.user))!;
const moderator = (await util.resolveNo