Updated Videotex frame to use Parser

This commit is contained in:
Deon George 2018-12-29 23:24:41 +11:00
parent 35b5bc2263
commit 390f52a460
12 changed files with 200 additions and 140 deletions

View File

@ -56,16 +56,9 @@ abstract class Frame
public $fields = NULL; // The fields in this 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 // Fields that are editable
private $fieldoptions = [ private $fieldoptions = [
'p'=>['edit'=>TRUE,'mask'=>'*'], // Password 'p'=>['edit'=>TRUE,'mask'=>'*'], // Password
'u'=>['edit'=>TRUE], // User
't'=>['edit'=>TRUE], // Text 't'=>['edit'=>TRUE], // Text
]; ];
@ -395,7 +388,7 @@ abstract class Frame
// Simulate a DB load // Simulate a DB load
$o = new \App\Models\Frame; $o = new \App\Models\Frame;
$o->content = ''; $content = '';
$o->flags = ['ip']; $o->flags = ['ip'];
$o->type = 'a'; $o->type = 'a';
$o->frame = 999; $o->frame = 999;
@ -406,14 +399,16 @@ abstract class Frame
// Header // Header
$sid = R_RED.'T'.R_BLUE.'E'.R_GREEN.'S'.R_YELLOW.'T'; $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'; R_WHITE.'999999999a'.R_RED.sprintf('%07.0f',999).'u';
$o->content .= R_WHITE.str_repeat('+-',static::$frame_width/2-3).' '.R_RED.'01'; $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).'|'; $content .= R_WHITE.'Name: '.ESC.str_repeat('t',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).'|'; $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).'|'; $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.' : '.ESC.str_repeat('t',19).' |'.str_repeat('+-',static::$frame_width/2-17).'|';
$o->content = $content;
return $o; return $o;
} }

View File

@ -5,7 +5,7 @@ namespace App\Classes\Frame;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use App\Classes\Frame as AbstractFrame; use App\Classes\Frame as AbstractFrame;
use App\Classes\FrameFields; use App\Classes\Parser\Videotex as VideotexParser;
class Videotex extends AbstractFrame class Videotex extends AbstractFrame
{ {
@ -31,107 +31,11 @@ class Videotex extends AbstractFrame
// @todo Change to use a Parser, like we do for ANSI // @todo Change to use a Parser, like we do for ANSI
public function fields($startline=1) 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 $this->fields = $o->fields;
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*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;
// 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);
}
}
} }
public function strlenv($text):int { public function strlenv($text):int {

View File

@ -4,4 +4,27 @@ namespace App\Classes;
abstract class Parser 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;
} }

View File

@ -9,22 +9,6 @@ use App\Classes\Parser as AbstractParser;
use App\Classes\Frame\Ansi as AnsiFrame; use App\Classes\Frame\Ansi as AnsiFrame;
class Ansi extends AbstractParser { 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 * Parse a string and look for the next character that is not $char
* *
@ -48,7 +32,7 @@ class Ansi extends AbstractParser {
* @param int $offset * @param int $offset
* @return string * @return string
*/ */
private function parse($startline): string protected function parse($startline): string
{ {
// Our starting coordinates // Our starting coordinates
$x = 1; $x = 1;

View File

@ -0,0 +1,122 @@
<?php
namespace App\Classes\Parser;
use Illuminate\Support\Facades\Log;
use App\Classes\FrameFields;
use App\Classes\Parser as AbstractParser;
use App\Classes\Frame\Videotex as VideotexFrame;
class Videotex extends AbstractParser
{
protected function parse($startline): string
{
// Our starting coordinates
$output = '';
$infield = FALSE; // In a field
$fieldtype = NULL; // Type of field
$fieldlength = 0; // Length of field
// $fieldadrline = 1;
// Scan the frame for a field start
for ($y=$startline-1;$y<=VideotexFrame::$frame_length;$y++)
{
// Fields can only be on a single line
$fieldx = $fieldy = FALSE;
for ($x=0;$x<VideotexFrame::$frame_width;$x++)
{
$posn = $y*VideotexFrame::$frame_width+$x;
// If the frame is not big enough, fill it with spaces.
$byte = ord(isset($this->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;
}
}

View File

@ -230,7 +230,7 @@ abstract class Server {
// If we are the main login screen, see if it is a new user // If we are the main login screen, see if it is a new user
if ($fo->isCUG(0)) 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; $action = ACTION_GOTO;
$page = ['frame'=>'981']; // @todo This should be in the DB. $page = ['frame'=>'981']; // @todo This should be in the DB.
@ -392,7 +392,7 @@ abstract class Server {
$page = $ao->page; $page = $ao->page;
} else { } else {
$this->sendBaseline($client, RED . 'NO method exists...'); $this->sendBaseline($client, RED.'NO method exists...');
$mode = MODE_RFSENT; $mode = MODE_RFSENT;
} }
@ -404,9 +404,19 @@ abstract class Server {
$mode = MODE_RFNOTSENT; $mode = MODE_RFNOTSENT;
// If a Control method was rejected, we can clear it // If a Control method was rejected, we can clear it
if ($control AND $method->count()) if ($control AND $method->count()) {
$method->pop(); $method->pop();
if ($method->count()) {
$control = $method->last()->state['control'];
} else {
$mode = $save->state['mode'];
$action = $save->state['action'];
$control = FALSE;
}
}
break; break;
case STAR: case STAR:
@ -682,6 +692,19 @@ abstract class Server {
if ($history->count() > 1) if ($history->count() > 1)
$history->pop(); $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(); $page = $history->last();
$this->log('debug','Backing up to:',$page); $this->log('debug','Backing up to:',$page);

View File

@ -7,6 +7,8 @@ use Illuminate\Database\Eloquent\Model;
class Frame extends Model class Frame extends Model
{ {
public $cache_content = '';
public function cug() public function cug()
{ {
return $this->belongsTo(CUG::class); return $this->belongsTo(CUG::class);
@ -32,9 +34,14 @@ class Frame extends Model
*/ */
public function getContentAttribute() public function getContentAttribute()
{ {
return is_resource($this->attributes['content']) // For stream resources, we need to cache this result.
? stream_get_contents($this->attributes['content']) if (! $this->cache_content) {
: $this->attributes['content']; $this->cache_content = is_resource($this->attributes['content'])
? stream_get_contents($this->attributes['content'])
: $this->attributes['content'];
}
return $this->cache_content;
} }
/** /**

View File

@ -16,5 +16,5 @@
 If you would like to host your own pages on this system, please let deon  If you would like to host your own pages on this system, please let deon
 know.  know.
 User: uuuuuuuuuuu [New Accounts use NEW#]  User: ttttttttttt [New Accounts use NEW#]
 Pass: ppppppppppp  Pass: ppppppppppp

View File

@ -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_ 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_

View File

@ -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 `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

1
data/981b-register.bin Normal file
View File

@ -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.

1
data/99a-goodbye.bin Normal file
View File

@ -0,0 +1 @@
 `pp0`pp `pp `pz5 up p0`0`pp  5j55j55j55j5 5j55j5uz5  5z55j55j55j5 5j55z55`0h4h4h "#j5"## "## "##! ### "#j5"##   ,.! ,.! Thanks for connecting. Come back again...