You've already forked revanced-patcher
mirror of
https://github.com/revanced/revanced-patcher
synced 2025-09-13 18:30:49 +02:00
Compare commits
49 Commits
v20.0.0-de
...
v20.0.1
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4c1c34ad01 | ||
![]() |
b2aecb726d | ||
![]() |
851f9c7885 | ||
![]() |
ea6fc70caa | ||
![]() |
a2875d1d64 | ||
![]() |
2be6e97817 | ||
![]() |
348d0070e7 | ||
![]() |
d53aacdad4 | ||
![]() |
f1615b7ab5 | ||
![]() |
ffb1d880d7 | ||
![]() |
e95f13ae3e | ||
![]() |
e1b984d601 | ||
![]() |
c2dc29e061 | ||
![]() |
69f2f20fd9 | ||
![]() |
525beda18e | ||
![]() |
73d3cbf4ff | ||
![]() |
70278dd79d | ||
![]() |
5e98e9e30a | ||
![]() |
ac1aff5a1a | ||
![]() |
5481d0c54c | ||
![]() |
4604742d0f | ||
![]() |
4beb907a61 | ||
![]() |
7f44174d91 | ||
![]() |
d310246852 | ||
![]() |
dcc989243c | ||
![]() |
5227e98abf | ||
![]() |
8c4dd5b3a3 | ||
![]() |
736b3eebbf | ||
![]() |
b41a542952 | ||
![]() |
d21128fe2e | ||
![]() |
cf4374b8cf | ||
![]() |
8a30b0fa10 | ||
![]() |
11a911dc67 | ||
![]() |
6e3ba7419b | ||
![]() |
50a66ccfed | ||
![]() |
0be79840b1 | ||
![]() |
d8b4c60321 | ||
![]() |
f77e99e817 | ||
![]() |
ea26c486c0 | ||
![]() |
bebb734608 | ||
![]() |
d842f82d07 | ||
![]() |
82bab58ac2 | ||
![]() |
90b7631d9e | ||
![]() |
26d449e6d9 | ||
![]() |
49466060e3 | ||
![]() |
620ea5b852 | ||
![]() |
3e2168a2b2 | ||
![]() |
13c77967b1 | ||
![]() |
f57e571a14 |
5
.github/workflows/release.yml
vendored
5
.github/workflows/release.yml
vendored
@@ -10,6 +10,9 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
name: Release
|
name: Release
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -46,5 +49,5 @@ jobs:
|
|||||||
|
|
||||||
- name: Release
|
- name: Release
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
run: npm exec semantic-release
|
run: npm exec semantic-release
|
||||||
|
@@ -23,7 +23,8 @@
|
|||||||
"assets": [
|
"assets": [
|
||||||
"CHANGELOG.md",
|
"CHANGELOG.md",
|
||||||
"gradle.properties"
|
"gradle.properties"
|
||||||
]
|
],
|
||||||
|
"message": "chore: Release v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
85
CHANGELOG.md
85
CHANGELOG.md
@@ -1,3 +1,88 @@
|
|||||||
|
## [20.0.1](https://github.com/ReVanced/revanced-patcher/compare/v20.0.0...v20.0.1) (2024-10-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Check for class type exactly instead of with contains ([#310](https://github.com/ReVanced/revanced-patcher/issues/310)) ([69f2f20](https://github.com/ReVanced/revanced-patcher/commit/69f2f20fd99162f91cd9c531dfe47d00d3152ead))
|
||||||
|
* Make it work on Android by not using APIs from JVM unavailable to Android. ([2be6e97](https://github.com/ReVanced/revanced-patcher/commit/2be6e97817437f40e17893dfff3bea2cd4c3ff9e))
|
||||||
|
* Use non-nullable type for options ([ea6fc70](https://github.com/ReVanced/revanced-patcher/commit/ea6fc70caab055251ad4d0d3f1b5cf53865abb85))
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* Free memory earlier and remove negligible lookup maps ([d53aacd](https://github.com/ReVanced/revanced-patcher/commit/d53aacdad4ed3750ddae526fb307577ea36e6171))
|
||||||
|
|
||||||
|
## [20.0.1-dev.5](https://github.com/ReVanced/revanced-patcher/compare/v20.0.1-dev.4...v20.0.1-dev.5) (2024-10-11)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Use non-nullable type for options ([ea6fc70](https://github.com/ReVanced/revanced-patcher/commit/ea6fc70caab055251ad4d0d3f1b5cf53865abb85))
|
||||||
|
|
||||||
|
## [20.0.1-dev.4](https://github.com/ReVanced/revanced-patcher/compare/v20.0.1-dev.3...v20.0.1-dev.4) (2024-10-07)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Make it work on Android by not using APIs from JVM unavailable to Android. ([2be6e97](https://github.com/ReVanced/revanced-patcher/commit/2be6e97817437f40e17893dfff3bea2cd4c3ff9e))
|
||||||
|
|
||||||
|
## [20.0.1-dev.3](https://github.com/ReVanced/revanced-patcher/compare/v20.0.1-dev.2...v20.0.1-dev.3) (2024-10-03)
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* Free memory earlier and remove negligible lookup maps ([d53aacd](https://github.com/ReVanced/revanced-patcher/commit/d53aacdad4ed3750ddae526fb307577ea36e6171))
|
||||||
|
|
||||||
|
## [20.0.1-dev.2](https://github.com/ReVanced/revanced-patcher/compare/v20.0.1-dev.1...v20.0.1-dev.2) (2024-10-01)
|
||||||
|
|
||||||
|
## [20.0.1-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v20.0.0...v20.0.1-dev.1) (2024-09-18)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Check for class type exactly instead of with contains ([#310](https://github.com/ReVanced/revanced-patcher/issues/310)) ([69f2f20](https://github.com/ReVanced/revanced-patcher/commit/69f2f20fd99162f91cd9c531dfe47d00d3152ead))
|
||||||
|
|
||||||
|
# [20.0.0](https://github.com/ReVanced/revanced-patcher/compare/v19.3.1...v20.0.0) (2024-08-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Downgrade smali to fix dex compilation issue ([5227e98](https://github.com/ReVanced/revanced-patcher/commit/5227e98abfaa2ff1204eb20a0f2671f58c489930))
|
||||||
|
* Improve exception message wording ([5481d0c](https://github.com/ReVanced/revanced-patcher/commit/5481d0c54ccecc91cd8d15af1ba2d3285a33e5ab))
|
||||||
|
* Make constructor internal as supposed ([7f44174](https://github.com/ReVanced/revanced-patcher/commit/7f44174d91f0af0d50a83d80a7103c779241e094))
|
||||||
|
* Merge all extensions before initializing lookup maps ([8c4dd5b](https://github.com/ReVanced/revanced-patcher/commit/8c4dd5b3a309077fa9a3827b4931fc28b0517809))
|
||||||
|
* Use null for compatible package version when adding packages only ([736b3ee](https://github.com/ReVanced/revanced-patcher/commit/736b3eebbfdd7279b8d5fcfc5c46c9e3aadbee12))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add ability to create options outside of a patch ([d310246](https://github.com/ReVanced/revanced-patcher/commit/d310246852504b08a15f6376bbf25ac7c6fae76f))
|
||||||
|
* Convert APIs to Kotlin DSL ([#298](https://github.com/ReVanced/revanced-patcher/issues/298)) ([11a911d](https://github.com/ReVanced/revanced-patcher/commit/11a911dc674eb0801649949dd3f28dfeb00efe97))
|
||||||
|
|
||||||
|
|
||||||
|
### BREAKING CHANGES
|
||||||
|
|
||||||
|
* Various old APIs are removed, and DSL APIs are added instead.
|
||||||
|
|
||||||
|
# [20.0.0-dev.4](https://github.com/ReVanced/revanced-patcher/compare/v20.0.0-dev.3...v20.0.0-dev.4) (2024-08-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Improve exception message wording ([bd434ce](https://github.com/ReVanced/revanced-patcher/commit/bd434ceb3394d1d5292e8b94e5bfd6da0e4e9c72))
|
||||||
|
|
||||||
|
# [20.0.0-dev.3](https://github.com/ReVanced/revanced-patcher/compare/v20.0.0-dev.2...v20.0.0-dev.3) (2024-08-01)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Make constructor internal as supposed ([e95fcd1](https://github.com/ReVanced/revanced-patcher/commit/e95fcd1c0b641164bbf0840ec7e562aeb3bacc3e))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add ability to create options outside of a patch ([b8d763a](https://github.com/ReVanced/revanced-patcher/commit/b8d763a66e0601627dd71c8c24247726aa300146))
|
||||||
|
|
||||||
# [20.0.0-dev.2](https://github.com/ReVanced/revanced-patcher/compare/v20.0.0-dev.1...v20.0.0-dev.2) (2024-07-31)
|
# [20.0.0-dev.2](https://github.com/ReVanced/revanced-patcher/compare/v20.0.0-dev.1...v20.0.0-dev.2) (2024-07-31)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -149,7 +149,6 @@ public final class app/revanced/patcher/patch/BytecodePatchBuilder : app/revance
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patcher/patch/BytecodePatchBuilder$InvokedFingerprint {
|
public final class app/revanced/patcher/patch/BytecodePatchBuilder$InvokedFingerprint {
|
||||||
public fun <init> (Lapp/revanced/patcher/Fingerprint;)V
|
|
||||||
public final fun getValue (Ljava/lang/Void;Lkotlin/reflect/KProperty;)Lapp/revanced/patcher/Match;
|
public final fun getValue (Ljava/lang/Void;Lkotlin/reflect/KProperty;)Lapp/revanced/patcher/Match;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,25 +204,43 @@ public final class app/revanced/patcher/patch/OptionException$ValueValidationExc
|
|||||||
|
|
||||||
public final class app/revanced/patcher/patch/OptionKt {
|
public final class app/revanced/patcher/patch/OptionKt {
|
||||||
public static final fun booleanOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
public static final fun booleanOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static final fun booleanOption (Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static synthetic fun booleanOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
public static synthetic fun booleanOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static synthetic fun booleanOption$default (Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static final fun booleansOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
public static final fun booleansOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static final fun booleansOption (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static synthetic fun booleansOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
public static synthetic fun booleansOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static synthetic fun booleansOption$default (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static final fun floatOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
public static final fun floatOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static final fun floatOption (Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static synthetic fun floatOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
public static synthetic fun floatOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static synthetic fun floatOption$default (Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static final fun floatsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
public static final fun floatsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static synthetic fun floatsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
public static synthetic fun floatsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static final fun intOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
public static final fun intOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static final fun intOption (Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static synthetic fun intOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
public static synthetic fun intOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static synthetic fun intOption$default (Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static final fun intsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
public static final fun intsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static final fun intsOption (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static synthetic fun intsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
public static synthetic fun intsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static synthetic fun intsOption$default (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static final fun longOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
public static final fun longOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static final fun longOption (Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static synthetic fun longOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
public static synthetic fun longOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static synthetic fun longOption$default (Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static final fun longsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
public static final fun longsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static final fun longsOption (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static synthetic fun longsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
public static synthetic fun longsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static synthetic fun longsOption$default (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static final fun stringOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
public static final fun stringOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static final fun stringOption (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static synthetic fun stringOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
public static synthetic fun stringOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static synthetic fun stringOption$default (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static final fun stringsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
public static final fun stringsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static final fun stringsOption (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option;
|
||||||
public static synthetic fun stringsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
public static synthetic fun stringsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
|
public static synthetic fun stringsOption$default (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patcher/patch/Options : java/util/Map, kotlin/jvm/internal/markers/KMappedMarker {
|
public final class app/revanced/patcher/patch/Options : java/util/Map, kotlin/jvm/internal/markers/KMappedMarker {
|
||||||
|
@@ -36,20 +36,21 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(libs.kotlinx.coroutines.core)
|
|
||||||
implementation(libs.xpp3)
|
|
||||||
implementation(libs.smali)
|
|
||||||
implementation(libs.multidexlib2)
|
|
||||||
implementation(libs.apktool.lib)
|
|
||||||
implementation(libs.kotlin.reflect)
|
|
||||||
|
|
||||||
// TODO: Convert project to KMP.
|
// TODO: Convert project to KMP.
|
||||||
compileOnly(libs.android) {
|
compileOnly(libs.android) {
|
||||||
// Exclude, otherwise the org.w3c.dom API breaks.
|
// Exclude, otherwise the org.w3c.dom API breaks.
|
||||||
exclude(group = "xerces", module = "xmlParserAPIs")
|
exclude(group = "xerces", module = "xmlParserAPIs")
|
||||||
}
|
}
|
||||||
testImplementation(libs.kotlin.test)
|
|
||||||
|
implementation(libs.apktool.lib)
|
||||||
|
implementation(libs.kotlin.reflect)
|
||||||
|
implementation(libs.kotlinx.coroutines.core)
|
||||||
|
implementation(libs.multidexlib2)
|
||||||
|
implementation(libs.smali)
|
||||||
|
implementation(libs.xpp3)
|
||||||
|
|
||||||
testImplementation(libs.mockk)
|
testImplementation(libs.mockk)
|
||||||
|
testImplementation(libs.kotlin.test)
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
|
@@ -149,6 +149,18 @@ The type of an option can be obtained from the `type` property of the option:
|
|||||||
option.type // The KType of the option.
|
option.type // The KType of the option.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Options can be declared outside of a patch and added to a patch manually:
|
||||||
|
|
||||||
|
```kt
|
||||||
|
val option = stringOption(key = "option")
|
||||||
|
|
||||||
|
bytecodePatch(name = "Patch") {
|
||||||
|
val value by option()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This is useful when the same option is referenced in multiple patches.
|
||||||
|
|
||||||
### 🧩 Extensions
|
### 🧩 Extensions
|
||||||
|
|
||||||
An extension is a precompiled DEX file merged into the patched app before a patch is executed.
|
An extension is a precompiled DEX file merged into the patched app before a patch is executed.
|
||||||
|
@@ -108,7 +108,7 @@ val rawResourcePatch = rawResourcePatch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Surpress("unused")
|
@Surpress("unused")
|
||||||
val resourcePatch = rawResourcePatch {
|
val resourcePatch = resourcePatch {
|
||||||
execute {
|
execute {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
org.gradle.parallel = true
|
org.gradle.parallel = true
|
||||||
org.gradle.caching = true
|
org.gradle.caching = true
|
||||||
version = 20.0.0-dev.2
|
version = 20.0.1
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
[versions]
|
[versions]
|
||||||
android = "4.1.1.4"
|
android = "4.1.1.4"
|
||||||
apktool-lib = "2.9.3"
|
apktool-lib = "2.9.3"
|
||||||
|
binary-compatibility-validator = "0.15.1"
|
||||||
kotlin = "2.0.0"
|
kotlin = "2.0.0"
|
||||||
kotlinx-coroutines-core = "1.8.1"
|
kotlinx-coroutines-core = "1.8.1"
|
||||||
mockk = "1.13.10"
|
mockk = "1.13.10"
|
||||||
@@ -8,15 +9,14 @@ multidexlib2 = "3.0.3.r3"
|
|||||||
# Tracking https://github.com/google/smali/issues/64.
|
# Tracking https://github.com/google/smali/issues/64.
|
||||||
#noinspection GradleDependency
|
#noinspection GradleDependency
|
||||||
smali = "3.0.5"
|
smali = "3.0.5"
|
||||||
binary-compatibility-validator = "0.15.1"
|
|
||||||
xpp3 = "1.1.4c"
|
xpp3 = "1.1.4c"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
android = { module = "com.google.android:android", version.ref = "android" }
|
android = { module = "com.google.android:android", version.ref = "android" }
|
||||||
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
|
|
||||||
apktool-lib = { module = "app.revanced:apktool-lib", version.ref = "apktool-lib" }
|
apktool-lib = { module = "app.revanced:apktool-lib", version.ref = "apktool-lib" }
|
||||||
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
|
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
|
||||||
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines-core" }
|
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines-core" }
|
||||||
|
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
|
||||||
mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
|
mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
|
||||||
multidexlib2 = { module = "app.revanced:multidexlib2", version.ref = "multidexlib2" }
|
multidexlib2 = { module = "app.revanced:multidexlib2", version.ref = "multidexlib2" }
|
||||||
smali = { module = "com.android.tools.smali:smali", version.ref = "smali" }
|
smali = { module = "com.android.tools.smali:smali", version.ref = "smali" }
|
||||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
8
gradle/wrapper/gradle-wrapper.properties
vendored
8
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,8 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
|
distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab
|
||||||
distributionSha256Sum=9631d53cf3e74bfa726893aee1f8994fee4e060c401335946dba2156f440f24c
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||||
|
networkTimeout=10000
|
||||||
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dist
|
zipStorePath=wrapper/dists
|
||||||
|
22
gradlew
vendored
22
gradlew
vendored
@@ -15,6 +15,8 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
@@ -55,7 +57,7 @@
|
|||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
@@ -83,7 +85,9 @@ done
|
|||||||
# This is normally unused
|
# This is normally unused
|
||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
|
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
||||||
|
' "$PWD" ) || exit
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
@@ -144,7 +148,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
|||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
max*)
|
max*)
|
||||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||||
# shellcheck disable=SC3045
|
# shellcheck disable=SC2039,SC3045
|
||||||
MAX_FD=$( ulimit -H -n ) ||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
warn "Could not query maximum file descriptor limit"
|
warn "Could not query maximum file descriptor limit"
|
||||||
esac
|
esac
|
||||||
@@ -152,7 +156,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
|||||||
'' | soft) :;; #(
|
'' | soft) :;; #(
|
||||||
*)
|
*)
|
||||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||||
# shellcheck disable=SC3045
|
# shellcheck disable=SC2039,SC3045
|
||||||
ulimit -n "$MAX_FD" ||
|
ulimit -n "$MAX_FD" ||
|
||||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
esac
|
esac
|
||||||
@@ -201,11 +205,11 @@ fi
|
|||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Collect all arguments for the java command;
|
# Collect all arguments for the java command:
|
||||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||||
# shell script including quotes and variable substitutions, so put them in
|
# and any embedded shellness will be escaped.
|
||||||
# double quotes to make sure that they get re-expanded; and
|
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||||
# * put everything else in single quotes, so that it's not re-expanded.
|
# treated as '${Hostname}' itself on the command line.
|
||||||
|
|
||||||
set -- \
|
set -- \
|
||||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
|
22
gradlew.bat
vendored
22
gradlew.bat
vendored
@@ -13,6 +13,8 @@
|
|||||||
@rem See the License for the specific language governing permissions and
|
@rem See the License for the specific language governing permissions and
|
||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
@rem SPDX-License-Identifier: Apache-2.0
|
||||||
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%"=="" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
|
|||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if %ERRORLEVEL% equ 0 goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
@@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|||||||
|
|
||||||
if exist "%JAVA_EXE%" goto execute
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||||
echo.
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
echo location of your Java installation.
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
|
2972
package-lock.json
generated
2972
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",
|
"@saithodev/semantic-release-backmerge": "^4.0.1",
|
||||||
"@semantic-release/changelog": "^6.0.3",
|
"@semantic-release/changelog": "^6.0.3",
|
||||||
"@semantic-release/git": "^10.0.1",
|
"@semantic-release/git": "^10.0.1",
|
||||||
"gradle-semantic-release-plugin": "^1.9.1",
|
"gradle-semantic-release-plugin": "^1.10.1",
|
||||||
"semantic-release": "^23.0.2"
|
"semantic-release": "^24.1.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,8 +3,7 @@
|
|||||||
package app.revanced.patcher
|
package app.revanced.patcher
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.instructionsOrNull
|
import app.revanced.patcher.extensions.InstructionExtensions.instructionsOrNull
|
||||||
import app.revanced.patcher.patch.BytecodePatchBuilder
|
import app.revanced.patcher.patch.*
|
||||||
import app.revanced.patcher.patch.BytecodePatchContext
|
|
||||||
import app.revanced.patcher.patch.BytecodePatchContext.LookupMaps.Companion.appendParameters
|
import app.revanced.patcher.patch.BytecodePatchContext.LookupMaps.Companion.appendParameters
|
||||||
import app.revanced.patcher.patch.MethodClassPairs
|
import app.revanced.patcher.patch.MethodClassPairs
|
||||||
import app.revanced.patcher.util.proxy.ClassProxy
|
import app.revanced.patcher.util.proxy.ClassProxy
|
||||||
@@ -67,36 +66,15 @@ class Fingerprint internal constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: If only one string is necessary, why not use a single string for every fingerprint?
|
// TODO: If only one string is necessary, why not use a single string for every fingerprint?
|
||||||
fun Fingerprint.lookupByStrings() = strings?.firstNotNullOfOrNull { lookupMaps.methodsByStrings[it] }
|
if (strings?.firstNotNullOfOrNull { lookupMaps.methodsByStrings[it] }?.let(::match) == true) {
|
||||||
if (lookupByStrings()?.let(::match) == true) {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// No strings declared or none matched (partial matches are allowed).
|
context.classes.forEach { classDef ->
|
||||||
// Use signature matching.
|
if (match(context, classDef)) return true
|
||||||
fun Fingerprint.lookupBySignature(): MethodClassPairs {
|
|
||||||
if (accessFlags == null) return lookupMaps.allMethods
|
|
||||||
|
|
||||||
var returnTypeValue = returnType
|
|
||||||
if (returnTypeValue == null) {
|
|
||||||
if (AccessFlags.CONSTRUCTOR.isSet(accessFlags)) {
|
|
||||||
// Constructors always have void return type.
|
|
||||||
returnTypeValue = "V"
|
|
||||||
} else {
|
|
||||||
return lookupMaps.allMethods
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val signature =
|
|
||||||
buildString {
|
|
||||||
append(accessFlags)
|
|
||||||
append(returnTypeValue.first())
|
|
||||||
appendParameters(parameters ?: return@buildString)
|
|
||||||
}
|
|
||||||
|
|
||||||
return lookupMaps.methodsBySignature[signature] ?: return MethodClassPairs()
|
|
||||||
}
|
}
|
||||||
return match(lookupBySignature())
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -129,7 +107,7 @@ class Fingerprint internal constructor(
|
|||||||
fun match(
|
fun match(
|
||||||
context: BytecodePatchContext,
|
context: BytecodePatchContext,
|
||||||
method: Method,
|
method: Method,
|
||||||
) = match(context, method, context.classByType(method.definingClass)!!.immutableClass)
|
) = match(context, method, context.classBy { method.definingClass == it.type }!!.immutableClass)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Match using a [Method].
|
* Match using a [Method].
|
||||||
|
@@ -98,14 +98,12 @@ class Patcher(private val config: PatcherConfig) : Closeable {
|
|||||||
|
|
||||||
logger.info("Merging extensions")
|
logger.info("Merging extensions")
|
||||||
|
|
||||||
context.executablePatches.forEachRecursively { patch ->
|
with(context.bytecodeContext) {
|
||||||
if (patch is BytecodePatch && patch.extension != null) {
|
context.executablePatches.mergeExtensions()
|
||||||
context.bytecodeContext.merge(patch.extension)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize lookup maps.
|
// Initialize lookup maps.
|
||||||
context.bytecodeContext.lookupMaps
|
lookupMaps
|
||||||
|
}
|
||||||
|
|
||||||
logger.info("Executing patches")
|
logger.info("Executing patches")
|
||||||
|
|
||||||
|
@@ -20,6 +20,7 @@ class PatcherConfig(
|
|||||||
private val temporaryFilesPath: File = File("revanced-temporary-files"),
|
private val temporaryFilesPath: File = File("revanced-temporary-files"),
|
||||||
aaptBinaryPath: String? = null,
|
aaptBinaryPath: String? = null,
|
||||||
frameworkFileDirectory: String? = null,
|
frameworkFileDirectory: String? = null,
|
||||||
|
@Deprecated("This is going to be removed in the future because it is not needed anymore.")
|
||||||
internal val multithreadingDexFileWriter: Boolean = false,
|
internal val multithreadingDexFileWriter: Boolean = false,
|
||||||
) {
|
) {
|
||||||
private val logger = Logger.getLogger(PatcherConfig::class.java.name)
|
private val logger = Logger.getLogger(PatcherConfig::class.java.name)
|
||||||
|
@@ -21,7 +21,6 @@ import lanchon.multidexlib2.MultiDexIO
|
|||||||
import lanchon.multidexlib2.RawDexIO
|
import lanchon.multidexlib2.RawDexIO
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
import java.io.FileFilter
|
import java.io.FileFilter
|
||||||
import java.io.InputStream
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.logging.Logger
|
import java.util.logging.Logger
|
||||||
|
|
||||||
@@ -60,40 +59,41 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
|
|||||||
internal val lookupMaps by lazy { LookupMaps(classes) }
|
internal val lookupMaps by lazy { LookupMaps(classes) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map for lookup by [merge].
|
* Merge the extensions for this set of patches.
|
||||||
*/
|
*/
|
||||||
internal val classesByType = mutableMapOf<String, ClassDef>().apply {
|
internal fun Set<Patch<*>>.mergeExtensions() {
|
||||||
classes.forEach { classDef -> put(classDef.type, classDef) }
|
// Lookup map for fast checking if a class exists by its type.
|
||||||
}
|
val classesByType = mutableMapOf<String, ClassDef>().apply {
|
||||||
|
classes.forEach { classDef -> put(classDef.type, classDef) }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
forEachRecursively { patch ->
|
||||||
* Merge an extension to [classes].
|
if (patch is BytecodePatch && patch.extension != null) {
|
||||||
*
|
|
||||||
* @param extensionInputStream The input stream of the extension to merge.
|
|
||||||
*/
|
|
||||||
internal fun merge(extensionInputStream: InputStream) {
|
|
||||||
val extension = extensionInputStream.readAllBytes()
|
|
||||||
|
|
||||||
RawDexIO.readRawDexFile(extension, 0, null).classes.forEach { classDef ->
|
val extension = patch.extension.readAllBytes()
|
||||||
val existingClass = classesByType[classDef.type] ?: run {
|
|
||||||
logger.fine("Adding class \"$classDef\"")
|
|
||||||
|
|
||||||
classes += classDef
|
RawDexIO.readRawDexFile(extension, 0, null).classes.forEach { classDef ->
|
||||||
classesByType[classDef.type] = classDef
|
val existingClass = classesByType[classDef.type] ?: run {
|
||||||
|
logger.fine("Adding class \"$classDef\"")
|
||||||
|
|
||||||
return@forEach
|
classes += classDef
|
||||||
}
|
classesByType[classDef.type] = classDef
|
||||||
|
|
||||||
logger.fine("Class \"$classDef\" exists already. Adding missing methods and fields.")
|
return@forEach
|
||||||
|
}
|
||||||
|
|
||||||
existingClass.merge(classDef, this@BytecodePatchContext).let { mergedClass ->
|
logger.fine("Class \"$classDef\" exists already. Adding missing methods and fields.")
|
||||||
// If the class was merged, replace the original class with the merged class.
|
|
||||||
if (mergedClass === existingClass) {
|
existingClass.merge(classDef, this@BytecodePatchContext).let { mergedClass ->
|
||||||
return@let
|
// If the class was merged, replace the original class with the merged class.
|
||||||
|
if (mergedClass === existingClass) {
|
||||||
|
return@let
|
||||||
|
}
|
||||||
|
|
||||||
|
classes -= existingClass
|
||||||
|
classes += mergedClass
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
classes -= existingClass
|
|
||||||
classes += mergedClass
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,6 +104,7 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
|
|||||||
* @param type The type of the class.
|
* @param type The type of the class.
|
||||||
* @return A proxy for the first class that matches the type.
|
* @return A proxy for the first class that matches the type.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Use classBy { type in it.type } instead.", ReplaceWith("classBy { type in it.type }"))
|
||||||
fun classByType(type: String) = classBy { type in it.type }
|
fun classByType(type: String) = classBy { type in it.type }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -144,6 +145,9 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
|
|||||||
override fun get(): Set<PatcherResult.PatchedDexFile> {
|
override fun get(): Set<PatcherResult.PatchedDexFile> {
|
||||||
logger.info("Compiling patched dex files")
|
logger.info("Compiling patched dex files")
|
||||||
|
|
||||||
|
// Free up memory before compiling the dex files.
|
||||||
|
lookupMaps.close()
|
||||||
|
|
||||||
val patchedDexFileResults =
|
val patchedDexFileResults =
|
||||||
config.patchedFiles.resolve("dex").also {
|
config.patchedFiles.resolve("dex").also {
|
||||||
it.deleteRecursively() // Make sure the directory is empty.
|
it.deleteRecursively() // Make sure the directory is empty.
|
||||||
@@ -177,21 +181,6 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
|
|||||||
* @param classes The list of classes to create the lookup maps from.
|
* @param classes The list of classes to create the lookup maps from.
|
||||||
*/
|
*/
|
||||||
internal class LookupMaps internal constructor(classes: List<ClassDef>) : Closeable {
|
internal class LookupMaps internal constructor(classes: List<ClassDef>) : Closeable {
|
||||||
/**
|
|
||||||
* Classes associated by their type.
|
|
||||||
*/
|
|
||||||
internal val classesByType = classes.associateBy { it.type }.toMutableMap()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All methods and the class they are a member of.
|
|
||||||
*/
|
|
||||||
internal val allMethods = MethodClassPairs()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Methods associated by its access flags, return type and parameter.
|
|
||||||
*/
|
|
||||||
internal val methodsBySignature = MethodClassPairsLookupMap()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Methods associated by strings referenced in it.
|
* Methods associated by strings referenced in it.
|
||||||
*/
|
*/
|
||||||
@@ -202,22 +191,6 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
|
|||||||
classDef.methods.forEach { method ->
|
classDef.methods.forEach { method ->
|
||||||
val methodClassPair: MethodClassPair = method to classDef
|
val methodClassPair: MethodClassPair = method to classDef
|
||||||
|
|
||||||
// For fingerprints with no access or return type specified.
|
|
||||||
allMethods += methodClassPair
|
|
||||||
|
|
||||||
val accessFlagsReturnKey = method.accessFlags.toString() + method.returnType.first()
|
|
||||||
|
|
||||||
// Add <access><returnType> as the key.
|
|
||||||
methodsBySignature[accessFlagsReturnKey] = methodClassPair
|
|
||||||
|
|
||||||
// Add <access><returnType>[parameters] as the key.
|
|
||||||
methodsBySignature[
|
|
||||||
buildString {
|
|
||||||
append(accessFlagsReturnKey)
|
|
||||||
appendParameters(method.parameterTypes)
|
|
||||||
},
|
|
||||||
] = methodClassPair
|
|
||||||
|
|
||||||
// Add strings contained in the method as the key.
|
// Add strings contained in the method as the key.
|
||||||
method.instructionsOrNull?.forEach instructions@{ instruction ->
|
method.instructionsOrNull?.forEach instructions@{ instruction ->
|
||||||
if (instruction.opcode != Opcode.CONST_STRING && instruction.opcode != Opcode.CONST_STRING_JUMBO) {
|
if (instruction.opcode != Opcode.CONST_STRING && instruction.opcode != Opcode.CONST_STRING_JUMBO) {
|
||||||
@@ -258,15 +231,12 @@ class BytecodePatchContext internal constructor(private val config: PatcherConfi
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
allMethods.clear()
|
|
||||||
methodsBySignature.clear()
|
|
||||||
methodsByStrings.clear()
|
methodsByStrings.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
lookupMaps.close()
|
lookupMaps.close()
|
||||||
classesByType.clear()
|
|
||||||
classes.clear()
|
classes.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,9 @@ import lanchon.multidexlib2.BasicDexFileNamer
|
|||||||
import lanchon.multidexlib2.MultiDexIO
|
import lanchon.multidexlib2.MultiDexIO
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
import java.lang.reflect.Member
|
||||||
|
import java.lang.reflect.Method
|
||||||
|
import java.lang.reflect.Modifier
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import java.util.jar.JarFile
|
import java.util.jar.JarFile
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
@@ -48,6 +51,9 @@ sealed class Patch<C : PatchContext<*>>(
|
|||||||
// if a patch has a finalizing block in order to not emit it twice.
|
// if a patch has a finalizing block in order to not emit it twice.
|
||||||
internal var finalizeBlock: (Patch<C>.(C) -> Unit)?,
|
internal var finalizeBlock: (Patch<C>.(C) -> Unit)?,
|
||||||
) {
|
) {
|
||||||
|
/**
|
||||||
|
* The options of the patch.
|
||||||
|
*/
|
||||||
val options = Options(options)
|
val options = Options(options)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -393,7 +399,7 @@ class BytecodePatchBuilder internal constructor(
|
|||||||
*/
|
*/
|
||||||
operator fun Fingerprint.invoke() = InvokedFingerprint(also { fingerprints.add(it) })
|
operator fun Fingerprint.invoke() = InvokedFingerprint(also { fingerprints.add(it) })
|
||||||
|
|
||||||
class InvokedFingerprint(private val fingerprint: Fingerprint) {
|
class InvokedFingerprint internal constructor(private val fingerprint: Fingerprint) {
|
||||||
// The reason getValue isn't extending the Fingerprint class is
|
// The reason getValue isn't extending the Fingerprint class is
|
||||||
// because delegating makes only sense if the fingerprint was previously added to the patch by invoking it.
|
// because delegating makes only sense if the fingerprint was previously added to the patch by invoking it.
|
||||||
// It may be likely to forget invoking it. By wrapping the fingerprint into this class,
|
// It may be likely to forget invoking it. By wrapping the fingerprint into this class,
|
||||||
@@ -633,7 +639,7 @@ sealed class PatchLoader private constructor(
|
|||||||
*/
|
*/
|
||||||
private val Class<*>.patchFields
|
private val Class<*>.patchFields
|
||||||
get() = fields.filter { field ->
|
get() = fields.filter { field ->
|
||||||
field.type.isPatch && field.canAccess(null)
|
field.type.isPatch && field.canAccess()
|
||||||
}.map { field ->
|
}.map { field ->
|
||||||
field.get(null) as Patch<*>
|
field.get(null) as Patch<*>
|
||||||
}
|
}
|
||||||
@@ -643,7 +649,7 @@ sealed class PatchLoader private constructor(
|
|||||||
*/
|
*/
|
||||||
private val Class<*>.patchMethods
|
private val Class<*>.patchMethods
|
||||||
get() = methods.filter { method ->
|
get() = methods.filter { method ->
|
||||||
method.returnType.isPatch && method.parameterCount == 0 && method.canAccess(null)
|
method.returnType.isPatch && method.parameterCount == 0 && method.canAccess()
|
||||||
}.map { method ->
|
}.map { method ->
|
||||||
method.invoke(null) as Patch<*>
|
method.invoke(null) as Patch<*>
|
||||||
}
|
}
|
||||||
@@ -667,6 +673,12 @@ sealed class PatchLoader private constructor(
|
|||||||
it.name != null
|
it.name != null
|
||||||
}.toSet()
|
}.toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Member.canAccess(): Boolean {
|
||||||
|
if (this is Method && parameterCount != 0) return false
|
||||||
|
|
||||||
|
return Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -179,7 +179,9 @@ internal object ClassMerger {
|
|||||||
callback: MutableClass.() -> Unit,
|
callback: MutableClass.() -> Unit,
|
||||||
) {
|
) {
|
||||||
callback(targetClass)
|
callback(targetClass)
|
||||||
this.classByType(targetClass.superclass ?: return)?.mutableClass?.let {
|
|
||||||
|
targetClass.superclass ?: return
|
||||||
|
this.classBy { targetClass.superclass == it.type }?.mutableClass?.let {
|
||||||
traverseClassHierarchy(it, callback)
|
traverseClassHierarchy(it, callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,9 @@ import app.revanced.patcher.util.ProxyClassList
|
|||||||
import com.android.tools.smali.dexlib2.immutable.ImmutableClassDef
|
import com.android.tools.smali.dexlib2.immutable.ImmutableClassDef
|
||||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
|
import io.mockk.just
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
|
import io.mockk.runs
|
||||||
import kotlinx.coroutines.flow.toList
|
import kotlinx.coroutines.flow.toList
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
@@ -193,6 +195,7 @@ internal object PatcherTest {
|
|||||||
private operator fun Set<Patch<*>>.invoke(): List<PatchResult> {
|
private operator fun Set<Patch<*>>.invoke(): List<PatchResult> {
|
||||||
every { patcher.context.executablePatches } returns toMutableSet()
|
every { patcher.context.executablePatches } returns toMutableSet()
|
||||||
every { patcher.context.bytecodeContext.lookupMaps } returns LookupMaps(patcher.context.bytecodeContext.classes)
|
every { patcher.context.bytecodeContext.lookupMaps } returns LookupMaps(patcher.context.bytecodeContext.classes)
|
||||||
|
every { with(patcher.context.bytecodeContext) { any<Set<Patch<*>>>().mergeExtensions() } } just runs
|
||||||
|
|
||||||
return runBlocking { patcher().toList() }
|
return runBlocking { patcher().toList() }
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,11 @@ import kotlin.reflect.typeOf
|
|||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
internal object OptionsTest {
|
internal object OptionsTest {
|
||||||
|
private val externalOption = stringOption("external", "default")
|
||||||
|
|
||||||
private val optionsTestPatch = bytecodePatch {
|
private val optionsTestPatch = bytecodePatch {
|
||||||
|
externalOption()
|
||||||
|
|
||||||
booleanOption("bool", true)
|
booleanOption("bool", true)
|
||||||
|
|
||||||
stringOption("required", "default", required = true)
|
stringOption("required", "default", required = true)
|
||||||
@@ -124,5 +128,17 @@ internal object OptionsTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `external option should be accessible`() {
|
||||||
|
assertDoesNotThrow {
|
||||||
|
externalOption.value = "test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should allow getting the external option from the patch`() {
|
||||||
|
assertEquals(optionsTestPatch.options["external"].value, externalOption.value)
|
||||||
|
}
|
||||||
|
|
||||||
private fun options(block: Options.() -> Unit) = optionsTestPatch.options.let(block)
|
private fun options(block: Options.() -> Unit) = optionsTestPatch.options.let(block)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user