Supreme Commander Forged Alliance 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 by exactly of type `bytes`
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.525173360016197
>>> timeit.timeit("body_ticks(body_data)", globals=globals(), number=100)
0.20764156704535708
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.4.0-cp37-cp37m-manylinux2010_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d2ad3ce3ead94572ea3370e73b031193a8675d44cfd4cfbecb5c40d59718906a |
|
MD5 | 6c58656f94d4f4fedbf3d709b413a545 |
|
BLAKE2b-256 | b038e9bfac7211054b9ca1028e2f76989f429c013fdefc72fc9c55185b2cea3d |
Hashes for faf_replay_parser-0.4.0-cp37-cp37m-manylinux1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 500e59ca2d419daa4ee7d899e3f417e3e442d9eca31d390b3798b7bd230bc7db |
|
MD5 | 97c1453126e14d42a7ce84f56b59aa31 |
|
BLAKE2b-256 | f55bf9b17e3c1dcafe1b57a082331389e0d4043020e4de4f7fea2d53575d1a8c |
Hashes for faf_replay_parser-0.4.0-cp36-cp36m-manylinux2010_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 606730f9f466ec5a7244d99a8a189989f361f207d3ccf8b066cb8dc4bc1a89cf |
|
MD5 | e40e189811861a1af4084a702406fcf7 |
|
BLAKE2b-256 | aded3b372aea6c2a2f6394497b5ed7a43cb1a7c2f832f05b95b164735875cd9a |
Hashes for faf_replay_parser-0.4.0-cp36-cp36m-manylinux1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b14dcb0d40d0cbeeb6f1abb8f38f798b8daa8cd714e2514c6af531c727584e6d |
|
MD5 | eee5bbfa57cf958bfe23f47f906f05f9 |
|
BLAKE2b-256 | e526dfe69433f64924a79683c15231c2fffd187b745e18f7452772edfa121527 |
Hashes for faf_replay_parser-0.4.0-cp35-cp35m-manylinux2010_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 65c45c537c15c7b9fec279070ae20c446412e10ed31a4efb99214ed1ae9992b9 |
|
MD5 | 14d15de0f40dcc2195ad5b04df5e8d1d |
|
BLAKE2b-256 | b176748f62893752a564369df119825457e9b40b926e9a3b0db0d2dabffdb489 |
Hashes for faf_replay_parser-0.4.0-cp35-cp35m-manylinux1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | eaa0682f2c374c9c3d271073b6db9428459dfd521de227aafffb767e8cf7bfaf |
|
MD5 | d7c680dd9ddd9ac1f2cb3013d98fcacb |
|
BLAKE2b-256 | b8dd8ac63b0012c7a2b414b317340090b954e27316e79d9a10cb797887ad1f51 |