diff options
| author | CoprDistGit <infra@openeuler.org> | 2023-05-18 06:43:40 +0000 |
|---|---|---|
| committer | CoprDistGit <infra@openeuler.org> | 2023-05-18 06:43:40 +0000 |
| commit | ffde5e8b2e9def8c3fa5e521fb793085c757e065 (patch) | |
| tree | 2ddf7a6bddaf2d8b93a57fa9d0c38f8beb6ab989 | |
| parent | 214fa2ce52c9e0639fc05fad41635a26d6ff39ee (diff) | |
automatic import of python-faf-replay-parser
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | python-faf-replay-parser.spec | 456 | ||||
| -rw-r--r-- | sources | 1 |
3 files changed, 458 insertions, 0 deletions
@@ -0,0 +1 @@ +/faf-replay-parser-0.5.3.tar.gz diff --git a/python-faf-replay-parser.spec b/python-faf-replay-parser.spec new file mode 100644 index 0000000..94fdc68 --- /dev/null +++ b/python-faf-replay-parser.spec @@ -0,0 +1,456 @@ +%global _empty_manifest_terminate_build 0 +Name: python-faf-replay-parser +Version: 0.5.3 +Release: 1 +Summary: Python bindings for faf-replay-parser +License: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3) +URL: https://github.com/Askaholic/faf-replay-parser-python +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/3a/56/6712c09742fcc086c9ccbea56d726d0182c22b191340d58758b4e878f86a/faf-replay-parser-0.5.3.tar.gz + +Requires: python3-zstd + +%description +# FAF Replay Parser + +[](https://pypi.python.org/pypi/faf-replay-parser) + + +A fast library for parsing Supreme Commander Forged Alliance replay files. + +## Installation +Pre-built packages are available for Linux, MacOS, and Windows. 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 +```python +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. + +```python +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 `8653680` (an almost 50 minute long Seton's game). + +```python +>>> 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`. + +### Reading .fafreplay files +Replays downloaded from [faforever.com](https://faforever.com) use a compressed +data format to reduce the size of the files. These can be decompressed to the +original `.scfareplay` data using the `extract_scfa` function. + +```python +from fafreplay import extract_scfa + + +with open("12345.scfareplay", "rb") as f: + scfa_data = f.read() + +with open("12345.fafreplay", "rb") as f: + faf_data = extract_scfa(f) + +# The extracted data is in the .scfareplay format +assert faf_data == scfa_data +``` + +Note that there are several versions of the `.fafreplay` format. Version 1 uses +base64 and zlib compression which are both part of the python standard library. +However, version 2 uses `zstd` which must be installed through a third party +package. To ensure that this dependency is installed you can use the `faf` extra +when installing the parser: + +``` +pip install "faf-replay-parser[faf]" +``` + + +%package -n python3-faf-replay-parser +Summary: Python bindings for faf-replay-parser +Provides: python-faf-replay-parser +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +BuildRequires: python3-cffi +BuildRequires: gcc +BuildRequires: gdb +%description -n python3-faf-replay-parser +# FAF Replay Parser + +[](https://pypi.python.org/pypi/faf-replay-parser) + + +A fast library for parsing Supreme Commander Forged Alliance replay files. + +## Installation +Pre-built packages are available for Linux, MacOS, and Windows. 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 +```python +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. + +```python +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 `8653680` (an almost 50 minute long Seton's game). + +```python +>>> 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`. + +### Reading .fafreplay files +Replays downloaded from [faforever.com](https://faforever.com) use a compressed +data format to reduce the size of the files. These can be decompressed to the +original `.scfareplay` data using the `extract_scfa` function. + +```python +from fafreplay import extract_scfa + + +with open("12345.scfareplay", "rb") as f: + scfa_data = f.read() + +with open("12345.fafreplay", "rb") as f: + faf_data = extract_scfa(f) + +# The extracted data is in the .scfareplay format +assert faf_data == scfa_data +``` + +Note that there are several versions of the `.fafreplay` format. Version 1 uses +base64 and zlib compression which are both part of the python standard library. +However, version 2 uses `zstd` which must be installed through a third party +package. To ensure that this dependency is installed you can use the `faf` extra +when installing the parser: + +``` +pip install "faf-replay-parser[faf]" +``` + + +%package help +Summary: Development documents and examples for faf-replay-parser +Provides: python3-faf-replay-parser-doc +%description help +# FAF Replay Parser + +[](https://pypi.python.org/pypi/faf-replay-parser) + + +A fast library for parsing Supreme Commander Forged Alliance replay files. + +## Installation +Pre-built packages are available for Linux, MacOS, and Windows. 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 +```python +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. + +```python +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 `8653680` (an almost 50 minute long Seton's game). + +```python +>>> 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`. + +### Reading .fafreplay files +Replays downloaded from [faforever.com](https://faforever.com) use a compressed +data format to reduce the size of the files. These can be decompressed to the +original `.scfareplay` data using the `extract_scfa` function. + +```python +from fafreplay import extract_scfa + + +with open("12345.scfareplay", "rb") as f: + scfa_data = f.read() + +with open("12345.fafreplay", "rb") as f: + faf_data = extract_scfa(f) + +# The extracted data is in the .scfareplay format +assert faf_data == scfa_data +``` + +Note that there are several versions of the `.fafreplay` format. Version 1 uses +base64 and zlib compression which are both part of the python standard library. +However, version 2 uses `zstd` which must be installed through a third party +package. To ensure that this dependency is installed you can use the `faf` extra +when installing the parser: + +``` +pip install "faf-replay-parser[faf]" +``` + + +%prep +%autosetup -n faf-replay-parser-0.5.3 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-faf-replay-parser -f filelist.lst +%dir %{python3_sitearch}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Thu May 18 2023 Python_Bot <Python_Bot@openeuler.org> - 0.5.3-1 +- Package Spec generated @@ -0,0 +1 @@ +fdecd1efe1b5e28b54abe3758c10d044 faf-replay-parser-0.5.3.tar.gz |
