Python bindings for faf-replay-parser
Project description
FAF Replay Parser
A fast library for parsing Supreme Commander Forged Alliance replay files.
Installation
Currently, pre-built packages are only available for Linux. You can install them with:
pip install faf-replay-parser
Documentation
Here are some examples of using the parser. Check help(fafreplay)
for more
details on available functions.
Gathering basic info
For the most basic uses there are a few special functions that should be
preferred over constructing a Parser
object. These do only one job, but they
do it very quickly.
Current functions:
body_offset
- Used for splitting replay data into header and body.body_ticks
- Used for extracting the game length.
Example
from datetime import timedelta
from fafreplay import body_offset, body_ticks
# Split replay data into header and body
offset = body_offset(data)
header_data, body_data = data[:offset], data[offset:]
# Get replay length in ticks
ticks = body_ticks(body_data)
print("Game length:", timedelta(milliseconds=ticks*100))
Using the Parser object
The Parser
object can be used to get fine grained control over how replay
commands are parsed. Generally it's a good idea to parse only the minimum
commands needed, as conversion back to python dictionaries is quite expensive.
from datetime import timedelta
from fafreplay import Parser, commands
parser = Parser(
# Skip all commands except the ones defined here
commands=[
commands.Advance, # For the tick counter
commands.VerifyChecksum, # For desync detection
],
# Throw away commands right after we parse them. Setting this to `True` will
# significantly increase the parse time.
save_commands=False,
limit=None,
stop_on_desync=False
)
# Or create a parser with default arguments (turn off save_commands though)
# parser = Parser(save_commands=False)
# Read replay to a `bytes` object
with open("12345.scfareplay", "rb") as f:
data = f.read()
# Parse to a python dictionary. Data must of type `bytes` or `bytearray`
replay = parser.parse(data)
print("Game time:", timedelta(milliseconds=replay["body"]["sim"]["tick"]*100))
if replay["body"]["sim"]["desync_ticks"]:
print("Replay desynced!")
Benchmark comparison
To see how much faster the basic functions can be, consider this simple example
done on replay 6176549
(an almost 50 minute long Seton's game).
>>> len(body_data)
5586339
>>> body_ticks(body_data)
28917
>>> parser = Parser(
... commands=[commands.Advance],
... save_commands=False
... )
>>> timeit.timeit("parser.parse_body(body_data)['sim']['tick']", globals=globals(), number=100)
1.4510237049980788
>>> timeit.timeit("body_ticks(body_data)", globals=globals(), number=100)
0.20173147800232982
In this case body_ticks
turned out to be more than 7x faster than using a
Parser
.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Hashes for faf_replay_parser-0.5.1-cp39-cp39-manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 481e4e47b2faf9769234d26f4267567fea6f32e15800704ee292cec47cbc0d85 |
|
MD5 | e3a30fbd7c28f91b10f39c20cfe482eb |
|
BLAKE2b-256 | 39bb668c8b9d9acb777fc408f8a9f88d969c266d0356bb4bace40499d60ba874 |
Hashes for faf_replay_parser-0.5.1-cp38-cp38-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | fd23295821b4572038f8deef998a034447433c6751be633874e6d1acc2983b87 |
|
MD5 | 75f092d9f3e3abf70bf477062ef7aa73 |
|
BLAKE2b-256 | 7d7c6a1c5f6f794cb721d5eb2dd9a85f771442d85576ab56db73839b9ce8de50 |
Hashes for faf_replay_parser-0.5.1-cp38-cp38-manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9c2d01c550a8ecf1a057aa59ae5457e400b9f9af1277523a49fe6096230b8185 |
|
MD5 | f7f1305ec66edc5ccc27beaf3cca61fe |
|
BLAKE2b-256 | 5e98fb8905d567c2c49dce1afd20eebfa5aaaf851d043a21292d6460aafc10c3 |
Hashes for faf_replay_parser-0.5.1-cp37-cp37m-manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 79074d341515eff38d48bc8ef17dc6794bda686e2ff41a9d443def32f6929243 |
|
MD5 | a9da230739f509f6c546a9e6cf4dc531 |
|
BLAKE2b-256 | 560c88a83568ea613e43b3417d8fba9fe77b90f2a57c401d7138b3f0299b08e3 |
Hashes for faf_replay_parser-0.5.1-cp36-cp36m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 20e0cd8b8ef867037d0022d31086d7af3ca3f6a5630bce52a2d2ae64934850fd |
|
MD5 | 229e5f2160fecb0bb582e348765d5e5b |
|
BLAKE2b-256 | 8cac39eaed01bf2fc71317cf7b82826a92ac243e44f1ec25920e3d7139d7bcf0 |
Hashes for faf_replay_parser-0.5.1-cp36-cp36m-manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 925ca8c8047150b69b3e6a23d553e3011d8689a5acca598a71764ac8473191e3 |
|
MD5 | 9206b41ecd34aa3098fa20fbc46a9c92 |
|
BLAKE2b-256 | 3b04907ebcd13c01e2dda87b9b502cfd105f3bbcb3ae3bbdb94667062a7dea7b |
Hashes for faf_replay_parser-0.5.1-2-cp37-cp37m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 667932112b3ad1341a1e04a4fdefe00d2e5d849e20176244ea0225bbb4f602f9 |
|
MD5 | ba4993f4d639a5e8c0bb80e6cf38b726 |
|
BLAKE2b-256 | 8ce6f6d039cd61fee113250313e961e77f1fb580034f20b02d9db1210feeb9fd |