1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
import { ActivePunishment, ActivePunishmentType, BotTask, Time } from '#lib';
import assert from 'assert/strict';
import { Op } from 'sequelize';
export default class RemoveExpiredPunishmentsTask extends BotTask {
public constructor() {
super('removeExpiredPunishments', {
delay: 15 * Time.Second,
runOnStart: true
});
}
public async exec() {
const expiredEntries = await ActivePunishment.findAll({
where: {
expires: {
[Op.lt]: new Date(Date.now() + 15 * Time.Second) // Find all rows with an expiry date before 15 seconds from now
}
}
});
void this.client.logger.verbose(
`removeExpiredPunishments`,
`Queried punishments, found <<${expiredEntries.length}>> expired punishments.`
);
for (const entry of expiredEntries) {
const guild = this.client.guilds.cache.get(entry.guild);
if (!guild) continue;
// eslint-disable-next-line @typescript-eslint/no-misused-promises
setTimeout(async () => {
const member = guild.members.cache.get(entry.user);
const user = await this.client.utils.resolveNonCachedUser(entry.user);
assert(guild);
switch (entry.type) {
case ActivePunishmentType.Ban: {
assert(user);
const result = await guild.customUnban({ user: user, reason: 'Punishment expired' });
if (['success', 'user not banned', 'cannot resolve user'].includes(result)) await entry.destroy();
else throw new Error(result);
void this.client.logger.verbose(`removeExpiredPunishments`, `Unbanned ${entry.user}.`);
break;
}
case ActivePunishmentType.Block: {
if (!member) {
await entry.destroy(); // channel overrides are removed when the member leaves the guild
return;
}
const result = await member.customUnblock({ reason: 'Punishment expired', channel: entry.extraInfo });
if (['success', 'user not blocked'].includes(result)) await entry.destroy();
else throw new Error(result);
void this.client.logger.verbose(`removeExpiredPunishments`, `Unblocked ${entry.user}.`);
break;
}
case ActivePunishmentType.Mute: {
if (!member) return;
const result = await member.customUnmute({ reason: 'Punishment expired' });
if (['success', 'failed to dm'].includes(result)) await entry.destroy();
else throw new Error(result);
void this.client.logger.verbose(`removeExpiredPunishments`, `Unmuted ${entry.user}.`);
break;
}
case ActivePunishmentType.Role: {
if (!member) return;
const role = guild?.roles?.cache?.get(entry.extraInfo);
if (!role) throw new Error(`Cannot unmute ${member.user.tag} because I cannot find the mute role.`);
const result = await member.customRemoveRole({
reason: 'Punishment expired',
role: role,
addToModlog: true
});
if (['success', 'failed to dm'].includes(result)) await entry.destroy();
else throw new Error(result);
void this.client.logger.verbose(`removeExpiredPunishments`, `Removed a punishment role from ${entry.user}.`);
break;
}
}
}, entry.expires!.getTime() - new Date().getTime());
}
}
}
|