aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/common/util/Moderation.ts101
-rw-r--r--src/lib/extensions/discord-akairo/BushClientUtil.ts17
-rw-r--r--src/lib/extensions/discord.js/BushClientEvents.ts7
-rw-r--r--src/lib/extensions/discord.js/BushGuild.ts85
4 files changed, 171 insertions, 39 deletions
diff --git a/src/lib/common/util/Moderation.ts b/src/lib/common/util/Moderation.ts
index 04ccb31..365dbd5 100644
--- a/src/lib/common/util/Moderation.ts
+++ b/src/lib/common/util/Moderation.ts
@@ -123,25 +123,41 @@ export class Moderation {
const user = (await util.resolveNonCachedUser(options.user))!.id;
const moderator = (await util.resolveNonCachedUser(options.moderator))!.id;
const guild = client.guilds.resolveId(options.guild)!;
- const duration = options.duration ? options.duration : undefined;
+ return this.createModLogEntrySimple(
+ {
+ ...options,
+ user: user,
+ moderator: moderator,
+ guild: guild
+ },
+ getCaseNumber
+ );
+ }
+
+ /**
+ * Creates a modlog entry with already resolved ids.
+ * @param options Options for creating a modlog entry.
+ * @param getCaseNumber Whether or not to get the case number of the entry.
+ * @returns An object with the modlog and the case number.
+ */
+ public static async createModLogEntrySimple(
+ options: SimpleCreateModLogEntryOptions,
+ getCaseNumber = false
+ ): Promise<{ log: ModLog | null; caseNum: number | null }> {
// If guild does not exist create it so the modlog can reference a guild.
await Guild.findOrCreate({
- where: {
- id: guild
- },
- defaults: {
- id: guild
- }
+ where: { id: options.guild },
+ defaults: { id: options.guild }
});
const modLogEntry = ModLog.build({
type: options.type,
- user,
- moderator,
+ user: options.user,
+ moderator: options.moderator,
reason: options.reason,
- duration: duration,
- guild,
+ duration: options.duration ? options.duration : undefined,
+ guild: options.guild,
pseudo: options.pseudo ?? false,
evidence: options.evidence,
hidden: options.hidden ?? false
@@ -153,7 +169,9 @@ export class Moderation {
if (!getCaseNumber) return { log: saveResult, caseNum: null };
- const caseNum = (await ModLog.findAll({ where: { type: options.type, user: user, guild: guild, hidden: 'false' } }))?.length;
+ const caseNum = (
+ await ModLog.findAll({ where: { type: options.type, user: options.user, guild: options.guild, hidden: false } })
+ )?.length;
return { log: saveResult, caseNum };
}
@@ -269,7 +287,6 @@ export class Moderation {
if (appealsEnabled && options.modlog)
components = [
new ActionRow({
- type: ComponentType.ActionRow,
components: [
new ButtonComponent({
custom_id: `appeal;${this.punishmentToPresentTense(options.punishment)};${
@@ -294,54 +311,76 @@ export class Moderation {
}
}
-/**
- * Options for creating a modlog entry.
- */
-export interface CreateModLogEntryOptions {
+interface BaseCreateModLogEntryOptions {
/**
* The type of modlog entry.
*/
type: ModLogType;
/**
- * The user that a modlog entry is created for.
+ * The reason for the punishment.
*/
- user: BushGuildMemberResolvable;
+ reason: string | undefined | null;
/**
- * The moderator that created the modlog entry.
+ * The duration of the punishment.
*/
- moderator: BushGuildMemberResolvable;
+ duration?: number;
/**
- * The reason for the punishment.
+ * Whether the punishment is a pseudo punishment.
*/
- reason: string | undefined | null;
+ pseudo?: boolean;
/**
- * The duration of the punishment.
+ * The evidence for the punishment.
*/
- duration?: number;
+ evidence?: string;
+
+ /**
+ * Makes the modlog entry hidden.
+ */
+ hidden?: boolean;
+}
+
+/**
+ * Options for creating a modlog entry.
+ */
+export interface CreateModLogEntryOptions extends BaseCreateModLogEntryOptions {
+ /**
+ * The user that a modlog entry is created for.
+ */
+ user: BushGuildMemberResolvable;
+
+ /**
+ * The moderator that created the modlog entry.
+ */
+ moderator: BushGuildMemberResolvable;
/**
* The guild that the punishment is created for.
*/
guild: BushGuildResolvable;
+}
+/**
+ * Simple options for creating a modlog entry.
+ */
+export interface SimpleCreateModLogEntryOptions extends BaseCreateModLogEntryOptions {
/**
- * Whether the punishment is a pseudo punishment.
+ * The user that a modlog entry is created for.
*/
- pseudo?: boolean;
+ user: Snowflake;
/**
- * The evidence for the punishment.
+ * The moderator that created the modlog entry.
*/
- evidence?: string;
+ moderator: Snowflake;
/**
- * Makes the modlog entry hidden.
+ * The guild that the punishment is created for.
*/
- hidden?: boolean;
+ guild: Snowflake;
}
/**
diff --git a/src/lib/extensions/discord-akairo/BushClientUtil.ts b/src/lib/extensions/discord-akairo/BushClientUtil.ts
index ecfa360..9903140 100644
--- a/src/lib/extensions/discord-akairo/BushClientUtil.ts
+++ b/src/lib/extensions/discord-akairo/BushClientUtil.ts
@@ -678,16 +678,17 @@ export class BushClientUtil extends ClientUtil {
*/
public async resolveNonCachedUser(user: UserResolvable | undefined | null): Promise<BushUser | undefined> {
if (user == null) return undefined;
- const id =
- user instanceof User || user instanceof GuildMember || user instanceof ThreadMember
- ? user.id
+ const resolvedUser =
+ user instanceof User
+ ? <BushUser>user
+ : user instanceof GuildMember
+ ? <BushUser>user.user
+ : user instanceof ThreadMember
+ ? <BushUser>user.user
: user instanceof Message
- ? user.author.id
- : typeof user === 'string'
- ? user
+ ? <BushUser>user.author
: undefined;
- if (!id) return undefined;
- else return await client.users.fetch(id).catch(() => undefined);
+ return resolvedUser ?? (await client.users.fetch(user as Snowflake).catch(() => undefined));
}
/**
diff --git a/src/lib/extensions/discord.js/BushClientEvents.ts b/src/lib/extensions/discord.js/BushClientEvents.ts
index 50b198d..e6cf93f 100644
--- a/src/lib/extensions/discord.js/BushClientEvents.ts
+++ b/src/lib/extensions/discord.js/BushClientEvents.ts
@@ -1,4 +1,5 @@
import type {
+ BanResponse,
BushApplicationCommand,
BushClient,
BushDMChannel,
@@ -264,6 +265,12 @@ export interface BushClientEvents extends AkairoClientEvents {
channelsSuccessMap: Collection<Snowflake, boolean>,
all?: boolean
];
+ massBan: [
+ moderator: BushGuildMember,
+ guild: BushGuild,
+ reason: string | undefined,
+ results: Collection<Snowflake, BanResponse>
+ ];
}
type Setting = GuildSettings | 'enabledFeatures' | 'blacklistedChannels' | 'blacklistedUsers' | 'disabledCommands';
diff --git a/src/lib/extensions/discord.js/BushGuild.ts b/src/lib/extensions/discord.js/BushGuild.ts
index 80799fd..155f32c 100644
--- a/src/lib/extensions/discord.js/BushGuild.ts
+++ b/src/lib/extensions/discord.js/BushGuild.ts
@@ -236,6 +236,69 @@ export class BushGuild extends Guild {
}
/**
+ * {@link bushBan} with less resolving and checks
+ * @param options Options for banning the user.
+ * @returns A string status message of the ban.
+ * **Preconditions:**
+ * - {@link me} has the `BanMembers` permission
+ * **Warning:**
+ * - Doesn't emit bushBan Event
+ */
+ public async massBanOne(options: GuildMassBanOneOptions): Promise<BanResponse> {
+ if (this.bans.cache.has(options.user)) return banResponse.ALREADY_BANNED;
+
+ const ret = await (async () => {
+ // add modlog entry
+ const { log: modlog } = await Moderation.createModLogEntrySimple({
+ type: ModLogType.PERM_BAN,
+ user: options.user,
+ moderator: options.moderator,
+ reason: options.reason,
+ duration: 0,
+ guild: this.id
+ });
+ if (!modlog) return banResponse.MODLOG_ERROR;
+
+ let dmSuccessEvent: boolean | undefined = undefined;
+ // dm user
+ if (this.members.cache.has(options.user)) {
+ dmSuccessEvent = await Moderation.punishDM({
+ modlog: modlog.id,
+ guild: this,
+ user: options.user,
+ punishment: 'banned',
+ duration: 0,
+ reason: options.reason ?? undefined,
+ sendFooter: true
+ });
+ }
+
+ // ban
+ const banSuccess = await this.bans
+ .create(options.user, {
+ reason: `${options.moderator} | ${options.reason}`,
+ deleteMessageDays: options.deleteDays
+ })
+ .catch(() => false);
+ if (!banSuccess) return banResponse.ACTION_ERROR;
+
+ // add punishment entry so they can be unbanned later
+ const punishmentEntrySuccess = await Moderation.createPunishmentEntry({
+ type: 'ban',
+ user: options.user,
+ guild: this,
+ duration: 0,
+ modlog: modlog.id
+ });
+ if (!punishmentEntrySuccess) return banResponse.PUNISHMENT_ENTRY_ADD_ERROR;
+
+ if (!dmSuccessEvent) return banResponse.DM_ERROR;
+ return banResponse.SUCCESS;
+ })();
+ return ret;
+ }
+
+ /**
* Unbans a user, dms them, creates a mod log entry, and destroys the punishment entry.
* @param options Options for unbanning the user.
* @returns A status message of the unban.
@@ -414,6 +477,28 @@ export interface GuildBushUnbanOptions {
evidence?: string;
}
+export interface GuildMassBanOneOptions {
+ /**
+ * The user to ban
+ */
+ user: Snowflake;
+
+ /**
+ * The reason to ban the user
+ */
+ reason: string;
+
+ /**
+ * The moderator who banned the user
+ */
+ moderator: Snowflake;
+
+ /**
+ * The number of days to delete the user's messages for
+ */
+ deleteDays?: number;
+}
+
/**
* Options for banning a user
*/