LihonT 2 Luna beta: source release
Mod for TikTok 47.1.3 (arm64) in Material 3 style: bottom bar, profile menu, TikTok settings and comments; downloads without the watermark; switches for ads, live streams and the Shop tab; badges of other mods next to names and the niche mod badge (members service); app icons; mod settings screen. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
80
scripts/quick_runtime.py
Normal file
80
scripts/quick_runtime.py
Normal file
@@ -0,0 +1,80 @@
|
||||
"""Quick rebuild after a change in the runtime Java only (src/lihont/two).
|
||||
|
||||
Takes an APK that py -m lihont.upgrade built earlier, swaps the mod's runtime classes inside its
|
||||
classes35.dex for a fresh compile of src/lihont/two, and signs the result. The smali patches of TikTok's
|
||||
own classes are not touched, so this is only right while lihont/*_patch.py and lihont/upgrade.py are
|
||||
unchanged since that APK was built; after any such change run the full build.
|
||||
|
||||
usage (from the repository root):
|
||||
py -B scripts/quick_runtime.py ComplectAPK/lihont-2.0-luna-beta5.apk -o ComplectAPK/lihont-2.0-luna-beta6.apk
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
os.chdir(ROOT)
|
||||
|
||||
from lihont import dexpatch, manifest as manifest_module # noqa: E402
|
||||
from lihont.apkzip import Apk # noqa: E402
|
||||
from lihont.axml import Axml # noqa: E402
|
||||
from lihont.toolchain import Toolchain # noqa: E402
|
||||
|
||||
RUNTIME = "Llihont/two/"
|
||||
DEX = "classes35.dex"
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("built", help="an APK built by lihont.upgrade")
|
||||
parser.add_argument("-o", "--out", required=True)
|
||||
parser.add_argument("--work", default="work/quick")
|
||||
args = parser.parse_args()
|
||||
|
||||
source, output, room = Path(args.built).resolve(), Path(args.out).resolve(), Path(args.work).resolve()
|
||||
if source == output:
|
||||
raise SystemExit("Write to a new file: the built APK stays as it is")
|
||||
room.mkdir(parents=True, exist_ok=True)
|
||||
tools = Toolchain("tools")
|
||||
apk = Apk(str(source))
|
||||
try:
|
||||
api = manifest_module.min_sdk(Axml.parse(apk.read("AndroidManifest.xml")))
|
||||
runtime = Path(tools.compile_dex("src/lihont/two", str(room / "runtime"), api)).read_bytes()
|
||||
|
||||
compiler = room / "compiler"
|
||||
compiler.mkdir(parents=True, exist_ok=True)
|
||||
subprocess.run(["javac", "--release", "17", "-cp", tools.smali, "-d", str(compiler),
|
||||
"src/RefreshClasses.java"], check=True)
|
||||
host_dex = apk.read(DEX)
|
||||
host, fresh, merged = room / "host.dex", room / "fresh.dex", room / "merged.dex"
|
||||
host.write_bytes(host_dex)
|
||||
fresh.write_bytes(runtime)
|
||||
subprocess.run(["java", "-Xmx1g", "-cp", os.pathsep.join([str(compiler), tools.smali]),
|
||||
"RefreshClasses", str(host), str(fresh), str(merged), str(api)], check=True)
|
||||
result = merged.read_bytes()
|
||||
|
||||
if dexpatch.dex_format(host_dex) != dexpatch.dex_format(result):
|
||||
raise SystemExit("The refresh changed the DEX format")
|
||||
before = {m for m in dexpatch.defined_methods(host_dex) if not m.startswith(RUNTIME)}
|
||||
after = dexpatch.defined_methods(result)
|
||||
if not before.issubset(after):
|
||||
raise SystemExit("The refresh lost classes that are not part of the runtime")
|
||||
if not any(m.startswith("Llihont/two/LihonTRegion;->") for m in after):
|
||||
raise SystemExit("LihonTRegion is missing after the refresh")
|
||||
|
||||
apk.replace(DEX, result)
|
||||
apk.drop_signature()
|
||||
output.parent.mkdir(parents=True, exist_ok=True)
|
||||
apk.write(str(output))
|
||||
finally:
|
||||
apk.close()
|
||||
tools.sign(str(output))
|
||||
print("%s %d bytes" % (output.name, output.stat().st_size))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user