blob: 05b70b7f56e67d44b169813f2b5ab0b35bcdf9d2 [file] [log] [blame]
PineaFan0d06edc2023-01-17 22:10:31 +00001import { AuditLogEvent, GuildAuditLogsEntry, GuildMember } from "discord.js";
PineaFan752af462022-12-31 21:59:38 +00002import type { NucleusClient } from "../utils/client.js";
TheCodedProfe35c4592023-02-20 12:47:12 -05003import type { LoggerOptions } from "../utils/log.js";
TheCodedProf1807fb32023-02-20 14:33:48 -05004import { generalException } from "../utils/createTemporaryStorage.js";
pineafan1e462ab2023-03-07 21:34:06 +00005import { doMemberChecks } from "../reflex/scanners.js";
pineafan0f5cc782022-08-12 21:55:42 +01006
pineafan63fc5e22022-08-04 22:04:10 +01007export const event = "guildMemberUpdate";
pineafane625d782022-05-09 18:04:32 +01008
PineaFan752af462022-12-31 21:59:38 +00009export async function callback(client: NucleusClient, before: GuildMember, after: GuildMember) {
TheCodedProfe35c4592023-02-20 12:47:12 -050010 const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = client.logger;
Skyler Greyda16adf2023-03-05 10:22:12 +000011 if (before.guild.id === "684492926528651336") {
12 await client.database.premium.checkAllPremium(after);
TheCodedProf94ff6de2023-02-22 17:47:26 -050013 }
TheCodedProfe35c4592023-02-20 12:47:12 -050014
Skyler Greyda16adf2023-03-05 10:22:12 +000015 if (!before.roles.cache.equals(after.roles.cache)) {
16 const auditLog = (await getAuditLog(after.guild, AuditLogEvent.MemberRoleUpdate)).filter(
17 (entry: GuildAuditLogsEntry) => (entry.target as GuildMember)!.id === after.id
18 )[0];
TheCodedProf1807fb32023-02-20 14:33:48 -050019 if (!auditLog) return;
20 if (client.noLog.includes(`${after.guild.id}${after.id}${auditLog.id}`)) return;
21 generalException(`${after.guild.id}${after.id}${auditLog.id}`);
22 if (auditLog.executor!.id !== client.user!.id) {
Skyler Greyda16adf2023-03-05 10:22:12 +000023 const rolesAdded = after.roles.cache.filter((role) => !before.roles.cache.has(role.id));
24 const rolesRemoved = before.roles.cache.filter((role) => !after.roles.cache.has(role.id));
TheCodedProf1807fb32023-02-20 14:33:48 -050025 let displayName = "Roles Removed";
26 let color = NucleusColors.red;
27 let emoji = "GUILD.ROLES.DELETE";
Skyler Greyda16adf2023-03-05 10:22:12 +000028 if (rolesAdded.size > 0 && rolesRemoved.size > 0) {
29 displayName = "Roles Changed";
30 color = NucleusColors.yellow;
31 emoji = "GUILD.ROLES.EDIT";
32 } else if (rolesAdded.size > 0) {
33 displayName = "Roles Added";
34 color = NucleusColors.green;
35 emoji = "GUILD.ROLES.CREATE";
36 }
37 const removedEntry = rolesRemoved.map((role) => role.id);
38 const addedEntry = rolesAdded.map((role) => role.id);
TheCodedProf1807fb32023-02-20 14:33:48 -050039
40 let list = {
41 memberId: entry(after.id, `\`${after.id}\``),
Skyler Greyda16adf2023-03-05 10:22:12 +000042 name: entry(after.user.id, renderUser(after.user))
TheCodedProf1807fb32023-02-20 14:33:48 -050043 };
44
45 if (rolesAdded.size > 0) {
Skyler Greyda16adf2023-03-05 10:22:12 +000046 list = Object.assign(list, {
47 rolesAdded: entry(addedEntry, addedEntry.map((id) => `<@&${id}>`).join(", "))
48 });
TheCodedProf1807fb32023-02-20 14:33:48 -050049 }
50 if (rolesRemoved.size > 0) {
Skyler Greyda16adf2023-03-05 10:22:12 +000051 list = Object.assign(list, {
52 rolesRemoved: entry(removedEntry, removedEntry.map((id) => `<@&${id}>`).join(", "))
53 });
TheCodedProf1807fb32023-02-20 14:33:48 -050054 }
55
56 list = Object.assign(list, {
57 changed: entry(Date.now(), renderDelta(Date.now())),
58 changedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!))
59 });
60
61 let data: LoggerOptions = {
62 meta: {
63 type: "memberUpdate",
64 displayName: displayName,
65 calculateType: "guildMemberUpdate",
66 color: color,
67 emoji: emoji,
68 timestamp: Date.now()
69 },
70 list: {},
71 hidden: {
72 guild: after.guild.id
73 }
74 };
75
Skyler Greyda16adf2023-03-05 10:22:12 +000076 if (rolesAdded.size > 0) {
77 list = Object.assign(list, {
78 rolesAdded: entry(addedEntry, addedEntry.map((id) => `<@&${id}>`).join(", "))
79 });
TheCodedProf1807fb32023-02-20 14:33:48 -050080 }
Skyler Greyda16adf2023-03-05 10:22:12 +000081 if (rolesRemoved.size > 0) {
82 list = Object.assign(list, {
83 rolesRemoved: entry(removedEntry, removedEntry.map((id) => `<@&${id}>`).join(", "))
84 });
TheCodedProf1807fb32023-02-20 14:33:48 -050085 }
Skyler Greyda16adf2023-03-05 10:22:12 +000086 data = Object.assign(data, { list: list });
Skyler Greyf4f21c42023-03-08 14:36:29 +000087 await log(data);
TheCodedProf1807fb32023-02-20 14:33:48 -050088 }
89 }
Skyler Greyda16adf2023-03-05 10:22:12 +000090 const auditLog = (await getAuditLog(after.guild, AuditLogEvent.MemberUpdate)).filter(
91 (entry: GuildAuditLogsEntry) => (entry.target as GuildMember)!.id === after.id
92 )[0];
PineaFanc4d6c3f2023-01-19 12:17:25 +000093 if (!auditLog) return;
94 if (auditLog.executor!.id === client.user!.id) return;
95 if (before.nickname !== after.nickname) {
Skyler Greyf4f21c42023-03-08 14:36:29 +000096 await doMemberChecks(after, after.guild);
PineaFanc4d6c3f2023-01-19 12:17:25 +000097 await client.database.history.create(
98 "nickname",
99 after.guild.id,
100 after.user,
101 auditLog.executor,
102 null,
103 before.nickname ?? before.user.username,
104 after.nickname ?? after.user.username
105 );
106 const data = {
107 meta: {
108 type: "memberUpdate",
109 displayName: "Nickname Changed",
110 calculateType: "guildMemberUpdate",
111 color: NucleusColors.yellow,
112 emoji: "PUNISH.NICKNAME.YELLOW",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500113 timestamp: Date.now()
PineaFanc4d6c3f2023-01-19 12:17:25 +0000114 },
115 list: {
PineaFanc4d6c3f2023-01-19 12:17:25 +0000116 name: entry(after.user.id, renderUser(after.user)),
117 before: entry(before.nickname, before.nickname ? before.nickname : "*None*"),
118 after: entry(after.nickname, after.nickname ? after.nickname : "*None*"),
TheCodedProf6ec331b2023-02-20 12:13:06 -0500119 changed: entry(Date.now(), renderDelta(Date.now())),
PineaFanc4d6c3f2023-01-19 12:17:25 +0000120 changedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!))
121 },
122 hidden: {
123 guild: after.guild.id
124 }
125 };
Skyler Greyf4f21c42023-03-08 14:36:29 +0000126 await log(data);
TheCodedProfe35c4592023-02-20 12:47:12 -0500127 }
128 if (
TheCodedProf6ec331b2023-02-20 12:13:06 -0500129 (before.communicationDisabledUntilTimestamp ?? 0) < Date.now() &&
pineafan96228bd2023-02-21 14:22:55 +0000130 new Date(after.communicationDisabledUntil ?? 0).getTime() > Date.now()
PineaFanc4d6c3f2023-01-19 12:17:25 +0000131 ) {
132 await client.database.history.create(
133 "mute",
134 after.guild.id,
135 after.user,
136 auditLog.executor,
137 auditLog.reason,
138 null,
139 null,
140 null
141 );
142 const data = {
143 meta: {
144 type: "memberMute",
145 displayName: "Muted",
146 calculateType: "guildMemberPunish",
147 color: NucleusColors.yellow,
148 emoji: "PUNISH.MUTE.YELLOW",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500149 timestamp: Date.now()
PineaFanc4d6c3f2023-01-19 12:17:25 +0000150 },
151 list: {
152 memberId: entry(after.id, `\`${after.id}\``),
153 name: entry(after.user.id, renderUser(after.user)),
154 mutedUntil: entry(
155 after.communicationDisabledUntilTimestamp,
156 renderDelta(after.communicationDisabledUntilTimestamp!)
157 ),
TheCodedProf6ec331b2023-02-20 12:13:06 -0500158 muted: entry(Date.now(), renderDelta(Date.now())),
PineaFanc4d6c3f2023-01-19 12:17:25 +0000159 mutedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!)),
160 reason: entry(auditLog.reason, auditLog.reason ? auditLog.reason : "\n> *No reason provided*")
161 },
162 hidden: {
163 guild: after.guild.id
164 }
165 };
Skyler Greyf4f21c42023-03-08 14:36:29 +0000166 await log(data);
167 await client.database.eventScheduler.schedule("naturalUnmute", after.communicationDisabledUntil?.toISOString()!, {
PineaFanc4d6c3f2023-01-19 12:17:25 +0000168 guild: after.guild.id,
169 user: after.id,
170 expires: after.communicationDisabledUntilTimestamp
171 });
TheCodedProfe35c4592023-02-20 12:47:12 -0500172 }
173 if (
PineaFanc4d6c3f2023-01-19 12:17:25 +0000174 after.communicationDisabledUntil === null &&
175 before.communicationDisabledUntilTimestamp !== null &&
TheCodedProf6ec331b2023-02-20 12:13:06 -0500176 Date.now() >= auditLog.createdTimestamp
PineaFanc4d6c3f2023-01-19 12:17:25 +0000177 ) {
178 await client.database.history.create(
179 "unmute",
180 after.guild.id,
181 after.user,
182 auditLog.executor,
183 null,
184 null,
185 null,
186 null
187 );
188 const data = {
189 meta: {
190 type: "memberUnmute",
191 displayName: "Unmuted",
192 calculateType: "guildMemberPunish",
193 color: NucleusColors.green,
194 emoji: "PUNISH.MUTE.GREEN",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500195 timestamp: Date.now()
PineaFanc4d6c3f2023-01-19 12:17:25 +0000196 },
197 list: {
198 memberId: entry(after.id, `\`${after.id}\``),
199 name: entry(after.user.id, renderUser(after.user)),
TheCodedProf6ec331b2023-02-20 12:13:06 -0500200 unmuted: entry(Date.now(), renderDelta(Date.now())),
PineaFanc4d6c3f2023-01-19 12:17:25 +0000201 unmutedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!))
202 },
203 hidden: {
204 guild: after.guild.id
205 }
206 };
Skyler Greyf4f21c42023-03-08 14:36:29 +0000207 await log(data);
208 await client.database.eventScheduler.cancel("naturalUnmute", {
PineaFanc4d6c3f2023-01-19 12:17:25 +0000209 guild: after.guild.id,
210 user: after.id,
211 expires: before.communicationDisabledUntilTimestamp
212 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100213 }
pineafane625d782022-05-09 18:04:32 +0100214}