* Work on themes. Ability to use ANSI to detect screen size if NAWS/etc. fail
This commit is contained in:
parent
1ef9a4a1ce
commit
14a321de2f
53
core/bbs.js
53
core/bbs.js
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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/'),
|
||||
},
|
||||
|
|
|
@ -568,8 +568,10 @@ TelnetClient.prototype.handleSbCommand = function(evt) {
|
|||
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));
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue