ä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

4
.env
View File

@ -9,4 +9,6 @@ DB_NAME=dok
OFFLINE_SERVER_1=Test Server Alpha
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 blackmarket = require("./routes/blackmarket");
const compression = require("compression");
const app = express();
app.set("trust proxy", 1);
const PORT = process.env.PORT || 3000;
@ -33,6 +35,12 @@ const PORT = process.env.PORT || 3000;
const server = http.createServer(app);
const io = new Server(server);
/* ========================
Compression
======================== */
app.use(compression());
/* ========================
Security Middleware
======================== */
@ -60,9 +68,14 @@ app.use(limiter);
app.use(
session({
secret: "dynastyofknights_secret",
secret: process.env.SESSION_SECRET || "dynastyofknights_secret",
resave: 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");
});
/* ========================
Webseite beschleunigen
======================== */
const compression = require("compression");
app.use(compression());
/* ========================
Chat System
======================== */

View File

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

View File

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

View File

@ -159,8 +159,15 @@ function initInventoryButtons() {
};
document.getElementById("inv-right").onclick = () => {
inventoryPage++;
renderInventory();
const totalPages = Math.max(
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 tooltip = document.getElementById("map-tooltip");
const tooltipCache = {};
const buildingModules = {
11: loadWohnhaus,
12: loadSchwarzmarkt,
@ -136,11 +138,15 @@ document.querySelectorAll(".building").forEach((building) => {
try {
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 = `
<strong>${data.name}</strong><br>

View File

@ -1,25 +1,35 @@
const express = require("express");
const router = express.Router();
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 { slot, itemId, itemLevelId } = req.body;
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, itemLevelId],
);
if (!slot) {
return res.status(400).json({ error: "Slot fehlt" });
}
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;

View File

@ -1,23 +1,33 @@
const express = require("express");
const router = express.Router();
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 [rows] = await db.query(
`
try {
const [rows] = await db.query(
`
SELECT
ae.slot,
items.icon
ae.item_id,
ae.item_level_id,
items.icon,
item_levels.level AS item_level
FROM avatar_equipment ae
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=?
`,
[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;

View File

@ -1,12 +1,14 @@
const express = require("express");
const router = express.Router();
const db = require("../database/database");
const auth = require("../middleware/auth");
router.get("/", async (req, res) => {
const userId = 1;
router.get("/", auth, async (req, res) => {
const userId = req.session.user.id;
const [items] = await db.query(
`
try {
const [items] = await db.query(
`
SELECT
items.id,
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
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;