Release Healer Man 0.1.29
This commit is contained in:
1 parent
8c9809d3e0
commit
544c1bee91
120 files changed
+4363
-1036
No files matched your search
@@ -0,0 +1,58 @@
|
||||
"""Verify the packaged bytes, including Android asset-name/compression behavior."""
|
||||
|
||||
import argparse
|
||||
import gzip
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
from zipfile import ZIP_STORED, ZipFile
|
||||
|
||||
|
||||
def verify_package(apk: Path) -> dict:
|
||||
with ZipFile(apk) as archive:
|
||||
manifest = json.loads(archive.read("assets/public/content/bootstrap-manifest.json"))
|
||||
checked = set()
|
||||
object_bytes = 0
|
||||
for logical_path, entry in manifest["files"].items():
|
||||
stored = entry.get("download", entry)
|
||||
if stored["url"] in checked:
|
||||
continue
|
||||
checked.add(stored["url"])
|
||||
name = "assets/public" + stored["url"]
|
||||
data = archive.read(name)
|
||||
if len(data) != stored["bytes"] or hashlib.sha256(data).hexdigest() != stored["sha256"]:
|
||||
raise ValueError(f"Packaged object failed verification: {logical_path}")
|
||||
object_bytes += len(data)
|
||||
if "download" in entry:
|
||||
if archive.getinfo(name).compress_type != ZIP_STORED:
|
||||
raise ValueError(f"Android recompressed an already compressed object: {name}")
|
||||
data = gzip.decompress(data)
|
||||
if len(data) != entry["bytes"] or hashlib.sha256(data).hexdigest() != entry["sha256"]:
|
||||
raise ValueError(f"Expanded object failed verification: {logical_path}")
|
||||
dungeons = sum(pack["id"].startswith("dungeon:") and pack["bundledOnAndroid"] for pack in manifest["packs"])
|
||||
expected_objects = {"assets/public" + url for url in checked}
|
||||
actual_objects = {name for name in archive.namelist() if name.startswith("assets/public/content/bundled/") and not name.endswith("/")}
|
||||
if actual_objects != expected_objects:
|
||||
raise ValueError("APK includes missing or unreferenced bundled objects.")
|
||||
manastorms = sum(pack["id"].startswith("manastorm:") and pack["bundledOnAndroid"] for pack in manifest["packs"])
|
||||
if dungeons != 84 or manastorms != 0:
|
||||
raise ValueError(f"Unexpected bundled content: {dungeons} dungeons, {manastorms} Manastorm packs")
|
||||
return {
|
||||
"apk": str(apk.resolve()), "apkBytes": apk.stat().st_size,
|
||||
"manifestVersion": manifest["version"], "logicalFiles": len(manifest["files"]),
|
||||
"verifiedUniqueObjects": len(checked), "storedObjectBytes": object_bytes,
|
||||
"bundledDungeons": dungeons, "bundledManastormPacks": manastorms,
|
||||
"allOriginalHashesMatch": True,
|
||||
}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("apk", type=Path)
|
||||
parser.add_argument("--report", type=Path)
|
||||
args = parser.parse_args()
|
||||
result = json.dumps(verify_package(args.apk), indent=2) + "\n"
|
||||
if args.report:
|
||||
args.report.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.report.write_text(result, encoding="utf-8")
|
||||
print(result, end="")
|
||||
Reference in new issue
Block a user