Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8faa67258f | |||
| 01260d7c16 |
@@ -1,4 +1,5 @@
|
|||||||
# Anixarty patcher
|

|
||||||
|
# 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)]
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"server": "https://anixarty.0x174.su/patch"
|
"server": "https://anixarts.0x174.su/patch"
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,5 @@
|
|||||||
{
|
{
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"items": [
|
"default_compact": false,
|
||||||
"home",
|
"items": ["home", "discover", "feed", "bookmarks", "profile"]
|
||||||
"discover",
|
|
||||||
"feed",
|
|
||||||
"bookmarks",
|
|
||||||
"profile"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
{
|
{
|
||||||
"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"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"title": "Anixarty",
|
"title": "Anixarts",
|
||||||
"title_color": "#FF252525",
|
"title_color": "#FF252525",
|
||||||
"title_bg_color": "#FFCFF04D",
|
"title_bg_color": "#FFCFF04D",
|
||||||
"body_bg_color": "#FF252525",
|
"body_bg_color": "#FF252525",
|
||||||
|
|||||||
@@ -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,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) # Получаем данные для патча
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ from utils.smali_parser import get_smali_lines, save_smali_lines, find_smali_lin
|
|||||||
|
|
||||||
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(True, description="Компактный вид по умолчанию")
|
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="Список элементов в панели навигации",
|
||||||
|
|||||||
+2
-2
@@ -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",
|
||||||
@@ -27,7 +27,7 @@ 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_color: str = Field("#FF252525", description="Цвет заголовка")
|
||||||
|
|
||||||
title_bg_color: str = Field("#FFCFF04D", description="Цвет фона заголовка")
|
title_bg_color: str = Field("#FFCFF04D", description="Цвет фона заголовка")
|
||||||
|
|||||||
@@ -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
@@ -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):
|
||||||
|
|||||||
Reference in New Issue
Block a user