Started on initial implementation

This commit is contained in:
Nathan Byrd 2023-10-01 21:09:14 +00:00
parent 19d92b34e4
commit d3a0fb40f9
10 changed files with 108 additions and 15 deletions

View File

@ -6,14 +6,19 @@ const Config = require('./config.js').get;
const StatLog = require('./stat_log.js');
const UserProps = require('./user_property.js');
const SysProps = require('./system_property.js');
const paths = require('path');
const Log = require('./logger.js').log;
const getPredefinedMCIFormatObject =
require('./predefined_mci').getPredefinedMCIFormatObject;
const stringFormat = require('./string_format');
// deps
const fs = require('graceful-fs');
const paths = require('path');
const _ = require('lodash');
const moment = require('moment');
const iconv = require('iconv-lite');
const { mkdirs } = require('fs-extra');
const { stripMciColorCodes } = require('./color_codes.js');
//
// Resources
@ -32,6 +37,12 @@ module.exports = class DropFile {
this.client = client;
this.fileType = fileType.toUpperCase();
this.baseDir = baseDir;
this.dropFileFormatDirectory = paths.join(
__dirname,
'dropfile_formats'
);
}
static dropFileDirectory(baseDir, client) {
@ -60,6 +71,8 @@ module.exports = class DropFile {
JUMPER: 'JUMPER.DAT', // 2AM BBS
SXDOOR: 'SXDOOR.' + _.pad(this.client.node.toString(), 3, '0'), // System/X, dESiRE
INFO: 'INFO.BBS', // Phoenix BBS
SOLARREALMS: 'DOORFILE.SR',
XTRN: 'XTRN.DAT',
}[this.fileType];
}
@ -68,11 +81,24 @@ module.exports = class DropFile {
}
getHandler() {
return {
DOOR: this.getDoorSysBuffer,
DOOR32: this.getDoor32Buffer,
DORINFO: this.getDoorInfoDefBuffer,
}[this.fileType];
// TODO: Replace with a switch statement once we have binary handlers as well
// Read the directory containing the dropfile formats, and return undefined if we don't have the format
const fileName = this.fileName();
if (!fileName) {
Log.info({fileType: this.fileType}, 'Dropfile format not supported.');
return undefined;
}
const filePath = paths.join(this.dropFileFormatDirectory, fileName);
fs.access(filePath, fs.constants.R_OK, err => {
if (err) {
Log.info({filename: fileName}, 'Dropfile format not found.');
return undefined;
}
});
// Return the handler to get the dropfile, because in the future we may have additional handlers
return this.getDropfile;
}
getContents() {
@ -80,6 +106,27 @@ module.exports = class DropFile {
return handler();
}
getDropfile() {
// Get the filename to read
const fileName = paths.join(this.dropFileFormatDirectory, this.fileName());
// Read file, or return empty string if it doesn't exist
fs.readFile(fileName, (err, data) => {
if (err) {
Log.warn({filename: fileName}, 'Error reading dropfile format file.');
return '';
}
let text = data;
// Format the data with string_format and predefined_mci
const formatObj = getPredefinedMCIFormatObject(this.client, data);
if (formatObj) {
// Expand the text
text = stringFormat(text, formatObj, true);
}
return text;
});
}
getDoorInfoFileName() {
let x;
const node = this.client.node;

View File

@ -124,6 +124,15 @@ const PREDEFINED_MCI_GENERATORS = {
UN: function userName(client) {
return client.user.username;
},
UZ: function sanitizedUserName(client) {
return client.user.getSanitizedName();
},
UM: function userComment(client) {
return userStatAsString(client, UserProps.UserComment, '');
},
LL: function legacyUserLevel(client) {
return client.user.getLegacySecurityLevel().toString();
},
UI: function userId(client) {
return client.user.userId.toString();
},

View File

@ -14,6 +14,8 @@ const {
formatCountAbbr,
} = require('./string_util.js');
const colorCodes = require('./color_codes.js');
// deps
const _ = require('lodash');
const moment = require('moment');
@ -210,7 +212,7 @@ function formatNumberHelper(n, precision, type) {
function formatNumber(value, tokens) {
const fill = tokens.fill || (tokens['0'] ? '0' : ' ');
const align = tokens.align || (tokens['0'] ? '=' : '>');
const width = Number(tokens.width);
const width = Number(tokens.width);value.replace(/\x1b\[[0-9;]*m/g, '');
const type = tokens.type || (tokens.precision ? 'g' : '');
if (['c', 'd', 'b', 'o', 'x', 'X'].indexOf(type) > -1) {
@ -299,6 +301,7 @@ const transformers = {
styleSmallI: s => stylizeString(s, 'small i'),
styleMixed: s => stylizeString(s, 'mixed'),
styleL33t: s => stylizeString(s, 'l33t'),
sanitized: s => stylizeString(s, 'sanitized'),
// :TODO:
// toMegs(), toKilobytes(), ...
@ -337,7 +340,7 @@ function getValue(obj, path) {
throw new KeyError(quote(path));
}
module.exports = function format(fmt, obj) {
module.exports = function format(fmt, obj, stripMciColorCodes = false) {
const re = REGEXP_BASIC_FORMAT;
re.lastIndex = 0; // reset from prev
@ -369,6 +372,11 @@ module.exports = function format(fmt, obj) {
value = transformValue(transformer, value);
}
// This is used in cases where the output shouldn't allow color codes
if (stripMciColorCodes) {
value = colorCodes.stripMciColorCodes(value);
}
tokens = tokenizeFormatSpec(formatSpec || '');
if (_.isNumber(value)) {

View File

@ -1,7 +1,7 @@
%UR
4
%SL
1000
%LL
999
COLOR
NOTPROVIDED

View File

@ -8,7 +8,7 @@ M
%DT
%SW
%SH
1
%LL
0
0
1

View File

@ -12,7 +12,7 @@ N
555 555-5555
555 555-5555
NOT PROVIDED
1
%LL
%UC
%DT
9999
@ -33,7 +33,7 @@ Y
C:\DATA
C:\DATA
%SR
%UN
%UZ
%CT
Y
Y
@ -47,6 +47,6 @@ Y
%DD
0
0
A user
%UM
%DR
32767

View File

@ -8,6 +8,6 @@ UNKNOWN
UNKNOWN
%LO
1
10
%LL
999
-1

View File

@ -0,0 +1,18 @@
%UI
%UN
NOTPROVIDED
%LL
N
Y
999
555-555-1212
%LO
%BD
%ND
1
19200
0
N
Y
%BN
%SR

View File

@ -10,7 +10,7 @@ C:\DATA
Yes
%SH
209087929
1
%LL
1
%BD
M

View File

@ -0,0 +1,11 @@
1
1
19200
%BN
%UI
%UR
%UN
1
999
1
%ND