#!/usr/bin/env node 'use strict'; /* eslint no-console: 0 */ const Net = require('net'); const kPort = 9999; const kEscape = new Buffer([0xFF, 0xF4, 0XFF, 0xFD, 0x06]); // IAC IP IAC DO TIMING_MARK const kNAWSRequest = new Buffer([0xFF, 0xFD, 0X1F]); // IAC DO NAWS const kNAWSResponse = new Buffer([0xFF, 0xFB, 0X1F, 0xFF, 0xFA, 0X1F]); // IAC WILL NAWS IAC SB NAWS const kFrequency = 333; const kModulationSpeed = 5; const run = function run () { const server = startServer(); bindEvents(server); }; const startServer = function startServer () { const server = Net.createServer(); server.listen(kPort, function () { const address = server.address(); console.log(`The server is now listening on ${address.address}:${address.port}`); }); return server; }; const bindEvents = function bindEvents (server) { server.on('error', function (err) { console.error(err.stack || err.message || err); process.exit(1); }); server.on('connection', function (socket) { let connectionData = { width: null, height: null, modulation: 0, screen: screens[Math.floor(Math.random() * screens.length)], mode: modes[Math.floor(Math.random() * modes.length)] }; let interval = null; socket.write(kNAWSRequest); // Currently this is naive, we should parse the buffer properly. socket.on('data', function (data) { // Only send message if NAWS is supported. if (data.slice(0, 6).compare(kNAWSResponse) === 0) { connectionData.width = parse16BitBuffer(data.slice(6, 8)); connectionData.height = parse16BitBuffer(data.slice(8, 10)); socket.write('\x1B[2J'); // Clear the Screen (CSI 2 J) interval = setInterval(writeMessage.bind(null, socket, connectionData), kFrequency); } if (data.compare(kEscape) === 0) { socket.write('\n'); clearInterval(interval); socket.end(); } }); }); }; const writeMessage = function writeMessage (socket, connectionData) { let message = ''; message += '\x1B[1;1H'; // Move cursor to top left (CSI 1;1 H) message += connectionData.screen(connectionData.modulation, connectionData.width, connectionData.height, getANSIColor.bind(null, connectionData.mode)); connectionData.modulation = connectionData.modulation + kModulationSpeed; if (connectionData.modulation === 255) { connectionData.modulation = 0; } socket.write(message); // return '\x1B[2J*** SUCCESSS ***'; }; const parse16BitBuffer = function parse16BitBuffer (buffer) { return buffer[0] * 256 + buffer[1]; }; // SCREENS const fillScreen = function fillScreen (modulation, width, height, getANSIColor) { let response = ''; for (let i = 0; i < height; i++) { for (let j = 0; j < width; j++) { let red = ((modulation + i) * 255 / height) % 255; let blue = ((modulation + j) * 255 / width) % 255; let green = ((modulation + i * j) * 255 / (width * height)) % 255; response = response + getANSIColor(red, blue, green); response = response + ' '; } if (i < height - 1) { response = response + '\n'; } } return response; }; const randomScreen = function randomScreen (modulation, width, height, getANSIColor) { let response = ''; for (let i = 0; i < height; i++) { for (let j = 0; j < width; j++) { let red = Math.floor(Math.random() * 255); let blue = Math.floor(Math.random() * 255); let green = Math.floor(Math.random() * 255); response = response + getANSIColor(red, blue, green); response = response + ' '; } if (i < height - 1) { response = response + '\n'; } } return response; }; const mirrorScreen = function mirrorScreen (modulation, width, height, getANSIColor) { let response = []; let scale = 2 + Math.round(Math.random() * 4); let scaledHeight = Math.floor(height / scale); let scaledWidth = Math.floor(width / scale); for (let i = 0; i < scaledHeight; i++) { let row = []; for (let j = 0; j < scaledWidth; j++) { let red = ((modulation + i) * 255 / height) % 255; let blue = ((modulation + j) * 255 / width) % 255; let green = ((modulation + i * j) * 255 / (width * height)) % 255; let cell = [getANSIColor(red, blue, green), ' ']; row.push(cell.join('')); } let rowText = ''; for (let j = 0; j < scale; j++) { rowText += row.reverse().join(''); } for (let j = 1; j < scale; j++) { response[j * i] = rowText; response[(height - 1 - (j * i))] = rowText; } } return response.join('\n'); }; const randomSprinkles = function mirrorRandomScreen (modulation, width, height, getANSIColor) { let response = ''; let maxSprinkleCount = (width * height) / 2; let minSprinkleCount = (width * height) / 8; let sprinkleCount = Math.round(Math.random() * (maxSprinkleCount - minSprinkleCount)) + minSprinkleCount; let red = Math.floor(Math.random() * 255); let blue = Math.floor(Math.random() * 255); let green = Math.floor(Math.random() * 255); for (let i = 0; i < sprinkleCount; i++) { let x = Math.round(Math.random() * (width - 1)) + 1; let y = Math.round(Math.random() * (height - 1)) + 1; let position = `\x1B[${y};${x}H`; // Move cursor to y,x (CSI y;x H) response += `${position}${getANSIColor(red, blue, green)} `; } return response; }; const circlesScreen = function circlesScreen (modulation, width, height, getANSIColor) { let response = []; let circles = width > height ? height : width; for (let i = 0; i < circles; i++) { let centerX = Math.round(width / 2) + 1; let centerY = Math.round(height / 2) + 1; let red = Math.floor(Math.random() * 255); let blue = Math.floor(Math.random() * 255); let green = Math.floor(Math.random() * 255); for (let j = 0; j < 180; j++) { let angle = 2 * j * (Math.PI / 180); let x = Math.round(centerX + Math.sin(angle) * i); let y = Math.round(centerY + Math.cos(angle) * i); if (x <= width && x > 0 && y <= height && y > 0) { let position = `\x1B[${y};${x}H`; // Move cursor to y,x (CSI y;x H) response += `${position}${getANSIColor(red, blue, green)} `; } } } return response; }; // instead of binding themode, return the one funciton... const getANSIColor = function getANSIColor (mode, red, blue, green) { let colorCode; if (mode === '256') { let redValue = Math.round(red * 5 / 255); let blueValue = Math.round(blue * 5 / 255); let greenValue = Math.round(green * 5 / 255); let colorNumber = 16 + 36 * redValue + 6 * greenValue + blueValue; colorCode = `\x1B[48;5;${colorNumber}m`; } else if (mode === 'ansi') { let colorOffset = Math.round((red + blue + green) * 7 / (255 * 3)); let colorNumber = 40 + colorOffset; colorCode = `\x1B[${colorNumber}m`; } else{ colorCode = `\x1B[48;2;${Math.round(red)};${Math.round(green)};${Math.round(blue)}m`; } return colorCode; }; const screens = [fillScreen, randomScreen, mirrorScreen, randomSprinkles, circlesScreen]; const modes = ['full', '256', 'ansi']; run();