aboutsummaryrefslogtreecommitdiff
path: root/src/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands')
-rw-r--r--src/commands/moderation/ban.ts21
-rw-r--r--src/commands/moderation/block.ts22
-rw-r--r--src/commands/moderation/kick.ts2
-rw-r--r--src/commands/moderation/lockdown.ts18
-rw-r--r--src/commands/moderation/mute.ts22
-rw-r--r--src/commands/moderation/role.ts12
-rw-r--r--src/commands/moderation/timeout.ts100
-rw-r--r--src/commands/moderation/unban.ts2
-rw-r--r--src/commands/moderation/unblock.ts6
-rw-r--r--src/commands/moderation/unlockdown.ts20
-rw-r--r--src/commands/moderation/unmute.ts6
-rw-r--r--src/commands/moderation/untimeout.ts100
-rw-r--r--src/commands/moderation/warn.ts4
13 files changed, 274 insertions, 61 deletions
diff --git a/src/commands/moderation/ban.ts b/src/commands/moderation/ban.ts
index 40ac506..f21ccdc 100644
--- a/src/commands/moderation/ban.ts
+++ b/src/commands/moderation/ban.ts
@@ -15,7 +15,7 @@ export default class BanCommand extends BushCommand {
aliases: ['ban', 'force-ban', 'dban'],
category: 'moderation',
description: 'Ban a member from the server.',
- usage: ['ban <member> <reason> [--delete]'],
+ usage: ['ban <member> [reasonAndDuration] [--delete]'],
examples: ['ban ironm00n 1 day commands in #general --delete 7'],
args: [
{
@@ -27,10 +27,10 @@ export default class BanCommand extends BushCommand {
slashType: 'USER'
},
{
- id: 'reason',
+ id: 'reason_and_duration',
description: 'The reason and duration of the ban.',
type: 'contentWithDuration',
- match: 'restContent',
+ match: 'rest',
prompt: 'Why should this user be banned and for how long?',
retry: '{error} Choose a valid ban reason and duration.',
slashType: 'STRING',
@@ -70,12 +70,12 @@ export default class BanCommand extends BushCommand {
message: BushMessage | BushSlashMessage,
args: {
user: ArgType<'user'> | ArgType<'snowflake'>;
- reason: OptionalArgType<'contentWithDuration'>;
+ reason_and_duration: OptionalArgType<'contentWithDuration'>;
days: OptionalArgType<'integer'>;
force: boolean;
}
) {
- if (args.reason && typeof args.reason === 'object') args.reason.duration ??= 0;
+ if (args.reason_and_duration && typeof args.reason_and_duration === 'object') args.reason_and_duration.duration ??= 0;
args.days ??= 0;
if (!message.guild) return message.util.reply(`${util.emojis.error} This command cannot be used in dms.`);
@@ -100,10 +100,13 @@ export default class BanCommand extends BushCommand {
}
let time: number | null;
- if (args.reason) {
- time = typeof args.reason === 'string' ? await util.arg.cast('duration', message, args.reason) : args.reason.duration;
+ if (args.reason_and_duration) {
+ time =
+ typeof args.reason_and_duration === 'string'
+ ? await util.arg.cast('duration', message, args.reason_and_duration)
+ : args.reason_and_duration.duration;
}
- const parsedReason = args.reason?.contentWithoutTime ?? null;
+ const parsedReason = args.reason_and_duration?.contentWithoutTime ?? null;
const responseCode = member
? await member.bushBan({
@@ -120,7 +123,7 @@ export default class BanCommand extends BushCommand {
deleteDays: args.days
});
- const responseMessage = () => {
+ const responseMessage = (): string => {
const victim = util.format.input(user.tag);
switch (responseCode) {
case 'missing permissions':
diff --git a/src/commands/moderation/block.ts b/src/commands/moderation/block.ts
index 371975b..d53ffd5 100644
--- a/src/commands/moderation/block.ts
+++ b/src/commands/moderation/block.ts
@@ -17,7 +17,7 @@ export default class BlockCommand extends BushCommand {
aliases: ['block'],
category: 'moderation',
description: 'Prevent a user from using a channel.',
- usage: ['block <member> [reason] [duration]'],
+ usage: ['block <member> [reasonAndDuration]'],
examples: ['block IRONM00N 2h bad jokes'],
args: [
{
@@ -29,7 +29,7 @@ export default class BlockCommand extends BushCommand {
slashType: 'USER'
},
{
- id: 'reason',
+ id: 'reason_and_duration',
description: 'The reason and duration of the block.',
type: 'contentWithDuration',
match: 'rest',
@@ -58,16 +58,20 @@ export default class BlockCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- args: { user: ArgType<'user'>; reason: OptionalArgType<'contentWithDuration'> | string; force?: ArgType<'boolean'> }
+ args: {
+ user: ArgType<'user'>;
+ reason_and_duration: OptionalArgType<'contentWithDuration'> | string;
+ force?: ArgType<'boolean'>;
+ }
) {
assert(message.inGuild());
if (!(message.channel instanceof BushTextChannel || message.channel instanceof BushThreadChannel))
return message.util.send(`${util.emojis.error} This command can only be used in text and thread channels.`);
- const reason = args.reason
- ? typeof args.reason === 'string'
- ? await util.arg.cast('contentWithDuration', message, args.reason)
- : args.reason
+ const reason = args.reason_and_duration
+ ? typeof args.reason_and_duration === 'string'
+ ? await util.arg.cast('contentWithDuration', message, args.reason_and_duration)
+ : args.reason_and_duration
: { duration: null, contentWithoutTime: '' };
if (reason.duration === null) reason.duration = 0;
@@ -91,14 +95,14 @@ export default class BlockCommand extends BushCommand {
const parsedReason = reason?.contentWithoutTime ?? '';
- const responseCode = await member.block({
+ const responseCode = await member.bushBlock({
reason: parsedReason,
moderator: message.member,
duration: time ?? 0,
channel: message.channel
});
- const responseMessage = () => {
+ const responseMessage = (): string => {
const victim = util.format.input(member.user.tag);
switch (responseCode) {
case 'missing permissions':
diff --git a/src/commands/moderation/kick.ts b/src/commands/moderation/kick.ts
index 587f89e..6d96ae9 100644
--- a/src/commands/moderation/kick.ts
+++ b/src/commands/moderation/kick.ts
@@ -65,7 +65,7 @@ export default class KickCommand extends BushCommand {
moderator: message.member
});
- const responseMessage = () => {
+ const responseMessage = (): string => {
const victim = util.format.input(member.user.tag);
switch (responseCode) {
case 'missing permissions':
diff --git a/src/commands/moderation/lockdown.ts b/src/commands/moderation/lockdown.ts
index b9febbd..ae9a62b 100644
--- a/src/commands/moderation/lockdown.ts
+++ b/src/commands/moderation/lockdown.ts
@@ -32,15 +32,6 @@ export default class LockdownCommand extends BushCommand {
optional: true
},
{
- id: 'all',
- description: 'Whether or not to lock all configured channels.',
- match: 'flag',
- flag: '--all',
- prompt: 'Would you like to lockdown all configured channels?',
- slashType: 'BOOLEAN',
- optional: true
- },
- {
id: 'reason',
description: 'The reason for the lockdown.',
type: 'string',
@@ -48,6 +39,15 @@ export default class LockdownCommand extends BushCommand {
prompt: 'What is the reason for the lockdown?',
slashType: 'STRING',
optional: true
+ },
+ {
+ id: 'all',
+ description: 'Whether or not to lock all configured channels.',
+ match: 'flag',
+ flag: '--all',
+ prompt: 'Would you like to lockdown all configured channels?',
+ slashType: 'BOOLEAN',
+ optional: true
}
],
slash: true,
diff --git a/src/commands/moderation/mute.ts b/src/commands/moderation/mute.ts
index eeffc6c..e731e30 100644
--- a/src/commands/moderation/mute.ts
+++ b/src/commands/moderation/mute.ts
@@ -15,7 +15,7 @@ export default class MuteCommand extends BushCommand {
aliases: ['mute'],
category: 'moderation',
description: 'Mute a user.',
- usage: ['mute <member> [reason] [duration]'],
+ usage: ['mute <member> [reasonAndDuration]'],
examples: ['mute ironm00n 1 day commands in #general'],
args: [
{
@@ -27,7 +27,7 @@ export default class MuteCommand extends BushCommand {
slashType: 'USER'
},
{
- id: 'reason',
+ id: 'reason_and_duration',
description: 'The reason and duration of the mute.',
type: 'contentWithDuration',
match: 'rest',
@@ -56,12 +56,16 @@ export default class MuteCommand extends BushCommand {
public override async exec(
message: BushMessage | BushSlashMessage,
- args: { user: ArgType<'user'>; reason: OptionalArgType<'contentWithDuration'> | string; force?: ArgType<'boolean'> }
+ args: {
+ user: ArgType<'user'>;
+ reason_and_duration: OptionalArgType<'contentWithDuration'> | string;
+ force?: ArgType<'boolean'>;
+ }
) {
- const reason = args.reason
- ? typeof args.reason === 'string'
- ? await util.arg.cast('contentWithDuration', message, args.reason)
- : args.reason
+ const reason = args.reason_and_duration
+ ? typeof args.reason_and_duration === 'string'
+ ? await util.arg.cast('contentWithDuration', message, args.reason_and_duration)
+ : args.reason_and_duration
: { duration: null, contentWithoutTime: '' };
if (reason.duration === null) reason.duration = 0;
@@ -85,13 +89,13 @@ export default class MuteCommand extends BushCommand {
const parsedReason = reason?.contentWithoutTime ?? '';
- const responseCode = await member.mute({
+ const responseCode = await member.bushMute({
reason: parsedReason,
moderator: message.member,
duration: time ?? 0
});
- const responseMessage = () => {
+ const responseMessage = (): string => {
const prefix = util.prefix(message);
const victim = util.format.input(member.user.tag);
switch (responseCode) {
diff --git a/src/commands/moderation/role.ts b/src/commands/moderation/role.ts
index 9fd34b5..6cb8d2f 100644
--- a/src/commands/moderation/role.ts
+++ b/src/commands/moderation/role.ts
@@ -154,20 +154,20 @@ export default class RoleCommand extends BushCommand {
const responseCode =
args.action === 'add'
- ? await args.member.addRole({
+ ? await args.member.bushAddRole({
moderator: message.member!,
addToModlog: shouldLog,
role: args.role,
duration: args.duration
})
- : await args.member.removeRole({
+ : await args.member.bushRemoveRole({
moderator: message.member!,
addToModlog: shouldLog,
role: args.role,
duration: args.duration
});
- const responseMessage = () => {
+ const responseMessage = (): string => {
const victim = util.format.input(args.member.user.tag);
switch (responseCode) {
case 'user hierarchy':
@@ -178,11 +178,13 @@ export default class RoleCommand extends BushCommand {
return `${util.emojis.error} <@&${args.role.id}> is higher or equal to my highest role.`;
case 'error creating modlog entry':
return `${util.emojis.error} There was an error creating a modlog entry, please report this to my developers.`;
- case 'error creating role entry' || 'error removing role entry':
+ case 'error creating role entry':
+ case 'error removing role entry':
return `${util.emojis.error} There was an error ${
args.action === 'add' ? 'creating' : 'removing'
} a punishment entry, please report this to my developers.`;
- case 'error adding role' || 'error removing role':
+ case 'error adding role':
+ case 'error removing role':
return `${util.emojis.error} An error occurred while trying to ${args.action} <@&${args.role.id}> ${
args.action === 'add' ? 'to' : 'from'
} ${victim}.`;
diff --git a/src/commands/moderation/timeout.ts b/src/commands/moderation/timeout.ts
new file mode 100644
index 0000000..f187a58
--- /dev/null
+++ b/src/commands/moderation/timeout.ts
@@ -0,0 +1,100 @@
+import { AllowedMentions, BushCommand, Moderation, type ArgType, type BushMessage, type BushSlashMessage } from '#lib';
+import assert from 'assert';
+
+export default class TimeoutCommand extends BushCommand {
+ public constructor() {
+ super('timeout', {
+ aliases: ['timeout'],
+ category: 'moderation',
+ description: 'Timeout a user.',
+ usage: ['timeout <user> <reasonAndDuration>'],
+ examples: ['timeout IRONM00N 2h'],
+ args: [
+ {
+ id: 'user',
+ description: 'The user to timeout.',
+ type: 'user',
+ prompt: 'What user would you like to timeout?',
+ retry: '{error} Choose a valid user to timeout.',
+ slashType: 'USER'
+ },
+ {
+ id: 'reason_and_duration',
+ description: 'The reason and duration of the timeout.',
+ type: 'contentWithDuration',
+ match: 'rest',
+ prompt: 'Why should this user be timed out and for how long?',
+ retry: '{error} Choose a valid timeout reason and duration.',
+ slashType: 'STRING'
+ },
+ {
+ id: 'force',
+ description: 'Override permission checks.',
+ flag: '--force',
+ match: 'flag',
+ optional: true,
+ slashType: false,
+ only: 'text',
+ ownerOnly: true
+ }
+ ],
+ slash: true,
+ channel: 'guild',
+ clientPermissions: (m) => util.clientSendAndPermCheck(m, ['MODERATE_MEMBERS']),
+ userPermissions: ['MODERATE_MEMBERS']
+ });
+ }
+
+ public override async exec(
+ message: BushMessage | BushSlashMessage,
+ args: { user: ArgType<'user'>; reason_and_duration: ArgType<'contentWithDuration'> | string; force?: ArgType<'boolean'> }
+ ) {
+ const reason = args.reason_and_duration
+ ? typeof args.reason_and_duration === 'string'
+ ? await util.arg.cast('contentWithDuration', message, args.reason_and_duration)
+ : args.reason_and_duration
+ : { duration: null, contentWithoutTime: '' };
+
+ if (reason.duration === null || reason.duration < 1)
+ return await message.util.reply(`${util.emojis.error} You must specify a duration for timeouts.`);
+ const member = await message.guild!.members.fetch(args.user.id).catch(() => null);
+ if (!member)
+ return await message.util.reply(`${util.emojis.error} The user you selected is not in the server or is not a valid user.`);
+
+ assert(message.member);
+ const useForce = args.force && message.author.isOwner();
+ const canModerateResponse = await Moderation.permissionCheck(message.member, member, 'timeout', true, useForce);
+
+ if (canModerateResponse !== true) {
+ return message.util.reply(canModerateResponse);
+ }
+
+ const time = reason.duration;
+ const parsedReason = reason.contentWithoutTime ?? '';
+
+ const responseCode = await member.bushTimeout({
+ reason: parsedReason,
+ moderator: message.member,
+ duration: time
+ });
+
+ const responseMessage = (): string => {
+ const victim = util.format.input(member.user.tag);
+ switch (responseCode) {
+ case 'missing permissions':
+ return `${util.emojis.error} Could not timeout ${victim} because I am missing the **Timeout Members** permission.`;
+ case 'duration too long':
+ return `${util.emojis.error} The duration you specified is too long, the longest you can timeout someone for is 28 days.`;
+ case 'error timing out':
+ return `${util.emojis.error} An unknown error occurred while trying to timeout ${victim}.`;
+ case 'error creating modlog entry':
+ return `${util.emojis.error} There was an error creating a modlog entry, please report this to my developers.`;
+ case 'failed to dm':
+ return `${util.emojis.warn} Timed out ${victim} however I could not send them a dm.`;
+ case 'success':
+ return `${util.emojis.success} Successfully timed out ${victim}.`;
+ }
+ };
+ return await message.util.reply({ content: responseMessage(), allowedMentions: AllowedMentions.none() });
+ }
+}
diff --git a/src/commands/moderation/unban.ts b/src/commands/moderation/unban.ts
index 03c60c0..bbce4e0 100644
--- a/src/commands/moderation/unban.ts
+++ b/src/commands/moderation/unban.ts
@@ -44,7 +44,7 @@ export default class UnbanCommand extends BushCommand {
reason
});
- const responseMessage = () => {
+ const responseMessage = (): string => {
const victim = util.format.input(user.tag);
switch (responseCode) {
case 'missing permissions':
diff --git a/src/commands/moderation/unblock.ts b/src/commands/moderation/unblock.ts
index f9f069b..4cc8b49 100644
--- a/src/commands/moderation/unblock.ts
+++ b/src/commands/moderation/unblock.ts
@@ -18,7 +18,7 @@ export default class UnblockCommand extends BushCommand {
category: 'moderation',
description: 'Allows a user to use a channel.',
usage: ['unblock <member> [reason]'],
- examples: ['unblock IRONM00N 2h bad jokes'],
+ examples: ['unblock IRONM00N nvm your jokes are funny'],
args: [
{
id: 'user',
@@ -78,13 +78,13 @@ export default class UnblockCommand extends BushCommand {
const parsedReason = args.reason ?? '';
- const responseCode = await member.unblock({
+ const responseCode = await member.bushUnblock({
reason: parsedReason,
moderator: message.member,
channel: message.channel
});
- const responseMessage = () => {
+ const responseMessage = (): string => {
const victim = util.format.input(member.user.tag);
switch (responseCode) {
case 'missing permissions':
diff --git a/src/commands/moderation/unlockdown.ts b/src/commands/moderation/unlockdown.ts
index 24af305..5bcea32 100644
--- a/src/commands/moderation/unlockdown.ts
+++ b/src/commands/moderation/unlockdown.ts
@@ -8,7 +8,7 @@ export default class UnlockdownCommand extends BushCommand {
category: 'moderation',
description: 'Allows you to unlockdown a channel or all configured channels.',
usage: ['unlockdown [channel] [reason] [--all]'],
- examples: ['unlockdown', 'unlockdown --all'],
+ examples: ['unlockdown', 'unlockdown raid is over --all'],
args: [
{
id: 'channel',
@@ -20,15 +20,6 @@ export default class UnlockdownCommand extends BushCommand {
optional: true
},
{
- id: 'all',
- description: 'Whether or not to unlock all configured channels.',
- match: 'flag',
- flag: '--all',
- prompt: 'Would you like to unlockdown all configured channels?',
- slashType: 'BOOLEAN',
- optional: true
- },
- {
id: 'reason',
description: 'The reason for the unlock.',
type: 'string',
@@ -36,6 +27,15 @@ export default class UnlockdownCommand extends BushCommand {
prompt: 'What is the reason for the unlock?',
slashType: 'STRING',
optional: true
+ },
+ {
+ id: 'all',
+ description: 'Whether or not to unlock all configured channels.',
+ match: 'flag',
+ flag: '--all',
+ prompt: 'Would you like to unlockdown all configured channels?',
+ slashType: 'BOOLEAN',
+ optional: true
}
],
slash: true,
diff --git a/src/commands/moderation/unmute.ts b/src/commands/moderation/unmute.ts
index e7a19d6..631f213 100644
--- a/src/commands/moderation/unmute.ts
+++ b/src/commands/moderation/unmute.ts
@@ -16,7 +16,7 @@ export default class UnmuteCommand extends BushCommand {
category: 'moderation',
description: 'unmute a user.',
usage: ['unmute <member> [reason]'],
- examples: ['unmute 322862723090219008 1 day commands in #general'],
+ examples: ['unmute 322862723090219008 you have been forgiven'],
args: [
{
id: 'user',
@@ -70,12 +70,12 @@ export default class UnmuteCommand extends BushCommand {
return message.util.reply(canModerateResponse);
}
- const responseCode = await member.unmute({
+ const responseCode = await member.bushUnmute({
reason,
moderator: message.member
});
- const responseMessage = () => {
+ const responseMessage = (): string => {
const prefix = util.prefix(message);
const victim = util.format.input(member.user.tag);
switch (responseCode) {
diff --git a/src/commands/moderation/untimeout.ts b/src/commands/moderation/untimeout.ts
new file mode 100644
index 0000000..b5ea5be
--- /dev/null
+++ b/src/commands/moderation/untimeout.ts
@@ -0,0 +1,100 @@
+import {
+ AllowedMentions,
+ BushCommand,
+ Moderation,
+ type ArgType,
+ type BushMessage,
+ type BushSlashMessage,
+ type OptionalArgType
+} from '#lib';
+import assert from 'assert';
+
+export default class UntimeoutCommand extends BushCommand {
+ public constructor() {
+ super('untimeout', {
+ aliases: ['untimeout', 'remove-timeout'],
+ category: 'moderation',
+ description: 'Removes a timeout from a user.',
+ usage: ['untimeout <user> [reason]'],
+ examples: ['untimeout 1 2'],
+ args: [
+ {
+ id: 'user',
+ description: 'The user to remove a timeout from.',
+ type: 'user',
+ prompt: 'What user would you like to untimeout?',
+ retry: '{error} Choose a valid user to untimeout.',
+ slashType: 'USER'
+ },
+ {
+ id: 'reason',
+ description: 'The reason for removing the timeout.',
+ type: 'string',
+ match: 'rest',
+ prompt: 'Why should this user have their timeout removed?',
+ retry: '{error} Choose a valid reason to remove the timeout.',
+ slashType: 'STRING',
+ optional: true
+ },
+ {
+ id: 'force',
+ description: 'Override permission checks.',
+ flag: '--force',
+ match: 'flag',
+ optional: true,
+ slashType: false,
+ only: 'text',
+ ownerOnly: true
+ }
+ ],
+ slash: true,
+ channel: 'guild',
+ clientPermissions: (m) => util.clientSendAndPermCheck(m, ['MODERATE_MEMBERS']),
+ userPermissions: ['MODERATE_MEMBERS']
+ });
+ }
+
+ public override async exec(
+ message: BushMessage | BushSlashMessage,
+ args: { user: ArgType<'user'>; reason: OptionalArgType<'string'>; force?: ArgType<'boolean'> }
+ ) {
+ assert(message.member);
+
+ const member = await message.guild!.members.fetch(args.user.id).catch(() => null);
+ if (!member)
+ return await message.util.reply(`${util.emojis.error} The user you selected is not in the server or is not a valid user.`);
+
+ if (!member.isCommunicationDisabled()) return message.util.reply(`${util.emojis.error} That user is not timed out.`);
+
+ const useForce = args.force && message.author.isOwner();
+ const canModerateResponse = await Moderation.permissionCheck(message.member, member, 'timeout', true, useForce);
+
+ if (canModerateResponse !== true) {
+ return message.util.reply(canModerateResponse);
+ }
+
+ const responseCode = await member.bushRemoveTimeout({
+ reason: args.reason ?? undefined,
+ moderator: message.member
+ });
+
+ const responseMessage = (): string => {
+ const victim = util.format.input(member.user.tag);
+ switch (responseCode) {
+ case 'missing permissions':
+ return `${util.emojis.error} Could not timeout ${victim} because I am missing the **Timeout Members** permission.`;
+ case 'duration too long':
+ return `${util.emojis.error} The duration you specified is too long, the longest you can timeout someone for is 28 days.`;
+ case 'error removing timeout':
+ return `${util.emojis.error} An unknown error occurred while trying to timeout ${victim}.`;
+ case 'error creating modlog entry':
+ return `${util.emojis.error} There was an error creating a modlog entry, please report this to my developers.`;
+ case 'failed to dm':
+ return `${util.emojis.warn} Timed out ${victim} however I could not send them a dm.`;
+ case 'success':
+ return `${util.emojis.success} Successfully timed out ${victim}.`;
+ }
+ };
+ return await message.util.reply({ content: responseMessage(), allowedMentions: AllowedMentions.none() });
+ }
+}
diff --git a/src/commands/moderation/warn.ts b/src/commands/moderation/warn.ts
index 5093c9b..05b1e36 100644
--- a/src/commands/moderation/warn.ts
+++ b/src/commands/moderation/warn.ts
@@ -67,12 +67,12 @@ export default class WarnCommand extends BushCommand {
return message.util.reply(canModerateResponse);
}
- const { result: response, caseNum } = await member.warn({
+ const { result: response, caseNum } = await member.bushWarn({
reason,
moderator: message.member
});
- const responseMessage = () => {
+ const responseMessage = (): string => {
const victim = util.format.input(member.user.tag);
switch (response) {
case 'error creating modlog entry':