diff --git a/src/events/interactionCreate/components/isCommand.ts b/src/events/interactionCreate/components/isCommand.ts index ac1e19d..b763bb0 100644 --- a/src/events/interactionCreate/components/isCommand.ts +++ b/src/events/interactionCreate/components/isCommand.ts @@ -4,16 +4,93 @@ import { CommandInteraction, MessageEmbed } from "discord.js"; import logger from "@logger"; import { errorColor, footerText, footerIcon } from "@config/embed"; +import i18next from "i18next"; export default async (interaction: CommandInteraction) => { if (!interaction.isCommand()) return; - const { client, guild, commandName, user } = interaction; + const { client, guild, commandName, user, memberPermissions } = interaction; const currentCommand = client.commands.get(commandName); - if (!currentCommand) return; + if (!currentCommand) { + logger.verbose(`Command ${commandName} not found`); + } - await interaction.deferReply({ ephemeral: true }); + // logger.warn(currentCommand.modules[interaction.options.getSubcommand()].meta); + + // const meta = { ephemeral: false, guildOnly: false }; + + let meta; + + if (!interaction.options.getSubcommandGroup(false)) { + meta = currentCommand.modules[interaction.options.getSubcommand()].meta; + } else { + meta = + currentCommand.groups[interaction.options.getSubcommandGroup()].modules[ + interaction.options.getSubcommand() + ].meta; + } + + await interaction.deferReply({ ephemeral: meta?.ephemeral || false }); + + if ( + meta.permissions && + meta.guildOnly && + !memberPermissions?.has(meta.permissions) + ) { + return interaction?.editReply({ + embeds: [ + new MessageEmbed() + .setTitle("[:toolbox:] Manage") + .setDescription(`You do not have the permission to manage the bot.`) + .setTimestamp(new Date()) + .setColor(errorColor) + .setFooter({ text: footerText, iconURL: footerIcon }), + ], + }); + } + + if (meta.guildOnly) { + if (!guild) { + logger.verbose(`Guild is null`); + + return interaction.editReply({ + embeds: [ + new MessageEmbed() + .setDescription( + i18next.t("guildOnly", { + lng: interaction.locale, + ns: "errors", + }) + ) + .setColor(errorColor) + .setTimestamp(new Date()) + .setFooter({ text: footerText, iconURL: footerIcon }), + ], + }); + } + } + + if (meta.dmOnly) { + if (guild) { + logger.verbose(`Guild exist`); + + return interaction.editReply({ + embeds: [ + new MessageEmbed() + .setDescription( + i18next.t("dmOnly", { + lng: interaction.locale, + ns: "errors", + }) + ) + .setColor(errorColor) + .setTimestamp(new Date()) + .setFooter({ text: footerText, iconURL: footerIcon }), + ], + }); + } + } await currentCommand .execute(interaction) diff --git a/src/handlers/commands.ts b/src/handlers/commands.ts index db65603..f5cfed0 100644 --- a/src/handlers/commands.ts +++ b/src/handlers/commands.ts @@ -15,7 +15,11 @@ export default async (client: Client) => { plugins.map(async (pluginName) => { const plugin = await import(`../plugins/${pluginName}`); - await client.commands.set(plugin.default.data.name, plugin.default); + await client.commands.set( + plugin.default.data.name, + plugin.default, + plugin.default.meta + ); }) ) .then(async () => { diff --git a/src/plugins/counters/index.ts b/src/plugins/counters/index.ts index 4da895c..1bd7c7b 100644 --- a/src/plugins/counters/index.ts +++ b/src/plugins/counters/index.ts @@ -1,17 +1,18 @@ -// Dependencies import { CommandInteraction } from "discord.js"; import { SlashCommandBuilder } from "@discordjs/builders"; - import logger from "@logger"; -import modules from "@root/plugins/counters/modules"; +import modules from "@plugins/counters/modules"; export default { - metadata: { author: "Zyner" }, + modules, + data: new SlashCommandBuilder() .setName("counters") .setDescription("View guild counters") + .addSubcommand(modules.view.data), + async execute(interaction: CommandInteraction) { const { options } = interaction; diff --git a/src/plugins/counters/modules/index.ts b/src/plugins/counters/modules/index.ts index dc539f8..8c5ea76 100644 --- a/src/plugins/counters/modules/index.ts +++ b/src/plugins/counters/modules/index.ts @@ -1,3 +1,3 @@ -import view from "./view"; +import view from "@plugins/counters/modules/view"; export default { view }; diff --git a/src/plugins/counters/modules/view/index.ts b/src/plugins/counters/modules/view/index.ts index 66f46c9..7dd8d52 100644 --- a/src/plugins/counters/modules/view/index.ts +++ b/src/plugins/counters/modules/view/index.ts @@ -1,11 +1,3 @@ -// Dependencies -import { CommandInteraction, MessageEmbed } from "discord.js"; -import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; -import { ChannelType } from "discord-api-types/v10"; - -import counterSchema from "@schemas/counter"; - -// Configuration import { errorColor, successColor, @@ -13,7 +5,15 @@ import { footerIcon, } from "@config/embed"; +import { CommandInteraction, MessageEmbed } from "discord.js"; +import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; +import { ChannelType } from "discord-api-types/v10"; + +import counterSchema from "@schemas/counter"; + export default { + meta: { guildOnly: true, ephemeral: false }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("view") @@ -28,6 +28,7 @@ export default { .addChannelTypes(ChannelType.GuildText) ); }, + execute: async (interaction: CommandInteraction) => { const { options, guild } = interaction; diff --git a/src/plugins/credits/index.ts b/src/plugins/credits/index.ts index e73aeb5..2ec3c92 100644 --- a/src/plugins/credits/index.ts +++ b/src/plugins/credits/index.ts @@ -5,6 +5,8 @@ import logger from "@logger"; import modules from "@plugins/credits/modules"; export default { + modules, + data: new SlashCommandBuilder() .setName("credits") .setDescription("Manage your credits.") diff --git a/src/plugins/credits/modules/balance/index.ts b/src/plugins/credits/modules/balance/index.ts index f292056..44ac45a 100644 --- a/src/plugins/credits/modules/balance/index.ts +++ b/src/plugins/credits/modules/balance/index.ts @@ -13,6 +13,7 @@ import logger from "@logger"; import fetchUser from "@helpers/fetchUser"; export default { + meta: { guildOnly: true, ephemeral: true }, data: (command: SlashCommandSubcommandBuilder) => { return command .setName("balance") diff --git a/src/plugins/credits/modules/gift/index.ts b/src/plugins/credits/modules/gift/index.ts index 5434dcb..82b6a28 100644 --- a/src/plugins/credits/modules/gift/index.ts +++ b/src/plugins/credits/modules/gift/index.ts @@ -22,6 +22,8 @@ import i18next from "i18next"; // Function export default { + meta: { guildOnly: true, ephemeral: true }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("gift") diff --git a/src/plugins/credits/modules/top/index.ts b/src/plugins/credits/modules/top/index.ts index b580204..1656c59 100644 --- a/src/plugins/credits/modules/top/index.ts +++ b/src/plugins/credits/modules/top/index.ts @@ -13,6 +13,8 @@ import logger from "@logger"; import userSchema, { IUser } from "@schemas/user"; export default { + meta: { guildOnly: true, ephemeral: false }, + data: (command: SlashCommandSubcommandBuilder) => { return command.setName("top").setDescription(`View the top users`); }, diff --git a/src/plugins/credits/modules/work/index.ts b/src/plugins/credits/modules/work/index.ts index 2ffb20d..4ad9d13 100644 --- a/src/plugins/credits/modules/work/index.ts +++ b/src/plugins/credits/modules/work/index.ts @@ -17,6 +17,8 @@ import fetchUser from "@helpers/fetchUser"; import fetchGuild from "@helpers/fetchGuild"; export default { + meta: { guildOnly: true, ephemeral: true }, + data: (command: SlashCommandSubcommandBuilder) => { return command.setName("work").setDescription(`Work to earn credits`); }, diff --git a/src/plugins/fun/index.ts b/src/plugins/fun/index.ts index 06a9e0b..0d727dc 100644 --- a/src/plugins/fun/index.ts +++ b/src/plugins/fun/index.ts @@ -5,6 +5,8 @@ import logger from "@logger"; import modules from "@plugins/fun/modules"; export default { + modules, + data: new SlashCommandBuilder() .setName("fun") .setDescription("Fun commands.") diff --git a/src/plugins/fun/modules/meme.ts b/src/plugins/fun/modules/meme.ts index c263fe6..40d5cdb 100644 --- a/src/plugins/fun/modules/meme.ts +++ b/src/plugins/fun/modules/meme.ts @@ -6,6 +6,8 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; import logger from "@logger"; export default { + meta: { guildOnly: false, ephemeral: false }, + data: (command: SlashCommandSubcommandBuilder) => { return command.setName("meme").setDescription("Get a meme from r/memes)"); }, diff --git a/src/plugins/manage/groups/counters/index.ts b/src/plugins/manage/groups/counters/index.ts index dc3c255..fec6a1d 100644 --- a/src/plugins/manage/groups/counters/index.ts +++ b/src/plugins/manage/groups/counters/index.ts @@ -5,31 +5,33 @@ import { CommandInteraction } from "discord.js"; import logger from "@logger"; // Modules -import moduleCreate from "./modules/create"; -import moduleDelete from "./modules/delete"; +import modules from "./modules"; // Function export default { + modules, + data: (group: SlashCommandSubcommandGroupBuilder) => { return group .setName("counters") .setDescription("Manage guild counters.") - .addSubcommand(moduleCreate.data) - .addSubcommand(moduleDelete.data); + .addSubcommand(modules.create.data) + .addSubcommand(modules.delete_.data); }, + execute: async (interaction: CommandInteraction) => { const { options } = interaction; if (options?.getSubcommand() === "create") { logger?.verbose(`Executing create subcommand`); - return moduleCreate.execute(interaction); + return modules.create.execute(interaction); } if (options?.getSubcommand() === "delete") { logger?.verbose(`Executing delete subcommand`); - return moduleDelete.execute(interaction); + return modules.delete_.execute(interaction); } logger?.verbose(`Unknown subcommand ${options?.getSubcommand()}`); diff --git a/src/plugins/manage/groups/counters/modules/create/index.ts b/src/plugins/manage/groups/counters/modules/create/index.ts index 495f57a..f23723c 100644 --- a/src/plugins/manage/groups/counters/modules/create/index.ts +++ b/src/plugins/manage/groups/counters/modules/create/index.ts @@ -1,5 +1,5 @@ // Dependencies -import { MessageEmbed, CommandInteraction } from "discord.js"; +import { MessageEmbed, CommandInteraction, Permissions } from "discord.js"; import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; import { ChannelType } from "discord-api-types/v10"; @@ -19,6 +19,12 @@ import counterSchema from "@schemas/counter"; // Function export default { + meta: { + guildOnly: true, + ephemeral: true, + permissions: [Permissions.FLAGS.MANAGE_GUILD], + }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("create") diff --git a/src/plugins/manage/groups/counters/modules/delete/index.ts b/src/plugins/manage/groups/counters/modules/delete/index.ts index 0d8f1d4..3035fa8 100644 --- a/src/plugins/manage/groups/counters/modules/delete/index.ts +++ b/src/plugins/manage/groups/counters/modules/delete/index.ts @@ -1,5 +1,5 @@ // Dependencies -import { CommandInteraction, MessageEmbed } from "discord.js"; +import { CommandInteraction, MessageEmbed, Permissions } from "discord.js"; // Configurations import { @@ -19,6 +19,12 @@ import { ChannelType } from "discord-api-types/v10"; // Function export default { + meta: { + guildOnly: true, + ephemeral: true, + permissions: [Permissions.FLAGS.MANAGE_GUILD], + }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("delete") diff --git a/src/plugins/manage/groups/counters/modules/index.ts b/src/plugins/manage/groups/counters/modules/index.ts new file mode 100644 index 0000000..37cb7aa --- /dev/null +++ b/src/plugins/manage/groups/counters/modules/index.ts @@ -0,0 +1,4 @@ +import create from "@plugins/manage/groups/counters/modules/create"; +import delete_ from "@plugins/manage/groups/counters/modules/delete"; + +export default { create, delete_ }; diff --git a/src/plugins/manage/groups/credits/index.ts b/src/plugins/manage/groups/credits/index.ts index 9209f8a..fc0839c 100644 --- a/src/plugins/manage/groups/credits/index.ts +++ b/src/plugins/manage/groups/credits/index.ts @@ -1,53 +1,43 @@ -// Dependencies import { CommandInteraction } from "discord.js"; import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders"; - import logger from "@logger"; -// Modules -import moduleGive from "./modules/give"; -import moduleSet from "./modules/set"; -import moduleTake from "./modules/take"; -import moduleTransfer from "./modules/transfer"; +import modules from "./modules"; -// Function export default { + modules, + data: (group: SlashCommandSubcommandGroupBuilder) => { return group .setName("credits") .setDescription("Manage the credits of a user.") - .addSubcommand(moduleGive.data) - .addSubcommand(moduleSet.data) - .addSubcommand(moduleTake.data) - .addSubcommand(moduleTransfer.data); + .addSubcommand(modules.give.data) + .addSubcommand(modules.set.data) + .addSubcommand(modules.take.data) + .addSubcommand(modules.transfer.data); }, execute: async (interaction: CommandInteraction) => { const { options } = interaction; - if (options?.getSubcommand() === "give") { - logger?.verbose(`Executing give subcommand`); + switch (options.getSubcommand()) { + case "give": + logger.verbose(`Executing give subcommand`); - return moduleGive.execute(interaction); + return modules.give.execute(interaction); + case "set": + logger.verbose(`Executing set subcommand`); + + return modules.set.execute(interaction); + case "take": + logger.verbose(`Executing take subcommand`); + + return modules.take.execute(interaction); + case "transfer": + logger.verbose(`Executing transfer subcommand`); + + return modules.transfer.execute(interaction); + default: + logger.verbose(`Unknown subcommand ${options.getSubcommand()}`); } - - if (options?.getSubcommand() === "set") { - logger?.verbose(`Executing set subcommand`); - - return moduleSet.execute(interaction); - } - - if (options?.getSubcommand() === "take") { - logger?.verbose(`Executing take subcommand`); - - return moduleTake.execute(interaction); - } - - if (options?.getSubcommand() === "transfer") { - logger?.verbose(`Executing transfer subcommand`); - - return moduleTransfer.execute(interaction); - } - - logger?.verbose(`No subcommand found`); }, }; diff --git a/src/plugins/manage/groups/credits/modules/give/index.ts b/src/plugins/manage/groups/credits/modules/give/index.ts index 2345852..38e272c 100644 --- a/src/plugins/manage/groups/credits/modules/give/index.ts +++ b/src/plugins/manage/groups/credits/modules/give/index.ts @@ -1,5 +1,5 @@ // Dependencies -import { CommandInteraction, MessageEmbed } from "discord.js"; +import { CommandInteraction, MessageEmbed, Permissions } from "discord.js"; import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Configurations @@ -21,6 +21,12 @@ import fetchUser from "@helpers/fetchUser"; // Function export default { + meta: { + guildOnly: true, + ephemeral: true, + permissions: [Permissions.FLAGS.MANAGE_GUILD], + }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("give") diff --git a/src/plugins/manage/groups/credits/modules/index.ts b/src/plugins/manage/groups/credits/modules/index.ts new file mode 100644 index 0000000..4065a60 --- /dev/null +++ b/src/plugins/manage/groups/credits/modules/index.ts @@ -0,0 +1,6 @@ +import give from "@plugins/manage/groups/credits/modules/give"; +import set from "@plugins/manage/groups/credits/modules/set"; +import take from "@plugins/manage/groups/credits/modules/take"; +import transfer from "@plugins/manage/groups/credits/modules/transfer"; + +export default { give, set, take, transfer }; diff --git a/src/plugins/manage/groups/credits/modules/set/index.ts b/src/plugins/manage/groups/credits/modules/set/index.ts index 53103a4..a2b8e18 100644 --- a/src/plugins/manage/groups/credits/modules/set/index.ts +++ b/src/plugins/manage/groups/credits/modules/set/index.ts @@ -1,5 +1,5 @@ // Dependencies -import { CommandInteraction, MessageEmbed } from "discord.js"; +import { CommandInteraction, MessageEmbed, Permissions } from "discord.js"; // Configurations import { @@ -20,6 +20,12 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function export default { + meta: { + guildOnly: true, + ephemeral: true, + permissions: [Permissions.FLAGS.MANAGE_GUILD], + }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("set") diff --git a/src/plugins/manage/groups/credits/modules/take/index.ts b/src/plugins/manage/groups/credits/modules/take/index.ts index 40e74bb..53b2864 100644 --- a/src/plugins/manage/groups/credits/modules/take/index.ts +++ b/src/plugins/manage/groups/credits/modules/take/index.ts @@ -1,5 +1,5 @@ // Dependencies -import { CommandInteraction, MessageEmbed } from "discord.js"; +import { CommandInteraction, MessageEmbed, Permissions } from "discord.js"; // Configurations import { @@ -21,6 +21,12 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function export default { + meta: { + guildOnly: true, + ephemeral: true, + permissions: [Permissions.FLAGS.MANAGE_GUILD], + }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("take") diff --git a/src/plugins/manage/groups/credits/modules/transfer/index.ts b/src/plugins/manage/groups/credits/modules/transfer/index.ts index 0dbd07d..4423ca5 100644 --- a/src/plugins/manage/groups/credits/modules/transfer/index.ts +++ b/src/plugins/manage/groups/credits/modules/transfer/index.ts @@ -1,5 +1,5 @@ // Dependencies -import { CommandInteraction, MessageEmbed } from "discord.js"; +import { CommandInteraction, MessageEmbed, Permissions } from "discord.js"; // Configurations import { @@ -21,6 +21,12 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function export default { + meta: { + guildOnly: true, + ephemeral: true, + permissions: [Permissions.FLAGS.MANAGE_GUILD], + }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("transfer") diff --git a/src/plugins/manage/groups/index.ts b/src/plugins/manage/groups/index.ts new file mode 100644 index 0000000..6b928fe --- /dev/null +++ b/src/plugins/manage/groups/index.ts @@ -0,0 +1,4 @@ +import counters from "@plugins/manage/groups/counters"; +import credits from "@plugins/manage/groups/credits"; + +export default { counters, credits }; diff --git a/src/plugins/manage/index.ts b/src/plugins/manage/index.ts index 32d066d..aecedf5 100644 --- a/src/plugins/manage/index.ts +++ b/src/plugins/manage/index.ts @@ -6,47 +6,33 @@ import { CommandInteraction, Permissions, MessageEmbed } from "discord.js"; import { errorColor, footerText, footerIcon } from "@config/embed"; // Groups -import credits from "./groups/credits"; -import counters from "./groups/counters"; +import groups from "@plugins/manage/groups"; import logger from "@logger"; // Function export default { - metadata: { author: "Zyner" }, + groups, + data: new SlashCommandBuilder() .setName("manage") .setDescription("Manage the bot.") - .addSubcommandGroup(counters.data) - .addSubcommandGroup(credits.data), + .addSubcommandGroup(groups.counters.data) + .addSubcommandGroup(groups.credits.data), async execute(interaction: CommandInteraction) { // Destructure - const { memberPermissions, options } = interaction; - - // Check permission - if (!memberPermissions?.has(Permissions?.FLAGS?.MANAGE_GUILD)) { - return interaction?.editReply({ - embeds: [ - new MessageEmbed() - .setTitle("[:toolbox:] Manage") - .setDescription(`You do not have the permission to manage the bot.`) - .setTimestamp(new Date()) - .setColor(errorColor) - .setFooter({ text: footerText, iconURL: footerIcon }), - ], - }); - } + const { options } = interaction; if (options?.getSubcommandGroup() === "credits") { logger?.verbose(`Subcommand group is credits`); - return credits.execute(interaction); + return groups.credits.execute(interaction); } if (options?.getSubcommandGroup() === "counters") { logger?.verbose(`Subcommand group is counters`); - return counters.execute(interaction); + return groups.counters.execute(interaction); } logger?.verbose(`Subcommand group is not credits or counters`); diff --git a/src/plugins/profile/index.ts b/src/plugins/profile/index.ts index a255a7a..1908543 100644 --- a/src/plugins/profile/index.ts +++ b/src/plugins/profile/index.ts @@ -3,34 +3,26 @@ import { SlashCommandBuilder } from "@discordjs/builders"; import { CommandInteraction } from "discord.js"; // Modules -import view from "./modules/view"; +import modules from "@plugins/profile/modules"; // Handlers import logger from "@logger"; // Function export default { - metadata: { author: "Zyner" }, + modules, + data: new SlashCommandBuilder() .setName("profile") .setDescription("Check a profile.") - .addSubcommand((subcommand) => - subcommand - .setName("view") - .setDescription("View a profile.") - .addUserOption((option) => - option - .setName("target") - .setDescription("The profile you wish to view") - ) - ), + .addSubcommand(modules.view.data), async execute(interaction: CommandInteraction) { const { options } = interaction; if (options?.getSubcommand() === "view") { logger?.verbose(`Executing view subcommand`); - return view(interaction); + return modules.view.execute(interaction); } logger?.verbose(`No subcommand found`); diff --git a/src/plugins/profile/modules/index.ts b/src/plugins/profile/modules/index.ts new file mode 100644 index 0000000..1dc8e1b --- /dev/null +++ b/src/plugins/profile/modules/index.ts @@ -0,0 +1,3 @@ +import view from "@plugins/profile/modules/view"; + +export default { view }; diff --git a/src/plugins/profile/modules/view.ts b/src/plugins/profile/modules/view.ts index 6e05df5..81bfc52 100644 --- a/src/plugins/profile/modules/view.ts +++ b/src/plugins/profile/modules/view.ts @@ -8,68 +8,82 @@ import { successColor, footerText, footerIcon } from "@config/embed"; import fetchUser from "@helpers/fetchUser"; import logger from "@logger"; +import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function -export default async (interaction: CommandInteraction) => { - // Destructure - const { client, options, user, guild } = interaction; +export default { + meta: { guildOnly: true, ephemeral: false }, - // Target information - const target = options?.getUser("target"); + data: (command: SlashCommandSubcommandBuilder) => { + return command + .setName("view") + .setDescription("View a profile.") + .addUserOption((option) => + option.setName("target").setDescription("The profile you wish to view") + ); + }, - // Discord User Information - const discordUser = await client?.users?.fetch( - `${target ? target?.id : user?.id}` - ); + execute: async (interaction: CommandInteraction) => { + // Destructure + const { client, options, user, guild } = interaction; - if (guild === null) { - return logger?.verbose(`Guild is null`); - } + // Target information + const target = options?.getUser("target"); - // User Information - const userObj = await fetchUser(discordUser, guild); + // Discord User Information + const discordUser = await client?.users?.fetch( + `${target ? target?.id : user?.id}` + ); - // Embed object - const embed = { - author: { - name: `${discordUser?.username}#${discordUser?.discriminator}`, - icon_url: discordUser?.displayAvatarURL(), - }, - color: successColor, - fields: [ - { - name: `:dollar: Credits`, - value: `${userObj?.credits || "Not found"}`, - inline: true, + if (guild === null) { + return logger?.verbose(`Guild is null`); + } + + // User Information + const userObj = await fetchUser(discordUser, guild); + + // Embed object + const embed = { + author: { + name: `${discordUser?.username}#${discordUser?.discriminator}`, + icon_url: discordUser?.displayAvatarURL(), }, - { - name: `:squeeze_bottle: Level`, - value: `${userObj?.level || "Not found"}`, - inline: true, + color: successColor, + fields: [ + { + name: `:dollar: Credits`, + value: `${userObj?.credits || "Not found"}`, + inline: true, + }, + { + name: `:squeeze_bottle: Level`, + value: `${userObj?.level || "Not found"}`, + inline: true, + }, + { + name: `:squeeze_bottle: Points`, + value: `${userObj?.points || "Not found"}`, + inline: true, + }, + { + name: `:loudspeaker: Reputation`, + value: `${userObj?.reputation || "Not found"}`, + inline: true, + }, + { + name: `:rainbow_flag: Language`, + value: `${userObj?.language || "Not found"}`, + inline: true, + }, + ], + timestamp: new Date(), + footer: { + iconURL: footerIcon, + text: footerText, }, - { - name: `:squeeze_bottle: Points`, - value: `${userObj?.points || "Not found"}`, - inline: true, - }, - { - name: `:loudspeaker: Reputation`, - value: `${userObj?.reputation || "Not found"}`, - inline: true, - }, - { - name: `:rainbow_flag: Language`, - value: `${userObj?.language || "Not found"}`, - inline: true, - }, - ], - timestamp: new Date(), - footer: { - iconURL: footerIcon, - text: footerText, - }, - }; + }; - // Return interaction reply - return interaction?.editReply({ embeds: [embed] }); + // Return interaction reply + return interaction?.editReply({ embeds: [embed] }); + }, }; diff --git a/src/plugins/reputation/index.ts b/src/plugins/reputation/index.ts index 4908641..7fd5218 100644 --- a/src/plugins/reputation/index.ts +++ b/src/plugins/reputation/index.ts @@ -3,25 +3,25 @@ import { SlashCommandBuilder } from "@discordjs/builders"; import { CommandInteraction } from "discord.js"; // Modules -import give from "./modules/give"; +import modules from "./modules"; // Handlers import logger from "@logger"; // Function export default { - metadata: { author: "Zyner" }, + modules, data: new SlashCommandBuilder() .setName("reputation") .setDescription("Manage reputation.") - .addSubcommand(give.data), + .addSubcommand(modules.give.data), async execute(interaction: CommandInteraction) { const { options } = interaction; if (options?.getSubcommand() === "give") { logger?.verbose(`Executing give subcommand`); - await give.execute(interaction); + await modules.give.execute(interaction); } logger?.verbose(`No subcommand found`); diff --git a/src/plugins/reputation/modules/give.ts b/src/plugins/reputation/modules/give.ts index 13f2162..c3cdf3c 100644 --- a/src/plugins/reputation/modules/give.ts +++ b/src/plugins/reputation/modules/give.ts @@ -21,6 +21,8 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function export default { + meta: { guildOnly: true, ephemeral: true }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("give") diff --git a/src/plugins/reputation/modules/index.ts b/src/plugins/reputation/modules/index.ts new file mode 100644 index 0000000..f6746fd --- /dev/null +++ b/src/plugins/reputation/modules/index.ts @@ -0,0 +1,3 @@ +import give from "@plugins/reputation/modules/give"; + +export default { give }; diff --git a/src/plugins/settings/groups/guild/index.ts b/src/plugins/settings/groups/guild/index.ts new file mode 100644 index 0000000..cfd2fe6 --- /dev/null +++ b/src/plugins/settings/groups/guild/index.ts @@ -0,0 +1,63 @@ +// Dependencies +import { Permissions, CommandInteraction } from "discord.js"; + +// Configurations +import { errorColor, footerText, footerIcon } from "@config/embed"; + +// Handlers +import logger from "@logger"; + +// Modules +import modules from "./modules"; + +import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders"; + +// Function +export default { + modules, + + data: (group: SlashCommandSubcommandGroupBuilder) => { + return group + .setName("guild") + .setDescription("Guild settings.") + .addSubcommand(modules.pterodactyl.data) + .addSubcommand(modules.credits.data) + .addSubcommand(modules.points.data) + .addSubcommand(modules.welcome.data) + .addSubcommand(modules.audits.data) + .addSubcommand(modules.shop.data); + }, + execute: async (interaction: CommandInteraction) => { + // Destructure member + const { options } = interaction; + + switch (options?.getSubcommand()) { + case "pterodactyl": + logger?.verbose(`Subcommand is pterodactyl`); + + return modules.pterodactyl.execute(interaction); + case "credits": + logger?.verbose(`Subcommand is credits`); + + return modules.credits.execute(interaction); + case "points": + logger?.verbose(`Subcommand is points`); + + return modules.points.execute(interaction); + case "welcome": + logger?.verbose(`Subcommand is welcome`); + + return modules.welcome.execute(interaction); + case "audits": + logger?.verbose(`Subcommand is audits`); + + return modules.audits.execute(interaction); + case "shop": + logger?.verbose(`Subcommand is shop`); + + return modules.shop.execute(interaction); + default: + logger?.verbose(`Subcommand is not found`); + } + }, +}; diff --git a/src/plugins/settings/guild/modules/audits.ts b/src/plugins/settings/groups/guild/modules/audits.ts similarity index 93% rename from src/plugins/settings/guild/modules/audits.ts rename to src/plugins/settings/groups/guild/modules/audits.ts index d9d789c..c54b4c2 100644 --- a/src/plugins/settings/guild/modules/audits.ts +++ b/src/plugins/settings/groups/guild/modules/audits.ts @@ -1,5 +1,5 @@ // Dependencies -import { CommandInteraction } from "discord.js"; +import { CommandInteraction, Permissions } from "discord.js"; // Configurations import { successColor, footerText, footerIcon } from "@config/embed"; @@ -14,6 +14,12 @@ import { ChannelType } from "discord-api-types/v10"; // Function export default { + meta: { + guildOnly: true, + ephemeral: true, + permissions: [Permissions.FLAGS.MANAGE_GUILD], + }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("audits") diff --git a/src/plugins/settings/guild/modules/credits.ts b/src/plugins/settings/groups/guild/modules/credits.ts similarity index 95% rename from src/plugins/settings/guild/modules/credits.ts rename to src/plugins/settings/groups/guild/modules/credits.ts index f7bd893..11589ab 100644 --- a/src/plugins/settings/guild/modules/credits.ts +++ b/src/plugins/settings/groups/guild/modules/credits.ts @@ -1,5 +1,5 @@ // Dependencies -import { CommandInteraction } from "discord.js"; +import { CommandInteraction, Permissions } from "discord.js"; // Configurations import { successColor, footerText, footerIcon } from "@config/embed"; @@ -13,6 +13,12 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function export default { + meta: { + guildOnly: true, + ephemeral: true, + permissions: [Permissions.FLAGS.MANAGE_GUILD], + }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("credits") diff --git a/src/plugins/settings/groups/guild/modules/index.ts b/src/plugins/settings/groups/guild/modules/index.ts new file mode 100644 index 0000000..9a5fcd6 --- /dev/null +++ b/src/plugins/settings/groups/guild/modules/index.ts @@ -0,0 +1,8 @@ +import audits from "@plugins/settings/groups/guild/modules/audits"; +import credits from "@plugins/settings/groups/guild/modules/credits"; +import points from "@plugins/settings/groups/guild/modules/points"; +import pterodactyl from "@plugins/settings/groups/guild/modules/pterodactyl"; +import shop from "@plugins/settings/groups/guild/modules/shop"; +import welcome from "@plugins/settings/groups/guild/modules/welcome"; + +export default { audits, credits, points, pterodactyl, shop, welcome }; diff --git a/src/plugins/settings/guild/modules/points.ts b/src/plugins/settings/groups/guild/modules/points.ts similarity index 94% rename from src/plugins/settings/guild/modules/points.ts rename to src/plugins/settings/groups/guild/modules/points.ts index f484f22..75ea6a7 100644 --- a/src/plugins/settings/guild/modules/points.ts +++ b/src/plugins/settings/groups/guild/modules/points.ts @@ -1,5 +1,5 @@ // Dependencies -import { CommandInteraction } from "discord.js"; +import { CommandInteraction, Permissions } from "discord.js"; // Configurations import { successColor, footerText, footerIcon } from "@config/embed"; @@ -13,6 +13,12 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function export default { + meta: { + guildOnly: true, + ephemeral: true, + permissions: [Permissions.FLAGS.MANAGE_GUILD], + }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("points") diff --git a/src/plugins/settings/guild/modules/pterodactyl.ts b/src/plugins/settings/groups/guild/modules/pterodactyl.ts similarity index 91% rename from src/plugins/settings/guild/modules/pterodactyl.ts rename to src/plugins/settings/groups/guild/modules/pterodactyl.ts index 14b0bf4..b595b80 100644 --- a/src/plugins/settings/guild/modules/pterodactyl.ts +++ b/src/plugins/settings/groups/guild/modules/pterodactyl.ts @@ -1,5 +1,5 @@ // Dependencies -import { CommandInteraction } from "discord.js"; +import { CommandInteraction, Permissions } from "discord.js"; // Configurations import { successColor, footerText, footerIcon } from "@config/embed"; @@ -14,6 +14,12 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function export default { + meta: { + guildOnly: true, + ephemeral: true, + permissions: [Permissions.FLAGS.MANAGE_GUILD], + }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("pterodactyl") diff --git a/src/plugins/settings/guild/modules/shop.ts b/src/plugins/settings/groups/guild/modules/shop.ts similarity index 93% rename from src/plugins/settings/guild/modules/shop.ts rename to src/plugins/settings/groups/guild/modules/shop.ts index 2b20d87..785c161 100644 --- a/src/plugins/settings/guild/modules/shop.ts +++ b/src/plugins/settings/groups/guild/modules/shop.ts @@ -1,5 +1,5 @@ // Dependencies -import { CommandInteraction } from "discord.js"; +import { CommandInteraction, Permissions } from "discord.js"; // Configurations import { successColor, footerText, footerIcon } from "@config/embed"; @@ -13,6 +13,12 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function export default { + meta: { + guildOnly: true, + ephemeral: true, + permissions: [Permissions.FLAGS.MANAGE_GUILD], + }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("shop") diff --git a/src/plugins/settings/guild/modules/welcome.ts b/src/plugins/settings/groups/guild/modules/welcome.ts similarity index 95% rename from src/plugins/settings/guild/modules/welcome.ts rename to src/plugins/settings/groups/guild/modules/welcome.ts index c8c8325..ad0c05b 100644 --- a/src/plugins/settings/guild/modules/welcome.ts +++ b/src/plugins/settings/groups/guild/modules/welcome.ts @@ -1,5 +1,5 @@ // Dependencies -import { CommandInteraction } from "discord.js"; +import { CommandInteraction, Permissions } from "discord.js"; // Configurations import { successColor, footerText, footerIcon } from "@config/embed"; @@ -14,6 +14,12 @@ import { ChannelType } from "discord-api-types/v10"; // Function export default { + meta: { + guildOnly: true, + ephemeral: true, + permissions: [Permissions.FLAGS.MANAGE_GUILD], + }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("welcome") diff --git a/src/plugins/settings/groups/index.ts b/src/plugins/settings/groups/index.ts new file mode 100644 index 0000000..3271a99 --- /dev/null +++ b/src/plugins/settings/groups/index.ts @@ -0,0 +1,3 @@ +import guild from "@plugins/settings/groups/guild"; + +export default { guild }; diff --git a/src/plugins/settings/guild/index.ts b/src/plugins/settings/guild/index.ts deleted file mode 100644 index 37218bd..0000000 --- a/src/plugins/settings/guild/index.ts +++ /dev/null @@ -1,94 +0,0 @@ -// Dependencies -import { Permissions, CommandInteraction } from "discord.js"; - -// Configurations -import { errorColor, footerText, footerIcon } from "@config/embed"; - -// Handlers -import logger from "@logger"; - -// Modules -import pterodactyl from "./modules/pterodactyl"; -import credits from "./modules/credits"; -import points from "./modules/points"; -import welcome from "./modules/welcome"; -import audits from "./modules/audits"; -import shop from "./modules/shop"; -import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders"; - -// Function -export default { - data: (group: SlashCommandSubcommandGroupBuilder) => { - return group - .setName("guild") - .setDescription("Guild settings.") - .addSubcommand(pterodactyl.data) - .addSubcommand(credits.data) - .addSubcommand(points.data) - .addSubcommand(welcome.data) - .addSubcommand(audits.data) - .addSubcommand(shop.data); - }, - execute: async (interaction: CommandInteraction) => { - // Destructure member - const { memberPermissions, options } = interaction; - - // Check permission - if (!memberPermissions?.has(Permissions?.FLAGS?.MANAGE_GUILD)) { - logger?.verbose(`User does not have permission to execute command.`); - - return interaction?.editReply({ - embeds: [ - { - title: ":tools: Settings - Guild", - color: errorColor, - description: "You do not have permission to use this command.", - timestamp: new Date(), - footer: { - iconURL: footerIcon as string, - text: footerText as string, - }, - }, - ], - }); - } - - if (options?.getSubcommand() === "pterodactyl") { - logger?.verbose(`Executing pterodactyl subcommand`); - - return pterodactyl.execute(interaction); - } - - if (options?.getSubcommand() === "credits") { - logger?.verbose(`Executing credits subcommand`); - - return credits.execute(interaction); - } - - if (options?.getSubcommand() === "points") { - logger?.verbose(`Executing points subcommand`); - - return points.execute(interaction); - } - - if (options?.getSubcommand() === "welcome") { - logger?.verbose(`Executing welcome subcommand`); - - return welcome.execute(interaction); - } - - if (options?.getSubcommand() === "audits") { - logger?.verbose(`Executing audit subcommand`); - - return audits.execute(interaction); - } - - if (options?.getSubcommand() === "shop") { - logger?.verbose(`Executing shop subcommand`); - - return shop.execute(interaction); - } - - logger?.verbose(`No subcommand found`); - }, -}; diff --git a/src/plugins/settings/index.ts b/src/plugins/settings/index.ts index a490fd2..c657e43 100644 --- a/src/plugins/settings/index.ts +++ b/src/plugins/settings/index.ts @@ -3,19 +3,20 @@ import { SlashCommandBuilder } from "@discordjs/builders"; import { CommandInteraction } from "discord.js"; // Groups -import guildGroup from "./guild"; +import groups from "./groups"; // Handlers import logger from "@logger"; // Function export default { - metadata: { author: "Zyner" }, + groups, + data: new SlashCommandBuilder() .setName("settings") .setDescription("Manage settings.") - .addSubcommandGroup(guildGroup.data), + .addSubcommandGroup(groups.guild.data), async execute(interaction: CommandInteraction) { const { options } = interaction; @@ -23,7 +24,7 @@ export default { if (options.getSubcommandGroup() === "guild") { logger.verbose(`Executing guild subcommand`); - return guildGroup.execute(interaction); + return groups.guild.execute(interaction); } logger.verbose(`No subcommand group found`); diff --git a/src/plugins/shop/groups/index.ts b/src/plugins/shop/groups/index.ts new file mode 100644 index 0000000..c1c25c9 --- /dev/null +++ b/src/plugins/shop/groups/index.ts @@ -0,0 +1,3 @@ +import roles from "./roles"; + +export default { roles }; diff --git a/src/plugins/shop/roles/index.ts b/src/plugins/shop/groups/roles/index.ts similarity index 84% rename from src/plugins/shop/roles/index.ts rename to src/plugins/shop/groups/roles/index.ts index 96ae1ca..26135e6 100644 --- a/src/plugins/shop/roles/index.ts +++ b/src/plugins/shop/groups/roles/index.ts @@ -3,24 +3,25 @@ import { SlashCommandSubcommandGroupBuilder } from "@discordjs/builders"; import { CommandInteraction } from "discord.js"; // Handlers -import logger from "../../../logger"; +import logger from "@logger"; import { errorColor, footerText, footerIcon } from "@config/embed"; // Modules -import buy from "./modules/buy"; -import cancel from "./modules/cancel"; +import modules from "./modules"; import guildSchema from "@schemas/guild"; // Function export default { + modules, + data: (group: SlashCommandSubcommandGroupBuilder) => { return group .setName("roles") .setDescription("Shop for custom roles.") - .addSubcommand(buy.data) - .addSubcommand(cancel.data); + .addSubcommand(modules.buy.data) + .addSubcommand(modules.cancel.data); }, execute: async (interaction: CommandInteraction) => { const { options, guild } = interaction; @@ -53,13 +54,13 @@ export default { if (options?.getSubcommand() === "buy") { logger.verbose(`Executing buy subcommand`); - await buy.execute(interaction); + await modules.buy.execute(interaction); } if (options?.getSubcommand() === "cancel") { logger.verbose(`Executing cancel subcommand`); - await cancel.execute(interaction); + await modules.cancel.execute(interaction); } }, }; diff --git a/src/plugins/shop/roles/modules/buy.ts b/src/plugins/shop/groups/roles/modules/buy.ts similarity index 98% rename from src/plugins/shop/roles/modules/buy.ts rename to src/plugins/shop/groups/roles/modules/buy.ts index 4fa2980..1f8c54b 100644 --- a/src/plugins/shop/roles/modules/buy.ts +++ b/src/plugins/shop/groups/roles/modules/buy.ts @@ -25,6 +25,8 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function export default { + meta: { guildOnly: true, ephemeral: true }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("buy") diff --git a/src/plugins/shop/roles/modules/cancel.ts b/src/plugins/shop/groups/roles/modules/cancel.ts similarity index 98% rename from src/plugins/shop/roles/modules/cancel.ts rename to src/plugins/shop/groups/roles/modules/cancel.ts index 380ac42..b35ef16 100644 --- a/src/plugins/shop/roles/modules/cancel.ts +++ b/src/plugins/shop/groups/roles/modules/cancel.ts @@ -20,6 +20,8 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function export default { + meta: { guildOnly: true, ephemeral: true }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("cancel") diff --git a/src/plugins/shop/groups/roles/modules/index.ts b/src/plugins/shop/groups/roles/modules/index.ts new file mode 100644 index 0000000..b9e1626 --- /dev/null +++ b/src/plugins/shop/groups/roles/modules/index.ts @@ -0,0 +1,7 @@ +import buy from "./buy"; +import cancel from "./cancel"; + +export default { + buy, + cancel, +}; diff --git a/src/plugins/shop/index.ts b/src/plugins/shop/index.ts index 7d222a8..f9af6d4 100644 --- a/src/plugins/shop/index.ts +++ b/src/plugins/shop/index.ts @@ -3,35 +3,37 @@ import { SlashCommandBuilder } from "@discordjs/builders"; import { CommandInteraction } from "discord.js"; // Modules -import pterodactyl from "./modules/pterodactyl"; +import modules from "./modules"; // Groups -import roles from "./roles"; +import groups from "./groups"; // Handlers import logger from "../../logger"; // Function export default { - metadata: { author: "Zyner" }, + modules, + groups, + data: new SlashCommandBuilder() .setName("shop") .setDescription("Shop for credits and custom roles.") - .addSubcommand(pterodactyl.data) - .addSubcommandGroup(roles.data), + .addSubcommand(modules.pterodactyl.data) + .addSubcommandGroup(groups.roles.data), async execute(interaction: CommandInteraction) { const { options } = interaction; if (options?.getSubcommand() === "pterodactyl") { logger.verbose(`Executing pterodactyl subcommand`); - return pterodactyl.execute(interaction); + return modules.pterodactyl.execute(interaction); } if (options?.getSubcommandGroup() === "roles") { logger?.verbose(`Subcommand group is roles`); - return roles.execute(interaction); + return groups.roles.execute(interaction); } logger?.verbose(`No subcommand found.`); diff --git a/src/plugins/shop/modules/index.ts b/src/plugins/shop/modules/index.ts new file mode 100644 index 0000000..bc33df3 --- /dev/null +++ b/src/plugins/shop/modules/index.ts @@ -0,0 +1,3 @@ +import pterodactyl from "@plugins/shop/modules/pterodactyl"; + +export default { pterodactyl }; diff --git a/src/plugins/shop/modules/pterodactyl.ts b/src/plugins/shop/modules/pterodactyl.ts index 01cd120..9ada9fb 100644 --- a/src/plugins/shop/modules/pterodactyl.ts +++ b/src/plugins/shop/modules/pterodactyl.ts @@ -25,6 +25,8 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function export default { + meta: { guildOnly: true, ephemeral: true }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("pterodactyl") diff --git a/src/plugins/utility/index.ts b/src/plugins/utility/index.ts index ccb2128..69e6268 100644 --- a/src/plugins/utility/index.ts +++ b/src/plugins/utility/index.ts @@ -10,7 +10,8 @@ import logger from "../../logger"; // Function export default { - metadata: { author: "Zyner" }, + modules, + data: new SlashCommandBuilder() .setName("utility") .setDescription("Common utility.") diff --git a/src/plugins/utility/modules/about.ts b/src/plugins/utility/modules/about.ts index f618149..cfeb44e 100644 --- a/src/plugins/utility/modules/about.ts +++ b/src/plugins/utility/modules/about.ts @@ -9,6 +9,8 @@ import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; // Function export default { + meta: { guildOnly: false, ephemeral: false }, + data: (command: SlashCommandSubcommandBuilder) => { return command.setName("about").setDescription("About this bot!)"); }, diff --git a/src/plugins/utility/modules/avatar.ts b/src/plugins/utility/modules/avatar.ts index 81112ff..9f57fb3 100644 --- a/src/plugins/utility/modules/avatar.ts +++ b/src/plugins/utility/modules/avatar.ts @@ -5,6 +5,8 @@ import { CommandInteraction, MessageEmbed } from "discord.js"; import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; export default { + meta: { guildOnly: false, ephemeral: false }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("avatar") diff --git a/src/plugins/utility/modules/lookup.ts b/src/plugins/utility/modules/lookup.ts index 6175418..73eb0bc 100644 --- a/src/plugins/utility/modules/lookup.ts +++ b/src/plugins/utility/modules/lookup.ts @@ -17,6 +17,8 @@ import logger from "@logger"; // Function export default { + meta: { guildOnly: false, ephemeral: false }, + data: (command: SlashCommandSubcommandBuilder) => { return command .setName("lookup") diff --git a/src/plugins/utility/modules/stats.ts b/src/plugins/utility/modules/stats.ts index 277f670..3b02684 100644 --- a/src/plugins/utility/modules/stats.ts +++ b/src/plugins/utility/modules/stats.ts @@ -2,6 +2,8 @@ import { successColor, footerText, footerIcon } from "@config/embed"; import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; import { CommandInteraction } from "discord.js"; export default { + meta: { guildOnly: false, ephemeral: false }, + data: (command: SlashCommandSubcommandBuilder) => { return command.setName("stats").setDescription("Check bot statistics!)"); },