You've already forked revanced-patcher
mirror of
https://github.com/revanced/revanced-patcher
synced 2025-09-06 16:38:50 +02:00
Compare commits
224 Commits
v11.0.4-de
...
v19.2.0-de
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d03591b735 | ||
![]() |
4a9184597b | ||
![]() |
0a482f8c9a | ||
![]() |
e7dacfba8c | ||
![]() |
2d7fffd4ec | ||
![]() |
f8baabbcec | ||
![]() |
716825f232 | ||
![]() |
58bd46750b | ||
![]() |
288240f163 | ||
![]() |
ff02452cb8 | ||
![]() |
462fbe2cad | ||
![]() |
7aeae93f3d | ||
![]() |
f1de9b39ef | ||
![]() |
db5b0ed7be | ||
![]() |
9f28a01c03 | ||
![]() |
80407b6102 | ||
![]() |
287841d806 | ||
![]() |
10c3be1195 | ||
![]() |
0c0e22013b | ||
![]() |
f35c8d4446 | ||
![]() |
17418d4b9c | ||
![]() |
ec1fbdf2ae | ||
![]() |
56e5a46fd5 | ||
![]() |
32e86d44a3 | ||
![]() |
7100606dfc | ||
![]() |
d7eb111460 | ||
![]() |
27ea46653e | ||
![]() |
12c43072cb | ||
![]() |
671aa6d507 | ||
![]() |
b697bbad2b | ||
![]() |
f05a404e48 | ||
![]() |
a46e948b5a | ||
![]() |
dc09ea639f | ||
![]() |
49ed096e85 | ||
![]() |
167bd83f4e | ||
![]() |
aed1eac315 | ||
![]() |
54a2f8f16f | ||
![]() |
2ca543ffb9 | ||
![]() |
58e7f815a5 | ||
![]() |
15b38fc841 | ||
![]() |
e2ca50729d | ||
![]() |
6192089b71 | ||
![]() |
a4212f6bf9 | ||
![]() |
124a2e9d3e | ||
![]() |
f77624b3b9 | ||
![]() |
a76ac04214 | ||
![]() |
0447fa9c28 | ||
![]() |
54ac1394a9 | ||
![]() |
0b04c73ac5 | ||
![]() |
079de45238 | ||
![]() |
56ce9ec2f9 | ||
![]() |
1b52e4b0f9 | ||
![]() |
098c2c1efa | ||
![]() |
64343e5a7c | ||
![]() |
0caf6caeb9 | ||
![]() |
55f6c2a9fc | ||
![]() |
c6095bc38a | ||
![]() |
09cd6aa568 | ||
![]() |
ebbaafb78e | ||
![]() |
e6de90d300 | ||
![]() |
c7922e90d0 | ||
![]() |
c1f4c0445a | ||
![]() |
caa634fac6 | ||
![]() |
f28bfe0dbd | ||
![]() |
155e787ff4 | ||
![]() |
c38f0ef42a | ||
![]() |
4456031459 | ||
![]() |
5fb59a227f | ||
![]() |
d9fb241d57 | ||
![]() |
642c4ea97e | ||
![]() |
8c8a251626 | ||
![]() |
5953d6cfb5 | ||
![]() |
a1962fe600 | ||
![]() |
77dbee3d6a | ||
![]() |
cb5e39d73e | ||
![]() |
38ef2f470a | ||
![]() |
129d84e108 | ||
![]() |
affeba76b8 | ||
![]() |
6059d3ca26 | ||
![]() |
444dee5a16 | ||
![]() |
d314466ce2 | ||
![]() |
fdaf9c21c8 | ||
![]() |
06c2b76f11 | ||
![]() |
3896b30738 | ||
![]() |
2c4b88e1a0 | ||
![]() |
dfc7e1596b | ||
![]() |
f590436399 | ||
![]() |
cbfb9ba02f | ||
![]() |
b4cfe80ad5 | ||
![]() |
b37906fa35 | ||
![]() |
356f1f1553 | ||
![]() |
e882af74ee | ||
![]() |
46875fb28e | ||
![]() |
417c3e4234 | ||
![]() |
6d2c28807b | ||
![]() |
4d6e08a650 | ||
![]() |
5cebc1fd30 | ||
![]() |
ac61731dc6 | ||
![]() |
9e4ffabd5c | ||
![]() |
3f410bd39f | ||
![]() |
d51bc32e37 | ||
![]() |
b7f6aa94cc | ||
![]() |
ff965e6953 | ||
![]() |
468d5d7421 | ||
![]() |
fc95b28c49 | ||
![]() |
69184187d9 | ||
![]() |
a802d0df46 | ||
![]() |
8de30633ae | ||
![]() |
a1fbb7990f | ||
![]() |
aa71146b1b | ||
![]() |
9fdb8f087f | ||
![]() |
670f0153de | ||
![]() |
1d7aeca696 | ||
![]() |
4e7811ea07 | ||
![]() |
e11283744a | ||
![]() |
91cdfd53ef | ||
![]() |
bc7d6b9941 | ||
![]() |
6b1e0a1656 | ||
![]() |
72c9eb2129 | ||
![]() |
4bc4b0dc01 | ||
![]() |
637d48746f | ||
![]() |
9a109c129b | ||
![]() |
d49e4ee5ea | ||
![]() |
30f0ea29a3 | ||
![]() |
49930f6565 | ||
![]() |
909d89fa8d | ||
![]() |
81d1d7f544 | ||
![]() |
67b7dff67a | ||
![]() |
4b76d19596 | ||
![]() |
080fbe9feb | ||
![]() |
d3721229bf | ||
![]() |
86c1c9c772 | ||
![]() |
c299817193 | ||
![]() |
fcc1de45ed | ||
![]() |
a29931f2ec | ||
![]() |
3fc6a139ee | ||
![]() |
4dd04975d9 | ||
![]() |
3b4db3ddb7 | ||
![]() |
c4a7117ee8 | ||
![]() |
b4e900fde8 | ||
![]() |
9818d730e4 | ||
![]() |
11a3378659 | ||
![]() |
1bb05f22d3 | ||
![]() |
26b70554c4 | ||
![]() |
93b29d2e83 | ||
![]() |
072986374a | ||
![]() |
2c590d212a | ||
![]() |
6cc863efb3 | ||
![]() |
b832812767 | ||
![]() |
c44558cacd | ||
![]() |
6d83a720cd | ||
![]() |
8d0dd9c448 | ||
![]() |
64020eec49 | ||
![]() |
4dedfb85cb | ||
![]() |
55d694579a | ||
![]() |
86db64edff | ||
![]() |
983563efb6 | ||
![]() |
37abb2db99 | ||
![]() |
5ba0b47e60 | ||
![]() |
e8f2087a6f | ||
![]() |
6ce99f5cdf | ||
![]() |
13c0c9cdd3 | ||
![]() |
58ffdb60d7 | ||
![]() |
ba56a6a2ee | ||
![]() |
ccccf5b1d2 | ||
![]() |
b507ac0a54 | ||
![]() |
e985676c2d | ||
![]() |
f7f4ba6c55 | ||
![]() |
4292f43814 | ||
![]() |
30bd4fd9fe | ||
![]() |
76de39369d | ||
![]() |
88a703ce36 | ||
![]() |
5938f6b7ea | ||
![]() |
5c0c0d6c37 | ||
![]() |
0f15077225 | ||
![]() |
273dd8d388 | ||
![]() |
1795f376ef | ||
![]() |
e7360a7692 | ||
![]() |
e1fc86934f | ||
![]() |
6b8977f178 | ||
![]() |
12c6c73de0 | ||
![]() |
db62a1607b | ||
![]() |
58bb879ef5 | ||
![]() |
254912438a | ||
![]() |
0e48918bcc | ||
![]() |
783ccf8529 | ||
![]() |
8fb2f2dc1d | ||
![]() |
2a8cc283c7 | ||
![]() |
433fe3af9f | ||
![]() |
c2d89c622e | ||
![]() |
02d6ff15fe | ||
![]() |
f2cb7ee7df | ||
![]() |
a2ac44dcc1 | ||
![]() |
3cf9d74efa | ||
![]() |
d5f89a903f | ||
![]() |
496c2242bc | ||
![]() |
98fbff87df | ||
![]() |
ddb51a1c45 | ||
![]() |
8df1155215 | ||
![]() |
53f2a61409 | ||
![]() |
746544f9d5 | ||
![]() |
c65c3df11c | ||
![]() |
b29b8f12b3 | ||
![]() |
d6945677c4 | ||
![]() |
aedf4aea08 | ||
![]() |
dc28d414dc | ||
![]() |
9755bab298 | ||
![]() |
fae4029cfc | ||
![]() |
1790f0d706 | ||
![]() |
0ba2c51676 | ||
![]() |
03cd97b49c | ||
![]() |
16a162c1dd | ||
![]() |
c9bbcf2bf2 | ||
![]() |
86e1bf6078 | ||
![]() |
1bca84ef0b | ||
![]() |
e0f8e1b71a | ||
![]() |
416d69142f | ||
![]() |
426807aeaa | ||
![]() |
90cb075a97 | ||
![]() |
ac2ca8fbd3 | ||
![]() |
69e4a49065 | ||
![]() |
a4a030f2b2 | ||
![]() |
dcc4ecd237 | ||
![]() |
57f3036a96 |
9
.gitattributes
vendored
Normal file
9
.gitattributes
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
#
|
||||
# https://help.github.com/articles/dealing-with-line-endings/
|
||||
#
|
||||
# Linux start script should use lf
|
||||
/gradlew text eol=lf
|
||||
|
||||
# These are Windows script files and should use crlf
|
||||
*.bat text eol=crlf
|
||||
|
72
.github/ISSUE_TEMPLATE/bug-issue.yml
vendored
72
.github/ISSUE_TEMPLATE/bug-issue.yml
vendored
@@ -1,72 +0,0 @@
|
||||
name: 🐞 Bug report
|
||||
description: Report a very clearly broken issue.
|
||||
title: 'bug: <title>'
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
# ReVanced bug report
|
||||
|
||||
Important to note that your issue may have already been reported before. Please check for existing issues [here](https://github.com/revanced/revanced-patcher/labels/bug).
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Type
|
||||
options:
|
||||
- Crash
|
||||
- Cosmetic
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Bug description
|
||||
description: How did you find the bug? Any additional details that might help?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Add the steps to reproduce this bug including your environment.
|
||||
placeholder: Step 1. Download some files. Step 2. ...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Screenshots or videos
|
||||
description: Add screenshots or videos that show the bug here.
|
||||
placeholder: Drag and drop the screenshots/videos into this box.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Solution
|
||||
description: If applicable, add a possible solution.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add additional context here.
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
id: acknowledgements
|
||||
attributes:
|
||||
label: Acknowledgements
|
||||
description: Your issue will be closed if you haven't done these steps.
|
||||
options:
|
||||
- label: I have searched the existing issues and this is a new and no duplicate or related to another open issue.
|
||||
required: true
|
||||
- label: I have written a short but informative title.
|
||||
required: true
|
||||
- label: I filled out all of the requested information in this issue properly.
|
||||
required: true
|
108
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
108
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
name: 🐞 Bug report
|
||||
description: Report a bug or an issue.
|
||||
title: 'bug: '
|
||||
labels: ['Bug report']
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
<p align="center">
|
||||
<picture>
|
||||
<source
|
||||
width="256px"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
srcset="https://raw.githubusercontent.com/revanced/revanced-patcher/main/assets/revanced-headline/revanced-headline-vertical-dark.svg"
|
||||
>
|
||||
<img
|
||||
width="256px"
|
||||
src="https://raw.githubusercontent.com/revanced/revanced-patcher/main/assets/revanced-headline/revanced-headline-vertical-light.svg"
|
||||
>
|
||||
</picture>
|
||||
<br>
|
||||
<a href="https://revanced.app/">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/revanced/revanced-patcher/main/assets/revanced-logo/revanced-logo.svg" />
|
||||
<img height="24px" src="https://raw.githubusercontent.com/revanced/revanced-patcher/main/assets/revanced-logo/revanced-logo.svg" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://github.com/ReVanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://i.ibb.co/dMMmCrW/Git-Hub-Mark.png" />
|
||||
<img height="24px" src="https://i.ibb.co/9wV3HGF/Git-Hub-Mark-Light.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="http://revanced.app/discord">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032563-d4e084b7-244e-4358-af50-26bde6dd4996.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032563-d4e084b7-244e-4358-af50-26bde6dd4996.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://reddit.com/r/revancedapp">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032351-9d9d5619-8ef7-470a-9eec-2744ece54553.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032351-9d9d5619-8ef7-470a-9eec-2744ece54553.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://t.me/app_revanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032213-faf25ab8-0bc3-4a94-a730-b524c96df124.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032213-faf25ab8-0bc3-4a94-a730-b524c96df124.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://x.com/revancedapp">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/93124920/270180600-7c1b38bf-889b-4d68-bd5e-b9d86f91421a.png">
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/93124920/270108715-d80743fa-b330-4809-b1e6-79fbdc60d09c.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://www.youtube.com/@ReVanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032714-c51c7492-0666-44ac-99c2-f003a695ab50.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032714-c51c7492-0666-44ac-99c2-f003a695ab50.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<br>
|
||||
<br>
|
||||
Continuing the legacy of Vanced
|
||||
</p>
|
||||
|
||||
# ReVanced Patcher bug report
|
||||
|
||||
Before creating a new bug report, please keep the following in mind:
|
||||
|
||||
- **Do not submit a duplicate bug report**: You can review existing bug reports [here](https://github.com/ReVanced/revanced-patcher/labels/Bug%20report).
|
||||
- **Do not use the issue page for support**: If you need help or have questions, check out other platforms on [revanced.app](https://revanced.app).
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Bug description
|
||||
description: |
|
||||
- Describe your bug in detail
|
||||
- Add steps to reproduce the bug if possible (Step 1. ... Step 2. ...)
|
||||
- Add images and videos if possible
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Error logs
|
||||
description: Exceptions can be captured by running `logcat | grep AndroidRuntime` in a shell.
|
||||
render: shell
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Solution
|
||||
description: If applicable, add a possible solution to the bug.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add additional context here.
|
||||
- type: checkboxes
|
||||
id: acknowledgements
|
||||
attributes:
|
||||
label: Acknowledgements
|
||||
description: Your bug report will be closed if you don't follow the checklist below.
|
||||
options:
|
||||
- label: This issue is not a duplicate of an existing bug report.
|
||||
required: true
|
||||
- label: I have chosen an appropriate title.
|
||||
required: true
|
||||
- label: All requested information has been provided properly.
|
||||
required: true
|
58
.github/ISSUE_TEMPLATE/feature-issue.yml
vendored
58
.github/ISSUE_TEMPLATE/feature-issue.yml
vendored
@@ -1,58 +0,0 @@
|
||||
name: ⭐ Feature request
|
||||
description: Create a detailed feature request.
|
||||
title: 'feat: <title>'
|
||||
labels: [feature-request]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
# ReVanced feature request
|
||||
|
||||
Do not submit requests for patches here. Please submit them [here](https://github.com/orgs/revanced/discussions/categories/patches) instead.
|
||||
Important to note that your feature request may have already been made before. Please check for existing feature requests [here](https://github.com/revanced/revanced-patcher/labels/feature-request).
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Type
|
||||
options:
|
||||
- Functionality
|
||||
- Cosmetic
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Issue
|
||||
description: What is the current problem. Why does it require a feature request?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Feature
|
||||
description: Describe your feature in detail. How does it solve the issue?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Motivation
|
||||
description: Why should your feature should be considered?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add additional context here.
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
id: acknowledgements
|
||||
attributes:
|
||||
label: Acknowledgements
|
||||
description: Your issue will be closed if you haven't done these steps.
|
||||
options:
|
||||
- label: I have searched the existing issues and this is a new and no duplicate or related to another open issue.
|
||||
required: true
|
||||
- label: I have written a short but informative title.
|
||||
required: true
|
||||
- label: I filled out all of the requested information in this issue properly.
|
||||
required: true
|
106
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
106
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
name: ⭐ Feature request
|
||||
description: Create a detailed request for a new feature.
|
||||
title: 'feat: '
|
||||
labels: ['Feature request']
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
<p align="center">
|
||||
<picture>
|
||||
<source
|
||||
width="256px"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
srcset="https://raw.githubusercontent.com/revanced/revanced-patcher/main/assets/revanced-headline/revanced-headline-vertical-dark.svg"
|
||||
>
|
||||
<img
|
||||
width="256px"
|
||||
src="https://raw.githubusercontent.com/revanced/revanced-patcher/main/assets/revanced-headline/revanced-headline-vertical-light.svg"
|
||||
>
|
||||
</picture>
|
||||
<br>
|
||||
<a href="https://revanced.app/">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/revanced/revanced-patcher/main/assets/revanced-logo/revanced-logo.svg" />
|
||||
<img height="24px" src="https://raw.githubusercontent.com/revanced/revanced-patcher/main/assets/revanced-logo/revanced-logo.svg" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://github.com/ReVanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://i.ibb.co/dMMmCrW/Git-Hub-Mark.png" />
|
||||
<img height="24px" src="https://i.ibb.co/9wV3HGF/Git-Hub-Mark-Light.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="http://revanced.app/discord">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032563-d4e084b7-244e-4358-af50-26bde6dd4996.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032563-d4e084b7-244e-4358-af50-26bde6dd4996.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://reddit.com/r/revancedapp">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032351-9d9d5619-8ef7-470a-9eec-2744ece54553.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032351-9d9d5619-8ef7-470a-9eec-2744ece54553.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://t.me/app_revanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032213-faf25ab8-0bc3-4a94-a730-b524c96df124.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032213-faf25ab8-0bc3-4a94-a730-b524c96df124.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://x.com/revancedapp">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/93124920/270180600-7c1b38bf-889b-4d68-bd5e-b9d86f91421a.png">
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/93124920/270108715-d80743fa-b330-4809-b1e6-79fbdc60d09c.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://www.youtube.com/@ReVanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032714-c51c7492-0666-44ac-99c2-f003a695ab50.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032714-c51c7492-0666-44ac-99c2-f003a695ab50.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<br>
|
||||
<br>
|
||||
Continuing the legacy of Vanced
|
||||
</p>
|
||||
|
||||
# ReVanced Patcher feature request
|
||||
|
||||
Before creating a new feature request, please keep the following in mind:
|
||||
|
||||
- **Do not submit a duplicate feature request**: You can review existing feature requests [here](https://github.com/ReVanced/revanced-patcher/labels/Feature%20request).
|
||||
- **Do not use the issue page for support**: If you need help or have questions, check out other platforms on [revanced.app](https://revanced.app).
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Feature description
|
||||
description: |
|
||||
- Describe your feature in detail
|
||||
- Add images, videos, links, examples, references, etc. if possible
|
||||
- Add the target application name in case you request a new patch
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Motivation
|
||||
description: |
|
||||
A strong motivation is necessary for a feature request to be considered.
|
||||
|
||||
- Why should this feature be implemented?
|
||||
- What is the explicit use case?
|
||||
- What are the benefits?
|
||||
- What makes this feature important?
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: acknowledgements
|
||||
attributes:
|
||||
label: Acknowledgements
|
||||
description: Your feature request will be closed if you don't follow the checklist below.
|
||||
options:
|
||||
- label: This issue is not a duplicate of an existing feature request.
|
||||
required: true
|
||||
- label: I have chosen an appropriate title.
|
||||
required: true
|
||||
- label: All requested information has been provided properly.
|
||||
required: true
|
2
.github/config.yml
vendored
2
.github/config.yml
vendored
@@ -1,2 +1,2 @@
|
||||
firstPRMergeComment: >
|
||||
Thank you for contributing to ReVanced. Join us on [Discord](https://revanced.app/discord) if you want to receive a contributor role.
|
||||
Thank you for contributing to ReVanced. Join us on [Discord](https://revanced.app/discord) to receive a role for your contribution.
|
||||
|
7
.github/workflows/pull_request.yml
vendored
7
.github/workflows/pull_request.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: PR to main
|
||||
name: Open a PR to main
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -7,7 +7,7 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
MESSAGE: merge branch `${{ github.head_ref || github.ref_name }}` to `main`
|
||||
MESSAGE: Merge branch `${{ github.head_ref || github.ref_name }}` to `main`
|
||||
|
||||
jobs:
|
||||
pull-request:
|
||||
@@ -15,7 +15,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Open pull request
|
||||
uses: repo-sync/pull-request@v2
|
||||
with:
|
||||
|
19
.github/workflows/release.yml
vendored
19
.github/workflows/release.yml
vendored
@@ -17,28 +17,31 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
# Make sure the release step uses its own credentials:
|
||||
# https://github.com/cycjimmy/semantic-release-action#private-packages
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
- name: Cache
|
||||
|
||||
- name: Cache Node modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
${{ runner.home }}/.gradle/caches
|
||||
${{ runner.home }}/.gradle/wrapper
|
||||
.gradle
|
||||
build
|
||||
node_modules
|
||||
key: ${{ runner.os }}-gradle-npm-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', 'package-lock.json') }}
|
||||
key: npm-${{ hashFiles('package-lock.json') }}
|
||||
|
||||
- name: Cache Gradle
|
||||
uses: burrunan/gradle-cache-action@v1
|
||||
|
||||
- name: Build with Gradle
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: ./gradlew clean --no-daemon
|
||||
run: ./gradlew build clean --no-daemon
|
||||
|
||||
- name: Setup semantic-release
|
||||
run: npm install
|
||||
|
||||
- name: Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }}
|
||||
|
@@ -7,7 +7,13 @@
|
||||
}
|
||||
],
|
||||
"plugins": [
|
||||
"@semantic-release/commit-analyzer",
|
||||
[
|
||||
"@semantic-release/commit-analyzer", {
|
||||
"releaseRules": [
|
||||
{ "type": "build", "scope": "Needs bump", "release": "patch" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"@semantic-release/release-notes-generator",
|
||||
"@semantic-release/changelog",
|
||||
"gradle-semantic-release-plugin",
|
||||
|
709
CHANGELOG.md
709
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
784
api/revanced-patcher.api
Normal file
784
api/revanced-patcher.api
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 11 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 11 KiB |
1
assets/revanced-logo/revanced-logo.svg
Normal file
1
assets/revanced-logo/revanced-logo.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 2.8 KiB |
@@ -1,47 +1,48 @@
|
||||
plugins {
|
||||
kotlin("jvm") version "1.8.10"
|
||||
kotlin("jvm") version "1.9.10"
|
||||
alias(libs.plugins.binary.compatibility.validator)
|
||||
`maven-publish`
|
||||
signing
|
||||
java
|
||||
}
|
||||
|
||||
group = "app.revanced"
|
||||
|
||||
val githubUsername: String = project.findProperty("gpr.user") as? String ?: System.getenv("GITHUB_ACTOR")
|
||||
val githubPassword: String = project.findProperty("gpr.key") as? String ?: System.getenv("GITHUB_TOKEN")
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
url = uri("https://maven.pkg.github.com/revanced/multidexlib2")
|
||||
credentials {
|
||||
username = githubUsername
|
||||
password = githubPassword
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("xpp3:xpp3:1.1.4c")
|
||||
implementation("app.revanced:smali:2.5.3-a3836654")
|
||||
implementation("app.revanced:multidexlib2:2.5.3-a3836654")
|
||||
implementation("app.revanced:apktool-lib:2.7.0")
|
||||
|
||||
implementation("org.jetbrains.kotlin:kotlin-reflect:1.8.20-RC")
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-test:1.8.20-RC")
|
||||
}
|
||||
|
||||
tasks {
|
||||
processResources {
|
||||
expand("projectVersion" to project.version)
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
events("PASSED", "SKIPPED", "FAILED")
|
||||
}
|
||||
}
|
||||
processResources {
|
||||
expand("projectVersion" to project.version)
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
maven { url = uri("https://jitpack.io") }
|
||||
google()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.kotlinx.coroutines.core)
|
||||
implementation(libs.xpp3)
|
||||
implementation(libs.smali)
|
||||
implementation(libs.multidexlib2)
|
||||
implementation(libs.apktool.lib)
|
||||
implementation(libs.kotlin.reflect)
|
||||
|
||||
compileOnly(libs.android)
|
||||
|
||||
testImplementation(libs.kotlin.test)
|
||||
}
|
||||
|
||||
java {
|
||||
withJavadocJar()
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
@@ -50,22 +51,36 @@ kotlin {
|
||||
}
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
if (System.getenv("GITHUB_ACTOR") != null)
|
||||
maven {
|
||||
name = "GitHubPackages"
|
||||
url = uri("https://maven.pkg.github.com/revanced/revanced-patcher")
|
||||
credentials {
|
||||
username = System.getenv("GITHUB_ACTOR")
|
||||
password = System.getenv("GITHUB_TOKEN")
|
||||
publications {
|
||||
create<MavenPublication>("revanced-patcher-publication") {
|
||||
from(components["java"])
|
||||
|
||||
version = project.version.toString()
|
||||
|
||||
pom {
|
||||
name = "ReVanced Patcher"
|
||||
description = "Patcher used by ReVanced."
|
||||
url = "https://revanced.app"
|
||||
|
||||
licenses {
|
||||
license {
|
||||
name = "GNU General Public License v3.0"
|
||||
url = "https://www.gnu.org/licenses/gpl-3.0.en.html"
|
||||
}
|
||||
}
|
||||
developers {
|
||||
developer {
|
||||
id = "ReVanced"
|
||||
name = "ReVanced"
|
||||
email = "contact@revanced.app"
|
||||
}
|
||||
}
|
||||
scm {
|
||||
connection = "scm:git:git://github.com/revanced/revanced-patcher.git"
|
||||
developerConnection = "scm:git:git@github.com:revanced/revanced-patcher.git"
|
||||
url = "https://github.com/revanced/revanced-patcher"
|
||||
}
|
||||
}
|
||||
else
|
||||
mavenLocal()
|
||||
}
|
||||
publications {
|
||||
register<MavenPublication>("gpr") {
|
||||
from(components["java"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,2 +1,4 @@
|
||||
org.gradle.parallel = true
|
||||
org.gradle.caching = true
|
||||
kotlin.code.style = official
|
||||
version = 11.0.4-dev.1
|
||||
version = 19.2.0-dev.1
|
||||
|
23
gradle/libs.versions.toml
Normal file
23
gradle/libs.versions.toml
Normal file
@@ -0,0 +1,23 @@
|
||||
[versions]
|
||||
android = "4.1.1.4"
|
||||
kotlin-reflect = "1.9.10"
|
||||
apktool-lib = "2.9.1"
|
||||
kotlin-test = "1.9.20"
|
||||
kotlinx-coroutines-core = "1.7.3"
|
||||
multidexlib2 = "3.0.3.r3"
|
||||
smali = "3.0.3"
|
||||
xpp3 = "1.1.4c"
|
||||
binary-compatibility-validator = "0.13.2"
|
||||
|
||||
[libraries]
|
||||
android = { module = "com.google.android:android", version.ref = "android" }
|
||||
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin-reflect" }
|
||||
apktool-lib = { module = "app.revanced:apktool", version.ref = "apktool-lib" }
|
||||
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin-test" }
|
||||
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines-core" }
|
||||
multidexlib2 = { module = "app.revanced:multidexlib2", version.ref = "multidexlib2" }
|
||||
smali = { module = "com.android.tools.smali:smali", version.ref = "smali" }
|
||||
xpp3 = { module = "xpp3:xpp3", version.ref = "xpp3" }
|
||||
|
||||
[plugins]
|
||||
binary-compatibility-validator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "binary-compatibility-validator" }
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
5
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
|
||||
distributionSha256Sum=3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
zipStorePath=wrapper/dist
|
40
gradlew
vendored
40
gradlew
vendored
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -32,10 +32,10 @@
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
@@ -55,7 +55,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@@ -80,13 +80,10 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# 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"'
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
@@ -133,22 +130,29 @@ location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
@@ -193,6 +197,10 @@ if "$cygwin" || "$msys" ; then
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# 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"'
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
@@ -205,6 +213,12 @@ set -- \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
|
15
gradlew.bat
vendored
15
gradlew.bat
vendored
@@ -14,7 +14,7 @@
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@@ -25,7 +25,8 @@
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
8612
package-lock.json
generated
8612
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"@saithodev/semantic-release-backmerge": "^3.1.0",
|
||||
"@semantic-release/changelog": "^6.0.2",
|
||||
"@saithodev/semantic-release-backmerge": "^3.2.1",
|
||||
"@semantic-release/changelog": "^6.0.3",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"gradle-semantic-release-plugin": "^1.7.6",
|
||||
"semantic-release": "^20.1.0"
|
||||
"gradle-semantic-release-plugin": "^1.8.0",
|
||||
"semantic-release": "^22.0.8"
|
||||
}
|
||||
}
|
||||
|
@@ -1 +1,7 @@
|
||||
rootProject.name = "revanced-patcher"
|
||||
|
||||
buildCache {
|
||||
local {
|
||||
isEnabled = "CI" !in System.getenv()
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,8 @@
|
||||
package app.revanced.patcher
|
||||
|
||||
import java.io.File
|
||||
|
||||
@FunctionalInterface
|
||||
interface IntegrationsConsumer {
|
||||
fun acceptIntegrations(integrations: List<File>)
|
||||
}
|
14
src/main/kotlin/app/revanced/patcher/PackageMetadata.kt
Normal file
14
src/main/kotlin/app/revanced/patcher/PackageMetadata.kt
Normal file
@@ -0,0 +1,14 @@
|
||||
package app.revanced.patcher
|
||||
|
||||
import brut.androlib.apk.ApkInfo
|
||||
|
||||
/**
|
||||
* Metadata about a package.
|
||||
*/
|
||||
class PackageMetadata internal constructor(internal val apkInfo: ApkInfo) {
|
||||
lateinit var packageName: String
|
||||
internal set
|
||||
|
||||
lateinit var packageVersion: String
|
||||
internal set
|
||||
}
|
136
src/main/kotlin/app/revanced/patcher/PatchBundleLoader.kt
Normal file
136
src/main/kotlin/app/revanced/patcher/PatchBundleLoader.kt
Normal file
@@ -0,0 +1,136 @@
|
||||
@file:Suppress("unused")
|
||||
|
||||
package app.revanced.patcher
|
||||
|
||||
import app.revanced.patcher.patch.Patch
|
||||
import dalvik.system.DexClassLoader
|
||||
import lanchon.multidexlib2.BasicDexFileNamer
|
||||
import lanchon.multidexlib2.MultiDexIO
|
||||
import java.io.File
|
||||
import java.net.URLClassLoader
|
||||
import java.util.jar.JarFile
|
||||
import java.util.logging.Logger
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
/**
|
||||
* A set of [Patch]es.
|
||||
*/
|
||||
typealias PatchSet = Set<Patch<*>>
|
||||
|
||||
/**
|
||||
* A [Patch] class.
|
||||
*/
|
||||
typealias PatchClass = KClass<out Patch<*>>
|
||||
|
||||
/**
|
||||
* A loader of [Patch]es from patch bundles.
|
||||
* This will load all [Patch]es from the given patch bundles that have a name.
|
||||
*
|
||||
* @param getBinaryClassNames A function that returns the binary names of all classes in a patch bundle.
|
||||
* @param classLoader The [ClassLoader] to use for loading the classes.
|
||||
* @param patchBundles A set of patches to initialize this instance with.
|
||||
*/
|
||||
sealed class PatchBundleLoader private constructor(
|
||||
classLoader: ClassLoader,
|
||||
patchBundles: Array<out File>,
|
||||
getBinaryClassNames: (patchBundle: File) -> List<String>,
|
||||
// This constructor parameter is unfortunately necessary,
|
||||
// so that a reference to the mutable set is present in the constructor to be able to add patches to it.
|
||||
// because the instance itself is a PatchSet, which is immutable, that is delegated by the parameter.
|
||||
private val patchSet: MutableSet<Patch<*>> = mutableSetOf(),
|
||||
) : PatchSet by patchSet {
|
||||
private val logger = Logger.getLogger(PatchBundleLoader::class.java.name)
|
||||
|
||||
init {
|
||||
patchBundles.flatMap(getBinaryClassNames).asSequence().map {
|
||||
classLoader.loadClass(it)
|
||||
}.filter {
|
||||
Patch::class.java.isAssignableFrom(it)
|
||||
}.mapNotNull { patchClass ->
|
||||
patchClass.getInstance(logger, silent = true)
|
||||
}.filter {
|
||||
it.name != null
|
||||
}.let { patches ->
|
||||
patchSet.addAll(patches)
|
||||
}
|
||||
}
|
||||
|
||||
internal companion object Utils {
|
||||
/**
|
||||
* Instantiates a [Patch]. If the class is a singleton, the INSTANCE field will be used.
|
||||
*
|
||||
* @param logger The [Logger] to use for logging.
|
||||
* @param silent Whether to suppress logging.
|
||||
* @return The instantiated [Patch] or `null` if the [Patch] could not be instantiated.
|
||||
*/
|
||||
internal fun Class<*>.getInstance(
|
||||
logger: Logger,
|
||||
silent: Boolean = false,
|
||||
): Patch<*>? {
|
||||
return try {
|
||||
getField("INSTANCE").get(null)
|
||||
} catch (exception: NoSuchFieldException) {
|
||||
if (!silent) {
|
||||
logger.fine(
|
||||
"Patch class '$name' has no INSTANCE field, therefor not a singleton. " +
|
||||
"Attempting to instantiate it.",
|
||||
)
|
||||
}
|
||||
|
||||
try {
|
||||
getDeclaredConstructor().newInstance()
|
||||
} catch (exception: Exception) {
|
||||
if (!silent) {
|
||||
logger.severe(
|
||||
"Patch class '$name' is not singleton and has no suitable constructor, " +
|
||||
"therefor cannot be instantiated and is ignored.",
|
||||
)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
} as Patch<*>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A [PatchBundleLoader] for JAR files.
|
||||
*
|
||||
* @param patchBundles The path to patch bundles of JAR format.
|
||||
*/
|
||||
class Jar(vararg patchBundles: File) : PatchBundleLoader(
|
||||
URLClassLoader(patchBundles.map { it.toURI().toURL() }.toTypedArray()),
|
||||
patchBundles,
|
||||
{ patchBundle ->
|
||||
JarFile(patchBundle).entries().toList().filter { it.name.endsWith(".class") }
|
||||
.map { it.name.replace('/', '.').replace(".class", "") }
|
||||
},
|
||||
)
|
||||
|
||||
/**
|
||||
* A [PatchBundleLoader] for [Dex] files.
|
||||
*
|
||||
* @param patchBundles The path to patch bundles of DEX format.
|
||||
* @param optimizedDexDirectory The directory to store optimized DEX files in.
|
||||
* This parameter is deprecated and has no effect since API level 26.
|
||||
*/
|
||||
class Dex(vararg patchBundles: File, optimizedDexDirectory: File? = null) : PatchBundleLoader(
|
||||
DexClassLoader(
|
||||
patchBundles.joinToString(File.pathSeparator) { it.absolutePath },
|
||||
optimizedDexDirectory?.absolutePath,
|
||||
null,
|
||||
PatchBundleLoader::class.java.classLoader,
|
||||
),
|
||||
patchBundles,
|
||||
{ patchBundle ->
|
||||
MultiDexIO.readDexFile(true, patchBundle, BasicDexFileNamer(), null, null).classes
|
||||
.map { classDef ->
|
||||
classDef.type.substring(1, classDef.length - 1)
|
||||
}
|
||||
},
|
||||
) {
|
||||
@Deprecated("This constructor is deprecated. Use the constructor with the second parameter instead.")
|
||||
constructor(vararg patchBundles: File) : this(*patchBundles, optimizedDexDirectory = null)
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
package app.revanced.patcher
|
||||
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import java.util.function.Function
|
||||
|
||||
@FunctionalInterface
|
||||
interface PatchExecutorFunction : Function<Boolean, Flow<PatchResult>>
|
File diff suppressed because it is too large
Load Diff
@@ -1,64 +1,41 @@
|
||||
package app.revanced.patcher
|
||||
|
||||
import app.revanced.patcher.data.*
|
||||
import app.revanced.patcher.logging.Logger
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.Patch
|
||||
import app.revanced.patcher.util.ClassMerger.merge
|
||||
import org.jf.dexlib2.iface.ClassDef
|
||||
import java.io.File
|
||||
import brut.androlib.apk.ApkInfo
|
||||
import brut.directory.ExtFile
|
||||
|
||||
data class PatcherContext(
|
||||
val classes: MutableList<ClassDef>,
|
||||
val resourceCacheDirectory: File,
|
||||
) {
|
||||
val packageMetadata = PackageMetadata()
|
||||
internal val patches = mutableListOf<Class<out Patch<Context>>>()
|
||||
internal val integrations = Integrations(this)
|
||||
internal val bytecodeContext = BytecodeContext(classes)
|
||||
internal val resourceContext = ResourceContext(resourceCacheDirectory)
|
||||
/**
|
||||
* A context for ReVanced [Patcher].
|
||||
*
|
||||
* @param options The [PatcherOptions] used to create this context.
|
||||
*/
|
||||
class PatcherContext internal constructor(options: PatcherOptions) {
|
||||
/**
|
||||
* [PackageMetadata] of the supplied [PatcherOptions.inputFile].
|
||||
*/
|
||||
val packageMetadata = PackageMetadata(ApkInfo(ExtFile(options.inputFile)))
|
||||
|
||||
internal class Integrations(val context: PatcherContext) {
|
||||
var callback: ((File) -> Unit)? = null
|
||||
private val integrations: MutableList<File> = mutableListOf()
|
||||
/**
|
||||
* The map of [Patch]es associated by their [PatchClass].
|
||||
*/
|
||||
internal val executablePatches = mutableMapOf<PatchClass, Patch<*>>()
|
||||
|
||||
fun add(integrations: List<File>) = this@Integrations.integrations.addAll(integrations)
|
||||
/**
|
||||
* The map of all [Patch]es and their dependencies associated by their [PatchClass].
|
||||
*/
|
||||
internal val allPatches = mutableMapOf<PatchClass, Patch<*>>()
|
||||
|
||||
/**
|
||||
* Merge integrations.
|
||||
* @param logger A logger.
|
||||
*/
|
||||
fun merge(logger: Logger) {
|
||||
with(context.bytecodeContext.classes) {
|
||||
for (integrations in integrations) {
|
||||
callback?.let { it(integrations) }
|
||||
/**
|
||||
* The [ResourceContext] of this [PatcherContext].
|
||||
* This holds the current state of the resources.
|
||||
*/
|
||||
internal val resourceContext = ResourceContext(this, options)
|
||||
|
||||
for (classDef in lanchon.multidexlib2.MultiDexIO.readDexFile(
|
||||
true,
|
||||
integrations,
|
||||
NAMER,
|
||||
null,
|
||||
null
|
||||
).classes) {
|
||||
val type = classDef.type
|
||||
|
||||
val result = classes.findIndexed { it.type == type }
|
||||
if (result == null) {
|
||||
logger.trace("Merging type $type")
|
||||
classes.add(classDef)
|
||||
continue
|
||||
}
|
||||
|
||||
val (existingClass, existingClassIndex) = result
|
||||
|
||||
logger.trace("Type $type exists. Adding missing methods and fields.")
|
||||
|
||||
existingClass.merge(classDef, context, logger).let { mergedClass ->
|
||||
if (mergedClass !== existingClass) // referential equality check
|
||||
classes[existingClassIndex] = mergedClass
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* The [BytecodeContext] of this [PatcherContext].
|
||||
* This holds the current state of the bytecode.
|
||||
*/
|
||||
internal val bytecodeContext = BytecodeContext(options)
|
||||
}
|
||||
|
15
src/main/kotlin/app/revanced/patcher/PatcherException.kt
Normal file
15
src/main/kotlin/app/revanced/patcher/PatcherException.kt
Normal file
@@ -0,0 +1,15 @@
|
||||
package app.revanced.patcher
|
||||
|
||||
/**
|
||||
* An exception thrown by ReVanced [Patcher].
|
||||
*
|
||||
* @param errorMessage The exception message.
|
||||
* @param cause The corresponding [Throwable].
|
||||
*/
|
||||
sealed class PatcherException(errorMessage: String?, cause: Throwable?) : Exception(errorMessage, cause) {
|
||||
constructor(errorMessage: String) : this(errorMessage, null)
|
||||
|
||||
class CircularDependencyException internal constructor(dependant: String) : PatcherException(
|
||||
"Patch '$dependant' causes a circular dependency",
|
||||
)
|
||||
}
|
@@ -1,21 +1,54 @@
|
||||
package app.revanced.patcher
|
||||
|
||||
import app.revanced.patcher.logging.Logger
|
||||
import app.revanced.patcher.logging.impl.NopLogger
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import brut.androlib.Config
|
||||
import java.io.File
|
||||
import java.util.logging.Logger
|
||||
|
||||
/**
|
||||
* Options for the [Patcher].
|
||||
* @param inputFile The input file (usually an apk file).
|
||||
* @param resourceCacheDirectory Directory to cache resources.
|
||||
* @param aaptPath Optional path to a custom aapt binary.
|
||||
* @param frameworkFolderLocation Optional path to a custom framework folder.
|
||||
* @param logger Custom logger implementation for the [Patcher].
|
||||
* Options for ReVanced [Patcher].
|
||||
* @param inputFile The input file to patch.
|
||||
* @param resourceCachePath The path to the directory to use for caching resources.
|
||||
* @param aaptBinaryPath The path to a custom aapt binary.
|
||||
* @param frameworkFileDirectory The path to the directory to cache the framework file in.
|
||||
* @param multithreadingDexFileWriter Whether to use multiple threads for writing dex files.
|
||||
* This can impact memory usage.
|
||||
*/
|
||||
data class PatcherOptions(
|
||||
internal val inputFile: File,
|
||||
internal val resourceCacheDirectory: String,
|
||||
internal val aaptPath: String? = null,
|
||||
internal val frameworkFolderLocation: String? = null,
|
||||
internal val logger: Logger = NopLogger
|
||||
)
|
||||
internal val resourceCachePath: File = File("revanced-resource-cache"),
|
||||
internal val aaptBinaryPath: String? = null,
|
||||
internal val frameworkFileDirectory: String? = null,
|
||||
internal val multithreadingDexFileWriter: Boolean = false,
|
||||
) {
|
||||
private val logger = Logger.getLogger(PatcherOptions::class.java.name)
|
||||
|
||||
/**
|
||||
* The mode to use for resource decoding.
|
||||
* @see ResourceContext.ResourceDecodingMode
|
||||
*/
|
||||
internal var resourceDecodingMode = ResourceContext.ResourceDecodingMode.MANIFEST_ONLY
|
||||
|
||||
/**
|
||||
* The configuration to use for resource decoding and compiling.
|
||||
*/
|
||||
internal val resourceConfig =
|
||||
Config.getDefaultConfig().apply {
|
||||
useAapt2 = true
|
||||
aaptPath = aaptBinaryPath ?: ""
|
||||
frameworkDirectory = frameworkFileDirectory
|
||||
}
|
||||
|
||||
fun recreateResourceCacheDirectory() =
|
||||
resourceCachePath.also {
|
||||
if (it.exists()) {
|
||||
logger.info("Deleting existing resource cache directory")
|
||||
|
||||
if (!it.deleteRecursively()) {
|
||||
logger.severe("Failed to delete existing resource cache directory")
|
||||
}
|
||||
}
|
||||
|
||||
it.mkdirs()
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user