StatsHelix / demoinfo

A library to analyze CS:GO demos in C#
MIT License
322 stars 78 forks source link

Header not parsing correctly #91

Open econoraptor opened 8 years ago

econoraptor commented 8 years ago

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.

econoraptor commented 8 years ago

Found some other matches from the same tournament with the same problem, so it's not just an isolated incident.

Calak commented 8 years ago

But you can play demos in cs go ? And in the demoui in the game, which information get you for the number of ticks , frames, and duration ?

econoraptor commented 8 years ago

Yes, i can play the demo in csgo and everything looks normal on demoui. Ticks and time duration is displayed properly.

Calak commented 8 years ago

And for this demo in particular how much time and ticks?

econoraptor commented 8 years ago

For the Dust2 demo: Ticks - 507904 Time - 1:06...

I did notice something else though that might be helpful. Right after selecting the demo there's a splash screen. Other demos seem to display the total ticks and time immediately, but this demo doesn't display them properly until the demo is fully loaded.

moritzuehling commented 8 years ago

Has anybody made any progress with this problem? I've seen it now myself "in the wild", and it's pretty annoying.

Calak commented 8 years ago

I did not had time to search about it but if they return 0 for ticks, duration, etc these demos seems to be corrupted. Maybe make a binary analyses the files to verify the 0 values.

In this case: On old version of the game engine, corrupted demos can't be read. Maybe recent engine extrapolates these values directly from demo's datas (last in-game tick, etc) and so, complete the demo header.
If I'm right, you have to implement the same process to handle these demos (if these files are really corrupted, maybe I'm wrong)

moritzuehling commented 8 years ago

https://github.com/SteamRE/SteamKit/blob/master/Resources/Protobufs/csgo/netmessages.proto#L245

It's open for grabs now, whoever wants to parse the Server-Message is open to do so :)

econoraptor commented 8 years ago

The bitstream is still a bit magic to me, but I was under the impression these types of messages don't get parsed?

main-- commented 8 years ago

@econoraptor We do parse netmessages for several important purposes. We used to use protobuf-net for them, but this turned out to be quite slow - so as of #26 some additional boilerplate code is unfortunately required. I'd recommend using e.g. NETTick (proto - impl) as a template since the general concept is very simple and repetitive.

As you can see, bitstream interaction is limited to just ReadProtobufString() and ReadProtobufVarInt() which are straightforward and do exactly what it says on the tin (and ChunkFinished but if you just copy the basic structure, you don't even need to think about it - unless you want to, of course).

main-- commented 8 years ago

@econoraptor That being said, there's obviously the alternative of just using the old SLOW_PROTOBUF mode which is still available (for debug purposes mostly) just like #65 does. You wouldn't have to implement a FastNetmessage then, but do consider that most DemoInfo users would not benefit from this then as our NuGet releases don't enable SLOW_PROTOBUF for performance reasons.

Whatever you choose, we would be happy about any contribution!

econoraptor commented 8 years ago

Ok, I'll take a look and see if I can figure out how to implement it.

econoraptor commented 8 years ago

Right at the start when I try to read the key I'm getting a NotSupportedException from this condition in ReadProtobufVarIntStub: if ((count == 9) ? (b != 1) : ((b & 0x7F) != 0x7F)) .

The exception is raised on 'var desc = bitstream.ReadProtobufVarInt();'

http://pastebin.com/vF9bc0fX

main-- commented 8 years ago

Alright, I found two potential issues:

econoraptor commented 8 years ago

Changing "(uint)bitstream.ReadProtobufVarInt();" to "bitstream.ReadInt(32);" as you suggested seems to have gotten things running. In the language guide (https://developers.google.com/protocol-buffers/docs/proto) it shows for c++ that fixed32 maps to uint32, so I figure it's probably the best bet for C#. I don't think I'll be messing around with trying to implement 64 bits, so I'll probably just comment the field out. It doesn't seem all that important anyways.

I still need to tie in tick_interval to the parser, but it's bedtime for me, so I'll finish up tomorrow.