Added ANSI parsers and rendering ANSI frames

This commit is contained in:
Deon George
2018-12-14 00:02:42 +11:00
parent e0306908bd
commit 6cc793c47f
14 changed files with 333 additions and 119 deletions

View File

@@ -23,7 +23,7 @@ abstract class Server {
$this->mo = $o;
define('MODE_BL', 1); // Typing a * command on the baseline
define('MODE_FIELD', 2); // typing into an imput field
define('MODE_FIELD', 2); // typing into an input field
define('MODE_WARPTO', 3); // awaiting selection of a timewarp
define('MODE_COMPLETE', 4); // Entry of data is complete ..
define('MODE_SUBMITRF', 5); // asking if should send or not.
@@ -64,12 +64,12 @@ abstract class Server {
define('TCP_OPT_LINEMODE', chr(34));
define('MSG_SENDORNOT', GREEN.'KEY 1 TO SEND, 2 NOT TO SEND');
define('MSG_SENT', GREEN.'MESSAGE SENT - KEY _ TO CONTINUE');
define('MSG_NOTSENT', GREEN.'MESSAGE NOT SENT - KEY _ TO CONTINUE');
define('MSG_SENT', GREEN.'MESSAGE SENT - KEY '.HASH.' TO CONTINUE');
define('MSG_NOTSENT', GREEN.'MESSAGE NOT SENT - KEY '.HASH.' TO CONTINUE');
define('ERR_DATABASE', RED.'UNAVAILABLE AT PRESENT - PLSE TRY LATER');
define('ERR_NOTSENT', WHITE.'MESSAGE NOT SENT DUE TO AN ERROR');
define('ERR_PRIVATE', WHITE.'PRIVATE PAGE'.GREEN.'- FOR EXPLANATION *37_..');
define('ERR_PRIVATE', WHITE.'PRIVATE PAGE'.GREEN.'- FOR EXPLANATION *37'.HASH.'..');
define('ERR_ROUTE', WHITE.'MISTAKE?'.GREEN.'TRY AGAIN OR TELL US ON *08');
define('ERR_PAGE',ERR_ROUTE);
define('ERR_USER_ALREADYMEMBER', RED.'ALREADY MEMBER OF CUG');
@@ -143,16 +143,17 @@ abstract class Server {
// @todo Get the login/start page, and if it is not available, throw the ERR_DATEBASE error.
if (isset($config['loginpage'])) {
$page = ['frame'=>$config['loginpage'],'index'=>'a'];
$page = ['frame'=>$config['loginpage']];
} else if (!empty($service['start_page'])) {
$page = ['frame'=>$service['start_page'],'index'=>'a'];
$page = ['frame'=>$service['start_page']];
} else {
$page = ['frame'=>'980','index'=>'a']; // next page
$page = ['frame'=>'980']; // next page
}
while ($action != ACTION_TERMINATE) {
// Read a character from the client session
$read = $client->read(1);
printf(". Got: %s (%s)\n",$read,ord($read));
// It appears that read will return '' instead of false when a disconnect has occurred.
// We'll set it to NULL so its caught later
@@ -181,6 +182,7 @@ abstract class Server {
case TCP_SE:
$session_option = $session_init = FALSE;
$this->log('debug',sprintf('Session Terminal: %s',$session_term));
$read = '';
break;
@@ -258,7 +260,7 @@ abstract class Server {
if ($current['field']->type == 'u' AND array_get($fielddata,$current['fieldnum']) == 'NEW')
{
$action = ACTION_GOTO;
$page = ['frame'=>'981','index'=>'a']; // @todo This should be in the DB.
$page = ['frame'=>'981']; // @todo This should be in the DB.
}
}
@@ -269,6 +271,7 @@ abstract class Server {
case Frame::FRAMETYPE_ACTION:
switch ($read) {
// End of field entry.
case LF:
case HASH:
// Next Field
$current['fieldnum']++;
@@ -391,11 +394,10 @@ abstract class Server {
$route = $fo->route(1);
if ($route == '*' OR is_numeric($route)) {
$this->sendBaseline($client, RED . 'NO action performed');
$this->sendBaseline($client,RED.'NO ACTION PERFORMED');
$mode = MODE_RFSENT;
} elseif ($ao = FrameClass\Action::factory($fo->route(1),$this,$user,$action,$mode)) {
$ao->handle($fielddata);
$mode = $ao->mode;
$action = $ao->action;
@@ -431,28 +433,22 @@ abstract class Server {
$client->send(COFF);
if ($read == HASH) {
if (! empty($pagedata['route1'])) {
$action = ACTION_GOTO;
$page['frame'] = $pagedata['route1'];
$page['index'] = 'a';
if ($route = $fo->route(2) AND $route !== '*' AND is_numeric($route)) {
$page = ['frame'=>$route];
} elseif (FrameModel::where('frame',$fo->frame())->where('index',$fo->index_next())->exists()) {
$action = ACTION_GOTO;
$page['frame'] = array_get($current,'page.frame');
$page['index'] = chr(1 + ord($page['index']));
$page = ['frame'=>$fo->frame(),'index'=>$fo->index_next()];
} elseif (! empty($pagedata['route0'])) {
$action = ACTION_GOTO;
$page['frame'] = $pagedata['route0'];
$page['index'] = 'a';
} elseif ($route = $fo->route(0) AND $route !== '*' AND is_numeric($route)) {
$page = ['frame'=>$route];
// No further routes defined, go home.
// No further routes defined, go home.
} else {
$action = ACTION_GOTO;
$page['frame'] = '0';
$page['index'] = 'a';
$page = ['frame'=>0];
}
$action = ACTION_GOTO;
} elseif ($read == STAR) {
$action = ACTION_STAR;
@@ -469,28 +465,22 @@ abstract class Server {
$client->send(COFF);
if ($read == HASH) {
if (! empty($pagedata['route2'])) {
$action = ACTION_GOTO;
$page['frame'] = $pagedata['route2'];
$page['index'] = 'a';
if ($route = $fo->route(2) AND $route !== '*' AND is_numeric($route)) {
$page = ['frame'=>$route];
} elseif (FrameModel::where('frame',$fo->frame())->where('index',$fo->index_next())->exists()) {
$action = ACTION_GOTO;
$page['frame'] = $fo->frame();
$page['index'] = $fo->index_next();
$page = ['frame'=>$fo->frame(),'index'=>$fo->index_next()];
} elseif (! empty($pagedata['route0'])) {
$action = ACTION_GOTO;
$page['frame'] = $pagedata['route0'];
$page['index'] = 'a';
} elseif ($route = $fo->route(0) AND $route !== '*' AND is_numeric($route)) {
$page = ['frame'=>$route];
// No further routes defined, go home.
// No further routes defined, go home.
} else {
$action = ACTION_GOTO;
$page['frame'] = '0';
$page['index'] = 'a';
$page = ['frame'=>0];
}
$action = ACTION_GOTO;
} elseif ($read == STAR) {
$action = ACTION_STAR;
@@ -554,7 +544,7 @@ abstract class Server {
// Currently accepting baseline input after a * was received
case MODE_BL:
echo "was waiting for page number\n";
echo "- Waiting for Page Number\n";
// if it's a number, continue entry
if (strpos('0123456789', $read) !== FALSE) {
@@ -623,7 +613,7 @@ abstract class Server {
}
// Complete request
if ($read === HASH) {
if ($read === HASH or $read === LF) {
$client->send(COFF);
$timewarpalt = FALSE;
@@ -657,21 +647,22 @@ abstract class Server {
// This section performs some action if it is deemed necessary
if ($action) {
echo "Performing action $action\n";
printf("+ Performing action: %s\n",$action);
}
switch ($action) {
case ACTION_STAR:
echo " star command started\n";
$this->sendBaseline($client,GREEN.STAR,true);
echo "+ Star command...\n";
$this->sendBaseline($client,GREEN.STAR,TRUE);
$client->send(CON);
$action = false;
$action = FALSE;
$mode = MODE_BL;
break;
case ACTION_SUBMITRF:
$action = false;
$action = FALSE;
$client->send(COFF);
$this->sendBaseline($client,MSG_SENDORNOT);
$mode = MODE_SUBMITRF;
@@ -705,7 +696,7 @@ abstract class Server {
try {
$fo = $timewarpalt
? $this->mo->frame(FrameModel::findOrFail($timewarpalt))
: $this->mo->frameLoad($page['frame'],$page['index'],$this);
: $this->mo->frameLoad($page['frame'],array_get($page,'index','a'),$this);
$this->log('debug',sprintf('Fetched frame: %s (%s)',$fo->id(),$fo->page()));
@@ -784,19 +775,8 @@ abstract class Server {
// drop into
case ACTION_RELOAD:
// @todo Move this $output into the object.
if ($fo->hasFlag('clear'))
{
$this->blp = 0;
$output = CLS;
} else {
$output = HOME;
// Clear the baseline.
$this->sendBaseline($client,'');
}
$output .= (string)$fo;
$this->sendBaseline($client,'');
$output = (string)$fo;
if ($timewarpalt) {
$this->sendBaseline($client,sprintf(MSG_TIMEWARP_TO,$fo->created() ? $fo->created()->format('Y-m-d H:i:s') : 'UNKNOWN'));
@@ -922,21 +902,7 @@ abstract class Server {
/**
* Move the cursor via the shortest path.
*/
function outputPosition($x,$y) {
// Take the shortest path.
if ($y < 12) {
return HOME.
(($x < 21)
? str_repeat(DOWN,$y).str_repeat(RIGHT,$x)
: str_repeat(DOWN,$y+1).str_repeat(LEFT,40-$x));
} else {
return HOME.str_repeat(UP,24-$y).
(($x < 21)
? str_repeat(RIGHT,$x)
: str_repeat(LEFT,40-$x));
}
}
abstract function outputPosition($x,$y);
/**
* Send a message to the base line