diff --git a/export.js b/export.js index 590a9d8..c04cfc2 100644 --- a/export.js +++ b/export.js @@ -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()) { diff --git a/frames_check.js b/frames_check.js index ed1bfba..28884e2 100644 --- a/frames_check.js +++ b/frames_check.js @@ -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; diff --git a/load/control-sqrllogin.js b/load/control-sqrllogin.js index a90cb8b..09bbb2b 100644 --- a/load/control-sqrllogin.js +++ b/load/control-sqrllogin.js @@ -195,7 +195,7 @@ function sqrllogin() { subframe.close(); action = ACTION_GOTO; - next_page = LOGIN_FRAME; + next_page = FRAME_LOGIN; } return read; diff --git a/load/control-echomail.js b/load/control/echomail.js similarity index 95% rename from load/control-echomail.js rename to load/control/echomail.js index 584dd0a..850dde6 100644 --- a/load/control-echomail.js +++ b/load/control/echomail.js @@ -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(); diff --git a/load/defs.js b/load/defs.js index 2c7445f..066bb72 100644 --- a/load/defs.js +++ b/load/defs.js @@ -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'; diff --git a/load/funcs.js b/load/funcs.js index f93975b..a40cc8d 100644 --- a/load/funcs.js +++ b/load/funcs.js @@ -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+']'); diff --git a/load/msgbases.js b/load/msgbases.js index 3631ff2..0649692 100644 --- a/load/msgbases.js +++ b/load/msgbases.js @@ -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() { diff --git a/load/page.js b/load/page.js index 71a1abe..a062372 100644 --- a/load/page.js +++ b/load/page.js @@ -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); } diff --git a/load/session.js b/load/session.js index 8f42e93..c621c81 100644 --- a/load/session.js +++ b/load/session.js @@ -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; diff --git a/load/session-ansitex.js b/load/session/ansitex.js similarity index 84% rename from load/session-ansitex.js rename to load/session/ansitex.js index e441ae9..c8e47be 100644 --- a/load/session-ansitex.js +++ b/load/session/ansitex.js @@ -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; diff --git a/load/session-viewdata.js b/load/session/viewdata.js similarity index 97% rename from load/session-viewdata.js rename to load/session/viewdata.js index f824586..a4f42ac 100644 --- a/load/session-viewdata.js +++ b/load/session/viewdata.js @@ -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 : ' -'); diff --git a/main.js b/main.js index f746577..16b3eaf 100644 --- a/main.js +++ b/main.js @@ -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]+'();'));