-
Notifications
You must be signed in to change notification settings - Fork 25
Parsing World of Tanks Replays
The replay file consists of a number of data blocks (lack of better word), the number of data blocks is stored in bytes 5 through 8 (starting counting from 1, I read the value as an unsigned 32 bits integer). After this you can read all the data blocks as follows, the next 4 bytes will contain the size of the data block (excluding the size it self), then you can read data block. This repeats itself untill all data blocks are stored. All but the last data block can be interpreted as JSON values, and contain (in order) pre-game description, post-game results (missing if the player left before the end of the battle) and then the binary replay data.
For futher details you can find the implementation in the following functions, parser_t::get_data_blocks and parser::get_data_block_count which can be found in the file parser.cpp .
As mentioned the last data block just contains the binary data, it requires some initial processing before we can work with it. The data is encrypted using blowfish and compressed using the DEFLATE compression algorithm. The key for the blow fish algorithm is DE 72 BE A0 DE 04 BE B1 DE FE BE EF DE AD BE EF.
The decryption process is as follows.
- Read the first 8 bytes
- Decrypt these 8 bytes
- Read the next 8 bytes
- Decrypt the 8 bytes and perform XOR operation with the previous decrypted 8 bytes
- Rinse and repeat untill you reach the end, if required pad the last bytes with zeroes
The decrypted data can then be decompressed using the DEFLATE compression algorithm. Implementation details can be found in parser_t::decrypt_replay and parser_t::extract_replay in the source file parser.cpp.
All that remains is reading the individual packets, the logic can be found in packet_reader_80.cpp. We can just read each packet as follows, the size is 12 + the unsigned 32-bit integer we find at the current position, we advance the current position with the current packet size, and continue until we reach the end.
The interpretation of the packets can be found here packet.cpp