UNPKG

node-insim

Version:

An InSim library for NodeJS with TypeScript support

80 lines (79 loc) 2.67 kB
import net from 'net'; import { copyBuffer } from '../lfspack'; import { log as baseLog } from '../log'; import { Protocol } from './Protocol'; const log = baseLog.extend('tcp'); /** @internal */ export class TCP extends Protocol { constructor(host, port, packetSizeMultiplier = 1) { super({ host, port, packetSizeMultiplier }); this.stream = null; this.tempBuf = null; this.connect = () => { this.stream = net.connect(this.port, this.host); this.stream.on('connect', () => { this.emit('connect'); }); this.stream.on('close', () => { log('Disconnected'); this.emit('disconnect'); }); this.stream.on('error', (error) => { this.emit('error', error); }); this.stream.on('data', (data) => { log('Data received:', data.join()); // Set or append to temp buffer if (this.tempBuf === null) { this.tempBuf = data; } else { this.tempBuf = Buffer.concat([this.tempBuf, data]); } this.processBuf(); }); }; this.send = (data) => { if (this.stream === null) { log('Cannot send data - not connected'); return; } log('Send data:', data.join()); this.stream.write(data); }; this.disconnect = () => { if (this.stream === null) { log('Cannot disconnect - not connected'); return; } this.stream.end(); }; } processBuf() { if (this.tempBuf === null) { log('No buffer to process'); return; } // Haven't got a full 32 bit header if (this.tempBuf.length < 4) { log('Got packet with <4 bytes'); return; } const size = this.tempBuf[0] * this.packetSizeMultiplier; if (this.tempBuf.length === size) { // We have at least one full packet this.emit('data', copyBuffer(this.tempBuf)); this.tempBuf = null; } else if (this.tempBuf.length > size) { // Process first packet... this.emit('data', copyBuffer(this.tempBuf.slice(0, size))); this.tempBuf = this.tempBuf.slice(size, this.tempBuf.length); // Recurse on remaining buffer this.processBuf(); } else { log('Got incomplete packet'); } } }