änderungen durch AI

This commit is contained in:
Cay 2026-03-15 10:24:21 +00:00
parent fb73aa59dd
commit 81d17c4da5
9 changed files with 149 additions and 80 deletions

2
.env
View File

@ -10,3 +10,5 @@ OFFLINE_SERVER_1=Test Server Alpha
OFFLINE_SERVER_2=Test Server Beta OFFLINE_SERVER_2=Test Server Beta
APP_URL=https://spiel.dynastyofknights.com APP_URL=https://spiel.dynastyofknights.com
SESSION_SECRET=irgendein_langer_geheimer_zufallstext_123!

21
app.js
View File

@ -22,6 +22,8 @@ const equip = require("./routes/equip");
const equipment = require("./routes/equipment"); const equipment = require("./routes/equipment");
const blackmarket = require("./routes/blackmarket"); const blackmarket = require("./routes/blackmarket");
const compression = require("compression");
const app = express(); const app = express();
app.set("trust proxy", 1); app.set("trust proxy", 1);
const PORT = process.env.PORT || 3000; const PORT = process.env.PORT || 3000;
@ -33,6 +35,12 @@ const PORT = process.env.PORT || 3000;
const server = http.createServer(app); const server = http.createServer(app);
const io = new Server(server); const io = new Server(server);
/* ========================
Compression
======================== */
app.use(compression());
/* ======================== /* ========================
Security Middleware Security Middleware
======================== */ ======================== */
@ -60,9 +68,14 @@ app.use(limiter);
app.use( app.use(
session({ session({
secret: "dynastyofknights_secret", secret: process.env.SESSION_SECRET || "dynastyofknights_secret",
resave: false, resave: false,
saveUninitialized: false, saveUninitialized: false,
cookie: {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
maxAge: 1000 * 60 * 60 * 24,
},
}), }),
); );
@ -204,12 +217,6 @@ app.use((req, res) => {
res.status(404).send("Seite nicht gefunden"); res.status(404).send("Seite nicht gefunden");
}); });
/* ========================
Webseite beschleunigen
======================== */
const compression = require("compression");
app.use(compression());
/* ======================== /* ========================
Chat System Chat System
======================== */ ======================== */

View File

@ -474,7 +474,7 @@ body {
filter: brightness(1.3); filter: brightness(1.3);
} }
.equip-slot:empty { .equip-slot:not(:has(img)) {
opacity: 0.7; opacity: 0.7;
} }
@ -507,11 +507,24 @@ body {
#item-tooltip { #item-tooltip {
position: fixed; position: fixed;
background: #111; pointer-events: none;
border: 1px solid #555;
padding: 6px; background: rgba(0, 0, 0, 0.85);
color: white; color: #fff;
padding: 8px 12px;
border-radius: 6px;
font-size: 14px;
display: none; display: none;
z-index: 9999;
max-width: 200px;
border: 1px solid #555;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
} }
/* ========================= /* =========================
@ -533,14 +546,6 @@ body {
/* ========================= /* =========================
Schwarzmarkt Schwarzmarkt
========================= */ ========================= */
#market-pages {
display: flex;
flex-direction: column;
gap: 8px;
margin-top: 15px;
}
.market-page { .market-page {
padding: 8px 12px; padding: 8px 12px;
@ -622,6 +627,8 @@ body {
justify-content: center; justify-content: center;
margin-top: 15px; margin-top: 15px;
/* Ehemals doppelt definiert zusammengeführt */
} }
.bag-icon { .bag-icon {

View File

@ -42,18 +42,22 @@ Geheimhandel
} }
async function loadPages() { async function loadPages() {
const res = await fetch("/api/blackmarket/pages"); try {
const data = await res.json(); const res = await fetch("/api/blackmarket/pages");
const container = document.getElementById("market-pages"); if (!res.ok) throw new Error("API Fehler");
let html = ""; const data = await res.json();
for (let i = 1; i <= data.maxPages; i++) { const container = document.getElementById("market-pages");
const price = data.prices.find((p) => p.page === i);
if (data.ownedPages.includes(i)) { let html = "";
html += `
for (let i = 1; i <= data.maxPages; i++) {
const price = data.prices.find((p) => p.page === i);
if (data.ownedPages.includes(i)) {
html += `
<div class="market-slot owned"> <div class="market-slot owned">
<img src="/images/items/beutel.png" class="bag-icon"> <img src="/images/items/beutel.png" class="bag-icon">
@ -64,8 +68,8 @@ async function loadPages() {
</div> </div>
`; `;
} else if (price) { } else if (price) {
html += ` html += `
<div class="market-slot buy" data-page="${i}"> <div class="market-slot buy" data-page="${i}">
<img src="/images/items/beutel.png" class="bag-icon"> <img src="/images/items/beutel.png" class="bag-icon">
@ -80,8 +84,8 @@ Kaufen
</div> </div>
`; `;
} else { } else {
html += ` html += `
<div class="market-slot locked"> <div class="market-slot locked">
<img src="/images/items/beutel.png" class="bag-icon"> <img src="/images/items/beutel.png" class="bag-icon">
@ -92,10 +96,13 @@ Kaufen
</div> </div>
`; `;
}
} }
}
container.innerHTML = html; container.innerHTML = html;
} catch (err) {
console.error("Schwarzmarkt Fehler:", err);
}
} }
/* Kaufen */ /* Kaufen */
@ -109,22 +116,29 @@ document.addEventListener("click", async (e) => {
const page = slot.dataset.page; const page = slot.dataset.page;
const res = await fetch("/api/blackmarket/buy-page", { try {
method: "POST", const res = await fetch("/api/blackmarket/buy-page", {
headers: { method: "POST",
"Content-Type": "application/json", headers: {
}, "Content-Type": "application/json",
body: JSON.stringify({ page }), },
}); body: JSON.stringify({ page }),
});
const data = await res.json(); if (!res.ok) throw new Error("API Fehler");
if (data.error) { const data = await res.json();
alert(data.error);
return; if (data.error) {
alert(data.error);
return;
}
loadPages();
} catch (err) {
console.error("Kauf Fehler:", err);
alert("Fehler beim Kauf. Bitte erneut versuchen.");
} }
loadPages();
}); });
/* Tabs */ /* Tabs */

View File

@ -159,8 +159,15 @@ function initInventoryButtons() {
}; };
document.getElementById("inv-right").onclick = () => { document.getElementById("inv-right").onclick = () => {
inventoryPage++; const totalPages = Math.max(
renderInventory(); 1,
Math.ceil(inventoryItems.length / slotsPerPage),
);
if (inventoryPage < totalPages - 1) {
inventoryPage++;
renderInventory();
}
}; };
} }

View File

@ -4,6 +4,8 @@ const popup = document.getElementById("building-popup");
const title = document.getElementById("popup-title"); const title = document.getElementById("popup-title");
const tooltip = document.getElementById("map-tooltip"); const tooltip = document.getElementById("map-tooltip");
const tooltipCache = {};
const buildingModules = { const buildingModules = {
11: loadWohnhaus, 11: loadWohnhaus,
12: loadSchwarzmarkt, 12: loadSchwarzmarkt,
@ -136,11 +138,15 @@ document.querySelectorAll(".building").forEach((building) => {
try { try {
const id = building.dataset.id; const id = building.dataset.id;
const res = await fetch("/api/building/" + id); if (!tooltipCache[id]) {
const res = await fetch("/api/building/" + id);
if (!res.ok) throw new Error("API Fehler"); if (!res.ok) throw new Error("API Fehler");
const data = await res.json(); tooltipCache[id] = await res.json();
}
const data = tooltipCache[id];
tooltip.innerHTML = ` tooltip.innerHTML = `
<strong>${data.name}</strong><br> <strong>${data.name}</strong><br>

View File

@ -1,25 +1,35 @@
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");
const auth = require("../middleware/auth");
router.post("/", async (req, res) => { router.post("/", auth, async (req, res) => {
const userId = req.session.user.id; const userId = req.session.user.id;
const { slot, itemId, itemLevelId } = req.body; const { slot, itemId, itemLevelId } = req.body;
await db.query( if (!slot) {
` return res.status(400).json({ error: "Slot fehlt" });
INSERT INTO avatar_equipment }
(user_id,slot,item_id,item_level_id)
VALUES (?,?,?,?)
ON DUPLICATE KEY UPDATE
item_id = VALUES(item_id),
item_level_id = VALUES(item_level_id)
`,
[userId, slot, itemId, itemLevelId],
);
res.json({ success: true }); try {
await db.query(
`
INSERT INTO avatar_equipment
(user_id,slot,item_id,item_level_id)
VALUES (?,?,?,?)
ON DUPLICATE KEY UPDATE
item_id = VALUES(item_id),
item_level_id = VALUES(item_level_id)
`,
[userId, slot, itemId || null, itemLevelId || null],
);
res.json({ success: true });
} catch (err) {
console.error("Equip Fehler:", err);
res.status(500).json({ error: "DB Fehler" });
}
}); });
module.exports = router; module.exports = router;

View File

@ -1,23 +1,33 @@
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");
const auth = require("../middleware/auth");
router.get("/", async (req, res) => { router.get("/", auth, async (req, res) => {
const userId = req.session.user.id; const userId = req.session.user.id;
const [rows] = await db.query( try {
` const [rows] = await db.query(
`
SELECT SELECT
ae.slot, ae.slot,
items.icon ae.item_id,
ae.item_level_id,
items.icon,
item_levels.level AS item_level
FROM avatar_equipment ae FROM avatar_equipment ae
LEFT JOIN items ON items.id = ae.item_id LEFT JOIN items ON items.id = ae.item_id
LEFT JOIN item_levels ON item_levels.id = ae.item_level_id
WHERE ae.user_id=? WHERE ae.user_id=?
`, `,
[userId], [userId],
); );
res.json(rows); res.json(rows);
} catch (err) {
console.error("Equipment Fehler:", err);
res.status(500).json({ error: "DB Fehler" });
}
}); });
module.exports = router; module.exports = router;

View File

@ -1,12 +1,14 @@
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");
const auth = require("../middleware/auth");
router.get("/", async (req, res) => { router.get("/", auth, async (req, res) => {
const userId = 1; const userId = req.session.user.id;
const [items] = await db.query( try {
` const [items] = await db.query(
`
SELECT SELECT
items.id, items.id,
items.name, items.name,
@ -19,10 +21,14 @@ JOIN items ON items.id=user_inventory.item_id
LEFT JOIN item_levels ON item_levels.id=user_inventory.item_level_id LEFT JOIN item_levels ON item_levels.id=user_inventory.item_level_id
WHERE user_inventory.user_id=? WHERE user_inventory.user_id=?
`, `,
[userId], [userId],
); );
res.json(items); res.json(items);
} catch (err) {
console.error("Inventory Fehler:", err);
res.status(500).json({ error: "DB Fehler" });
}
}); });
module.exports = router; module.exports = router;