From fd3afa70e56c69e5979e790e88f7796ac98f67a2 Mon Sep 17 00:00:00 2001 From: stolarchukboris Date: Mon, 5 May 2025 00:31:38 +0300 Subject: [PATCH 1/6] `/points leaderboard` command --- src/commands/command/points.js | 62 ++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/src/commands/command/points.js b/src/commands/command/points.js index a83255d..127cb34 100644 --- a/src/commands/command/points.js +++ b/src/commands/command/points.js @@ -39,6 +39,10 @@ export const data = new SlashCommandBuilder() .setDescription('The reason behind this action.') ) ) + .addSubcommand(sc => sc + .setName('leaderboard') + .setDescription('Show points leaderboard.') + ) export async function execute(interaction) { await interaction.deferReply(); @@ -57,7 +61,7 @@ export async function execute(interaction) { if (subcommand === 'fetch') { const user = interaction.options.getUser('user') ?? interaction.user; - + if (user !== interaction.user && !interaction.member.roles.cache.hasAny(...allowedIds)) return await interaction.editReply({ embeds: [ new EmbedBuilder() @@ -71,7 +75,7 @@ export async function execute(interaction) { }) ] }); - + const result = await client.knex('points') .select('*') .where('discord_id', user.id) @@ -82,7 +86,7 @@ export async function execute(interaction) { new EmbedBuilder() .setColor(Colors.Blurple) .setTitle('Point stats.') - .setDescription(`${user} has ${result?.amount ?? 0} points.`) + .setDescription(`${user} has ${result?.amount ?? 0} point(s).`) .setThumbnail(user.avatarURL()) .setTimestamp() .setFooter({ @@ -91,21 +95,24 @@ export async function execute(interaction) { }) ] }); - } else if (subcommand === 'alter') { - if (!interaction.member.roles.cache.hasAny(...allowedIds)) return await interaction.editReply({ - embeds: [ - new EmbedBuilder() - .setTitle('Access denied.') - .setDescription('You do not have the required permissions to use this command.') - .setColor(Colors.Red) - .setTimestamp() - .setFooter({ - text: interaction.guild.name, - iconURL: interaction.guild.iconURL() - }) - ] - }); + } + + if (!interaction.member.roles.cache.hasAny(...allowedIds)) return await interaction.editReply({ + embeds: [ + new EmbedBuilder() + .setTitle('Access denied.') + .setDescription('You do not have the required permissions to use this command.') + .setColor(Colors.Red) + .setTimestamp() + .setFooter({ + text: interaction.guild.name, + iconURL: interaction.guild.iconURL() + }) + ] + }); + + if (subcommand === 'alter') { const user = interaction.options.getUser('user', true); const action = interaction.options.getString('action', true); const amount = interaction.options.getInteger('amount', true); @@ -199,5 +206,26 @@ export async function execute(interaction) { }) ] }); + } else if (subcommand === 'leaderboard') { + const points = await client.knex('points') + .select('*') + .orderBy('amount', 'desc'); + let desc; + + for (let i = 0; i < points.length; i++) desc = desc.concat(`${i}. <@${points[i].discord_id}>: ${points[i].amount} point(s).\n`); + + return await interaction.editReply({ + embeds: [ + new EmbedBuilder() + .setColor(Colors.Blurple) + .setTitle('Points leaderboard.') + .setDescription(`Here is the points leaderboard for Chaos Forces Alliance.\n\n${desc}`) + .setTimestamp() + .setFooter({ + text: interaction.guild.name, + iconURL: interaction.guild.iconURL() + }) + ] + }); } } From 85194436a38d2e490e11b7bcb24bc56d0f7b8b02 Mon Sep 17 00:00:00 2001 From: stolarchukboris Date: Mon, 5 May 2025 18:46:11 +0300 Subject: [PATCH 2/6] `/points wipe` command, permission prefixes in (sub)command descriptions for clarity --- src/commands/command/blacklist.js | 4 +- src/commands/command/dm.js | 2 +- src/commands/command/points.js | 126 +++++++++++++++++++++++++++++- src/commands/command/raid.js | 20 ++--- src/commands/command/st.js | 18 ++--- src/commands/command/strikes.js | 4 +- src/commands/command/training.js | 12 +-- src/commands/command/warnings.js | 4 +- 8 files changed, 155 insertions(+), 35 deletions(-) diff --git a/src/commands/command/blacklist.js b/src/commands/command/blacklist.js index 24d05d1..c2f6cdf 100644 --- a/src/commands/command/blacklist.js +++ b/src/commands/command/blacklist.js @@ -5,7 +5,7 @@ export const data = new SlashCommandBuilder() .setDescription('Manage CFA application blacklists.') .addSubcommand(subCommand => subCommand .setName('issue') - .setDescription('Blacklist a person from applying.') + .setDescription('[COM+] Blacklist a person from applying.') .addUserOption(option => option .setName('user') .setDescription('The user to be blacklisted.') @@ -24,7 +24,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(subCommand => subCommand .setName('remove') - .setDescription('Unblacklist a person from applying.') + .setDescription('[COM+] Unblacklist a person from applying.') .addUserOption(option => option .setName('user') .setDescription('The user to be unblacklisted.') diff --git a/src/commands/command/dm.js b/src/commands/command/dm.js index a623f03..2af0d98 100644 --- a/src/commands/command/dm.js +++ b/src/commands/command/dm.js @@ -2,7 +2,7 @@ import { SlashCommandBuilder, EmbedBuilder, Colors } from 'discord.js'; export const data = new SlashCommandBuilder() .setName('dm') - .setDescription('Send a direct message to a user.') + .setDescription('[COM+] Send a direct message to a user.') .addUserOption(option => option .setName('member') .setDescription('The server member to DM.') diff --git a/src/commands/command/points.js b/src/commands/command/points.js index 127cb34..2f61399 100644 --- a/src/commands/command/points.js +++ b/src/commands/command/points.js @@ -1,4 +1,4 @@ -import { SlashCommandBuilder, EmbedBuilder, Colors } from 'discord.js'; +import { SlashCommandBuilder, EmbedBuilder, Colors, ActionRowBuilder, ButtonBuilder, ButtonStyle } from 'discord.js'; export const data = new SlashCommandBuilder() .setName('points') @@ -13,7 +13,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(sc => sc .setName('alter') - .setDescription(`Alter user's point balance.`) + .setDescription(`[COM+] Alter user's point balance.`) .addUserOption(option => option .setName('user') .setDescription('The user whose point balance should be altered.') @@ -41,7 +41,11 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(sc => sc .setName('leaderboard') - .setDescription('Show points leaderboard.') + .setDescription('[COM+] Show points leaderboard.') + ) + .addSubcommand(sc => sc + .setName('wipe') + .setDescription('[HICOM+] Wipe EVERYONE\'s points.') ) export async function execute(interaction) { @@ -227,5 +231,121 @@ export async function execute(interaction) { }) ] }); + } else if (subcommand === 'wipe') { + if (!interaction.member.roles.cache.hasAny(...['1255634139730935860'])) return await interaction.editReply({ + embeds: [ + new EmbedBuilder() + .setTitle('Access denied.') + .setDescription('You do not have the required permissions to use this command.') + .setColor(Colors.Red) + .setTimestamp() + .setFooter({ + text: interaction.guild.name, + iconURL: interaction.guild.iconURL() + }) + ] + }); + + const existingPoints = await client.knex('points').select('*'); + if (existingPoints.length === 0) return await interaction.editReply({ embeds: [errorEmbed.setDescription('No one currently has points.')] }); + + const row = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId('cancel') + .setLabel('Abort wipe') + .setStyle(ButtonStyle.Danger) + .setEmoji({ name: '❌' }), + new ButtonBuilder() + .setCustomId('confirm') + .setLabel('Confirm wipe') + .setStyle(ButtonStyle.Success) + .setEmoji({ name: '✅' }) + ); + + const response = await interaction.editReply({ + embeds: [ + new EmbedBuilder() + .setTitle('Are you sure?') + .setDescription(`Are you sure you want to wipe **EVERYONE'S** points? **This action cannot be undone.**\nIf you would like to only reset a few people's points, please use the \`/points alter\` command instead.`) + .setColor(Colors.Orange) + .setTimestamp() + .setFooter({ + text: interaction.guild.name, + iconURL: interaction.guild.iconURL() + }) + ], + components: [row] + }); + + try { + const confirmation = await response.awaitMessageComponent({ filter: i => i.user.id === interaction.user.id, time: 15_000 }) + + if (confirmation.customId === 'confirm') { + await confirmation.update({ + embeds: [ + new EmbedBuilder() + .setTitle('Wiping...') + .setDescription(`Points wipe in progress. Please wait...`) + .setColor(Colors.Yellow) + .setTimestamp() + .setFooter({ + text: interaction.guild.name, + iconURL: interaction.guild.iconURL() + }) + + ], + components: [] + }); + } else if (confirmation.customId === 'cancel') { + await confirmation.update({ + embeds: [ + new EmbedBuilder() + .setTitle('Wipe cancelled.') + .setDescription(`Points have not been wiped.`) + .setColor(Colors.DarkRed) + .setTimestamp() + .setFooter({ + text: interaction.guild.name, + iconURL: interaction.guild.iconURL() + }) + + ], + components: [] + }); + return; + } + } catch (e) { + return await interaction.editReply({ + embeds: [ + new EmbedBuilder() + .setTitle('Confirmation prompt timed out.') + .setDescription(`No interaction received within 15 seconds, aborting...`) + .setColor(Colors.DarkRed) + .setTimestamp() + .setFooter({ + text: interaction.guild.name, + iconURL: interaction.guild.iconURL() + }) + ], + components: [] + }); + } + + await client.knex('points').del(); + + return await interaction.editReply({ + embeds: [ + new EmbedBuilder() + .setColor(Colors.Green) + .setTitle('Success.') + .setDescription('Successfully wiped everyone\'s points.') + .setTimestamp() + .setFooter({ + text: interaction.guild.name, + iconURL: interaction.guild.iconURL() + }) + ] + }); } } diff --git a/src/commands/command/raid.js b/src/commands/command/raid.js index e55bf38..371ab9e 100644 --- a/src/commands/command/raid.js +++ b/src/commands/command/raid.js @@ -7,7 +7,7 @@ export const data = new SlashCommandBuilder() .setDescription('Allows you to interact with a Chaos Forces raid on CPUF') .addSubcommand(subCommand => subCommand .setName('schedule') - .setDescription('Schedule a raid on CPUF') + .setDescription('[RH] Schedule a raid on CPUF') .addIntegerOption(option => option .setName('time') .setDescription('The time at which the raid will take place (UNIX)') @@ -16,7 +16,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(subCommand => subCommand .setName('start') - .setDescription('Start a raid.') + .setDescription('[RH] Start a raid.') .addStringOption(option => option .setName('id') .setDescription('The ID of the raid you want to start') @@ -29,7 +29,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(subCommand => subCommand .setName('end') - .setDescription('End a raid.') + .setDescription('[RH] End a raid.') .addStringOption(option => option .setName('id') .setDescription('The ID of the raid that you want to end') @@ -50,7 +50,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(subCommand => subCommand .setName('cancel') - .setDescription('Cancel a raid.') + .setDescription('[RH] Cancel a raid.') .addStringOption(option => option .setName('id') .setDescription('The ID of the raid that you want to cancel') @@ -64,7 +64,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(subCommand => subCommand .setName('update') - .setDescription('Update the raid information.') + .setDescription('[RH] Update the raid information.') .addStringOption(option => option .setName('id') .setDescription('The ID of the raid you want to change') @@ -78,7 +78,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(subCommand => subCommand .setName('log_add') - .setDescription('Create a raid log for a person.') + .setDescription('[RH] Create a raid log for a person.') .addStringOption(option => option .setName('raid_id') .setDescription('The ID of the raid you want to log.') @@ -96,7 +96,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(subCommand => subCommand .setName('log_remove') - .setDescription('Delete a person\'s raid log.') + .setDescription('[RH] Delete a person\'s raid log.') .addStringOption(option => option .setName('log_id') .setDescription('The ID of the log you want to delete.') @@ -105,7 +105,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(subCommand => subCommand .setName('log_edit') - .setDescription('Edit a person\'s raid log. WARNING: this overwrites the log entirely.') + .setDescription('[RH] Edit a person\'s raid log. WARNING: this overwrites the log entirely.') .addStringOption(option => option .setName('log_id') .setDescription('The ID of the log you want to edit. WARNING: this overwrites the log entirely.') @@ -119,7 +119,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(subCommand => subCommand .setName('log_view') - .setDescription('View the raid log(s). Please use at least one search option.') + .setDescription('[RH] View the raid log(s). Please use at least one search option.') .addStringOption(option => option .setName('log_id') .setDescription('View the log by its ID.') @@ -138,7 +138,7 @@ export async function execute(interaction) { await interaction.deferReply({ flags: MessageFlags.Ephemeral }); const client = await interaction.client; - const allowedIDs = ["1268226274401193984", "1157806062070681600", "846692755496763413", "1066470548399468644", "1248632771900084286"]; // raid hosting perms, something else, lead insurgent, strike team + const allowedIDs = ["1157806062070681600"]; // raid hosting perms if (!interaction.member.roles.cache.hasAny(...allowedIDs)) return await interaction.editReply({ embeds: [ diff --git a/src/commands/command/st.js b/src/commands/command/st.js index aa03967..5e5aeb1 100644 --- a/src/commands/command/st.js +++ b/src/commands/command/st.js @@ -8,7 +8,7 @@ export const data = new SlashCommandBuilder() .setDescription('Manage Strike Team tryouts.') .addSubcommand(sc => sc .setName('schedule') - .setDescription('Schedule a Strike Team tryout.') + .setDescription('[STL] Schedule a Strike Team tryout.') .addIntegerOption(option => option .setName('time') .setDescription('The time at which the tryout is going to be hosted (UNIX).') @@ -16,13 +16,13 @@ export const data = new SlashCommandBuilder() ) .addRoleOption(option => option .setName('ping_role') - .setDescription('The role to ping for this announcement') + .setDescription('The role to ping for this announcement.') .setRequired(true) ) ) .addSubcommand(sc => sc .setName('start') - .setDescription('Start a Strike Team tryout.') + .setDescription('[STL] Start a Strike Team tryout.') .addStringOption(option => option .setName('tryout_id') .setDescription('ID of a tryout to be started.') @@ -30,7 +30,7 @@ export const data = new SlashCommandBuilder() ) .addRoleOption(option => option .setName('ping_role') - .setDescription('The role to ping for this announcement') + .setDescription('The role to ping for this announcement.') .setRequired(true) ) .addStringOption(option => option @@ -40,7 +40,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(sc => sc .setName('lock') - .setDescription('Lock a Strike Team tryout.') + .setDescription('[STL] Lock a Strike Team tryout.') .addStringOption(option => option .setName('tryout_id') .setDescription('ID of a tryout to be locked.') @@ -49,7 +49,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(sc => sc .setName('conclude') - .setDescription('Conclude a Strike Team tryout.') + .setDescription('[STL] Conclude a Strike Team tryout.') .addStringOption(option => option .setName('tryout_id') .setDescription('ID of a tryout to be concluded.') @@ -58,7 +58,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(sc => sc .setName('cancel') - .setDescription('Cancel a Strike Team tryout.') + .setDescription('[STL] Cancel a Strike Team tryout.') .addStringOption(option => option .setName('tryout_id') .setDescription('ID of a tryout to be cancelled.') @@ -71,13 +71,13 @@ export const data = new SlashCommandBuilder() ) .addRoleOption(option => option .setName('ping_role') - .setDescription('The role to ping for this announcement') + .setDescription('The role to ping for this announcement.') .setRequired(true) ) ) .addSubcommand(sc => sc .setName('update') - .setDescription('Update a Strike Team tryout.') + .setDescription('[STL] Update a Strike Team tryout.') .addStringOption(option => option .setName('tryout_id') .setDescription('ID of a tryout to be updated.') diff --git a/src/commands/command/strikes.js b/src/commands/command/strikes.js index 8cca466..ec9e511 100644 --- a/src/commands/command/strikes.js +++ b/src/commands/command/strikes.js @@ -5,7 +5,7 @@ export const data = new SlashCommandBuilder() .setDescription('Allows authorized users to manage CFA operatives\' strikes.') .addSubcommand(subcommand => subcommand .setName('issue') - .setDescription('Issue a strike to a CFA operative.') + .setDescription('[COM+] Issue a strike to a CFA operative.') .addUserOption(option => option .setName('member') .setDescription('The server member you want to strike.') @@ -23,7 +23,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(subcommand => subcommand .setName('remove') - .setDescription('Remove a strike from the CFA operative\'s record.') + .setDescription('[COM+] Remove a strike from the CFA operative\'s record.') .addStringOption(option => option .setName('strike_id') .setDescription('ID of the strike you want to remove.') diff --git a/src/commands/command/training.js b/src/commands/command/training.js index 66251e0..5bbf28c 100644 --- a/src/commands/command/training.js +++ b/src/commands/command/training.js @@ -5,7 +5,7 @@ export const data = new SlashCommandBuilder() .setDescription('Allows authorized users to schedule the CFA training.') .addSubcommand(subcommand => subcommand .setName('schedule') - .setDescription('Schedules a training.') + .setDescription('[TH] Schedule a training.') .addIntegerOption(option => option .setName('time') .setDescription('The time at which the training will take place.') @@ -24,7 +24,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(subcommand => subcommand .setName('start') - .setDescription('Starts a training.') + .setDescription('[TH] Start a training.') .addStringOption(option => option .setName('id') .setDescription('The ID of the training that you want to start.') @@ -38,7 +38,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(subcommand => subcommand .setName('lock') - .setDescription('Informs others of training lock.') + .setDescription('[TH] Inform others of training lock.') .addStringOption(option => option .setName('id') .setDescription('The ID of the training that you want to lock.') @@ -47,7 +47,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(subcommand => subcommand .setName('end') - .setDescription('Ends a training.') + .setDescription('[TH] End a training.') .addStringOption(option => option .setName('id') .setDescription('The ID of the training that you want to end.') @@ -56,7 +56,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(subcommand => subcommand .setName('cancel') - .setDescription('Cancels a training.') + .setDescription('[TH] Cancel a training.') .addStringOption(option => option .setName('id') .setDescription('The ID of the training that you want to cancel.') @@ -70,7 +70,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(subcommand => subcommand .setName('update') - .setDescription('Updates the training time.') + .setDescription('[TH] Update the training time.') .addStringOption(option => option .setName('id') .setDescription('The ID of the training that you want to update.') diff --git a/src/commands/command/warnings.js b/src/commands/command/warnings.js index ff382f6..b858d2b 100644 --- a/src/commands/command/warnings.js +++ b/src/commands/command/warnings.js @@ -5,7 +5,7 @@ export const data = new SlashCommandBuilder() .setDescription('Allows authorized users to manage CFA operatives\' formal warnings.') .addSubcommand(subcommand => subcommand .setName('issue') - .setDescription('Issue a formal warning to a CFA operative.') + .setDescription('[COM+] Issue a formal warning to a CFA operative.') .addUserOption(option => option .setName('member') .setDescription('The server member you want to warn.') @@ -23,7 +23,7 @@ export const data = new SlashCommandBuilder() ) .addSubcommand(subcommand => subcommand .setName('remove') - .setDescription('Remove a formal warning from the CFA operative\'s record.') + .setDescription('[COM+] Remove a formal warning from the CFA operative\'s record.') .addStringOption(option => option .setName('warning_id') .setDescription('ID of the warning you want to remove.') From 4ede472a0a8237122fc26580329feae4bab2b256 Mon Sep 17 00:00:00 2001 From: stolarchukboris Date: Mon, 5 May 2025 18:50:46 +0300 Subject: [PATCH 3/6] bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2d3b1b3..d103a6c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cfa-manager", - "version": "1.6.4", + "version": "1.6.5", "description": "Discord bot that manages the Chaos Forces Alliance.", "main": "src/index.js", "type": "module", From 8750f168b313f4907d014c5e17862630ca909e3c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 22:19:58 +0300 Subject: [PATCH 4/6] Bump discord.js from 14.19.1 to 14.19.3 (#34) Bumps [discord.js](https://github.com/discordjs/discord.js/tree/HEAD/packages/discord.js) from 14.19.1 to 14.19.3. - [Release notes](https://github.com/discordjs/discord.js/releases) - [Changelog](https://github.com/discordjs/discord.js/blob/14.19.3/packages/discord.js/CHANGELOG.md) - [Commits](https://github.com/discordjs/discord.js/commits/14.19.3/packages/discord.js) --- updated-dependencies: - dependency-name: discord.js dependency-version: 14.19.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- pnpm-lock.yaml | 42 +++++++++++++++++++++--------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index d103a6c..21f32ad 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "author": "Asynchronite", "license": "AGPLv3", "dependencies": { - "discord.js": "^14.19.1", + "discord.js": "^14.19.3", "dotenv": "^16.5.0", "knex": "^3.1.0", "moment": "^2.30.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a583034..cc742e7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: discord.js: - specifier: ^14.19.1 - version: 14.19.1 + specifier: ^14.19.3 + version: 14.19.3 dotenv: specifier: ^16.5.0 version: 16.5.0 @@ -35,8 +35,8 @@ importers: packages: - '@discordjs/builders@1.11.1': - resolution: {integrity: sha512-2zDAVuoeAkdv0YQzYKO8vZfaDfB+1KZ60ymBKtD7QDpsh6lzAnQSUBLqeRkhlons6BT9+yRctOh9fPy94w6kDA==} + '@discordjs/builders@1.11.2': + resolution: {integrity: sha512-F1WTABdd8/R9D1icJzajC4IuLyyS8f3rTOz66JsSI3pKvpCAtsMBweu8cyNYsIyvcrKAVn9EPK+Psoymq+XC0A==} engines: {node: '>=16.11.0'} '@discordjs/collection@1.5.3': @@ -302,11 +302,11 @@ packages: resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} engines: {node: '>=0.10'} - discord-api-types@0.38.1: - resolution: {integrity: sha512-vsjsqjAuxsPhiwbPjTBeGQaDPlizFmSkU0mTzFGMgRxqCDIRBR7iTY74HacpzrDV0QtERHRKQEk1tq7drZUtHg==} + discord-api-types@0.38.3: + resolution: {integrity: sha512-vijevLh06Gtmex6BQzc9jRrGce6La0qnsF4bKwKM2L1ou0/sbJIOAkg7wz6YLLaodnUwQLljIhtrGxnkMjc1Ew==} - discord.js@14.19.1: - resolution: {integrity: sha512-r5jsPyaeoCrRGbdse4vQNbHAsoc2zuueyiTFJ2Ce7BiaJak9OldzKZWaWGwKdCFDH3zXlthU1hHXkx1EswKZCA==} + discord.js@14.19.3: + resolution: {integrity: sha512-lncTRk0k+8Q5D3nThnODBR8fR8x2fM798o8Vsr40Krx0DjPwpZCuxxTcFMrXMQVOqM1QB9wqWgaXPg3TbmlHqA==} engines: {node: '>=18'} dotenv@16.5.0: @@ -1098,8 +1098,8 @@ packages: utf-8-validate: optional: true - ws@8.18.1: - resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==} + ws@8.18.2: + resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -1115,12 +1115,12 @@ packages: snapshots: - '@discordjs/builders@1.11.1': + '@discordjs/builders@1.11.2': dependencies: '@discordjs/formatters': 0.6.1 '@discordjs/util': 1.1.1 '@sapphire/shapeshift': 4.0.0 - discord-api-types: 0.38.1 + discord-api-types: 0.38.3 fast-deep-equal: 3.1.3 ts-mixer: 6.0.4 tslib: 2.8.1 @@ -1131,7 +1131,7 @@ snapshots: '@discordjs/formatters@0.6.1': dependencies: - discord-api-types: 0.38.1 + discord-api-types: 0.38.3 '@discordjs/rest@2.5.0': dependencies: @@ -1140,7 +1140,7 @@ snapshots: '@sapphire/async-queue': 1.5.5 '@sapphire/snowflake': 3.5.3 '@vladfrangu/async_event_emitter': 2.4.6 - discord-api-types: 0.38.1 + discord-api-types: 0.38.3 magic-bytes.js: 1.12.1 tslib: 2.8.1 undici: 6.21.1 @@ -1155,9 +1155,9 @@ snapshots: '@sapphire/async-queue': 1.5.5 '@types/ws': 8.18.1 '@vladfrangu/async_event_emitter': 2.4.6 - discord-api-types: 0.38.1 + discord-api-types: 0.38.3 tslib: 2.8.1 - ws: 8.18.1 + ws: 8.18.2 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -1419,18 +1419,18 @@ snapshots: denque@2.1.0: {} - discord-api-types@0.38.1: {} + discord-api-types@0.38.3: {} - discord.js@14.19.1: + discord.js@14.19.3: dependencies: - '@discordjs/builders': 1.11.1 + '@discordjs/builders': 1.11.2 '@discordjs/collection': 1.5.3 '@discordjs/formatters': 0.6.1 '@discordjs/rest': 2.5.0 '@discordjs/util': 1.1.1 '@discordjs/ws': 1.2.2 '@sapphire/snowflake': 3.5.3 - discord-api-types: 0.38.1 + discord-api-types: 0.38.3 fast-deep-equal: 3.1.3 lodash.snakecase: 4.1.1 magic-bytes.js: 1.12.1 @@ -2407,6 +2407,6 @@ snapshots: ws@7.5.10: {} - ws@8.18.1: {} + ws@8.18.2: {} yallist@4.0.0: {} From a76d780674b2c2df92a708a4c1b23525e3e286a9 Mon Sep 17 00:00:00 2001 From: stolarchukboris Date: Wed, 7 May 2025 23:22:16 +0300 Subject: [PATCH 5/6] `/dod requirements` command for quickly checking if dod can possibly be authorized --- src/commands/general/dod.js | 68 +++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/commands/general/dod.js diff --git a/src/commands/general/dod.js b/src/commands/general/dod.js new file mode 100644 index 0000000..b2b7cfc --- /dev/null +++ b/src/commands/general/dod.js @@ -0,0 +1,68 @@ +import { Colors, EmbedBuilder, SlashCommandBuilder } from 'discord.js'; + +export const data = new SlashCommandBuilder() + .setName('dod') + .setDescription('Door of Dread related commands.') + .addSubcommand(sc => sc + .setName('requirements') + .setDescription('Check if the requirements for activating the Door of Dread are met.') + ) + +export async function execute(interaction) { + await interaction.deferReply(); + + const client = interaction.client; + const onDuty1 = await client.knex('hsps.shook').select('*'); + const onDuty2 = await client.knex('hsps.active_shifts').select('*'); + const ranks = ['Senior Guardsman', 'Elite Guardsman', 'Specialist', 'Senior Specialist', 'Officer', 'Junior Instructor', 'Instructor', 'Deputy Director', 'Director of Defense', 'Owner']; + const sgPlus = []; + + for (const log of onDuty1) { + const guard = await client.knex('hsps.guards') + .select('*') + .where('guard_id', log.guard_id) + .first(); + + if (ranks.includes(guard.hsps_rank)) sgPlus.push(`${guard.guard_username} (${guard.hsps_rank})`); + } + + for (const log of onDuty2) { + const guard = await client.knex('hsps.guards') + .select('*') + .where('guard_username', log.guard_username) + .first(); + + if (ranks.includes(guard.hsps_rank)) sgPlus.push(`${guard.guard_username} (${guard.hsps_rank})`); + } + + if (sgPlus.length < 2) return await interaction.editReply({ + embeds: [ + new EmbedBuilder() + .setColor(Colors.Red) + .setTitle('Requirements not met.') + .setDescription('The Door of Dread cannot be authorized right now because there are currently less than 2 Senior Guardsmen+ on-duty.') + .setTimestamp() + .setFooter({ + text: interaction.guild.name, + iconURL: interaction.guild.iconURL() + }) + ] + }); + + return await interaction.editReply({ + embeds: [ + new EmbedBuilder() + .setColor(Colors.Green) + .setTitle('Requirements possibly met.') + .setDescription(`The following HSPS members that suit the Door of Dread requirements are currently on-duty: +- ${sgPlus.join('\n- ')} + +**Please make sure they are in the server with you before asking for authorization.**`) + .setTimestamp() + .setFooter({ + text: interaction.guild.name, + iconURL: interaction.guild.iconURL() + }) + ] + }); +} From c745a2a5a8b1a6f66f2f8b691b9100fbfa329d83 Mon Sep 17 00:00:00 2001 From: stolarchukboris <120730722+stolarchukboris@users.noreply.github.com> Date: Wed, 7 May 2025 23:29:29 +0300 Subject: [PATCH 6/6] add requirement in parentheses --- src/commands/general/dod.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/general/dod.js b/src/commands/general/dod.js index b2b7cfc..14dc547 100644 --- a/src/commands/general/dod.js +++ b/src/commands/general/dod.js @@ -54,7 +54,7 @@ export async function execute(interaction) { new EmbedBuilder() .setColor(Colors.Green) .setTitle('Requirements possibly met.') - .setDescription(`The following HSPS members that suit the Door of Dread requirements are currently on-duty: + .setDescription(`The following HSPS members that suit the Door of Dread requirements *(2 or more Senior Guardsmen+)* are currently on-duty: - ${sgPlus.join('\n- ')} **Please make sure they are in the server with you before asking for authorization.**`)