Compare commits
3 Commits
4727434362
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 878e8fcdaa | |||
| 57d3ca6929 | |||
| f1335162aa |
@@ -9,16 +9,16 @@ Arthonor-Neo is a custom Discord bot designed for community interaction and fun.
|
|||||||
## Features
|
## Features
|
||||||
|
|
||||||
### Core Interactions
|
### Core Interactions
|
||||||
- Nut Economy – Earn and spend nuts in server activities
|
- Nut Economy - Earn and spend nuts in server activities
|
||||||
- Honor System – Show recognition and respect to users
|
- Honor System - Show recognition and respect to users
|
||||||
- Quotes – Save and retrieve memorable quotes
|
- Quotes - Save and retrieve memorable quotes
|
||||||
|
|
||||||
### Community & Events
|
### Community & Events
|
||||||
- Automatic Welcome Messages – Greet new members
|
- Automatic Welcome Messages - Greet new members
|
||||||
- Birthday System – Track and celebrate birthdays
|
- Birthday System - Track and celebrate birthdays
|
||||||
- Automatic Birthday Cards – Personalized greetings on birthdays
|
- Automatic Birthday Cards - Personalized greetings on birthdays
|
||||||
- Wednesday Frog – Midweek server event
|
- Wednesday Frog - Midweek server event
|
||||||
- Friday Reminder (Coming Soon)
|
- WGE Core - With Periodic Reminders and Random Function
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -32,11 +32,11 @@ These have been mostly removed with certain exceptions:
|
|||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- Timers
|
- Timers
|
||||||
- WGE
|
|
||||||
- Weather commands
|
- Weather commands
|
||||||
- GIF commands
|
- GIF commands
|
||||||
- Certain developer tools
|
- Certain developer tools
|
||||||
- WOKCommands Core
|
- WOKCommands Core
|
||||||
|
- Friday Reminder
|
||||||
|
|
||||||
### Upgraded to Slash Commands
|
### Upgraded to Slash Commands
|
||||||
- Nuts
|
- Nuts
|
||||||
@@ -46,6 +46,7 @@ These have been mostly removed with certain exceptions:
|
|||||||
- Role Selection
|
- Role Selection
|
||||||
- Channel Selection
|
- Channel Selection
|
||||||
- Meme Commands
|
- Meme Commands
|
||||||
|
- WGE (NEW)
|
||||||
|
|
||||||
### New and Improved
|
### New and Improved
|
||||||
- Interactive Honor Menu
|
- Interactive Honor Menu
|
||||||
|
|||||||
@@ -9,95 +9,36 @@ const {
|
|||||||
const { mClient } = require('../../..');
|
const { mClient } = require('../../..');
|
||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
|
||||||
|
const db = mClient.db(process.env.M_DB); // adjust if needed
|
||||||
|
const coll = db.collection('items_daily_numbers');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('ezd')
|
.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) {
|
async execute(interaction, client) {
|
||||||
const db = mClient.db(process.env.M_DB); // adjust if needed
|
switch (interaction.options._subcommand) {
|
||||||
const coll = db.collection('items_daily_numbers');
|
case 'show':
|
||||||
|
ezdShow(interaction)
|
||||||
|
break;
|
||||||
|
case 'leaderboard':
|
||||||
|
ezdLeaderboard(interaction)
|
||||||
|
break;
|
||||||
|
|
||||||
const today = new Date().toLocaleDateString("en-CA", {
|
default:
|
||||||
timeZone: "Europe/Berlin"
|
break;
|
||||||
});
|
}
|
||||||
|
|
||||||
let currentDate = today;
|
|
||||||
|
|
||||||
const sessionId = `${interaction.user.id}-${Date.now()}`;
|
|
||||||
|
|
||||||
const buildEmbed = (doc, date) => {
|
|
||||||
const p = doc?.positions || {};
|
|
||||||
|
|
||||||
const line = (emoji, label, key) => {
|
|
||||||
const v = p[key];
|
|
||||||
return `${emoji} **${label}:** ${v ? `<@${v.userId}>` : "—"}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const germanDate = new Date(`${date}T00:00:00`).toLocaleDateString("de-DE", {
|
|
||||||
timeZone: "Europe/Berlin",
|
|
||||||
day: "2-digit",
|
|
||||||
month: "2-digit",
|
|
||||||
year: "numeric"
|
|
||||||
});
|
|
||||||
|
|
||||||
return new EmbedBuilder()
|
|
||||||
.setTitle(`📊 EZD Übersicht – ${germanDate}`)
|
|
||||||
.setColor(0x2b2d31)
|
|
||||||
.setDescription([
|
|
||||||
line("🥇", "Ersti", "Ersti"),
|
|
||||||
line("🥈", "Zweiti", "Zweiti"),
|
|
||||||
line("🥉", "Dritti", "Dritti")
|
|
||||||
].join("\n"));
|
|
||||||
};
|
|
||||||
|
|
||||||
const buildButtons = (date) => {
|
|
||||||
return new ActionRowBuilder().addComponents(
|
|
||||||
new ButtonBuilder()
|
|
||||||
.setCustomId(`ezd_prev`)
|
|
||||||
.setLabel("⬅️")
|
|
||||||
.setStyle(ButtonStyle.Secondary),
|
|
||||||
new ButtonBuilder()
|
|
||||||
.setCustomId(`ezd_next`)
|
|
||||||
.setLabel("➡️")
|
|
||||||
.setStyle(ButtonStyle.Secondary)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const doc = await coll.findOne({ date: currentDate });
|
|
||||||
|
|
||||||
const msg = await interaction.reply({
|
|
||||||
embeds: [buildEmbed(doc, currentDate)],
|
|
||||||
components: [buildButtons(currentDate)]
|
|
||||||
});
|
|
||||||
|
|
||||||
const collector = msg.createMessageComponentCollector({
|
|
||||||
time: 1000 * 60 * 10 // 10 minutes
|
|
||||||
});
|
|
||||||
|
|
||||||
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_prev`) {
|
|
||||||
currentDate = shiftDate(currentDate, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (btn.customId === `ezd_next`) {
|
|
||||||
currentDate = shiftDate(currentDate, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const newDoc = await coll.findOne({ date: currentDate });
|
|
||||||
|
|
||||||
await btn.update({
|
|
||||||
embeds: [buildEmbed(newDoc, currentDate)],
|
|
||||||
components: [buildButtons(currentDate)]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -106,4 +47,203 @@ function shiftDate(dateStr, offset) {
|
|||||||
const d = new Date(dateStr);
|
const d = new Date(dateStr);
|
||||||
d.setDate(d.getDate() + offset);
|
d.setDate(d.getDate() + offset);
|
||||||
return d.toISOString().slice(0, 10);
|
return d.toISOString().slice(0, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function ezdShow(interaction) {
|
||||||
|
const today = new Date().toLocaleDateString("en-CA", {
|
||||||
|
timeZone: "Europe/Berlin"
|
||||||
|
});
|
||||||
|
|
||||||
|
let currentDate = today;
|
||||||
|
|
||||||
|
const sessionId = `${interaction.user.id}-${Date.now()}`;
|
||||||
|
|
||||||
|
const buildEmbed = (doc, date) => {
|
||||||
|
const p = doc?.positions || {};
|
||||||
|
|
||||||
|
const line = (emoji, label, key) => {
|
||||||
|
const v = p[key];
|
||||||
|
return `${emoji} **${label}:** ${v ? `<@${v.userId}>` : "—"}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const germanDate = new Date(`${date}T00:00:00`).toLocaleDateString("de-DE", {
|
||||||
|
timeZone: "Europe/Berlin",
|
||||||
|
day: "2-digit",
|
||||||
|
month: "2-digit",
|
||||||
|
year: "numeric"
|
||||||
|
});
|
||||||
|
|
||||||
|
return new EmbedBuilder()
|
||||||
|
.setTitle(`📊 EZD Übersicht – ${germanDate}`)
|
||||||
|
.setColor(0x2b2d31)
|
||||||
|
.setDescription([
|
||||||
|
line("🥇", "Ersti", "Ersti"),
|
||||||
|
line("🥈", "Zweiti", "Zweiti"),
|
||||||
|
line("🥉", "Dritti", "Dritti")
|
||||||
|
].join("\n"));
|
||||||
|
};
|
||||||
|
|
||||||
|
const buildButtons = (date) => {
|
||||||
|
return new ActionRowBuilder().addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(`ezd_prev`)
|
||||||
|
.setLabel("⬅️")
|
||||||
|
.setStyle(ButtonStyle.Secondary),
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(`ezd_next`)
|
||||||
|
.setLabel("➡️")
|
||||||
|
.setStyle(ButtonStyle.Secondary)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const doc = await coll.findOne({ date: currentDate });
|
||||||
|
|
||||||
|
const msg = await interaction.reply({
|
||||||
|
embeds: [buildEmbed(doc, currentDate)],
|
||||||
|
components: [buildButtons(currentDate)]
|
||||||
|
});
|
||||||
|
|
||||||
|
const collector = msg.createMessageComponentCollector({
|
||||||
|
time: 1000 * 60 * 10 // 10 minutes
|
||||||
|
});
|
||||||
|
|
||||||
|
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_prev`) {
|
||||||
|
currentDate = shiftDate(currentDate, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (btn.customId === `ezd_next`) {
|
||||||
|
currentDate = shiftDate(currentDate, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newDoc = await coll.findOne({ date: currentDate });
|
||||||
|
|
||||||
|
await btn.update({
|
||||||
|
embeds: [buildEmbed(newDoc, currentDate)],
|
||||||
|
components: [buildButtons(currentDate)]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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]) =>
|
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];
|
)?.[1];
|
||||||
|
|
||||||
if (!found) return;
|
if (!found) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user