const https = require('https').createServer; const WebSocket = require('ws'); const url = require('url'); const fs = require('fs'); const objectsModule = require('./objects'); const options = { cert: fs.readFileSync("/home/ubuntu/servers/keys/gta6/cert.pem"), key: fs.readFileSync("/home/ubuntu/servers/keys/gta6/privkey.pem") }; const server = https(options, (req, res)=>{ res.end("Grand Tabernacle Auto 6") }); const wss = new WebSocket.Server({ server }); const spawnPoints = [{"x":218,"y":193},{"x":601,"y":715},{"x":1264,"y":57},{"x":274,"y":506},{"x":921,"y":854},{"x":1041,"y":442},{"x":638,"y":124},{"x":483,"y":436}] const connections = new Set(); var playerCount = 0; var players = [] const NAME_MAXLEN = 25; function generatePosition() { let index = Math.floor(Math.random()*spawnPoints.length); return [spawnPoints[index].x, spawnPoints[index].y]; } function getUsername(req){ 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); } return username; } 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); } function kick_player(player_id, socket, reason){ //send cheating info to all players broadcast(JSON.stringify({ type: "kick", data: { player_id: player_id, reason: reason } })); deletePlayer(socket); //delete player of players list socket.terminate(); //disconnect cheating player } function update(message, socket){ for (var i = players.length - 1; i >= 0; i--) { if(message.data.health <= MAX_HEALTH) { if (players[i].id == message.data.id) { players[i] = message.data; } }else{ //cheat detected kick_player(message.data.id, socket, "health cheat"); } } broadcast(JSON.stringify(message), socket.id); } function newBullet(message, socket){ broadcast(JSON.stringify(message), socket.id); } function died(message, socket){ 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] })) } } } function deletePlayer(socket){ 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 recievemessage(msg, socket){ broadcast(JSON.stringify(msg), socket.id); } function broadcast(message, exceptId = -1) { connections.forEach((socket) => { if (socket.readyState === WebSocket.OPEN && socket.id != exceptId) { socket.send(message); } }); } wss.on('connection', (socket, req) => { //create new player, send informations to new player and broadcast new player for all let username = getUsername(req); createNewPlayer(socket, username); //handle client's messages socket.on('message', (message) => { try{ message = JSON.parse(message); switch (message.type) { case 'ping': socket.send("pong"); break; case "update": update(message, socket); break; case "newBullet": newBullet(message, socket); break; case "died": died(message, socket); break; case "message": recievemessage(message, socket); break; default: break; } }catch(e){ console.log('error'); } }); //handle disconnecting socket.on('close', () => { deletePlayer(socket); }); }); const PORT = 8080; server.listen(PORT, () => { console.log(`WebSocket listening on port ${PORT}.`); });