mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-27 20:51:03 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2193a0307e | ||
|
|
58dcd172f9 | ||
|
|
f818396243 | ||
|
|
3d124af58c | ||
|
|
df18d4a15a | ||
|
|
f08a2b6a90 | ||
|
|
fce8df8284 | ||
|
|
6ec99045d7 | ||
|
|
757784b038 | ||
|
|
7e06f23e29 |
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
|||||||
runs-on: ubuntu-18.04
|
runs-on: ubuntu-18.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Setup JDK
|
- name: Setup JDK
|
||||||
|
|||||||
30
CHANGELOG.md
30
CHANGELOG.md
@@ -1,3 +1,33 @@
|
|||||||
|
## [2.100.3](https://github.com/revanced/revanced-patches/compare/v2.100.2...v2.100.3) (2022-11-01)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube/video-ads:** add switch to temporarily fix buffering issues ([7aa3bce](https://github.com/revanced/revanced-patches/commit/7aa3bce6ccd669a66de10ef6ffe2151f27b40365))
|
||||||
|
|
||||||
|
## [2.100.2](https://github.com/revanced/revanced-patches/compare/v2.100.1...v2.100.2) (2022-10-31)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube/theme-patch:** respect app specific theme ([#946](https://github.com/revanced/revanced-patches/issues/946)) ([fe8d6c7](https://github.com/revanced/revanced-patches/commit/fe8d6c7b2c10be5cca0717b6a03cfa1bef10e2c0))
|
||||||
|
|
||||||
|
## [2.100.1](https://github.com/revanced/revanced-patches/compare/v2.100.0...v2.100.1) (2022-10-31)
|
||||||
|
|
||||||
|
# [2.100.0](https://github.com/revanced/revanced-patches/compare/v2.99.0...v2.100.0) (2022-10-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* `hide-watch-in-vr` patch ([#911](https://github.com/revanced/revanced-patches/issues/911)) ([8ea0b20](https://github.com/revanced/revanced-patches/commit/8ea0b20e96df53211039df0468b2d4a735a381f1))
|
||||||
|
|
||||||
|
# [2.99.0](https://github.com/revanced/revanced-patches/compare/v2.98.0...v2.99.0) (2022-10-29)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube/sponsorblock:** skip segments once automatically ([#907](https://github.com/revanced/revanced-patches/issues/907)) ([afc7588](https://github.com/revanced/revanced-patches/commit/afc75882062a9316dbc28a9dc4f990cf88b52654))
|
||||||
|
|
||||||
# [2.98.0](https://github.com/revanced/revanced-patches/compare/v2.97.0...v2.98.0) (2022-10-29)
|
# [2.98.0](https://github.com/revanced/revanced-patches/compare/v2.97.0...v2.98.0) (2022-10-29)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ The official Patch bundle provided by ReVanced and the community.
|
|||||||
| `hide-cast-button` | Hides the cast button in the video player. | all |
|
| `hide-cast-button` | Hides the cast button in the video player. | all |
|
||||||
| `sponsorblock` | Integrate SponsorBlock. | 17.41.37 |
|
| `sponsorblock` | Integrate SponsorBlock. | 17.41.37 |
|
||||||
| `hide-autoplay-button` | Hides the autoplay button in the video player. | 17.41.37 |
|
| `hide-autoplay-button` | Hides the autoplay button in the video player. | 17.41.37 |
|
||||||
|
| `hide-watch-in-vr` | Hides the Watch in VR option from the player settings flyout panel. | 17.41.37 |
|
||||||
| `hide-album-cards` | Hides the album cards below the artist description. | 17.41.37 |
|
| `hide-album-cards` | Hides the album cards below the artist description. | 17.41.37 |
|
||||||
| `disable-auto-player-popup-panels` | Disable automatic popup panels (playlist or live chat) on video player. | 17.41.37 |
|
| `disable-auto-player-popup-panels` | Disable automatic popup panels (playlist or live chat) on video player. | 17.41.37 |
|
||||||
| `disable-auto-captions` | Disable forced captions from being automatically enabled. | 17.41.37 |
|
| `disable-auto-captions` | Disable forced captions from being automatically enabled. | 17.41.37 |
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
kotlin.code.style = official
|
kotlin.code.style = official
|
||||||
version = 2.98.0
|
version = 2.100.3
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -15,12 +15,13 @@ import app.revanced.patcher.util.smali.ExternalLabel
|
|||||||
import app.revanced.patches.youtube.ad.video.annotations.VideoAdsCompatibility
|
import app.revanced.patches.youtube.ad.video.annotations.VideoAdsCompatibility
|
||||||
import app.revanced.patches.youtube.ad.video.fingerprints.LoadVideoAdsFingerprint
|
import app.revanced.patches.youtube.ad.video.fingerprints.LoadVideoAdsFingerprint
|
||||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
|
import app.revanced.patches.youtube.misc.playback.patch.FixPlaybackPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
|
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
|
||||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
|
@DependsOn([IntegrationsPatch::class, SettingsPatch::class, FixPlaybackPatch::class])
|
||||||
@Name("video-ads")
|
@Name("video-ads")
|
||||||
@Description("Removes ads in the video player.")
|
@Description("Removes ads in the video player.")
|
||||||
@VideoAdsCompatibility
|
@VideoAdsCompatibility
|
||||||
|
|||||||
@@ -7,40 +7,41 @@ import app.revanced.patcher.data.BytecodeContext
|
|||||||
import app.revanced.patcher.data.toMethodWalker
|
import app.revanced.patcher.data.toMethodWalker
|
||||||
import app.revanced.patcher.extensions.addInstruction
|
import app.revanced.patcher.extensions.addInstruction
|
||||||
import app.revanced.patcher.extensions.addInstructions
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
import app.revanced.patcher.extensions.or
|
|
||||||
import app.revanced.patcher.extensions.replaceInstruction
|
import app.revanced.patcher.extensions.replaceInstruction
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
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
|
||||||
|
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.proxy.mutableTypes.MutableMethod
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
|
||||||
import app.revanced.patches.youtube.layout.autocaptions.fingerprints.StartVideoInformerFingerprint
|
import app.revanced.patches.youtube.layout.autocaptions.fingerprints.StartVideoInformerFingerprint
|
||||||
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
|
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
|
||||||
import app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints.*
|
import app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints.*
|
||||||
import app.revanced.patches.youtube.layout.sponsorblock.resource.patch.SponsorBlockResourcePatch
|
import app.revanced.patches.youtube.layout.sponsorblock.resource.patch.SponsorBlockResourcePatch
|
||||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
||||||
|
import app.revanced.patches.youtube.misc.playercontroller.patch.PlayerControllerPatch
|
||||||
import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch
|
import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch
|
||||||
import app.revanced.patches.youtube.misc.videoid.patch.VideoIdPatch
|
import app.revanced.patches.youtube.misc.videoid.patch.VideoIdPatch
|
||||||
import org.jf.dexlib2.AccessFlags
|
|
||||||
import org.jf.dexlib2.Opcode
|
import org.jf.dexlib2.Opcode
|
||||||
import org.jf.dexlib2.builder.MutableMethodImplementation
|
|
||||||
import org.jf.dexlib2.iface.instruction.*
|
import org.jf.dexlib2.iface.instruction.*
|
||||||
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
|
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
|
||||||
import org.jf.dexlib2.iface.reference.FieldReference
|
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.iface.reference.StringReference
|
import org.jf.dexlib2.iface.reference.StringReference
|
||||||
import org.jf.dexlib2.immutable.ImmutableMethod
|
|
||||||
import org.jf.dexlib2.immutable.ImmutableMethodParameter
|
|
||||||
import org.jf.dexlib2.util.MethodUtil
|
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
@DependsOn(
|
@DependsOn(
|
||||||
dependencies = [PlayerControlsBytecodePatch::class, IntegrationsPatch::class, SponsorBlockResourcePatch::class, VideoIdPatch::class]
|
dependencies = [
|
||||||
|
PlayerControllerPatch::class, // updates video length and adds method to seek in video
|
||||||
|
PlayerControlsBytecodePatch::class,
|
||||||
|
IntegrationsPatch::class,
|
||||||
|
SponsorBlockResourcePatch::class,
|
||||||
|
VideoIdPatch::class
|
||||||
|
]
|
||||||
)
|
)
|
||||||
@Name("sponsorblock")
|
@Name("sponsorblock")
|
||||||
@Description("Integrate SponsorBlock.")
|
@Description("Integrate SponsorBlock.")
|
||||||
@@ -53,7 +54,6 @@ class SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
VideoTimeFingerprint,
|
VideoTimeFingerprint,
|
||||||
NextGenWatchLayoutFingerprint,
|
NextGenWatchLayoutFingerprint,
|
||||||
AppendTimeFingerprint,
|
AppendTimeFingerprint,
|
||||||
PlayerInitFingerprint,
|
|
||||||
PlayerOverlaysLayoutInitFingerprint,
|
PlayerOverlaysLayoutInitFingerprint,
|
||||||
ShortsPlayerConstructorFingerprint,
|
ShortsPlayerConstructorFingerprint,
|
||||||
StartVideoInformerFingerprint
|
StartVideoInformerFingerprint
|
||||||
@@ -160,23 +160,6 @@ class SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
"invoke-static {v$canvasInstance, v$centerY}, Lapp/revanced/integrations/sponsorblock/PlayerController;->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V"
|
"invoke-static {v$canvasInstance, v$centerY}, Lapp/revanced/integrations/sponsorblock/PlayerController;->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
|
||||||
Set video length
|
|
||||||
*/
|
|
||||||
VideoLengthFingerprint.resolve(context, seekbarSignatureResult.classDef)
|
|
||||||
val videoLengthMethodResult = VideoLengthFingerprint.result!!
|
|
||||||
val videoLengthMethod = videoLengthMethodResult.mutableMethod
|
|
||||||
val videoLengthMethodInstructions = videoLengthMethod.implementation!!.instructions
|
|
||||||
|
|
||||||
val videoLengthRegister =
|
|
||||||
(videoLengthMethodInstructions[videoLengthMethodResult.scanResult.patternScanResult!!.endIndex - 2] as OneRegisterInstruction).registerA
|
|
||||||
val dummyRegisterForLong =
|
|
||||||
videoLengthRegister + 1 // this is required for long values since they are 64 bit wide
|
|
||||||
videoLengthMethod.addInstruction(
|
|
||||||
videoLengthMethodResult.scanResult.patternScanResult!!.endIndex,
|
|
||||||
"invoke-static {v$videoLengthRegister, v$dummyRegisterForLong}, Lapp/revanced/integrations/sponsorblock/PlayerController;->setVideoLength(J)V"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Voting & Shield button
|
Voting & Shield button
|
||||||
*/
|
*/
|
||||||
@@ -249,12 +232,7 @@ class SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
)
|
)
|
||||||
|
|
||||||
// initialize the player controller
|
// initialize the player controller
|
||||||
val initFingerprintResult = PlayerInitFingerprint.result!!
|
PlayerControllerPatch.onCreateHook("Lapp/revanced/integrations/sponsorblock/PlayerController;", "initialize")
|
||||||
val initInstanceRegister = 0
|
|
||||||
initFingerprintResult.mutableClass.methods.first { MethodUtil.isConstructor(it) }.addInstruction(
|
|
||||||
4, // after super class invoke
|
|
||||||
"invoke-static {v$initInstanceRegister}, Lapp/revanced/integrations/sponsorblock/PlayerController;->onCreate(Ljava/lang/Object;)V"
|
|
||||||
)
|
|
||||||
|
|
||||||
// initialize the sponsorblock view
|
// initialize the sponsorblock view
|
||||||
PlayerOverlaysLayoutInitFingerprint.result!!.mutableMethod.addInstruction(
|
PlayerOverlaysLayoutInitFingerprint.result!!.mutableMethod.addInstruction(
|
||||||
@@ -262,39 +240,6 @@ class SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
"invoke-static {p0}, Lapp/revanced/integrations/sponsorblock/player/ui/SponsorBlockView;->initialize(Ljava/lang/Object;)V"
|
"invoke-static {p0}, Lapp/revanced/integrations/sponsorblock/player/ui/SponsorBlockView;->initialize(Ljava/lang/Object;)V"
|
||||||
)
|
)
|
||||||
|
|
||||||
// lastly create hooks for the player controller
|
|
||||||
|
|
||||||
// get original seek method
|
|
||||||
SeekFingerprint.resolve(context, initFingerprintResult.classDef)
|
|
||||||
val seekFingerprintResultMethod = SeekFingerprint.result!!.method
|
|
||||||
// get enum type for the seek helper method
|
|
||||||
val seekSourceEnumType = seekFingerprintResultMethod.parameterTypes[1].toString()
|
|
||||||
|
|
||||||
// create helper method
|
|
||||||
val seekHelperMethod = ImmutableMethod(
|
|
||||||
seekFingerprintResultMethod.definingClass,
|
|
||||||
"seekHelper",
|
|
||||||
listOf(ImmutableMethodParameter("J", null, "time")),
|
|
||||||
"Z",
|
|
||||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
|
||||||
null, null,
|
|
||||||
MutableMethodImplementation(4)
|
|
||||||
).toMutable()
|
|
||||||
|
|
||||||
// insert helper method instructions
|
|
||||||
seekHelperMethod.addInstructions(
|
|
||||||
0,
|
|
||||||
"""
|
|
||||||
sget-object v0, $seekSourceEnumType->a:$seekSourceEnumType
|
|
||||||
invoke-virtual {p0, p1, p2, v0}, ${seekFingerprintResultMethod.definingClass}->${seekFingerprintResultMethod.name}(J$seekSourceEnumType)Z
|
|
||||||
move-result p1
|
|
||||||
return p1
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
// add the helper method to the original class
|
|
||||||
initFingerprintResult.mutableClass.methods.add(seekHelperMethod)
|
|
||||||
|
|
||||||
// get rectangle field name
|
// get rectangle field name
|
||||||
RectangleFieldInvalidatorFingerprint.resolve(context, seekbarSignatureResult.classDef)
|
RectangleFieldInvalidatorFingerprint.resolve(context, seekbarSignatureResult.classDef)
|
||||||
val rectangleFieldInvalidatorInstructions =
|
val rectangleFieldInvalidatorInstructions =
|
||||||
@@ -302,35 +247,31 @@ class SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
val rectangleFieldName =
|
val rectangleFieldName =
|
||||||
((rectangleFieldInvalidatorInstructions.elementAt(rectangleFieldInvalidatorInstructions.count() - 3) as ReferenceInstruction).reference as FieldReference).name
|
((rectangleFieldInvalidatorInstructions.elementAt(rectangleFieldInvalidatorInstructions.count() - 3) as ReferenceInstruction).reference as FieldReference).name
|
||||||
|
|
||||||
// get the player controller class from the integrations
|
|
||||||
val playerControllerMethods =
|
|
||||||
context.proxy(context.classes.first { it.type.endsWith("PlayerController;") }).mutableClass.methods
|
|
||||||
|
|
||||||
// get the method which contain the "replaceMe" strings
|
|
||||||
val replaceMeMethods =
|
|
||||||
playerControllerMethods.filter { it.name == "onCreate" || it.name == "setSponsorBarRect" }
|
|
||||||
|
|
||||||
fun MutableMethod.replaceStringInstruction(index: Int, instruction: Instruction, with: String) {
|
|
||||||
val register = (instruction as OneRegisterInstruction).registerA
|
|
||||||
this.replaceInstruction(
|
|
||||||
index, "const-string v$register, \"$with\""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// replace the "replaceMeWith*" strings
|
// replace the "replaceMeWith*" strings
|
||||||
for (method in replaceMeMethods) {
|
context
|
||||||
for ((index, it) in method.implementation!!.instructions.withIndex()) {
|
.proxy(context.classes.first { it.type.endsWith("PlayerController;") })
|
||||||
if (it.opcode.ordinal != Opcode.CONST_STRING.ordinal) continue
|
.mutableClass
|
||||||
|
.methods
|
||||||
when (((it as ReferenceInstruction).reference as StringReference).string) {
|
.find { it.name == "setSponsorBarRect" }
|
||||||
"replaceMeWithsetSponsorBarRect" ->
|
?.let { method ->
|
||||||
method.replaceStringInstruction(index, it, rectangleFieldName)
|
fun MutableMethod.replaceStringInstruction(index: Int, instruction: Instruction, with: String) {
|
||||||
|
val register = (instruction as OneRegisterInstruction).registerA
|
||||||
"replaceMeWithsetMillisecondMethod" ->
|
this.replaceInstruction(
|
||||||
method.replaceStringInstruction(index, it, "seekHelper")
|
index, "const-string v$register, \"$with\""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
for ((index, it) in method.implementation!!.instructions.withIndex()) {
|
||||||
}
|
if (it.opcode.ordinal != Opcode.CONST_STRING.ordinal) continue
|
||||||
|
|
||||||
|
when (((it as ReferenceInstruction).reference as StringReference).string) {
|
||||||
|
"replaceMeWithsetSponsorBarRect" ->
|
||||||
|
method.replaceStringInstruction(index, it, rectangleFieldName)
|
||||||
|
|
||||||
|
"replaceMeWithsetMillisecondMethod" ->
|
||||||
|
method.replaceStringInstruction(index, it, "seekHelper")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} ?: return PatchResultError("Could not find the method which contains the replaceMeWith* strings")
|
||||||
|
|
||||||
val startVideoInformerMethod = StartVideoInformerFingerprint.result!!.mutableMethod
|
val startVideoInformerMethod = StartVideoInformerFingerprint.result!!.mutableMethod
|
||||||
startVideoInformerMethod.addInstructions(
|
startVideoInformerMethod.addInstructions(
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.watchinvr.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf("17.33.42", "17.34.36", "17.36.37", "17.41.37")
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class WatchinVRCompatibility
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.watchinvr.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.watchinvr.annotations.WatchinVRCompatibility
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
@Name("watch-in-vr-fingerprint")
|
||||||
|
@WatchinVRCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object WatchinVRFingerprint : MethodFingerprint(
|
||||||
|
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("Z"),
|
||||||
|
strings = listOf("menu_item_cardboard_vr")
|
||||||
|
)
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.watchinvr.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.youtube.layout.watchinvr.annotations.WatchinVRCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.watchinvr.fingerprints.WatchinVRFingerprint
|
||||||
|
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.framework.components.impl.StringResource
|
||||||
|
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
|
||||||
|
@Name("hide-watch-in-vr")
|
||||||
|
@Description("Hides the Watch in VR option from the player settings flyout panel.")
|
||||||
|
@WatchinVRCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class WatchinVRPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
WatchinVRFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_watch_in_vr",
|
||||||
|
StringResource("revanced_hide_watch_in_vr_title", "Hide Watch in VR option"),
|
||||||
|
false,
|
||||||
|
StringResource("revanced_hide_watch_in_vr_summary_on", "Watch in VR option is hidden"),
|
||||||
|
StringResource("revanced_hide_watch_in_vr_summary_off", "Watch in VR option is shown")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
WatchinVRFingerprint.result!!.mutableMethod.addInstructions(
|
||||||
|
0, """
|
||||||
|
invoke-static {}, Lapp/revanced/integrations/patches/HideWatchinVRPatch;->hideWatchinVR()Z
|
||||||
|
move-result v0
|
||||||
|
if-eqz v0, :shown
|
||||||
|
return-void
|
||||||
|
:shown
|
||||||
|
nop
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.playback.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf("17.41.37")
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class FixPlaybackCompatibility
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.playback.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.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.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
|
import app.revanced.patches.youtube.misc.playback.annotations.FixPlaybackCompatibility
|
||||||
|
import app.revanced.patches.youtube.misc.playercontroller.patch.PlayerControllerPatch
|
||||||
|
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||||
|
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
|
||||||
|
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||||
|
import app.revanced.patches.youtube.misc.videoid.patch.VideoIdPatch
|
||||||
|
|
||||||
|
@DependsOn([
|
||||||
|
IntegrationsPatch::class,
|
||||||
|
PlayerControllerPatch::class, // updates video length and adds method to seek in video, necessary for this patch
|
||||||
|
SettingsPatch::class,
|
||||||
|
VideoIdPatch::class
|
||||||
|
])
|
||||||
|
@Name("fix-playback")
|
||||||
|
@Description("Fixes the issue with videos not playing when video ads are removed.")
|
||||||
|
@FixPlaybackCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class FixPlaybackPatch : ResourcePatch {
|
||||||
|
override fun execute(context: ResourceContext): PatchResult {
|
||||||
|
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_fix_playback",
|
||||||
|
StringResource("revanced_fix_playback_title", "Fix video playback issues"),
|
||||||
|
false,
|
||||||
|
StringResource(
|
||||||
|
"revanced_fix_playback_summary_on",
|
||||||
|
"The fix is enabled"
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_fix_playback_summary_off",
|
||||||
|
"The fix is disabled"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// If a new video loads, fix the playback issue
|
||||||
|
VideoIdPatch.injectCall("Lapp/revanced/integrations/patches/FixPlaybackPatch;->newVideoLoaded(Ljava/lang/String;)V")
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.playercontroller.annotation
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf("17.41.37")
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class PlayerControllerCompatibility
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.playercontroller.fingerprint
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
|
||||||
|
|
||||||
|
@Name("create-video-player-seekbar-fingerprint")
|
||||||
|
@SponsorBlockCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object CreateVideoPlayerSeekbarFingerprint : MethodFingerprint(
|
||||||
|
"V",
|
||||||
|
strings = listOf("timed_markers_width")
|
||||||
|
)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints
|
package app.revanced.patches.youtube.misc.playercontroller.fingerprint
|
||||||
|
|
||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints
|
package app.revanced.patches.youtube.misc.playercontroller.fingerprint
|
||||||
|
|
||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints
|
package app.revanced.patches.youtube.misc.playercontroller.fingerprint
|
||||||
|
|
||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.playercontroller.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.addInstruction
|
||||||
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.instruction
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||||
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
|
import app.revanced.patches.youtube.misc.playercontroller.annotation.PlayerControllerCompatibility
|
||||||
|
import app.revanced.patches.youtube.misc.playercontroller.fingerprint.CreateVideoPlayerSeekbarFingerprint
|
||||||
|
import app.revanced.patches.youtube.misc.playercontroller.fingerprint.PlayerInitFingerprint
|
||||||
|
import app.revanced.patches.youtube.misc.playercontroller.fingerprint.SeekFingerprint
|
||||||
|
import app.revanced.patches.youtube.misc.playercontroller.fingerprint.VideoLengthFingerprint
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
import org.jf.dexlib2.builder.MutableMethodImplementation
|
||||||
|
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
import org.jf.dexlib2.immutable.ImmutableMethod
|
||||||
|
import org.jf.dexlib2.immutable.ImmutableMethodParameter
|
||||||
|
import org.jf.dexlib2.util.MethodUtil
|
||||||
|
|
||||||
|
@Name("player-controller-hook")
|
||||||
|
@Description("Hooks the player controller")
|
||||||
|
@PlayerControllerCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
@DependsOn([IntegrationsPatch::class])
|
||||||
|
class PlayerControllerPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
PlayerInitFingerprint,
|
||||||
|
CreateVideoPlayerSeekbarFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
with(PlayerInitFingerprint.result!!) {
|
||||||
|
playerInitMethod = mutableClass.methods.first { MethodUtil.isConstructor(it) }
|
||||||
|
|
||||||
|
// hook the player controller for use through integrations
|
||||||
|
onCreateHook(INTEGRATIONS_CLASS_DESCRIPTOR, "playerController_onCreateHook")
|
||||||
|
|
||||||
|
// seek method
|
||||||
|
val seekFingerprintResultMethod = SeekFingerprint.also { it.resolve(context, classDef) }.result!!.method
|
||||||
|
|
||||||
|
// create helper method
|
||||||
|
val seekHelperMethod = ImmutableMethod(
|
||||||
|
seekFingerprintResultMethod.definingClass,
|
||||||
|
"seekTo",
|
||||||
|
listOf(ImmutableMethodParameter("J", null, "time")),
|
||||||
|
"Z",
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
null, null,
|
||||||
|
MutableMethodImplementation(4)
|
||||||
|
).toMutable()
|
||||||
|
|
||||||
|
// get enum type for the seek helper method
|
||||||
|
val seekSourceEnumType = seekFingerprintResultMethod.parameterTypes[1].toString()
|
||||||
|
|
||||||
|
// insert helper method instructions
|
||||||
|
seekHelperMethod.addInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
sget-object v0, $seekSourceEnumType->a:$seekSourceEnumType
|
||||||
|
invoke-virtual {p0, p1, p2, v0}, ${seekFingerprintResultMethod.definingClass}->${seekFingerprintResultMethod.name}(J$seekSourceEnumType)Z
|
||||||
|
move-result p1
|
||||||
|
return p1
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
// add the seekTo method to the class for the integrations to call
|
||||||
|
mutableClass.methods.add(seekHelperMethod)
|
||||||
|
}
|
||||||
|
|
||||||
|
with(CreateVideoPlayerSeekbarFingerprint.result!!) {
|
||||||
|
val videoLengthMethodResult = VideoLengthFingerprint.also { it.resolve(context, classDef) }.result!!
|
||||||
|
|
||||||
|
with(videoLengthMethodResult.mutableMethod) {
|
||||||
|
val videoLengthRegisterIndex = videoLengthMethodResult.scanResult.patternScanResult!!.endIndex - 2
|
||||||
|
val videoLengthRegister = (instruction(videoLengthRegisterIndex) as OneRegisterInstruction).registerA
|
||||||
|
val dummyRegisterForLong = videoLengthRegister + 1 // required for long values since they are wide
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
videoLengthMethodResult.scanResult.patternScanResult!!.endIndex,
|
||||||
|
"invoke-static {v$videoLengthRegister, v$dummyRegisterForLong}, $INTEGRATIONS_CLASS_DESCRIPTOR->setCurrentVideoLength(J)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/PlayerControllerPatch;"
|
||||||
|
private const val INSERT_INDEX = 4
|
||||||
|
|
||||||
|
private lateinit var playerInitMethod: MutableMethod
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook the player controller.
|
||||||
|
*
|
||||||
|
* @param targetMethodClass The descriptor for the static method to invoke when the player controller is created.
|
||||||
|
*/
|
||||||
|
internal fun onCreateHook(targetMethodClass: String, targetMethodName: String) =
|
||||||
|
playerInitMethod.addInstruction(
|
||||||
|
INSERT_INDEX,
|
||||||
|
"invoke-static { v0 }, $targetMethodClass->$targetMethodName(Ljava/lang/Object;)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,9 +24,9 @@ object ThemeSetterAppFingerprint : MethodFingerprint(
|
|||||||
Opcode.MOVE_RESULT_OBJECT,
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
Opcode.SGET_OBJECT,
|
Opcode.SGET_OBJECT,
|
||||||
Opcode.IF_NE,
|
Opcode.IF_NE,
|
||||||
Opcode.CONST,
|
Opcode.CONST, //target reference
|
||||||
Opcode.GOTO,
|
Opcode.GOTO,
|
||||||
Opcode.CONST,
|
Opcode.CONST, //target reference
|
||||||
Opcode.INVOKE_DIRECT,
|
Opcode.INVOKE_DIRECT,
|
||||||
Opcode.RETURN_OBJECT,
|
Opcode.RETURN_OBJECT,
|
||||||
Opcode.NEW_INSTANCE,
|
Opcode.NEW_INSTANCE,
|
||||||
@@ -34,6 +34,6 @@ object ThemeSetterAppFingerprint : MethodFingerprint(
|
|||||||
Opcode.MOVE_RESULT_OBJECT,
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
Opcode.SGET_OBJECT,
|
Opcode.SGET_OBJECT,
|
||||||
Opcode.IF_NE,
|
Opcode.IF_NE,
|
||||||
Opcode.CONST,
|
Opcode.CONST, //target reference
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -75,7 +75,15 @@ class SettingsPatch : BytecodePatch(
|
|||||||
scanResult.patternScanResult!!.endIndex + 1,
|
scanResult.patternScanResult!!.endIndex + 1,
|
||||||
buildInstructionsString(1)
|
buildInstructionsString(1)
|
||||||
)
|
)
|
||||||
|
addInstructions(
|
||||||
|
scanResult.patternScanResult!!.endIndex - 7,
|
||||||
|
buildInstructionsString(0)
|
||||||
|
)
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
scanResult.patternScanResult!!.endIndex - 9,
|
||||||
|
buildInstructionsString(1)
|
||||||
|
)
|
||||||
addInstructions(
|
addInstructions(
|
||||||
mutableMethod.implementation!!.instructions.size - 2,
|
mutableMethod.implementation!!.instructions.size - 2,
|
||||||
buildInstructionsString(0)
|
buildInstructionsString(0)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import app.revanced.patches.youtube.misc.videoid.fingerprint.VideoIdFingerprint
|
|||||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
|
||||||
@Name("video-id-hook")
|
@Name("video-id-hook")
|
||||||
@Description("Hook to detect when the video id changes")
|
@Description("Hooks to detect when the video id changes")
|
||||||
@VideoIdCompatibility
|
@VideoIdCompatibility
|
||||||
@Version("0.0.1")
|
@Version("0.0.1")
|
||||||
@DependsOn([IntegrationsPatch::class])
|
@DependsOn([IntegrationsPatch::class])
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
<string name="skipped_filler">Skipped filler</string>
|
<string name="skipped_filler">Skipped filler</string>
|
||||||
<string name="skipped_unsubmitted">Skipped unsubmitted segment</string>
|
<string name="skipped_unsubmitted">Skipped unsubmitted segment</string>
|
||||||
<string name="skip_automatically">Skip automatically</string>
|
<string name="skip_automatically">Skip automatically</string>
|
||||||
|
<string name="skip_automatically_once">Skip automatically once</string>
|
||||||
<string name="skip_showbutton">Show a skip button</string>
|
<string name="skip_showbutton">Show a skip button</string>
|
||||||
<string name="skip_ignore">Don\'t do anything</string>
|
<string name="skip_ignore">Don\'t do anything</string>
|
||||||
<string name="skip_sponsor">Skip segment</string>
|
<string name="skip_sponsor">Skip segment</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user