rsthj
This commit is contained in:
parent
bcbeff5f10
commit
57910a9392
37
app.js
37
app.js
@ -22,6 +22,7 @@ const equip = require("./routes/equip");
|
||||
const equipment = require("./routes/equipment");
|
||||
const blackmarket = require("./routes/blackmarket");
|
||||
const mineRoute = require("./routes/mine");
|
||||
const carddeckRoutes = require("./routes/carddeck");
|
||||
const arenaRoutes = require("./routes/arena");
|
||||
const { registerArenaHandlers } = require("./sockets/arena");
|
||||
const { registerChatHandlers } = require("./sockets/chat");
|
||||
@ -297,44 +298,9 @@ app.get("/api/buildings", requireLogin, async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
/* ========================
|
||||
Card Groups API
|
||||
======================== */
|
||||
|
||||
app.get("/api/card-groups", requireLogin, 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" });
|
||||
}
|
||||
});
|
||||
|
||||
/* ========================
|
||||
Cards API
|
||||
======================== */
|
||||
|
||||
app.get("/api/cards", requireLogin, 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,
|
||||
cl.attack, cl.defense, cl.cooldown
|
||||
FROM cards c
|
||||
LEFT JOIN card_groups cg ON cg.id = c.group_id
|
||||
LEFT JOIN card_levels cl ON cl.card_id = c.id AND cl.level = 1
|
||||
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" });
|
||||
@ -367,6 +333,7 @@ app.use("/api/equip", equip);
|
||||
app.use("/api/equipment", equipment);
|
||||
app.use("/api/blackmarket", blackmarket);
|
||||
app.use("/api/mine", mineRoute);
|
||||
app.use("/api", carddeckRoutes);
|
||||
app.use("/arena", arenaRoutes);
|
||||
|
||||
/* ========================
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
326
routes/carddeck.route.js
Normal file
326
routes/carddeck.route.js
Normal file
@ -0,0 +1,326 @@
|
||||
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,
|
||||
cl.attack, cl.defense, cl.cooldown
|
||||
FROM cards c
|
||||
LEFT JOIN card_groups cg ON cg.id = c.group_id
|
||||
LEFT JOIN card_levels cl ON cl.card_id = c.id AND cl.level = 1
|
||||
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.level,
|
||||
uc.amount,
|
||||
c.name,
|
||||
c.image,
|
||||
cg.name AS group_name,
|
||||
cg.color AS group_color,
|
||||
cl.attack,
|
||||
cl.defense,
|
||||
cl.cooldown
|
||||
FROM user_cards uc
|
||||
JOIN cards c ON c.id = uc.card_id
|
||||
JOIN card_groups cg ON cg.id = c.group_id
|
||||
LEFT JOIN card_levels cl ON cl.card_id = uc.card_id AND cl.level = uc.level
|
||||
WHERE uc.user_id = ? AND c.group_id = ?
|
||||
ORDER BY c.id, uc.level
|
||||
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.level,
|
||||
dc.amount,
|
||||
c.name,
|
||||
c.image,
|
||||
cl.attack,
|
||||
cl.defense
|
||||
FROM deck_cards dc
|
||||
JOIN cards c ON c.id = dc.card_id
|
||||
LEFT JOIN card_levels cl ON cl.card_id = dc.card_id AND cl.level = dc.level
|
||||
WHERE dc.deck_id = ?
|
||||
ORDER BY c.name, dc.level`,
|
||||
[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, level = 1 } = 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 mit diesem Level?
|
||||
const [[owned]] = await db.query(
|
||||
"SELECT amount FROM user_cards WHERE user_id = ? AND card_id = ? AND level = ?",
|
||||
[userId, card_id, level]
|
||||
);
|
||||
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)." });
|
||||
}
|
||||
|
||||
// Level > 5: max. 1× im Deck
|
||||
const [[existing]] = await db.query(
|
||||
"SELECT amount FROM deck_cards WHERE deck_id = ? AND card_id = ? AND level = ?",
|
||||
[deckId, card_id, level]
|
||||
);
|
||||
|
||||
if (level > 5 && existing) {
|
||||
return res.status(400).json({ error: "Karten ab Level 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 = ? AND level = ?",
|
||||
[deckId, card_id, level]
|
||||
);
|
||||
} else {
|
||||
await db.query(
|
||||
"INSERT INTO deck_cards (deck_id, card_id, level, amount) VALUES (?, ?, ?, 1)",
|
||||
[deckId, card_id, level]
|
||||
);
|
||||
}
|
||||
|
||||
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, level = 1 } = 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 = ? AND level = ?",
|
||||
[deckId, card_id, level]
|
||||
);
|
||||
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