/[sudobot]/trunk/src/commands/moderation/MuteCommand.ts
ViewVC logotype

Annotation of /trunk/src/commands/moderation/MuteCommand.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 427 - (hide annotations)
Mon Jul 29 17:30:11 2024 UTC (8 months, 3 weeks ago) by rakin
File MIME type: application/typescript
File size: 10755 byte(s)
refactor(muting): use new queue handler
1 rakin 393 /**
2     * This file is part of SudoBot.
3     *
4     * Copyright (C) 2021-2022 OSN Inc.
5     *
6     * SudoBot is free software; you can redistribute it and/or modify it
7     * under the terms of the GNU Affero General Public License as published by
8     * the Free Software Foundation, either version 3 of the License, or
9     * (at your option) any later version.
10     *
11     * SudoBot is distributed in the hope that it will be useful, but
12     * WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU Affero General Public License for more details.
15     *
16     * You should have received a copy of the GNU Affero General Public License
17     * along with SudoBot. If not, see <https://www.gnu.org/licenses/>.
18     */
19    
20 rakin 400 import { CommandInteraction, Guild, GuildMember, Message, Permissions, User } from 'discord.js';
21 rakin 51 import BaseCommand from '../../utils/structures/BaseCommand';
22     import DiscordClient from '../../client/Client';
23     import CommandOptions from '../../types/CommandOptions';
24     import InteractionOptions from '../../types/InteractionOptions';
25     import MessageEmbed from '../../client/MessageEmbed';
26     import getMember from '../../utils/getMember';
27     import ms from 'ms';
28 rakin 86 import PunishmentType from '../../types/PunishmentType';
29 rakin 194 import { hasPermission, shouldNotModerate } from '../../utils/util';
30 rakin 427 import UnmuteQueue from '../../queues/UnmuteQueue';
31 rakin 51
32 rakin 400 export async function mute(client: DiscordClient, dateTime: number | undefined, user: GuildMember, msg: Message | CommandInteraction | { guild: Guild, member: GuildMember, editReply?: undefined }, timeInterval: number | undefined, reason: string | undefined, hard: boolean = false) {
33 rakin 51 try {
34 rakin 86 const { default: Punishment } = await import('../../models/Punishment');
35    
36 rakin 102 const { getTimeouts, clearTimeoutv2, setTimeoutv2 } = await import('../../utils/setTimeout');
37    
38     const timeouts = getTimeouts();
39    
40     for (const timeout of timeouts.values()) {
41     if (timeout.row.params) {
42     try {
43     const json = JSON.parse(timeout.row.params);
44    
45     if (json) {
46 rakin 106 if (json[1] === user.id && timeout.row.filePath.endsWith('unmute-job')) {
47 rakin 102 await clearTimeoutv2(timeout);
48     }
49     }
50     }
51     catch (e) {
52     console.log(e);
53     }
54     }
55     }
56    
57     if (dateTime && timeInterval) {
58 rakin 427 // await setTimeoutv2('unmute-job', timeInterval, msg.guild!.id, `unmute ${user.id}`, msg.guild!.id, user.id);
59     await client.queueManager.addQueue(UnmuteQueue, {
60     data: {
61     guildID: msg.guild!.id,
62     memberID: user.id
63     },
64     runAt: new Date(Date.now() + timeInterval)
65     });
66 rakin 51 }
67 rakin 102
68 rakin 124 if (hard) {
69     const { default: Hardmute } = await import("../../models/Hardmute");
70     const roles = await user.roles.cache.filter(r => r.id !== msg.guild!.id);
71     await user.roles.remove(roles, reason);
72    
73     await Hardmute.create({
74     user_id: user.id,
75     roles: roles.map(role => role.id),
76     guild_id: msg.guild!.id,
77 rakin 333 createdAt: new Date()
78 rakin 124 });
79     }
80    
81 rakin 400 const role = await msg.guild!.roles.fetch(client.config.props[msg.guild!.id].mute_role);
82 rakin 124 await user.roles.add(role!, reason);
83 rakin 86
84     await Punishment.create({
85 rakin 124 type: hard ? PunishmentType.HARDMUTE : PunishmentType.MUTE,
86 rakin 86 user_id: user.id,
87     guild_id: msg.guild!.id,
88     mod_id: msg.member!.user.id,
89     mod_tag: (msg.member!.user as User).tag,
90     reason,
91     meta: {
92     time: timeInterval ? ms(timeInterval) : undefined
93 rakin 336 },
94     createdAt: new Date()
95 rakin 86 });
96 rakin 124
97     await client.logger.logMute(user, reason === undefined || reason.trim() === '' ? "*No reason provided*" : reason, timeInterval, msg.member!.user as User, hard);
98 rakin 159
99     try {
100     await user.send({
101     embeds: [
102     new MessageEmbed()
103     .setAuthor({
104     iconURL: <string> msg.guild!.iconURL(),
105     name: `\tYou have been muted in ${msg.guild!.name}`
106     })
107     .addField("Reason", reason === undefined || reason.trim() === '' ? "*No reason provided*" : reason)
108     ]
109     });
110     }
111     catch (e) {
112     console.log(e);
113     }
114 rakin 51 }
115     catch (e) {
116     console.log(e);
117    
118 rakin 124 if (msg instanceof Message)
119     await msg.reply({
120     embeds: [
121     new MessageEmbed()
122     .setColor('#f14a60')
123     .setDescription("Failed to assign the muted role to this user. Maybe missing permisions/roles or I'm not allowed to assign roles this user?")
124     ]
125     });
126 rakin 400 else if (msg.editReply)
127 rakin 124 await msg.editReply({
128     embeds: [
129     new MessageEmbed()
130     .setColor('#f14a60')
131     .setDescription("Failed to assign the muted role to this user. Maybe missing permisions/roles or I'm not allowed to assign roles this user?")
132     ]
133     });
134 rakin 51
135     return;
136     }
137     }
138    
139     export default class MuteCommand extends BaseCommand {
140     supportsInteractions: boolean = true;
141 rakin 203 permissions = [Permissions.FLAGS.MODERATE_MEMBERS];
142 rakin 51
143     constructor() {
144     super('mute', 'moderation', []);
145     }
146    
147     async run(client: DiscordClient, msg: Message | CommandInteraction, options: CommandOptions | InteractionOptions) {
148     if (!options.isInteraction && typeof options.args[0] === 'undefined') {
149     await msg.reply({
150     embeds: [
151     new MessageEmbed()
152     .setColor('#f14a60')
153     .setDescription(`This command requires at least one argument.`)
154     ]
155     });
156    
157     return;
158     }
159    
160 rakin 124 if (msg instanceof CommandInteraction)
161     await msg.deferReply();
162    
163 rakin 51 let user: GuildMember;
164     let reason: string | undefined;
165     let time: string | undefined;
166     let timeInterval: number | undefined;
167     let dateTime: number | undefined;
168 rakin 124 let hard: boolean = false;
169 rakin 51
170     if (options.isInteraction) {
171     user = await <GuildMember> options.options.getMember('member');
172    
173     if (options.options.getString('reason')) {
174     reason = await <string> options.options.getString('reason');
175     }
176    
177 rakin 124 if (options.options.getBoolean('hardmute')) {
178     hard = await <boolean> options.options.getBoolean('hardmute');
179     }
180    
181 rakin 51 if (options.options.getString('time')) {
182     time = await options.options.getString('time') as string;
183     timeInterval = await ms(time);
184    
185     if (!timeInterval) {
186 rakin 124 await this.deferReply(msg, {
187 rakin 51 embeds: [
188     new MessageEmbed()
189     .setColor('#f14a60')
190     .setDescription(`Option \`-t\` (time) requires an argument which must be a valid time interval.`)
191     ]
192     });
193    
194     return;
195     }
196     }
197     }
198     else {
199     const user2 = await getMember((msg as Message), options);
200    
201     if (!user2) {
202 rakin 124 await this.deferReply(msg, {
203 rakin 51 embeds: [
204     new MessageEmbed()
205     .setColor('#f14a60')
206     .setDescription(`Invalid user given.`)
207     ]
208     });
209    
210     return;
211     }
212    
213     user = user2;
214    
215     const index = await options.args.indexOf('-t');
216    
217     if (options.args[1]) {
218     const args = [...options.args];
219     args.shift();
220    
221     if (index !== -1) {
222 rakin 124 args.splice(index - 1, 2);
223 rakin 51 }
224    
225     reason = await args.join(' ');
226     }
227    
228     if (index !== -1) {
229     time = await options.args[index + 1];
230    
231     if (time === undefined) {
232 rakin 124 await this.deferReply(msg, {
233 rakin 51 embeds: [
234     new MessageEmbed()
235     .setColor('#f14a60')
236     .setDescription(`Option \`-t\` (time) requires an argument.`)
237     ]
238     });
239    
240     return;
241     }
242    
243     if (!ms(time)) {
244 rakin 124 await this.deferReply(msg, {
245 rakin 51 embeds: [
246     new MessageEmbed()
247     .setColor('#f14a60')
248     .setDescription(`Option \`-t\` (time) requires an argument which must be a valid time interval.`)
249     ]
250     });
251    
252     return;
253     }
254    
255     timeInterval = await ms(time);
256     }
257     }
258    
259     if (timeInterval) {
260     dateTime = Date.now() + timeInterval;
261     }
262    
263 rakin 194 if (!(await hasPermission(client, user, msg, null, "You don't have permission to mute this user."))) {
264     return;
265     }
266    
267 rakin 153 if (shouldNotModerate(client, user)) {
268     await msg.reply({
269     embeds: [
270     {
271     description: "This user cannot be muted."
272     }
273     ]
274     });
275    
276     return;
277     }
278    
279 rakin 124 await mute(client, dateTime, user, msg, timeInterval, reason, hard);
280 rakin 51
281     const fields = [
282     {
283     name: "Muted by",
284     value: (msg.member!.user as User).tag
285     },
286     {
287     name: "Reason",
288     value: reason === undefined || reason.trim() === '' ? "*No reason provided*" : reason
289     },
290     {
291     name: "Duration",
292     value: time === undefined ? "*No duration set*" : (time + '')
293 rakin 124 },
294     {
295     name: "Role Takeout",
296     value: hard ? 'Yes' : 'No'
297 rakin 51 }
298     ];
299    
300     console.log(fields);
301    
302 rakin 124 await this.deferReply(msg, {
303 rakin 51 embeds: [
304     new MessageEmbed()
305     .setAuthor({
306     name: user.user.tag,
307     iconURL: user.displayAvatarURL(),
308     })
309     .setDescription(user.user.tag + " has been muted.")
310     .addFields(fields)
311     ]
312     });
313     }
314 rakin 153 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26