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,