Fixed typing

pull/39/head
pineafan 3 years ago
parent 6de4da59ed
commit 1e462ab654
Signed by: Pinea
GPG Key ID: E5E1C2D43B0E4AB3

@ -34,7 +34,7 @@ const callback = async (interaction: CommandInteraction | ButtonInteraction, mem
let deleteDays; let deleteDays;
if (!interaction.isButton()) { if (!interaction.isButton()) {
member = interaction.options.getMember("user") as GuildMember; member = interaction.options.getMember("user") as GuildMember;
deleteDays = (interaction.options.get("delete")?.value as number | null) ?? 0 deleteDays = (interaction.options.get("delete")?.value as number | null) ?? 0;
} else { } else {
deleteDays = 0; deleteDays = 0;
} }
@ -115,12 +115,7 @@ const callback = async (interaction: CommandInteraction | ButtonInteraction, mem
new ButtonBuilder() new ButtonBuilder()
.setStyle(ButtonStyle.Link) .setStyle(ButtonStyle.Link)
.setLabel(config.moderation.ban.text) .setLabel(config.moderation.ban.text)
.setURL( .setURL(config.moderation.ban.link.replaceAll("{id}", member.id))
config.moderation.ban.link.replaceAll(
"{id}",
member.id
)
)
) )
); );
} }
@ -204,7 +199,7 @@ const check = (interaction: CommandInteraction | ButtonInteraction, partial: boo
apply = target!; apply = target!;
} else { } else {
apply = interaction.options.getMember("user") as GuildMember; apply = interaction.options.getMember("user") as GuildMember;
}; }
const memberPos = member.roles.cache.size > 1 ? member.roles.highest.position : 0; const memberPos = member.roles.cache.size > 1 ? member.roles.highest.position : 0;
const mePos = me.roles.cache.size > 1 ? me.roles.highest.position : 0; const mePos = me.roles.cache.size > 1 ? me.roles.highest.position : 0;
const applyPos = apply.roles.cache.size > 1 ? apply.roles.highest.position : 0; const applyPos = apply.roles.cache.size > 1 ? apply.roles.highest.position : 0;

@ -103,12 +103,7 @@ const callback = async (interaction: CommandInteraction | ButtonInteraction, mem
new ButtonBuilder() new ButtonBuilder()
.setStyle(ButtonStyle.Link) .setStyle(ButtonStyle.Link)
.setLabel(config.moderation.kick.text) .setLabel(config.moderation.kick.text)
.setURL( .setURL(config.moderation.kick.link.replaceAll("{id}", member.id))
config.moderation.kick.link.replaceAll(
"{id}",
member.id
)
)
) )
); );
} }

@ -1,5 +1,12 @@
import { LinkWarningFooter, LoadingEmbed } from "../../utils/defaults.js"; import { LinkWarningFooter, LoadingEmbed } from "../../utils/defaults.js";
import Discord, { CommandInteraction, GuildMember, ActionRowBuilder, ButtonBuilder, ButtonStyle, ButtonInteraction } from "discord.js"; import Discord, {
CommandInteraction,
GuildMember,
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
ButtonInteraction
} from "discord.js";
import type { SlashCommandSubcommandBuilder } from "discord.js"; import type { SlashCommandSubcommandBuilder } 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";
@ -49,7 +56,10 @@ const command = (builder: SlashCommandSubcommandBuilder) =>
.setRequired(false) .setRequired(false)
); );
const callback = async (interaction: CommandInteraction | ButtonInteraction, member?: GuildMember): Promise<unknown> => { const callback = async (
interaction: CommandInteraction | ButtonInteraction,
member?: GuildMember
): Promise<unknown> => {
if (!interaction.guild) return; if (!interaction.guild) return;
const { log, NucleusColors, renderUser, entry, renderDelta } = client.logger; const { log, NucleusColors, renderUser, entry, renderDelta } = client.logger;
let time: { days: number; hours: number; minutes: number; seconds: number } | null = null; let time: { days: number; hours: number; minutes: number; seconds: number } | null = null;
@ -62,7 +72,7 @@ const callback = async (interaction: CommandInteraction | ButtonInteraction, mem
seconds: (interaction.options.get("seconds")?.value as number | null) ?? 0 seconds: (interaction.options.get("seconds")?.value as number | null) ?? 0
}; };
} else { } else {
time = {days: 0, hours: 0, minutes: 0, seconds: 0}; time = { days: 0, hours: 0, minutes: 0, seconds: 0 };
} }
if (!member) return; if (!member) return;
const config = await client.database.guilds.read(interaction.guild.id); const config = await client.database.guilds.read(interaction.guild.id);
@ -203,8 +213,7 @@ const callback = async (interaction: CommandInteraction | ButtonInteraction, mem
"appeal", "appeal",
"Create appeal ticket", "Create appeal ticket",
!(await areTicketsEnabled(interaction.guild.id)), !(await areTicketsEnabled(interaction.guild.id)),
async () => async () => await create(interaction.guild!, member!.user, interaction.user, reason),
await create(interaction.guild!, member!.user, interaction.user, reason),
"An appeal ticket will be created when Confirm is clicked", "An appeal ticket will be created when Confirm is clicked",
null, null,
"CONTROL.TICKET", "CONTROL.TICKET",

@ -1,5 +1,16 @@
import { LinkWarningFooter } from "./../../utils/defaults.js"; import { LinkWarningFooter } from "./../../utils/defaults.js";
import { ActionRowBuilder, ButtonBuilder, CommandInteraction, GuildMember, ButtonStyle, Message, ButtonInteraction, ModalBuilder, TextInputBuilder, TextInputStyle } from "discord.js"; import {
ActionRowBuilder,
ButtonBuilder,
CommandInteraction,
GuildMember,
ButtonStyle,
Message,
ButtonInteraction,
ModalBuilder,
TextInputBuilder,
TextInputStyle
} from "discord.js";
import type { SlashCommandSubcommandBuilder } from "discord.js"; import type { SlashCommandSubcommandBuilder } from "discord.js";
import confirmationMessage from "../../utils/confirmationMessage.js"; import confirmationMessage from "../../utils/confirmationMessage.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js"; import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
@ -17,7 +28,10 @@ const command = (builder: SlashCommandSubcommandBuilder) =>
option.setName("name").setDescription("The name to set | Leave blank to clear").setRequired(false) option.setName("name").setDescription("The name to set | Leave blank to clear").setRequired(false)
); );
const callback = async (interaction: CommandInteraction | ButtonInteraction, member?: GuildMember): Promise<unknown> => { const callback = async (
interaction: CommandInteraction | ButtonInteraction,
member?: GuildMember
): Promise<unknown> => {
const { log, NucleusColors, entry, renderDelta, renderUser } = client.logger; const { log, NucleusColors, entry, renderDelta, renderUser } = client.logger;
let newNickname; let newNickname;
if (!interaction.isButton()) { if (!interaction.isButton()) {
@ -39,28 +53,15 @@ const callback = async (interaction: CommandInteraction | ButtonInteraction, mem
.setDescription( .setDescription(
keyValueList({ keyValueList({
user: renderUser(member.user), user: renderUser(member.user),
"new nickname": `${ "new nickname": `${newNickname ? newNickname : "*No nickname*"}`
newNickname }) + `Are you sure you want to ${newNickname ? "change" : "clear"} <@!${member.id}>'s nickname?`
? newNickname
: "*No nickname*"
}`
}) +
`Are you sure you want to ${
newNickname ? "change" : "clear"
} <@!${member.id}>'s nickname?`
) )
.setColor("Danger") .setColor("Danger")
.addCustomBoolean( .addCustomBoolean(
"appeal", "appeal",
"Create appeal ticket", "Create appeal ticket",
!(await areTicketsEnabled(interaction.guild!.id)), !(await areTicketsEnabled(interaction.guild!.id)),
async () => async () => await create(interaction.guild!, member!.user, interaction.user, "Nickname changed"),
await create(
interaction.guild!,
member!.user,
interaction.user,
"Nickname changed"
),
"An appeal ticket will be created", "An appeal ticket will be created",
null, null,
"CONTROL.TICKET", "CONTROL.TICKET",
@ -81,18 +82,16 @@ const callback = async (interaction: CommandInteraction | ButtonInteraction, mem
"ICONS.EDIT", "ICONS.EDIT",
"modal", "modal",
newNickname ?? "", newNickname ?? "",
new ModalBuilder() new ModalBuilder().setTitle("Editing nickname").addComponents(
.setTitle("Editing nickname") new ActionRowBuilder<TextInputBuilder>().addComponents(
.addComponents( new TextInputBuilder()
new ActionRowBuilder<TextInputBuilder>().addComponents( .setCustomId("default")
new TextInputBuilder() .setLabel("Nickname")
.setCustomId("default") .setMaxLength(32)
.setLabel("Nickname") .setRequired(false)
.setMaxLength(32) .setStyle(TextInputStyle.Short)
.setRequired(false) .setValue(newNickname ? newNickname : " ")
.setStyle(TextInputStyle.Short) )
.setValue(newNickname ? newNickname : " ")
)
) )
) )
.setFailedMessage("No changes were made", "Success", "PUNISH.NICKNAME.GREEN") .setFailedMessage("No changes were made", "Success", "PUNISH.NICKNAME.GREEN")
@ -104,7 +103,7 @@ const callback = async (interaction: CommandInteraction | ButtonInteraction, mem
notify = confirmation.components["notify"]!.active; notify = confirmation.components["notify"]!.active;
createAppealTicket = confirmation.components["appeal"]!.active; createAppealTicket = confirmation.components["appeal"]!.active;
} }
if (confirmation.modals) newNickname = confirmation.modals![0]!.value if (confirmation.modals) newNickname = confirmation.modals![0]!.value;
} while (!timedOut && !success); } while (!timedOut && !success);
if (timedOut || !success) return; if (timedOut || !success) return;
let dmSent = false; let dmSent = false;
@ -121,12 +120,8 @@ const callback = async (interaction: CommandInteraction | ButtonInteraction, mem
.setEmoji("PUNISH.NICKNAME.RED") .setEmoji("PUNISH.NICKNAME.RED")
.setTitle("Nickname changed") .setTitle("Nickname changed")
.setDescription( .setDescription(
`Your nickname was ${ `Your nickname was ${newNickname ? "changed" : "cleared"} in ${interaction.guild!.name}.` +
newNickname ? "changed" : "cleared" (newNickname ? `\nIt is now: ${newNickname}` : "") +
} in ${interaction.guild!.name}.` +
(newNickname
? `\nIt is now: ${newNickname}`
: "") +
"\n\n" + "\n\n" +
(createAppealTicket (createAppealTicket
? `You can appeal this in the ticket created in <#${ ? `You can appeal this in the ticket created in <#${
@ -145,12 +140,7 @@ const callback = async (interaction: CommandInteraction | ButtonInteraction, mem
new ButtonBuilder() new ButtonBuilder()
.setStyle(ButtonStyle.Link) .setStyle(ButtonStyle.Link)
.setLabel(config.moderation.nick.text) .setLabel(config.moderation.nick.text)
.setURL( .setURL(config.moderation.nick.link.replaceAll("{id}", member.id))
config.moderation.nick.link.replaceAll(
"{id}",
member.id
)
)
) )
); );
} }

@ -101,8 +101,7 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
let component; let component;
try { try {
component = m.awaitMessageComponent({ component = m.awaitMessageComponent({
filter: (i) => filter: (i) => i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id,
i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id,
time: 300000 time: 300000
}); });
} catch (e) { } catch (e) {

@ -1,4 +1,11 @@
import Discord, { CommandInteraction, GuildMember, ActionRowBuilder, ButtonBuilder, ButtonStyle, ButtonInteraction } from "discord.js"; import Discord, {
CommandInteraction,
GuildMember,
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
ButtonInteraction
} from "discord.js";
import type { SlashCommandSubcommandBuilder } from "discord.js"; import type { SlashCommandSubcommandBuilder } from "discord.js";
import confirmationMessage from "../../utils/confirmationMessage.js"; import confirmationMessage from "../../utils/confirmationMessage.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js"; import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
@ -14,7 +21,10 @@ const command = (builder: SlashCommandSubcommandBuilder) =>
.setDescription("Warns a user") .setDescription("Warns a user")
.addUserOption((option) => option.setName("user").setDescription("The user to warn").setRequired(true)); .addUserOption((option) => option.setName("user").setDescription("The user to warn").setRequired(true));
const callback = async (interaction: CommandInteraction | ButtonInteraction, member?: GuildMember): Promise<unknown> => { const callback = async (
interaction: CommandInteraction | ButtonInteraction,
member?: GuildMember
): Promise<unknown> => {
if (!interaction.guild) return; if (!interaction.guild) return;
const { log, NucleusColors, renderUser, entry } = client.logger; const { log, NucleusColors, renderUser, entry } = client.logger;
if (!interaction.isButton()) member = interaction.options.getMember("user") as GuildMember; if (!interaction.isButton()) member = interaction.options.getMember("user") as GuildMember;
@ -41,8 +51,7 @@ const callback = async (interaction: CommandInteraction | ButtonInteraction, mem
"appeal", "appeal",
"Create appeal ticket", "Create appeal ticket",
!(await areTicketsEnabled(interaction.guild.id)), !(await areTicketsEnabled(interaction.guild.id)),
async () => async () => await create(interaction.guild!, member!.user, interaction.user, reason),
await create(interaction.guild!, member!.user, interaction.user, reason),
"An appeal ticket will be created", "An appeal ticket will be created",
null, null,
"CONTROL.TICKET", "CONTROL.TICKET",
@ -110,12 +119,7 @@ const callback = async (interaction: CommandInteraction | ButtonInteraction, mem
new ButtonBuilder() new ButtonBuilder()
.setStyle(ButtonStyle.Link) .setStyle(ButtonStyle.Link)
.setLabel(config.moderation.warn.text) .setLabel(config.moderation.warn.text)
.setURL( .setURL(config.moderation.warn.link.replaceAll("{id}", member.id))
config.moderation.warn.link.replaceAll(
"{id}",
member.id
)
)
) )
); );
} }
@ -135,10 +139,7 @@ const callback = async (interaction: CommandInteraction | ButtonInteraction, mem
timestamp: Date.now() timestamp: Date.now()
}, },
list: { list: {
user: entry( user: entry(member.user.id, renderUser(member.user)),
member.user.id,
renderUser(member.user)
),
warnedBy: entry(interaction.member!.user.id, renderUser(interaction.member!.user as Discord.User)), warnedBy: entry(interaction.member!.user.id, renderUser(interaction.member!.user as Discord.User)),
reason: reason ? reason : "*No reason provided*" reason: reason ? reason : "*No reason provided*"
}, },
@ -151,13 +152,7 @@ const callback = async (interaction: CommandInteraction | ButtonInteraction, mem
guild: interaction.guild.id guild: interaction.guild.id
} }
}; };
await client.database.history.create( await client.database.history.create("warn", interaction.guild.id, member.user, interaction.user, reason);
"warn",
interaction.guild.id,
member.user,
interaction.user,
reason
);
log(data); log(data);
const failed = !dmSent && notify; const failed = !dmSent && notify;
if (!failed) { if (!failed) {
@ -179,9 +174,7 @@ const callback = async (interaction: CommandInteraction | ButtonInteraction, mem
components: [] components: []
}); });
} else { } else {
const canSeeChannel = member const canSeeChannel = member.permissionsIn(interaction.channel as Discord.TextChannel).has("ViewChannel");
.permissionsIn(interaction.channel as Discord.TextChannel)
.has("ViewChannel");
const m = (await interaction.editReply({ const m = (await interaction.editReply({
embeds: [ embeds: [
new EmojiEmbed() new EmojiEmbed()

@ -1,4 +1,18 @@
import { ActionRowBuilder, AttachmentBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, ChannelType, CommandInteraction, ComponentType, Guild, ModalBuilder, ModalSubmitInteraction, TextInputBuilder, TextInputStyle } from "discord.js"; import {
ActionRowBuilder,
AttachmentBuilder,
ButtonBuilder,
ButtonInteraction,
ButtonStyle,
ChannelType,
CommandInteraction,
ComponentType,
Guild,
ModalBuilder,
ModalSubmitInteraction,
TextInputBuilder,
TextInputStyle
} from "discord.js";
import type { SlashCommandSubcommandBuilder } from "discord.js"; import type { SlashCommandSubcommandBuilder } from "discord.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";
@ -8,7 +22,7 @@ const command = (builder: SlashCommandSubcommandBuilder) =>
builder.setName("stats").setDescription("Gets the bot's stats"); builder.setName("stats").setDescription("Gets the bot's stats");
const callback = async (interaction: CommandInteraction): Promise<void> => { const callback = async (interaction: CommandInteraction): Promise<void> => {
const description = `**Servers:** ${client.guilds.cache.size}\n` + `**Ping:** \`${client.ws.ping * 2}ms\`` const description = `**Servers:** ${client.guilds.cache.size}\n` + `**Ping:** \`${client.ws.ping * 2}ms\``;
const m = await interaction.reply({ const m = await interaction.reply({
embeds: [ embeds: [
new EmojiEmbed() new EmojiEmbed()
@ -28,30 +42,39 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
.setDescription(description) .setDescription(description)
.setStatus("Success") .setStatus("Success")
.setEmoji("SETTINGS.STATS.GREEN") .setEmoji("SETTINGS.STATS.GREEN")
], components: [new ActionRowBuilder<ButtonBuilder>().addComponents( ],
new ButtonBuilder().setCustomId("admin").setLabel("Admin Panel").setStyle(ButtonStyle.Primary), components: [
new ButtonBuilder().setCustomId("mod:nickname:599498449733550102").setLabel("Testing").setStyle(ButtonStyle.Primary) new ActionRowBuilder<ButtonBuilder>().addComponents(
)] new ButtonBuilder().setCustomId("admin").setLabel("Admin Panel").setStyle(ButtonStyle.Primary),
new ButtonBuilder()
.setCustomId("mod:nickname:599498449733550102")
.setLabel("Testing")
.setStyle(ButtonStyle.Primary)
)
]
}); });
const modal = new ModalBuilder() const modal = new ModalBuilder()
.addComponents( .addComponents(
new ActionRowBuilder<TextInputBuilder>() new ActionRowBuilder<TextInputBuilder>().addComponents(
.addComponents( new TextInputBuilder()
new TextInputBuilder() .setStyle(TextInputStyle.Short)
.setStyle(TextInputStyle.Short) .setLabel("Guild ID")
.setLabel("Guild ID") .setCustomId("guildID")
.setCustomId("guildID") .setPlaceholder("Guild ID")
.setPlaceholder("Guild ID") .setMinLength(16)
.setMinLength(16) .setMaxLength(25)
.setMaxLength(25) )
)
) )
.setTitle("Admin Panel") .setTitle("Admin Panel")
.setCustomId("adminPanel") .setCustomId("adminPanel");
let i1: ButtonInteraction; let i1: ButtonInteraction;
const channel = await client.channels.fetch(interaction.channelId) const channel = await client.channels.fetch(interaction.channelId);
if(!channel || [ChannelType.GuildCategory, ChannelType.GroupDM, ChannelType.GuildStageVoice].includes(channel.type)) return; if (
!channel ||
[ChannelType.GuildCategory, ChannelType.GroupDM, ChannelType.GuildStageVoice].includes(channel.type)
)
return;
// console.log(interaction) // console.log(interaction)
if (!("awaitMessageComponent" in channel)) return; if (!("awaitMessageComponent" in channel)) return;
try { try {
@ -59,27 +82,28 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
filter: (i) => i.customId === "admin" && i.user.id === interaction.user.id, filter: (i) => i.customId === "admin" && i.user.id === interaction.user.id,
time: 300000 time: 300000
}); });
} catch (e) { console.log(e); return } } catch (e) {
await i1.showModal(modal) console.log(e);
return;
}
await i1.showModal(modal);
let out: ModalSubmitInteraction; let out: ModalSubmitInteraction;
try { try {
out = await i1.awaitModalSubmit({ out = await i1.awaitModalSubmit({
filter: (i) => i.customId === "adminPanel" && i.user.id === interaction.user.id, filter: (i) => i.customId === "adminPanel" && i.user.id === interaction.user.id,
time: 300000 time: 300000
}) });
} catch { return } } catch {
return;
}
out.deferUpdate(); out.deferUpdate();
const GuildID = out.fields.getTextInputValue("guildID"); const GuildID = out.fields.getTextInputValue("guildID");
if (!client.guilds.cache.has(GuildID)) { if (!client.guilds.cache.has(GuildID)) {
await interaction.editReply({ await interaction.editReply({
embeds: [ embeds: [new EmojiEmbed().setTitle("Admin").setDescription("Not in server").setStatus("Danger")],
new EmojiEmbed() components: []
.setTitle("Admin")
.setDescription("Not in server")
.setStatus("Danger")
], components: []
}); });
}; }
await interaction.editReply({ await interaction.editReply({
embeds: [], embeds: [],
@ -91,24 +115,23 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
new ButtonBuilder().setCustomId("purge").setLabel("Delete data").setStyle(ButtonStyle.Danger), new ButtonBuilder().setCustomId("purge").setLabel("Delete data").setStyle(ButtonStyle.Danger),
new ButtonBuilder().setCustomId("cache").setLabel("Reset cache").setStyle(ButtonStyle.Success) new ButtonBuilder().setCustomId("cache").setLabel("Reset cache").setStyle(ButtonStyle.Success)
) )
]}); ]
});
let i; let i;
try { try {
i = await m.awaitMessageComponent<ComponentType.Button>({ i = await m.awaitMessageComponent<ComponentType.Button>({
filter: (i) => i.user.id === interaction.user.id, filter: (i) => i.user.id === interaction.user.id,
time: 300000 time: 300000
}) });
} catch { return } } catch {
return;
}
i.deferUpdate(); i.deferUpdate();
const guild = await client.guilds.fetch(GuildID) as Guild | null; const guild = (await client.guilds.fetch(GuildID)) as Guild | null;
if (!guild) { if (!guild) {
await interaction.editReply({ await interaction.editReply({
embeds: [ embeds: [new EmojiEmbed().setTitle("Admin").setDescription("Not in server").setStatus("Danger")],
new EmojiEmbed() components: []
.setTitle("Admin")
.setDescription("Not in server")
.setStatus("Danger")
], components: []
}); });
return; return;
} }
@ -119,17 +142,17 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
.setTitle("Stats") .setTitle("Stats")
.setDescription( .setDescription(
`**Name:** ${guild.name}\n` + `**Name:** ${guild.name}\n` +
`**ID:** \`${guild.id}\`\n` + `**ID:** \`${guild.id}\`\n` +
`**Owner:** ${client.users.cache.get(guild.ownerId)!.tag}\n` + `**Owner:** ${client.users.cache.get(guild.ownerId)!.tag}\n` +
`**Member Count:** ${guild.memberCount}\n` + `**Member Count:** ${guild.memberCount}\n` +
`**Created:** <t:${guild.createdTimestamp}:F>\n` + `**Created:** <t:${guild.createdTimestamp}:F>\n` +
`**Added Nucleus:** <t:${guild.members.me!.joinedTimestamp}:R>\n` + `**Added Nucleus:** <t:${guild.members.me!.joinedTimestamp}:R>\n` +
`**Nucleus' Perms:** https://discordapi.com/permissions.html#${guild.members.me!.permissions.valueOf()}\n` `**Nucleus' Perms:** https://discordapi.com/permissions.html#${guild.members.me!.permissions.valueOf()}\n`
) )
.setStatus("Success") .setStatus("Success")
.setEmoji("SETTINGS.STATS.GREEN") .setEmoji("SETTINGS.STATS.GREEN")
] ]
}) });
} else if (i.customId === "leave") { } else if (i.customId === "leave") {
await guild.leave(); await guild.leave();
await interaction.editReply({ await interaction.editReply({
@ -139,8 +162,9 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
.setDescription(`Left ${guild.name}`) .setDescription(`Left ${guild.name}`)
.setStatus("Success") .setStatus("Success")
.setEmoji("SETTINGS.STATS.GREEN") .setEmoji("SETTINGS.STATS.GREEN")
], components: [] ],
}) components: []
});
} else if (i.customId === "data") { } else if (i.customId === "data") {
// Get all the data and convert to a string // Get all the data and convert to a string
const data = await client.database.guilds.read(guild.id); const data = await client.database.guilds.read(guild.id);
@ -150,9 +174,10 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
await interaction.editReply({ await interaction.editReply({
embeds: [ embeds: [
new EmojiEmbed().setTitle("Data").setDescription(`Data for ${guild.name}`).setStatus("Success") new EmojiEmbed().setTitle("Data").setDescription(`Data for ${guild.name}`).setStatus("Success")
], components: [], ],
components: [],
files: [attachment] files: [attachment]
}) });
} else if (i.customId === "purge") { } else if (i.customId === "purge") {
await client.database.guilds.delete(GuildID); await client.database.guilds.delete(GuildID);
await client.database.history.delete(GuildID); await client.database.history.delete(GuildID);
@ -165,8 +190,9 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
.setDescription(`Deleted data for ${guild.name}`) .setDescription(`Deleted data for ${guild.name}`)
.setStatus("Success") .setStatus("Success")
.setEmoji("SETTINGS.STATS.GREEN") .setEmoji("SETTINGS.STATS.GREEN")
], components: [] ],
}) components: []
});
} else if (i.customId === "cache") { } else if (i.customId === "cache") {
await client.memory.forceUpdate(guild.id); await client.memory.forceUpdate(guild.id);
await interaction.editReply({ await interaction.editReply({
@ -176,8 +202,9 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
.setDescription(`Reset cache for ${guild.name}`) .setDescription(`Reset cache for ${guild.name}`)
.setStatus("Success") .setStatus("Success")
.setEmoji("SETTINGS.STATS.GREEN") .setEmoji("SETTINGS.STATS.GREEN")
], components: [] ],
}) components: []
});
} }
} }
}; };

@ -176,7 +176,7 @@ const editRoleMenuPage = async (
m: Message, m: Message,
data?: ObjectSchema data?: ObjectSchema
): Promise<ObjectSchema | null> => { ): Promise<ObjectSchema | null> => {
if (!data) data = _.cloneDeep(defaultRoleMenuData) if (!data) data = _.cloneDeep(defaultRoleMenuData);
const buttons = new ActionRowBuilder<ButtonBuilder>().addComponents( const buttons = new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder() new ButtonBuilder()
.setCustomId("back") .setCustomId("back")

@ -2,6 +2,7 @@ import { AuditLogEvent, GuildAuditLogsEntry, GuildMember } from "discord.js";
import type { NucleusClient } from "../utils/client.js"; import type { NucleusClient } from "../utils/client.js";
import type { LoggerOptions } from "../utils/log.js"; import type { LoggerOptions } from "../utils/log.js";
import { generalException } from "../utils/createTemporaryStorage.js"; import { generalException } from "../utils/createTemporaryStorage.js";
import { doMemberChecks } from "../reflex/scanners.js";
export const event = "guildMemberUpdate"; export const event = "guildMemberUpdate";
@ -92,6 +93,7 @@ export async function callback(client: NucleusClient, before: GuildMember, after
if (!auditLog) return; if (!auditLog) return;
if (auditLog.executor!.id === client.user!.id) return; if (auditLog.executor!.id === client.user!.id) return;
if (before.nickname !== after.nickname) { if (before.nickname !== after.nickname) {
doMemberChecks(after, after.guild);
await client.database.history.create( await client.database.history.create(
"nickname", "nickname",
after.guild.id, after.guild.id,

@ -19,10 +19,7 @@ export const event = "interactionCreate";
async function errorMessage(interaction: ButtonInteraction, message: string) { async function errorMessage(interaction: ButtonInteraction, message: string) {
await interaction.reply({ await interaction.reply({
embeds: [new EmojiEmbed() embeds: [new EmojiEmbed().setDescription(message).setStatus("Danger")],
.setDescription(message)
.setStatus("Danger")
],
ephemeral: true, ephemeral: true,
components: [] components: []
}); });
@ -60,23 +57,27 @@ async function interactionCreate(interaction: Interaction) {
const member = await interaction.guild?.members.fetch(memberId!); const member = await interaction.guild?.members.fetch(memberId!);
switch (action) { switch (action) {
case "kick": { case "kick": {
const check = await kickCheck(interaction, false, member) const check = await kickCheck(interaction, false, member);
if (check !== true) return await errorMessage(interaction, check!); if (check !== true) return await errorMessage(interaction, check!);
return await kickCallback(interaction, member); return await kickCallback(interaction, member);
} case "ban": { }
const check = await banCheck(interaction, false, member) case "ban": {
const check = await banCheck(interaction, false, member);
if (check !== true) return await errorMessage(interaction, check!); if (check !== true) return await errorMessage(interaction, check!);
return await banCallback(interaction, member); return await banCallback(interaction, member);
} case "mute": { }
const check = await muteCheck(interaction, false, member) case "mute": {
const check = await muteCheck(interaction, false, member);
if (check !== true) return await errorMessage(interaction, check!); if (check !== true) return await errorMessage(interaction, check!);
return await muteCallback(interaction, member); return await muteCallback(interaction, member);
} case "nickname": { }
const check = await nicknameCheck(interaction, false, member) case "nickname": {
const check = await nicknameCheck(interaction, false, member);
if (check !== true) return await errorMessage(interaction, check || "Something went wrong"); if (check !== true) return await errorMessage(interaction, check || "Something went wrong");
return await nicknameCallback(interaction, member); return await nicknameCallback(interaction, member);
} case "warn": { }
const check = await warnCheck(interaction, false, member) case "warn": {
const check = await warnCheck(interaction, false, member);
if (check !== true) return await errorMessage(interaction, check!); if (check !== true) return await errorMessage(interaction, check!);
return await warnCallback(interaction, member); return await warnCallback(interaction, member);
} }

@ -9,7 +9,7 @@ export const event = "guildMemberAdd";
export async function callback(client: NucleusClient, member: GuildMember) { export async function callback(client: NucleusClient, member: GuildMember) {
welcome(member); welcome(member);
statsChannelAdd(member.user, member.guild); statsChannelAdd(member.user, member.guild);
doMemberChecks(member, member.guild) doMemberChecks(member, member.guild);
const { log, isLogging, NucleusColors, entry, renderUser, renderDelta } = client.logger; const { log, isLogging, NucleusColors, entry, renderUser, renderDelta } = client.logger;
if (!(await isLogging(member.guild.id, "guildMemberUpdate"))) return; if (!(await isLogging(member.guild.id, "guildMemberUpdate"))) return;
await client.database.history.create("join", member.guild.id, member.user, null, null); await client.database.history.create("join", member.guild.id, member.user, null, null);

@ -5,9 +5,9 @@ import Tesseract from "node-tesseract-ocr";
import type Discord from "discord.js"; import type Discord from "discord.js";
import client from "../utils/client.js"; import client from "../utils/client.js";
import { createHash } from "crypto"; import { createHash } from "crypto";
import * as nsfwjs from 'nsfwjs'; // import * as nsfwjs from "nsfwjs";
import * as clamscan from 'clamscan' // import * as clamscan from "clamscan";
import * as tf from "@tensorflow/tfjs-node"; // import * as tf from "@tensorflow/tfjs-node";
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 { ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js"; import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
@ -21,10 +21,10 @@ interface MalwareSchema {
errored?: boolean; errored?: boolean;
} }
const model = await nsfwjs.load(); // const model = await nsfwjs.load();
export async function testNSFW(link: string): Promise<NSFWSchema> { export async function testNSFW(link: string): Promise<NSFWSchema> {
const [fileName, hash] = await saveAttachment(link); const [_fileName, hash] = await saveAttachment(link);
const alreadyHaveCheck = await client.database.scanCache.read(hash); const alreadyHaveCheck = await client.database.scanCache.read(hash);
if (alreadyHaveCheck) return { nsfw: alreadyHaveCheck.data }; if (alreadyHaveCheck) return { nsfw: alreadyHaveCheck.data };
@ -167,7 +167,12 @@ export async function MalwareCheck(element: string): Promise<boolean> {
} }
} }
export function TestString(string: string, soft: string[], strict: string[], enabled?: boolean): {word: string, type: string} | null { export function TestString(
string: string,
soft: string[],
strict: string[],
enabled?: boolean
): { word: string; type: string } | null {
if (!enabled) return null; if (!enabled) return null;
for (const word of strict) { for (const word of strict) {
if (string.toLowerCase().includes(word)) { if (string.toLowerCase().includes(word)) {
@ -197,34 +202,56 @@ export async function doMemberChecks(member: Discord.GuildMember, guild: Discord
if (member.user.bot) return; if (member.user.bot) return;
const guildData = await client.database.guilds.read(guild.id); const guildData = await client.database.guilds.read(guild.id);
if (!guildData.logging.staff.channel) return; if (!guildData.logging.staff.channel) return;
const [ loose, strict ] = [guildData.filters.wordFilter.words.loose, guildData.filters.wordFilter.words.strict]; const [loose, strict] = [guildData.filters.wordFilter.words.loose, guildData.filters.wordFilter.words.strict];
// Does the username contain filtered words // Does the username contain filtered words
const usernameCheck = TestString(member.user.username, loose, strict, guildData.filters.wordFilter.enabled); const usernameCheck = TestString(member.user.username, loose, strict, guildData.filters.wordFilter.enabled);
// Does the nickname contain filtered words // Does the nickname contain filtered words
const nicknameCheck = TestString(member.nickname ?? "", loose, strict, guildData.filters.wordFilter.enabled); const nicknameCheck = TestString(member.nickname ?? "", loose, strict, guildData.filters.wordFilter.enabled);
// Does the profile picture contain filtered words // Does the profile picture contain filtered words
const avatarTextCheck = TestString(await TestImage(member.user.displayAvatarURL({ forceStatic: true })) ?? "", loose, strict, guildData.filters.wordFilter.enabled); const avatarTextCheck = TestString(
(await TestImage(member.user.displayAvatarURL({ forceStatic: true }))) ?? "",
loose,
strict,
guildData.filters.wordFilter.enabled
);
// Is the profile picture NSFW // Is the profile picture NSFW
const avatarCheck = guildData.filters.images.NSFW && await NSFWCheck(member.user.displayAvatarURL({ forceStatic: true })); const avatarCheck =
guildData.filters.images.NSFW && (await NSFWCheck(member.user.displayAvatarURL({ forceStatic: true })));
// Does the username contain an invite // Does the username contain an invite
const inviteCheck = guildData.filters.invite.enabled && member.user.username.match(/discord\.gg\/[a-zA-Z0-9]+/gi) !== null; const inviteCheck =
guildData.filters.invite.enabled && member.user.username.match(/discord\.gg\/[a-zA-Z0-9]+/gi) !== null;
// Does the nickname contain an invite // Does the nickname contain an invite
const nicknameInviteCheck = guildData.filters.invite.enabled && member.nickname?.match(/discord\.gg\/[a-zA-Z0-9]+/gi) !== null; const nicknameInviteCheck =
guildData.filters.invite.enabled && member.nickname?.match(/discord\.gg\/[a-zA-Z0-9]+/gi) !== null;
if (usernameCheck !== null || nicknameCheck !== null || avatarCheck || inviteCheck || nicknameInviteCheck || avatarTextCheck !== null) { if (
usernameCheck !== null ||
nicknameCheck !== null ||
avatarCheck ||
inviteCheck ||
nicknameInviteCheck ||
avatarTextCheck !== null
) {
const infractions = []; const infractions = [];
if (usernameCheck !== null) { if (usernameCheck !== null) {
infractions.push(`Username contains a ${usernameCheck.type}ly filtered word (${usernameCheck.word})`); infractions.push(`Username contains a ${usernameCheck.type}ly filtered word (${usernameCheck.word})`);
} if (nicknameCheck !== null) { }
if (nicknameCheck !== null) {
infractions.push(`Nickname contains a ${nicknameCheck.type}ly filtered word (${nicknameCheck.word})`); infractions.push(`Nickname contains a ${nicknameCheck.type}ly filtered word (${nicknameCheck.word})`);
} if (avatarCheck) { }
if (avatarCheck) {
infractions.push("Profile picture is NSFW"); infractions.push("Profile picture is NSFW");
} if (inviteCheck) { }
if (inviteCheck) {
infractions.push("Username contains an invite"); infractions.push("Username contains an invite");
} if (nicknameInviteCheck) { }
if (nicknameInviteCheck) {
infractions.push("Nickname contains an invite"); infractions.push("Nickname contains an invite");
} if (avatarTextCheck !== null) { }
infractions.push(`Profile picture contains a ${avatarTextCheck.type}ly filtered word: ${avatarTextCheck.word}`); if (avatarTextCheck !== null) {
infractions.push(
`Profile picture contains a ${avatarTextCheck.type}ly filtered word: ${avatarTextCheck.word}`
);
} }
if (infractions.length === 0) return; if (infractions.length === 0) return;
// This is bad - Warn in the staff notifications channel // This is bad - Warn in the staff notifications channel
@ -234,34 +261,43 @@ export async function doMemberChecks(member: Discord.GuildMember, guild: Discord
.setTitle("Member Flagged") .setTitle("Member Flagged")
.setEmoji("ICONS.FLAGS.RED") .setEmoji("ICONS.FLAGS.RED")
.setStatus("Danger") .setStatus("Danger")
.setDescription(`**Member:** ${member.user.username} (<@${member.user.id}>)\n\n` + .setDescription(
infractions.map((element) => `${filter} ${element}`).join("\n") `**Member:** ${member.user.username} (<@${member.user.id}>)\n\n` +
) infractions.map((element) => `${filter} ${element}`).join("\n")
);
await channel.send({ await channel.send({
embeds: [embed], embeds: [embed],
components: [new ActionRowBuilder<ButtonBuilder>().addComponents(...[ components: [
new ButtonBuilder() new ActionRowBuilder<ButtonBuilder>().addComponents(
.setCustomId(`mod:warn:${member.user.id}`) ...[
.setLabel("Warn") new ButtonBuilder()
.setStyle(ButtonStyle.Primary), .setCustomId(`mod:warn:${member.user.id}`)
new ButtonBuilder() .setLabel("Warn")
.setCustomId(`mod:mute:${member.user.id}`) .setStyle(ButtonStyle.Primary),
.setLabel("Mute") new ButtonBuilder()
.setStyle(ButtonStyle.Primary), .setCustomId(`mod:mute:${member.user.id}`)
new ButtonBuilder() .setLabel("Mute")
.setCustomId(`mod:kick:${member.user.id}`) .setStyle(ButtonStyle.Primary),
.setLabel("Kick") new ButtonBuilder()
.setStyle(ButtonStyle.Danger), .setCustomId(`mod:kick:${member.user.id}`)
new ButtonBuilder() .setLabel("Kick")
.setCustomId(`mod:ban:${member.user.id}`) .setStyle(ButtonStyle.Danger),
.setLabel("Ban") new ButtonBuilder()
.setStyle(ButtonStyle.Danger), .setCustomId(`mod:ban:${member.user.id}`)
].concat((usernameCheck !== null || nicknameCheck !== null || avatarTextCheck !== null) ? [ .setLabel("Ban")
new ButtonBuilder() .setStyle(ButtonStyle.Danger)
.setCustomId(`mod:nickname:${member.user.id}`) ].concat(
.setLabel("Change Name") usernameCheck !== null || nicknameCheck !== null || avatarTextCheck !== null
.setStyle(ButtonStyle.Primary) ? [
] : []))] new ButtonBuilder()
.setCustomId(`mod:nickname:${member.user.id}`)
.setLabel("Change Name")
.setStyle(ButtonStyle.Primary)
]
: []
)
)
]
}); });
} }
} }

@ -37,7 +37,13 @@ class confirmationMessage {
inverted = false; inverted = false;
reason: string | null = null; reason: string | null = null;
modals: {buttonText: string, emoji: string, customId: string, modal: Discord.ModalBuilder, value: string | undefined}[] = []; modals: {
buttonText: string;
emoji: string;
customId: string;
modal: Discord.ModalBuilder;
value: string | undefined;
}[] = [];
constructor(interaction: CommandInteraction | ButtonInteraction) { constructor(interaction: CommandInteraction | ButtonInteraction) {
this.interaction = interaction; this.interaction = interaction;
@ -102,7 +108,7 @@ class confirmationMessage {
} }
addModal(buttonText: string, emoji: string, customId: string, current: string, modal: Discord.ModalBuilder) { addModal(buttonText: string, emoji: string, customId: string, current: string, modal: Discord.ModalBuilder) {
modal.setCustomId(customId); modal.setCustomId(customId);
this.modals.push({buttonText, emoji, customId, modal, value: current}); this.modals.push({ buttonText, emoji, customId, modal, value: current });
return this; return this;
} }
async send(editOnly?: boolean): Promise<{ async send(editOnly?: boolean): Promise<{
@ -110,7 +116,13 @@ class confirmationMessage {
cancelled?: boolean; cancelled?: boolean;
components?: Record<string, CustomBoolean<unknown>>; components?: Record<string, CustomBoolean<unknown>>;
newReason?: string; newReason?: string;
modals?: {buttonText: string, emoji: string, customId: string, modal: Discord.ModalBuilder, value: string | undefined}[]; modals?: {
buttonText: string;
emoji: string;
customId: string;
modal: Discord.ModalBuilder;
value: string | undefined;
}[];
}> { }> {
let cancelled = false; let cancelled = false;
let success: boolean | undefined = undefined; let success: boolean | undefined = undefined;
@ -212,7 +224,7 @@ class confirmationMessage {
time: 300000 time: 300000
}); });
} catch (e) { } catch (e) {
success = false success = false;
break; break;
} }
if (component.customId === "yes") { if (component.customId === "yes") {
@ -291,7 +303,12 @@ class confirmationMessage {
continue; continue;
} }
} else if (this.modals.map((m) => m.customId).includes(component.customId)) { } else if (this.modals.map((m) => m.customId).includes(component.customId)) {
const chosenModal = this.modals.find((component => m => m.customId === component.customId)(component)); const chosenModal = this.modals.find(
(
(component) => (m) =>
m.customId === component.customId
)(component)
);
await component.showModal(chosenModal!.modal); await component.showModal(chosenModal!.modal);
await this.interaction.editReply({ await this.interaction.editReply({
embeds: [ embeds: [
@ -364,7 +381,12 @@ class confirmationMessage {
const modals = this.modals; const modals = this.modals;
const typedReturnValue = returnValue as const typedReturnValue = returnValue as
| { cancelled: true } | { cancelled: true }
| { success: boolean; components: Record<string, CustomBoolean<unknown>>; modals: typeof modals; newReason?: string } | {
success: boolean;
components: Record<string, CustomBoolean<unknown>>;
modals: typeof modals;
newReason?: string;
}
| { newReason: string; components: Record<string, CustomBoolean<unknown>>; modals: typeof modals } | { newReason: string; components: Record<string, CustomBoolean<unknown>>; modals: typeof modals }
| { components: Record<string, CustomBoolean<unknown>>; modals: typeof modals }; | { components: Record<string, CustomBoolean<unknown>>; modals: typeof modals };

@ -836,9 +836,7 @@ export class Premium {
} }
} }
export class Plugins { // export class Plugins {}
}
export interface GuildConfig { export interface GuildConfig {
id: string; id: string;

Loading…
Cancel
Save