Work on v2 frame files
This commit is contained in:
14
load/defs.js
14
load/defs.js
@@ -62,19 +62,19 @@ const MODE_RFERROR = 6;
|
||||
// @todo Change these to bits
|
||||
|
||||
/* Information Frame, requires no response after viewed */
|
||||
const FRAME_TYPE_INFO = 'i';
|
||||
const FRAME_TYPE_INFO = 0; //'i';
|
||||
/* Terminate Frame, contents displayed and then carrier dropped */
|
||||
const FRAME_TYPE_TERMINATE = 't';
|
||||
const FRAME_TYPE_TERMINATE = 15; //'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 = 13; //'x';
|
||||
/**
|
||||
* Frame calls a door
|
||||
* Contents indicate the name of the door
|
||||
*/
|
||||
const FRAME_TYPE_DOOR = 'X';
|
||||
const FRAME_TYPE_DOOR = 11; //'X';
|
||||
/**
|
||||
* Frame renders a BBS from sbbslist
|
||||
* Contents can be:
|
||||
@@ -86,13 +86,13 @@ 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 = 1; //'r';
|
||||
/* Login frame, enables the user to authenticate to the system, or to a CUG */
|
||||
const FRAME_TYPE_LOGIN = 'l';
|
||||
const FRAME_TYPE_LOGIN = 12; //'l';
|
||||
/* Mail template frames - mail templates will have the user's stats for the area passed to render() */
|
||||
const FRAME_TYPE_MAIL_TEMPLATE = 'm';
|
||||
/* Frame is a message */
|
||||
const FRAME_TYPE_MESSAGE = 'M';
|
||||
const FRAME_TYPE_MESSAGE = 2; // 'M';
|
||||
|
||||
/* Disable *# going backwards for the following frames */
|
||||
const FRAMES_NO_HISTORY = ['980a','98b','981a','982a','983a','998a'];
|
||||
|
204
load/page.js
204
load/page.js
@@ -123,14 +123,15 @@ function Page(debug) {
|
||||
|
||||
this.__properties__ = {
|
||||
name: new PageObject,
|
||||
type: undefined, // Frame type
|
||||
//type: undefined, // Frame type (deprecated, see attrs)
|
||||
attrs: 0, // (Type 0, CUG 0 (public), Hidden=false)
|
||||
|
||||
input_fields: [], // Array of our input fields
|
||||
dynamic_fields: [], // Array of our dynamic fields
|
||||
|
||||
isAccessible: undefined, // Is this page visible to all users
|
||||
//isAccessible: undefined, // Is this page visible to all users (deprecated, see attrs)
|
||||
// If FALSE, only the SP can view/edit the frame
|
||||
isPublic: undefined, // Is this page visible to public (not CUG) users
|
||||
//isPublic: undefined, // Is this page visible to public (not CUG) users (deprecated, see attrs)
|
||||
// If FALSE user must be a member of the CUG to view the frame
|
||||
// All users, including unauthenticated, are members of 'system' (owner = 0)
|
||||
// Frame's owned by the system where:
|
||||
@@ -197,57 +198,89 @@ function Page(debug) {
|
||||
}
|
||||
}
|
||||
|
||||
// @todo change this to Object.defineProperty() - see page.js
|
||||
/**
|
||||
* Determine if this frame is accessible to the current user
|
||||
*/
|
||||
Page.prototype.__defineGetter__('accessible',function() {
|
||||
log(LOG_DEBUG,'- Checking if user ['+user.number+'] can access frame: '+this.name.toString());
|
||||
log(LOG_DEBUG,'|* Frame Owner: '+JSON.stringify(this.pageowner)+', System Frame: '+(this.pageowner === SYSTEM_OWNER));
|
||||
log(LOG_DEBUG,'|* Accessible: '+JSON.stringify(this.__properties__.isAccessible));
|
||||
log(LOG_DEBUG,'|* Public: '+JSON.stringify(this.__properties__.isPublic));
|
||||
log(LOG_DEBUG,'|* Member: '+JSON.stringify(this.isMember));
|
||||
Object.defineProperty(this,'accessible',{
|
||||
get: function() {
|
||||
log(LOG_DEBUG,'- Checking if user ['+user.number+'] can access frame: '+this.name.toString());
|
||||
log(LOG_DEBUG,'|* Frame Owner: '+this.owner+', System Frame: '+this.isSystemPage);
|
||||
log(LOG_DEBUG,'|* Accessible: '+this.isAccessible);
|
||||
log(LOG_DEBUG,'|* Public: '+this.isPublic);
|
||||
log(LOG_DEBUG,'|* Member: '+this.isMember);
|
||||
|
||||
// user.number 0 is unidentified user.
|
||||
if (user.number) {
|
||||
return (
|
||||
(this.__properties__.isAccessible && this.pageowner === SYSTEM_OWNER && ! this.__properties__.isPublic) ||
|
||||
(this.__properties__.isAccessible && this.__properties__.isPublic) ||
|
||||
(this.__properties__.isAccessible && ! this.__properties__.isPublic && this.isMember) ||
|
||||
(pageEditor(this.name.frame))
|
||||
);
|
||||
// user.number 0 is unidentified user.
|
||||
if (user.number) {
|
||||
return (
|
||||
(this.isAccessible && this.isSystemPage && ! this.isPublic) ||
|
||||
(this.isAccessible && this.isPublic) ||
|
||||
(this.isAccessible && ! this.isPublic && this.isMember) ||
|
||||
(pageEditor(this.name.frame))
|
||||
);
|
||||
|
||||
} else {
|
||||
return this.__properties__.isAccessible && (this.pageowner === SYSTEM_OWNER) && this.__properties__.isPublic;
|
||||
} else {
|
||||
return this.isAccessible && this.isSystemPage && this.isPublic;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Page.prototype.__defineGetter__('cost',function() {
|
||||
return Number(this.__properties__.cost);
|
||||
// The page attributes, which determine accessible, public, cug and frame type
|
||||
Object.defineProperty(this,'attrs',{
|
||||
get: function() {
|
||||
return this.__properties__.attrs;
|
||||
},
|
||||
|
||||
/* Frame attributes are bit items, bits:
|
||||
* 1-4 TYPE
|
||||
* 5-7 CUG
|
||||
* 8 accessible
|
||||
*/
|
||||
set: function(int) {
|
||||
if (int === undefined)
|
||||
int = 0;
|
||||
|
||||
this.__properties__.attrs = int;
|
||||
}
|
||||
});
|
||||
Page.prototype.__defineSetter__('cost',function(int) {
|
||||
if (typeof int !== 'number')
|
||||
throw new Error('Cost must be a number');
|
||||
|
||||
this.__properties__.cost = int;
|
||||
Object.defineProperty(this,'cost',{
|
||||
get: function() {
|
||||
return Number(this.__properties__.cost);
|
||||
},
|
||||
|
||||
if ((''+int).length > FRAME_COST_LENGTH-1-FRAME_ATTR_LENGTH)
|
||||
throw new Error('Cost too large');
|
||||
set: function(int) {
|
||||
if (int === undefined)
|
||||
int = 0;
|
||||
|
||||
// Populate the cost window
|
||||
switch (SESSION_EXT) {
|
||||
case 'tex':
|
||||
this.__window__.cost.__properties__.content = rawtoattrs(ESC+'[1;32m'+padright(int,FRAME_COST_LENGTH-1-FRAME_ATTR_LENGTH,' ')+FRAME_COSTUNIT).content;
|
||||
if (typeof int !== 'number')
|
||||
throw new Error('Cost must be a number');
|
||||
|
||||
break;
|
||||
this.__properties__.cost = int;
|
||||
|
||||
case 'vtx':
|
||||
this.__window__.cost.__properties__.content = rawtoattrs(VIEWDATA_BIN_GREEN+padright(int,FRAME_COST_LENGTH-1-FRAME_ATTR_LENGTH,' ')+FRAME_COSTUNIT).content;
|
||||
if ((''+int).length > FRAME_COST_LENGTH-1-FRAME_ATTR_LENGTH)
|
||||
throw new Error('Cost too large');
|
||||
|
||||
break;
|
||||
// Populate the cost window
|
||||
switch (SESSION_EXT) {
|
||||
case 'tex':
|
||||
this.__window__.cost.__properties__.content = rawtoattrs(ESC+'[1;32m'+padright(int,FRAME_COST_LENGTH-1-FRAME_ATTR_LENGTH,' ')+FRAME_COSTUNIT).content;
|
||||
|
||||
default:
|
||||
throw new Error(SESSION_EXT+' type not implemented');
|
||||
break;
|
||||
|
||||
case 'vtx':
|
||||
this.__window__.cost.__properties__.content = rawtoattrs(VIEWDATA_BIN_GREEN+padright(int,FRAME_COST_LENGTH-1-FRAME_ATTR_LENGTH,' ')+FRAME_COSTUNIT).content;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(SESSION_EXT+' type not implemented');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(this,'cug',{
|
||||
get: function() {
|
||||
return ((this.__properties__.attrs >> 4) & 0x7);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -273,26 +306,34 @@ function Page(debug) {
|
||||
this.__properties__.input_fields = array;
|
||||
});
|
||||
|
||||
Page.prototype.__defineSetter__('isAccessible',function(bool) {
|
||||
if (typeof bool !== 'boolean')
|
||||
throw new Error('isAccessible must be a boolean');
|
||||
|
||||
this.__properties__.isAccessible = bool;
|
||||
Object.defineProperty(this,'isAccessible',{
|
||||
get: function() {
|
||||
return (this.__properties__.attrs >> 7 !== 1);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Check if the user is already a member of the CUG
|
||||
*/
|
||||
Page.prototype.__defineGetter__('isMember',function() {
|
||||
// @todo Implement CUGs, this would be "=== SERVICE_PROVIDER" and user is a member of SERVICE_PROVIDER
|
||||
return user.number && (this.pageowner === SYSTEM_OWNER);
|
||||
Object.defineProperty(this,'isMember',{
|
||||
get: function() {
|
||||
// @todo Implement CUGs, this would be "=== SERVICE_PROVIDER" and user is a member of SERVICE_PROVIDER
|
||||
return (user.number > 0) && this.isSystemPage;
|
||||
}
|
||||
});
|
||||
|
||||
Page.prototype.__defineSetter__('isPublic',function(bool) {
|
||||
if (typeof bool !== 'boolean')
|
||||
throw new Error('isPublic must be a boolean');
|
||||
// Is the page public or CUG
|
||||
Object.defineProperty(this,'isPublic',{
|
||||
get: function() {
|
||||
return (this.cug === 0);
|
||||
}
|
||||
});
|
||||
|
||||
this.__properties__.isPublic = bool;
|
||||
// Is this a system page
|
||||
Object.defineProperty(this,'isSystemPage',{
|
||||
get: function() {
|
||||
return (this.owner === SYSTEM_OWNER);
|
||||
}
|
||||
});
|
||||
|
||||
// Key Array
|
||||
@@ -337,12 +378,20 @@ function Page(debug) {
|
||||
}
|
||||
});
|
||||
|
||||
// Display who owns the page
|
||||
Object.defineProperty(this,'owner',{
|
||||
get: function() {
|
||||
return pageOwner(this.__properties__.name.frame).prefix;
|
||||
},
|
||||
});
|
||||
|
||||
Page.prototype.__defineGetter__('pagenext',function() {
|
||||
return this.__properties__.name.next;
|
||||
});
|
||||
|
||||
/**
|
||||
* Determine who the owner of a page is
|
||||
* @deprecated use owner
|
||||
*/
|
||||
Page.prototype.__defineGetter__('pageowner',function() {
|
||||
return pageOwner(this.__properties__.name.frame).prefix;
|
||||
@@ -386,6 +435,12 @@ function Page(debug) {
|
||||
this.__window__.header.visible = bool;
|
||||
});
|
||||
|
||||
Object.defineProperty(this,'type',{
|
||||
get: function() {
|
||||
return this.__properties__.attrs & 0xf;
|
||||
},
|
||||
});
|
||||
|
||||
Page.prototype.__defineGetter__('type',function() {
|
||||
return this.__properties__.type;
|
||||
});
|
||||
@@ -839,8 +894,10 @@ function Page(debug) {
|
||||
if (!(page instanceof PageObject))
|
||||
throw new Error('page must be a PageObject');
|
||||
|
||||
this.name = page;
|
||||
|
||||
// Load a page from disk first if it exists
|
||||
if (FRAMES_MSG_FILES && this.import(FRAMES_HOME+SESSION_EXT+'/'+page.toString(),SESSION_EXT))
|
||||
if (FRAMES_MSG_FILES && this.import(FRAMES_HOME+page.toString(),SESSION_EXT))
|
||||
return true;
|
||||
|
||||
// Fall back to loading from msgbase
|
||||
@@ -1192,9 +1249,34 @@ function Page(debug) {
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// Load the page content
|
||||
var content_file = FRAMES_HOME+SESSION_EXT+'/'+this.name.toString()+'.'+CONTENT_EXT;
|
||||
log(LOG_DEBUG,'|-- Importing frame content: ['+content_file+']');
|
||||
|
||||
var f = new File(content_file);
|
||||
if (! f.exists || ! f.open('rb',true)) {
|
||||
log(LOG_ERROR,'|? File doesnt exist: ['+content_file+']');
|
||||
this.get(new PageObject(FRAME_SYSTEM_ERROR));
|
||||
break;
|
||||
}
|
||||
|
||||
this.__properties__.raw = f.read();
|
||||
f.close();
|
||||
|
||||
var page = rawtoattrs(this.__properties__.raw,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; });
|
||||
|
||||
// Work out frame type
|
||||
writeln(JSON.stringify(contents));
|
||||
exit(2);
|
||||
this.attrs = contents.attrs;
|
||||
this.cost = contents.cost;
|
||||
this.key = contents.key;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1354,11 +1436,19 @@ function PageObject(frame,index) {
|
||||
this.__properties__.frame = frame.frame.toString();
|
||||
this.index = frame.index;
|
||||
|
||||
} else {
|
||||
this.__properties__.frame = frame;
|
||||
} else if ((frame !== undefined) && (index === undefined)) {
|
||||
if (/^\d+[a-z]$/.test(frame)) {
|
||||
var split = frame.split(/(\d+)/);
|
||||
this.__properties__.frame = split[1];
|
||||
this.index = split[2];
|
||||
|
||||
if (index)
|
||||
this.index = index;
|
||||
} else {
|
||||
this.__properties__.frame = frame;
|
||||
}
|
||||
|
||||
} else if ((frame !== undefined) && (index !== undefined)) {
|
||||
this.__properties__.frame = frame;
|
||||
this.index = index;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
const SESSION_ANSITEX = (1<<1);
|
||||
var SESSION_EXT = 'tex';
|
||||
var CONTENT_EXT = 'ans';
|
||||
|
||||
var FRAME_WIDTH = 80;
|
||||
var FRAME_HEIGHT = 22;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
const SESSION_VIEWDATA = (1<<2);
|
||||
var SESSION_EXT = 'vtx';
|
||||
var CONTENT_EXT = 'bin';
|
||||
|
||||
var FRAME_WIDTH = 40;
|
||||
var FRAME_HEIGHT = 22;
|
||||
|
@@ -944,13 +944,15 @@ function Char(ch,attr) {
|
||||
ansi.push(r);
|
||||
}
|
||||
|
||||
if (false && debug)
|
||||
if (debug)
|
||||
writeln(' - ansi:'+ansi);
|
||||
|
||||
return ansi.length ? (debug ? '': '\x1b')+'['+ansi.join(';')+'m' : undefined;
|
||||
|
||||
case 'vtx':
|
||||
log(LOG_DEBUG,'+ last:'+last+', attr ('+this.attr+')');
|
||||
if (debug)
|
||||
log(LOG_DEBUG,'+ last:'+last+', attr ('+this.attr+')');
|
||||
|
||||
switch (this.attr) {
|
||||
// \x08
|
||||
case BLINK:
|
||||
@@ -1039,7 +1041,9 @@ function Char(ch,attr) {
|
||||
}
|
||||
}
|
||||
|
||||
log(LOG_DEBUG,'= result:'+r.charCodeAt(0)+', ('+r+')');
|
||||
if (debug)
|
||||
log(LOG_DEBUG,'= result:'+r.charCodeAt(0)+', ('+r+')');
|
||||
|
||||
return ESC+r;
|
||||
|
||||
default:
|
||||
|
Reference in New Issue
Block a user