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> </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 = " ";
}
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>