Gamestat.txt
gamestat.txt is one of the five log files that the server writes to when Logging is set to 1 in the soldat.ini file. It is, like the rest of the logs, a plain ASCII text file, exploded by new line characters (\r\n). The update rate is set by the variable LogFilesUpdate set in soldat.ini.
Contents
Format
In-Game Statistics [!] Header Players: n [!] Number of players, n being an unsigned int Map: map_name [!] Map name, without path or extension, case sensitive Gamemode: game_mode [!] Gamemode, game_mode being a string: "Deathmatch,TeamDeathmatch,Capture the Flag,Hold the Flag,Infiltration or Pointmatch" Timeleft: m:s [!] m = minutes & s = seconds (unsigned ints, without leading zeros, standard time) Team 1: n [!] Score for the team, unsigned int n. Shows only if Gamemode is team-based Team 2: n [!] Score for the team, unsigned int n. Shows only if Gamemode is team-based Team 3: n [!] Score for the team, unsigned int n. Shows only if Gamemode is team-based Team 4: n [!] Score for the team, unsigned int n. Shows only if Gamemode is team-based Players list: (name/kills/deaths/team/ping) player_name [!] string with the player's nick player_points [!] unsigned int holding the player's points (kills and caps/scores added) player_deaths [!] unsigned int with the player's deaths player_team [!] unsigned int with the player's team (Alpha=1,Bravo=2,Charlie=3,Delta=4) [!] Repeats for each player
Example request
[!] to Server STARTFILES\r\n logs/gamestat.txt\r\n ENDFILES\r\n [!] from Server STARTFILES\r\n <total size of all files as 4 byte integer> [!] equals to gamestat.txt size, as we requested only 1 file logs/gamestat.txt\r\n <size of gamestat as 4 byte integer> <gamestat data>\r\n ENDFILES\r\n
Example gamestat.txt from a CTF server
In-Game Statistics Players: 6 Map: ctf_B2b Gamemode: Capture the Flag Timeleft: 9:19 Team 1: 0 Team 2: 0 Team 3: 0 Team 4: 0 Players list: (name/kills/deaths/team/ping) Gaurdian/Nw 2 0 2 50 =AeG= Taimaishu 1 0 1 66 .:|EN|:. Arato 1 1 2 50 T1X: Zero Static 1 1 1 250 Vox\\Control 0 1 2 50 ]{inG 0 2 1 66
Example parsers
PHP
<?php
$file = "out/server/logs/gamestat.txt";
$contents = file($file);
$players = str_replace("Players: ", "", $contents[1]);
$map = str_replace("Map: ", "", $contents[2]);
$mode = str_replace("Gamemode: ", "", $contents[3]);
$timeleft = str_replace("Timeleft: ", "", $contents[4]);
$alpha = str_replace("Team 1: ", "", $contents[5]);
$bravo = str_replace("Team 2: ", "", $contents[6]);
echo "<u>Gamestat.txt information</u><br>";
echo "Players: $players<br>";
echo "Mode: $mode<br>";
echo "Map: $map<br>";
echo "Timeleft: $timeleft<br>";
echo "Alpha: $alpha <br>";
echo "Bravo: $bravo<br>";
echo "<br><u>Players Online</u><br>";
echo "(Name / Points / Deaths / Ping)<br>";
for($i = 0; $i < $players; $i++) {
$pos = 10 + ($i * 5);
$name = htmlentities(trim($contents[$pos]));
$points = trim($contents[$pos+1]);
$deaths = trim($contents[$pos+2]);
$team = trim($contents[$pos+3]);
$ping = trim($contents[$pos+4]);
if($team == 1){
echo "<font color=\"Red\">";
}elseif($team == 2){
echo "<font color=\"#3366FF\">";
}else{
echo "<font>";
}
echo $name." / ".$points." / ".$deaths." / " .$ping. "</font><br>";
}
?>
D
// this parser should work with every gamemode (has been tested with CTF, Rambomatch and
// Teamdeatchmatch
struct Server
{
struct Player
{
char[] name;
ushort kills, deaths;
ubyte team;
uint ping;
}
ubyte players;
ushort[4] teamScores;
char[] map, mode, timeleft;
Player[] playerList;
}
// parseGamestat takes the file CONTENTS, not the actual file
Server parseGamestat(char[] stat)
{
Server tmp;
char[][] splitted = std.string.split(stat, "\n");
char[][] players = std.string.split(splitted[1], ": ");
tmp.players = toUbyte(players[1]);
char[][] map = std.string.split(splitted[2], ": ");
tmp.map = map[1];
char[][] mode = std.string.split(splitted[3], ": ");
tmp.mode = mode[1];
char[][] time = std.string.split(splitted[4], ": ");
char[][] timeSplit = std.string.split(time[1], ":");
tmp.timeleft = format("%02s:%02s", timeSplit[0], timeSplit[1]);
ubyte team = 0;
int index = 5;
for (int i = 0; i < getTeamNum(mode[1]); i++)
{
char[][] teamSplit = std.string.split(splitted[index], ": ");
tmp.teamScores[team] = toUshort(teamSplit[1]);
index++;
team++;
}
index++;
for (int i = 0; i < toUbyte(players[1]); i++)
{
Server.Player sp;
sp.name = splitted[index]; index++;
sp.kills = toUshort(splitted[index]); index++;
sp.deaths = toUshort(splitted[index]); index++;
sp.team = toUbyte(splitted[index]); index++;
sp.ping = toUbyte(splitted[index]); index++;
tmp.playerList ~= sp;
}
return tmp;
}
ubyte getTeamNum(char[] gameMode)
{
switch (gameMode)
{
case "Deathmatch":
case "Pointmatch":
case "Rambomatch": return 0;
case "Capture the Flag":
case "Infiltration":
case "Hold the Flag":
case "Teammatch": return 4;
default: return 0;
}
return 0;
}