First part of removing cursor position reports

This commit is contained in:
Nathan Byrd 2022-03-23 18:43:49 -05:00
parent 265688a342
commit 5cb239157c
6 changed files with 45 additions and 82 deletions

View File

@ -190,10 +190,11 @@ function ANSIEscapeParser(options) {
self.emit('mci', { self.emit('mci', {
mci : mciCode, position : [self.row, self.column],
id : id ? parseInt(id, 10) : null, mci : mciCode,
args : args, id : id ? parseInt(id, 10) : null,
SGR : ansi.getSGRFromGraphicRendition(self.graphicRendition, true) args : args,
SGR : ansi.getSGRFromGraphicRendition(self.graphicRendition, true)
}); });
if(self.mciReplaceChar.length > 0) { if(self.mciReplaceChar.length > 0) {

View File

@ -272,16 +272,12 @@ function display(client, art, options, cb) {
}); });
let parseComplete = false; let parseComplete = false;
let cprListener;
let mciMap; let mciMap;
const mciCprQueue = []; const mciCprQueue = [];
let artHash; let artHash;
let mciMapFromCache; let mciMapFromCache;
function completed() { function completed() {
if(cprListener) {
client.removeListener('cursor position report', cprListener);
}
if(!options.disableMciCache && !mciMapFromCache) { if(!options.disableMciCache && !mciMapFromCache) {
// cache our MCI findings... // cache our MCI findings...
@ -314,18 +310,6 @@ function display(client, art, options, cb) {
// no cached MCI info // no cached MCI info
mciMap = {}; 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; let generatedId = 100;
ansiParser.on('mci', mciInfo => { ansiParser.on('mci', mciInfo => {
@ -339,18 +323,19 @@ function display(client, art, options, cb) {
mapEntry.focusArgs = mciInfo.args; mapEntry.focusArgs = mciInfo.args;
} else { } else {
mciMap[mapKey] = { mciMap[mapKey] = {
args : mciInfo.args, position : mciInfo.position,
SGR : mciInfo.SGR, args : mciInfo.args,
code : mciInfo.mci, SGR : mciInfo.SGR,
id : id, code : mciInfo.mci,
id : id,
}; };
if(!mciInfo.id) { if(!mciInfo.id) {
++generatedId; ++generatedId;
} }
mciCprQueue.push(mapKey); // mciCprQueue.push(mapKey);
client.term.rawWrite(ansi.queryPos()); // client.term.rawWrite(ansi.queryPos());
} }
}); });

View File

@ -4,11 +4,12 @@
// ENiGMA½ // ENiGMA½
var Log = require('./logger.js').log; var Log = require('./logger.js').log;
var renegadeToAnsi = require('./color_codes.js').renegadeToAnsi; var renegadeToAnsi = require('./color_codes.js').renegadeToAnsi;
const Config = require('./config.js').get;
var iconv = require('iconv-lite'); var iconv = require('iconv-lite');
var assert = require('assert'); var assert = require('assert');
var _ = require('lodash'); var _ = require('lodash');
exports.ClientTerminal = ClientTerminal; exports.ClientTerminal = ClientTerminal;
function ClientTerminal(output) { function ClientTerminal(output) {
@ -115,7 +116,8 @@ ClientTerminal.prototype.isNixTerm = function() {
return true; 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() { ClientTerminal.prototype.isANSI = function() {
@ -153,7 +155,8 @@ ClientTerminal.prototype.isANSI = function() {
// linux: // linux:
// * JuiceSSH (note: TERM=linux also) // * 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) // :TODO: probably need to update these to convert IAC (0xff) -> IACIAC (escape it)

View File

@ -17,6 +17,18 @@ module.exports = () => {
achievementFile : 'achievements.hjson', 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 : { users : {
usernameMin : 2, usernameMin : 2,
usernameMax : 16, // Note that FidoNet wants 36 max usernameMax : 16, // Note that FidoNet wants 36 max

View File

@ -4,6 +4,7 @@
// ENiGMA½ // ENiGMA½
const ansi = require('./ansi_term.js'); const ansi = require('./ansi_term.js');
const Events = require('./events.js'); const Events = require('./events.js');
const Config = require('./config.js').get;
const { Errors } = require('./enig_error.js'); const { Errors } = require('./enig_error.js');
// deps // deps
@ -11,51 +12,6 @@ const async = require('async');
exports.connectEntry = connectEntry; 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) { function ansiAttemptDetectUTF8(client, cb) {
// //
// Trick to attempt and detect UTF-8. While there is a lot more than // 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 // We currently only do this if the term hasn't already been ID'd as a
// "*nix" terminal -- that is, xterm, etc. // "*nix" terminal -- that is, xterm, etc.
// // Also skip this check if checkUtf8Encoding is disabled in the config
if(!client.term.isNixTerm()) {
if(!client.term.isNixTerm() || !Config().term.checkUtf8Encoding) {
return cb(null); return cb(null);
} }
@ -119,6 +76,8 @@ function ansiAttemptDetectUTF8(client, cb) {
return giveUp(); return giveUp();
}, 2000); }, 2000);
client.once('cursor position report', cprListener); client.once('cursor position report', cprListener);
client.term.rawWrite(ansi.goHome() + ansi.queryPos()); client.term.rawWrite(ansi.goHome() + ansi.queryPos());
} }
@ -214,12 +173,6 @@ function connectEntry(client, nextMenu) {
term.rawWrite(ansi.queryDeviceAttributes(0)); term.rawWrite(ansi.queryDeviceAttributes(0));
return callback(null); 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) { function queryTermSizeByNonStandardAnsi(callback) {
ansiQueryTermSizeIfNeeded(client, err => { ansiQueryTermSizeIfNeeded(client, err => {
if(err) { if(err) {

View File

@ -67,6 +67,15 @@
description : 'Yet another awesome ENiGMA½ BBS' 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: { paths: {
// //
// Other paths can also be configured as well, // Other paths can also be configured as well,