Advertisement
quixadhal

I3.pl

Dec 17th, 2013
291
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 18.33 KB | None | 0 0
  1. #!/usr/bin/perl -w
  2.  
  3. package Serialize::LPC;
  4.  
  5. # Minimalistic LPC. Adapted from JSON::Tiny, and in turn Adapted from Mojo::JSON and Mojo::Util.
  6.  
  7. # Licensed under the Artistic 2.0 license.
  8. # http://www.perlfoundation.org/artistic_license_2_0.
  9.  
  10. use strict;
  11. use warnings;
  12. use B;
  13. use Exporter 'import';
  14. use Scalar::Util ();
  15. use Encode ();
  16.  
  17. our $VERSION = '0.01';
  18. our @EXPORT_OK = qw(j);
  19.  
  20. # Constructor and accessor: we don't have Mojo::Base.
  21.  
  22. sub new {
  23.   my $class = shift;
  24.   bless @_ ? @_ > 1 ? {@_} : {%{$_[0]}} : {}, $class;
  25. }
  26.  
  27. sub error {
  28.   $_[0]->{error} = $_[1] if @_ > 1;
  29.   return $_[0]->{error};
  30. }
  31.  
  32. # The rest adapted from Mojo::JSON, with minor mods & naming changes.
  33.  
  34. # Mojo::JSON sets these up as 'my' lexicals. We use 'our' so that users can
  35. # explicitly override the Booleans with just zero or one if they desire.
  36. # Literal names
  37. our $FALSE = bless \(my $false = 0), 'Serialize::LPC::_Bool';
  38. our $TRUE  = bless \(my $true  = 1), 'Serialize::LPC::_Bool';
  39.  
  40. # Escaped special character map (with u2028 and u2029)
  41. my %ESCAPE = (
  42.   '"'     => '"',
  43.   '\\'    => '\\',
  44. #  '/'     => '/',
  45.   'b'     => "\x07",
  46.   'f'     => "\x0c",
  47.   'n'     => "\x0a",
  48.   'r'     => "\x0d",
  49.   't'     => "\x09",
  50.   'u2028' => "\x{2028}",
  51.   'u2029' => "\x{2029}"
  52. );
  53. my %REVERSE = map { $ESCAPE{$_} => "\\$_" } keys %ESCAPE;
  54.  
  55. #for (0x00 .. 0x1f, 0x7f) { $REVERSE{pack 'C', $_} //= sprintf '\u%.4X', $_ }
  56. for( 0x00 .. 0x1f, 0x7f ) {
  57.   my $packed = pack 'C', $_;
  58.   $REVERSE{$packed} = sprintf '\u%.4X', $_
  59.     if ! defined( $REVERSE{$packed} );
  60. }
  61.  
  62. # Unicode encoding detection
  63. my $UTF_PATTERNS = {
  64.   'UTF-32BE' => qr/^\x00{3}[^\x00]/,
  65.   'UTF-32LE' => qr/^[^\x00]\x00{3}/,
  66.   'UTF-16BE' => qr/^(?:\x00[^\x00]){2}/,
  67.   'UTF-16LE' => qr/^(?:[^\x00]\x00){2}/
  68. };
  69.  
  70. my $WHITESPACE_RE = qr/[\x20\x09\x0a\x0d]*/;
  71.  
  72. sub decode {
  73.   my ($self, $bytes) = @_;
  74.  
  75.   # Clean start
  76.   $self->error(undef);
  77.  
  78.   # Missing input
  79.   $self->error('Missing or empty input') and return undef unless $bytes; ## no critic (undef)
  80.  
  81.   # Remove BOM
  82.   $bytes =~ s/^(?:\357\273\277|\377\376\0\0|\0\0\376\377|\376\377|\377\376)//g;
  83.  
  84.   # Wide characters
  85.   $self->error('Wide character in input') and return undef ## no critic (undef)
  86.     unless utf8::downgrade($bytes, 1);
  87.  
  88.   # Detect and decode Unicode
  89.   my $encoding = 'UTF-8';
  90.   $bytes =~ $UTF_PATTERNS->{$_} and $encoding = $_ for keys %$UTF_PATTERNS;
  91.  
  92.   my $d_res = eval { $bytes = Encode::decode($encoding, $bytes, 1); 1 };
  93.   $bytes = undef unless $d_res;
  94.  
  95.   # Object or array
  96.   my $res = eval {
  97.     local $_ = $bytes;
  98.  
  99.     # Leading whitespace
  100.     m/\G$WHITESPACE_RE/gc;
  101.  
  102.     # Array
  103.     my $ref;
  104.     if (m/\G\(\{/gc) { $ref = _decode_array() }
  105.  
  106.     # Object
  107.     elsif (m/\G\(\[/gc) { $ref = _decode_object() }
  108.  
  109.     # Invalid character
  110.     else { _exception('Expected array or object') }
  111.  
  112.     # Leftover data
  113.     unless (m/\G$WHITESPACE_RE\z/gc) {
  114.       my $got = ref $ref eq 'ARRAY' ? 'array' : 'object';
  115.       _exception("Unexpected data after $got");
  116.     }
  117.  
  118.     $ref;
  119.   };
  120.  
  121.   # Exception
  122.   if (!$res && (my $e = $@)) {
  123.     chomp $e;
  124.     $self->error($e);
  125.   }
  126.  
  127.   return $res;
  128. }
  129.  
  130. sub encode {
  131.   my ($self, $ref) = @_;
  132.   return Encode::encode 'UTF-8', _encode_value($ref);
  133. }
  134.  
  135. sub false {$FALSE}
  136.  
  137. sub j {
  138.   my( $d, $j ) = ( shift, __PACKAGE__->new );
  139.   return $j->encode($d) if ref $d eq 'ARRAY' || ref $d eq 'HASH';
  140.   defined and return $_ for $j->decode($d);
  141.   die $j->error;
  142. }
  143.  
  144. sub true  {$TRUE}
  145.  
  146. sub _decode_array {
  147.   my @array;
  148.   until (m/\G$WHITESPACE_RE\}\)/gc) {
  149.  
  150.     # Value
  151.     push @array, _decode_value();
  152.  
  153.     # Separator
  154.     redo if m/\G$WHITESPACE_RE,/gc;
  155.  
  156.     # End
  157.     last if m/\G$WHITESPACE_RE\}\)/gc;
  158.  
  159.     # Invalid character
  160.     _exception('Expected comma or right curly brace and right paren while parsing array');
  161.   }
  162.  
  163.   return \@array;
  164. }
  165.  
  166. sub _decode_object {
  167.   my %hash;
  168.   until (m/\G$WHITESPACE_RE\]\)/gc) {
  169.  
  170.     # Quote
  171.     m/\G$WHITESPACE_RE"/gc
  172.       or _exception('Expected string while parsing object');
  173.  
  174.     # Key
  175.     my $key = _decode_string();
  176.  
  177.     # Colon
  178.     m/\G$WHITESPACE_RE:/gc
  179.       or _exception('Expected colon while parsing object');
  180.  
  181.     # Value
  182.     $hash{$key} = _decode_value();
  183.  
  184.     # Separator
  185.     redo if m/\G$WHITESPACE_RE,/gc;
  186.  
  187.     # End
  188.     last if m/\G$WHITESPACE_RE\]\)/gc;
  189.  
  190.     # Invalid character
  191.     _exception('Expected comma or right square bracket and right paren while parsing object');
  192.   }
  193.  
  194.   return \%hash;
  195. }
  196.  
  197. sub _decode_string {
  198.   my $pos = pos;
  199.   # Extract string with escaped characters
  200.   m!\G((?:(?:[^\x00-\x1f\\"]|\\(?:["\\/bfnrt]|u[0-9a-fA-F]{4})){0,32766})*)!gc; # segfault under 5.8.x in t/20-mojo-json.t #83
  201.   my $str = $1;
  202.  
  203.   # Invalid character
  204.   unless (m/\G"/gc) {
  205.     _exception('Unexpected character or invalid escape while parsing string')
  206.       if m/\G[\x00-\x1f\\]/;
  207.     _exception('Unterminated string');
  208.   }
  209.  
  210.   # Unescape popular characters
  211.   if (index($str, '\\u') < 0) {
  212.     $str =~ s!\\(["\\/bfnrt])!$ESCAPE{$1}!gs;
  213.    return $str;
  214.  }
  215.  
  216.  # Unescape everything else
  217.  my $buffer = '';
  218.  while ($str =~ m/\G([^\\]*)\\(?:([^u])|u(.{4}))/gc) {
  219.    $buffer .= $1;
  220.  
  221.    # Popular character
  222.    if ($2) { $buffer .= $ESCAPE{$2} }
  223.  
  224.    # Escaped
  225.    else {
  226.      my $ord = hex $3;
  227.  
  228.      # Surrogate pair
  229.      if (($ord & 0xf800) == 0xd800) {
  230.  
  231.        # High surrogate
  232.        ($ord & 0xfc00) == 0xd800
  233.          or pos($_) = $pos + pos($str), _exception('Missing high-surrogate');
  234.  
  235.        # Low surrogate
  236.        $str =~ m/\G\\u([Dd][C-Fc-f]..)/gc
  237.          or pos($_) = $pos + pos($str), _exception('Missing low-surrogate');
  238.  
  239.        # Pair
  240.        $ord = 0x10000 + ($ord - 0xd800) * 0x400 + (hex($1) - 0xdc00);
  241.      }
  242.  
  243.      # Character
  244.      $buffer .= pack 'U', $ord;
  245.    }
  246.  }
  247.  
  248.  # The rest
  249.  return $buffer . substr $str, pos($str), length($str);
  250. }
  251.  
  252. sub _decode_value {
  253.  
  254.  # Leading whitespace
  255.  m/\G$WHITESPACE_RE/gc;
  256.  
  257.  # String
  258.  return _decode_string() if m/\G"/gc;
  259.  
  260.   # Array
  261.   return _decode_array() if m/\G\(\{/gc;
  262.  
  263.   # Object
  264.   return _decode_object() if m/\G\(\[/gc;
  265.  
  266.   # Number
  267.   return 0 + $1
  268.     if m/\G([-]?(?:0|[1-9][0-9]*)(?:\.[0-9]*)?(?:[eE][+-]?[0-9]+)?)/gc;
  269.  
  270.   # True
  271.   return $TRUE if m/\Gtrue/gc;
  272.  
  273.   # False
  274.   return $FALSE if m/\Gfalse/gc;
  275.  
  276.   # Null
  277.   return undef if m/\Gnull/gc;  ## no critic (return)
  278.  
  279.   # Invalid character
  280.   _exception('Expected string, array, object, number, boolean or null');
  281. }
  282.  
  283. sub _encode_array {
  284.   my $array = shift;
  285.   return '({' . join(',', map { _encode_value($_) } @$array) . '})';
  286. }
  287.  
  288. sub _encode_object {
  289.   my $object = shift;
  290.   my @pairs = map { _encode_string($_) . ':' . _encode_value($object->{$_}) }
  291.     keys %$object;
  292.   return '([' . join(',', @pairs) . '])';
  293. }
  294.  
  295. sub _encode_string {
  296.   my $str = shift;
  297.   $str =~ s!([\x00-\x1f\x7f\x{2028}\x{2029}\\"/\b\f\n\r\t])!$REVERSE{$1}!gs;
  298.  return "\"$str\"";
  299. }
  300.  
  301. sub _encode_value {
  302.   my $value = shift;
  303.  
  304.   # Reference
  305.   if (my $ref = ref $value) {
  306.  
  307.     # Array
  308.     return _encode_array($value) if $ref eq 'ARRAY';
  309.  
  310.     # Object
  311.     return _encode_object($value) if $ref eq 'HASH';
  312.  
  313.     # True or false
  314.     return $value  ? 'true' : 'false' if $ref eq 'Serialize::LPC::_Bool';
  315.  
  316.     # Blessed reference with TO_LPC method
  317.     if (Scalar::Util::blessed $value && (my $sub = $value->can('TO_LPC'))) {
  318.       return _encode_value($value->$sub);
  319.     }
  320.  
  321.     # References to scalars (including blessed) will be encoded as Booleans.
  322.     return $$value ? 'true' : 'false' if $ref =~ /SCALAR/;
  323.  
  324.   }
  325.  
  326.   # Null
  327.   return 'null' unless defined $value;
  328.  
  329.   # Number
  330.   my $flags = B::svref_2object(\$value)->FLAGS;
  331.   return 0 + $value if $flags & (B::SVp_IOK | B::SVp_NOK) && $value * 0 == 0;
  332.  
  333.  
  334.   # String
  335.   return _encode_string($value);
  336. }
  337.  
  338. sub _exception {
  339.  
  340.   # Leading whitespace
  341.   m/\G$WHITESPACE_RE/gc;
  342.  
  343.   # Context
  344.   my $context = 'Malformed LPC: ' . shift;
  345.   if (m/\G\z/gc) { $context .= ' before end of data' }
  346.   else {
  347.     my @lines = split /\n/, substr($_, 0, pos);
  348.     $context .= ' at line ' . @lines . ', offset ' . length(pop @lines || '');
  349.   }
  350.  
  351.   die "$context\n";
  352. }
  353.  
  354. # Emulate boolean type
  355. package Serialize::LPC::_Bool;
  356. use overload '0+' => sub { ${$_[0]} }, '""' => sub { ${$_[0]} }, fallback => 1;
  357.  
  358. 1;
  359.  
  360. package Serialize::MudMode;
  361.  
  362. use strict;
  363.  
  364. sub new {
  365.   my $class = shift;
  366.   bless @_ ? @_ > 1 ? {@_} : {%{$_[0]}} : {}, $class;
  367. }
  368.  
  369. sub encode {
  370.     my ($self, $ref) = @_;
  371.     my $lpc = new Serialize::LPC;
  372.     my $thing = $lpc->encode($ref);
  373.     my $len = length( $thing ) + 1;
  374.     my $packet = pack( 'NZ*', $len, $thing );
  375.     return $packet;
  376. }
  377.  
  378. sub decode {
  379.     my ($self, $packet) = @_;
  380.     my $lpc = new Serialize::LPC;
  381.     my ($len, $thing) = unpack( 'NZ*', $packet );
  382.     my $ref = $lpc->decode($thing);
  383.     return $ref;
  384. }
  385.  
  386. package I3::Packet;
  387.  
  388. use strict;
  389. use overload (
  390.     '""'    => \&as_string,
  391.     '@{}'   => \&as_array,
  392. );
  393.  
  394. sub new {
  395.     my $class = shift;
  396.     my $data = shift;
  397.     my @args = @_;
  398.  
  399.     my $self_array = [ "error", 5, 0, 0, 0, 0, 0, 0, 0 ];
  400.     my $self = {
  401.         type                => "invalid",
  402.         ttl                 => 5,
  403.         originator_mudname  => 0,
  404.         originator_username => 0,
  405.         target_mudname      => 0,
  406.         target_username     => 0,
  407.     };
  408.     $self->{as_array} = $self_array;
  409.  
  410.     if( ref $data and ref $data eq "ARRAY") {
  411.         # We passed in an array, probably decoded from a mudmode packet.
  412.         if( scalar @$data < 6 or !defined $data->[0]) {
  413.             warn "Invalid initialization data for __PACKAGE__";
  414.             return undef;
  415.         }
  416.  
  417.         # Valid I3 packets have (int)0 as their "undefined" value.
  418.         for(my $i = 2; $i < scalar @$data; $i++) {
  419.             $self_array->[$i] = (defined $data->[$i]) ? $data->[$i] : 0;
  420.         }
  421.  
  422.         # Setup the hash to mirror the array contents.
  423.         my $i = 2;
  424.         foreach my $k (qw( originator_mudname originator_username target_mudname target_username )) {
  425.             $self->{$k} = $self_array->[$i++];
  426.         }
  427.  
  428.     } elsif (ref $data and ref $data eq "HASH" ) {
  429.         # We passed in a hash, either by hand or from an object.
  430.         # We SHOULD be using a subclass, as the base class can only verify fields known to all packet types.
  431.         my $i = 2;
  432.         foreach my $k (qw( originator_mudname originator_username target_mudname target_username )) {
  433.             $self->{$k} = (exists $data->{$k} ? $data->{$k} : 0);
  434.             $self_array->[$i++] = (exists $data->{$k}) ? $data->{$k} : 0;
  435.         }
  436.         foreach my $k (grep { ! /^(type|ttl|originator_mudname|originator_username|target_mudname|target_username)$/ } (keys %$data)) {
  437.             $self->{$k} = $data->{$k};
  438.             $self_array->[$i++] = $data->{$k};
  439.         }
  440.     } elsif (defined $data) {
  441.         # We're asking for a specific type of packet.
  442.         if( $data eq "error" ) {
  443.             return I3::Packet::error->new( @args );
  444.         }
  445.         return undef;
  446.     } else {
  447.         # Nothing passed in at all?  ERROR!
  448.         return I3::Packet::error->new();
  449.     }
  450.  
  451.     bless $self, $class;
  452.     return $self;
  453. }
  454.  
  455. sub as_array {
  456.     my $self = shift;
  457.  
  458.     return $self->{as_array};
  459. }
  460.  
  461. sub as_string {
  462.     my $self = shift;
  463.  
  464.     my $lpc = new Serialize::LPC;
  465.     my $mudmode = new Serialize::MudMode;
  466.     my $stuff =  $lpc->encode($self->as_array);
  467.     my $packet = $mudmode->encode($stuff);
  468.     return $packet;
  469. }
  470.  
  471. sub type {
  472.     my $self = shift;
  473.  
  474.     return $self->{type};
  475. }
  476.  
  477. sub ttl {
  478.     my $self = shift;
  479.  
  480.     return $self->{ttl};
  481. }
  482.  
  483. sub originator_mudname {
  484.     my $self = shift;
  485.     my $value = shift;
  486.  
  487.     if(defined $value) {
  488.         $self->{originator_mudname} = $value;
  489.         $self->{as_array}->[2] = $value;
  490.     }
  491.     return $self->{originator_mudname};
  492. }
  493.  
  494. sub originator_username {
  495.     my $self = shift;
  496.     my $value = shift;
  497.  
  498.     if(defined $value) {
  499.         $self->{originator_username} = $value;
  500.         $self->{as_array}->[3] = $value;
  501.     }
  502.     return $self->{originator_username};
  503. }
  504.  
  505. sub target_mudname {
  506.     my $self = shift;
  507.     my $value = shift;
  508.  
  509.     if(defined $value) {
  510.         $self->{target_mudname} = $value;
  511.         $self->{as_array}->[4] = $value;
  512.     }
  513.     return $self->{target_mudname};
  514. }
  515.  
  516. sub target_username {
  517.     my $self = shift;
  518.     my $value = shift;
  519.  
  520.     if(defined $value) {
  521.         $self->{target_username} = $value;
  522.         $self->{as_array}->[5] = $value;
  523.     }
  524.     return $self->{target_username};
  525. }
  526.  
  527. package I3::Packet::error;
  528.  
  529. use strict;
  530.  
  531. our @ISA = qw(I3::Packet);
  532.  
  533. #use overload (
  534. #    '""'    => \&as_string,
  535. #    '@{}'   => \&as_array,
  536. #);
  537.  
  538. sub new {
  539.     my $class = shift;
  540.     my $data = shift;
  541.  
  542.     my $self_array = [ "error", 5, 0, 0, 0, 0, 0, 0, 0 ];
  543.     my $self = {
  544.         type                => "error",
  545.         ttl                 => 5,
  546.         originator_mudname  => 0,
  547.         originator_username => 0,
  548.         target_mudname      => 0,
  549.         target_username     => 0,
  550.  
  551.         error_code          => 0,
  552.         error_message       => 0,
  553.         error_packet        => 0,
  554.     };
  555.     $self->{as_array} = $self_array;
  556.  
  557.     if( ref $data and ref $data eq "ARRAY") {
  558.         # We passed in an array, probably decoded from a mudmode packet.
  559.         if( scalar @$data != 9 or $data->[0] != "error" ) {
  560.             warn "Invalid initialization data for __PACKAGE__";
  561.             return undef;
  562.         }
  563.  
  564.         # Valid I3 packets have (int)0 as their "undefined" value.
  565.         for(my $i = 2; $i < scalar @$data; $i++) {
  566.             $self_array->[$i] = (defined $data->[$i]) ? $data->[$i] : 0;
  567.         }
  568.  
  569.         # Setup the hash to mirror the array contents.
  570.         my $i = 2;
  571.         foreach my $k (qw( originator_mudname originator_username target_mudname target_username error_code error_message error_packet )) {
  572.             $self->{$k} = $self_array->[$i++];
  573.         }
  574.  
  575.     } elsif (ref $data and ref $data eq "HASH" ) {
  576.         # We passed in a hash, either by hand or from an object.
  577.         my $i = 2;
  578.         foreach my $k (qw( originator_mudname originator_username target_mudname target_username error_code error_message error_packet )) {
  579.             $self->{$k} = (exists $data->{$k} ? $data->{$k} : 0);
  580.             $self_array->[$i++] = (exists $data->{$k}) ? $data->{$k} : 0;
  581.         }
  582.     } else {
  583.         # We may just be setting up an empty packet.
  584.     }
  585.  
  586.     bless $self, $class;
  587.     return $self;
  588. }
  589.  
  590. sub error_code {
  591.     my $self = shift;
  592.     my $value = shift;
  593.  
  594.     if(defined $value) {
  595.         $self->{error_code} = $value;
  596.         $self->{as_array}->[6] = $value;
  597.     }
  598.     return $self->{error_code};
  599. }
  600.  
  601. sub error_message {
  602.     my $self = shift;
  603.     my $value = shift;
  604.  
  605.     if(defined $value) {
  606.         $self->{error_message} = $value;
  607.         $self->{as_array}->[7] = $value;
  608.     }
  609.     return $self->{error_message};
  610. }
  611.  
  612. sub error_packet {
  613.     my $self = shift;
  614.     my $value = shift;
  615.  
  616.     if(defined $value) {
  617.         $self->{error_packet} = $value;
  618.         $self->{as_array}->[8] = $value;
  619.     }
  620.     return $self->{error_packet};
  621. }
  622.  
  623.  
  624. package I3;
  625.  
  626. sub new {
  627.     my $class = shift;
  628.     bless @_ ? @_ > 1 ? {@_} : {%{$_[0]}} : {}, $class;
  629. }
  630.  
  631. # Accessor methods
  632.  
  633. sub router {
  634.     my $self = shift;
  635.     my $value = shift;
  636.  
  637.     $self->{router} = $value if defined $value;
  638.     return $self->{router};
  639. }
  640.  
  641. sub password {
  642.     my $self = shift;
  643.     my $value = shift;
  644.  
  645.     $self->{password} = $value if defined $value;
  646.     return $self->{password};
  647. }
  648.  
  649. sub mudlistid {
  650.     my $self = shift;
  651.     my $value = shift;
  652.  
  653.     $self->{mudlistid} = $value if defined $value;
  654.     return $self->{mudlistid};
  655. }
  656.  
  657. sub chanlistid {
  658.     my $self = shift;
  659.     my $value = shift;
  660.  
  661.     $self->{chanlistid} = $value if defined $value;
  662.     return $self->{chanlistid};
  663. }
  664.  
  665. sub mudinfo {
  666.     my $self = shift;
  667.     my $value = shift;
  668.  
  669.     if (defined $value and ref $value and ref $value eq 'HASH') {
  670.         $self->{mudinfo} = $value;
  671.         return $self->{mudinfo};
  672.     }
  673.     if (exists $self->{mudinfo}{$value}) {
  674.         return $self->{mudinfo}{$value};
  675.     }
  676.  
  677.     return undef;
  678. }
  679.  
  680. sub mudname {
  681.     my $self = shift;
  682.     my $value = shift;
  683.  
  684.     $self->{mudname} = $value if defined $value;
  685.     return $self->{mudname};
  686. }
  687.  
  688. # Packet methods
  689.  
  690. sub send_startup {
  691.     my $self = shift;
  692.  
  693.     my $originator_mudname = $self->mudname;
  694.     my $target_mudname = $self->router;
  695. }
  696.  
  697. package main;
  698.  
  699. use strict;
  700. use Data::Dumper;
  701. use Data::Hexdumper qw(hexdump);
  702.  
  703. sub DumpString {
  704. my $s = shift || "";
  705. my @a = unpack('C*',$s);
  706. my $o = 0;
  707. my $i = 0;
  708. print "\tb0 b1 b2 b3 b4 b5 b6 b7\n";
  709. print "\t-- -- -- -- -- -- -- --\n";
  710. while (@a) {
  711. my @b = splice @a,0,8;
  712. my @x = map sprintf("%02x",$_), @b;
  713. my $c = substr($s,$o,8);
  714. $c =~ s/[[:^print:]]/ /g;
  715. printf "w%02d",$i;
  716. print " "x5,join(' ',@x),"\n";
  717. $o += 8;
  718. $i++;
  719. }
  720. }
  721.  
  722.  
  723. my %foo = ( 12 => "hello", "bob" => 32112, "a" => [ 1, 2, 3 ], );
  724. my @bar = ( 12, 444, 90, "heil", "ball", \%foo, 34343 );
  725. my $test = <<EOM
  726. ({ "channel-m", 5, "Rock the Halo", "thegrauniad", 0, 0, "inews", "TheGrauniad", "Life and style: Ten reasons to love winter [Stuart Heritage] (http://www.theguardian.com/lifeandstyle/2013/oct/25/10-reasons-to-love-winter)" })
  727. EOM
  728. ;
  729.  
  730. my $lpc = new Serialize::LPC;
  731. my $stuff =  $lpc->encode(\@bar);
  732.  
  733. print "original stuff: " . Dumper(\@bar) . "\n";
  734. print "encoded stuff: $stuff\n";
  735. print "decoded stuff: " . Dumper($lpc->decode($stuff)) . "\n";
  736.  
  737. print "original test: $test\n";
  738. my $thing = $lpc->decode($test);
  739. print "decoded test: " . Dumper($thing) . "\n";
  740. print "encoded test: " . $lpc->encode($thing) . "\n";
  741.  
  742. my $mudmode = new Serialize::MudMode;
  743. my $packet = $mudmode->encode($thing);
  744. print "packetized test:\n" . hexdump($packet) . "\n";
  745.  
  746. my $err = new I3::Packet;
  747. print Dumper($err);
  748.  
  749. $err->error_code(37);
  750. print $err->error_code . "\n";
  751. print $err->[6] . "\n";
  752. print Dumper($err);
  753.  
  754. # Intermud
  755. #
  756. # First, open a socket and connect to a router.
  757. # Send a startup-req-3 packet
  758. #
  759. # WHen a reply is received, mudmode says....
  760. #
  761. # read 4 bytes, unpack that as the packet length.
  762. # read LEN more bytes for the packet.
  763. #
  764. # if < LEN bytes are there, fragmented... so save what you have
  765. # and read LEN - whatyougot next time.
  766. #
  767. # decode that into a data structure, and use the handler appropriate
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement