aboutsummaryrefslogtreecommitdiff
path: root/src/lib/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/extensions')
-rw-r--r--src/lib/extensions/discord-akairo/BushClientUtil.ts63
-rw-r--r--src/lib/extensions/discord.js/BushGuild.ts64
-rw-r--r--src/lib/extensions/discord.js/BushGuildMember.ts149
3 files changed, 237 insertions, 39 deletions
diff --git a/src/lib/extensions/discord-akairo/BushClientUtil.ts b/src/lib/extensions/discord-akairo/BushClientUtil.ts
index 6c6d49a..a981d30 100644
--- a/src/lib/extensions/discord-akairo/BushClientUtil.ts
+++ b/src/lib/extensions/discord-akairo/BushClientUtil.ts
@@ -643,21 +643,7 @@ export class BushClientUtil extends ClientUtil {
guild: BushGuildResolvable;
modlog: string;
}): Promise<Mute | Ban | PunishmentRole> {
- let dbModel: typeof Mute | typeof Ban | typeof PunishmentRole;
- switch (options.type) {
- case 'mute':
- dbModel = Mute;
- break;
- case 'ban':
- dbModel = Ban;
- break;
- case 'role':
- dbModel = PunishmentRole;
- break;
- default:
- throw 'choose a valid punishment entry type';
- }
-
+ const dbModel = this.findPunishmentModel(options.type);
const expires = options.duration ? new Date(new Date().getTime() + options.duration) : null;
const user = this.client.users.resolveId(options.user);
const guild = this.client.guilds.resolveId(options.guild);
@@ -669,6 +655,53 @@ export class BushClientUtil extends ClientUtil {
});
}
+ public async removePunishmentEntry(options: {
+ type: 'mute' | 'ban' | 'role';
+ user: BushGuildMemberResolvable;
+ guild: BushGuildResolvable;
+ }): Promise<boolean> {
+ const dbModel = this.findPunishmentModel(options.type);
+ const user = this.client.users.resolveId(options.user);
+ const guild = this.client.guilds.resolveId(options.guild);
+
+ let success = true;
+
+ const entries = await dbModel
+ .findAll({
+ // finding all cases of a certain type incase there were duplicates or something
+ where: {
+ user,
+ guild
+ }
+ })
+ .catch((e) => {
+ this.client.console.error('removePunishmentEntry', e?.stack || e);
+ success = false;
+ });
+ if (entries) {
+ entries.forEach(async (entry) => {
+ await entry.destroy().catch((e) => {
+ this.client.console.error('removePunishmentEntry', e?.stack || e);
+ });
+ success = false;
+ });
+ }
+ return success;
+ }
+
+ private findPunishmentModel(type: 'mute' | 'ban' | 'role'): typeof Mute | typeof Ban | typeof PunishmentRole {
+ switch (type) {
+ case 'mute':
+ return Mute;
+ case 'ban':
+ return Ban;
+ case 'role':
+ return PunishmentRole;
+ default:
+ throw 'choose a valid punishment entry type';
+ }
+ }
+
public humanizeDuration(duration: number): string {
return humanizeDuration(duration, { language: 'en', maxDecimalPoints: 2 });
}
diff --git a/src/lib/extensions/discord.js/BushGuild.ts b/src/lib/extensions/discord.js/BushGuild.ts
index ea34aec..6eca44d 100644
--- a/src/lib/extensions/discord.js/BushGuild.ts
+++ b/src/lib/extensions/discord.js/BushGuild.ts
@@ -1,6 +1,7 @@
-import { Guild } from 'discord.js';
+import { Guild, User } from 'discord.js';
+import { ModLogType } from '../..';
import { Guild as GuildDB, GuildModel } from '../../models/Guild';
-import { BushClient } from '../discord-akairo/BushClient';
+import { BushClient, BushUserResolvable } from '../discord-akairo/BushClient';
export class BushGuild extends Guild {
public declare readonly client: BushClient;
@@ -19,4 +20,63 @@ export class BushGuild extends Guild {
row[setting] = value;
return await row.save();
}
+
+ public async unban(options: {
+ user: BushUserResolvable | User;
+ reason?: string;
+ moderator?: BushUserResolvable;
+ }): Promise<
+ | 'success'
+ | 'missing permissions'
+ | 'user not banned'
+ | 'error unbanning'
+ | 'error creating modlog entry'
+ | 'error removing ban entry'
+ > {
+ const user = this.client.users.resolveId(options.user);
+ const moderator = this.client.users.cache.get(this.client.users.resolveId(options.moderator));
+
+ const bans = await this.bans.fetch();
+
+ let notBanned = false;
+ if (!bans.has(user)) notBanned = true;
+
+ const unbanSuccess = this.bans.remove(user, `${moderator.tag} | ${options.reason || 'No reason provided.'}`).catch((e) => {
+ if (e?.code === 'UNKNOWN_BAN') {
+ notBanned = true;
+ return true;
+ } else return false;
+ });
+
+ if (!unbanSuccess) return 'error unbanning';
+
+ // add modlog entry
+ const modlog = await this.client.util
+ .createModLogEntry({
+ type: ModLogType.UNBAN,
+ user,
+ moderator: moderator.id,
+ reason: options.reason,
+ guild: this
+ })
+ .catch(() => null);
+ if (!modlog) return 'error creating modlog entry';
+
+ // remove punishment entry
+ const removePunishmentEntrySuccess = await this.client.util
+ .removePunishmentEntry({
+ type: 'ban',
+ user,
+ guild: this
+ })
+ .catch(() => null);
+ if (!removePunishmentEntrySuccess) return 'error removing ban entry';
+
+ const userObject = this.client.users.cache.get(user);
+
+ userObject?.send(`You have been unbanned from **${this}** for **${options.reason || 'No reason provided'}**.`);
+
+ if (notBanned) return 'user not banned';
+ return 'success';
+ }
}
diff --git a/src/lib/extensions/discord.js/BushGuildMember.ts b/src/lib/extensions/discord.js/BushGuildMember.ts
index 9e9266e..adcae69 100644
--- a/src/lib/extensions/discord.js/BushGuildMember.ts
+++ b/src/lib/extensions/discord.js/BushGuildMember.ts
@@ -7,7 +7,7 @@ import { BushUser } from './BushUser';
interface BushPunishmentOptions {
reason?: string;
- moderator: BushUserResolvable;
+ moderator?: BushUserResolvable;
}
interface BushTimedPunishmentOptions extends BushPunishmentOptions {
@@ -24,6 +24,8 @@ type WarnResponse = PunishmentResponse;
type PunishmentRoleResponse = PunishmentResponse;
+type RemovePunishmentRoleResponse = PunishmentResponse;
+
type MuteResponse =
| PunishmentResponse
| 'missing permissions'
@@ -33,16 +35,22 @@ type MuteResponse =
| 'error giving mute role'
| 'error creating mute entry';
-type UnmuteResponse = PunishmentResponse;
+type UnmuteResponse =
+ | PunishmentResponse
+ | 'missing permissions'
+ | 'no mute role'
+ | 'invalid mute role'
+ | 'mute role not manageable'
+ | 'error removing mute role'
+ | 'error removing mute entry';
type KickResponse = PunishmentResponse | 'missing permissions' | 'error kicking';
interface BushBanOptions extends BushTimedPunishmentOptions {
deleteDays?: number;
- duration?: number;
}
-type BanResponse = PunishmentResponse;
+type BanResponse = PunishmentResponse | 'missing permissions' | 'error creating ban entry' | 'error banning';
export class BushGuildMember extends GuildMember {
public declare readonly client: BushClient;
@@ -53,7 +61,7 @@ export class BushGuildMember extends GuildMember {
}
public async warn(options: BushPunishmentOptions): Promise<{ result: WarnResponse; caseNum: number }> {
- //add modlog entry
+ // add modlog entry
const { log, caseNum } = await this.client.util
.createModLogEntry(
{
@@ -68,7 +76,7 @@ export class BushGuildMember extends GuildMember {
.catch(() => null);
if (!log) return { result: 'error creating modlog entry', caseNum: null };
- //dm user
+ // dm user
const ending = this.guild.getSetting('punishmentEnding');
const dmSuccess = await this.send({
content: `You have been warned in **${this.guild}** for **${options.reason || 'No reason provided'}**.${
@@ -85,8 +93,12 @@ export class BushGuildMember extends GuildMember {
throw 'not implemented';
}
+ public removePunishRole(options: BushPunishmentRoleOptions): Promise<RemovePunishmentRoleResponse> {
+ throw 'not implemented';
+ }
+
public async mute(options: BushTimedPunishmentOptions): Promise<MuteResponse> {
- //checks
+ // checks
if (!this.guild.me.permissions.has('MANAGE_ROLES')) return 'missing permissions';
const muteRoleID = await this.guild.getSetting('muteRole');
if (!muteRoleID) return 'no mute role';
@@ -94,20 +106,20 @@ export class BushGuildMember extends GuildMember {
if (!muteRole) return 'invalid mute role';
if (muteRole.position >= this.guild.me.roles.highest.position || muteRole.managed) return 'mute role not manageable';
- const moderator = this.client.users.cache.get(this.client.users.resolveId(options.moderator));
+ const moderator = this.client.users.cache.get(this.client.users.resolveId(options.moderator || this.client.user));
- //add role
+ // add role
const muteSuccess = await this.roles
.add(muteRole, `[Mute] ${moderator.tag} | ${options.reason || 'No reason provided.'}`)
.catch(() => null);
if (!muteSuccess) return 'error giving mute role';
- //add modlog entry
+ // add modlog entry
const modlog = await this.client.util
.createModLogEntry({
type: options.duration ? ModLogType.TEMP_MUTE : ModLogType.PERM_MUTE,
user: this,
- moderator: options.moderator,
+ moderator: moderator.id,
reason: options.reason,
duration: options.duration,
guild: this.guild
@@ -116,7 +128,7 @@ export class BushGuildMember extends GuildMember {
if (!modlog) return 'error creating modlog entry';
// add punishment entry so they can be unmuted later
- const mute = await this.client.util
+ const punishmentEntrySuccess = await this.client.util
.createPunishmentEntry({
type: 'mute',
user: this,
@@ -125,9 +137,9 @@ export class BushGuildMember extends GuildMember {
modlog: modlog.id
})
.catch(() => null);
- if (!mute) return 'error creating mute entry';
+ if (!punishmentEntrySuccess) return 'error creating mute entry';
- //dm user
+ // dm user
const ending = this.guild.getSetting('punishmentEnding');
const dmSuccess = await this.send({
content: `You have been muted ${
@@ -141,14 +153,61 @@ export class BushGuildMember extends GuildMember {
}
public async unmute(options: BushPunishmentOptions): Promise<UnmuteResponse> {
- throw 'not implemented';
+ //checks
+ if (!this.guild.me.permissions.has('MANAGE_ROLES')) return 'missing permissions';
+ const muteRoleID = await this.guild.getSetting('muteRole');
+ if (!muteRoleID) return 'no mute role';
+ const muteRole = this.guild.roles.cache.get(muteRoleID);
+ if (!muteRole) return 'invalid mute role';
+ if (muteRole.position >= this.guild.me.roles.highest.position || muteRole.managed) return 'mute role not manageable';
+
+ const moderator = this.client.users.cache.get(this.client.users.resolveId(options.moderator || this.client.user));
+
+ //remove role
+ const muteSuccess = await this.roles
+ .remove(muteRole, `[Unmute] ${moderator.tag} | ${options.reason || 'No reason provided.'}`)
+ .catch(() => null);
+ if (!muteSuccess) return 'error removing mute role';
+
+ //remove modlog entry
+ const modlog = await this.client.util
+ .createModLogEntry({
+ type: ModLogType.UNMUTE,
+ user: this,
+ moderator: moderator.id,
+ reason: options.reason,
+ guild: this.guild
+ })
+ .catch(() => null);
+ if (!modlog) return 'error creating modlog entry';
+
+ // remove mute entry
+ const removePunishmentEntrySuccess = await this.client.util
+ .removePunishmentEntry({
+ type: 'mute',
+ user: this,
+ guild: this.guild
+ })
+ .catch(() => null);
+ if (!removePunishmentEntrySuccess) return 'error removing mute entry';
+
+ //dm user
+ const dmSuccess = await this.send({
+ content: `You have been unmuted in **${this.guild}** because **${options.reason || 'No reason provided'}**.`
+ }).catch(() => null);
+
+ if (!dmSuccess) return 'failed to dm';
+
+ return 'success';
}
public async bushKick(options: BushPunishmentOptions): Promise<KickResponse> {
- //checks
+ // checks
if (!this.guild.me.permissions.has('KICK_MEMBERS') || !this.kickable) return 'missing permissions';
- //dm user
+ const moderator = this.client.users.cache.get(this.client.users.resolveId(options.moderator || this.client.user));
+
+ // dm user
const ending = this.guild.getSetting('punishmentEnding');
const dmSuccess = await this.send({
content: `You have been kicked from **${this.guild}** for **${options.reason || 'No reason provided'}**.${
@@ -156,16 +215,16 @@ export class BushGuildMember extends GuildMember {
}`
}).catch(() => null);
- //Kick
- const kickSuccess = await this.kick().catch(() => null);
+ // kick
+ const kickSuccess = await this.kick(`${moderator.tag} | ${options.reason || 'No reason provided.'}`).catch(() => null);
if (!kickSuccess) return 'error kicking';
- //add modlog entry
+ // add modlog entry
const modlog = await this.client.util
.createModLogEntry({
type: ModLogType.KICK,
user: this,
- moderator: options.moderator,
+ moderator: moderator.id,
reason: options.reason,
guild: this.guild
})
@@ -176,7 +235,53 @@ export class BushGuildMember extends GuildMember {
}
public async bushBan(options?: BushBanOptions): Promise<BanResponse> {
- throw 'not implemented';
+ // checks
+ if (!this.guild.me.permissions.has('BAN_MEMBERS') || !this.bannable) return 'missing permissions';
+
+ const moderator = this.client.users.cache.get(this.client.users.resolveId(options.moderator || this.client.user));
+
+ // dm user
+ const ending = this.guild.getSetting('punishmentEnding');
+ const dmSuccess = await this.send({
+ content: `You have been banned ${
+ options.duration ? 'for ' + this.client.util.humanizeDuration(options.duration) : 'permanently'
+ } from **${this.guild}** for **${options.reason || 'No reason provided'}**.${ending ? `\n\n${ending}` : ''}`
+ }).catch(() => null);
+
+ // ban
+ const banSuccess = await this.ban({
+ reason: `${moderator.tag} | ${options.reason || 'No reason provided.'}`,
+ days: options.deleteDays
+ });
+ if (!banSuccess) return 'error banning';
+
+ // add modlog entry
+ const modlog = await this.client.util
+ .createModLogEntry({
+ type: options.duration ? ModLogType.TEMP_BAN : ModLogType.PERM_BAN,
+ user: this,
+ moderator: moderator.id,
+ reason: options.reason,
+ duration: options.duration,
+ guild: this.guild
+ })
+ .catch(() => null);
+ if (!modlog) return 'error creating modlog entry';
+
+ // add punishment entry so they can be unbanned later
+ const punishmentEntrySuccess = await this.client.util
+ .createPunishmentEntry({
+ type: 'ban',
+ user: this,
+ guild: this.guild,
+ duration: options.duration,
+ modlog: modlog.id
+ })
+ .catch(() => null);
+ if (!punishmentEntrySuccess) return 'error creating ban entry';
+
+ if (!dmSuccess) return 'failed to dm';
+ return 'success';
}
public isOwner(): boolean {