#!/usr/bin/perl -w
# WAB - the Wolfenstein Admin Bot
# An administration assistant for Return to Castle Wolfenstein Multiplayer
# server admins.  See http://www.castlewolfenstein.com/ for more infor
# on this excellent game.
#
# Copyright (C) 2001 Brett A. Thomas <quark@baz.com>.  All rights reserved.
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
# 
# Email quark@baz.com with questions, comments and patches, and
# especially see the WAB homepage at http://www.baz.com/quark/software/wab/

use strict;
use IO::Socket;
use Symbol;
use Carp;
use Wab;

my %Args = ("daemonize" => 1,
	    "do_stat" => 1,
	    "read_log" => 1,
	    "test_mode" => 0, #1 means nothing that will actually change game state
	    "logfile_test" => undef,
	    "config_file" => "wab.cfg",
	    "debug" => 0);

my %Switches = ("d,daemonize", {"type" => "binary",
		      "action" => "daemonize=0"},
		"D,debug", {"type" => "binary",
		      "action" => "debug=1"},
		"t,test_mode", {"type" => "binary",
				"action" => "test_mode=1"},
		"no_stat", {"type" => "binary",
			    "action" => "no_stat=1"},
		"c,config" => {"type" => "string",
				    "action" => "config_file"},
		"h,help" => {"type" => "binary",
			     "action" => "help=1"},
		"logfile_test" => {"type" => "string",
				   "action" => "logfile_test"});

my $Wab = Wab->new();

my ($Result, $Args) = $Wab->ParseArgs(\%Args, \%Switches, @ARGV);

if(defined($Result))
{
    print "$Result\n";
    $Args->{"help"} = 1;
}

if($Args->{"help"})
{
    ShowHelp();
    exit 0;
}

$Wab->MergeArgs($Args);

if($Wab->{Config}{"#args"}{"daemonize"})
{
    if(fork())
    {
	#We're parent, exit:
	exit 0;
    }
}

my $Platform = DetectOS();

if($Platform =~ /linux/i)
{
    $SIG{HUP} = sub {$Wab->ReloadConfig(1)};
    $SIG{USR1} = sub {$Wab->DumpState()};
}

my $Err;

do
{
    #Do we need to reload the config file?
    if($Wab->ReloadConfig())
    {
	#Yup.  Let's close everything out and reset:
	$Wab->ServerDisconnect();
	$Wab->CloseGameLogFile();
	$Result = $Wab->
	    LoadConfigFile($Wab->{Config}{"#args"}{"config_file"});
	if(defined($Result))
	{
	    die "$Result\n";
	}
	
	$Err = $Wab->OpenGameLogFile();
	die "Can't open game logfile:\n$Err\n"
	    if($Err);

	$Err = $Wab->ServerConnect();
	die "Can't connect to server:\n$Err\n"
	    if(defined($Err));

	#Seed things:
	$Wab->Stat();

	$Wab->ReloadConfig(0)
    }

    #Get log backup.  If there isn't any backlog, this will block until
    #there is, or we need to connect to the server on the OOB channel
    my @LogBuffer = ($Wab->GetLogBacklog());

    if((@LogBuffer) && ($Wab->Continue()))
    {
	$Wab->ProcessLog(@LogBuffer);
    }

    $Wab->TakeAction();

    #This sends the MOTD if we haven't lately:
    $Wab->MOTD();

    #And, finally, stat the server ocassionally to make sure we're not
    #smoking crack about the game state:
    $Wab->PeriodicStat();
}while($Wab->Continue());

$Wab->ServerDisconnect();
$Wab->CloseGameLogFile();

exit 0;	     

sub ShowHelp
{
    print STDERR "wab [-d|--daemonize] [-t|--test] [--no_stat]\n";
    print STDERR "    [-c|--config <config_file>] [-h|--help]\n";
}

sub DetectOS
{
    my $Platform = "Windows";
    my $Proc = gensym();
    if(opendir($Proc, "/proc"))
    {
	$Platform = "Linux";
	close($Proc);
    }
    
    return($Platform);
}
