WIP: Using new page object, frames stored and retrieved in msgbase, code cleanup, more optimisations needed

This commit is contained in:
Deon George 2023-12-24 17:44:02 +11:00
parent 9513f8d144
commit b90a058d47
12 changed files with 541 additions and 322 deletions

View File

@ -231,7 +231,7 @@ function msgBaseExport(msgbase) {
}
}
var msgbase = new MsgBase(findMsgBase(null));
var msgbase = new MsgBase(findMsgBase(null).code);
log(LOG_DEBUG,'+ ANSITEX_EXPORT: Open message base in ['+msgbase.file+']');
if (! msgbase.open()) {

View File

@ -47,7 +47,7 @@ writeln('Comparing Frame: '+page);
// Load frame
vtx = new FrameViewdata();
vtx.load(page);
vtx.load(page,'bin');
if (! vtx.content) {
writeln('- ! ERROR: VTX File doesnt exist? :'+page);
errors = true;
@ -76,7 +76,7 @@ if (! vtx.content) {
}
ans = new FrameAnsi();
ans.load(page);
ans.load(page,'ans');
if (! ans.content) {
writeln('- ! ERROR: ANS File doesnt exist? :'+page);
errors = true;

View File

@ -195,7 +195,7 @@ function sqrllogin() {
subframe.close();
action = ACTION_GOTO;
next_page = LOGIN_FRAME;
next_page = FRAME_LOGIN;
}
return read;

View File

@ -12,8 +12,8 @@
var CONTROL_ECHOMAIL = '1';
load('frame.js');
load('graphic.js');
//load('frame.js');
//load('graphic.js');
log(LOG_DEBUG,'+ Control ECHOMAIL loaded');
@ -25,7 +25,7 @@ function echomail(page) {
// Setup our frame
fo = viewdata ? new FrameViewdata() : new FrameAnsi();
fo.loadMessage(page);
fo.loadMessage(page,viewdata ? 'vtx' : 'tex');
if (fo.content)
pageframe = fo.render();

View File

@ -2,112 +2,140 @@
* ANSItex definitions
*/
/* Load frames from msgbase */
const FRAMES_MSG_BASE = 'vtx_data';
/* Load frames from files */
const FRAMES_MSG_FILES = true;
/* Unit of cost */
const FRAME_COSTUNIT ='c';
const FRAME_COSTUNIT = 'c';
/** ACTIONS **/
/* Exit the script */
const ACTION_EXIT =99;
const ACTION_EXIT = 99;
/* Reload the current frame */
const ACTION_RELOAD =1;
const ACTION_RELOAD = 1;
/* Goto a specific frame */
const ACTION_GOTO =2;
const ACTION_GOTO = 2;
/* Goto previous frame */
const ACTION_BACKUP =3;
const ACTION_BACKUP = 3;
/* Goto next frame */
const ACTION_NEXT =4;
const ACTION_NEXT = 4;
/* Terminate the session */
const ACTION_TERMINATE =5;
const ACTION_TERMINATE = 5;
/* Submit form contents */
const ACTION_SUBMITRF =6;
const ACTION_SUBMITRF = 6;
/* Star command entry */
const ACTION_STAR =7;
const ACTION_STAR = 7;
/* Edit a frame */
const ACTION_EDIT =8;
const ACTION_EDIT = 8;
/** MODES **/
/* Typing * command on baseline */
const MODE_BL =1;
const MODE_BL = 1;
/* Field Input */
const MODE_FIELD =2;
const MODE_FIELD = 2;
/* Asking if form should be submitted */
const MODE_SUBMITRF =3;
const MODE_SUBMITRF = 3;
/* Response frame not sent */
const MODE_RFNOTSENT =4;
const MODE_RFNOTSENT = 4;
/* Response frame sent */
const MODE_RFSENT =5;
const MODE_RFSENT = 5;
/* Response frame error */
const MODE_RFERROR =6;
const MODE_RFERROR = 6;
/** FRAME TYPES **/
/* Information Frame, requires no response after viewed */
const FRAME_TYPE_INFO ='i';
const FRAME_TYPE_INFO = 'i';
/* Terminate Frame, contents displayed and then carrier dropped */
const FRAME_TYPE_TERMINATE ='t';
const FRAME_TYPE_TERMINATE = 't';
/**
* Frame the calls an External Method
* Contents indicate the method to be called with arguments
*/
const FRAME_TYPE_EXTERNAL ='x';
const FRAME_TYPE_EXTERNAL = 'x';
/**
* Frame calls a door
* Contents indicate the name of the door
*/
const FRAME_TYPE_DOOR = 'X';
/**
* Frame renders a BBS from sbbslist
* Contents can be:
* + preview(bbs) - to show the BBS preview display
* + telnet(bbs) - to telgate to the BBS
*/
const FRAME_TYPE_BBS = 'b';
/**
* Response frame, input fields are embedded in the frame and after input the
* response will be submitted to the Service Provider, or to a method
*/
const FRAME_TYPE_RESPONSE ='r';
const FRAME_TYPE_RESPONSE = 'r';
/* Login frame, enables the user to authenticate to the system, or to a CUG */
const FRAME_TYPE_LOGIN ='l';
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';
const FRAME_TYPE_MAIL_TEMPLATE = 'm';
/* Frame is a message */
const FRAME_TYPE_MESSAGE ='M';
const FRAME_TYPE_MESSAGE = 'M';
/* Disable *# going backwards for the following frames */
var NO_HISTORY_FRAMES =['980a','98b','981a','982a','983a','998a'];
const FRAMES_NO_HISTORY = ['980a','98b','981a','982a','983a','998a'];
/* Frames prefixed with this are owned by the system */
const SYSTEM_OWNER =9;
const SYSTEM_OWNER = 9;
// @todo can we get this from the message base?
const SYSTEM_ZONE = 516;
/* Time to wait for a key press */
const INKEY_TIMEOUT =10000;
const INACTIVE_TIMEOUT = 100000;
/* Idle time for un-authenticated users */
const INACTIVE_NOLOGIN =30000;
const INACTIVE_NOLOGIN = 30000;
/* Idle time for authenticated users */
const INACTIVE_LOGIN =5*60000;
const INACTIVE_LOGIN = 5*60000;
var SYSTEM_ZONE =516;
// @todo rename these all to FRAME_*
/* Home Frame */
const HOME_FRAME ={frame: 1,index: 'a'};
const FRAME_HOME = {frame: 1,index: 'a'};
/* Login Frame */
const LOGIN_FRAME ={frame: 98,index: 'a'};
const FRAME_LOGIN = {frame: 98,index: 'a'};
/* Registration Frame */
const REGISTER_FRAME ={frame: 981,index: 'a'};
const FRAME_REGISTER = {frame: 981,index: 'a'};
/* SQRL Login */
const SQRL_FRAME ={frame: 982,index: 'a'};
const FRAME_SQRL = {frame: 982,index: 'a'};
/* Login Failed */
const LOGIN_FAILED_FRAME ={frame: 983,index: 'a'};
const FRAME_LOGIN_FAILED = {frame: 983,index: 'a'};
/* Home page after authentication */
const HOME_FRAME_AUTH ={frame: 98,index: 'b'};
const FRAME_HOME_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'};
const FRAME_HOME_CONNECT = {frame: 980,index: 'a'};
const FRAME_SYSTEM_ERROR = {frame: 998,index: 'a'};
/* Attributes saved/loaded from files */
const SAVED_FRAME_ATTRS =['content','version','frame','input_fields','index','owner','cost','isPublic','isAccessible','type','key','date'];
const FRAME_SAVE_ATTRS = [
'content', // raw source content of a frame (as stored in vtx/tex files)
'cost', // integer, frame cost
'dynamic_fields', // array of fields
'frame', // Page ID,
'index', // Page index,
'input_fields', // array of fields
'isAccessible', // boolean
'isPublic', // boolean
'key', // array, representing our key actions
'type', // frame type
'version', // frame version (1)
'window' // processed frame data
];
/* The page that has our echomail area reading template */
var MAIL_TEMPLATE_FRAME ='199a';
const MAIL_TEMPLATE_FRAME = '199a';
/* The page that has our echomail area summary template */
var MAIL_TEMPLATE_AREA_SUMMARY ='198a';
const MAIL_TEMPLATE_AREA_SUMMARY = '198a';
// The maximum size of embedded dynamic fields in frames
var DYNAMIC_FIELD_SIZE_MAX =50;
const DYNAMIC_FIELD_SIZE_MAX = 50;
/** ESCAPE CODES **/
const ESC = '\x1b';
this;
const ESC = '\x1b';

View File

@ -331,19 +331,18 @@ function atcode(field,length,pad,context) {
*
* @param code
* @returns {number | string|boolean}
* @deprecated Can this move to the msgbases.js?
*/
function findMsgBase(code) {
if (! code)
code = "tex_data";
// Find the actual sub-code
var sub_code;
code = "vtx_data";
for (var s in msg_area.sub) {
var sub = msg_area.sub[s];
writeln('sub:'+sub.code);
if (sub.code.substr(-code.length).toLowerCase() === code)
return sub.code;
return sub;
}
return false;
@ -438,7 +437,7 @@ function loadOptions(option) {
}
function msgBaseImport(msgbase,page,text) {
var msgbase = new MsgBase(findMsgBase(msgbase));
var msgbase = new MsgBase(findMsgBase(msgbase).code);
log(LOG_DEBUG,'Sending ['+page+'] to message base ['+msgbase.cfg.code+']');

View File

@ -1,6 +1,6 @@
const PAGE_LENGTH = 4; // The size of our page tag.
const PAGE_LAST_KEY = 'last_page';
const MAX_PAGE_NUM = 9999;
const PAGE_LENGTH = 4; // The size of our page tag as stored in the msgbase for echomail/netmail
const PAGE_LAST_KEY = 'last_page'; // Last page which has the latest message
const MAX_PAGE_NUM = 9999; // Maximum page number. @todo Can this be changed to '9'.repeat(PAGE_LENGTH)?
// Our message bases
function MsgAreas() {
@ -40,6 +40,23 @@ function MsgAreas() {
}
}
}
Object.defineProperty(this,'list',{
get: function() {
writeln('Areas that we are NOT managing mail:'+this.areas_excluded.length);
writeln('Areas that we ARE managing mail:'+this.areas.length);
for(var x in this.areas_excluded) {
/*
writeln(this.areas_excluded[x].area_name = undefined
? JSON.stringify(this.areas_excluded[x])
: this.areas_excluded[x].area_name);
*/
writeln(JSON.stringify(this.areas_excluded[x]));
exit();
}
}
});
}
function MsgArea() {

View File

@ -76,9 +76,9 @@
*/
load('ansitex/load/windows.js'); // Our supporting window class
require('sbbsdefs.js','SS_USERON'); // Need for our ANSI colors eg: BG_*
require('ansitex/load/defs.js','FRAME_TYPE_INFO'); // FRAME definitions
require('ansitex/load/msgbases.js','MAX_PAGE_NUM'); // To read/write to message bases
require('ansitex/load/session-ansitex.js','SESSION_ANSITEX'); // @todo Only load this if it is an ANSI page we are loading
require('sbbsdefs.js','SS_USERON'); // Need for our ANSI colors eg: BG_*
/**
* This object represents a full page that interacts with the user
@ -122,14 +122,16 @@ function Page(service,debug) {
};
this.__properties__ = {
type: undefined, // Viewdata or ANSItex frame
name: new PageObject,
type: undefined, // Frame type
input_fields: [], // Array of our input fields
dynamic_fields: [], // Array of our dynamic fields
isAccessible: undefined, // Is this page visible to all users
isPublic: undefined, // Is this page visible to public (not CUG) users
key: [], // Key actions
};
this.__defaults__ = {
@ -156,8 +158,9 @@ function Page(service,debug) {
function init(service,debug) {
log(LOG_DEBUG,'- PAGE::init(): type ['+service+']');
switch (service) {
switch (SESSION_EXT) {
case 'tex':
require('ansitex/load/session/ansitex.js','SESSION_ANSITEX');
this.__window__.layout = new Window(1,1,ANSI_FRAME_WIDTH,ANSI_FRAME_HEIGHT+1,'LAYOUT',this,debug);
this.__window__.body = new Window(1,2,ANSI_FRAME_WIDTH,ANSI_FRAME_HEIGHT,'CONTENT',this.__window__.layout,debug);
@ -169,6 +172,7 @@ function Page(service,debug) {
break;
case 'vtx':
require('ansitex/load/session/viewdata.js','SESSION_VIEWDATA');
// @todo VTX hasnt been worked on at all - need at last a viewdata2attrs function
this.__window__.layout = new Window(1,1,VIEWDATA_FRAME_WIDTH,VIEWDATA_FRAME_HEIGHT+1,'LAYOUT',this,debug);
this.__window__.body = new Window(1,2,VIEWDATA_FRAME_WIDTH,VIEWDATA_FRAME_HEIGHT,'CONTENT',this.__window__.layout,debug)
@ -181,10 +185,8 @@ function Page(service,debug) {
break;
default:
throw new Error('INVALID Page Service: '+service);
throw new Error('INVALID Page Service: '+SESSION_EXT);
}
this.service = service;
}
// @todo change this to Object.defineProperty() - see session.js
@ -192,9 +194,11 @@ function Page(service,debug) {
* Determine if this frame is accessible to the current user
*/
Page.prototype.__defineGetter__('accessible',function() {
log(LOG_DEBUG,'- Checking if user can access frame: '+this.name.name);
log(LOG_DEBUG,'- Checking if user can access frame: '+this.name.toString());
log(LOG_DEBUG,' - User: '+JSON.stringify(user.number));
log(LOG_DEBUG,' - Frame Owner: '+JSON.stringify(this.owner)+', System Frame: '+(this.pageowner === SYSTEM_OWNER));
log(LOG_DEBUG,' - Frame Owner: '+JSON.stringify(this.pageowner)+', System Frame: '+(this.pageowner === SYSTEM_OWNER));
log(LOG_DEBUG,' - Accessible: '+JSON.stringify(this.isAccessible));
log(LOG_DEBUG,' - Public: '+JSON.stringify(this.isPublic));
// user.number 0 is unidentified user.
if (user.number) {
@ -206,7 +210,7 @@ function Page(service,debug) {
);
} else {
return (this.__properties__.isAccessible && this.pageowner === SYSTEM_OWNER && this.__properties__.isPublic);
return this.__properties__.isAccessible && (this.pageowner === SYSTEM_OWNER) && this.__properties__.isPublic;
}
});
@ -214,34 +218,40 @@ function Page(service,debug) {
if (typeof int !== 'number')
throw new Error('Cost must be a number');
switch (this.__properties__.service) {
this.__properties__.cost = int;
// Populate the cost window
switch (SESSION_EXT) {
case 'tex':
if ((''+int).length > ANSI_FRAME_COST_LENGTH-1)
if ((''+int).length > ANSI_FRAME_COST_LENGTH-1-ANSI_FRAME_ATTR_LENGTH)
throw new Error('Cost too large');
this.__window__.cost.__properties__.content = anstoattrs(ESC+'[1;32m'+padright(int,ANSI_FRAME_COST_LENGTH-1,' ')+'c').content;
this.__window__.cost.__properties__.content = anstoattrs(ESC+'[1;32m'+padright(int,ANSI_FRAME_COST_LENGTH-1-ANSI_FRAME_ATTR_LENGTH,' ')+'c').content;
break;
case 'vtx':
if ((''+int).length > VIEWDATA_FRAME_COST_LENGTH-2)
if ((''+int).length > VIEWDATA_FRAME_COST_LENGTH-1-VIEWDATA_FRAME_ATTR_LENGTH)
throw new Error('Cost too large');
this.__window__.cost.__properties__.content = bintoattrs(VIEWDATA_BIN_GREEN+padright(int,VIEWDATA_FRAME_COST_LENGTH-2,' ')+'c').content;
this.__window__.cost.__properties__.content = bintoattrs(VIEWDATA_BIN_GREEN+padright(int,VIEWDATA_FRAME_COST_LENGTH-1-VIEWDATA_FRAME_ATTR_LENGTH,' ')+'c').content;
break;
default:
throw new Error(this.__properties__.service+' type not implemented');
throw new Error(SESSION_EXT+' type not implemented');
}
});
Page.prototype.__defineGetter__('cost',function() {
return Number(this.__properties__.cost);
});
Page.prototype.__defineGetter__('dimensions',function() {
return this.__properties__.width+' X '+this.__properties__.height;
});
Page.prototype.__defineGetter__('dynamic_fields',function() {
return this.__properties__.dynamic_fields;
return this.__properties__.dynamic_fields === undefined ? [] : this.__properties__.dynamic_fields;
});
Page.prototype.__defineSetter__('dynamic_fields',function(array) {
this.__properties__.dynamic_fields = array;
@ -259,17 +269,27 @@ function Page(service,debug) {
});
Page.prototype.__defineSetter__('isAccessible',function(bool) {
if ((typeof bool !== 'boolean') && (typeof bool !== 'number'))
if (typeof bool !== 'boolean')
throw new Error('isAccessible must be a boolean');
this.__properties__.isAccessible = (bool === 1);
this.__properties__.isAccessible = bool;
});
Page.prototype.__defineSetter__('isPublic',function(bool) {
if ((typeof bool !== 'boolean') && (typeof bool !== 'number'))
if (typeof bool !== 'boolean')
throw new Error('isPublic must be a boolean');
this.__properties__.isPublic = (bool === 1);
this.__properties__.isPublic = bool;
});
Page.prototype.__defineGetter__('key',function() {
return this.__properties__.key;
});
Page.prototype.__defineSetter__('key',function(array) {
if (typeof array !== 'object')
throw new Error('key must be an array :'+typeof array);
return this.__properties__.key = array;
});
Page.prototype.__defineGetter__('name',function() {
@ -281,25 +301,25 @@ function Page(service,debug) {
this.__properties__.name = object;
switch (this.__properties__.service) {
switch (SESSION_EXT) {
case 'tex':
if ((''+this.__properties__.name.frame).length > ANSI_FRAME_PAGE_LENGTH-1)
if ((''+this.__properties__.name.frame).length > ANSI_FRAME_PAGE_LENGTH-1-ANSI_FRAME_ATTR_LENGTH)
throw new Error('Pagenum too large');
this.__window__.pagenum.__properties__.content = anstoattrs(ESC+'[1;37m'+this.__properties__.name.name).content;
this.__window__.pagenum.__properties__.content = anstoattrs(ESC+'[1;37m'+this.__properties__.name.toString()).content;
break;
case 'vtx':
if ((''+this.__properties__.name.frame).length > VIEWDATA_FRAME_PAGE_LENGTH-2)
if ((''+this.__properties__.name.frame).length > VIEWDATA_FRAME_PAGE_LENGTH-1-VIEWDATA_FRAME_ATTR_LENGTH)
throw new Error('Pagenum too large');
this.__window__.pagenum.__properties__.content = bintoattrs(VIEWDATA_BIN_WHITE+this.__properties__.name.name).content;
this.__window__.pagenum.__properties__.content = bintoattrs(VIEWDATA_BIN_WHITE+this.__properties__.name.toString()).content;
break;
default:
throw new Error(this.__properties__.service+' type not implemented');
throw new Error(SESSION_EXT+' type not implemented');
}
});
@ -319,7 +339,7 @@ function Page(service,debug) {
Page.prototype.__defineSetter__('provider',function(ansi) {
var provider;
switch (this.__properties__.service) {
switch (SESSION_EXT) {
case 'tex':
provider = anstoattrs(ansi+ESC+'[0m').content;
@ -337,25 +357,12 @@ function Page(service,debug) {
break;
default:
throw new Error(this.__properties__.service+' not implemented');
throw new Error(SESSION_EXT+' not implemented');
}
this.__window__.provider.__properties__.content = provider;
});
Page.prototype.__defineGetter__('service',function() {
return this.__properties__.service;
});
Page.prototype.__defineSetter__('service',function(string) {
if (this.__properties__.service)
throw new Error('service already DEFINED');
if (['VTX','TEX'].indexOf(string) === undefined)
throw new Error('Unknown SERVICE:'+string);
return this.__properties__.service = string;
});
Page.prototype.__defineSetter__('showHeader',function(bool) {
if (typeof bool !== 'boolean')
throw new Error('showHeader expected a true/false');
@ -363,6 +370,16 @@ function Page(service,debug) {
this.__window__.header.visible = bool;
});
Page.prototype.__defineGetter__('type',function() {
return this.__properties__.type;
});
Page.prototype.__defineSetter__('type',function(string) {
if (typeof string !== 'string')
throw new Error('type must be an string :'+typeof string);
return this.__properties__.type = string;
});
Page.prototype.__defineGetter__('width',function() {
return Number(this.__window__.layout.width);
});
@ -381,16 +398,15 @@ function Page(service,debug) {
// Add our dynamic values
var fields = this.dynamic_fields.filter(function(item) { return item.value !== undefined; });
// writeln('We have DF fields:'+fields.length);
log(LOG_DEBUG,'We have DF fields:'+fields.length);
if (fields.length)
insert_fields(fields,this.__compiled__.build);
// Add our dynamic values
fields = this.input_fields.filter(function(item) { return item.value !== undefined; });
log(LOG_DEBUG,'We have INPUT fields:'+fields.length);
// writeln('We have INPUT fields:'+fields.length);
if (fields.length)
insert_fields(fields,this.__compiled__.build);
@ -439,6 +455,7 @@ function Page(service,debug) {
*/
this.display = function(last,color) {
var debug = false;
log(LOG_DEBUG,'DISPLAY CALLED:'+last);
if (! this.__compiled__.build)
this.build();
@ -455,7 +472,7 @@ function Page(service,debug) {
var attr;
switch (this.service) {
switch (SESSION_EXT) {
case 'tex':
new_screen = BG_BLACK|LIGHTGRAY;
break;
@ -505,11 +522,11 @@ function Page(service,debug) {
if ((color === undefined) || color) {
// Only write a new attribute if it has changed (and not Videotex)
if ((this.service === 'vtx') || (last === undefined) || (last !== char.attr)) {
if ((SESSION_EXT === 'vtx') || (last === undefined) || (last !== char.attr)) {
// The current attribute for this character
attr = (char === undefined) ? undefined : char.attribute(last,this.service,debug);
attr = (char === undefined) ? undefined : char.attribute(last,SESSION_EXT,debug);
switch (this.service) {
switch (SESSION_EXT) {
case 'tex':
// If the attribute is null, we'll write our default attribute
if (attr === null)
@ -530,13 +547,13 @@ function Page(service,debug) {
break;
default:
throw new Error('service type:'+this.service+' hasnt been implemented.');
throw new Error('service type:'+SESSION_EXT+' hasnt been implemented.');
}
}
// For no-color output and ViewData, we'll render a character
} else {
if ((this.service === 'vtx') && char.attr)
if ((SESSION_EXT === 'vtx') && char.attr)
line += '^';
}
@ -598,7 +615,7 @@ function Page(service,debug) {
color = (color === undefined) || (color === '1') || (color === true);
writeln('Dumping Page:'+this.name.name);
writeln('Dumping Page:'+this.name.toString());
writeln('= Size :'+this.dimensions);
writeln('- Last :'+last);
writeln('- Color:'+color);
@ -674,7 +691,7 @@ function Page(service,debug) {
var attr = display[y][x].attr;
writeln('X:'+(xx++)+'|'+attr+':'+display[y][x].ch+'|'+display[y][x].attribute(last,this.service,debug));
writeln('X:'+(xx++)+'|'+attr+':'+display[y][x].ch+'|'+display[y][x].attribute(last,SESSION_EXT,debug));
// Only write a new attribute if it has changed
if ((this.last === undefined) || (this.last !== attr)) {
@ -751,17 +768,54 @@ function Page(service,debug) {
this.dynamic_fields[this.dynamic_fields.indexOf(fields[0])].value = value;
}
/**
* Save the frame for later retrieval
* @todo Inject back all input_fields and dynamic_fields
* @todo this is not complete?
*/
this.export = function() {
var line;
// If we have any input fields, we need to insert them back inside ESC .... ESC \ control codes
// @todo avoid the ending ESC \ with a control code.
this.input_fields.filter(function(child) {
if (child.y === y) {
line.content = line.content.substring(0,child.x-1)
+ 'FIELD:'+child.name
+ line.content.substring(child.x+child.length,80)
+ 'END';
}
})
// We draw line by line.
for (var y=1;y<=this.height;y++) {
// Line intro
write('\x1b[0m');
line = this.__window__.layout.drawline(1,this.width,y,false);
write(line.content);
write('\x1b[0m');
writeln();
}
}
/**
* Load a specific page
*
* @param page
* @param ext
*/
this.get = function(page,ext) {
this.get = function(page) {
if (!(page instanceof PageObject))
throw new Error('page must be a PageObject');
return this.import(system.mods_dir+'ansitex/text/'+page.name+'.'+ext);
// Try to load from the msgbase first
if (FRAMES_MSG_BASE && this.load(page))
return true;
return FRAMES_MSG_FILES ? this.import(system.mods_dir+'ansitex/text/'+page.toString()+'.'+SESSION_EXT) : false;
}
/**
@ -866,9 +920,24 @@ function Page(service,debug) {
contents = contents.substr(0, sauceless_size);
}
log(LOG_DEBUG,'*** ['+ext+'].');
return this.preload((['vtx','tex'].indexOf(ext) !== -1) ? JSON.parse(contents) : contents,ext,width,height);
}
/**
* Process a loaded frame from either a file or message base
*
* @param contents
* @param ext
* @param width
* @param height
* @returns {boolean|null}
*/
this.preload = function(contents,ext,width,height) {
switch (ext) {
// ANSI files
case 'ans':
log(LOG_DEBUG,'Processing ANSI file');
var page = anstoattrs(contents,this.width,this.__window__.body.y,this.__window__.body.x);
this.__window__.body.__properties__.content = page.content;
@ -881,83 +950,145 @@ function Page(service,debug) {
// ANSItex files
case 'tex':
case 'vtx':
log(LOG_DEBUG,'Loading FRAME from: '+filename);
log(LOG_DEBUG,'Processing FRAME file');
try {
var load = JSON.parse(contents);
//var load = JSON.parse(contents);
var load = contents;
for (property in SAVED_FRAME_ATTRS) {
switch (SAVED_FRAME_ATTRS[property]) {
log(LOG_DEBUG,'*** ['+JSON.stringify(Object.keys(contents))+']['+(typeof contents)+'].');
for (var index in contents) {
if (FRAME_SAVE_ATTRS.indexOf(index) === -1) {
log(LOG_ERROR,'- Unknown index ['+index+'] in input.');
continue;
}
log(LOG_DEBUG,'* Processing ['+index+'] with value ['+JSON.stringify(contents[index])+'].');
switch (index) {
case 'content':
log(LOG_INFO,'- Parsing content');
//log(LOG_ERROR,'Frame content: '+JSON.stringify(base64_decode(load[SAVED_FRAME_ATTRS[property]])));
if (ext === 'tex')
var page = anstoattrs(base64_decode(load[SAVED_FRAME_ATTRS[property]]).replace("\x0a\x0d\x0a\x0d","\x0a\x0d"),this.width,this.__window__.body.y,this.__window__.body.x);
var page = anstoattrs(base64_decode(contents[index]).replace("\x0a\x0d\x0a\x0d","\x0a\x0d"),this.width,this.__window__.body.y,this.__window__.body.x);
else if (ext === 'vtx')
var page = bintoattrs(base64_decode(load[SAVED_FRAME_ATTRS[property]]),this.width,this.__window__.body.y,this.__window__.body.x);
//log(LOG_ERROR,'Frame content: '+JSON.stringify(page));
var page = bintoattrs(base64_decode(contents[index]),this.width,this.__window__.body.y,this.__window__.body.x);
this.__window__.body.__properties__.content = page.content;
this.dynamic_fields = page.dynamic_fields;
// Our fields are sorted in x descending order
if (page.input_fields.length)
this.input_fields = page.input_fields.sort(function(a,b) { return a.x < b.x ? 1 : -1; });
log(LOG_INFO,'- Parsing content complete');
break;
case 'cost':
this.cost = contents[index];
break;
case 'date':
log(LOG_INFO,'- Frame date : '+load[SAVED_FRAME_ATTRS[property]]);
log(LOG_INFO,'- Frame date : '+contents[index]);
break;
case 'dynamic_fields':
this.dynamic_fields = contents[index];
break;
case 'frame':
this.name.frame = ''+load[SAVED_FRAME_ATTRS[property]];
break;
case 'input_fields':
if (load[SAVED_FRAME_ATTRS[property]])
this.input_fields = load[SAVED_FRAME_ATTRS[property]];
log(LOG_INFO,'- Frame ID : '+contents[index]);
this.name.frame = ''+contents[index];
break;
case 'index':
this.name.index = load[SAVED_FRAME_ATTRS[property]];
log(LOG_INFO,'- Frame Index : '+contents[index]);
this.name.index = contents[index];
break;
case 'input_fields':
this.input_fields = contents[index];
break;
case 'isAccessible':
this.isAccessible = ((contents[index] === 1) || (contents[index] === true));
break;
case 'isPublic':
this.isPublic = ((contents[index] === 1) || (contents[index] === true));
break;
case 'key':
this.key = contents[index];
break;
/*
case 'name':
log(LOG_INFO,'- PAGE name : '+JSON.stringify(contents[index]));
this.name.frame = contents[index].frame;
this.name.index = contents[index].index;
break;
*/
case 'type':
this.type = contents[index];
break;
case 'version':
log(LOG_INFO,'- Frame version : '+load[SAVED_FRAME_ATTRS[property]]);
log(LOG_INFO,'- Frame version : '+contents[index]);
break;
case 'window':
log(LOG_DEBUG,' - RAW: '+JSON.stringify(contents[index]));
for (var y in contents[index]) {
//log(LOG_DEBUG,' - Y: '+y+', '+JSON.stringify(contents[index][y]));
if (contents[index][y] === null)
continue;
for (var x in contents[index][y]) {
//log(LOG_DEBUG,' - X: '+x+', '+JSON.stringify(contents[index][y][x]));
if (contents[index][y][x] === null)
continue;
this.__window__.body.__properties__.content[y][x] = new Char(
contents[index][y][x].__properties__.ch,
contents[index][y][x].__properties__.attr
);
}
}
log(LOG_DEBUG,' - CONTENT: '+JSON.stringify(this.__window__.body.__properties__.content));
break;
default:
log(LOG_DEBUG,'- Frame property: '+SAVED_FRAME_ATTRS[property]+', value:'+load[SAVED_FRAME_ATTRS[property]]);
this[SAVED_FRAME_ATTRS[property]] = load[SAVED_FRAME_ATTRS[property]];
log(LOG_ERROR,'! Frame property not handled: '+index+', value:'+contents[index]);
//this[index] = contents[index];
}
}
// If the page doesnt match the filename, throw an error
// @todo This needs to be tested.
// @todo doesnt work on command line
/*
if (this.name.name !== filename.replace(system.mods_dir+'ansitex/text/','').replace('.'+ext,''))
throw new Error('Frame '+this.name.name+' doesnt match filename:'+filename.replace(system.mods_dir+'ansitex/text/','').replace('.'+ext,''));
*/
} catch (error) {
log(LOG_ERROR,'! Frame error : '+error);
// Load our system error frame.
this.get(new PageObject(FRAME_SYSTEM_ERROR),ext);
// @todo If our system error page errors, then we go into a loop
this.get(new PageObject(FRAME_SYSTEM_ERROR));
return null;
}
log(LOG_DEBUG,'= Loaded frame : '+this.name.toString());
this.loadcomplete();
log(LOG_DEBUG,'= Loaded frame : '+this.name.name);
log(LOG_DEBUG,'= Frame complete : '+this.name.toString());
break;
// ViewData files
case 'bin':
log(LOG_DEBUG,'Processing VIEWDATA file');
var page = bintoattrs(contents,this.width,this.__window__.body.y,this.__window__.body.x,debug);
this.__window__.body.__properties__.content = page.content;
@ -987,27 +1118,71 @@ function Page(service,debug) {
return true;
}
this.load = function(page) {
var mb = new MsgBase(FRAMES_MSG_BASE);
var headers;
try {
if (mb.open()) {
headers = mb.get_all_msg_headers(false,false) || [];
} else {
log(LOG_ERROR,code+' cannot be opened:'+mb.error);
return false;
}
} catch (e) {
log(LOG_ERROR,code+' cannot be opened:'+e.message);
return false;
}
var msg;
// Find existing message with the page number and delete it if defined
for(var x in headers) {
if ((headers[x].tags === page.toString()) && (!(headers[x].attr&MSG_DELETE)) && (headers[x].from === SESSION_EXT)) {
msg = headers[x];
break;
}
}
if (msg === undefined) {
log(LOG_DEBUG,' - Frame not found: ['+page.toString()+'] to ['+FRAMES_MSG_BASE+']');
return false;
} else {
log(LOG_DEBUG,' - LOADING frame: ['+page.toString()+'] from ['+msg.number+']');
var contents = JSON.parse(mb.get_msg_body(false,msg.number,false,false,true,true));
return this.preload(contents,SESSION_EXT);
}
return false;
}
/**
* After page load routines
*/
this.loadcomplete = function() {
var po = pageOwner(this.name.frame);
switch (this.service) {
switch (SESSION_EXT) {
case 'tex':
this.__window__.pagenum.__properties__.content = anstoattrs(ESC+'[1;37m'+this.name.name).content;
this.__window__.pagenum.__properties__.content = anstoattrs(ESC+'[1;37m'+this.name.toString()).content;
this.provider = base64_decode(po.logoans);
break;
case 'vtx':
this.__window__.pagenum.__properties__.content = bintoattrs(VIEWDATA_BIN_WHITE+this.name.name).content;
this.__window__.pagenum.__properties__.content = bintoattrs(VIEWDATA_BIN_WHITE+this.name.toString()).content;
this.provider = base64_decode(po.logovtx);
break;
default:
throw new Error(this.service+' hasnt been implemented');
throw new Error(SESSION_EXT+' hasnt been implemented');
}
// Dont show header on un-authed login frames
@ -1016,37 +1191,129 @@ function Page(service,debug) {
}
/**
* Save the frame for later retrieval
* @todo Inject back all input_fields and dynamic_fields
* @todo this is not complete?
* Save the frame to the message base
*/
this.save = function() {
var line;
var mb = new MsgBase(FRAMES_MSG_BASE);
var headers;
// If we have any input fields, we need to insert them back inside ESC .... ESC \ control codes
// @todo avoid the ending ESC \ with a control code.
try {
if (mb.open()) {
headers = mb.get_all_msg_headers(false,false) || [];
this.input_fields.filter(function(child) {
if (child.y === y) {
line.content = line.content.substring(0,child.x-1)
+ 'FIELD:'+child.name
+ line.content.substring(child.x+child.length,80)
+ 'END';
} else {
log(LOG_ERROR,FRAMES_MSG_BASE+' cannot be opened:'+mb.error);
return;
}
})
// We draw line by line.
for (var y=1;y<=this.height;y++) {
// Line intro
write('\x1b[0m');
} catch (e) {
log(LOG_ERROR,FRAMES_MSG_BASE+' cannot be opened:'+e.message);
line = this.__window__.layout.drawline(1,this.width,y,false);
write(line.content);
write('\x1b[0m');
writeln();
return;
}
// Build the save content
var content = {};
for (var index in FRAME_SAVE_ATTRS) {
switch (FRAME_SAVE_ATTRS[index]) {
case 'cost':
content[FRAME_SAVE_ATTRS[index]] = this.cost;
break;
case 'dynamic_fields':
content[FRAME_SAVE_ATTRS[index]] = this.dynamic_fields;
break;
case 'frame':
content[FRAME_SAVE_ATTRS[index]] = this.name.frame;
break;
case 'index':
content[FRAME_SAVE_ATTRS[index]] = this.name.index;
break;
case 'input_fields':
content[FRAME_SAVE_ATTRS[index]] = this.input_fields;
break;
case 'isAccessible':
content[FRAME_SAVE_ATTRS[index]] = this.__properties__.isAccessible;
break;
case 'isPublic':
content[FRAME_SAVE_ATTRS[index]] = this.__properties__.isPublic;
break;
case 'key':
content[FRAME_SAVE_ATTRS[index]] = this.key;
break;
/*
case 'name':
content[FRAME_SAVE_ATTRS[index]] = { frame: this.name.frame, index: this.name.index };
break;
case 'owner':
content[FRAME_SAVE_ATTRS[index]] = this.owner;
break;
*/
case 'type':
content[FRAME_SAVE_ATTRS[index]] = this.type;
break;
case 'version':
content[FRAME_SAVE_ATTRS[index]] = 1;
break;
case 'window':
content[FRAME_SAVE_ATTRS[index]] = this.__window__.body.__properties__.content;
break;
default:
log(LOG_ERROR,' ! NOTE Index ['+FRAME_SAVE_ATTRS[index]+'] has been ignored.');
continue;
}
log(LOG_DEBUG,' / Storing ['+FRAME_SAVE_ATTRS[index]+'] with value:'+content[FRAME_SAVE_ATTRS[index]]);
}
// Find existing message with the page number and delete it if defined
var msg;
for(var x in headers) {
if ((headers[x].tags === this.name.toString()) && (!(headers[x].attr&MSG_DELETE))) {
msg = headers[x];
break;
}
}
if (msg === undefined) {
log(LOG_DEBUG,' - Saving NEW frame: ['+this.name.toString()+'] to ['+FRAMES_MSG_BASE+']');
} else {
log(LOG_DEBUG,' - REPLACING frame: ['+this.name.toString()+'] at ['+msg.number+']');
if (! mb.remove_msg(msg.number))
log(LOG_ERROR,' ! Error removing frame: ['+this.name.toString()+'] to ['+msg.number+']');
}
log(LOG_DEBUG,'** Save frame with keys'+JSON.stringify(Object.keys(content)));
//ma = new MsgBase(MSG_BASE);
if (! mb.save_msg(
{
subject: this.name.toString(),
to: this.name.toString(),
from: SESSION_EXT,
tags: this.name.toString(),
},
JSON.stringify(content)
))
log(LOG_ERROR,' ! Error saving frame: ['+this.name.toString()+']');
mb.close();
}
init.apply(this,arguments);
@ -1071,8 +1338,6 @@ function PageObject(frame,index) {
}
}
init.apply(this,arguments);
PageObject.prototype.__defineGetter__('frame',function() {
return this.__properties__.frame;
});
@ -1097,10 +1362,6 @@ function PageObject(frame,index) {
this.__properties__.index = string;
});
PageObject.prototype.__defineGetter__('name',function() {
return (this.frame && this.index) ? this.frame+this.index : null;
});
PageObject.prototype.__defineGetter__('next',function() {
var next = undefined;
@ -1112,4 +1373,10 @@ function PageObject(frame,index) {
return next;
});
PageObject.prototype.toString = function() {
return (this.frame && this.index) ? this.frame+this.index : null;
}
init.apply(this,arguments);
}

View File

@ -104,18 +104,9 @@ function Session() {
if (!(page instanceof PageObject))
throw new Error('page must be a PageObject');
switch (this.settings.ext) {
case 'tex':
case 'vtx':
this.page = new Page(this.settings.ext);
break;
default:
throw new Error(this.settings.ext+' has not been implemented');
}
this.baselineSend('LOADING');
this.page.get(page,this.settings.ext);
this.page = new Page(SESSION_EXT);
this.page.get(page);
this.baselineClear();
}
@ -124,7 +115,7 @@ function Session() {
*
* @param page
*/
this.loadMessage = function(page) {
this.loadMessage = function(page,ext) {
this.frame = ''+page;
this.index = 'a';
this.owner = 1;
@ -146,7 +137,7 @@ function Session() {
// @todo Search 1zzzzEE..., 1zzzz...
var to = viewdata ? new FrameViewdata() : new FrameAnsi();
to.load(MAIL_TEMPLATE_FRAME);
to.load(MAIL_TEMPLATE_FRAME,ext);
// @todo Check that this is a frame of type "m" and report error if not
// @todo Take the cost from the template
this.cost = 5;

View File

@ -1,11 +1,12 @@
var SESSION_ANSITEX = (1<<1);
var SESSION_EXT = 'tex';
const SESSION_ANSITEX = (1<<1);
const SESSION_EXT = 'tex';
var ANSI_FRAME_WIDTH = 80;
var ANSI_FRAME_HEIGHT = 22;
var ANSI_FRAME_PROVIDER_LENGTH = 55;
var ANSI_FRAME_PAGE_LENGTH = 13;
var ANSI_FRAME_COST_LENGTH = 10;
const ANSI_FRAME_WIDTH = 80;
const ANSI_FRAME_HEIGHT = 22;
const ANSI_FRAME_PROVIDER_LENGTH = 55;
const ANSI_FRAME_PAGE_LENGTH = 13;
const ANSI_FRAME_COST_LENGTH = 10;
const ANSI_FRAME_ATTR_LENGTH = 0; // Space that an attribute takes
/**
* This function converts ANSI text into an array of attributes
@ -433,20 +434,6 @@ load('ansitex/load/session.js');
function SessionAnsitex() {
Session.apply(this,arguments);
/* File Extension used for frames */
this.settings.ext = 'tex';
/* Length of a frame */
this.settings.FRAME_LENGTH = 22;
/* Width of a frame */
this.settings.FRAME_WIDTH = 80;
/* Size of page owner (length) */
this.settings.FRAME_HEADER = 56;
/* Size of page number (length with a-z) */
this.settings.FRAME_PAGENUM = 12;
/* Size of cost (length without unit) */
this.settings.FRAME_COST = 9;
this.settings.MSG_SENDORNOT = '\1n\1h\1GKEY 1 TO SEND, 2 NOT TO SEND';
this.settings.MSG_LOGON = '\1n\1h\1GKEY 1 TO LOGON, 2 TO RETURN';
this.settings.MSG_SENT = '\1n\1h\1GMESSAGE SENT - KEY # TO CONTINUE';
@ -554,50 +541,7 @@ function SessionAnsitex() {
write('\x1b['+y+';'+x+'H');
}
/*
// Render the frame to the user
this.render=function(context,withoutHeader) {
log(LOG_DEBUG,'- ANSI FRAME');
owner = base64_decode(this.owner);
const frame = new Frame(1,1,this.settings.FRAME_WIDTH,this.settings.FRAME_LENGTH+2,LIGHTGRAY);
frame.open();
// Dont show the page number on system login page
if ((! withoutHeader) && (user.number || (this.type !== FRAME_TYPE_LOGIN && NO_HISTORY_FRAMES.indexOf(this.page) === -1))) {
log(LOG_DEBUG,' - Owner: ['+this.pageowner+']');
cost = (this.isAccessible ? this.cost+FRAME_COSTUNIT : ' -');
header = '\1n'+this.pageownerlogo+' '.repeat(this.settings.FRAME_HEADER-console.strlen(this.pageownerlogo))+'\1n '+
(this.isAccessible ? '\1W' : '\1R')+'\1H'+this.page+' '.repeat(this.settings.FRAME_PAGENUM-this.page.length)+' '+
'\1G\1H'+' '.repeat(this.settings.FRAME_COST-cost.toString().length+1)+cost+'\1n'+
(console.screen_columns > 80 ? '\n\r' : '');
frame.putmsg(header);
}
contentgraphic = new Graphic(this.settings.FRAME_WIDTH);
contentgraphic.auto_extend = true;
contentgraphic.atcodes = false;
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();
contentframe.lf_strict = false;
contentframe.atcodes = false;
contentframe.word_wrap = false
contentframe.putmsg(contentgraphic.MSG)
contentframe.scrollTo(0,0);
frame.cycle();
return contentframe;
};
*/
this.qrcode=function(qr,subframe) {
this.qrcode = function(qr,subframe) {
// SMALL Image
var full = ascii(0xdb);
var top = ascii(0xdf);
@ -644,22 +588,6 @@ function SessionAnsitex() {
subframe.open();
subframe.cycle();
};
/*
this.save=function() {
file = system.mods_dir+'ansitex/text/'+this.page+'.tex';
w = new File(file);
if (! w.open('w')) {
log(LOG_ERROR,'! ERROR: Unable to create TEX file for '+this.page);
exit(1);
}
w.write(JSON.stringify(this));
w.close();
log(LOG_DEBUG,'Saved file: '+this.page+'.tex');
}
*/
}
SessionAnsitex.prototype = Session.prototype;

View File

@ -6,6 +6,7 @@ var VIEWDATA_FRAME_HEIGHT = 22;
var VIEWDATA_FRAME_PROVIDER_LENGTH = 23;
var VIEWDATA_FRAME_PAGE_LENGTH = 11;
var VIEWDATA_FRAME_COST_LENGTH = 6;
const VIEWDATA_FRAME_ATTR_LENGTH = 0; // Space that an attribute takes
var VIEWDATA_LEFT = '\x08';
var VIEWDATA_RIGHT = '\x09';
@ -437,20 +438,6 @@ load('ansitex/load/session.js');
function SessionViewdata() {
Session.apply(this,arguments);
/* File Extension used for frames */
this.settings.ext = 'vtx';
/* Length of a frame */
this.settings.FRAME_LENGTH = 22;
/* Width of a frame */
this.settings.FRAME_WIDTH = 40;
/* Size of page owner (length) */
this.settings.FRAME_HEADER = 23;
/* Size of page number (length with a-z) */
this.settings.FRAME_PAGENUM = 11;
/* Size of cost (length without unit) */
this.settings.FRAME_COST = 3;
this.settings.MSG_SENDORNOT = ascii(27)+'BKEY 1 TO SEND, 2 NOT TO SEND';
this.settings.MSG_LOGON = ascii(27)+'BKEY 1 TO LOGON, 2 TO RETURN';
this.settings.MSG_SENT = ascii(27)+'BMESSAGE SENT - KEY _ TO CONTINUE';
@ -576,7 +563,7 @@ function SessionViewdata() {
//log(LOG_DEBUG,' - FRAME User: ['+JSON.stringify(user)+']');
// Dont show the page number on system login page
if (user.number || (this.type !== FRAME_TYPE_LOGIN && NO_HISTORY_FRAMES.indexOf(this.page) === -1)) {
if (user.number || (this.type !== FRAME_TYPE_LOGIN && FRAMES_NO_HISTORY.indexOf(this.page) === -1)) {
log(LOG_DEBUG,' - Owner: ['+this.pageowner+'] ('+this.strlen(videotex(this.pageownerlogo))+')');
cost = (this.isAccessible ? this.cost+FRAME_COSTUNIT : ' -');

68
main.js
View File

@ -43,12 +43,12 @@ bbs.replace_text(826,''); // LoggingOn
switch (client.socket.local_port) {
case 516:
require('ansitex/load/session-viewdata.js','SESSION_VIEWDATA');
require('ansitex/load/session/viewdata.js','SESSION_VIEWDATA');
break;
// Assume ANSItex
default:
require('ansitex/load/session-ansitex.js','SESSION_ANSITEX');
require('ansitex/load/session/ansitex.js','SESSION_ANSITEX');
}
// @todo Suppress "Read your mail now" at login
@ -81,13 +81,13 @@ while (bbs.online) {
* The next page to display
* @type {PageObject}
*/
var next_page = new PageObject(user.name ? HOME_FRAME_AUTH : HOME_FRAME_CONNECT); // Start Frame
var next_page = new PageObject(user.name ? FRAME_HOME_AUTH : FRAME_HOME_CONNECT); // Start Frame
/**
* Variable holding our current key timeout value
* @type {number}
*/
var inkey_timeout = INKEY_TIMEOUT;
var inkey_timeout = INACTIVE_TIMEOUT;
/**
* Current Session Object that describe the terminal that the user has connected on
@ -195,7 +195,7 @@ while (bbs.online) {
} else if (esc && ! extendedkey && read !== '[') {
log(LOG_DEBUG,'- READ SPECIAL KEY ABANDONED: ['+read+'] ('+read.charCodeAt(0)+')');
esc = false;
inkey_timeout = INKEY_TIMEOUT;
inkey_timeout = INACTIVE_TIMEOUT;
read = KEY_ESC;
// Recognise when the ESC sequence has ended (with a ~ or ;)
@ -216,7 +216,7 @@ while (bbs.online) {
esc = false;
extendedkey = '';
inkey_timeout = INKEY_TIMEOUT;
inkey_timeout = INACTIVE_TIMEOUT;
// Record the character as an extended key
} else if (esc) {
@ -232,7 +232,7 @@ while (bbs.online) {
log(LOG_DEBUG,'- READ empty, evaluating timeouts...');
// Terminate the user if they have been inactive too long.
if (time() > timer+((user.number ? INACTIVE_LOGIN : INACTIVE_NOLOGIN)+INKEY_TIMEOUT)/1000) {
if (time() > timer+((user.number ? INACTIVE_LOGIN : INACTIVE_NOLOGIN)+INACTIVE_TIMEOUT)/1000) {
so.baselineSend('INACTIVE',false);
action = ACTION_TERMINATE;
mode = null;
@ -296,7 +296,7 @@ while (bbs.online) {
// If there are no more control items
if (control.length === 0)
inkey_timeout = INKEY_TIMEOUT;
inkey_timeout = INACTIVE_TIMEOUT;
}
}
@ -330,14 +330,14 @@ while (bbs.online) {
if (so.page.key[read] !== null) {
// If a page routes to 0, requesting the home page
if (so.page.key[read] === 0) {
next_page = new PageObject(user.number ? HOME_FRAME : LOGIN_FRAME);
next_page = new PageObject(user.number ? FRAME_HOME : FRAME_LOGIN);
action = ACTION_GOTO;
log(LOG_DEBUG,'- NULL: Key ['+read+'] ['+next_page.name+']');
log(LOG_DEBUG,'- NULL: Key ['+read+'] ['+next_page.toString()+']');
} else if (so.page.key[read].toString().match(/^[0-9]+/)) {
next_page = new PageObject(so.page.key[read],'a');
action = ACTION_GOTO;
log(LOG_DEBUG,'- NULL: Key ['+read+'] ['+next_page.name+']');
log(LOG_DEBUG,'- NULL: Key ['+read+'] ['+next_page.toString()+']');
} else {
so.baselineSend('ERR_ROUTE',false);
@ -354,7 +354,7 @@ while (bbs.online) {
if (SESSION_EXT === 'tex') break;
/* fallthrough */
case '#':
log(LOG_DEBUG,'- NULL: Key ['+read+'] ['+so.page.name.name+']');
log(LOG_DEBUG,'- NULL: Key ['+read+'] ['+so.page.name.toString()+']');
next_page = so.page.pagenext;
if (next_page) {
@ -400,7 +400,7 @@ while (bbs.online) {
cmd = '';
so.cursorOff();
so.baselineClear();
next_page = new PageObject(SQRL_FRAME);
next_page = new PageObject(FRAME_SQRL);
break;
}
@ -428,7 +428,7 @@ while (bbs.online) {
so.baselineClear();
next_page = new PageObject(parseInt(cmd.substr(2,cmd.length-1)),read);
log(LOG_DEBUG,'- MODE_BL: EDIT ['+JSON.stringify(next_page.name)+']');
log(LOG_DEBUG,'- MODE_BL: EDIT ['+JSON.stringify(next_page.toString())+']');
}
mode = null;
@ -459,7 +459,7 @@ while (bbs.online) {
// Report Problem
if (cmd === '08') {
log(LOG_DEBUG,'- MODE_BL: Report Problem ['+cmd+'] ('+so.page.name.name+')');
log(LOG_DEBUG,'- MODE_BL: Report Problem ['+cmd+'] ('+so.page.name.toString()+')');
if (! user.number) {
so.baselineSend('ERR_ROUTE',false);
@ -478,7 +478,7 @@ while (bbs.online) {
// Reload frame
if (cmd === '09') {
log(LOG_DEBUG,'- MODE_BL: Reload frame ['+cmd+'] ('+so.page.name.name+')');
log(LOG_DEBUG,'- MODE_BL: Reload frame ['+cmd+'] ('+so.page.name.toString()+')');
action = ACTION_GOTO;
cmd = '';
@ -521,7 +521,7 @@ while (bbs.online) {
action = ACTION_BACKUP;
} else if (cmd === '0') {
next_page = new PageObject(user.number ? HOME_FRAME : LOGIN_FRAME);
next_page = new PageObject(user.number ? FRAME_HOME : FRAME_LOGIN);
action = ACTION_GOTO;
// Edit frame
@ -566,7 +566,7 @@ while (bbs.online) {
// If we are the main login screen, see if it is a new user
if (cf.type === 't' && cf.value.toUpperCase() === 'NEW') {
action = ACTION_GOTO;
next_page = new PageObject(REGISTER_FRAME);
next_page = new PageObject(FRAME_REGISTER);
break;
}
@ -741,7 +741,7 @@ while (bbs.online) {
log(LOG_DEBUG,'***:'+JSON.stringify(bbs));
log(LOG_DEBUG,' ! Login failed for User:'+JSON.stringify(so.page.input_fields[0].value));
action = ACTION_GOTO;
next_page = new PageObject(LOGIN_FAILED_FRAME);
next_page = new PageObject(FRAME_LOGIN_FAILED);
break;
default:
@ -943,7 +943,7 @@ while (bbs.online) {
so.get(next_page);
// If the frame doesnt exist, check that the parent frame exists in case we are creating a new one
if (so.page.name.name === null) {
if (so.page.name.toString() === null) {
log(LOG_DEBUG,'- ACTION_EDIT: check index: '+next_page.index+' ('+String.fromCharCode(next_page.index.charCodeAt(0)-1)+')');
// We can always create an 'a' frame
@ -952,7 +952,7 @@ while (bbs.online) {
so.get(pageStr({frame: next_page.frame, index: String.fromCharCode(next_page.index.charCodeAt(0)-1)}));
log(LOG_DEBUG,'- ACTION_EDIT: check index: '+JSON.stringify(so)+' ('+String.fromCharCode(next_page.index.charCodeAt(0)-1)+')');
if (so.page.name.name === null) {
if (so.page.name.toString() === null) {
so = current;
// sendbaseline ERR_PAGE
so.baselineSend('ERR_NO_PARENT',false);
@ -987,10 +987,10 @@ while (bbs.online) {
next_page = (history.length > 0) ? history[history.length-1] : null;
log(LOG_DEBUG,'- ACTION_BACKUP: Backing up to ['+JSON.stringify(next_page)+'] current ['+so.page.name.name+']');
log(LOG_DEBUG,'- ACTION_BACKUP: Backing up to ['+JSON.stringify(next_page)+'] current ['+so.page.name.toString()+']');
// If there is no next page, we'll ignore the request.
if (! next_page || (next_page.name === so.page.name.name)) {
if (! next_page || (next_page.toString() === so.page.name.toString())) {
action = null;
break;
}
@ -1000,7 +1000,7 @@ while (bbs.online) {
// Clear any controls
control = [];
log(LOG_DEBUG,'- ACTION_GOTO: ['+(next_page.name+']'));
log(LOG_DEBUG,'- ACTION_GOTO: ['+(next_page.toString()+']'));
var current = null;
// For logged in users, we'll see if this is a mail page.
@ -1055,7 +1055,7 @@ while (bbs.online) {
log(LOG_DEBUG,'- ACTION_GOTO - load message: ['+next_page.frame+']');
if (next_page.index === 'a') {
require('ansitex/load/control-echomail.js','CONTROL_ECHOMAIL');
require('ansitex/load/control/echomail.js','CONTROL_ECHOMAIL');
control.push(new echomail(next_page.frame));
action = null;
next_page = null;
@ -1091,10 +1091,12 @@ while (bbs.online) {
if (next_page !== null) {
current = so;
so = (SESSION_EXT === 'vtx') ? new SessionViewdata() : new SessionAnsitex();
log(LOG_DEBUG,'**** Got: ['+JSON.stringify(next_page)+']');
so.get(next_page);
log(LOG_DEBUG,' - Got: ['+so.page.name.toString()+']');
if (so.page.name.name === null) {
log(LOG_DEBUG,'- Next Page: ['+(next_page.name+'] doesnt exist?'));
if (so.page.name.toString() === null) {
log(LOG_DEBUG,'- Next Page: ['+(next_page.toString()+'] doesnt exist?'));
so = current;
// In case the frame doesnt exist
@ -1132,9 +1134,9 @@ while (bbs.online) {
// Record our history
if ((! history.length || (pageStr(history[history.length-1]) !== so.page.name)) && (so.page.type !== FRAME_TYPE_LOGIN)) {
// Ignore the login frames
if (NO_HISTORY_FRAMES.indexOf(so.page.name) === -1) {
if (FRAMES_NO_HISTORY.indexOf(so.page.name.toString()) === -1) {
history.push(so.page.name);
log(LOG_DEBUG,'- ACTION_GOTO: Added to history ['+so.page.name.name+'] now ['+history.length+']');
log(LOG_DEBUG,'- ACTION_GOTO: Added to history ['+so.page.name.toString()+'] now ['+history.length+']');
}
}
@ -1149,8 +1151,8 @@ while (bbs.online) {
so.cursorOff();
// 695 = NodeActionMain
bbs.replace_text(695,'\1h%s \1nViewing \1h*'+so.page.name.name+'#\1n');
bbs.log_str(so.page.name.name+'|');
bbs.replace_text(695,'\1h%s \1nViewing \1h*'+so.page.name.toString()+'#\1n');
bbs.log_str(so.page.name.toString()+'|');
bbs.node_action=NODE_MAIN;
switch(so.page.type) {
@ -1233,12 +1235,12 @@ while (bbs.online) {
}
// If this is the register page
if (so.page.name === new PageObject(REGISTER_FRAME)) {
if (so.page.name === new PageObject(FRAME_REGISTER)) {
log(LOG_DEBUG,'Adding REGISTER to control stack');
require('ansitex/load/control-'+so.page.key[1]+'.js','CONTROL_REGISTER');
control.push(eval('new '+so.page.key[1]+'();'));
} else if (so.page.name === new PageObject(SQRL_FRAME)) {
} else if (so.page.name === new PageObject(FRAME_SQRL)) {
log(LOG_DEBUG,'Adding SQRL to control stack');
require('ansitex/load/control-'+so.page.key[1]+'.js','CONTROL_SQRL');
control.push(eval('new '+so.page.key[1]+'();'));