1 |
rakinar2 |
577 |
/** |
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, Message, 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 getUser from '../../utils/getUser'; |
27 |
|
|
import Punishment from '../../models/Punishment'; |
28 |
|
|
import { fetchEmoji } from '../../utils/Emoji'; |
29 |
|
|
import PunishmentType from '../../types/PunishmentType'; |
30 |
|
|
|
31 |
|
|
export default class WarningCommand extends BaseCommand { |
32 |
|
|
supportsInteractions: boolean = true; |
33 |
|
|
|
34 |
|
|
constructor() { |
35 |
|
|
super('warning', 'moderation', []); |
36 |
|
|
} |
37 |
|
|
|
38 |
|
|
async list(client: DiscordClient, msg: Message | CommandInteraction, options: CommandOptions | InteractionOptions) { |
39 |
|
|
if (!options.isInteraction && typeof options.args[0] === 'undefined') { |
40 |
|
|
await msg.reply({ |
41 |
|
|
embeds: [ |
42 |
|
|
new MessageEmbed() |
43 |
|
|
.setColor('#f14a60') |
44 |
|
|
.setDescription(`This command requires an argument.`) |
45 |
|
|
] |
46 |
|
|
}); |
47 |
|
|
|
48 |
|
|
return; |
49 |
|
|
} |
50 |
|
|
|
51 |
|
|
let user: User; |
52 |
|
|
|
53 |
|
|
try { |
54 |
|
|
user = await (options.isInteraction ? options.options.getUser('user') : (await getUser(client, msg as Message, options)))!; |
55 |
|
|
|
56 |
|
|
if (!user) |
57 |
|
|
throw new Error(); |
58 |
|
|
} |
59 |
|
|
catch (e) { |
60 |
|
|
await msg.reply({ |
61 |
|
|
embeds: [ |
62 |
|
|
new MessageEmbed() |
63 |
|
|
.setColor('#f14a60') |
64 |
|
|
.setDescription(`Invalid user given.`) |
65 |
|
|
] |
66 |
|
|
}); |
67 |
|
|
|
68 |
|
|
return; |
69 |
|
|
} |
70 |
|
|
|
71 |
|
|
const warnings = await Punishment.find({ |
72 |
|
|
guild_id: msg.guild!.id, |
73 |
|
|
user_id: user.id, |
74 |
|
|
type: PunishmentType.WARNING |
75 |
|
|
}).sort({ createdAt: -1 }); |
76 |
|
|
|
77 |
|
|
if (warnings.length < 1) { |
78 |
|
|
await msg.reply({ |
79 |
|
|
embeds: [ |
80 |
|
|
new MessageEmbed() |
81 |
|
|
.setColor('#f14a60') |
82 |
|
|
.setDescription(`No warnings found for that user.`) |
83 |
|
|
] |
84 |
|
|
}); |
85 |
|
|
|
86 |
|
|
return; |
87 |
|
|
} |
88 |
|
|
|
89 |
|
|
let str = ''; |
90 |
|
|
|
91 |
|
|
for await (const warning of warnings) { |
92 |
|
|
str += `ID: ${warning.id}\n`; |
93 |
|
|
str += `Reason: ${warning.reason ?? '*No reason provided*'}\n`; |
94 |
|
|
|
95 |
|
|
try { |
96 |
|
|
str += `Warned by: ${(await client.users.fetch(warning.mod_id)).tag}\n`; |
97 |
|
|
} |
98 |
|
|
catch (e) { |
99 |
|
|
str += `Warned by: ${warning.mod_id}\n`; |
100 |
|
|
} |
101 |
|
|
|
102 |
|
|
str += `Date: ${warning.createdAt}\n\n`; |
103 |
|
|
} |
104 |
|
|
|
105 |
|
|
await msg.reply({ |
106 |
|
|
embeds: [ |
107 |
|
|
new MessageEmbed() |
108 |
|
|
.setAuthor({ |
109 |
|
|
name: user.tag, |
110 |
|
|
iconURL: user.displayAvatarURL() |
111 |
|
|
}) |
112 |
|
|
.setDescription(`**All warnings**\n\n${str}`) |
113 |
|
|
] |
114 |
|
|
}); |
115 |
|
|
} |
116 |
|
|
|
117 |
|
|
async clear(client: DiscordClient, msg: Message | CommandInteraction, options: CommandOptions | InteractionOptions) { |
118 |
|
|
if (!options.isInteraction && typeof options.args[0] === 'undefined') { |
119 |
|
|
await msg.reply({ |
120 |
|
|
embeds: [ |
121 |
|
|
new MessageEmbed() |
122 |
|
|
.setColor('#f14a60') |
123 |
|
|
.setDescription(`This command requires an argument.`) |
124 |
|
|
] |
125 |
|
|
}); |
126 |
|
|
|
127 |
|
|
return; |
128 |
|
|
} |
129 |
|
|
|
130 |
|
|
let user: User; |
131 |
|
|
|
132 |
|
|
try { |
133 |
|
|
user = await (options.isInteraction ? options.options.getUser('user') : (await getUser(client, msg as Message, options)))!; |
134 |
|
|
|
135 |
|
|
if (!user) |
136 |
|
|
throw new Error(); |
137 |
|
|
} |
138 |
|
|
catch (e) { |
139 |
|
|
await msg.reply({ |
140 |
|
|
embeds: [ |
141 |
|
|
new MessageEmbed() |
142 |
|
|
.setColor('#f14a60') |
143 |
|
|
.setDescription(`Invalid user given.`) |
144 |
|
|
] |
145 |
|
|
}); |
146 |
|
|
|
147 |
|
|
return; |
148 |
|
|
} |
149 |
|
|
|
150 |
|
|
const warning = await Punishment.deleteOne({ |
151 |
|
|
guild_id: msg.guild!.id, |
152 |
|
|
user_id: user.id, |
153 |
|
|
type: PunishmentType.WARNING |
154 |
|
|
}); |
155 |
|
|
|
156 |
|
|
if (warning.deletedCount < 1) { |
157 |
|
|
await msg.reply({ |
158 |
|
|
embeds: [ |
159 |
|
|
new MessageEmbed() |
160 |
|
|
.setColor('#f14a60') |
161 |
|
|
.setDescription(`No warnings found for that user.`) |
162 |
|
|
] |
163 |
|
|
}); |
164 |
|
|
|
165 |
|
|
return; |
166 |
|
|
} |
167 |
|
|
|
168 |
|
|
await msg.reply({ |
169 |
|
|
embeds: [ |
170 |
|
|
new MessageEmbed() |
171 |
|
|
.setColor('GREEN') |
172 |
|
|
.setDescription(`${(await fetchEmoji('check'))?.toString()} Cleared ${warning} warnings for ${user.tag}`) |
173 |
|
|
] |
174 |
|
|
}); |
175 |
|
|
} |
176 |
|
|
|
177 |
|
|
async remove(client: DiscordClient, msg: Message | CommandInteraction, options: CommandOptions | InteractionOptions) { |
178 |
|
|
if (!options.isInteraction && typeof options.args[0] === 'undefined') { |
179 |
|
|
await msg.reply({ |
180 |
|
|
embeds: [ |
181 |
|
|
new MessageEmbed() |
182 |
|
|
.setColor('#f14a60') |
183 |
|
|
.setDescription(`This command requires an argument.`) |
184 |
|
|
] |
185 |
|
|
}); |
186 |
|
|
|
187 |
|
|
return; |
188 |
|
|
} |
189 |
|
|
|
190 |
|
|
const id = options.isInteraction ? options.options.getString('id') : parseInt(options.args[0]); |
191 |
|
|
|
192 |
|
|
const warning = await Punishment.findOne({ |
193 |
|
|
id, |
194 |
|
|
guild_id: msg.guild!.id, |
195 |
|
|
type: PunishmentType.WARNING |
196 |
|
|
}); |
197 |
|
|
|
198 |
|
|
if (!warning) { |
199 |
|
|
await msg.reply({ |
200 |
|
|
embeds: [ |
201 |
|
|
new MessageEmbed() |
202 |
|
|
.setColor('#f14a60') |
203 |
|
|
.setDescription(`Invalid warning ID given.`) |
204 |
|
|
] |
205 |
|
|
}); |
206 |
|
|
|
207 |
|
|
return; |
208 |
|
|
} |
209 |
|
|
|
210 |
|
|
await warning.delete(); |
211 |
|
|
|
212 |
|
|
await msg.reply({ |
213 |
|
|
embeds: [ |
214 |
|
|
new MessageEmbed() |
215 |
|
|
.setColor('GREEN') |
216 |
|
|
.setDescription(`${(await fetchEmoji('check'))?.toString()} Warning removed successfully!`) |
217 |
|
|
] |
218 |
|
|
}); |
219 |
|
|
} |
220 |
|
|
|
221 |
|
|
async view(client: DiscordClient, msg: Message | CommandInteraction, options: CommandOptions | InteractionOptions) { |
222 |
|
|
if (!options.isInteraction && typeof options.args[0] === 'undefined') { |
223 |
|
|
await msg.reply({ |
224 |
|
|
embeds: [ |
225 |
|
|
new MessageEmbed() |
226 |
|
|
.setColor('#f14a60') |
227 |
|
|
.setDescription(`This command requires an argument.`) |
228 |
|
|
] |
229 |
|
|
}); |
230 |
|
|
|
231 |
|
|
return; |
232 |
|
|
} |
233 |
|
|
|
234 |
|
|
const id = options.isInteraction ? options.options.getString('id') : parseInt(options.args[0]); |
235 |
|
|
|
236 |
|
|
const warning = await Punishment.findOne({ |
237 |
|
|
id, |
238 |
|
|
guild_id: msg.guild!.id, |
239 |
|
|
type: PunishmentType.WARNING |
240 |
|
|
}); |
241 |
|
|
|
242 |
|
|
if (!warning) { |
243 |
|
|
await msg.reply({ |
244 |
|
|
embeds: [ |
245 |
|
|
new MessageEmbed() |
246 |
|
|
.setColor('#f14a60') |
247 |
|
|
.setDescription(`Invalid warning ID given.`) |
248 |
|
|
] |
249 |
|
|
}); |
250 |
|
|
|
251 |
|
|
return; |
252 |
|
|
} |
253 |
|
|
|
254 |
|
|
let mod: string = warning.get('mod_id') as string; |
255 |
|
|
|
256 |
|
|
try { |
257 |
|
|
const m = await client.users.fetch(mod); |
258 |
|
|
mod = m.tag; |
259 |
|
|
} |
260 |
|
|
catch (e) { |
261 |
|
|
|
262 |
|
|
} |
263 |
|
|
|
264 |
|
|
let user: User | string = warning.get('user_id') as string; |
265 |
|
|
|
266 |
|
|
try { |
267 |
|
|
user = await client.users.fetch(user); |
268 |
|
|
} |
269 |
|
|
catch (e) { |
270 |
|
|
|
271 |
|
|
} |
272 |
|
|
|
273 |
|
|
const fields = [ |
274 |
|
|
{ |
275 |
|
|
name: 'Warning ID', |
276 |
|
|
value: (warning.get('id') as number) + '' |
277 |
|
|
}, |
278 |
|
|
{ |
279 |
|
|
name: 'Reason', |
280 |
|
|
value: warning.get('reason') as string|null ?? '*No reason provided*' |
281 |
|
|
}, |
282 |
|
|
{ |
283 |
|
|
name: 'Warned by', |
284 |
|
|
value: mod |
285 |
|
|
}, |
286 |
|
|
]; |
287 |
|
|
|
288 |
|
|
console.log(fields); |
289 |
|
|
|
290 |
|
|
|
291 |
|
|
await msg.reply({ |
292 |
|
|
embeds: [ |
293 |
|
|
new MessageEmbed({ |
294 |
|
|
author: { |
295 |
|
|
name: typeof user === 'string' ? user : user.tag, |
296 |
|
|
iconURL: typeof user === 'string' ? undefined : user.displayAvatarURL() |
297 |
|
|
}, |
298 |
|
|
fields, |
299 |
|
|
}) |
300 |
|
|
.setTimestamp(warning.get('createdAt') as Date) |
301 |
|
|
] |
302 |
|
|
}); |
303 |
|
|
} |
304 |
|
|
|
305 |
|
|
async run(client: DiscordClient, msg: Message | CommandInteraction, options: CommandOptions | InteractionOptions) { |
306 |
|
|
if (!options.isInteraction && typeof options.args[0] === 'undefined') { |
307 |
|
|
await msg.reply({ |
308 |
|
|
embeds: [ |
309 |
|
|
new MessageEmbed() |
310 |
|
|
.setColor('#f14a60') |
311 |
|
|
.setDescription(`This command requires a subcommand.`) |
312 |
|
|
] |
313 |
|
|
}); |
314 |
|
|
|
315 |
|
|
return; |
316 |
|
|
} |
317 |
|
|
|
318 |
|
|
const subcmd = options.isInteraction ? options.options.getSubcommand(true) : options.args[0]; |
319 |
|
|
|
320 |
|
|
if (!['view', 'remove', 'clear', 'list'].includes(subcmd)) { |
321 |
|
|
await msg.reply({ |
322 |
|
|
embeds: [ |
323 |
|
|
new MessageEmbed() |
324 |
|
|
.setColor('#f14a60') |
325 |
|
|
.setDescription(`Invalid subcommand given.`) |
326 |
|
|
] |
327 |
|
|
}); |
328 |
|
|
|
329 |
|
|
return; |
330 |
|
|
} |
331 |
|
|
|
332 |
|
|
if (!options.isInteraction) |
333 |
|
|
options.args.shift(); |
334 |
|
|
|
335 |
|
|
await (this as any)[subcmd](client, msg, options); |
336 |
|
|
} |
337 |
|
|
} |