* 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 iconv = require('iconv-lite');
|
||||||
var paths = require('path');
|
var paths = require('path');
|
||||||
|
var async = require('async');
|
||||||
|
|
||||||
exports.bbsMain = function() {
|
exports.bbsMain = bbsMain;
|
||||||
|
|
||||||
|
function bbsMain() {
|
||||||
var mainArgs = parseArgs();
|
var mainArgs = parseArgs();
|
||||||
|
|
||||||
var configPathSupplied = false;
|
var configPathSupplied = false;
|
||||||
|
@ -74,6 +77,41 @@ function parseArgs() {
|
||||||
return args;
|
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() {
|
function preServingInit() {
|
||||||
iconv.extendNodeEncodings();
|
iconv.extendNodeEncodings();
|
||||||
}
|
}
|
||||||
|
@ -164,16 +202,11 @@ function prepareClient(client, cb) {
|
||||||
if('*' === conf.config.preLoginTheme) {
|
if('*' === conf.config.preLoginTheme) {
|
||||||
var theme = require('./theme.js');
|
var theme = require('./theme.js');
|
||||||
theme.getRandomTheme(function onRandTheme(err, themeId) {
|
theme.getRandomTheme(function onRandTheme(err, themeId) {
|
||||||
if(err) {
|
client.user.properties.art_theme_id = themeId || '';
|
||||||
// :TODO: how to propertly set default/fallback?
|
cb(null);
|
||||||
client.user.properties.art_theme_name = '';
|
|
||||||
} else {
|
|
||||||
client.user.properties.art_theme_name = themeId;
|
|
||||||
}
|
|
||||||
cb();
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
client.user.properties.art_theme_name = conf.config.preLoginTheme;
|
client.user.properties.art_theme_id = conf.config.preLoginTheme;
|
||||||
cb();
|
cb(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -34,6 +34,7 @@ module.exports = {
|
||||||
mods : paths.join(__dirname, './../mods/'),
|
mods : paths.join(__dirname, './../mods/'),
|
||||||
servers : paths.join(__dirname, './servers/'),
|
servers : paths.join(__dirname, './servers/'),
|
||||||
art : paths.join(__dirname, './../mods/art/'),
|
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
|
logs : paths.join(__dirname, './../logs/'), // :TODO: set up based on system, e.g. /var/logs/enigmabbs or such
|
||||||
db : paths.join(__dirname, './../db/'),
|
db : paths.join(__dirname, './../db/'),
|
||||||
},
|
},
|
||||||
|
|
|
@ -562,14 +562,16 @@ TelnetClient.prototype.handleSbCommand = function(evt) {
|
||||||
// * Map COLUMNS -> 'termWidth' and only update if ours is 0
|
// * Map COLUMNS -> 'termWidth' and only update if ours is 0
|
||||||
// * Map ROWS -> 'termHeight' and only update if ours is 0
|
// * Map ROWS -> 'termHeight' and only update if ours is 0
|
||||||
// * Add any new variables, ignore any existing
|
// * Add any new variables, ignore any existing
|
||||||
//
|
//
|
||||||
Object.keys(evt.envVars).forEach(function onEnv(name) {
|
Object.keys(evt.envVars).forEach(function onEnv(name) {
|
||||||
if('TERM' === name && 'unknown' === self.term.termType) {
|
if('TERM' === name && 'unknown' === self.term.termType) {
|
||||||
self.setTermType(evt.envVars[name]);
|
self.setTermType(evt.envVars[name]);
|
||||||
} else if('COLUMNS' === name && 0 === self.term.termWidth) {
|
} else if('COLUMNS' === name && 0 === self.term.termWidth) {
|
||||||
self.term.termWidth = parseInt(evt.envVars[name]);
|
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) {
|
} else if('ROWS' === name && 0 === self.term.termHeight) {
|
||||||
self.term.termHeight = parseInt(evt.envVars[name]);
|
self.term.termHeight = parseInt(evt.envVars[name]);
|
||||||
|
logger.log.debug({ termHeight : self.term.termHeight, updateSource : 'NEW-ENVIRON'}, 'Window height updated');
|
||||||
} else {
|
} else {
|
||||||
if(name in self.term.env) {
|
if(name in self.term.env) {
|
||||||
assert(evt.type === SB_COMMANDS.INFO);
|
assert(evt.type === SB_COMMANDS.INFO);
|
||||||
|
@ -582,6 +584,7 @@ TelnetClient.prototype.handleSbCommand = function(evt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} else if('window size' === evt.option) {
|
} else if('window size' === evt.option) {
|
||||||
//
|
//
|
||||||
// Update termWidth & termHeight.
|
// Update termWidth & termHeight.
|
||||||
|
@ -598,7 +601,7 @@ TelnetClient.prototype.handleSbCommand = function(evt) {
|
||||||
self.term.env['ROWS'] = evt.height;
|
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 {
|
} else {
|
||||||
console.log('unhandled SB: ' + JSON.stringify(evt));
|
console.log('unhandled SB: ' + JSON.stringify(evt));
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,18 +11,10 @@ var async = require('async');
|
||||||
exports.getThemeInfo = getThemeInfo;
|
exports.getThemeInfo = getThemeInfo;
|
||||||
exports.getThemeArt = getThemeArt;
|
exports.getThemeArt = getThemeArt;
|
||||||
exports.getRandomTheme = getRandomTheme;
|
exports.getRandomTheme = getRandomTheme;
|
||||||
|
exports.initAvailableThemes = initAvailableThemes;
|
||||||
|
|
||||||
// getThemeInfo(themeName)
|
|
||||||
/*
|
|
||||||
// getThemeFile(themeShortName, name)
|
|
||||||
// getArt(name, {
|
|
||||||
basePath : themeDir,
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
function getThemeInfo(themeID, cb) {
|
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) {
|
fs.readFile(path, function onData(err, data) {
|
||||||
if(err) {
|
if(err) {
|
||||||
|
@ -38,20 +30,20 @@ function getThemeInfo(themeID, cb) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var availableThemes;
|
var availableThemes = {};
|
||||||
|
|
||||||
function loadAvailableThemes(cb) {
|
function initAvailableThemes(cb) {
|
||||||
// lazy init
|
// lazy init
|
||||||
async.waterfall(
|
async.waterfall(
|
||||||
[
|
[
|
||||||
function getDir(callback) {
|
function getDir(callback) {
|
||||||
fs.readdir(Config.paths.art, function onReadDir(err, files) {
|
fs.readdir(Config.paths.themes, function onReadDir(err, files) {
|
||||||
callback(err, files);
|
callback(err, files);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function filterFiles(files, callback) {
|
function filterFiles(files, callback) {
|
||||||
var filtered = files.filter(function onFilter(file) {
|
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);
|
callback(null, filtered);
|
||||||
},
|
},
|
||||||
|
@ -75,30 +67,17 @@ function loadAvailableThemes(cb) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!availableThemes) {
|
cb(null, availableThemes.length);
|
||||||
cb(new Error('No themes found'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cb(null);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRandomTheme(cb) {
|
function getRandomTheme(cb) {
|
||||||
var themeIds;
|
if(availableThemes.length > 0) {
|
||||||
if(availableThemes) {
|
var themeIds = Object.keys(availableThemes);
|
||||||
themeIds = Object.keys(availableThemes);
|
|
||||||
cb(null, themeIds[Math.floor(Math.random() * themeIds.length)]);
|
cb(null, themeIds[Math.floor(Math.random() * themeIds.length)]);
|
||||||
} else {
|
} else {
|
||||||
loadAvailableThemes(function onThemes(err) {
|
cb(new Error('No themes available'));
|
||||||
if(err) {
|
|
||||||
cb(err);
|
|
||||||
} else {
|
|
||||||
themeIds = Object.keys(availableThemes);
|
|
||||||
cb(null, themeIds[Math.floor(Math.random() * themeIds.length)]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,11 +92,11 @@ function getThemeArt(name, themeID, options, cb) {
|
||||||
options.asAnsi = true;
|
options.asAnsi = true;
|
||||||
options.readSauce = true; // can help with encoding
|
options.readSauce = true; // can help with encoding
|
||||||
options.random = miscUtil.valueWithDefault(options.random, true);
|
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) {
|
art.getArt(name, options, function onThemeArt(err, theArt) {
|
||||||
if(err) {
|
if(err) {
|
||||||
// try fallback
|
// try fallback of art directory
|
||||||
options.basePath = Config.paths.art;
|
options.basePath = Config.paths.art;
|
||||||
art.getArt(name, options, function onFallbackArt(err, theArt) {
|
art.getArt(name, options, function onFallbackArt(err, theArt) {
|
||||||
if(err) {
|
if(err) {
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
var ansi = require('../core/ansi_term.js');
|
var ansi = require('../core/ansi_term.js');
|
||||||
var artwork = require('../core/art.js');
|
var artwork = require('../core/art.js');
|
||||||
var modules = require('../core/modules.js');
|
var modules = require('../core/modules.js');
|
||||||
|
var Log = require('../core/logger.js').log;
|
||||||
var packageJson = require('../package.json');
|
var packageJson = require('../package.json');
|
||||||
|
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
|
|
||||||
exports.moduleInfo = {
|
exports.moduleInfo = {
|
||||||
|
@ -15,17 +17,55 @@ exports.moduleInfo = {
|
||||||
|
|
||||||
exports.entryPoint = entryPoint;
|
exports.entryPoint = entryPoint;
|
||||||
|
|
||||||
function entryPoint(client) {
|
function ansiQueryTermSizeIfNeeded(client) {
|
||||||
/*var self = this;
|
if(client.term.termHeight > 0 || client.term.termWidth > 0) {
|
||||||
this.client = client;
|
return;
|
||||||
var term = this.client.term;*/
|
}
|
||||||
|
|
||||||
|
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;
|
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.normal());
|
||||||
|
|
||||||
term.write(ansi.disableVT100LineWrapping());
|
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: set xterm stuff -- see x84/others
|
||||||
|
|
||||||
// :TODO: add URL to banner
|
// :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
|
// :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) {
|
//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) {
|
//art.getArt('MATRIX_1.ANS', {}, function onArt(err, theArt) {
|
||||||
if(!err) {
|
if(!err) {
|
||||||
|
|
Loading…
Reference in New Issue