Added ANSI parsers and rendering ANSI frames
This commit is contained in:
parent
e0306908bd
commit
6cc793c47f
@ -35,7 +35,8 @@ use App\Models\CUG;
|
||||
abstract class Frame
|
||||
{
|
||||
protected $frame = NULL;
|
||||
protected $output = NULL;
|
||||
protected $output = '';
|
||||
protected $startline = 1;
|
||||
|
||||
// All this vars should be overridden in the child class
|
||||
/*
|
||||
@ -71,17 +72,11 @@ abstract class Frame
|
||||
// @todo Move this to the database
|
||||
private $header = RED.'T'.BLUE.'E'.GREEN.'S'.YELLOW.'T'.MAGENTA.'!';
|
||||
|
||||
public function __construct(\App\Models\Frame $o,string $msg=NULL)
|
||||
public function __construct(\App\Models\Frame $o)
|
||||
{
|
||||
$this->frame = $o;
|
||||
|
||||
$this->output = $this->hasFlag('clear') ? CLS : HOME;
|
||||
|
||||
// If we have a message to display on the bottom line.
|
||||
if ($msg)
|
||||
$this->output .= UP.$msg.HOME;
|
||||
|
||||
$startline = 0;
|
||||
$this->output = $this->frame->cls ? CLS : HOME;
|
||||
|
||||
if (! $this->hasFlag('ip') AND (! $this->isCUG(0) OR $this->type() !== self::FRAMETYPE_LOGIN)) {
|
||||
// Set the page header: CUG/Site Name | Page # | Cost
|
||||
@ -89,12 +84,16 @@ abstract class Frame
|
||||
$this->render_page($this->frame->frame,$this->frame->index).
|
||||
$this->render_cost($this->frame->cost);
|
||||
|
||||
$startline = 1;
|
||||
$this->startline = 2;
|
||||
|
||||
} elseif ($this->isCUG(0) AND $this->type() === self::FRAMETYPE_LOGIN) {
|
||||
$this->startline = 2;
|
||||
$this->output .= str_repeat(DOWN,$this->startline-1);
|
||||
}
|
||||
|
||||
// Calculate fields and render output.
|
||||
$this->fields = collect(); // Fields in this frame.
|
||||
$this->fields($startline);
|
||||
$this->fields = collect(); // Fields in this frame.
|
||||
$this->fields($this->startline);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -403,17 +402,18 @@ abstract class Frame
|
||||
$o->index = 'a';
|
||||
$o->access = 1;
|
||||
$o->closed = 0;
|
||||
$o->cls = 1;
|
||||
|
||||
// Header
|
||||
$sid = R_RED.'T'.R_BLUE.'E'.R_GREEN.'S'.R_YELLOW.'T';
|
||||
$o->content .= substr($sid.'-'.str_repeat('12345678901234567890',4),0,static::$header_length+(strlen($sid)-$so->strlenv($sid))).
|
||||
R_WHITE.'999999999a'.R_RED.sprintf('%07.0f',999).'u';
|
||||
|
||||
$o->content .= str_repeat('+-',18).' '.R_RED.'01';
|
||||
$o->content .= 'Name: '.ESC.str_repeat('u',5).str_repeat('+-',14);
|
||||
$o->content .= 'Date: '.ESC.str_repeat('d',25).str_repeat('+-',4);
|
||||
$o->content .= 'Address: '.ESC.str_repeat('a',19).' '.str_repeat('+-',5);
|
||||
$o->content .= ' : '.ESC.str_repeat('a',19).' '.str_repeat('+-',5);
|
||||
$o->content .= R_WHITE.str_repeat('+-',static::$frame_width/2-3).' '.R_RED.'01';
|
||||
$o->content .= R_WHITE.'Name: '.ESC.str_repeat('u',5).' |'.str_repeat('+-',static::$frame_width/2-8).'|';
|
||||
$o->content .= R_WHITE.'Date: '.ESC.str_repeat('d',17).' |'.str_repeat('+-',static::$frame_width/2-14).'|';
|
||||
$o->content .= R_WHITE.'Address: '.ESC.str_repeat('t',19).' |'.str_repeat('+-',static::$frame_width/2-17).'|';
|
||||
$o->content .= R_WHITE.' : '.ESC.str_repeat('t',19).' |'.str_repeat('+-',static::$frame_width/2-17).'|';
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ class Login extends Action
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$this->so->log('info','User Login: '.$this->uo->name);
|
||||
$this->page = ['frame'=>1,'index'=>'a']; // @todo Get from DB.
|
||||
|
||||
$this->action = 2; // ACTION_GOTO
|
||||
|
@ -5,6 +5,7 @@ namespace App\Classes\Frame;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use App\Classes\Frame as AbstractFrame;
|
||||
use App\Classes\Parser\Ansi as AnsiParser;
|
||||
|
||||
class Ansi extends AbstractFrame
|
||||
{
|
||||
@ -18,9 +19,21 @@ class Ansi extends AbstractFrame
|
||||
|
||||
public static $if_filler = '.';
|
||||
|
||||
public function fields($startline=0)
|
||||
public function __construct(\App\Models\Frame $o,string $msg='')
|
||||
{
|
||||
$this->output .= str_replace(LF,CR.LF,$this->frame->content);
|
||||
parent::__construct($o);
|
||||
|
||||
// If we have a message to display on the bottom line.
|
||||
if ($msg)
|
||||
$this->output .= ESC.'[24;0f'.$msg.HOME;
|
||||
}
|
||||
|
||||
public function fields($startline=1)
|
||||
{
|
||||
$o = new AnsiParser($this->frame->content,$startline);
|
||||
$this->output .= (string)$o;
|
||||
|
||||
$this->fields = $o->fields;
|
||||
}
|
||||
|
||||
public function strlenv($text):int {
|
||||
|
@ -19,26 +19,32 @@ class Videotex extends AbstractFrame
|
||||
|
||||
public static $if_filler = '.';
|
||||
|
||||
public function fields($startline=0)
|
||||
public function __construct(\App\Models\Frame $o,string $msg='')
|
||||
{
|
||||
parent::__construct($o);
|
||||
|
||||
// If we have a message to display on the bottom line.
|
||||
if ($msg)
|
||||
$this->output .= HOME.UP.$msg.HOME;
|
||||
}
|
||||
|
||||
public function fields($startline=1)
|
||||
{
|
||||
$infield = FALSE; // In a field
|
||||
$fieldtype = NULL; // Type of field
|
||||
$fieldlength = 0; // Length of field
|
||||
|
||||
if ($startline)
|
||||
$this->output .= str_repeat(DOWN,$startline);
|
||||
|
||||
// $fieldadrline = 1;
|
||||
|
||||
// Scan the frame for a field start
|
||||
for ($y=$startline;$y<=static::$frame_length;$y++)
|
||||
for ($y=$startline-1;$y<=static::$frame_length;$y++)
|
||||
{
|
||||
// Fields can only be on a single line
|
||||
$fieldx = $fieldy = FALSE;
|
||||
|
||||
for ($x=0;$x<static::$frame_width;$x++)
|
||||
{
|
||||
$posn = $y*40+$x;
|
||||
$posn = $y*static::$frame_width+$x;
|
||||
|
||||
// If the frame is not big enough, fill it with spaces.
|
||||
$byte = ord(isset($this->frame->content{$posn}) ? $this->frame->content{$posn} : ' ')%128;
|
||||
@ -62,7 +68,6 @@ class Videotex extends AbstractFrame
|
||||
}
|
||||
|
||||
// Is this a magic field?
|
||||
// @todo For page redisplay *00, we should show entered contents - for refresh *09 we should show updated contents
|
||||
if (array_get($this->fieldmap,chr($fieldtype)) ) {
|
||||
$field = $this->fieldmap[chr($fieldtype)];
|
||||
//dump(['infield','byte'=>$byte,'fieldtype'=>$fieldtype,'field'=>$field,'strpos'=>strpos($field,'#')]);
|
||||
|
@ -15,4 +15,17 @@ class FrameFields
|
||||
{
|
||||
return array_get($this->fields,$key);
|
||||
}
|
||||
|
||||
public function output(string $filler)
|
||||
{
|
||||
switch ($this->type) {
|
||||
case 'd':
|
||||
$out = date('D d M H:ia');
|
||||
|
||||
return substr($out.($this->length > strlen($out) ? str_repeat($filler,$this->length-strlen($out)) : ''),0,$this->length);
|
||||
|
||||
default:
|
||||
return str_repeat($filler,$this->length);
|
||||
}
|
||||
}
|
||||
}
|
7
app/Classes/Parser.php
Normal file
7
app/Classes/Parser.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes;
|
||||
|
||||
class Parser
|
||||
{
|
||||
}
|
156
app/Classes/Parser/Ansi.php
Normal file
156
app/Classes/Parser/Ansi.php
Normal file
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Parser;
|
||||
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use App\Classes\FrameFields;
|
||||
use App\Classes\Parser as AbstractParser;
|
||||
use App\Classes\Frame\Ansi as AnsiFrame;
|
||||
|
||||
class Ansi extends AbstractParser {
|
||||
private $content = '';
|
||||
private $startline = 0;
|
||||
public $fields = NULL;
|
||||
|
||||
public function __construct(string $content,int $startline=1)
|
||||
{
|
||||
$this->content = $content;
|
||||
$this->startline = $startline;
|
||||
$this->fields = collect();
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->parse($this->startline);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a string and look for the next character that is not $char
|
||||
*
|
||||
* @param string $char
|
||||
* @param int $start
|
||||
* @return bool|int
|
||||
*/
|
||||
private function findEOF(string $char,int $start)
|
||||
{
|
||||
for ($c=$start;$c <= strlen($this->content);$c++)
|
||||
{
|
||||
if ($this->content{$c} != $char)
|
||||
return $c-$start;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $startline
|
||||
* @param int $offset
|
||||
* @return string
|
||||
*/
|
||||
private function parse($startline): string
|
||||
{
|
||||
// Our starting coordinates
|
||||
$x = 1;
|
||||
$y = $startline;
|
||||
$output = '';
|
||||
|
||||
// Scan the frame for a field start
|
||||
for ($c=0; $c<=strlen($this->content); $c++)
|
||||
{
|
||||
// If the frame is not big enough, fill it with spaces.
|
||||
$byte = isset($this->content{$c}) ? $this->content{$c} : ' ';
|
||||
$advance = 0;
|
||||
|
||||
switch ($byte) {
|
||||
case CR:
|
||||
$x = 1;
|
||||
break;
|
||||
|
||||
case LF:
|
||||
$y++;
|
||||
break;
|
||||
|
||||
case ESC:
|
||||
$advance = 1;
|
||||
// Is the next byte something we know about
|
||||
$nextbyte = isset($this->content{$c+$advance}) ? $this->content{$c+$advance} : ' ';
|
||||
|
||||
switch ($nextbyte) {
|
||||
case '[':
|
||||
$advance++;
|
||||
$chars = $nextbyte;
|
||||
|
||||
// Find our end CSI param
|
||||
$matches = [];
|
||||
|
||||
$a = preg_match('/([0-9]+[;]?)+([a-zA-Z])/',$this->content,$matches,NULL,$c+$advance);
|
||||
|
||||
if (! $a)
|
||||
break;
|
||||
|
||||
$advance += strlen($matches[0])-1;
|
||||
$chars .= $matches[0];
|
||||
|
||||
switch ($matches[2]) {
|
||||
// We ignore 'm' they are color CSIs
|
||||
case 'm': break;
|
||||
|
||||
case 'C':
|
||||
$x += $matches[1]; // Advance our position
|
||||
break;
|
||||
|
||||
default:
|
||||
dump('Unhandled CSI: '.$matches[2]);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
dump(['l'=>__LINE__,'LOOSE ESC?']);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$c--; // Allow for the original ESC
|
||||
$advance++;
|
||||
$fieldtype = ord($nextbyte)%128; // @todo Do we need the %128 for ANSI?
|
||||
$fieldlength = $this->findEOF(chr($fieldtype),$c+1)+1;
|
||||
|
||||
$byte = '';
|
||||
|
||||
$this->fields->push(new FrameFields([
|
||||
'type'=>chr($fieldtype),
|
||||
'length'=>$fieldlength,
|
||||
'x'=>$x, // Adjust for the ESC char
|
||||
'y'=>$y,
|
||||
]));
|
||||
|
||||
Log::debug(sprintf('Field found at [%s,%s], Type: %s, Length: %s',$x-1,$y,$fieldtype,$fieldlength));
|
||||
$advance += $fieldlength-2;
|
||||
$x += $fieldlength;
|
||||
$chars = $this->fields->last()->output(AnsiFrame::$if_filler);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$x++;
|
||||
}
|
||||
|
||||
$output .= $byte;
|
||||
|
||||
if ($advance) {
|
||||
$output .= $chars;
|
||||
$c += $advance;
|
||||
}
|
||||
|
||||
if ($x > 80) {
|
||||
$x = 1;
|
||||
$y++;
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -16,8 +16,8 @@ class Ansi extends AbstractServer {
|
||||
define('HOME', ESC.'[0;0f');
|
||||
define('LEFT', ESC.'[D'); // Move Cursor
|
||||
define('RIGHT', ESC.'[C'); // Move Cursor
|
||||
define('DOWN', chr(10)); // Move Cursor
|
||||
define('UP', chr(11)); // Move Cursor
|
||||
define('DOWN', ESC.'[B'); // Move Cursor
|
||||
define('UP', ESC.'[A'); // Move Cursor
|
||||
define('CR', chr(13));
|
||||
define('LF', chr(10));
|
||||
define('CLS', ESC.'[2J');
|
||||
@ -48,6 +48,10 @@ class Ansi extends AbstractServer {
|
||||
parent::__construct($o);
|
||||
}
|
||||
|
||||
function outputPosition($x,$y) {
|
||||
return ESC.'['.$y.';'.$x.'f';
|
||||
}
|
||||
|
||||
// Abstract function
|
||||
public function sendBaseline($client,$text,$reposition=FALSE) {
|
||||
$client->send(ESC.'[24;0f'.$text.
|
||||
|
@ -48,6 +48,22 @@ class Videotex extends AbstractServer {
|
||||
parent::__construct($o);
|
||||
}
|
||||
|
||||
public 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));
|
||||
}
|
||||
}
|
||||
|
||||
public function sendBaseline($client,$text,$reposition=FALSE) {
|
||||
$client->send(HOME.UP.$text.
|
||||
($this->blp > $this->strlenv($text)
|
||||
|
@ -61,6 +61,7 @@ class FrameImport extends Command
|
||||
try {
|
||||
$o = $o->where('frame',$this->argument('frame'))
|
||||
->where('index',$this->argument('index'))
|
||||
->where('mode_id',$this->option('mode'))
|
||||
->firstOrFail();
|
||||
|
||||
} catch (ModelNotFoundException $e) {
|
||||
@ -71,6 +72,7 @@ class FrameImport extends Command
|
||||
} else {
|
||||
$o->frame = $this->argument('frame');
|
||||
$o->index = $this->argument('index');
|
||||
$o->mode_id = $this->option('mode');
|
||||
}
|
||||
|
||||
$o->content = ($this->option('trim'))
|
||||
@ -80,7 +82,6 @@ class FrameImport extends Command
|
||||
$o->access = $this->option('access');
|
||||
$o->closed = $this->option('closed');
|
||||
$o->cost = $this->option('cost');
|
||||
$o->mode_id = $this->option('mode');
|
||||
$o->type = $this->option('type');
|
||||
|
||||
$o->save();
|
||||
|
@ -44,11 +44,11 @@ class Mode extends Model
|
||||
*
|
||||
* @param int $frame
|
||||
* @param string $index
|
||||
* @param Server $so
|
||||
* @return FrameClass
|
||||
* @throws \Exception
|
||||
*/
|
||||
//@todo Move Server $so first
|
||||
public function frameLoad(int $frame,string $index='a',Server $so): FrameClass
|
||||
public function frameLoad(int $frame,string $index,Server $so): FrameClass
|
||||
{
|
||||
return $this->frame(
|
||||
// Return our internal test frame.
|
||||
|
@ -16,19 +16,19 @@ class CreateFramemeta extends Migration
|
||||
$this->down();
|
||||
|
||||
Schema::create('framemeta', function (Blueprint $table) {
|
||||
$table->integer('frame_id')->primary();
|
||||
$table->string('r0')->default('*');
|
||||
$table->string('r1')->default('*');
|
||||
$table->string('r2')->default('*');
|
||||
$table->string('r3')->default('*');
|
||||
$table->string('r4')->default('*');
|
||||
$table->string('r5')->default('*');
|
||||
$table->string('r6')->default('*');
|
||||
$table->string('r7')->default('*');
|
||||
$table->string('r8')->default('*');
|
||||
$table->string('r9')->default('*');
|
||||
$table->integer('frame_id')->primary();
|
||||
$table->string('r0')->default('*');
|
||||
$table->string('r1')->default('*');
|
||||
$table->string('r2')->default('*');
|
||||
$table->string('r3')->default('*');
|
||||
$table->string('r4')->default('*');
|
||||
$table->string('r5')->default('*');
|
||||
$table->string('r6')->default('*');
|
||||
$table->string('r7')->default('*');
|
||||
$table->string('r8')->default('*');
|
||||
$table->string('r9')->default('*');
|
||||
|
||||
$table->foreign('frame_id')->references('id')->on('frames');
|
||||
$table->foreign('frame_id')->references('id')->on('frames');
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class FrameAddClear extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('frames', function (Blueprint $table) {
|
||||
$table->boolean('cls')->default(TRUE);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('frames', function (Blueprint $table) {
|
||||
$table->dropColumn('cls');
|
||||
});
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user