diff --git a/core/ansi_escape_parser.js b/core/ansi_escape_parser.js index 88063bef..ad41fd27 100644 --- a/core/ansi_escape_parser.js +++ b/core/ansi_escape_parser.js @@ -190,10 +190,11 @@ function ANSIEscapeParser(options) { self.emit('mci', { - mci : mciCode, - id : id ? parseInt(id, 10) : null, - args : args, - SGR : ansi.getSGRFromGraphicRendition(self.graphicRendition, true) + position : [self.row, self.column], + mci : mciCode, + id : id ? parseInt(id, 10) : null, + args : args, + SGR : ansi.getSGRFromGraphicRendition(self.graphicRendition, true) }); if(self.mciReplaceChar.length > 0) { diff --git a/core/art.js b/core/art.js index 0ff4835f..c8205c47 100644 --- a/core/art.js +++ b/core/art.js @@ -272,16 +272,12 @@ function display(client, art, options, cb) { }); let parseComplete = false; - let cprListener; let mciMap; const mciCprQueue = []; let artHash; let mciMapFromCache; function completed() { - if(cprListener) { - client.removeListener('cursor position report', cprListener); - } if(!options.disableMciCache && !mciMapFromCache) { // cache our MCI findings... @@ -314,18 +310,6 @@ function display(client, art, options, cb) { // no cached MCI info mciMap = {}; - cprListener = function(pos) { - if(mciCprQueue.length > 0) { - mciMap[mciCprQueue.shift()].position = pos; - - if(parseComplete && 0 === mciCprQueue.length) { - return completed(); - } - } - }; - - client.on('cursor position report', cprListener); - let generatedId = 100; ansiParser.on('mci', mciInfo => { @@ -339,18 +323,19 @@ function display(client, art, options, cb) { mapEntry.focusArgs = mciInfo.args; } else { mciMap[mapKey] = { - args : mciInfo.args, - SGR : mciInfo.SGR, - code : mciInfo.mci, - id : id, + position : mciInfo.position, + args : mciInfo.args, + SGR : mciInfo.SGR, + code : mciInfo.mci, + id : id, }; if(!mciInfo.id) { ++generatedId; } - mciCprQueue.push(mapKey); - client.term.rawWrite(ansi.queryPos()); + // mciCprQueue.push(mapKey); + // client.term.rawWrite(ansi.queryPos()); } }); diff --git a/core/client_term.js b/core/client_term.js index d390d8ac..b19b4771 100644 --- a/core/client_term.js +++ b/core/client_term.js @@ -4,11 +4,12 @@ // ENiGMA½ var Log = require('./logger.js').log; var renegadeToAnsi = require('./color_codes.js').renegadeToAnsi; - +const Config = require('./config.js').get; var iconv = require('iconv-lite'); var assert = require('assert'); var _ = require('lodash'); + exports.ClientTerminal = ClientTerminal; function ClientTerminal(output) { @@ -115,7 +116,8 @@ ClientTerminal.prototype.isNixTerm = function() { return true; } - return [ 'xterm', 'linux', 'screen', 'dumb', 'rxvt', 'konsole', 'gnome', 'x11 terminal emulator' ].includes(this.termType); + const utf8TermList = Config().term.utf8TermList; + return utf8TermList.includes(this.termType); }; ClientTerminal.prototype.isANSI = function() { @@ -153,7 +155,8 @@ ClientTerminal.prototype.isANSI = function() { // linux: // * JuiceSSH (note: TERM=linux also) // - return [ 'ansi', 'pcansi', 'pc-ansi', 'ansi-bbs', 'qansi', 'scoansi', 'syncterm', 'ansi-256color', 'ansi-256color-rgb' ].includes(this.termType); + const cp437TermList = Config().term.cp437TermList; + return cp437TermList.includes(this.termType); }; // :TODO: probably need to update these to convert IAC (0xff) -> IACIAC (escape it) diff --git a/core/config_default.js b/core/config_default.js index c5e0b86b..d5b71ed7 100644 --- a/core/config_default.js +++ b/core/config_default.js @@ -17,6 +17,18 @@ module.exports = () => { achievementFile : 'achievements.hjson', }, + term : { + // checkUtf8Encoding requires the use of cursor position reports, which are not supported on all terminals. + // Using this with a terminal that does not support cursor position reports results in a 2 second delay + // during the connect process, but provides better autoconfiguration of utf-8 + checkUtf8Encoding : true, + + // List of terms that should be assumed to use cp437 encoding + cp437TermList : ['ansi', 'pcansi', 'pc-ansi', 'ansi-bbs', 'qansi', 'scoansi', 'syncterm', 'ansi-256color', 'ansi-256color-rgb'], + // List of terms that should be assumed to use utf8 encoding + utf8TermList : ['xterm', 'linux', 'screen', 'dumb', 'rxvt', 'konsole', 'gnome', 'x11 terminal emulator'], + }, + users : { usernameMin : 2, usernameMax : 16, // Note that FidoNet wants 36 max diff --git a/core/connect.js b/core/connect.js index 29d5443d..d20aae39 100644 --- a/core/connect.js +++ b/core/connect.js @@ -4,6 +4,7 @@ // ENiGMA½ const ansi = require('./ansi_term.js'); const Events = require('./events.js'); +const Config = require('./config.js').get; const { Errors } = require('./enig_error.js'); // deps @@ -11,51 +12,6 @@ const async = require('async'); exports.connectEntry = connectEntry; -function ansiDiscoverHomePosition(client, cb) { - // - // We want to find the home position. ANSI-BBS and most terminals - // utilize 1,1 as home. However, some terminals such as ConnectBot - // think of home as 0,0. If this is the case, we need to offset - // our positioning to accommodate for such. - // - const done = (err) => { - client.removeListener('cursor position report', cprListener); - clearTimeout(giveUpTimer); - return cb(err); - }; - - const cprListener = function(pos) { - const h = pos[0]; - const w = pos[1]; - - // - // We expect either 0,0, or 1,1. Anything else will be filed as bad data - // - if(h > 1 || w > 1) { - client.log.warn( { height : h, width : w }, 'Ignoring ANSI home position CPR due to unexpected values'); - return done(Errors.UnexpectedState('Home position CPR expected to be 0,0, or 1,1')); - } - - if(0 === h & 0 === w) { - // - // Store a CPR offset in the client. All CPR's from this point on will offset by this amount - // - client.log.info('Setting CPR offset to 1'); - client.cprOffset = 1; - } - - return done(null); - }; - - client.once('cursor position report', cprListener); - - const giveUpTimer = setTimeout( () => { - return done(Errors.General('Giving up on home position CPR')); - }, 3000); // 3s - - client.term.write(`${ansi.goHome()}${ansi.queryPos()}`); // go home, query pos -} - function ansiAttemptDetectUTF8(client, cb) { // // Trick to attempt and detect UTF-8. While there is a lot more than @@ -68,8 +24,9 @@ function ansiAttemptDetectUTF8(client, cb) { // // We currently only do this if the term hasn't already been ID'd as a // "*nix" terminal -- that is, xterm, etc. - // - if(!client.term.isNixTerm()) { + // Also skip this check if checkUtf8Encoding is disabled in the config + + if(!client.term.isNixTerm() || !Config().term.checkUtf8Encoding) { return cb(null); } @@ -119,6 +76,8 @@ function ansiAttemptDetectUTF8(client, cb) { return giveUp(); }, 2000); + + client.once('cursor position report', cprListener); client.term.rawWrite(ansi.goHome() + ansi.queryPos()); } @@ -214,12 +173,6 @@ function connectEntry(client, nextMenu) { term.rawWrite(ansi.queryDeviceAttributes(0)); return callback(null); }, - function discoverHomePosition(callback) { - ansiDiscoverHomePosition(client, () => { - // :TODO: If CPR for home fully fails, we should bail out on the connection with an error, e.g. ANSI support required - return callback(null); // we try to continue anyway - }); - }, function queryTermSizeByNonStandardAnsi(callback) { ansiQueryTermSizeIfNeeded(client, err => { if(err) { diff --git a/misc/config_template.in.hjson b/misc/config_template.in.hjson index 21cefeb6..a4dc0c9b 100644 --- a/misc/config_template.in.hjson +++ b/misc/config_template.in.hjson @@ -67,6 +67,15 @@ description : 'Yet another awesome ENiGMA½ BBS' } + term: { + // checkUtf8Encoding requires the use of cursor position reports, which are not supported on all terminals. + // Using this with a terminal that does not support cursor position reports results in a 2 second delay + // during the connect process, but provides better autoconfiguration of utf-8 + checkUtf8Encoding : true + + // other options here include cp437TermList and utf8TermList, see config_default.js for more information + } + paths: { // // Other paths can also be configured as well,