const Util = require('./util');
const internals = {
- // Interpret as Command Sequences.
- kEscape: new Buffer([0xFF, 0xF4, 0XFF, 0xFD, 0x06]), // IAC IP IAC DO TIMING_MARK
- kNAWSRequest: new Buffer([0xFF, 0xFD, 0X1F]), // IAC DO NAWS
- kNAWSResponse: new Buffer([0xFF, 0xFB, 0X1F, 0xFF, 0xFA, 0X1F]) // IAC WILL NAWS IAC SB NAWS
+ // Interpret as Command Sequences.
+ kEscape: Buffer.from([0xFF, 0xF4, 0XFF, 0xFD, 0x06]), // IAC IP IAC DO TIMING_MARK
+ kNAWSRequest: Buffer.from([0xFF, 0xFD, 0X1F]), // IAC DO NAWS
+ kNAWSResponse: Buffer.from([0xFF, 0xFB, 0X1F, 0xFF, 0xFA, 0X1F]) // IAC WILL NAWS IAC SB NAWS
};
/**
*/
const TomatoSauce = class TomatoSauce extends EventEmitter {
- constructor(config = {}) {
+ constructor(config = {}) {
- super();
+ super();
- this.screens = [];
- this.renderers = [];
+ this.screens = [];
+ this.renderers = [];
- // Defaults.
- this.port = 9999;
- this.frequency = 333;
- this.modulation = 5;
+ // Defaults.
+ this.port = 9999;
+ this.frequency = 333;
+ this.modulation = 5;
- Object.assign(this, config);
- }
+ Object.assign(this, config);
+ }
- /**
+ /**
* Main entry point, initializes the server and binds events for connections
*
* @function run
* @instance
* @memberof TomatoSauce
*/
- run() {
+ run() {
- this._startServer();
- this._bindEvents();
- }
+ this._startServer();
+ this._bindEvents();
+ }
- // Creates a socket, server based on the configuration. Emits the
- // listening event when ready.
+ // Creates a socket, server based on the configuration. Emits the
+ // listening event when ready.
- _startServer() {
+ _startServer() {
- const server = Net.createServer();
- this.server = server;
- server.listen(this.port, () => {
+ const server = Net.createServer();
+ this.server = server;
+ server.listen(this.port, () => {
- this.emit('listening', {
- data: {
- server
- }
- });
- });
- }
+ this.emit('listening', {
+ data: {
+ server
+ }
+ });
+ });
+ }
- // Binds the connection and error events
+ // Binds the connection and error events
- _bindEvents() {
+ _bindEvents() {
- // Send the error event all the way up.
- this.server.on('error', (error) => {
+ // Send the error event all the way up.
+ this.server.on('error', (error) => {
- this.emit('error', {
- data: {
- error
- }
- });
- });
+ this.emit('error', {
+ data: {
+ error
+ }
+ });
+ });
- // Send the error event all the way up.
- this.server.on('connection', (socket) => {
+ // Send the error event all the way up.
+ this.server.on('connection', (socket) => {
- this._renderScreen(socket);
- });
- }
+ this._renderScreen(socket);
+ });
+ }
- // Obtains viewport size, and initializes a random screen with a random
- // renderer, setting the required interval to draw.
+ // Obtains viewport size, and initializes a random screen with a random
+ // renderer, setting the required interval to draw.
- _renderScreen(socket) {
+ _renderScreen(socket) {
- const connectionData = {
- width: null,
- height: null,
- modulation: 0,
- screen: this._getScreen(),
- renderer: this._getRenderer(),
- socket
- };
- const interval = null;
+ const connectionData = {
+ width: null,
+ height: null,
+ modulation: 0,
+ screen: this._getScreen(),
+ renderer: this._getRenderer(),
+ socket
+ };
+ let interval = null;
- socket.write(internals.kNAWSRequest);
+ socket.write(internals.kNAWSRequest);
- socket.on('data', (data) => {
+ socket.on('data', (data) => {
- if (data.slice(0, 6).compare(internals.kNAWSResponse) === 0) {
- connectionData.width = Util.parse16BitBuffer(data.slice(6, 8));
- connectionData.height = Util.parse16BitBuffer(data.slice(8, 10));
+ if (data.slice(0, 6).compare(internals.kNAWSResponse) === 0) {
+ connectionData.width = Util.parse16BitBuffer(data.slice(6, 8));
+ connectionData.height = Util.parse16BitBuffer(data.slice(8, 10));
- socket.write('\x1B[2J'); // Clear the Screen (CSI 2 J)
- interval = setInterval(this._writeMessage.bind(this, connectionData), this.frequency);
- }
+ socket.write('\x1B[2J'); // Clear the Screen (CSI 2 J)
+ interval = setInterval(this._writeMessage.bind(this, connectionData), this.frequency);
+ }
- if (data.compare(internals.kEscape) === 0) {
- socket.write('\n');
- clearInterval(interval);
- socket.end();
- }
- });
- }
+ if (data.compare(internals.kEscape) === 0) {
+ socket.write('\n');
+ clearInterval(interval);
+ socket.end();
+ }
+ });
+ }
- // Resets the cursor, gets a frame and sends it to the socket.
+ // Resets the cursor, gets a frame and sends it to the socket.
- _writeMessage(connectionData) {
+ _writeMessage(connectionData) {
- const payload = connectionData.screen(connectionData.modulation, connectionData.width, connectionData.height, connectionData.renderer);
- const message = `\x1B[1;1H${payload}`; // reset cursor position before payload
+ const payload = connectionData.screen(connectionData.modulation, connectionData.width, connectionData.height, connectionData.renderer);
+ const message = `\x1B[1;1H${payload}`; // reset cursor position before payload
- connectionData.modulation = (connectionData.modulation + this.modulation) % 256;
- connectionData.socket.write(message);
- }
+ connectionData.modulation = (connectionData.modulation + this.modulation) % 256;
+ connectionData.socket.write(message);
+ }
- _getScreen() {
+ _getScreen() {
- return Util.pickRandom(this.screens);
- }
+ return Util.pickRandom(this.screens);
+ }
- _getRenderer() {
+ _getRenderer() {
- return Util.pickRandom(this.renderers);
- }
+ return Util.pickRandom(this.renderers);
+ }
};
module.exports = TomatoSauce;