Gamestat.txt

From Soldat Community Wiki
Jump to: navigation, search

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.

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;
}