Compare commits

...

25 Commits

Author SHA1 Message Date
semantic-release-bot
228834fda8 chore(release): 2.118.0 [skip ci]
# [2.118.0](https://github.com/revanced/revanced-patches/compare/v2.117.1...v2.118.0) (2022-11-22)

### Features

* **youtube:** bump patches compatibility to v17.45.36 ([5ee123f](7466aecc5b))
2022-11-22 22:56:01 +00:00
oSumAtrIX
7466aecc5b feat(youtube): bump patches compatibility to v17.45.36 2022-11-22 23:54:07 +01:00
semantic-release-bot
8ee36541b4 chore(release): 2.117.1 [skip ci]
## [2.117.1](https://github.com/revanced/revanced-patches/compare/v2.117.0...v2.117.1) (2022-11-22)

### Bug Fixes

* **youtube/general-ads:** hide reels shelf ([2f8b911](a4fd6603fe))
2022-11-22 22:43:58 +00:00
oSumAtrIX
a4fd6603fe fix(youtube/general-ads): hide reels shelf 2022-11-22 23:41:53 +01:00
oSumAtrIX
510cb8f590 refactor: apply auto-refactor 2022-11-22 20:18:29 +01:00
Sculas
c02ebd752c refactor(integrations): merge integrations code (#1052)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-11-21 22:26:43 +01:00
semantic-release-bot
b4d7eca5fa chore(release): 2.117.0 [skip ci]
# [2.117.0](https://github.com/revanced/revanced-patches/compare/v2.116.0...v2.117.0) (2022-11-21)

### Features

* **tiktok:** `tiktok-web-login` patch ([#593](https://github.com/revanced/revanced-patches/issues/593)) ([879f9c5](c6125c071b))
2022-11-21 15:16:45 +00:00
d4rkk3y
c6125c071b feat(tiktok): tiktok-web-login patch (#593) 2022-11-21 16:14:58 +01:00
d4rkk3y
478de297f9 frat(tiktok/settings): make patch name unique (#1082) 2022-11-21 16:12:44 +01:00
semantic-release-bot
ebc4a12cd7 chore(release): 2.116.0 [skip ci]
# [2.116.0](https://github.com/revanced/revanced-patches/compare/v2.115.0...v2.116.0) (2022-11-21)

### Features

* **youtube/theme:** make amoled the default color for dark theme background" ([5a904ce](b3c0291e70))
2022-11-21 02:55:24 +00:00
oSumAtrIX
b3c0291e70 feat(youtube/theme): make amoled the default color for dark theme background"
This reverts commit 91ae954210.
2022-11-21 03:53:18 +01:00
semantic-release-bot
c43588ee40 chore(release): 2.115.0 [skip ci]
# [2.115.0](https://github.com/revanced/revanced-patches/compare/v2.114.2...v2.115.0) (2022-11-21)

### Features

* **youtube/general-ads:** normalize switch names ([e9d5a5e](c2122494bc))
* **youtube/theme:** exclude the patch by default ([bfda80c](c74b5d4e47))
* **youtube/theme:** make dark the default color for dark theme background ([b099d8b](91ae954210))
2022-11-21 00:00:19 +00:00
oSumAtrIX
c74b5d4e47 feat(youtube/theme): exclude the patch by default 2022-11-21 00:58:56 +01:00
oSumAtrIX
91ae954210 feat(youtube/theme): make dark the default color for dark theme background 2022-11-21 00:58:56 +01:00
oSumAtrIX
65172cad4f refactor(youtube/general-ads): apply auto-refactor 2022-11-21 00:58:55 +01:00
oSumAtrIX
c2122494bc feat(youtube/general-ads): normalize switch names 2022-11-21 00:58:55 +01:00
semantic-release-bot
6ed94935ca chore(release): 2.114.2 [skip ci]
## [2.114.2](https://github.com/revanced/revanced-patches/compare/v2.114.1...v2.114.2) (2022-11-20)

### Bug Fixes

* **youtube/general-ads:** hide bytecode home ad view ([a2717d1](f3785c4e47))
* **youtube/general-ads:** remove unused switch ([e05dd02](a934821fa7))
2022-11-20 23:27:07 +00:00
oSumAtrIX
a934821fa7 fix(youtube/general-ads): remove unused switch 2022-11-21 00:25:31 +01:00
oSumAtrIX
f3785c4e47 fix(youtube/general-ads): hide bytecode home ad view 2022-11-21 00:25:30 +01:00
oSumAtrIX
67e0db5ac9 refactor(youtube/resource-mapping): move to appropriate package 2022-11-21 00:25:30 +01:00
oSumAtrIX
aaa820430b style(youtube/resource-mapping): use shorter name for class 2022-11-21 00:25:29 +01:00
semantic-release-bot
cf5ed1baea chore(release): 2.114.1 [skip ci]
## [2.114.1](https://github.com/revanced/revanced-patches/compare/v2.114.0...v2.114.1) (2022-11-20)

### Bug Fixes

* **tiktok/settings:** make compatible with newer versions ([#1057](https://github.com/revanced/revanced-patches/issues/1057)) ([79e6fcb](206341cec4))
2022-11-20 16:12:02 +00:00
d4rkk3y
206341cec4 fix(tiktok/settings): make compatible with newer versions (#1057)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-11-20 17:09:59 +01:00
semantic-release-bot
e8f4890edd chore(release): 2.114.0 [skip ci]
# [2.114.0](https://github.com/revanced/revanced-patches/compare/v2.113.0...v2.114.0) (2022-11-20)

### Features

* **youtube:** `disable-zoom-haptics` patch ([#1079](https://github.com/revanced/revanced-patches/issues/1079)) ([974a042](9463f11dbf))
2022-11-20 13:26:23 +00:00
aliernfrog
9463f11dbf feat(youtube): disable-zoom-haptics patch (#1079) 2022-11-20 14:24:41 +01:00
84 changed files with 713 additions and 306 deletions

View File

@@ -1,3 +1,62 @@
# [2.118.0](https://github.com/revanced/revanced-patches/compare/v2.117.1...v2.118.0) (2022-11-22)
### Features
* **youtube:** bump patches compatibility to v17.45.36 ([ab7dfd8](https://github.com/revanced/revanced-patches/commit/ab7dfd8ee1d902095811ed91b80aa0ed362ee9c5))
## [2.117.1](https://github.com/revanced/revanced-patches/compare/v2.117.0...v2.117.1) (2022-11-22)
### Bug Fixes
* **youtube/general-ads:** hide reels shelf ([a436663](https://github.com/revanced/revanced-patches/commit/a436663e7755fc714c735df626d39bbd94f83dbb))
# [2.117.0](https://github.com/revanced/revanced-patches/compare/v2.116.0...v2.117.0) (2022-11-21)
### Features
* **tiktok:** `tiktok-web-login` patch ([#593](https://github.com/revanced/revanced-patches/issues/593)) ([233e578](https://github.com/revanced/revanced-patches/commit/233e578b4d1cd5e783369e0c855e8246d158f8ed))
# [2.116.0](https://github.com/revanced/revanced-patches/compare/v2.115.0...v2.116.0) (2022-11-21)
### Features
* **youtube/theme:** make amoled the default color for dark theme background" ([2b68ac7](https://github.com/revanced/revanced-patches/commit/2b68ac7796e54ed07c697909a84b3847f4ed7f01))
# [2.115.0](https://github.com/revanced/revanced-patches/compare/v2.114.2...v2.115.0) (2022-11-21)
### Features
* **youtube/general-ads:** normalize switch names ([7636180](https://github.com/revanced/revanced-patches/commit/763618002ab6ccd9cd23889275c0e9b23642763e))
* **youtube/theme:** exclude the patch by default ([57358ed](https://github.com/revanced/revanced-patches/commit/57358edc4cf3ae6b05cfb51359f66fc94c71cb5c))
* **youtube/theme:** make dark the default color for dark theme background ([db44fa6](https://github.com/revanced/revanced-patches/commit/db44fa6f5adad19384970dad58784b2bf5fe1007))
## [2.114.2](https://github.com/revanced/revanced-patches/compare/v2.114.1...v2.114.2) (2022-11-20)
### Bug Fixes
* **youtube/general-ads:** hide bytecode home ad view ([4976ad4](https://github.com/revanced/revanced-patches/commit/4976ad44b1867c93e976d91075b5bcead8d69c90))
* **youtube/general-ads:** remove unused switch ([43cddcc](https://github.com/revanced/revanced-patches/commit/43cddcc85830524cd88d87ae1178f11451f158d8))
## [2.114.1](https://github.com/revanced/revanced-patches/compare/v2.114.0...v2.114.1) (2022-11-20)
### Bug Fixes
* **tiktok/settings:** make compatible with newer versions ([#1057](https://github.com/revanced/revanced-patches/issues/1057)) ([e1d5d64](https://github.com/revanced/revanced-patches/commit/e1d5d6492ed660f43c87c796a59e766ea6b8ead0))
# [2.114.0](https://github.com/revanced/revanced-patches/compare/v2.113.0...v2.114.0) (2022-11-20)
### Features
* **youtube:** `disable-zoom-haptics` patch ([#1079](https://github.com/revanced/revanced-patches/issues/1079)) ([a7cfba5](https://github.com/revanced/revanced-patches/commit/a7cfba54fbb3ee0ee5511a45d0b3c4620eb0c861))
# [2.113.0](https://github.com/revanced/revanced-patches/compare/v2.112.0...v2.113.0) (2022-11-19) # [2.113.0](https://github.com/revanced/revanced-patches/compare/v2.112.0...v2.113.0) (2022-11-19)

View File

@@ -21,8 +21,9 @@ The official Patch bundle provided by ReVanced and the community.
| `tiktok-speed` | Enables the playback speed option for all videos. | all | | `tiktok-speed` | Enables the playback speed option for all videos. | all |
| `tiktok-download` | Removes download restrictions and changes the default path to download to. | all | | `tiktok-download` | Removes download restrictions and changes the default path to download to. | all |
| `tiktok-seekbar` | Show progress bar for all video. | all | | `tiktok-seekbar` | Show progress bar for all video. | all |
| `tiktok-settings` | Add settings menu to TikTok. | all | | `tiktok-settings` | Adds settings for ReVanced to TikTok. | all |
| `tiktok-force-login` | Do not force login. | all | | `tiktok-force-login` | Do not force login. | all |
| `tiktok-web-login` | Allows logging in with a Google account. | all |
| `tiktok-feed-filter` | Filters tiktok videos: removing ads, removing livestreams. | all | | `tiktok-feed-filter` | Filters tiktok videos: removing ads, removing livestreams. | all |
</details> </details>
@@ -35,8 +36,9 @@ The official Patch bundle provided by ReVanced and the community.
| `tiktok-speed` | Enables the playback speed option for all videos. | all | | `tiktok-speed` | Enables the playback speed option for all videos. | all |
| `tiktok-download` | Removes download restrictions and changes the default path to download to. | all | | `tiktok-download` | Removes download restrictions and changes the default path to download to. | all |
| `tiktok-seekbar` | Show progress bar for all video. | all | | `tiktok-seekbar` | Show progress bar for all video. | all |
| `tiktok-settings` | Add settings menu to TikTok. | all | | `tiktok-settings` | Adds settings for ReVanced to TikTok. | all |
| `tiktok-force-login` | Do not force login. | all | | `tiktok-force-login` | Do not force login. | all |
| `tiktok-web-login` | Allows logging in with a Google account. | all |
| `tiktok-feed-filter` | Filters tiktok videos: removing ads, removing livestreams. | all | | `tiktok-feed-filter` | Filters tiktok videos: removing ads, removing livestreams. | all |
</details> </details>
@@ -81,51 +83,52 @@ The official Patch bundle provided by ReVanced and the community.
| 💊 Patch | 📜 Description | 🏹 Target Version | | 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:| |:--------:|:--------------:|:-----------------:|
| `hide-crowdfunding-box` | Hides the crowdfunding box between the player and video description. | 17.43.36 | | `hide-crowdfunding-box` | Hides the crowdfunding box between the player and video description. | 17.45.36 |
| `hide-time-and-seekbar` | Hides progress bar and time counter on videos. | 17.43.36 | | `hide-time-and-seekbar` | Hides progress bar and time counter on videos. | 17.45.36 |
| `hide-video-buttons` | Adds options to hide action buttons under a video. | 17.43.36 | | `hide-video-buttons` | Adds options to hide action buttons under a video. | 17.45.36 |
| `enable-wide-searchbar` | Replaces the search icon with a wide search bar. This will hide the YouTube logo when active. | 17.43.36 | | `enable-wide-searchbar` | Replaces the search icon with a wide search bar. This will hide the YouTube logo when active. | 17.43.36 |
| `hide-captions-button` | Hides the captions button on video player. | 17.43.36 | | `hide-captions-button` | Hides the captions button on video player. | 17.45.36 |
| `hide-shorts-button` | Hides the shorts button on the navigation bar. | 17.43.36 | | `hide-shorts-button` | Hides the shorts button on the navigation bar. | 17.43.36 |
| `hide-create-button` | Hides the create button in the navigation bar. | 17.43.36 | | `hide-create-button` | Hides the create button in the navigation bar. | 17.43.36 |
| `disable-startup-shorts-player` | Disables playing YouTube Shorts when launching YouTube. | 17.43.36 | | `disable-startup-shorts-player` | Disables playing YouTube Shorts when launching YouTube. | 17.45.36 |
| `hide-endscreen-cards` | Hides the suggested video cards at the end of a video in fullscreen. | 17.43.36 | | `hide-endscreen-cards` | Hides the suggested video cards at the end of a video in fullscreen. | 17.45.36 |
| `hide-cast-button` | Hides the cast button in the video player. | all | | `hide-cast-button` | Hides the cast button in the video player. | all |
| `sponsorblock` | Integrate SponsorBlock. | 17.43.36 | | `sponsorblock` | Integrate SponsorBlock. | 17.45.36 |
| `hide-autoplay-button` | Hides the autoplay button in the video player. | 17.43.36 | | `hide-autoplay-button` | Hides the autoplay button in the video player. | 17.45.36 |
| `hide-watch-in-vr` | Hides the Watch in VR option from the player settings flyout panel. | 17.43.36 | | `hide-watch-in-vr` | Hides the Watch in VR option from the player settings flyout panel. | 17.45.36 |
| `hide-album-cards` | Hides the album cards below the artist description. | 17.43.36 | | `hide-album-cards` | Hides the album cards below the artist description. | 17.45.36 |
| `disable-auto-player-popup-panels` | Disable automatic popup panels (playlist or live chat) on video player. | 17.43.36 | | `disable-auto-player-popup-panels` | Disable automatic popup panels (playlist or live chat) on video player. | 17.45.36 |
| `disable-auto-captions` | Disable forced captions from being automatically enabled. | 17.43.36 | | `disable-auto-captions` | Disable forced captions from being automatically enabled. | 17.45.36 |
| `disable-fullscreen-panels` | Disables video description and comments panel in fullscreen view. | 17.43.36 | | `disable-fullscreen-panels` | Disables video description and comments panel in fullscreen view. | 17.45.36 |
| `hide-artist-card` | Hides the artist card below the searchbar. | 17.43.36 | | `hide-artist-card` | Hides the artist card below the searchbar. | 17.45.36 |
| `return-youtube-dislike` | Shows the dislike count of videos using the Return YouTube Dislike API. | 17.43.36 | | `return-youtube-dislike` | Shows the dislike count of videos using the Return YouTube Dislike API. | 17.45.36 |
| `comments` | Hides components related to comments. | 17.43.36 | | `comments` | Hides components related to comments. | 17.45.36 |
| `theme` | Applies a custom theme. | all | | `theme` | Applies a custom theme. | all |
| `hide-email-address` | Hides the email address in the account switcher. | 17.43.36 | | `hide-email-address` | Hides the email address in the account switcher. | 17.45.36 |
| `tablet-mini-player` | Enables the tablet mini player layout. | 17.43.36 | | `tablet-mini-player` | Enables the tablet mini player layout. | 17.45.36 |
| `hide-watermark` | Hides creator's watermarks on videos. | 17.43.36 | | `hide-watermark` | Hides creator's watermarks on videos. | 17.45.36 |
| `hide-info-cards` | Hides info-cards in videos. | 17.43.36 | | `hide-info-cards` | Hides info-cards in videos. | 17.45.36 |
| `hide-my-mix` | Hides mix playlists. | 17.43.36 | | `hide-my-mix` | Hides mix playlists. | 17.45.36 |
| `custom-branding` | Changes the YouTube launcher icon and name to your choice (defaults to ReVanced). | all | | `custom-branding` | Changes the YouTube launcher icon and name to your choice (defaults to ReVanced). | all |
| `premium-heading` | Shows premium branding on the home screen. | all | | `premium-heading` | Shows premium branding on the home screen. | all |
| `old-quality-layout` | Enables the original quality flyout menu. | 17.43.36 | | `old-quality-layout` | Enables the original quality flyout menu. | 17.45.36 |
| `general-ads` | Removes general ads. | 17.43.36 | | `general-ads` | Removes general ads. | 17.45.36 |
| `video-ads` | Removes ads in the video player. | 17.43.36 | | `video-ads` | Removes ads in the video player. | 17.45.36 |
| `swipe-controls` | Adds volume and brightness swipe controls. | 17.43.36 | | `swipe-controls` | Adds volume and brightness swipe controls. | 17.45.36 |
| `downloads` | Enables downloading music and videos from YouTube. | 17.43.36 | | `downloads` | Enables downloading music and videos from YouTube. | 17.45.36 |
| `seekbar-tapping` | Enables tap-to-seek on the seekbar of the video player. | 17.43.36 | | `seekbar-tapping` | Enables tap-to-seek on the seekbar of the video player. | 17.45.36 |
| `disable-zoom-haptics` | Disables haptics when zooming. | all |
| `settings` | Adds settings for ReVanced to YouTube. | all | | `settings` | Adds settings for ReVanced to YouTube. | all |
| `open-links-directly` | Bypasses redirect links and allows opening links directly. | 17.43.36 | | `open-links-directly` | Bypasses redirect links and allows opening links directly. | 17.45.36 |
| `microg-support` | Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG. | 17.43.36 | | `microg-support` | Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG. | 17.45.36 |
| `custom-video-buffer` | Lets you change the buffers of videos. | 17.43.36 | | `custom-video-buffer` | Lets you change the buffers of videos. | 17.45.36 |
| `debugging` | Adds debugging options. | all | | `debugging` | Adds debugging options. | all |
| `client-spoof` | Spoofs the YouTube or Vanced client to prevent playback issues. | all | | `client-spoof` | Spoofs the YouTube or Vanced client to prevent playback issues. | all |
| `always-autorepeat` | Always repeats the playing video again. | 17.43.36 | | `always-autorepeat` | Always repeats the playing video again. | 17.45.36 |
| `minimized-playback` | Enables minimized and background playback. | 17.43.36 | | `minimized-playback` | Enables minimized and background playback. | 17.45.36 |
| `custom-video-speed` | Adds more video speed options. | 17.43.36 | | `custom-video-speed` | Adds more video speed options. | 17.45.36 |
| `remember-video-quality` | Adds the ability to remember the video quality you chose in the video quality flyout. | 17.43.36 | | `remember-video-quality` | Adds the ability to remember the video quality you chose in the video quality flyout. | 17.45.36 |
| `hdr-auto-brightness` | Makes the brightness of HDR videos follow the system default. | 17.43.36 | | `hdr-auto-brightness` | Makes the brightness of HDR videos follow the system default. | 17.45.36 |
</details> </details>
### 📦 `com.vanced.android.youtube` ### 📦 `com.vanced.android.youtube`

View File

@@ -1,2 +1,2 @@
kotlin.code.style = official kotlin.code.style = official
version = 2.113.0 version = 2.118.0

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
package app.revanced.patches.youtube.misc.mapping.patch package app.revanced.patches.shared.mapping.patch
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
@@ -16,7 +16,7 @@ import java.util.concurrent.TimeUnit
@Name("resource-mapping") @Name("resource-mapping")
@Description("Creates a map of public resources.") @Description("Creates a map of public resources.")
@Version("0.0.1") @Version("0.0.1")
class ResourceMappingResourcePatch : ResourcePatch { class ResourceMappingPatch : ResourcePatch {
companion object { companion object {
internal lateinit var resourceMappings: List<ResourceElement> internal lateinit var resourceMappings: List<ResourceElement>
private set private set

View File

@@ -14,7 +14,7 @@ import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.spotify.premium_navbar_tab.annotations.PremiumNavbarTabCompatibility import app.revanced.patches.spotify.premium_navbar_tab.annotations.PremiumNavbarTabCompatibility
import app.revanced.patches.spotify.premium_navbar_tab.fingerprints.AddPremiumNavbarTabFingerprint import app.revanced.patches.spotify.premium_navbar_tab.fingerprints.AddPremiumNavbarTabFingerprint
import app.revanced.patches.spotify.premium_navbar_tab.fingerprints.AddPremiumNavbarTabParentFingerprint import app.revanced.patches.spotify.premium_navbar_tab.fingerprints.AddPremiumNavbarTabParentFingerprint
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch import app.revanced.patches.shared.mapping.patch.ResourceMappingPatch
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@@ -23,7 +23,7 @@ import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Description("Removes the premium tab from the navbar.") @Description("Removes the premium tab from the navbar.")
@PremiumNavbarTabCompatibility @PremiumNavbarTabCompatibility
@Version("0.0.1") @Version("0.0.1")
@DependsOn([ResourceMappingResourcePatch::class]) @DependsOn([ResourceMappingPatch::class])
class PremiumNavbarTabPatch : BytecodePatch( class PremiumNavbarTabPatch : BytecodePatch(
listOf( listOf(
AddPremiumNavbarTabParentFingerprint AddPremiumNavbarTabParentFingerprint
@@ -40,7 +40,7 @@ class PremiumNavbarTabPatch : BytecodePatch(
val lastInstructionIdx = methodInstructions.size - 1 val lastInstructionIdx = methodInstructions.size - 1
val premiumTabId = val premiumTabId =
ResourceMappingResourcePatch.resourceMappings.single { it.type == "id" && it.name == "premium_tab" }.id ResourceMappingPatch.resourceMappings.single { it.type == "id" && it.name == "premium_tab" }.id
var removeAmount = 2 var removeAmount = 2
// 2nd const remove method // 2nd const remove method

View File

@@ -2,13 +2,13 @@ package app.revanced.patches.tiktok.misc.integrations.fingerprints
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.tiktok.misc.integrations.annotations.TikTokIntegrationsCompatibility import app.revanced.patches.tiktok.misc.integrations.annotations.TikTokIntegrationsCompatibility
import app.revanced.shared.patches.AbstractIntegrationsPatch.IntegrationsFingerprint
@Name("init-fingerprint") @Name("init-fingerprint")
@TikTokIntegrationsCompatibility @TikTokIntegrationsCompatibility
@Version("0.0.1") @Version("0.0.1")
object InitFingerprint : MethodFingerprint( object InitFingerprint : IntegrationsFingerprint(
customFingerprint = { methodDef -> customFingerprint = { methodDef ->
methodDef.definingClass.endsWith("/AwemeHostApplication;") && methodDef.definingClass.endsWith("/AwemeHostApplication;") &&
methodDef.name == "onCreate" methodDef.name == "onCreate"

View File

@@ -1,38 +1,13 @@
package app.revanced.patches.tiktok.misc.integrations.patch package app.revanced.patches.tiktok.misc.integrations.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.tiktok.misc.integrations.annotations.TikTokIntegrationsCompatibility import app.revanced.patches.tiktok.misc.integrations.annotations.TikTokIntegrationsCompatibility
import app.revanced.patches.tiktok.misc.integrations.fingerprints.InitFingerprint import app.revanced.patches.tiktok.misc.integrations.fingerprints.InitFingerprint
import app.revanced.shared.patches.AbstractIntegrationsPatch
@Name("tiktok-integrations") @Name("tiktok-integrations")
@Description("Applies mandatory patches to implement the ReVanced integrations into the application.")
@TikTokIntegrationsCompatibility @TikTokIntegrationsCompatibility
@Version("0.0.1") class TikTokIntegrationsPatch : AbstractIntegrationsPatch(
class TikTokIntegrationsPatch : BytecodePatch( "Lapp/revanced/tiktok/utils/ReVancedUtils;",
listOf( listOf(InitFingerprint)
InitFingerprint )
)
) {
override fun execute(context: BytecodeContext): PatchResult {
if (context.findClass("Lapp/revanced/tiktok/utils/ReVancedUtils") == null)
return PatchResultError("Integrations have not been merged yet. This patch can not succeed without the integrations.")
val result = InitFingerprint.result!!
val method = result.mutableMethod
val implementation = method.implementation!!
val count = implementation.registerCount - 1
method.addInstruction(
0, "sput-object v$count, Lapp/revanced/tiktok/utils/ReVancedUtils;->context:Landroid/content/Context;"
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,14 @@
package app.revanced.patches.tiktok.misc.loginfallback.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[
Package("com.ss.android.ugc.trill"),
Package("com.zhiliaoapp.musically")
]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class TikTokWebLoginCompatibility

View File

@@ -0,0 +1,20 @@
package app.revanced.patches.tiktok.misc.loginfallback.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.tiktok.misc.loginfallback.annotations.TikTokWebLoginCompatibility
import org.jf.dexlib2.AccessFlags
@Name("google-one-tap-auth-available-fingerprint")
@TikTokWebLoginCompatibility
@Version("0.0.1")
object GoogleAuthAvailableFingerprint : MethodFingerprint(
returnType = "Z",
access = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf(),
customFingerprint = { methodDef ->
methodDef.definingClass == "Lcom/bytedance/lobby/google/GoogleAuth;"
}
)

View File

@@ -0,0 +1,20 @@
package app.revanced.patches.tiktok.misc.loginfallback.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.tiktok.misc.loginfallback.annotations.TikTokWebLoginCompatibility
import org.jf.dexlib2.AccessFlags
@Name("google-one-tap-auth-available-fingerprint")
@TikTokWebLoginCompatibility
@Version("0.0.1")
object GoogleOneTapAuthAvailableFingerprint : MethodFingerprint(
returnType = "Z",
access = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf(),
customFingerprint = { methodDef ->
methodDef.definingClass == "Lcom/bytedance/lobby/google/GoogleOneTapAuth;"
}
)

View File

@@ -0,0 +1,44 @@
package app.revanced.patches.tiktok.misc.loginfallback.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.tiktok.misc.loginfallback.annotations.TikTokWebLoginCompatibility
import app.revanced.patches.tiktok.misc.loginfallback.fingerprints.GoogleAuthAvailableFingerprint
import app.revanced.patches.tiktok.misc.loginfallback.fingerprints.GoogleOneTapAuthAvailableFingerprint
@Patch
@Name("tiktok-web-login")
@Description("Allows logging in with a Google account.")
@TikTokWebLoginCompatibility
@Version("0.0.1")
class TikTokLoginFallbackPatch : BytecodePatch(
listOf(
GoogleOneTapAuthAvailableFingerprint,
GoogleAuthAvailableFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
listOf(
GoogleOneTapAuthAvailableFingerprint,
GoogleAuthAvailableFingerprint
).forEach {
with(it.result!!.mutableMethod) {
addInstructions(
0,
"""
const/4 v0, 0x0
return v0
"""
)
}
}
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,18 @@
package app.revanced.patches.tiktok.misc.settings.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.tiktok.misc.settings.annotations.TikTokSettingsCompatibility
@Name("about-onclick-method-fingerprint")
@TikTokSettingsCompatibility
@Version("0.0.1")
object AboutOnClickMethodFingerprint : MethodFingerprint(
strings = listOf(
"//setting/about",
"enter_from",
"settings_page",
"enter_settings_about"
)
)

View File

@@ -5,10 +5,10 @@ import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.tiktok.misc.settings.annotations.TikTokSettingsCompatibility import app.revanced.patches.tiktok.misc.settings.annotations.TikTokSettingsCompatibility
@Name("ad-personalization-activity-fingerprint") @Name("ad-personalization-activity-on-create-fingerprint")
@TikTokSettingsCompatibility @TikTokSettingsCompatibility
@Version("0.0.1") @Version("0.0.1")
object AdPersonalizationActivityFingerprint : MethodFingerprint( object AdPersonalizationActivityOnCreateFingerprint : MethodFingerprint(
customFingerprint = { methodDef -> customFingerprint = { methodDef ->
methodDef.definingClass.endsWith("/AdPersonalizationActivity;") && methodDef.definingClass.endsWith("/AdPersonalizationActivity;") &&
methodDef.name == "onCreate" methodDef.name == "onCreate"

View File

@@ -8,7 +8,7 @@ import app.revanced.patches.tiktok.misc.settings.annotations.TikTokSettingsCompa
@Name("copyright-settings-string-fingerprint") @Name("copyright-settings-string-fingerprint")
@TikTokSettingsCompatibility @TikTokSettingsCompatibility
@Version("0.0.1") @Version("0.0.1")
object CopyRightSettingsStringFingerprint : MethodFingerprint( object SettingsOnViewCreatedFingerprint : MethodFingerprint(
customFingerprint = { methodDef -> customFingerprint = { methodDef ->
methodDef.definingClass.endsWith("/SettingNewVersionFragment;") && methodDef.definingClass.endsWith("/SettingNewVersionFragment;") &&
methodDef.name == "onViewCreated" methodDef.name == "onViewCreated"

View File

@@ -5,6 +5,7 @@ import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.instruction
import app.revanced.patcher.extensions.replaceInstruction import app.revanced.patcher.extensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
@@ -14,85 +15,111 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.tiktok.misc.integrations.patch.TikTokIntegrationsPatch import app.revanced.patches.tiktok.misc.integrations.patch.TikTokIntegrationsPatch
import app.revanced.patches.tiktok.misc.settings.annotations.TikTokSettingsCompatibility import app.revanced.patches.tiktok.misc.settings.annotations.TikTokSettingsCompatibility
import app.revanced.patches.tiktok.misc.settings.fingerprints.AdPersonalizationActivityFingerprint import app.revanced.patches.tiktok.misc.settings.fingerprints.AboutOnClickMethodFingerprint
import app.revanced.patches.tiktok.misc.settings.fingerprints.CopyRightSettingsStringFingerprint import app.revanced.patches.tiktok.misc.settings.fingerprints.AdPersonalizationActivityOnCreateFingerprint
import app.revanced.patches.tiktok.misc.settings.fingerprints.SettingsOnViewCreatedFingerprint
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.instruction.formats.Instruction21c
import org.jf.dexlib2.iface.instruction.formats.Instruction35c import org.jf.dexlib2.iface.instruction.formats.Instruction35c
import org.jf.dexlib2.iface.reference.MethodReference
import org.jf.dexlib2.iface.reference.StringReference import org.jf.dexlib2.iface.reference.StringReference
import org.jf.dexlib2.iface.reference.TypeReference
@Patch @Patch
@DependsOn([TikTokIntegrationsPatch::class]) @DependsOn([TikTokIntegrationsPatch::class])
@Name("tiktok-settings") @Name("tiktok-settings")
@Description("Add settings menu to TikTok.") @Description("Adds settings for ReVanced to TikTok.")
@TikTokSettingsCompatibility @TikTokSettingsCompatibility
@Version("0.0.1") @Version("0.0.1")
class TikTokSettingsPatch : BytecodePatch( class TikTokSettingsPatch : BytecodePatch(
listOf( listOf(
AdPersonalizationActivityFingerprint, AdPersonalizationActivityOnCreateFingerprint,
CopyRightSettingsStringFingerprint SettingsOnViewCreatedFingerprint,
AboutOnClickMethodFingerprint
) )
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
//Replace string `Copyright Policy` to 'Revanced Settings` in TikTok settings. // Patch Settings UI to add 'Revanced Settings'.
val method1 = CopyRightSettingsStringFingerprint.result!!.mutableMethod val targetIndexes = findOptionsOnClickIndex()
val implementation1 = method1.implementation!! with(SettingsOnViewCreatedFingerprint.result!!.mutableMethod) {
for ((index, instruction) in implementation1.instructions.withIndex()) { for (index in targetIndexes) {
if (instruction.opcode != Opcode.CONST_STRING) continue if (
val string = ((instruction as ReferenceInstruction).reference as StringReference).string instruction(index).opcode != Opcode.NEW_INSTANCE ||
if (string != "copyright_policy") continue instruction(index - 4).opcode != Opcode.MOVE_RESULT_OBJECT
var targetIndex = index )
while (targetIndex >= 0) { return PatchResultError("Hardcode offset changed.")
targetIndex-- patchOptionNameAndOnClickEvent(index, context)
val invokeInstruction = implementation1.instructions[targetIndex] }
if (invokeInstruction.opcode != Opcode.INVOKE_VIRTUAL) continue }
val methodName = ((invokeInstruction as Instruction35c).reference as MethodReference).name // Implement settings screen in `AdPersonalizationActivity`
if (methodName != "getString") continue with(AdPersonalizationActivityOnCreateFingerprint.result!!.mutableMethod) {
val resultInstruction = implementation1.instructions[targetIndex + 1] for ((index, instruction) in implementation!!.instructions.withIndex()) {
if (resultInstruction.opcode != Opcode.MOVE_RESULT_OBJECT) continue if (instruction.opcode != Opcode.INVOKE_SUPER) continue
val overrideRegister = (resultInstruction as OneRegisterInstruction).registerA val thisRegister = (instruction as Instruction35c).registerC
method1.replaceInstruction( addInstructions(
targetIndex + 1, index + 1,
""" """
const-string v$overrideRegister, "Revanced Settings" invoke-static {v$thisRegister}, Lapp/revanced/tiktok/settingsmenu/SettingsMenu;->initializeSettings(Lcom/bytedance/ies/ugc/aweme/commercialize/compliance/personalization/AdPersonalizationActivity;)V
return-void
""" """
) )
break break
} }
//Change onClick to start settings activity.
val clickInstruction = implementation1.instructions[index - 1]
if (clickInstruction.opcode != Opcode.INVOKE_DIRECT)
return PatchResultError("Can not find click listener.")
val clickClass = ((clickInstruction as ReferenceInstruction).reference as MethodReference).definingClass
val mutableClickClass = context.findClass(clickClass)!!.mutableClass
val mutableOnClickMethod = mutableClickClass.methods.first {
it.name == "onClick"
}
mutableOnClickMethod.addInstructions(
0,
"""
invoke-static {}, Lapp/revanced/tiktok/settingsmenu/SettingsMenu;->startSettingsActivity()V
return-void
"""
)
break
}
//Implement revanced settings screen in `AdPersonalizationActivity`
val method2 = AdPersonalizationActivityFingerprint.result!!.mutableMethod
for ((index, instruction) in method2.implementation!!.instructions.withIndex()) {
if (instruction.opcode != Opcode.INVOKE_SUPER) continue
val thisRegister = (instruction as Instruction35c).registerC
method2.addInstructions(
index + 1,
"""
invoke-static {v$thisRegister}, Lapp/revanced/tiktok/settingsmenu/SettingsMenu;->initializeSettings(Lcom/bytedance/ies/ugc/aweme/commercialize/compliance/personalization/AdPersonalizationActivity;)V
return-void
"""
)
break
} }
return PatchResultSuccess() return PatchResultSuccess()
} }
private fun findOptionsOnClickIndex(): IntArray {
val results = IntArray(2)
var found = 0
with(SettingsOnViewCreatedFingerprint.result!!.mutableMethod) {
for ((index, instruction) in implementation!!.instructions.withIndex()) {
// Old UI settings option to replace to 'Revanced Settings'
if (instruction.opcode == Opcode.CONST_STRING) {
val string = ((instruction as ReferenceInstruction).reference as StringReference).string
if (string == "copyright_policy") {
results[0] = index - 2
found++
}
}
// New UI settings option to replace to 'Revanced Settings'
if (instruction.opcode == Opcode.NEW_INSTANCE) {
val onClickClass = ((instruction as Instruction21c).reference as TypeReference).type
if (onClickClass == AboutOnClickMethodFingerprint.result!!.mutableMethod.definingClass) {
results[1] = index
found++
}
}
if (found > 1) break
}
}
return results
}
private fun patchOptionNameAndOnClickEvent(index: Int, context: BytecodeContext) {
with(SettingsOnViewCreatedFingerprint.result!!.mutableMethod) {
// Patch option name
val overrideRegister = (instruction(index - 4) as OneRegisterInstruction).registerA
replaceInstruction(
index - 4,
"""
const-string v$overrideRegister, "Revanced Settings"
"""
)
// Patch option OnClick Event
with(((instruction(index) as ReferenceInstruction).reference as TypeReference).type) {
context.findClass(this)!!.mutableClass.methods.first { it.name == "onClick" }
.addInstructions(
0,
"""
invoke-static {}, Lapp/revanced/tiktok/settingsmenu/SettingsMenu;->startSettingsActivity()V
return-void
"""
)
}
}
}
} }

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -0,0 +1,23 @@
package app.revanced.patches.youtube.ad.general.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility
import app.revanced.patches.youtube.ad.general.resource.patch.GeneralAdsResourcePatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Name("reel-constructor-fingerprint")
@GeneralAdsCompatibility
@Version("0.0.1")
object ReelConstructorFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.INVOKE_VIRTUAL
),
customFingerprint = { method ->
method.implementation?.instructions?.any {
it.opcode == Opcode.CONST && (it as WideLiteralInstruction).wideLiteral == GeneralAdsResourcePatch.reelMultipleItemShelfId
} ?: false
}
)

View File

@@ -0,0 +1,107 @@
package app.revanced.patches.youtube.ad.general.bytecode.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.instruction
import app.revanced.patcher.extensions.softCompareTo
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility
import app.revanced.patches.youtube.ad.general.bytecode.fingerprints.ReelConstructorFingerprint
import app.revanced.patches.youtube.ad.general.resource.patch.GeneralAdsResourcePatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.*
import org.jf.dexlib2.iface.Method
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
import org.jf.dexlib2.iface.instruction.formats.Instruction31i
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
import java.util.*
@Patch
@DependsOn([GeneralAdsResourcePatch::class])
@Name("general-ads")
@Description("Removes general ads.")
@GeneralAdsCompatibility
@Version("0.0.1")
class GeneralAdsPatch : BytecodePatch(
listOf(ReelConstructorFingerprint)
) {
internal companion object {
private fun MutableClass.findMutableMethodOf(
method: Method
) = this.methods.first {
it.softCompareTo(
ImmutableMethodReference(
method.definingClass, method.name, method.parameters, method.returnType
)
)
}
}
override fun execute(context: BytecodeContext): PatchResult {
fun String.buildHideCall(viewRegister: Int) = "invoke-static { v$viewRegister }, " +
"Lapp/revanced/integrations/patches/GeneralAdsPatch;" +
"->" +
"$this(Landroid/view/View;)V"
fun MutableMethod.injectHideCall(insertIndex: Int, viewRegister: Int, method: String) =
this.addInstruction(insertIndex, method.buildHideCall(viewRegister))
context.classes.forEach { classDef ->
classDef.methods.forEach { method ->
with(method.implementation) {
this?.instructions?.forEachIndexed { index, instruction ->
if (instruction.opcode != org.jf.dexlib2.Opcode.CONST)
return@forEachIndexed
// Instruction to store the id adAttribution into a register
if ((instruction as Instruction31i).wideLiteral != GeneralAdsResourcePatch.adAttributionId)
return@forEachIndexed
val insertIndex = index + 1
// Call to get the view with the id adAttribution
with(instructions.elementAt(insertIndex)) {
if (opcode != org.jf.dexlib2.Opcode.INVOKE_VIRTUAL)
return@forEachIndexed
// Hide the view
val viewRegister = (this as Instruction35c).registerC
context.proxy(classDef)
.mutableClass
.findMutableMethodOf(method)
.injectHideCall(insertIndex, viewRegister, "hideAdAttributionView")
}
}
}
}
}
with(
ReelConstructorFingerprint.result
?: return PatchResultError("Could not resolve fingerprint")
) {
// iput-object v$viewRegister, ...
val insertIndex = this.scanResult.patternScanResult!!.startIndex + 2
with(this.mutableMethod) {
val viewRegister = (instruction(insertIndex) as TwoRegisterInstruction).registerA
injectHideCall(insertIndex, viewRegister, "hideReelView")
}
}
return PatchResultSuccess()
}
}

View File

@@ -1,14 +1,12 @@
package app.revanced.patches.youtube.ad.general.patch package app.revanced.patches.youtube.ad.general.resource.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patches.shared.mapping.patch.ResourceMappingPatch
import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility
import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
@@ -16,81 +14,81 @@ import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch.PreferenceScreen import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.framework.components.impl.* import app.revanced.patches.youtube.misc.settings.framework.components.impl.*
@Patch @DependsOn(dependencies = [
@DependsOn(dependencies = [FixLocaleConfigErrorPatch::class, LithoFilterPatch::class, SettingsPatch::class]) FixLocaleConfigErrorPatch::class,
@Name("general-ads") LithoFilterPatch::class,
@Description("Removes general ads.") SettingsPatch::class,
ResourceMappingPatch::class
])
@GeneralAdsCompatibility @GeneralAdsCompatibility
@Version("0.0.1") @Version("0.0.1")
class GeneralAdsPatch : ResourcePatch { class GeneralAdsResourcePatch : ResourcePatch {
internal companion object {
var adAttributionId: Long = -1
var reelMultipleItemShelfId: Long = -1
}
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {
PreferenceScreen.ADS.addPreferences( PreferenceScreen.ADS.addPreferences(
SwitchPreference(
"revanced_home_ads_removal",
StringResource("revanced_home_ads_removal_title", "Remove home ads"),
true,
StringResource("revanced_home_ads_removal_summary_on", "Home ads are hidden"),
StringResource("revanced_home_ads_removal_summary_off", "Home ads are shown")
),
SwitchPreference( SwitchPreference(
"revanced_adremover_ad_removal", "revanced_adremover_ad_removal",
StringResource("revanced_adremover_ad_removal_enabled_title", "Remove general ads"), StringResource("revanced_adremover_ad_removal_enabled_title", "Hide general ads"),
true, true,
StringResource("revanced_adremover_ad_removal_enabled_summary_on", "General ads are hidden"), StringResource("revanced_adremover_ad_removal_enabled_summary_on", "General ads are hidden"),
StringResource("revanced_adremover_ad_removal_enabled_summary_off", "General ads are shown") StringResource("revanced_adremover_ad_removal_enabled_summary_off", "General ads are shown")
), ),
SwitchPreference( SwitchPreference(
"revanced_adremover_buttoned", "revanced_adremover_buttoned",
StringResource("revanced_adremover_buttoned_enabled_title", "Remove buttoned ad"), StringResource("revanced_adremover_buttoned_enabled_title", "Hide buttoned ad"),
true, true,
StringResource("revanced_adremover_buttoned_enabled_summary_on", "Buttoned ads are hidden"), StringResource("revanced_adremover_buttoned_enabled_summary_on", "Buttoned ads are hidden"),
StringResource("revanced_adremover_buttoned_enabled_summary_off", "Buttoned ads are shown") StringResource("revanced_adremover_buttoned_enabled_summary_off", "Buttoned ads are shown")
), ),
SwitchPreference( SwitchPreference(
"revanced_adremover_merchandise", "revanced_adremover_merchandise",
StringResource("revanced_adremover_merchandise_enabled_title", "Remove merchandise banners"), StringResource("revanced_adremover_merchandise_enabled_title", "Hide merchandise banners"),
true, true,
StringResource("revanced_adremover_merchandise_enabled_summary_on", "Merchandise banners are hidden"), StringResource("revanced_adremover_merchandise_enabled_summary_on", "Merchandise banners are hidden"),
StringResource("revanced_adremover_merchandise_enabled_summary_off", "Merchandise banners are shown") StringResource("revanced_adremover_merchandise_enabled_summary_off", "Merchandise banners are shown")
), ),
SwitchPreference( SwitchPreference(
"revanced_adremover_community_posts_removal", "revanced_adremover_community_posts_removal",
StringResource("revanced_adremover_community_posts_enabled_title", "Remove community posts"), StringResource("revanced_adremover_community_posts_enabled_title", "Hide community posts"),
false, false,
StringResource("revanced_adremover_community_posts_enabled_summary_on", "Community posts are hidden"), StringResource("revanced_adremover_community_posts_enabled_summary_on", "Community posts are hidden"),
StringResource("revanced_adremover_community_posts_enabled_summary_off", "Community posts are shown") StringResource("revanced_adremover_community_posts_enabled_summary_off", "Community posts are shown")
), ),
SwitchPreference( SwitchPreference(
"revanced_adremover_compact_banner_removal", "revanced_adremover_compact_banner_removal",
StringResource("revanced_adremover_compact_banner_enabled_title", "Remove compact banners"), StringResource("revanced_adremover_compact_banner_enabled_title", "Hide compact banners"),
true, true,
StringResource("revanced_adremover_compact_banner_enabled_summary_on", "Compact banners are hidden"), StringResource("revanced_adremover_compact_banner_enabled_summary_on", "Compact banners are hidden"),
StringResource("revanced_adremover_compact_banner_enabled_summary_off", "Compact banners are shown") StringResource("revanced_adremover_compact_banner_enabled_summary_off", "Compact banners are shown")
), ),
SwitchPreference( SwitchPreference(
"revanced_adremover_movie", "revanced_adremover_movie",
StringResource("revanced_adremover_movie_enabled_title", "Remove movies section"), StringResource("revanced_adremover_movie_enabled_title", "Hide movies section"),
true, true,
StringResource("revanced_adremover_movie_enabled_summary_on", "Movies section is hidden"), StringResource("revanced_adremover_movie_enabled_summary_on", "Movies section is hidden"),
StringResource("revanced_adremover_movie_enabled_summary_off", "Movies section is shown") StringResource("revanced_adremover_movie_enabled_summary_off", "Movies section is shown")
), ),
SwitchPreference( SwitchPreference(
"revanced_adremover_feed_survey", "revanced_adremover_feed_survey",
StringResource("revanced_adremover_feed_survey_enabled_title", "Remove feed surveys"), StringResource("revanced_adremover_feed_survey_enabled_title", "Hide feed surveys"),
true, true,
StringResource("revanced_adremover_feed_survey_enabled_summary_on", "Feed surveys are hidden"), StringResource("revanced_adremover_feed_survey_enabled_summary_on", "Feed surveys are hidden"),
StringResource("revanced_adremover_feed_survey_enabled_summary_off", "Feed surveys are shown") StringResource("revanced_adremover_feed_survey_enabled_summary_off", "Feed surveys are shown")
), ),
SwitchPreference( SwitchPreference(
"revanced_adremover_shorts", "revanced_adremover_shorts",
StringResource("revanced_adremover_shorts_enabled_title", "Remove shorts"), StringResource("revanced_adremover_shorts_enabled_title", "Hide shorts"),
true, true,
StringResource("revanced_adremover_shorts_enabled_summary_on", "Shorts are hidden"), StringResource("revanced_adremover_shorts_enabled_summary_on", "Shorts are hidden"),
StringResource("revanced_adremover_shorts_enabled_summary_off", "Shorts are shown") StringResource("revanced_adremover_shorts_enabled_summary_off", "Shorts are shown")
), ),
SwitchPreference( SwitchPreference(
"revanced_adremover_community_guidelines", "revanced_adremover_community_guidelines",
StringResource("revanced_adremover_community_guidelines_enabled_title", "Remove community guidelines"), StringResource("revanced_adremover_community_guidelines_enabled_title", "Hide community guidelines"),
true, true,
StringResource( StringResource(
"revanced_adremover_community_guidelines_enabled_summary_on", "revanced_adremover_community_guidelines_enabled_summary_on",
@@ -103,28 +101,28 @@ class GeneralAdsPatch : ResourcePatch {
), ),
SwitchPreference( SwitchPreference(
"revanced_adremover_emergency_box_removal", "revanced_adremover_emergency_box_removal",
StringResource("revanced_adremover_emergency_box_enabled_title", "Remove emergency boxes"), StringResource("revanced_adremover_emergency_box_enabled_title", "Hide emergency boxes"),
true, true,
StringResource("revanced_adremover_emergency_box_enabled_summary_on", "Emergency boxes are hidden"), StringResource("revanced_adremover_emergency_box_enabled_summary_on", "Emergency boxes are hidden"),
StringResource("revanced_adremover_emergency_box_enabled_summary_off", "Emergency boxes are shown") StringResource("revanced_adremover_emergency_box_enabled_summary_off", "Emergency boxes are shown")
), ),
SwitchPreference( SwitchPreference(
"revanced_adremover_info_panel", "revanced_adremover_info_panel",
StringResource("revanced_adremover_info_panel_enabled_title", "Remove info panels"), StringResource("revanced_adremover_info_panel_enabled_title", "Hide info panels"),
true, true,
StringResource("revanced_adremover_info_panel_enabled_summary_on", "Info panels are hidden"), StringResource("revanced_adremover_info_panel_enabled_summary_on", "Info panels are hidden"),
StringResource("revanced_adremover_info_panel_enabled_summary_off", "Info panels are shown") StringResource("revanced_adremover_info_panel_enabled_summary_off", "Info panels are shown")
), ),
SwitchPreference( SwitchPreference(
"revanced_adremover_medical_panel", "revanced_adremover_medical_panel",
StringResource("revanced_adremover_medical_panel_enabled_title", "Remove medical panels"), StringResource("revanced_adremover_medical_panel_enabled_title", "Hide medical panels"),
true, true,
StringResource("revanced_adremover_medical_panel_enabled_summary_on", "Medical panels are hidden"), StringResource("revanced_adremover_medical_panel_enabled_summary_on", "Medical panels are hidden"),
StringResource("revanced_adremover_medical_panel_enabled_summary_off", "Medical panels are shown") StringResource("revanced_adremover_medical_panel_enabled_summary_off", "Medical panels are shown")
), ),
SwitchPreference( SwitchPreference(
"revanced_adremover_paid_content", "revanced_adremover_paid_content",
StringResource("revanced_adremover_paid_content_enabled_title", "Remove paid content"), StringResource("revanced_adremover_paid_content_enabled_title", "Hide paid content"),
true, true,
StringResource("revanced_adremover_paid_content_enabled_summary_on", "Paid content is hidden"), StringResource("revanced_adremover_paid_content_enabled_summary_on", "Paid content is hidden"),
StringResource("revanced_adremover_paid_content_enabled_summary_off", "Paid content is shown") StringResource("revanced_adremover_paid_content_enabled_summary_off", "Paid content is shown")
@@ -221,6 +219,11 @@ class GeneralAdsPatch : ResourcePatch {
) )
) )
fun String.getId() = ResourceMappingPatch.resourceMappings.single { it.name == this }.id
adAttributionId = "ad_attribution".getId()
reelMultipleItemShelfId = "reel_multiple_items_shelf".getId()
return PatchResultSuccess() return PatchResultSuccess()
} }
} }

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -15,7 +15,7 @@ import app.revanced.patches.youtube.layout.autoplaybutton.annotations.AutoplayBu
import app.revanced.patches.youtube.layout.autoplaybutton.fingerprints.AutoNavInformerFingerprint import app.revanced.patches.youtube.layout.autoplaybutton.fingerprints.AutoNavInformerFingerprint
import app.revanced.patches.youtube.layout.autoplaybutton.fingerprints.LayoutConstructorFingerprint import app.revanced.patches.youtube.layout.autoplaybutton.fingerprints.LayoutConstructorFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch import app.revanced.patches.shared.mapping.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
@@ -25,7 +25,7 @@ import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
import org.jf.dexlib2.iface.reference.MethodReference import org.jf.dexlib2.iface.reference.MethodReference
@Patch @Patch
@DependsOn([IntegrationsPatch::class, SettingsPatch::class, ResourceMappingResourcePatch::class]) @DependsOn([IntegrationsPatch::class, SettingsPatch::class, ResourceMappingPatch::class])
@Name("hide-autoplay-button") @Name("hide-autoplay-button")
@Description("Hides the autoplay button in the video player.") @Description("Hides the autoplay button in the video player.")
@AutoplayButtonCompatibility @AutoplayButtonCompatibility
@@ -53,7 +53,7 @@ class HideAutoplayButtonPatch : BytecodePatch(
val layoutGenMethodInstructions = layoutGenMethod.implementation!!.instructions val layoutGenMethodInstructions = layoutGenMethod.implementation!!.instructions
// resolve the offsets such as ... // resolve the offsets such as ...
val autoNavPreviewStubId = ResourceMappingResourcePatch.resourceMappings.single { val autoNavPreviewStubId = ResourceMappingPatch.resourceMappings.single {
it.name == "autonav_preview_stub" it.name == "autonav_preview_stub"
}.id }.id
// where to insert the branch instructions and ... // where to insert the branch instructions and ...

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -11,14 +11,14 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
import app.revanced.patches.youtube.layout.buttons.annotations.HideButtonsCompatibility import app.revanced.patches.youtube.layout.buttons.annotations.HideButtonsCompatibility
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch import app.revanced.patches.shared.mapping.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.PreferenceScreen import app.revanced.patches.youtube.misc.settings.framework.components.impl.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
@Patch @Patch
@DependsOn([ResourceMappingResourcePatch::class, LithoFilterPatch::class]) @DependsOn([ResourceMappingPatch::class, LithoFilterPatch::class])
@Name("hide-video-buttons") @Name("hide-video-buttons")
@Description("Adds options to hide action buttons under a video.") @Description("Adds options to hide action buttons under a video.")
@HideButtonsCompatibility @HideButtonsCompatibility

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -8,7 +8,7 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.youtube.layout.comments.annotations.CommentsCompatibility import app.revanced.patches.youtube.layout.comments.annotations.CommentsCompatibility
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch import app.revanced.patches.shared.mapping.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.PreferenceScreen import app.revanced.patches.youtube.misc.settings.framework.components.impl.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
@@ -16,7 +16,7 @@ import app.revanced.patches.youtube.misc.settings.framework.components.impl.Swit
@Name("comments-resource-patch") @Name("comments-resource-patch")
@CommentsCompatibility @CommentsCompatibility
@DependsOn([SettingsPatch::class, ResourceMappingResourcePatch::class]) @DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@Version("0.0.1") @Version("0.0.1")
class CommentsResourcePatch : ResourcePatch { class CommentsResourcePatch : ResourcePatch {
companion object { companion object {
@@ -55,7 +55,7 @@ class CommentsResourcePatch : ResourcePatch {
) )
) )
shortsCommentsButtonId = ResourceMappingResourcePatch.resourceMappings.single { shortsCommentsButtonId = ResourceMappingPatch.resourceMappings.single {
it.type == "drawable" && it.name == "ic_right_comment_32c" it.type == "drawable" && it.name == "ic_right_comment_32c"
}.id }.id

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -8,14 +8,14 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.youtube.layout.hidealbumcards.annotations.AlbumCardsCompatibility import app.revanced.patches.youtube.layout.hidealbumcards.annotations.AlbumCardsCompatibility
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch import app.revanced.patches.shared.mapping.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
@Name("hide-album-cards-resource-patch") @Name("hide-album-cards-resource-patch")
@AlbumCardsCompatibility @AlbumCardsCompatibility
@DependsOn([SettingsPatch::class, ResourceMappingResourcePatch::class]) @DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@Version("0.0.1") @Version("0.0.1")
class AlbumCardsResourcePatch : ResourcePatch { class AlbumCardsResourcePatch : ResourcePatch {
companion object { companion object {
@@ -33,7 +33,7 @@ class AlbumCardsResourcePatch : ResourcePatch {
) )
) )
albumCardId = ResourceMappingResourcePatch.resourceMappings.single { albumCardId = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "album_card" it.type == "layout" && it.name == "album_card"
}.id }.id

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -11,13 +11,13 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
import app.revanced.patches.youtube.layout.buttons.annotations.HideArtistCardCompatibility import app.revanced.patches.youtube.layout.buttons.annotations.HideArtistCardCompatibility
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch import app.revanced.patches.shared.mapping.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
@Patch @Patch
@DependsOn([ResourceMappingResourcePatch::class, LithoFilterPatch::class]) @DependsOn([ResourceMappingPatch::class, LithoFilterPatch::class])
@Name("hide-artist-card") @Name("hide-artist-card")
@Description("Hides the artist card below the searchbar.") @Description("Hides the artist card below the searchbar.")
@HideArtistCardCompatibility @HideArtistCardCompatibility

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -8,14 +8,14 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.youtube.layout.hidecrowdfundingbox.annotations.CrowdfundingBoxCompatibility import app.revanced.patches.youtube.layout.hidecrowdfundingbox.annotations.CrowdfundingBoxCompatibility
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch import app.revanced.patches.shared.mapping.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
@Name("crowdfunding-box-resource-patch") @Name("crowdfunding-box-resource-patch")
@CrowdfundingBoxCompatibility @CrowdfundingBoxCompatibility
@DependsOn([SettingsPatch::class, ResourceMappingResourcePatch::class]) @DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@Version("0.0.1") @Version("0.0.1")
class CrowdfundingBoxResourcePatch : ResourcePatch { class CrowdfundingBoxResourcePatch : ResourcePatch {
companion object { companion object {
@@ -33,7 +33,7 @@ class CrowdfundingBoxResourcePatch : ResourcePatch {
) )
) )
crowdfundingBoxId = ResourceMappingResourcePatch.resourceMappings.single { crowdfundingBoxId = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "donation_companion" it.type == "layout" && it.name == "donation_companion"
}.id }.id

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -8,14 +8,14 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch import app.revanced.patches.shared.mapping.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
@Name("hide-endscreen-cards-resource-patch") @Name("hide-endscreen-cards-resource-patch")
@HideEndscreenCardsCompatibility @HideEndscreenCardsCompatibility
@DependsOn([SettingsPatch::class, ResourceMappingResourcePatch::class]) @DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@Version("0.0.1") @Version("0.0.1")
class HideEndscreenCardsResourcePatch : ResourcePatch { class HideEndscreenCardsResourcePatch : ResourcePatch {
internal companion object { internal companion object {
@@ -35,7 +35,7 @@ class HideEndscreenCardsResourcePatch : ResourcePatch {
), ),
) )
fun findEndscreenResourceId(name: String) = ResourceMappingResourcePatch.resourceMappings.single { fun findEndscreenResourceId(name: String) = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "endscreen_element_layout_$name" it.type == "layout" && it.name == "endscreen_element_layout_$name"
}.id }.id

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -7,13 +7,13 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.youtube.layout.hideinfocards.annotations.HideInfocardsCompatibility import app.revanced.patches.youtube.layout.hideinfocards.annotations.HideInfocardsCompatibility
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch import app.revanced.patches.shared.mapping.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
@HideInfocardsCompatibility @HideInfocardsCompatibility
@DependsOn([SettingsPatch::class, ResourceMappingResourcePatch::class]) @DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@Version("0.0.1") @Version("0.0.1")
class HideInfocardsResourcePatch : ResourcePatch { class HideInfocardsResourcePatch : ResourcePatch {
internal companion object { internal companion object {
@@ -31,7 +31,7 @@ class HideInfocardsResourcePatch : ResourcePatch {
) )
) )
drawerResourceId = ResourceMappingResourcePatch.resourceMappings.single { drawerResourceId = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == "info_cards_drawer_header" it.type == "id" && it.name == "info_cards_drawer_header"
}.id }.id

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.36.39", "17.37.35", "17.38.36", "17.39.35", "17.40.41", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.36.39", "17.37.35", "17.38.36", "17.39.35", "17.40.41", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -8,14 +8,14 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.youtube.layout.personalinformation.annotations.HideEmailAddressCompatibility import app.revanced.patches.youtube.layout.personalinformation.annotations.HideEmailAddressCompatibility
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch import app.revanced.patches.shared.mapping.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
@Name("hide-email-address-resource-patch") @Name("hide-email-address-resource-patch")
@HideEmailAddressCompatibility @HideEmailAddressCompatibility
@DependsOn([SettingsPatch::class, ResourceMappingResourcePatch::class]) @DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@Version("0.0.1") @Version("0.0.1")
class HideEmailAddressResourcePatch : ResourcePatch { class HideEmailAddressResourcePatch : ResourcePatch {
companion object { companion object {
@@ -33,7 +33,7 @@ class HideEmailAddressResourcePatch : ResourcePatch {
) )
) )
accountSwitcherAccessibilityLabelId = ResourceMappingResourcePatch.resourceMappings.single { accountSwitcherAccessibilityLabelId = ResourceMappingPatch.resourceMappings.single {
it.type == "string" && it.name == "account_switcher_accessibility_label" it.type == "string" && it.name == "account_switcher_accessibility_label"
}.id }.id

View File

@@ -18,13 +18,13 @@ import app.revanced.patches.youtube.layout.pivotbar.fingerprints.PivotBarFingerp
import app.revanced.patches.youtube.layout.pivotbar.utils.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT import app.revanced.patches.youtube.layout.pivotbar.utils.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT
import app.revanced.patches.youtube.layout.pivotbar.utils.InjectionUtils.injectHook import app.revanced.patches.youtube.layout.pivotbar.utils.InjectionUtils.injectHook
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch import app.revanced.patches.shared.mapping.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
@Patch @Patch
@DependsOn([IntegrationsPatch::class, ResourceMappingResourcePatch::class, SettingsPatch::class]) @DependsOn([IntegrationsPatch::class, ResourceMappingPatch::class, SettingsPatch::class])
@Name("hide-create-button") @Name("hide-create-button")
@Description("Hides the create button in the navigation bar.") @Description("Hides the create button in the navigation bar.")
@CreateButtonCompatibility @CreateButtonCompatibility

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -21,7 +21,7 @@ import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlock
import app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints.* import app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints.*
import app.revanced.patches.youtube.layout.sponsorblock.resource.patch.SponsorBlockResourcePatch import app.revanced.patches.youtube.layout.sponsorblock.resource.patch.SponsorBlockResourcePatch
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch import app.revanced.patches.shared.mapping.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch
import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch
import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch
@@ -158,9 +158,9 @@ class SponsorBlockBytecodePatch : BytecodePatch(
val controlsMethodResult = PlayerControlsBytecodePatch.showPlayerControlsFingerprintResult val controlsMethodResult = PlayerControlsBytecodePatch.showPlayerControlsFingerprintResult
val controlsLayoutStubResourceId = val controlsLayoutStubResourceId =
ResourceMappingResourcePatch.resourceMappings.single { it.type == "id" && it.name == "controls_layout_stub" }.id ResourceMappingPatch.resourceMappings.single { it.type == "id" && it.name == "controls_layout_stub" }.id
val zoomOverlayResourceId = val zoomOverlayResourceId =
ResourceMappingResourcePatch.resourceMappings.single { it.type == "id" && it.name == "video_zoom_overlay_stub" }.id ResourceMappingPatch.resourceMappings.single { it.type == "id" && it.name == "video_zoom_overlay_stub" }.id
methods@ for (method in controlsMethodResult.mutableClass.methods) { methods@ for (method in controlsMethodResult.mutableClass.methods) {
val instructions = method.implementation?.instructions!! val instructions = method.implementation?.instructions!!

View File

@@ -9,7 +9,7 @@ import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch import app.revanced.patches.shared.mapping.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.Preference import app.revanced.patches.youtube.misc.settings.framework.components.impl.Preference
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
@@ -20,7 +20,7 @@ import app.revanced.util.resources.ResourceUtils.copyXmlNode
@Name("sponsorblock-resource-patch") @Name("sponsorblock-resource-patch")
@SponsorBlockCompatibility @SponsorBlockCompatibility
@DependsOn([FixLocaleConfigErrorPatch::class, SettingsPatch::class, ResourceMappingResourcePatch::class]) @DependsOn([FixLocaleConfigErrorPatch::class, SettingsPatch::class, ResourceMappingPatch::class])
@Version("0.0.1") @Version("0.0.1")
class SponsorBlockResourcePatch : ResourcePatch { class SponsorBlockResourcePatch : ResourcePatch {
companion object { companion object {
@@ -107,7 +107,7 @@ class SponsorBlockResourcePatch : ResourcePatch {
} }
}.close() // close afterwards }.close() // close afterwards
reelButtonGroupResourceId = ResourceMappingResourcePatch.resourceMappings.single { reelButtonGroupResourceId = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == "reel_persistent_edu_button_group" it.type == "id" && it.name == "reel_persistent_edu_button_group"
}.id }.id

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,11 +5,9 @@ import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.instruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.layout.theme.annotations.ThemeCompatibility import app.revanced.patches.youtube.layout.theme.annotations.ThemeCompatibility
import app.revanced.patches.youtube.layout.theme.fingerprints.LithoThemeFingerprint import app.revanced.patches.youtube.layout.theme.fingerprints.LithoThemeFingerprint

View File

@@ -13,7 +13,7 @@ import app.revanced.util.resources.ResourceUtils
import app.revanced.util.resources.ResourceUtils.copyResources import app.revanced.util.resources.ResourceUtils.copyResources
import org.w3c.dom.Element import org.w3c.dom.Element
@Patch @Patch(include = false)
@DependsOn([LithoThemePatch::class, FixLocaleConfigErrorPatch::class]) @DependsOn([LithoThemePatch::class, FixLocaleConfigErrorPatch::class])
@Name("theme") @Name("theme")
@Description("Applies a custom theme.") @Description("Applies a custom theme.")

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -2,12 +2,12 @@ package app.revanced.patches.youtube.misc.integrations.fingerprints
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility
import app.revanced.shared.patches.AbstractIntegrationsPatch.IntegrationsFingerprint
@Name("init-fingerprint") @Name("init-fingerprint")
@IntegrationsCompatibility @IntegrationsCompatibility
@Version("0.0.1") @Version("0.0.1")
object InitFingerprint : MethodFingerprint( object InitFingerprint : IntegrationsFingerprint(
strings = listOf("Application creation") strings = listOf("Application creation"),
) )

View File

@@ -2,12 +2,13 @@ package app.revanced.patches.youtube.misc.integrations.fingerprints
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility
import app.revanced.shared.patches.AbstractIntegrationsPatch.IntegrationsFingerprint
@Name("service-fingerprint") @Name("service-fingerprint")
@IntegrationsCompatibility @IntegrationsCompatibility
@Version("0.0.1") @Version("0.0.1")
object ServiceFingerprint : MethodFingerprint( object ServiceFingerprint : IntegrationsFingerprint(
customFingerprint = { methodDef -> methodDef.definingClass.endsWith("ApiPlayerService;") && methodDef.name == "<init>" } customFingerprint = { methodDef -> methodDef.definingClass.endsWith("ApiPlayerService;") && methodDef.name == "<init>" },
contextRegisterResolver = { it.implementation!!.registerCount - it.parameters.size }
) )

View File

@@ -2,15 +2,15 @@ package app.revanced.patches.youtube.misc.integrations.fingerprints
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility
import app.revanced.shared.patches.AbstractIntegrationsPatch.IntegrationsFingerprint
@Name("standalone-player-fingerprint") @Name("standalone-player-fingerprint")
@IntegrationsCompatibility @IntegrationsCompatibility
@Version("0.0.1") @Version("0.0.1")
object StandalonePlayerFingerprint : MethodFingerprint( object StandalonePlayerFingerprint : IntegrationsFingerprint(
strings = listOf( strings = listOf(
"Invalid PlaybackStartDescriptor. Returning the instance itself.", "Invalid PlaybackStartDescriptor. Returning the instance itself.",
"com.google.android.music", "com.google.android.music",
) ),
) )

View File

@@ -1,59 +1,15 @@
package app.revanced.patches.youtube.misc.integrations.patch package app.revanced.patches.youtube.misc.integrations.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.MethodFingerprintExtensions.name
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patcher.util.smali.toInstructions
import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility
import app.revanced.patches.youtube.misc.integrations.fingerprints.InitFingerprint import app.revanced.patches.youtube.misc.integrations.fingerprints.InitFingerprint
import app.revanced.patches.youtube.misc.integrations.fingerprints.ServiceFingerprint import app.revanced.patches.youtube.misc.integrations.fingerprints.ServiceFingerprint
import app.revanced.patches.youtube.misc.integrations.fingerprints.StandalonePlayerFingerprint import app.revanced.patches.youtube.misc.integrations.fingerprints.StandalonePlayerFingerprint
import org.jf.dexlib2.AccessFlags import app.revanced.shared.patches.AbstractIntegrationsPatch
import org.jf.dexlib2.immutable.ImmutableMethod
import org.jf.dexlib2.immutable.ImmutableMethodImplementation
@Name("integrations") @Name("integrations")
@Description("Applies mandatory patches to implement the ReVanced integrations into the application.")
@IntegrationsCompatibility @IntegrationsCompatibility
@Version("0.0.1") class IntegrationsPatch : AbstractIntegrationsPatch(
class IntegrationsPatch : BytecodePatch( "Lapp/revanced/integrations/utils/ReVancedUtils;",
listOf( listOf(InitFingerprint, StandalonePlayerFingerprint, ServiceFingerprint),
InitFingerprint, StandalonePlayerFingerprint, ServiceFingerprint )
)
) {
companion object {
private const val INTEGRATIONS_DESCRIPTOR = "Lapp/revanced/integrations/utils/ReVancedUtils;"
}
override fun execute(context: BytecodeContext): PatchResult {
if (context.findClass(INTEGRATIONS_DESCRIPTOR) == null)
return PatchResultError("Integrations have not been merged yet. This patch can not succeed without merging the integrations.")
arrayOf(InitFingerprint, StandalonePlayerFingerprint, ServiceFingerprint).map {
it to (it.result ?: return PatchResultError("${it.name} failed to resolve"))
}.forEach { (fingerprint, result) ->
with(result.mutableMethod) {
// parameter which holds the context
val contextParameter = if (fingerprint == ServiceFingerprint) parameters.size else 1
// register which holds the context
val contextRegister = implementation!!.registerCount - contextParameter
addInstruction(
0,
"sput-object v$contextRegister, $INTEGRATIONS_DESCRIPTOR->context:Landroid/content/Context;"
)
}
}
return PatchResultSuccess()
}
}

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.34.36", "17.36.39", "17.38.36", "17.39.35" , "17.40.41", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.34.36", "17.36.39", "17.38.36", "17.39.35" , "17.40.41", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -11,14 +11,14 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch import app.revanced.patches.shared.mapping.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.playercontrols.annotation.PlayerControlsCompatibility import app.revanced.patches.youtube.misc.playercontrols.annotation.PlayerControlsCompatibility
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.BottomControlsInflateFingerprint import app.revanced.patches.youtube.misc.playercontrols.fingerprints.BottomControlsInflateFingerprint
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint import app.revanced.patches.youtube.misc.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Name("player-controls-bytecode-patch") @Name("player-controls-bytecode-patch")
@DependsOn([ResourceMappingResourcePatch::class]) @DependsOn([ResourceMappingPatch::class])
@Description("Manages the code for the player controls of the YouTube player.") @Description("Manages the code for the player controls of the YouTube player.")
@PlayerControlsCompatibility @PlayerControlsCompatibility
@Version("0.0.1") @Version("0.0.1")
@@ -28,7 +28,7 @@ class PlayerControlsBytecodePatch : BytecodePatch(
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
showPlayerControlsFingerprintResult = PlayerControlsVisibilityFingerprint.result!! showPlayerControlsFingerprintResult = PlayerControlsVisibilityFingerprint.result!!
bottomUiContainerResourceId = ResourceMappingResourcePatch bottomUiContainerResourceId = ResourceMappingPatch
.resourceMappings .resourceMappings
.single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id .single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -9,7 +9,7 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch import app.revanced.patches.shared.mapping.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.settings.annotations.SettingsCompatibility import app.revanced.patches.youtube.misc.settings.annotations.SettingsCompatibility
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.BasePreference import app.revanced.patches.youtube.misc.settings.framework.components.BasePreference
@@ -21,14 +21,14 @@ import org.w3c.dom.Node
@Name("settings-resource-patch") @Name("settings-resource-patch")
@SettingsCompatibility @SettingsCompatibility
@DependsOn([FixLocaleConfigErrorPatch::class, ResourceMappingResourcePatch::class]) @DependsOn([FixLocaleConfigErrorPatch::class, ResourceMappingPatch::class])
@Version("0.0.1") @Version("0.0.1")
class SettingsResourcePatch : ResourcePatch { class SettingsResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {
/* /*
* used by a fingerprint of SettingsPatch * used by a fingerprint of SettingsPatch
*/ */
appearanceStringId = ResourceMappingResourcePatch.resourceMappings.find { appearanceStringId = ResourceMappingPatch.resourceMappings.find {
it.type == "string" && it.name == "app_theme_appearance_dark" it.type == "string" && it.name == "app_theme_appearance_dark"
}!!.id }!!.id

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -0,0 +1,9 @@
package app.revanced.patches.youtube.misc.zoomhaptics.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("com.google.android.youtube")])
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class ZoomHapticsCompatibility

View File

@@ -0,0 +1,9 @@
package app.revanced.patches.youtube.misc.zoomhaptics.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object ZoomHapticsFingerprint : MethodFingerprint(
strings = listOf(
"Failed to haptics vibrate for video zoom"
)
)

View File

@@ -0,0 +1,54 @@
package app.revanced.patches.youtube.misc.zoomhaptics.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.instruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
import app.revanced.patches.youtube.misc.zoomhaptics.annotations.ZoomHapticsCompatibility
import app.revanced.patches.youtube.misc.zoomhaptics.fingerprints.ZoomHapticsFingerprint
@Patch
@Name("disable-zoom-haptics")
@Description("Disables haptics when zooming.")
@DependsOn([SettingsPatch::class])
@ZoomHapticsCompatibility
@Version("0.0.1")
class ZoomHapticsPatch : BytecodePatch(
listOf(ZoomHapticsFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
SettingsPatch.PreferenceScreen.MISC.addPreferences(
SwitchPreference(
"revanced_disable_zoom_haptics",
StringResource("revanced_disable_zoom_haptics_title", "Disable zoom haptics"),
true,
StringResource("revanced_disable_zoom_haptics_summary_on", "Haptics are disabled"),
StringResource("revanced_disable_zoom_haptics_summary_off", "Haptics are enabled")
)
)
val zoomHapticsFingerprintMethod = ZoomHapticsFingerprint.result!!.mutableMethod
zoomHapticsFingerprintMethod.addInstructions(
0, """
invoke-static { }, Lapp/revanced/integrations/patches/ZoomHapticsPatch;->shouldVibrate()Z
move-result v0
if-nez v0, :vibrate
return-void
""", listOf(ExternalLabel("vibrate", zoomHapticsFingerprintMethod.instruction(0)))
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,67 @@
package app.revanced.shared.patches
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.shared.patches.AbstractIntegrationsPatch.IntegrationsFingerprint.RegisterResolver
import org.jf.dexlib2.iface.Method
@Description("Applies mandatory patches to implement the ReVanced integrations into the application.")
@Version("0.0.1")
abstract class AbstractIntegrationsPatch(
private val integrationsDescriptor: String,
private val hooks: Iterable<IntegrationsFingerprint>
) : BytecodePatch(hooks) {
/**
* [MethodFingerprint] for integrations.
*
* @param contextRegisterResolver A [RegisterResolver] to get the register.
* @see MethodFingerprint
*/
abstract class IntegrationsFingerprint(
strings: Iterable<String>? = null,
customFingerprint: ((methodDef: Method) -> Boolean)? = null,
private val contextRegisterResolver: (Method) -> Int = object : RegisterResolver {}
) : MethodFingerprint(strings = strings, customFingerprint = customFingerprint) {
fun invoke(integrationsDescriptor: String): PatchResult {
result?.mutableMethod?.let { method ->
val contextRegister = contextRegisterResolver(method)
method.addInstruction(
0,
"sput-object v$contextRegister, " +
"$integrationsDescriptor->context:Landroid/content/Context;"
)
} ?: return PatchResultError("Could not find hook target fingerprint.")
return PatchResultSuccess()
}
interface RegisterResolver : (Method) -> Int {
override operator fun invoke(method: Method) = method.implementation!!.registerCount - 1
}
}
override fun execute(context: BytecodeContext): PatchResult {
if (context.findClass(integrationsDescriptor) == null) return MISSING_INTEGRATIONS
for (hook in hooks) hook.invoke(integrationsDescriptor).let {
if (it is PatchResultError) return it
}
return PatchResultSuccess()
}
private companion object {
val MISSING_INTEGRATIONS = PatchResultError(
"Integrations have not been merged yet. " +
"This patch can not succeed without merging the integrations."
)
}
}