dok/routes/booster.js
2026-04-06 13:52:15 +01:00

116 lines
3.5 KiB
JavaScript

const express = require("express");
const router = express.Router();
const db = require("../database/database");
/* ================================
Gewichtete Zufallsauswahl
================================ */
function weightedRandom(weights) {
const total = weights.reduce((s, w) => s + w.weight, 0);
let r = Math.random() * total;
for (const entry of weights) {
r -= entry.weight;
if (r <= 0) return entry.maxLevel;
}
return weights[weights.length - 1].maxLevel;
}
/* ================================
Gewichte je Spielerlevel
================================ */
function getWeights(playerLevel) {
if (playerLevel < 10) return [
{ maxLevel: 1, weight: 85 },
{ maxLevel: 2, weight: 15 },
];
if (playerLevel < 20) return [
{ maxLevel: 1, weight: 65 },
{ maxLevel: 2, weight: 27 },
{ maxLevel: 3, weight: 8 },
];
if (playerLevel < 30) return [
{ maxLevel: 1, weight: 55 },
{ maxLevel: 2, weight: 26 },
{ maxLevel: 3, weight: 13 },
{ maxLevel: 4, weight: 6 },
];
if (playerLevel < 40) return [
{ maxLevel: 1, weight: 50 },
{ maxLevel: 2, weight: 25 },
{ maxLevel: 3, weight: 14 },
{ maxLevel: 4, weight: 7 },
{ maxLevel: 5, weight: 4 },
];
return [
{ maxLevel: 1, weight: 47 },
{ maxLevel: 2, weight: 25 },
{ maxLevel: 3, weight: 15 },
{ maxLevel: 4, weight: 8 },
{ maxLevel: 5, weight: 4.5 },
{ maxLevel: 6, weight: 0.5 },
];
}
/* ================================
GET /api/booster/cards
Alle Karten inkl. Stats für Slot-Animation
================================ */
router.get("/booster/cards", async (req, res) => {
if (!req.session?.user) return res.status(401).json({ error: "Nicht eingeloggt" });
try {
const [cards] = await db.query(
"SELECT id, name, image, icon, max_level, rarity, attack, defends, cooldown FROM cards ORDER BY id"
);
res.json(cards);
} catch (err) {
console.error(err);
res.status(500).json({ error: "DB Fehler" });
}
});
/* ================================
POST /api/booster/open
5 gewichtete Zufallskarten inkl. Stats
================================ */
router.post("/booster/open", async (req, res) => {
if (!req.session?.user) return res.status(401).json({ error: "Nicht eingeloggt" });
const userId = req.session.user.id;
try {
const [[account]] = await db.query(
"SELECT level FROM accounts WHERE id = ?", [userId]
);
const playerLevel = account?.level ?? 1;
const weights = getWeights(playerLevel);
const maxAllowed = Math.max(...weights.map(w => w.maxLevel));
const [allCards] = await db.query(
"SELECT id, name, image, icon, max_level, rarity, attack, defends, cooldown FROM cards WHERE max_level <= ?",
[maxAllowed]
);
if (!allCards.length) return res.status(400).json({ error: "Keine Karten verfügbar" });
const result = [];
for (let i = 0; i < 5; i++) {
const targetLevel = weightedRandom(weights);
let pool = allCards.filter(c => c.max_level === targetLevel);
if (!pool.length) {
for (let fb = targetLevel - 1; fb >= 1; fb--) {
pool = allCards.filter(c => c.max_level === fb);
if (pool.length) break;
}
}
if (!pool.length) pool = allCards;
result.push(pool[Math.floor(Math.random() * pool.length)]);
}
res.json({ cards: result, playerLevel });
} catch (err) {
console.error(err);
res.status(500).json({ error: "DB Fehler" });
}
});
module.exports = router;