DJCtrlEmu/server.js
2023-10-03 06:53:25 -04:00

154 lines
3.6 KiB
JavaScript

const path = require("node:path");
const fs = require("node:fs");
const http = require("node:http");
const ws = require("ws");
let driver;
let mappings;
const webServer = new http.Server();
const socketServer = new ws.WebSocketServer({
"noServer": true
});
function sendToClients(message) {
socketServer.clients.forEach(function (client) {
if (client.readyState === ws.OPEN) {
client.send(message);
}
});
}
webServer.on("request", function (request, response) {
switch (request.method) {
case "GET":
switch (request.url) {
default:
var filePath = path.join(__dirname, "view", request.url);
if (!fs.existsSync(filePath)) {
response.writeHead(404);
return response.end("No entry. ");
}
if (fs.statSync(filePath).isDirectory()) {
var entryPath = path.join(filePath, "index.html");
if (!fs.existsSync(entryPath)) {
response.writeHead(404);
return response.end("No entry. ");
}
response.writeHead(200);
fs.createReadStream(entryPath).pipe(response);
} else {
response.writeHead(200);
fs.createReadStream(filePath).pipe(response);
}
break;
}
break;
default:
response.writeHead(404);
return response.end("No entry. ");
break;
}
});
webServer.on("upgrade", function (request, socket, head) {
if (request.url === "/socket") {
socketServer.handleUpgrade(request, socket, head, function (ws) {
socketServer.emit("connection", ws, request);
});
} else {
socket.destroy();
}
});
socketServer.on("connection", function (socket) {
socket.on("error", console.error);
socket.on("message", function (event) {
var data = JSON.parse(event);
switch (data.event) {
case "load-driver":
if (driver) {
driver.close();
delete driver;
}
var driverPath = path.join(__dirname, "drivers", path.basename(data.data.name) + ".js");
driver = require(driverPath);
break;
case "load-mappings":
if (mappings) {
delete mappings;
}
var mappingsPath = path.join(__dirname, "mappings", path.basename(data.data.name) + ".json");
mappings = JSON.parse(fs.readFileSync(mappingsPath));
break;
case "list-devices":
socket.send(JSON.stringify({
"event": "device-list",
"data": {
"devices": driver.list()
}
}));
break;
case "open-device":
driver.open(data.data.name, function (message) {
var byteArray = new Array(...message);
var hexStringifiedMessage = byteArray.map(b => b.toString(16)).map(c => ("00".substring(c.length) + c)).join(" ");
for (var mappingRegExpString in mappings.inbound) {
if (mappings.inbound.hasOwnProperty(mappingRegExpString)) {
var mappingRegExp = new RegExp(mappingRegExpString);
var mappingMatches = hexStringifiedMessage.match(mappingRegExp);
if (!mappingMatches) continue;
var mappingName = mappings.inbound[mappingRegExpString];
mappingMatches.shift();
var value = parseInt(mappingMatches[0], 16);
sendToClients(JSON.stringify({
"event": "signal",
"data": {
"name": mappingName,
"value": value
}
}));
}
}
});
break;
case "control":
if (!driver) return;
if (!mappings.outbound[data.data.name]) return;
var message = mappings.outbound[data.data.name].map(function (byte) {
if (typeof byte != "number") {
return data.data.value;
} else {
return byte;
}
});
driver.send(message);
break;
case "close-device":
driver.close();
break;
default:
}
});
});
webServer.listen(23272);