#!/usr/local/bin/perl
#
# SYNOPSIS
#   @(#) Generate PWstats from an INL_log file
#
# AUTHOR
#   Kurt Siegl <007@freemail.at>
#
# USAGE
#   thisfile < INL_log
#
# DESCRIPTION
#   Generate PWstats from an INL_log file
#
# OPTIONS
#   none
#
# FILES
#   thisfile ... this script file.
#
# REMARKS
#   Nothing special to remark.
#
# EXIT CODES
    $ERR_ARGS=1; # Error on arguments.
#
# SEE ALSO
#   Vanilla Server Docs
#
# REVISION HISTORY
#   96-10-11 Kurt Siegl [007] :      created this file


# Variables:
%Planets = ();        # [race, armies] of planet

%Players = ();        # current status of player by number
$nameIdx    = 0;      # for mapping player number to names
$accToIdx   = 1;      # who gave us the first kill
$carriedIdx = 2;      # kill is worth a pck
$armsIdx    = 3;      # currently carring armies

%Race = (             # map race key to race name
         F, FED,
         R, ROM,
         K, KLI,
         O, ORI,
         I, IND
        );

@Ranks = ("Ensign", "Lieutenant", "Lt. Cmdr.", "Commander", 
	  "Captain", "Flt. Capt.", "Commodore", "Rear Adm.", "Admiral");

%PlayerStats = ();    # stats of player
%TeamStats   = ();    # stats of team

$tekIdx = 0;          # Total Enemies Killed
$defIdx = 1;          # Death due Enemy Fire
$tabIdx = 2;          # Total Armies Bombed
$eaoIdx = 3;          # Enemy Armies Ogged
$tacIdx = 4;          # Total Armies Carried
$cakIdx = 5;          # Carried Armies Killed
$tptIdx = 6;          # Total Planets Taken
$tpdIdx = 7;          # Total Planets Destroyed
$tpbIdx = 8;          # Total Planets Bombed
$eckIdx = 9;          # Enemy Carriers Killed
$accIdx =10;          # Actual Carriers Created
$pckIdx =11;          # Actual Carriers Created
$whoIdx =12;          # Adress of the player
$raceIdx=13;          # Last Race and number of Player

$homeName = "Home Team";
$homeRace = IND;
$homePlanets = 10;
$awayName = "Away Team";
$awayRace = IND;
$awayPlanets = 10;

&resetStats();

sub resetStats {

    %Planets = 
    (
       "Earth", [FED, 17] ,
       "Rigel", [FED, 17] ,
       "Canopus", [FED, 17] ,
       "Beta Crucis", [FED, 17] ,
       "Organia", [FED, 17] ,
       "Deneb", [FED, 17] ,
       "Ceti Alpha V", [FED, 17] ,
       "Altair", [FED, 17] ,
       "Vega", [FED, 17] ,
       "Alpha Centauri", [FED, 17] ,

       "Romulus", [ROM, 17] ,
       "Eridani", [ROM, 17] ,
       "Aldeberan", [ROM, 17] ,
       "Regulus", [ROM, 17] ,
       "Capella", [ROM, 17] ,
       "Tauri", [ROM, 17] ,
       "Draconis", [ROM, 17] ,
       "Sirius", [ROM, 17] ,
       "Indi", [ROM, 17] ,
       "Hydrae", [ROM, 17] ,

       "Klingus", [KLI, 17] ,
       "Pliedes V", [KLI, 17] ,
       "Andromeda", [KLI, 17] ,
       "Lalande", [KLI, 17] ,
       "Praxis", [KLI, 17] ,
       "Lyrae", [KLI, 17] ,
       "Scorpii", [KLI, 17] ,
       "Mira", [KLI, 17] ,
       "Cygni", [KLI, 17] ,
       "Achernar", [KLI, 17] ,
      
       "Orion", [ORI, 17] ,
       "Cassiopia", [ORI, 17] ,
       "El Nath", [ORI, 17] ,
       "Spica", [ORI, 17] ,
       "Procyon", [ORI, 17] ,
       "Polaris", [ORI, 17] ,
       "Arcturus", [ORI, 17] ,
       "Ursae Majoris", [ORI, 17] ,
       "Herculis", [ORI, 17] ,
       "Antares", [ORI, 17] 
    );

    %TeamStats = 
    (
	 FED, [] ,
	 ROM, [] ,
	 KLI, [] ,
	 ORI, [] 
    );

    for (keys(%PlayerStats)) 
    {
	$who = $PlayerStats{$_}[$whoIdx];
        $race = $PlayerStats{$_}[$raceIdx];
	$PlayerStats{$_} = [0,0,0,0,0,0,0,0,0,0,0,0,$who,$race];
    }
}


while( <> ) 
{


    # Let's check for a normal message with exact border match which makes
    # fooling the script with messages impossible.
    if ( /^([ \d]{5}):\s+([\w\s]+)->(\w+)\s*(.*)\s*$/ )
    {
#  830:  O9->ORI  Distress Call from O9:  0% damage, 100% shields, 2 armies!
#  950: WRN->Ob   Weapons Officer: Bombarding Scorpii...  Sensors read 17 armies left.
# 2910: GOD->ALL  RH6 (K6+3 armies) was kill 1.80 for RA3 (Ob) [photon]

	$time=$1;
	$from=$2;
	$to=$3;
	$line=$4;
        # Destination has 2 digits -> message to player
	if ($to =~ /^(\w)(\w)$/)
	{
	    $toRace = $1; 
	    $toPlayer = $2;
	    $dest = player;
	} 
	elsif ($to =~ "ALL")
	{
	    $dest = all;
	}
	else
	{
	    $dest = team;
	}

        # Sender has 2 digits -> message to player
	if ($from =~ /^(\w)(\w)$/)
	{
	    $fromRace = $1; 
	    $fromPlayer = $2;
	    $sender = player;
	} 
	elsif ($from =~ "INL")
	{
	    $sender = robot;
	}
	elsif ($from =~ "WRN")
	{
	    $sender = info;
	}
	elsif ($from =~ "GOD")
	{
	    $sender = god;
	}
	else
	{
	    $sender = planet;
	}

	if ( $sender == robot && $dest == all)
	{
# Game start
#   10: INL->ALL  INL Tournament starting now. rewling home(KLI) vs. the away fighter(ORI).
	    if ($line =~ /INL Tournament starting now. (.*)\((\w\w\w)\) vs. (.*)\((\w\w\w)\)\./ )
	    {
		$homeName = $1;
		$homeRace = $2;
		$awayName = $3;
		$awayRace = $4;

		# print "Game Start H: $homeName - $homeRace A: $awayName - $awayRace\n";
		&resetStats();
	    }
# 9000: INL->ALL  Result: 13 - 7
	    if ($line =~ /Result: (\d+) - (\d+)/)
	    {
		$homePlanets = $1;
		$awayPlanets = $2;
	    }
	}

# A player joins
# 08:26  F0->ALL  Ensign 007 is now F0 (007@doosh.siegl.priv.at)
               
	if ( $sender == player && $dest == all
	    && $line =~ /^(.*) is now $from \((.*)\)\s*$/ )
	{
	    local ($name, $mail) = ($1, $2);

	    for (@Ranks) 
	    {
		last if $name =~ s/$_//;    # skip the rank part   
	    }
	    $name =~ s/^\s*//;
	    $Players{$fromPlayer} = [$name," ",0,0];
	    if ($PlayerStats{$name})
	    {                               # player just rejoined
		$PlayerStats{$name}[$raceIdx]=$from;
	    }
	    else
	    {
		$PlayerStats{$name} = [0,0,0,0,0,0,0,0,0,0,0,0,$mail,$from];
	    }

	    # print "Joined: P: $name N: $fromPlayer R: $Race{$fromRace}\n";
	}

        next if $time == 0;    # skip pregame stats

# Kill message
#  460: GOD->ALL  Away Capt (O8) was kill 1.06 for RH2 (K2) [phaser]

	if ( $sender == god && $dest == all )
	{
	    if ($line =~ /\(\w(\w)\) was kill ([\d\.]+) for .* \(\w(\w)\) \[(\w+)\]/)
	    {
		local ($looser, $kills, $winner, $whydead) = ($1, $2, $3, $4);
		$PlayerStats{$Players{$looser}[$nameIdx]}[$defIdx] ++;
		$PlayerStats{$Players{$winner}[$nameIdx]}[$tekIdx] ++;
		$PlayerStats{$Players{$winner}[$nameIdx]}[$pckIdx] ++ 
		    if $Players{$looser}[$carriedIdx];
		$Players{$winner}[$accToIdx] = $Players{$looser}[$nameIdx]
		    if $Players{$winner}[$accToIdx] =~" ";
		$Players{$looser}[$accToIdx] = " ";
		$Players{$looser}[$carriedIdx] = 0;

		# print "Kill: L: $looser W: $winner K: $kills W: $4\n";
	    }
# 2910: GOD->ALL  RH6 (K6+3 armies) was kill 1.80 for RA3 (Ob) [photon]
	    elsif ($line =~ /\(\w(\w)\+(\d+) armies\) was kill ([\d\.]+) for .* \(\w(\w)\) \[(\w+)\]/)
	    {
		local ($looser, $armies, $kills, $winner, $whydead) = ($1, $2, $3, $4, $5);
		$PlayerStats{$Players{$looser}[$nameIdx]}[$defIdx] ++;
		$PlayerStats{$Players{$winner}[$nameIdx]}[$tekIdx] ++;
		$PlayerStats{$Players{$winner}[$nameIdx]}[$eckIdx] ++; 
		$PlayerStats{$Players{$winner}[$nameIdx]}[$eaoIdx] += $armies; 
		$PlayerStats{$Players{$looser}[$nameIdx]}[$cakIdx] += $armies; 
		$Players{$winner}[$accToIdx] = $Players{$looser}[$nameIdx]
		    if $Players{$winner}[$accToIdx] =~ " ";
		$Players{$looser}[$accToIdx] = " ";
		$Players{$looser}[$carriedIdx] = 0;
		$Players{$toPlayer}[$armsIdx] = 0;
		
		# print "Kill: L: $looser W: $winner K: $kills A: $armies\n";
	    }

	}
	    
	if ( $sender == info && $dest == player )
	{
		# Remove observers
		next if $Players{$toPlayer}[$nameIdx] =~ /\cA/;

#  310: WRN->Oe   Beaming up: (0/2) Cassiopia has 17 armies left
# 1220: WRN->O8   Beaming down: (1/2) Mira has 1 armies left
	    if ($line =~ /: \((\d+)\/\d+\) (\w[\w ]*\w) has (\d+) armies/)
	    {
		local ($armies, $old) = ($1, 0);
		$Planets{$2}[1] = $3 if ! ($2 =~ /Starbase/);
		$old = $Players{$toPlayer}[$armsIdx];
		if ($old < $armies)
		{
		    $PlayerStats{$Players{$toPlayer}[$nameIdx]}[$tacIdx] ++;
		    $PlayerStats{$Players{$toPlayer}[$accToIdx]}[$accIdx] ++
			if ! $Players{$toPlayer}[$carriedIdx];

		    $Players{$toPlayer}[$carriedIdx] = 1;
		} 
		$Players{$toPlayer}[$armsIdx] = $armies;

	    }


#  190: WRN->O8   Weapons Officer: Bombarding Mira...  Sensors read 16 armies left.
#  190: WRN->Ka   Weapons Officer: Bombing is ineffective.  Only 3 armies are defending
#  Planet missing message useless. Message changed:
#  new_warning(UNDEF, "Weapons Officer: Bombarding %s... Ineffective, only %d armies defending.",
	    if ($line =~ /Bombarding (\w[\w ]*\w)... .* (\d+) armies/)
	    {
		local ($planet, $armies, $old) = ($1, $2, 0);
		$old = $Planets{$planet}[1];
		if ($old > $armies)
		{
		    $PlayerStats{$Players{$toPlayer}[$nameIdx]}[$tabIdx] += $old - $armies;
		    # print "Bombed: $planet P: $toPlayer O: $old A: $armies B:", $old - $armies, " \n";
		}
		
		$Planets{$planet}[1] = $armies;
	    }


	}

	if ( $sender == planet && $dest == team )
	{
#  190: Mira->KLI We are being attacked by Away Capt O8 who is 6% damaged.
	    if ($line =~ /attacked by (\w[\w ]*\w) \w\w who is/)
	    {
		$PlayerStats{$1}[$tpbIdx] ++ ;
	    }

# 1220: Mira->ORI Mira taken over by Away Capt (O8)
	    if ($line =~ /taken over by (\w[\w ]*\w) \(\w\w\)/)
	    {
		$PlayerStats{$1}[$tptIdx] ++ ;
	    }

# 1090: Mira->KLI Mira destroyed by Away Capt (O8)
	    if ($line =~ /destroyed by (\w[\w ]*\w) \(\w\w\)/)
	    {
		$PlayerStats{$1}[$tpdIdx] ++ ;
	    }

	}


    };
 	
    # PLANET: Deneb's armies have increased to 20
    # PLANET: El Nath's armies have been reduced to 5
    if ( /^PLANET: (\w[\w ]*\w)'s armies have (.*) to (\d+)\s*$/ )
    {
	$Planets{$1}[1] = $3;    # Planet pop, plaque or other army change
	# print "Planet: $1 A: $3 \n";
    }

};

format STDOUT_TOP =
                      Vanilla INL robot PW stats

Home: @||  @>  @<<<<<<<<<<<<<<<<<<<<<<<
      $homeRace, $homePlanets, $homeName
Away: @||  @>  @<<<<<<<<<<<<<<<<<<<<<<<
      $awayRace, $awayPlanets, $awayName

   Player       tek def tpd tpt tpb tab tac cak eao eck pck acc    Login
------------------------------------------------------------------------------
.

format STDOUT =
@<<@<<<<<<<<<<<@>>>@>>>@>>>@>>>@>>>@>>>@>>>@>>>@>>>@>>>@>>>@>>> @<<<<<<<<<<<<<<<
$race,$name, $tek,$def,$tpd,$tpt,$tpb,$tab,$tac,$cak,$eao,$eck,$pck,$acc,$who
.

for (sort(keys(%PlayerStats))) 
{
    $name = $_;
    $tek  = $PlayerStats{$_}[$tekIdx];
    $def  = $PlayerStats{$_}[$defIdx];
    $tab  = $PlayerStats{$_}[$tabIdx];
    $eao  = $PlayerStats{$_}[$eaoIdx];
    $tac  = $PlayerStats{$_}[$tacIdx];
    $cak  = $PlayerStats{$_}[$cakIdx];
    $tpt  = $PlayerStats{$_}[$tptIdx];
    $tpd  = $PlayerStats{$_}[$tpdIdx];
    $tpb  = $PlayerStats{$_}[$tpbIdx];
    $eck  = $PlayerStats{$_}[$eckIdx];
    $acc  = $PlayerStats{$_}[$accIdx];
    $pck  = $PlayerStats{$_}[$pckIdx];
    $who  = $PlayerStats{$_}[$whoIdx];
    $race = $PlayerStats{$_}[$raceIdx];

    write;

}
