Giter Site home page Giter Site logo

saul / demofile Goto Github PK

View Code? Open in Web Editor NEW
480.0 480.0 55.0 57.4 MB

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

Home Page: https://demofile.dev

License: MIT License

JavaScript 79.19% HTML 0.03% TypeScript 20.77% Shell 0.01%
analysis counter-strike csgo demo parser

demofile's People

Contributors

akiver avatar alexhelkar avatar bitdesert avatar dependabot[bot] avatar gitter-badger avatar negezor avatar pedrofornaza avatar razor-x avatar saul avatar thecatontheflat avatar thorebear avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

demofile's Issues

Finding the "thrower" of a molo/incin for inferno_startburn events

Hey Saul; thanks so much for the awesome lib and all the effort you put in!

I've been working on something to parse demos and get all the he/smoke/flash/molo/incin data. For all the others it's been relatively straight forward to match up the start & end locations (of a throw) by getting the event userid on weapon_fire and then matching it up when seeing the corresponding event like flashbang_detonate or hegrenade_detonate.

From what I can tell though there is no userid in the inferno_startburn event? Have I missed something or is there some special trick to finding out who threw a moly/incin in the startburn event?

Thanks in advance!
Nic.

Demo currentTime scale

As the docblock says @returns {float} Number of seconds elapsed. But i did some tests and im almost sure that its miliseconds. Which one is right?

RangeError when parsing ESEA demos

Hey, I got an error when parsing huge demo files (120mb).

I tried same code with a 34mb (old) demo and with a new demo from ESL with 140mb, and in the second case it throws a error on bytebuffer-node:

bytebuffer-node.js:499
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.length);
^

RangeError: Illegal offset: 0 <= 137980764 (+152) <= 137980880
at RangeError (native)
at module.exports.ByteBufferPrototype.readBytes (C:\Users\marce\Desktop\csgo_demoaparser__NEW\node_modules\bytebuffer\dist\bytebuffer-node.js:499:23)
at DemoFile._handleDemoPacket (C:\Users\marce\Desktop\csgo_demoaparser__NEW\demo.js:156:44)
at DemoFile._parseRecurse (C:\Users\marce\Desktop\csgo_demoaparser__NEW\demo.js:271:14)
at tryOnImmediate (timers.js:543:15)
at processImmediate [as _immediateCallback] (timers.js:523:5)

Any ideia on how to solve it?

ESEA Demos with missing playbackTime, ticks, frames & signonLength

Hey mate,

I've got a lot of ESEA demos that appear to be missing the end of the file.

    at ByteBuffer.module.exports.ByteBufferPrototype.readBytes (C:\test\node_modules\bytebuffer\dist\bytebuffer-node.js:499:23)
    at ByteBuffer.readIBytes (C:\test\node_modules\demofile\ext\bytebuffer.js:21:15)
    at DemoFile._handleDemoPacket (C:\test\node_modules\demofile\demo.js:207:31)
    at DemoFile._parseRecurse (C:\test\node_modules\demofile\demo.js:321:16)
    at runCallback (timers.js:794:20)
    at tryOnImmediate (timers.js:752:5)
    at processImmediate [as _immediateCallback] (timers.js:729:5)

demoFile.header returns:

  protocol: 4,
  networkProtocol: 13626,
  serverName: 'Counter-Strike: Global Offensive',
  clientName: 'GOTV Demo',
  mapName: 'de_mirage',
  gameDirectory: 'csgo',
  playbackTime: 0,
  playbackTicks: 0,
  playbackFrames: 0,
  signonLength: 0 }

sv_minupdaterate & sv_maxupdaterate are set to 128 - what is the best way to try to heal the header information?

Wrong players position for POV Demo ?

I recorded a demo from my POV. When I try to get other players position when an event is fired, I got mine, is that a correct behavior ?


 var player = demo.entities.getByUserId(e.userid);
            console.log(player.name);

            if (isWeaponMonitored(e.weapon) !== -1) {
                var position = player.position;
                console.log(position);

Displays :

Agouha 
{ x: 1257.800048828125, y: -229.25465393066406, z: -163.96875 }

소리
{ x: 1159.30859375,  y: 45.68016052246094,  z: -167.10072326660156 }

While one player is at T spawn, and the other at CT spawn, it just displays my position at T spawn for both players.

demo date

is it possible to get the date of the demo?

add to player m_iCashSpentThisRound and m_iTotalCashSpent

G'day mate,

Reference: https://github.com/L33T/CSGO-Reflection/blob/master/DT_CSPlayerResource.txt

Is it possible to add m_iCashSpentThisRound and m_iTotalCashSpent to the Player entity?

I see the is account() that returns m_iAccount

Would adding these be similar to the the mvps() getter?

get mvps() {
    let pr = this._demo.entities.getSingleton('DT_CSPlayerResource');
    let mvps = pr.props['m_iMVPs'];
    return mvps[Object.keys(mvps)[this.index]];
  }

Cheers

Improved handling for ESEA demos

Hey mate,

This is a bit of an odd request but ESEA and bot is resetting the match at halftime and overtime so it breaks round counts and overtime triggers in the game, including m_gamePhase.

I've written my own phase and overtime detection logic, do you think it's worth adding this into the demofile parser? It's very edge case but a lot of games are played on ESEA these days. Would also be nice to have an auto overtime lo3/lo5 detection.

Cheers,

Mav

Improved Examples

Hey, awesome module first up!

I'm still getting my head around the documentation and what data is valuable and how it's all linked together. I see a lot of questions popping up around how can I do 'x' or how do I get 'y' data for a player etc.

I think it would be valuable to come up with a list of popular requests and some additional ones then build some code examples.

For me I want to be able to determine if a player is "tracing" or essentially "aimbotting" using the data available in the demofile. I don't have much experience with demofiles so there is a bit of a learning curve. If you wanted to leave it open for people to learn on their own then perhaps an FAQ, with examples like:

"If you want to determine where a player is looking then using the entities.on("change") method and look for DT_CTPlayerBase->m_blah value".

What do you think?

get correct roundtime

Hello, me again.

I am trying to get the roundtime of when e.g. a kill happened in during a round.

I am currently trying this:

    let stat = {
          attackerName: attacker.name,
          attackerHealth: attacker.health,
          weapon: e.weapon,
          // ...
          roundNumber: demoFile.gameRules.roundNumber,
          roundTime: demoFile.gameRules.getProp('DT_CSGameRules', 'm_iRoundTime')
        };

but that just returns 115 which I believe is the total round time.

Thanks,
Raphael Hippe

How to get user entity?

So how can I get DT_BasePlayer based on userinfo table data? Is there corresponding field I should look for? Since I cant find steam id in DT_BasePlayer.

Inconsistency between Player.kills and Player.matchStats.kills

I'm trying to calculate headshot-percentage of kills.

Executing the following code gives percentages between 0 and 100%, but totalKills[i] == p.kills is false most of the time.

let totalKills = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let totalHeadshotKills = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let headShotPercentage = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

demoFile.gameEvents.on('round_end', () => {
	let roundNumber = demoFile.gameRules.roundsPlayed;
	let i = 0;
	for (p of teamT.members) {
		totalKills[i] += p.matchStats[roundNumber-1].kills;
		totalHeadshotKills[i] += p.matchStats[roundNumber-1].headShotKills;
		headShotPercentage[i] = totalHeadshotKills[i] / totalKills[i] * 100;
		// totalKills[i] == p.kills
		i++;
	}
	for (p of teamCT.members) {
		totalKills[i] += p.matchStats[roundNumber-1].kills;
		totalHeadshotKills[i] += p.matchStats[roundNumber-1].headShotKills;
		headShotPercentage[i] = totalHeadshotKills[i] / totalKills[i] * 100;
		// totalKills[i] == p.kills
		i++;
	}
});

The following code gives percentage over 100%. But here I am sure that the amount of kills is correct (looking at vod of the game).

let totalHeadshotKills = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let headShotPercentage = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

demoFile.gameEvents.on('round_end', () => {
	let roundNumber = demoFile.gameRules.roundsPlayed;
	let i = 0;
	for (p of teamT.members) {
		totalHeadshotKills[i] += p.matchStats[roundNumber-1].headShotKills;
		headShotPercentage[i] = totalHeadshotKills[i] / p.kills * 100;
		i++;
	}
	for (p of teamCT.members) {
		totalHeadshotKills[i] += p.matchStats[roundNumber-1].headShotKills;
		headShotPercentage[i] = totalHeadshotKills[i] / p.kills * 100;
		i++;
	}
});

Smoke detonate position

Hey Saul,

First of all, thank you so much for all your work on this lib.

I'm writing a replay viewer using demofile but I'm not able to get the correct position of the smoke when smoke_detonate is triggered.

I've checked your last commit and updated demofile to master, but still, I'm not able to get the exactly smoke's position when it happens.

I'm listening for 'smokegrenade_detonate' and I get x, y and z.
Is it expected to get the exactly position of this entity when it explodes or not?

I'm already checking it as follows (the same I do to get the player position on map):

let overviewData = {
    "mirage": {
      "pos_x": -3230,
      "pos_y": 1713,
      "scale": 5
    }
};
var positionX = (gameEvent.x - overviewData[map].pos_x) / overviewData[map].scale;
var positionY = (overviewData[map].pos_y - gameEvent.y) / overviewData[map].scale;

What am I doing wrong?

Thank you!

Incorrect bomb position

Hello. I want to track position of bomb. This is my code:

demo.gameEvents.on('bomb_dropped', function(e) {
    console.log(demo.entities.entities[e.entindex].position);
});

However I am getting incorrect values. Output looks like this:

...
{ x: 27.5625,  y: 0.40625,  z: 29.4375 }
{ x: 26.125,   y: 9.4375,   z: 29.96875 }
{ x: 29.65625, y: 6.84375,  z: 16.1875 }
{ x: 21.71875, y: 29.5,     z: 21.1875 }
{ x: 13.1875,  y: 12.59375, z: 12.09375 }
{ x: 15.09375, y: 2.75,     z: 20.15625 }
{ x: 13.875,   y: 23.90625, z: 20.96875 }
{ x: 6.40625,  y: 17.59375, z: 19.15625 }
{ x: 2.96875,  y: 19.3125,  z: 15.75 }
{ x: 5,        y: 29.75,    z: 15.65625 }
...

Notice all values are less than 30. Range of coordinates should be much bigger. Now it looks like bomb is always dropped very close to the center of map, but I'm sure this is not the case.

start datetime

Can't seem to find the property to get the datetime for when the map started?

The team Id

Is there a number for each team such as fnatic ?
Can I get the number of the team from the dem file with this project?

m_iMatchStats_Damage

Hey mate,

Happy new years!

I'm having a bit of trouble trying to get the damage dealt per user per round with m_iMatchStats_Damage

I've tried using:

let pr = this._demo.entities.getSingleton('DT_CSPlayer');
let values = pr.props['m_iMatchStats_Damage'];
return values[Object.keys(values)[this.index]];	

But it just results with a zero 0 value.

Ideally I want to calculate damage dealt per round and average damage per player.

How can I translate the position

How can I convert the position in the file to the position in the map ?
The postion I get is like this (3305171700,1159083300, 1094367000) .
I don't know where is the point in the map of the match !

round_end event not being triggered correctly

image

i'm only seeing a total of 20 round_end events for match 2 that should have 26.

Match Data: https://www.hltv.org/matches/2318632/faze-vs-cloud9-eleague-major-2018

All 3 demos from the GOTV are missing round_end events.

match 1: https://mega.nz/#!OwFC2Q6J!mye2CCLGE8xojqDd6h6gy2aXPrH5kkfRSEIcUtlXtgI
match 2: https://mega.nz/#!ihURHbxK!IumMuyWguCWg4DKmj8jKFPyDTq0wyrRolN_JjmRcnpA
match 3: https://mega.nz/#!e9sWEJSD!9WYbyWozXZOZ7Ftxpv01G_S5NBx12paJz_ysHQr71wc

But if I process a match from IEM Oakland https://www.hltv.org/matches/2317279/sk-vs-astralis-iem-oakland-2017

The round_end events are correct.

Using latest version of demofile

Demos not being parsed after last update

Ever since the update (i think it was this one: http://blog.counter-strike.net/index.php/2017/11/19757/), that demo parser are crashing very early in the game, on this:

TypeError: Cannot read property 'slice' of undefined
    at _.reduce (/home/demos2/csgodemoparser/stringtables.js:193:38)
    at arrayReduce (/home/demos2/csgodemoparser/node_modules/lodash/index.js:1450:23)
    at Function.<anonymous> (/home/demos2/csgodemoparser/node_modules/lodash/index.js:3445:13)
    at StringTables._parseStringTableUpdate (/home/demos2/csgodemoparser/stringtables.js:175:7)
    at StringTables._handleUpdateStringTable (/home/demos2/csgodemoparser/stringtables.js:287:10)
    at emitOne (events.js:96:13)
    at DemoFile.emit (events.js:188:7)
    at DemoFile._handleDemoPacket (/home/demos2/csgodemoparser/demo.js:218:12)
    at DemoFile._parseRecurse (/home/demos2/csgodemoparser/demo.js:312:14)
    at runCallback (timers.js:672:20)

Solutions?

roundNumber is amibguous

Thanks for this awesome library, and all your great work on it. I hope I can contribute to it in the future.

roundNumber sounds like it'll be the round number for the round currently in progress, but it changes when the score changes, before the round actually ends. The field's name of m_totalRoundsPlayed sounds more accurate, and if people wanna keep track of the round currently in progress then roundNumber would probably be m_totalRoundsPlayed + 1, except between the round ending and the round actually ending.

round_end: when the bomb explodes / last player dies and the score changes, but folks can still move around for some amount of time to save weapons or whatever.
round_officially_ended: when players finally "respawn" / move back to their spawns.

Demo start time

I need to find in which time demo started e.g. freeze time, round time etc, so that i can start counting my own time. I'm able to do that after receiving round end/round start, but not before.

Is there any property i missed, where is stored time of server, when demo was started?

get players position at x roundtime

Hey, me again ;-),

first of all: I saw this issue: #3 and tried to use it.
but I don't want to get the position of each player every tick or every event but at a set round timer mark so e.g. after 30 seconds have past in each round.

    demoFile.on('tickend', e => {
      let currentRoundTime = demoFile.currentTime - currentRoundStarttime;
      if (currentRoundTime > 30.0 && currentRoundTime < 30.025) {
        console.log(e, demoFile.currentTime, currentRoundTime);
        console.log('NEW ROUND 30 SEC MARK');
        for (var i = 0; i < myUserIds.length; i++) {
          let ent = demoFile.entities.entities[myUserIds[i]];
          console.log(myUserIds[i], ent.position);
          let xy = ent.getProp('DT_CSNonLocalPlayerExclusive', 'm_vecOrigin');
          console.log('xy', xy);
          let pos = {
            x: xy.x,
            y: xy.y,
            z: ent.getProp('DT_CSNonLocalPlayerExclusive', 'm_vecOrigin[2]')
          }
          console.log(myUserIds[i], pos);
        }
      }
    });


demoFile.gameEvents.on('round_start', e => {
      currentRoundStarttime = demoFile.currentTime;
    });

The issues I have with this are:

  • multiple results for the same second because ticks happen faster than seconds
  • different amount of results per round (sometimes 2, sometimes 3 and so on)
  • xy seems to be undefined sometimes:
x: xy.x,
TypeError: Cannot read property 'x' of undefined

after that I tried the ent.position but that returns the same position everytime (every round, and every tick) for each player, which I find very odd.

Thank,

Raphael Hippe

Trying to read past the end of the stream

I'm trying to use demofile to parse a recently played demo file, and it's failing right after the match starts (This happens to multiple demo files). Here's the output from running the examples/dumpfile.js:

Demo header: { magic: 'HL2DEMO',
  protocol: 4,
  networkProtocol: 13569,
  serverName: 'Valve CS:GO US SouthEast Server (srcds007.125.44)',
  clientName: 'GOTV Demo',
  mapName: 'de_cache',
  gameDirectory: 'csgo',
  playbackTime: 3098.859375,
  playbackTicks: 198327,
  playbackFrames: 99125,
  signonLength: 614211 }
cash_team_rescued_hostage: undefined -> 600
bot_autodifficulty_threshold_high: undefined -> 0
cash_team_win_by_defusing_bomb: undefined -> 3500
game_mode: undefined -> 1
mp_ggtr_bomb_pts_for_upgrade: undefined -> 2
ff_damage_reduction_bullets: undefined -> 0.33
bot_quota_mode: undefined -> fill
cash_player_interact_with_hostage: undefined -> 300
mp_maxrounds: undefined -> 30
ammo_grenade_limit_total: undefined -> 4
mp_respawn_immunitytime: undefined -> 0
mp_roundtime_defuse: undefined -> 1.92
mp_ggprogressive_round_restart_delay: undefined -> 15
mp_timelimit: undefined -> 0
mp_warmuptime: undefined -> 60
sv_deadtalk: undefined -> 1
mp_randomspawn_los: undefined -> 0
mp_weapons_allow_map_placed: undefined -> 1
sv_hosting_lobby: undefined -> 1
nextlevel: undefined -> de_cache
mp_ggtr_bomb_defuse_bonus: undefined -> 1
mp_buytime: undefined -> 20
bot_difficulty: undefined -> 2
mp_roundtime_hostage: undefined -> 1.92
mp_freezetime: undefined -> 15
bot_defer_to_human_goals: undefined -> 1
sv_skyname: undefined -> sky_cs15_daylight01_hdr
sv_reliableavatardata: undefined -> 1
mp_friendlyfire: undefined -> 1
cash_team_hostage_interaction: undefined -> 600
spec_freeze_panel_extended_time: undefined -> 0
ff_damage_reduction_other: undefined -> 0.4
mp_molotovusedelay: undefined -> 0
cash_team_elimination_hostage_map_t: undefined -> 3000
mp_ggtr_bomb_detonation_bonus: undefined -> 1
ammo_grenade_limit_flashbang: undefined -> 2
mp_roundtime: undefined -> 1.92
mp_halftime: undefined -> 1
mp_ggtr_bomb_respawn_delay: undefined -> 0
think_limit: undefined -> 0
ff_damage_reduction_grenade: undefined -> 0.85
cash_team_elimination_hostage_map_ct: undefined -> 3000
cash_team_win_by_hostage_rescue: undefined -> 2900
tv_transmitall: undefined -> 1
GOTV (BOT) joined the game
syncopate (STEAM_1:1:18164814) joined the game
Larry (BOT) joined the game
Bert (BOT) joined the game
*** Round ended 'first' (reason: 16)
	Terrorists:  score 0
	CTs:  score 0
Fergus (BOT) joined the game
Bob (BOT) joined the game
Ryan (BOT) joined the game
Yanni (BOT) joined the game
Graham (BOT) joined the game
Allen (BOT) joined the game
Opie (BOT) joined the game
TAK1N L1VES (STEAM_1:0:42267311) joined the game
/home/dangmai/Dev/demo-analyzer/node_modules/demofile/ext/bitbuffer.js:201
  CW_LowPrecision,
           ^

Error: Trying to read past the end of the stream
    at BitStream.<anonymous> (/home/dangmai/Dev/demo-analyzer/node_modules/bit-buffer/bit-buffer.js:191:10)
    at _.map (/home/dangmai/Dev/demo-analyzer/node_modules/demofile/ext/bitbuffer.js:46:54)
    at arrayMap (/home/dangmai/Dev/demo-analyzer/node_modules/demofile/node_modules/lodash/index.js:1406:25)
    at Function.map (/home/dangmai/Dev/demo-analyzer/node_modules/demofile/node_modules/lodash/index.js:6710:14)
    at BitStream.bitBuffer.BitStream.readBytes (/home/dangmai/Dev/demo-analyzer/node_modules/demofile/ext/bitbuffer.js:46:23)
    at _.reduce (/home/dangmai/Dev/demo-analyzer/node_modules/demofile/stringtables.js:217:34)
    at arrayReduce (/home/dangmai/Dev/demo-analyzer/node_modules/demofile/node_modules/lodash/index.js:1450:23)
    at Function.<anonymous> (/home/dangmai/Dev/demo-analyzer/node_modules/demofile/node_modules/lodash/index.js:3445:13)
    at StringTables._parseStringTableUpdate (/home/dangmai/Dev/demo-analyzer/node_modules/demofile/stringtables.js:175:7)
    at StringTables._handleUpdateStringTable (/home/dangmai/Dev/demo-analyzer/node_modules/demofile/stringtables.js:287:10)

how can i get item_purchase event?

When use demofile i wan't to get item info , i code like this
demoFile.gameEvents.on('item_purchase',e=>{ console.log(e); });
I can get player_death event but can't get any item about event, is there anything wrong?
Home for you replay!

Some events missing from alliedmods

I found the following events in my demo that aren't in AlliedMods. Can't figure out how to make an account there though. 🤔

begin_new_match
cs_round_final_beep
cs_round_start_beep
hltv_chase
hltv_status
item_remove
player_disconnect
player_spawn
player_team
round_announce_last_round_half
round_announce_match_point
round_announce_match_start
round_officially_ended
round_time_warning

P.S. Thanks for the awesome library.

Make a browser version

mikeemoo/jsgo has one, would be really nice as it would open a lot of possible uses

Is there something hindering this, or is it just a matter of correctly configuring webpack/browserify (which I was unable to)?

Streaming interface

Right now in order to parse the demo, we have to read the entire file first. I think it'd be really cool if we can also support Node streams, so that we can have this stream: download .dem.bz file from Valve server -> unzip -> parse. It'd be much faster than download the zip file, unzip it completely, then read the unzipped file and parse it.

I thought about trying demofile as is, to see if it'd just magically work, using the following code:

function streamingAnalyze(stream, done) {
  const demoFile = new demofile.DemoFile();
  stream.pipe(through2(function handle(chunk, enc, callback) {
    demoFile.parse(chunk);
    callback();
  }))
  .on('finish', () => done(result));
}

But it failed, throwing the following stack trace:

C:\Dev\demo\node_modules\bytebuffer\dist\bytebuffer-node.js:499
                throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.length);
                ^

RangeError: Illegal offset: 0 <= 170 (+107899) <= 64464
    at ByteBuffer.Object.<anonymous>.module.exports.ByteBufferPrototype.readBytes (C:\Dev\demo\node_modules\bytebuffer\dist\bytebuffer-node.js:499:23)
    at ByteBuffer.Object.<anonymous>.ByteBuffer.readIBytes (C:\Dev\demo\node_modules\demofile\ext\bytebuffer.js:21:15)
    at DemoFile._handleDemoPacket (C:\Dev\demo\node_modules\demofile\demo.js:203:31)
    at DemoFile._parseRecurse (C:\Dev\demo\node_modules\demofile\demo.js:312:14)
    at ontimeout (timers.js:380:14)
    at tryOnTimeout (timers.js:244:5)
    at Timer.listOnTimeout (timers.js:214:5)

Get Game Patch

Hey,

I was wondering if there was a way to get the CSGO game patch version of a given HLTV demofile.

I looked for that in the demoHeader and parseHeader of your parser, the L33T/CSGO-Reflection repository for the csgo entity classes as well as CSGO and CS Source events but did not find anything.

I basically want to know on which patch (http://liquipedia.net/counterstrike/Patches) the game of the demofile was played on.

thanks and cheers,

Raphael Hippe

.on('error') handler for corrupt/incomplete demos

Hey mate,

I've been testing against a couple thousand demos and have noticed a good few of them are corrupt and it throws and exception.

I'm running this as a lambda function so an exception is very expensive. It would be great to have an .on('error') handler.

Currently I've solved this with:

process.on("uncaughtException", function (err) 
{
  console.error((new Date).toUTCString() + " uncaughtException:", err.message);
  console.error(err.stack);
});

Some of the errors I'm seeing:

at, 27 Jan 2018 02:24:38 GMT uncaughtException: Illegal offset: 0 <= 45087626 (+152) <= 45087696
RangeError: Illegal offset: 0 <= 45087626 (+152) <= 45087696
    at ByteBuffer.module.exports.ByteBufferPrototype.readBytes (C:\test\node_modules\bytebuffer\dist\bytebuffer-node.js:499:23)
    at DemoFile._handleDemoPacket (C:\test\node_modules\demofile\demo.js:197:44)
    at DemoFile._parseRecurse (C:\test\node_modules\demofile\demo.js:319:14)
    at runCallback (timers.js:789:20)
    at tryOnImmediate (timers.js:751:5)
    at processImmediate [as _immediateCallback] (timers.js:722:5)
Sat, 27 Jan 2018 02:24:38 GMT uncaughtException: undefined
undefined
Sat, 27 Jan 2018 02:24:38 GMT uncaughtException: undefined
undefined
Sat, 27 Jan 2018 02:24:38 GMT uncaughtException: undefined
undefined
Sat, 27 Jan 2018 02:24:38 GMT uncaughtException: undefined
undefined
Sat, 27 Jan 2018 02:24:38 GMT uncaughtException: undefined
undefined
Sat, 27 Jan 2018 02:24:38 GMT uncaughtException: undefined
undefined
Sat, 27 Jan 2018 02:24:38 GMT uncaughtException: undefined
undefined
Sat, 27 Jan 2018 02:24:38 GMT uncaughtException: undefined
undefined
Sat, 27 Jan 2018 02:24:38 GMT uncaughtException: undefined
undefined
Sat, 27 Jan 2018 02:24:38 GMT uncaughtException: undefined
undefined
Sat, 27 Jan 2018 02:24:38 GMT uncaughtException: undefined
undefined
Sat, 27 Jan 2018 02:24:38 GMT uncaughtException: Illegal offset: 0 <= 45087693 (+4) <= 45087696
RangeError: Illegal offset: 0 <= 45087693 (+4) <= 45087696
    at ByteBuffer.module.exports.ByteBufferPrototype.readInt32 (C:\test\node_modules\bytebuffer\dist\bytebuffer-node.js:906:23)
    at DemoFile._parseRecurse (C:\test\node_modules\demofile\demo.js:306:32)
    at runCallback (timers.js:789:20)
    at tryOnImmediate (timers.js:751:5)
    at processImmediate [as _immediateCallback] (timers.js:722:5)
Sat, 27 Jan 2018 02:24:38 GMT uncaughtException: Illegal offset: 0 <= 45087694 (+4) <= 45087696
RangeError: Illegal offset: 0 <= 45087694 (+4) <= 45087696
    at ByteBuffer.module.exports.ByteBufferPrototype.readInt32 (C:\test\node_modules\bytebuffer\dist\bytebuffer-node.js:906:23)
    at DemoFile._parseRecurse (C:\test\node_modules\demofile\demo.js:306:32)
    at runCallback (timers.js:789:20)
    at tryOnImmediate (timers.js:751:5)
    at processImmediate [as _immediateCallback] (timers.js:722:5)
Sat, 27 Jan 2018 02:24:38 GMT uncaughtException: Illegal offset: 0 <= 45087695 (+4) <= 45087696
RangeError: Illegal offset: 0 <= 45087695 (+4) <= 45087696
    at ByteBuffer.module.exports.ByteBufferPrototype.readInt32 (C:\test\node_modules\bytebuffer\dist\bytebuffer-node.js:906:23)
    at DemoFile._parseRecurse (C:\test\node_modules\demofile\demo.js:306:32)
    at runCallback (timers.js:789:20)
    at tryOnImmediate (timers.js:751:5)
    at processImmediate [as _immediateCallback] (timers.js:722:5)
Sat, 27 Jan 2018 02:24:38 GMT uncaughtException: Illegal offset: 0 <= 45087696 (+4) <= 45087696
RangeError: Illegal offset: 0 <= 45087696 (+4) <= 45087696
    at ByteBuffer.module.exports.ByteBufferPrototype.readInt32 (C:\test\node_modules\bytebuffer\dist\bytebuffer-node.js:906:23)
    at DemoFile._parseRecurse (C:\test\node_modules\demofile\demo.js:306:32)
    at runCallback (timers.js:789:20)
    at tryOnImmediate (timers.js:751:5)
    at processImmediate [as _immediateCallback] (timers.js:722:5)

The demo's are indeed corrupt or the match was killed via a command or the server was killed/restarted. The .on('end') appears to be called for a few of the demos.

How to get team information from player

Hello,

I want to take the team information that corresponds to a player. I've read the documentation but I wasn't able to get it done.

Thanks in advance.

Some detonate events cannot be resolved to an entity

I am trying to get the entity on a detonate event using the entityid. For the hegrenade_detonate and smokegrenade_detonate events, this resolves to an entity. However, for flashbang_detonate and decoy_detonate this cannot be resolved to an entity. (This is also the case for molotov_detonate, but this does not seem to have an entityid property, according to https://wiki.alliedmods.net/Counter-Strike:_Global_Offensive_Events#molotov_detonate)

I am running the following code, which results in grenade being undefined for the events mentioned above.

demoFile.gameEvents.on('***_detonate', e => {
	let thrower = demoFile.entities.getByUserId(e.userid);
	let grenade = demoFile.entities.entities[e.entityid];
	if (thrower && grenade) {
		let throwerPosition = thrower.position;
		let grenadePostiion = grenade.position;
		console.log('%s threw a grenade from position [%s,%s,%s] to position [%s,%s,%s]', thrower.name, throwerPosition.x, throwerPosition.y, throwerPosition.z,  grenadePostiion.x, grenadePostiion.y, grenadePostiion.z);
			}
    });

Add basic API methods to README

I think it can be helpful to new comers and even for who already uses the project. Sometimes, getting to the docs folder can be expensive and having a quickview at the README is nice, more when you are on your phone or just in a hurry.

It dont need to be extensive or even provide ALL methods, but the main ones. Maybe something like this:

// Player entity
player.health // int
player.name // string
player.kills // int
player.isDefusing // bool

TypeScript typings

The module would be easier to manage with TypeScript if there were a typings file. @types/demofile, or demo.d.ts typings definition file for the module.

`npm run generate-docs` fails

Christophers-MacBook-Pro:~ chris$ npm run generate-docs
npm ERR! path /Users/chris/package.json
npm ERR! code ENOENT
npm ERR! errno -2
npm ERR! syscall open
npm ERR! enoent ENOENT: no such file or directory, open '/Users/chris/package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent 

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/chris/.npm/_logs/2017-08-15T05_54_54_452Z-debug.log

Know when a grenade is launched ?

How would you proceed to get when a grenade (whatever the type is) is lauched (that means that the click has been released) ? Does the "fire" event works for grenade ?

userId of player changes

Hello,

first of all I'd like to thank you for this awesome library.

I am currently working with this GOTV demofile: https://www.hltv.org/matches/2317947/mousesports-vs-faze-ecs-season-4-finals

and noticed that the userId for rain seems to change right at the end of the game:

for every kill / assist / death for rain it is: 187

when the 'end' event is fired I am checking for all userIds:

demoFile.on('end', () => {
      let testPlayerIds = demoFile.players.map(p => p.userId);
      console.log('testPlayerIds', testPlayerIds);

and get the following output:

testPlayerIds [ 176, 177, 178, 179, 192, 181, 182, 183, 189, 185, 190, 188, 191 ]

and the 187 is missing.

I left in the example code for notification when a player joins:

 demoFile.entities.on('create', e => {
      if (e.entity.serverClass.name !== 'CCSPlayer') {
        return;
      }
      if (e.entity.userInfo) {
        console.log('%s (%s) joined the game', e.entity.name, e.entity.steamId);
      }
    });

and don't get any console prints mid game for rain rejoining the game. Therefore it seems like the userId is changing mid game for no obvious reason.

Do you have any idea why that would be the case?

Thanks,
Raphael Hippe

DemoFile.cancel() not working

As I try to build a workaround for #11 I get an error when trying to cancel the parsing.

D:\git\demoanalyzer\node_modules\demofile\demo.js:287
      timers.cancelImmediate(this._immediateTimerToken);
             ^

TypeError: timers.cancelImmediate is not a function
    at DemoFile.cancel (D:\git\demoanalyzer\node_modules\demofile\demo.js:287:14)
    at DemoFile.demo.on.v (D:\git\demoanalyzer\demoworker.js:70:14)
    at emitOne (events.js:96:13)
    at DemoFile.emit (events.js:188:7)
    at DemoFile._parseRecurse (D:\git\demoanalyzer\node_modules\demofile\demo.js:297:10)
    at runCallback (timers.js:666:20)
    at tryOnImmediate (timers.js:639:5)
    at processImmediate [as _immediateCallback] (timers.js:611:5)

As described in the timers documentation the function name is "clearImmediate" but even when I change it the parsing goes on. Is there anything else wrong?
https://nodejs.org/api/timers.html#timers_cancelling_timers

Node v6.10.2

Getting weapon name and info

Since player.weapon returns a BaseEntity, how to get that weapon name (i didnt found it on the entity props)? Could we consider making a class to Weapon (like Player, Team, etc.) ?

Parsing Error

I got an error with this demo file

C:\temp\git\demoanalyzer\node_modules\demofile\entities.js:54
    return this.props[tableName][varName];
                                ^

TypeError: Cannot read property 'm_iPrimaryAmmoType' of undefined
    at Entity.getProp (C:\temp\git\demoanalyzer\node_modules\demofile\entities.js:54:33)
    at Entities._readNewEntity (C:\temp\git\demoanalyzer\node_modules\demofile\entities.js:414:29)
    at Entities._handlePacketEntities (C:\temp\git\demoanalyzer\node_modules\demofile\entities.js:451:14)
    at emitOne (events.js:77:13)
    at DemoFile.emit (events.js:169:7)
    at DemoFile._handleDemoPacket (C:\temp\git\demoanalyzer\node_modules\demofile\demo.js:177:12)
    at DemoFile._parseRecurse (C:\temp\git\demoanalyzer\node_modules\demofile\demo.js:271:14)
    at processImmediate [as _immediateCallback] (timers.js:383:17)

Is the demo file broken or is there something with the library? Thanks!

Any way to find a players rank?

I have been looking through the docs and I can't seem to find anything leading to players ranks. Is there any way of finding a players rank and if not is it possible to implement in the future?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.