fhnjstre
This commit is contained in:
parent
edf8a37ddc
commit
4810950d4e
46
app.js
46
app.js
@ -28,7 +28,6 @@ const { registerArenaHandlers } = require("./sockets/arena");
|
||||
const { registerChatHandlers } = require("./sockets/chat");
|
||||
const boosterRoutes = require("./routes/booster.route");
|
||||
const pointsRoutes = require("./routes/points.route");
|
||||
const shopRoutes = require("./routes/shop.route");
|
||||
|
||||
const compression = require("compression");
|
||||
|
||||
@ -58,14 +57,13 @@ app.use(
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
defaultSrc: ["'self'"],
|
||||
scriptSrc: ["'self'", "'unsafe-inline'", "https://js.stripe.com"],
|
||||
scriptSrc: ["'self'", "'unsafe-inline'"],
|
||||
scriptSrcAttr: ["'unsafe-inline'"],
|
||||
styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
|
||||
fontSrc: ["'self'", "https://fonts.gstatic.com"],
|
||||
imgSrc: ["'self'", "data:", "blob:", "https://*.stripe.com"],
|
||||
connectSrc: ["'self'", "ws:", "wss:", "https://api.stripe.com"],
|
||||
frameSrc: ["https://js.stripe.com", "https://hooks.stripe.com"],
|
||||
frameAncestors: ["'self'"],
|
||||
imgSrc: ["'self'", "data:", "blob:"],
|
||||
connectSrc: ["'self'", "ws:", "wss:"],
|
||||
frameAncestors: ["'self'"], // Erlaubt iframe von eigener Domain
|
||||
},
|
||||
},
|
||||
}),
|
||||
@ -80,6 +78,9 @@ app.use(limiter);
|
||||
|
||||
/* ========================
|
||||
Lösung 2: Session Config
|
||||
maxAge: 24h – Sessions laufen
|
||||
automatisch ab, auch wenn der
|
||||
Browser einfach geschlossen wurde.
|
||||
======================== */
|
||||
|
||||
app.use(
|
||||
@ -90,7 +91,7 @@ app.use(
|
||||
cookie: {
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
maxAge: 1000 * 60 * 60 * 24,
|
||||
maxAge: 1000 * 60 * 60 * 24, // 24 Stunden
|
||||
},
|
||||
}),
|
||||
);
|
||||
@ -102,21 +103,30 @@ app.use(
|
||||
app.set("view engine", "ejs");
|
||||
app.set("views", path.join(__dirname, "views"));
|
||||
|
||||
/* Webhook braucht raw body – alle anderen json */
|
||||
app.use((req, res, next) => {
|
||||
if (req.originalUrl === "/api/shop/webhook") {
|
||||
express.raw({ type: "application/json" })(req, res, next);
|
||||
} else {
|
||||
express.json()(req, res, next);
|
||||
}
|
||||
});
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
app.use(express.static(path.join(__dirname, "public")));
|
||||
|
||||
/* ========================
|
||||
Login Middleware
|
||||
Server Stats (öffentlich – kein Login nötig)
|
||||
Zählt online Spieler pro Server
|
||||
via Socket.io Verbindungen
|
||||
======================== */
|
||||
|
||||
app.get("/api/server-stats", (req, res) => {
|
||||
const stats = {};
|
||||
|
||||
// Alle verbundenen Sockets durchgehen
|
||||
const sockets = io.sockets.sockets;
|
||||
sockets.forEach((socket) => {
|
||||
if (socket.user && socket.serverId) {
|
||||
stats[socket.serverId] = (stats[socket.serverId] || 0) + 1;
|
||||
}
|
||||
});
|
||||
|
||||
res.json(stats);
|
||||
});
|
||||
|
||||
function requireLogin(req, res, next) {
|
||||
if (!req.session.user) {
|
||||
return res.status(401).json({ error: "Nicht eingeloggt" });
|
||||
@ -325,7 +335,7 @@ app.get("/api/hud", requireLogin, async (req, res) => {
|
||||
[userId],
|
||||
);
|
||||
const [[currency]] = await db.query(
|
||||
"SELECT silver, gold, gems, wood, stone, iron FROM account_currency WHERE account_id = ?",
|
||||
"SELECT silver, gold, gems, wood, stone FROM account_currency WHERE account_id = ?",
|
||||
[userId],
|
||||
);
|
||||
res.json({
|
||||
@ -335,7 +345,6 @@ app.get("/api/hud", requireLogin, async (req, res) => {
|
||||
gems: currency?.gems || 0,
|
||||
wood: currency?.wood || 0,
|
||||
stone: currency?.stone || 0,
|
||||
iron: currency?.iron || 0,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
@ -392,7 +401,6 @@ app.use("/arena", arenaRoutes);
|
||||
app.use("/api", boosterRoutes);
|
||||
app.use("/api", require("./routes/daily.route"));
|
||||
app.use("/api/points", pointsRoutes);
|
||||
app.use("/api", shopRoutes);
|
||||
|
||||
/* ========================
|
||||
404 Handler
|
||||
|
||||
@ -12,14 +12,15 @@ function registerChatHandlers(io, socket) {
|
||||
/* ── Registrierung ── */
|
||||
socket.on("register", async (username) => {
|
||||
const [rows] = await db.query(
|
||||
"SELECT ingame_name FROM accounts WHERE username = ?",
|
||||
"SELECT ingame_name, server_id FROM accounts WHERE username = ?",
|
||||
[username],
|
||||
);
|
||||
|
||||
if (!rows.length) return;
|
||||
|
||||
const ingameName = rows[0].ingame_name;
|
||||
socket.user = ingameName;
|
||||
socket.user = ingameName;
|
||||
socket.serverId = rows[0].server_id;
|
||||
onlineUsers[ingameName] = socket.id;
|
||||
});
|
||||
|
||||
|
||||
@ -52,17 +52,34 @@
|
||||
<div class="server-status">
|
||||
|
||||
<% servers.forEach(server => { %>
|
||||
<%= server.name %>:
|
||||
<span class="online">Online</span><br>
|
||||
<div class="server-status-row">
|
||||
<span class="server-name"><%= server.name %></span>
|
||||
<span class="online">Online</span>
|
||||
<span class="server-players" id="players-<%= server.id %>">– Spieler online</span>
|
||||
</div>
|
||||
<% }) %>
|
||||
|
||||
<% extraServers.forEach(server => { %>
|
||||
<%= server.name %>:
|
||||
<span class="offline">Offline</span><br>
|
||||
<div class="server-status-row">
|
||||
<span class="server-name"><%= server.name %></span>
|
||||
<span class="offline">Offline</span>
|
||||
</div>
|
||||
<% }) %>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
fetch('/api/server-stats')
|
||||
.then(r => r.json())
|
||||
.then(stats => {
|
||||
Object.entries(stats).forEach(([serverId, count]) => {
|
||||
const el = document.getElementById('players-' + serverId);
|
||||
if (el) el.textContent = '– ' + count + ' Spieler online';
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
</script>
|
||||
|
||||
</div>
|
||||
|
||||
<% if (typeof error !== 'undefined' && error) { %>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user