tfausak / rattletrap

:car: Parse and generate Rocket League replays.
https://hackage.haskell.org/package/rattletrap
MIT License
150 stars 21 forks source link

Rocket League crashes when I open encoded replay-file (only old ones!) #122

Closed Propagand4lf closed 5 years ago

Propagand4lf commented 5 years ago

I cannot encode old replay-files and run them in Rocket League anymore - even if I don't edit the json-file. Newer ones does work without any problems (!). Rattletrap does not give me any warnings or error-messages either, so I can both create the json-file and the replay-file. I have been able to do this before on "same age" replays (long time ago), so I tested using different releases of rattletrap but without any success - version 6.0.0 to 7.0.1.

Any idea how to solve this?

Example-file from 3 Jan 2019: 383E6E974DC7D2A127564F8957BCDE45

Btw, thanks for an awesome tool :) !

tfausak commented 5 years ago

Huh, weird! Rattletrap has automated tests to ensure that round-tripping a replay through Rattletrap (that is, decoding it then encoding it) results in the exact same replay. However obviously something sneaked through because round-tripping your replay shrinks it by 4 bytes!

stack exec -- rattletrap -i tmp/383E6E974DC7D2A127564F8957BCDE45.replay -o tmp/replay.json -c
stack exec -- rattletrap -i tmp/replay.json -o tmp/new.replay

# 383E...    is 1,143,415 bytes
# new.replay is 1,143,411 bytes

This is definitely a bug. Thanks for reporting it! I don't have any ideas off the top of my head, but I'll poke around.

tfausak commented 5 years ago

Comparing the JSON output from decoding the original replay and the round-tripped replay, the only difference is the size and CRC of the content section.

fc 2.json 4.json

Comparing files 2.json and 4.JSON
***** 2.json
    },
    "crc": 359892154,
    "size": 1138318
  },
***** 4.JSON
    },
    "crc": 3817519591,
    "size": 1138314
  },
*****

That makes it seem like the problem is something that used to be encoded one way but is now done differently. Rattletrap can parse either one, but it's only writing the new way. Unfortunately that doesn't narrow it down much because there are many thing that change behavior based on the version of the replay being decoded.

tfausak commented 5 years ago

The binary replays have five bytes that differ.

fc /b 1.replay 3.replay

Comparing files 1.replay and 3.REPLAY
000013E1: 8E 8A
000013E5: BA E7
000013E6: 84 B9
000013E7: 73 8A
000013E8: 15 E3
FC: 1.replay longer than 3.REPLAY

That's not the most useful output, but at least it pinpoints the problem in the file.

tfausak commented 5 years ago

Oh, duh. That's just the size and CRC in binary. The only actual difference appears the be that the original replay has 4 null bytes at the end but the round-tripped one is missing those. That might correspond to the contentUnknown field, which was added in 83578053aaaa7dd6d954396ad1e3389df9e03e7f. Maybe I got the version constraint wrong on that field? Perhaps it's been around longer than I thought.