statshelix / demoinfo Goto Github PK
View Code? Open in Web Editor NEWA library to analyze CS:GO demos in C#
License: MIT License
A library to analyze CS:GO demos in C#
License: MIT License
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;
}
raises multiple questions:
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...
}
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!
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.
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.
Would it by any means be possible to get the rank of a player?
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.
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
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");
};
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.
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?
People are always having problems with the sn-tool, and only you can fix this @main--
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.
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?
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.
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
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"]))
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
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?
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.
`
Make a method or a check to detect if it is actually a csgo demo because it tries to parse:
How do you go about figuring out if someone is ducking?
During my original write of the parser I left this out, because the dota2-parsers that I based my work on didn't (need to) use this feature, and in CS:GO it was unused as well. Now it is used, so somebody has to implement it:
Reference in the Valve-Parser: https://github.com/csgo-data/demoinfogo-mirror/blob/master/demofilepropdecode.cpp#L51
Pull requests are very welcome, since I am extremely busy right now.
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:
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)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 :)
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.
There is an exception during the parsing of the packet-entites. (sigh)
An example of a non-working demo is in the hltv demo archive (tested with the demo of de_inferno).
Example outout of demoinfogo by Valve: https://gist.github.com/moritzuehling/a89a9587ab19d7953547
If anybody finds my mistakes, I'd be thankful. I'll look into the parsing-code myself.
Thanks to /u/Pigophone for reporting this bug!
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)
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)
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
Is it possible to parse player's rank from the demo, if yes, can this be added to the Player object?
Renaming the Mag-7 to Swag7 in EquipmentElements isn't the most user friendly thing to do. Took me a minute to find it.
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
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?
please remove this from the solution, or, include it in this or another repository.
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.
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.
The possible reason of this bug could be players disconnecting during the game (timedout for instance, which was the case of my demo).
Nevermind I just noticed the flashbang count is captured in the ReserveAmmo stat on the weapon.
I would to get the impact location of the bullets (when it hit's the walls etc.).
As far as I have seen something like that does not exist yet.
Would this be the right location to implement?
https://github.com/EHVAG/demoinfo/blob/master/DemoInfo/DP/Handler/GameEventHandler.cs#L120
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.
I'm encountering a bug in this GOTV demo http://www.hltv.org/match/2300904-dollarhouse-rize-nordic-masters-season-2-finals
Header.PlaybackFrames, Header.PlaybackTime, Header.PlaybackTicks, Header.SignonLength are all 0. I tried the dust2 and mirage matches and both had this bug. I also tried another matchup from the same tournament, but didn't encounter the problem, so I don't know how widespread it is.
Hi, for a project of my own, I'd like to be able to retrieve events from CSGO demo files, and your lib is great! However, it lacks events for when a netmessage is coming (https://github.com/alliedmodders/hl2sdk/blob/csgo/game/shared/usercmd.h).
Do you think it would be possible to subscribe to such event while parsing?
Many thanks,
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.
Feature Request:
Are you planning to implement the newly added timeout event?
SteamDatabase/GameTracking@d19ea48
Above link has some messages added. I thought those might be related to this functionality.
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.
DemoInfo/DP/Handler/GameEventHandler.cs is not thread-safe currently. Bug was introduced by you, @main--!
The title says it all. Relevant line that causes the error:
parser.PlayerKilled += HandlePlayerKilled;
btw. there is also a typo in the summary of the event. "Not"->"Note"
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.
When parsing a Demo from 04.02 an IndexOutOfRange occured in AttributeWeapon(Int32, DemoInfo.Player), with the WeaponEntityIndex being bigger than the Array of WeaponEntitites.
I can provide the Demo in question.
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 ๐ !
I dont have those events to attach to, these guys seem to have it working but the DLL isnt signed.
Have trouble with some demos like this one:
http://www.hltv.org/?pageid=28&demoid=26994&comments=1
throwed exception "Can't handle Demo-Command: 0" at DemoParser.cs line 639
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.