3 Commits

17 changed files with 151 additions and 91 deletions
+14 -9
View File
@@ -1,4 +1,5 @@
# Anixarty patcher ![logo](./logo.png)
# Anixarts patcher
### Описание: ### Описание:
Автоматический патчер для приложения anixart. Автоматический патчер для приложения anixart.
@@ -8,11 +9,15 @@
### Структура проекта: ### Структура проекта:
- `main.py` Главный файл - `main.py` Главный файл
- `config.json` Глобальный конфиг
- `configs` Конфигурации патчей
- `patches` Модули патчей - `patches` Модули патчей
- `resources` Ресурсы, используемые патчами
- `utils` Вспомогательные модули - `utils` Вспомогательные модули
- `tools` Инструменты для модификации - `tools` Инструменты для модификации
- `resources` Ресурсы, используемые патчами - `original` Оригинальные apk файлы
- `todo_drafts` Заметки для новых патчей(можно в любом формате) - `decompiled` Декомпилированные файлы выбраного apk
- `modified` Модифицированные apk файлы и отчёт сборки
### Схема ### Схема
@@ -26,7 +31,7 @@ flowchart TD
B f2@==> p[Декомпиляция] B f2@==> p[Декомпиляция]
subgraph p["Применение патчей по возрастанию приоритета"] subgraph p["Применение патчей по убыванию приоритета"]
C[Патч 1] --> D C[Патч 1] --> D
D[Патч 2] --...--> E[Патч n] D[Патч 2] --...--> E[Патч n]
end end
@@ -49,7 +54,7 @@ flowchart TD
1. Клонируйте репозиторий: 1. Клонируйте репозиторий:
```sh ```sh
git clone https://git.wowlikon.tech/anixart-mod/patcher.git git clone https://git.0x174.su/anixart-mod/patcher.git
``` ```
Требования: Требования:
- Python 3.8+ - Python 3.8+
@@ -66,8 +71,8 @@ flowchart TD
``` ```
Пароль от keystore нужно сохранить в `keystore.pass` для полностью автоматической сборки. Пароль от keystore нужно сохранить в `keystore.pass` для полностью автоматической сборки.
3. Измените настройки мода в файле `patches/config.json`. Если вы развернули свой [сервер](https://git.wowlikon.tech/anixart-mod/server), то измените `"server": "https://new.url"` 3. Измените конфигурацию в файле `configs/change_server.json`. Если вы развернули свой [сервер](https://git.0x174.su/anixart-mod/server), то измените `"server": "https://new.url/patch"` на своё значение
4. Поместите оригинальный apk файла anixart в папку `original` 4. Поместите оригинальный apk файл anixart в папку `original`
5. Запустите `main.py build` и выберите файл apk 5. Запустите `main.py build` и выберите файл apk
6. Установите приложение на ваше устройство. 6. Установите приложение на ваше устройство.
@@ -76,6 +81,6 @@ flowchart TD
Этот проект лицензирован под лицензией MIT. См. [LICENSE](./LICENSE) для получения подробной информации. Этот проект лицензирован под лицензией MIT. См. [LICENSE](./LICENSE) для получения подробной информации.
### Вклад в проект: ### Вклад в проект:
- [Kentai Radiquum](https://git.0x174.su/Radiquum) - Значительный вклад в развитие патчера, разработка [anix](https://github.com/AniX-org/AniX) и помощь с API [[GitHub](https://github.com/adiquum) | [Telegram](https://t.me/radiquum)] - [wowlikon](https://git.0x174.su/wowlikon) - Создание и поддержка проекта [[GitHub](https://github.com/wowlikon) | [Telegram](https://t.me/wowlikon)]
- [Kentai Radiquum](https://git.0x174.su/Radiquum) - Значительный вклад в развитие патчера, разработка [anix](https://github.com/AniX-org/AniX) и помощь с API [[GitHub](https://github.com/radiquum) | [Telegram](https://t.me/radiquum)]
- [Seele](https://git.0x174.su/seele_archive) - Оригинальные патчи в начале разработки основаны на модификации от Seele - [Seele](https://git.0x174.su/seele_archive) - Оригинальные патчи в начале разработки основаны на модификации от Seele
- [ReCode Liner](https://git.0x174.su/ReCodeLiner) - Помощь в изучении моддинга приложения [[Telegram](https://t.me/recodius)]
+2 -2
View File
@@ -1,4 +1,4 @@
{ {
"enabled": false, "enabled": false,
"server": "https://anixarty.0x174.su/patch" "server": "https://anixarts.0x174.su/patch"
} }
+3 -8
View File
@@ -1,10 +1,5 @@
{ {
"enabled": true, "enabled": true,
"items": [ "default_compact": false,
"home", "items": ["home", "discover", "feed", "bookmarks", "profile"]
"discover", }
"feed",
"bookmarks",
"profile"
]
}
+2 -2
View File
@@ -29,10 +29,10 @@
{ {
"title": "Помочь проекту", "title": "Помочь проекту",
"description": "Вы можете помочь нам с идеями, написанием кода или тестированием.", "description": "Вы можете помочь нам с идеями, написанием кода или тестированием.",
"url": "https://git.wowlikon.tech/anixart-mod", "url": "https://git.0x174.su/anixart-mod",
"icon": "@drawable/ic_custom_crown", "icon": "@drawable/ic_custom_crown",
"icon_space_reserved": "false" "icon_space_reserved": "false"
} }
] ]
} }
} }
+10 -5
View File
@@ -1,9 +1,14 @@
{ {
"enabled": true, "enabled": true,
"title": "Anixarty", "title": "Anixarts",
"title_color": "#FF252525",
"title_bg_color": "#FFCFF04D",
"body_bg_color": "#FF252525",
"description": "Описание", "description": "Описание",
"link_text": "МЫ В TELEGRAM", "description_color": "#FFFFFFFF",
"link_url": "https://t.me/http_teapod",
"skip_text": "Пропустить", "skip_text": "Пропустить",
"title_bg_color": "#FFFFFF" "skip_color": "#FFFFFFFF",
} "link_text": "МЫ В TELEGRAM",
"link_color": "#FFCFF04D",
"link_url": "https://t.me/http_teapod"
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

+4 -4
View File
@@ -21,7 +21,7 @@ from utils.tools import (CONFIGS, DECOMPILED, MODIFIED, ORIGINAL, PATCHES,
console = Console() console = Console()
app = typer.Typer( app = typer.Typer(
name="anixarty-patcher", name="anixarts-patcher",
help="Инструмент для модификации Anixarty APK", help="Инструмент для модификации Anixarty APK",
add_completion=False, add_completion=False,
) )
@@ -62,7 +62,7 @@ def generate_report(
return info return info
lines = [] lines = []
lines.append(f"Anixarty {meta.version_name} (build {meta.version_code})") lines.append(f"Anixarts {meta.version_name} (build {meta.version_code})")
lines.append("") lines.append("")
lines.append("## 📦 Информация о сборке") lines.append("## 📦 Информация о сборке")
@@ -114,7 +114,7 @@ def generate_report(
lines.append("---") lines.append("---")
lines.append("") lines.append("")
lines.append( lines.append(
"*Собрано с помощью [anixarty-patcher](https://git.0x174.su/anixart-mod/patcher)*" "*Собрано с помощью [anixarts-patcher](https://git.0x174.su/anixart-mod/patcher)*"
) )
report_path.write_text("\n".join(lines), encoding="utf-8") report_path.write_text("\n".join(lines), encoding="utf-8")
@@ -467,7 +467,7 @@ def config():
@handle_errors @handle_errors
def version(): def version():
"""Показать версию инструмента""" """Показать версию инструмента"""
console.print(f"[cyan]anixarty-patcher[/cyan] v{__version__}") console.print(f"[cyan]anixarts-patcher[/cyan] v{__version__}")
if __name__ == "__main__": if __name__ == "__main__":
+2 -2
View File
@@ -2,7 +2,7 @@
"change_server": { "change_server": {
"enabled": true, "enabled": true,
"server": "https://anixarty.0x174.su/patch" "server": "https://anixarts.0x174.su/patch"
} }
""" """
@@ -20,7 +20,7 @@ from utils.config import PatchTemplate
class Patch(PatchTemplate): class Patch(PatchTemplate):
priority: int = Field(frozen=True, exclude=True, default=0) priority: int = Field(frozen=True, exclude=True, default=0)
server: str = Field("https://anixarty.0x174.su/patch", description="URL сервера") server: str = Field("https://anixarts.0x174.su/patch", description="URL сервера")
def apply(self, base: Dict[str, Any]) -> bool: def apply(self, base: Dict[str, Any]) -> bool:
response = requests.get(self.server) # Получаем данные для патча response = requests.get(self.server) # Получаем данные для патча
+1 -1
View File
@@ -21,7 +21,7 @@ class Patch(PatchTemplate):
priority: int = Field(frozen=True, exclude=True, default=0) priority: int = Field(frozen=True, exclude=True, default=0)
def apply(self, base: Dict[str, Any]) -> bool: def apply(self, base: Dict[str, Any]) -> bool:
path = "./decompiled/smali_classes2/com/swiftsoft/anixartd/Prefs.smali" path = "./decompiled/smali_classes3/com/swiftsoft/anixartd/Prefs.smali"
replacement = [ replacement = [
f"\t{line}\n" f"\t{line}\n"
for line in textwrap.dedent( for line in textwrap.dedent(
+30 -1
View File
@@ -16,10 +16,11 @@ from pydantic import Field
from tqdm import tqdm from tqdm import tqdm
from utils.config import PatchTemplate from utils.config import PatchTemplate
from utils.smali_parser import get_smali_lines, save_smali_lines, find_smali_line
class Patch(PatchTemplate): class Patch(PatchTemplate):
priority: int = Field(frozen=True, exclude=True, default=0) priority: int = Field(frozen=True, exclude=True, default=0)
default_compact: bool = Field(False, description="Компактный вид по умолчанию")
items: List[str] = Field( items: List[str] = Field(
["home", "discover", "feed", "bookmarks", "profile"], ["home", "discover", "feed", "bookmarks", "profile"],
description="Список элементов в панели навигации", description="Список элементов в панели навигации",
@@ -64,4 +65,32 @@ class Patch(PatchTemplate):
tree.write(file_path, pretty_print=True, xml_declaration=True, encoding="utf-8") tree.write(file_path, pretty_print=True, xml_declaration=True, encoding="utf-8")
# Изменение компактного вида
if self.default_compact:
main_file_path = "./decompiled/smali_classes3/com/swiftsoft/anixartd/ui/activity/MainActivity.smali"
main_lines = get_smali_lines(main_file_path)
preference_file_path = "./decompiled/smali_classes3/com/swiftsoft/anixartd/ui/fragment/main/preference/AppearancePreferenceFragment.smali"
preference_lines = get_smali_lines(preference_file_path)
main_const = find_smali_line(main_lines, "BOTTOM_NAVIGATION_COMPACT")[-1]
preference_const = find_smali_line(preference_lines, "BOTTOM_NAVIGATION_COMPACT")[-1]
main_invoke = find_smali_line(main_lines, "Landroid/content/SharedPreferences;->getBoolean(Ljava/lang/String;Z)Z")[0]
preference_invoke = find_smali_line(preference_lines, "Landroid/content/SharedPreferences;->getBoolean(Ljava/lang/String;Z)Z")[0]
main_value = set(find_smali_line(main_lines, "const/4 v7, 0x0"))
preference_value = set(find_smali_line(preference_lines, "const/4 v7, 0x0"))
main_target_line = main_value & set(range(main_const, main_invoke))
preference_tartget_line = preference_value & set(range(preference_const, preference_invoke))
assert len(main_target_line) == 1 and len(preference_tartget_line) == 1
main_lines[main_target_line.pop()] = "const/4 v7, 0x1"
preference_lines[preference_tartget_line.pop()] = "const/4 v7, 0x1"
save_smali_lines(main_file_path, main_lines)
save_smali_lines(preference_file_path, preference_lines)
return True return True
+10 -10
View File
@@ -34,6 +34,13 @@ from utils.public import insert_after_public
# Config # Config
DEFAULT_MENU = { DEFAULT_MENU = {
"Мы в социальных сетях": [ "Мы в социальных сетях": [
{
"title": "Мы в Telegram",
"description": "Подпишитесь на канал, чтобы быть в курсе последних новостей.",
"url": "https://t.me/http_teapod",
"icon": "@drawable/ic_custom_telegram",
"icon_space_reserved": "false",
},
{ {
"title": "wowlikon", "title": "wowlikon",
"description": "Разработчик", "description": "Разработчик",
@@ -48,19 +55,12 @@ DEFAULT_MENU = {
"icon": "@drawable/ic_custom_telegram", "icon": "@drawable/ic_custom_telegram",
"icon_space_reserved": "false", "icon_space_reserved": "false",
}, },
{
"title": "Мы в Telegram",
"description": "Подпишитесь на канал, чтобы быть в курсе последних новостей.",
"url": "https://t.me/http_teapod",
"icon": "@drawable/ic_custom_telegram",
"icon_space_reserved": "false",
},
], ],
"Прочее": [ "Прочее": [
{ {
"title": "Помочь проекту", "title": "Помочь проекту",
"description": "Вы можете помочь нам с идеями, написанием кода или тестированием.", "description": "Вы можете помочь нам с идеями, написанием кода или тестированием.",
"url": "https://git.wowlikon.tech/anixart-mod", "url": "https://git.0x174.su/anixart-mod",
"icon": "@drawable/ic_custom_crown", "icon": "@drawable/ic_custom_crown",
"icon_space_reserved": "false", "icon_space_reserved": "false",
} }
@@ -122,8 +122,8 @@ class Patch(PatchTemplate):
# Добавление суффикса версии # Добавление суффикса версии
filepaths = [ filepaths = [
"./decompiled/smali_classes2/com/swiftsoft/anixartd/ui/activity/UpdateActivity.smali", "./decompiled/smali_classes3/com/swiftsoft/anixartd/ui/activity/UpdateActivity.smali",
"./decompiled/smali_classes2/com/swiftsoft/anixartd/ui/fragment/main/preference/MainPreferenceFragment.smali", "./decompiled/smali_classes3/com/swiftsoft/anixartd/ui/fragment/main/preference/MainPreferenceFragment.smali",
] ]
for filepath in filepaths: for filepath in filepaths:
content = "" content = ""
+49 -6
View File
@@ -2,7 +2,7 @@
"welcome": { "welcome": {
"enabled": true, "enabled": true,
"title": "Anixarty", "title": "Anixarts",
"description": "Описание", "description": "Описание",
"link_text": "МЫ В TELEGRAM", "link_text": "МЫ В TELEGRAM",
"link_url": "https://t.me/http_teapod", "link_url": "https://t.me/http_teapod",
@@ -15,6 +15,7 @@ __author__ = "wowlikon <wowlikon@gmail.com>"
__version__ = "1.0.0" __version__ = "1.0.0"
import shutil import shutil
from typing import Any, Dict from typing import Any, Dict
from urllib import parse
from pydantic import Field from pydantic import Field
@@ -25,23 +26,38 @@ from utils.smali_parser import (find_and_replace_smali_line, get_smali_lines,
class Patch(PatchTemplate): class Patch(PatchTemplate):
priority: int = Field(frozen=True, exclude=True, default=0) priority: int = Field(frozen=True, exclude=True, default=0)
title: str = Field("Anixarty", description="Заголовок")
title: str = Field("Anixarts", description="Заголовок")
title_color: str = Field("#FF252525", description="Цвет заголовка")
title_bg_color: str = Field("#FFCFF04D", description="Цвет фона заголовка")
body_bg_color: str = Field("#FF252525", description="Цвет фона окна")
description: str = Field("Описание", description="Описание") description: str = Field("Описание", description="Описание")
description_color: str = Field("#FFFFFFFF", description="Цвет описания")
skip_text: str = Field("Пропустить", description="Текст кнопки пропустить")
skip_color: str = Field("#FFFFFFFF", description="Цвет кнопки пропустить")
link_text: str = Field("МЫ В TELEGRAM", description="Текст ссылки") link_text: str = Field("МЫ В TELEGRAM", description="Текст ссылки")
link_color: str = Field("#FFCFF04D", description="Цвет ссылки")
link_url: str = Field("https://t.me/http_teapod", description="Ссылка") link_url: str = Field("https://t.me/http_teapod", description="Ссылка")
skip_text: str = Field("Пропустить", description="Текст кнопки пропуска")
title_bg_color: str = Field("#FFFFFF", description="Цвет фона заголовка") def encode_text(self, text: str) -> str:
return '+'.join([parse.quote(i) for i in text.split(' ')])
def apply(self, base: Dict[str, Any]) -> bool: def apply(self, base: Dict[str, Any]) -> bool:
file_path = "./decompiled/smali_classes2/com/swiftsoft/anixartd/ui/activity/MainActivity.smali"
# Добавление ресурсов окна первого входа # Добавление ресурсов окна первого входа
shutil.copy("./resources/avatar.png", "./decompiled/assets/avatar.png") shutil.copy("./resources/avatar.png", "./decompiled/assets/avatar.png")
shutil.copy( shutil.copy(
"./resources/OpenSans-Regular.ttf", "./resources/OpenSans-Regular.ttf",
"./decompiled/assets/OpenSans-Regular.ttf", "./decompiled/assets/OpenSans-Regular.ttf",
) )
shutil.copytree("./resources/smali_classes4/", "./decompiled/smali_classes4/") for subdir in ["about/", "authorization/"]:
shutil.copytree("./resources/smali_classes4/com/swiftsoft/"+subdir, "./decompiled/smali_classes4/com/swiftsoft/"+subdir)
# Привязка к первому запуску
file_path = "./decompiled/smali_classes3/com/swiftsoft/anixartd/ui/activity/MainActivity.smali"
method = "invoke-super {p0}, Lmoxy/MvpAppCompatActivity;->onResume()V" method = "invoke-super {p0}, Lmoxy/MvpAppCompatActivity;->onResume()V"
lines = get_smali_lines(file_path) lines = get_smali_lines(file_path)
lines = find_and_replace_smali_line( lines = find_and_replace_smali_line(
@@ -52,4 +68,31 @@ class Patch(PatchTemplate):
) )
save_smali_lines(file_path, lines) save_smali_lines(file_path, lines)
# Замена ссылки
file_path = "./decompiled/smali_classes4/com/swiftsoft/about/$4.smali"
lines = get_smali_lines(file_path)
lines = find_and_replace_smali_line(
lines,
"const-string v0, \"https://example.com\"",
'const-string v0, "' + self.link_url + '"',
)
save_smali_lines(file_path, lines)
# Настройка всплывающго окна
file_path = "./decompiled/smali_classes4/com/swiftsoft/about/$2.smali"
lines = get_smali_lines(file_path)
for replacement in [
('const-string v5, "#FF252525" # Title color', f'const-string v5, "{self.title_color}"'),
('const-string v7, "#FFFFFFFF" # Description color', f'const-string v7, "{self.description_color}"'),
('const-string v8, "#FFCFF04D" # Link color', f'const-string v8, "{self.link_color}"'),
('const-string v9, "#FFFFFFFF" # Skip color', f'const-string v9, "{self.skip_color}"'),
('const-string v5, "#FF252525" # Body background', f'const-string v5, "{self.body_bg_color}"'),
('const-string v10, "#FFCFF04D" # Title background', f'const-string v10, "{self.title_bg_color}"'),
('const-string v12, "Title"', f'const-string v12, "{self.encode_text(self.title)}"'),
('const-string v11, "Description"', f'const-string v11, "{self.encode_text(self.description)}"'),
('const-string v12, "URL"', f'const-string v12, "{self.link_text.encode('unicode-escape').decode()}"'),
('const-string v12, "Skip"', f'const-string v12, "{self.skip_text.encode('unicode-escape').decode()}"')
]: lines = find_and_replace_smali_line(lines, *replacement)
save_smali_lines(file_path, lines)
return True return True
@@ -95,28 +95,28 @@
move-result-object v2 move-result-object v2
const-string v5, "#FF252525" const-string v5, "#FF252525" # Title color
.line 43 .line 43
invoke-static {v5}, Landroid/graphics/Color;->parseColor(Ljava/lang/String;)I invoke-static {v5}, Landroid/graphics/Color;->parseColor(Ljava/lang/String;)I
move-result v6 move-result v6
const-string v7, "#FFFFFFFF" const-string v7, "#FFFFFFFF" # Description color
.line 44 .line 44
invoke-static {v7}, Landroid/graphics/Color;->parseColor(Ljava/lang/String;)I invoke-static {v7}, Landroid/graphics/Color;->parseColor(Ljava/lang/String;)I
move-result v7 move-result v7
const-string v8, "#FFCFF04D" const-string v8, "#FFCFF04D" # Link color
.line 45 .line 45
invoke-static {v8}, Landroid/graphics/Color;->parseColor(Ljava/lang/String;)I invoke-static {v8}, Landroid/graphics/Color;->parseColor(Ljava/lang/String;)I
move-result v8 move-result v8
const-string v9, "#FFFFFFFF" const-string v9, "#FFFFFFFF" # Skip color
.line 46 .line 46
invoke-static {v9}, Landroid/graphics/Color;->parseColor(Ljava/lang/String;)I invoke-static {v9}, Landroid/graphics/Color;->parseColor(Ljava/lang/String;)I
@@ -124,13 +124,13 @@
move-result v9 move-result v9
.line 47 .line 47
const-string v5, "#FF252525" const-string v5, "#FF252525" # Body background
invoke-static {v5}, Landroid/graphics/Color;->parseColor(Ljava/lang/String;)I invoke-static {v5}, Landroid/graphics/Color;->parseColor(Ljava/lang/String;)I
move-result v5 move-result v5
const-string v10, "#FFCFF04D" const-string v10, "#FFCFF04D" # Title background
.line 48 .line 48
invoke-static {v10}, Landroid/graphics/Color;->parseColor(Ljava/lang/String;)I invoke-static {v10}, Landroid/graphics/Color;->parseColor(Ljava/lang/String;)I
@@ -177,7 +177,7 @@
invoke-direct {v11, v0, v12}, Landroid/app/AlertDialog$Builder;-><init>(Landroid/content/Context;I)V invoke-direct {v11, v0, v12}, Landroid/app/AlertDialog$Builder;-><init>(Landroid/content/Context;I)V
const-string v12, "wowlikon+ID" const-string v12, "Title"
.line 67 .line 67
invoke-virtual {v11, v12}, Landroid/app/AlertDialog$Builder;->setTitle(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder; invoke-virtual {v11, v12}, Landroid/app/AlertDialog$Builder;->setTitle(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;
@@ -189,7 +189,7 @@
move-result-object v3 move-result-object v3
const-string v11, "%D0%9C%D0%BE%D0%B4+%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D0%BD+wowlikon+%D1%81+%D0%BD%D0%BE%D0%B2%D1%8B%D1%8B%D0%BC%D0%B8+%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D1%8F%D0%BC%D0%B8%21%0A%0A%D0%A1%D0%B4%D0%B5%D0%BB%D0%B0%D0%BD%D0%BE+%D1%81+%E2%9D%A4%EF%B8%8F+%D0%BE%D1%82+swiftsoft" const-string v11, "Description"
.line 69 .line 69
invoke-virtual {v3, v11}, Landroid/app/AlertDialog$Builder;->setMessage(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder; invoke-virtual {v3, v11}, Landroid/app/AlertDialog$Builder;->setMessage(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;
@@ -200,7 +200,7 @@
invoke-direct {v11}, Lcom/swiftsoft/about/$4;-><init>()V invoke-direct {v11}, Lcom/swiftsoft/about/$4;-><init>()V
const-string v12, "\u041c\u044b \u0432 Telegram" const-string v12, "URL"
.line 70 .line 70
invoke-virtual {v3, v12, v11}, Landroid/app/AlertDialog$Builder;->setPositiveButton(Ljava/lang/CharSequence;Landroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder; invoke-virtual {v3, v12, v11}, Landroid/app/AlertDialog$Builder;->setPositiveButton(Ljava/lang/CharSequence;Landroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder;
@@ -211,7 +211,7 @@
invoke-direct {v11}, Lcom/swiftsoft/about/$3;-><init>()V invoke-direct {v11}, Lcom/swiftsoft/about/$3;-><init>()V
const-string v12, "\u041f\u043e\u043d\u044f\u0442\u043d\u043e" const-string v12, "Skip"
.line 71 .line 71
invoke-virtual {v3, v12, v11}, Landroid/app/AlertDialog$Builder;->setNeutralButton(Ljava/lang/CharSequence;Landroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder; invoke-virtual {v3, v12, v11}, Landroid/app/AlertDialog$Builder;->setNeutralButton(Ljava/lang/CharSequence;Landroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder;
@@ -32,7 +32,7 @@
new-instance p2, Landroid/content/Intent; new-instance p2, Landroid/content/Intent;
const-string v0, "https://t.me/wowlikon" const-string v0, "https://example.com"
invoke-static {v0}, Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri; invoke-static {v0}, Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;
-27
View File
@@ -1,27 +0,0 @@
/res/layout/release_info.xml
<TextView android:textColor="@color/light_md_blue_500" android:id="@id/note" android:background="@drawable/bg_release_note" android:paddingTop="12.0dip" android:paddingBottom="12.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textIsSelectable="true" android:paddingStart="16.0dip" android:paddingEnd="16.0dip" style="?textAppearanceBodyMedium" />
</FrameLayout>
<LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
<LinearLayout android:gravity="center_vertical" android:orientation="horizontal" android:id="@id/countryLayout" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="fill_parent">
<androidx.appcompat.widget.AppCompatImageView android:id="@id/iconCountry" android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@drawable/ic_flag_japan" />
<TextView android:textColor="?primaryTextColor" android:textColorLink="?primaryTextColor" android:gravity="center_vertical" android:linksClickable="true" android:id="@id/tvCountry" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textIsSelectable="true" android:layout_marginStart="8.0dip" style="?textAppearanceBodyMedium" />
</LinearLayout>
<LinearLayout android:gravity="center_vertical" android:orientation="horizontal" android:id="@id/episodesLayout" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginTop="2.0dip">
<androidx.appcompat.widget.AppCompatImageView android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@drawable/ic_episodes" />
<TextView android:textColor="?primaryTextColor" android:textColorLink="?primaryTextColor" android:gravity="center_vertical" android:linksClickable="true" android:id="@id/tvEpisodes" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textIsSelectable="true" android:layout_marginStart="8.0dip" style="?textAppearanceBodyMedium" />
</LinearLayout>
<LinearLayout android:gravity="center_vertical" android:orientation="horizontal" android:id="@id/scheduleLayout" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginTop="2.0dip">
<androidx.appcompat.widget.AppCompatImageView android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@drawable/ic_schedule" />
<TextView android:textColor="?primaryTextColor" android:textColorLink="?primaryTextColor" android:gravity="center_vertical" android:linksClickable="true" android:id="@id/tvSchedule" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textIsSelectable="true" android:layout_marginStart="8.0dip" style="?textAppearanceBodyMedium" />
</LinearLayout>
<LinearLayout android:gravity="center_vertical" android:orientation="horizontal" android:id="@id/sourceLayout" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginTop="2.0dip">
<androidx.appcompat.widget.AppCompatImageView android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@drawable/ic_source" />
<TextView android:textColor="?primaryTextColor" android:textColorLink="?primaryTextColor" android:gravity="center_vertical" android:linksClickable="true" android:id="@id/tvSource" android:layout_width="fill_parent" android:layout_height="wrap_content" android:lineSpacingExtra="4.0sp" android:textIsSelectable="true" android:layout_marginStart="8.0dip" style="?textAppearanceBodyMedium" />
</LinearLayout>
<LinearLayout android:orientation="horizontal" android:id="@id/studioLayout" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="2.0dip">
<androidx.appcompat.widget.AppCompatImageView android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@drawable/ic_studio" />
<TextView android:textColor="?primaryTextColor" android:textColorLink="?primaryTextColor" android:gravity="center_vertical" android:linksClickable="true" android:id="@id/tvStudio" android:layout_width="fill_parent" android:layout_height="wrap_content" android:lineSpacingExtra="4.0sp" android:textIsSelectable="true" android:layout_marginStart="8.0dip" style="?textAppearanceBodyMedium" />
</LinearLayout>
</LinearLayout>
<TextView android:textColor="?primaryTextColor" android:textColorLink="?primaryTextColor" android:linksClickable="true" android:id="@id/tvGenres" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="16.0dip" android:layout_marginBottom="2.0dip" android:lineSpacingExtra="4.0sp" android:textIsSelectable="true" style="?textAppearanceBodyMedium" />
<at.blogc.android.views.ExpandableTextView android:textColor="?primaryTextColor" android:id="@id/description" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="8.0dip" android:layout_marginBottom="8.0dip" android:maxLines="5" android:lineSpacingExtra="4.0sp" android:textIsSelectable="true" app:animation_duration="225" style="?textAppearanceBodyMedium" />
+3 -3
View File
@@ -27,19 +27,19 @@ class APKMeta(BaseModel):
@property @property
def output_name(self) -> str: def output_name(self) -> str:
"""Имя выходного файла""" """Имя выходного файла"""
return f"Anixarty-v{self.safe_version}.apk" return f"Anixarts-v{self.safe_version}.apk"
@computed_field @computed_field
@property @property
def aligned_name(self) -> str: def aligned_name(self) -> str:
"""Имя выровненного файла""" """Имя выровненного файла"""
return f"Anixarty-v{self.safe_version}-aligned.apk" return f"Anixarts-v{self.safe_version}-aligned.apk"
@computed_field @computed_field
@property @property
def signed_name(self) -> str: def signed_name(self) -> str:
"""Имя подписанного файла""" """Имя подписанного файла"""
return f"Anixarty-v{self.safe_version}-mod.apk" return f"Anixarts-v{self.safe_version}-mod.apk"
class SigningConfig(BaseModel): class SigningConfig(BaseModel):
+10
View File
@@ -64,6 +64,16 @@ def find_and_replace_smali_line(
return lines return lines
def find_smali_line(
lines: list[str], search: str
) -> list[int]:
result = []
for index, line in enumerate(lines):
if line.find(search) >= 0:
result.append(index)
return result
def float_to_hex(f): def float_to_hex(f):
b = struct.pack(">f", f) b = struct.pack(">f", f)
return b.hex() return b.hex()