Compare commits

...

17 Commits

Author SHA1 Message Date
semantic-release-bot
e53cc9bba9 chore(release): 4.8.0-dev.1 [skip ci]
# [4.8.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.7.0...v4.8.0-dev.1) (2024-04-21)

### Bug Fixes

* **YouTube - Hide video action buttons:** Remove obsolete `hide Shop button` ([#3057](https://github.com/ReVanced/revanced-patches/issues/3057)) ([fc43dd7](fc43dd709f))

### Features

* **YouTube - Hide Shorts components:** Hide like / dislike button in video ads ([#3062](https://github.com/ReVanced/revanced-patches/issues/3062)) ([3a018ff](3a018ff002))
2024-04-21 14:59:47 +00:00
LisoUseInAIKyrios
fc43dd709f fix(YouTube - Hide video action buttons): Remove obsolete hide Shop button (#3057) 2024-04-21 18:57:35 +04:00
LisoUseInAIKyrios
3a018ff002 feat(YouTube - Hide Shorts components): Hide like / dislike button in video ads (#3062) 2024-04-21 18:55:26 +04:00
LisoUseInAIKyrios
86f11480e7 chore: Fix duplicate strings that is confusing Crowdin 2024-04-21 08:03:11 +04:00
LisoUseInAIKyrios
0190d5a5c9 chore: Adjust hide fullscreen ads toast text, move hide Playables to feed menu 2024-04-21 06:06:16 +04:00
semantic-release-bot
50735fabbc chore(release): 4.7.0 [skip ci]
# [4.7.0](https://github.com/ReVanced/revanced-patches/compare/v4.6.0...v4.7.0) (2024-04-21)

### Bug Fixes

* **Tumblr - Fix old versions:** Improve reliability by removing remnances of Tumblr Live  ([#2988](https://github.com/ReVanced/revanced-patches/issues/2988)) ([1ac6127](1ac612798b))
* **YouTube - GmsCore support:** Prompt to disable battery optimizations, if not done already ([#2958](https://github.com/ReVanced/revanced-patches/issues/2958)) ([b80bb89](b80bb8969c))
* **YouTube - Hide ads:** rename `Hide paid content` to `Hide paid promotion label` ([#3026](https://github.com/ReVanced/revanced-patches/issues/3026)) ([58ce37b](58ce37b0d3))
* **YouTube - Hide load more button:** Include patch with `Hide layout components`, and hide button only in search feed  ([#2959](https://github.com/ReVanced/revanced-patches/issues/2959)) ([0e88306](0e88306f3f))
* **YouTube - Hide Shorts components:** Correctly hide Shorts if navigation tab is changed using device back button ([#3007](https://github.com/ReVanced/revanced-patches/issues/3007)) ([e97aaf4](e97aaf4aae))
* **YouTube - Player flyout menu:** Add hide Lock screen menu ([#2985](https://github.com/ReVanced/revanced-patches/issues/2985)) ([6175841](61758414c2))
* **YouTube - Spoof device dimensions:** Warn about potential performance issues ([#3039](https://github.com/ReVanced/revanced-patches/issues/3039)) ([cc7f79d](cc7f79d903))
* **YouTube Music - Remove upgrade button:** Fix compatibility with latest versions ([#3045](https://github.com/ReVanced/revanced-patches/issues/3045)) ([e329e1d](e329e1dd1a))

### Features

* Add `Hex` patch ([#3034](https://github.com/ReVanced/revanced-patches/issues/3034)) ([6fd46ad](6fd46ad9b6))
* **Amazon:** Add `Always allow deep-linking` patch ([#3000](https://github.com/ReVanced/revanced-patches/issues/3000)) ([f2fe0d5](f2fe0d5c6f))
* **Strava - Unlock subscription:** Remove compatible version constraint ([e798341](e7983411a7))
* **Twitter:** Add `Sanitize sharing links` patch ([#3003](https://github.com/ReVanced/revanced-patches/issues/3003)) ([b4e8beb](b4e8beb8ec))
* **YouTube - Hide layout components:** Add option to hide horizontal shelves ([#2951](https://github.com/ReVanced/revanced-patches/issues/2951)) ([122f042](122f04219f))
* **YouTube - Hide layout components:** Hide playables ([f85f518](f85f518fc9))
* **YouTube - Hide Shorts components:** Hide `Shop`, `Location` and `Save sound to playlist` buttons ([#3018](https://github.com/ReVanced/revanced-patches/issues/3018)) ([be76e49](be76e49a8b))
* **YouTube - Hide Shorts components:** Hide tagged products, hide search suggestions ([#3019](https://github.com/ReVanced/revanced-patches/issues/3019)) ([2e59965](2e59965bb5))
* **YouTube - Swipe controls:** Save and restore brightness and add auto-brightness toggle ([#2996](https://github.com/ReVanced/revanced-patches/issues/2996)) ([533f9a9](533f9a964d))
* **YouTube:** Add 'About' preference to settings menu ([#2981](https://github.com/ReVanced/revanced-patches/issues/2981)) ([c272333](c272333adb))
* **YouTube:** Match overlay icons style to YouTube ([#3023](https://github.com/ReVanced/revanced-patches/issues/3023)) ([366f754](366f754a6a))
* **YouTube:** Support version `19.09.38`, `19.10.39` and `19.11.43` ([#2971](https://github.com/ReVanced/revanced-patches/issues/2971)) ([96e17cf](96e17cf4de))
* **YT Music - Hide 'Get Music Premium' label:** Remove occurences of label in settings ([#3046](https://github.com/ReVanced/revanced-patches/issues/3046)) ([7ecd992](7ecd992def))
2024-04-21 01:49:13 +00:00
oSumAtrIX
653631703c chore: Merge branch dev to main (#2982) 2024-04-21 03:47:03 +02:00
semantic-release-bot
2587508944 chore(release): 4.7.0-dev.16 [skip ci]
# [4.7.0-dev.16](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.15...v4.7.0-dev.16) (2024-04-21)

### Features

* **YouTube - Swipe controls:** Save and restore brightness and add auto-brightness toggle ([#2996](https://github.com/ReVanced/revanced-patches/issues/2996)) ([533f9a9](533f9a964d))
2024-04-21 00:00:57 +00:00
MarcaD
533f9a964d feat(YouTube - Swipe controls): Save and restore brightness and add auto-brightness toggle (#2996)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2024-04-21 01:58:56 +02:00
semantic-release-bot
fb0b3bd673 chore(release): 4.7.0-dev.15 [skip ci]
# [4.7.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.14...v4.7.0-dev.15) (2024-04-20)

### Features

* **YouTube:** Support version `19.09.38`, `19.10.39` and `19.11.43` ([#2971](https://github.com/ReVanced/revanced-patches/issues/2971)) ([96e17cf](96e17cf4de))
2024-04-20 23:17:38 +00:00
LisoUseInAIKyrios
96e17cf4de feat(YouTube): Support version 19.09.38, 19.10.39 and 19.11.43 (#2971)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2024-04-21 01:15:31 +02:00
semantic-release-bot
a7bd0b111e chore(release): 4.7.0-dev.14 [skip ci]
# [4.7.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.13...v4.7.0-dev.14) (2024-04-20)

### Features

* **YT Music - Hide 'Get Music Premium' label:** Remove occurences of label in settings ([#3046](https://github.com/ReVanced/revanced-patches/issues/3046)) ([7ecd992](7ecd992def))
2024-04-20 22:39:55 +00:00
Alberto Ponces
7ecd992def feat(YT Music - Hide 'Get Music Premium' label): Remove occurences of label in settings (#3046)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2024-04-21 00:37:51 +02:00
semantic-release-bot
217d3c69ba chore(release): 4.7.0-dev.13 [skip ci]
# [4.7.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.12...v4.7.0-dev.13) (2024-04-18)

### Bug Fixes

* **YouTube Music - Remove upgrade button:** Fix compatibility with latest versions ([#3045](https://github.com/ReVanced/revanced-patches/issues/3045)) ([e329e1d](e329e1dd1a))
2024-04-18 23:18:22 +00:00
Alberto Ponces
e329e1dd1a fix(YouTube Music - Remove upgrade button): Fix compatibility with latest versions (#3045) 2024-04-19 01:16:25 +02:00
semantic-release-bot
6a8b669ba2 chore(release): 4.7.0-dev.12 [skip ci]
# [4.7.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.11...v4.7.0-dev.12) (2024-04-18)

### Features

* Add `Hex` patch ([#3034](https://github.com/ReVanced/revanced-patches/issues/3034)) ([6fd46ad](6fd46ad9b6))
2024-04-18 22:50:02 +00:00
oSumAtrIX
6fd46ad9b6 feat: Add Hex patch (#3034) 2024-04-18 21:37:46 +02:00
88 changed files with 748 additions and 307 deletions

View File

@@ -1,3 +1,81 @@
# [4.8.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.7.0...v4.8.0-dev.1) (2024-04-21)
### Bug Fixes
* **YouTube - Hide video action buttons:** Remove obsolete `hide Shop button` ([#3057](https://github.com/ReVanced/revanced-patches/issues/3057)) ([b5e34f3](https://github.com/ReVanced/revanced-patches/commit/b5e34f3aabc1d9df8c41f92251618243caecdc9f))
### Features
* **YouTube - Hide Shorts components:** Hide like / dislike button in video ads ([#3062](https://github.com/ReVanced/revanced-patches/issues/3062)) ([1296985](https://github.com/ReVanced/revanced-patches/commit/12969853adfe530eb6006df38e1a5aa30b28fdf9))
# [4.7.0](https://github.com/ReVanced/revanced-patches/compare/v4.6.0...v4.7.0) (2024-04-21)
### Bug Fixes
* **Tumblr - Fix old versions:** Improve reliability by removing remnances of Tumblr Live ([#2988](https://github.com/ReVanced/revanced-patches/issues/2988)) ([897b4db](https://github.com/ReVanced/revanced-patches/commit/897b4dbce984270ae1fd7de5bd30bd05153e45f2))
* **YouTube - GmsCore support:** Prompt to disable battery optimizations, if not done already ([#2958](https://github.com/ReVanced/revanced-patches/issues/2958)) ([82acb84](https://github.com/ReVanced/revanced-patches/commit/82acb84b5f6ff0722a2eb080b53da9dd3622502f))
* **YouTube - Hide ads:** rename `Hide paid content` to `Hide paid promotion label` ([#3026](https://github.com/ReVanced/revanced-patches/issues/3026)) ([17e4ac9](https://github.com/ReVanced/revanced-patches/commit/17e4ac978a2f109fd62469a3163b636cd63c55ae))
* **YouTube - Hide load more button:** Include patch with `Hide layout components`, and hide button only in search feed ([#2959](https://github.com/ReVanced/revanced-patches/issues/2959)) ([b007e8e](https://github.com/ReVanced/revanced-patches/commit/b007e8e06a3afad79b40bec1c6a14604f059049c))
* **YouTube - Hide Shorts components:** Correctly hide Shorts if navigation tab is changed using device back button ([#3007](https://github.com/ReVanced/revanced-patches/issues/3007)) ([e5848e9](https://github.com/ReVanced/revanced-patches/commit/e5848e99c4cc838595164ef673a77fe60d28086b))
* **YouTube - Player flyout menu:** Add hide Lock screen menu ([#2985](https://github.com/ReVanced/revanced-patches/issues/2985)) ([308de4a](https://github.com/ReVanced/revanced-patches/commit/308de4a63ca99b8d30d6b3242f98d6f0e2aefb37))
* **YouTube - Spoof device dimensions:** Warn about potential performance issues ([#3039](https://github.com/ReVanced/revanced-patches/issues/3039)) ([9d6f305](https://github.com/ReVanced/revanced-patches/commit/9d6f305b7c923e62b89581d221fedbe1e3f81835))
* **YouTube Music - Remove upgrade button:** Fix compatibility with latest versions ([#3045](https://github.com/ReVanced/revanced-patches/issues/3045)) ([80de996](https://github.com/ReVanced/revanced-patches/commit/80de99666555694670529bbfe2e0be7a14d66555))
### Features
* Add `Hex` patch ([#3034](https://github.com/ReVanced/revanced-patches/issues/3034)) ([3c95aac](https://github.com/ReVanced/revanced-patches/commit/3c95aac838693b354d3a7b0e3dc57c6da5adfa9e))
* **Amazon:** Add `Always allow deep-linking` patch ([#3000](https://github.com/ReVanced/revanced-patches/issues/3000)) ([a92b7fb](https://github.com/ReVanced/revanced-patches/commit/a92b7fb43c8b1b45577360cdc6d883fe2815c2f2))
* **Strava - Unlock subscription:** Remove compatible version constraint ([80a5599](https://github.com/ReVanced/revanced-patches/commit/80a55991683d7b22626224fa2935a5bf9bfcbfee))
* **Twitter:** Add `Sanitize sharing links` patch ([#3003](https://github.com/ReVanced/revanced-patches/issues/3003)) ([186b887](https://github.com/ReVanced/revanced-patches/commit/186b8874157eef1b882b05d491ba1d4ca2809535))
* **YouTube - Hide layout components:** Add option to hide horizontal shelves ([#2951](https://github.com/ReVanced/revanced-patches/issues/2951)) ([9ae0650](https://github.com/ReVanced/revanced-patches/commit/9ae0650c0005d882299996aa442410bab4261395))
* **YouTube - Hide layout components:** Hide playables ([8423515](https://github.com/ReVanced/revanced-patches/commit/842351548baa33737db09be1cbca9f87c1951341))
* **YouTube - Hide Shorts components:** Hide `Shop`, `Location` and `Save sound to playlist` buttons ([#3018](https://github.com/ReVanced/revanced-patches/issues/3018)) ([5210ac4](https://github.com/ReVanced/revanced-patches/commit/5210ac431c191987264865bf8e789ea9f3fdd360))
* **YouTube - Hide Shorts components:** Hide tagged products, hide search suggestions ([#3019](https://github.com/ReVanced/revanced-patches/issues/3019)) ([e0d2fe5](https://github.com/ReVanced/revanced-patches/commit/e0d2fe5bd2e681b9a5252a8e4ad582cc019b1606))
* **YouTube - Swipe controls:** Save and restore brightness and add auto-brightness toggle ([#2996](https://github.com/ReVanced/revanced-patches/issues/2996)) ([f6c3bc4](https://github.com/ReVanced/revanced-patches/commit/f6c3bc43190d33e06f49b74fc056d26da1bb014a))
* **YouTube:** Add 'About' preference to settings menu ([#2981](https://github.com/ReVanced/revanced-patches/issues/2981)) ([5abf894](https://github.com/ReVanced/revanced-patches/commit/5abf89444a3e6a211ec03c242eb9a7847542b08c))
* **YouTube:** Match overlay icons style to YouTube ([#3023](https://github.com/ReVanced/revanced-patches/issues/3023)) ([6849393](https://github.com/ReVanced/revanced-patches/commit/684939314be3d0d43482f229b2adb033e7aa492a))
* **YouTube:** Support version `19.09.38`, `19.10.39` and `19.11.43` ([#2971](https://github.com/ReVanced/revanced-patches/issues/2971)) ([730f3e3](https://github.com/ReVanced/revanced-patches/commit/730f3e3a7e058b60f9a8130980ecb0a747fa0a8a))
* **YT Music - Hide 'Get Music Premium' label:** Remove occurences of label in settings ([#3046](https://github.com/ReVanced/revanced-patches/issues/3046)) ([10e170a](https://github.com/ReVanced/revanced-patches/commit/10e170a7302fdb585efee663ca13c814aea46c54))
# [4.7.0-dev.16](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.15...v4.7.0-dev.16) (2024-04-21)
### Features
* **YouTube - Swipe controls:** Save and restore brightness and add auto-brightness toggle ([#2996](https://github.com/ReVanced/revanced-patches/issues/2996)) ([f6c3bc4](https://github.com/ReVanced/revanced-patches/commit/f6c3bc43190d33e06f49b74fc056d26da1bb014a))
# [4.7.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.14...v4.7.0-dev.15) (2024-04-20)
### Features
* **YouTube:** Support version `19.09.38`, `19.10.39` and `19.11.43` ([#2971](https://github.com/ReVanced/revanced-patches/issues/2971)) ([730f3e3](https://github.com/ReVanced/revanced-patches/commit/730f3e3a7e058b60f9a8130980ecb0a747fa0a8a))
# [4.7.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.13...v4.7.0-dev.14) (2024-04-20)
### Features
* **YT Music - Hide 'Get Music Premium' label:** Remove occurences of label in settings ([#3046](https://github.com/ReVanced/revanced-patches/issues/3046)) ([10e170a](https://github.com/ReVanced/revanced-patches/commit/10e170a7302fdb585efee663ca13c814aea46c54))
# [4.7.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.12...v4.7.0-dev.13) (2024-04-18)
### Bug Fixes
* **YouTube Music - Remove upgrade button:** Fix compatibility with latest versions ([#3045](https://github.com/ReVanced/revanced-patches/issues/3045)) ([80de996](https://github.com/ReVanced/revanced-patches/commit/80de99666555694670529bbfe2e0be7a14d66555))
# [4.7.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.11...v4.7.0-dev.12) (2024-04-18)
### Features
* Add `Hex` patch ([#3034](https://github.com/ReVanced/revanced-patches/issues/3034)) ([3c95aac](https://github.com/ReVanced/revanced-patches/commit/3c95aac838693b354d3a7b0e3dc57c6da5adfa9e))
# [4.7.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.10...v4.7.0-dev.11) (2024-04-18) # [4.7.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.10...v4.7.0-dev.11) (2024-04-18)

View File

@@ -28,6 +28,10 @@ public final class app/revanced/patches/all/misc/debugging/EnableAndroidDebuggin
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
} }
public final class app/revanced/patches/all/misc/hex/HexPatch : app/revanced/patches/shared/misc/hex/BaseHexPatch {
public fun <init> ()V
}
public final class app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch : app/revanced/patcher/patch/ResourcePatch { public final class app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch : app/revanced/patcher/patch/ResourcePatch {
public static final field INSTANCE Lapp/revanced/patches/all/misc/network/OverrideCertificatePinningPatch; public static final field INSTANCE Lapp/revanced/patches/all/misc/network/OverrideCertificatePinningPatch;
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
@@ -669,6 +673,21 @@ public abstract class app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportRes
protected final fun getGmsCoreVendorGroupId ()Ljava/lang/String; protected final fun getGmsCoreVendorGroupId ()Ljava/lang/String;
} }
public abstract class app/revanced/patches/shared/misc/hex/BaseHexPatch : app/revanced/patcher/patch/RawResourcePatch {
public fun <init> ()V
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
}
public final class app/revanced/patches/shared/misc/hex/BaseHexPatch$Replacement {
public static final field Companion Lapp/revanced/patches/shared/misc/hex/BaseHexPatch$Replacement$Companion;
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
public final fun replacePattern ([B)V
}
public final class app/revanced/patches/shared/misc/hex/BaseHexPatch$Replacement$Companion {
}
public abstract class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch : app/revanced/patcher/patch/BytecodePatch { public abstract class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch : app/revanced/patcher/patch/BytecodePatch {
public fun <init> (Ljava/lang/String;Ljava/util/Set;)V public fun <init> (Ljava/lang/String;Ljava/util/Set;)V
public fun <init> (Ljava/util/Set;)V public fun <init> (Ljava/util/Set;)V
@@ -705,6 +724,7 @@ public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatch
public static final field INSTANCE Lapp/revanced/patches/shared/misc/mapping/ResourceMappingPatch; public static final field INSTANCE Lapp/revanced/patches/shared/misc/mapping/ResourceMappingPatch;
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
public final fun get (Ljava/lang/String;Ljava/lang/String;)J
} }
public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatch$ResourceElement { public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatch$ResourceElement {
@@ -1827,11 +1847,12 @@ public final class app/revanced/patches/yuka/misc/unlockpremium/UnlockPremiumPat
public final class app/revanced/util/BytecodeUtilsKt { public final class app/revanced/util/BytecodeUtilsKt {
public static final fun containsWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z public static final fun containsWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z
public static final fun findIndexForIdResource (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
public static final fun findMutableMethodOf (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod; public static final fun findMutableMethodOf (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;
public static final fun getException (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/patch/PatchException; public static final fun getException (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/patch/PatchException;
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I
public static final fun indexOfFirstWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)I public static final fun indexOfFirstWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
public static final fun indexOfIdResource (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
public static final fun indexOfIdResourceOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
public static final fun injectHideViewCall (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;IILjava/lang/String;Ljava/lang/String;)V public static final fun injectHideViewCall (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;IILjava/lang/String;Ljava/lang/String;)V
public static final fun resultOrThrow (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/fingerprint/MethodFingerprintResult; public static final fun resultOrThrow (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/fingerprint/MethodFingerprintResult;
public static final fun returnEarly (Ljava/util/List;Z)V public static final fun returnEarly (Ljava/util/List;Z)V

View File

@@ -1,4 +1,4 @@
org.gradle.parallel = true org.gradle.parallel = true
org.gradle.caching = true org.gradle.caching = true
kotlin.code.style = official kotlin.code.style = official
version = 4.7.0-dev.11 version = 4.8.0-dev.1

View File

@@ -0,0 +1,55 @@
package app.revanced.patches.all.misc.hex
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.registerNewPatchOption
import app.revanced.patches.shared.misc.hex.BaseHexPatch
import app.revanced.util.Utils.trimIndentMultiline
import app.revanced.patcher.patch.Patch as PatchClass
@Patch(
name = "Hex",
description = "Replaces a hexadecimal patterns of bytes of files in an APK.",
use = false,
)
@Suppress("unused")
class HexPatch : BaseHexPatch() {
// TODO: Instead of stringArrayOption, use a custom option type to work around
// https://github.com/ReVanced/revanced-library/issues/48.
// Replace the custom option type with a stringArrayOption once the issue is resolved.
private val replacementsOption by registerNewPatchOption<PatchClass<*>, List<String>>(
key = "replacements",
title = "replacements",
description = """
Hexadecimal patterns to search for and replace with another in a target file.
A pattern is a sequence of case insensitive strings, each representing hexadecimal bytes, separated by spaces.
An example pattern is 'aa 01 02 FF'.
Every pattern must be followed by a pipe ('|'), the replacement pattern,
another pipe ('|'), and the path to the file to make the changes in relative to the APK root.
The replacement pattern must have the same length as the original pattern.
Full example of a valid input:
'aa 01 02 FF|00 00 00 00|path/to/file'
""".trimIndentMultiline(),
required = true,
valueType = "StringArray",
)
override val replacements
get() = replacementsOption!!.map { from ->
val (pattern, replacementPattern, targetFilePath) = try {
from.split("|", limit = 3)
} catch (e: Exception) {
throw PatchException(
"Invalid input: $from.\n" +
"Every pattern must be followed by a pipe ('|'), " +
"the replacement pattern, another pipe ('|'), " +
"and the path to the file to make the changes in relative to the APK root. ",
)
}
Replacement(pattern, replacementPattern, targetFilePath)
}
}

View File

@@ -2,23 +2,28 @@ package app.revanced.patches.music.layout.premium
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumFingerprint import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumFingerprint
import app.revanced.patches.music.layout.premium.fingerprints.MembershipSettingsFingerprint
import app.revanced.util.exception import app.revanced.util.exception
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@Patch( @Patch(
name = "Hide 'Get Music Premium' label", name = "Hide 'Get Music Premium' label",
description = "Hides the red \"Get Music Premium\" label from the account menu.", description = "Hides the \"Get Music Premium\" label from the account menu and settings.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")], compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
) )
@Suppress("unused") @Suppress("unused")
object HideGetPremiumPatch : BytecodePatch( object HideGetPremiumPatch : BytecodePatch(
setOf(HideGetPremiumFingerprint), setOf(
HideGetPremiumFingerprint,
MembershipSettingsFingerprint,
),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
HideGetPremiumFingerprint.result?.let { HideGetPremiumFingerprint.result?.let {
@@ -41,5 +46,13 @@ object HideGetPremiumPatch : BytecodePatch(
) )
} }
} ?: throw HideGetPremiumFingerprint.exception } ?: throw HideGetPremiumFingerprint.exception
MembershipSettingsFingerprint.result?.mutableMethod?.addInstructions(
0,
"""
const/4 v0, 0x0
return-object v0
""",
) ?: throw MembershipSettingsFingerprint.exception
} }
} }

View File

@@ -12,6 +12,8 @@ internal object HideGetPremiumFingerprint : MethodFingerprint(
listOf( listOf(
Opcode.IF_NEZ, Opcode.IF_NEZ,
Opcode.CONST_16, Opcode.CONST_16,
Opcode.GOTO,
Opcode.NOP,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
), ),
listOf("FEmusic_history", "FEmusic_offline"), listOf("FEmusic_history", "FEmusic_offline"),

View File

@@ -0,0 +1,20 @@
package app.revanced.patches.music.layout.premium.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal object MembershipSettingsFingerprint : MethodFingerprint(
returnType = "Ljava/lang/CharSequence;",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf(
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT
)
)

View File

@@ -13,6 +13,7 @@ internal object PivotBarConstructorFingerprint : MethodFingerprint(
Opcode.CHECK_CAST, Opcode.CHECK_CAST,
Opcode.INVOKE_INTERFACE, Opcode.INVOKE_INTERFACE,
Opcode.GOTO, Opcode.GOTO,
Opcode.NOP,
Opcode.IPUT_OBJECT, Opcode.IPUT_OBJECT,
Opcode.RETURN_VOID, Opcode.RETURN_VOID,
), ),

View File

@@ -0,0 +1,120 @@
package app.revanced.patches.shared.misc.hex
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.RawResourcePatch
import kotlin.math.max
abstract class BaseHexPatch : RawResourcePatch() {
internal abstract val replacements: List<Replacement>
override fun execute(context: ResourceContext) {
replacements.groupBy { it.targetFilePath }.forEach { (targetFilePath, replacements) ->
val targetFile = try {
context[targetFilePath, true]
} catch (e: Exception) {
throw PatchException("Could not find target file: $targetFilePath")
}
// TODO: Use a file channel to read and write the file instead of reading the whole file into memory,
// in order to reduce memory usage.
val targetFileBytes = targetFile.readBytes()
replacements.forEach { replacement ->
replacement.replacePattern(targetFileBytes)
}
targetFile.writeBytes(targetFileBytes)
}
}
/**
* Represents a pattern to search for and its replacement pattern.
*
* @property pattern The pattern to search for.
* @property replacementPattern The pattern to replace the [pattern] with.
* @property targetFilePath The path to the file to make the changes in relative to the APK root.
*/
class Replacement(
private val pattern: String,
replacementPattern: String,
internal val targetFilePath: String,
) {
private val patternBytes = pattern.toByteArrayPattern()
private val replacementPattern = replacementPattern.toByteArrayPattern()
init {
if (this.patternBytes.size != this.replacementPattern.size) {
throw PatchException("Pattern and replacement pattern must have the same length: $pattern")
}
}
/**
* Replaces the [patternBytes] with the [replacementPattern] in the [targetFileBytes].
*
* @param targetFileBytes The bytes of the file to make the changes in.
*/
fun replacePattern(targetFileBytes: ByteArray) {
val startIndex = indexOfPatternIn(targetFileBytes)
if (startIndex == -1) {
throw PatchException("Pattern not found in target file: $pattern")
}
replacementPattern.copyInto(targetFileBytes, startIndex)
}
// TODO: Allow searching in a file channel instead of a byte array to reduce memory usage.
/**
* Returns the index of the first occurrence of [patternBytes] in the haystack
* using the Boyer-Moore algorithm.
*
* @param haystack The array to search in.
*
* @return The index of the first occurrence of the [patternBytes] in the haystack or -1
* if the [patternBytes] is not found.
*/
private fun indexOfPatternIn(haystack: ByteArray): Int {
val needle = patternBytes
val haystackLength = haystack.size - 1
val needleLength = needle.size - 1
val right = IntArray(256) { -1 }
for (i in 0 until needleLength) right[needle[i].toInt().and(0xFF)] = i
var skip: Int
for (i in 0..haystackLength - needleLength) {
skip = 0
for (j in needleLength - 1 downTo 0)
if (needle[j] != haystack[i + j]) {
skip = max(1, j - right[haystack[i + j].toInt().and(0xFF)])
break
}
if (skip == 0) return i
}
return -1
}
companion object {
/**
* Convert a string representing a pattern of hexadecimal bytes to a byte array.
*
* @return The byte array representing the pattern.
* @throws PatchException If the pattern is invalid.
*/
private fun String.toByteArrayPattern() = try {
split(" ").map { it.toInt(16).toByte() }.toByteArray()
} catch (e: NumberFormatException) {
throw PatchException(
"Could not parse pattern: $this. A pattern is a sequence of case insensitive strings " +
"representing hexadecimal bytes separated by spaces",
e,
)
}
}
}
}

View File

@@ -8,19 +8,15 @@ import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
object ResourceMappingPatch : ResourcePatch() { object ResourceMappingPatch : ResourcePatch() {
internal lateinit var resourceMappings: List<ResourceElement> private val resourceMappings = Collections.synchronizedList(mutableListOf<ResourceElement>())
private set
private val THREAD_COUNT = Runtime.getRuntime().availableProcessors() private val THREAD_COUNT = Runtime.getRuntime().availableProcessors()
private val threadPoolExecutor = Executors.newFixedThreadPool(THREAD_COUNT) private val threadPoolExecutor = Executors.newFixedThreadPool(THREAD_COUNT)
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
// save the file in memory to concurrently read from // sSve the file in memory to concurrently read from it.
val resourceXmlFile = context.get("res/values/public.xml").readBytes() val resourceXmlFile = context.get("res/values/public.xml").readBytes()
// create a synchronized list to store the resource mappings
val mappings = Collections.synchronizedList(mutableListOf<ResourceElement>())
for (threadIndex in 0 until THREAD_COUNT) { for (threadIndex in 0 until THREAD_COUNT) {
threadPoolExecutor.execute thread@{ threadPoolExecutor.execute thread@{
context.xmlEditor[resourceXmlFile.inputStream()].use { editor -> context.xmlEditor[resourceXmlFile.inputStream()].use { editor ->
@@ -33,7 +29,7 @@ object ResourceMappingPatch : ResourcePatch() {
val batchStart = jobSize * threadIndex val batchStart = jobSize * threadIndex
val batchEnd = jobSize * (threadIndex + 1) val batchEnd = jobSize * (threadIndex + 1)
element@ for (i in batchStart until batchEnd) { element@ for (i in batchStart until batchEnd) {
// make sure to not go out of bounds when rounding errors occur at calculating the jobSize // Prevent out of bounds.
if (i >= resourcesLength) return@thread if (i >= resourcesLength) return@thread
val node = resources.item(i) val node = resources.item(i)
@@ -46,18 +42,18 @@ object ResourceMappingPatch : ResourcePatch() {
val id = node.getAttribute("id").substring(2).toLong(16) val id = node.getAttribute("id").substring(2).toLong(16)
mappings.add(ResourceElement(typeAttribute, nameAttribute, id)) resourceMappings.add(ResourceElement(typeAttribute, nameAttribute, id))
} }
} }
} }
} }
threadPoolExecutor threadPoolExecutor.also { it.shutdown() }.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS)
.also { it.shutdown() }
.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS)
resourceMappings = mappings
} }
operator fun get(type: String, name: String) = resourceMappings.first {
it.type == type && it.name == name
}.id
data class ResourceElement(val type: String, val name: String, val id: Long) data class ResourceElement(val type: String, val name: String, val id: Long)
} }

View File

@@ -11,12 +11,11 @@ object PremiumNavbarTabResourcePatch : ResourcePatch() {
internal var premiumTabId = -1L internal var premiumTabId = -1L
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
premiumTabId = ResourceMappingPatch.resourceMappings.single { premiumTabId = ResourceMappingPatch["id", "premium_tab"]
it.type == "id" && it.name == "premium_tab"
}.id
showBottomNavigationItemsTextId = ResourceMappingPatch.resourceMappings.single { showBottomNavigationItemsTextId = ResourceMappingPatch[
it.type == "bool" && it.name == "show_bottom_navigation_items_text" "bool",
}.id "show_bottom_navigation_items_text",
]
} }
} }

View File

@@ -62,7 +62,17 @@ object SettingsPatch : BytecodePatch(
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
PreferenceScreen.MISC.OTHER.addPreferences( PreferenceScreen.MISC.OTHER.addPreferences(
SwitchPreference("revanced_debug") // The debug setting is shared across multiple apps and the key must be the same.
// But the title and summary must be different, otherwise when the strings file is flattened
// for Crowdin push, Crowdin gets confused by the duplicate keys.
// FIXME: Ideally the shared debug strings are extracted into a common app group
// and then both apps import that. But for now unique unique title and summary keys also works.
SwitchPreference(
key = "revanced_debug",
titleKey = "revanced_twitch_debug_title",
summaryOnKey = "revanced_twitch_debug_summary_on",
summaryOffKey = "revanced_twitch_debug_summary_off"
)
) )
// Hook onCreate to handle fragment creation // Hook onCreate to handle fragment creation

View File

@@ -42,7 +42,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View File

@@ -14,8 +14,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
LithoFilterPatch::class, LithoFilterPatch::class,
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
] ],
) )
object HideAdsResourcePatch : ResourcePatch() { object HideAdsResourcePatch : ResourcePatch() {
private const val FILTER_CLASS_DESCRIPTOR = private const val FILTER_CLASS_DESCRIPTOR =
@@ -35,11 +35,11 @@ object HideAdsResourcePatch : ResourcePatch() {
SwitchPreference("revanced_hide_products_banner"), SwitchPreference("revanced_hide_products_banner"),
SwitchPreference("revanced_hide_shopping_links"), SwitchPreference("revanced_hide_shopping_links"),
SwitchPreference("revanced_hide_web_search_results"), SwitchPreference("revanced_hide_web_search_results"),
SwitchPreference("revanced_hide_merchandise_banners") SwitchPreference("revanced_hide_merchandise_banners"),
) )
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
adAttributionId = ResourceMappingPatch.resourceMappings.single { it.name == "ad_attribution" }.id adAttributionId = ResourceMappingPatch["id", "ad_attribution"]
} }
} }

View File

@@ -36,7 +36,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -41,7 +41,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -29,7 +29,9 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -35,7 +35,9 @@ import app.revanced.util.resultOrThrow
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -40,7 +40,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -36,7 +36,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
], ],

View File

@@ -20,7 +20,7 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
dependencies = [ dependencies = [
IntegrationsPatch::class, IntegrationsPatch::class,
PlayerTypeHookPatch::class, PlayerTypeHookPatch::class,
SwipeControlsResourcePatch::class SwipeControlsResourcePatch::class,
], ],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
@@ -42,17 +42,22 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
] "19.10.39",
) "19.11.43", // 19.12.x has an issue with opening YT using external links,
] // and the app then crashes if double tap to skip forward/back is immediately used.
// The stack trace shows a call coming from integrations SwipeController,
// but it may be a bug in YT itself as other target versions do not have this issue.
],
),
],
) )
@Suppress("unused") @Suppress("unused")
object SwipeControlsBytecodePatch : BytecodePatch( object SwipeControlsBytecodePatch : BytecodePatch(
setOf( setOf(
MainActivityFingerprint, MainActivityFingerprint,
SwipeControlsHostActivityFingerprint SwipeControlsHostActivityFingerprint,
) ),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
val wrapperClass = SwipeControlsHostActivityFingerprint.result!!.mutableClass val wrapperClass = SwipeControlsHostActivityFingerprint.result!!.mutableClass
@@ -74,7 +79,7 @@ object SwipeControlsBytecodePatch : BytecodePatch(
accessFlags and AccessFlags.FINAL.value.inv(), accessFlags and AccessFlags.FINAL.value.inv(),
annotations, annotations,
hiddenApiRestrictions, hiddenApiRestrictions,
implementation implementation,
).toMutable() ).toMutable()
} }
} }

View File

@@ -24,6 +24,7 @@ internal object SwipeControlsResourcePatch : ResourcePatch() {
SwitchPreference("revanced_swipe_press_to_engage"), SwitchPreference("revanced_swipe_press_to_engage"),
SwitchPreference("revanced_swipe_haptic_feedback"), SwitchPreference("revanced_swipe_haptic_feedback"),
SwitchPreference("revanced_swipe_save_and_restore_brightness"), SwitchPreference("revanced_swipe_save_and_restore_brightness"),
SwitchPreference("revanced_swipe_lowest_value_enable_auto_brightness"),
TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER), TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_text_overlay_size", inputType = InputType.NUMBER), TextPreference("revanced_swipe_text_overlay_size", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_overlay_background_alpha", inputType = InputType.NUMBER), TextPreference("revanced_swipe_overlay_background_alpha", inputType = InputType.NUMBER),

View File

@@ -40,7 +40,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
], ],

View File

@@ -39,7 +39,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]
@@ -63,8 +65,7 @@ object HideButtonsPatch : ResourcePatch() {
SwitchPreference("revanced_hide_download_button"), SwitchPreference("revanced_hide_download_button"),
SwitchPreference("revanced_hide_thanks_button"), SwitchPreference("revanced_hide_thanks_button"),
SwitchPreference("revanced_hide_clip_button"), SwitchPreference("revanced_hide_clip_button"),
SwitchPreference("revanced_hide_playlist_button"), SwitchPreference("revanced_hide_playlist_button")
SwitchPreference("revanced_hide_shop_button")
), ),
) )
) )

View File

@@ -14,7 +14,7 @@ import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.shared.fingerprints.LayoutConstructorFingerprint import app.revanced.patches.youtube.shared.fingerprints.LayoutConstructorFingerprint
import app.revanced.util.exception import app.revanced.util.exception
import app.revanced.util.findIndexForIdResource import app.revanced.util.indexOfIdResourceOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.Instruction import com.android.tools.smali.dexlib2.iface.instruction.Instruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@@ -27,7 +27,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
IntegrationsPatch::class, IntegrationsPatch::class,
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
@@ -49,27 +49,29 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
] "19.10.39",
) "19.11.43",
] ],
),
],
) )
@Suppress("unused") @Suppress("unused")
object HideAutoplayButtonPatch : BytecodePatch( object HideAutoplayButtonPatch : BytecodePatch(
setOf(LayoutConstructorFingerprint) setOf(LayoutConstructorFingerprint),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences( SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_autoplay_button") SwitchPreference("revanced_hide_autoplay_button"),
) )
LayoutConstructorFingerprint.result?.mutableMethod?.apply { LayoutConstructorFingerprint.result?.mutableMethod?.apply {
val layoutGenMethodInstructions = implementation!!.instructions val layoutGenMethodInstructions = implementation!!.instructions
// resolve the offsets of where to insert the branch instructions and ... // resolve the offsets of where to insert the branch instructions and ...
val insertIndex = findIndexForIdResource("autonav_preview_stub") val insertIndex = indexOfIdResourceOrThrow("autonav_preview_stub")
// where to branch away // where to branch away
val branchIndex = val branchIndex =
@@ -90,7 +92,7 @@ object HideAutoplayButtonPatch : BytecodePatch(
move-result v$clobberRegister move-result v$clobberRegister
if-eqz v$clobberRegister, :hidden if-eqz v$clobberRegister, :hidden
""", """,
ExternalLabel("hidden", jumpInstruction) ExternalLabel("hidden", jumpInstruction),
) )
} ?: throw LayoutConstructorFingerprint.exception } ?: throw LayoutConstructorFingerprint.exception
} }

View File

@@ -40,7 +40,9 @@ import com.android.tools.smali.dexlib2.Opcode
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -47,7 +47,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37", "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View File

@@ -44,7 +44,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction3rc
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
) )
internal object AlbumCardsResourcePatch : ResourcePatch() { internal object AlbumCardsResourcePatch : ResourcePatch() {
@@ -22,11 +22,9 @@ internal object AlbumCardsResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.FEED.addPreferences( SettingsPatch.PreferenceScreen.FEED.addPreferences(
SwitchPreference("revanced_hide_album_cards") SwitchPreference("revanced_hide_album_cards"),
) )
albumCardId = ResourceMappingPatch.resourceMappings.single { albumCardId = ResourceMappingPatch["layout", "album_card"]
it.type == "layout" && it.name == "album_card"
}.id
} }
} }

View File

@@ -38,7 +38,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
) )
internal object CrowdfundingBoxResourcePatch : ResourcePatch() { internal object CrowdfundingBoxResourcePatch : ResourcePatch() {
@@ -22,11 +22,12 @@ internal object CrowdfundingBoxResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.FEED.addPreferences( SettingsPatch.PreferenceScreen.FEED.addPreferences(
SwitchPreference("revanced_hide_crowdfunding_box") SwitchPreference("revanced_hide_crowdfunding_box"),
) )
crowdfundingBoxId = ResourceMappingPatch.resourceMappings.single { crowdfundingBoxId = ResourceMappingPatch[
it.type == "layout" && it.name == "donation_companion" "layout",
}.id "donation_companion",
]
} }
} }

View File

@@ -41,7 +41,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
) )
internal object HideEndscreenCardsResourcePatch : ResourcePatch() { internal object HideEndscreenCardsResourcePatch : ResourcePatch() {
@@ -24,15 +24,13 @@ internal object HideEndscreenCardsResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences( SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_endscreen_cards") SwitchPreference("revanced_hide_endscreen_cards"),
) )
fun findEndscreenResourceId(name: String) = ResourceMappingPatch.resourceMappings.single { fun idOf(name: String) = ResourceMappingPatch["layout", "endscreen_element_layout_$name"]
it.type == "layout" && it.name == "endscreen_element_layout_$name"
}.id
layoutCircle = findEndscreenResourceId("circle") layoutCircle = idOf("circle")
layoutIcon = findEndscreenResourceId("icon") layoutIcon = idOf("icon")
layoutVideo = findEndscreenResourceId("video") layoutVideo = idOf("video")
} }
} }

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -25,15 +25,12 @@ internal object HideFilterBarResourcePatch : ResourcePatch() {
SwitchPreference("revanced_hide_filter_bar_feed_in_feed"), SwitchPreference("revanced_hide_filter_bar_feed_in_feed"),
SwitchPreference("revanced_hide_filter_bar_feed_in_search"), SwitchPreference("revanced_hide_filter_bar_feed_in_search"),
SwitchPreference("revanced_hide_filter_bar_feed_in_related_videos"), SwitchPreference("revanced_hide_filter_bar_feed_in_related_videos"),
) ),
) ),
) )
relatedChipCloudMarginId = "related_chip_cloud_reduced_margins".layoutResourceId("layout") relatedChipCloudMarginId = ResourceMappingPatch["layout", "related_chip_cloud_reduced_margins"]
filterBarHeightId = "filter_bar_height".layoutResourceId() filterBarHeightId = ResourceMappingPatch["dimen", "filter_bar_height"]
barContainerHeightId = "bar_container_height".layoutResourceId() barContainerHeightId = ResourceMappingPatch["dimen", "bar_container_height"]
} }
private fun String.layoutResourceId(type: String = "dimen") =
ResourceMappingPatch.resourceMappings.single { it.type == type && it.name == this }.id
} }

View File

@@ -34,7 +34,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -1,7 +1,6 @@
package app.revanced.patches.youtube.layout.hide.floatingmicrophone package app.revanced.patches.youtube.layout.hide.floatingmicrophone
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch import app.revanced.patches.all.misc.resources.AddResourcesPatch
@@ -13,8 +12,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
] ],
) )
internal object HideFloatingMicrophoneButtonResourcePatch : ResourcePatch() { internal object HideFloatingMicrophoneButtonResourcePatch : ResourcePatch() {
internal var fabButtonId: Long = -1 internal var fabButtonId: Long = -1
@@ -23,10 +22,9 @@ internal object HideFloatingMicrophoneButtonResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences( SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
SwitchPreference("revanced_hide_floating_microphone_button") SwitchPreference("revanced_hide_floating_microphone_button"),
) )
fabButtonId = ResourceMappingPatch.resourceMappings.find { it.type == "id" && it.name == "fab" }?.id fabButtonId = ResourceMappingPatch["id", "fab"]
?: throw PatchException("Can not find required fab button resource id")
} }
} }

View File

@@ -34,7 +34,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -57,7 +57,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37", "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],
@@ -101,7 +103,6 @@ object HideLayoutComponentsPatch : BytecodePatch(
SwitchPreference("revanced_hide_info_panels"), SwitchPreference("revanced_hide_info_panels"),
SwitchPreference("revanced_hide_join_membership_button"), SwitchPreference("revanced_hide_join_membership_button"),
SwitchPreference("revanced_hide_medical_panels"), SwitchPreference("revanced_hide_medical_panels"),
SwitchPreference("revanced_hide_playables"),
SwitchPreference("revanced_hide_quick_actions"), SwitchPreference("revanced_hide_quick_actions"),
SwitchPreference("revanced_hide_related_videos"), SwitchPreference("revanced_hide_related_videos"),
SwitchPreference("revanced_hide_subscribers_community_guidelines"), SwitchPreference("revanced_hide_subscribers_community_guidelines"),
@@ -120,6 +121,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
SwitchPreference("revanced_hide_mix_playlists"), SwitchPreference("revanced_hide_mix_playlists"),
SwitchPreference("revanced_hide_movies_section"), SwitchPreference("revanced_hide_movies_section"),
SwitchPreference("revanced_hide_notify_me_button"), SwitchPreference("revanced_hide_notify_me_button"),
SwitchPreference("revanced_hide_playables"),
SwitchPreference("revanced_hide_search_result_recommendations"), SwitchPreference("revanced_hide_search_result_recommendations"),
SwitchPreference("revanced_hide_search_result_shelf_header"), SwitchPreference("revanced_hide_search_result_shelf_header"),
SwitchPreference("revanced_hide_show_more_button"), SwitchPreference("revanced_hide_show_more_button"),

View File

@@ -5,22 +5,22 @@ import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch
@Patch( @Patch(
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
] ],
) )
internal object HideLayoutComponentsResourcePatch : ResourcePatch() { internal object HideLayoutComponentsResourcePatch : ResourcePatch() {
internal var expandButtonDownId: Long = -1 internal var expandButtonDownId: Long = -1
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
expandButtonDownId = ResourceMappingPatch.resourceMappings.single { expandButtonDownId = ResourceMappingPatch[
it.type == "layout" && it.name == "expand_button_down" "layout",
}.id "expand_button_down",
]
} }
} }

View File

@@ -45,7 +45,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
) )
object HideInfocardsResourcePatch : ResourcePatch() { object HideInfocardsResourcePatch : ResourcePatch() {
@@ -22,11 +22,12 @@ object HideInfocardsResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences( SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_info_cards") SwitchPreference("revanced_hide_info_cards"),
) )
drawerResourceId = ResourceMappingPatch.resourceMappings.single { drawerResourceId = ResourceMappingPatch[
it.type == "id" && it.name == "info_cards_drawer_header" "id",
}.id "info_cards_drawer_header",
]
} }
} }

View File

@@ -39,7 +39,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -36,7 +36,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -41,7 +41,9 @@ import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -1,8 +1,5 @@
package app.revanced.patches.youtube.layout.hide.shorts package app.revanced.patches.youtube.layout.hide.shorts
import app.revanced.util.exception
import app.revanced.util.findIndexForIdResource
import app.revanced.util.injectHideViewCall
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
@@ -15,9 +12,15 @@ import app.revanced.patches.youtube.layout.hide.shorts.fingerprints.*
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
import app.revanced.util.exception
import app.revanced.util.getReference
import app.revanced.util.indexOfIdResourceOrThrow
import app.revanced.util.injectHideViewCall
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Patch( @Patch(
name = "Hide Shorts components", name = "Hide Shorts components",
@@ -27,11 +30,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
LithoFilterPatch::class, LithoFilterPatch::class,
HideShortsComponentsResourcePatch::class, HideShortsComponentsResourcePatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
NavigationBarHookPatch::class NavigationBarHookPatch::class,
], ],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
"com.google.android.youtube", [ "com.google.android.youtube",
[
"18.32.39", "18.32.39",
"18.37.36", "18.37.36",
"18.38.44", "18.38.44",
@@ -48,10 +52,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
] "19.10.39",
) "19.11.43",
] ],
),
],
) )
@Suppress("unused") @Suppress("unused")
object HideShortsComponentsPatch : BytecodePatch( object HideShortsComponentsPatch : BytecodePatch(
@@ -60,8 +66,8 @@ object HideShortsComponentsPatch : BytecodePatch(
ReelConstructorFingerprint, ReelConstructorFingerprint,
BottomNavigationBarFingerprint, BottomNavigationBarFingerprint,
RenderBottomNavigationBarParentFingerprint, RenderBottomNavigationBarParentFingerprint,
SetPivotBarVisibilityParentFingerprint SetPivotBarVisibilityParentFingerprint,
) ),
) { ) {
private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/components/ShortsFilter;" private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/components/ShortsFilter;"
@@ -79,7 +85,7 @@ object HideShortsComponentsPatch : BytecodePatch(
insertIndex, insertIndex,
viewRegister, viewRegister,
FILTER_CLASS_DESCRIPTOR, FILTER_CLASS_DESCRIPTOR,
"hideShortsShelf" "hideShortsShelf",
) )
} }
} // Do not throw an exception if not resolved. } // Do not throw an exception if not resolved.
@@ -93,7 +99,6 @@ object HideShortsComponentsPatch : BytecodePatch(
ShortsButtons.entries.forEach { button -> button.injectHideCall(it.mutableMethod) } ShortsButtons.entries.forEach { button -> button.injectHideCall(it.mutableMethod) }
} ?: throw CreateShortsButtonsFingerprint.exception } ?: throw CreateShortsButtonsFingerprint.exception
// endregion // endregion
// region Hide the Shorts buttons in newer versions of YouTube. // region Hide the Shorts buttons in newer versions of YouTube.
@@ -106,8 +111,9 @@ object HideShortsComponentsPatch : BytecodePatch(
// Hook to get the pivotBar view. // Hook to get the pivotBar view.
SetPivotBarVisibilityParentFingerprint.result?.let { SetPivotBarVisibilityParentFingerprint.result?.let {
if (!SetPivotBarVisibilityFingerprint.resolve(context, it.classDef)) if (!SetPivotBarVisibilityFingerprint.resolve(context, it.classDef)) {
throw SetPivotBarVisibilityFingerprint.exception throw SetPivotBarVisibilityFingerprint.exception
}
SetPivotBarVisibilityFingerprint.result!!.let { result -> SetPivotBarVisibilityFingerprint.result!!.let { result ->
result.mutableMethod.apply { result.mutableMethod.apply {
@@ -116,7 +122,7 @@ object HideShortsComponentsPatch : BytecodePatch(
addInstruction( addInstruction(
insertIndex, insertIndex,
"sput-object v$viewRegister, $FILTER_CLASS_DESCRIPTOR->pivotBar:" + "sput-object v$viewRegister, $FILTER_CLASS_DESCRIPTOR->pivotBar:" +
"Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;" "Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;",
) )
} }
} }
@@ -124,8 +130,9 @@ object HideShortsComponentsPatch : BytecodePatch(
// Hook to hide the navigation bar when Shorts are being played. // Hook to hide the navigation bar when Shorts are being played.
RenderBottomNavigationBarParentFingerprint.result?.let { RenderBottomNavigationBarParentFingerprint.result?.let {
if (!RenderBottomNavigationBarFingerprint.resolve(context, it.classDef)) if (!RenderBottomNavigationBarFingerprint.resolve(context, it.classDef)) {
throw RenderBottomNavigationBarFingerprint.exception throw RenderBottomNavigationBarFingerprint.exception
}
RenderBottomNavigationBarFingerprint.result!!.mutableMethod.apply { RenderBottomNavigationBarFingerprint.result!!.mutableMethod.apply {
addInstruction(0, "invoke-static { }, $FILTER_CLASS_DESCRIPTOR->hideNavigationBar()V") addInstruction(0, "invoke-static { }, $FILTER_CLASS_DESCRIPTOR->hideNavigationBar()V")
@@ -142,7 +149,7 @@ object HideShortsComponentsPatch : BytecodePatch(
addInstruction( addInstruction(
insertIndex, insertIndex,
"invoke-static { v$viewRegister }, $FILTER_CLASS_DESCRIPTOR->" + "invoke-static { v$viewRegister }, $FILTER_CLASS_DESCRIPTOR->" +
"hideNavigationBar(Landroid/view/View;)Landroid/view/View;" "hideNavigationBar(Landroid/view/View;)Landroid/view/View;",
) )
} }
} ?: throw BottomNavigationBarFingerprint.exception } ?: throw BottomNavigationBarFingerprint.exception
@@ -150,18 +157,25 @@ object HideShortsComponentsPatch : BytecodePatch(
// endregion // endregion
} }
private enum class ShortsButtons(private val resourceName: String, private val methodName: String) { private enum class ShortsButtons(private val resourceName: String, private val methodName: String) {
LIKE("reel_dyn_like", "hideLikeButton"),
DISLIKE("reel_dyn_dislike", "hideDislikeButton"),
COMMENTS("reel_dyn_comment", "hideShortsCommentsButton"), COMMENTS("reel_dyn_comment", "hideShortsCommentsButton"),
REMIX("reel_dyn_remix", "hideShortsRemixButton"), REMIX("reel_dyn_remix", "hideShortsRemixButton"),
SHARE("reel_dyn_share", "hideShortsShareButton"); SHARE("reel_dyn_share", "hideShortsShareButton");
fun injectHideCall(method: MutableMethod) { fun injectHideCall(method: MutableMethod) {
val referencedIndex = method.findIndexForIdResource(resourceName) val referencedIndex = method.indexOfIdResourceOrThrow(resourceName)
val setIdIndex = referencedIndex + 1 val instruction = method.implementation!!.instructions
.subList(referencedIndex, referencedIndex + 20)
.first {
it.opcode == Opcode.INVOKE_VIRTUAL && it.getReference<MethodReference>()?.name == "setId"
}
val setIdIndex = instruction.location.index
val viewRegister = method.getInstruction<FiveRegisterInstruction>(setIdIndex).registerC val viewRegister = method.getInstruction<FiveRegisterInstruction>(setIdIndex).registerC
method.injectHideViewCall(setIdIndex, viewRegister, FILTER_CLASS_DESCRIPTOR, methodName) method.injectHideViewCall(setIdIndex + 1, viewRegister, FILTER_CLASS_DESCRIPTOR, methodName)
} }
} }
} }

View File

@@ -50,15 +50,19 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
SwitchPreference("revanced_hide_shorts_navigation_bar"), SwitchPreference("revanced_hide_shorts_navigation_bar"),
) )
ResourceMappingPatch.resourceMappings.find { reelPlayerRightCellButtonHeight = ResourceMappingPatch[
it.type == "layout" && it.name == "reel_multiple_items_shelf" "dimen",
}?.also { "reel_player_right_cell_button_height",
reelMultipleItemShelfId = it.id ]
}
reelPlayerRightCellButtonHeight = // Resource not present in new versions of the app.
ResourceMappingPatch.resourceMappings.single { try {
it.type == "dimen" && it.name == "reel_player_right_cell_button_height" ResourceMappingPatch[
}.id "dimen",
"reel_player_right_cell_button_height",
]
} catch (e: NoSuchElementException) {
return
}.also { reelPlayerRightCellButtonHeight = it }
} }
} }

View File

@@ -1,13 +1,10 @@
package app.revanced.patches.youtube.layout.hide.shorts.fingerprints package app.revanced.patches.youtube.layout.hide.shorts.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.hide.shorts.HideShortsComponentsResourcePatch import app.revanced.patches.youtube.layout.hide.shorts.HideShortsComponentsResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal object CreateShortsButtonsFingerprint : LiteralValueFingerprint( internal object CreateShortsButtonsFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, // YT 19.12.x moved this code inside another method, and each method has different parameters.
returnType = "V", returnType = "V",
parameters = listOf("Z", "Z", "L"),
literalSupplier = { HideShortsComponentsResourcePatch.reelPlayerRightCellButtonHeight } literalSupplier = { HideShortsComponentsResourcePatch.reelPlayerRightCellButtonHeight }
) )

View File

@@ -33,7 +33,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
) )
internal object DisableSuggestedVideoEndScreenResourcePatch : ResourcePatch() { internal object DisableSuggestedVideoEndScreenResourcePatch : ResourcePatch() {
@@ -22,11 +22,12 @@ internal object DisableSuggestedVideoEndScreenResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences( SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_disable_suggested_video_end_screen") SwitchPreference("revanced_disable_suggested_video_end_screen"),
) )
sizeAdjustableLiteAutoNavOverlay = ResourceMappingPatch.resourceMappings.single { sizeAdjustableLiteAutoNavOverlay = ResourceMappingPatch[
it.type == "layout" && it.name == "size_adjustable_lite_autonav_overlay" "layout",
}.id "size_adjustable_lite_autonav_overlay",
]
} }
} }

View File

@@ -34,7 +34,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -35,7 +35,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -30,7 +30,9 @@ import org.w3c.dom.Element
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View File

@@ -10,7 +10,7 @@ import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch
@Patch( @Patch(
dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class] dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class],
) )
internal object CustomPlayerOverlayOpacityResourcePatch : ResourcePatch() { internal object CustomPlayerOverlayOpacityResourcePatch : ResourcePatch() {
internal var scrimOverlayId = -1L internal var scrimOverlayId = -1L
@@ -19,11 +19,12 @@ internal object CustomPlayerOverlayOpacityResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences( SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
TextPreference("revanced_player_overlay_opacity", inputType = InputType.NUMBER) TextPreference("revanced_player_overlay_opacity", inputType = InputType.NUMBER),
) )
scrimOverlayId = ResourceMappingPatch.resourceMappings.single { scrimOverlayId = ResourceMappingPatch[
it.type == "id" && it.name == "scrim_overlay" "id",
}.id "scrim_overlay",
]
} }
} }

View File

@@ -64,7 +64,9 @@ import com.android.tools.smali.dexlib2.iface.reference.TypeReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -12,8 +12,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsResourcePatch
@Patch( @Patch(
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
] ],
) )
internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() { internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() {
internal var oldUIDislikeId: Long = -1 internal var oldUIDislikeId: Long = -1
@@ -25,11 +25,12 @@ internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() {
key = "revanced_settings_screen_09", key = "revanced_settings_screen_09",
titleKey = "revanced_ryd_settings_title", titleKey = "revanced_ryd_settings_title",
summaryKey = null, summaryKey = null,
intent = SettingsPatch.newIntent("revanced_ryd_settings_intent") intent = SettingsPatch.newIntent("revanced_ryd_settings_intent"),
) )
oldUIDislikeId = ResourceMappingPatch.resourceMappings.single { oldUIDislikeId = ResourceMappingPatch[
it.type == "id" && it.name == "dislike_button" "id",
}.id "dislike_button",
]
} }
} }

View File

@@ -39,7 +39,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -35,7 +35,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -15,18 +15,18 @@ internal object SeekbarColorResourcePatch : ResourcePatch() {
internal var inlineTimeBarPlayedNotHighlightedColorId = -1L internal var inlineTimeBarPlayedNotHighlightedColorId = -1L
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
fun findColorResource(resourceName: String): Long { reelTimeBarPlayedColorId = ResourceMappingPatch[
return ResourceMappingPatch.resourceMappings "color",
.find { it.type == "color" && it.name == resourceName }?.id "reel_time_bar_played_color",
?: throw PatchException("Could not find color resource: $resourceName") ]
} inlineTimeBarColorizedBarPlayedColorDarkId = ResourceMappingPatch[
"color",
reelTimeBarPlayedColorId = "inline_time_bar_colorized_bar_played_color_dark",
findColorResource("reel_time_bar_played_color") ]
inlineTimeBarColorizedBarPlayedColorDarkId = inlineTimeBarPlayedNotHighlightedColorId = ResourceMappingPatch[
findColorResource("inline_time_bar_colorized_bar_played_color_dark") "color",
inlineTimeBarPlayedNotHighlightedColorId = "inline_time_bar_played_not_highlighted_color",
findColorResource("inline_time_bar_played_not_highlighted_color") ]
// Edit the resume playback drawable and replace the progress bar with a custom drawable // Edit the resume playback drawable and replace the progress bar with a custom drawable
context.xmlEditor["res/drawable/resume_playback_progressbar_drawable.xml"].use { editor -> context.xmlEditor["res/drawable/resume_playback_progressbar_drawable.xml"].use { editor ->
@@ -39,10 +39,9 @@ internal object SeekbarColorResourcePatch : ResourcePatch() {
} }
val scaleNode = progressNode.getElementsByTagName("scale").item(0) as Element val scaleNode = progressNode.getElementsByTagName("scale").item(0) as Element
val shapeNode = scaleNode.getElementsByTagName("shape").item(0) as Element val shapeNode = scaleNode.getElementsByTagName("shape").item(0) as Element
val replacementNode = val replacementNode = document.createElement(
document.createElement( "app.revanced.integrations.youtube.patches.theme.ProgressBarDrawable",
"app.revanced.integrations.youtube.patches.theme.ProgressBarDrawable", )
)
scaleNode.replaceChild(replacementNode, shapeNode) scaleNode.replaceChild(replacementNode, shapeNode)
} }
} }

View File

@@ -1,6 +1,5 @@
package app.revanced.patches.youtube.layout.sponsorblock package app.revanced.patches.youtube.layout.sponsorblock
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
@@ -25,6 +24,7 @@ import app.revanced.patches.youtube.shared.fingerprints.SeekbarFingerprint
import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
import app.revanced.patches.youtube.video.information.VideoInformationPatch import app.revanced.patches.youtube.video.information.VideoInformationPatch
import app.revanced.patches.youtube.video.videoid.VideoIdPatch import app.revanced.patches.youtube.video.videoid.VideoIdPatch
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.* import com.android.tools.smali.dexlib2.iface.instruction.*
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
@@ -37,7 +37,8 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
description = "Adds options to enable and configure SponsorBlock, which can skip undesired video segments such as sponsored content.", description = "Adds options to enable and configure SponsorBlock, which can skip undesired video segments such as sponsored content.",
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
"com.google.android.youtube", [ "com.google.android.youtube",
[
"18.48.39", "18.48.39",
"18.49.37", "18.49.37",
"19.01.34", "19.01.34",
@@ -48,9 +49,11 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
] "19.10.39",
) "19.11.43",
],
),
], ],
dependencies = [ dependencies = [
IntegrationsPatch::class, IntegrationsPatch::class,
@@ -60,8 +63,8 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
// Used to prevent SponsorBlock from running on Shorts because SponsorBlock does not yet support Shorts. // Used to prevent SponsorBlock from running on Shorts because SponsorBlock does not yet support Shorts.
PlayerTypeHookPatch::class, PlayerTypeHookPatch::class,
PlayerControlsBytecodePatch::class, PlayerControlsBytecodePatch::class,
SponsorBlockResourcePatch::class SponsorBlockResourcePatch::class,
] ],
) )
@Suppress("unused") @Suppress("unused")
object SponsorBlockBytecodePatch : BytecodePatch( object SponsorBlockBytecodePatch : BytecodePatch(
@@ -69,8 +72,8 @@ object SponsorBlockBytecodePatch : BytecodePatch(
SeekbarFingerprint, SeekbarFingerprint,
AppendTimeFingerprint, AppendTimeFingerprint,
LayoutConstructorFingerprint, LayoutConstructorFingerprint,
AutoRepeatParentFingerprint AutoRepeatParentFingerprint,
) ),
) { ) {
private const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR = private const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/sponsorblock/SegmentPlaybackController;" "Lapp/revanced/integrations/youtube/sponsorblock/SegmentPlaybackController;"
@@ -83,8 +86,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
LayoutConstructorFingerprint.result?.let { LayoutConstructorFingerprint.result?.let {
if (!ControlsOverlayFingerprint.resolve(context, it.classDef)) if (!ControlsOverlayFingerprint.resolve(context, it.classDef)) {
throw ControlsOverlayFingerprint.exception throw ControlsOverlayFingerprint.exception
}
} ?: throw LayoutConstructorFingerprint.exception } ?: throw LayoutConstructorFingerprint.exception
/* /*
@@ -93,7 +97,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
with(VideoInformationPatch) { with(VideoInformationPatch) {
videoTimeHook( videoTimeHook(
INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR, INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR,
"setVideoTime" "setVideoTime",
) )
} }
@@ -121,7 +125,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
seekbarMethod.addInstruction( seekbarMethod.addInstruction(
moveRectangleToRegisterIndex + 1, moveRectangleToRegisterIndex + 1,
"invoke-static/range {p0 .. p0}, " + "invoke-static/range {p0 .. p0}, " +
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarRect(Ljava/lang/Object;)V" "$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarRect(Ljava/lang/Object;)V",
) )
for ((index, instruction) in seekbarMethodInstructions.withIndex()) { for ((index, instruction) in seekbarMethodInstructions.withIndex()) {
@@ -136,7 +140,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
seekbarMethod.addInstruction( seekbarMethod.addInstruction(
insertIndex, insertIndex,
"invoke-static {v${invokeInstruction.registerC}}, " + "invoke-static {v${invokeInstruction.registerC}}, " +
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V" "$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V",
) )
break break
} }
@@ -154,7 +158,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
} }
seekbarMethod.addInstruction( seekbarMethod.addInstruction(
i, i,
"invoke-static {v$canvasInstance, v$centerY}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V" "invoke-static {v$canvasInstance, v$centerY}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V",
) )
break break
@@ -166,9 +170,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
val controlsMethodResult = PlayerControlsBytecodePatch.showPlayerControlsFingerprintResult val controlsMethodResult = PlayerControlsBytecodePatch.showPlayerControlsFingerprintResult
val controlsLayoutStubResourceId = val controlsLayoutStubResourceId =
ResourceMappingPatch.resourceMappings.single { it.type == "id" && it.name == "controls_layout_stub" }.id ResourceMappingPatch["id", "controls_layout_stub"]
val zoomOverlayResourceId = val zoomOverlayResourceId =
ResourceMappingPatch.resourceMappings.single { it.type == "id" && it.name == "video_zoom_overlay_stub" }.id ResourceMappingPatch["id", "video_zoom_overlay_stub"]
methods@ for (method in controlsMethodResult.mutableClass.methods) { methods@ for (method in controlsMethodResult.mutableClass.methods) {
val instructions = method.implementation?.instructions!! val instructions = method.implementation?.instructions!!
@@ -188,7 +192,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
""" """
invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V
invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V
""" """,
) )
} }
@@ -201,7 +205,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
""" """
invoke-static {p1}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V invoke-static {p1}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V
invoke-static {p1}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V invoke-static {p1}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V
""".trimIndent() """.trimIndent(),
) )
} }
} }
@@ -223,7 +227,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
""" """
invoke-static {v$targetRegister}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->appendTimeWithoutSegments(Ljava/lang/String;)Ljava/lang/String; invoke-static {v$targetRegister}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->appendTimeWithoutSegments(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$targetRegister move-result-object v$targetRegister
""" """,
) )
// initialize the player controller // initialize the player controller
@@ -236,10 +240,10 @@ object SponsorBlockBytecodePatch : BytecodePatch(
val frameLayoutRegister = (getInstruction(startIndex + 2) as OneRegisterInstruction).registerA val frameLayoutRegister = (getInstruction(startIndex + 2) as OneRegisterInstruction).registerA
addInstruction( addInstruction(
startIndex + 3, startIndex + 3,
"invoke-static {v$frameLayoutRegister}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/ViewGroup;)V" "invoke-static {v$frameLayoutRegister}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/ViewGroup;)V",
) )
} }
} ?: throw ControlsOverlayFingerprint.exception } ?: throw ControlsOverlayFingerprint.exception
// get rectangle field name // get rectangle field name
RectangleFieldInvalidatorFingerprint.resolve(context, seekbarSignatureResult.classDef) RectangleFieldInvalidatorFingerprint.resolve(context, seekbarSignatureResult.classDef)
@@ -258,7 +262,8 @@ object SponsorBlockBytecodePatch : BytecodePatch(
fun MutableMethod.replaceStringInstruction(index: Int, instruction: Instruction, with: String) { fun MutableMethod.replaceStringInstruction(index: Int, instruction: Instruction, with: String) {
val register = (instruction as OneRegisterInstruction).registerA val register = (instruction as OneRegisterInstruction).registerA
this.replaceInstruction( this.replaceInstruction(
index, "const-string v$register, \"$with\"" index,
"const-string v$register, \"$with\"",
) )
} }
for ((index, it) in method.implementation!!.instructions.withIndex()) { for ((index, it) in method.implementation!!.instructions.withIndex()) {
@@ -268,13 +273,12 @@ object SponsorBlockBytecodePatch : BytecodePatch(
"replaceMeWithsetSponsorBarRect" -> method.replaceStringInstruction( "replaceMeWithsetSponsorBarRect" -> method.replaceStringInstruction(
index, index,
it, it,
rectangleFieldName rectangleFieldName,
) )
} }
} }
} ?: throw PatchException("Could not find the method which contains the replaceMeWith* strings") } ?: throw PatchException("Could not find the method which contains the replaceMeWith* strings")
// The vote and create segment buttons automatically change their visibility when appropriate, // The vote and create segment buttons automatically change their visibility when appropriate,
// but if buttons are showing when the end of the video is reached then they will not automatically hide. // but if buttons are showing when the end of the video is reached then they will not automatically hide.
// Add a hook to forcefully hide when the end of the video is reached. // Add a hook to forcefully hide when the end of the video is reached.
@@ -283,7 +287,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
it.resolve(context, AutoRepeatParentFingerprint.result!!.classDef) it.resolve(context, AutoRepeatParentFingerprint.result!!.classDef)
}.result?.mutableMethod?.addInstruction( }.result?.mutableMethod?.addInstruction(
0, 0,
"invoke-static {}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->endOfVideoReached()V" "invoke-static {}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->endOfVideoReached()V",
) ?: throw AutoRepeatFingerprint.exception ) ?: throw AutoRepeatFingerprint.exception
// TODO: isSBChannelWhitelisting implementation // TODO: isSBChannelWhitelisting implementation

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -44,7 +44,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -43,7 +43,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
) )
) )
] ]

View File

@@ -12,7 +12,7 @@ internal object MiniPlayerDimensionsCalculatorParentFingerprint : MethodFingerpr
opcodes = listOf( opcodes = listOf(
Opcode.CONST_HIGH16, Opcode.CONST_HIGH16,
Opcode.ADD_FLOAT_2ADDR, Opcode.ADD_FLOAT_2ADDR,
Opcode.MUL_FLOAT, null, // Opcode.MUL_FLOAT or Opcode.MUL_FLOAT_2ADDR
Opcode.CONST_4, Opcode.CONST_4,
Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,

View File

@@ -50,7 +50,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -61,7 +61,9 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View File

@@ -39,7 +39,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -34,7 +34,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -11,8 +11,9 @@ object SpoofSignatureResourcePatch : ResourcePatch() {
internal var scrubbedPreviewThumbnailResourceId: Long = -1 internal var scrubbedPreviewThumbnailResourceId: Long = -1
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
scrubbedPreviewThumbnailResourceId = ResourceMappingPatch.resourceMappings.single { scrubbedPreviewThumbnailResourceId = ResourceMappingPatch[
it.type == "id" && it.name == "thumbnail" "id",
}.id "thumbnail",
]
} }
} }

View File

@@ -44,7 +44,9 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37", "19.09.38",
"19.10.39",
"19.11.43"
), ),
), ),
), ),

View File

@@ -36,7 +36,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -40,7 +40,9 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -45,7 +45,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -6,19 +6,14 @@ import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
@Patch( @Patch(
dependencies = [ResourceMappingPatch::class] dependencies = [ResourceMappingPatch::class],
) )
internal object NavigationBarHookResourcePatch : ResourcePatch() { internal object NavigationBarHookResourcePatch : ResourcePatch() {
internal var imageOnlyTabResourceId: Long = -1 internal var imageOnlyTabResourceId: Long = -1
internal var actionBarSearchResultsViewMicId: Long = -1 internal var actionBarSearchResultsViewMicId: Long = -1
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
imageOnlyTabResourceId = ResourceMappingPatch.resourceMappings.first { imageOnlyTabResourceId = ResourceMappingPatch["layout", "image_only_tab"]
it.type == "layout" && it.name == "image_only_tab" actionBarSearchResultsViewMicId = ResourceMappingPatch["layout", "action_bar_search_results_view_mic"]
}.id
actionBarSearchResultsViewMicId = ResourceMappingPatch.resourceMappings.first {
it.type == "layout" && it.name == "action_bar_search_results_view_mic"
}.id
} }
} }

View File

@@ -24,8 +24,7 @@ object BottomControlsResourcePatch : ResourcePatch(), Closeable {
resourceContext = context resourceContext = context
targetDocumentEditor = context.xmlEditor[TARGET_RESOURCE] targetDocumentEditor = context.xmlEditor[TARGET_RESOURCE]
bottomUiContainerResourceId = ResourceMappingPatch.resourceMappings bottomUiContainerResourceId = ResourceMappingPatch["id", "bottom_ui_container_stub"]
.single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id
} }
/** /**

View File

@@ -41,7 +41,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -31,10 +31,7 @@ object SettingsResourcePatch : BaseSettingsResourcePatch(
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
// Used for a fingerprint from SettingsPatch. // Used for a fingerprint from SettingsPatch.
appearanceStringId = appearanceStringId = ResourceMappingPatch["string", "app_theme_appearance_dark"]
ResourceMappingPatch.resourceMappings.find {
it.type == "string" && it.name == "app_theme_appearance_dark"
}!!.id
arrayOf( arrayOf(
ResourceGroup("layout", "revanced_settings_with_toolbar.xml"), ResourceGroup("layout", "revanced_settings_with_toolbar.xml"),

View File

@@ -45,7 +45,9 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -25,7 +25,9 @@ import app.revanced.patches.youtube.video.speed.remember.RememberPlaybackSpeedPa
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View File

@@ -8,8 +8,9 @@ internal object CustomPlaybackSpeedResourcePatch : ResourcePatch() {
var speedUnavailableId: Long = -1 var speedUnavailableId: Long = -1
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
speedUnavailableId = ResourceMappingPatch.resourceMappings.single { speedUnavailableId = ResourceMappingPatch[
it.type == "string" && it.name == "varispeed_unavailable_message" "string",
}.id "varispeed_unavailable_message",
]
} }
} }

View File

@@ -41,7 +41,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -1,7 +1,6 @@
package app.revanced.patches.youtube.video.videoqualitymenu package app.revanced.patches.youtube.video.videoqualitymenu
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch import app.revanced.patches.all.misc.resources.AddResourcesPatch
@@ -10,7 +9,7 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch
@Patch( @Patch(
dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class] dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class],
) )
object RestoreOldVideoQualityMenuResourcePatch : ResourcePatch() { object RestoreOldVideoQualityMenuResourcePatch : ResourcePatch() {
internal var videoQualityBottomSheetListFragmentTitle = -1L internal var videoQualityBottomSheetListFragmentTitle = -1L
@@ -19,13 +18,13 @@ object RestoreOldVideoQualityMenuResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.VIDEO.addPreferences( SettingsPatch.PreferenceScreen.VIDEO.addPreferences(
SwitchPreference("revanced_restore_old_video_quality_menu") SwitchPreference("revanced_restore_old_video_quality_menu"),
) )
fun findResource(name: String) = ResourceMappingPatch.resourceMappings.find { it.name == name }?.id
?: throw PatchException("Could not find resource")
// Used for the old type of the video quality menu. // Used for the old type of the video quality menu.
videoQualityBottomSheetListFragmentTitle = findResource("video_quality_bottom_sheet_list_fragment_title") videoQualityBottomSheetListFragmentTitle = ResourceMappingPatch[
"layout",
"video_quality_bottom_sheet_list_fragment_title",
]
} }
} }

View File

@@ -15,7 +15,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction
import com.android.tools.smali.dexlib2.iface.reference.Reference import com.android.tools.smali.dexlib2.iface.reference.Reference
import com.android.tools.smali.dexlib2.util.MethodUtil import com.android.tools.smali.dexlib2.util.MethodUtil
fun MethodFingerprint.resultOrThrow() = result ?: throw exception fun MethodFingerprint.resultOrThrow() = result ?: throw exception
/** /**
@@ -59,24 +58,41 @@ fun MutableMethod.injectHideViewCall(
insertIndex: Int, insertIndex: Int,
viewRegister: Int, viewRegister: Int,
classDescriptor: String, classDescriptor: String,
targetMethod: String targetMethod: String,
) = addInstruction( ) = addInstruction(
insertIndex, insertIndex,
"invoke-static { v$viewRegister }, $classDescriptor->$targetMethod(Landroid/view/View;)V" "invoke-static { v$viewRegister }, $classDescriptor->$targetMethod(Landroid/view/View;)V",
) )
/** /**
* Find the index of the first instruction with the id of the given resource name. * Get the index of the first instruction with the id of the given resource name.
*
* Requires [ResourceMappingPatch] as a dependency.
* *
* @param resourceName the name of the resource to find the id for. * @param resourceName the name of the resource to find the id for.
* @return the index of the first instruction with the id of the given resource name, or -1 if not found. * @return the index of the first instruction with the id of the given resource name, or -1 if not found.
* @throws PatchException if the resource cannot be found.
* @see [indexOfIdResourceOrThrow]
*/ */
fun Method.findIndexForIdResource(resourceName: String): Int { fun Method.indexOfIdResource(resourceName: String): Int {
fun getIdResourceId(resourceName: String) = ResourceMappingPatch.resourceMappings.single { val resourceId = ResourceMappingPatch["id", resourceName]
it.type == "id" && it.name == resourceName return indexOfFirstWideLiteralInstructionValue(resourceId)
}.id }
return indexOfFirstWideLiteralInstructionValue(getIdResourceId(resourceName)) /**
* Get the index of the first instruction with the id of the given resource name or throw a [PatchException].
*
* Requires [ResourceMappingPatch] as a dependency.
*
* @throws [PatchException] if the resource is not found, or the method does not contain the resource id literal value.
*/
fun Method.indexOfIdResourceOrThrow(resourceName: String): Int {
val index = indexOfIdResource(resourceName)
if (index < 0) {
throw PatchException("Found resource id for: '$resourceName' but method does not contain the id: $this")
}
return index
} }
/** /**
@@ -130,27 +146,29 @@ inline fun <reified T : Reference> Instruction.getReference() = (this as? Refere
fun Method.indexOfFirstInstruction(predicate: Instruction.() -> Boolean) = fun Method.indexOfFirstInstruction(predicate: Instruction.() -> Boolean) =
this.implementation!!.instructions.indexOfFirst(predicate) this.implementation!!.instructions.indexOfFirst(predicate)
/** /**
* Return the resolved methods of [MethodFingerprint]s early. * Return the resolved methods of [MethodFingerprint]s early.
*/ */
fun List<MethodFingerprint>.returnEarly(bool: Boolean = false) { fun List<MethodFingerprint>.returnEarly(bool: Boolean = false) {
val const = if (bool) "0x1" else "0x0" val const = if (bool) "0x1" else "0x0"
this.forEach { fingerprint -> this.forEach { fingerprint ->
fingerprint.result?.let { result -> fingerprint.result?.let { result ->
val stringInstructions = when (result.method.returnType.first()) { val stringInstructions = when (result.method.returnType.first()) {
'L' -> """ 'L' ->
"""
const/4 v0, $const const/4 v0, $const
return-object v0 return-object v0
""" """
'V' -> "return-void" 'V' -> "return-void"
'I', 'Z' -> """ 'I', 'Z' ->
"""
const/4 v0, $const const/4 v0, $const
return v0 return v0
""" """
else -> throw Exception("This case should never happen.") else -> throw Exception("This case should never happen.")
} }
result.mutableMethod.addInstructions(0, stringInstructions) result.mutableMethod.addInstructions(0, stringInstructions)
} ?: throw fingerprint.exception } ?: throw fingerprint.exception
}
} }
}

View File

@@ -171,7 +171,7 @@
<string name="revanced_hide_channel_bar_title">Hide channel bar</string> <string name="revanced_hide_channel_bar_title">Hide channel bar</string>
<string name="revanced_hide_channel_bar_summary_on">Channel bar is hidden</string> <string name="revanced_hide_channel_bar_summary_on">Channel bar is hidden</string>
<string name="revanced_hide_channel_bar_summary_off">Channel bar is shown</string> <string name="revanced_hide_channel_bar_summary_off">Channel bar is shown</string>
<string name="revanced_hide_playables_title">Hide playables</string> <string name="revanced_hide_playables_title">Hide Playables</string>
<string name="revanced_hide_playables_summary_on">Playables are hidden</string> <string name="revanced_hide_playables_summary_on">Playables are hidden</string>
<string name="revanced_hide_playables_summary_off">Playables are shown</string> <string name="revanced_hide_playables_summary_off">Playables are shown</string>
<string name="revanced_hide_quick_actions_title">Hide quick actions in fullscreen</string> <string name="revanced_hide_quick_actions_title">Hide quick actions in fullscreen</string>
@@ -249,7 +249,7 @@
<string name="revanced_hide_general_ads_summary_on">General ads are hidden</string> <string name="revanced_hide_general_ads_summary_on">General ads are hidden</string>
<string name="revanced_hide_general_ads_summary_off">General ads are shown</string> <string name="revanced_hide_general_ads_summary_off">General ads are shown</string>
<string name="revanced_hide_fullscreen_ads_title">Hide fullscreen ads</string> <string name="revanced_hide_fullscreen_ads_title">Hide fullscreen ads</string>
<string name="revanced_hide_fullscreen_ads_summary_on">Fullscreen ads are hidden</string> <string name="revanced_hide_fullscreen_ads_summary_on">Fullscreen ads are hidden\n\nThis feature is only available for older devices</string>
<string name="revanced_hide_fullscreen_ads_summary_off">Fullscreen ads are shown</string> <string name="revanced_hide_fullscreen_ads_summary_off">Fullscreen ads are shown</string>
<string name="revanced_hide_buttoned_ads_title">Hide buttoned ads</string> <string name="revanced_hide_buttoned_ads_title">Hide buttoned ads</string>
<string name="revanced_hide_buttoned_ads_summary_on">Buttoned ads are hidden</string> <string name="revanced_hide_buttoned_ads_summary_on">Buttoned ads are hidden</string>
@@ -272,7 +272,7 @@
<string name="revanced_hide_merchandise_banners_title">Hide merchandise banners</string> <string name="revanced_hide_merchandise_banners_title">Hide merchandise banners</string>
<string name="revanced_hide_merchandise_banners_summary_on">Merchandise banners are hidden</string> <string name="revanced_hide_merchandise_banners_summary_on">Merchandise banners are hidden</string>
<string name="revanced_hide_merchandise_banners_summary_off">Merchandise banners are shown</string> <string name="revanced_hide_merchandise_banners_summary_off">Merchandise banners are shown</string>
<string name="revanced_hide_fullscreen_ads_feature_not_available_toast">Could not hide fullscreen ad. Hide setting disabled to prevent issues.</string> <string name="revanced_hide_fullscreen_ads_feature_not_available_toast">Hide fullscreen ads only works with older devices</string>
</patch> </patch>
<patch id="ad.getpremium.HideGetPremiumPatch"> <patch id="ad.getpremium.HideGetPremiumPatch">
<string name="revanced_hide_get_premium_title">Hide YouTube Premium promotions</string> <string name="revanced_hide_get_premium_title">Hide YouTube Premium promotions</string>
@@ -340,6 +340,10 @@
<string name="revanced_swipe_save_and_restore_brightness_title">Save and restore brightness</string> <string name="revanced_swipe_save_and_restore_brightness_title">Save and restore brightness</string>
<string name="revanced_swipe_save_and_restore_brightness_summary_on">Save and restore brightness when exiting or entering fullscreen</string> <string name="revanced_swipe_save_and_restore_brightness_summary_on">Save and restore brightness when exiting or entering fullscreen</string>
<string name="revanced_swipe_save_and_restore_brightness_summary_off">Do not save and restore brightness when exiting or entering fullscreen</string> <string name="revanced_swipe_save_and_restore_brightness_summary_off">Do not save and restore brightness when exiting or entering fullscreen</string>
<string name="revanced_swipe_lowest_value_enable_auto_brightness_title">Enable auto-brightness gesture</string>
<string name="revanced_swipe_lowest_value_enable_auto_brightness_summary_on">Swiping down to the lowest value of the brightness gesture enable auto-brightness</string>
<string name="revanced_swipe_lowest_value_enable_auto_brightness_summary_off">Swiping down to the lowest value does not enable auto-brightness</string>
<string name="revanced_swipe_lowest_value_enable_auto_brightness_overlay_text">Auto</string>
<string name="revanced_swipe_overlay_timeout_title">Swipe overlay timeout</string> <string name="revanced_swipe_overlay_timeout_title">Swipe overlay timeout</string>
<string name="revanced_swipe_overlay_timeout_summary">The amount of milliseconds the overlay is visible</string> <string name="revanced_swipe_overlay_timeout_summary">The amount of milliseconds the overlay is visible</string>
<string name="revanced_swipe_text_overlay_size_title">Swipe overlay text size</string> <string name="revanced_swipe_text_overlay_size_title">Swipe overlay text size</string>
@@ -389,11 +393,6 @@
<string name="revanced_hide_playlist_button_title">Hide Save to playlist</string> <string name="revanced_hide_playlist_button_title">Hide Save to playlist</string>
<string name="revanced_hide_playlist_button_summary_on">Save to playlist button is hidden</string> <string name="revanced_hide_playlist_button_summary_on">Save to playlist button is hidden</string>
<string name="revanced_hide_playlist_button_summary_off">Save to playlist button is shown</string> <string name="revanced_hide_playlist_button_summary_off">Save to playlist button is shown</string>
<!-- 'Shop' should be translated with the same localized wording that YouTube displays.
Shop button appears only for some videos in certain regions. Translate the button name normally if this menu is never shown. -->
<string name="revanced_hide_shop_button_title">Hide Shop</string>
<string name="revanced_hide_shop_button_summary_on">Shop button is hidden</string>
<string name="revanced_hide_shop_button_summary_off">Shop button is shown</string>
</patch> </patch>
<patch id="layout.buttons.autoplay.HideAutoplayButtonPatch"> <patch id="layout.buttons.autoplay.HideAutoplayButtonPatch">
<string name="revanced_hide_autoplay_button_title">Hide autoplay button</string> <string name="revanced_hide_autoplay_button_title">Hide autoplay button</string>
@@ -1151,9 +1150,9 @@
<string name="revanced_other_category_title">Other settings</string> <string name="revanced_other_category_title">Other settings</string>
<string name="revanced_client_ads_category_title">Client-side ads</string> <string name="revanced_client_ads_category_title">Client-side ads</string>
<string name="revanced_surestream_ads_category_title">Server-side surestream ads</string> <string name="revanced_surestream_ads_category_title">Server-side surestream ads</string>
<string name="revanced_debug_title">Debug logging</string> <string name="revanced_twitch_debug_title">Debug logging</string>
<string name="revanced_debug_summary_on">Debug logs are enabled</string> <string name="revanced_twitch_debug_summary_on">Debug logs are enabled</string>
<string name="revanced_debug_summary_off">Debug logs are disabled</string> <string name="revanced_twitch_debug_summary_off">Debug logs are disabled</string>
</patch> </patch>
</app> </app>
</resources> </resources>