From 76cf8fed6911d0881e84b869f213472a51f77997 Mon Sep 17 00:00:00 2001 From: Ave Ozkal Date: Fri, 8 Mar 2019 14:53:24 +0300 Subject: [PATCH] patchport: Add automated patch porting --- .gitignore | 1 + README.md | 4 ++-- patchport.py | 25 +++++++++++++++++++++---- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 629742a..e2b49e0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ patches/*/*-custom.patch +patches/*/*.patch-failed diff --git a/README.md b/README.md index 30695aa..0559383 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Feel free to ignore play protect, it's bullshit. #### Toolchain setup -- Get apktool (due to [a bug](https://github.com/iBotPeaches/Apktool/issues/1909) present on apktool v2.3.4, I recommend using [this build](https://elixi.re/i/cq4r2zxg.jar)) +- Get apktool (due to 2 bugs present in v2.3.4, you're strongly recommended to use v2.4.0) - Get a keystore, see [here](https://stackoverflow.com/a/14994354/3286892), step 1. - If you want Mutant Standard emoji patches, get 72x72 copies of latest version of mutant standard emojis with codepoints. I have a zip [here](https://mutant.lavatech.top/72x72.zip). - Extract the emojis you got somewhere. @@ -46,7 +46,7 @@ To get the diff, run `diff -crB -x "dist" -x "res/raw" -x "build" CleanFolder Pa #### Porting patches -You can use `patchport` to easily attempt to port patches. +You can use `patchport.py` to easily attempt to port patches. It's not really intelligent and doesn't do much more than just checking if an existing patch can be applied to a given version (it also replaces relevant variables required for porting various patches), but it saves a lot of time if used carefully. diff --git a/patchport.py b/patchport.py index 449172a..7e8b0b0 100644 --- a/patchport.py +++ b/patchport.py @@ -4,6 +4,7 @@ import sys import os import subprocess import datetime +import shutil # Example invocation: # python3 patchport.py 839 8.3.9g @@ -14,6 +15,7 @@ from_versionname = sys.argv[2] apk_folder = sys.argv[3] cutthecord_folder = sys.argv[4] debug = False +tmp_folder = "/tmp/patchport" def modify_patch(patch_name, patch_path): @@ -32,6 +34,20 @@ def modify_patch(patch_name, patch_path): return patch_content +def fix_offset(patch_contents): + # OH GOD OH FUCK + shutil.rmtree(tmp_folder, ignore_errors=True) + shutil.copytree(apk_folder, tmp_folder) + subprocess.run("patch -p1 --no-backup-if-mismatch --force", + shell=True, input=patch_contents, text=True, + cwd=tmp_folder) + out = subprocess.run(f"diff -crB {apk_folder} {tmp_folder}", + shell=True, input=patch_contents, text=True, + cwd=tmp_folder, capture_output=True) + shutil.rmtree(tmp_folder, ignore_errors=True) + return out.stdout + + re_versioncode = re.compile(r'platformBuildVersionCode="([0-9]+)"') re_versionname = re.compile(r'platformBuildVersionName="([0-9a-z.]+)"') re_releasedate = re.compile(r'released on ([0-9]{4}-[0-9]{2}-[0-9]{2})') @@ -64,7 +80,8 @@ for patch in os.listdir(os.path.join(cutthecord_folder, "patches")): # Check if patch exists for from_version, if it doesn't, warn user if not os.path.isfile(patch_path): # Don't warn on instructional patches - if patch not in ["customfont", "customring", "bettertm", "bettertmlight"]: + if patch not in ["customfont", "customring", + "bettertm", "bettertmlight"]: print(f"SKIPPED: No {from_versionname} version found for {patch}.") continue @@ -80,10 +97,10 @@ for patch in os.listdir(os.path.join(cutthecord_folder, "patches")): if "FAILED" in out.stdout: print(f"FAILED: {patch} failed, please fix by hand.") failures.append(patch) - continue - # TODO: Can we do this automatically? + out_path += "-failed" elif "offset" in out.stdout: - print(f"WARNING: {patch} has offsets, please correct by hand.") + patch_contents = fix_offset(patch_contents) + print(f"WARNING: {patch} has offsets which were auto corrected.") if debug: print(out.stdout)