Log Files

From WinBolo

Jump to: navigation, search

Winbolo log files are server recorded files that allow a game to be replayed via the Log Viewer application.

Contents

File Format

Design

The log file format design concept is similar to a video compression code that uses Keyframes. In the log file. A snapshot is equivalent to a key frame and the events are the changes between key frames.

A deficiency with this file format is it is not easy to go back a single event or a group of events, only to go back to the last snapshot.

bolo/log.c handles most of the log file preparation and creation.

logWriteTick() is called every game tick to write log data. Data for the log file is gathered using the same functions used to prepare data for drawing the main screen by a game client, however it is collected for the entire map rather then the immediate visible area.

logWriteSnapshot() is called every 30 seconds (600 ticks) to create a new snapshot.


Overview

Log files are stored in a zip compressed file with the extension of wlg. The zip file contains a single file log.dat which contains the log file data encrypted using XOR with a rotating key.

The file format could be described as a finite state machine that follows the following

<HEADER> -> <SNAPSHOT> -> (<STATE> or <SNAPSHOT> repeated) -> <QUIT>

(Replace above with state diagram)

The list of log states that are stored in the log file are located in bolo/log.h. The are:

#define LOG_QUIT 0
#define LOG_NOEVENTS 1
#define LOG_NOEVENTS_LONG 2
#define LOG_EVENT 3
#define LOG_EVENT_LONG 4
#define LOG_EVENT_SNAPSHOT 5

The first byte of each state determines the state type.


Header

The header of the log file is as followed

  • 8 byte header WBOLOMOV
  • 1 byte version number (currently 0)
  • Map name as Pascal String
  • 1 byte Game Type
  • 1 byte boolean allow hidden mines setting
  • 1 byte AI Type
  • 1 byte boolean password used
  • 1 byte maximum number of players in the game
  • 1 byte WinBolo major version number
  • 1 byte WinBolo minor version number
  • 1 byte WinBolo revision version number
  • 4 bytes server IP address (sprintf(serverIP, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);)
  • 2 bytes server port in host network byte order
  • 4 bytes game creation time in network byte order
  • 32 byte WBN server key (all 0's for non participating servers)


The last byte of the creation time (network byte order) becomes the first encryption key.

The header must be immediately followed by a snapshot. From this point on the data in the log file is XOR'd with the current encryption key.

Snapshot

The snapshot event of the log file contains the following data:

  • 4 bytes game start delay in network byte order
  • 4 bytes game time remaining in network byte order
  • 1 byte data length of pillbox network data
    • For each pillbox in the game
    • 1 byte map position X location
    • 1 byte map position Y location
    • 1 byte owner
    • 1 byte speed
    • 1 byte in tank boolean
  • 1 byte data length of base network data
    • For each base in the game
    • 1 byte map position X location
    • 1 byte map position Y location
    • 1 byte owner
    • 1 byte armour
    • 1 byte shells
    • 1 byte mines
  • 1 byte data length of starts network data
    • For each start in the game
    • 1 byte map position X location
    • 1 byte map position Y location
    • 1 byte direction
  • Bolo Map Runs of entire map (See map file format)
  • Data for each 16 tank slots:
    • First byte data length
    • If the data length is two player slot is empty
    • 1 byte tank map position X location
    • 1 byte tank map position Y location
    • 1 byte tank pixel X/Y position (High nibble x)
    • 1 byte tank frame (0-15 direction)
    • 1 byte boolean tank on boat
    • 1 byte LGM map position X location
    • 1 byte LGM map position Y location
    • 1 byte LGM pixel X/Y position (High nibble x)
    • 1 byte LGM frame
    • Player name as Pascal String
    • Player location as Pascal String
    • 1 byte number of allies
    • [number of allies] bytes for representing other players in this alliance

Log No Events

States LOG_NO_EVENTS and LOG_NOEVENTS_LONG are two states to indicate nothing happens on the log file for the next X ticks.

For LOG_NO_EVENTS the next byte indicates the number of ticks there are no events. For LOG_NO_EVENTS_LONG the next 2 bytes indicates the number of ticks there are no events. This is stored as a short in network byte order.


Log Events

States LOG_EVENTS and LOG_EVENTS_LONG are two states to indicate one or more events happens in this tick

For LOG_EVENTS the next byte indicates the number events that happen. For LOG_EVENTS_LONG the next 2 bytes indicates the number of events that happen in this tick. This is stored as a short in network byte order.

Each even has a variable number of bytes of data. For more information see the function screenProcessLog() in logviewer/screen.c

After processing the data associated with each event. The XOR key is updated to the event type byte.

The list of possible log items that are stored in the log file are located in bolo/log.h. The are:

/* The events we record in our log file */
typedef enum {
log_PlayerJoined=1,
log_PlayerQuit,
log_PlayerLocation,
log_LgmLocation,
log_MapChange,
log_Shell,
log_SoundBuild,
log_SoundFarm,
log_SoundShoot,
log_SoundHitTank,
log_SoundHitTree,
log_SoundHitWall,
log_SoundMineLay,
log_SoundMineExplode,
log_SoundExplosion,
log_SoundBigExplosion,
log_SoundManDie,
log_MessageServer,
log_MessageAll,
log_MessagePlayers,
log_ChangeName,
log_AllyRequest,
log_AllyAccept,
log_AllyLeave,
log_BaseSetOwner,
log_BaseSetStock,
log_PillSetOwner,
log_PillSetHealth,
log_PillSetPlace,
log_PillSetInTank,
log_SaveMap,
log_LostMan,
log_KillPlayer,
log_PlayerRejoin,
log_PlayerLeaving,
log_PlayerDied
} logitem;
Personal tools