Слияние с обновлённым main
This commit is contained in:
@@ -33,12 +33,17 @@ jobs:
|
|||||||
echo "$KEYSTORE" | base64 -d > keystore.jks
|
echo "$KEYSTORE" | base64 -d > keystore.jks
|
||||||
echo "$KEYSTORE_PASS" > keystore.pass
|
echo "$KEYSTORE_PASS" > keystore.pass
|
||||||
|
|
||||||
- name: Build APK
|
- name: Prepare to build APK
|
||||||
id: build
|
id: build
|
||||||
run: |
|
run: |
|
||||||
mkdir original
|
mkdir original
|
||||||
mv app.apk original/
|
mv app.apk original/
|
||||||
python ./main.py -f
|
python ./main.py init
|
||||||
|
|
||||||
|
- name: Build APK
|
||||||
|
id: build
|
||||||
|
run: |
|
||||||
|
python ./main.py build -f
|
||||||
|
|
||||||
- name: Read title from report.log
|
- name: Read title from report.log
|
||||||
id: get_title
|
id: get_title
|
||||||
|
|||||||
+8
-2
@@ -13,8 +13,14 @@
|
|||||||
"package_name": {
|
"package_name": {
|
||||||
"new_package_name": "com.wowlikon.anixart"
|
"new_package_name": "com.wowlikon.anixart"
|
||||||
},
|
},
|
||||||
"cleanup": {
|
"compress": {
|
||||||
"keep_dirs": ["META-INF", "kotlin"]
|
"remove_language_files": true,
|
||||||
|
"remove_AI_voiceover": true,
|
||||||
|
"remove_debug_lines": true,
|
||||||
|
"remove_drawable_files": false,
|
||||||
|
"remove_unknown_files": true,
|
||||||
|
"remove_unknown_files_keep_dirs": ["META-INF", "kotlin"],
|
||||||
|
"compress_png_files": true
|
||||||
},
|
},
|
||||||
"change_server": {
|
"change_server": {
|
||||||
"server": "https://anixarty.wowlikon.tech/modding"
|
"server": "https://anixarty.wowlikon.tech/modding"
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
"""Remove unnecessary files"""
|
|
||||||
priority = 0
|
|
||||||
from tqdm import tqdm
|
|
||||||
|
|
||||||
import os
|
|
||||||
import shutil
|
|
||||||
|
|
||||||
|
|
||||||
def apply(config: dict) -> bool:
|
|
||||||
for item in os.listdir("./decompiled/unknown/"):
|
|
||||||
item_path = os.path.join("./decompiled/unknown/", item)
|
|
||||||
|
|
||||||
if os.path.isfile(item_path):
|
|
||||||
os.remove(item_path)
|
|
||||||
if config.get("verbose", False):
|
|
||||||
tqdm.write(f'Удалён файл: {item_path}')
|
|
||||||
elif os.path.isdir(item_path):
|
|
||||||
if item not in config["keep_dirs"]:
|
|
||||||
shutil.rmtree(item_path)
|
|
||||||
if config.get("verbose", False):
|
|
||||||
tqdm.write(f'Удалена папка: {item_path}')
|
|
||||||
return True
|
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Compress
|
||||||
|
|
||||||
|
Патч удаляет ненужные ресурсы что-бы уменьшить размер АПК
|
||||||
|
|
||||||
|
## настройки (compress в config.json)
|
||||||
|
|
||||||
|
- remove_unknown_files: true/false - удаляет файлы из директории decompiled/unknown
|
||||||
|
- remove_unknown_files_keep_dirs: list[str] - оставляет указанные директории в decompiled/unknown
|
||||||
|
- remove_debug_lines: true/false - удаляет строки `.line n` из декомпилированных smali файлов использованные для дебага
|
||||||
|
- remove_AI_voiceover: true/false - заменяет ИИ озвучку маскота аниксы пустыми mp3 файлами
|
||||||
|
- compress_png_files: true/false - сжимает PNG в директории decompiled/res
|
||||||
|
- remove_drawable_files: true/false - удаляет неиспользованные drawable-* из директории decompiled/res
|
||||||
|
- remove_language_files: true/false - удаляет все языки кроме русского и английского
|
||||||
|
|
||||||
|
## efficiency
|
||||||
|
|
||||||
|
Проверено с версией 9.0 Beta 7
|
||||||
|
|
||||||
|
разница = оригинальный размер апк - патченный размер апк, не учитывая другие патчи
|
||||||
|
|
||||||
|
| Настройка | Размер файла | Разница | % |
|
||||||
|
| :----------- | :-------------------: | :-----------------: | :-: |
|
||||||
|
| None | 17092 bytes - 17.1 MB | - | - |
|
||||||
|
| Compress PNG | 17072 bytes - 17.1 MB | 20 bytes - 0.0 MB | 0.11% |
|
||||||
|
| Remove files | 17020 bytes - 17.0 MB | 72 bytes - 0.1 MB | 0.42% |
|
||||||
|
| Remove draws | 16940 bytes - 16.9 MB | 152 bytes - 0.2 MB | 0.89% |
|
||||||
|
| Remove lines | 16444 bytes - 16.4 MB | 648 bytes - 0.7 MB | 3.79% |
|
||||||
|
| Remove ai vo | 15812 bytes - 15.8 MB | 1280 bytes - 1.3 MB | 7.49% |
|
||||||
|
| Remove langs | 15764 bytes - 15.7 MB | 1328 bytes - 1.3 MB | 7.76% |
|
||||||
|
| Все включены | 13592 bytes - 13.6 MB | 3500 bytes - 4.8 MB | 20.5% |
|
||||||
@@ -0,0 +1,269 @@
|
|||||||
|
"""Remove and compress resources"""
|
||||||
|
|
||||||
|
priority = -1
|
||||||
|
|
||||||
|
# imports
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
from tqdm import tqdm
|
||||||
|
from utils.smali_parser import get_smali_lines, save_smali_lines
|
||||||
|
|
||||||
|
|
||||||
|
# Patch
|
||||||
|
def remove_unknown_files(config):
|
||||||
|
path = "./decompiled/unknown"
|
||||||
|
items = os.listdir(path)
|
||||||
|
for item in items:
|
||||||
|
item_path = f"{path}/{item}"
|
||||||
|
if os.path.isfile(item_path):
|
||||||
|
os.remove(item_path)
|
||||||
|
if config.get("verbose", False):
|
||||||
|
tqdm.write(f"Удалён файл: {item_path}")
|
||||||
|
elif os.path.isdir(item_path):
|
||||||
|
if item not in config["remove_unknown_files_keep_dirs"]:
|
||||||
|
shutil.rmtree(item_path)
|
||||||
|
if config.get("verbose", False):
|
||||||
|
tqdm.write(f"Удалёна директория: {item_path}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def remove_debug_lines(config):
|
||||||
|
for root, _, files in os.walk("./decompiled"):
|
||||||
|
for filename in files:
|
||||||
|
file_path = os.path.join(root, filename)
|
||||||
|
if os.path.isfile(file_path) and filename.endswith(".smali"):
|
||||||
|
file_content = get_smali_lines(file_path)
|
||||||
|
new_content = []
|
||||||
|
for line in file_content:
|
||||||
|
if line.find(".line") >= 0:
|
||||||
|
continue
|
||||||
|
new_content.append(line)
|
||||||
|
save_smali_lines(file_path, new_content)
|
||||||
|
if config.get("verbose", False):
|
||||||
|
tqdm.write(f"Удалены дебаг линии из: {file_path}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def compress_png(config, png_path: str):
|
||||||
|
try:
|
||||||
|
assert subprocess.run(
|
||||||
|
[
|
||||||
|
"pngquant",
|
||||||
|
"--force",
|
||||||
|
"--ext",
|
||||||
|
".png",
|
||||||
|
"--quality=65-90",
|
||||||
|
png_path,
|
||||||
|
],
|
||||||
|
capture_output=True,
|
||||||
|
).returncode in [0, 99]
|
||||||
|
if config.get("verbose", False):
|
||||||
|
tqdm.write(f"Сжат файл PNG: {png_path}")
|
||||||
|
return True
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
tqdm.write(f"Ошибка при сжатии {png_path}: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def compress_png_files(config):
|
||||||
|
compressed = []
|
||||||
|
for root, _, files in os.walk("./decompiled"):
|
||||||
|
for file in files:
|
||||||
|
if file.lower().endswith(".png"):
|
||||||
|
compress_png(config, f"{root}/{file}")
|
||||||
|
compressed.append(f"{root}/{file}")
|
||||||
|
return len(compressed) > 0 and any(compressed)
|
||||||
|
|
||||||
|
|
||||||
|
def remove_AI_voiceover(config):
|
||||||
|
blank = "./patches/resources/blank.mp3"
|
||||||
|
path = "./decompiled/res/raw"
|
||||||
|
files = [
|
||||||
|
"reputation_1.mp3",
|
||||||
|
"reputation_2.mp3",
|
||||||
|
"reputation_3.mp3",
|
||||||
|
"sound_beta_1.mp3",
|
||||||
|
"sound_create_blog_1.mp3",
|
||||||
|
"sound_create_blog_2.mp3",
|
||||||
|
"sound_create_blog_3.mp3",
|
||||||
|
"sound_create_blog_4.mp3",
|
||||||
|
"sound_create_blog_5.mp3",
|
||||||
|
"sound_create_blog_6.mp3",
|
||||||
|
"sound_create_blog_reputation_1.mp3",
|
||||||
|
"sound_create_blog_reputation_2.mp3",
|
||||||
|
"sound_create_blog_reputation_3.mp3",
|
||||||
|
"sound_create_blog_reputation_4.mp3",
|
||||||
|
"sound_create_blog_reputation_5.mp3",
|
||||||
|
"sound_create_blog_reputation_6.mp3",
|
||||||
|
]
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
if os.path.exists(f"{path}/{file}"):
|
||||||
|
os.remove(f"{path}/{file}")
|
||||||
|
shutil.copyfile(blank, f"{path}/{file}")
|
||||||
|
if config.get("verbose", False):
|
||||||
|
tqdm.write(f"Файл mp3 был заменён на пустой: {path}/{file}")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def remove_language_files(config):
|
||||||
|
path = "./patches/res"
|
||||||
|
folders = [
|
||||||
|
"values-af",
|
||||||
|
"values-am",
|
||||||
|
"values-ar",
|
||||||
|
"values-as",
|
||||||
|
"values-az",
|
||||||
|
"values-b+es+419",
|
||||||
|
"values-b+sr+Latn",
|
||||||
|
"values-be",
|
||||||
|
"values-bg",
|
||||||
|
"values-bn",
|
||||||
|
"values-bs",
|
||||||
|
"values-ca",
|
||||||
|
"values-cs",
|
||||||
|
"values-da",
|
||||||
|
"values-de",
|
||||||
|
"values-el",
|
||||||
|
"values-en-rAU",
|
||||||
|
"values-en-rCA",
|
||||||
|
"values-en-rGB",
|
||||||
|
"values-en-rIN",
|
||||||
|
"values-en-rXC",
|
||||||
|
"values-es",
|
||||||
|
"values-es-rGT",
|
||||||
|
"values-es-rUS",
|
||||||
|
"values-et",
|
||||||
|
"values-eu",
|
||||||
|
"values-fa",
|
||||||
|
"values-fi",
|
||||||
|
"values-fr",
|
||||||
|
"values-fr-rCA",
|
||||||
|
"values-gl",
|
||||||
|
"values-gu",
|
||||||
|
"values-hi",
|
||||||
|
"values-hr",
|
||||||
|
"values-hu",
|
||||||
|
"values-hy",
|
||||||
|
"values-in",
|
||||||
|
"values-is",
|
||||||
|
"values-it",
|
||||||
|
"values-iw",
|
||||||
|
"values-ja",
|
||||||
|
"values-ka",
|
||||||
|
"values-kk",
|
||||||
|
"values-km",
|
||||||
|
"values-kn",
|
||||||
|
"values-ko",
|
||||||
|
"values-ky",
|
||||||
|
"values-lo",
|
||||||
|
"values-lt",
|
||||||
|
"values-lv",
|
||||||
|
"values-mk",
|
||||||
|
"values-ml",
|
||||||
|
"values-mn",
|
||||||
|
"values-mr",
|
||||||
|
"values-ms",
|
||||||
|
"values-my",
|
||||||
|
"values-nb",
|
||||||
|
"values-ne",
|
||||||
|
"values-nl",
|
||||||
|
"values-or",
|
||||||
|
"values-pa",
|
||||||
|
"values-pl",
|
||||||
|
"values-pt",
|
||||||
|
"values-pt-rBR",
|
||||||
|
"values-pt-rPT",
|
||||||
|
"values-ro",
|
||||||
|
"values-si",
|
||||||
|
"values-sk",
|
||||||
|
"values-sl",
|
||||||
|
"values-sq",
|
||||||
|
"values-sr",
|
||||||
|
"values-sv",
|
||||||
|
"values-sw",
|
||||||
|
"values-ta",
|
||||||
|
"values-te",
|
||||||
|
"values-th",
|
||||||
|
"values-tl",
|
||||||
|
"values-tr",
|
||||||
|
"values-uk",
|
||||||
|
"values-ur",
|
||||||
|
"values-uz",
|
||||||
|
"values-vi",
|
||||||
|
"values-zh",
|
||||||
|
"values-zh-rCN",
|
||||||
|
"values-zh-rHK",
|
||||||
|
"values-zh-rTW",
|
||||||
|
"values-zu",
|
||||||
|
"values-watch",
|
||||||
|
]
|
||||||
|
|
||||||
|
for folder in folders:
|
||||||
|
if os.path.exists(f"{path}/{folder}"):
|
||||||
|
shutil.rmtree(f"{path}/{folder}")
|
||||||
|
if config.get("verbose", False):
|
||||||
|
tqdm.write(f"Удалена директория: {path}/{folder}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def remove_drawable_files(config):
|
||||||
|
path = "./patches/res"
|
||||||
|
folders = [
|
||||||
|
"drawable-en-hdpi",
|
||||||
|
"drawable-en-ldpi",
|
||||||
|
"drawable-en-mdpi",
|
||||||
|
"drawable-en-xhdpi",
|
||||||
|
"drawable-en-xxhdpi",
|
||||||
|
"drawable-en-xxxhdpi",
|
||||||
|
"drawable-ldrtl-hdpi",
|
||||||
|
"drawable-ldrtl-mdpi",
|
||||||
|
"drawable-ldrtl-xhdpi",
|
||||||
|
"drawable-ldrtl-xxhdpi",
|
||||||
|
"drawable-ldrtl-xxxhdpi",
|
||||||
|
"drawable-tr-anydpi",
|
||||||
|
"drawable-tr-hdpi",
|
||||||
|
"drawable-tr-ldpi",
|
||||||
|
"drawable-tr-mdpi",
|
||||||
|
"drawable-tr-xhdpi",
|
||||||
|
"drawable-tr-xxhdpi",
|
||||||
|
"drawable-tr-xxxhdpi",
|
||||||
|
"drawable-watch",
|
||||||
|
"layout-watch",
|
||||||
|
]
|
||||||
|
|
||||||
|
for folder in folders:
|
||||||
|
if os.path.exists(f"{path}/{folder}"):
|
||||||
|
shutil.rmtree(f"{path}/{folder}")
|
||||||
|
if config.get("verbose", False):
|
||||||
|
tqdm.write(f"Удалена директория: {path}/{folder}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def apply(config) -> bool:
|
||||||
|
if config["remove_unknown_files"]:
|
||||||
|
tqdm.write(f"Удаление неизвестных файлов...")
|
||||||
|
remove_unknown_files(config)
|
||||||
|
|
||||||
|
if config["remove_drawable_files"]:
|
||||||
|
tqdm.write(f"Удаление директорий drawable-xx...")
|
||||||
|
remove_drawable_files(config)
|
||||||
|
|
||||||
|
if config["compress_png_files"]:
|
||||||
|
tqdm.write(f"Сжатие PNG файлов...")
|
||||||
|
compress_png_files(config)
|
||||||
|
|
||||||
|
if config["remove_language_files"]:
|
||||||
|
tqdm.write(f"Удаление языков...")
|
||||||
|
remove_language_files(config)
|
||||||
|
|
||||||
|
if config["remove_AI_voiceover"]:
|
||||||
|
tqdm.write(f"Удаление ИИ озвучки...")
|
||||||
|
remove_AI_voiceover(config)
|
||||||
|
|
||||||
|
if config["remove_debug_lines"]:
|
||||||
|
tqdm.write(f"Удаление дебаг линий...")
|
||||||
|
remove_debug_lines(config)
|
||||||
|
|
||||||
|
return True
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
"""Compress PNGs"""
|
|
||||||
priority = -1
|
|
||||||
from tqdm import tqdm
|
|
||||||
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
|
|
||||||
def compress_pngs(root_dir: str, verbose: bool = False):
|
|
||||||
compressed_files = []
|
|
||||||
for dirpath, _, filenames in os.walk(root_dir):
|
|
||||||
for filename in filenames:
|
|
||||||
if filename.lower().endswith(".png"):
|
|
||||||
filepath = os.path.join(dirpath, filename)
|
|
||||||
if verbose: tqdm.write(f"Сжимаю: {filepath}")
|
|
||||||
try:
|
|
||||||
assert subprocess.run(
|
|
||||||
[
|
|
||||||
"pngquant",
|
|
||||||
"--force",
|
|
||||||
"--ext",
|
|
||||||
".png",
|
|
||||||
"--quality=65-90",
|
|
||||||
filepath,
|
|
||||||
],
|
|
||||||
capture_output=True,
|
|
||||||
).returncode in [0, 99]
|
|
||||||
compressed_files.append(filepath)
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
tqdm.write(f"Ошибка при сжатии {filepath}: {e}")
|
|
||||||
return compressed_files
|
|
||||||
|
|
||||||
|
|
||||||
def apply(config: dict) -> bool:
|
|
||||||
files = compress_pngs("./decompiled", config.get("verbose", False))
|
|
||||||
return len(files) > 0 and any(files)
|
|
||||||
Binary file not shown.
+19
-17
@@ -4,24 +4,35 @@ def get_smali_lines(file: str) -> list[str]:
|
|||||||
lines = smali.readlines()
|
lines = smali.readlines()
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
|
|
||||||
|
def save_smali_lines(file: str, lines: list[str]) -> None:
|
||||||
|
with open(file, "w", encoding="utf-8") as f:
|
||||||
|
f.writelines(lines)
|
||||||
|
|
||||||
|
|
||||||
def find_smali_method_start(lines: list[str], index: int) -> int:
|
def find_smali_method_start(lines: list[str], index: int) -> int:
|
||||||
while True:
|
while True:
|
||||||
index -= 1
|
index -= 1
|
||||||
if lines[index].find(".method") >= 0:
|
if lines[index].find(".method") >= 0:
|
||||||
return index
|
return index
|
||||||
|
|
||||||
|
|
||||||
def find_smali_method_end(lines: list[str], index: int) -> int:
|
def find_smali_method_end(lines: list[str], index: int) -> int:
|
||||||
while True:
|
while True:
|
||||||
index += 1
|
index += 1
|
||||||
if lines[index].find(".end method") >= 0:
|
if lines[index].find(".end method") >= 0:
|
||||||
return index
|
return index
|
||||||
|
|
||||||
|
|
||||||
def debug_print_smali_method(lines: list[str], start: int, end: int) -> None:
|
def debug_print_smali_method(lines: list[str], start: int, end: int) -> None:
|
||||||
while start != (end + 1):
|
while start != (end + 1):
|
||||||
print(start, lines[start])
|
print(start, lines[start])
|
||||||
start += 1
|
start += 1
|
||||||
|
|
||||||
def replace_smali_method_body(lines: list[str], start: int, end: int, new_lines: list[str]) -> list[str]:
|
|
||||||
|
def replace_smali_method_body(
|
||||||
|
lines: list[str], start: int, end: int, new_lines: list[str]
|
||||||
|
) -> list[str]:
|
||||||
new_content = []
|
new_content = []
|
||||||
index = 0
|
index = 0
|
||||||
skip = end - start - 1
|
skip = end - start - 1
|
||||||
@@ -38,21 +49,12 @@ def replace_smali_method_body(lines: list[str], start: int, end: int, new_lines:
|
|||||||
new_content.append(lines[index])
|
new_content.append(lines[index])
|
||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
|
|
||||||
return new_content
|
return new_content
|
||||||
|
|
||||||
# example i guess
|
def find_and_replace_smali_line(
|
||||||
# if __name__ == "__main__":
|
lines: list[str], search: str, replace: str
|
||||||
# lines = get_smali_lines("./decompiled/smali_classes2/com/radiquum/anixart/Prefs.smali")
|
) -> list[str]:
|
||||||
|
for index, line in enumerate(lines):
|
||||||
# for index, line in enumerate(lines):
|
if line.find(search) >= 0:
|
||||||
# if line.find("IS_SPONSOR") >= 0:
|
lines[index] = lines[index].replace(search, replace)
|
||||||
# method_start = find_smali_method_start(lines, index)
|
return lines
|
||||||
# method_end = find_smali_method_end(lines, index)
|
|
||||||
# new_content = replace_smali_method_body(lines, method_start, method_end, c)
|
|
||||||
|
|
||||||
# with open("./help/Prefs_orig.smali", "w", encoding="utf-8") as file:
|
|
||||||
# file.writelines(lines)
|
|
||||||
# with open("./help/Prefs_modified.smali", "w", encoding="utf-8") as file:
|
|
||||||
# file.writelines(new_content)
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user