8 |
my $outdir = $ARGV[1]; |
my $outdir = $ARGV[1]; |
9 |
mkdir $outdir or die "Failed to create output directory $outdir: $!"; |
mkdir $outdir or die "Failed to create output directory $outdir: $!"; |
10 |
my $dir = $0; |
my $dir = $0; |
11 |
$dir =~ s!(^|/)[^/]+$!$1!; |
$dir =~ s#(^|/)[^/]+$#$1#; |
12 |
(system "cp ${dir}t2matchlog.css $outdir/") == 0 or die "Failed to copy stylesheet: $!"; |
(system "cp ${dir}t2matchlog.css $outdir/") == 0 or die "Failed to copy stylesheet: $!"; |
13 |
|
|
14 |
$/ = "\r\n"; |
$/ = "\r\n"; |
70 |
$icon{'solar'} = load_image("${dir}icons/com_icon_solar_gen.png"); |
$icon{'solar'} = load_image("${dir}icons/com_icon_solar_gen.png"); |
71 |
|
|
72 |
my %colour = ('S' => 0xffff00, 'A' => 0xff8000, 'KK' => 0x00ff00, 'K' => 0xff0000, |
my %colour = ('S' => 0xffff00, 'A' => 0xff8000, 'KK' => 0x00ff00, 'K' => 0xff0000, |
73 |
|
'KS' => 0xff0000, |
74 |
'L' => 0xff8000, 'F+' => 0x00ffff, 'F-' => 0xff00ff, 'P' => 0xff8000, |
'L' => 0xff8000, 'F+' => 0x00ffff, 'F-' => 0xff00ff, 'P' => 0xff8000, |
75 |
'V' => 0xffff00, 'W' => 0xff0000, 'G' => 0x0080ff, 'J' => 0x00ff80, |
'V' => 0xffff00, 'W' => 0xff0000, 'G' => 0x0080ff, 'J' => 0x00ff80, |
76 |
'GG' => 0x0080ff, 'JJ' => 0x00ff80); |
'GG' => 0x0080ff, 'JJ' => 0x00ff80, |
77 |
|
'C' => 0x00ff00, 'R' => 0x00ff00); |
78 |
my $colour_me = 0xffffff; |
my $colour_me = 0xffffff; |
79 |
my %desc = ('S' => 'spawned on team $team_name[$p1]', |
my %desc = ('S' => 'spawned on team $team_name[$p1]', |
80 |
'A' => '$p1 armour', |
'A' => '$p1 armour', |
81 |
'KK' => 'killed $enemy using $DamageTypeText[$p2]', |
'KK' => 'killed $enemy using $DamageTypeText[$p2]', |
82 |
'K' => 'killed by $DamageTypeText[$p2] $enemy', |
'K' => 'killed by $DamageTypeText[$p2] $enemy', |
83 |
|
'KS' => 'killed himself using $DamageTypeText[$p2]', |
84 |
'L' => 'left the game', |
'L' => 'left the game', |
85 |
'F+' => 'took the $team_name[$p1] flag', |
'F+' => '${melink}took the $team_name[$p1] flag', |
86 |
'F-' => 'dropped the $team_name[$p1] flag', |
'F-' => '${melink}dropped the $team_name[$p1] flag', |
87 |
'P' => '$p1', |
'P' => '$p1', |
88 |
'V' => 'vehicle created', |
'V' => 'vehicle created', |
89 |
'W' => 'vehicle destroyed', |
'W' => 'vehicle destroyed', |
90 |
'G' => 'entered " . vehicle_link($p1) . " as ${seat{$p2}}', |
'G' => 'entered " . vehicle_link($p1) . " as ${seat{$p2}}', |
91 |
'J' => 'ejected from vehicle', |
'J' => 'ejected from vehicle', |
92 |
'GG' => '<a href=\'" . safe_name($p1) . ".html#t$time\'>$p1</a> entered as ${seat{$p2}}', |
'GG' => '<a href=\'" . safe_name($p1) . ".html#t$time\'>$p1</a> entered as ${seat{$p2}}', |
93 |
'JJ' => '<a href=\'" . safe_name($p1) . ".html#t$time\'>$p1</a> ejected'); |
'JJ' => '<a href=\'" . safe_name($p1) . ".html#t$time\'>$p1</a> ejected', |
94 |
|
'C' => '<strong>${melink}captured the $team_name[$p1] flag!</strong>', |
95 |
|
'R' => '${melink}returned the $team_name[$p1] flag',); |
96 |
my @teamcol = (0xffffff, 0x0000ff, 0xff00ff); |
my @teamcol = (0xffffff, 0x0000ff, 0xff00ff); |
97 |
my %seat = ('' => 'a passenger', 'p' => 'pilot', 'w' => 'gunner'); |
my %seat = ('' => 'a passenger', 'p' => 'pilot', 'w' => 'gunner'); |
98 |
my %veh_name = ('BomberFlyer' => 'Bomber', |
my %veh_name = ('BomberFlyer' => 'Bomber', |
113 |
my %score = (); |
my %score = (); |
114 |
my %kills = (); |
my %kills = (); |
115 |
my %deaths = (); |
my %deaths = (); |
116 |
|
my %grabs = (); |
117 |
|
my %caps = (); |
118 |
|
my %returns = (); |
119 |
my %player = (); |
my %player = (); |
120 |
my %vehicle = (); |
my %vehicle = (); |
121 |
my %team = (); |
my %team = (); |
122 |
my $end_time; |
my $end_time; |
123 |
my (@final_score, @team_name); |
my (@final_score, @team_name); |
124 |
|
my %flag = (); |
125 |
|
my @flag_coords = (); |
126 |
|
|
127 |
read_data(); |
read_data(); |
128 |
print ".\n"; |
print ".\n"; |
142 |
write_vehicle_report($name, $team); |
write_vehicle_report($name, $team); |
143 |
print ".\n"; |
print ".\n"; |
144 |
} |
} |
145 |
|
my $team; |
146 |
|
foreach $team (keys %flag) { |
147 |
|
print "$team_name[$team] flag"; |
148 |
|
write_flag_report($team); |
149 |
|
print ".\n"; |
150 |
|
} |
151 |
write_summary_report(); |
write_summary_report(); |
152 |
|
|
153 |
exit; |
exit; |
196 |
my %name = (); |
my %name = (); |
197 |
my @flag_carrier; |
my @flag_carrier; |
198 |
my %player_veh; |
my %player_veh; |
199 |
|
my %player_flag; |
200 |
|
|
201 |
while (<LOG>) { |
while (<LOG>) { |
202 |
chomp; |
chomp; |
217 |
|
|
218 |
} elsif ($cmd eq 'K') { # player killed |
} elsif ($cmd eq 'K') { # player killed |
219 |
my ($victim, $killer, $weapon) = split / /, $params; |
my ($victim, $killer, $weapon) = split / /, $params; |
220 |
|
next unless exists $name{$victim}; |
221 |
$deaths{$name{$victim}}++; |
$deaths{$name{$victim}}++; |
222 |
$kills{$name{$killer}}++ if exists $name{$killer}; |
$kills{$name{$killer}}++ if exists $name{$killer}; |
223 |
push @events, [$time, 'K', $name{$victim}, $name{$killer}, $weapon]; |
push @events, [$time, 'K', $name{$victim}, $name{$killer}, $weapon]; |
224 |
push @events, [$time, 'KK', $name{$killer}, $name{$victim}, $weapon] |
push @events, [$time, 'KK', $name{$killer}, $name{$victim}, $weapon] |
225 |
if exists $name{$killer}; |
if exists $name{$killer} and $killer != $victim; |
226 |
if (exists $name{$killer} and $player_veh{$name{$killer}}) { |
if (exists $name{$killer} and $player_veh{$name{$killer}}) { |
227 |
push @events, [$time, 'KK', $name{$player_veh{$name{$killer}}}, |
push @events, [$time, 'KK', $name{$player_veh{$name{$killer}}}, |
228 |
$name{$victim}, $weapon]; |
$name{$victim}, $weapon]; |
229 |
} |
} |
230 |
# if (defined $player_veh{$name}) TODO |
# if (defined $player_veh{$name}) TODO |
231 |
delete $name{$victim}; |
# delete $name{$victim}; |
232 |
|
|
233 |
} elsif ($cmd eq 'L') { # player left |
} elsif ($cmd eq 'L') { # player left |
234 |
my ($id, $score) = split / /, $params; |
my ($id, $score) = split / /, $params; |
235 |
|
next unless exists $name{$id}; |
236 |
push @events, [$time, 'L', $name{$id}]; |
push @events, [$time, 'L', $name{$id}]; |
237 |
$score{$name{$id}} += $score; |
$score{$name{$id}} += $score; |
238 |
delete $name{$id}; |
delete $name{$id}; |
271 |
} elsif ($cmd eq 'F') { # flag position |
} elsif ($cmd eq 'F') { # flag position |
272 |
my ($team, @data) = split / /, $params; |
my ($team, @data) = split / /, $params; |
273 |
my $carrier; |
my $carrier; |
274 |
|
$flag{$team} = 1; |
275 |
|
$team{"$team flag"} = $team; |
276 |
$flag_carrier[$team] = 0 unless defined $flag_carrier[$team]; |
$flag_carrier[$team] = 0 unless defined $flag_carrier[$team]; |
277 |
if (@data == 3) { |
if (@data == 3) { |
278 |
my ($x, $y, $z) = @data; |
my ($x, $y, $z) = @data; |
279 |
$x -= $x0; $y = $height - $y + $y0; |
$x -= $x0; $y = $height - $y + $y0; |
280 |
|
${$coords[$time]}{"$team flag"} = "$x $y $z"; |
281 |
$carrier = 0; |
$carrier = 0; |
282 |
} else { |
} else { |
283 |
$carrier = $name{$data[0]}; |
$carrier = $name{$data[0]}; |
285 |
if ($carrier ne $flag_carrier[$team]) { |
if ($carrier ne $flag_carrier[$team]) { |
286 |
if ($flag_carrier[$team]) { |
if ($flag_carrier[$team]) { |
287 |
push @events, [$time, 'F-', $flag_carrier[$team], $team]; |
push @events, [$time, 'F-', $flag_carrier[$team], $team]; |
288 |
|
delete $player_flag{$flag_carrier[$team]}; |
289 |
} |
} |
290 |
if ($carrier) { |
if ($carrier) { |
291 |
push @events, [$time, 'F+', $carrier, $team]; |
push @events, [$time, 'F+', $carrier, $team]; |
292 |
|
$grabs{$carrier}++; |
293 |
|
$player_flag{$carrier} = $team; |
294 |
} |
} |
295 |
$flag_carrier[$team] = $carrier; |
$flag_carrier[$team] = $carrier; |
296 |
} |
} |
297 |
|
|
298 |
|
} elsif ($cmd eq 'C') { # flag captured (CTF) |
299 |
|
my ($team, $id) = split / /, $params; |
300 |
|
push @events, [$time, 'C', $name{$id}, $team]; |
301 |
|
$flag_carrier[$team] = 0; |
302 |
|
$caps{$name{$id}}++; |
303 |
|
|
304 |
|
} elsif ($cmd eq 'R') { # flag returned (CTF) |
305 |
|
my ($team, $id) = split / /, $params; |
306 |
|
push @events, [$time, 'R', exists $name{$id} ? $name{$id} : '', $team]; |
307 |
|
$returns{$name{$id}}++; |
308 |
|
|
309 |
} else { # player / vehicle position |
} else { # player / vehicle position |
310 |
my $id = $cmd; |
my $id = $cmd; |
311 |
next unless exists $name{$id}; |
next unless exists $name{$id}; |
328 |
} |
} |
329 |
$player_veh{$name} = $vehicle; |
$player_veh{$name} = $vehicle; |
330 |
} |
} |
331 |
|
if (exists $player_flag{$name}) { |
332 |
|
${$coords[$time]}{$player_flag{$name} . " flag"} = "$x $y $z"; |
333 |
|
} |
334 |
} |
} |
335 |
} |
} |
336 |
$end_time = $time + 1; |
$end_time = $time + 1; |
382 |
my $time0 = shift; |
my $time0 = shift; |
383 |
my $time1 = shift; |
my $time1 = shift; |
384 |
|
|
|
my $prev_time = -1; |
|
|
|
|
|
my $html = "<table>\n"; |
|
|
|
|
385 |
my $im = create_image(); |
my $im = create_image(); |
386 |
plot_route($im, $player, $time0, $time1); |
plot_route($im, $player, $time0, $time1); |
387 |
|
|
388 |
my @evs = grep {$$_[2] eq $player and $time0 <= $$_[0] and $$_[0] <= $time1} @events; |
my @evs = grep {$$_[2] eq $player and $time0 <= $$_[0] and $$_[0] <= $time1} @events; |
389 |
|
my $html = write_events($player, \@evs, $im); |
390 |
|
|
391 |
|
save_image($im, $imname); |
392 |
|
|
393 |
|
return $html; |
394 |
|
} |
395 |
|
|
396 |
|
#################################################################################################### |
397 |
|
|
398 |
|
sub write_events { |
399 |
|
my $player = shift; |
400 |
|
my $evs = shift; |
401 |
|
my $im = shift; |
402 |
|
|
403 |
|
my $prev_time = -1; |
404 |
|
my $html = "<table>\n"; |
405 |
|
|
406 |
my $event; |
my $event; |
407 |
foreach $event (@evs) { |
foreach $event (@$evs) { |
408 |
my ($time, $ev, $me, $p1, $p2) = @$event; |
my ($time, $ev, $me, $p1, $p2) = @$event; |
409 |
|
|
410 |
my $nicetime = nice_time($time); |
my $nicetime = nice_time($time); |
414 |
$html .= "<tr id='t$time'><td class='time'>$nicetime</td>"; |
$html .= "<tr id='t$time'><td class='time'>$nicetime</td>"; |
415 |
} |
} |
416 |
|
|
417 |
|
my $melink = ''; |
418 |
my $enemy = ''; |
my $enemy = ''; |
419 |
if (($ev eq 'K' or $ev eq 'KK') and defined $p1) { |
$ev = 'KS' if ($ev eq 'K' and defined $p1 and $p1 eq $player); |
420 |
|
if (defined $me and $me ne $player) { |
421 |
|
my $sname_me = safe_name($me); |
422 |
|
$melink = "<a href='$sname_me.html#t$time'>$me</a> "; |
423 |
|
} |
424 |
|
if (defined $p1) { |
425 |
my $sname_en = safe_name($p1); |
my $sname_en = safe_name($p1); |
426 |
$enemy = "<a href='$sname_en.html#t$time'>$p1</a>"; |
$enemy = "<a href='$sname_en.html#t$time'>$p1</a>"; |
427 |
} |
} |
440 |
} |
} |
441 |
|
|
442 |
$html .= "</table>\n"; |
$html .= "</table>\n"; |
|
save_image($im, $imname); |
|
443 |
|
|
444 |
return $html; |
return $html; |
445 |
} |
} |
541 |
|
|
542 |
#################################################################################################### |
#################################################################################################### |
543 |
|
|
544 |
|
sub write_flag_report { |
545 |
|
my $team = shift; |
546 |
|
|
547 |
|
my $html = create_html($team_name[$team] . ' flag'); |
548 |
|
|
549 |
|
my @grab; |
550 |
|
my @return; |
551 |
|
|
552 |
|
my @fevs = grep {($$_[1] eq 'F+' or $$_[1] eq 'F-' or $$_[1] eq 'C' or $$_[1] eq 'R') and |
553 |
|
$$_[3] == $team} @events; |
554 |
|
my $event; |
555 |
|
my $at_stand = 1; |
556 |
|
foreach $event (@fevs) { |
557 |
|
if ($at_stand and $$event[1] eq 'F+') { |
558 |
|
push @grab, $$event[0]; |
559 |
|
$at_stand = 0; |
560 |
|
} elsif (!$at_stand and ($$event[1] eq 'C' or $$event[1] eq 'R')) { |
561 |
|
push @return, $$event[0]; |
562 |
|
$at_stand = 1; |
563 |
|
} |
564 |
|
} |
565 |
|
|
566 |
|
for (my $grab = 0; $grab != @grab; $grab++) { |
567 |
|
my $nicetime = nice_time($grab[$grab]); |
568 |
|
my $nicedtime = nice_time($return[$grab]); |
569 |
|
my $grab1 = $grab + 1; |
570 |
|
$html .= <<END; |
571 |
|
<div><h2 id="grab$grab1">Grab $grab1 ($nicetime - $nicedtime)</h2> |
572 |
|
<div><a href="${team}_flag_$grab1.png"><img src="s${team}_flag_$grab1.png" |
573 |
|
alt="" title="Map of ${team_name[$team]} flag grab $grab1"></a></div> |
574 |
|
END |
575 |
|
|
576 |
|
my $im = create_image(); |
577 |
|
plot_route($im, "$team flag", $grab[$grab], $return[$grab] - 1); |
578 |
|
|
579 |
|
my @fevs; |
580 |
|
my $carrier = ''; |
581 |
|
foreach $event (grep {$grab[$grab] <= $$_[0] and $$_[0] <= $return[$grab]} @events) { |
582 |
|
if ($$event[1] eq 'F+' and $$event[3] == $team) { |
583 |
|
$carrier = $$event[2]; |
584 |
|
} elsif (($$event[1] eq 'F-' or $$event[1] eq 'C' or $$event[1] eq 'R') |
585 |
|
and $$event[3] == $team) { |
586 |
|
$carrier = ''; |
587 |
|
} elsif ($$event[1] eq 'K' and $$event[2] eq $carrier) { |
588 |
|
; |
589 |
|
} else { |
590 |
|
next; |
591 |
|
} |
592 |
|
push @fevs, $event; |
593 |
|
} |
594 |
|
$html .= write_events("$team flag", \@fevs, $im); |
595 |
|
$html .= '</div>'; |
596 |
|
|
597 |
|
save_image($im, "${team}_flag_$grab1.png"); |
598 |
|
} |
599 |
|
|
600 |
|
save_html("${team}_flag.html", $html); |
601 |
|
} |
602 |
|
|
603 |
|
#################################################################################################### |
604 |
|
|
605 |
sub write_summary_report { |
sub write_summary_report { |
606 |
my $html = create_html("Match Summary"); |
my $html = create_html("Match Summary"); |
607 |
my $name; |
my $name; |
617 |
for ($i = 1; $i != @team_name; $i++) { |
for ($i = 1; $i != @team_name; $i++) { |
618 |
$html .= "<tr><td>${team_name[$i]}</td><td>${final_score[$i]}</td></tr>\n"; |
$html .= "<tr><td>${team_name[$i]}</td><td>${final_score[$i]}</td></tr>\n"; |
619 |
} |
} |
620 |
|
$html .= "</table>\n"; |
621 |
|
|
622 |
|
my $team; |
623 |
|
foreach $team (keys %flag) { |
624 |
|
$html .= "<p><a href=\"${team}_flag.html\">${team_name[$team]} flag</a></p>\n"; |
625 |
|
} |
626 |
|
|
627 |
$html .= <<END; |
$html .= <<END; |
628 |
</table> |
<h2>Players and Vehicles</h2> |
629 |
<table> |
<table> |
630 |
<tr><th>Player</th><th>Team</th><th>Score</th><th>Deaths</th><th>Kills</th></tr> |
<tr><th>Player</th><th>Team</th><th>Score</th><th>Deaths</th><th>Kills</th><th>Grabs</th><th>Caps</th><th>Returns</th></tr> |
631 |
END |
END |
632 |
|
|
633 |
|
sub lookup { |
634 |
|
my $hash = shift; |
635 |
|
my $name = shift; |
636 |
|
my $max = 0; grep { $max = $_ if $max < $_ } values %$hash; |
637 |
|
my $n = exists $$hash{$name} ? $$hash{$name} : 0; |
638 |
|
return $n == $max ? "<td><strong class=\"max\">$n</strong></td>" : "<td>$n</td>"; |
639 |
|
} |
640 |
|
|
641 |
foreach $name (sort keys %player) { |
foreach $name (sort keys %player) { |
642 |
my $sname = safe_name($name); |
my $sname = safe_name($name); |
643 |
my $score = exists $score{$name} ? $score{$name} : 0; |
$html .= "<tr><td><a href=\"$sname.html\">$name</a></td>" . |
644 |
my $deaths = exists $deaths{$name} ? $deaths{$name} : 0; |
"<td>$team_name[$team{$name}]</td>" . |
645 |
my $kills = exists $kills{$name} ? $kills{$name} : 0; |
lookup(\%score, $name) . |
646 |
$html .= <<END; |
lookup(\%deaths, $name) . |
647 |
<tr><td><a href="$sname.html">$name</a></td><td>$team_name[$team{$name}]</td><td>$score</td><td>$deaths</td><td>$kills</td></tr> |
lookup(\%kills, $name) . |
648 |
END |
lookup(\%grabs, $name) . |
649 |
|
lookup(\%caps, $name) . |
650 |
|
lookup(\%returns, $name) . |
651 |
|
"</tr>\n"; |
652 |
} |
} |
653 |
|
|
654 |
$html .= "</table>\n"; |
$html .= "</table>\n"; |
655 |
|
|
656 |
$html .= "<table><tr><th>Vehicles</th><th>Total used</th></tr>\n"; |
if (keys %vehicle) { |
657 |
foreach $vehicle (sort keys %vehicle) { |
$html .= "<table><tr><th>Vehicles</th><th>Total used</th></tr>\n"; |
658 |
my ($team, $name) = split / /, $vehicle, 2; |
foreach $vehicle (sort keys %vehicle) { |
659 |
my $sname = safe_name($name); |
my ($team, $name) = split / /, $vehicle, 2; |
660 |
$html .= <<END; |
my $sname = safe_name($name); |
661 |
|
$html .= <<END; |
662 |
<tr><td><a href="${team}_$sname.html">$team_name[$team] $veh_name{$name}s</a></td><td>${vehicle{"$team $name"}}</td></tr> |
<tr><td><a href="${team}_$sname.html">$team_name[$team] $veh_name{$name}s</a></td><td>${vehicle{"$team $name"}}</td></tr> |
663 |
END |
END |
664 |
|
} |
665 |
|
$html .= "</table>\n"; |
666 |
} |
} |
|
$html .= "</table>\n"; |
|
667 |
|
|
668 |
save_html('index.html', $html); |
save_html('index.html', $html); |
669 |
save_image($imall, 'Overview.png'); |
save_image($imall, 'Overview.png'); |