SkillAgentSearch skills...

Tf2logparser

A log parser for the game Team Fortress 2, written in Javascript for use with node.js. It retrieves stats and game events, and then outputs the data to JSON format.

Install / Use

/learn @barncow/Tf2logparser
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

tf2logparser v0.2.0

A log parser for the game Team Fortress 2, written in Javascript for use with node.js. It retrieves stats and game events, and then outputs the data to JSON format.

With Node and NPM installed, you can install using:

npm install tf2logparser

And in the code, use:

var TF2LogParser = require('tf2logparser').TF2LogParser;
var parser = new TF2LogParser(); //need to create a new instance, since this stores state between lines.

//the 'done' event is thrown when processing is complete.
parser.on('done', function(log) {
  //log is the final log object, that contains all stats.
  console.log("Blue Score: %d\nRed Score: %d", log.blueScore, log.redScore);
});

//the 'line' event is thrown when processing for a line is complete.
parser.on('line', function(line) {
  console.log(line);
});

//the 'error' event is thrown when an error is encountered.
parser.on('error', function(err) {
  throw err;
});

//start processing
parser.parseLogFile('blah.log');

Real Time Mode

Real time mode is a way for you to manually feed through lines to the parser. There are some differences between normal log file processing and real time:

  1. No line events are emitted. Since you have to manually call parseLine, it doesn't make sense to emit this event. The done event is still emitted.
  2. parseLine will return what events and positions were added from the given line, called "delta".
  3. The parseLogFile will consider the log file as a complete game, with multiple halves, etc. In real time, there is no good way to determine what should be considered a game, so the done event is fired when a game over occurs or Log file closed is sent to the parser.

How to use:

var TF2LogParser = require('tf2logparser').TF2LogParser;
var parser = new TF2LogParser({isRealTime: true}); //need to create a new instance, since this stores state between lines.

//the 'done' event is thrown when processing is complete.
parser.on('done', function(log) {
  //log is the final log object, that contains all stats.
  console.log("Blue Score: %d\nRed Score: %d", log.blueScore, log.redScore);
});

//the 'error' event is thrown when an error is encountered.
parser.on('error', function(err) {
  throw err;
});

//send a line to the parser - do this for each line
var deltas = parser.parseLine('L 07/11/2011 - 18:45:36: "Target<7><STEAM_0:0:6845279><Red>" spawned as "scout"');
//deltas.events will have an array of event objects for events that occurred in that line.
//deltas.positions will have an array of position objects for positions that occurred in that line.

The tf2logparser Command

This log parser ships with a tf2logparser binary that can be used to generate JSON output from the command line. tf2logparser mylog.log will output the resulting log object from mylog.log to the console. You can save it to a file by doing: tf2logparser mylog.log > mylog.json The resulting JSON, by default, does not contain whitespace, to keep the file small. However, you can make it indented and pretty by doing: tf2logparser mylog.log -p and save it to a file by doing: tf2logparser mylog.log -p > mylog.json

A Note About This File

The following documentation is a work in progress, and will change as time goes on. However, it should be enough to get you going. Also, the code is fairly well documented.

The log Object

The done event from TF2LogParser.parseLogFile returns a log object, which is an object that holds all data about the game that was played. The overall structure is listed below, along with comments. Some properties of the object have more explanation further below.

{
  blueScore: 0, //blue team's score
  redScore: 0, //red team's score
  gameStartTimestamp: null, //the timestamp of when the game started, not necessarily where the log file starts.
  gameEndTimestamp: null, //the timestamp of when the game ends, not necessarily where the log file ends.
  elapsedSeconds: 0, //the number of total seconds, from start to finish
  playableSeconds: 0, //the number of seconds that were played: elapsedSeconds - humiliation rounds - pauses
  mapName: "", //name of the map, if found in the log
  mapType: "cp", //map type. This will only likely be "cp" or "ctf", and will likely be changed in a future release.
  events: [], //events that occurred in the game, such as kills. Expanded further below.
  players: [], //players that were in the game, along with their stats. Expanded further below.
  weapons: [], //a list of all weapons that were in the game. These are their raw names from the log. You will need to use WeaponList.findWeapon() to translate to the actual weapon name and the class (we use the term role to prevent language conflicts), if applicable, that uses it.
  positions: [] //an array of the positions of the players that were in the game, if enabled in the log.
}

The events Property

The events property of the log object is an array of objects that represent kills, point captures, flag events, etc. The format of these objects can differ based on what data they need to carry, however all event objects will all have the type property, that shows what type of event the object represents. They will also have a timestamp, which is the timestamp from the log of when the action occurred, and a elapsedSeconds property, which is the number of seconds from when the game started (useful for doing playback).

The kill Type Event

{
  timestamp: new Date(2010, 8, 29, 19, 14, 43, 0), //when the event occurred in the log
  elapsedSeconds: 347, //number of seconds that this event occurred from the start of the game
  type: 'kill', //type of event
  //"player" and "victim" are the player that attacked, and the player that died, respectively.
  player: {
    name: 'Ctrl+f Muffin!', //name of the player
    userid: 50, //server userid of the player
    steamid: 'STEAM_0:1:9852193', //steamid of the player
    team: 'Red', //current team of the player
    position: {x: -2771, y: 1546, z: -295}, //the in-game coordinates of the player when the action occurred.
    role: { key: 'sniper', name: 'Sniper' } //the class of the player when performing the action. "key" is how the class is referred to in the log, and "name" is a more human-readable format.
  },
  victim: {name: 'Target', userid: 46, steamid: 'STEAM_0:0:6845279', team: 'Blue', position: {x: -3308, y: 1790, z: -220}, role: { key: 'scout', name: 'Scout' }},
  assister: false, //if false, there was no player that had an assist for this kill. Otherwise, there would be a full player object, just like the "player" and "victim" objects above.
  weapon: 'sniperrifle_hs', //the raw weapon name from the log, except that for headshots, "_hs" is appended, and for backstabs, "_bs" is appended. Use WeaponList.findWeapon() to translate to the actual weapon name and the class.
  customKill: 'headshot' //if false, no extra information. Otherwise this will be "headshot", "backstab", or "feign_death" (spy using Dead Ringer).
}

(more events to be added)

The players Property

The players property of the log object is an array of objects that represent the players that were in the game, along with their stats. Below is an example object.

{
  name: 'FSTNG! Barncow', //current name of the player
  userid: 53, //the player's current server userid
  steamid: 'STEAM_0:1:16481274', //the player's steam id
  team: 'Blue', //the player's current team
  friendid: '76561197993228277', //the player's friend id (for example, http://steamcommunity.com/profiles/76561197993228277)
  joinedGame: Date(2010, 8, 29, 19, 8, 56, 0), //when the player joined the game, either when the game starts, or afterwards.
  role: {
    key: 'medic', //the player's current class, as the log refers to it
    name: 'Medic' //the player's current class, in a more human-readable form
  },
  damage: 0, //the amount of damage that a player has done to other players
  online: true, //whether or not the player is still in the game
  kills: 0,
  deaths: 2,
  assists: 0,
  longestKillStreak: 0, //highest number of kills without a death
  longestDeathStreak: 2, //highest number of deaths without a kill
  headshots: 0,
  backstabs: 0,
  pointCaptures: 0,
  pointCaptureBlocks: 0,
  flagDefends: 0,
  flagCaptures: 0,
  dominations: 0,
  timesDominated: 0,
  revenges: 0,
  extinguishes: 0, //number of times that a player put out another player on fire
  ubers: 1,
  droppedUbers: 1,
  healing: 2310,
  medPicksTotal: 0, //total number of medics killed
  medPicksDroppedUber: 0, //number of medics killed, where the medic dropped their uber
  position: { x: -3308, y: 1790, z: -220 }, //current position of the player
  roleSpread: { //the classes that the player played, along with the number of seconds that they played it
    'medic': {
      key: 'medic',
      name: 'Medic',
      secondsPlayed: 1666
    }
  },
  itemSpread: { //the items that a player picked up
    medkit_small: 2,
    medkit_medium: 1
  },
  healSpread: { //the amount of healing done to each player
    'STEAM_0:0:8581157': {
      name: 'Cres',
      steamid: 'STEAM_0:0:8581157',
      healing: 72
    },
    'STEAM_0:0:6845279': {
      name: 'Target',
      steamid: 'STEAM_0:0:6845279',
      healing: 27
    }
  },
  weaponSpread: {  //weapons that this player killed with and/or died from
    'scattergun': {
      key: 'scattergun',
      kills: 0,
      deaths: 1
    },
   'sniperrifle': {
      key: 'sniperrifle',
      kills: 0,
      deaths: 1
    }
  },
  playerSpread: { //players that this player killed and/or died from
    'STEAM_0:0:6845279': {
        name: 'Target',
        steamid: 'STEAM_0:0:6845279',
        kills: 0,
        deaths: 1
    },
    'STEAM_0:1:9852193': {
      name: 'Ctrl+f Muffin!',
      steamid: 'STEAM_0:1:9852193',
      kills: 0,
      deaths: 1
    }
  }
}

The positions Property

This holds the positions of players, if the

View on GitHub
GitHub Stars22
CategoryDevelopment
Updated3y ago
Forks4

Languages

JavaScript

Security Score

60/100

Audited on Jun 5, 2022

No findings