View Single Post
  #5  
Old July 21st, 2004, 08:36 PM

BugRoger BugRoger is offline
Corporal
 
Join Date: Jan 2004
Location: Berlin, Germany
Posts: 64
Thanks: 0
Thanked 0 Times in 0 Posts
BugRoger is on a distinguished road
Default Re: Anyone managed to redirect linux server output?

Here's the code I'm currently using for running and logging my games. Maybe you can salvage the redirection code... It's a modified Version of Mose's domwatcher script. It creates a log file and a special status file that I use for creating a game status page.

PS: Mose, I hope you don't mind me posting this...

code:
#!/usr/bin/perl -w

my %nations = (
Aby => "Abysia",
Atl => "Atlantis",
Py => "Pythium",
Man => "Man",
Ul => "Ulm",
Ct => "C\'tis",
Arc => "Arcoscephale",
Ca => "Caelum",
Er => "Ermor",
Mar => "Marignon",
Pa => "Pangaea",
Va => "Vanheim",
Jo => "Jotunheim",
Rl => "R\'lyeh",
Mi => "Mictlan",
Ti => "T\'ien Ch\'i",
Mac => "Machaka"
);


sub playgame {
my $gamename = "CradleOfDoom";
my $playerCount = 10;

# generate command
my $command = "dom2 --postexec /usr/local/games/dominions2/notification_CradleOfDoom --tcpserver --port 6666 --noclientstart --mapfile cradle.map --textonly --quickhost --minutes 2880 -d $gamename";

# Fork off server
use IO::Pty; # This stuff is brilliant!
use POSIX ":sys_wait_h"; # WNOHANG

my $master = new IO::Pty;
my $pid = fork;
die "Failed to fork: $!" unless (defined($pid));
unless ($pid) {
#child
$master->make_slave_controlling_terminal();
select STDOUT; $| = 1; # make unbuffered
$fh = $master->slave->fileno;
open(STDOUT, ">&$fh") or die "Unable to redirect STDOUT: $!";

exec($command) or die "Failed to execute ($command)";
}
$master->close_slave();

open(LOG, ">>$gamename.log") or die "Failed to $gamename.log: $!";
open(STDERR, ">&LOG");
open(STDOUT, ">&LOG");

select LOG; $| = 1;
print LOG "domlogger Version 0.1 started\n";
print LOG "$command\n";

#The game is well startet...record pid
print LOG "pid=$pid\n";


my $server_quit = 0;
my $turn = -1;
my $timeleft = -1;
my $waitingFor = -1;
my $playersConnected = 0;
my $turnsTaken = 0;

PLAY_GAME: while (!$server_quit) {
if ($pid == waitpid($pid, WNOHANG)) {
$server_quit = 1;
print LOG "Server quit, exiting\n";
`beep -r 2 -f 300 -l 1000`;
Last;
}

my $nextLineIsGameStatus = 0;
while (<$master>) {
print LOG $_;

if ($nextLineIsGameStatus) {
my $currentlyConnected = 0;
my $currentlyTakenTurns = 0;

open(STATUS, ">$gamename.stats") or die "Failed to create $gamename.stats: $!";
print STATUS "$pid\n";
print STATUS "$gamename\n";
print STATUS "$turn\n";
print STATUS "$timeleft\n";

@nat = split;
for $nat (@nat) {
my ($computer_controlled, $connected, $shortName, $waiting_for) = $nat =~/(\(?)(\*?)(\w+)\)?([+-]?)/;
$waiting_for = ($waiting_for eq '-') ? 1 : 0;
$connected = ($connected eq '*') ? 1 : 0;
$computer_controlled = ($computer_controlled eq '(') ? 1 : 0;
$nationLongName = $nations{$shortName};

if ($connected) {
$currentlyConnected += 1;
}

if (!$waiting_for) {
$currentlyTakenTurns += 1;
}

print STATUS "$shortName $nationLongName $waiting_for $connected $computer_controlled\n";
}

close(STATUS);

if ($currentlyConnected != $playersConnected) {
$playersConnected = $currentlyConnected;
`beep -r $playersConnected -l 10 -f 100`;
}

if ($currentlyTakenTurns != $turnsTaken) {
$turnsTaken = $currentlyTakenTurns;
my $beeps = $playerCount - $turnsTaken;
`beep -r $beeps -l 10`;
}


$nextLineIsGameStatus = 0;
} else {
if (/^fatherturn/) {
($turn) = /^fatherturn (.*\S)\s*$/;
next;
}

if (/^$gamename/) {
$nextLineIsGameStatus = 1;

($timeleft, $unit) = /Time (\d+)(\w)/;
if (defined($timeleft) && defined($unit)) {
$timeleft *= 60 if ($unit eq 'h');
}

next;
}

if (/^\s*Generating next turn\s*$/) {
`beep -r 3`;
}

}

}
}




# Game has ended (or server crashed)
print LOG "Update game status to ended\n";
close(LOG);
}

playgame();

And this is the script that generates the status page out of the statsfile. You can see it in action on http://cradleofdoom.dyndns.org/gamestatus/

code:
  
<?php
$gameName = "CradleOfDoom";
$stats = file($gameName . ".stats");
$modified = stat($gameName . ".stats");
$modifiedDate = date("l dS of F Y h:i:s A",$modified[9]);

$pid = $stats[0];
$isServerOnline = exec("ps aux | awk '{print $2}' | grep -c $pid");
?>

<html>
<head>
<title><?php echo $stats[1] ?> - Turn <?php echo $stats[2] ?></title>
<meta http-equiv="refresh" content="60; URL=http://cradleofdoom.dyndns.org/gamestatus/">
<style>
body {
background: #222;
font-family: Arial, sans-serif;
color: #eee;
}

#status {
color: #000;
border: 2px solid #99835C;
background: url(bg.gif);
}

#status td {
padding: 5px 10px 5px 10px;
border-top: 1px solid #FFF1C5;
border-bottom: 1px solid #99835C;
}

#status th {
padding: 5px 30px 5px 10px;
border-bottom: 1px solid #99835C;
}

th {
text-align: left;
}


</style>
</head>
<body>

<h1><?php echo $stats[1] ?> - Turn <?php echo $stats[2] ?></h1>


<table id="status" cellpadding="0" cellspacing="0">
<tr>
<th>&nbsp;</th>
<th>Nation</th>
<th>Turn Taken</th>
<th>Connected</th>
</tr>
<?php
for ($i=4; $i < count($stats); $i++) {
list($short, $long, $waiting, $connected, $ai) = split(" ", $stats[$i]);

if ($waiting) {
$waiting = "has <b>not</b> played its turn";
} else {
$waiting = "has played its turn";
}

if ($connected) {
$connected = "currently connected";
} else {
$connected = "&nbsp;";
}

if ($ai == 1) {
$waiting = "is computer controlled";
}
?>
<tr>
<td><img src="unwise_flags/<?php echo strtolower($short) ?>_icon.gif" alt=""></td>
<td><?php echo $long ?></td>
<td><?php echo $waiting ?></td>
<td><?php echo $connected ?></td>
</tr>
<?php
}
?>
</table>
<br />
<table>
<tr>
<th>Server status:</th>
<td><?php if ($isServerOnline) echo "Online"; else echo "offline"; ?></td>
</tr>
<tr>
<th>Forced host in:</th>
<td><?php echo $stats[3] ?> minutes</td>
</tr>
<tr>
<th>Last update:</th>
<td><?php echo $modifiedDate ?> CEST</td>
</tr>
</table>

</body>
</html>

Reply With Quote