Working on viewas

pull/17/head
PineaFan 3 years ago
parent 538d375729
commit 1dee28f37e
No known key found for this signature in database
GPG Key ID: D404018735F488C9

@ -23,6 +23,7 @@
"node-tesseract-ocr": "^2.2.1", "node-tesseract-ocr": "^2.2.1",
"pastebin-api": "^5.1.1", "pastebin-api": "^5.1.1",
"structured-clone": "^0.2.2", "structured-clone": "^0.2.2",
"systeminformation": "^5.17.3",
"typescript": "^5.0.0-dev.20230102", "typescript": "^5.0.0-dev.20230102",
"uuid": "^8.3.2" "uuid": "^8.3.2"
}, },

@ -1,4 +1,4 @@
import { LoadingEmbed } from './../../utils/defaultEmbeds.js'; import { LoadingEmbed } from '../../utils/defaultEmbeds.js';
import type { HistorySchema } from "../../utils/database.js"; import type { HistorySchema } from "../../utils/database.js";
import Discord, { import Discord, {
CommandInteraction, CommandInteraction,
@ -22,8 +22,8 @@ import pageIndicator from "../../utils/createPageIndicator.js";
const command = (builder: SlashCommandSubcommandBuilder) => const command = (builder: SlashCommandSubcommandBuilder) =>
builder builder
.setName("info") .setName("about")
// .setNameLocalizations({"ru": "about", "zh-CN": "history", "zh-TW": "notes", "pt-BR": "flags"}) // .setNameLocalizations({"ru": "info", "zh-CN": "history", "zh-TW": "notes", "pt-BR": "flags"})
.setDescription("Shows moderator information about a user") .setDescription("Shows moderator information about a user")
.addUserOption((option) => .addUserOption((option) =>
option.setName("user").setDescription("The user to get information about").setRequired(true) option.setName("user").setDescription("The user to get information about").setRequired(true)

@ -59,6 +59,7 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
) )
.setColor("Danger") .setColor("Danger")
.addReasonButton(reason ?? "") .addReasonButton(reason ?? "")
.setFailedMessage("No changes were made", "Success", "PUNISH.BAN.GREEN")
.send(reason !== null); .send(reason !== null);
reason = reason ?? ""; reason = reason ?? "";
if (confirmation.cancelled) timedOut = true; if (confirmation.cancelled) timedOut = true;
@ -66,8 +67,7 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
else if (confirmation.newReason) reason = confirmation.newReason; else if (confirmation.newReason) reason = confirmation.newReason;
else if (confirmation.components) notify = confirmation.components["notify"]!.active; else if (confirmation.components) notify = confirmation.components["notify"]!.active;
} while (!timedOut && !chosen) } while (!timedOut && !chosen)
if (timedOut) return; if (timedOut || !confirmation.success) return;
if (confirmation.success) {
reason = reason.length ? reason : null reason = reason.length ? reason : null
let dmSent = false; let dmSent = false;
let dmMessage; let dmMessage;
@ -164,18 +164,6 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
], ],
components: [] components: []
}); });
} else {
await interaction.editReply({
embeds: [
new EmojiEmbed()
.setEmoji("PUNISH.BAN.GREEN")
.setTitle("Ban")
.setDescription("No changes were made")
.setStatus("Success")
],
components: []
});
}
}; };
const check = async (interaction: CommandInteraction) => { const check = async (interaction: CommandInteraction) => {

@ -47,6 +47,7 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
notify notify
) )
.addReasonButton(reason ?? "") .addReasonButton(reason ?? "")
.setFailedMessage("No changes were made", "Success", "PUNISH.KICK.GREEN")
.send(reason !== null); .send(reason !== null);
reason = reason ?? ""; reason = reason ?? "";
if (confirmation.cancelled) timedOut = true; if (confirmation.cancelled) timedOut = true;
@ -56,20 +57,7 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
notify = confirmation.components["notify"]!.active; notify = confirmation.components["notify"]!.active;
} }
} while (!timedOut && !success) } while (!timedOut && !success)
if (timedOut) return; if (timedOut || !confirmation.success) return;
if (!confirmation.success) {
await interaction.editReply({
embeds: [
new EmojiEmbed()
.setEmoji("PUNISH.KICK.GREEN")
.setTitle("Kick")
.setDescription("No changes were made")
.setStatus("Success")
],
components: []
});
return;
}
let dmSent = false; let dmSent = false;
let dmMessage; let dmMessage;
const config = await client.database.guilds.read(interaction.guild.id); const config = await client.database.guilds.read(interaction.guild.id);

@ -207,6 +207,7 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
notify notify
) )
.addReasonButton(reason ?? "") .addReasonButton(reason ?? "")
.setFailedMessage("No changes were made", "Success", "PUNISH.MUTE.GREEN")
.send(true); .send(true);
reason = reason ?? ""; reason = reason ?? "";
if (confirmation.cancelled) timedOut = true; if (confirmation.cancelled) timedOut = true;
@ -217,20 +218,7 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
createAppealTicket = confirmation.components["appeal"]!.active; createAppealTicket = confirmation.components["appeal"]!.active;
} }
} while (!timedOut && !success) } while (!timedOut && !success)
if (timedOut) return; if (timedOut || !confirmation.success) return;
if (!confirmation.success) {
await interaction.editReply({
embeds: [
new EmojiEmbed()
.setEmoji("PUNISH.BAN.GREEN")
.setTitle("Softban")
.setDescription("No changes were made")
.setStatus("Success")
],
components: []
});
return;
}
const status: {timeout: boolean | null, role: boolean | null, dm: boolean | null} = {timeout: null, role: null, dm: null}; const status: {timeout: boolean | null, role: boolean | null, dm: boolean | null} = {timeout: null, role: null, dm: null};
let dmMessage; let dmMessage;
try { try {

@ -169,22 +169,22 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
const check = (interaction: CommandInteraction) => { const check = (interaction: CommandInteraction) => {
const member = interaction.member as GuildMember; const member = interaction.member as GuildMember;
const me = interaction.guild.me!; const me = interaction.guild!.members.me!;
const apply = interaction.options.getMember("user") as GuildMember; const apply = interaction.options.getMember("user") as GuildMember;
if (member === null || me === null || apply === null) throw new Error("That member is not in the server");
const memberPos = member.roles.cache.size ? member.roles.highest.position : 0; const memberPos = member.roles.cache.size ? member.roles.highest.position : 0;
const mePos = me.roles.cache.size ? me.roles.highest.position : 0; const mePos = me.roles.cache.size ? me.roles.highest.position : 0;
const applyPos = apply.roles.cache.size ? apply.roles.highest.position : 0; const applyPos = apply.roles.cache.size ? apply.roles.highest.position : 0;
if (!interaction.guild) return false;
// Do not allow any changing of the owner // Do not allow any changing of the owner
if (member.id === interaction.guild.ownerId) throw new Error("You cannot change the owner's nickname"); if (member.id === interaction.guild.ownerId) throw new Error("You cannot change the owner's nickname");
// Check if Nucleus can change the nickname // Check if Nucleus can change the nickname
if (!(mePos > applyPos)) throw new Error("I do not have a role higher than that member"); if (!(mePos > applyPos)) throw new Error("I do not have a role higher than that member");
// Check if Nucleus has permission to change the nickname // Check if Nucleus has permission to change the nickname
if (!me.permissions.has("MANAGE_NICKNAMES")) throw new Error("I do not have the *Manage Nicknames* permission"); if (!me.permissions.has("ManageNicknames")) throw new Error("I do not have the *Manage Nicknames* permission");
// Allow the owner to change anyone's nickname // Allow the owner to change anyone's nickname
if (member.id === interaction.guild.ownerId) return true; if (member.id === interaction.guild.ownerId) return true;
// Check if the user has manage_nicknames permission // Check if the user has manage_nicknames permission
if (!member.permissions.has("MANAGE_NICKNAMES")) if (!member.permissions.has("ManageNicknames"))
throw new Error("You do not have the *Manage Nicknames* permission"); throw new Error("You do not have the *Manage Nicknames* permission");
// Allow changing your own nickname // Allow changing your own nickname
if (member === apply) return true; if (member === apply) return true;

@ -240,9 +240,9 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
}) })
) )
.setColor("Danger") .setColor("Danger")
.setFailedMessage("No changes were made", "Success", "CHANNEL.PURGE.GREEN")
.send(); .send();
if (confirmation.cancelled) return; if (confirmation.cancelled || !confirmation.success) return;
if (confirmation.success) {
let messages; let messages;
try { try {
if (!user) { if (!user) {
@ -397,18 +397,6 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
components: [] components: []
}); });
} }
} else {
await interaction.editReply({
embeds: [
new EmojiEmbed()
.setEmoji("CHANNEL.PURGE.GREEN")
.setTitle("Purge")
.setDescription("No changes were made")
.setStatus("Success")
],
components: []
});
}
} }
}; };

@ -47,9 +47,9 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
}) + "Are you sure you want to set the slowmode in this channel?" }) + "Are you sure you want to set the slowmode in this channel?"
) )
.setColor("Danger") .setColor("Danger")
.setFailedMessage("No changes were made", "Danger", "CHANNEL.SLOWMODE.ON")
.send(); .send();
if (confirmation.cancelled) return; if (confirmation.cancelled || !confirmation.success) return;
if (confirmation.success) {
try { try {
(interaction.channel as TextChannel).setRateLimitPerUser(time); (interaction.channel as TextChannel).setRateLimitPerUser(time);
} catch (e) { } catch (e) {
@ -74,18 +74,6 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
], ],
components: [] components: []
}); });
} else {
await interaction.editReply({
embeds: [
new EmojiEmbed()
.setEmoji("CHANNEL.SLOWMODE.ON")
.setTitle("Slowmode")
.setDescription("No changes were made")
.setStatus("Success")
],
components: []
});
}
}; };
const check = (interaction: CommandInteraction) => { const check = (interaction: CommandInteraction) => {

@ -1,13 +1,13 @@
import Discord, { import Discord, {
CategoryChannel,
CommandInteraction, CommandInteraction,
GuildMember, GuildMember,
ActionRowBuilder, ActionRowBuilder,
ButtonBuilder, ButtonBuilder,
SelectMenuBuilder, ButtonStyle,
ButtonStyle NonThreadGuildBasedChannel
} from "discord.js"; } from "discord.js";
import type { SlashCommandSubcommandBuilder } from "@discordjs/builders"; import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import type { GuildBasedChannel } from "discord.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js"; import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js"; import getEmojiByName from "../../utils/getEmojiByName.js";
import pageIndicator from "../../utils/createPageIndicator.js"; import pageIndicator from "../../utils/createPageIndicator.js";
@ -19,145 +19,185 @@ const command = (builder: SlashCommandSubcommandBuilder) =>
.addUserOption((option) => option.setName("member").setDescription("The member to view as").setRequired(true)); .addUserOption((option) => option.setName("member").setDescription("The member to view as").setRequired(true));
const callback = async (interaction: CommandInteraction): Promise<void> => { const callback = async (interaction: CommandInteraction): Promise<void> => {
let channels = []; /*
let m; * {
interaction.guild.channels.cache.forEach((channel) => { categoryObject: channel[],
if (!channel.parent && channel.type !== "GUILD_CATEGORY") channels.push(channel); categoryObject: channel[],
"null": channel[]
}
*/
const channels: Record<string, GuildBasedChannel[]> = {"": [] as GuildBasedChannel[]};
interaction.guild!.channels.fetch().then(channelCollection => {
channelCollection.forEach(channel => {
if (!channel) return; // if no channel
if (channel.type === Discord.ChannelType.GuildCategory) {
if(!channels[channel!.id]) channels[channel!.id] = [channel];
} else if (channel.parent) {
if (!channels[channel.parent.id]) channels[channel.parent.id] = [channel];
else (channels[channel.parent.id as string])!.push(channel);
} else {
channels[""]!.push(channel);
}
}); });
channels = [channels];
channels = channels.concat(
interaction.guild.channels.cache
.filter((c) => c.type === "GUILD_CATEGORY")
.map((c) => (c as CategoryChannel).children.map((c) => c))
);
const autoSortBelow = ["GUILD_VOICE", "GUILD_STAGE_VOICE"];
channels = channels.map((c) =>
c.sort((a, b) => {
if (autoSortBelow.includes(a.type) && autoSortBelow.includes(b.type)) return a.position - b.position;
if (autoSortBelow.includes(a.type)) return 1;
if (autoSortBelow.includes(b.type)) return -1;
return a.position - b.position;
})
);
// Sort all arrays by the position of the first channels parent position
channels = channels.sort((a, b) => {
if (!a[0].parent) return -1;
if (!b[0].parent) return 1;
return a[0].parent.position - b[0].parent.position;
}); });
const member = interaction.options.getMember("member") as Discord.GuildMember; const member = interaction.options.getMember("member") as Discord.GuildMember;
m = await interaction.reply({ const autoSortBelow = [Discord.ChannelType.GuildVoice, Discord.ChannelType.GuildStageVoice];
embeds: [ // for each category, sort its channels. This should be based on the order of the channels, with voice and stage channels sorted below text
new EmojiEmbed() channels = Object.values(channels).map((c) => {
.setEmoji("MEMBER.JOIN") return c.sort((a: GuildBasedChannel, b: GuildBasedChannel) => {
.setTitle("Viewing as " + member.displayName) if (a.type === Discord.ChannelType.PrivateThread || b.type === Discord.ChannelType.PrivateThread)
.setStatus("Success") if (autoSortBelow.includes(a.type) && autoSortBelow.includes(b.type)) return a.position ?? 0 - b.position ;
], if (autoSortBelow.includes(a.type)) return 1;
ephemeral: true, if (autoSortBelow.includes(b.type)) return -1;
fetchReply: true return a - b;
});
let page = 0;
let timedOut = false;
while (!timedOut) {
m = await interaction.editReply({
embeds: [
new EmojiEmbed()
.setEmoji("MEMBER.JOIN")
.setTitle("Viewing as " + member.displayName)
.setStatus("Success")
.setDescription(
`**${channels[page][0].parent ? channels[page][0].parent.name : "Uncategorised"}**` +
"\n" +
channels[page]
.map((c) => {
let channelType = c.type;
if (interaction.guild.rulesChannelId === c.id) channelType = "RULES";
else if ("nsfw" in c && c.nsfw) channelType += "_NSFW";
return c.permissionsFor(member).has("VIEW_CHANNEL")
? `${getEmojiByName("ICONS.CHANNEL." + channelType)} ${c.name}\n` +
(() => {
if ("threads" in c && c.threads.cache.size > 0) {
return (
c.threads.cache
.map(
(t) =>
` ${
getEmojiByName("ICONS.CHANNEL.THREAD_PIPE") +
" " +
getEmojiByName("ICONS.CHANNEL.THREAD_CHANNEL")
} ${t.name}`
)
.join("\n") + "\n"
);
}
return "";
})()
: "";
})
.join("") +
"\n" +
pageIndicator(channels.length, page)
)
],
components: [
new ActionRowBuilder().addComponents([
new SelectMenuBuilder()
.setOptions(
channels.map((c, index) => ({
label: c[0].parent ? c[0].parent.name : "Uncategorised",
value: index.toString(),
default: page === index
}))
)
.setCustomId("select")
.setMaxValues(1)
.setMinValues(1)
.setPlaceholder("Select a category")
]),
new ActionRowBuilder().addComponents([
new ButtonBuilder()
.setLabel(
page === 0
? ""
: channels[page - 1][0].parent
? channels[page - 1][0].parent.name
: "Uncategorised"
)
.setDisabled(page === 0)
.setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
.setStyle(ButtonStyle.Primary)
.setCustomId("previous"),
new ButtonBuilder()
.setLabel(
page === channels.length - 1
? ""
: channels[page + 1][0].parent
? channels[page + 1][0].parent.name
: "Uncategorised"
)
.setDisabled(page === channels.length - 1)
.setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
.setStyle(ButtonStyle.Primary)
.setCustomId("next")
])
]
}); });
let i;
try {
i = await m.awaitMessageComponent({ time: 300000 });
} catch (e) {
timedOut = true;
continue;
}
i.deferUpdate();
if (i.customId === "next") {
page++;
} else if (i.customId === "previous") {
page--;
} else if (i.customId === "select") {
page = parseInt(i.values[0]);
}
} }
//OLD CODE START
// const unprocessedChannels: GuildBasedChannel[] = [];
// let m;
// interaction.guild!.channels.cache.forEach((channel) => {
// if (!channel.parent && channel.type !== Discord.ChannelType.GuildCategory) unprocessedChannels.push(channel);
// });
// let channels: GuildBasedChannel[][] = [unprocessedChannels];
// channels = channels.concat(
// interaction.guild!.channels.cache
// .filter((c) => c.type === Discord.ChannelType.GuildCategory)
// .map((c) => (c as CategoryChannel).children.map((c) => c))
// );
// const autoSortBelow = ["GUILD_VOICE", "GUILD_STAGE_VOICE"];
// channels = channels.map((c) =>
// c.sort((a, b) => {
// if (autoSortBelow.includes(a.type) && autoSortBelow.includes(b.type)) return a.position - b.position;
// if (autoSortBelow.includes(a.type)) return 1;
// if (autoSortBelow.includes(b.type)) return -1;
// return a.position - b.position;
// })
// );
// // Sort all arrays by the position of the first channels parent position
// channels = channels.sort((a, b) => {
// if (!a[0].parent) return -1;
// if (!b[0].parent) return 1;
// return a[0].parent.position - b[0].parent.position;
// });
// const member = interaction.options.getMember("member") as Discord.GuildMember;
// m = await interaction.reply({
// embeds: [
// new EmojiEmbed()
// .setEmoji("MEMBER.JOIN")
// .setTitle("Viewing as " + member.displayName)
// .setStatus("Success")
// ],
// ephemeral: true,
// fetchReply: true
// });
// let page = 0;
// let timedOut = false;
// while (!timedOut) {
// m = await interaction.editReply({
// embeds: [
// new EmojiEmbed()
// .setEmoji("MEMBER.JOIN")
// .setTitle("Viewing as " + member.displayName)
// .setStatus("Success")
// .setDescription(
// `**${channels[page][0].parent ? channels[page][0].parent.name : "Uncategorised"}**` +
// "\n" +
// channels[page]
// .map((c) => {
// let channelType = c.type;
// if (interaction.guild.rulesChannelId === c.id) channelType = "RULES";
// else if ("nsfw" in c && c.nsfw) channelType += "_NSFW";
// return c.permissionsFor(member).has("VIEW_CHANNEL")
// ? `${getEmojiByName("ICONS.CHANNEL." + channelType)} ${c.name}\n` +
// (() => {
// if ("threads" in c && c.threads.cache.size > 0) {
// return (
// c.threads.cache
// .map(
// (t) =>
// ` ${
// getEmojiByName("ICONS.CHANNEL.THREAD_PIPE") +
// " " +
// getEmojiByName("ICONS.CHANNEL.THREAD_CHANNEL")
// } ${t.name}`
// )
// .join("\n") + "\n"
// );
// }
// return "";
// })()
// : "";
// })
// .join("") +
// "\n" +
// pageIndicator(channels.length, page)
// )
// ],
// components: [
// new ActionRowBuilder().addComponents([
// new SelectMenuBuilder()
// .setOptions(
// channels.map((c, index) => ({
// label: c[0].parent ? c[0].parent.name : "Uncategorised",
// value: index.toString(),
// default: page === index
// }))
// )
// .setCustomId("select")
// .setMaxValues(1)
// .setMinValues(1)
// .setPlaceholder("Select a category")
// ]),
// new ActionRowBuilder().addComponents([
// new ButtonBuilder()
// .setLabel(
// page === 0
// ? ""
// : channels[page - 1][0].parent
// ? channels[page - 1][0].parent.name
// : "Uncategorised"
// )
// .setDisabled(page === 0)
// .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
// .setStyle(ButtonStyle.Primary)
// .setCustomId("previous"),
// new ButtonBuilder()
// .setLabel(
// page === channels.length - 1
// ? ""
// : channels[page + 1][0].parent
// ? channels[page + 1][0].parent.name
// : "Uncategorised"
// )
// .setDisabled(page === channels.length - 1)
// .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
// .setStyle(ButtonStyle.Primary)
// .setCustomId("next")
// ])
// ]
// });
// let i;
// try {
// i = await m.awaitMessageComponent({ time: 300000 });
// } catch (e) {
// timedOut = true;
// continue;
// }
// i.deferUpdate();
// if (i.customId === "next") {
// page++;
// } else if (i.customId === "previous") {
// page--;
// } else if (i.customId === "select") {
// page = parseInt(i.values[0]);
// }
// }
}; };
const check = (interaction: CommandInteraction) => { const check = (interaction: CommandInteraction) => {

@ -56,6 +56,7 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
notify notify
) )
.addReasonButton(reason ?? "") .addReasonButton(reason ?? "")
.setFailedMessage("No changes were made", "Success", "PUNISH.WARN.GREEN")
.send(reason !== null); .send(reason !== null);
reason = reason ?? ""; reason = reason ?? "";
if (confirmation.cancelled) timedOut = true; if (confirmation.cancelled) timedOut = true;
@ -66,20 +67,7 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
createAppealTicket = confirmation.components["appeal"]!.active; createAppealTicket = confirmation.components["appeal"]!.active;
} }
} while (!timedOut && !success) } while (!timedOut && !success)
if (timedOut) return; if (timedOut || !confirmation.success) return;
if (!confirmation.success) {
await interaction.editReply({
embeds: [
new EmojiEmbed()
.setEmoji("PUNISH.WARN.GREEN")
.setTitle("Warn")
.setDescription("No changes were made")
.setStatus("Success")
],
components: []
});
return;
}
let dmSent = false; let dmSent = false;
const config = await client.database.guilds.read(interaction.guild.id); const config = await client.database.guilds.read(interaction.guild.id);
try { try {

@ -1,9 +1,11 @@
import type { CommandInteraction } from "discord.js"; import { LoadingEmbed } from './../../utils/defaultEmbeds.js';
import type Discord from "discord.js"; import { ButtonStyle, CommandInteraction } from "discord.js";
import Discord from "discord.js";
import type { SlashCommandSubcommandBuilder } from "@discordjs/builders"; import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import confirmationMessage from "../../utils/confirmationMessage.js"; import confirmationMessage from "../../utils/confirmationMessage.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js"; import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import client from "../../utils/client.js"; import client from "../../utils/client.js";
import getEmojiByName from '../../utils/getEmojiByName.js';
const command = (builder: SlashCommandSubcommandBuilder) => const command = (builder: SlashCommandSubcommandBuilder) =>
builder builder
@ -17,6 +19,7 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
await interaction.guild?.members.fetch(interaction.member!.user.id) await interaction.guild?.members.fetch(interaction.member!.user.id)
const { renderUser } = client.logger; const { renderUser } = client.logger;
const suggestion = interaction.options.get("suggestion")?.value as string; const suggestion = interaction.options.get("suggestion")?.value as string;
await interaction.reply({embeds: LoadingEmbed, ephemeral: true})
const confirmation = await new confirmationMessage(interaction) const confirmation = await new confirmationMessage(interaction)
.setEmoji("ICONS.OPP.ADD") .setEmoji("ICONS.OPP.ADD")
.setTitle("Suggest") .setTitle("Suggest")
@ -26,7 +29,7 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
) )
.setColor("Danger") .setColor("Danger")
.setInverted(true) .setInverted(true)
.send(); .send(true);
if (confirmation.cancelled) return; if (confirmation.cancelled) return;
if (confirmation.success) { if (confirmation.success) {
await (client.channels.cache.get("955161206459600976") as Discord.TextChannel).send({ await (client.channels.cache.get("955161206459600976") as Discord.TextChannel).send({
@ -34,11 +37,22 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
new EmojiEmbed() new EmojiEmbed()
.setTitle("Suggestion") .setTitle("Suggestion")
.setDescription( .setDescription(
`**From:** ${renderUser(interaction.member!.user as Discord.User)}\n**Suggestion:**\n> ${suggestion}` `**From:** ${renderUser(interaction.member!.user as Discord.User)}\n**Suggestion:**\n> ${suggestion}\n\n` +
`**Server:** ${interaction.guild!.name} (${interaction.guild!.id})\n`,
) )
.setStatus("Danger") .setStatus("Warning")
.setEmoji("NUCLEUS.LOGO") ], components: [new Discord.ActionRowBuilder<Discord.ButtonBuilder>().addComponents(
] new Discord.ButtonBuilder()
.setCustomId("suggestionAccept")
.setLabel("Accept")
.setStyle(ButtonStyle.Secondary)
.setEmoji(getEmojiByName("ICONS.ADD", "id")),
new Discord.ButtonBuilder()
.setCustomId("suggestionDeny")
.setLabel("Delete")
.setStyle(ButtonStyle.Secondary)
.setEmoji(getEmojiByName("ICONS.REMOVE", "id"))
)]
}); });
await interaction.editReply({ await interaction.editReply({
embeds: [ embeds: [

@ -5,7 +5,9 @@ import close from "../actions/tickets/delete.js";
import createTranscript from "../premium/createTranscript.js"; import createTranscript from "../premium/createTranscript.js";
import type { Interaction } from "discord.js"; import type { Interaction } from "discord.js";
import type Discord from "discord.js";
import type { NucleusClient } from "../utils/client.js"; import type { NucleusClient } from "../utils/client.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
export const event = "interactionCreate"; export const event = "interactionCreate";
@ -18,20 +20,29 @@ async function interactionCreate(interaction: Interaction) {
case "createticket": { return await create(interaction); } case "createticket": { return await create(interaction); }
case "closeticket": { return await close(interaction); } case "closeticket": { return await close(interaction); }
case "createtranscript": { return await createTranscript(interaction); } case "createtranscript": { return await createTranscript(interaction); }
case "suggestionAccept": { return await modifySuggestion(interaction, true); }
case "suggestionDeny": { return await modifySuggestion(interaction, false); }
} }
// } else if (interaction.type === "APPLICATION_COMMAND_AUTOCOMPLETE") {
// const int = interaction as AutocompleteInteraction;
// switch (`${int.commandName} ${int.options.getSubcommandGroup(false)} ${int.options.getSubcommand(false)}`) {
// case "settings null stats": {
// return int.respond(generateStatsChannelAutocomplete(int.options.getString("name") ?? ""));
// }
// case "settings null welcome": {
// return int.respond(generateWelcomeMessageAutocomplete(int.options.getString("message") ?? ""));
// }
// }
} }
} }
async function modifySuggestion(interaction: Discord.MessageComponentInteraction, accept: boolean) {
const message = await interaction.message;
await message.fetch();
if (message.embeds.length === 0) return;
const embed = message.embeds[0];
const newColour = accept ? "Success" : "Danger";
const footer = {text: `Suggestion ${accept ? "accepted" : "denied"} by ${interaction.user.tag}`, iconURL: interaction.user.displayAvatarURL()};
const newEmbed = new EmojiEmbed()
.setTitle(embed!.title!)
.setDescription(embed!.description!)
.setFooter(footer)
.setStatus(newColour);
await interaction.update({embeds: [newEmbed], components: []});
}
export async function callback(_client: NucleusClient, interaction: Interaction) { export async function callback(_client: NucleusClient, interaction: Interaction) {
await interactionCreate(interaction); await interactionCreate(interaction);
} }

@ -30,7 +30,9 @@ class confirmationMessage {
title = ""; title = "";
emoji = ""; emoji = "";
redEmoji: string | null = null; redEmoji: string | null = null;
timeoutText: string | null = null; failedMessage: string | null = null;
failedEmoji: string | null = null;
failedStatus: "Success" | "Danger" | "Warning" | null = null;
description = ""; description = "";
color: "Danger" | "Warning" | "Success" = "Success"; color: "Danger" | "Warning" | "Success" = "Success";
customButtons: Record<string, CustomBoolean<unknown>> = {}; customButtons: Record<string, CustomBoolean<unknown>> = {};
@ -45,14 +47,13 @@ class confirmationMessage {
this.title = title; this.title = title;
return this; return this;
} }
setEmoji(emoji: string, redEmoji?: string) { setEmoji(emoji: string) {
this.emoji = emoji; this.emoji = emoji;
if (redEmoji) this.redEmoji = redEmoji; // TODO: go through all confirmation messages and change them to use this, and not do their own edits
return this; return this;
} }
setDescription(description: string, timedOut?: string) { setDescription(description: string, timedOut?: string) {
this.description = description; this.description = description;
if (timedOut) this.timeoutText = timedOut; // TODO also this if (timedOut) this.failedMessage = timedOut;
return this; return this;
} }
setColor(color: "Danger" | "Warning" | "Success") { setColor(color: "Danger" | "Warning" | "Success") {
@ -63,6 +64,12 @@ class confirmationMessage {
this.inverted = inverted; this.inverted = inverted;
return this; return this;
} }
setFailedMessage(text: string, failedStatus: "Success" | "Danger" | "Warning" | null, failedEmoji: string | null = null) {
this.failedMessage = text;
this.failedStatus = failedStatus;
this.failedEmoji = failedEmoji;
return this;
}
addCustomBoolean( addCustomBoolean(
customId: string, customId: string,
title: string, title: string,
@ -243,8 +250,7 @@ class confirmationMessage {
out = await modalInteractionCollector( out = await modalInteractionCollector(
m, m,
(m: Interaction) => (m: Interaction) =>
(m as MessageComponentInteraction | ModalSubmitInteraction).channelId === (m as MessageComponentInteraction | ModalSubmitInteraction).channelId === this.interaction.channelId,
this.interaction.channelId,
(m) => m.customId === "reason" (m) => m.customId === "reason"
); );
} catch (e) { } catch (e) {
@ -277,6 +283,17 @@ class confirmationMessage {
await this.timeoutError() await this.timeoutError()
returnValue.cancelled = true; returnValue.cancelled = true;
} }
if (success == false) {
await this.interaction.editReply({
embeds: [new EmojiEmbed()
.setTitle(this.title)
.setDescription(this.failedMessage ?? "")
.setStatus(this.failedStatus ?? "Danger")
.setEmoji(this.failedEmoji ?? this.redEmoji ?? this.emoji)
], components: []
});
return {success: false}
}
if (newReason) returnValue.newReason = newReason; if (newReason) returnValue.newReason = newReason;
const typedReturnValue = returnValue as {cancelled: true} | const typedReturnValue = returnValue as {cancelled: true} |
@ -294,7 +311,7 @@ class confirmationMessage {
.setTitle(this.title) .setTitle(this.title)
.setDescription("We closed this message because it was not used for a while.") .setDescription("We closed this message because it was not used for a while.")
.setStatus("Danger") .setStatus("Danger")
.setEmoji(this.redEmoji ?? this.emoji) .setEmoji("CONTROL.BLOCKCROSS")
], ],
components: [] components: []
}) })

@ -1,7 +1,9 @@
import client from "../client.js"; import client from "../client.js";
import { resourceUsage } from "process"; import * as CP from 'child_process';
import { spawn } from "child_process"; import * as process from 'process';
import systeminformation from "systeminformation";
import config from "../../config/main.json" assert { type: "json" }; import config from "../../config/main.json" assert { type: "json" };
import singleNotify from "../singleNotify.js";
const discordPing = () => { const discordPing = () => {
@ -18,17 +20,11 @@ const databaseReadTime = async () => {
return end - start; return end - start;
} }
const resources = () => { const resources = async () => {
const current = resourceUsage();
const temperatureRaw = spawn("acpi", ["-t"])
let temperatureData: number = 0;
temperatureRaw.stdout.on("data", (data) => {
return temperatureData = data.toString().split(", ")[1].split(" ")[0]; // °C
})
return { return {
memory: current.sharedMemorySize, memory: process.memoryUsage().rss / 1024 / 1024,
cpu: current.userCPUTime + current.systemCPUTime, cpu: parseFloat(CP.execSync(`ps -p ${process.pid} -o %cpu=`).toString().trim()),
temperature: temperatureData temperature: (await systeminformation.cpuTemperature()).main
} }
} }
@ -36,12 +32,24 @@ const record = async () => {
const results = { const results = {
discord: discordPing(), discord: discordPing(),
databaseRead: await databaseReadTime(), databaseRead: await databaseReadTime(),
resources: resources() resources: await resources()
};
if (results.discord > 1000 || results.databaseRead > 500 || results.resources.cpu > 100) {
singleNotify(
"performanceTest",
config.developmentGuildID,
`Discord ping time: \`${results.discord}ms\`\nDatabase read time: \`${results.databaseRead}ms\`\nCPU usage: \`${results.resources.cpu}%\`\nMemory usage: \`${results.resources.memory}MB\`\nCPU temperature: \`${results.resources.temperature}°C\``,
"Critical",
config.owners
)
} else {
singleNotify("performanceTest", config.developmentGuildID, true)
} }
client.database.performanceTest.record(results) client.database.performanceTest.record(results)
setInterval(async () => { setTimeout(async () => {
record(); await record();
}, 10 * 1000); }, 60 * 1000);
} }
export { record }; export { record };

@ -13,7 +13,8 @@ export default async function (
type: string, type: string,
guild: string, guild: string,
message: string | true, message: string | true,
severity: "Critical" | "Warning" | "Info" = "Info" severity: "Critical" | "Warning" | "Info" = "Info",
pings?: string[]
) { ) {
const data = await client.database.guilds.read(guild); const data = await client.database.guilds.read(guild);
if (data.logging.staff.channel === null) return; if (data.logging.staff.channel === null) return;
@ -30,6 +31,11 @@ export default async function (
const channel = await client.channels.fetch(data.logging.staff.channel); const channel = await client.channels.fetch(data.logging.staff.channel);
if (!channel) return; if (!channel) return;
if (!channel.isTextBased()) return; if (!channel.isTextBased()) return;
if (pings) {
await channel.send({
content: pings.map((ping) => `<@${ping}>`).join(" ")
});
}
await channel.send({ await channel.send({
embeds: [ embeds: [
new EmojiEmbed() new EmojiEmbed()

Loading…
Cancel
Save