72 lines
2.5 KiB
JavaScript
72 lines
2.5 KiB
JavaScript
const
|
|
BUFFER = true,
|
|
BUFFER_INTERVAL = 50,
|
|
PEER_PUBLIC_KEY = "e3950b1762fff528bc891ae227006ce6ba88eb9573ea0d3fb97785163f7eb330",
|
|
PEER_ADDRESS = "pixelflut.semisol.net",
|
|
PORT = 1338,
|
|
SECURE = true,
|
|
LISTEN_PORT = 1337,
|
|
SIZE = [1024, 768]
|
|
!async function () {
|
|
let dgram = require("dgram")
|
|
let crypto = require("crypto")
|
|
let net = require("net")
|
|
let readline = require("readline")
|
|
let monocypher = require("monocypher-wasm")
|
|
let udpClient = dgram.createSocket({ type: "udp4" })
|
|
await monocypher.ready
|
|
let pubkey, shared
|
|
if (SECURE) {
|
|
let key = crypto.randomBytes(32)
|
|
pubkey = monocypher.crypto_key_exchange_public_key(key)
|
|
shared = monocypher.crypto_key_exchange(key, Buffer.from(PEER_PUBLIC_KEY, "hex"))
|
|
if (!shared) {
|
|
console.error("Failed to perform key exchange")
|
|
process.exit(1)
|
|
}
|
|
}
|
|
let queue = []
|
|
net.createServer((sock) => {
|
|
let rl = readline.createInterface(sock)
|
|
rl.on("line", (l) => {
|
|
let data = l.split(" ")
|
|
if (data.length === 1 && data[0] === "SIZE") {
|
|
sock.write("SIZE " + SIZE.join(" ") + "\n")
|
|
}
|
|
if (data.length === 4 && data[0] === "PX") {
|
|
let x = parseInt(data[1], 10)
|
|
let y = parseInt(data[2], 10)
|
|
let r = parseInt(data[3].slice(0, 2), 16)
|
|
let g = parseInt(data[3].slice(2, 4), 16)
|
|
let b = parseInt(data[3].slice(4, 6), 16)
|
|
if (
|
|
check(x, 0xfff) ||
|
|
check(y, 0xfff) ||
|
|
check(r, 0xff) ||
|
|
check(g, 0xff) ||
|
|
check(b, 0xff)
|
|
) return
|
|
queue.push(x >> 4, ((x & 0xf) << 4) | (y >> 8), y & 0xff, r, g, b)
|
|
if (!BUFFER || queue.length > 1000) processQueue()
|
|
}
|
|
})
|
|
sock.on("close", () => rl.close())
|
|
sock.on("error", () => sock.end())
|
|
}).listen(LISTEN_PORT)
|
|
udpClient.bind()
|
|
if (BUFFER) setInterval(() => {
|
|
if (queue.length > 0) processQueue()
|
|
}, BUFFER_INTERVAL)
|
|
function processQueue() {
|
|
let data = Buffer.from(queue)
|
|
queue = []
|
|
if (SECURE) {
|
|
let nonce = crypto.randomBytes(24)
|
|
data = Buffer.concat([pubkey, nonce, monocypher.crypto_lock(shared, nonce, data)])
|
|
}
|
|
udpClient.send(data, PORT, PEER_ADDRESS)
|
|
}
|
|
function check(num, max) {
|
|
return isNaN(num) || num < 0 || num >= max
|
|
}
|
|
}() |