forked from distok/cutthecord
		
	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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue