xgzjkx
This commit is contained in:
parent
06eebb345d
commit
1550e581d7
248
routes/booster_route.js
Normal file
248
routes/booster_route.js
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
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.rarity;
|
||||||
|
}
|
||||||
|
return weights[weights.length - 1].rarity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================
|
||||||
|
Gewichte je Spielerlevel
|
||||||
|
================================ */
|
||||||
|
function getWeights(playerLevel) {
|
||||||
|
if (playerLevel < 10)
|
||||||
|
return [
|
||||||
|
{ rarity: 1, weight: 95 }, // 95%
|
||||||
|
{ rarity: 2, weight: 5 }, // 5%
|
||||||
|
];
|
||||||
|
if (playerLevel < 20)
|
||||||
|
return [
|
||||||
|
{ rarity: 1, weight: 87 }, // 87%
|
||||||
|
{ rarity: 2, weight: 11 }, // 11%
|
||||||
|
{ rarity: 3, weight: 2 }, // 2%
|
||||||
|
];
|
||||||
|
if (playerLevel < 30)
|
||||||
|
return [
|
||||||
|
{ rarity: 1, weight: 80 }, // 80%
|
||||||
|
{ rarity: 2, weight: 14 }, // 14%
|
||||||
|
{ rarity: 3, weight: 4 }, // 4%
|
||||||
|
{ rarity: 4, weight: 2 }, // 2%
|
||||||
|
];
|
||||||
|
if (playerLevel < 40)
|
||||||
|
return [
|
||||||
|
{ 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 [
|
||||||
|
{ rarity: 1, weight: 60 }, // 60.0%
|
||||||
|
{ rarity: 2, weight: 25 }, // 25.0%
|
||||||
|
{ rarity: 3, weight: 9 }, // 9.0%
|
||||||
|
{ rarity: 4, weight: 4 }, // 4.0%
|
||||||
|
{ rarity: 5, weight: 1.5 }, // 1.5%
|
||||||
|
{ rarity: 6, weight: 0.5 }, // 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, `range`, `race` 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.rarity));
|
||||||
|
|
||||||
|
const [allCards] = await db.query(
|
||||||
|
"SELECT id, name, image, icon, max_level, rarity, attack, defends, cooldown, `range`, `race` FROM cards WHERE rarity <= ?",
|
||||||
|
[maxAllowed],
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!allCards.length)
|
||||||
|
return res.status(400).json({ error: "Keine Karten verfügbar" });
|
||||||
|
|
||||||
|
const result = [];
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
const targetRarity = weightedRandom(weights);
|
||||||
|
let pool = allCards.filter((c) => parseInt(c.rarity) === targetRarity);
|
||||||
|
if (!pool.length) {
|
||||||
|
for (let fb = targetRarity - 1; fb >= 1; fb--) {
|
||||||
|
pool = allCards.filter((c) => parseInt(c.rarity) === 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" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ================================
|
||||||
|
POST /api/booster/save
|
||||||
|
Gezogene Karten in user_cards speichern
|
||||||
|
Body: { cardIds: [1, 2, 3, 4, 5] }
|
||||||
|
================================ */
|
||||||
|
router.post("/booster/save", async (req, res) => {
|
||||||
|
if (!req.session?.user)
|
||||||
|
return res.status(401).json({ error: "Nicht eingeloggt" });
|
||||||
|
|
||||||
|
const userId = req.session.user.id;
|
||||||
|
const cardIds = req.body?.cardIds;
|
||||||
|
|
||||||
|
if (!Array.isArray(cardIds) || cardIds.length === 0) {
|
||||||
|
return res.status(400).json({ error: "Keine Karten übergeben" });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (const cardId of cardIds) {
|
||||||
|
await db.query(
|
||||||
|
`INSERT INTO user_cards (user_id, card_id, amount)
|
||||||
|
VALUES (?, ?, 1)
|
||||||
|
ON DUPLICATE KEY UPDATE amount = amount + 1`,
|
||||||
|
[userId, cardId],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).json({ error: "DB Fehler beim Speichern" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ================================
|
||||||
|
POST /api/booster/wood-donate
|
||||||
|
100 Holz bezahlen → 1 zufällige Rarity-3 Karte
|
||||||
|
================================ */
|
||||||
|
router.post("/booster/wood-donate", async (req, res) => {
|
||||||
|
if (!req.session?.user)
|
||||||
|
return res.status(401).json({ error: "Nicht eingeloggt" });
|
||||||
|
|
||||||
|
const userId = req.session.user.id;
|
||||||
|
try {
|
||||||
|
// Holz prüfen
|
||||||
|
const [[currency]] = await db.query(
|
||||||
|
"SELECT wood FROM account_currency WHERE account_id = ?",
|
||||||
|
[userId],
|
||||||
|
);
|
||||||
|
if (!currency || currency.wood < 100) {
|
||||||
|
return res.status(400).json({ error: "Nicht genug Holz (100 benötigt)" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rarity-3 Karten laden
|
||||||
|
const [pool] = await db.query(
|
||||||
|
"SELECT id, name, image, icon, max_level, rarity, attack, defends, cooldown, `range`, `race` FROM cards WHERE rarity = 3",
|
||||||
|
);
|
||||||
|
if (!pool.length)
|
||||||
|
return res.status(400).json({ error: "Keine Rarity-3 Karten verfügbar" });
|
||||||
|
|
||||||
|
// 100 Holz abziehen
|
||||||
|
await db.query(
|
||||||
|
"UPDATE account_currency SET wood = wood - 100 WHERE account_id = ?",
|
||||||
|
[userId],
|
||||||
|
);
|
||||||
|
|
||||||
|
// 1 zufällige Rarity-3 Karte ziehen
|
||||||
|
const card = pool[Math.floor(Math.random() * pool.length)];
|
||||||
|
|
||||||
|
// Direkt in user_cards speichern
|
||||||
|
await db.query(
|
||||||
|
`INSERT INTO user_cards (user_id, card_id, amount) VALUES (?, ?, 1)
|
||||||
|
ON DUPLICATE KEY UPDATE amount = amount + 1`,
|
||||||
|
[userId, card.id],
|
||||||
|
);
|
||||||
|
|
||||||
|
res.json({ card });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).json({ error: "DB Fehler" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ================================
|
||||||
|
POST /api/booster/gold-donate
|
||||||
|
100 Gold bezahlen → 1 zufällige Rarity-4 Karte
|
||||||
|
================================ */
|
||||||
|
router.post("/booster/gold-donate", async (req, res) => {
|
||||||
|
if (!req.session?.user)
|
||||||
|
return res.status(401).json({ error: "Nicht eingeloggt" });
|
||||||
|
|
||||||
|
const userId = req.session.user.id;
|
||||||
|
try {
|
||||||
|
const [[currency]] = await db.query(
|
||||||
|
"SELECT gold FROM account_currency WHERE account_id = ?",
|
||||||
|
[userId],
|
||||||
|
);
|
||||||
|
if (!currency || currency.gold < 100) {
|
||||||
|
return res.status(400).json({ error: "Nicht genug Gold (100 benötigt)" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const [pool] = await db.query(
|
||||||
|
"SELECT id, name, image, icon, max_level, rarity, attack, defends, cooldown, `range`, `race` FROM cards WHERE rarity = 4",
|
||||||
|
);
|
||||||
|
if (!pool.length)
|
||||||
|
return res.status(400).json({ error: "Keine Rarity-4 Karten verfügbar" });
|
||||||
|
|
||||||
|
await db.query(
|
||||||
|
"UPDATE account_currency SET gold = gold - 100 WHERE account_id = ?",
|
||||||
|
[userId],
|
||||||
|
);
|
||||||
|
|
||||||
|
const card = pool[Math.floor(Math.random() * pool.length)];
|
||||||
|
|
||||||
|
await db.query(
|
||||||
|
`INSERT INTO user_cards (user_id, card_id, amount) VALUES (?, ?, 1)
|
||||||
|
ON DUPLICATE KEY UPDATE amount = amount + 1`,
|
||||||
|
[userId, card.id],
|
||||||
|
);
|
||||||
|
|
||||||
|
res.json({ card });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).json({ error: "DB Fehler" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
332
routes/carddeck_route.js
Normal file
332
routes/carddeck_route.js
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
const express = require("express");
|
||||||
|
const router = express.Router();
|
||||||
|
const db = require("../database/database");
|
||||||
|
|
||||||
|
/* ========================
|
||||||
|
Auth Middleware
|
||||||
|
======================== */
|
||||||
|
|
||||||
|
function requireLogin(req, res, next) {
|
||||||
|
if (!req.session.user) return res.status(401).json({ error: "Nicht eingeloggt" });
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
router.use(requireLogin);
|
||||||
|
|
||||||
|
/* ════════════════════════════════════════════
|
||||||
|
GET /api/card-groups
|
||||||
|
Alle Kartengruppen
|
||||||
|
════════════════════════════════════════════ */
|
||||||
|
|
||||||
|
router.get("/card-groups", async (req, res) => {
|
||||||
|
try {
|
||||||
|
const [groups] = await db.query("SELECT * FROM card_groups ORDER BY id");
|
||||||
|
res.json(groups);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).json({ error: "DB Fehler" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ════════════════════════════════════════════
|
||||||
|
GET /api/cards?group_id=X&page=Y&limit=Z
|
||||||
|
Alle Karten (Admin-/Gruppen-Ansicht, kein Besitz)
|
||||||
|
════════════════════════════════════════════ */
|
||||||
|
|
||||||
|
router.get("/cards", async (req, res) => {
|
||||||
|
const { group_id, page = 1, limit = 12 } = req.query;
|
||||||
|
const offset = (page - 1) * limit;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const [cards] = await db.query(
|
||||||
|
`SELECT c.*, cg.name AS group_name, cg.color AS group_color,
|
||||||
|
c.attack, c.defends, c.cooldown, c.\`range\`, c.\`race\`
|
||||||
|
FROM cards c
|
||||||
|
LEFT JOIN card_groups cg ON cg.id = c.group_id
|
||||||
|
WHERE c.group_id = ?
|
||||||
|
LIMIT ? OFFSET ?`,
|
||||||
|
[group_id, parseInt(limit), parseInt(offset)]
|
||||||
|
);
|
||||||
|
const [[{ total }]] = await db.query(
|
||||||
|
"SELECT COUNT(*) AS total FROM cards WHERE group_id = ?",
|
||||||
|
[group_id]
|
||||||
|
);
|
||||||
|
res.json({ cards, total, page: parseInt(page), totalPages: Math.ceil(total / limit) });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).json({ error: "DB Fehler" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ════════════════════════════════════════════
|
||||||
|
GET /api/user-cards?group_id=X&page=Y&limit=Z
|
||||||
|
Karten die der Spieler besitzt (mit amount)
|
||||||
|
════════════════════════════════════════════ */
|
||||||
|
|
||||||
|
router.get("/user-cards", async (req, res) => {
|
||||||
|
const userId = req.session.user.id;
|
||||||
|
const { group_id, page = 1, limit = 18 } = req.query;
|
||||||
|
const offset = (page - 1) * limit;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const [cards] = await db.query(
|
||||||
|
`SELECT
|
||||||
|
uc.card_id,
|
||||||
|
uc.amount,
|
||||||
|
c.name,
|
||||||
|
c.image,
|
||||||
|
c.rarity,
|
||||||
|
cg.name AS group_name,
|
||||||
|
cg.color AS group_color,
|
||||||
|
c.attack,
|
||||||
|
c.defends,
|
||||||
|
c.cooldown,
|
||||||
|
c.`range`,
|
||||||
|
c.`race`
|
||||||
|
FROM user_cards uc
|
||||||
|
JOIN cards c ON c.id = uc.card_id
|
||||||
|
JOIN card_groups cg ON cg.id = c.group_id
|
||||||
|
WHERE uc.user_id = ? AND c.group_id = ?
|
||||||
|
ORDER BY c.id
|
||||||
|
LIMIT ? OFFSET ?`,
|
||||||
|
[userId, group_id, parseInt(limit), parseInt(offset)]
|
||||||
|
);
|
||||||
|
|
||||||
|
const [[{ total }]] = await db.query(
|
||||||
|
`SELECT COUNT(*) AS total
|
||||||
|
FROM user_cards uc
|
||||||
|
JOIN cards c ON c.id = uc.card_id
|
||||||
|
WHERE uc.user_id = ? AND c.group_id = ?`,
|
||||||
|
[userId, group_id]
|
||||||
|
);
|
||||||
|
|
||||||
|
res.json({ cards, total, page: parseInt(page), totalPages: Math.ceil(total / limit) });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).json({ error: "DB Fehler" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ════════════════════════════════════════════
|
||||||
|
GET /api/decks
|
||||||
|
Alle Decks des Spielers
|
||||||
|
════════════════════════════════════════════ */
|
||||||
|
|
||||||
|
router.get("/decks", async (req, res) => {
|
||||||
|
const userId = req.session.user.id;
|
||||||
|
try {
|
||||||
|
const [decks] = await db.query(
|
||||||
|
`SELECT d.id, d.name,
|
||||||
|
COALESCE(SUM(dc.amount), 0) AS card_count
|
||||||
|
FROM decks d
|
||||||
|
LEFT JOIN deck_cards dc ON dc.deck_id = d.id
|
||||||
|
WHERE d.user_id = ?
|
||||||
|
GROUP BY d.id
|
||||||
|
ORDER BY d.created_at`,
|
||||||
|
[userId]
|
||||||
|
);
|
||||||
|
res.json(decks);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).json({ error: "DB Fehler" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ════════════════════════════════════════════
|
||||||
|
POST /api/decks { name }
|
||||||
|
Neues Deck erstellen (max. 10 pro Spieler)
|
||||||
|
════════════════════════════════════════════ */
|
||||||
|
|
||||||
|
router.post("/decks", async (req, res) => {
|
||||||
|
const userId = req.session.user.id;
|
||||||
|
const { name } = req.body;
|
||||||
|
|
||||||
|
if (!name || !name.trim()) {
|
||||||
|
return res.status(400).json({ error: "Name darf nicht leer sein." });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const [[{ count }]] = await db.query(
|
||||||
|
"SELECT COUNT(*) AS count FROM decks WHERE user_id = ?",
|
||||||
|
[userId]
|
||||||
|
);
|
||||||
|
if (count >= 10) {
|
||||||
|
return res.status(400).json({ error: "Maximale Anzahl von 10 Decks erreicht." });
|
||||||
|
}
|
||||||
|
|
||||||
|
const [result] = await db.query(
|
||||||
|
"INSERT INTO decks (user_id, name) VALUES (?, ?)",
|
||||||
|
[userId, name.trim()]
|
||||||
|
);
|
||||||
|
res.status(201).json({ id: result.insertId, name: name.trim(), card_count: 0 });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).json({ error: "DB Fehler" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ════════════════════════════════════════════
|
||||||
|
GET /api/decks/:id/cards
|
||||||
|
Karten eines bestimmten Decks
|
||||||
|
════════════════════════════════════════════ */
|
||||||
|
|
||||||
|
router.get("/decks/:id/cards", async (req, res) => {
|
||||||
|
const userId = req.session.user.id;
|
||||||
|
const deckId = req.params.id;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Deck gehört dem Spieler?
|
||||||
|
const [[deck]] = await db.query(
|
||||||
|
"SELECT id FROM decks WHERE id = ? AND user_id = ?",
|
||||||
|
[deckId, userId]
|
||||||
|
);
|
||||||
|
if (!deck) return res.status(404).json({ error: "Deck nicht gefunden." });
|
||||||
|
|
||||||
|
const [cards] = await db.query(
|
||||||
|
`SELECT
|
||||||
|
dc.card_id,
|
||||||
|
dc.amount,
|
||||||
|
c.name,
|
||||||
|
c.image,
|
||||||
|
c.rarity,
|
||||||
|
c.attack,
|
||||||
|
c.defends,
|
||||||
|
c.cooldown,
|
||||||
|
c.`range`,
|
||||||
|
c.`race`
|
||||||
|
FROM deck_cards dc
|
||||||
|
JOIN cards c ON c.id = dc.card_id
|
||||||
|
WHERE dc.deck_id = ?
|
||||||
|
ORDER BY c.name`,
|
||||||
|
[deckId]
|
||||||
|
);
|
||||||
|
res.json(cards);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).json({ error: "DB Fehler" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ════════════════════════════════════════════
|
||||||
|
POST /api/decks/:id/cards { card_id, level }
|
||||||
|
Karte zum Deck hinzufügen
|
||||||
|
════════════════════════════════════════════ */
|
||||||
|
|
||||||
|
router.post("/decks/:id/cards", async (req, res) => {
|
||||||
|
const userId = req.session.user.id;
|
||||||
|
const deckId = req.params.id;
|
||||||
|
const { card_id } = req.body;
|
||||||
|
|
||||||
|
if (!card_id) return res.status(400).json({ error: "card_id fehlt." });
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Deck gehört dem Spieler?
|
||||||
|
const [[deck]] = await db.query(
|
||||||
|
"SELECT id FROM decks WHERE id = ? AND user_id = ?",
|
||||||
|
[deckId, userId]
|
||||||
|
);
|
||||||
|
if (!deck) return res.status(404).json({ error: "Deck nicht gefunden." });
|
||||||
|
|
||||||
|
// Besitzt der Spieler diese Karte?
|
||||||
|
const [[owned]] = await db.query(
|
||||||
|
"SELECT amount FROM user_cards WHERE user_id = ? AND card_id = ?",
|
||||||
|
[userId, card_id]
|
||||||
|
);
|
||||||
|
if (!owned) return res.status(400).json({ error: "Du besitzt diese Karte nicht." });
|
||||||
|
|
||||||
|
// Deck-Gesamtzahl prüfen (max 30)
|
||||||
|
const [[{ total }]] = await db.query(
|
||||||
|
"SELECT COALESCE(SUM(amount), 0) AS total FROM deck_cards WHERE deck_id = ?",
|
||||||
|
[deckId]
|
||||||
|
);
|
||||||
|
if (total >= 30) {
|
||||||
|
return res.status(400).json({ error: "Deck ist voll (max. 30 Karten)." });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rarity > 5: max. 1× im Deck
|
||||||
|
const [[cardInfo]] = await db.query(
|
||||||
|
"SELECT rarity FROM cards WHERE id = ?",
|
||||||
|
[card_id]
|
||||||
|
);
|
||||||
|
const [[existing]] = await db.query(
|
||||||
|
"SELECT amount FROM deck_cards WHERE deck_id = ? AND card_id = ?",
|
||||||
|
[deckId, card_id]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (parseInt(cardInfo?.rarity) > 5 && existing) {
|
||||||
|
return res.status(400).json({ error: "Karten ab Rarity 6 dürfen nur einmal im Deck sein." });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nicht mehr einfügen als besessen
|
||||||
|
const currentInDeck = existing ? existing.amount : 0;
|
||||||
|
if (currentInDeck >= owned.amount) {
|
||||||
|
return res.status(400).json({ error: "Du hast keine weiteren Exemplare dieser Karte." });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Einfügen oder erhöhen
|
||||||
|
if (existing) {
|
||||||
|
await db.query(
|
||||||
|
"UPDATE deck_cards SET amount = amount + 1 WHERE deck_id = ? AND card_id = ?",
|
||||||
|
[deckId, card_id]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await db.query(
|
||||||
|
"INSERT INTO deck_cards (deck_id, card_id, amount) VALUES (?, ?, 1)",
|
||||||
|
[deckId, card_id]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch (err) {
|
||||||
|
// DB-Trigger Fehler (45000) sauber weitergeben
|
||||||
|
if (err.sqlState === "45000") {
|
||||||
|
return res.status(400).json({ error: err.message });
|
||||||
|
}
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).json({ error: "DB Fehler" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ════════════════════════════════════════════
|
||||||
|
DELETE /api/decks/:id/cards { card_id, level }
|
||||||
|
Karte aus Deck entfernen (amount - 1, bei 0 löschen)
|
||||||
|
════════════════════════════════════════════ */
|
||||||
|
|
||||||
|
router.delete("/decks/:id/cards", async (req, res) => {
|
||||||
|
const userId = req.session.user.id;
|
||||||
|
const deckId = req.params.id;
|
||||||
|
const { card_id } = req.body;
|
||||||
|
|
||||||
|
if (!card_id) return res.status(400).json({ error: "card_id fehlt." });
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Deck gehört dem Spieler?
|
||||||
|
const [[deck]] = await db.query(
|
||||||
|
"SELECT id FROM decks WHERE id = ? AND user_id = ?",
|
||||||
|
[deckId, userId]
|
||||||
|
);
|
||||||
|
if (!deck) return res.status(404).json({ error: "Deck nicht gefunden." });
|
||||||
|
|
||||||
|
const [[entry]] = await db.query(
|
||||||
|
"SELECT id, amount FROM deck_cards WHERE deck_id = ? AND card_id = ?",
|
||||||
|
[deckId, card_id]
|
||||||
|
);
|
||||||
|
if (!entry) return res.status(404).json({ error: "Karte nicht im Deck." });
|
||||||
|
|
||||||
|
if (entry.amount > 1) {
|
||||||
|
await db.query(
|
||||||
|
"UPDATE deck_cards SET amount = amount - 1 WHERE id = ?",
|
||||||
|
[entry.id]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await db.query("DELETE FROM deck_cards WHERE id = ?", [entry.id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).json({ error: "DB Fehler" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
Loading…
Reference in New Issue
Block a user