Updated Videotex frame to use Parser
This commit is contained in:
parent
35b5bc2263
commit
390f52a460
@ -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;
|
||||
}
|
||||
|
@ -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;$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);
|
||||
}
|
||||
}
|
||||
$this->fields = $o->fields;
|
||||
}
|
||||
|
||||
public function strlenv($text):int {
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
||||
|
122
app/Classes/Parser/Videotex.php
Normal file
122
app/Classes/Parser/Videotex.php
Normal 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;
|
||||
}
|
||||
}
|
@ -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.
|
||||
@ -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);
|
||||
|
@ -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,11 +34,16 @@ class Frame extends Model
|
||||
*/
|
||||
public function getContentAttribute()
|
||||
{
|
||||
return is_resource($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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Page Number
|
||||
*
|
||||
|
@ -16,5 +16,5 @@
|
||||
[0m [1mIf you would like to host your own pages on this system, please let [0;31mdeon
|
||||
[37m [1mknow.
|
||||
|
||||
[0;31m User: [1;37muuuuuuuuuuu[0m [New Accounts use[1m [33mNEW#[0m]
|
||||
[0;31m User: [1;37mttttttttttt[0m [New Accounts use[1m [33mNEW#[0m]
|
||||
[31m Pass: [1;37mppppppppppp
|
||||
|
@ -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_
|
||||
|
@ -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
1
data/981b-register.bin
Normal 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
1
data/99a-goodbye.bin
Normal 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...
|
Reference in New Issue
Block a user