"""Restore immutable public build inputs; no company secrets required (Python 3.10+).""" import hashlib from pathlib import Path import urllib.request import zipfile ROOT = Path(__file__).resolve().parent LIBS = ROOT / 'V2rayNG/app/libs' CACHE = ROOT / '.tools/public-build-inputs' def get(url, sha256, target): if target.exists() and hashlib.sha256(target.read_bytes()).hexdigest() == sha256: return target target.parent.mkdir(parents=True, exist_ok=True) temporary = target.with_suffix(target.suffix + '.download') try: with urllib.request.urlopen(url, timeout=180) as response, temporary.open('wb') as output: while block := response.read(1024 * 1024): output.write(block) if hashlib.sha256(temporary.read_bytes()).hexdigest() != sha256: raise ValueError('Build input SHA256 mismatch: ' + target.name) temporary.replace(target) finally: temporary.unlink(missing_ok=True) return target def main(): inputs = [ ('libv2ray.aar', 'https://github.com/2dust/AndroidLibXrayLite/releases/download/v26.5.19/libv2ray.aar', '3d43b9344723e9c0625527de4f2bea0ee02c21180224e5ecab3384af143ca6d0'), ('quickie-foss-1.14.0.aar', 'https://jitpack.io/com/github/T8RIN/QuickieExtended/quickie-foss/1.14.0/quickie-foss-1.14.0.aar', '4d90e9cb37e07b57eaa3a839be2abdc422c0ce9ac8e969720a2a71c968cd771f'), ('Toasty-1.5.2.aar', 'https://jitpack.io/com/github/GrenderG/Toasty/1.5.2/Toasty-1.5.2.aar', '57866e731ebe3ef82328942cd4d96cf940b2406c9440f33857f69777027f36b5')] for name, url, digest in inputs: get(url, digest, LIBS / name) print('Verified ' + name) upstream = get('https://github.com/2dust/v2rayNG/releases/download/2.2.1/v2rayNG_2.2.1_universal.apk', '6139e6c04926f85c5aa9f66ce54c94f311b31d2818b55c36068fe9f983eb5001', CACHE / 'v2rayNG_2.2.1_universal.apk') hashes = {'arm64-v8a': '4eb0b2353f4fb6d45f43cca39fe72197ce9df8c8f5ba5a82feac87abceb9ea7a', 'armeabi-v7a': '816c48bab1785fcdaaf7fc2f49dc6b0733cf11e68b9379640d22d6a539f306ff', 'x86': '6e42da45387d76630a8ffd52ea45cd5738395da39df31dba1a48806fa79d3572', 'x86_64': 'c61a54f38f61feb73b465d2245fe6e4746c2efba7e9024de8de025ce3fc9206e'} with zipfile.ZipFile(upstream) as archive: for abi, expected in hashes.items(): data = archive.read(f'lib/{abi}/libhev-socks5-tunnel.so') assert hashlib.sha256(data).hexdigest() == expected target = LIBS / abi / 'libhev-socks5-tunnel.so' target.parent.mkdir(parents=True, exist_ok=True) target.write_bytes(data) print('Verified HEV ' + abi) if __name__ == '__main__': main()