mine update

This commit is contained in:
Cay 2026-03-16 12:50:00 +00:00
parent d72fcb2fe7
commit 56cfcb2de1

View File

@ -1,18 +1,32 @@
const express = require("express"); const express = require("express");
const router = express.Router(); const router = require("express").Router();
const db = require("../database/database"); const db = require("../database/database");
const auth = require("../middleware/auth"); const auth = require("../middleware/auth");
/* /*
GET /api/mine/:buildingId/status HELPER: Timer sicherstellen
Liefert Level, verfügbare Ressourcen Legt beim allerersten Aufruf einen
und Countdown bis zum nächsten Zyklus Eintrag an laeuft dann fuer immer durch.
Wird NUR durch collect() zurueckgesetzt.
*/ */
router.get("/:buildingId/status", auth, async (req, res) => { async function ensureTimer(userBuildingId) {
const userId = req.session.user.id; const [[existing]] = await db.query(
const buildingId = req.params.buildingId; "SELECT last_collected FROM building_collect_timer WHERE user_building_id = ?",
[userBuildingId]
);
if (!existing) {
await db.query(
"INSERT INTO building_collect_timer (user_building_id, last_collected) VALUES (?, NOW())",
[userBuildingId]
);
}
}
try { /*
HELPER: Produktionsdaten laden
Gibt immer last_collected aus der DB
*/
async function loadMineData(userId, buildingId) {
const [rows] = await db.query( const [rows] = await db.query(
` `
SELECT SELECT
@ -21,28 +35,50 @@ router.get("/:buildingId/status", auth, async (req, res) => {
bp.resource, bp.resource,
bp.amount, bp.amount,
bp.cycle_seconds, bp.cycle_seconds,
COALESCE(bct.last_collected, NOW()) AS last_collected bct.last_collected
FROM user_buildings ub FROM user_buildings ub
JOIN building_production bp JOIN building_production bp
ON bp.building_id = ub.building_id ON bp.building_id = ub.building_id
AND bp.level = ub.level AND bp.level = ub.level
LEFT JOIN building_collect_timer bct JOIN building_collect_timer bct
ON bct.user_building_id = ub.id ON bct.user_building_id = ub.id
WHERE ub.user_id = ? WHERE ub.user_id = ?
AND ub.building_id = ? AND ub.building_id = ?
`, `,
[userId, buildingId] [userId, buildingId]
); );
return rows;
}
/*
GET /api/mine/:buildingId/status
*/
router.get("/:buildingId/status", auth, async (req, res) => {
const userId = req.session.user.id;
const buildingId = req.params.buildingId;
try {
// user_building holen
const [[userBuilding]] = await db.query(
"SELECT id, level FROM user_buildings WHERE user_id = ? AND building_id = ?",
[userId, buildingId]
);
if (!userBuilding) {
return res.status(404).json({ error: "Gebaeude nicht gefunden" });
}
// Timer einmalig starten falls noch nie geoeffnet
await ensureTimer(userBuilding.id);
const rows = await loadMineData(userId, buildingId);
if (!rows.length) { if (!rows.length) {
return res.status(404).json({ error: "Gebäude nicht gefunden" }); return res.status(404).json({ error: "Gebaeude nicht gefunden" });
} }
const { cycle_seconds, last_collected, level } = rows[0]; const { cycle_seconds, last_collected, level } = rows[0];
const elapsed = Math.floor( const elapsed = Math.floor((Date.now() - new Date(last_collected).getTime()) / 1000);
(Date.now() - new Date(last_collected).getTime()) / 1000
);
const cycles = Math.floor(elapsed / cycle_seconds); const cycles = Math.floor(elapsed / cycle_seconds);
const nextIn = cycle_seconds - (elapsed % cycle_seconds); const nextIn = cycle_seconds - (elapsed % cycle_seconds);
@ -59,6 +95,7 @@ router.get("/:buildingId/status", auth, async (req, res) => {
last_collected, last_collected,
next_cycle_in_seconds: nextIn, next_cycle_in_seconds: nextIn,
}); });
} catch (err) { } catch (err) {
console.error(err); console.error(err);
res.status(500).json({ error: "DB Fehler" }); res.status(500).json({ error: "DB Fehler" });
@ -67,43 +104,34 @@ router.get("/:buildingId/status", auth, async (req, res) => {
/* /*
POST /api/mine/:buildingId/collect POST /api/mine/:buildingId/collect
Schreibt Ressourcen gut, setzt Timer Ressourcen gutschreiben + Timer reset
*/ */
router.post("/:buildingId/collect", auth, async (req, res) => { router.post("/:buildingId/collect", auth, async (req, res) => {
const userId = req.session.user.id; const userId = req.session.user.id;
const buildingId = req.params.buildingId; const buildingId = req.params.buildingId;
try { try {
const [rows] = await db.query( // user_building holen
` const [[userBuilding]] = await db.query(
SELECT "SELECT id FROM user_buildings WHERE user_id = ? AND building_id = ?",
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] [userId, buildingId]
); );
if (!userBuilding) {
return res.status(404).json({ error: "Gebaeude nicht gefunden" });
}
// Timer sicherstellen (Fallback falls Status nie aufgerufen wurde)
await ensureTimer(userBuilding.id);
const rows = await loadMineData(userId, buildingId);
if (!rows.length) { if (!rows.length) {
return res.status(404).json({ error: "Gebäude nicht gefunden" }); return res.status(404).json({ error: "Gebaeude nicht gefunden" });
} }
const { user_building_id, cycle_seconds, last_collected } = rows[0]; const { user_building_id, cycle_seconds, last_collected } = rows[0];
const elapsed = Math.floor( const elapsed = Math.floor((Date.now() - new Date(last_collected).getTime()) / 1000);
(Date.now() - new Date(last_collected).getTime()) / 1000
);
const cycles = Math.floor(elapsed / cycle_seconds); const cycles = Math.floor(elapsed / cycle_seconds);
if (cycles < 1) { if (cycles < 1) {
@ -121,27 +149,20 @@ router.post("/:buildingId/collect", auth, async (req, res) => {
for (const row of rows) { for (const row of rows) {
const toAdd = row.amount * cycles; const toAdd = row.amount * cycles;
await db.query( await db.query(
` "INSERT INTO account_currency (account_id, `" + row.resource + "`) VALUES (?, ?) ON DUPLICATE KEY UPDATE `" + row.resource + "` = `" + row.resource + "` + ?",
INSERT INTO account_currency (account_id, \`${row.resource}\`)
VALUES (?, ?)
ON DUPLICATE KEY UPDATE \`${row.resource}\` = \`${row.resource}\` + ?
`,
[userId, toAdd, toAdd] [userId, toAdd, toAdd]
); );
} }
// Timer vorsetzen — Rest-Sekunden bleiben erhalten, kein Verlust // Timer zuruecksetzen: last_collected um genau die abgeschlossenen
// Zyklen vorruecken Restsekunden bleiben erhalten, kein Verlust
const newLastCollected = new Date( const newLastCollected = new Date(
new Date(last_collected).getTime() + cycles * cycle_seconds * 1000 new Date(last_collected).getTime() + cycles * cycle_seconds * 1000
); );
await db.query( await db.query(
` "UPDATE building_collect_timer SET last_collected = ? WHERE user_building_id = ?",
INSERT INTO building_collect_timer (user_building_id, last_collected) [newLastCollected, user_building_id]
VALUES (?, ?)
ON DUPLICATE KEY UPDATE last_collected = ?
`,
[user_building_id, newLastCollected, newLastCollected]
); );
const collected = rows.map((r) => ({ const collected = rows.map((r) => ({
@ -149,11 +170,8 @@ router.post("/:buildingId/collect", auth, async (req, res) => {
amount: r.amount * cycles, amount: r.amount * cycles,
})); }));
res.json({ res.json({ success: true, cycles, collected });
success: true,
cycles,
collected,
});
} catch (err) { } catch (err) {
console.error(err); console.error(err);
res.status(500).json({ error: "DB Fehler" }); res.status(500).json({ error: "DB Fehler" });