added ezd leaderboard
This commit is contained in:
@@ -9,15 +9,47 @@ const {
|
||||
const { mClient } = require('../../..');
|
||||
require('dotenv').config()
|
||||
|
||||
const db = mClient.db(process.env.M_DB); // adjust if needed
|
||||
const coll = db.collection('items_daily_numbers');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('ezd')
|
||||
.setDescription('Zeigt die täglichen Erster/Zweiter/Dritter Ergebnisse'),
|
||||
|
||||
.setDescription('Ersti Zweiti Dritti')
|
||||
.addSubcommand(s =>
|
||||
s
|
||||
.setName('show')
|
||||
.setDescription('Zeigt die täglichen Erster/Zweiter/Dritter Ergebnisse')
|
||||
)
|
||||
.addSubcommand(s =>
|
||||
s
|
||||
.setName('leaderboard')
|
||||
.setDescription('Zeigt die Rangliste der EZDler')
|
||||
)
|
||||
,
|
||||
async execute(interaction, client) {
|
||||
const db = mClient.db(process.env.M_DB); // adjust if needed
|
||||
const coll = db.collection('items_daily_numbers');
|
||||
switch (interaction.options._subcommand) {
|
||||
case 'show':
|
||||
ezdShow(interaction)
|
||||
break;
|
||||
case 'leaderboard':
|
||||
ezdLeaderboard(interaction)
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// helper: shift YYYY-MM-DD safely
|
||||
function shiftDate(dateStr, offset) {
|
||||
const d = new Date(dateStr);
|
||||
d.setDate(d.getDate() + offset);
|
||||
return d.toISOString().slice(0, 10);
|
||||
}
|
||||
|
||||
async function ezdShow(interaction) {
|
||||
const today = new Date().toLocaleDateString("en-CA", {
|
||||
timeZone: "Europe/Berlin"
|
||||
});
|
||||
@@ -98,12 +130,120 @@ module.exports = {
|
||||
components: [buildButtons(currentDate)]
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// helper: shift YYYY-MM-DD safely
|
||||
function shiftDate(dateStr, offset) {
|
||||
const d = new Date(dateStr);
|
||||
d.setDate(d.getDate() + offset);
|
||||
return d.toISOString().slice(0, 10);
|
||||
}
|
||||
|
||||
async function ezdLeaderboard(interaction) {
|
||||
const docs = await coll.find({}).toArray();
|
||||
|
||||
const leaderboard = new Map();
|
||||
|
||||
const add = (entry, place) => {
|
||||
if (!entry?.userId) return;
|
||||
|
||||
if (!leaderboard.has(entry.userId)) {
|
||||
leaderboard.set(entry.userId, {
|
||||
userId: entry.userId,
|
||||
points: 0,
|
||||
Ersti: 0,
|
||||
Zweiti: 0,
|
||||
Dritti: 0
|
||||
});
|
||||
}
|
||||
|
||||
const user = leaderboard.get(entry.userId);
|
||||
|
||||
user[place]++;
|
||||
|
||||
if (place === "Ersti") user.points += 3;
|
||||
if (place === "Zweiti") user.points += 2;
|
||||
if (place === "Dritti") user.points += 1;
|
||||
};
|
||||
|
||||
for (const doc of docs) {
|
||||
const p = doc.positions || {};
|
||||
|
||||
add(p.Ersti, "Ersti");
|
||||
add(p.Zweiti, "Zweiti");
|
||||
add(p.Dritti, "Dritti");
|
||||
}
|
||||
|
||||
const users = [...leaderboard.values()].sort((a, b) => {
|
||||
if (b.points !== a.points) return b.points - a.points;
|
||||
if (b.Ersti !== a.Ersti) return b.Ersti - a.Ersti;
|
||||
if (b.Zweiti !== a.Zweiti) return b.Zweiti - a.Zweiti;
|
||||
return b.Dritti - a.Dritti;
|
||||
});
|
||||
|
||||
const PAGE_SIZE = 5;
|
||||
const pageCount = Math.max(1, Math.ceil(users.length / PAGE_SIZE));
|
||||
let page = 0;
|
||||
|
||||
const buildEmbed = () => {
|
||||
const slice = users.slice(
|
||||
page * PAGE_SIZE,
|
||||
page * PAGE_SIZE + PAGE_SIZE
|
||||
);
|
||||
|
||||
const description = slice.length
|
||||
? slice.map((u, i) => {
|
||||
const rank = page * PAGE_SIZE + i + 1;
|
||||
|
||||
return `**#${rank}** <@${u.userId}> — **${u.points}**
|
||||
🥇 ${u.Ersti} · 🥈 ${u.Zweiti} · 🥉 ${u.Dritti}`;
|
||||
}).join("\n\n")
|
||||
: "—";
|
||||
|
||||
return new EmbedBuilder()
|
||||
.setTitle("🏆 EZD Rangliste")
|
||||
.setColor(0x2b2d31)
|
||||
.setDescription(description);
|
||||
};
|
||||
|
||||
const buildButtons = () =>
|
||||
new ActionRowBuilder().addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId("ezd_lb_prev")
|
||||
.setLabel("⬅️")
|
||||
.setStyle(ButtonStyle.Secondary),
|
||||
|
||||
new ButtonBuilder()
|
||||
.setCustomId("ezd_lb_page")
|
||||
.setLabel(`${page + 1}/${pageCount}`)
|
||||
.setStyle(ButtonStyle.Primary)
|
||||
.setDisabled(true),
|
||||
|
||||
new ButtonBuilder()
|
||||
.setCustomId("ezd_lb_next")
|
||||
.setLabel("➡️")
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
);
|
||||
|
||||
const msg = await interaction.reply({
|
||||
embeds: [buildEmbed()],
|
||||
components: [buildButtons()]
|
||||
});
|
||||
|
||||
const collector = msg.createMessageComponentCollector({
|
||||
time: 1000 * 60 * 10
|
||||
});
|
||||
|
||||
collector.on("collect", async btn => {
|
||||
if (btn.user.id !== interaction.user.id) {
|
||||
return btn.reply({
|
||||
content: "❌ Diese Buttons gehören nicht dir.",
|
||||
flags: MessageFlags.Ephemeral
|
||||
});
|
||||
}
|
||||
|
||||
if (btn.customId === "ezd_lb_prev")
|
||||
page = (page - 1 + pageCount) % pageCount;
|
||||
|
||||
if (btn.customId === "ezd_lb_next")
|
||||
page = (page + 1) % pageCount;
|
||||
|
||||
await btn.update({
|
||||
embeds: [buildEmbed()],
|
||||
components: [buildButtons()]
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -19,7 +19,7 @@ module.exports = {
|
||||
};
|
||||
|
||||
const found = Object.entries(numbered).find(([stem]) =>
|
||||
new RegExp(`\\b${stem}\\w*\\b`, "i").test(message.content)
|
||||
new RegExp(`\\b\\w*${stem}\\w*\\b`, "i").test(message.content)
|
||||
)?.[1];
|
||||
|
||||
if (!found) return;
|
||||
|
||||
Reference in New Issue
Block a user