require("dotenv").config(); const express = require("express"); const path = require("path"); const helmet = require("helmet"); const rateLimit = require("express-rate-limit"); const http = require("http"); const { Server } = require("socket.io"); const serverRoutes = require("./routes/servers"); const registerRoutes = require("./routes/register"); const verifyRoutes = require("./routes/verify"); const characterRoutes = require("./routes/character"); const session = require("express-session"); const loginRoutes = require("./routes/login"); const launcherRoutes = require("./routes/launcher"); const buildingRoutes = require("./routes/buildings"); const app = express(); const PORT = process.env.PORT || 3000; /* ======================== Chatserver ======================== */ const server = http.createServer(app); const io = new Server(server); /* ======================== Security Middleware ======================== */ app.use( helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], scriptSrc: ["'self'", "'unsafe-inline'"], styleSrc: ["'self'", "'unsafe-inline'"], imgSrc: ["'self'", "data:"], connectSrc: ["'self'", "ws:", "wss:"], }, }, }), ); const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100, }); app.use(limiter); app.use( session({ secret: "dynastyofknights_secret", resave: false, saveUninitialized: false, }), ); /* ======================== Express Settings ======================== */ app.set("view engine", "ejs"); app.set("views", path.join(__dirname, "views")); /* ======================== Route für Ajax ======================== */ app.get("/api/building/:id", (req, res) => { const data = { name: "Burg", level: 3, description: "Das Herz deiner Stadt.", upgradeCost: "500 Holz, 200 Stein", history: "Die Burg wurde vor Jahrhunderten erbaut.", }; res.json(data); }); /* ======================== Body Parser ======================== */ app.use(express.json()); app.use(express.urlencoded({ extended: true })); /* ======================== Static Files ======================== */ app.use(express.static(path.join(__dirname, "public"))); /* ======================== Routes ======================== */ app.use("/", serverRoutes); app.use("/register", registerRoutes); app.use("/verify", verifyRoutes); app.use("/create-character", characterRoutes); app.use("/login", loginRoutes); app.use("/launcher", launcherRoutes); app.use("/", buildingRoutes); /* ======================== 404 Handler ======================== */ app.use((req, res) => { res.status(404).send("Seite nicht gefunden"); }); /* ======================== Webseite beschleunigen ======================== */ const compression = require("compression"); app.use(compression()); /* ======================== Chat System ======================== */ let onlineUsers = {}; io.on("connection", (socket) => { console.log("Spieler verbunden"); socket.on("register", (username) => { const name = String(username); socket.user = name; onlineUsers[name] = socket.id; io.emit("onlineUsers", Object.keys(onlineUsers)); }); socket.on("disconnect", () => { if (socket.user) { delete onlineUsers[socket.user]; io.emit("onlineUsers", Object.keys(onlineUsers)); } }); socket.on("chatMessage", (data) => { if (data.channel === "global") { io.emit("chatMessage", { user: socket.user, message: data.message, channel: "global", }); } if (data.channel === "guild") { io.to("guild_" + data.guild).emit("chatMessage", { user: socket.user, message: data.message, channel: "guild", }); } }); socket.on("whisper", (data) => { const targetSocket = onlineUsers[data.to]; if (!targetSocket) { socket.emit("systemMessage", { message: data.to + " ist offline", }); return; } io.to(targetSocket).emit("chatMessage", { user: socket.user, message: data.message, channel: "private", }); socket.emit("chatMessage", { user: "(an " + data.to + ")", message: data.message, channel: "private", }); }); socket.on("privateMessage", (data) => { const target = onlineUsers[data.to]; if (target) { io.to(target).emit("chatMessage", { user: socket.user, message: data.message, channel: "private", }); } }); }); /* ======================== Server Start ======================== */ server.listen(PORT, () => { console.log(`Dynasty of Knights Server läuft auf http://localhost:${PORT}`); });