blob: 4e512ee2ed87242fc4587f9b2f7b41301d486853 [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 Grey017c3722023-03-09 20:09:57 +000015 if (before.displayAvatarURL({ forceStatic: true }) !== after.displayAvatarURL({ forceStatic: true }))
16 await doMemberChecks(after);
Skyler Greyda16adf2023-03-05 10:22:12 +000017 if (!before.roles.cache.equals(after.roles.cache)) {
18 const auditLog = (await getAuditLog(after.guild, AuditLogEvent.MemberRoleUpdate)).filter(
19 (entry: GuildAuditLogsEntry) => (entry.target as GuildMember)!.id === after.id
20 )[0];
TheCodedProf1807fb32023-02-20 14:33:48 -050021 if (!auditLog) return;
22 if (client.noLog.includes(`${after.guild.id}${after.id}${auditLog.id}`)) return;
23 generalException(`${after.guild.id}${after.id}${auditLog.id}`);
24 if (auditLog.executor!.id !== client.user!.id) {
Skyler Greyda16adf2023-03-05 10:22:12 +000025 const rolesAdded = after.roles.cache.filter((role) => !before.roles.cache.has(role.id));
26 const rolesRemoved = before.roles.cache.filter((role) => !after.roles.cache.has(role.id));
TheCodedProf1807fb32023-02-20 14:33:48 -050027 let displayName = "Roles Removed";
28 let color = NucleusColors.red;
29 let emoji = "GUILD.ROLES.DELETE";
Skyler Greyda16adf2023-03-05 10:22:12 +000030 if (rolesAdded.size > 0 && rolesRemoved.size > 0) {
31 displayName = "Roles Changed";
32 color = NucleusColors.yellow;
33 emoji = "GUILD.ROLES.EDIT";
34 } else if (rolesAdded.size > 0) {
35 displayName = "Roles Added";
36 color = NucleusColors.green;
37 emoji = "GUILD.ROLES.CREATE";
38 }
39 const removedEntry = rolesRemoved.map((role) => role.id);
40 const addedEntry = rolesAdded.map((role) => role.id);
TheCodedProf1807fb32023-02-20 14:33:48 -050041
42 let list = {
43 memberId: entry(after.id, `\`${after.id}\``),
Skyler Greyda16adf2023-03-05 10:22:12 +000044 name: entry(after.user.id, renderUser(after.user))
TheCodedProf1807fb32023-02-20 14:33:48 -050045 };
46
47 if (rolesAdded.size > 0) {
Skyler Greyda16adf2023-03-05 10:22:12 +000048 list = Object.assign(list, {
49 rolesAdded: entry(addedEntry, addedEntry.map((id) => `<@&${id}>`).join(", "))
50 });
TheCodedProf1807fb32023-02-20 14:33:48 -050051 }
52 if (rolesRemoved.size > 0) {
Skyler Greyda16adf2023-03-05 10:22:12 +000053 list = Object.assign(list, {
54 rolesRemoved: entry(removedEntry, removedEntry.map((id) => `<@&${id}>`).join(", "))
55 });
TheCodedProf1807fb32023-02-20 14:33:48 -050056 }
57
58 list = Object.assign(list, {
59 changed: entry(Date.now(), renderDelta(Date.now())),
60 changedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!))
61 });
62
63 let data: LoggerOptions = {
64 meta: {
65 type: "memberUpdate",
66 displayName: displayName,
67 calculateType: "guildMemberUpdate",
68 color: color,
69 emoji: emoji,
70 timestamp: Date.now()
71 },
72 list: {},
73 hidden: {
74 guild: after.guild.id
75 }
76 };
77
Skyler Greyda16adf2023-03-05 10:22:12 +000078 if (rolesAdded.size > 0) {
79 list = Object.assign(list, {
80 rolesAdded: entry(addedEntry, addedEntry.map((id) => `<@&${id}>`).join(", "))
81 });
TheCodedProf1807fb32023-02-20 14:33:48 -050082 }
Skyler Greyda16adf2023-03-05 10:22:12 +000083 if (rolesRemoved.size > 0) {
84 list = Object.assign(list, {
85 rolesRemoved: entry(removedEntry, removedEntry.map((id) => `<@&${id}>`).join(", "))
86 });
TheCodedProf1807fb32023-02-20 14:33:48 -050087 }
Skyler Greyda16adf2023-03-05 10:22:12 +000088 data = Object.assign(data, { list: list });
Skyler Greyf4f21c42023-03-08 14:36:29 +000089 await log(data);
TheCodedProf1807fb32023-02-20 14:33:48 -050090 }
91 }
Skyler Greyda16adf2023-03-05 10:22:12 +000092 const auditLog = (await getAuditLog(after.guild, AuditLogEvent.MemberUpdate)).filter(
93 (entry: GuildAuditLogsEntry) => (entry.target as GuildMember)!.id === after.id
94 )[0];
PineaFanc4d6c3f2023-01-19 12:17:25 +000095 if (!auditLog) return;
96 if (auditLog.executor!.id === client.user!.id) return;
97 if (before.nickname !== after.nickname) {
Skyler Grey0d885222023-03-08 21:46:37 +000098 await doMemberChecks(after);
PineaFanc4d6c3f2023-01-19 12:17:25 +000099 await client.database.history.create(
100 "nickname",
101 after.guild.id,
102 after.user,
103 auditLog.executor,
104 null,
105 before.nickname ?? before.user.username,
106 after.nickname ?? after.user.username
107 );
108 const data = {
109 meta: {
110 type: "memberUpdate",
111 displayName: "Nickname Changed",
112 calculateType: "guildMemberUpdate",
113 color: NucleusColors.yellow,
114 emoji: "PUNISH.NICKNAME.YELLOW",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500115 timestamp: Date.now()
PineaFanc4d6c3f2023-01-19 12:17:25 +0000116 },
117 list: {
PineaFanc4d6c3f2023-01-19 12:17:25 +0000118 name: entry(after.user.id, renderUser(after.user)),
119 before: entry(before.nickname, before.nickname ? before.nickname : "*None*"),
120 after: entry(after.nickname, after.nickname ? after.nickname : "*None*"),
TheCodedProf6ec331b2023-02-20 12:13:06 -0500121 changed: entry(Date.now(), renderDelta(Date.now())),
PineaFanc4d6c3f2023-01-19 12:17:25 +0000122 changedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!))
123 },
124 hidden: {
125 guild: after.guild.id
126 }
127 };
Skyler Greyf4f21c42023-03-08 14:36:29 +0000128 await log(data);
TheCodedProfe35c4592023-02-20 12:47:12 -0500129 }
130 if (
TheCodedProf6ec331b2023-02-20 12:13:06 -0500131 (before.communicationDisabledUntilTimestamp ?? 0) < Date.now() &&
pineafan96228bd2023-02-21 14:22:55 +0000132 new Date(after.communicationDisabledUntil ?? 0).getTime() > Date.now()
PineaFanc4d6c3f2023-01-19 12:17:25 +0000133 ) {
134 await client.database.history.create(
135 "mute",
136 after.guild.id,
137 after.user,
138 auditLog.executor,
139 auditLog.reason,
140 null,
141 null,
142 null
143 );
144 const data = {
145 meta: {
146 type: "memberMute",
147 displayName: "Muted",
148 calculateType: "guildMemberPunish",
149 color: NucleusColors.yellow,
150 emoji: "PUNISH.MUTE.YELLOW",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500151 timestamp: Date.now()
PineaFanc4d6c3f2023-01-19 12:17:25 +0000152 },
153 list: {
154 memberId: entry(after.id, `\`${after.id}\``),
155 name: entry(after.user.id, renderUser(after.user)),
156 mutedUntil: entry(
157 after.communicationDisabledUntilTimestamp,
158 renderDelta(after.communicationDisabledUntilTimestamp!)
159 ),
TheCodedProf6ec331b2023-02-20 12:13:06 -0500160 muted: entry(Date.now(), renderDelta(Date.now())),
PineaFanc4d6c3f2023-01-19 12:17:25 +0000161 mutedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!)),
162 reason: entry(auditLog.reason, auditLog.reason ? auditLog.reason : "\n> *No reason provided*")
163 },
164 hidden: {
165 guild: after.guild.id
166 }
167 };
Skyler Greyf4f21c42023-03-08 14:36:29 +0000168 await log(data);
Skyler Greyc6a93662023-03-08 16:13:39 +0000169 await client.database.eventScheduler.schedule(
170 "naturalUnmute",
171 after.communicationDisabledUntil?.toISOString()!,
172 {
173 guild: after.guild.id,
174 user: after.id,
175 expires: after.communicationDisabledUntilTimestamp
176 }
177 );
TheCodedProfe35c4592023-02-20 12:47:12 -0500178 }
179 if (
PineaFanc4d6c3f2023-01-19 12:17:25 +0000180 after.communicationDisabledUntil === null &&
181 before.communicationDisabledUntilTimestamp !== null &&
TheCodedProf6ec331b2023-02-20 12:13:06 -0500182 Date.now() >= auditLog.createdTimestamp
PineaFanc4d6c3f2023-01-19 12:17:25 +0000183 ) {
184 await client.database.history.create(
185 "unmute",
186 after.guild.id,
187 after.user,
188 auditLog.executor,
189 null,
190 null,
191 null,
192 null
193 );
194 const data = {
195 meta: {
196 type: "memberUnmute",
197 displayName: "Unmuted",
198 calculateType: "guildMemberPunish",
199 color: NucleusColors.green,
200 emoji: "PUNISH.MUTE.GREEN",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500201 timestamp: Date.now()
PineaFanc4d6c3f2023-01-19 12:17:25 +0000202 },
203 list: {
204 memberId: entry(after.id, `\`${after.id}\``),
205 name: entry(after.user.id, renderUser(after.user)),
TheCodedProf6ec331b2023-02-20 12:13:06 -0500206 unmuted: entry(Date.now(), renderDelta(Date.now())),
PineaFanc4d6c3f2023-01-19 12:17:25 +0000207 unmutedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!))
208 },
209 hidden: {
210 guild: after.guild.id
211 }
212 };
Skyler Greyf4f21c42023-03-08 14:36:29 +0000213 await log(data);
214 await client.database.eventScheduler.cancel("naturalUnmute", {
PineaFanc4d6c3f2023-01-19 12:17:25 +0000215 guild: after.guild.id,
216 user: after.id,
217 expires: before.communicationDisabledUntilTimestamp
218 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100219 }
pineafane625d782022-05-09 18:04:32 +0100220}