dok/routes/mine_route.js
2026-03-16 12:29:44 +00:00

164 lines
4.9 KiB
JavaScript

const express = require("express");
const router = express.Router();
const db = require("../database/database");
const auth = require("../middleware/auth");
/* ─────────────────────────────────────────
GET /api/mine/:buildingId/status
Liefert Level, verfügbare Ressourcen
und Countdown bis zum nächsten Zyklus
───────────────────────────────────────── */
router.get("/:buildingId/status", auth, async (req, res) => {
const userId = req.session.user.id;
const buildingId = req.params.buildingId;
try {
const [rows] = await db.query(
`
SELECT
ub.id AS user_building_id,
ub.level,
bp.resource,
bp.amount,
bp.cycle_seconds,
COALESCE(bct.last_collected, NOW()) AS last_collected
FROM user_buildings ub
JOIN building_production bp
ON bp.building_id = ub.building_id
AND bp.level = ub.level
LEFT JOIN building_collect_timer bct
ON bct.user_building_id = ub.id
WHERE ub.user_id = ?
AND ub.building_id = ?
`,
[userId, buildingId]
);
if (!rows.length) {
return res.status(404).json({ error: "Gebäude nicht gefunden" });
}
const { cycle_seconds, last_collected, level } = rows[0];
const elapsed = Math.floor(
(Date.now() - new Date(last_collected).getTime()) / 1000
);
const cycles = Math.floor(elapsed / cycle_seconds);
const nextIn = cycle_seconds - (elapsed % cycle_seconds);
const available = rows.map((r) => ({
resource: r.resource,
amount: r.amount * cycles,
}));
res.json({
level,
cycles,
ready: cycles > 0,
available,
last_collected,
next_cycle_in_seconds: nextIn,
});
} catch (err) {
console.error(err);
res.status(500).json({ error: "DB Fehler" });
}
});
/* ─────────────────────────────────────────
POST /api/mine/:buildingId/collect
Schreibt Ressourcen gut, setzt Timer
───────────────────────────────────────── */
router.post("/:buildingId/collect", auth, async (req, res) => {
const userId = req.session.user.id;
const buildingId = req.params.buildingId;
try {
const [rows] = await db.query(
`
SELECT
ub.id AS user_building_id,
ub.level,
bp.resource,
bp.amount,
bp.cycle_seconds,
COALESCE(bct.last_collected, NOW()) AS last_collected
FROM user_buildings ub
JOIN building_production bp
ON bp.building_id = ub.building_id
AND bp.level = ub.level
LEFT JOIN building_collect_timer bct
ON bct.user_building_id = ub.id
WHERE ub.user_id = ?
AND ub.building_id = ?
`,
[userId, buildingId]
);
if (!rows.length) {
return res.status(404).json({ error: "Gebäude nicht gefunden" });
}
const { user_building_id, cycle_seconds, last_collected } = rows[0];
const elapsed = Math.floor(
(Date.now() - new Date(last_collected).getTime()) / 1000
);
const cycles = Math.floor(elapsed / cycle_seconds);
if (cycles < 1) {
const waitSeconds = cycle_seconds - elapsed;
const minutes = Math.floor(waitSeconds / 60);
const seconds = waitSeconds % 60;
return res.json({
error: "Noch nichts bereit",
ready_in_seconds: waitSeconds,
ready_in_display: `${minutes}m ${seconds}s`,
});
}
// Ressourcen gutschreiben
for (const row of rows) {
const toAdd = row.amount * cycles;
await db.query(
`
INSERT INTO account_currency (account_id, \`${row.resource}\`)
VALUES (?, ?)
ON DUPLICATE KEY UPDATE \`${row.resource}\` = \`${row.resource}\` + ?
`,
[userId, toAdd, toAdd]
);
}
// Timer vorsetzen — Rest-Sekunden bleiben erhalten, kein Verlust
const newLastCollected = new Date(
new Date(last_collected).getTime() + cycles * cycle_seconds * 1000
);
await db.query(
`
INSERT INTO building_collect_timer (user_building_id, last_collected)
VALUES (?, ?)
ON DUPLICATE KEY UPDATE last_collected = ?
`,
[user_building_id, newLastCollected, newLastCollected]
);
const collected = rows.map((r) => ({
resource: r.resource,
amount: r.amount * cycles,
}));
res.json({
success: true,
cycles,
collected,
});
} catch (err) {
console.error(err);
res.status(500).json({ error: "DB Fehler" });
}
});
module.exports = router;