sbbs/main.js
2020-02-26 22:54:39 +11:00

339 lines
8.2 KiB
JavaScript

// Load many SBBS definitions
load('sbbsdefs.js');
// Load text.dat defintions
load('text.js');
// Enable to manipulate the ANSI terminal
ansiterm = load({},'ansiterm_lib.js');
// Ansitex specific includes
load('ansitex/load/defs.js');
load('ansitex/load/funcs.js');
while(bbs.online) {
var mode = false; // Initial mode
var next_page = { frame: 98,index: 'b' }; // Start Frame
var action = ACTION_GOTO; // Initial action
var inkey_timeout = 600000; // Timeout waiting for input @todo required? check if idle timetout occurs
var fo = null; // Current Frame
var history = []; // Page history
ansiterm.send('ext_mode','clear','cursor');
while (action != ACTION_TERMINATE) {
bbs.nodesync(false); // @todo Stop the display of telegrams
read = '';
if (action == false) {
read = console.inkey(K_NONE,inkey_timeout);
}
system.node_list[bbs.node_num-1].action=0xff; // to ensure our node status is updated correctly
inkey_timeout = 60000; // Set our key timeout to 60s
log(LOG_DEBUG,'READ: ['+read+']');
log(LOG_DEBUG,'MODE START: ['+read+']');
switch (mode) {
case false:
log(LOG_DEBUG,'- false: ['+read+']');
cmd='';
switch (read) {
case '*': action = ACTION_STAR
break;
// Frame Routing
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (fo.key[read]) {
next_page = { frame: fo.key[read] };
action = ACTION_GOTO;
log(LOG_DEBUG,'- false: Key ['+read+'] ['+pageStr(next_page)+']');
} else {
sendBaseline(ERR_ROUTE,false);
}
break;
case '#':
if (frame.index !== 'z') {
next_page = { frame: fo.frame, index: String.fromCharCode(fo.index.charCodeAt(0)+1) };
action = ACTION_GOTO;
} else {
sendBaseline(ERR_ROUTE,false);
}
break;
}
break;
// Command input on bottom line
case MODE_BL:
log(LOG_DEBUG,'- MODE_BL: ['+read+']');
if (read.match(/[0-9]/)) {
cmd += read;
console.write(read);
}
// @todo check if CTRL_H is required?
if ((read == CTRL_H || read == KEY_DEL) && cmd.length) {
console.backspace();
cmd = cmd.substring(0,cmd.length-1);
}
if (cmd == '00') {
action = ACTION_RELOAD;
cmd = '';
cursorOff();
break;
}
// Edit specific frame
if (cmd.match(/^04/) && read.match(/[a-z]/)) {
// @todo
mode = action = false;
cmd = '';
cursorOff();
sendBaseline(ERR_NOT_IMPLEMENTED,false);
break;
}
// Bookmark frame
if (cmd == '05') {
// @todo
mode = action = false;
cmd = '';
cursorOff();
sendBaseline(ERR_NOT_IMPLEMENTED,false);
break;
}
// Report Problem
if (cmd == '08') {
// @todo
mode = action = false;
cmd = '';
cursorOff();
sendBaseline(ERR_NOT_IMPLEMENTED,false);
break;
}
// Reload frame
if (cmd == '09') {
// @todo
action = ACTION_GOTO;
cmd = '';
cursorOff();
next_page = { frame: fo.frame, index: fo.index};
break;
}
// Another star aborts the command
if (read == '*') {
mode = action = false;
sendBaseline('',false);
cmd = '';
cursorOff();
// @todo If we are editing a field...
}
if (read == '#' || read == '\r') {
// Nothing typed between * and #
// *# means go back
if (cmd == '') {
mode = false;
cursorOff();
sendBaseline('',false);
action = ACTION_BACKUP;
} else if (cmd == '0') {
next_page = { frame: 1 }; // @todo specify home page in config
action = ACTION_GOTO;
// Edit frame
} else if (cmd == '04') {
sendBaseline(ERR_NOT_IMPLEMENTED,false);
} else {
next_page = { frame: cmd };
action = ACTION_GOTO;
}
// Clear the command we are finished processing...
cursorOff();
cmd = '';
mode = false;
}
break;
// @todo MODE_CONTROL
default:
log(LOG_DEBUG,'- SHOULDNT GET HERE: ['+read+']');
}
log(LOG_DEBUG,'MODE END: ['+read+']');
log(LOG_DEBUG,'ACTION START: ['+read+']');
switch (action) {
// Start command entry
case ACTION_STAR:
log(LOG_DEBUG,'- ACTION_STAR: ['+(next_page ? pageStr(next_page) : '')+']');
// @todo If something on the baseline preserve it
ansiterm.send('ext_mode','set','cursor');
sendBaseline('\1N\1G\1H*',true);
action = false;
mode = MODE_BL;
bbs.replace_text(NodeActionRetrieving,'\1h%s \1n\1gJumping to page');
bbs.node_action=NODE_RFSD;
break;
// GO Backwards
case ACTION_BACKUP:
// Do we have anywhere to go, drop the current page from the history.
if (history.length > 1)
history.pop();
// @todo If in control...
next_page = (history.length > 0) ? history[history.length-1] : null;
log(LOG_DEBUG,'- ACTION_BACKUP: Backing up to ['+(next_page ? pageStr(next_page) : '')+'] current ['+fo.page+']');
// If there is no next page, we'll ignore the request.
if (! next_page || (pageStr(next_page) == fo.page)) {
action = false;
break;
}
// Goto specific page
case ACTION_GOTO:
log(LOG_DEBUG,'- ACTION_GOTO: ['+(next_page ? pageStr(next_page) : '')+']');
if (next_page !== null) {
current = fo;
fo = getFrame(next_page);
if (! fo) {
fo = current;
// sendbaseline ERR_PAGE
sendBaseline(ERR_ROUTE,false);
mode = action = false;
break;
}
current = null;
}
if (fo.isPublic && fo.isAccessible) {
// @todo if its a login frame and the user is already member of CUG, display error
if (false) {
// baseline USER_ALREADY_MEMBER
break;
}
} else {
// @todo if user is not the owner
if (false) {
// @todo if frame is not accessible
if (false) {
// baseline ACCESS_DENIED
break;
}
// @todo if user not a member
if (false) {
// baseline ACCESS_DENIED_NOT_IN_CUG
break;
}
}
}
log(LOG_DEBUG,'- ACTION_GOTO: next_page ['+JSON.stringify(next_page)+'] last history ['+JSON.stringify(history[history.length-1])+']');
// Record our history
if (next_page && (! history.length || (pageStr(history[history.length-1]) != pageStr(next_page)))) {
// Ignore the login frames
if (LOGIN_FRAMES.indexOf(pageStr(next_page)) == -1) {
history.push(next_page);
log(LOG_DEBUG,'- ACTION_GOTO: Added to history ['+(next_page ? pageStr(next_page) : '')+'] now ['+history.length+']');
}
}
next_page = null;
case ACTION_RELOAD:
log(LOG_DEBUG,'- ACTION_RELOAD: ['+(next_page ? pageStr(next_page) : '')+']');
// Clear the baseline history
// $this->sendBaseline($client,'');
// $current['baseline'] = '';
console.line_counter=0; // @todo fix to suppress a pause that is occurring before clear()
console.clear();
bbs.replace_text(NodeActionMain,'\1h%s \1nViewing \1h*'+fo.frame+'#\1n ['+fo.index+']');
bbs.log_str(fo.page+'|');
bbs.node_action=NODE_MAIN;
switch(fo.type) {
// Terminate frame
case FRAME_TYPE_TERMINATE:
console.putmsg(fo.render());
bbs.hangup();
exit();
// External Frame
// @todo returning from the frame, go to the 0 key if it is set
case FRAME_TYPE_EXTERNAL:
log(LOG_DEBUG,'- ACTION_GOTO: EXTERNAL ['+JSON.stringify(fo.raw())+']');
switch(fo.raw()) {
case 'bbs.user_config()':
case 'bbs.read_mail(MAIL_YOUR)':
case 'bbs.scan_subs(SCAN_NEW)':
case 'bbs.scan_posts()':
case 'bbs.post_msg()':
eval(fo.raw());
// Check and see if our shell was changed
if (user.command_shell != 'ansitex') {
exit();
}
action = ACTION_BACKUP;
break;
default:
console.putmsg(JSON.stringify(fo.raw()));
sendBaseline(ERR_ROUTE,false);
action = false;
break;
}
mode = false;
break;
// Standard Frame
case FRAME_TYPE_INFO:
default:
console.putmsg(fo.render());
mode = action = false;
break;
// Active frame
}
break;
}
log(LOG_DEBUG,'ACTION END: ['+read+']');
}
}