From: Shiar Date: Sat, 19 Jan 2008 05:29:47 +0000 (+0100) Subject: Merge commit 'raz/master' X-Git-Url: http://git.shiar.net/perl/schtarr.git/commitdiff_plain/65b175df2569427fb67295c5e131c94668fecbf6 Merge commit 'raz/master' Conflicts: screp --- 65b175df2569427fb67295c5e131c94668fecbf6 diff --cc screp index a97ea97,8fb41f5..dc24f05 --- a/screp +++ b/screp @@@ -2,18 -2,20 +2,23 @@@ use strict; use warnings; use Data::Dumper; - +use Data::StarCraft::Replay; + our $VERSION = '1.01'; + my $SHOWWARN = 0; +my $ACTGIF = undef; my $APMSVG = undef; + my $DBNAME = undef; + my $DBGAME = undef; - use Getopt::Long; + use Getopt::Long qw(:config bundling auto_version auto_help); GetOptions( "verbose|v!" => \$SHOWWARN, "apm|a=s" => \$APMSVG, + "act" => \$ACTGIF, + "dbname|D=s" => \$DBNAME, + "dbid|d=s" => \$DBGAME, ); use constant { APM_FIRSTFRAME => 80 / .042 }; @@@ -161,53 -568,96 +169,143 @@@ for my $player (sort keys %stats) ) if 0; } +if ($ACTGIF) { + open my $imgfile, '>', "test.gif" or die; + binmode $imgfile; + select $imgfile; + + use GD; + my $ani = GD::Image->new($head->{width}, $head->{height}); + my $bg = $ani->colorAllocate(0, 0, 0); + my @plot = ( + $ani->colorAllocate(255, 0, 0), + $ani->colorAllocate(255, 255, 0), + $ani->colorAllocate(0, 255, 0), + $ani->colorAllocate(0, 255, 255), + $ani->colorAllocate(0, 0, 255), + $ani->colorAllocate(255, 0, 255), + ); + + print $ani->gifanimbegin; +# print $ani->gifanimadd; + { + my $frame = GD::Image->new($ani->getBounds); + print $frame->gifanimadd; + my $length = 30 / .042; + my $last = 0; + for (@$map) { + my ($time, $player, $cmd, @data) = @$_; +#$time < $length * 10 or last; + while ($time > $last + $length) { + $last += $length; + print $frame->gifanimadd(0, 0, 0, 32); +# $frame = GD::Image->new($ani->getBounds); + } + if ($cmd eq "build") { + $frame->setPixel($data[1]>>5, $data[2]>>5, $plot[$player]); + } + elsif ($cmd eq "move" or $cmd eq "attack") { + $frame->setPixel($data[0]>>5, $data[1]>>5, $plot[$player]); +# if $data[2] == 0xFFFF_FFFF; + } + } +# add_frame_data($frame); + print $frame->gifanimadd; + } + print $ani->gifanimend; + select STDOUT; +} + + use Games::StarCraft::DB; + my $Db = Games::StarCraft::DB->connect({RaiseError => 1}) + or die "No database: $DBI::errstr\n"; + sub findaccount ($) { + my ($name) = @_; + my $query = $Db->query(q{ + SELECT DISTINCT account FROM play + WHERE name = ? AND account IS NOT NULL + }, $name); + return $query->rows == 1 ? $query->list : undef; + } + + if ($DBGAME) {{ + print "\n"; + my $game = $Db->query("SELECT * FROM game WHERE id=?", $DBGAME)->hash; + if (not $game) { + printf "Database game # %d not found\n", $DBGAME; + last; + } + if ($game->{map} ne $head->{map}) { + printf "Replay map (%s) does not match database map (%s)\n", + $head->{map}, $game->{map}; + last; + } + + $Db->begin; + $Db->insert("game", { + frames => $head->{frames}, + # map => $head->{map}, + # start => time2str('%Y-%m-%d %X', $head->{time}), + # endreplay => time2str('%Y-%m-%d %X', $repstats[9]), # mtime + # durationguess => \"endreplay - start", + }); + $Db->update("play", { + name => $_->{name}, #TODO: --force + race => $_->{race}, # --force + apm => $_->{gameactions} / ($_->{last} - APM_FIRSTFRAME) * 60 / .042, + team => $_->{team}, + color => $_->{color}, + }, { + game => $DBGAME, + slot => $_->{slot}, + }) for values %stats; + $Db->commit; + }} + + if ($DBNAME) { + print "\n"; + my @repstats = stat $DBNAME or die "no rep: $!\n"; + my ($name) = $DBNAME =~ m{.*/([^.]+)}; + + my %placetxt = ( + bn => "bnet", + gr => "groningen", + md => "mdhq", + ); + my ($placeid) = $name =~ /.*([a-z]{2})/; + my $place = defined $placetxt{$placeid} ? $placetxt{$placeid} : undef; + + my $winslot; + if (@ARGV == 1 and $ARGV[0] =~ /^\d$/) { + $winslot = $ARGV[0]; + } + + $Db->begin; + $Db->insert("game", { + name => $name, + frames => $head->{frames}, + map => $head->{map}, + start => time2str('%Y-%m-%d %X', $head->{time}), + endreplay => time2str('%Y-%m-%d %X', $repstats[9]), # mtime + # durationguess => \"endreplay - start", + place => $place, + }); + my $gameid = $Db->last_insert_id((undef)x4, {sequence => "game_id_seq"}); + $Db->update("game", {durationguess => \"endreplay - start"}, {id => $gameid}); + $Db->insert("play", { + game => $gameid, + slot => $_->{slot}, + name => $_->{name}, + race => $_->{race}, + apm => $_->{gameactions} / ($_->{last} - APM_FIRSTFRAME) * 60 / .042, + team => $_->{team}, + color => $_->{color}, + account => findaccount($_->{name}), + result => defined $winslot ? $_->{slot} == $winslot ? 1 : -1 : 0, + }) for values %stats; + $Db->commit; + } + if ($APMSVG) { my @seq; # player => time (s) => actions $seq[$_->[1]][$_->[0] * .042]++ for @$map; @@@ -264,3 -714,27 +362,28 @@@ print $apmfile $svg; } + __END__ + + =head1 NAME + + screp - StarCraft replay parser + + =head1 SYNOPSIS + + screp [options] < [replay data] + + Options: + --verbose + --apm ++ --act + --dbname + --dbid + + =head1 OPTIONS + + =head1 AUTHOR + + Mischa POSLAWSKY + + =head1 STUFF +