mirror of
https://github.com/ReVanced/revanced-cli.git
synced 2026-01-11 13:56:18 +00:00
Compare commits
24 Commits
v5.0.0-dev
...
chore/scri
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e87ee9c5b8 | ||
|
|
504c6c1ea5 | ||
|
|
f58b101636 | ||
|
|
292b93b609 | ||
|
|
e60a61b098 | ||
|
|
1da8ae9e46 | ||
|
|
a9f2538827 | ||
|
|
5f952f35f5 | ||
|
|
280ded2281 | ||
|
|
bb6bc1ba9a | ||
|
|
04b178b701 | ||
|
|
32e6aae132 | ||
|
|
7ee4f15ab9 | ||
|
|
a7af611ef0 | ||
|
|
9440dc769e | ||
|
|
751fa1d889 | ||
|
|
3300e6b433 | ||
|
|
ba159a35a9 | ||
|
|
74ff94037e | ||
|
|
7e8fb5722a | ||
|
|
7b4af46c94 | ||
|
|
45c998b335 | ||
|
|
9b03963687 | ||
|
|
6e7797a3f0 |
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -10,6 +10,8 @@ on:
|
||||
jobs:
|
||||
release:
|
||||
name: Release
|
||||
permissions:
|
||||
contents: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -46,5 +48,5 @@ jobs:
|
||||
|
||||
- name: Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: npm exec semantic-release
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -122,4 +122,7 @@ revanced-cache/
|
||||
options.toml
|
||||
|
||||
# Generated by Android projects
|
||||
local.properties
|
||||
local.properties
|
||||
|
||||
# Generated by scripts
|
||||
scripts/workspace
|
||||
@@ -23,7 +23,8 @@
|
||||
"assets": [
|
||||
"CHANGELOG.md",
|
||||
"gradle.properties"
|
||||
]
|
||||
],
|
||||
"message": "chore: Release v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
|
||||
}
|
||||
],
|
||||
[
|
||||
|
||||
50
CHANGELOG.md
50
CHANGELOG.md
@@ -1,3 +1,53 @@
|
||||
# [5.0.0-dev.8](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.7...v5.0.0-dev.8) (2024-10-17)
|
||||
|
||||
# [5.0.0-dev.7](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.6...v5.0.0-dev.7) (2024-10-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Check for null when no device serial was specified ([1da8ae9](https://github.com/ReVanced/revanced-cli/commit/1da8ae9e46000dd3c4eecd793c559e75012cf535))
|
||||
|
||||
# [5.0.0-dev.6](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.5...v5.0.0-dev.6) (2024-10-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Use the first connected device when no ADB device is specified ([5f952f3](https://github.com/ReVanced/revanced-cli/commit/5f952f35f5cb388b6509b2b4d905b8143ebc7996))
|
||||
|
||||
# [5.0.0-dev.5](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.4...v5.0.0-dev.5) (2024-09-30)
|
||||
|
||||
# [5.0.0-dev.4](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.3...v5.0.0-dev.4) (2024-09-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Make patches selectable by using a mutable collection for the selection option ([751fa1d](https://github.com/ReVanced/revanced-cli/commit/751fa1d889f40c51b291116029fd84f2b051f2f0))
|
||||
* Make the patch command work without specifying any selection ([ba159a3](https://github.com/ReVanced/revanced-cli/commit/ba159a35a9a99d18a4c1e04128b08ae336a49b3e))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Show error about no installation device found at the beginning ([3300e6b](https://github.com/ReVanced/revanced-cli/commit/3300e6b4333ed1c4e6785cb82eca9016fc6d4a20))
|
||||
|
||||
# [5.0.0-dev.3](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.2...v5.0.0-dev.3) (2024-08-14)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Simplify option descriptions ([45c998b](https://github.com/ReVanced/revanced-cli/commit/45c998b335b65ac233fece8b804dc7410142691c))
|
||||
|
||||
# [5.0.0-dev.2](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.1...v5.0.0-dev.2) (2024-08-14)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Simplify command and option names and descriptions ([#338](https://github.com/ReVanced/revanced-cli/issues/338)) ([6e7797a](https://github.com/ReVanced/revanced-cli/commit/6e7797a3f0525a8f48af7182157da0d045600ac2))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* Options have been renamed.
|
||||
|
||||
# [5.0.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.6.0...v5.0.0-dev.1) (2024-08-12)
|
||||
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ To use ReVanced CLI, you will need to fulfill specific requirements.
|
||||
|
||||
## 🤝 Requirements
|
||||
|
||||
- Java Runtime Environment 11 ([Azul Zulu JRE](https://www.azul.com/downloads/?version=java-11-lts&package=jdk#zulu) or [OpenJDK](https://jdk.java.net/archive/))
|
||||
- Java Runtime Environment 11 or higher ([Eclipse Temurin JRE](https://adoptium.net/temurin/releases/?package=jre) or [OpenJDK](https://jdk.java.net/archive/))
|
||||
- [Android Debug Bridge (ADB)](https://developer.android.com/studio/command-line/adb) if you want to install the patched APK file on your device
|
||||
- An ABI other than ARMv7 such as x86 or x86-64 (or a custom AAPT binary that supports ARMv7)
|
||||
- x86 or x86-64 (For [other architectures](https://github.com/ReVanced/revanced-manager/tree/main/android/app/src/main/jniLibs) use the `--custom-aapt2-binary` option)
|
||||
|
||||
## ⏭️ Whats next
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ java -jar revanced-cli.jar -h
|
||||
## 📃 List patches
|
||||
|
||||
```bash
|
||||
java -jar revanced-cli.jar list-patches --with-packages --with-versions --with-options revanced-patches.rvp
|
||||
java -jar revanced-cli.jar list-patches --with-packages --with-versions --with-options patches.rvp
|
||||
```
|
||||
|
||||
## 💉 Patch an app
|
||||
@@ -21,48 +21,48 @@ java -jar revanced-cli.jar list-patches --with-packages --with-versions --with-o
|
||||
To patch an app using the default list of patches, use the `patch` command:
|
||||
|
||||
```bash
|
||||
java -jar revanced-cli.jar patch -b revanced-patches.rvp input.apk
|
||||
java -jar revanced-cli.jar patch -p patches.rvp input.apk
|
||||
```
|
||||
|
||||
You can also use multiple patch bundles:
|
||||
You can also use multiple RVP files:
|
||||
|
||||
```bash
|
||||
java -jar revanced-cli.jar patch -b revanced-patches.rvp -b another-patches.rvp input.apk
|
||||
java -jar revanced-cli.jar patch -p patches.rvp -p another-patches.rvp input.apk
|
||||
```
|
||||
|
||||
To change the default set of used patches, use the option `-i` or `-e` to use or disuse specific patches.
|
||||
You can use the `list-patches` command to see which patches are used by default.
|
||||
To change the default set of enabled or disabled patches, use the option `-e` or `-d` to enable or disable specific patches.
|
||||
You can use the `list-patches` command to see which patches are enabled by default.
|
||||
|
||||
To only use specific patches, you can use the option `--exclusive` combined with `-i`.
|
||||
Remember that the options `-i` and `-e` match the patch's name exactly. Here is an example:
|
||||
To only enable specific patches, you can use the option `--exclusive` combined with `-e`.
|
||||
Remember that the options `-e` and `-d` match the patch's name exactly. Here is an example:
|
||||
|
||||
```bash
|
||||
java -jar revanced-cli.jar patch -b revanced-patches.rvp --exclusive -i "Patch name" -i "Another patch name" input.apk
|
||||
java -jar revanced-cli.jar patch -p patches.rvp --exclusive -e "Patch name" -e "Another patch name" input.apk
|
||||
```
|
||||
|
||||
You can also use the options `--ii` and `--ie` to use or disuse patches by their index.
|
||||
This is useful, if two patches happen to have the same name.
|
||||
You can also use the options `--ei` or `--di` to enable or disable patches by their index.
|
||||
This is useful, if two patches happen to have the same name, or if typing the names is too cumbersome.
|
||||
To know the indices of patches, use the command `list-patches`:
|
||||
|
||||
```bash
|
||||
java -jar revanced-cli.jar list-patches revanced-patches.rvp
|
||||
java -jar revanced-cli.jar list-patches patches.rvp
|
||||
```
|
||||
|
||||
Then you can use the indices to use or disuse patches:
|
||||
Then you can use the indices to enable or disable patches:
|
||||
|
||||
```bash
|
||||
java -jar revanced-cli.jar patch -b revanced-patches.rvp --ii 123 --ie 456 input.apk
|
||||
java -jar revanced-cli.jar patch -p patches.rvp --ei 123 --di 456 input.apk
|
||||
```
|
||||
|
||||
You can combine the option `-i`, `-e`, `--ii`, `--ie` and `--exclusive`. Here is an example:
|
||||
You can combine the option `-e`, `-d`, `--ei`, `--di` and `--exclusive`. Here is an example:
|
||||
|
||||
```bash
|
||||
java -jar revanced-cli.jar patch -b revanced-patches.rvp --exclusive -i "Patch name" --ii 123 input.apk
|
||||
java -jar revanced-cli.jar patch -p patches.rvp --exclusive -e "Patch name" --ei 123 input.apk
|
||||
```
|
||||
|
||||
|
||||
> [!TIP]
|
||||
> You can use the option `-d` to automatically install the patched app after patching.
|
||||
> You can use the option `-i` to automatically install the patched app after patching.
|
||||
> Make sure ADB is working:
|
||||
>
|
||||
> ```bash
|
||||
@@ -83,7 +83,7 @@ Patches can have options you can set using the option `-O` alongside the option
|
||||
To know the options of a patch, use the option `--with-options` when listing patches:
|
||||
|
||||
```bash
|
||||
java -jar revanced-cli.jar list-patches --with-options revanced-patches.rvp
|
||||
java -jar revanced-cli.jar list-patches --with-options patches.rvp
|
||||
```
|
||||
|
||||
Each patch can have multiple options. You can set them using the option `-O`.
|
||||
@@ -91,18 +91,18 @@ For example, to set the options for the patch with the name `Patch name`
|
||||
with the key `key1` and `key2` to `value1` and `value2` respectively, use the following command:
|
||||
|
||||
```bash
|
||||
java -jar revanced-cli.jar patch -b revanced-patches.rvp -i "Patch name" -Okey1=value1 -Okey2=value2 input.apk
|
||||
java -jar revanced-cli.jar patch -p patches.rvp -e "Patch name" -Okey1=value1 -Okey2=value2 input.apk
|
||||
```
|
||||
|
||||
If you want to set a value to `null`, you can omit the value:
|
||||
If you want to set the option value to `null`, you can omit the value:
|
||||
|
||||
```bash
|
||||
java -jar revanced-cli.jar patch -b revanced-patches.rvp -i "Patch name" -Okey1 input.apk
|
||||
java -jar revanced-cli.jar patch -p patches.rvp -i "Patch name" -Okey1 input.apk
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Option values are usually typed. If you set a value with the wrong type, the patch can fail.
|
||||
> Option value types can be seen when listing patches with the option `--with-options`.
|
||||
> The value types can be seen when listing patches with the option `--with-options`.
|
||||
>
|
||||
> Example option values:
|
||||
>
|
||||
@@ -131,7 +131,7 @@ java -jar revanced-cli.jar patch -b revanced-patches.rvp -i "Patch name" -Okey1
|
||||
> Example command with an escaped integer as a string:
|
||||
>
|
||||
> ```bash
|
||||
> java -jar revanced-cli.jar -b revanced-patches.rvp -i "Patch name" -OstringKey=\'1\' input.apk
|
||||
> java -jar revanced-cli.jar -p patches.rvp -e "Patch name" -OstringKey=\'1\' input.apk
|
||||
> ```
|
||||
## 📦 Install an app manually
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
org.gradle.parallel = true
|
||||
org.gradle.caching = true
|
||||
kotlin.code.style = official
|
||||
version = 5.0.0-dev.1
|
||||
version = 5.0.0-dev.8
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[versions]
|
||||
shadow = "8.1.1"
|
||||
kotlin = "2.0.0"
|
||||
kotlin = "2.0.20"
|
||||
kotlinx = "1.8.1"
|
||||
picocli = "4.7.6"
|
||||
revanced-patcher = "20.0.0"
|
||||
revanced-patcher = "20.0.2"
|
||||
revanced-library = "3.0.0"
|
||||
|
||||
[libraries]
|
||||
|
||||
2387
package-lock.json
generated
2387
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@
|
||||
"@saithodev/semantic-release-backmerge": "^4.0.1",
|
||||
"@semantic-release/changelog": "^6.0.3",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"gradle-semantic-release-plugin": "^1.9.1",
|
||||
"semantic-release": "^23.0.8"
|
||||
"gradle-semantic-release-plugin": "^1.10.1",
|
||||
"semantic-release": "^24.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
29
scripts/1-setup-environment.bat
Normal file
29
scripts/1-setup-environment.bat
Normal file
@@ -0,0 +1,29 @@
|
||||
@echo off
|
||||
|
||||
echo Check, if OpenJDK/ Eclipse Temurin 11 or newer is installed.
|
||||
pause
|
||||
echo:
|
||||
|
||||
cd modules
|
||||
call run java -version
|
||||
cd ..
|
||||
|
||||
echo:
|
||||
set /P INSTALLED_JAVA=Can you see OpenJDK/ Eclipse Temurin 11 or newer? (y/n)
|
||||
|
||||
if "%INSTALLED_JAVA%"=="y" (
|
||||
echo The environment is set up.
|
||||
pause
|
||||
exit
|
||||
)
|
||||
|
||||
cls
|
||||
echo Install Eclipse Temurin JRE 21.
|
||||
pause
|
||||
|
||||
cd modules
|
||||
call install-java
|
||||
cd ..
|
||||
|
||||
echo The environment is set up. Rerun this script to check your environment.
|
||||
pause
|
||||
11
scripts/2-download.bat
Normal file
11
scripts/2-download.bat
Normal file
@@ -0,0 +1,11 @@
|
||||
@echo off
|
||||
|
||||
echo Download necessary files from GitHub.
|
||||
pause
|
||||
|
||||
cd modules
|
||||
call composite download %~dp0\workspace
|
||||
cd ..
|
||||
|
||||
echo Files downloaded.
|
||||
pause
|
||||
14
scripts/3-patch.bat
Normal file
14
scripts/3-patch.bat
Normal file
@@ -0,0 +1,14 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
echo Patch an APK with the patches in the workspace.
|
||||
pause
|
||||
|
||||
cd modules
|
||||
call composite patch %~dp0\workspace
|
||||
cd ..
|
||||
|
||||
mv %~dp0\workspace\patched.apk %~dp0\patched.apk
|
||||
|
||||
echo Patched APK saved at %~dp0\patched.apk.
|
||||
pause
|
||||
11
scripts/4-cleanup.bat
Normal file
11
scripts/4-cleanup.bat
Normal file
@@ -0,0 +1,11 @@
|
||||
@echo off
|
||||
|
||||
echo Clean the workspace.
|
||||
pause
|
||||
|
||||
cd modules
|
||||
call composite clean %~dp0\workspace
|
||||
cd ..
|
||||
|
||||
echo Cleaned workspace.
|
||||
pause
|
||||
8
scripts/README.md
Normal file
8
scripts/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# 📜 Scripts
|
||||
|
||||
This directory contain click-to-run scripts to use ReVanced CLI.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [cURL](https://curl.haxx.se/)
|
||||
- [WinGet](https://aka.ms/getwinget), if you are on Windows
|
||||
1
scripts/customize.bat
Normal file
1
scripts/customize.bat
Normal file
@@ -0,0 +1 @@
|
||||
notepad modules\env.bat
|
||||
12
scripts/modules/check-java.bat
Normal file
12
scripts/modules/check-java.bat
Normal file
@@ -0,0 +1,12 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
for /f "tokens=8 delims=. " %%a in ('java --version 2^>nul ^| findstr /r "build"') do (
|
||||
set JAVA_VERSION_MAJOR=%%a
|
||||
goto :break
|
||||
)
|
||||
:break
|
||||
|
||||
if %JAVA_VERSION_MAJOR% LSS 11 (
|
||||
echo It looks like Java version is less than 11. Install OpenJDK/ Eclipse Temurin 11 or newer.
|
||||
)
|
||||
51
scripts/modules/composite.bat
Normal file
51
scripts/modules/composite.bat
Normal file
@@ -0,0 +1,51 @@
|
||||
@echo off
|
||||
setlocal EnableDelayedExpansion
|
||||
|
||||
if "%~1"=="" (
|
||||
set INVALID_ARGS=true
|
||||
)
|
||||
if "%~2"=="" (
|
||||
set INVALID_ARGS=true
|
||||
)
|
||||
if defined INVALID_ARGS (
|
||||
echo Runs curated compositions of scripts.
|
||||
echo:
|
||||
echo Usage: composite ^<script^> ^<workspace^>
|
||||
echo Example: composite patch C:/revanced
|
||||
echo:
|
||||
echo Available commands:
|
||||
echo: download - Download files
|
||||
echo: patch - Patches an application
|
||||
echo: clean - Cleans the workspace
|
||||
echo: env - Check for a valid environment setup
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
call env
|
||||
|
||||
set WORKSPACE=%2
|
||||
|
||||
if "%~1"=="download" (
|
||||
call create %WORKSPACE%
|
||||
|
||||
if not exist %WORKSPACE%/revanced-cli.jar (
|
||||
echo Downloading ReVanced CLI...
|
||||
call download %CLI_REPO% jar %WORKSPACE%/revanced-cli.jar
|
||||
)
|
||||
|
||||
if not exist %WORKSPACE%/patches.rvp (
|
||||
echo Downloading ReVanced patches...
|
||||
call download %PATCHES_REPO% jar %WORKSPACE%/patches.rvp
|
||||
)
|
||||
)
|
||||
if "%~1"=="patch" (
|
||||
set /p APK="Path to the APK file: "
|
||||
|
||||
call patch !APK! %WORKSPACE%
|
||||
)
|
||||
if "%~1"=="clean" (
|
||||
call delete %WORKSPACE%
|
||||
)
|
||||
if "%~1"=="env" (
|
||||
call check-java
|
||||
)
|
||||
19
scripts/modules/create.bat
Normal file
19
scripts/modules/create.bat
Normal file
@@ -0,0 +1,19 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
if "%~1"=="" (
|
||||
set INVALID_ARGS=true
|
||||
)
|
||||
if defined INVALID_ARGS (
|
||||
echo Creates a directory using the mkdir command.
|
||||
echo:
|
||||
echo Usage: create ^<path^>
|
||||
echo Example: create C:/revanced
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
set DIRECTORY=%1
|
||||
|
||||
if not exist %DIRECTORY% (
|
||||
run "mkdir.exe" -p %DIRECTORY%
|
||||
)
|
||||
20
scripts/modules/delete.bat
Normal file
20
scripts/modules/delete.bat
Normal file
@@ -0,0 +1,20 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
if "%~1"=="" (
|
||||
set INVALID_ARGS=true
|
||||
)
|
||||
if defined INVALID_ARGS (
|
||||
echo Deletes a directory relative to the current directory using the rmdir command.
|
||||
echo:
|
||||
echo Usage: delete ^<path^>
|
||||
echo Example: delete C:/revanced
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
set DIRECTORY=%1
|
||||
|
||||
if exist %DIRECTORY% (
|
||||
echo Confirm deletion of
|
||||
run rmdir /s %DIRECTORY%
|
||||
)
|
||||
30
scripts/modules/download.bat
Normal file
30
scripts/modules/download.bat
Normal file
@@ -0,0 +1,30 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
if "%~1"=="" (
|
||||
set INVALID_ARGS=true
|
||||
)
|
||||
if "%~2"=="" (
|
||||
set INVALID_ARGS=true
|
||||
)
|
||||
if "%~3"=="" (
|
||||
set INVALID_ARGS=true
|
||||
)
|
||||
if defined INVALID_ARGS (
|
||||
echo Downloads a file from a GitHub repository release.
|
||||
echo:
|
||||
echo Usage: download ^<repo^> ^<asset-extension^> ^<out^>
|
||||
echo Example: download revanced/revanced-cli jar C:/revanced/revanced-cli.jar
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
set REPO=%1
|
||||
set ASSET_EXTENSION=%2
|
||||
set OUT=%3
|
||||
|
||||
set URL=https://api.github.com/repos/%REPO%/releases/latest
|
||||
for /f "delims=" %%i in ('curl -s %URL% ^| jq -r ".assets[] | select(.name | endswith(\"%ASSET_EXTENSION%\")) | .browser_download_url"') do (
|
||||
set JAR_URL=%%i
|
||||
)
|
||||
|
||||
run curl --silent --location --output %OUT% %JAR_URL%
|
||||
6
scripts/modules/env.bat
Normal file
6
scripts/modules/env.bat
Normal file
@@ -0,0 +1,6 @@
|
||||
@echo off
|
||||
|
||||
:: Customize your environment.
|
||||
|
||||
set CLI_REPO=revanced/revanced-cli
|
||||
set PATCHES_REPO=revanced/revanced-patches
|
||||
1
scripts/modules/install-java.bat
Normal file
1
scripts/modules/install-java.bat
Normal file
@@ -0,0 +1 @@
|
||||
run install EclipseAdoptium.Temurin.21.JRE
|
||||
1
scripts/modules/install-jq.bat
Normal file
1
scripts/modules/install-jq.bat
Normal file
@@ -0,0 +1 @@
|
||||
run install jqlang.jq
|
||||
14
scripts/modules/install.bat
Normal file
14
scripts/modules/install.bat
Normal file
@@ -0,0 +1,14 @@
|
||||
@echo off
|
||||
|
||||
if "%~1"=="" (
|
||||
set INVALID_ARGS=true
|
||||
)
|
||||
if defined INVALID_ARGS (
|
||||
echo Installs a package using winget.
|
||||
echo:
|
||||
echo Usage: install ^<id^>
|
||||
echo Example: install jqlang.jq
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
run winget install -e --id=%1
|
||||
28
scripts/modules/patch.bat
Normal file
28
scripts/modules/patch.bat
Normal file
@@ -0,0 +1,28 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
if "%~1"=="" (
|
||||
set INVALID_ARGS=true
|
||||
)
|
||||
if "%~2"=="" (
|
||||
set INVALID_ARGS=true
|
||||
)
|
||||
if defined INVALID_ARGS (
|
||||
echo Patches an application using the specified patches.
|
||||
echo:
|
||||
echo Usage: patch ^<apk^> ^<workspace^>
|
||||
echo Example: patch C:/app.apk C:/workspace
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
set APK=%1
|
||||
set WORKSPACE=%2
|
||||
|
||||
call run java -jar %WORKSPACE%/revanced-cli.jar patch ^
|
||||
--patch-bundle %WORKSPACE%/patches.rvp ^
|
||||
--temporary-files-path %WORKSPACE%/temporary-files ^
|
||||
--out %WORKSPACE%/patched.apk ^
|
||||
--purge ^
|
||||
%APK%
|
||||
|
||||
mv %WORKSPACE%/patched.apk
|
||||
23
scripts/modules/run.bat
Normal file
23
scripts/modules/run.bat
Normal file
@@ -0,0 +1,23 @@
|
||||
@echo off
|
||||
|
||||
if "%~1"=="" (
|
||||
set INVALID_ARGS=true
|
||||
)
|
||||
if defined INVALID_ARGS (
|
||||
echo Run a command with arguments.
|
||||
echo:
|
||||
echo Usage: run.bat ^<command^> [arguments]
|
||||
echo Example: run.bat echo Hello, World!
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
%*
|
||||
|
||||
if %ERRORLEVEL% NEQ 0 (
|
||||
echo:
|
||||
echo Failed to run command with exit code %ERRORLEVEL%.
|
||||
echo Failed command: %*
|
||||
echo:
|
||||
pause
|
||||
exit /b %ERRORLEVEL%
|
||||
)
|
||||
@@ -12,17 +12,17 @@ import java.util.logging.Logger
|
||||
name = "list-versions",
|
||||
description = [
|
||||
"List the most common compatible versions of apps that are compatible " +
|
||||
"with the patches in the supplied patch bundles.",
|
||||
"with the patches from RVP files.",
|
||||
],
|
||||
)
|
||||
internal class ListCompatibleVersions : Runnable {
|
||||
private val logger = Logger.getLogger(this::class.java.name)
|
||||
|
||||
@CommandLine.Parameters(
|
||||
description = ["Paths to patch bundles."],
|
||||
description = ["Paths to RVP files."],
|
||||
arity = "1..*",
|
||||
)
|
||||
private lateinit var patchBundles: Set<File>
|
||||
private lateinit var patchesFiles: Set<File>
|
||||
|
||||
@CommandLine.Option(
|
||||
names = ["-f", "--filter-package-names"],
|
||||
@@ -56,7 +56,7 @@ internal class ListCompatibleVersions : Runnable {
|
||||
appendLine(versions.buildVersionsString().prependIndent("\t"))
|
||||
}
|
||||
|
||||
val patches = loadPatchesFromJar(patchBundles)
|
||||
val patches = loadPatchesFromJar(patchesFiles)
|
||||
|
||||
patches.mostCommonCompatibleVersions(
|
||||
packageNames,
|
||||
|
||||
@@ -11,16 +11,16 @@ import app.revanced.patcher.patch.Option as PatchOption
|
||||
|
||||
@Command(
|
||||
name = "list-patches",
|
||||
description = ["List patches from supplied patch bundles."],
|
||||
description = ["List patches from supplied RVP files."],
|
||||
)
|
||||
internal object ListPatchesCommand : Runnable {
|
||||
private val logger = Logger.getLogger(this::class.java.name)
|
||||
|
||||
@Parameters(
|
||||
description = ["Paths to patch bundles."],
|
||||
description = ["Paths to RVP files."],
|
||||
arity = "1..*",
|
||||
)
|
||||
private lateinit var patchBundles: Set<File>
|
||||
private lateinit var patchesFiles: Set<File>
|
||||
|
||||
@Option(
|
||||
names = ["-d", "--with-descriptions"],
|
||||
@@ -59,7 +59,7 @@ internal object ListPatchesCommand : Runnable {
|
||||
|
||||
@Option(
|
||||
names = ["-i", "--index"],
|
||||
description = ["List the index of each patch in relation to the supplied patch bundles."],
|
||||
description = ["List the index of each patch in relation to the supplied RVP files."],
|
||||
showDefaultValue = ALWAYS,
|
||||
)
|
||||
private var withIndex: Boolean = true
|
||||
@@ -111,6 +111,8 @@ internal object ListPatchesCommand : Runnable {
|
||||
|
||||
if (withDescriptions) append("\nDescription: ${patch.description}")
|
||||
|
||||
append("Enabled: ${patch.use}")
|
||||
|
||||
if (withOptions && patch.options.isNotEmpty()) {
|
||||
appendLine("\nOptions:")
|
||||
append(
|
||||
@@ -135,7 +137,7 @@ internal object ListPatchesCommand : Runnable {
|
||||
compatiblePackages?.any { (compatiblePackageName, _) -> compatiblePackageName == name }
|
||||
?: withUniversalPatches
|
||||
|
||||
val patches = loadPatchesFromJar(patchBundles).withIndex().toList()
|
||||
val patches = loadPatchesFromJar(patchesFiles).withIndex().toList()
|
||||
|
||||
val filtered =
|
||||
packageName?.let { patches.filter { (_, patch) -> patch.filterCompatiblePackages(it) } } ?: patches
|
||||
|
||||
@@ -30,27 +30,27 @@ internal object PatchCommand : Runnable {
|
||||
private lateinit var spec: CommandSpec
|
||||
|
||||
@ArgGroup(multiplicity = "0..*")
|
||||
private lateinit var selection: Set<Selection>
|
||||
private var selection = mutableSetOf<Selection>()
|
||||
|
||||
internal class Selection {
|
||||
@ArgGroup(exclusive = false, multiplicity = "1")
|
||||
internal var include: IncludeSelection? = null
|
||||
internal var enabled: EnableSelection? = null
|
||||
|
||||
internal class IncludeSelection {
|
||||
internal class EnableSelection {
|
||||
@ArgGroup(multiplicity = "1")
|
||||
internal lateinit var selector: IncludeSelector
|
||||
internal lateinit var selector: EnableSelector
|
||||
|
||||
internal class IncludeSelector {
|
||||
internal class EnableSelector {
|
||||
@CommandLine.Option(
|
||||
names = ["-i", "--include"],
|
||||
description = ["The name of the patch."],
|
||||
names = ["-e", "--enable"],
|
||||
description = ["Name of the patch."],
|
||||
required = true,
|
||||
)
|
||||
internal var name: String? = null
|
||||
|
||||
@CommandLine.Option(
|
||||
names = ["--ii"],
|
||||
description = ["The index of the patch in the combined list of all supplied patch bundles."],
|
||||
names = ["--ei"],
|
||||
description = ["Index of the patch in the combined list of the supplied RVP files."],
|
||||
required = true,
|
||||
)
|
||||
internal var index: Int? = null
|
||||
@@ -58,7 +58,7 @@ internal object PatchCommand : Runnable {
|
||||
|
||||
@CommandLine.Option(
|
||||
names = ["-O", "--options"],
|
||||
description = ["The option values keyed by the option keys."],
|
||||
description = ["Option values keyed by option keys."],
|
||||
mapFallbackValue = CommandLine.Option.NULL_VALUE,
|
||||
converter = [OptionKeyConverter::class, OptionValueConverter::class],
|
||||
)
|
||||
@@ -66,23 +66,23 @@ internal object PatchCommand : Runnable {
|
||||
}
|
||||
|
||||
@ArgGroup(exclusive = false, multiplicity = "1")
|
||||
internal var exclude: ExcludeSelection? = null
|
||||
internal var disable: DisableSelection? = null
|
||||
|
||||
internal class ExcludeSelection {
|
||||
internal class DisableSelection {
|
||||
@ArgGroup(multiplicity = "1")
|
||||
internal lateinit var selector: ExcludeSelector
|
||||
internal lateinit var selector: DisableSelector
|
||||
|
||||
internal class ExcludeSelector {
|
||||
internal class DisableSelector {
|
||||
@CommandLine.Option(
|
||||
names = ["-e", "--exclude"],
|
||||
description = ["The name of the patch."],
|
||||
names = ["-d", "--disable"],
|
||||
description = ["Name of the patch."],
|
||||
required = true,
|
||||
)
|
||||
internal var name: String? = null
|
||||
|
||||
@CommandLine.Option(
|
||||
names = ["--ie"],
|
||||
description = ["The index of the patch in the combined list of all supplied patch bundles."],
|
||||
names = ["--di"],
|
||||
description = ["Index of the patch in the combined list of the supplied RVP files."],
|
||||
required = true,
|
||||
)
|
||||
internal var index: Int? = null
|
||||
@@ -92,14 +92,14 @@ internal object PatchCommand : Runnable {
|
||||
|
||||
@CommandLine.Option(
|
||||
names = ["--exclusive"],
|
||||
description = ["Only include patches that are explicitly specified to be included."],
|
||||
description = ["Disable all patches except the ones enabled."],
|
||||
showDefaultValue = ALWAYS,
|
||||
)
|
||||
private var exclusive = false
|
||||
|
||||
@CommandLine.Option(
|
||||
names = ["-f", "--force"],
|
||||
description = ["Bypass compatibility checks for the supplied APK's version."],
|
||||
description = ["Don't check for compatibility with the supplied APK's version."],
|
||||
showDefaultValue = ALWAYS,
|
||||
)
|
||||
private var force: Boolean = false
|
||||
@@ -108,7 +108,7 @@ internal object PatchCommand : Runnable {
|
||||
|
||||
@CommandLine.Option(
|
||||
names = ["-o", "--out"],
|
||||
description = ["Path to save the patched APK file to. Defaults to the same directory as the supplied APK file."],
|
||||
description = ["Path to save the patched APK file to. Defaults to the same path as the supplied APK file."],
|
||||
)
|
||||
@Suppress("unused")
|
||||
private fun setOutputFilePath(outputFilePath: File?) {
|
||||
@@ -116,8 +116,8 @@ internal object PatchCommand : Runnable {
|
||||
}
|
||||
|
||||
@CommandLine.Option(
|
||||
names = ["-d", "--device-serial"],
|
||||
description = ["ADB device serial to install to. If not supplied, the first connected device will be used."],
|
||||
names = ["-i", "--install"],
|
||||
description = ["Serial of the ADB device to install to. If not specified, the first connected device will be used."],
|
||||
// Empty string to indicate that the first connected device should be used.
|
||||
fallbackValue = "",
|
||||
arity = "0..1",
|
||||
@@ -126,7 +126,7 @@ internal object PatchCommand : Runnable {
|
||||
|
||||
@CommandLine.Option(
|
||||
names = ["--mount"],
|
||||
description = ["Install by mounting the patched APK file."],
|
||||
description = ["Install the patched APK file by mounting."],
|
||||
showDefaultValue = ALWAYS,
|
||||
)
|
||||
private var mount: Boolean = false
|
||||
@@ -134,28 +134,28 @@ internal object PatchCommand : Runnable {
|
||||
@CommandLine.Option(
|
||||
names = ["--keystore"],
|
||||
description = [
|
||||
"Path to the keystore to sign the patched APK file with. " +
|
||||
"Path to the keystore file containing a private key and certificate pair to sign the patched APK file with. " +
|
||||
"Defaults to the same directory as the supplied APK file.",
|
||||
],
|
||||
)
|
||||
private var keystoreFilePath: File? = null
|
||||
private var keyStoreFilePath: File? = null
|
||||
|
||||
@CommandLine.Option(
|
||||
names = ["--keystore-password"],
|
||||
description = ["The password of the keystore to sign the patched APK file with. Empty password by default."],
|
||||
description = ["Password of the keystore. Empty password by default."],
|
||||
)
|
||||
private var keyStorePassword: String? = null // Empty password by default
|
||||
|
||||
@CommandLine.Option(
|
||||
names = ["--keystore-entry-alias"],
|
||||
description = ["The alias of the keystore entry to sign the patched APK file with."],
|
||||
description = ["Alias of the private key and certificate pair keystore entry."],
|
||||
showDefaultValue = ALWAYS,
|
||||
)
|
||||
private var keyStoreEntryAlias = "ReVanced Key"
|
||||
|
||||
@CommandLine.Option(
|
||||
names = ["--keystore-entry-password"],
|
||||
description = ["The password of the entry from the keystore for the key to sign the patched APK file with."],
|
||||
description = ["Password of the keystore entry."],
|
||||
)
|
||||
private var keyStoreEntryPassword = "" // Empty password by default
|
||||
|
||||
@@ -175,15 +175,15 @@ internal object PatchCommand : Runnable {
|
||||
private var aaptBinaryPath: File? = null
|
||||
|
||||
@CommandLine.Option(
|
||||
names = ["-p", "--purge"],
|
||||
description = ["Purge the temporary resource cache directory after patching."],
|
||||
names = ["--purge"],
|
||||
description = ["Purge temporary files directory after patching."],
|
||||
showDefaultValue = ALWAYS,
|
||||
)
|
||||
private var purge: Boolean = false
|
||||
|
||||
@CommandLine.Parameters(
|
||||
description = ["APK file to be patched."],
|
||||
arity = "1..1",
|
||||
description = ["APK file to patch."],
|
||||
arity = "1",
|
||||
)
|
||||
@Suppress("unused")
|
||||
private fun setApk(apk: File) {
|
||||
@@ -199,19 +199,19 @@ internal object PatchCommand : Runnable {
|
||||
private lateinit var apk: File
|
||||
|
||||
@CommandLine.Option(
|
||||
names = ["-b", "--patch-bundle"],
|
||||
description = ["One or more bundles of patches."],
|
||||
names = ["-p", "--patches"],
|
||||
description = ["One or more path to RVP files."],
|
||||
required = true,
|
||||
)
|
||||
@Suppress("unused")
|
||||
private fun setPatchBundles(patchBundles: Set<File>) {
|
||||
patchBundles.firstOrNull { !it.exists() }?.let {
|
||||
throw CommandLine.ParameterException(spec.commandLine(), "Patch bundle ${it.name} does not exist")
|
||||
private fun setPatchesFile(patchesFiles: Set<File>) {
|
||||
patchesFiles.firstOrNull { !it.exists() }?.let {
|
||||
throw CommandLine.ParameterException(spec.commandLine(), "${it.name} can't be found")
|
||||
}
|
||||
this.patchBundles = patchBundles
|
||||
this.patchesFiles = patchesFiles
|
||||
}
|
||||
|
||||
private var patchBundles = emptySet<File>()
|
||||
private var patchesFiles = emptySet<File>()
|
||||
|
||||
@CommandLine.Option(
|
||||
names = ["--custom-aapt2-binary"],
|
||||
@@ -242,16 +242,44 @@ internal object PatchCommand : Runnable {
|
||||
)
|
||||
|
||||
val keystoreFilePath =
|
||||
keystoreFilePath ?: outputFilePath.parentFile
|
||||
keyStoreFilePath ?: outputFilePath.parentFile
|
||||
.resolve("${outputFilePath.nameWithoutExtension}.keystore")
|
||||
|
||||
val installer = if (deviceSerial != null) {
|
||||
val deviceSerial = deviceSerial!!.ifEmpty { null }
|
||||
|
||||
try {
|
||||
if (mount) {
|
||||
AdbRootInstaller(deviceSerial)
|
||||
} else {
|
||||
AdbInstaller(deviceSerial)
|
||||
}
|
||||
} catch (e: DeviceNotFoundException) {
|
||||
if (deviceSerial?.isNotEmpty() == true) {
|
||||
logger.severe(
|
||||
"Device with serial $deviceSerial not found to install to. " +
|
||||
"Ensure the device is connected and the serial is correct when using the --install option.",
|
||||
)
|
||||
} else {
|
||||
logger.severe(
|
||||
"No device has been found to install to. " +
|
||||
"Ensure a device is connected when using the --install option.",
|
||||
)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Load patches
|
||||
|
||||
logger.info("Loading patches")
|
||||
|
||||
val patches = loadPatchesFromJar(patchBundles)
|
||||
val patches = loadPatchesFromJar(patchesFiles)
|
||||
|
||||
// endregion
|
||||
|
||||
@@ -274,11 +302,11 @@ internal object PatchCommand : Runnable {
|
||||
logger.info("Setting patch options")
|
||||
|
||||
val patchesList = patches.toList()
|
||||
selection.filter { it.include != null }.associate {
|
||||
val includeSelection = it.include!!
|
||||
selection.filter { it.enabled != null }.associate {
|
||||
val enabledSelection = it.enabled!!
|
||||
|
||||
(includeSelection.selector.name ?: patchesList[includeSelection.selector.index!!].name!!) to
|
||||
includeSelection.options
|
||||
(enabledSelection.selector.name ?: patchesList[enabledSelection.selector.index!!].name!!) to
|
||||
enabledSelection.options
|
||||
}.let(filteredPatches::setOptions)
|
||||
|
||||
patcher += filteredPatches
|
||||
@@ -332,13 +360,7 @@ internal object PatchCommand : Runnable {
|
||||
val deviceSerial = it.ifEmpty { null }
|
||||
|
||||
runBlocking {
|
||||
val result = if (mount) {
|
||||
AdbRootInstaller(deviceSerial)
|
||||
} else {
|
||||
AdbInstaller(deviceSerial)
|
||||
}.install(Installer.Apk(outputFilePath, packageName))
|
||||
|
||||
when (result) {
|
||||
when (val result = installer!!.install(Installer.Apk(outputFilePath, packageName))) {
|
||||
RootInstallerResult.FAILURE -> logger.severe("Failed to mount the patched APK file")
|
||||
is AdbInstallerResult.Failure -> logger.severe(result.exception.toString())
|
||||
else -> logger.info("Installed the patched APK file")
|
||||
@@ -365,21 +387,21 @@ internal object PatchCommand : Runnable {
|
||||
packageName: String,
|
||||
packageVersion: String,
|
||||
): Set<Patch<*>> = buildSet {
|
||||
val includedPatchesByName =
|
||||
selection.asSequence().mapNotNull { it.include?.selector?.name }.toSet()
|
||||
val includedPatchesByIndex =
|
||||
selection.asSequence().mapNotNull { it.include?.selector?.index }.toSet()
|
||||
val enabledPatchesByName =
|
||||
selection.mapNotNull { it.enabled?.selector?.name }.toSet()
|
||||
val enabledPatchesByIndex =
|
||||
selection.mapNotNull { it.enabled?.selector?.index }.toSet()
|
||||
|
||||
val excludedPatches =
|
||||
selection.asSequence().mapNotNull { it.exclude?.selector?.name }.toSet()
|
||||
val excludedPatchesByIndex =
|
||||
selection.asSequence().mapNotNull { it.exclude?.selector?.index }.toSet()
|
||||
val disabledPatches =
|
||||
selection.mapNotNull { it.disable?.selector?.name }.toSet()
|
||||
val disabledPatchesByIndex =
|
||||
selection.mapNotNull { it.disable?.selector?.index }.toSet()
|
||||
|
||||
this@filterPatchSelection.withIndex().forEach patchLoop@{ (i, patch) ->
|
||||
val patchName = patch.name!!
|
||||
|
||||
val isManuallyExcluded = patchName in excludedPatches || i in excludedPatchesByIndex
|
||||
if (isManuallyExcluded) return@patchLoop logger.info("\"$patchName\" excluded manually")
|
||||
val isManuallyDisabled = patchName in disabledPatches || i in disabledPatchesByIndex
|
||||
if (isManuallyDisabled) return@patchLoop logger.info("\"$patchName\" disabled manually")
|
||||
|
||||
// Make sure the patch is compatible with the supplied APK files package name and version.
|
||||
patch.compatiblePackages?.let { packages ->
|
||||
@@ -409,11 +431,11 @@ internal object PatchCommand : Runnable {
|
||||
return@let
|
||||
} ?: logger.fine("\"$patchName\" has no package constraints")
|
||||
|
||||
val isIncluded = !exclusive && patch.use
|
||||
val isManuallyIncluded = patchName in includedPatchesByName || i in includedPatchesByIndex
|
||||
val isEnabled = !exclusive && patch.use
|
||||
val isManuallyEnabled = patchName in enabledPatchesByName || i in enabledPatchesByIndex
|
||||
|
||||
if (!(isIncluded || isManuallyIncluded)) {
|
||||
return@patchLoop logger.info("\"$patchName\" excluded")
|
||||
if (!(isEnabled || isManuallyEnabled)) {
|
||||
return@patchLoop logger.info("\"$patchName\" disabled")
|
||||
}
|
||||
|
||||
add(patch)
|
||||
|
||||
@@ -10,27 +10,27 @@ import java.util.logging.Logger
|
||||
|
||||
@Command(
|
||||
name = "install",
|
||||
description = ["Install an APK file to devices with the supplied ADB device serials"],
|
||||
description = ["Install an APK file."],
|
||||
)
|
||||
internal object InstallCommand : Runnable {
|
||||
private val logger = Logger.getLogger(this::class.java.name)
|
||||
|
||||
@Parameters(
|
||||
description = ["ADB device serials. If not supplied, the first connected device will be used."],
|
||||
description = ["Serial of ADB devices. If not supplied, the first connected device will be used."],
|
||||
arity = "0..*",
|
||||
)
|
||||
private var deviceSerials: Array<String>? = null
|
||||
|
||||
@Option(
|
||||
names = ["-a", "--apk"],
|
||||
description = ["APK file to be installed"],
|
||||
description = ["APK file to be installed."],
|
||||
required = true,
|
||||
)
|
||||
private lateinit var apk: File
|
||||
|
||||
@Option(
|
||||
names = ["-m", "--mount"],
|
||||
description = ["Mount the supplied APK file over the app with the supplied package name"],
|
||||
description = ["Mount the supplied APK file over the app with the supplied package name."],
|
||||
)
|
||||
private var packageName: String? = null
|
||||
|
||||
|
||||
@@ -13,27 +13,27 @@ import java.util.logging.Logger
|
||||
|
||||
@Command(
|
||||
name = "uninstall",
|
||||
description = ["Uninstall a patched app from the devices with the supplied ADB device serials"],
|
||||
description = ["Uninstall a patched app."],
|
||||
)
|
||||
internal object UninstallCommand : Runnable {
|
||||
private val logger = Logger.getLogger(this::class.java.name)
|
||||
|
||||
@Parameters(
|
||||
description = ["ADB device serials. If not supplied, the first connected device will be used."],
|
||||
description = ["Serial of ADB devices. If not supplied, the first connected device will be used."],
|
||||
arity = "0..*",
|
||||
)
|
||||
private var deviceSerials: Array<String>? = null
|
||||
|
||||
@Option(
|
||||
names = ["-p", "--package-name"],
|
||||
description = ["Package name of the app to uninstall"],
|
||||
description = ["Package name of the app to uninstall."],
|
||||
required = true,
|
||||
)
|
||||
private lateinit var packageName: String
|
||||
|
||||
@Option(
|
||||
names = ["-u", "--unmount"],
|
||||
description = ["Uninstall by unmounting the patched APK file"],
|
||||
description = ["Uninstall the patched APK file by unmounting."],
|
||||
showDefaultValue = ALWAYS,
|
||||
)
|
||||
private var unmount: Boolean = false
|
||||
|
||||
Reference in New Issue
Block a user