#!/usr/local/bin/perl
# 
# end_tourney.pl
#
# Generates PWstats from an EVENTLOG=1 enabled INL_log file.
# Mails stats to statboys if REGISTER was used.
#
# usage: end_tourney.pl [-register] [ID] 
# If "ID" exists, will open "INL_log.<ID>", else will open INL_log.
#
# The stats are saved in a hash of arrays, $stat{"statname"}[n].  Each
# array index represents one player.  A separate hash, $index{"netrekslot"}
# keeps track of which player is in which slot--we can't just use netrek
# slot number because that can change.  On output, the first player slot
# a player used is printed.
#
# Some of this logic is really ugly; the reason I'm rewriting it
# rather than using Kurt's code is that he only did the easy stats
# like tek, and didn't have code for the hard ones like tab.  It'll
# be easier to deal with the hard ones with better data structures.

$debug = 1;

$bgcolor="6699CC";
$th = "<th bgcolor=$bgcolor>";
$statboys = "statboys\@csua.berkeley.edu";
$mailprog = "/usr/lib/sendmail";

# Uncomment this if you want pwstats to be automatically dropped in a
# directory.  This should be a FULL UNIX DIRECTORY PATHNAME, without
# a trailing slash.
#
$dropdir = "/ls/home/tom/public_html/results";

foreach $argument ( @ARGV ) {
    if ( $argument eq "-register" ) {
	$register = 1;
    } else {
	$id = $argument;
    }
}

if ( $id ) {
    $inputfile = "INL_log." . $id;
    $outputfile = "pwstats." . $id . ".html";
} else { 
    $inputfile = "INL_log";
    $outputfile = "pwstats.html";
}

    open (INPUT,"$inputfile");
    open (OUTPUT,">$outputfile");

$homecurrentplanets=10;
$awaycurrentplanets=10;

&parselog;
&printstats;
&printstdout;

if ( $dropdir ) {
    if ( -d $dropdir ) {
	system("cp -f $outputfile $dropdir/$outputfile");
    } else {
	print STDERR "Dropdir " , $dropdir , " is not a directory!\n";
    }
}

if ( $register ) {
    &maillog;
}


sub parselog {
    # Go through the log and get the data we need.  This is the main
    # loop of the program.

while ( $line = <INPUT> ) {

    if ( $line =~ /^(\s+)\d/ ) {
	$line =~ s/^$1//;
    }

    # Skip to T-60 seconds, where teams are finalized
    
    next if $line !~ /^\d+: INL->ALL\s+Teams are/;

    $line =~ /^\d+: INL->ALL  Teams are\s+(.*) \((.*)\): .*,   (.*) \((.*)\):/;

    $hometeam = $1;
    $homerace = $2;
    $awayteam = $3;
    $awayrace = $4;

    last;

}

if ( $debug > 1 ) {
    print STDERR "$hometeam\n$homerace\n$awayteam\n$awayrace\n";
}

while ( $line = <INPUT> ) {

    if ( $line =~ /^(\s+)\d/ ) {
	$line =~ s/^$1//;
    }

    # Skip to the beginning of the game

    next if $line !~ /^\d+: INL->ALL  INL Tournament/;

    last;
}

while ( $line = <INPUT> ) {

    if ( $line =~ /^(\s+)\d/ ) {
	$line =~ s/^$1//;
    }

    # This is the main game loop.  Here's where it starts to get ugly.
    # Try to skip the common cases first so we do less regexp matching.

    study $line;

    next if $line =~ /^\d+: WRN->.*Must be orbiting/;
    next if $line =~ /^\d+: WRN->.*Phasers have/;
    next if $line =~ /^\d+: WRN->.*Our computers/;
    next if $line =~ /^\d+: WRN->.*Weapon\'s Officer:  Vessel/;
    next if $line =~ /^\d+: WRN->.*enough fuel/;
    next if $line =~ /^\d+:.*Phaser missed/;
    next if $line =~ /^\d+:.*Cannot fire/;
    next if $line =~ /^\d+:.*maximum safe/;
    next if $line =~ /^\d+:.*Player lock/;
    next if $line =~ /^\d+:.*Lock onto/;
    next if $line =~ /^\d+:.*You can only warp/;
    next if $line =~ /^\d+:.*cannot allow/;
    next if $line =~ /^\d+:.*We are being attacked/;

    if ( $debug > 2 ) {
	print STDERR $line;
    }

    if ( $line =~ 
	 /^(\d+): GOD->ALL  (.*) \((.*)\) \{(..)\} was kill (.*) for (.*) \((..)\) \{(..)\} \[(.*)$/ ||
	 $line =~ 
	 /^(\d+): GOD->ALL  (.*) \((.*)\) \{(..)\} was kill (.*) for (.*) \((..)\)/ ) {

	# Kill message

	my $timestamp = $1;
	my $losername = $2;
	my $loserslot = $3;
	my $losership = $4;
	my $kill = $5;
	my $winnername = $6;
	my $winnerslot = $7;
	my $winnership = $8;
	my $killedby = $9;

	undef $9;

	if ( ! $killedby ) { 

	    # Some kill messages, particularly dooshes, are too big to
	    # fit on one line.  Substitute some defaults if it got cut
	    # off.
	    $winnership = "CA";
	    $killedby = "unknown";

	}


	if ( $kill eq "NO CREDIT" ) {
	    # Grab the next line to figure out who gets credit
	    # (this is really ugly)

	    $line = <INPUT>;
	    if ( $line =~ /^(\s+)\d/ ) {
		$line =~ s/^$1//;
	    }

	    $line =~ /.*awarded to (.*) \((.*)\), kill (.*)/;

	    $winnername = $1;
	    $winnerslot = $2;
	    $kill = $3;
	    
	}

	&kill($timestamp,$losername,$loserslot,$losership,$kill,$winnername,$winnerslot,$winnership,$killedby);
	next;

    }

    if ( $line =~ /^(\d+): WRN->(.*)   ARMYTRACK.*\{(.*)\} \((.*)\) beamed up (\d+) armies/ ||
	 $line =~ /^(\d+): WRN->(.*)   ARMYTRACK.*\{(.*)\} \((.*)\) transferred up (\d+) armies at (..)/ ) {

	# Player is beaming up.

	&beamup($1,$2,$3,$4,$5,$6);
	next;
    }

    if ( $line =~ /^(\d+): WRN->(.*)   ARMYTRACK.*\{(.*)\} \((.*)\) beamed down (\d+) armies at (.*) \(.*\[(.*)\]/ ) {
	 
	# Player is beaming down on a planet

	&beamdown($1,$2,$3,$4,$5,$6,$7);
	next;
    }

    if ( $line =~ /^(\d+): WRN->(.*)   ARMYTRACK.*\{(.*)\} \((.*)\) transferred down (\d+) armies at (..).*\[(.*)\]/ ) {

	# Player is beaming down on base

	&beamdown($1,$2,$3,$4,$5,$6,$7,"SB");

    }

    if ( $line =~ /^(\d+): WRN->(.*)   ARMYTRACK.*(\d+) armies at (.*) \(\d+\) \[(.*)\]/ ) {

	# Player is bombing.

	&bomb($1,$2,$3,$4,$5);

    }

    if ( $line =~ /^(\d+): (.*)->.*taken over.*\((.*)\)/ ) {

	# Planet take
	&planettake($1,$2,$3);
	next;
    }

    if ( $line =~ /^(\d+): (.*)->.*destroyed by.*\((.*)\)/ ) {

	# Planet neut
	&planetdestroy($1,$2,$3);
	next;
    }

    if ( $line =~ /^(\d+): WRN->GOD  ARMYTRACK .*popped (\d+) armies at (.*) \(.*\[(.*)\]/ ) {
	# Army pop
	if ( $debug > 1 ) {
	    print STDERR "pop, $2, $4 \n";
	}

	&pop($2,$4)
	}

    if ( $line =~ /^(\d+): WRN->GOD  ARMYTRACK .*plagued (\d+) armies at (.*) \(.*\[(.*)\]/ ) {
	# Army plague
	if ( $debug > 1) {
	    print STDERR "plague, $2, $4 \n";
	}

	&plague($2,$4)
	}

} ### end main while loop

close INPUT;

} ### end sub parselog


sub printstdout {
    # Prints a plain text summary of stats so the server can pipe it to
    # stdout on the clients

    if ( $awayscore > $homescore ) {
	print "FINAL SCORE: $awayteam defeats $hometeam, ${awayscore}-$homescore ($awaycurrentplanets-$homecurrentplanets)\n\n";
    } else {
	print "FINAL SCORE: $hometeam defeats $awayteam, ${homescore}-$awayscore ($homecurrentplanets-$awaycurrentplanets)\n\n";
    }

    print "PLAYER STATS for $hometeam\n";
    print "Name\t\ttpt\ttpd\ttab\ttek\tdef\tacc\n";
 
    for ( $count = 0 ; $count <=40 ; $count++ ) {
	next if ! $stat{name}[$count];
	next if $stat{playerslot}[$count] !~ /^$homeraceinit/;

	print $stat{name}[$count] , "\t\t" , $stat{tpt}[$count] , "\t" ,
	$stat{tpd}[$count] , "\t" , $stat{tab}[$count] , "\t" ,
	$stat{tek}[$count] , "\t" , $stat{def}[$count] , "\t" , 
	$stat{acc}[$count] , "\n";
			
    }

    print "\nPLAYER STATS for $awayteam\n";
    print "Name\t\ttpt\ttpd\ttab\ttek\tdef\tacc\n";
 
    for ( $count = 0 ; $count <=40 ; $count++ ) {
	next if ! $stat{name}[$count];
	next if $stat{playerslot}[$count] !~ /^$awayraceinit/;

	print $stat{name}[$count] , "\t\t" , $stat{tpt}[$count] , "\t" ,
	$stat{tpd}[$count] , "\t" , $stat{tab}[$count] , "\t" ,
	$stat{tek}[$count] , "\t" , $stat{def}[$count] , "\t" , 
	$stat{acc}[$count] , "\n";
			
    }

} ### end sub printstdout

sub printstats {

    # After the log has been wholly parsed, get the information
    # (mostly from the %stat hash) and print it.

print OUTPUT  <<END;
<title>PWstats: $awayteam ($awayrace) at $hometeam ($homerace)</title>

<center>
<h2>PWstats: $awayteam ($awayrace) at $hometeam ($homerace)</h2>

<table>
<tr><th valign=center rowspan=2><font size=+3>FINAL SCORE: 
END

if ( $awayscore > $homescore ) {
    print OUTPUT  <<END;
<td><font size=+2>$awayteam ($awayrace) ${th}<font size=+2>$awayscore
<tr><td><font size=+2>$hometeam ($homerace) ${th}<font size=+2>$homescore
<tr><td><th align=left colspan=2>
Planet Count
($awaycurrentplanets-$homecurrentplanets)
</table>
</center>
END

} else {
    print OUTPUT  <<END;
<td><font size=+2>$hometeam ($homerace) ${th}<font size=+2>$homescore
<tr><td><font size=+2>$awayteam ($awayrace) ${th}<font size=+2>$awayscore
<tr><td><th align=left colspan=2>
Planet Count
($homecurrentplanets-$awaycurrentplanets)
</table>
</center>
END
}

# Change all undef values to 0's for printing

foreach $value ( sort keys %stat ) {

    for ( $count=0; $count <=40; $count++) {
	if ( ! $stat{$value}[$count] ) {
	    $stat{$value}[$count] = 0;
	}
    }
}

# Go through printing the home team first, then their totals, then 
# the away team and their totals, then SB stats.

$homeraceinit = substr($homerace,0,1);
$awayraceinit = substr($awayrace,0,1);

$count = 0;


print OUTPUT  <<END;

<h3>Player Stats</h3>

<h4>Home Team</h4>

<table border cellpadding=4>
    <tr>${th}Slot${th}Name${th}tpd${th}tpt${th}tpb${th}tab
    ${th}tad/tac/%ad${th}cak${th}eao${th}eck${th}pck${th}tek${th}def${th}acc

<tr>

END



for ( $count=0; $count <=40 ; $count++ )  {

    next if ! $stat{name}[$count];

next if $stat{playerslot}[$count] !~ /^$homeraceinit/;

printrecord($count);

$home{tpd}+=$stat{tpd}[$count];
$home{tpt}+=$stat{tpt}[$count];
$home{tpb}+=$stat{tpb}[$count];
$home{tab}+=$stat{tab}[$count];
$home{tac}+=$stat{tac}[$count];
$home{tad}+=$stat{tad}[$count];
$home{cak}+=$stat{cak}[$count];
$home{eao}+=$stat{eao}[$count];
$home{eck}+=$stat{eck}[$count];
$home{pck}+=$stat{pck}[$count];
$home{tek}+=$stat{tek}[$count];
$home{def}+=$stat{def}[$count];
$home{acc}+=$stat{acc}[$count];

}

print OUTPUT  <<END;
<tr><td>
    ${th}Home Total
    ${th}$home{tpd}
${th}$home{tpt}
${th}$home{tpb}
${th}$home{tab}
${th}$home{tad}/$home{tac},
END

    printf OUTPUT ("%2.1f",($home{tad}/$home{tac})*100);

print OUTPUT  <<END;
%
${th}$home{cak}
${th}$home{eao}
${th}$home{eck}
${th}$home{pck}
${th}$home{tek}
${th}$home{def}
${th}$home{acc}

</table>
<p>
<h4>Away Team</h4>

<table border cellpadding=4>
    <tr>${th}Slot${th}Name${th}tpd${th}tpt${th}tpb${th}tab
    ${th}tad/tac/%ad${th}cak${th}eao${th}eck${th}pck${th}tek${th}def${th}acc

END



for ( $count=0; $count <=40; $count++ )  {

    next if ! $stat{name}[$count];

if ( $debug > 2) {
    print STDERR "<td>stat{playerslot}[count], awayraceinit = $stat{playerslot}[$count] , $awayraceinit\n";
}

next if $stat{playerslot}[$count] !~ /^$awayraceinit/;

printrecord($count);

$away{tpd}+=$stat{tpd}[$count];
$away{tpt}+=$stat{tpt}[$count];
$away{tpb}+=$stat{tpb}[$count];
$away{tab}+=$stat{tab}[$count];
$away{tac}+=$stat{tac}[$count];
$away{tad}+=$stat{tad}[$count];
$away{cak}+=$stat{cak}[$count];
$away{eao}+=$stat{eao}[$count];
$away{eck}+=$stat{eck}[$count];
$away{pck}+=$stat{pck}[$count];
$away{tek}+=$stat{tek}[$count];
$away{def}+=$stat{def}[$count];
$away{acc}+=$stat{acc}[$count];

}

print OUTPUT  <<END;
<tr><td>
${th}Away Total
${th}$away{tpd}
${th}$away{tpt}
${th}$away{tpb}
${th}$away{tab}
${th}$away{tad}/$away{tac},
END

printf OUTPUT ("%2.1f",($away{tad}/$away{tac})*100);

print OUTPUT  <<END;
%
${th}$away{cak}
${th}$away{eao}
${th}$away{eck}
${th}$away{pck}
${th}$away{tek}
${th}$away{def}
${th}$away{acc}
END

print OUTPUT  <<END;
</table>
<p>

<h3>Starbase Stats</h3>

<table border cellpadding=4>
    <tr>${th}Slot${th}Name${th}tek${th}def${th}tac${th}tad${th}cak
    ${th}eao${th}eck${th}pck
END

for ($count = 0 ; $count <=40 ; $count++ ){
    next if ! $stat{name}[$count];
    if ( $stat{sbtac}[$count] ) {
	print OUTPUT  <<END;
	<tr>$td $stat{playerslot}[$count]
	$td $stat{name}[$count]
        $td $stat{sbtek}[$count]
	$td $stat{sbdef}[$count]
	$td $stat{sbtac}[$count]
	$td $stat{sbtad}[$count]
	$td $stat{sbcak}[$count]
        $td $stat{sbeao}[$count]
	$td $stat{sbeck}[$count]
	$td $stat{sbpck}[$count]

END
    }
}

print OUTPUT  <<END;
</table>
<p>
<h3>Army Stats</h3>
<table border cellpadding=4>
    <tr>${th}Race${th}Popped${th}Bombed${th}Dropped${th}Dropped On
    ${th}Dooshed${th}Plagued

END

    foreach $race ( sort keys %bombed ) {
	next if $race ne $homerace && $race ne $awayrace;
	print OUTPUT  <<END;
<tr>
    $td $race 
	$td $poparmies{$race} 
	$td $bombed{$race}
	$td $dropped{$race}
	$td $droppedon{$race}
	$td $dooshed{$race}
	$td $plaguearmies{$race}
END

    }

print OUTPUT  <<END;
</table>
<p>
<h3>Kill Stats</h3>

<table border cellpadding=4>
<tr>${th}Slot${th}Name${th}kbp${th}kbt${th}kbe${th}kbd${th}kbs
${th}dbp${th}dbt${th}dbe${th}dbd${th}dbs
END

for ( $count = 0 ; $count <=40 ; $count++ ) {
    next if ! $stat{name}[$count];
print OUTPUT  <<END;
<tr>
    $td $stat{playerslot}[$count]
    $td $stat{name}[$count]
$td $stat{kbp}[$count]
$td $stat{kbt}[$count]
$td $stat{kbe}[$count]
$td $stat{kbd}[$count]
$td $stat{kbs}[$count]
$td $stat{dbp}[$count]
$td $stat{dbt}[$count]
$td $stat{dbe}[$count]
$td $stat{dbd}[$count]
$td $stat{dbs}[$count]
END
}

print OUTPUT  <<END;
</table>
<p>
<h3>Starbase Kill Stats</h3>

<table border cellpadding=4>
<tr>${th}Slot${th}Name${th}kbp${th}kbt${th}kbe${th}kbd${th}kbs
${th}dbp${th}dbt${th}dbe${th}dbd${th}dbs
END

for ( $count = 0 ; $count <=40 ; $count++ ) {
    next if ! $stat{name}[$count];
    next if ! $stat{sbkbp}[$count];

print OUTPUT  <<END;
<tr>
    $td $stat{playerslot}[$count]
    $td $stat{name}[$count]
$td $stat{sbkbp}[$count]
$td $stat{sbkbt}[$count]
$td $stat{sbkbe}[$count]
$td $stat{sbkbd}[$count]
$td $stat{sbkbs}[$count]
$td $stat{sbdbp}[$count]
$td $stat{sbdbt}[$count]
$td $stat{sbdbe}[$count]
$td $stat{sbdbd}[$count]
$td $stat{sbdbs}[$count]
END
}

    print OUTPUT  "</table>\n";

close OUTPUT;

} ### end sub printstats


sub printrecord {
    # Takes one argument, an array index, and prints the information in
    # tabular form.

    my $record=$_[0];

    $td = "<td align=center>";

print OUTPUT  <<END;
<tr>
$td $stat{playerslot}[$record]
    $td $stat{name}[$record]
    $td $stat{tpd}[$record]
    $td $stat{tpt}[$record]
    $td $stat{tpb}[$record]
    $td $stat{tab}[$record]
    $td $stat{tad}[$record]/$stat{tac}[$record], 
END

    if ( $stat{tac}[$record] ) {
my $pad = $stat{tad}[$record]/$stat{tac}[$record]*100;
printf OUTPUT ("%2.1f",$pad);
print OUTPUT  "%";
} else {
    print OUTPUT  "0.0%";
}

print OUTPUT  <<END;
$td $stat{cak}[$record]
    $td $stat{eao}[$record]
    $td $stat{eck}[$record]
    $td $stat{pck}[$record]
    $td $stat{tek}[$record]
    $td $stat{def}[$record]
    $td $stat{acc}[$record]

END

} ### end sub printrecord


sub planettake {

# Handle planet takes.  Takes 3 arguments; timestamp, planet name, and 
# player slot.  Computes stats and increments score for team.

    my ( $timestamp, $planetname, $playerslot ) = @_;

    $playerteam = substr($playerslot,0,1);

    if ( $homerace =~ /^$playerteam/ ) {

	# it's a take by the home team

	$homecurrentplanets++;
	$homescore++;
    } else {

	# it better be a take by the away team

	$awaycurrentplanets++;
	$awayscore++;
    }

    my $playerindex = getindex($playerslot);

    $stat{tpt}[$playerindex]++;

} ### end sub planettake


sub planetdestroy {

# Handle planet neuts.  Takes 3 arguments; timestamp, planet name, and 
# player slot.  Computes stats and increments score for team.
# Timestamp is not currently used.

    my ( $timestamp, $planetname, $playerslot ) = @_;

    $playerteam = substr($playerslot,0,1);

    if ( $homerace =~ /^$playerteam/ ) {

	# it's a neut by the home team

	$awaycurrentplanets--;
	$homescore++;
    } else {

	# it better be a neut by the away team

	$homecurrentplanets--;
	$awayscore++;
    }

    my $playerindex = getindex($playerslot);

    $stat{tpd}[$playerindex]++;

} ### end sub planetdestroy


sub kill {

# Processes a kill message.  Takes 6 arguments: timestamp, name of loser,
# player slot for loser, kill total for winner, name of winner, winner slot.
#
# Bases are currently not treated differently, because information about
# whether someone is in a base is not available in kill messages.
# To be fixed quickly, hopefully.

    my ( $timestamp, $losername, $loserslot, $losership, $killtotal , 
	 $winnername, $winnerslot, $winnership, $killedby ) = @_;

    if ($debug > 1 ) {

	print STDERR "$timestamp, $losername, $loserslot, $losership, $killtotal, $winnername, $winnerslot, $winnership, $killedby\n";
    }

    if ( $loserslot =~ /(.*)\+(\d+) / ) {
	# DOOSH!
	$loserslot = $1;
	doosh($winnerslot, $winnership, $loserslot, $losership, $2);
	if ( $debug > 1 ) {
	    print STDERR "DOOSH! $winnerslot, $winnership, $loserslot, $losership, $2 \n";
	}
    }

    my $loserindex = getindex($loserslot);
    my $winnerindex = getindex($winnerslot);

    if ( ! $stat{"name"}[$winnerindex] ) {
	$stat{"name"}[$winnerindex] = $winnername;
    } elsif ( $winnername ne $stat{"name"}[$winnerindex] ) {

	if ( $debug >1 ) {
	    print STDERR "winnername, stat{name}[winnerindex] = |$winnername| |$stat{name}[$winnerindex]|\n";
	}

	# Sanity check.  If the player name has changed, generate a new
	# index for them (someone quit and someone else took their slot)

	undef $index{"$winnerslot"};
	$winnerindex = getindex("$winnerslot");
	$stat{"name"}[$winnerindex] = $winnername;
    }

    if ( ! $stat{"name"}[$loserindex] ) {
	$stat{"name"}[$loserindex] = $losername;
    } elsif ( $losername ne $stat{"name"}[$loserindex] ) {

	undef $index{"$loserslot"};
	$loserindex = getindex("$loserslot");
	$stat{"name"}[$loserindex] = $losername;
    }

    if ( $debug > 2 ) {
	print STDERR "winner, loser index: $winnerindex, $loserindex \n";
    }

    if ( $winnership ne "SB" ) {
	$stat{"tek"}[$winnerindex]++;
    } else {
	$stat{"sbtek"}[$winnerindex]++;
    }

    if ( $losership ne "SB" ) {
	$stat{"def"}[$loserindex]++;
    } else {
	$stat{"sbdef"}[$loserindex]++;
    }

    # Check if the loser is a pck

    if ( $stat{"kill1"}[$loserindex] ) {
	if ( $stat{"killtime"}[$loserindex] && 
	     $timestamp - $stat{"killtime"}[$loserindex] > 70 ) {
	    # if he got his first kill more than 70 ticks (7 secs) ago
	    if ( $winnership eq "SB" ) {
		$stat{sbpck}[$winnerindex]++;
	    } else {
		$stat{pck}[$winnerindex]++;
	    }
	} elsif ( $winnerindex != $stat{"kill1"}[$loserindex] ) {
	    # If he was killed by someone other than the guy who killed
	    # him, don't need to wait 7 secs
	    if ( $winnership eq "SB" ) {
		$stat{sbpck}[$winnerindex]++;
	    } else {
		$stat{pck}[$winnerindex]++;
	    }
	}
    }

    # Store the kill type stats

    if ( $killedby =~ /^pha/ ) {
	if ( $losership eq "SB" ) {
	    $stat{sbdbp}[$loserindex]++;
	} else {
	    $stat{dbp}[$loserindex]++;
	}

	if ( $winnership eq "SB" ) {
	    $stat{sbkbp}[$winnerindex]++;
	} else {
	    $stat{kbp}[$winnerindex]++;
	}
    } elsif ( $killedby =~ /^pho/ ) {
	if ( $losership eq "SB" ) {
	    $stat{sbdbt}[$loserindex]++;
	} else {
	    $stat{dbt}[$loserindex]++;
	}

	if ( $winnership eq "SB" ) {
	    $stat{sbkbt}[$winnerindex]++;
	} else {
	    $stat{kbt}[$winnerindex]++;
	}
    } elsif ( $killedby =~ /^exp/ ) {
	if ( $losership eq "SB" ) {
	    $stat{sbdbe}[$loserindex]++;
	} else {
	    $stat{dbe}[$loserindex]++;
	}

	if ( $winnership eq "SB" ) {
	    $stat{sbkbe}[$winnerindex]++;
	} else {
	    $stat{kbe}[$winnerindex]++;
	}
    } elsif ( $killedby =~ /^det/ ) {
	if ( $losership eq "SB" ) {
	    $stat{sbdbd}[$loserindex]++;
	} else {
	    $stat{dbd}[$loserindex]++;
	}

	if ( $winnership eq "SB" ) {
	    $stat{sbkbd}[$winnerindex]++;
	} else {
	    $stat{kbd}[$winnerindex]++;
	}
    } elsif ( $killedby =~ /^pla/ ) {
	if ( $losership eq "SB" ) {
	    $stat{sbdbs}[$loserindex]++;
	} else {
	    $stat{dbs}[$loserindex]++;
	}

	if ( $winnership eq "SB" ) {
	    $stat{sbkbs}[$winnerindex]++;
	} else {
	    $stat{kbs}[$winnerindex]++;
	}
    }



    # clear the acc data for the loser

    foreach $kill ( 1,2,3,4,5 ) {
	$stat{"kill$kill"}[$loserindex]=0;
    }

    $stat{"killtime"}[$loserindex]=0;

    # Save the loser's index number for future acc reference

    if ( $killtotal < 2 ) {
	$stat{"kill1"}[$winnerindex]=$loserindex;
	$stat{"killtime"}[$winnerindex]=$timestamp;
    } else {
	foreach $kill ( 2,3,4,5 ) {
	    if ( ! $stat{"kill$kill"}[$winnerindex] ) {
		$stat{"kill$kill"}[$winnerindex]=$loserindex;
		last;
	    }
	}
    }


} ### end sub kill


sub doosh {
    # Someone just got dooshed.  Takes five arguments; winnerslot, winnership,
    # loserslot, losership, and number of armies.

    my ( $winnerslot , $winnership, $loserslot , $losership, $armies ) = @_;

    my $winnerindex = getindex($winnerslot);
    my $loserindex = getindex($loserslot);

    if ( $losership eq "SB" ) {
	$stat{sbcak}[$loserindex] += $armies;
    } else {
	$stat{cak}[$loserindex] += $armies;
    }

    if ( $winnership eq "SB" ) {
	$stat{sbeao}[$winnerindex] += $armies;
	$stat{sbeck}[$winnerindex] += $armies;
    } else { 
	$stat{eao}[$winnerindex] += $armies;
	$stat{eck}[$winnerindex]++;
    }

    my $loserteaminit = substr($loserslot,0,1);
    if ( $homerace =~ /^$loserteaminit/ ) {
	$dooshed{$homerace} += $armies;
    } else { 
	$dooshed{$awayrace} += $armies;
    }

} ### end sub doosh


sub getteam {
    # Given a single character, returns the team associated with it (in caps)

    my $character = $_[0];

    if ( $character eq "R" ) {
	return ("ROM");
    } elsif ( $character eq "F" ) {
	return ("FED");
    } elsif ( $character eq "K" ) {
	return ("KLI");
    } elsif ( $character eq "O" ) {
	return ("ORI");
    }
} ### end sub getteam


sub plague {
    # Planet just plagued.  Takes 2 parameters, army count and race.
    # Increments team army stats.

    my ( $armies, $race ) = @_;

    $plaguecount{$race}++;
    $plaguearmies{$race} += $armies;

} ### end sub plague


sub pop {

    # Planet just popped.  Takes 2 parameters; army count and race.
    # Increments team army stats.

    my ( $armies, $race ) = @_;

    $popcount{$race}++;
    $poparmies{$race} += $armies;

} ### end sub pop


sub bomb {

    # Player is bombing armies.  Takes 5 parameters: timestamp, netrek
    # slot, armies bombed, planet name, race.  Checks the timestamp of
    # the last bomb message we have for this planet; if it is more
    # than 20 ticks ago (2 secs), give credit for tpb.  Add to armies
    # bombed total for team.

    my ( $timestamp , $slot , $armies , $planet , $team ) = @_;

    my $playerindex = getindex($slot);

    $stat{tab}[$playerindex] += $armies;

    if ( $timestamp - $bomb{$planet} > 20 ) {
	$stat{tpb}[$playerindex]++;
    }

    $bomb{$planet} = $timestamp;

    $bombed{$team} += $armies;

} ### end sub bomb


sub beamup {

    # Player is beaming up armies.  Takes 6 parameters: timestamp
    # (5-digit int), netrek slot, ship type, current armies carried,
    # number of armies beamed up (should be 1 always), sbslot (should
    # be false unless beaming from base.  Also compute acc.  Bleh, I
    # don't even wanna think about it.  The last 5 kills of each are
    # stored in $stat{kill[1-5]}[index]; if this is the first time one
    # of those kills was used to pick, increment acc for the person
    # who gave it.  No special-case for AS yet, because I don't have
    # ship types.

    my ( $timestamp , $playerslot, $shiptype , $currentarmies , $beamed , $sbslot) = @_;

    my $playerindex = getindex($playerslot);

    if ( $shiptype eq "SB" ) {
	$stat{sbtac}[$playerindex] += $beamed;
    } else {
	$stat{tac}[$playerindex] += $beamed;
    }

    my $acckill = 0;

    if ( $shiptype eq "AS" ) {
	$acckill = int ($currentarmies / 3) + 1;
    } else {
	$acckill = int($currentarmies / 2) + 1;
    }

    my $killacc = "kill" . $acckill . "acc";

    if ( ! $stat{$killacc}[$playerindex] ) {
	# OK this is ugly.  stat{kill[1-5]}[playerindex] stores the player
	# index of the player who gave us the kill.  stat{kill[1-5]acc} stores
	# whether that kill has already been used to compute an acc.
	# If it hasn't, add an acc to the person who gave us the kill.
	# Unless there is no one--if we got a kill by bombing or something.
	# This is also inaccurate because we get more than one kill per
	# ship on average, but I'm ignoring that.


	if ( $stat{"kill$acckill"}[$playerindex] ) {
	    # will be false if we got kill by bombing or by partials

	    my $accindex = $stat{"kill$acckill"}[$playerindex];

	    $stat{"acc"}[$accindex]++;
	    $stat{"$killacc"}[$playerindex] = 1;
	}
    }

    if ( $sbslot ) {
	# Beaming from the base; subtract from base armies, increment base
	# army delivery.  

	my $sbindex=getindex($sbslot);
	$stat{sbtad}[$sbindex] += $beamed;

    }

} ### end sub beamup

sub beamdown {

    # Similar in logic to &beamup, at least we don't have to worry about acc
    # here.

    my ( $timestamp , $playerslot, $shiptype, $currentarmies, $beamed, $where, $race, $starbase ) = @_;

    my $playerindex = getindex($playerslot);

    if ( $shiptype eq "SB" ) {
	$stat{sbtad}[$playerindex] += $beamed;
    } else {
	$stat{tad}[$playerindex] += $beamed;
    }

    if ( $starbase ) {
	my $sbindex = getindex($sbslot);
	$stat{sbtac}[$sbindex] += $beamed;
    } 

    my $teaminit = substr($playerslot,0,1);

    if ( $race !~ /^$teaminit/ ) {
	if ( $homerace =~ /^$teaminit/ ) {
	    $dropped{$homerace} += $beamed;
	    $droppedon{$awayrace} += $beamed;
	} else {
	    $dropped{$awayrace} += $beamed;
	    $droppedon{$homerace} += $beamed;
	}
    }

} ### end sub beamdown


sub getindex {

    # Return the index for the %index hash, given the current player slot.

    my $playerslot = $_[0];

    # See if we already know it.

    if ( $index{$playerslot} ) {
	return $index{$playerslot};
    }

    # We haven't assigned this player slot yet.  Find the next open
    # slot, set it in the slot hash, and return it.
    #
    # I can't figure out how to get the last array index of a particular array
    # in a hash of arrays, so here's the long way:

    my $count = 0;

    while ( $stat{"playerslot"}[$count] ) {
	$count++;
    }

    $stat{"playerslot"}[$count]=$playerslot;
    $index{$playerslot}=$count;

    return $index{$playerslot};

} ### end sub getindex

sub maillog {
    # Takes a completed log and mails it to statboys, along with the
    # INL log.

    if ( ! -e $mailprog ) {
	# they don't have /usr/lib/sendmail?  What the heck are they
	# using?  Let's try random shit:
	#
	if ( -e "/usr/sbin/sendmail" ) {
	    $mailprog = "/usr/sbin/sendmail";
	} elsif ( -e "/usr/bin/sendmail" ) {
	    $mailprog = "/usr/bin/sendmail";
	} elsif ( -e "/usr/bin/mailx" ) {
	    $mailprog = "/usr/bin/mailx"; 
	} elsif ( -e "/usr/bin/mail" ) {
	    $mailprog = "/usr/bin/mail"; 
	} elsif ( -e "/bin/mail" ) {
	    $mailprog = "/bin/mail";
	} else {
	    die "I give up, I can't find a mail program";
	}
    }

    open (MAIL,"|$mailprog -t");
    print MAIL "Subject: INL RESULTS: $awayteam at $hometeam\n";
    print MAIL "To: " , $statboys , "\n\n";
    open (INLLOG,"$inputfile");
    while ( $line = <INLLOG> ) {
	print MAIL $line;
    }
    close INLLOG;

    open (PWSTATS,"$outputfile");
    while ( $line = <PWSTATS> ) {
	print MAIL $line;
    }
    close PWSTATS;
    close MAIL;

}


