so much more shit man

This commit is contained in:
Your Name 2024-08-17 19:14:45 +02:00
parent 9e065cd638
commit e8ffddf93f
8 changed files with 17732 additions and 68 deletions

View file

@ -1,39 +0,0 @@
from lark import Lark
from lark.lexer import Token
from lark.tree import Branch
import re
def parse_string(token: Token):
if token.type == 'STRING':
string = token.value[1:-1]
string = re.sub(r"\\n","\n", string)
string = re.sub(r"\\t","\t", string)
string = re.sub(r"\\r","\r", string)
string = re.sub(r"\\(.)",r"\1", string)
return string
elif token.type == 'RAW_STRING':
string = token.value[1:-1]
return string
elif token.type == 'LONG_STRING':
string = re.match(re.compile(r"<<\s*(?P<terminator>[^\n]+)\n(.*)\n(?P=terminator)", re.MULTILINE + re.DOTALL),token.value)
assert string is not None
string = string.group(2)
return string
def process_patch(branch: Branch[Token]):
# First instruction is always file declaration
target_file = parse_string(branch.children[0].children[0]) # pyright: ignore[reportUnknownMemberType, reportArgumentType]
for inst in branch.children[1:]:
match inst.data:
case "insert":
print(f"Inserting {parse_string(inst.children[1])} at {inst.children[0]} in {target_file}")
if __name__ == '__main__':
lark = Lark.open('grammar.lark', rel_to=__file__)
with open('test.txt', 'r') as f:
result = lark.parse(f.read())
for patch in result.children:
process_patch(patch)

View file

@ -0,0 +1,26 @@
from polly import parse_patch_file
from polly import parse_location
from pathlib import Path
from ..task.util import *
def read_insertion(action, patch_file):
with open(patch_file, 'r') as f:
src = f.read()
location = parse_location(action["at"], src)
def process_patch_file(patch_file: str, check_date: bool = True):
patches = parse_patch_file(patch_file)
for patch in patches:
target_dest = (PATCHED_RSC_DIR / patch["target"])
if check_date and target_dest.exists() and target_dest.stat().st_mtime > patch["timestamp"]:
# Patch skipped
continue
insertions = [read_insertion(action) for action in patch["actions"]]
insertions = [x for x in insertions if x is not None]

View file

@ -38,4 +38,7 @@ LINE_COLUMN: /ln\d+c\d+/
IDENTIFIER: /[a-zA-Z_][a-zA-Z0-9_]*/
PATTERN: /\/([^\/\\]|\\.)*\//
COMMENT: /#[^\r\n]+/
%ignore /[\t \f\n]+/
%ignore COMMENT

View file

@ -0,0 +1,77 @@
from lark import Lark
from lark.lexer import Token
from lark.tree import Branch
import os
import re
from math import floor
def parse_string(token: Token):
if token.type == 'STRING':
string = token.value[1:-1]
string = re.sub(r"\\n","\n", string)
string = re.sub(r"\\t","\t", string)
string = re.sub(r"\\r","\r", string)
string = re.sub(r"\\(.)",r"\1", string)
return string
elif token.type == 'RAW_STRING':
string = token.value[1:-1]
return string
elif token.type == 'LONG_STRING':
string = re.match(re.compile(r"<<\s*(?P<terminator>[^\n]+)\n(.*)\n(?P=terminator)", re.MULTILINE + re.DOTALL),token.value)
assert string is not None
string = string.group(2)
return string
def parse_location(location: Token):
assert isinstance(location.value, str)
m = re.match(r"ln([0-9]+)(?:c([0-9]+))?", location.value)
if m:
ln, col = m.groups()
return {"type": "lncol", "line": ln, "column": col}
m = re.match(r"ch([0-9]+)", location.value)
if m:
ch = m.groups()[0]
return {"type": "char", "index": ch}
raise RuntimeError("Cannot parse location")
def absolute_location(location, src: str):
if location["type"] == "char":
return location["index"]
elif location["type"] == "lncol":
j = 0
for i, x in enumerate(src.split('\n')):
if i ==
j += len(x) + 1
print(f"Cannot insert at line {location['line']}. The file is not long enough.")
exit(-1)
def parse_patch(branch: Branch[Token], mtime: float):
# First instruction is always file declaration
target_file = parse_string(branch.children[0].children[0]) # pyright: ignore[reportUnknownMemberType, reportArgumentType]
actions = []
for inst in branch.children[1:]:
match inst.data:
case "insert":
actions.append({"type": "insert", "at": parse_location(inst.children[0]), "content": parse_string(inst.children[1])})
# print(f"Inserting {parse_string(inst.children[1])} at {inst.children[0]} in {target_file}")
return {"target": target_file, "actions": actions, "timestamp": mtime}
def parse_patch_file(file: str):
lark = Lark.open('grammar.lark', rel_to=__file__)
mtime = os.path.getmtime(file)
with open(file, 'r') as f:
result = lark.parse(f.read())
patches = [parse_patch(patch, mtime) for patch in result.children]
return patches

View file

@ -1,7 +1,7 @@
from pathlib import Path
import shutil
def merge_into(src: Path | str, dest: Path | str):
def merge_into(src: Path | str, dest: Path | str, check_date: bool = True):
src = Path(src)
dest = Path(dest)
@ -13,7 +13,7 @@ def merge_into(src: Path | str, dest: Path | str):
dest_file = dest / src_file.relative_to(src)
# Don't update if dest is newer than source
if dest_file.exists() and src_file.stat().st_mtime < dest_file.stat().st_mtime:
if check_date and dest_file.exists() and src_file.stat().st_mtime < dest_file.stat().st_mtime:
continue
dest_file.parent.mkdir(parents=True, exist_ok=True)
@ -21,4 +21,3 @@ def merge_into(src: Path | str, dest: Path | str):
changed = True
return changed

View file

@ -9,33 +9,18 @@ from .extract import extract
def patch_resources():
_ = extract()
# The way we merge resources is as follows:
# First, we copy our raw-resources from src/resources
# Second, we apply our patches, which are handled by polly
# Finally, we populate all missing entries from build/extracted
# The reason we do this is that build/extracted will always have a date greater than src/resources
# until the files are modified after first build, which makes simply merging-by-date impossible.
first_time = False
s = fileutil.merge_into(SRC_RESOURCES_DIR, PATCHED_RSC_DIR)
# Copy original resources only the first time
if not PATCHED_RSC_DIR.exists():
print("Copying original resources...")
shutil.copytree(EXTRACTED_DIR, PATCHED_RSC_DIR, ignore=shutil.ignore_patterns("smali*"))
first_time = True
s = fileutil.merge_into(SRC_RESOURCES_DIR, PATCHED_RSC_DIR, check_date=not first_time)
if s:
print("Copied custom resources from src/resources")
else:
print("Skipped copying resources from src/resources")
print("Copying original resources...")
for (cd, _, files) in EXTRACTED_DIR.walk():
for file in files:
# Don't copy smali code
if file.startswith("smali"):
continue
src_file = cd / file
dest_file = PATCHED_RSC_DIR / src_file.relative_to(EXTRACTED_DIR)
# Don't update if dest is newer than source
if dest_file.exists() and src_file.stat().st_mtime < dest_file.stat().st_mtime:
continue
dest_file.parent.mkdir(parents=True, exist_ok=True)
_ = shutil.copyfile(src_file, dest_file)

12
src/patches/public.patch Normal file
View file

@ -0,0 +1,12 @@
file 'res/values/public.xml'
insert ln17595 << @end
<public type="drawable" name="oval_yellow" id="0x7f08f001" /> <!-- YKit-BringBackPhoebe -->
<public type="id" name="ykit_settings" id="0x7f0bf001" /> <!-- YKit-Settings -->
<public type="id" name="ykit_version" id="0x7f0bf003" /> <!-- YKit-Settings -->
<public type="id" name="text_color_yellow" id="0x7f0bf002" /> <!-- YKit-BringBackPhoebe -->
<public type="layout" name="activity_ykit_settings" id="0x7f0ef001" /> <!-- YKit-Settings -->
<public type="raw" name="ykit_meow" id="0x7f12f001" /> <!-- YKit-Settings -->
@end
#17595

17601
src/patches/public.xml Normal file

File diff suppressed because it is too large Load diff