diff --git a/.gitignore b/.gitignore index 7ec2f93..68a4ce8 100755 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,9 @@ .vscode .python-version +.pre-commit-config.yaml +resources/ +octocacheevai +exports/ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fd16ba2..8a56343 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,9 +2,17 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.2.0 + rev: v4.0.1 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - id: check-added-large-files +- repo: https://gitlab.com/pycqa/flake8 + rev: 3.8.3 + hooks: + - id: flake8 +- repo: https://github.com/psf/black + rev: 20.8b1 + hooks: + - id: black diff --git a/build.py b/build.py index 4fb8981..7022cc5 100755 --- a/build.py +++ b/build.py @@ -11,33 +11,30 @@ kuro_dir = Path(__file__).resolve().parent.joinpath("ReinKuro") clibs_dir = kuro_dir.joinpath("_clibs") kuro_ext_config = dict( - include_dirs=[ - str(clibs_dir.joinpath("kuro")) - ], - sources=[ - str(clibs_dir.joinpath("kuro/kuro.c")), - str(clibs_dir.joinpath("kuromodule.c")) - ] + include_dirs=[str(clibs_dir.joinpath("kuro"))], + sources=[str(clibs_dir.joinpath("kuro/kuro.c")), str(clibs_dir.joinpath("kuromodule.c"))], ) ext_modules = [Extension("reinkuro._clibs.kuro", **kuro_ext_config)] + class BuildFailed(Exception): pass -class ExtBuilder(build_ext): +class ExtBuilder(build_ext): def run(self): try: build_ext.run(self) except (DistutilsPlatformError, FileNotFoundError): - print('Could not compile C extension.') + print("Could not compile C extension.") def build_extension(self, ext): try: build_ext.build_extension(self, ext) except (CCompilerError, DistutilsExecError, DistutilsPlatformError, ValueError): - print('Could not compile C extension.') + print("Could not compile C extension.") + def build(setup_kwargs: Dict[str, Any]) -> None: setup_kwargs.update( diff --git a/poetry.lock b/poetry.lock index 61b6e8a..700e41a 100755 --- a/poetry.lock +++ b/poetry.lock @@ -28,6 +28,28 @@ docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"] tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"] +[[package]] +name = "black" +version = "21.6b0" +description = "The uncompromising code formatter." +category = "dev" +optional = false +python-versions = ">=3.6.2" + +[package.dependencies] +appdirs = "*" +click = ">=7.1.2" +mypy-extensions = ">=0.4.3" +pathspec = ">=0.8.1,<1" +regex = ">=2020.1.8" +toml = ">=0.10.1" + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.6.0)", "aiohttp-cors (>=0.4.0)"] +python2 = ["typed-ast (>=1.4.2)"] +uvloop = ["uvloop (>=0.15.2)"] + [[package]] name = "cfgv" version = "3.3.0" @@ -36,6 +58,17 @@ category = "dev" optional = false python-versions = ">=3.6.1" +[[package]] +name = "click" +version = "8.0.1" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + [[package]] name = "colorama" version = "0.4.4" @@ -82,6 +115,19 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "flake8" +version = "3.9.2" +description = "the modular source code checker: pep8 pyflakes and co" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[package.dependencies] +mccabe = ">=0.6.0,<0.7.0" +pycodestyle = ">=2.7.0,<2.8.0" +pyflakes = ">=2.3.0,<2.4.0" + [[package]] name = "identify" version = "2.2.11" @@ -93,6 +139,14 @@ python-versions = ">=3.6.1" [package.extras] license = ["editdistance-s"] +[[package]] +name = "mccabe" +version = "0.6.1" +description = "McCabe checker, plugin for flake8" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "more-itertools" version = "8.8.0" @@ -101,6 +155,14 @@ category = "dev" optional = false python-versions = ">=3.5" +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "nodeenv" version = "1.6.0" @@ -120,6 +182,14 @@ python-versions = ">=3.6" [package.dependencies] pyparsing = ">=2.0.2" +[[package]] +name = "pathspec" +version = "0.8.1" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + [[package]] name = "pluggy" version = "0.13.1" @@ -147,6 +217,17 @@ pyyaml = ">=5.1" toml = "*" virtualenv = ">=20.0.8" +[[package]] +name = "protobuf" +version = "3.17.3" +description = "Protocol Buffers" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +six = ">=1.9" + [[package]] name = "py" version = "1.10.0" @@ -155,6 +236,14 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "pycodestyle" +version = "2.7.0" +description = "Python style guide checker" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + [[package]] name = "pycryptodome" version = "3.10.1" @@ -163,6 +252,14 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "pyflakes" +version = "2.3.1" +description = "passive checker of Python programs" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + [[package]] name = "pygments" version = "2.9.0" @@ -225,6 +322,14 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +[[package]] +name = "regex" +version = "2021.7.6" +description = "Alternative regular expression module, to replace re." +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "rich" version = "10.5.0" @@ -245,7 +350,7 @@ jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" @@ -286,7 +391,7 @@ python-versions = "*" [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "206e6200f797e8e3f1ca468eb45a6d8ad38e671a9f8faab7b7d06a8b1f61766a" +content-hash = "504b318478d3622072383993048a46874991ea559eccc04f7c375d8c3020227c" [metadata.files] appdirs = [ @@ -301,10 +406,18 @@ attrs = [ {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, ] +black = [ + {file = "black-21.6b0-py3-none-any.whl", hash = "sha256:dfb8c5a069012b2ab1e972e7b908f5fb42b6bbabcba0a788b86dc05067c7d9c7"}, + {file = "black-21.6b0.tar.gz", hash = "sha256:dc132348a88d103016726fe360cb9ede02cecf99b76e3660ce6c596be132ce04"}, +] cfgv = [ {file = "cfgv-3.3.0-py2.py3-none-any.whl", hash = "sha256:b449c9c6118fe8cca7fa5e00b9ec60ba08145d281d52164230a69211c5d597a1"}, {file = "cfgv-3.3.0.tar.gz", hash = "sha256:9e600479b3b99e8af981ecdfc80a0296104ee610cab48a5ae4ffd0b668650eb1"}, ] +click = [ + {file = "click-8.0.1-py3-none-any.whl", hash = "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"}, + {file = "click-8.0.1.tar.gz", hash = "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a"}, +] colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, @@ -375,14 +488,26 @@ filelock = [ {file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"}, {file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"}, ] +flake8 = [ + {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, + {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, +] identify = [ {file = "identify-2.2.11-py2.py3-none-any.whl", hash = "sha256:7abaecbb414e385752e8ce02d8c494f4fbc780c975074b46172598a28f1ab839"}, {file = "identify-2.2.11.tar.gz", hash = "sha256:a0e700637abcbd1caae58e0463861250095dfe330a8371733a471af706a4a29a"}, ] +mccabe = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] more-itertools = [ {file = "more-itertools-8.8.0.tar.gz", hash = "sha256:83f0308e05477c68f56ea3a888172c78ed5d5b3c282addb67508e7ba6c8f813a"}, {file = "more_itertools-8.8.0-py3-none-any.whl", hash = "sha256:2cf89ec599962f2ddc4d568a05defc40e0a587fbc10d5989713638864c36be4d"}, ] +mypy-extensions = [ + {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, + {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, +] nodeenv = [ {file = "nodeenv-1.6.0-py2.py3-none-any.whl", hash = "sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7"}, {file = "nodeenv-1.6.0.tar.gz", hash = "sha256:3ef13ff90291ba2a4a7a4ff9a979b63ffdd00a464dbe04acf0ea6471517a4c2b"}, @@ -391,6 +516,10 @@ packaging = [ {file = "packaging-21.0-py3-none-any.whl", hash = "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14"}, {file = "packaging-21.0.tar.gz", hash = "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7"}, ] +pathspec = [ + {file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"}, + {file = "pathspec-0.8.1.tar.gz", hash = "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd"}, +] pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, @@ -399,10 +528,43 @@ pre-commit = [ {file = "pre_commit-2.13.0-py2.py3-none-any.whl", hash = "sha256:b679d0fddd5b9d6d98783ae5f10fd0c4c59954f375b70a58cbe1ce9bcf9809a4"}, {file = "pre_commit-2.13.0.tar.gz", hash = "sha256:764972c60693dc668ba8e86eb29654ec3144501310f7198742a767bec385a378"}, ] +protobuf = [ + {file = "protobuf-3.17.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ab6bb0e270c6c58e7ff4345b3a803cc59dbee19ddf77a4719c5b635f1d547aa8"}, + {file = "protobuf-3.17.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:13ee7be3c2d9a5d2b42a1030976f760f28755fcf5863c55b1460fd205e6cd637"}, + {file = "protobuf-3.17.3-cp35-cp35m-macosx_10_9_intel.whl", hash = "sha256:1556a1049ccec58c7855a78d27e5c6e70e95103b32de9142bae0576e9200a1b0"}, + {file = "protobuf-3.17.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:f0e59430ee953184a703a324b8ec52f571c6c4259d496a19d1cabcdc19dabc62"}, + {file = "protobuf-3.17.3-cp35-cp35m-win32.whl", hash = "sha256:a981222367fb4210a10a929ad5983ae93bd5a050a0824fc35d6371c07b78caf6"}, + {file = "protobuf-3.17.3-cp35-cp35m-win_amd64.whl", hash = "sha256:6d847c59963c03fd7a0cd7c488cadfa10cda4fff34d8bc8cba92935a91b7a037"}, + {file = "protobuf-3.17.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:145ce0af55c4259ca74993ddab3479c78af064002ec8227beb3d944405123c71"}, + {file = "protobuf-3.17.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6ce4d8bf0321e7b2d4395e253f8002a1a5ffbcfd7bcc0a6ba46712c07d47d0b4"}, + {file = "protobuf-3.17.3-cp36-cp36m-win32.whl", hash = "sha256:7a4c97961e9e5b03a56f9a6c82742ed55375c4a25f2692b625d4087d02ed31b9"}, + {file = "protobuf-3.17.3-cp36-cp36m-win_amd64.whl", hash = "sha256:a22b3a0dbac6544dacbafd4c5f6a29e389a50e3b193e2c70dae6bbf7930f651d"}, + {file = "protobuf-3.17.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ffea251f5cd3c0b9b43c7a7a912777e0bc86263436a87c2555242a348817221b"}, + {file = "protobuf-3.17.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:9b7a5c1022e0fa0dbde7fd03682d07d14624ad870ae52054849d8960f04bc764"}, + {file = "protobuf-3.17.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:8727ee027157516e2c311f218ebf2260a18088ffb2d29473e82add217d196b1c"}, + {file = "protobuf-3.17.3-cp37-cp37m-win32.whl", hash = "sha256:14c1c9377a7ffbeaccd4722ab0aa900091f52b516ad89c4b0c3bb0a4af903ba5"}, + {file = "protobuf-3.17.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c56c050a947186ba51de4f94ab441d7f04fcd44c56df6e922369cc2e1a92d683"}, + {file = "protobuf-3.17.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2ae692bb6d1992afb6b74348e7bb648a75bb0d3565a3f5eea5bec8f62bd06d87"}, + {file = "protobuf-3.17.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:99938f2a2d7ca6563c0ade0c5ca8982264c484fdecf418bd68e880a7ab5730b1"}, + {file = "protobuf-3.17.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6902a1e4b7a319ec611a7345ff81b6b004b36b0d2196ce7a748b3493da3d226d"}, + {file = "protobuf-3.17.3-cp38-cp38-win32.whl", hash = "sha256:59e5cf6b737c3a376932fbfb869043415f7c16a0cf176ab30a5bbc419cd709c1"}, + {file = "protobuf-3.17.3-cp38-cp38-win_amd64.whl", hash = "sha256:ebcb546f10069b56dc2e3da35e003a02076aaa377caf8530fe9789570984a8d2"}, + {file = "protobuf-3.17.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4ffbd23640bb7403574f7aff8368e2aeb2ec9a5c6306580be48ac59a6bac8bde"}, + {file = "protobuf-3.17.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:26010f693b675ff5a1d0e1bdb17689b8b716a18709113288fead438703d45539"}, + {file = "protobuf-3.17.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e76d9686e088fece2450dbc7ee905f9be904e427341d289acbe9ad00b78ebd47"}, + {file = "protobuf-3.17.3-cp39-cp39-win32.whl", hash = "sha256:a38bac25f51c93e4be4092c88b2568b9f407c27217d3dd23c7a57fa522a17554"}, + {file = "protobuf-3.17.3-cp39-cp39-win_amd64.whl", hash = "sha256:85d6303e4adade2827e43c2b54114d9a6ea547b671cb63fafd5011dc47d0e13d"}, + {file = "protobuf-3.17.3-py2.py3-none-any.whl", hash = "sha256:2bfb815216a9cd9faec52b16fd2bfa68437a44b67c56bee59bc3926522ecb04e"}, + {file = "protobuf-3.17.3.tar.gz", hash = "sha256:72804ea5eaa9c22a090d2803813e280fb273b62d5ae497aaf3553d141c4fdd7b"}, +] py = [ {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, ] +pycodestyle = [ + {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, + {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, +] pycryptodome = [ {file = "pycryptodome-3.10.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1c5e1ca507de2ad93474be5cfe2bfa76b7cf039a1a32fc196f40935944871a06"}, {file = "pycryptodome-3.10.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:6260e24d41149268122dd39d4ebd5941e9d107f49463f7e071fd397e29923b0c"}, @@ -435,6 +597,10 @@ pycryptodome = [ {file = "pycryptodome-3.10.1-pp36-pypy36_pp73-win32.whl", hash = "sha256:6bbf7fee7b7948b29d7e71fcacf48bac0c57fb41332007061a933f2d996f9713"}, {file = "pycryptodome-3.10.1.tar.gz", hash = "sha256:3e2e3a06580c5f190df843cdb90ea28d61099cf4924334d5297a995de68e4673"}, ] +pyflakes = [ + {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, + {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, +] pygments = [ {file = "Pygments-2.9.0-py3-none-any.whl", hash = "sha256:d66e804411278594d764fc69ec36ec13d9ae9147193a1740cd34d272ca383b8e"}, {file = "Pygments-2.9.0.tar.gz", hash = "sha256:a18f47b506a429f6f4b9df81bb02beab9ca21d0a5fee38ed15aef65f0545519f"}, @@ -482,6 +648,49 @@ pyyaml = [ {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, ] +regex = [ + {file = "regex-2021.7.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e6a1e5ca97d411a461041d057348e578dc344ecd2add3555aedba3b408c9f874"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:6afe6a627888c9a6cfbb603d1d017ce204cebd589d66e0703309b8048c3b0854"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ccb3d2190476d00414aab36cca453e4596e8f70a206e2aa8db3d495a109153d2"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:ed693137a9187052fc46eedfafdcb74e09917166362af4cc4fddc3b31560e93d"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:99d8ab206a5270c1002bfcf25c51bf329ca951e5a169f3b43214fdda1f0b5f0d"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:b85ac458354165405c8a84725de7bbd07b00d9f72c31a60ffbf96bb38d3e25fa"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:3f5716923d3d0bfb27048242a6e0f14eecdb2e2a7fac47eda1d055288595f222"}, + {file = "regex-2021.7.6-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5983c19d0beb6af88cb4d47afb92d96751fb3fa1784d8785b1cdf14c6519407"}, + {file = "regex-2021.7.6-cp36-cp36m-win32.whl", hash = "sha256:c92831dac113a6e0ab28bc98f33781383fe294df1a2c3dfd1e850114da35fd5b"}, + {file = "regex-2021.7.6-cp36-cp36m-win_amd64.whl", hash = "sha256:791aa1b300e5b6e5d597c37c346fb4d66422178566bbb426dd87eaae475053fb"}, + {file = "regex-2021.7.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:59506c6e8bd9306cd8a41511e32d16d5d1194110b8cfe5a11d102d8b63cf945d"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:564a4c8a29435d1f2256ba247a0315325ea63335508ad8ed938a4f14c4116a5d"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:59c00bb8dd8775473cbfb967925ad2c3ecc8886b3b2d0c90a8e2707e06c743f0"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:9a854b916806c7e3b40e6616ac9e85d3cdb7649d9e6590653deb5b341a736cec"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:db2b7df831c3187a37f3bb80ec095f249fa276dbe09abd3d35297fc250385694"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:173bc44ff95bc1e96398c38f3629d86fa72e539c79900283afa895694229fe6a"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:15dddb19823f5147e7517bb12635b3c82e6f2a3a6b696cc3e321522e8b9308ad"}, + {file = "regex-2021.7.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ddeabc7652024803666ea09f32dd1ed40a0579b6fbb2a213eba590683025895"}, + {file = "regex-2021.7.6-cp37-cp37m-win32.whl", hash = "sha256:f080248b3e029d052bf74a897b9d74cfb7643537fbde97fe8225a6467fb559b5"}, + {file = "regex-2021.7.6-cp37-cp37m-win_amd64.whl", hash = "sha256:d8bbce0c96462dbceaa7ac4a7dfbbee92745b801b24bce10a98d2f2b1ea9432f"}, + {file = "regex-2021.7.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:edd1a68f79b89b0c57339bce297ad5d5ffcc6ae7e1afdb10f1947706ed066c9c"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux1_i686.whl", hash = "sha256:422dec1e7cbb2efbbe50e3f1de36b82906def93ed48da12d1714cabcd993d7f0"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:cbe23b323988a04c3e5b0c387fe3f8f363bf06c0680daf775875d979e376bd26"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:0eb2c6e0fcec5e0f1d3bcc1133556563222a2ffd2211945d7b1480c1b1a42a6f"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:1c78780bf46d620ff4fff40728f98b8afd8b8e35c3efd638c7df67be2d5cddbf"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:bc84fb254a875a9f66616ed4538542fb7965db6356f3df571d783f7c8d256edd"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:598c0a79b4b851b922f504f9f39a863d83ebdfff787261a5ed061c21e67dd761"}, + {file = "regex-2021.7.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875c355360d0f8d3d827e462b29ea7682bf52327d500a4f837e934e9e4656068"}, + {file = "regex-2021.7.6-cp38-cp38-win32.whl", hash = "sha256:e586f448df2bbc37dfadccdb7ccd125c62b4348cb90c10840d695592aa1b29e0"}, + {file = "regex-2021.7.6-cp38-cp38-win_amd64.whl", hash = "sha256:2fe5e71e11a54e3355fa272137d521a40aace5d937d08b494bed4529964c19c4"}, + {file = "regex-2021.7.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6110bab7eab6566492618540c70edd4d2a18f40ca1d51d704f1d81c52d245026"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux1_i686.whl", hash = "sha256:4f64fc59fd5b10557f6cd0937e1597af022ad9b27d454e182485f1db3008f417"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:89e5528803566af4df368df2d6f503c84fbfb8249e6631c7b025fe23e6bd0cde"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2366fe0479ca0e9afa534174faa2beae87847d208d457d200183f28c74eaea59"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:f9392a4555f3e4cb45310a65b403d86b589adc773898c25a39184b1ba4db8985"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:2bceeb491b38225b1fee4517107b8491ba54fba77cf22a12e996d96a3c55613d"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:f98dc35ab9a749276f1a4a38ab3e0e2ba1662ce710f6530f5b0a6656f1c32b58"}, + {file = "regex-2021.7.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:319eb2a8d0888fa6f1d9177705f341bc9455a2c8aca130016e52c7fe8d6c37a3"}, + {file = "regex-2021.7.6-cp39-cp39-win32.whl", hash = "sha256:eaf58b9e30e0e546cdc3ac06cf9165a1ca5b3de8221e9df679416ca667972035"}, + {file = "regex-2021.7.6-cp39-cp39-win_amd64.whl", hash = "sha256:4c9c3155fe74269f61e27617529b7f09552fbb12e44b1189cebbdb24294e6e1c"}, + {file = "regex-2021.7.6.tar.gz", hash = "sha256:8394e266005f2d8c6f0bc6780001f7afa3ef81a7a2111fa35058ded6fce79e4d"}, +] rich = [ {file = "rich-10.5.0-py3-none-any.whl", hash = "sha256:d36d4dddbb6cb87cdcb2c02f8ffd7836e1b136e3ba45d4b5a4da057f3b5e7798"}, {file = "rich-10.5.0.tar.gz", hash = "sha256:f8a16484b3d70708bdafd04f659f9ca0e2c0129b33a343c10c734838d361777f"}, diff --git a/pyproject.toml b/pyproject.toml index 064ca90..262b259 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,11 +9,38 @@ build = "build.py" python = "^3.8" rich = "^10.5.0" pycryptodome = "^3.10.1" +protobuf = "^3.17.3" [tool.poetry.dev-dependencies] pytest = "^5.2" pytest-cov = "^2.12.1" pre-commit = "^2.13.0" +flake8 = "^3.9.2" +black = {version = "^21.6b0", allow-prereleases = true} + +[tool.black] +line-length = 120 +target-version = ['py38'] +include = '\.pyi?$' +exclude = ''' + +( + /( + \.eggs # exclude a few common directories in the + | \.git # root of the project + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | _build + | buck-out + | build + | dist + )/ + | foo.py # also separately exclude a file named foo.py in + # the root of the project +) +''' [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/reinkuro/__init__.py b/reinkuro/__init__.py index b794fd4..3dc1f76 100755 --- a/reinkuro/__init__.py +++ b/reinkuro/__init__.py @@ -1 +1 @@ -__version__ = '0.1.0' +__version__ = "0.1.0" diff --git a/reinkuro/kuro.py b/reinkuro/kuro.py index ca34d34..88dcc42 100755 --- a/reinkuro/kuro.py +++ b/reinkuro/kuro.py @@ -2,7 +2,8 @@ from reinkuro._clibs import kuro -def cryptbystring(input:bytes, mask:str) -> bytes: + +def cryptbystring(input: bytes, mask: str) -> bytes: """Decrypts assets by applying a byte mask to the file. Args: diff --git a/reinkuro/octo.py b/reinkuro/octo.py new file mode 100644 index 0000000..0f0cdf0 --- /dev/null +++ b/reinkuro/octo.py @@ -0,0 +1,333 @@ +import argparse +import hashlib +import json +import logging +import re +from pathlib import Path + +from Crypto.Cipher import AES +from Crypto.Util.Padding import unpad +from rich import print +from rich.logging import RichHandler +from rich.progress import track + +import kuro +import octodb_pb2 + +# Compile regex because it's used frequently +regex = re.compile(r"\)") +# Setup logger +console_logger = RichHandler(level=logging.CRITICAL, show_time=False, rich_tracebacks=True, markup=True) +console_logger.setFormatter(logging.Formatter("%(name)s - %(message)s")) + +debug_logger = logging.FileHandler("octo.log", "a") +debug_logger.setFormatter( + logging.Formatter( + "%(asctime)s - %(levelname)s - %(name)s - %(message)s", + "%Y/%m/%d %H:%M:%S", + ) +) + +logging.basicConfig( + format="%(asctime)s - %(levelname)s - %(message)s", + datefmt="[%X]", + handlers=[console_logger, debug_logger], + level=logging.DEBUG, +) + +con = logging.getLogger("reinkuro.octo") + + +def cache_from_encrypted(encrypted_cache_path: Path, key: bytes, iv: bytes) -> octodb_pb2.Database: + """Decrypts a cache file and deserializes it to a protobuf object + + Args: + encrypted_cache_path (Path): The path to the encrypted ``octocacheevai`` file. + key (bytes): A byte-string. Currently 16 characters long and appears to be alpha-numeric. + iv (bytes): A byte-string. Currently 10 characters long and appears to be base64-ish. + + Returns: + octodb_pb2.Database: A protobuf object representing the deserialized cache. + """ + + # The actual key and iv passed in during encryption are the md5 hashes of the respective strings + key = hashlib.md5(key).digest() + print(f"key: [green]{key.hex()}[/green]") + + iv = hashlib.md5(iv).digest() + print(f"iv : [green]{iv.hex()}[/green]\n") + + cipher = AES.new(key, AES.MODE_CBC, IV=iv) + + # Open the current (encrypted) octocacheevai + try: + data = encrypted_cache_path.read_bytes() + except FileNotFoundError: + print( + f'[bold red]>>> [Error][/bold red] [bold]Encrypted cache "{encrypted_cache_path.name}" not found.[/bold] [bold red]<<<[/bold red]' + ) + print( + " Place the encrypted cache file in the root folder next to the script.\n" + ' It can be found at: "\\data\\data\\com.square_enix.android_googleplay.nierspjp\\files\\octo\\pdb\\201\\\\octocacheevai".\n' + ) + raise SystemExit(1) + # For some reason there's a single extra 0x01 byte at the start of the encrypted file + try: + dec_bytes = unpad(padded_data=cipher.decrypt(data[1:]), block_size=16, style="pkcs7") + except ValueError: + # Should quit early if the supplied key is wrong somehow. + print(f"[bold red]>>> [Error][/bold red] [bold]Key {key}is incorrect.[/bold] [bold red]<<<[/bold red]\n") + raise SystemExit(1) + + # The first 16 bytes are an md5 hash of the database that follows it, which is skipped because it's useless for this purpose + dec_bytes = dec_bytes[16:] + # Read the decrypted bytes to a protobuf object + current = octodb_pb2.Database() + current.ParseFromString(dec_bytes) + # Revision number should probably change with every update..? + print(f"Current revision : {current.revision}\n") + # Write the decrypted cache to a local file + current_path = Path(f"caches/octocache_v{current.revision}.bin") + if not current_path.exists(): + current_path.parent.mkdir(parents=True, exist_ok=True) + current_path.write_bytes(dec_bytes) + return current + + +def dict_from_cache(cache: octodb_pb2.Database) -> dict: + """Quick conversion to dict from a cache object. Mostly because the ``in`` operation is useful. + + Args: + cache (octodb_pb2.Database): A protobuf object representing the deserialized cache. + + Returns: + dict: Dictionary + """ + return { + "revision": cache.revision, + "assetBundleList": { + assetbundle.id: { + # The "name" is actually the file path and "objectName" is the real name + "name": assetbundle.name, + "size": assetbundle.size, + "crc": assetbundle.crc, + # "deps": assetbundle.deps, + "md5": assetbundle.md5, + "objectName": assetbundle.objectName, + "generation": assetbundle.generation, + } + for assetbundle in cache.assetBundleList + }, + "resourceList": { + assetbundle.id: { + "name": assetbundle.name, + "size": assetbundle.size, + "crc": assetbundle.crc, + # "deps": assetbundle.deps, + "md5": assetbundle.md5, + "objectName": assetbundle.objectName, + "generation": assetbundle.generation, + } + for assetbundle in cache.resourceList + }, + } + + +def decrypt_from_dict(asset_dict: dict, out_path: Path): + """Accepts a ``dict`` where the key is the resource ``md5`` and the value is it's ``name`` and decrypts files to the directory given in ``out_path``. + The encrypted resource files are named after their md5 hash, and their true name is used to decrypt them. + + Args: + asset_dict (dict): Dictionary in the format ``"md5" : "name"`` + out_path (Path): The destination folder to write decrypted files to. + """ + contents = Path("resources").iterdir() + # Filter for anything in the resources folder + to_decrypt = [path for path in contents if path.name in asset_dict] + # Sort the list so it decrypts in order + to_decrypt.sort(key=lambda x: asset_dict[x.name]) + + for path in track(to_decrypt, description=f"[cyan]Decrypting {out_path.name}..."): + buff = path.read_bytes() + if buff[0] == 0x32: + crypttype = "[ Version1Full ]" + elif buff[0] == 0x31: + crypttype = "[ Version1 ]" + else: + crypttype = "[ Raw ]" + + maskstring = asset_dict[path.name] + decrypted = kuro.cryptbystring(input=buff, mask=maskstring) + fixedpath = re.sub(regex, "/", asset_dict[path.name]) + con.debug(f"{crypttype} <{path.name}> {fixedpath}") + + file = out_path.joinpath(f"{fixedpath}.assets") + file.parent.mkdir(parents=True, exist_ok=True) + file.write_bytes(decrypted) + + +def export_all(cache: octodb_pb2.Database): + """Decrypts and exports all assets using the given cache object. + + Args: + cache (octodb_pb2.Database): A protobuf object representing the deserialized cache. + """ + current_dict = dict_from_cache(cache) + all_assets = {v["md5"]: v["name"] for k, v in current_dict["assetBundleList"].items()} + readable = {v["name"]: v["md5"] for k, v in current_dict["assetBundleList"].items()} + + export_folder = Path(f"exports/v{cache.revision}_assets/") + export_folder.parent.mkdir(parents=True, exist_ok=True) + + export_folder.joinpath("db.json").write_text(json.dumps(readable, sort_keys=True, indent=4)) + decrypt_from_dict(all_assets, export_folder.joinpath("decrypted")) + + +def parse_difference( + current: octodb_pb2.Database, + previous: octodb_pb2.Database, + export_json=None, + decrypt=None, +): + """Parses the difference between two cache objects and optionally decrypts the "new" entires in the cache, and/or exports a human-readable json of the differences. + + Args: + current (octodb_pb2.Database): The newer cache of the two. + previous (octodb_pb2.Database): The older cache to compare against. + export_json ([bool], optional): Defaults to None. + decrypt ([bool], optional): Defaults to None. + """ + + # convert to dict for access to the "in" operation + current_dict = dict_from_cache(current) + previous_dict = dict_from_cache(previous) + + # Compare the two for new and changed assets + new_assets = { + v["md5"]: v["name"] + for k, v in current_dict["assetBundleList"].items() + if k not in previous_dict["assetBundleList"] + } + changed_assets = { + v["md5"]: v["name"] + for k, v in current_dict["assetBundleList"].items() + if k in previous_dict["assetBundleList"] + and previous_dict["assetBundleList"][k]["generation"] != current_dict["assetBundleList"][k]["generation"] + } + + export_folder = Path(f"exports/v{current.revision}_assets/") + export_folder.mkdir(parents=True, exist_ok=True) + + if export_json: + # Dump human-readable json + export_folder.joinpath("new.json").write_text( + json.dumps( + { + v["name"]: v["generation"] + for k, v in current_dict["assetBundleList"].items() + if k not in previous_dict["assetBundleList"] + }, + sort_keys=True, + indent=4, + ) + ) + export_folder.joinpath("changed.json").write_text( + json.dumps( + { + v["name"]: v["generation"] + for k, v in current_dict["assetBundleList"].items() + if k in previous_dict["assetBundleList"] + and previous_dict["assetBundleList"][k]["generation"] + != current_dict["assetBundleList"][k]["generation"] + }, + sort_keys=True, + indent=4, + ) + ) + + if decrypt: + # Run the asset decrypt loop to write them to "{version}_exports/new/..." and "{version}_exports/changed/..." + decrypt_from_dict(new_assets, export_folder.joinpath("new")) + decrypt_from_dict(changed_assets, export_folder.joinpath("changed")) + + +def init_arguments() -> argparse.ArgumentParser: + + parser = argparse.ArgumentParser( + usage="%(prog)s [OPTION]...", + description="Decrypts stuff", + formatter_class=argparse.RawTextHelpFormatter, + ) + parser.add_argument( + "-r", + "--revision", + type=int, + default=None, + metavar="", + help="The target cache revision to read during parsing for new assets.", + ) + parser.add_argument( + "-d", + "--decrypt", + action="store_false", + help="Decrypt and export assets after processing the database.", + ) + parser.add_argument( + "-e", + "--export", + choices=["all", "new"], + default="new", + help="Which assets to export.", + ) + + # These are just "magic numbers" pay no attention to them + parser.add_argument( + "-k", + "--key", + type=str, + default="p4nohhrnijynw45m", + metavar="", + help="Magic alphanumeric numbers.", + ) + parser.add_argument( + "-iv", + "--iv", + type=str, + default="LvAUtf+tnz", + metavar="", + help="Magic base64-ish numbers.", + ) + return parser.parse_args() + + +if __name__ == "__main__": + + __args__ = init_arguments() + # Key and iv must be byte arrays for hashing + __args__.key = bytes(__args__.key, "utf-8") + __args__.iv = bytes(__args__.iv, "utf-8") + print(f"\n{ __args__}\n") + + # Create current database object + current = cache_from_encrypted(Path("octocacheevai"), key=__args__.key, iv=__args__.iv) + current_dict = dict_from_cache(current) + if __args__.export == "new": + # Read the highest numbered previous cache revision + if not __args__.revision: + cache_revisions = [int(file.stem[11:]) for file in Path("caches/").iterdir()] + cache_revisions.remove(current.revision) + previous_revision = max(cache_revisions) + else: + previous_revision = __args__.revision + print(f"Previous revision: {previous_revision}\n") + # Create previous database object + previous = octodb_pb2.Database() + try: + previous.ParseFromString(Path(f"caches/octocache_v{previous_revision}.bin").read_bytes()) + except FileNotFoundError: + print( + f"[bold red]>>> [Error][/bold red] [bold]Cache revision {previous_revision} not found.[/bold] [bold red]<<<[/bold red]" + ) + parse_difference(current, previous, export_json=True, decrypt=__args__.decrypt) + else: # all + export_all(current) diff --git a/reinkuro/octodb.proto b/reinkuro/octodb.proto new file mode 100644 index 0000000..b889dbd --- /dev/null +++ b/reinkuro/octodb.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; +//protoc -I=. --python_out=. octodb.proto +//"[Octo.Data.Item: id={0}, name={1}, size={2}, crc={3}, tags=[{4}], deps=[{5}], state={6}, md5={7}, objectName={8}, generation={9}" +message Database { + int32 revision = 1; + repeated Data assetBundleList = 2; + repeated string _tagname = 3; + repeated Data resourceList = 4; + string urlFormat = 5; +} + +message Data { + int32 id = 1; //id={0} + string filepath = 2; + string name = 3; //name={1} + int32 size = 4; //size={2} + uint32 crc = 5; //crc={3} + repeated int32 tags = 6; //tags=[{4}] + int32 priority = 7; + repeated int32 deps = 8; //deps=[{5}] + State state = 9; //state={6}? + string md5 = 10; //md5={7} + string objectName = 11; //objectName={8} + uint64 generation = 12; //generation={9} + enum State { + NONE = 0; + ADD = 1; + UPDATE = 2; + LATEST = 3; + DELETE = 4; + } +} diff --git a/reinkuro/octodb_pb2.py b/reinkuro/octodb_pb2.py new file mode 100644 index 0000000..8bec7f0 --- /dev/null +++ b/reinkuro/octodb_pb2.py @@ -0,0 +1,480 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: octodb.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor.FileDescriptor( + name="octodb.proto", + package="", + syntax="proto3", + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\x0foctodb.proto"~\n\x08\x44\x61tabase\x12\x10\n\x08revision\x18\x01 \x01(\x05\x12\x1e\n\x0f\x61ssetBundleList\x18\x02 \x03(\x0b\x32\x05.Data\x12\x10\n\x08_tagname\x18\x03 \x03(\t\x12\x1b\n\x0cresourceList\x18\x04 \x03(\x0b\x32\x05.Data\x12\x11\n\turlFormat\x18\x05 \x01(\t"\x8c\x02\n\x04\x44\x61ta\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x10\n\x08\x66ilepath\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x0c\n\x04size\x18\x04 \x01(\x05\x12\x0b\n\x03\x63rc\x18\x05 \x01(\r\x12\x0c\n\x04tags\x18\x06 \x03(\x05\x12\x10\n\x08priority\x18\x07 \x01(\x05\x12\x0c\n\x04\x64\x65ps\x18\x08 \x03(\x05\x12\x1a\n\x05state\x18\t \x01(\x0e\x32\x0b.Data.State\x12\x0b\n\x03md5\x18\n \x01(\t\x12\x12\n\nobjectName\x18\x0b \x01(\t\x12\x12\n\ngeneration\x18\x0c \x01(\x04">\n\x05State\x12\x08\n\x04NONE\x10\x00\x12\x07\n\x03\x41\x44\x44\x10\x01\x12\n\n\x06UPDATE\x10\x02\x12\n\n\x06LATEST\x10\x03\x12\n\n\x06\x44\x45LETE\x10\x04\x62\x06proto3', +) + + +_DATA_STATE = _descriptor.EnumDescriptor( + name="State", + full_name="Data.State", + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name="NONE", + index=0, + number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.EnumValueDescriptor( + name="ADD", + index=1, + number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.EnumValueDescriptor( + name="UPDATE", + index=2, + number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.EnumValueDescriptor( + name="LATEST", + index=3, + number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.EnumValueDescriptor( + name="DELETE", + index=4, + number=4, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), + ], + containing_type=None, + serialized_options=None, + serialized_start=354, + serialized_end=416, +) +_sym_db.RegisterEnumDescriptor(_DATA_STATE) + + +_DATABASE = _descriptor.Descriptor( + name="Database", + full_name="Database", + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name="revision", + full_name="Database.revision", + index=0, + number=1, + type=5, + cpp_type=1, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="assetBundleList", + full_name="Database.assetBundleList", + index=1, + number=2, + type=11, + cpp_type=10, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="_tagname", + full_name="Database._tagname", + index=2, + number=3, + type=9, + cpp_type=9, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="resourceList", + full_name="Database.resourceList", + index=3, + number=4, + type=11, + cpp_type=10, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="urlFormat", + full_name="Database.urlFormat", + index=4, + number=5, + type=9, + cpp_type=9, + label=1, + has_default_value=False, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + ], + extensions=[], + nested_types=[], + enum_types=[], + serialized_options=None, + is_extendable=False, + syntax="proto3", + extension_ranges=[], + oneofs=[], + serialized_start=19, + serialized_end=145, +) + + +_DATA = _descriptor.Descriptor( + name="Data", + full_name="Data", + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name="id", + full_name="Data.id", + index=0, + number=1, + type=5, + cpp_type=1, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="filepath", + full_name="Data.filepath", + index=1, + number=2, + type=9, + cpp_type=9, + label=1, + has_default_value=False, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="name", + full_name="Data.name", + index=2, + number=3, + type=9, + cpp_type=9, + label=1, + has_default_value=False, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="size", + full_name="Data.size", + index=3, + number=4, + type=5, + cpp_type=1, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="crc", + full_name="Data.crc", + index=4, + number=5, + type=13, + cpp_type=3, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="tags", + full_name="Data.tags", + index=5, + number=6, + type=5, + cpp_type=1, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="priority", + full_name="Data.priority", + index=6, + number=7, + type=5, + cpp_type=1, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="deps", + full_name="Data.deps", + index=7, + number=8, + type=5, + cpp_type=1, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="state", + full_name="Data.state", + index=8, + number=9, + type=14, + cpp_type=8, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="md5", + full_name="Data.md5", + index=9, + number=10, + type=9, + cpp_type=9, + label=1, + has_default_value=False, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="objectName", + full_name="Data.objectName", + index=10, + number=11, + type=9, + cpp_type=9, + label=1, + has_default_value=False, + default_value=b"".decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + _descriptor.FieldDescriptor( + name="generation", + full_name="Data.generation", + index=11, + number=12, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + serialized_options=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + ), + ], + extensions=[], + nested_types=[], + enum_types=[ + _DATA_STATE, + ], + serialized_options=None, + is_extendable=False, + syntax="proto3", + extension_ranges=[], + oneofs=[], + serialized_start=148, + serialized_end=416, +) + +_DATABASE.fields_by_name["assetBundleList"].message_type = _DATA +_DATABASE.fields_by_name["resourceList"].message_type = _DATA +_DATA.fields_by_name["state"].enum_type = _DATA_STATE +_DATA_STATE.containing_type = _DATA +DESCRIPTOR.message_types_by_name["Database"] = _DATABASE +DESCRIPTOR.message_types_by_name["Data"] = _DATA +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +Database = _reflection.GeneratedProtocolMessageType( + "Database", + (_message.Message,), + { + "DESCRIPTOR": _DATABASE, + "__module__": "octodb_pb2" + # @@protoc_insertion_point(class_scope:Database) + }, +) +_sym_db.RegisterMessage(Database) + +Data = _reflection.GeneratedProtocolMessageType( + "Data", + (_message.Message,), + { + "DESCRIPTOR": _DATA, + "__module__": "octodb_pb2" + # @@protoc_insertion_point(class_scope:Data) + }, +) +_sym_db.RegisterMessage(Data) + + +# @@protoc_insertion_point(module_scope) diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..9abb985 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,4 @@ +[flake8] +extend-ignore = E203 + E501 +max-line-length = 120 diff --git a/setup.py b/setup.py index 145013e..246b1b7 100755 --- a/setup.py +++ b/setup.py @@ -1,45 +1,44 @@ # -*- coding: utf-8 -*- from pathlib import Path from setuptools import Extension, find_packages, setup -from build import * +from build import build kuro_dir = Path(__file__).resolve().parent.joinpath("reinkuro") clibs_dir = kuro_dir.joinpath("_clibs") kuro_ext_config = dict( - include_dirs=[ - str(clibs_dir.joinpath("kuro")) - ], + include_dirs=[str(clibs_dir.joinpath("kuro"))], sources=[ str(clibs_dir.joinpath("kuro/kuro.c")), - str(clibs_dir.joinpath("kuromodule.c")) - ] + str(clibs_dir.joinpath("kuromodule.c")), + ], ) ext_modules = [Extension("reinkuro._clibs.kuro", **kuro_ext_config)] packages = find_packages(exclude=["tests", "*.tests", "*.tests.*"]) -package_data = {'': ['*'], 'reinkuro._clibs': ['kuro/*']} -install_requires = ['pycryptodome>=3.10.1,<4.0.0', 'rich>=10.5.0,<11.0.0'] +package_data = {"": ["*"], "reinkuro._clibs": ["kuro/*"]} + +install_requires = ["pycryptodome>=3.10.1,<4.0.0", "rich>=10.5.0,<11.0.0"] setup_kwargs = { - 'name': 'reinkuro', - 'version': '0.1.0', - 'description': 'Tools for working with Nier Reincarnation.', - 'long_description': None, - 'author': 'Bivi', - 'author_email': '190nano@gmail.com', - 'maintainer': None, - 'maintainer_email': None, - 'url': None, - 'packages': packages, - 'package_data': package_data, - 'install_requires': install_requires, - 'python_requires': '>=3.8,<4.0', - 'ext_modules': ext_modules, + "name": "reinkuro", + "version": "0.1.0", + "description": "Tools for working with Nier Reincarnation.", + "long_description": None, + "author": "Bivi", + "author_email": "190nano@gmail.com", + "maintainer": None, + "maintainer_email": None, + "url": None, + "packages": packages, + "package_data": package_data, + "install_requires": install_requires, + "python_requires": ">=3.8,<4.0", + "ext_modules": ext_modules, } build(setup_kwargs) diff --git a/tests/test_reinkuro.py b/tests/test_reinkuro.py index 6d4277c..03469ab 100755 --- a/tests/test_reinkuro.py +++ b/tests/test_reinkuro.py @@ -2,9 +2,11 @@ from reinkuro.kuro import cryptbystring from pathlib import Path + def test_version(): assert __version__ == "0.1.0" + def test_cryptbystring(): testasset = Path("tests/sample.bin").read_bytes()