195 lines
6.1 KiB
JavaScript
195 lines
6.1 KiB
JavaScript
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);
|
|
}); |