forked from Galactic/galactic-bot
- Fixed member requirement for Mute command
- Fixing other random shit - Limit TIME to Max32BitInt - Adding case delete commandoption
This commit is contained in:
parent
c8fb823b05
commit
427f07c5bb
@ -6,6 +6,7 @@ import { inspect } from 'util';
|
||||
import Util from '../../../../utilities/Util.js';
|
||||
import { EmbedDefaultColor, InfractionColors } from '../../../../constants/Constants.js';
|
||||
import { APIEmbed, GuildChannel, User } from 'discord.js';
|
||||
import Infraction from '../../../interfaces/Infraction.js';
|
||||
|
||||
class CaseCommand extends SlashCommand
|
||||
{
|
||||
@ -22,12 +23,13 @@ class CaseCommand extends SlashCommand
|
||||
minimum: 0,
|
||||
required: true
|
||||
}, {
|
||||
name: [ 'export', 'verbose', 'changes' ], //
|
||||
name: [ 'export', 'verbose', 'changes', 'delete' ], //
|
||||
type: CommandOptionType.BOOLEAN,
|
||||
description: [
|
||||
'Print out raw infraction data in JSON form',
|
||||
'Print out more detailed information about the case',
|
||||
'List changes to the case'
|
||||
'List changes to the case',
|
||||
'Delete the case'
|
||||
],
|
||||
dependsOn: [ 'id' ],
|
||||
flag: true,
|
||||
@ -41,24 +43,32 @@ class CaseCommand extends SlashCommand
|
||||
});
|
||||
}
|
||||
|
||||
async execute (invoker: InvokerWrapper, opts: CommandParams)
|
||||
async execute (invoker: InvokerWrapper<true>, opts: CommandParams)
|
||||
{
|
||||
const { id, verbose, export: exp, changes } = opts;
|
||||
const { id, verbose, export: exp, changes, delete: remove } = opts;
|
||||
const guild = invoker.guild!;
|
||||
|
||||
const infraction = await this.client.storageManager.mongodb.infractions.findOne({
|
||||
id: `${guild.id}:${id?.asNumber}`
|
||||
}, { projection: { _id: 0 } });
|
||||
const infraction = await new Infraction(this.client, this.logger, { guild, case: id!.asNumber }).fetch(true).catch(() => null);
|
||||
|
||||
if (!infraction)
|
||||
return { emoji: 'failure', index: 'COMMAND_CASE_NOTFOUND', params: { caseID: id!.asNumber } };
|
||||
if (remove?.asBool === true)
|
||||
{
|
||||
if (!invoker.member?.permissions.has('Administrator'))
|
||||
return { emoji: 'failure', index: 'ERR_MISSING_PERMISSIONS' };
|
||||
await infraction.resolve(invoker.member, invoker.format('COMMAND_CASE_DELETED_LOG'), false);
|
||||
await this.client.storageManager.mongodb.infractions.deleteOne({
|
||||
id: `${guild.id}:${id?.asNumber}`
|
||||
});
|
||||
return { emoji: 'success', index: 'COMMAND_CASE_DELETED', params: { caseID: id!.asNumber } };
|
||||
}
|
||||
if (exp?.asString)
|
||||
return `\`\`\`js\n${inspect(infraction)}\`\`\``;
|
||||
if (changes?.asString)
|
||||
return { embed: await this._listChanges(invoker, infraction) };
|
||||
return { embed: await this._listChanges(invoker, infraction.json) };
|
||||
|
||||
const target = infraction.targetType === 'USER' ? await this.client.resolver.resolveUser(infraction.target) : await guild.resolveChannel(infraction.target);
|
||||
const staff = await this.client.resolver.resolveUser(infraction.executor);
|
||||
const target = infraction.targetType === 'USER' ? await this.client.resolver.resolveUser(infraction.targetId!) : await guild.resolveChannel(infraction.targetId);
|
||||
const staff = await this.client.resolver.resolveUser(infraction.executor!);
|
||||
|
||||
let index = 'COMMAND_CASE_TEMPLATE',
|
||||
caseTitleIndex = 'COMMAND_CASE_TITLE',
|
||||
@ -75,7 +85,7 @@ class CaseCommand extends SlashCommand
|
||||
targetUserIndex += '_VERBOSE';
|
||||
targetChannelIndex += '_VERBOSE';
|
||||
}
|
||||
|
||||
const { json } = infraction;
|
||||
let description = invoker.format(index, {
|
||||
uniqueID: infraction.id,
|
||||
type: infraction.type,
|
||||
@ -86,25 +96,25 @@ class CaseCommand extends SlashCommand
|
||||
target: infraction.targetType === 'USER' ? invoker.format(targetUserIndex, { target: (target as User).tag, targetID: target!.id }) : invoker.format(targetChannelIndex, { target: (target as GuildChannel).name, targetID: target!.id }),
|
||||
staff: staff?.tag??'N/A',
|
||||
staffID: staff?.id??'N/A',
|
||||
nrChanges: infraction.changes?.length || 0,
|
||||
changes: infraction.changes?.map((change) => change.type).join(', ') || 'N/A',
|
||||
nrChanges: json.changes?.length || 0,
|
||||
changes: json.changes?.map((change) => change.type).join(', ') || 'N/A',
|
||||
guild: guild.id,
|
||||
channel: infraction.channel,
|
||||
message: infraction.message
|
||||
channel: json.channel,
|
||||
message: json.message
|
||||
});
|
||||
|
||||
if (infraction.data?.seconds)
|
||||
description += '\n' + invoker.format(caseSlowmodeIndex, { readable: Util.humanise(infraction.data.seconds), seconds: infraction.data.seconds });
|
||||
if (infraction.duration !== null)
|
||||
if (json.duration !== null)
|
||||
{
|
||||
const duration = Math.floor(infraction.duration / 1000);
|
||||
const duration = Math.floor(json.duration / 1000);
|
||||
description += '\n' + invoker.format(caseLengthIndex, { time: Util.humanise(duration), inSeconds: duration });
|
||||
}
|
||||
|
||||
if (guild._settings.modpoints.enabled)
|
||||
description += '\n' + invoker.format('COMMAND_CASE_MODPOINTS', {
|
||||
points: infraction.points,
|
||||
expires: infraction.expiration ? `<t:${Math.round(infraction.expiration / 1000)}:R>` : false
|
||||
expires: json.expiration ? `<t:${Math.round(json.expiration / 1000)}:R>` : false
|
||||
});
|
||||
|
||||
description += '\n\n' + invoker.format('COMMAND_CASE_REASON', { reason: infraction.reason });
|
||||
|
@ -3,7 +3,7 @@ import DiscordClient from '../../../DiscordClient.js';
|
||||
import { Mute } from '../../../infractions/index.js';
|
||||
import { CommandError, ModerationCommand } from '../../../interfaces/index.js';
|
||||
import InvokerWrapper from '../../wrappers/InvokerWrapper.js';
|
||||
import UserWrapper from '../../wrappers/UserWrapper.js';
|
||||
import MemberWrapper from '../../wrappers/MemberWrapper.js';
|
||||
|
||||
class MuteCommand extends ModerationCommand
|
||||
{
|
||||
@ -41,9 +41,9 @@ class MuteCommand extends ModerationCommand
|
||||
else if (!me!.permissions.has('ManageRoles'))
|
||||
throw new CommandError(invoker, { index: 'INHIBITOR_CLIENTPERMISSIONS_ERROR', formatParams: { command: this.name, missing: 'ManageRoles' } });
|
||||
|
||||
const wrappers = await Promise.all(users.asUsers.map(user => this.client.getUserWrapper(user)));
|
||||
const wrappers = await Promise.all(users!.asUsers.map(user => guild.memberWrapper(user)));
|
||||
return this.client.moderation.handleInfraction(Mute, invoker, {
|
||||
targets: wrappers.filter(Boolean) as UserWrapper[],
|
||||
targets: wrappers.filter(Boolean) as MemberWrapper[],
|
||||
args
|
||||
});
|
||||
|
||||
|
@ -3,7 +3,7 @@ import DiscordClient from '../../../DiscordClient.js';
|
||||
import { Nickname } from '../../../infractions/index.js';
|
||||
import { CommandError, ModerationCommand } from '../../../interfaces/index.js';
|
||||
import InvokerWrapper from '../../wrappers/InvokerWrapper.js';
|
||||
import UserWrapper from '../../wrappers/UserWrapper.js';
|
||||
import MemberWrapper from '../../wrappers/MemberWrapper.js';
|
||||
|
||||
class NicknameCommand extends ModerationCommand
|
||||
{
|
||||
@ -28,15 +28,15 @@ class NicknameCommand extends ModerationCommand
|
||||
|
||||
}
|
||||
|
||||
async execute (invoker: InvokerWrapper, { users, name, ...args }: CommandParams)
|
||||
async execute (invoker: InvokerWrapper<true>, { users, name, ...args }: CommandParams)
|
||||
{
|
||||
|
||||
if (!users)
|
||||
throw new CommandError(invoker, { index: 'MODERATION_MISSING_USERS' });
|
||||
|
||||
const wrappers = await Promise.all(users.asUsers.map(user => this.client.getUserWrapper(user)));
|
||||
const wrappers = await Promise.all(users!.asUsers.map(user => invoker.guild.memberWrapper(user)));
|
||||
return this.client.moderation.handleInfraction(Nickname, invoker, {
|
||||
targets: wrappers.filter(Boolean) as UserWrapper[],
|
||||
targets: wrappers.filter(Boolean) as MemberWrapper[],
|
||||
args,
|
||||
data: {
|
||||
name: name?.asString
|
||||
|
@ -21,7 +21,6 @@ class MuteInfraction extends Infraction
|
||||
}
|
||||
|
||||
member?: MemberWrapper;
|
||||
duration?: number;
|
||||
|
||||
constructor (client: DiscordClient, logger: LoggerClient, opts: MuteData)
|
||||
{
|
||||
@ -52,10 +51,7 @@ class MuteInfraction extends Infraction
|
||||
this.member = opts.target;
|
||||
const { mute } = this.guild._settings;
|
||||
if (!this.duration && (!mute.permanent || mute.type === MuteType.Timeout))
|
||||
{
|
||||
this.duration = mute.default * 1000;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -277,6 +273,7 @@ class MuteInfraction extends Infraction
|
||||
break;
|
||||
}
|
||||
}
|
||||
await super.resolve(_staff, _reason, _notify);
|
||||
return { message, error };
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import Command from './commands/Command.js';
|
||||
import moment from 'moment';
|
||||
import { GuildBasedChannel, GuildMember, Role, User } from 'discord.js';
|
||||
import Module from './Module.js';
|
||||
import { Max32BitInt } from '../../constants/Constants.js';
|
||||
|
||||
const PointsReg = /^([-+]?[0-9]+) ?(points|point|pts|pt|p)$/iu;
|
||||
const ChannelType: {[key: string]: number} = {
|
||||
@ -100,6 +101,8 @@ class CommandOption
|
||||
this.#minimum = options.minimum;
|
||||
if (typeof options.maximum === 'number')
|
||||
this.#maximum = options.maximum;
|
||||
if (typeof this.#maximum === 'undefined' || this.#maximum > Number.MAX_SAFE_INTEGER)
|
||||
this.#maximum = Number.MAX_SAFE_INTEGER;
|
||||
|
||||
this.#slashOption = options.slashOption || false;
|
||||
this.#flag = options.flag ?? false; // used with message based command options
|
||||
@ -277,7 +280,7 @@ class CommandOption
|
||||
POINTS: async () =>
|
||||
{
|
||||
if (this.slashOption)
|
||||
return { value: this.#rawValue };
|
||||
return { value: parseInt(this.#rawValue as string) };
|
||||
let value = null,
|
||||
removed = null;
|
||||
if (!this.#rawValue)
|
||||
@ -470,6 +473,8 @@ class CommandOption
|
||||
const value = this.client.resolver.resolveTime(this.#rawValue);
|
||||
if (value === null)
|
||||
return { error: true };
|
||||
if ((value*1000) > Max32BitInt)
|
||||
return { error: true, index: 'O_COMMANDHANDLER_TYPETIME_MAX', params: { maximum: Util.humanise(Max32BitInt/1000) } };
|
||||
if (typeof this.#maximum !== 'undefined' && value > this.#maximum)
|
||||
return { error: true, index: 'O_COMMANDHANDLER_TYPETIME_MAX', params: { maximum: Util.humanise(this.#maximum) } };
|
||||
return { value, removed: [ this.#rawValue ] };
|
||||
|
@ -244,9 +244,12 @@ class Infraction
|
||||
|
||||
async save ()
|
||||
{
|
||||
const { json } = this;
|
||||
const filter: {id: string, _id?: ObjectId} = { id: this.id };
|
||||
if (this.#mongoId)
|
||||
filter._id = this.#mongoId;
|
||||
if (json.points && typeof json.points !== 'number')
|
||||
throw new Error('Invalid points type');
|
||||
return this.#client.mongodb.infractions.updateOne(filter, { $set: this.json })
|
||||
.catch((error: Error) =>
|
||||
{
|
||||
@ -566,6 +569,16 @@ class Infraction
|
||||
return InfractionColors[this.#type!];
|
||||
}
|
||||
|
||||
get duration ()
|
||||
{
|
||||
return this.#duration;
|
||||
}
|
||||
|
||||
set duration (duration: number | null)
|
||||
{
|
||||
this.#duration = duration;
|
||||
}
|
||||
|
||||
// Super Functions
|
||||
protected _succeed (): InfractionSuccess
|
||||
{
|
||||
|
@ -2,6 +2,7 @@ import { InfractionType } from "../../@types/Client.js";
|
||||
|
||||
const ZeroWidthChar = '\u200b';
|
||||
const EmbedDefaultColor = 619452;
|
||||
const Max32BitInt = 2147483647;
|
||||
|
||||
const UploadLimit = {
|
||||
'0': 8,
|
||||
@ -235,6 +236,7 @@ export {
|
||||
UploadLimit,
|
||||
ZeroWidthChar,
|
||||
EmbedDefaultColor,
|
||||
Max32BitInt,
|
||||
PermissionNames,
|
||||
EmbedLimits,
|
||||
InfractionResolves,
|
||||
|
@ -369,6 +369,12 @@ View a specific case
|
||||
[COMMAND_CASE_NOTFOUND]
|
||||
No case matching ID `{caseID}` was found.
|
||||
|
||||
[COMMAND_CASE_DELETED]
|
||||
Case `{caseID}` was deleted.
|
||||
|
||||
[COMMAND_CASE_DELETED_LOG]
|
||||
Case deleted.
|
||||
|
||||
[COMMAND_CASE_TITLE]
|
||||
{emoji_book} Case **#{caseID}**
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user