const WebSocket = require('ws'); const path = require('path'); const pug = require('pug'); const Jimp = require('jimp'); const fs = require('fs'); const https = require('https'); const http = require('http'); const express = require('express'); const app = express(); app.use(express.static(path.join(__dirname, '../html'))); app.set('view engine', 'pug'); const config = require("../settings.json"); const httpPort = config.httpPort; const serverAddress = config.serverAddress; const saveFile = config.saveFile; const boardWidth = config.boardWidth; const boardHeight = config.boardHeight; const timeBetweenPixels = config.timeBetweenPixels; const credentails = { key: fs.readFileSync("key.pem"), cert: fs.readFileSync("cert.pem") } 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 httpsServer = https .createServer( credentails, app ) .listen(httpPort, "0.0.0.0", () => { console.log("test))0"); // const ws = new WebSocket(`wss://127.0.0.1:${httpPort}`, { // rejectUnauthorized: false // }); // ws.on('error', console.error); // ws.on('message', (msg) => { // console.log("Client got a message: ", msg.toString()) // }) // ws.on('open', function open() { // ws.send('All glory to WebSockets!'); // }); }) const server = new WebSocket.Server({ server: httpsServer, host: "0.0.0.0", }); let clients = []; let lastPixelTimestamp = []; const evaulatePixelNumber = (x, y) => { let pixelNumber; if (y > 0) pixelNumber = (y) * boardWidth + x; if (y == 0) pixelNumber = x; return pixelNumber; } server.on('connection', (client) => { client.id = clients.length; clients.push(client); console.log(`New client has connected, assigning id ${clients.length} to it.`) 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; response.timeBetweenPixels = timeBetweenPixels; client.send(Buffer.from(JSON.stringify(response))); break; case 1: response.code = 1; response.content = content; response.pixelOwner = false; contentJson = JSON.parse(content); let pixelNumber = evaulatePixelNumber(contentJson.x * 4, contentJson.y * 4); if (contentJson.x < 0 || contentJson.y < 0) client.send("{\"code\":-1}"); let unixTime = Math.floor(new Date().getTime() / 1000); if (lastPixelTimestamp[client.id] == undefined || unixTime - lastPixelTimestamp[client.id] > timeBetweenPixels - 1) { lastPixelTimestamp[client.id] = unixTime; for (let i = 0; i < clients.length; i++) { response.pixelOwner = i == client.id ? true : false; clients[i].send(Buffer.from(JSON.stringify(response))); 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)))); // client.send("{\"code\":2}") } else { // client.send("{\"code\":3}") } break; default: console.log("Packet cannot be understood: ", packet); client.send("{\"code\":-1}"); } }); client.on('close', function () { clients = clients.filter(s => s !== client); }); }); app.get('/', (req, res) => { // res.send("Hello") res.render('index.pug', { root: __dirname, server: serverAddress, port: httpPort }); }) app.use(function (err, req, res, next) { if (err) console.log(err); next(); }); 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); });