Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/saul/demofile

Node.js library for parsing Counter-Strike: Global Offensive demo files
https://github.com/saul/demofile

analysis counter-strike csgo demo parser

Last synced: 2 months ago
JSON representation

Node.js library for parsing Counter-Strike: Global Offensive demo files

Awesome Lists containing this project

README

        

# demofile ![npm](https://img.shields.io/npm/v/demofile) ![CI](https://github.com/saul/demofile/workflows/CI/badge.svg)

A node.js library for parsing Counter-Strike Global Offensive (CSGO) demo files.
The library is also Browserify-able, and a standalone bundle that you can `` is available in [browser/bundle.js](browser/bundle.js).

This library also supports streaming from [GOTV broadcasts](https://developer.valvesoftware.com/wiki/Counter-Strike:_Global_Offensive_Broadcast) over HTTP, with `DemoFile#parseBroadcast`.

> ⚠️ This library requires Node v14 or later.

### ❓ Need help

- First, search the ['Questions' discussion board](https://github.com/saul/demofile/discussions/categories/questions) - your question has probably already been asked.
- If not, [start a new 'Questions' discussion](https://github.com/saul/demofile/discussions/new?category=questions).
- If you think you've found a bug, [raise an issue](https://github.com/saul/demofile/issues/new/choose).

## Supported demo features

- GOTV and POV perspective fully supported
- Game events (e.g. `player_death`)
- User messages (e.g. chat messages, HUD text)
- Console variables (cvar/convars)
- Entity updates, server classes, data tables
- String tables
- Reading encrypted messages (e.g. chat in public matchmaking demos)
- Streaming from [GOTV broadcasts over HTTP](https://developer.valvesoftware.com/wiki/Counter-Strike:_Global_Offensive_Broadcast)

## Running the examples

Getting started is simple:

```bash
.../demofile$ npm ci
.../demofile$ cd examples
.../demofile/examples$ npm ci
```

You can now run the example scripts. Take a look in the [`examples`](https://github.com/saul/demofile/tree/master/examples) folder for some scripts to try out. Detailed descriptions of these scripts can be found below in the [Examples](#examples) section below.

If you don't have any demo files to hand, use the `demos/download.sh` Bash script to download the ones used for testing.

```bash
.../demofile/examples$ npx ts-node dumpfile.ts ../demos/pc419-vs-chiefs-mirage.dem
npx: installed 14 in 1.883s
Demo header: {
magic: 'HL2DEMO',
protocol: 4,
networkProtocol: 13753,
serverName: 'Counter-Strike: Global Offensive',
clientName: 'GOTV Demo',
mapName: 'de_mirage',
gameDirectory: 'csgo',
playbackTime: 2569.375,
playbackTicks: 328880,
playbackFrames: 164271,
signonLength: 433479
}
...
```

## Installation

### Node

```bash
npm install --save demofile
```

### Browser

```html
<script src="browser/bundle.js">
```

The `DemoFile` module will be available as `window.demofile`.

## Screenshot

Using the [dumpfile example](https://github.com/saul/demofile/blob/master/examples/dumpfile.ts):

![Example output](./example.png)

## Documentation

Auto-generated API documentation is available at [saul.github.io/demofile](https://saul.github.io/demofile).

| Class | Description |
| ----------------------------------------------------------------- | ----------------------------------- |
| [DemoFile](https://saul.github.io/demofile/classes/DemoFile.html) | Represents a demo file for parsing. |

The _DemoFile_ object has properties which point to instances of several other classes that can be used to inspect and listen to changes in the game world:

| Class | Property | Description |
| ------------------------------------------------------------------------- | ----------------------- | -------------------------------------------------------------------------------------- |
| [ConVars](https://saul.github.io/demofile/classes/ConVars.html) | `demoFile.conVars` | Manages console variables. (Only `FCVAR_NOTIFY` and `FCVAR_REPLICATED` are available.) |
| [Entities](https://saul.github.io/demofile/classes/Entities.html) | `demoFile.entities` | Represents entities and networked properties within a demo. |
| [GameEvents](https://saul.github.io/demofile/classes/GameEvents.html) | `demoFile.gameEvents` | Manages game events for a demo file. (e.g. `player_death`, `bomb_defused`) |
| [StringTables](https://saul.github.io/demofile/classes/StringTables.html) | `demoFile.stringTables` | Handles string tables for a demo file. (e.g. `userinfo`) |
| [UserMessages](https://saul.github.io/demofile/classes/UserMessages.html) | `demoFile.userMessages` | Handles user messages for a demo file. (e.g. `SayText` for in-game chat messages) |

There are several classes which allow access to different types of entities (e.g. players, items, props). These are summarised below:

| Entity | Usage | Description |
| ----------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| [Networkable](https://saul.github.io/demofile/classes/Networkable.html) | `demoFile.entities.getByHandle`
`demoFile.entities.entities.get(entIndex)` | Base class of all in-game entities, even non-renderable entities (e.g. `CCSTeam`). |
| [BaseEntity](https://saul.github.io/demofile/classes/BaseEntity.html) | | Base class of the vast majority of in-game entities (e.g. players, weapons, all other renderable entities). |
| [Player](https://saul.github.io/demofile/classes/Player.html) | `demoFile.entities.players`
`demoFile.entities.getByUserId` | Represents an in-game player. |
| [Team](https://saul.github.io/demofile/classes/Team.html) | `demoFile.entities.teams`
`player.team` | Represents a team (terrorists, counter-terrorists, spectators). |
| [Weapon](https://saul.github.io/demofile/classes/Weapon.html) | `demoFile.entities.weapons`
`player.weapon`
`player.weapons` | Represents an in-game weapon (guns, grenades, knifes). |
| [Projectile](https://saul.github.io/demofile/classes/Projectile.html) | | Represents a thrown grenade projectile (e.g. a flying smoke grenade). |
| [GameRules](https://saul.github.io/demofile/classes/GameRules.html) | `demoFile.gameRules` | Represents the game rules and parts of the match state (e.g. round number, is warmup) |

## API

This library provides full access to all data available in CSGO demo files. Unlike some other libraries, `demofile` is feature complete and supports the latest demos. As well as providing high-level APIs to access the state of the game, low-level access is available and is not discouraged.

Note that events are fired at the end of a tick, after all entity props and string tables have been updated.

### Examples

Various examples are available in the `examples` folder:

| Example | Description |
| ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| [`join-leave.ts`](https://github.com/saul/demofile/blob/master/examples/join-leave.ts) | Print all players that join and leave the game during the course of the demo. |
| [`molotov.ts`](https://github.com/saul/demofile/blob/master/examples/molotov.ts) | Prints the location of molotov/incendiary grenade explosions. |
| [`paintkits.ts`](https://github.com/saul/demofile/blob/master/examples/paintkits.ts) | Collects paint kits of each weapon that is used in a kill. |
| [`plant-site.ts`](https://github.com/saul/demofile/blob/master/examples/plant-site.ts) | Prints which player planted the bomb and at which site. |
| [`purchases.ts`](https://github.com/saul/demofile/blob/master/examples/purchases.ts) | Prints which items are purchased by each player. |
| [`rank.ts`](https://github.com/saul/demofile/blob/master/examples/rank.ts) | At the end of the game, prints all player ranks. |
| [`scores.ts`](https://github.com/saul/demofile/blob/master/examples/scores.ts) | Prints team scores after each round. |
| [`tickrate.ts`](https://github.com/saul/demofile/blob/master/examples/tickrate.ts) | Prints demo tick rate and duration in seconds. |
| [`trajectory.ts`](https://github.com/saul/demofile/blob/master/examples/trajectory.ts) | Prints grenade trajectories and who threw them. |
| ⚠ Advanced: [`dumpfile.ts`](https://github.com/saul/demofile/blob/master/examples/dumpfile.ts) | Advanced example of recreating coloured chat messages, round scores and the kill feed. |

#### Print kills

```js
const fs = require("fs");
const demofile = require("demofile");

const demoFile = new demofile.DemoFile();

demoFile.gameEvents.on("player_death", e => {
const victim = demoFile.entities.getByUserId(e.userid);
const victimName = victim ? victim.name : "unnamed";

// Attacker may have disconnected so be aware.
// e.g. attacker could have thrown a grenade, disconnected, then that grenade
// killed another player.
const attacker = demoFile.entities.getByUserId(e.attacker);
const attackerName = attacker ? attacker.name : "unnamed";

const headshotText = e.headshot ? " HS" : "";

console.log(`${attackerName} [${e.weapon}${headshotText}] ${victimName}`);
});

demoFile.parseStream(fs.createReadStream("test.dem"));

/* Outputs:

HS [cz75a HS] flusha
Lekr0 [ak47 HS] friberg
KRIMZ [ak47] HS
JW [mac10 HS] Mixwell
JW [hegrenade] HS
JW [mac10 HS] Magisk

*/
```

#### Print player information when it changes

```js
const fs = require("fs");
const demofile = require("demofile");

const demoFile = new demofile.DemoFile();

demoFile.stringTables.on("update", e => {
if (e.table.name === "userinfo" && e.userData != null) {
console.log("\nPlayer info updated:");
console.log(e.entryIndex, e.userData);
}
});

demoFile.parseStream(fs.createReadStream("test.dem"));

/* Outputs:

Player info updated:
0 {
xuid: Long { low: 0, high: 0, unsigned: false },
name: 'ESEA SourceTV',
userId: 2,
guid: 'BOT',
friendsId: 0,
friendsName: '',
fakePlayer: true,
isHltv: false
}

Player info updated:
1 {
xuid: Long { low: 32578248, high: 17825793, unsigned: false },
name: 'PC419 m0nt-S-',
userId: 3,
guid: 'STEAM_1:0:16289124',
friendsId: 32578248,
friendsName: '',
fakePlayer: false,
isHltv: false
}

[repeated for other players]
*/
```

### Useful links

- [CS:GO Game Events - AlliedModders Wiki](https://wiki.alliedmods.net/Counter-Strike:_Global_Offensive_Events)

## Contributing

Please read the [Contributing Guidelines](./CONTRIBUTING.md) to learn how you can help out on the project.