This commit is contained in:
cay 2026-04-07 09:30:30 +01:00
parent 5d8e53f325
commit a41b02d11c

View File

@ -1,6 +1,6 @@
const express = require("express"); const express = require("express");
const router = express.Router(); const router = express.Router();
const db = require("../database/database"); const db = require("../database/database");
/* ================================ /* ================================
Gewichtete Zufallsauswahl Gewichtete Zufallsauswahl
@ -19,35 +19,39 @@ function weightedRandom(weights) {
Gewichte je Spielerlevel Gewichte je Spielerlevel
================================ */ ================================ */
function getWeights(playerLevel) { function getWeights(playerLevel) {
if (playerLevel < 10) return [ if (playerLevel < 10)
{ rarity: 1, weight: 95 }, // 95% return [
{ rarity: 2, weight: 5 }, // 5% { rarity: 1, weight: 95 }, // 95%
]; { rarity: 2, weight: 5 }, // 5%
if (playerLevel < 20) return [ ];
{ rarity: 1, weight: 87 }, // 87% if (playerLevel < 20)
{ rarity: 2, weight: 11 }, // 11% return [
{ rarity: 3, weight: 2 }, // 2% { rarity: 1, weight: 87 }, // 87%
]; { rarity: 2, weight: 11 }, // 11%
if (playerLevel < 30) return [ { rarity: 3, weight: 2 }, // 2%
{ rarity: 1, weight: 80 }, // 80% ];
{ rarity: 2, weight: 14 }, // 14% if (playerLevel < 30)
{ rarity: 3, weight: 4 }, // 4% return [
{ rarity: 4, weight: 2 }, // 2% { rarity: 1, weight: 80 }, // 80%
]; { rarity: 2, weight: 14 }, // 14%
if (playerLevel < 40) return [ { rarity: 3, weight: 4 }, // 4%
{ rarity: 1, weight: 75 }, // 75% { rarity: 4, weight: 2 }, // 2%
{ rarity: 2, weight: 16 }, // 16% ];
{ rarity: 3, weight: 5 }, // 5% if (playerLevel < 40)
{ rarity: 4, weight: 3 }, // 3% return [
{ rarity: 5, weight: 1 }, // 1% { rarity: 1, weight: 75 }, // 75%
]; { rarity: 2, weight: 16 }, // 16%
{ rarity: 3, weight: 5 }, // 5%
{ rarity: 4, weight: 3 }, // 3%
{ rarity: 5, weight: 1 }, // 1%
];
return [ return [
{ rarity: 1, weight: 60 }, // 60.0% { rarity: 1, weight: 60 }, // 60.0%
{ rarity: 2, weight: 25 }, // 25.0% { rarity: 2, weight: 25 }, // 25.0%
{ rarity: 3, weight: 9 }, // 9.0% { rarity: 3, weight: 9 }, // 9.0%
{ rarity: 4, weight: 4 }, // 4.0% { rarity: 4, weight: 4 }, // 4.0%
{ rarity: 5, weight: 1.5 }, // 1.5% { rarity: 5, weight: 1.5 }, // 1.5%
{ rarity: 6, weight: 0.5 }, // 0.5% { rarity: 6, weight: 0.5 }, // 0.5%
]; ];
} }
@ -56,10 +60,11 @@ function getWeights(playerLevel) {
Alle Karten inkl. Stats für Slot-Animation Alle Karten inkl. Stats für Slot-Animation
================================ */ ================================ */
router.get("/booster/cards", async (req, res) => { router.get("/booster/cards", async (req, res) => {
if (!req.session?.user) return res.status(401).json({ error: "Nicht eingeloggt" }); if (!req.session?.user)
return res.status(401).json({ error: "Nicht eingeloggt" });
try { try {
const [cards] = await db.query( const [cards] = await db.query(
"SELECT id, name, image, icon, max_level, rarity, attack, defends, cooldown FROM cards ORDER BY id" "SELECT id, name, image, icon, max_level, rarity, attack, defends, cooldown FROM cards ORDER BY id",
); );
res.json(cards); res.json(cards);
} catch (err) { } catch (err) {
@ -73,31 +78,34 @@ router.get("/booster/cards", async (req, res) => {
5 gewichtete Zufallskarten inkl. Stats 5 gewichtete Zufallskarten inkl. Stats
================================ */ ================================ */
router.post("/booster/open", async (req, res) => { router.post("/booster/open", async (req, res) => {
if (!req.session?.user) return res.status(401).json({ error: "Nicht eingeloggt" }); if (!req.session?.user)
return res.status(401).json({ error: "Nicht eingeloggt" });
const userId = req.session.user.id; const userId = req.session.user.id;
try { try {
const [[account]] = await db.query( const [[account]] = await db.query(
"SELECT level FROM accounts WHERE id = ?", [userId] "SELECT level FROM accounts WHERE id = ?",
[userId],
); );
const playerLevel = account?.level ?? 1; const playerLevel = account?.level ?? 1;
const weights = getWeights(playerLevel); const weights = getWeights(playerLevel);
const maxAllowed = Math.max(...weights.map(w => w.rarity)); const maxAllowed = Math.max(...weights.map((w) => w.rarity));
const [allCards] = await db.query( const [allCards] = await db.query(
"SELECT id, name, image, icon, max_level, rarity, attack, defends, cooldown FROM cards WHERE rarity <= ?", "SELECT id, name, image, icon, max_level, rarity, attack, defends, cooldown FROM cards WHERE rarity <= ?",
[maxAllowed] [maxAllowed],
); );
if (!allCards.length) return res.status(400).json({ error: "Keine Karten verfügbar" }); if (!allCards.length)
return res.status(400).json({ error: "Keine Karten verfügbar" });
const result = []; const result = [];
for (let i = 0; i < 5; i++) { for (let i = 0; i < 5; i++) {
const targetRarity = weightedRandom(weights); const targetRarity = weightedRandom(weights);
let pool = allCards.filter(c => parseInt(c.rarity) === targetRarity); let pool = allCards.filter((c) => parseInt(c.rarity) === targetRarity);
if (!pool.length) { if (!pool.length) {
for (let fb = targetRarity - 1; fb >= 1; fb--) { for (let fb = targetRarity - 1; fb >= 1; fb--) {
pool = allCards.filter(c => parseInt(c.rarity) === fb); pool = allCards.filter((c) => parseInt(c.rarity) === fb);
if (pool.length) break; if (pool.length) break;
} }
} }
@ -118,9 +126,10 @@ router.post("/booster/open", async (req, res) => {
Body: { cardIds: [1, 2, 3, 4, 5] } Body: { cardIds: [1, 2, 3, 4, 5] }
================================ */ ================================ */
router.post("/booster/save", async (req, res) => { router.post("/booster/save", async (req, res) => {
if (!req.session?.user) return res.status(401).json({ error: "Nicht eingeloggt" }); if (!req.session?.user)
return res.status(401).json({ error: "Nicht eingeloggt" });
const userId = req.session.user.id; const userId = req.session.user.id;
const cardIds = req.body?.cardIds; const cardIds = req.body?.cardIds;
if (!Array.isArray(cardIds) || cardIds.length === 0) { if (!Array.isArray(cardIds) || cardIds.length === 0) {
@ -133,7 +142,7 @@ router.post("/booster/save", async (req, res) => {
`INSERT INTO user_cards (user_id, card_id, amount) `INSERT INTO user_cards (user_id, card_id, amount)
VALUES (?, ?, 1) VALUES (?, ?, 1)
ON DUPLICATE KEY UPDATE amount = amount + 1`, ON DUPLICATE KEY UPDATE amount = amount + 1`,
[userId, cardId] [userId, cardId],
); );
} }
res.json({ success: true }); res.json({ success: true });
@ -148,13 +157,15 @@ router.post("/booster/save", async (req, res) => {
100 Holz bezahlen 1 zufällige Rarity-3 Karte 100 Holz bezahlen 1 zufällige Rarity-3 Karte
================================ */ ================================ */
router.post("/booster/wood-donate", async (req, res) => { router.post("/booster/wood-donate", async (req, res) => {
if (!req.session?.user) return res.status(401).json({ error: "Nicht eingeloggt" }); if (!req.session?.user)
return res.status(401).json({ error: "Nicht eingeloggt" });
const userId = req.session.user.id; const userId = req.session.user.id;
try { try {
// Holz prüfen // Holz prüfen
const [[currency]] = await db.query( const [[currency]] = await db.query(
"SELECT wood FROM account_currency WHERE account_id = ?", [userId] "SELECT wood FROM account_currency WHERE account_id = ?",
[userId],
); );
if (!currency || currency.wood < 100) { if (!currency || currency.wood < 100) {
return res.status(400).json({ error: "Nicht genug Holz (100 benötigt)" }); return res.status(400).json({ error: "Nicht genug Holz (100 benötigt)" });
@ -162,13 +173,15 @@ router.post("/booster/wood-donate", async (req, res) => {
// Rarity-3 Karten laden // Rarity-3 Karten laden
const [pool] = await db.query( const [pool] = await db.query(
"SELECT id, name, image, icon, max_level, rarity, attack, defends, cooldown FROM cards WHERE rarity = 3" "SELECT id, name, image, icon, max_level, rarity, attack, defends, cooldown FROM cards WHERE rarity = 3",
); );
if (!pool.length) return res.status(400).json({ error: "Keine Rarity-3 Karten verfügbar" }); if (!pool.length)
return res.status(400).json({ error: "Keine Rarity-3 Karten verfügbar" });
// 100 Holz abziehen // 100 Holz abziehen
await db.query( await db.query(
"UPDATE account_currency SET wood = wood - 100 WHERE account_id = ?", [userId] "UPDATE account_currency SET wood = wood - 100 WHERE account_id = ?",
[userId],
); );
// 1 zufällige Rarity-3 Karte ziehen // 1 zufällige Rarity-3 Karte ziehen
@ -178,7 +191,7 @@ router.post("/booster/wood-donate", async (req, res) => {
await db.query( await db.query(
`INSERT INTO user_cards (user_id, card_id, amount) VALUES (?, ?, 1) `INSERT INTO user_cards (user_id, card_id, amount) VALUES (?, ?, 1)
ON DUPLICATE KEY UPDATE amount = amount + 1`, ON DUPLICATE KEY UPDATE amount = amount + 1`,
[userId, card.id] [userId, card.id],
); );
res.json({ card }); res.json({ card });
@ -190,27 +203,31 @@ router.post("/booster/wood-donate", async (req, res) => {
/* ================================ /* ================================
POST /api/booster/gold-donate POST /api/booster/gold-donate
100 Gold bezahlen 1 zufällige Rarity-3 Karte 100 Gold bezahlen 1 zufällige Rarity-4 Karte
================================ */ ================================ */
router.post("/booster/gold-donate", async (req, res) => { router.post("/booster/gold-donate", async (req, res) => {
if (!req.session?.user) return res.status(401).json({ error: "Nicht eingeloggt" }); if (!req.session?.user)
return res.status(401).json({ error: "Nicht eingeloggt" });
const userId = req.session.user.id; const userId = req.session.user.id;
try { try {
const [[currency]] = await db.query( const [[currency]] = await db.query(
"SELECT gold FROM account_currency WHERE account_id = ?", [userId] "SELECT gold FROM account_currency WHERE account_id = ?",
[userId],
); );
if (!currency || currency.gold < 100) { if (!currency || currency.gold < 100) {
return res.status(400).json({ error: "Nicht genug Gold (100 benötigt)" }); return res.status(400).json({ error: "Nicht genug Gold (100 benötigt)" });
} }
const [pool] = await db.query( const [pool] = await db.query(
"SELECT id, name, image, icon, max_level, rarity, attack, defends, cooldown FROM cards WHERE rarity = 3" "SELECT id, name, image, icon, max_level, rarity, attack, defends, cooldown FROM cards WHERE rarity = 4",
); );
if (!pool.length) return res.status(400).json({ error: "Keine Rarity-3 Karten verfügbar" }); if (!pool.length)
return res.status(400).json({ error: "Keine Rarity-4 Karten verfügbar" });
await db.query( await db.query(
"UPDATE account_currency SET gold = gold - 100 WHERE account_id = ?", [userId] "UPDATE account_currency SET gold = gold - 100 WHERE account_id = ?",
[userId],
); );
const card = pool[Math.floor(Math.random() * pool.length)]; const card = pool[Math.floor(Math.random() * pool.length)];
@ -218,7 +235,7 @@ router.post("/booster/gold-donate", async (req, res) => {
await db.query( await db.query(
`INSERT INTO user_cards (user_id, card_id, amount) VALUES (?, ?, 1) `INSERT INTO user_cards (user_id, card_id, amount) VALUES (?, ?, 1)
ON DUPLICATE KEY UPDATE amount = amount + 1`, ON DUPLICATE KEY UPDATE amount = amount + 1`,
[userId, card.id] [userId, card.id],
); );
res.json({ card }); res.json({ card });