const WebSocket = require('ws'); const express = require('express'); const http = express(); const path = require('path'); const pug = require('pug'); const Jimp = require('jimp'); const fs = require('fs'); http.use(express.static(path.join(__dirname, '../html'))); http.set('view engine', 'pug'); const config = require("../settings.json"); const httpPort = config.httpPort; const appPort = config.appPort; const serverAddress = config.serverAddress; const saveFile = config.saveFile; const boardWidth = config.boardWidth; const boardHeight = config.boardHeight; var toQuit = false; var board = new Array(boardWidth * boardHeight * 4); if (!fs.existsSync(saveFile)) { console.log("No save file found, creating blank board."); board.fill(255); } else { console.log("Save file found, loading") let image = Jimp.read(`./${saveFile}`, (err, image) => { for (let x = 0; x < boardWidth; x ++) { for (let y = 0; y < boardHeight; y ++) { pixelNumber = evaulatePixelNumber(x * 4, y * 4); let pixel = Jimp.intToRGBA(image.getPixelColor(x, y)) board[pixelNumber + 0] = pixel.r board[pixelNumber + 1] = pixel.g board[pixelNumber + 2] = pixel.b board[pixelNumber + 3] = 255; } } console.log("Loaded") }); } const server = new WebSocket.Server({ port: appPort }); let clients = []; const evaulatePixelNumber = (x, y) => { let pixelNumber; if (y > 0) pixelNumber = (y) * boardWidth + x; if (y == 0) pixelNumber = x; return pixelNumber; } server.on('connection', function(client) { clients.push(client); // When you receive a message, send that message to every socket. client.on('message', function(msg) { let packet, content, code; try { packet = JSON.parse(msg.toString()); content = packet.content; code = packet.code; } catch (e) {console.log(e)} let response = {}; switch(code) { case 0: response.code = 0; response.content = board; client.send(Buffer.from(JSON.stringify(response))); break; case 1: response.code = 1; response.content = content; console.log(`response content ${response.content}`); contentJson = JSON.parse(content); let pixelNumber = evaulatePixelNumber(contentJson.x * 4, contentJson.y * 4); if (contentJson.x < 0 || contentJson.y < 0) { break; } board[pixelNumber + 0] = contentJson.r; board[pixelNumber + 1] = contentJson.g; board[pixelNumber + 2] = contentJson.b; board[pixelNumber + 3] = 255; clients.forEach(c => c.send(Buffer.from(JSON.stringify(response)))); break; default: console.log("Packet cannot be understood: ", packet); client.send("{\"code\":-1}"); } }); client.on('close', function() { clients = clients.filter(s => s !== client); }); }); http.get('/', (req, res) => { res.render('index.pug', {root: __dirname, server: serverAddress, port:appPort}); }) http.listen(httpPort, "0.0.0.0", () => { console.log(`Starting pixelbattle http server on port ${httpPort}`); }) const save = (err, image) => { if (err) throw err; console.log() for (let x = 0; x < boardWidth; x ++) { for (let y = 0; y < boardHeight; y ++) { let pixelNumber = evaulatePixelNumber(x * 4 , y * 4); image.setPixelColor( Jimp.rgbaToInt( Number(board[pixelNumber + 0]), Number(board[pixelNumber + 1]), Number(board[pixelNumber + 2]), Number(board[pixelNumber + 3]) ), x, y ); } } image.write(`./${saveFile}`, (err) => { if (err) throw err; console.log("Saved") if (toQuit) process.exit(); }); } process.stdin.resume(); process.on('SIGUSR1', () => { //save console.log(`Caught SIGUSR1, saving ${boardWidth}x${boardHeight} image`) toQuit = false; let image = new Jimp(boardWidth, boardHeight, save); }); process.on('SIGINT', () => { //save console.log(`Caught SIGINT, saving ${boardWidth}x${boardHeight} image and quitting`) toQuit = true; let image = new Jimp(boardWidth, boardHeight, save); });