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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26