GithubHelp home page GithubHelp logo

statshelix / demoinfo Goto Github PK

View Code? Open in Web Editor NEW
321.0 31.0 78.0 689 KB

A library to analyze CS:GO demos in C#

License: MIT License

C# 99.39% Shell 0.08% Python 0.53%
fancy demo parser c-sharp nuget csgo source-engine

demoinfo's Introduction

Archived

This project is archived, and no longer maintained. A more maintained version of this project can be found e.g. here.

DemoInfo

This is a C#-Library that makes reading CS:GO-Demos and analyzing them easier.

Travis CI results

nuget-package

We now have an official nuget-package! See https://www.nuget.org/packages/DemoInfo/

Stable releases

These are created and uploaded manually by us. The assemblies are properly signed (the public key is right here in the repo).

Prereleases

Our nuget prereleases are created automatically by travis whenever the master branch is updated. Therefore, bugs and sudden API changes are more likely. In return, you always get the latest improvements as soon as we push them. The version strings look like this: 0.0.0-ci<unix timestamp when the package was built>-<git commit hash>

Please note that the assemblies in these releases are not properly signed. They're delay-signed to ensure seamless compatibility with regular (stable) releases, but they don't carry a valid signature. This means that you may have to exclude DemoInfo.dll from strong name verification if you use these prereleases (see also: #39).

Debug symbols

Since no Windows machines are involved in any part of the development process, we can't provide pdb symbols for our releases. If you need to step into DemoInfo during debugging, you have to download the source code and add it to your project. Sorry.

Usage

Refer to this guide. There is also an example-project where you can see the parser in action!

Features

  • Get Informations about each player at any point in time:
  • Name
  • SteamID
  • Team
  • Clantag
  • Position
  • View-Direction
  • HP
  • Whether he is alive
  • The players team (CT / T / Spectator)
  • The players weapons
  • Kills
  • Deaths
  • Assists
  • MVPs
  • Score
  • Money
    • Current money
    • Current equipment value
  • Scores
  • Team-names
  • The following game-events:
  • Player was attacked (for GOTV demos newer than July 1st 2015)
  • Exploding / starting / stopping of the following nades:
    • Grenade (position, throwing player)
    • Smoke (position, throwing player, when did it start, when did it stop)
    • Fire (position, throwing player[1], when did it start, when did it stop)
    • Flash (position, throwing player, flashed players)
  • Weapon fired (who fired, what weapon[2], position)
  • Player died (weapon, killer, victim, weapon, position)
  • Round start
  • Match start
  • End of Freezetime
  • Bomb-Events

[1] This is not networked for some odd reason.

[2] This is actually pretty tricky since, for example the USP and the CZ are actually networked with the same class. We use some dark magic to find out what is the correct weapon.

Any questions? Contact me per mail or just join #demoinfogo on QuakeNet.

demoinfo's People

Contributors

0burner avatar adamburgess avatar akiver avatar calak avatar dennisfischer avatar econoraptor avatar jsterling8 avatar main-- avatar master117 avatar maxmeijer42 avatar moritzuehling avatar skirsten avatar suvjunmd avatar tabakhase avatar tpf89 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  avatar  avatar  avatar  avatar

demoinfo's Issues

Can't get teams flags

We can't retrieve Team flag from DemoParser class nor other class if I'm right.
Can you add the possibility to retrieve them ?
Thx

UnsafeBitStream and allocating memory

I did some tests, and it turns out that the allocating and pinning memory for UnsafeBitStream takes around 2s to complete on my system.
see http://git.io/b_HBJg for my implementation

Making only two allocations per demo speeds that process up, removing 2 seconds off the total.
complete with the fixes at #22, that would be around 7 seconds saved. On my system, DHW14-GF-ldlc-vs-nip-dust2 parse time goes from 10 seconds down to 3 seconds, which is a significant improvement.

The reason you need two allocations is because there is a nested reader (ReadEnterPVS).
Currently, it will crash and burn if more than one demo is parsed in different threads simultaneously -- this should be fixed by attaching the properties to the DemoParser instead of a static class.

any thoughts? making this issue as a request for comments, mainly.

Proposal: PickupWeapon and DropWeapon events

I would like to add events for when items are picked up and dropped.

I'm not 100% clear on what's going on with the bitmasking (I get the basic idea, but unclear on the details), but it looks like DropWeapon events could be added here:
https://github.com/StatsHelix/demoinfo/blob/master/DemoInfo/DemoParser.cs#L918

and on line 928.

And a PickupWeapon event could be added here:
https://github.com/StatsHelix/demoinfo/blob/master/DemoInfo/DemoParser.cs#L979

Not an actual issue.

Hello, I'm working on my own demo parser and have a couple questions, is there a way I can contact you?

Sorry about making this an "issue", I couldn't find any other way to contact you.

New Player object is referenced when player rejoins

What's the recommended way of dealing with player reconnects?

It seems that when a player leaves and rejoins the game, a new object is created rather than linking the player to the old object through their SteamID or some other persistent identifier. This, coupled with the fact that there's no event raised when a player connects, makes dealing with player reconnects tricky.

I poked around a bit to see if I could easily make a persistent object, but because of where SteamIDs are added to the player object and the fact that the RawPlayers entry is deleted when the player disconnects, this turns out to be fairly involved.

Repository moved to the StatsHelix organisation

Hello guys,

since this is the easiest way to reach everyone who watches this repository:

We have moved this repository to the StatsHelix-Organisation. The new link is

However, the old links all still work. This won't have any changes to the codebase or how it's maintained, but since @main-- and me both are founders of StatsHelix, we think that our demo-stuff is better suited at this organisation.

The license of this project is and will still be the MIT-License, so you can still use the code freely.

Accessing unexisting parser.Players

DP/GameEventHandler.cs ~line 140 (event "player_disconnect")
Got out of index exception on parser.Players[(int)data["userid"]].Disconnected = true;, fixed by making sure the index is valid: if(parser.Players.ContainsKey ((int)data ["userid"]))

parser.CurrentTick doesn't refer to the current tick of an event

When I print out the current tick in for example an RoundStart event and then load the demo in csgo at that tick and use demo_gototick it's not actually at a round start.

Is the parser async? Do I have to subtract the warmup ticks? Or is there a different way to get the current tick of an event?

Not self explanatory code in bombsite location snippet

The following code

var relevantTrigger = parser.triggers.Single(a => a.Index == site);

if ((parser.bombsiteACenter - bombEventArgs.Player.Position).Absolute <
    (parser.bombsiteBCenter - bombEventArgs.Player.Position).Absolute) {
    // planted at A.

    bombEventArgs.Site = 'A';
    parser.bombsiteAIndex = site;
} else if (relevantTrigger.Contains(parser.bombsiteBCenter)) {
    // planted at B.

    bombEventArgs.Site = 'B';
    parser.bombsiteBIndex = site;
}

GameEventHandler.cs Line 303

raises multiple questions:

  1. Why the bounding box check at bombsite b? Is this not sufficient enough:

    if ((parser.bombsiteACenter - bombEventArgs.Player.Position).Absolute <
        (parser.bombsiteBCenter - bombEventArgs.Player.Position).Absolute) {
        // planted at A.
        // set site...
    } else {
        // planted at B.
        // set site...
    }
  2. Why not use only the bounding box:

    var relevantTrigger = parser.triggers.Single(a => a.Index == site);
    
    if (relevantTrigger.Contains(parser.bombsiteACenter)) {
        // planted at A.
        // set site...
    } else {
        // planted at B.
        // set site...
    }

Am I missing something?

Also: Which of the used methods (absolute relative position or bounding box) should be used to identify the bombsite in the BombBeginDefuse and BombAbortDefuse events? (They do not contain site information)

Or should I save the last planted site and use that?

Anyway thanks for the awesome project!

Rounds which do not end

Hello, I have discovered a number of rounds which do not end, specifically the first three rounds. Take a look at this output:

Started Round number: 1
Started Round number: 2
Started Round number: 3
Ended Round number : 3
Started Round number: 4
Started Round number: 5
Started Round number: 6
Started Round number: 7
Ended Round number : 7
Started Round number: 8
Ended Round number : 8
Started Round number: 9
Ended Round number : 9
Started Round number: 10
Ended Round number : 10
Started Round number: 11
Ended Round number : 11
Started Round number: 12
Ended Round number : 12
Started Round number: 13
Ended Round number : 13
Started Round number: 14
Ended Round number : 14
Started Round number: 15
Ended Round number : 15
Started Round number: 16
Ended Round number : 16
Started Round number: 17
Ended Round number : 17
Started Round number: 18
Ended Round number : 18
Started Round number: 19
Ended Round number : 19
Started Round number: 20
Ended Round number : 20
Started Round number: 21
Ended Round number : 21
Started Round number: 22
Ended Round number : 22
Started Round number: 23
Ended Round number : 23
Started Round number: 24
Ended Round number : 24
Started Round number: 25
Ended Round number : 25
Started Round number: 26
Ended Round number : 26
Started Round number: 27
Ended Round number : 27
Started Round number: 28
Ended Round number : 28
Started Round number: 29
Ended Round number : 29
Started Round number: 30
Ended Round number : 30
Started Round number: 31

Update readme to reflect current status

I just worked on a little project with CS:GO demo files, and looked at the available projects. I read the readme for this project, which stated that a lot of events where still not implemented!

Instead I settled on https://github.com/mikeemoo/jsgo. But it seems this repo is in fact much more maintained, and has a lot more useful features to do the heavy lifting for you.

If you could update the readme to reflect the current status of the project, so other people don't make the same mistake as I did, that would be super fantastic ๐Ÿ‘ !

parser.RoundEnd fires to early

You can see this easily in rounds where one team is eliminated:
The last killed guy will be shown as alive in parser.PlayingParticipants and still has the amount of HP he had before the last shot hit him.

RoundOfficiallyEnd isn't called at match end.

Using the following code gives the following output on a demo that ended 16-11:

parser.RoundOfficiallyEnd += (sender, e) =>
{
    if (!hasMatchStarted)
        return;
    totalRounds++;
    Console.WriteLine(totalRounds + ": T " + parser.TScore + " - " + parser.CTScore + " CT");
};

Output

As you can see, the twenty-seventh round isn't called, and as such neither is the 16-11 scoreline visible at that point. Running the same output command after parser.ParseToEnd(); does have the right scoreline.

Player Rank

Is it possible to parse player's rank from the demo, if yes, can this be added to the Player object?

FileLoadException when trying to use Nuget Package in Visual Studio

I get this error with the nuget package when trying to use demoinfo in Visual Studio:

An unhandled exception of type 'System.IO.FileLoadException' occurred in mscorlib.dll

Additional information: Could not load file or assembly 'DemoInfo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=dc7de83c756ec63d' or one of its dependencies. Strong name validation failed. (Exception from HRESULT: 0x8013141A)

Only 1 flashbang counted

Nevermind I just noticed the flashbang count is captured in the ReserveAmmo stat on the weapon.

Plans on POV demo analyser

Hi, any plans on implementing POV demo analyzer? I've tested valve tool on github and it can read POV demos so I assume that it's not that hard to do if you already implemented GOTV, in terms of code adjustments. Or there are some issues with POVs?

Travis can't set profiling results for pull requests

As seen in #23, all travis builds for pull requests currently fail.

Reason: A pull request could change anything, including brofiler.py. And anyone can create a pull request. Because of that, travis doesn't set secret variables when building pull requests from forks, to avoid straight up leaking the secret.

Yo @moritzuehling, please choose a solution:

  • somehow convince me to fix it
  • Use a Workaround: Just ignore it because it doesn't affect internal pull requests and copy pull requests to internal branches to test them
  • assign it to me and I'll close it as wontfix
  • assign it to yourself and fix brofiler.py, so it detects pull request builds (travis will set special envvars for that) and doesn't try to set a commit status for those (just print the link to console instead)

Implement UserMessages parsing

It could be great to be able to retrieve usermessages.
There are some info such as players ranking data that are really useful.

I tried to do it some time ago but wasn't able don't remember why. If you could take a closer look at it would be awesome.

Not all participants being listed

I use this library to get all participants of a particular match from the users demo folder, but for some of the demos it will only show me some of the participants, sometimes 6, 7, 9 or all 10 of them. This is true for both matxhmaking demos and demos from MLG Columbus

The code I'm using is the following:

(It's VB.NET but that shouldn't really make a difference)

`For Each _player As Player In demoParser.PlayingParticipants

            Dim lvItem As New ListViewItem
                lvItem.Text = _player.Name
                lvItem.SubItems.Add(New ListViewItem.ListViewSubItem(lvItem, _player.AdditionaInformations.Kills))
                lvItem.SubItems.Add(New ListViewItem.ListViewSubItem(lvItem, _player.AdditionaInformations.Assists))
                lvItem.SubItems.Add(New ListViewItem.ListViewSubItem(lvItem, _player.AdditionaInformations.Deaths))

            lvDemoPlayers.Items.Add(lvItem)
        Next`

Maybe I'm just missing something, but I can't get it to work properly

Wrong win at the end of a round

When analysing the end of a round information for a win I have the following data output using the information in e.RoundEndReason and e.Winner.
Reason: TerroristWin, Winner: CounterTerrorist
Reason: Draw, Winner: Terrorist
Reason: Draw, Winner: Terrorist

This seems to be wrong. Can you explain why?

parser.RawPlayers not ensuring unicity

I had an exception on var user = parser.RawPlayers.Single(a => a.UserID == (int)data["userid"]);.
You are not ensuring the unicity of entities in this list because you are checking only the array index and not the actual object instance.

You need to check already existing players with the same userid before adding any object.
For instance
var olduser = parser.RawPlayers.SingleOrDefault(a => a.UserID == info.UserID); if(olduser != null) parser.RawPlayers.Remove(olduser); parser.RawPlayers.Add(player);
Note that my quick fix is probably not the best. (removing + adding => keeps last occurrence only)

Need to be fixed in all places you add players in this list.

  • DP/Handler/GameEventHandler.cs ~line 130 (event "player_connect")
  • DP/Handler/CreateStringTableUserInfoHandler.cs ~line 100
  • ST/StringTableParser.cs ~line 50

The possible reason of this bug could be players disconnecting during the game (timedout for instance, which was the case of my demo).

Swag7

Renaming the Mag-7 to Swag7 in EquipmentElements isn't the most user friendly thing to do. Took me a minute to find it.

Player_hurt event

Hi,
Good news from last CSGO update (30 Juni) :

โ€“ Added the player_hurt event to GOTV demos.

Can you implement it ?
Then we will be able to compute Efficacity like ESEA or CEVO :)

Fix instance baseline parsing

yay for git bisect:

9672e10105c790ecc2b5ffe950ca38fb470429c4 is the first bad commit
commit 9672e10105c790ecc2b5ffe950ca38fb470429c4
Author: moritzuehling <[email protected]>
Date:   Sun Nov 23 13:21:28 2014 +0100

    Implemented Instance-Baseline Parsing.

    #fancy.

Since 9672e10, the bitstream overflows and reads garbage. (tested with ESL One, fnatic vs NiP on de_cbbl)

A quick look at monodevelop's debug output shows that the anti-overflow assertion fails. So what do we do? Switch to Bitstream-Debugging, of course. And there we go: BitArray throws.

DevNullPlayer is broken

RIP travis build

https://travis-ci.org/moritzuehling/demoinfo-public/builds/48599599#L1255

Errors:
/home/travis/build/moritzuehling/demoinfo-public/DemoInfo.sln (default targets) ->
(Build target) ->
/home/travis/build/moritzuehling/demoinfo-public/DevNullPlayer/DevNullPlayer.csproj (default targets) ->
/usr/lib/mono/4.5/Microsoft.CSharp.targets (CoreCompile target) ->
    Program.cs(16,12): error CS0619: `DemoInfo.DemoParser.ParseDemo(bool)' is obsolete: `Use ParserHeader() and afterwards ParseToEnd() or ParseNextTick() please'
     26 Warning(s)
     1 Error(s)

Missing events(Jumping, Steps, Flashduration)(?)

Hi guys,

i noticed that there is no bool or event for jumping and steps(hearable movement).
Also i found code for flashduration(when downloading the zip on github) but no flashduration in the nuget version. Are these coming soon?

Regards

weapon_fire event not triggered for some knife attacks

I noticed that some of my player_hurt events caused by knife attacks had no associated weapon_fire event. I'm not sure if this is a problem with the parser or the demo though because when I used demoinfogo to get a text output of the demo, no weapon_fire event showed up in the text.

I'm not 100% certain, but I think this only happens with knives and not other weapons.

Off-Topic Help: Counter Strike Global Offensive Coordinate System

I hope nobody gets offended if i post a little off topic question here but does anybody know how the coordinate system in CSGO works. Looks like they have a weird center. I want to calculate the parser koordinates to my own :)

UPDATE: found a way, and as noone seems to be interested i dont bother explaining -> CLOSED.

Player not getting added to RawPlayers

I noticed that player_hurt and player_death events were sending a null Player in the eventargs, and I figured out that the player with the corresponding userid isn't ever being added to RawPlayers.

The fact that null is explicitly sent rather than raising an exception leads me to think that there is a known gap where events can be sent for players who haven't been added yet. I wanted to be sure this was known though, and I was also hoping someone could give a bit of an explanation. Thanks.

Here's a link to the demo where it's happening -- the d2 match: http://www.hltv.org/interfaces/download.php?demoid=19733

edit: When I play the demo the name of the victim doesn't show in the upper right when killed, so it's probably a bug with the demo itself. Kind of strange because he's clearly fully loaded into the game -- running around and everything.

Newcomer problems

Hi guys,

I am realtively new to C# and demofile parsing. I wanted to subscribe to playerHurt event but i get told that DemoParser does not contain the defintion "PlayerHurt" although it is implemented and defined.
Can somebody tell me why this is happening? It also tells me that PlayerHurtEventArgs namespace/type could not be found. I used this https://github.com/EHVAG/demostatistics-generator as a template (the Generator Classes)

Thanks in advance.
`

get rank (CSGO)

Would it by any means be possible to get the rank of a player?

Realtime playback

Hey,
not really an Issue but whatever :P
How can I know how many milliseconds I need to wait for the next tick, to play it in realtime?
So how many milliseconds I need per tick? Do you know that?

Confused w/ ManagedBitStream method

Hello,
I have been trying to get this library into Java in order to utilize it's functionality in my own project. However, I have been having some trouble with the ManagedBitStream method PeekInt. I am just a bit (lul) confused on what it is doing in the return statement line:
return (uint)((BitConverter.ToUInt64(Buffer, (Offset / 8) & ~3) << ((8 * 8) - (Offset % (8 * 4)) - numBits)) >> ((8 * 8) - numBits));

I am relatively new to C# and nothing is really making sense, it just won't translate into Java for me.

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.