X-Git-Url: http://git.shiar.net/perl/schtarr.git/blobdiff_plain/d6d562d921c72ddc11597a2c45fdc5182d5907cf..65b175df2569427fb67295c5e131c94668fecbf6:/screp diff --git a/screp b/screp index a97ea97..dc24f05 100755 --- a/screp +++ b/screp @@ -2,18 +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 }; @@ -59,7 +64,7 @@ for (0 .. 11) { my $number = shift @playdata; defined $player[$number] and warn "Player #$number redefined"; my ($data) = unpackhash("VcccZ25", shift @playdata, qw( - slot type race unknown name + slot type race team name )); defined $race[$_] ? ($data->{race} = $race[$_]) : warn "Unknown race #$_ for player $number" @@ -120,11 +125,14 @@ for (@$map) { } for my $player (sort keys %stats) { + $stats{$player}{$_} = $player[$slot[$player]]{$_} + for keys %{ $player[$slot[$player]] }; my $row = $stats{$player}; $row->{last} ||= $map->[-1][0]; # printf("%-16s%6d actions (%3d micro,%4d macro);%4d APM\n", my $name = showplayer($player); - printf("%-16s%6d actions in%7d frames (%s) = %d APM\n", + printf("%d %-16s%6d actions in%7d frames (%s) = %d APM\n", + $row->{slot}, $name, $row->{actions}, $row->{last}, showtime($row->{last}), # $row->{micro} / $row->{last} * 60 / .042 * 1.05, @@ -208,6 +216,96 @@ if ($ACTGIF) { 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 +362,28 @@ if ($APMSVG) { 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 +