From 1018485e8e55e5be284502080f27698c02cb0207 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sun, 17 May 2020 21:36:48 -0600 Subject: [PATCH] WIP --- core/config.js | 5 -- core/servers/login/telnet2.js | 126 ++++++++++++++++++++++++++++++++-- 2 files changed, 120 insertions(+), 11 deletions(-) diff --git a/core/config.js b/core/config.js index 76ee98f5..66ffab14 100644 --- a/core/config.js +++ b/core/config.js @@ -285,11 +285,6 @@ function getDefaultConfig() { }, loginServers : { - telnet2: { - port: 8810, - enabled : true, - firstMenu: 'telnetConnected', - }, telnet : { port : 8888, enabled : true, diff --git a/core/servers/login/telnet2.js b/core/servers/login/telnet2.js index a19fe675..3127dfb8 100644 --- a/core/servers/login/telnet2.js +++ b/core/servers/login/telnet2.js @@ -1,10 +1,16 @@ // ENiGMA½ const LoginServerModule = require('../../login_server_module'); -const Client = require('../../client'); +const { Client } = require('../../client'); +const Config = require('../../config').get; +const { log: Log } = require('../../logger'); // deps const net = require('net'); -const { TelnetSocket, TelnetSpec } = require('telnet-socket'); +const { + TelnetSocket, + TelnetSpec: { Options, Commands } +} = require('telnet-socket'); +const { inherits } = require('util'); const ModuleInfo = exports.moduleInfo = { name : 'Telnet', @@ -16,17 +22,104 @@ const ModuleInfo = exports.moduleInfo = { -class TelnetClient extends Client { +class TelnetClient { constructor(socket) { - super(); + Client.apply(this, socket, socket); this.setInputOutput(socket, socket); - this.telnetSocket = new TelnetSocket(socket); + this.socket = new TelnetSocket(socket); - // :TODO: banner + // + // Wait up to 3s to hear about from our terminal type request + // then go ahead and move on... + // + setTimeout(() => { + this.clientReady(); + }, 3000); + + this.socket.on('WILL', command => { + switch (command.option) { + case Options.LINEMODE : + return this.socket.dont.linemode(); + + case Options.TTYPE : + return this.socket.sb.send.ttype(); + + case Options.NEW_ENVIRON : + return this.socket.sb.send.new_environ(); + + default : + break; + } + }); + + this.socket.on('SB', command => { + switch (command.option) { + case Options.TTYPE : + this.setTermType(command.optionData.ttype); + this.clientReady(); + break; + + case Options.NEW_ENVIRON : + { + if ('unknown' === this.term.termType) { + const term = + command.optionData.vars.find(nv => nv.TERM) || + command.optionData.userVars.find(nv => nv.TERM); + if (term) { + this.setTermType(term); + } + } + + command.optionData.vars.forEach(nv => { + console.log(nv); + }); + } + break; + + case Options.NAWS : + this.term.termWidth = command.optionData.width; + this.term.termHeight = command.optionData.height; + + // :TODO: update env, see old telnet.js + + this.clearMciCache(); + + // :TODO: Log negotiation + break; + } + }); + + this.banner(); + } + + clientReady() { + if (this.clientReadyHandled) { + return; // already processed + } + + this.clientReadyHandled = true; + this.emit('ready', { firstMenu : Config().loginServers.telnet.firstMenu } ); + } + + banner() { + this.socket.do.echo(); + this.socket.will.echo(); // we'll echo back + + this.socket.will.sga(); + this.socket.do.sga(); + + this.socket.do.transmit_binary(); + this.socket.will.transmit_binary(); + + this.socket.do.ttype(); + this.socket.do.naws(); + this.socket.do.new_environ(); } }; +inherits(TelnetClient, Client); + exports.getModule = class TelnetServerModule extends LoginServerModule { constructor() { super(); @@ -38,6 +131,27 @@ exports.getModule = class TelnetServerModule extends LoginServerModule { this.handleNewClient(client, socket, ModuleInfo); }); + this.server.on('error', err => { + Log.info( { error : err.message }, 'Telnet server error'); + }); + return cb(null); } + + listen(cb) { + const config = Config(); + //const port = parseInt(config.loginServers.telnet.port); + const port = 8810; // :TODO: Put me back ;) + if(isNaN(port)) { + Log.error( { server : ModuleInfo.name, port : config.loginServers.telnet.port }, 'Cannot load server (invalid port)' ); + return cb(Errors.Invalid(`Invalid port: ${config.loginServers.telnet.port}`)); + } + + this.server.listen(port, config.loginServers.telnet.address, err => { + if(!err) { + Log.info( { server : ModuleInfo.name, port : port }, 'Listening for connections' ); + } + return cb(err); + }); + } };