* Work on themes. Ability to use ANSI to detect screen size if NAWS/etc. fail

This commit is contained in:
Bryan 2014-10-29 05:30:20 -06:00
parent 1ef9a4a1ce
commit 14a321de2f
6 changed files with 107 additions and 50 deletions

View File

@ -10,8 +10,11 @@ var database = require('./database.js');
var iconv = require('iconv-lite');
var paths = require('path');
var async = require('async');
exports.bbsMain = function() {
exports.bbsMain = bbsMain;
function bbsMain() {
var mainArgs = parseArgs();
var configPathSupplied = false;
@ -74,6 +77,41 @@ function parseArgs() {
return args;
}
function initialize(cb) {
async.series(
[
function basicInit(callback) {
logger.init();
process.on('SIGINT', function onSigInt() {
// :TODO: for any client in |clientConnections|, if 'ready', send a "Server Disconnecting" + semi-gracefull hangup
// e.g. client.disconnectNow()
logger.log.info('Process interrupted, shutting down');
process.exit();
});
callback(null);
},
function initDatabases(callback) {
database.initializeDatabases();
callback(null);
},
function initThemes(callback) {
// Have to pull in here so it's after Config init
var theme = require('./theme.js');
theme.initAvailableThemes(function onThemesInit(err, themeCount) {
logger.log.info({ themeCount : themeCount }, 'Themes initialized');
callback(err);
});
}
],
function onComplete(err) {
cb(err);
}
);
}
function preServingInit() {
iconv.extendNodeEncodings();
}
@ -164,16 +202,11 @@ function prepareClient(client, cb) {
if('*' === conf.config.preLoginTheme) {
var theme = require('./theme.js');
theme.getRandomTheme(function onRandTheme(err, themeId) {
if(err) {
// :TODO: how to propertly set default/fallback?
client.user.properties.art_theme_name = '';
} else {
client.user.properties.art_theme_name = themeId;
}
cb();
client.user.properties.art_theme_id = themeId || '';
cb(null);
});
} else {
client.user.properties.art_theme_name = conf.config.preLoginTheme;
cb();
client.user.properties.art_theme_id = conf.config.preLoginTheme;
cb(null);
}
}

View File

@ -34,6 +34,7 @@ module.exports = {
mods : paths.join(__dirname, './../mods/'),
servers : paths.join(__dirname, './servers/'),
art : paths.join(__dirname, './../mods/art/'),
themes : paths.join(__dirname, './../mods/art/themes/'),
logs : paths.join(__dirname, './../logs/'), // :TODO: set up based on system, e.g. /var/logs/enigmabbs or such
db : paths.join(__dirname, './../db/'),
},

View File

@ -562,14 +562,16 @@ TelnetClient.prototype.handleSbCommand = function(evt) {
// * Map COLUMNS -> 'termWidth' and only update if ours is 0
// * Map ROWS -> 'termHeight' and only update if ours is 0
// * Add any new variables, ignore any existing
//
//
Object.keys(evt.envVars).forEach(function onEnv(name) {
if('TERM' === name && 'unknown' === self.term.termType) {
self.setTermType(evt.envVars[name]);
} else if('COLUMNS' === name && 0 === self.term.termWidth) {
self.term.termWidth = parseInt(evt.envVars[name]);
logger.log.debug({ termWidth : self.term.termWidth, updateSource : 'NEW-ENVIRON'}, 'Window width updated');
} else if('ROWS' === name && 0 === self.term.termHeight) {
self.term.termHeight = parseInt(evt.envVars[name]);
logger.log.debug({ termHeight : self.term.termHeight, updateSource : 'NEW-ENVIRON'}, 'Window height updated');
} else {
if(name in self.term.env) {
assert(evt.type === SB_COMMANDS.INFO);
@ -582,6 +584,7 @@ TelnetClient.prototype.handleSbCommand = function(evt) {
}
}
});
} else if('window size' === evt.option) {
//
// Update termWidth & termHeight.
@ -598,7 +601,7 @@ TelnetClient.prototype.handleSbCommand = function(evt) {
self.term.env['ROWS'] = evt.height;
}
logger.log.debug({ termWidth : evt.width , termHeight : evt.height }, 'Window size updated');
logger.log.debug({ termWidth : evt.width , termHeight : evt.height, updateSource : 'NAWS' }, 'Window size updated');
} else {
console.log('unhandled SB: ' + JSON.stringify(evt));
}

View File

@ -11,18 +11,10 @@ var async = require('async');
exports.getThemeInfo = getThemeInfo;
exports.getThemeArt = getThemeArt;
exports.getRandomTheme = getRandomTheme;
// getThemeInfo(themeName)
/*
// getThemeFile(themeShortName, name)
// getArt(name, {
basePath : themeDir,
}
*/
exports.initAvailableThemes = initAvailableThemes;
function getThemeInfo(themeID, cb) {
var path = paths.join(Config.paths.art, themeID, 'theme_info.json');
var path = paths.join(Config.paths.themes, themeID, 'theme_info.json');
fs.readFile(path, function onData(err, data) {
if(err) {
@ -38,20 +30,20 @@ function getThemeInfo(themeID, cb) {
});
}
var availableThemes;
var availableThemes = {};
function loadAvailableThemes(cb) {
function initAvailableThemes(cb) {
// lazy init
async.waterfall(
[
function getDir(callback) {
fs.readdir(Config.paths.art, function onReadDir(err, files) {
fs.readdir(Config.paths.themes, function onReadDir(err, files) {
callback(err, files);
});
},
function filterFiles(files, callback) {
var filtered = files.filter(function onFilter(file) {
return fs.statSync(paths.join(Config.paths.art, file)).isDirectory();
return fs.statSync(paths.join(Config.paths.themes, file)).isDirectory();
});
callback(null, filtered);
},
@ -75,30 +67,17 @@ function loadAvailableThemes(cb) {
return;
}
if(!availableThemes) {
cb(new Error('No themes found'));
return;
}
cb(null);
cb(null, availableThemes.length);
}
);
}
function getRandomTheme(cb) {
var themeIds;
if(availableThemes) {
themeIds = Object.keys(availableThemes);
if(availableThemes.length > 0) {
var themeIds = Object.keys(availableThemes);
cb(null, themeIds[Math.floor(Math.random() * themeIds.length)]);
} else {
loadAvailableThemes(function onThemes(err) {
if(err) {
cb(err);
} else {
themeIds = Object.keys(availableThemes);
cb(null, themeIds[Math.floor(Math.random() * themeIds.length)]);
}
});
cb(new Error('No themes available'));
}
}
@ -113,11 +92,11 @@ function getThemeArt(name, themeID, options, cb) {
options.asAnsi = true;
options.readSauce = true; // can help with encoding
options.random = miscUtil.valueWithDefault(options.random, true);
options.basePath = paths.join(Config.paths.art, themeID);
options.basePath = paths.join(Config.paths.themes, themeID);
art.getArt(name, options, function onThemeArt(err, theArt) {
if(err) {
// try fallback
// try fallback of art directory
options.basePath = Config.paths.art;
art.getArt(name, options, function onFallbackArt(err, theArt) {
if(err) {

View File

@ -4,7 +4,9 @@
var ansi = require('../core/ansi_term.js');
var artwork = require('../core/art.js');
var modules = require('../core/modules.js');
var Log = require('../core/logger.js').log;
var packageJson = require('../package.json');
var util = require('util');
exports.moduleInfo = {
@ -15,17 +17,55 @@ exports.moduleInfo = {
exports.entryPoint = entryPoint;
function entryPoint(client) {
/*var self = this;
this.client = client;
var term = this.client.term;*/
function ansiQueryTermSizeIfNeeded(client) {
if(client.term.termHeight > 0 || client.term.termWidth > 0) {
return;
}
var onCPR = function(pos) {
//
// If we've already found out, disregard
//
if(client.term.termHeight > 0 || client.term.termWidth > 0) {
return;
}
client.term.termHeight = pos[0];
client.term.termWidth = pos[1];
Log.debug({ termWidth : client.term.termWidth, termHeight : client.term.termHeight, updateSource : 'ANSI CPR' }, 'Window size updated');
};
client.once('cursor position report', onCPR);
// give up after 2s
setTimeout(function onTimeout() {
client.removeListener('cursor position report', onCPR);
}, 2000);
client.term.write(ansi.queryScreenSize());
}
function entryPoint(client) {
var term = client.term;
//
// If we don't yet know the client term width/height,
// try with a nonstandard ANSI DSR type request.
//
ansiQueryTermSizeIfNeeded(client);
term.write(ansi.normal());
term.write(ansi.disableVT100LineWrapping());
//
// If we don't yet know the client term width/height, try
// a nonstandard ANSI query
//
// :TODO: set xterm stuff -- see x84/others
// :TODO: add URL to banner

View File

@ -29,7 +29,8 @@ function entryPoint(client) {
// :TODO: types, random, and others? could come from conf.mods.matrix or such
//art.getArt('SO-CC1.ANS'/* 'MATRIX'*/, { types: ['.ans'], random: true}, function onArt(err, theArt) {
theme.getThemeArt('MATRIX_1', client.user.properties.art_theme_name, function onArt(err, theArt) {
//client.user.properties.art_theme_id = '';
theme.getThemeArt('MATRIX_1', client.user.properties.art_theme_id, function onArt(err, theArt) {
//art.getArt('MATRIX_1.ANS', {}, function onArt(err, theArt) {
if(!err) {