From 4e872a03587f68adee9ebc191e1cac0f9b120699 Mon Sep 17 00:00:00 2001 From: w1dering Date: Fri, 27 Sep 2024 20:25:49 -0400 Subject: [PATCH 1/4] initial commit of coin prune coin prune is a new command that accepts an argument and divides all users' coin balances by the argument. it is designed to be used at the end of a term to highlight active users on the codeycoin leaderboard --- docs/COMMAND-WIKI.md | 11 ++- src/commandDetails/coin/leaderboard.ts | 2 +- src/commandDetails/coin/prune.ts | 99 ++++++++++++++++++++++++++ src/commands/coin/coin.ts | 2 + src/components/coin.ts | 1 + 5 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 src/commandDetails/coin/prune.ts diff --git a/docs/COMMAND-WIKI.md b/docs/COMMAND-WIKI.md index c2cc7eca..1e0eb6d9 100644 --- a/docs/COMMAND-WIKI.md +++ b/docs/COMMAND-WIKI.md @@ -14,7 +14,7 @@ - **Description:** Handle coin functions. - **Examples:**
`.coin adjust @Codey 100`
`.coin adjust @Codey -100 Codey broke.`
`.coin`
`.coin check @Codey`
`.coin c @Codey`
`.coin info`
`.coin i`
`.coin update @Codey 100`
`.coin update @Codey 0 Reset Codey's balance.`
`.coin transfer @Codey 10`
`.coin transfer @Codey 15 Lost a bet to Codey ` - **Options:** None -- **Subcommands:** `adjust`, `check`, `info`, `update`, `leaderboard`, `transfer` +- **Subcommands:** `adjust`, `check`, `info`, `update`, `leaderboard`, `transfer`, `prune` ## coin adjust - **Aliases:** `a` @@ -48,6 +48,15 @@ - **Options:** None - **Subcommands:** None +## coin prune +- **Aliases:** `p` +- **Description:** Divide every users\ +- **Examples:**
`.coin prune @Codey 100`
`.coin prune @Codey -100 Codey broke.` +- **Options:** + - ``divisor``: The number to divide all users\ + - ``reason``: The reason why we are pruning the balances. +- **Subcommands:** None + ## coin transfer - **Aliases:** `t` - **Description:** Transfer coins from your balance to another user. diff --git a/src/commandDetails/coin/leaderboard.ts b/src/commandDetails/coin/leaderboard.ts index 25c24f31..2d0d0354 100644 --- a/src/commandDetails/coin/leaderboard.ts +++ b/src/commandDetails/coin/leaderboard.ts @@ -25,7 +25,7 @@ const getCoinLeaderboardEmbed = async ( // Initialize user's coin balance if they have not already const userBalance = await getCoinBalanceByUserId(userId); let previousBalance = -1; - let position = 0; + let position = 0; let rank = 0; let offset = 0; let i = 0; diff --git a/src/commandDetails/coin/prune.ts b/src/commandDetails/coin/prune.ts new file mode 100644 index 00000000..49198e4f --- /dev/null +++ b/src/commandDetails/coin/prune.ts @@ -0,0 +1,99 @@ +import { CodeyUserError } from './../../codeyUserError'; +import { container } from '@sapphire/framework'; +import { ChatInputCommandInteraction, PermissionsBitField, User} from 'discord.js'; +import { + CodeyCommandDetails, + CodeyCommandOptionType, + SapphireMessageExecuteType, + SapphireMessageResponse, +} from '../../codeyCommand'; +import { + updateCoinBalanceByUserId, + getCoinBalanceByUserId, + UserCoinEvent, +} from '../../components/coin'; +import { getCoinEmoji } from '../../components/emojis'; +import { pluralize } from '../../utils/pluralize'; + +// Divide everyone's coin counts by given divisor to promote more recent users +// Designed to be used at the end of a term +const coinPruneExecuteCommand: SapphireMessageExecuteType = async ( + client, + messageFromUser, + args, +): Promise => { + if ( + !(>messageFromUser.member?.permissions).has( + PermissionsBitField.Flags.Administrator, + ) + ) { + throw new CodeyUserError(messageFromUser, `You do not have permission to use this command.`); + } + + // First and only mandatory argument is divisor + const divisor = args['divisor']; // Cast divisor to a number to allow arithmetic operations + if (!divisor || divisor < 1) { + throw new CodeyUserError(messageFromUser, 'Please enter a valid number to divide by.'); + } + + // Optional argument is reason + const reason = args['reason']; + + if (messageFromUser instanceof ChatInputCommandInteraction) { + await (messageFromUser).deferReply(); + } + // Prune coin balance of all users + const allMembers = await messageFromUser.guild?.members.fetch(); + if (allMembers) { + for (const member of allMembers.values()) { + let currentBalance: number = await getCoinBalanceByUserId(member.user.id); + await updateCoinBalanceByUserId( + member.user.id, + Math.round(currentBalance / divisor), + UserCoinEvent.AdminCoinPrune, + (reason ? reason : ''), + client.user?.id, + ); + } + } + // The message to be displayed after the command has been completed + const returnMessage = `Divided all users' coin balances by ${divisor}.`; + + if (messageFromUser instanceof ChatInputCommandInteraction) { + await(messageFromUser).editReply( + returnMessage, + ); + } + else { + await messageFromUser.channel?.send(returnMessage); + } + return; +}; + +export const coinPruneCommandDetails: CodeyCommandDetails = { + name: 'prune', + aliases: ['p'], + description: 'Divide every users\' coin balance by the passed argument.', + detailedDescription: `**Examples:** +\`${container.botPrefix}coin prune @Codey 100\` +\`${container.botPrefix}coin prune @Codey -100 Codey broke.\``, + + isCommandResponseEphemeral: false, + messageWhenExecutingCommand: 'Pruning...', + executeCommand: coinPruneExecuteCommand, + options: [ + { + name: 'divisor', + description: 'The number to divide all users\' coin balances by.', + type: CodeyCommandOptionType.NUMBER, + required: true, + }, + { + name: 'reason', + description: 'The reason why we are pruning the balances.', + type: CodeyCommandOptionType.STRING, + required: false, + }, + ], + subcommandDetails: {}, +}; diff --git a/src/commands/coin/coin.ts b/src/commands/coin/coin.ts index 21f5f702..d845662c 100644 --- a/src/commands/coin/coin.ts +++ b/src/commands/coin/coin.ts @@ -6,6 +6,7 @@ import { coinInfoCommandDetails } from '../../commandDetails/coin/info'; import { coinLeaderboardCommandDetails } from '../../commandDetails/coin/leaderboard'; import { coinTransferCommandDetails } from '../../commandDetails/coin/transfer'; import { coinUpdateCommandDetails } from '../../commandDetails/coin/update'; +import { coinPruneCommandDetails } from '../../commandDetails/coin/prune'; const coinCommandDetails: CodeyCommandDetails = { name: 'coin', @@ -31,6 +32,7 @@ const coinCommandDetails: CodeyCommandDetails = { update: coinUpdateCommandDetails, leaderboard: coinLeaderboardCommandDetails, transfer: coinTransferCommandDetails, + prune: coinPruneCommandDetails }, defaultSubcommandDetails: coinCheckCommandDetails, }; diff --git a/src/components/coin.ts b/src/components/coin.ts index 328443b4..4cdb2886 100644 --- a/src/components/coin.ts +++ b/src/components/coin.ts @@ -23,6 +23,7 @@ export enum BonusType { export enum UserCoinEvent { AdminCoinAdjust, + AdminCoinPrune, AdminCoinUpdate, BonusDaily, BonusActivity, From f8f2c4b4a7e12d6e1a1ce8ecb8ef2119cf3e3bb5 Mon Sep 17 00:00:00 2001 From: w1dering Date: Fri, 27 Sep 2024 21:04:38 -0400 Subject: [PATCH 2/4] code clean up + prevent pruning with 1 removed unnecessary imports and disallowed divisor to be 1 --- src/commandDetails/coin/prune.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/commandDetails/coin/prune.ts b/src/commandDetails/coin/prune.ts index 49198e4f..04cad53a 100644 --- a/src/commandDetails/coin/prune.ts +++ b/src/commandDetails/coin/prune.ts @@ -1,6 +1,6 @@ import { CodeyUserError } from './../../codeyUserError'; import { container } from '@sapphire/framework'; -import { ChatInputCommandInteraction, PermissionsBitField, User} from 'discord.js'; +import { ChatInputCommandInteraction, PermissionsBitField,} from 'discord.js'; import { CodeyCommandDetails, CodeyCommandOptionType, @@ -12,10 +12,8 @@ import { getCoinBalanceByUserId, UserCoinEvent, } from '../../components/coin'; -import { getCoinEmoji } from '../../components/emojis'; -import { pluralize } from '../../utils/pluralize'; -// Divide everyone's coin counts by given divisor to promote more recent users +// Divide everyone's coin counts by given divisor to ensure the leaderboard is populated with more active members // Designed to be used at the end of a term const coinPruneExecuteCommand: SapphireMessageExecuteType = async ( client, @@ -32,7 +30,7 @@ const coinPruneExecuteCommand: SapphireMessageExecuteType = async ( // First and only mandatory argument is divisor const divisor = args['divisor']; // Cast divisor to a number to allow arithmetic operations - if (!divisor || divisor < 1) { + if (!divisor || divisor <= 1) { throw new CodeyUserError(messageFromUser, 'Please enter a valid number to divide by.'); } From e9b841441e9de4c8d29e8ecc1c14be0bb3ea9ab5 Mon Sep 17 00:00:00 2001 From: w1dering Date: Sat, 28 Sep 2024 01:14:54 -0400 Subject: [PATCH 3/4] ran linter --- src/commandDetails/coin/leaderboard.ts | 2 +- src/commandDetails/coin/prune.ts | 15 ++++++--------- src/commands/coin/coin.ts | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/commandDetails/coin/leaderboard.ts b/src/commandDetails/coin/leaderboard.ts index 2d0d0354..25c24f31 100644 --- a/src/commandDetails/coin/leaderboard.ts +++ b/src/commandDetails/coin/leaderboard.ts @@ -25,7 +25,7 @@ const getCoinLeaderboardEmbed = async ( // Initialize user's coin balance if they have not already const userBalance = await getCoinBalanceByUserId(userId); let previousBalance = -1; - let position = 0; + let position = 0; let rank = 0; let offset = 0; let i = 0; diff --git a/src/commandDetails/coin/prune.ts b/src/commandDetails/coin/prune.ts index 04cad53a..0d98b61c 100644 --- a/src/commandDetails/coin/prune.ts +++ b/src/commandDetails/coin/prune.ts @@ -1,6 +1,6 @@ import { CodeyUserError } from './../../codeyUserError'; import { container } from '@sapphire/framework'; -import { ChatInputCommandInteraction, PermissionsBitField,} from 'discord.js'; +import { ChatInputCommandInteraction, PermissionsBitField } from 'discord.js'; import { CodeyCommandDetails, CodeyCommandOptionType, @@ -44,7 +44,7 @@ const coinPruneExecuteCommand: SapphireMessageExecuteType = async ( const allMembers = await messageFromUser.guild?.members.fetch(); if (allMembers) { for (const member of allMembers.values()) { - let currentBalance: number = await getCoinBalanceByUserId(member.user.id); + const currentBalance: number = await getCoinBalanceByUserId(member.user.id); await updateCoinBalanceByUserId( member.user.id, Math.round(currentBalance / divisor), @@ -58,11 +58,8 @@ const coinPruneExecuteCommand: SapphireMessageExecuteType = async ( const returnMessage = `Divided all users' coin balances by ${divisor}.`; if (messageFromUser instanceof ChatInputCommandInteraction) { - await(messageFromUser).editReply( - returnMessage, - ); - } - else { + await (messageFromUser).editReply(returnMessage); + } else { await messageFromUser.channel?.send(returnMessage); } return; @@ -71,7 +68,7 @@ const coinPruneExecuteCommand: SapphireMessageExecuteType = async ( export const coinPruneCommandDetails: CodeyCommandDetails = { name: 'prune', aliases: ['p'], - description: 'Divide every users\' coin balance by the passed argument.', + description: "Divide every users' coin balance by the passed argument.", detailedDescription: `**Examples:** \`${container.botPrefix}coin prune @Codey 100\` \`${container.botPrefix}coin prune @Codey -100 Codey broke.\``, @@ -82,7 +79,7 @@ export const coinPruneCommandDetails: CodeyCommandDetails = { options: [ { name: 'divisor', - description: 'The number to divide all users\' coin balances by.', + description: "The number to divide all users' coin balances by.", type: CodeyCommandOptionType.NUMBER, required: true, }, diff --git a/src/commands/coin/coin.ts b/src/commands/coin/coin.ts index d845662c..889a03b5 100644 --- a/src/commands/coin/coin.ts +++ b/src/commands/coin/coin.ts @@ -32,7 +32,7 @@ const coinCommandDetails: CodeyCommandDetails = { update: coinUpdateCommandDetails, leaderboard: coinLeaderboardCommandDetails, transfer: coinTransferCommandDetails, - prune: coinPruneCommandDetails + prune: coinPruneCommandDetails, }, defaultSubcommandDetails: coinCheckCommandDetails, }; From 99ba7c77aec88ec4791b2fcb656a727f98162f87 Mon Sep 17 00:00:00 2001 From: w1dering Date: Sat, 28 Sep 2024 19:02:55 -0400 Subject: [PATCH 4/4] updated command wiki to fit prune's descriptions --- docs/COMMAND-WIKI.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/COMMAND-WIKI.md b/docs/COMMAND-WIKI.md index 1e0eb6d9..63acc14e 100644 --- a/docs/COMMAND-WIKI.md +++ b/docs/COMMAND-WIKI.md @@ -50,10 +50,9 @@ ## coin prune - **Aliases:** `p` -- **Description:** Divide every users\ +- **Description:** The reason why we are pruning the balances. - **Examples:**
`.coin prune @Codey 100`
`.coin prune @Codey -100 Codey broke.` - **Options:** - - ``divisor``: The number to divide all users\ - ``reason``: The reason why we are pruning the balances. - **Subcommands:** None