blob: 537a4838c48fecc6c7bef949207fa3b1ad45e820 [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);
Skyler Greyc6a93662023-03-08 16:13:39 +0000167 await client.database.eventScheduler.schedule(
168 "naturalUnmute",
169 after.communicationDisabledUntil?.toISOString()!,
170 {
171 guild: after.guild.id,
172 user: after.id,
173 expires: after.communicationDisabledUntilTimestamp
174 }
175 );
TheCodedProfe35c4592023-02-20 12:47:12 -0500176 }
177 if (
PineaFanc4d6c3f2023-01-19 12:17:25 +0000178 after.communicationDisabledUntil === null &&
179 before.communicationDisabledUntilTimestamp !== null &&
TheCodedProf6ec331b2023-02-20 12:13:06 -0500180 Date.now() >= auditLog.createdTimestamp
PineaFanc4d6c3f2023-01-19 12:17:25 +0000181 ) {
182 await client.database.history.create(
183 "unmute",
184 after.guild.id,
185 after.user,
186 auditLog.executor,
187 null,
188 null,
189 null,
190 null
191 );
192 const data = {
193 meta: {
194 type: "memberUnmute",
195 displayName: "Unmuted",
196 calculateType: "guildMemberPunish",
197 color: NucleusColors.green,
198 emoji: "PUNISH.MUTE.GREEN",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500199 timestamp: Date.now()
PineaFanc4d6c3f2023-01-19 12:17:25 +0000200 },
201 list: {
202 memberId: entry(after.id, `\`${after.id}\``),
203 name: entry(after.user.id, renderUser(after.user)),
TheCodedProf6ec331b2023-02-20 12:13:06 -0500204 unmuted: entry(Date.now(), renderDelta(Date.now())),
PineaFanc4d6c3f2023-01-19 12:17:25 +0000205 unmutedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!))
206 },
207 hidden: {
208 guild: after.guild.id
209 }
210 };
Skyler Greyf4f21c42023-03-08 14:36:29 +0000211 await log(data);
212 await client.database.eventScheduler.cancel("naturalUnmute", {
PineaFanc4d6c3f2023-01-19 12:17:25 +0000213 guild: after.guild.id,
214 user: after.id,
215 expires: before.communicationDisabledUntilTimestamp
216 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100217 }
pineafane625d782022-05-09 18:04:32 +0100218}