blob: fe11ee106c201d11cc3d6e75dc5df8fdd23c76fd [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 Grey0d885222023-03-08 21:46:37 +000096 await doMemberChecks(after);
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 }
Skyler Grey0d885222023-03-08 21:46:37 +0000128 if (before.displayAvatarURL !== after.displayAvatarURL) await doMemberChecks(after);
TheCodedProfe35c4592023-02-20 12:47:12 -0500129 if (
TheCodedProf6ec331b2023-02-20 12:13:06 -0500130 (before.communicationDisabledUntilTimestamp ?? 0) < Date.now() &&
pineafan96228bd2023-02-21 14:22:55 +0000131 new Date(after.communicationDisabledUntil ?? 0).getTime() > Date.now()
PineaFanc4d6c3f2023-01-19 12:17:25 +0000132 ) {
133 await client.database.history.create(
134 "mute",
135 after.guild.id,
136 after.user,
137 auditLog.executor,
138 auditLog.reason,
139 null,
140 null,
141 null
142 );
143 const data = {
144 meta: {
145 type: "memberMute",
146 displayName: "Muted",
147 calculateType: "guildMemberPunish",
148 color: NucleusColors.yellow,
149 emoji: "PUNISH.MUTE.YELLOW",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500150 timestamp: Date.now()
PineaFanc4d6c3f2023-01-19 12:17:25 +0000151 },
152 list: {
153 memberId: entry(after.id, `\`${after.id}\``),
154 name: entry(after.user.id, renderUser(after.user)),
155 mutedUntil: entry(
156 after.communicationDisabledUntilTimestamp,
157 renderDelta(after.communicationDisabledUntilTimestamp!)
158 ),
TheCodedProf6ec331b2023-02-20 12:13:06 -0500159 muted: entry(Date.now(), renderDelta(Date.now())),
PineaFanc4d6c3f2023-01-19 12:17:25 +0000160 mutedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!)),
161 reason: entry(auditLog.reason, auditLog.reason ? auditLog.reason : "\n> *No reason provided*")
162 },
163 hidden: {
164 guild: after.guild.id
165 }
166 };
Skyler Greyf4f21c42023-03-08 14:36:29 +0000167 await log(data);
Skyler Greyc6a93662023-03-08 16:13:39 +0000168 await client.database.eventScheduler.schedule(
169 "naturalUnmute",
170 after.communicationDisabledUntil?.toISOString()!,
171 {
172 guild: after.guild.id,
173 user: after.id,
174 expires: after.communicationDisabledUntilTimestamp
175 }
176 );
TheCodedProfe35c4592023-02-20 12:47:12 -0500177 }
178 if (
PineaFanc4d6c3f2023-01-19 12:17:25 +0000179 after.communicationDisabledUntil === null &&
180 before.communicationDisabledUntilTimestamp !== null &&
TheCodedProf6ec331b2023-02-20 12:13:06 -0500181 Date.now() >= auditLog.createdTimestamp
PineaFanc4d6c3f2023-01-19 12:17:25 +0000182 ) {
183 await client.database.history.create(
184 "unmute",
185 after.guild.id,
186 after.user,
187 auditLog.executor,
188 null,
189 null,
190 null,
191 null
192 );
193 const data = {
194 meta: {
195 type: "memberUnmute",
196 displayName: "Unmuted",
197 calculateType: "guildMemberPunish",
198 color: NucleusColors.green,
199 emoji: "PUNISH.MUTE.GREEN",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500200 timestamp: Date.now()
PineaFanc4d6c3f2023-01-19 12:17:25 +0000201 },
202 list: {
203 memberId: entry(after.id, `\`${after.id}\``),
204 name: entry(after.user.id, renderUser(after.user)),
TheCodedProf6ec331b2023-02-20 12:13:06 -0500205 unmuted: entry(Date.now(), renderDelta(Date.now())),
PineaFanc4d6c3f2023-01-19 12:17:25 +0000206 unmutedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!))
207 },
208 hidden: {
209 guild: after.guild.id
210 }
211 };
Skyler Greyf4f21c42023-03-08 14:36:29 +0000212 await log(data);
213 await client.database.eventScheduler.cancel("naturalUnmute", {
PineaFanc4d6c3f2023-01-19 12:17:25 +0000214 guild: after.guild.id,
215 user: after.id,
216 expires: before.communicationDisabledUntilTimestamp
217 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100218 }
pineafane625d782022-05-09 18:04:32 +0100219}