// 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('texdefs.js'); load('texfuncs.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(); 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 } bbs.replace_text(NodeActionMain,'\1h%s \1nViewing \1h*'+fo.frame+'#\1n ['+fo.index+']'); bbs.log_str(fo.page+'|'); bbs.node_action=NODE_MAIN; break; } log(LOG_DEBUG,'ACTION END: ['+read+']'); } }