joshuaferrara / node-csgo

A node-steam plugin for Counter-Strike: Global Offensive.
MIT License
460 stars 82 forks source link

Unable to turn json back into proto objects #58

Closed ajohnsen closed 5 years ago

ajohnsen commented 5 years ago

I'm having a problem with turning the json response back into protos.

This worked earlier with the bundled protos in v1.5.7.

What im trying to do is to be able to create the dem.info files so that i keep the same format that downloading manually from csgo does.

So what im doing is to take the matchList response, taking out the match in that list trying to create a proto object with it.

if you check out this repo i've created a demo that showcases the error, https://github.com/ajohnsen/node-csgo-proto-encode-error

if you download that and run 'STEAM_USERNAME= STEAM_PASSWORD= npm start' it will run the demo and request a game from a sharecode. And then when the matchList response comes in it tries to create the dem.info file, but fails when trying to make the proto file.

If you take a look at works.js (run with 'npm works') this will read match.dem.info and decode it into a json object, before it turns it back into a protobuf object and writes it to a new file (new.dem.info).

You can check that these files are the same with md5

The only difference i see in the json is that the one that is not working is missing the tv_control and flags attribute from roundstatall[].reservation, and that the last roundstatall[].map is null on the working one and has the download link on the non working one.

Edit: even if i add the missing flags and make the json completely different (using JSON.strigify and comparing with jsondiff.com) i still only get the problem with one of them. Even if i do it in the same file.

The error message im getting is: Error: Illegal value for [object Object] of type uint64: object (not convertible to Long) at line 1769 in Protobuf.js

Edit 2: From my digging around in protobuf.js it looks like its trying to read the Long value for matchId by parsing the entire json object as the long value and failing.

joshuaferrara commented 5 years ago

image

Will test this once the GC is back up.

ajohnsen commented 5 years ago

I got to do some more testing, and i found two things.

  1. There seems to be a change on valves side that demos downloaded from the csgo client is missing the download url in the last roundstatall.map attribute, i hope this isn't a permanent change. (The parameter is still there when using node-csgo, edit: Maybe it has been like this for a long time(?))

  2. I got the protobuf encoding to work when i wrapped the match object in JSON.parse(JSON.stringify(match)), so there is something fishy with the object that is returned from the matchList event

joshuaferrara commented 5 years ago

So your JSON parse/stringify workaround probably changes the type of something in the match list to make ProtobufJS happy. From what I can tell, it seems to be complaining about the match ID not being converted to/from an Object to a Long correctly.

This could be fixed on our end by modifying the returned object from ProtobufJS that's presented in the matchList event, but I'd rather leave that to ProtobufJS as it makes what's happening kinda ambiguous. I'm going to close this for now as it seems like your workaround is good enough.