Enabled adding a context to render, so that dynamic fields can resolve locally (like in a message). Improved dynamic fields identification and resolution. Use of more consts for standard frames. Fix history recording and backtracking.
This commit is contained in:
15
load/defs.js
15
load/defs.js
@@ -59,6 +59,10 @@ const FRAME_TYPE_EXTERNAL ='x';
|
||||
const FRAME_TYPE_RESPONSE ='r';
|
||||
/* Login frame, enables the user to authenticate to the system, or to a CUG */
|
||||
const FRAME_TYPE_LOGIN ='l';
|
||||
/* Mail template frames - mail templates will have the user's stats for the area passed to render() */
|
||||
const FRAME_TYPE_MAIL_TEMPLATE ='m';
|
||||
/* Frame is a message */
|
||||
const FRAME_TYPE_MESSAGE ='M';
|
||||
|
||||
/* Disable *# going backwards for the following frames */
|
||||
var NO_HISTORY_FRAMES =['980a','98b','981a','982a','983a','998a'];
|
||||
@@ -74,6 +78,7 @@ const INACTIVE_LOGIN =5*60000;
|
||||
|
||||
var SYSTEM_ZONE =516;
|
||||
|
||||
// @todo rename these all to FRAME_*
|
||||
/* Home Frame */
|
||||
const HOME_FRAME ={frame: 1,index: 'a'};
|
||||
/* Login Frame */
|
||||
@@ -88,8 +93,18 @@ const LOGIN_FAILED_FRAME ={frame: 983,index: 'a'};
|
||||
const HOME_FRAME_AUTH ={frame: 98,index: 'b'};
|
||||
/* Home page for initial connection */
|
||||
const HOME_FRAME_CONNECT ={frame: 980,index: 'a'};
|
||||
const FRAME_SYSTEM_ERROR ={frame: 998,index: 'a'};
|
||||
|
||||
/* Attributes saved/loaded from files */
|
||||
const SAVED_FRAME_ATTRS =['version','frame','frame_fields','index','owner','cost','content','isPublic','isAccessible','type','key'];
|
||||
|
||||
/* The page that has our echomail area reading template */
|
||||
var MAIL_TEMPLATE_FRAME ='199a';
|
||||
|
||||
/* The page that has our echomail area summary template */
|
||||
var MAIL_TEMPLATE_AREA_SUMMARY ='198a';
|
||||
|
||||
// The maximum size of embedded dynamic fields in frames
|
||||
var DYNAMIC_FIELD_SIZE_MAX =50;
|
||||
|
||||
this;
|
||||
|
@@ -75,7 +75,7 @@ function FrameAnsi() {
|
||||
}
|
||||
|
||||
// Render the frame to the user
|
||||
this.render=function(withoutHeader) {
|
||||
this.render=function(context,withoutHeader) {
|
||||
log(LOG_DEBUG,'- ANSI FRAME');
|
||||
owner = base64_decode(this.owner);
|
||||
|
||||
@@ -99,7 +99,7 @@ function FrameAnsi() {
|
||||
contentgraphic = new Graphic(this.settings.FRAME_WIDTH);
|
||||
contentgraphic.auto_extend = true;
|
||||
contentgraphic.atcodes = false;
|
||||
contentgraphic.ANSI = this.parse(base64_decode(this.content));
|
||||
contentgraphic.ANSI = this.parse(base64_decode(this.content),context);
|
||||
|
||||
var contentframe = new Frame(1,2,this.settings.FRAME_WIDTH,this.settings.FRAME_LENGTH,LIGHTGRAY,frame);
|
||||
contentframe.open();
|
||||
|
@@ -1,5 +1,3 @@
|
||||
var MAIL_TEMPLATE_FRAME = '199a';
|
||||
|
||||
// Our frame object
|
||||
function PageFrame() {
|
||||
'use strict';
|
||||
@@ -171,8 +169,7 @@ PageFrame.prototype.load = function(filename) {
|
||||
log(LOG_ERROR,'Frame error: '+error);
|
||||
|
||||
// Load our system error frame.
|
||||
// @todo this should be a config item
|
||||
this.load('998a');
|
||||
this.load(pageStr(FRAME_SYSTEM_ERROR));
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -190,11 +187,13 @@ PageFrame.prototype.loadMessage = function(page) {
|
||||
this.owner = 1;
|
||||
this.isPublic = true;
|
||||
this.isAccessible = true;
|
||||
this.key = [0,null,null,null,null,null,null,null,null,918];
|
||||
// @todo Keys should map to next/previous/send, etc as indicated in the template frame.
|
||||
this.key = [this.frame.substr(0,7)+'1',null,null,null,null,null,null,null,null,null];
|
||||
this.type = FRAME_TYPE_MESSAGE;
|
||||
|
||||
// Load our message
|
||||
var ma = new MsgAreas()
|
||||
var msg = ma.getMessage(page);
|
||||
var msg = ma.getMessage(this.frame);
|
||||
var msg_header;
|
||||
|
||||
if (! msg)
|
||||
@@ -215,6 +214,7 @@ PageFrame.prototype.loadMessage = function(page) {
|
||||
msg_header += 'SUBJECT: '+msg.subject.substr(0,72)+"\n\r";
|
||||
|
||||
} else {
|
||||
// @todo change this to use atcode()
|
||||
msg_header = base64_decode(to.content).replace(/@(.*)@/g,
|
||||
function (str, code, offset, s) {
|
||||
var length = code.split(':')[1];
|
||||
@@ -228,7 +228,7 @@ PageFrame.prototype.loadMessage = function(page) {
|
||||
);
|
||||
}
|
||||
|
||||
log(LOG_DEBUG,'Loaded message: '+msg_header+msg.content);
|
||||
//log(LOG_DEBUG,'Loaded message: '+msg_header+msg.content);
|
||||
this.content = base64_encode(msg_header+msg.content);
|
||||
|
||||
log(LOG_DEBUG,'Loaded frame: ['+this.frame+']['+this.index+'] ('+this.page+')');
|
||||
@@ -247,8 +247,16 @@ PageFrame.prototype.loadMessage = function(page) {
|
||||
* should apply for that field.
|
||||
*
|
||||
* @param text
|
||||
* @param context
|
||||
*/
|
||||
PageFrame.prototype.parse = function(text) {
|
||||
PageFrame.prototype.parse = function(text,context) {
|
||||
log(LOG_DEBUG,'Parsing Frame ...');
|
||||
|
||||
if (this.type === FRAME_TYPE_MESSAGE) {
|
||||
log(LOG_DEBUG,'- Not parsing message frame');
|
||||
return text;
|
||||
}
|
||||
|
||||
/** Column
|
||||
* @type {number}
|
||||
*/
|
||||
@@ -394,13 +402,16 @@ PageFrame.prototype.parse = function(text) {
|
||||
break;
|
||||
|
||||
// X - dynamic fields, terminated with ESC
|
||||
// Dynamic fields are defined with ESC X FIELD;LENGTH;PAD ESC \
|
||||
// @note FIELD & LENGTH are required
|
||||
// @note Dynamic field is can only be DYNAMIC_FIELD_SIZE_MAX chars in size
|
||||
case 'X':
|
||||
//log(LOG_DEBUG,'PU ['+r+'x'+c+'] '+advance);
|
||||
//log(LOG_DEBUG,'DF ['+r+'x'+c+'] '+advance);
|
||||
advance++;
|
||||
|
||||
// Find our end ST param in the next 50 chars
|
||||
matches = text.substr(p+advance,50).match(/(([a-z]+;[0-9]+)([;]?.+)?)\x1b\\/);
|
||||
//log(LOG_DEBUG,'PU ['+r+'x'+c+'] ADVANCE: '+advance+', MATCHES: '+JSON.stringify(matches)+', LENGTH: '+(matches ? matches[0].length : 0)+', STRING: '+text.substr(p+advance,50));
|
||||
// Find our end ST param in the next DYNAMIC_FIELD_SIZE_MAX chars
|
||||
matches = text.substr(p+advance,DYNAMIC_FIELD_SIZE_MAX).match(/(([a-zA-Z._^;]+[0-9]?;-?[0-9^;]+)([;]?[^;]+)?)\x1b\\/);
|
||||
//log(LOG_DEBUG,'- DF ['+r+'x'+c+'] ADVANCE: '+advance+', MATCHES: '+JSON.stringify(matches)+', LENGTH: '+(matches ? matches[0].length : 0)+', STRING: '+text.substr(p+advance,50));
|
||||
|
||||
if (! matches) {
|
||||
chars += nextbyte;
|
||||
@@ -410,14 +421,13 @@ PageFrame.prototype.parse = function(text) {
|
||||
|
||||
advance += matches[0].length-1;
|
||||
|
||||
var pu = matches[0].substr(0,matches[0].length-2).split(';');
|
||||
//log(LOG_DEBUG,'PU ['+r+'x'+c+'] ADVANCE: '+advance+', PU: '+pu);
|
||||
var df = matches[0].substr(0,matches[0].length-2).split(';');
|
||||
//log(LOG_DEBUG,'- DF ['+r+'x'+c+'] ADVANCE: '+advance+', DF: '+df);
|
||||
|
||||
chars = renderfield(pu[0],pu[1]);
|
||||
log(LOG_DEBUG,'- DF found at ['+r+'x'+(c-1)+'], Field: '+df[0]+', Length: '+df[1]+', Attrs: '+JSON.stringify({i:i,f:f,b:b}));
|
||||
chars = atcode(df[0],df[1],df[2],context);
|
||||
byte = '';
|
||||
|
||||
log(LOG_DEBUG,'PU Field found at ['+r+'x'+(c-1)+'], Field: '+pu[0]+', Length: '+pu[1]+', Attrs: '+JSON.stringify({i:i,f:f,b:b}));
|
||||
|
||||
break;
|
||||
|
||||
// _ - has our fields that take input
|
||||
@@ -528,12 +538,5 @@ PageFrame.prototype.parse = function(text) {
|
||||
*/
|
||||
}
|
||||
|
||||
// Convert any atcodes
|
||||
output = output.replace(/@(.*)@/g,
|
||||
function (str, code, offset, s) {
|
||||
return bbs.atcode(code);
|
||||
}
|
||||
);
|
||||
|
||||
return output;
|
||||
};
|
||||
|
@@ -104,6 +104,58 @@ function ans2bin(ansi,frame) {
|
||||
}
|
||||
}
|
||||
|
||||
// Dynamic Field Processing
|
||||
// @note bbs.atcodes() cannot process modifiers, so this function is a replacement.
|
||||
function atcode(field,length,pad,context) {
|
||||
'use strict';
|
||||
|
||||
length = length ? length : field.length;
|
||||
pad = pad ? pad : ' ';
|
||||
var result = '';
|
||||
|
||||
switch(field) {
|
||||
// Get the ECHOAREA FTN AREA_TAG
|
||||
case 'areatag':
|
||||
if (typeof context !== 'object') {
|
||||
log(LOG_ERROR,'Unable to render ['+field+'], no context provided');
|
||||
break;
|
||||
}
|
||||
|
||||
result = context.msgbase.cfg.area_tag;
|
||||
break;
|
||||
|
||||
// Get the ECHOAREA Description
|
||||
case 'areadesc':
|
||||
if (typeof context !== 'object') {
|
||||
log(LOG_ERROR,'Unable to render ['+field+'], no context provided');
|
||||
break;
|
||||
}
|
||||
|
||||
result = context.msgbase.cfg.description;
|
||||
break;
|
||||
|
||||
case 'nodeid':
|
||||
result = getNodeID();
|
||||
break;
|
||||
|
||||
default:
|
||||
result = bbs.atcode(field);
|
||||
|
||||
if (result === null)
|
||||
result = '';
|
||||
}
|
||||
|
||||
log(LOG_DEBUG,' - result length ['+result.length+'] desired ('+length+')');
|
||||
if (result.length < Math.abs(length))
|
||||
result = (length < 0) ? padright(result,Math.abs(length),pad) : padleft(result,length,pad);
|
||||
else if (result.length > Math.abs(length))
|
||||
result = result.substr(0,Math.abs(length));
|
||||
|
||||
log(LOG_DEBUG,'- ATCODE ['+field+'] ('+length+'|"'+pad+'") returns ['+result+']');
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a message base by code
|
||||
*
|
||||
@@ -164,7 +216,7 @@ function getNodeID() {
|
||||
}
|
||||
}
|
||||
|
||||
return pad(matches[0],3)+pad(matches[1],3)+pad(bbs.node_num,2);
|
||||
return padleft(matches[0],3,'0')+padleft(matches[1],3,'0')+padleft(bbs.node_num,2,'0');
|
||||
}
|
||||
|
||||
function getPageOwners() {
|
||||
@@ -228,11 +280,18 @@ function msgBaseImport(msgbase,page,text) {
|
||||
return msgbase.save_msg(hdr, body);
|
||||
}
|
||||
|
||||
// Pad a number with zeros
|
||||
function pad(n, width, z) {
|
||||
z = z || '0';
|
||||
// Right Pad a string with char c
|
||||
function padright(n,width,c) {
|
||||
c = c || '0';
|
||||
n = n + '';
|
||||
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
|
||||
return n.length >= width ? n : new Array(width - n.length + 1).join(c) + n;
|
||||
}
|
||||
|
||||
// Left Pad a string with char c
|
||||
function padleft(n,width,c) {
|
||||
c = c || '0';
|
||||
n = n + '';
|
||||
return n.length >= width ? n : n+new Array(width - n.length + 1).join(c);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -314,20 +373,6 @@ function pageEditor(page) {
|
||||
return pageditor;
|
||||
}
|
||||
|
||||
function renderfield(field,length) {
|
||||
switch (field) {
|
||||
case 'nodeid':
|
||||
result = getNodeID();
|
||||
}
|
||||
|
||||
if (result.length < length)
|
||||
result += ' '.repeat(length-result.length);
|
||||
else if (result.length > length)
|
||||
result = result.substr(0,length);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns a list of zones used by this system.
|
||||
*/
|
||||
|
@@ -230,17 +230,30 @@ MsgArea.prototype.tag_msgs = function() {
|
||||
return true;
|
||||
}
|
||||
|
||||
MsgAreas.prototype.getMessage = function(page) {
|
||||
if (page === undefined)
|
||||
MsgAreas.prototype.getArea = function(area) {
|
||||
log(LOG_DEBUG,'- AREA:'+JSON.stringify(area));
|
||||
if (area === undefined)
|
||||
return undefined;
|
||||
|
||||
var zone = page.substr(0,4);
|
||||
var echo = page.substr(4,2);
|
||||
var page = page.substr(6);
|
||||
var zone = (''+area).substr(1,4);
|
||||
var echo = (''+area).substr(5,2);
|
||||
log(LOG_DEBUG,' - zone:'+JSON.stringify(zone));
|
||||
log(LOG_DEBUG,' - echo:'+JSON.stringify(echo));
|
||||
|
||||
area = this.areas.filter(function(x) {
|
||||
return this.areas.filter(function(x) {
|
||||
return x.zone_id === zone && x.area_id === echo;
|
||||
})[0]
|
||||
|
||||
return area ? area.getMessage(page) : undefined;
|
||||
}
|
||||
|
||||
MsgAreas.prototype.getMessage = function(page) {
|
||||
var area = this.getArea(page);
|
||||
log(LOG_DEBUG,' - msg:'+JSON.stringify(page.substr(7,4)));
|
||||
|
||||
return area ? area.getMessage(page.substr(7,4)) : undefined;
|
||||
}
|
||||
|
||||
MsgAreas.prototype.getUserStats = function(page) {
|
||||
var area = this.getArea(page);
|
||||
|
||||
return area ? msg_area.grp_list[area.msgbase.cfg.grp_number].sub_list[msg_area.sub[area.msgbase.cfg.code].index] : undefined;
|
||||
}
|
||||
|
Reference in New Issue
Block a user