const express = require('express'); const http = require('http'); const WebSocket = require('ws'); const url = require('url'); const objectsModule = require('./objects'); const app = express(); const server = http.createServer(app); const wss = new WebSocket.Server({ server }); const connections = new Set(); var playerCount = 0; var players = [] const NAME_MAXLEN = 25; app.get('/', (req, res) => { res.send('Grand Tabernacle Auto VI'); }); function norm(x1, x2, y1, y2) { return Math.sqrt((x1 - x2) ** 2 + (y1 + y2) ** 2); } function circleCollide(x, y) { let colliding = false; objectsModule.objects.circles.forEach((circle) => { if (norm(x, circle.x, y, circle.y) <= circle.r) { colliding = true; } }) return colliding; } function squareCollide(x, y) { let colliding = false; objectsModule.objects.squares.forEach((square) => { if (square.x <= x && x <= square.x + square.w && square.y <= y && y <= square.y + square.h) { colliding = true; } }) return colliding; } function generatePosition() { let mapWidth = 1000; let mapHeight = 1000; let count = 0; let x = Math.floor(Math.random() * mapWidth); let y = Math.floor(Math.random() * mapHeight); while ((circleCollide(x, y) || squareCollide(x, y))) { x = Math.floor(Math.random() * mapWidth); y = Math.floor(Math.random() * mapHeight); count++; if (count >= 1000) { break; } } return [x, y]; } function createNewPlayer(socket, name) { let pos = generatePosition(); var obj = { id: playerCount, x: pos[0], y: pos[1], dir: 0, visibleDir: 0, name: name } players.push(obj); playerCount++; socket.send(JSON.stringify({ type: "connect", data: { playerId: obj.id, players: players } })) broadcast(JSON.stringify({ type: "newplayer", data: obj }), obj.id); socket.id = obj.id; connections.add(socket); } wss.on('connection', (socket, req) => { //create new player, send informations to new player and broadcast new player for all let username = url.parse(req.url, true).query.name; if (username === undefined || username == null || username == "null") { username = "Soldat Inconnu" } if (username.length > NAME_MAXLEN) { username = username.substring(0, NAME_MAXLEN); } createNewPlayer(socket, username); socket.on('message', (message) => { message = JSON.parse(message); switch (message.type) { case 'ping': socket.send("pong"); break; case "update": for (var i = players.length - 1; i >= 0; i--) { if (players[i].id == message.data.id) { players[i] = message.data; } } broadcast(JSON.stringify(message), socket.id); break; case "newBullet": broadcast(JSON.stringify(message), socket.id); break; case "died": broadcast(JSON.stringify(message), socket.id); for (var i = players.length - 1; i >= 0; i--) { if (players[i].id == message.data.id) { let pos = generatePosition(); players[i].x = pos[0]; players[i].y = pos[1]; broadcast(JSON.stringify({ type: "update", data: players[i] })) } } break; default: break; } }); socket.on('close', () => { for (var i = players.length - 1; i >= 0; i--) { broadcast(JSON.stringify({ type: "removePlayer", data: { id: socket.id } })); if (players[i].id == socket.id) { players.splice(i, 1); } } connections.delete(socket); }); }); function broadcast(message, exceptId = -1) { connections.forEach((socket) => { if (socket.readyState === WebSocket.OPEN && socket.id != exceptId) { socket.send(message); } }); } const PORT = 8080; server.listen(PORT, () => { console.log(`Serveur WebSocket écoutant sur le port ${PORT}`); });