Compare commits

...

29 Commits

Author SHA1 Message Date
semantic-release-bot
ae40d87bb3 chore(release): 2.185.0-dev.7 [skip ci]
# [2.185.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.6...v2.185.0-dev.7) (2023-07-19)

### Bug Fixes

* **YouTube - Spoof client:** show video time and chapters while using seekbar ([#2607](https://github.com/ReVanced/revanced-patches/issues/2607)) ([7fdc0d2](7fdc0d2a70))
2023-07-19 23:20:29 +00:00
LisoUseInAIKyrios
7fdc0d2a70 fix(YouTube - Spoof client): show video time and chapters while using seekbar (#2607) 2023-07-20 01:17:47 +02:00
semantic-release-bot
1fade09694 chore(release): 2.185.0-dev.6 [skip ci]
# [2.185.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.5...v2.185.0-dev.6) (2023-07-19)

### Bug Fixes

* **Tiktok - Settings:** bump compatibility ([#2656](https://github.com/ReVanced/revanced-patches/issues/2656)) ([90e32ea](90e32eac54))
2023-07-19 23:16:57 +00:00
Vu Hoan Huy
90e32eac54 fix(Tiktok - Settings): bump compatibility (#2656) 2023-07-20 01:13:33 +02:00
semantic-release-bot
a0632c8a92 chore(release): 2.185.0-dev.5 [skip ci]
# [2.185.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.4...v2.185.0-dev.5) (2023-07-19)

### Bug Fixes

* **Trakt - Unlock pro:** constraint to last known working version ([#2662](https://github.com/ReVanced/revanced-patches/issues/2662)) ([9da2bc3](9da2bc32a1))
2023-07-19 22:52:54 +00:00
johnconner122
9da2bc32a1 fix(Trakt - Unlock pro): constraint to last known working version (#2662) 2023-07-20 00:50:16 +02:00
semantic-release-bot
89fed3874f chore(release): 2.185.0-dev.4 [skip ci]
# [2.185.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.3...v2.185.0-dev.4) (2023-07-19)

### Bug Fixes

* **TikTok - Show seekbar:** fix seekbar not always showing ([#2660](https://github.com/ReVanced/revanced-patches/issues/2660)) ([e4adaeb](e4adaebad4))
2023-07-19 12:58:39 +00:00
Vu Hoan Huy
e4adaebad4 fix(TikTok - Show seekbar): fix seekbar not always showing (#2660) 2023-07-19 14:55:17 +02:00
semantic-release-bot
0b78e8377b chore(release): 2.185.0-dev.3 [skip ci]
# [2.185.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.2...v2.185.0-dev.3) (2023-07-17)

### Bug Fixes

* **Sync for Reddit - Disable ads:** fix compatibility with latest version ([6b2f786](6b2f7862d1))
2023-07-17 22:39:26 +00:00
oSumAtrIX
6b2f7862d1 fix(Sync for Reddit - Disable ads): fix compatibility with latest version 2023-07-18 00:36:37 +02:00
Aaronjamt
4668861d65 chore: fix typos (fingereprints -> fingerprints) (#2650) 2023-07-17 15:21:07 +04:00
semantic-release-bot
c5c63537ff chore(release): 2.185.0-dev.2 [skip ci]
# [2.185.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.1...v2.185.0-dev.2) (2023-07-15)

### Bug Fixes

* allocate for more than eight `LithoFilter` array items ([#2643](https://github.com/ReVanced/revanced-patches/issues/2643)) ([5de8ee5](5de8ee51c1))
2023-07-15 21:27:19 +00:00
johnconner122
5de8ee51c1 fix: allocate for more than eight LithoFilter array items (#2643) 2023-07-15 23:24:34 +02:00
semantic-release-bot
65087833b0 chore(release): 2.185.0-dev.1 [skip ci]
# [2.185.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.184.1-dev.1...v2.185.0-dev.1) (2023-07-15)

### Features

* **youtube:** rename `video-speed` to `playback-speed` ([#2642](https://github.com/revanced/revanced-patches/issues/2642)) ([75fd96f](75fd96f4c3))
2023-07-15 12:36:34 +00:00
KAZI MMT
75fd96f4c3 feat(youtube): rename video-speed to playback-speed (#2642) 2023-07-15 16:32:39 +04:00
semantic-release-bot
2cac5b1b74 chore(release): 2.184.1-dev.1 [skip ci]
## [2.184.1-dev.1](https://github.com/revanced/revanced-patches/compare/v2.184.0...v2.184.1-dev.1) (2023-07-14)

### Bug Fixes

* **youtube/sponsorblock:** fix some segments skipping slightly too late ([#2634](https://github.com/revanced/revanced-patches/issues/2634)) ([180c777](180c7775e6))
2023-07-14 08:39:40 +00:00
LisoUseInAIKyrios
180c7775e6 fix(youtube/sponsorblock): fix some segments skipping slightly too late (#2634) 2023-07-14 12:35:49 +04:00
semantic-release-bot
d0440c17f6 chore(release): 2.184.0 [skip ci]
# [2.184.0](https://github.com/revanced/revanced-patches/compare/v2.183.1...v2.184.0) (2023-07-11)

### Features

* **youtube/custom-branding:** update logo ([801584b](801584b78c))
2023-07-11 00:56:29 +00:00
oSumAtrIX
c6f4497031 chore: merge branch dev to main (#2615) 2023-07-11 02:54:05 +02:00
semantic-release-bot
20f24513d5 chore(release): 2.184.0-dev.1 [skip ci]
# [2.184.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.183.1...v2.184.0-dev.1) (2023-07-11)

### Features

* **youtube/custom-branding:** update logo ([801584b](801584b78c))
2023-07-11 00:48:58 +00:00
oSumAtrIX
db2fd097f6 refactor: remove unnecessary annotations 2023-07-11 02:45:56 +02:00
oSumAtrIX
801584b78c feat(youtube/custom-branding): update logo 2023-07-11 02:45:15 +02:00
semantic-release-bot
8c23fddcca chore(release): 2.183.1 [skip ci]
## [2.183.1](https://github.com/revanced/revanced-patches/compare/v2.183.0...v2.183.1) (2023-07-10)

### Bug Fixes

* find resource by correct name ([3113bb6](3113bb6599))
* use correct patch naming convention ([668d1fd](668d1fda49))
2023-07-10 18:38:38 +00:00
oSumAtrIX
eeca09ac78 chore: merge branch dev to main (#2613) 2023-07-10 20:36:12 +02:00
semantic-release-bot
8f22663a7c chore(release): 2.183.1-dev.1 [skip ci]
## [2.183.1-dev.1](https://github.com/revanced/revanced-patches/compare/v2.183.0...v2.183.1-dev.1) (2023-07-10)

### Bug Fixes

* find resource by correct name ([3113bb6](3113bb6599))
* use correct patch naming convention ([668d1fd](668d1fda49))
2023-07-10 18:34:54 +00:00
oSumAtrIX
3113bb6599 fix: find resource by correct name 2023-07-10 20:31:36 +02:00
oSumAtrIX
668d1fda49 fix: use correct patch naming convention 2023-07-10 20:28:50 +02:00
semantic-release-bot
6d474fb083 chore(release): 2.183.0 [skip ci]
# [2.183.0](https://github.com/revanced/revanced-patches/compare/v2.182.0...v2.183.0) (2023-07-10)

### Bug Fixes

* **youtube/custom-video-buffer:** remove non functional deprecated patch ([e5abe4f](e5abe4f0e5))
* **youtube/custom-video-speed:** don not implicitly depend on `old-video-quality-menu` patch ([9b2d89c](9b2d89cda5))

### Features

* change patches naming convention ([#2612](https://github.com/revanced/revanced-patches/issues/2612)) ([5e4c054](5e4c054834))
2023-07-10 18:17:02 +00:00
oSumAtrIX
1d6baa1228 chore: merge branch dev to main (#2598) 2023-07-10 20:14:36 +02:00
77 changed files with 453 additions and 361 deletions

View File

@@ -1,3 +1,102 @@
# [2.185.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.6...v2.185.0-dev.7) (2023-07-19)
### Bug Fixes
* **YouTube - Spoof client:** show video time and chapters while using seekbar ([#2607](https://github.com/ReVanced/revanced-patches/issues/2607)) ([9546d12](https://github.com/ReVanced/revanced-patches/commit/9546d126430870d1abd8f43bb687b31b9fcb6fb5))
# [2.185.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.5...v2.185.0-dev.6) (2023-07-19)
### Bug Fixes
* **Tiktok - Settings:** bump compatibility ([#2656](https://github.com/ReVanced/revanced-patches/issues/2656)) ([6641356](https://github.com/ReVanced/revanced-patches/commit/6641356d41813a20c77faac67c37ea517690d25b))
# [2.185.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.4...v2.185.0-dev.5) (2023-07-19)
### Bug Fixes
* **Trakt - Unlock pro:** constraint to last known working version ([#2662](https://github.com/ReVanced/revanced-patches/issues/2662)) ([324bbde](https://github.com/ReVanced/revanced-patches/commit/324bbde92a851e855c11f266e92fa14c39d88160))
# [2.185.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.3...v2.185.0-dev.4) (2023-07-19)
### Bug Fixes
* **TikTok - Show seekbar:** fix seekbar not always showing ([#2660](https://github.com/ReVanced/revanced-patches/issues/2660)) ([f2742f1](https://github.com/ReVanced/revanced-patches/commit/f2742f1ba117809971a10780823fca99c19a4f34))
# [2.185.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.2...v2.185.0-dev.3) (2023-07-17)
### Bug Fixes
* **Sync for Reddit - Disable ads:** fix compatibility with latest version ([1456577](https://github.com/ReVanced/revanced-patches/commit/1456577f11c4a7e49d6c1ba0103b919dc487f4cf))
# [2.185.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.1...v2.185.0-dev.2) (2023-07-15)
### Bug Fixes
* allocate for more than eight `LithoFilter` array items ([#2643](https://github.com/ReVanced/revanced-patches/issues/2643)) ([fc8660b](https://github.com/ReVanced/revanced-patches/commit/fc8660b740bec2747e5f82b7321027bb8a51e0cf))
# [2.185.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.184.1-dev.1...v2.185.0-dev.1) (2023-07-15)
### Features
* **youtube:** rename `video-speed` to `playback-speed` ([#2642](https://github.com/revanced/revanced-patches/issues/2642)) ([77e8639](https://github.com/revanced/revanced-patches/commit/77e8639b71048f2795f8f32fe18d052b335e3ce4))
## [2.184.1-dev.1](https://github.com/revanced/revanced-patches/compare/v2.184.0...v2.184.1-dev.1) (2023-07-14)
### Bug Fixes
* **youtube/sponsorblock:** fix some segments skipping slightly too late ([#2634](https://github.com/revanced/revanced-patches/issues/2634)) ([3175431](https://github.com/revanced/revanced-patches/commit/31754311870324b1e245b12965d7486878e9eba4))
# [2.184.0](https://github.com/revanced/revanced-patches/compare/v2.183.1...v2.184.0) (2023-07-11)
### Features
* **youtube/custom-branding:** update logo ([e2187f3](https://github.com/revanced/revanced-patches/commit/e2187f33ff82fce40592517aef31cb191b42987c))
# [2.184.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.183.1...v2.184.0-dev.1) (2023-07-11)
### Features
* **youtube/custom-branding:** update logo ([e2187f3](https://github.com/revanced/revanced-patches/commit/e2187f33ff82fce40592517aef31cb191b42987c))
## [2.183.1](https://github.com/revanced/revanced-patches/compare/v2.183.0...v2.183.1) (2023-07-10)
### Bug Fixes
* find resource by correct name ([7e562f3](https://github.com/revanced/revanced-patches/commit/7e562f3fb30d0ef5601114433090b2eebcf04c9e))
* use correct patch naming convention ([3d8856b](https://github.com/revanced/revanced-patches/commit/3d8856b29aba4d7436e637bc5778261b4acddeba))
## [2.183.1-dev.1](https://github.com/revanced/revanced-patches/compare/v2.183.0...v2.183.1-dev.1) (2023-07-10)
### Bug Fixes
* find resource by correct name ([7e562f3](https://github.com/revanced/revanced-patches/commit/7e562f3fb30d0ef5601114433090b2eebcf04c9e))
* use correct patch naming convention ([3d8856b](https://github.com/revanced/revanced-patches/commit/3d8856b29aba4d7436e637bc5778261b4acddeba))
# [2.183.0](https://github.com/revanced/revanced-patches/compare/v2.182.0...v2.183.0) (2023-07-10)
### Bug Fixes
* **youtube/custom-video-buffer:** remove non functional deprecated patch ([de233e2](https://github.com/revanced/revanced-patches/commit/de233e28246b1716b42bf331d2355ff4beed9564))
* **youtube/custom-video-speed:** don not implicitly depend on `old-video-quality-menu` patch ([acfda46](https://github.com/revanced/revanced-patches/commit/acfda46bce2558df18a6fa562008e058df5ad31e))
### Features
* change patches naming convention ([#2612](https://github.com/revanced/revanced-patches/issues/2612)) ([2dacc45](https://github.com/revanced/revanced-patches/commit/2dacc45f7430f7b3e60a8a2db60c3d6395a2f5cc))
# [2.183.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.182.1-dev.2...v2.183.0-dev.1) (2023-07-10) # [2.183.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.182.1-dev.2...v2.183.0-dev.1) (2023-07-10)

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 = 2.183.0-dev.1 version = 2.185.0-dev.7

File diff suppressed because one or more lines are too long

View File

@@ -1,17 +1,13 @@
package app.revanced.patches.all.screencapture.removerestriction.resource.patch package app.revanced.patches.all.screencapture.removerestriction.resource.patch
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import org.w3c.dom.Element import org.w3c.dom.Element
@Name("Remove screen capture restriction resource patch")
@Description("Sets allowAudioPlaybackCapture in manifest to true.") @Description("Sets allowAudioPlaybackCapture in manifest to true.")
@Version("0.0.1")
internal class RemoveCaptureRestrictionResourcePatch : ResourcePatch { internal class RemoveCaptureRestrictionResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {
// create an xml editor instance // create an xml editor instance

View File

@@ -1,13 +1,10 @@
package app.revanced.patches.music.misc.microg.patch.resource package app.revanced.patches.music.misc.microg.patch.resource
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patches.music.annotations.MusicCompatibility
import app.revanced.patches.music.misc.microg.shared.Constants.MUSIC_PACKAGE_NAME import app.revanced.patches.music.misc.microg.shared.Constants.MUSIC_PACKAGE_NAME
import app.revanced.patches.music.misc.microg.shared.Constants.REVANCED_MUSIC_APP_NAME import app.revanced.patches.music.misc.microg.shared.Constants.REVANCED_MUSIC_APP_NAME
import app.revanced.patches.music.misc.microg.shared.Constants.REVANCED_MUSIC_PACKAGE_NAME import app.revanced.patches.music.misc.microg.shared.Constants.REVANCED_MUSIC_PACKAGE_NAME
@@ -16,10 +13,7 @@ import app.revanced.patches.music.misc.microg.shared.Constants.SPOOFED_PACKAGE_S
import app.revanced.util.microg.MicroGManifestHelper import app.revanced.util.microg.MicroGManifestHelper
import app.revanced.util.microg.MicroGResourceHelper import app.revanced.util.microg.MicroGResourceHelper
@Name("Vanced MicroG resource patch")
@Description("Resource patch to allow YouTube Music ReVanced to run without root and under a different package name.") @Description("Resource patch to allow YouTube Music ReVanced to run without root and under a different package name.")
@MusicCompatibility
@Version("0.0.2")
class MicroGResourcePatch : ResourcePatch { class MicroGResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {
// update manifest // update manifest

View File

@@ -1,10 +1,9 @@
package app.revanced.patches.reddit.customclients package app.revanced.patches.reddit.customclients
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Patch @Patch
@Name("Change oauth client id") @Name("Change OAuth client id")
annotation class ChangeOAuthClientIdPatchAnnotation annotation class ChangeOAuthClientIdPatchAnnotation

View File

@@ -1,11 +1,10 @@
package app.revanced.patches.syncforreddit.detection.piracy.fingerprints package app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.TypeReference
object PiracyDetectionFingerprint : MethodFingerprint( object PiracyDetectionFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",

View File

@@ -1,19 +1,18 @@
package app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.patch package app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Version
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.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.syncforreddit.detection.piracy.fingerprints.PiracyDetectionFingerprint import app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.fingerprints.PiracyDetectionFingerprint
@Description("Disables detection of modified versions.") @Description("Disables detection of modified versions.")
@Version("0.0.1")
class DisablePiracyDetectionPatch : BytecodePatch(listOf(PiracyDetectionFingerprint)) { class DisablePiracyDetectionPatch : BytecodePatch(listOf(PiracyDetectionFingerprint)) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
// Do not return an error if the fingerprint is not resolved.
// This is fine because new versions of the target app do not need this patch.
PiracyDetectionFingerprint.result?.mutableMethod?.apply { PiracyDetectionFingerprint.result?.mutableMethod?.apply {
addInstruction( addInstruction(
0, 0,
@@ -21,7 +20,7 @@ class DisablePiracyDetectionPatch : BytecodePatch(listOf(PiracyDetectionFingerpr
return-void return-void
""" """
) )
} ?: return PiracyDetectionFingerprint.toErrorResult() }
return PatchResultSuccess() return PatchResultSuccess()
} }

View File

@@ -1,8 +1,5 @@
package app.revanced.patches.shared.mapping.misc.patch package app.revanced.patches.shared.mapping.misc.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
@@ -13,9 +10,6 @@ import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@Name("Resource mapping")
@Description("Creates a map of public resources.")
@Version("0.0.1")
class ResourceMappingPatch : ResourcePatch { class ResourceMappingPatch : ResourcePatch {
companion object { companion object {
internal lateinit var resourceMappings: List<ResourceElement> internal lateinit var resourceMappings: List<ResourceElement>

View File

@@ -1,12 +0,0 @@
package app.revanced.patches.tiktok.interaction.seekbar.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
object AwemeGetVideoControlFingerprint : MethodFingerprint(
"L",
AccessFlags.PUBLIC.value,
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/Aweme;") && methodDef.name == "getVideoControl"
}
)

View File

@@ -0,0 +1,9 @@
package app.revanced.patches.tiktok.interaction.seekbar.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object SetSeekBarShowTypeFingerprint : MethodFingerprint(
strings = listOf(
"seekbar show type change, change to:"
),
)

View File

@@ -6,17 +6,14 @@ import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.tiktok.interaction.seekbar.annotations.ShowSeekbarCompatibility import app.revanced.patches.tiktok.interaction.seekbar.annotations.ShowSeekbarCompatibility
import app.revanced.patches.tiktok.interaction.seekbar.fingerprints.AwemeGetVideoControlFingerprint import app.revanced.patches.tiktok.interaction.seekbar.fingerprints.SetSeekBarShowTypeFingerprint
import org.jf.dexlib2.Opcode import org.jf.dexlib2.iface.instruction.formats.Instruction22t
import org.jf.dexlib2.builder.instruction.BuilderInstruction11n
import org.jf.dexlib2.builder.instruction.BuilderInstruction21t
import org.jf.dexlib2.builder.instruction.BuilderInstruction22c
@Patch @Patch
@Name("Show seekbar") @Name("Show seekbar")
@@ -25,27 +22,20 @@ import org.jf.dexlib2.builder.instruction.BuilderInstruction22c
@Version("0.0.1") @Version("0.0.1")
class ShowSeekbarPatch : BytecodePatch( class ShowSeekbarPatch : BytecodePatch(
listOf( listOf(
AwemeGetVideoControlFingerprint SetSeekBarShowTypeFingerprint,
) )
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
//Get VideoControl FieldReference SetSeekBarShowTypeFingerprint.result?.mutableMethod?.apply {
val videoControl = context.findClass { it.type.endsWith("/VideoControl;") } val typeRegister = getInstruction<Instruction22t>(1).registerB
?: return PatchResultError("Can not find target class")
val fieldList = videoControl.immutableClass.fields.associateBy { field -> field.name }
AwemeGetVideoControlFingerprint.result?.mutableMethod?.implementation?.apply {
val ifNullLabel = newLabelForIndex(1)
addInstructions( addInstructions(
1, 0,
listOf( """
BuilderInstruction11n(Opcode.CONST_4, 1, 1), const/16 v$typeRegister, 0x64
BuilderInstruction21t(Opcode.IF_EQZ, 0, ifNullLabel), """
BuilderInstruction22c(Opcode.IPUT, 1, 0, fieldList["showProgressBar"]!!),
BuilderInstruction22c(Opcode.IPUT, 1, 0, fieldList["draftProgressBar"]!!)
)
) )
} ?: return AwemeGetVideoControlFingerprint.toErrorResult() } ?: return SetSeekBarShowTypeFingerprint.toErrorResult()
return PatchResultSuccess() return PatchResultSuccess()
} }

View File

@@ -1,17 +0,0 @@
package app.revanced.patches.tiktok.misc.settings.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.Opcode
object AboutPageFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.CONST, // copyrightPolicyLabel resource id
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_STRING
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/ss/android/ugc/aweme/setting/page/AboutPage;" &&
methodDef.name == "onViewCreated"
}
)

View File

@@ -0,0 +1,22 @@
package app.revanced.patches.tiktok.misc.settings.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.Opcode
object AddSettingsEntryFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.CONST_CLASS,
Opcode.APUT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/SettingNewVersionFragment;") &&
methodDef.name == "onViewCreated"
}
)

View File

@@ -0,0 +1,9 @@
package app.revanced.patches.tiktok.misc.settings.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object SettingsEntryFingerprint : MethodFingerprint(
strings = listOf(
"pls pass item or extends the EventUnit"
)
)

View File

@@ -0,0 +1,10 @@
package app.revanced.patches.tiktok.misc.settings.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object SettingsEntryInfoFingerprint : MethodFingerprint(
strings = listOf(
"ExposeItem(title=",
", icon="
)
)

View File

@@ -1,10 +0,0 @@
package app.revanced.patches.tiktok.misc.settings.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object SettingsOnViewCreatedFingerprint : MethodFingerprint(
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/SettingNewVersionFragment;") &&
methodDef.name == "onViewCreated"
}
)

View File

@@ -6,24 +6,19 @@ import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
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.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.tiktok.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.tiktok.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.tiktok.misc.settings.annotations.SettingsCompatibility import app.revanced.patches.tiktok.misc.settings.annotations.SettingsCompatibility
import app.revanced.patches.tiktok.misc.settings.fingerprints.AboutPageFingerprint import app.revanced.patches.tiktok.misc.settings.fingerprints.*
import app.revanced.patches.tiktok.misc.settings.fingerprints.AdPersonalizationActivityOnCreateFingerprint
import app.revanced.patches.tiktok.misc.settings.fingerprints.SettingsOnViewCreatedFingerprint
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Patch @Patch
@DependsOn([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class])
@@ -33,65 +28,44 @@ import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Version("0.0.1") @Version("0.0.1")
class SettingsPatch : BytecodePatch( class SettingsPatch : BytecodePatch(
listOf( listOf(
AboutPageFingerprint,
AdPersonalizationActivityOnCreateFingerprint, AdPersonalizationActivityOnCreateFingerprint,
SettingsOnViewCreatedFingerprint, AddSettingsEntryFingerprint,
SettingsEntryFingerprint,
SettingsEntryInfoFingerprint,
) )
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
SettingsOnViewCreatedFingerprint.result?.mutableMethod?.apply { // Find the class name of classes which construct a settings entry
val instructions = implementation!!.instructions val settingsButtonClass = SettingsEntryFingerprint.result?.classDef?.type?.toClassName()
?: return SettingsEntryFingerprint.toErrorResult()
val settingsButtonInfoClass = SettingsEntryInfoFingerprint.result?.classDef?.type?.toClassName()
?: return SettingsEntryInfoFingerprint.toErrorResult()
// Find the indices that need to be patched. // Create a settings entry for 'revanced settings' and add it to settings fragment
val copyrightPolicyLabelId = AboutPageFingerprint.result?.let { AddSettingsEntryFingerprint.result?.apply {
val startIndex = it.scanResult.patternScanResult!!.startIndex scanResult.patternScanResult?.startIndex?.let {
it.mutableMethod.getInstruction<WideLiteralInstruction>(startIndex).wideLiteral val settingsEntries = mutableMethod.getInstruction(it + 3)
} ?: return AboutPageFingerprint.toErrorResult() val addEntry = mutableMethod.getInstruction(it + 5)
// Add the settings entry created to the settings fragment
val copyrightIndex = instructions.indexOfFirst { mutableMethod.addInstructions(
(it as? ReferenceInstruction)?.reference.toString() == "copyright_policy" it + 6,
} - 6 listOf(
settingsEntries,
addEntry
// fixme: instead use Method.indexOfFirstConstantInstructionValue() )
val copyrightPolicyIndex = instructions.indexOfFirst {
(it as? WideLiteralInstruction)?.wideLiteral == copyrightPolicyLabelId
} + 2
// Replace an existing settings entry with ReVanced settings entry.
arrayOf(
copyrightIndex,
copyrightPolicyIndex
).forEach { index ->
val instruction = getInstruction(index)
if (instruction.opcode != Opcode.MOVE_RESULT_OBJECT)
return PatchResultError("Hardcoded offset changed.")
val settingsEntryStringRegister = (instruction as OneRegisterInstruction).registerA
// Replace the settings entry string with a custom one.
replaceInstruction(
index,
"""
const-string v$settingsEntryStringRegister, "ReVanced Settings"
"""
) )
// These instructions call a method that create a settings entry use reflection base on the class name of classes that construct settings entry
// Replace the OnClickListener class with a custom one. mutableMethod.addInstructions(
val onClickListener = getInstruction<ReferenceInstruction>(index + 4).reference.toString() it + 6,
context.findClass(onClickListener)?.mutableClass?.methods?.first {
it.name == "onClick"
}?.addInstructions(
0,
""" """
invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->startSettingsActivity()V const-string v1, "$settingsButtonClass"
return-void const-string v2, "$settingsButtonInfoClass"
invoke-static {v1, v2}, $CREATE_SETTINGS_ENTRY_METHOD_DESCRIPTOR
move-result-object v1
""" """
) ?: return PatchResultError("Could not find the onClick method.") )
} }
} ?: return AddSettingsEntryFingerprint.toErrorResult()
} ?: return SettingsOnViewCreatedFingerprint.toErrorResult()
// Initialize the settings menu once the replaced setting entry is clicked. // Initialize the settings menu once the replaced setting entry is clicked.
AdPersonalizationActivityOnCreateFingerprint.result?.mutableMethod?.apply { AdPersonalizationActivityOnCreateFingerprint.result?.mutableMethod?.apply {
@@ -101,18 +75,25 @@ class SettingsPatch : BytecodePatch(
val thisRegister = getInstruction<FiveRegisterInstruction>(initializeSettingsIndex - 1).registerC val thisRegister = getInstruction<FiveRegisterInstruction>(initializeSettingsIndex - 1).registerC
addInstructions( addInstructionsWithLabels(
initializeSettingsIndex, initializeSettingsIndex,
""" """
invoke-static {v$thisRegister}, $INITIALIZE_SETTINGS_METHOD_DESCRIPTOR invoke-static {v$thisRegister}, $INITIALIZE_SETTINGS_METHOD_DESCRIPTOR
move-result v0
if-eqz v0, :notrevanced
return-void return-void
""" """,
ExternalLabel("notrevanced", getInstruction(initializeSettingsIndex))
) )
} ?: return AdPersonalizationActivityOnCreateFingerprint.toErrorResult() } ?: return AdPersonalizationActivityOnCreateFingerprint.toErrorResult()
return PatchResultSuccess() return PatchResultSuccess()
} }
private fun String.toClassName(): String {
return substring(1, this.length - 1).replace("/", ".")
}
private companion object { private companion object {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/tiktok/settingsmenu/SettingsMenu;" "Lapp/revanced/tiktok/settingsmenu/SettingsMenu;"
@@ -120,6 +101,11 @@ class SettingsPatch : BytecodePatch(
private const val INITIALIZE_SETTINGS_METHOD_DESCRIPTOR = private const val INITIALIZE_SETTINGS_METHOD_DESCRIPTOR =
"$INTEGRATIONS_CLASS_DESCRIPTOR->initializeSettings(" + "$INTEGRATIONS_CLASS_DESCRIPTOR->initializeSettings(" +
"Lcom/bytedance/ies/ugc/aweme/commercialize/compliance/personalization/AdPersonalizationActivity;" + "Lcom/bytedance/ies/ugc/aweme/commercialize/compliance/personalization/AdPersonalizationActivity;" +
")V" ")Z"
private const val CREATE_SETTINGS_ENTRY_METHOD_DESCRIPTOR =
"$INTEGRATIONS_CLASS_DESCRIPTOR->createSettingsEntry(" +
"Ljava/lang/String;" +
"Ljava/lang/String;" +
")Ljava/lang/Object;"
} }
} }

View File

@@ -3,6 +3,6 @@ package app.revanced.patches.trakt.annotations
import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package import app.revanced.patcher.annotation.Package
@Compatibility([Package("tv.trakt.trakt")]) @Compatibility([Package("tv.trakt.trakt", arrayOf("1.1.1"))])
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
internal annotation class UnlockProCompatibility internal annotation class UnlockProCompatibility

View File

@@ -1,15 +1,9 @@
package app.revanced.patches.twitch.misc.settings.resource.patch package app.revanced.patches.twitch.misc.settings.resource.patch
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patches.shared.settings.preference.impl.ArrayResource import app.revanced.patches.shared.settings.preference.impl.ArrayResource
import app.revanced.patches.shared.settings.preference.impl.PreferenceScreen import app.revanced.patches.shared.settings.preference.impl.PreferenceScreen
import app.revanced.patches.shared.settings.resource.patch.AbstractSettingsResourcePatch import app.revanced.patches.shared.settings.resource.patch.AbstractSettingsResourcePatch
import app.revanced.patches.twitch.misc.settings.annotations.SettingsCompatibility
@Name("Settings resource patch")
@SettingsCompatibility
@Version("0.0.1")
class SettingsResourcePatch : AbstractSettingsResourcePatch( class SettingsResourcePatch : AbstractSettingsResourcePatch(
"revanced_prefs", "revanced_prefs",
"twitch/settings" "twitch/settings"

View File

@@ -1,7 +1,5 @@
package app.revanced.patches.youtube.interaction.copyvideourl.resource.patch package app.revanced.patches.youtube.interaction.copyvideourl.resource.patch
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
@@ -16,9 +14,7 @@ import app.revanced.util.resources.ResourceUtils
import app.revanced.util.resources.ResourceUtils.copyResources import app.revanced.util.resources.ResourceUtils.copyResources
import app.revanced.util.resources.ResourceUtils.mergeStrings import app.revanced.util.resources.ResourceUtils.mergeStrings
@Name("Copy video url resource")
@DependsOn([BottomControlsResourcePatch::class, SettingsPatch::class]) @DependsOn([BottomControlsResourcePatch::class, SettingsPatch::class])
@Version("0.0.1")
class CopyVideoUrlResourcePatch : ResourcePatch { class CopyVideoUrlResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {
SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences( SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences(

View File

@@ -1,7 +1,5 @@
package app.revanced.patches.youtube.interaction.downloads.resource.patch package app.revanced.patches.youtube.interaction.downloads.resource.patch
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
@@ -14,9 +12,7 @@ import app.revanced.util.resources.ResourceUtils
import app.revanced.util.resources.ResourceUtils.copyResources import app.revanced.util.resources.ResourceUtils.copyResources
import app.revanced.util.resources.ResourceUtils.mergeStrings import app.revanced.util.resources.ResourceUtils.mergeStrings
@Name("External downloads resource patch")
@DependsOn([BottomControlsResourcePatch::class, SettingsPatch::class]) @DependsOn([BottomControlsResourcePatch::class, SettingsPatch::class])
@Version("0.0.1")
class ExternalDownloadsResourcePatch : ResourcePatch { class ExternalDownloadsResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {

View File

@@ -12,7 +12,6 @@ import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.util.resources.ResourceUtils import app.revanced.util.resources.ResourceUtils
import app.revanced.util.resources.ResourceUtils.copyResources import app.revanced.util.resources.ResourceUtils.copyResources
@Name("Swipe controls resource patch")
@DependsOn([SettingsPatch::class]) @DependsOn([SettingsPatch::class])
@Version("0.0.1") @Version("0.0.1")
class SwipeControlsResourcePatch : ResourcePatch { class SwipeControlsResourcePatch : ResourcePatch {

View File

@@ -1,7 +1,5 @@
package app.revanced.patches.youtube.layout.hide.albumcards.resource.patch package app.revanced.patches.youtube.layout.hide.albumcards.resource.patch
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
@@ -10,13 +8,9 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.layout.hide.albumcards.annotations.AlbumCardsCompatibility
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@Name("Hide album cards resource patch")
@AlbumCardsCompatibility
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) @DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@Version("0.0.1")
class AlbumCardsResourcePatch : ResourcePatch { class AlbumCardsResourcePatch : ResourcePatch {
companion object { companion object {
internal var albumCardId: Long = -1 internal var albumCardId: Long = -1

View File

@@ -1,7 +1,5 @@
package app.revanced.patches.youtube.layout.hide.breakingnews.resource.patch package app.revanced.patches.youtube.layout.hide.breakingnews.resource.patch
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
@@ -12,9 +10,7 @@ import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@Name("Breaking news shelf resource patch")
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) @DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@Version("0.0.1")
class BreakingNewsResourcePatch : ResourcePatch { class BreakingNewsResourcePatch : ResourcePatch {
companion object { companion object {
internal var horizontalCardListId: Long = -1 internal var horizontalCardListId: Long = -1

View File

@@ -1,7 +1,5 @@
package app.revanced.patches.youtube.layout.hide.crowdfundingbox.resource.patch package app.revanced.patches.youtube.layout.hide.crowdfundingbox.resource.patch
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
@@ -10,13 +8,9 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.layout.hide.crowdfundingbox.annotations.CrowdfundingBoxCompatibility
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@Name("Crowdfunding box resource patch")
@CrowdfundingBoxCompatibility
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) @DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@Version("0.0.1")
class CrowdfundingBoxResourcePatch : ResourcePatch { class CrowdfundingBoxResourcePatch : ResourcePatch {
companion object { companion object {
internal var crowdfundingBoxId: Long = -1 internal var crowdfundingBoxId: Long = -1

View File

@@ -1,7 +1,5 @@
package app.revanced.patches.youtube.layout.hide.endscreencards.resource.patch package app.revanced.patches.youtube.layout.hide.endscreencards.resource.patch
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
@@ -10,13 +8,9 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.layout.hide.endscreencards.annotations.HideEndscreenCardsCompatibility
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@Name("Hide endscreen cards resource patch")
@HideEndscreenCardsCompatibility
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) @DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@Version("0.0.1")
class HideEndscreenCardsResourcePatch : ResourcePatch { class HideEndscreenCardsResourcePatch : ResourcePatch {
internal companion object { internal companion object {
var layoutCircle: Long = -1 var layoutCircle: Long = -1

View File

@@ -1,6 +1,5 @@
package app.revanced.patches.youtube.layout.hide.loadmorebutton.resource.patch package app.revanced.patches.youtube.layout.hide.loadmorebutton.resource.patch
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
@@ -9,12 +8,9 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.layout.hide.loadmorebutton.annotations.HideLoadMoreButtonCompatibility
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@Name("Hide load more button resource patch")
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) @DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@HideLoadMoreButtonCompatibility
class HideLoadMoreButtonResourcePatch : ResourcePatch { class HideLoadMoreButtonResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(

View File

@@ -1,7 +1,5 @@
package app.revanced.patches.youtube.layout.hide.personalinformation.resource.patch package app.revanced.patches.youtube.layout.hide.personalinformation.resource.patch
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
@@ -10,13 +8,9 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.layout.hide.personalinformation.annotations.HideEmailAddressCompatibility
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@Name("Hide email address resource patch")
@HideEmailAddressCompatibility
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) @DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@Version("0.0.1")
class HideEmailAddressResourcePatch : ResourcePatch { class HideEmailAddressResourcePatch : ResourcePatch {
companion object { companion object {
internal var accountSwitcherAccessibilityLabelId: Long = -1 internal var accountSwitcherAccessibilityLabelId: Long = -1

View File

@@ -8,13 +8,9 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.layout.hide.player.overlay.annotations.HidePlayerOverlayPatchCompatibility
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import jdk.jfr.Name
@Name("Hide player overlay resource patch")
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) @DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@HidePlayerOverlayPatchCompatibility
class HidePlayerOverlayResourcePatch : ResourcePatch { class HidePlayerOverlayResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(

View File

@@ -39,7 +39,7 @@ import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
PlayerTypeHookPatch::class, PlayerTypeHookPatch::class,
] ]
) )
@Name("Return youtube dislike") @Name("Return YouTube Dislike")
@Description("Shows the dislike count of videos using the Return YouTube Dislike API.") @Description("Shows the dislike count of videos using the Return YouTube Dislike API.")
@ReturnYouTubeDislikeCompatibility @ReturnYouTubeDislikeCompatibility
@Version("0.0.1") @Version("0.0.1")

View File

@@ -1,8 +1,5 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.resource.patch package app.revanced.patches.youtube.layout.returnyoutubedislike.resource.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
@@ -11,15 +8,10 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.Preference import app.revanced.patches.shared.settings.preference.impl.Preference
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.util.resources.ResourceUtils.mergeStrings import app.revanced.util.resources.ResourceUtils.mergeStrings
@DependsOn([SettingsPatch::class]) @DependsOn([SettingsPatch::class])
@Name("Return youtube dislike resource patch")
@Description("Adds the preferences for Return YouTube Dislike.")
@ReturnYouTubeDislikeCompatibility
@Version("0.0.1")
class ReturnYouTubeDislikeResourcePatch : ResourcePatch { class ReturnYouTubeDislikeResourcePatch : ResourcePatch {
companion object { companion object {
internal var oldUIDislikeId: Long = -1 internal var oldUIDislikeId: Long = -1

View File

@@ -1,7 +1,5 @@
package app.revanced.patches.youtube.layout.sponsorblock.resource.patch package app.revanced.patches.youtube.layout.sponsorblock.resource.patch
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
@@ -16,9 +14,7 @@ import app.revanced.util.resources.ResourceUtils.copyResources
import app.revanced.util.resources.ResourceUtils.copyXmlNode import app.revanced.util.resources.ResourceUtils.copyXmlNode
import app.revanced.util.resources.ResourceUtils.mergeStrings import app.revanced.util.resources.ResourceUtils.mergeStrings
@Name("SponsorBlock resource patch")
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) @DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@Version("0.0.1")
class SponsorBlockResourcePatch : ResourcePatch { class SponsorBlockResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {

View File

@@ -11,7 +11,7 @@ import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
@DependsOn([ResourceMappingPatch::class]) @DependsOn([ResourceMappingPatch::class])
class BottomSheetHookResourcePatch : ResourcePatch { class BottomSheetHookResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {
bottomSheetMargins = ResourceMappingPatch.resourceMappings.find { it.name == "bottomSheetMargins" }?.id bottomSheetMargins = ResourceMappingPatch.resourceMappings.find { it.name == "bottom_sheet_margins" }?.id
?: return PatchResultError("Could not find resource") ?: return PatchResultError("Could not find resource")
return PatchResultSuccess() return PatchResultSuccess()

View File

@@ -0,0 +1,27 @@
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.misc.fix.playback.patch.SpoofSignatureVerificationResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object ScrubbedPreviewLayoutFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("Landroid/content/Context;", "Landroid/util/AttributeSet;", "I", "I"),
opcodes = listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.INVOKE_VIRTUAL,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.IPUT_OBJECT, // preview imageview
),
// This resource is used in ~ 40 different locations, but this method has a distinct list of parameters to match to.
literal = SpoofSignatureVerificationResourcePatch.scrubbedPreviewThumbnailResourceId
)

View File

@@ -0,0 +1,23 @@
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
/**
* Resolves using the class found in [StoryboardThumbnailParentFingerprint].
*/
object StoryboardThumbnailFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "Z",
parameters = listOf(),
opcodes = listOf(
Opcode.MOVE_RESULT,
Opcode.IF_GTZ,
Opcode.GOTO,
Opcode.CONST_4,
Opcode.RETURN,
Opcode.RETURN, // Last instruction of method.
),
)

View File

@@ -0,0 +1,17 @@
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
/**
* Here lies code that creates the seekbar thumbnails.
*
* An additional change here might force the thumbnails to be created,
* or possibly a change somewhere else (maybe involving YouTube 18.23.35 class `hte`)
*/
object StoryboardThumbnailParentFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "Landroid/graphics/Bitmap;",
strings = listOf("Storyboard regionDecoder.decodeRegion exception - "),
)

View File

@@ -1,6 +1,5 @@
package app.revanced.patches.youtube.misc.fix.playback.fingerprints package app.revanced.patches.youtube.misc.fix.playback.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode

View File

@@ -7,47 +7,35 @@ import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.data.toMethodWalker import app.revanced.patcher.data.toMethodWalker
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.youtube.misc.fix.playback.fingerprints.*
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ProtobufParameterBuilderFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import org.jf.dexlib2.iface.instruction.ReferenceInstruction
@Name("Spoof signature verification") @Name("Spoof signature verification")
@Description("Spoofs a patched client to prevent playback issues.") @Description("Spoofs a patched client to prevent playback issues.")
@DependsOn([ @DependsOn([
SpoofSignatureVerificationResourcePatch::class,
IntegrationsPatch::class, IntegrationsPatch::class,
SettingsPatch::class, PlayerTypeHookPatch::class
PlayerTypeHookPatch::class,
]) ])
@Version("0.0.1") @Version("0.0.1")
class SpoofSignatureVerificationPatch : BytecodePatch( class SpoofSignatureVerificationPatch : BytecodePatch(
listOf( listOf(
ProtobufParameterBuilderFingerprint, ProtobufParameterBuilderFingerprint,
StoryboardThumbnailParentFingerprint,
ScrubbedPreviewLayoutFingerprint,
) )
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
SettingsPatch.PreferenceScreen.MISC.addPreferences(
SwitchPreference(
"revanced_spoof_signature_verification",
StringResource("revanced_spoof_signature_verification_title", "Spoof app signature"),
StringResource("revanced_spoof_signature_verification_summary_on",
"App signature spoofed\\n\\n"
+ "Side effects include:\\n"
+ "• Ambient mode may not work\\n"
+ "• Seekbar thumbnails are hidden\\n"
+ "• Downloading videos may not work"),
StringResource("revanced_spoof_signature_verification_summary_off", "App signature not spoofed"),
StringResource("revanced_spoof_signature_verification_user_dialog_message",
"Turning off this setting may cause playback issues.")
)
)
// hook parameter // hook parameter
ProtobufParameterBuilderFingerprint.result?.let { ProtobufParameterBuilderFingerprint.result?.let {
@@ -68,6 +56,53 @@ class SpoofSignatureVerificationPatch : BytecodePatch(
} }
} ?: return ProtobufParameterBuilderFingerprint.toErrorResult() } ?: return ProtobufParameterBuilderFingerprint.toErrorResult()
// When signature spoofing is enabled, the seekbar when tapped does not show
// the video time, chapter names, or the video thumbnail.
// Changing the value returned of this method forces all of these to show up,
// except the thumbnails are blank, which is handled with the patch below.
StoryboardThumbnailParentFingerprint.result ?: return StoryboardThumbnailParentFingerprint.toErrorResult()
StoryboardThumbnailFingerprint.resolve(context, StoryboardThumbnailParentFingerprint.result!!.classDef)
StoryboardThumbnailFingerprint.result?.apply {
val endIndex = scanResult.patternScanResult!!.endIndex
// Replace existing instruction to preserve control flow label.
// The replaced return instruction always returns false
// (it is the 'no thumbnails found' control path),
// so there is no need to pass the existing return value to integrations.
mutableMethod.replaceInstruction(
endIndex,
"""
invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->getSeekbarThumbnailOverrideValue()Z
"""
)
// Since this is end of the method must replace one line then add the rest.
mutableMethod.addInstructions(
endIndex + 1,
"""
move-result v0
return v0
"""
)
} ?: return StoryboardThumbnailFingerprint.toErrorResult()
// Seekbar thumbnail now show up but are always a blank image.
// Additional changes are needed to force the client to generate the thumbnails (assuming it's possible),
// but for now hide the empty thumbnail.
ScrubbedPreviewLayoutFingerprint.result?.apply {
val endIndex = scanResult.patternScanResult!!.endIndex
mutableMethod.apply {
val imageViewFieldName = getInstruction<ReferenceInstruction>(endIndex).reference
addInstructions(
implementation!!.instructions.lastIndex,
"""
iget-object v0, p0, $imageViewFieldName # copy imageview field to a register
invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->seekbarImageViewCreated(Landroid/widget/ImageView;)V
"""
)
}
} ?: return ScrubbedPreviewLayoutFingerprint.toErrorResult()
return PatchResultSuccess() return PatchResultSuccess()
} }

View File

@@ -0,0 +1,44 @@
package app.revanced.patches.youtube.misc.fix.playback.patch
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.*
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
class SpoofSignatureVerificationResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
SettingsPatch.PreferenceScreen.MISC.addPreferences(
SwitchPreference(
"revanced_spoof_signature_verification",
StringResource("revanced_spoof_signature_verification_title", "Spoof app signature"),
StringResource("revanced_spoof_signature_verification_summary_on",
"App signature spoofed\\n\\n"
+ "Side effects include:\\n"
+ "• Ambient mode may not work\\n"
+ "• Seekbar thumbnails are hidden\\n"
+ "• Downloading videos may not work"),
StringResource("revanced_spoof_signature_verification_summary_off", "App signature not spoofed"),
StringResource("revanced_spoof_signature_verification_user_dialog_message",
"Turning off this setting may cause playback issues.")
)
)
scrubbedPreviewThumbnailResourceId = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == "thumbnail"
}.id
return PatchResultSuccess()
}
companion object {
var scrubbedPreviewThumbnailResourceId: Long = -1
}
}

View File

@@ -176,7 +176,7 @@ class LithoFilterPatch : BytecodePatch(
""" """
new-instance v1, $classDescriptor new-instance v1, $classDescriptor
invoke-direct {v1}, $classDescriptor-><init>()V invoke-direct {v1}, $classDescriptor-><init>()V
const/4 v2, ${filterCount++} const/16 v2, ${filterCount++}
aput-object v1, v0, v2 aput-object v1, v0, v2
""" """
) )
@@ -187,7 +187,7 @@ class LithoFilterPatch : BytecodePatch(
} }
override fun close() = LithoFilterFingerprint.result!! override fun close() = LithoFilterFingerprint.result!!
.mutableMethod.replaceInstruction(0, "const/4 v0, $filterCount") .mutableMethod.replaceInstruction(0, "const/16 v0, $filterCount")
companion object { companion object {
private val MethodFingerprint.patternScanResult private val MethodFingerprint.patternScanResult
@@ -208,4 +208,4 @@ class LithoFilterPatch : BytecodePatch(
private var filterCount = 0 private var filterCount = 0
} }
} }

View File

@@ -1,8 +1,5 @@
package app.revanced.patches.youtube.misc.microg.patch.resource package app.revanced.patches.youtube.misc.microg.patch.resource
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
@@ -10,7 +7,6 @@ import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.settings.preference.impl.Preference import app.revanced.patches.shared.settings.preference.impl.Preference
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.youtube.misc.microg.annotations.MicroGPatchCompatibility
import app.revanced.patches.youtube.misc.microg.shared.Constants.PACKAGE_NAME import app.revanced.patches.youtube.misc.microg.shared.Constants.PACKAGE_NAME
import app.revanced.patches.youtube.misc.microg.shared.Constants.REVANCED_APP_NAME import app.revanced.patches.youtube.misc.microg.shared.Constants.REVANCED_APP_NAME
import app.revanced.patches.youtube.misc.microg.shared.Constants.REVANCED_PACKAGE_NAME import app.revanced.patches.youtube.misc.microg.shared.Constants.REVANCED_PACKAGE_NAME
@@ -22,11 +18,7 @@ import app.revanced.util.microg.Constants.MICROG_VENDOR
import app.revanced.util.microg.MicroGManifestHelper import app.revanced.util.microg.MicroGManifestHelper
import app.revanced.util.microg.MicroGResourceHelper import app.revanced.util.microg.MicroGResourceHelper
@Name("Vanced MicroG resource patch")
@DependsOn([SettingsResourcePatch::class]) @DependsOn([SettingsResourcePatch::class])
@Description("Resource patch to allow YouTube ReVanced to run without root and under a different package name.")
@MicroGPatchCompatibility
@Version("0.0.1")
class MicroGResourcePatch : ResourcePatch { class MicroGResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {
SettingsPatch.addPreference( SettingsPatch.addPreference(

View File

@@ -1,8 +1,5 @@
package app.revanced.patches.youtube.misc.playercontrols.resource.patch package app.revanced.patches.youtube.misc.playercontrols.resource.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.DomFileEditor import app.revanced.patcher.data.DomFileEditor
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
@@ -10,14 +7,9 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.playercontrols.annotation.PlayerControlsCompatibility
import java.io.Closeable import java.io.Closeable
@Name("Bottom controls resource patch")
@Description("Manages the resources for the bottom controls of the YouTube player.")
@PlayerControlsCompatibility
@DependsOn([ResourceMappingPatch::class]) @DependsOn([ResourceMappingPatch::class])
@Version("0.0.1")
class BottomControlsResourcePatch : ResourcePatch, Closeable { class BottomControlsResourcePatch : ResourcePatch, Closeable {
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {
resourceContext = context resourceContext = context

View File

@@ -1,8 +1,5 @@
package app.revanced.patches.youtube.misc.settings.resource.patch package app.revanced.patches.youtube.misc.settings.resource.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.DomFileEditor import app.revanced.patcher.data.DomFileEditor
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
@@ -19,10 +16,7 @@ import app.revanced.util.resources.ResourceUtils.mergeStrings
import org.w3c.dom.Element import org.w3c.dom.Element
import org.w3c.dom.Node import org.w3c.dom.Node
@Name("Settings resource patch")
@DependsOn([ResourceMappingPatch::class]) @DependsOn([ResourceMappingPatch::class])
@Description("Applies mandatory patches to implement ReVanced settings into the application.")
@Version("0.0.1")
class SettingsResourcePatch : AbstractSettingsResourcePatch( class SettingsResourcePatch : AbstractSettingsResourcePatch(
"revanced_prefs", "revanced_prefs",
"settings" "settings"

View File

@@ -21,7 +21,7 @@ import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
import org.jf.dexlib2.iface.reference.FieldReference import org.jf.dexlib2.iface.reference.FieldReference
@Patch @Patch
@Name("Hdr auto brightness") @Name("HDR auto brightness")
@Description("Makes the brightness of HDR videos follow the system default.") @Description("Makes the brightness of HDR videos follow the system default.")
@HDRBrightnessCompatibility @HDRBrightnessCompatibility
@Version("0.0.2") @Version("0.0.2")

View File

@@ -1,8 +0,0 @@
package app.revanced.patches.youtube.video.information.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object VideoTimeFingerprint : MethodFingerprint(
strings = listOf("MedialibPlayerTimeInfo{currentPositionMillis=")
)

View File

@@ -10,7 +10,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions 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.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
@@ -44,7 +43,6 @@ class VideoInformationPatch : BytecodePatch(
PlayerInitFingerprint, PlayerInitFingerprint,
CreateVideoPlayerSeekbarFingerprint, CreateVideoPlayerSeekbarFingerprint,
PlayerControllerSetTimeReferenceFingerprint, PlayerControllerSetTimeReferenceFingerprint,
VideoTimeFingerprint,
OnPlaybackSpeedItemClickFingerprint, OnPlaybackSpeedItemClickFingerprint,
) )
) { ) {
@@ -118,18 +116,10 @@ class VideoInformationPatch : BytecodePatch(
.getMethod() as MutableMethod .getMethod() as MutableMethod
} }
/*
* Set the high precision video time method
*/
highPrecisionTimeMethod =
(object : MethodFingerprint("V", null, listOf("J", "J", "J", "J", "I", "L"), null) {}).also {
it.resolve(context, VideoTimeFingerprint.result!!.classDef)
}.result!!.mutableMethod
/* /*
* Hook the methods which set the time * Hook the methods which set the time
*/ */
highPrecisionTimeHook(INTEGRATIONS_CLASS_DESCRIPTOR, "setVideoTimeHighPrecision") videoTimeHook(INTEGRATIONS_CLASS_DESCRIPTOR, "setVideoTime")
/* /*
@@ -164,9 +154,6 @@ class VideoInformationPatch : BytecodePatch(
private lateinit var timeMethod: MutableMethod private lateinit var timeMethod: MutableMethod
private var timeInitInsertIndex = 2 private var timeInitInsertIndex = 2
private lateinit var highPrecisionTimeMethod: MutableMethod
private var highPrecisionInsertIndex = 0
private fun MutableMethod.insert(insertIndex: Int, register: String, descriptor: String) = private fun MutableMethod.insert(insertIndex: Int, register: String, descriptor: String) =
addInstruction(insertIndex, "invoke-static { $register }, $descriptor") addInstruction(insertIndex, "invoke-static { $register }, $descriptor")
@@ -202,20 +189,6 @@ class VideoInformationPatch : BytecodePatch(
"$targetMethodClass->$targetMethodName(J)V" "$targetMethodClass->$targetMethodName(J)V"
) )
/**
* Hook the high precision video time.
* The hooks is called extremely often (10 to 15 times a seconds), so use with caution.
* Note: the hook is usually called _off_ the main thread
*
* @param targetMethodClass The descriptor for the static method to invoke when the player controller is created.
* @param targetMethodName The name of the static method to invoke when the player controller is created.
*/
internal fun highPrecisionTimeHook(targetMethodClass: String, targetMethodName: String) =
highPrecisionTimeMethod.insertTimeHook(
highPrecisionInsertIndex++,
"$targetMethodClass->$targetMethodName(J)V"
)
private fun getReference(instructions: List<BuilderInstruction>, offset: Int, opcode: Opcode) = private fun getReference(instructions: List<BuilderInstruction>, offset: Int, opcode: Opcode) =
(instructions[instructions.indexOfFirst { it.opcode == opcode } + offset] as ReferenceInstruction) (instructions[instructions.indexOfFirst { it.opcode == opcode } + offset] as ReferenceInstruction)
.reference.toString() .reference.toString()

View File

@@ -1,25 +1,25 @@
package app.revanced.patches.youtube.video.speed package app.revanced.patches.youtube.video.speed
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.youtube.video.speed.custom.patch.CustomVideoSpeedPatch import app.revanced.patches.youtube.video.speed.custom.patch.CustomPlaybackSpeedPatch
import app.revanced.patches.youtube.video.speed.remember.patch.RememberPlaybackSpeedPatch import app.revanced.patches.youtube.video.speed.remember.patch.RememberPlaybackSpeedPatch
@Patch @Patch
@Name("Video speed") @Name("Playback speed")
@Description("Adds custom video speeds and ability to remember the playback speed you chose in the video playback speed flyout.") @Description("Adds custom playback speeds and ability to remember the playback speed you chose in the video playback speed flyout.")
@DependsOn([CustomVideoSpeedPatch::class, RememberPlaybackSpeedPatch::class]) @DependsOn([CustomPlaybackSpeedPatch::class, RememberPlaybackSpeedPatch::class])
@VideoSpeedCompatibility @PlaybackSpeedCompatibility
@Version("0.0.1") @Version("0.0.1")
class VideoSpeed : BytecodePatch() { class PlaybackSpeed : BytecodePatch() {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
return PatchResultSuccess() // All patches this patch depends on succeed. return PatchResultSuccess() // All patches this patch depends on succeed.
} }
} }

View File

@@ -5,4 +5,4 @@ import app.revanced.patcher.annotation.Package
@Compatibility([Package("com.google.android.youtube", arrayOf("18.20.39", "18.23.35"))]) @Compatibility([Package("com.google.android.youtube", arrayOf("18.20.39", "18.23.35"))])
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
internal annotation class VideoSpeedCompatibility internal annotation class PlaybackSpeedCompatibility

View File

@@ -2,7 +2,7 @@ package app.revanced.patches.youtube.video.speed.custom.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object GetOldVideoSpeedsFingerprint : MethodFingerprint( object GetOldPlaybackSpeedsFingerprint : MethodFingerprint(
parameters = listOf("[L", "I"), parameters = listOf("[L", "I"),
strings = listOf("menu_item_playback_speed") strings = listOf("menu_item_playback_speed")
) )

View File

@@ -2,6 +2,6 @@ package app.revanced.patches.youtube.video.speed.custom.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object ShowOldVideoSpeedMenuFingerprint : MethodFingerprint( object ShowOldPlaybackSpeedMenuFingerprint : MethodFingerprint(
strings = listOf("PLAYBACK_RATE_MENU_BOTTOM_SHEET_FRAGMENT") strings = listOf("PLAYBACK_RATE_MENU_BOTTOM_SHEET_FRAGMENT")
) )

View File

@@ -0,0 +1,7 @@
package app.revanced.patches.youtube.video.speed.custom.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object ShowOldPlaybackSpeedMenuIntegrationsFingerprint : MethodFingerprint(
customFingerprint = { method, _ -> method.name == "showOldPlaybackSpeedMenu" }
)

View File

@@ -1,7 +0,0 @@
package app.revanced.patches.youtube.video.speed.custom.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object ShowOldVideoSpeedMenuIntegrationsFingerprint : MethodFingerprint(
customFingerprint = { method, _ -> method.name == "showOldVideoSpeedMenu" }
)

View File

@@ -31,16 +31,16 @@ import org.jf.dexlib2.iface.reference.FieldReference
import org.jf.dexlib2.iface.reference.MethodReference import org.jf.dexlib2.iface.reference.MethodReference
import org.jf.dexlib2.immutable.ImmutableField import org.jf.dexlib2.immutable.ImmutableField
@Name("Custom video speed") @Name("Custom playback speed")
@Description("Adds custom video speed options.") @Description("Adds custom playback speed options.")
@DependsOn([IntegrationsPatch::class, LithoFilterPatch::class, SettingsPatch::class, BottomSheetHookPatch::class]) @DependsOn([IntegrationsPatch::class, LithoFilterPatch::class, SettingsPatch::class, BottomSheetHookPatch::class])
@Version("0.0.1") @Version("0.0.1")
class CustomVideoSpeedPatch : BytecodePatch( class CustomPlaybackSpeedPatch : BytecodePatch(
listOf( listOf(
SpeedArrayGeneratorFingerprint, SpeedArrayGeneratorFingerprint,
SpeedLimiterFingerprint, SpeedLimiterFingerprint,
GetOldVideoSpeedsFingerprint, GetOldPlaybackSpeedsFingerprint,
ShowOldVideoSpeedMenuIntegrationsFingerprint ShowOldPlaybackSpeedMenuIntegrationsFingerprint
) )
) { ) {
@@ -81,12 +81,12 @@ class CustomVideoSpeedPatch : BytecodePatch(
val arrayLengthConstDestination = (arrayLengthConst as OneRegisterInstruction).registerA val arrayLengthConstDestination = (arrayLengthConst as OneRegisterInstruction).registerA
val videoSpeedsArrayType = "$INTEGRATIONS_CLASS_DESCRIPTOR->customVideoSpeeds:[F" val playbackSpeedsArrayType = "$INTEGRATIONS_CLASS_DESCRIPTOR->customPlaybackSpeeds:[F"
arrayGenMethod.addInstructions( arrayGenMethod.addInstructions(
arrayLengthConstIndex + 1, arrayLengthConstIndex + 1,
""" """
sget-object v$arrayLengthConstDestination, $videoSpeedsArrayType sget-object v$arrayLengthConstDestination, $playbackSpeedsArrayType
array-length v$arrayLengthConstDestination, v$arrayLengthConstDestination array-length v$arrayLengthConstDestination, v$arrayLengthConstDestination
""" """
) )
@@ -102,7 +102,7 @@ class CustomVideoSpeedPatch : BytecodePatch(
arrayGenMethod.replaceInstruction( arrayGenMethod.replaceInstruction(
originalArrayFetchIndex, originalArrayFetchIndex,
"sget-object v$originalArrayFetchDestination, $videoSpeedsArrayType" "sget-object v$originalArrayFetchDestination, $playbackSpeedsArrayType"
) )
val limiterMethod = SpeedLimiterFingerprint.result?.mutableMethod!! val limiterMethod = SpeedLimiterFingerprint.result?.mutableMethod!!
@@ -121,24 +121,24 @@ class CustomVideoSpeedPatch : BytecodePatch(
// edit: alternatively this might work by overriding with fixed values such as 0.1x and 10x // edit: alternatively this might work by overriding with fixed values such as 0.1x and 10x
limiterMethod.replaceInstruction( limiterMethod.replaceInstruction(
limiterMinConstIndex, limiterMinConstIndex,
"sget v$limiterMinConstDestination, $INTEGRATIONS_CLASS_DESCRIPTOR->minVideoSpeed:F" "sget v$limiterMinConstDestination, $INTEGRATIONS_CLASS_DESCRIPTOR->minPlaybackSpeed:F"
) )
limiterMethod.replaceInstruction( limiterMethod.replaceInstruction(
limiterMaxConstIndex, limiterMaxConstIndex,
"sget v$limiterMaxConstDestination, $INTEGRATIONS_CLASS_DESCRIPTOR->maxVideoSpeed:F" "sget v$limiterMaxConstDestination, $INTEGRATIONS_CLASS_DESCRIPTOR->maxPlaybackSpeed:F"
) )
// region Force old video quality menu. // region Force old video quality menu.
// This is necessary, because there is no known way of adding custom video speeds to the new menu. // This is necessary, because there is no known way of adding custom playback speeds to the new menu.
BottomSheetHookPatch.addHook(INTEGRATIONS_CLASS_DESCRIPTOR) BottomSheetHookPatch.addHook(INTEGRATIONS_CLASS_DESCRIPTOR)
// Required to check if the video speed menu is currently shown. // Required to check if the playback speed menu is currently shown.
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
GetOldVideoSpeedsFingerprint.result?.let { result -> GetOldPlaybackSpeedsFingerprint.result?.let { result ->
// Add a static INSTANCE field to the class. // Add a static INSTANCE field to the class.
// This is later used to call "showOldVideoSpeedMenu" on the instance. // This is later used to call "showOldPlaybackSpeedMenu" on the instance.
val instanceField = ImmutableField( val instanceField = ImmutableField(
result.classDef.type, result.classDef.type,
"INSTANCE", "INSTANCE",
@@ -154,15 +154,15 @@ class CustomVideoSpeedPatch : BytecodePatch(
// In order to prevent a conflict with another patch, add the instruction at index 1. // In order to prevent a conflict with another patch, add the instruction at index 1.
result.mutableMethod.addInstruction(1, "sput-object p0, $instanceField") result.mutableMethod.addInstruction(1, "sput-object p0, $instanceField")
// Get the "showOldVideoSpeedMenu" method. // Get the "showOldPlaybackSpeedMenu" method.
// This is later called on the field INSTANCE. // This is later called on the field INSTANCE.
val showOldVideoSpeedMenuMethod = ShowOldVideoSpeedMenuFingerprint.also { val showOldPlaybackSpeedMenuMethod = ShowOldPlaybackSpeedMenuFingerprint.also {
if (!it.resolve(context, result.classDef)) if (!it.resolve(context, result.classDef))
throw ShowOldVideoSpeedMenuFingerprint.toErrorResult() throw ShowOldPlaybackSpeedMenuFingerprint.toErrorResult()
}.result!!.method.toString() }.result!!.method.toString()
// Insert the call to the "showOldVideoSpeedMenu" method on the field INSTANCE. // Insert the call to the "showOldPlaybackSpeedMenu" method on the field INSTANCE.
ShowOldVideoSpeedMenuIntegrationsFingerprint.result?.mutableMethod?.apply { ShowOldPlaybackSpeedMenuIntegrationsFingerprint.result?.mutableMethod?.apply {
addInstructionsWithLabels( addInstructionsWithLabels(
implementation!!.instructions.lastIndex, implementation!!.instructions.lastIndex,
""" """
@@ -170,11 +170,11 @@ class CustomVideoSpeedPatch : BytecodePatch(
if-nez v0, :not_null if-nez v0, :not_null
return-void return-void
:not_null :not_null
invoke-virtual { v0 }, $showOldVideoSpeedMenuMethod invoke-virtual { v0 }, $showOldPlaybackSpeedMenuMethod
""" """
) )
} ?: return ShowOldVideoSpeedMenuIntegrationsFingerprint.toErrorResult() } ?: return ShowOldPlaybackSpeedMenuIntegrationsFingerprint.toErrorResult()
} ?: return GetOldVideoSpeedsFingerprint.toErrorResult() } ?: return GetOldPlaybackSpeedsFingerprint.toErrorResult()
// endregion // endregion
@@ -183,10 +183,10 @@ class CustomVideoSpeedPatch : BytecodePatch(
private companion object { private companion object {
private const val FILTER_CLASS_DESCRIPTOR = private const val FILTER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/patches/components/VideoSpeedMenuFilterPatch;" "Lapp/revanced/integrations/patches/components/PlaybackSpeedMenuFilterPatch;"
private const val INTEGRATIONS_CLASS_DESCRIPTOR = private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/patches/playback/speed/CustomVideoSpeedPatch;" "Lapp/revanced/integrations/patches/playback/speed/CustomPlaybackSpeedPatch;"
} }
} }

View File

@@ -19,13 +19,13 @@ import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.video.information.patch.VideoInformationPatch import app.revanced.patches.youtube.video.information.patch.VideoInformationPatch
import app.revanced.patches.youtube.video.speed.custom.patch.CustomVideoSpeedPatch import app.revanced.patches.youtube.video.speed.custom.patch.CustomPlaybackSpeedPatch
import app.revanced.patches.youtube.video.speed.remember.fingerprint.InitializePlaybackSpeedValuesFingerprint import app.revanced.patches.youtube.video.speed.remember.fingerprint.InitializePlaybackSpeedValuesFingerprint
import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction
@Name("Remember playback speed") @Name("Remember playback speed")
@Description("Adds the ability to remember the playback speed you chose in the video playback speed flyout.") @Description("Adds the ability to remember the playback speed you chose in the playback speed flyout.")
@DependsOn([IntegrationsPatch::class, SettingsPatch::class, VideoInformationPatch::class, CustomVideoSpeedPatch::class]) @DependsOn([IntegrationsPatch::class, SettingsPatch::class, VideoInformationPatch::class, CustomPlaybackSpeedPatch::class])
@Version("0.0.1") @Version("0.0.1")
class RememberPlaybackSpeedPatch : BytecodePatch( class RememberPlaybackSpeedPatch : BytecodePatch(
listOf( listOf(

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB