patchport: Add automated patch porting
This commit is contained in:
parent
1a4c42b810
commit
76cf8fed69
3 changed files with 24 additions and 6 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
patches/*/*-custom.patch
|
||||
patches/*/*.patch-failed
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
25
patchport.py
25
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)
|
||||
|
|
Reference in a new issue