Started on initial implementation
This commit is contained in:
parent
19d92b34e4
commit
d3a0fb40f9
|
@ -6,14 +6,19 @@ const Config = require('./config.js').get;
|
||||||
const StatLog = require('./stat_log.js');
|
const StatLog = require('./stat_log.js');
|
||||||
const UserProps = require('./user_property.js');
|
const UserProps = require('./user_property.js');
|
||||||
const SysProps = require('./system_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
|
// deps
|
||||||
const fs = require('graceful-fs');
|
const fs = require('graceful-fs');
|
||||||
const paths = require('path');
|
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const moment = require('moment');
|
const moment = require('moment');
|
||||||
const iconv = require('iconv-lite');
|
const iconv = require('iconv-lite');
|
||||||
const { mkdirs } = require('fs-extra');
|
const { mkdirs } = require('fs-extra');
|
||||||
|
const { stripMciColorCodes } = require('./color_codes.js');
|
||||||
|
|
||||||
//
|
//
|
||||||
// Resources
|
// Resources
|
||||||
|
@ -32,6 +37,12 @@ module.exports = class DropFile {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.fileType = fileType.toUpperCase();
|
this.fileType = fileType.toUpperCase();
|
||||||
this.baseDir = baseDir;
|
this.baseDir = baseDir;
|
||||||
|
|
||||||
|
|
||||||
|
this.dropFileFormatDirectory = paths.join(
|
||||||
|
__dirname,
|
||||||
|
'dropfile_formats'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static dropFileDirectory(baseDir, client) {
|
static dropFileDirectory(baseDir, client) {
|
||||||
|
@ -60,6 +71,8 @@ module.exports = class DropFile {
|
||||||
JUMPER: 'JUMPER.DAT', // 2AM BBS
|
JUMPER: 'JUMPER.DAT', // 2AM BBS
|
||||||
SXDOOR: 'SXDOOR.' + _.pad(this.client.node.toString(), 3, '0'), // System/X, dESiRE
|
SXDOOR: 'SXDOOR.' + _.pad(this.client.node.toString(), 3, '0'), // System/X, dESiRE
|
||||||
INFO: 'INFO.BBS', // Phoenix BBS
|
INFO: 'INFO.BBS', // Phoenix BBS
|
||||||
|
SOLARREALMS: 'DOORFILE.SR',
|
||||||
|
XTRN: 'XTRN.DAT',
|
||||||
}[this.fileType];
|
}[this.fileType];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,11 +81,24 @@ module.exports = class DropFile {
|
||||||
}
|
}
|
||||||
|
|
||||||
getHandler() {
|
getHandler() {
|
||||||
return {
|
// TODO: Replace with a switch statement once we have binary handlers as well
|
||||||
DOOR: this.getDoorSysBuffer,
|
|
||||||
DOOR32: this.getDoor32Buffer,
|
// Read the directory containing the dropfile formats, and return undefined if we don't have the format
|
||||||
DORINFO: this.getDoorInfoDefBuffer,
|
const fileName = this.fileName();
|
||||||
}[this.fileType];
|
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() {
|
getContents() {
|
||||||
|
@ -80,6 +106,27 @@ module.exports = class DropFile {
|
||||||
return handler();
|
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() {
|
getDoorInfoFileName() {
|
||||||
let x;
|
let x;
|
||||||
const node = this.client.node;
|
const node = this.client.node;
|
||||||
|
|
|
@ -124,6 +124,15 @@ const PREDEFINED_MCI_GENERATORS = {
|
||||||
UN: function userName(client) {
|
UN: function userName(client) {
|
||||||
return client.user.username;
|
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) {
|
UI: function userId(client) {
|
||||||
return client.user.userId.toString();
|
return client.user.userId.toString();
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,6 +14,8 @@ const {
|
||||||
formatCountAbbr,
|
formatCountAbbr,
|
||||||
} = require('./string_util.js');
|
} = require('./string_util.js');
|
||||||
|
|
||||||
|
const colorCodes = require('./color_codes.js');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const moment = require('moment');
|
const moment = require('moment');
|
||||||
|
@ -210,7 +212,7 @@ function formatNumberHelper(n, precision, type) {
|
||||||
function formatNumber(value, tokens) {
|
function formatNumber(value, tokens) {
|
||||||
const fill = tokens.fill || (tokens['0'] ? '0' : ' ');
|
const fill = tokens.fill || (tokens['0'] ? '0' : ' ');
|
||||||
const align = tokens.align || (tokens['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' : '');
|
const type = tokens.type || (tokens.precision ? 'g' : '');
|
||||||
|
|
||||||
if (['c', 'd', 'b', 'o', 'x', 'X'].indexOf(type) > -1) {
|
if (['c', 'd', 'b', 'o', 'x', 'X'].indexOf(type) > -1) {
|
||||||
|
@ -299,6 +301,7 @@ const transformers = {
|
||||||
styleSmallI: s => stylizeString(s, 'small i'),
|
styleSmallI: s => stylizeString(s, 'small i'),
|
||||||
styleMixed: s => stylizeString(s, 'mixed'),
|
styleMixed: s => stylizeString(s, 'mixed'),
|
||||||
styleL33t: s => stylizeString(s, 'l33t'),
|
styleL33t: s => stylizeString(s, 'l33t'),
|
||||||
|
sanitized: s => stylizeString(s, 'sanitized'),
|
||||||
|
|
||||||
// :TODO:
|
// :TODO:
|
||||||
// toMegs(), toKilobytes(), ...
|
// toMegs(), toKilobytes(), ...
|
||||||
|
@ -337,7 +340,7 @@ function getValue(obj, path) {
|
||||||
throw new KeyError(quote(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;
|
const re = REGEXP_BASIC_FORMAT;
|
||||||
re.lastIndex = 0; // reset from prev
|
re.lastIndex = 0; // reset from prev
|
||||||
|
|
||||||
|
@ -369,6 +372,11 @@ module.exports = function format(fmt, obj) {
|
||||||
value = transformValue(transformer, value);
|
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 || '');
|
tokens = tokenizeFormatSpec(formatSpec || '');
|
||||||
|
|
||||||
if (_.isNumber(value)) {
|
if (_.isNumber(value)) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
%UR
|
%UR
|
||||||
4
|
4
|
||||||
%SL
|
%SL
|
||||||
1000
|
%LL
|
||||||
999
|
999
|
||||||
COLOR
|
COLOR
|
||||||
NOTPROVIDED
|
NOTPROVIDED
|
||||||
|
|
|
@ -8,7 +8,7 @@ M
|
||||||
%DT
|
%DT
|
||||||
%SW
|
%SW
|
||||||
%SH
|
%SH
|
||||||
1
|
%LL
|
||||||
0
|
0
|
||||||
0
|
0
|
||||||
1
|
1
|
||||||
|
|
|
@ -12,7 +12,7 @@ N
|
||||||
555 555-5555
|
555 555-5555
|
||||||
555 555-5555
|
555 555-5555
|
||||||
NOT PROVIDED
|
NOT PROVIDED
|
||||||
1
|
%LL
|
||||||
%UC
|
%UC
|
||||||
%DT
|
%DT
|
||||||
9999
|
9999
|
||||||
|
@ -33,7 +33,7 @@ Y
|
||||||
C:\DATA
|
C:\DATA
|
||||||
C:\DATA
|
C:\DATA
|
||||||
%SR
|
%SR
|
||||||
%UN
|
%UZ
|
||||||
%CT
|
%CT
|
||||||
Y
|
Y
|
||||||
Y
|
Y
|
||||||
|
@ -47,6 +47,6 @@ Y
|
||||||
%DD
|
%DD
|
||||||
0
|
0
|
||||||
0
|
0
|
||||||
A user
|
%UM
|
||||||
%DR
|
%DR
|
||||||
32767
|
32767
|
|
@ -8,6 +8,6 @@ UNKNOWN
|
||||||
UNKNOWN
|
UNKNOWN
|
||||||
%LO
|
%LO
|
||||||
1
|
1
|
||||||
10
|
%LL
|
||||||
999
|
999
|
||||||
-1
|
-1
|
|
@ -0,0 +1,18 @@
|
||||||
|
%UI
|
||||||
|
%UN
|
||||||
|
NOTPROVIDED
|
||||||
|
%LL
|
||||||
|
N
|
||||||
|
Y
|
||||||
|
999
|
||||||
|
555-555-1212
|
||||||
|
%LO
|
||||||
|
%BD
|
||||||
|
%ND
|
||||||
|
1
|
||||||
|
19200
|
||||||
|
0
|
||||||
|
N
|
||||||
|
Y
|
||||||
|
%BN
|
||||||
|
%SR
|
|
@ -10,7 +10,7 @@ C:\DATA
|
||||||
Yes
|
Yes
|
||||||
%SH
|
%SH
|
||||||
209087929
|
209087929
|
||||||
1
|
%LL
|
||||||
1
|
1
|
||||||
%BD
|
%BD
|
||||||
M
|
M
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
1
|
||||||
|
1
|
||||||
|
19200
|
||||||
|
%BN
|
||||||
|
%UI
|
||||||
|
%UR
|
||||||
|
%UN
|
||||||
|
1
|
||||||
|
999
|
||||||
|
1
|
||||||
|
%ND
|
Loading…
Reference in New Issue