diff --git a/docs/COMMAND-WIKI.md b/docs/COMMAND-WIKI.md index c2cc7eca..63acc14e 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,14 @@ - **Options:** None - **Subcommands:** None +## coin prune +- **Aliases:** `p` +- **Description:** The reason why we are pruning the balances. +- **Examples:**
`.coin prune @Codey 100`
`.coin prune @Codey -100 Codey broke.` +- **Options:** + - ``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/prune.ts b/src/commandDetails/coin/prune.ts new file mode 100644 index 00000000..0d98b61c --- /dev/null +++ b/src/commandDetails/coin/prune.ts @@ -0,0 +1,94 @@ +import { CodeyUserError } from './../../codeyUserError'; +import { container } from '@sapphire/framework'; +import { ChatInputCommandInteraction, PermissionsBitField } from 'discord.js'; +import { + CodeyCommandDetails, + CodeyCommandOptionType, + SapphireMessageExecuteType, + SapphireMessageResponse, +} from '../../codeyCommand'; +import { + updateCoinBalanceByUserId, + getCoinBalanceByUserId, + UserCoinEvent, +} from '../../components/coin'; + +// 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, + 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()) { + const 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..889a03b5 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,