const express = require('express'); const http = require('http'); const { Server } = require("socket.io"); const fs = require('fs').promises; const path = require('path'); const app = express(); const server = http.createServer(app); const io = new Server(server); // Serve your existing static files (HTML, JS, CSS) app.use(express.static(__dirname)); // File path for persistent storage const DRAWINGS_FILE = path.join(__dirname, 'data', 'drawings.json'); const RATE_LIMIT_MS = 50; // Minimum time between draws const lastDrawTime = {}; async function loadDrawings() { try { await fs.mkdir(path.join(__dirname, 'data'), { recursive: true }); const data = await fs.readFile(DRAWINGS_FILE, 'utf8'); drawings = JSON.parse(data); console.log('Loaded drawings:', Object.keys(drawings).length); } catch (error) { if (error.code !== 'ENOENT') { console.error('Error loading drawings:', error); } drawings = {}; console.log('No existing drawings found, starting fresh'); } } // Save drawings to file async function saveDrawings() { try { await fs.writeFile(DRAWINGS_FILE, JSON.stringify(drawings)); } catch (error) { console.error('Error saving drawings:', error); } } // Initialize drawings from file loadDrawings(); let players = {}; let drawings = {}; io.on('connection', (socket) => { console.log('A user connected:', socket.id); // Create a new player and add them to the players object players[socket.id] = { rotation: { x: 0, y: 0, z: 0 }, position: { x: 0, y: 1, z: 0 }, socketId: socket.id }; // Send the new player the list of all other players socket.emit('currentPlayers', players); // Announce the new player to all other players socket.broadcast.emit('newPlayer', players[socket.id]); // Handle player disconnection socket.on('disconnect', () => { console.log('User disconnected:', socket.id); delete players[socket.id]; // Announce the player's disconnection to all other players io.emit('playerDisconnected', socket.id); }); // Handle player movement updates socket.on('playerMovement', (movementData) => { if (players[socket.id]) { players[socket.id].position = movementData.position; players[socket.id].rotation = movementData.rotation; // Broadcast the movement to all other players socket.broadcast.emit('playerMoved', players[socket.id]); } }); // Send existing drawings to new players socket.emit('initialDrawings', drawings); socket.on('drawingUpdate', async (drawData) => { const { objectId, drawData: data } = drawData; if (!drawings[objectId]) { drawings[objectId] = []; } drawings[objectId].push(data); await saveDrawings(); socket.broadcast.emit('drawingUpdated', { objectId: objectId, drawData: data }); }); }); const PORT = process.env.PORT || 3000; server.listen(PORT, () => { console.log(`Server listening on port ${PORT}`); });