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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26