From 80e893e4edd9fe3e2f3c7eae0e49d193f19f2a16 Mon Sep 17 00:00:00 2001 From: Shiar Date: Mon, 12 Nov 2007 05:24:26 +0100 Subject: [PATCH] also read replay header in screp Parses the header leading commands (no problem since it should always have a constant size), so input (extractor) needs to be modified. Recognizes most data, but players array can benefit from some additional parsing and usage in commands output. --- screp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/screp b/screp index 1922415..10a2554 100755 --- a/screp +++ b/screp @@ -417,6 +417,53 @@ sub showtime { return sprintf "%d:%04.1f", $minutes, $time - $minutes * 60; } +sub unpackhash { + my ($template, $expr, @elements) = @_; + my @data = unpack $template, $expr; + my %map; + $map{$_} = shift @data for @elements; + return (\%map, @data); +} + +local $_ = Data::StarCraft::Replay::_read(undef, \*STDIN, 633) + and my ($head, @headdata) = unpackhash("CVa3Va12Z28v2Z16Z24Ca26a38a*", $_, qw( + engine frames mag1 time mag2 name width height + unknown1 creator unknown2 map unknown3 + )) + or die "Couldn't read replay header\n"; + +$_ eq "\0\0\110" or warn sprintf( + "Mismatch in first header constant: %s\n", + join ",", map ord, split //, $_ +) for $head->{mag1}; +$_ eq "\10"x8 . "\0"x4 or warn sprintf( + "Mismatch in second header constant: %s\n", + join ",", map ord, split //, $_ +) for $head->{mag2}; +delete $head->{$_} for qw(mag1 mag2 unknown1 unknown2); + +my @playdata = unpack "a36"x12 . "V8C8", $headdata[0] + or die "Couldn't parse player data in replay header\n"; + +my @player; +push @player, unpackhash("x11Z25", shift @playdata, qw/name/) for 0 .. 11; +$player[$_]->{color} = shift @playdata for 0 .. 7; +$player[$_]->{index} = shift @playdata for 0 .. 7; + +printf "%s: %s\n", $_, $head->{$_} for qw(name creator); +use Date::Format; +printf "created: %s\n", time2str('%Y-%m-%d %X', $_) for $head->{time}; +printf "map: %s (%dx%d)\n", map $head->{$_}, qw(map width height); +printf "frames: %s (%s)\n", $_, showtime($_) for $head->{frames}; +print "\n"; + +if ($SHOWWARN) { + print Dumper $head; + print Dumper \@player; + #printf ":%s\n", join ",", map sprintf('%X', ord $_), split // for @headdata; + print "\n"; +} + my $map = Data::StarCraft::Replay->new->open(\*STDIN); if ($SHOWWARN) { -- 2.30.0