Skip to content

Commit

Permalink
Fixed position #0 in coin leaderboard (#420)
Browse files Browse the repository at this point in the history
  • Loading branch information
Picowchew authored Dec 25, 2022
1 parent 8824470 commit 290a927
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 53 deletions.
2 changes: 1 addition & 1 deletion src/commandDetails/coin/info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const coinInfoExecuteCommand: SapphireMessageExecuteType = async (
export const coinInfoCommandDetails: CodeyCommandDetails = {
name: 'info',
aliases: ['information, i'],
description: 'Get info about CodeyCoin.',
description: 'Get info about Codey coin.',
detailedDescription: `**Examples:**
\`${container.botPrefix}coin info\`
\`${container.botPrefix}coin information\`
Expand Down
101 changes: 54 additions & 47 deletions src/commandDetails/coin/leaderboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,86 +6,93 @@ import {
SapphireMessageExecuteType,
SapphireMessageResponse,
} from '../../codeyCommand';
import {
getCoinBalanceByUserId,
getCurrentCoinLeaderboard,
UserCoinEntry,
} from '../../components/coin';
import { getCoinBalanceByUserId, getCoinLeaderboard } from '../../components/coin';
import { getCoinEmoji } from '../../components/emojis';
import { DEFAULT_EMBED_COLOUR } from '../../utils/embeds';

// How many people are shown on the leaderboard
const limit = 10;
// Number of users to display on leaderboard
const LEADERBOARD_LIMIT_DISPLAY = 10;
// Number of users to fetch for leaderboard
const LEADERBOARD_LIMIT_FETCH = LEADERBOARD_LIMIT_DISPLAY * 2;

const getCurrentCoinLeaderboardEmbed = async (
const getCoinLeaderboardEmbed = async (
client: SapphireClient<boolean>,
leaderboard: UserCoinEntry[],
currentUserId: string,
userId: string,
): Promise<MessageEmbed> => {
// Initialise user's coin balance if they have not already
const userBalance = await getCoinBalanceByUserId(currentUserId);
let currentPosition = 0;

// Get extra users to filter bots later
let leaderboard = await getCoinLeaderboard(LEADERBOARD_LIMIT_FETCH);
const leaderboardArray: string[] = [];
let rank = 0;
// Initialize user's coin balance if they have not already
const userBalance = await getCoinBalanceByUserId(userId);
let previousBalance = -1;
for (let i = 0; i < leaderboard.length && leaderboardArray.length < limit; i++) {
const userCoinEntry = leaderboard[i];
let position = 0;
let rank = 0;
let offset = 0;
let i = 0;
while (leaderboardArray.length < LEADERBOARD_LIMIT_DISPLAY || position === 0) {
if (i === LEADERBOARD_LIMIT_FETCH) {
offset += LEADERBOARD_LIMIT_FETCH;
leaderboard = await getCoinLeaderboard(LEADERBOARD_LIMIT_FETCH, offset);
i = 0;
}
if (leaderboard.length === 0) {
break;
}
const userCoinEntry = leaderboard[i++];
let user: User;
try {
user = await client.users.fetch(userCoinEntry.user_id);
} catch (e) {
continue;
}
if (user.bot) continue;
const userTag = user?.tag ?? '<unknown>';
const cleanUserTag = userTag
.split('~')
.join('\\~')
.split('*')
.join('\\*')
.split('_')
.join('\\_')
.split('`')
.join('\\`');
if (previousBalance !== userCoinEntry.balance) {
previousBalance = userCoinEntry.balance;
rank = rank + 1;
}
const userCoinEntryText = `${rank}. ${cleanUserTag} - ${
userCoinEntry.balance
} ${getCoinEmoji()}`;
if (userCoinEntry.user_id === currentUserId) {
currentPosition = rank;
if (userCoinEntry.user_id === userId) {
position = rank;
}
if (leaderboardArray.length < LEADERBOARD_LIMIT_DISPLAY) {
const userTag = user?.tag ?? '<unknown>';
const cleanUserTag = userTag
.split('~')
.join('\\~')
.split('*')
.join('\\*')
.split('_')
.join('\\_')
.split('`')
.join('\\`');
const userCoinEntryText = `${rank}. ${cleanUserTag} - ${
userCoinEntry.balance
} ${getCoinEmoji()}`;
leaderboardArray.push(userCoinEntryText);
}
leaderboardArray.push(userCoinEntryText);
}
const currentLeaderboardText = leaderboardArray.join('\n');
const currentLeaderboardEmbed = new MessageEmbed()
const leaderboardText = leaderboardArray.join('\n');
const leaderboardEmbed = new MessageEmbed()
.setColor(DEFAULT_EMBED_COLOUR)
.setTitle('CodeyCoin Leaderboard')
.setDescription(currentLeaderboardText);

currentLeaderboardEmbed.addFields({
.setTitle('Codey Coin Leaderboard')
.setDescription(leaderboardText);
leaderboardEmbed.addFields({
name: 'Your Position',
value: `You are currently **#${currentPosition}** in the leaderboard with ${userBalance} ${getCoinEmoji()}.`,
value: `You are currently **#${position}** in the leaderboard with ${userBalance} ${getCoinEmoji()}.`,
});

return currentLeaderboardEmbed;
return leaderboardEmbed;
};

const coinCurrentLeaderboardExecuteCommand: SapphireMessageExecuteType = async (
const coinLeaderboardExecuteCommand: SapphireMessageExecuteType = async (
client,
messageFromUser,
_args,
): Promise<SapphireMessageResponse> => {
const userId = getUserFromMessage(messageFromUser).id;
// Get extra users to filter bots later
const leaderboard = await getCurrentCoinLeaderboard(limit * 2);
return { embeds: [await getCurrentCoinLeaderboardEmbed(client, leaderboard, userId)] };
return { embeds: [await getCoinLeaderboardEmbed(client, userId)] };
};

export const coinCurrentLeaderboardCommandDetails: CodeyCommandDetails = {
export const coinLeaderboardCommandDetails: CodeyCommandDetails = {
name: 'leaderboard',
aliases: ['lb'],
description: 'Get the current coin leaderboard.',
Expand All @@ -95,7 +102,7 @@ export const coinCurrentLeaderboardCommandDetails: CodeyCommandDetails = {

isCommandResponseEphemeral: false,
messageWhenExecutingCommand: 'Getting the current coin leaderboard...',
executeCommand: coinCurrentLeaderboardExecuteCommand,
executeCommand: coinLeaderboardExecuteCommand,
options: [],
subcommandDetails: {},
};
4 changes: 2 additions & 2 deletions src/commands/coin/coin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CodeyCommand, CodeyCommandDetails } from '../../codeyCommand';
import { coinAdjustCommandDetails } from '../../commandDetails/coin/adjust';
import { coinCheckCommandDetails } from '../../commandDetails/coin/check';
import { coinInfoCommandDetails } from '../../commandDetails/coin/info';
import { coinCurrentLeaderboardCommandDetails } from '../../commandDetails/coin/leaderboard';
import { coinLeaderboardCommandDetails } from '../../commandDetails/coin/leaderboard';
import { coinUpdateCommandDetails } from '../../commandDetails/coin/update';

const coinCommandDetails: CodeyCommandDetails = {
Expand All @@ -26,7 +26,7 @@ const coinCommandDetails: CodeyCommandDetails = {
check: coinCheckCommandDetails,
info: coinInfoCommandDetails,
update: coinUpdateCommandDetails,
leaderboard: coinCurrentLeaderboardCommandDetails,
leaderboard: coinLeaderboardCommandDetails,
},
defaultSubcommandDetails: coinCheckCommandDetails,
};
Expand Down
2 changes: 1 addition & 1 deletion src/commands/profile/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export class ProfileCommand extends SubCommandPluginCommand {
);
}
}
// add codeycoins onto the fields as well
// add Codey coins onto the fields as well
const userCoins = (await getCoinBalanceByUserId(user.id))!.toString();
profileDisplay.addField('Codey Coins', userCoins, true);
// display last updated last
Expand Down
5 changes: 3 additions & 2 deletions src/components/coin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,16 +146,17 @@ export const changeDbCoinBalanceByUserId = async (
/*
Get the leaderboard for the current coin amounts.
*/
export const getCurrentCoinLeaderboard = async (limit = 10): Promise<UserCoinEntry[]> => {
export const getCoinLeaderboard = async (limit: number, offset = 0): Promise<UserCoinEntry[]> => {
const db = await openDB();
const res = await db.all(
`
SELECT user_id, balance
FROM user_coin
ORDER BY balance DESC
LIMIT ?
LIMIT ? OFFSET ?
`,
limit,
offset,
);
return res;
};
Expand Down

0 comments on commit 290a927

Please sign in to comment.