From 390f52a46041669fb6e02300a48d253e53a6f460 Mon Sep 17 00:00:00 2001 From: Deon George Date: Sat, 29 Dec 2018 23:24:41 +1100 Subject: [PATCH] Updated Videotex frame to use Parser --- app/Classes/Frame.php | 23 +++--- app/Classes/Frame/Videotex.php | 104 ++------------------------- app/Classes/Parser.php | 23 ++++++ app/Classes/Parser/Ansi.php | 18 +---- app/Classes/Parser/Videotex.php | 122 ++++++++++++++++++++++++++++++++ app/Classes/Server.php | 29 +++++++- app/Models/Frame.php | 13 +++- data/980a-login.ans | 2 +- data/980a-login.bin | 2 +- data/981a-register.bin | 2 +- data/981b-register.bin | 1 + data/99a-goodbye.bin | 1 + 12 files changed, 200 insertions(+), 140 deletions(-) create mode 100644 app/Classes/Parser/Videotex.php create mode 100644 data/981b-register.bin create mode 100644 data/99a-goodbye.bin diff --git a/app/Classes/Frame.php b/app/Classes/Frame.php index d29ac89..4461ea2 100644 --- a/app/Classes/Frame.php +++ b/app/Classes/Frame.php @@ -56,16 +56,9 @@ abstract class Frame public $fields = NULL; // The fields in this frame. - // Magic Fields that are pre-filled - protected $fieldmap = [ - 'a'=>'address#', - 'd'=>'%date', - ]; - // Fields that are editable private $fieldoptions = [ 'p'=>['edit'=>TRUE,'mask'=>'*'], // Password - 'u'=>['edit'=>TRUE], // User 't'=>['edit'=>TRUE], // Text ]; @@ -395,7 +388,7 @@ abstract class Frame // Simulate a DB load $o = new \App\Models\Frame; - $o->content = ''; + $content = ''; $o->flags = ['ip']; $o->type = 'a'; $o->frame = 999; @@ -406,14 +399,16 @@ abstract class Frame // 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))). + $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 .= 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).'|'; + $content .= R_WHITE.str_repeat('+-',static::$frame_width/2-3).' '.R_RED.'01'; + $content .= R_WHITE.'Name: '.ESC.str_repeat('t',5).' |'.str_repeat('+-',static::$frame_width/2-8).'|'; + $content .= R_WHITE.'Date: '.ESC.str_repeat('d',17).' |'.str_repeat('+-',static::$frame_width/2-14).'|'; + $content .= R_WHITE.'Address: '.ESC.str_repeat('t',19).' |'.str_repeat('+-',static::$frame_width/2-17).'|'; + $content .= R_WHITE.' : '.ESC.str_repeat('t',19).' |'.str_repeat('+-',static::$frame_width/2-17).'|'; + + $o->content = $content; return $o; } diff --git a/app/Classes/Frame/Videotex.php b/app/Classes/Frame/Videotex.php index ad113f8..84abba6 100644 --- a/app/Classes/Frame/Videotex.php +++ b/app/Classes/Frame/Videotex.php @@ -5,7 +5,7 @@ namespace App\Classes\Frame; use Illuminate\Support\Facades\Log; use App\Classes\Frame as AbstractFrame; -use App\Classes\FrameFields; +use App\Classes\Parser\Videotex as VideotexParser; class Videotex extends AbstractFrame { @@ -31,107 +31,11 @@ class Videotex extends AbstractFrame // @todo Change to use a Parser, like we do for ANSI public function fields($startline=1) { - $infield = FALSE; // In a field - $fieldtype = NULL; // Type of field - $fieldlength = 0; // Length of field - // $fieldadrline = 1; + $o = new VideotexParser($this->frame->content,$startline); + $this->output .= (string)$o; - // Scan the frame for a field start - for ($y=$startline-1;$y<=static::$frame_length;$y++) - { - // Fields can only be on a single line - $fieldx = $fieldy = FALSE; - - for ($x=0;$xframe->content{$posn}) ? $this->frame->content{$posn} : ' ')%128; - - // Check for start-of-field - if ($byte == ord(ESC)) { // Esc designates start of field (Esc-K is end of edit) - $infield = TRUE; - $fieldlength = 1; - $fieldtype = ord(substr($this->frame->content,$posn+1,1))%128; - $this->output .= static::$if_filler; - - } else { - if ($infield) { - if ($byte == $fieldtype) { - $fieldlength++; - $byte = ord(static::$if_filler); // Replace field with static::$if_filler. - - if ($fieldx === FALSE) { - $fieldx = $x; - $fieldy = $y; - } - - // Is this a magic field? - if (array_get($this->fieldmap,chr($fieldtype)) ) { - $field = $this->fieldmap[chr($fieldtype)]; - //dump(['infield','byte'=>$byte,'fieldtype'=>$fieldtype,'field'=>$field,'strpos'=>strpos($field,'#')]); - - /* - // address field has many lines. increment when hit on first character. - if ($fieldlength == 1 && strpos($field,'#') !== false) { - $field = str_replace('#',$fieldadrline,$field); - dump(['field'=>$field,'fieldadrline'=>$fieldadrline,'fieldadrline'=>$fieldadrline]); - $fieldadrline++; - } - */ - - // Replace field with Date - if ($field == '%date') { - // Drop the last dot and replace it. - if ($fieldlength == 2) { - $datetime = date('D d M H:ia'); - $this->output = rtrim($this->output,static::$if_filler); - $this->output .= $datetime{0}; - } - - if ($fieldlength > 1 AND $fieldlength <= strlen($datetime)) - $byte = ord($datetime{$fieldlength-1}); - } - - // @todo user data - /* else if (isset($user[$field])) { - if ($fieldlength <= strlen($user[$field])) { - $byte = ord($user[$field]{$fieldlength-1}); - } - } /*else // pre-load field contents. PAM or *00 ? - if (isset($fields[what]['value'])) { - - */ - } - - } else { - $this->fields->push(new FrameFields([ - 'type'=>chr($fieldtype), - 'length'=>$fieldlength, - 'x'=>$fieldx-1, // Adjust for the ESC char - 'y'=>$fieldy, - ])); - - Log::debug(sprintf('Frame: %s, Field found at [%s,%s], Type: %s, Length: %s',$this->page(),$fieldx-1,$fieldy,$fieldtype,$fieldlength)); - - $infield = FALSE; - $fieldx = $fieldy = FALSE; - } - } - } - - // truncate end of lines @todo havent validated this code or used it? - if (isset($pageflags['tru']) && substr($this->frame->content,$posn,40-$x) === str_repeat(' ',40-$x)) { - $this->output .= CR . LF; - break; - } - - if (! $infield OR $fieldlength > 1) - $this->output .= ($byte < 32) ? ESC.chr($byte+64) : chr($byte); - } - } + $this->fields = $o->fields; } public function strlenv($text):int { diff --git a/app/Classes/Parser.php b/app/Classes/Parser.php index 264962e..4a615ef 100644 --- a/app/Classes/Parser.php +++ b/app/Classes/Parser.php @@ -4,4 +4,27 @@ namespace App\Classes; abstract class Parser { + protected $content = ''; + protected $startline = 0; + public $fields = NULL; + + // Magic Fields that are pre-filled + protected $fieldmap = [ + 'a'=>'address#', + 'd'=>'%date', + ]; + + 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); + } + + abstract protected function parse($startline): string; } \ No newline at end of file diff --git a/app/Classes/Parser/Ansi.php b/app/Classes/Parser/Ansi.php index a819afb..833707e 100644 --- a/app/Classes/Parser/Ansi.php +++ b/app/Classes/Parser/Ansi.php @@ -9,22 +9,6 @@ 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 * @@ -48,7 +32,7 @@ class Ansi extends AbstractParser { * @param int $offset * @return string */ - private function parse($startline): string + protected function parse($startline): string { // Our starting coordinates $x = 1; diff --git a/app/Classes/Parser/Videotex.php b/app/Classes/Parser/Videotex.php new file mode 100644 index 0000000..1b7b9b5 --- /dev/null +++ b/app/Classes/Parser/Videotex.php @@ -0,0 +1,122 @@ +content{$posn}) ? $this->content{$posn} : ' ')%128; + + // Check for start-of-field + if ($byte == ord(ESC)) { // Esc designates start of field (Esc-K is end of edit) + $infield = TRUE; + $fieldlength = 1; + $fieldtype = ord(substr($this->content,$posn+1,1))%128; + $output .= VideotexFrame::$if_filler; + + } else { + if ($infield) { + if ($byte == $fieldtype) { + $fieldlength++; + $byte = ord(VideotexFrame::$if_filler); // Replace field with VideotexFrame::$if_filler. + + if ($fieldx === FALSE) { + $fieldx = $x; + $fieldy = $y; + } + + // Is this a magic field? + if (array_get($this->fieldmap,chr($fieldtype)) ) { + $field = $this->fieldmap[chr($fieldtype)]; + //dump(['infield','byte'=>$byte,'fieldtype'=>$fieldtype,'field'=>$field,'strpos'=>strpos($field,'#')]); + + /* + // address field has many lines. increment when hit on first character. + if ($fieldlength == 1 && strpos($field,'#') !== false) { + $field = str_replace('#',$fieldadrline,$field); + dump(['field'=>$field,'fieldadrline'=>$fieldadrline,'fieldadrline'=>$fieldadrline]); + $fieldadrline++; + } + */ + + // Replace field with Date + if ($field == '%date') { + // Drop the last dot and replace it. + if ($fieldlength == 2) { + $datetime = date('D d M H:ia'); + $output = rtrim($output,VideotexFrame::$if_filler); + $output .= $datetime{0}; + } + + if ($fieldlength > 1 AND $fieldlength <= strlen($datetime)) + $byte = ord($datetime{$fieldlength-1}); + } + + // @todo user data + /* else if (isset($user[$field])) { + if ($fieldlength <= strlen($user[$field])) { + $byte = ord($user[$field]{$fieldlength-1}); + } + } /*else // pre-load field contents. PAM or *00 ? + if (isset($fields[what]['value'])) { + + */ + } + + } else { + $this->fields->push(new FrameFields([ + 'type'=>chr($fieldtype), + 'length'=>$fieldlength, + 'x'=>$fieldx-1, // Adjust for the ESC char + 'y'=>$fieldy, + ])); + + Log::debug(sprintf('Frame Field found at [%s,%s], Type: %s, Length: %s',$fieldx-1,$fieldy,$fieldtype,$fieldlength)); + + $infield = FALSE; + $fieldx = $fieldy = FALSE; + } + } + } + + // truncate end of lines @todo havent validated this code or used it? + if (isset($pageflags['tru']) && substr($this->content,$posn,40-$x) === str_repeat(' ',40-$x)) { + $output .= CR . LF; + break; + } + + if (! $infield OR $fieldlength > 1) + $output .= ($byte < 32) ? ESC.chr($byte+64) : chr($byte); + } + } + + return $output; + } +} \ No newline at end of file diff --git a/app/Classes/Server.php b/app/Classes/Server.php index 0a8f3a6..1aa6452 100644 --- a/app/Classes/Server.php +++ b/app/Classes/Server.php @@ -230,7 +230,7 @@ abstract class Server { // If we are the main login screen, see if it is a new user if ($fo->isCUG(0)) { - if ($current['field']->type == 'u' AND array_get($fielddata,$current['fieldnum']) == 'NEW') + if ($current['field']->type == 't' AND array_get($fielddata,$current['fieldnum']) == 'NEW') { $action = ACTION_GOTO; $page = ['frame'=>'981']; // @todo This should be in the DB. @@ -392,7 +392,7 @@ abstract class Server { $page = $ao->page; } else { - $this->sendBaseline($client, RED . 'NO method exists...'); + $this->sendBaseline($client, RED.'NO method exists...'); $mode = MODE_RFSENT; } @@ -404,9 +404,19 @@ abstract class Server { $mode = MODE_RFNOTSENT; // If a Control method was rejected, we can clear it - if ($control AND $method->count()) + if ($control AND $method->count()) { $method->pop(); + if ($method->count()) { + $control = $method->last()->state['control']; + + } else { + $mode = $save->state['mode']; + $action = $save->state['action']; + $control = FALSE; + } + } + break; case STAR: @@ -682,6 +692,19 @@ abstract class Server { if ($history->count() > 1) $history->pop(); + if ($control AND $method->count()) { + $method->pop(); + + if ($method->count()) { + $control = $method->last()->state['control']; + + } else { + $mode = $save->state['mode']; + $action = $save->state['action']; + $control = FALSE; + } + } + $page = $history->last(); $this->log('debug','Backing up to:',$page); diff --git a/app/Models/Frame.php b/app/Models/Frame.php index 9c4fc7a..c725645 100644 --- a/app/Models/Frame.php +++ b/app/Models/Frame.php @@ -7,6 +7,8 @@ use Illuminate\Database\Eloquent\Model; class Frame extends Model { + public $cache_content = ''; + public function cug() { return $this->belongsTo(CUG::class); @@ -32,9 +34,14 @@ class Frame extends Model */ public function getContentAttribute() { - return is_resource($this->attributes['content']) - ? stream_get_contents($this->attributes['content']) - : $this->attributes['content']; + // For stream resources, we need to cache this result. + if (! $this->cache_content) { + $this->cache_content = is_resource($this->attributes['content']) + ? stream_get_contents($this->attributes['content']) + : $this->attributes['content']; + } + + return $this->cache_content; } /** diff --git a/data/980a-login.ans b/data/980a-login.ans index 8773ef4..c0f3c55 100644 --- a/data/980a-login.ans +++ b/data/980a-login.ans @@ -16,5 +16,5 @@  If you would like to host your own pages on this system, please let deon  know. - User: uuuuuuuuuuu [New Accounts use NEW#] + User: ttttttttttt [New Accounts use NEW#]  Pass: ppppppppppp diff --git a/data/980a-login.bin b/data/980a-login.bin index 7cca475..1ea1075 100644 --- a/data/980a-login.bin +++ b/data/980a-login.bin @@ -1 +1 @@ - p0`0`0`pp 5 `pp `pp p0p0p `pp 5  5j5j5uz55 5"!5j57j7j5uz55  ujuj55`05 05`05j55j5j55`0p0 "!#!#!"## "## "## "## #!"!"!"## #!  A vBBS by...deon x}|4 ~ x|x0 | x}x4 `x}t x////////////| Welcome to} k/////// "OzTex? k'# "o% *?'! !+? oo/ User:uuuuuuuuuuu `tt Pass:ppppppppppp o% To register as a new user, useNEW_ \ No newline at end of file + p0`0`0`pp 5 `pp `pp p0p0p `pp 5  5j5j5uz55 5"!5j57j7j5uz55  ujuj55`05 05`05j55j5j55`0p0 "!#!#!"## "## "## "## #!"!"!"## #!  A vBBS by...deon x}|4 ~ x|x0 | x}x4 `x}t x////////////| Welcome to} k/////// "OzTex? k'# "o% *?'! !+? oo/ User:ttttttttttt `tt Pass:ppppppppppp o% To register as a new user, useNEW_ diff --git a/data/981a-register.bin b/data/981a-register.bin index 5633e4c..205e15f 100644 --- a/data/981a-register.bin +++ b/data/981a-register.bin @@ -1 +1 @@ - `pp `pp `pp s1`pp u0`pp `pp  5"!uz55j55us15 uz55"!  5 5`05z55p0z55 5`05 p p p 0 #! "##!"#j5#!"## "#!"##!#! # # # !  ,.! Press_ after each field entry! *00to start againUser :uuuuuuuuuu Pass :pppppppppp Again :pppppppppp Email :ttttttttttttttttttttttttttt Location:ttttttttttttttttttttttttttt 888888888888888888888888888888888888 Please provide your login details and remember your password! Your information isNOTshared with anybody else, and is only used to access and interact on this system. Problems? Emaildeon@leenooks.net \ No newline at end of file + `pp `pp `pp s1`pp u0`pp `pp  5"!uz55j55us15 uz55"!  5 5`05z55p0z55 5`05 p p p 0 #! "##!"#j5#!"## "#!"##!#! # # # !  ,.! Press_ after each field entry! *00to start againUsername :tttttttttt Real Name:tttttttttttttttttttttttttt Email :tttttttttttttttttttttttttt Pass :pppppppppp Again :pppppppppp Location :tttttttttttttttttttttttttt Token :ttttt 888888888888888888888888888888888888 Please provide your login details and remember your password! Your information isNOTshared with anybody else, and is only used to access and interact on this system. Problems? Emaildeon@leenooks.net diff --git a/data/981b-register.bin b/data/981b-register.bin new file mode 100644 index 0000000..1cd3942 --- /dev/null +++ b/data/981b-register.bin @@ -0,0 +1 @@ + `pp 5 5 `pp `pp u0  sqz55 5 us1uz55  5z55 05 0 p0z55`05 "#"!"## "## "## "## "#!  Your account has been created... You are all set to login. Press1to head back to the login screen and use the details you provided. If you have any trouble using this system, you can email deon@leenooks.netand describe your problems and I'll take a look to see what is going on. If you would like to own some page prefixes, on this site, please drop me a message. \ No newline at end of file diff --git a/data/99a-goodbye.bin b/data/99a-goodbye.bin new file mode 100644 index 0000000..33bf251 --- /dev/null +++ b/data/99a-goodbye.bin @@ -0,0 +1 @@ +  `pp0`pp `pp `pz5 up p0`0`pp  5j55j55j55j5 5j55j5uz5  5z55j55j55j5 5j55z55`0h4h4h "#j5"## "## "##! ### "#j5"##   ,.! ,.! Thanks for connecting. Come back again... \ No newline at end of file