Merge commit 'raz/master'
authorShiar <shiar@shiar.org>
Sat, 19 Jan 2008 05:29:47 +0000 (06:29 +0100)
committerShiar <shiar@shiar.org>
Sat, 19 Jan 2008 05:29:47 +0000 (06:29 +0100)
Conflicts:
screp

1  2 
screp

diff --cc screp
index a97ea97234fceb7690a7ce9efe960550edc30e2b,8fb41f5b4e5c03749660151d8857665479c58cde..dc24f05259d103026a968787d00f6ff0c21dcedc
--- 1/screp
--- 2/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;
        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 <perl@shiar.org>
+ =head1 STUFF