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 };
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"
}
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,
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
+