62 lines
2.3 KiB
TypeScript
62 lines
2.3 KiB
TypeScript
import { createCommand } from "@shared/lib/utils";
|
|
import { SlashCommandBuilder } from "discord.js";
|
|
import { DrizzleClient } from "@shared/db/DrizzleClient";
|
|
import { users, items, inventory } from "@db/schema";
|
|
import { desc, sql, eq } from "drizzle-orm";
|
|
import { createWarningEmbed } from "@lib/embeds";
|
|
import { getLeaderboardEmbed } from "@/modules/leveling/leveling.view";
|
|
|
|
export const leaderboard = createCommand({
|
|
data: new SlashCommandBuilder()
|
|
.setName("leaderboard")
|
|
.setDescription("View the top players")
|
|
.addStringOption(option =>
|
|
option.setName("type")
|
|
.setDescription("Sort by XP, Balance, or Net Worth")
|
|
.setRequired(true)
|
|
.addChoices(
|
|
{ name: "Level / XP", value: "xp" },
|
|
{ name: "Balance", value: "balance" },
|
|
{ name: "Net Worth", value: "networth" }
|
|
)
|
|
),
|
|
execute: async (interaction) => {
|
|
await interaction.deferReply();
|
|
|
|
const type = interaction.options.getString("type", true);
|
|
|
|
let leaders;
|
|
|
|
if (type === 'networth') {
|
|
leaders = await DrizzleClient.select({
|
|
username: users.username,
|
|
level: users.level,
|
|
xp: users.xp,
|
|
balance: users.balance,
|
|
netWorth: sql<bigint>`${users.balance} + COALESCE(SUM(${items.price} * ${inventory.quantity}), 0)`.as('net_worth')
|
|
})
|
|
.from(users)
|
|
.leftJoin(inventory, eq(users.id, inventory.userId))
|
|
.leftJoin(items, eq(inventory.itemId, items.id))
|
|
.groupBy(users.id)
|
|
.orderBy(desc(sql`net_worth`))
|
|
.limit(10);
|
|
} else {
|
|
const isXp = type === "xp";
|
|
leaders = await DrizzleClient.query.users.findMany({
|
|
orderBy: isXp ? desc(users.xp) : desc(users.balance),
|
|
limit: 10
|
|
});
|
|
}
|
|
|
|
if (leaders.length === 0) {
|
|
await interaction.editReply({ embeds: [createWarningEmbed("No users found.", "Leaderboard")] });
|
|
return;
|
|
}
|
|
|
|
const embed = getLeaderboardEmbed(leaders, type as 'xp' | 'balance' | 'networth');
|
|
|
|
await interaction.editReply({ embeds: [embed] });
|
|
}
|
|
});
|