blob: c3d6b33968057d2e614033eea00c139689b2e4af [file] [log] [blame]
pineafanbd02b4a2022-08-05 22:01:38 +01001import { CommandInteraction, GuildMember } from "discord.js";
pineafan32767212022-03-14 21:27:39 +00002import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
pineafan32767212022-03-14 21:27:39 +00003import confirmationMessage from "../../utils/confirmationMessage.js";
pineafan4edb7762022-06-26 19:21:04 +01004import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
pineafan32767212022-03-14 21:27:39 +00005import keyValueList from "../../utils/generateKeyValueList.js";
pineafan63fc5e22022-08-04 22:04:10 +01006import client from "../../utils/client.js";
pineafan32767212022-03-14 21:27:39 +00007
8const command = (builder: SlashCommandSubcommandBuilder) =>
9 builder
pineafan63fc5e22022-08-04 22:04:10 +010010 .setName("nick")
11 .setDescription("Changes a users nickname")
Skyler Grey75ea9172022-08-06 10:22:23 +010012 .addUserOption((option) =>
13 option
14 .setName("user")
15 .setDescription("The user to change")
16 .setRequired(true)
17 )
18 .addStringOption((option) =>
19 option
20 .setName("name")
21 .setDescription("The name to set | Leave blank to clear")
22 .setRequired(false)
23 );
pineafan32767212022-03-14 21:27:39 +000024
Skyler Grey75ea9172022-08-06 10:22:23 +010025const callback = async (
26 interaction: CommandInteraction
27): Promise<void | unknown> => {
pineafan63fc5e22022-08-04 22:04:10 +010028 const { renderUser } = client.logger;
pineafan377794f2022-04-18 19:01:01 +010029 // TODO:[Modals] Replace this with a modal
pineafan02ba0232022-07-24 22:16:15 +010030 let notify = true;
31 let confirmation;
32 while (true) {
33 confirmation = await new confirmationMessage(interaction)
34 .setEmoji("PUNISH.NICKNAME.RED")
35 .setTitle("Nickname")
Skyler Grey75ea9172022-08-06 10:22:23 +010036 .setDescription(
37 keyValueList({
38 user: renderUser(interaction.options.getUser("user")),
39 "new nickname": `${
40 interaction.options.getString("name")
41 ? interaction.options.getString("name")
42 : "*No nickname*"
43 }`
44 }) +
45 `The user **will${notify ? "" : " not"}** be notified\n\n` +
46 `Are you sure you want to ${
47 interaction.options.getString("name")
48 ? "change"
49 : "clear"
50 } <@!${
51 (interaction.options.getMember("user") as GuildMember)
52 .id
53 }>'s nickname?`
54 )
pineafan02ba0232022-07-24 22:16:15 +010055 .setColor("Danger")
Skyler Grey75ea9172022-08-06 10:22:23 +010056 .addCustomBoolean(
57 "notify",
58 "Notify user",
59 false,
60 null,
61 null,
62 "ICONS.NOTIFY." + (notify ? "ON" : "OFF"),
63 notify
64 )
pineafan63fc5e22022-08-04 22:04:10 +010065 .send(interaction.options.getString("name") !== null);
66 if (confirmation.cancelled) return;
67 if (confirmation.success) break;
pineafan02ba0232022-07-24 22:16:15 +010068 if (confirmation.components) {
pineafan63fc5e22022-08-04 22:04:10 +010069 notify = confirmation.components.notify.active;
pineafan02ba0232022-07-24 22:16:15 +010070 }
71 }
pineafan377794f2022-04-18 19:01:01 +010072 if (confirmation.success) {
pineafan63fc5e22022-08-04 22:04:10 +010073 let dmd = false;
pineafan377794f2022-04-18 19:01:01 +010074 let dm;
75 try {
pineafan02ba0232022-07-24 22:16:15 +010076 if (notify) {
Skyler Grey75ea9172022-08-06 10:22:23 +010077 dm = await (
78 interaction.options.getMember("user") as GuildMember
79 ).send({
80 embeds: [
81 new EmojiEmbed()
82 .setEmoji("PUNISH.NICKNAME.RED")
83 .setTitle("Nickname changed")
84 .setDescription(
85 `Your nickname was ${
86 interaction.options.getString("name")
87 ? "changed"
88 : "cleared"
89 } in ${interaction.guild.name}.` +
90 (interaction.options.getString("name")
91 ? ` it is now: ${interaction.options.getString(
92 "name"
93 )}`
94 : "") +
95 "\n\n" +
96 (confirmation.components.appeal.response
97 ? `You can appeal this here: <#${confirmation.components.appeal.response}>`
98 : "")
99 )
100 .setStatus("Danger")
pineafan377794f2022-04-18 19:01:01 +0100101 ]
pineafan63fc5e22022-08-04 22:04:10 +0100102 });
103 dmd = true;
pineafan377794f2022-04-18 19:01:01 +0100104 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100105 } catch {
106 dmd = false;
107 }
pineafan377794f2022-04-18 19:01:01 +0100108 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100109 const member = interaction.options.getMember("user") as GuildMember;
pineafan63fc5e22022-08-04 22:04:10 +0100110 const before = member.nickname;
111 const nickname = interaction.options.getString("name");
112 member.setNickname(nickname ?? null, "Nucleus Nickname command");
113 await client.database.history.create(
Skyler Grey75ea9172022-08-06 10:22:23 +0100114 "nickname",
115 interaction.guild.id,
116 member.user,
117 interaction.user,
118 null,
119 before,
120 nickname
121 );
122 const { log, NucleusColors, entry, renderUser, renderDelta } =
123 client.logger;
pineafan63fc5e22022-08-04 22:04:10 +0100124 const data = {
pineafane625d782022-05-09 18:04:32 +0100125 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100126 type: "memberUpdate",
127 displayName: "Member Updated",
128 calculateType: "guildMemberUpdate",
pineafane625d782022-05-09 18:04:32 +0100129 color: NucleusColors.yellow,
130 emoji: "PUNISH.NICKNAME.YELLOW",
131 timestamp: new Date().getTime()
132 },
133 list: {
pineafanda6e5342022-07-03 10:03:16 +0100134 memberId: entry(member.id, `\`${member.id}\``),
pineafan63fc5e22022-08-04 22:04:10 +0100135 before: entry(before, before ? before : "*None*"),
136 after: entry(nickname, nickname ? nickname : "*None*"),
Skyler Grey75ea9172022-08-06 10:22:23 +0100137 updated: entry(
138 new Date().getTime(),
139 renderDelta(new Date().getTime())
140 ),
141 updatedBy: entry(
142 interaction.user.id,
143 renderUser(interaction.user)
144 )
pineafane625d782022-05-09 18:04:32 +0100145 },
146 hidden: {
147 guild: interaction.guild.id
148 }
pineafan63fc5e22022-08-04 22:04:10 +0100149 };
pineafan4edb7762022-06-26 19:21:04 +0100150 log(data);
pineafan377794f2022-04-18 19:01:01 +0100151 } catch {
Skyler Grey75ea9172022-08-06 10:22:23 +0100152 await interaction.editReply({
153 embeds: [
154 new EmojiEmbed()
155 .setEmoji("PUNISH.NICKNAME.RED")
156 .setTitle("Nickname")
157 .setDescription(
158 "Something went wrong and the users nickname could not be changed."
159 )
160 .setStatus("Danger")
161 ],
162 components: []
163 });
pineafan63fc5e22022-08-04 22:04:10 +0100164 if (dmd) await dm.delete();
165 return;
pineafan377794f2022-04-18 19:01:01 +0100166 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100167 const failed = !dmd && notify;
168 await interaction.editReply({
169 embeds: [
170 new EmojiEmbed()
171 .setEmoji(`PUNISH.NICKNAME.${failed ? "YELLOW" : "GREEN"}`)
172 .setTitle("Nickname")
173 .setDescription(
174 "The members nickname was changed" +
175 (failed ? ", but was not notified" : "") +
176 (confirmation.components.appeal.response
177 ? ` and an appeal ticket was opened in <#${confirmation.components.appeal.response}>`
178 : "")
179 )
180 .setStatus(failed ? "Warning" : "Success")
181 ],
182 components: []
183 });
pineafan377794f2022-04-18 19:01:01 +0100184 } else {
Skyler Grey75ea9172022-08-06 10:22:23 +0100185 await interaction.editReply({
186 embeds: [
187 new EmojiEmbed()
188 .setEmoji("PUNISH.NICKNAME.GREEN")
189 .setTitle("Nickname")
190 .setDescription("No changes were made")
191 .setStatus("Success")
192 ],
193 components: []
194 });
pineafan377794f2022-04-18 19:01:01 +0100195 }
pineafan63fc5e22022-08-04 22:04:10 +0100196};
pineafan32767212022-03-14 21:27:39 +0000197
pineafanbd02b4a2022-08-05 22:01:38 +0100198const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100199 const member = interaction.member as GuildMember;
200 const me = interaction.guild.me!;
201 const apply = interaction.options.getMember("user") as GuildMember;
202 if (member === null || me === null || apply === null)
203 throw "That member is not in the server";
pineafan63fc5e22022-08-04 22:04:10 +0100204 const memberPos = member.roles ? member.roles.highest.position : 0;
205 const mePos = me.roles ? me.roles.highest.position : 0;
206 const applyPos = apply.roles ? apply.roles.highest.position : 0;
pineafanc1c18792022-08-03 21:41:36 +0100207 // Do not allow any changing of the owner
Skyler Grey75ea9172022-08-06 10:22:23 +0100208 if (member.id === interaction.guild.ownerId)
209 throw "You cannot change the owner's nickname";
pineafan377794f2022-04-18 19:01:01 +0100210 // Check if Nucleus can change the nickname
Skyler Grey75ea9172022-08-06 10:22:23 +0100211 if (!(mePos > applyPos))
212 throw "I do not have a role higher than that member";
pineafan377794f2022-04-18 19:01:01 +0100213 // Check if Nucleus has permission to change the nickname
Skyler Grey75ea9172022-08-06 10:22:23 +0100214 if (!me.permissions.has("MANAGE_NICKNAMES"))
215 throw "I do not have the *Manage Nicknames* permission";
pineafan377794f2022-04-18 19:01:01 +0100216 // Allow the owner to change anyone's nickname
pineafan63fc5e22022-08-04 22:04:10 +0100217 if (member.id === interaction.guild.ownerId) return true;
pineafan377794f2022-04-18 19:01:01 +0100218 // Check if the user has manage_nicknames permission
Skyler Grey75ea9172022-08-06 10:22:23 +0100219 if (!member.permissions.has("MANAGE_NICKNAMES"))
220 throw "You do not have the *Manage Nicknames* permission";
pineafane625d782022-05-09 18:04:32 +0100221 // Allow changing your own nickname
pineafan63fc5e22022-08-04 22:04:10 +0100222 if (member === apply) return true;
pineafan377794f2022-04-18 19:01:01 +0100223 // Check if the user is below on the role list
Skyler Grey75ea9172022-08-06 10:22:23 +0100224 if (!(memberPos > applyPos))
225 throw "You do not have a role higher than that member";
pineafan377794f2022-04-18 19:01:01 +0100226 // Allow change
pineafan63fc5e22022-08-04 22:04:10 +0100227 return true;
228};
pineafan32767212022-03-14 21:27:39 +0000229
Skyler Grey75ea9172022-08-06 10:22:23 +0100230export { command, callback, check };