diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/bytecode/fingerprints/VideoSpeedChangedFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/speed/bytecode/fingerprints/VideoSpeedChangedFingerprint.kt new file mode 100644 index 000000000..091159ee1 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/video/speed/bytecode/fingerprints/VideoSpeedChangedFingerprint.kt @@ -0,0 +1,17 @@ +package app.revanced.patches.youtube.video.speed.bytecode.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.Opcode + +object VideoSpeedChangedFingerprint : MethodFingerprint( + opcodes = listOf( + Opcode.IGET_OBJECT, + Opcode.IF_EQZ, + Opcode.IF_EQZ, + Opcode.IGET, + Opcode.CHECK_CAST, + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL + ), + customFingerprint = { it.name == "onItemClick" } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/bytecode/fingerprints/VideoSpeedParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/speed/bytecode/fingerprints/VideoSpeedParentFingerprint.kt new file mode 100644 index 000000000..c97886640 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/video/speed/bytecode/fingerprints/VideoSpeedParentFingerprint.kt @@ -0,0 +1,8 @@ +package app.revanced.patches.youtube.video.speed.bytecode.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint + +object VideoSpeedParentFingerprint : MethodFingerprint( + returnType = "V", + strings = listOf("PLAYBACK_RATE_MENU_BOTTOM_SHEET_FRAGMENT") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/bytecode/fingerprints/VideoUserSpeedChangeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/speed/bytecode/fingerprints/VideoUserSpeedChangeFingerprint.kt deleted file mode 100644 index 5ae0f6e50..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/video/speed/bytecode/fingerprints/VideoUserSpeedChangeFingerprint.kt +++ /dev/null @@ -1,27 +0,0 @@ -package app.revanced.patches.youtube.video.speed.bytecode.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 - -object VideoUserSpeedChangeFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("L","L","I","J"), - listOf( - Opcode.IGET_OBJECT, - Opcode.IF_EQZ, - Opcode.IF_EQZ, - Opcode.IGET, - Opcode.CHECK_CAST, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/bytecode/patch/VideoSpeedBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/speed/bytecode/patch/VideoSpeedBytecodePatch.kt index af2296c21..f6d889d4e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/speed/bytecode/patch/VideoSpeedBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/speed/bytecode/patch/VideoSpeedBytecodePatch.kt @@ -7,22 +7,25 @@ import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.annotations.DependsOn 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.Companion.toMutable import app.revanced.patcher.util.smali.toInstructions -import app.revanced.patches.youtube.video.speed.bytecode.fingerprints.VideoSpeedSetterFingerprint -import app.revanced.patches.youtube.video.speed.bytecode.fingerprints.VideoUserSpeedChangeFingerprint import app.revanced.patches.youtube.misc.videoid.legacy.patch.LegacyVideoIdPatch +import app.revanced.patches.youtube.video.speed.bytecode.fingerprints.VideoSpeedChangedFingerprint +import app.revanced.patches.youtube.video.speed.bytecode.fingerprints.VideoSpeedParentFingerprint +import app.revanced.patches.youtube.video.speed.bytecode.fingerprints.VideoSpeedSetterFingerprint import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.util.bytecode.BytecodeHelper import app.revanced.shared.util.integrations.Constants.VIDEO_PATH import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.dexbacked.reference.DexBackedMethodReference +import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.reference.FieldReference -import org.jf.dexlib2.iface.reference.MethodReference import org.jf.dexlib2.immutable.ImmutableMethod import org.jf.dexlib2.immutable.ImmutableMethodImplementation import org.jf.dexlib2.immutable.ImmutableMethodParameter @@ -33,74 +36,83 @@ import org.jf.dexlib2.immutable.ImmutableMethodParameter @Version("0.0.1") class VideoSpeedBytecodePatch : BytecodePatch( listOf( - VideoSpeedSetterFingerprint, VideoUserSpeedChangeFingerprint + VideoSpeedChangedFingerprint, + VideoSpeedParentFingerprint, + VideoSpeedSetterFingerprint ) ) { - private companion object { - const val INTEGRATIONS_VIDEO_SPEED_CLASS_DESCRIPTOR = - "$VIDEO_PATH/VideoSpeedPatch;" - } override fun execute(context: BytecodeContext): PatchResult { - val userSpeedResult = VideoUserSpeedChangeFingerprint.result!! - val userSpeedMutableMethod = userSpeedResult.mutableMethod + VideoSpeedParentFingerprint.result?.let { parentResult -> + val parentClassDef = parentResult.classDef - val setterResult = VideoSpeedSetterFingerprint.result!! - val setterMutableMethod = setterResult.mutableMethod + VideoSpeedChangedFingerprint.also { it.resolve(context, parentClassDef) }.result?.let { result -> + startIndex = result.scanResult.patternScanResult!!.startIndex + endIndex = result.scanResult.patternScanResult!!.endIndex + + with (result.method) { + val speedInstruction = implementation!!.instructions - VideoUserSpeedChangeFingerprint.resolve(context, setterResult.classDef) - val FirstReference = - VideoUserSpeedChangeFingerprint.result!!.method.let { method -> - (method.implementation!!.instructions.elementAt(5) as ReferenceInstruction).reference as FieldReference - } - val SecondReference = - VideoUserSpeedChangeFingerprint.result!!.method.let { method -> - (method.implementation!!.instructions.elementAt(10) as ReferenceInstruction).reference as FieldReference - } - val ThirdReference = - VideoUserSpeedChangeFingerprint.result!!.method.let { method -> - (method.implementation!!.instructions.elementAt(11) as ReferenceInstruction).reference as MethodReference - } + firstRef = + (speedInstruction.elementAt(startIndex) as ReferenceInstruction).reference as FieldReference - userSpeedMutableMethod.addInstruction( - 0, "invoke-static {}, $INTEGRATIONS_VIDEO_SPEED_CLASS_DESCRIPTOR->userChangedSpeed()V" - ) + secondRef = + (speedInstruction.elementAt(endIndex - 1) as ReferenceInstruction).reference as FieldReference - setterMutableMethod.addInstructions( - 0, - """ - invoke-static {p1, p2}, $INTEGRATIONS_VIDEO_SPEED_CLASS_DESCRIPTOR->getSpeedValue([Ljava/lang/Object;I)F - move-result v0 - invoke-direct {p0, v0}, ${setterResult.classDef.type}->overrideSpeed(F)V - """, - ) + thirdRef = + (speedInstruction.elementAt(endIndex) as ReferenceInstruction).reference as DexBackedMethodReference - val classDef = userSpeedResult.mutableClass - classDef.methods.add( - ImmutableMethod( - classDef.type, - "overrideSpeed", - listOf(ImmutableMethodParameter("F", null, null)), - "V", - AccessFlags.PRIVATE or AccessFlags.PRIVATE, - null, - null, - ImmutableMethodImplementation( - 4, """ - const/4 v0, 0x0 - cmpg-float v0, v3, v0 - if-gez v0, :cond_0 - return-void - :cond_0 - iget-object v0, v2, ${setterResult.classDef.type}->${FirstReference.name}:${FirstReference.type} - check-cast v0, ${SecondReference.definingClass} - iget-object v1, v0, ${SecondReference.definingClass}->${SecondReference.name}:${SecondReference.type} - invoke-virtual {v1, v3}, $ThirdReference - return-void - """.toInstructions(), null, null + val register = + (speedInstruction.elementAt(endIndex) as FiveRegisterInstruction).registerD + + result.mutableMethod.addInstruction( + endIndex, + "invoke-static { v$register }, $INTEGRATIONS_VIDEO_SPEED_CLASS_DESCRIPTOR" + + "->" + + "userChangedSpeed(F)V" + ) + } + + } ?: return VideoSpeedChangedFingerprint.toErrorResult() + + val parentMutableClass = parentResult.mutableClass + + parentMutableClass.methods.add( + ImmutableMethod( + parentMutableClass.type, + "overrideSpeed", + listOf(ImmutableMethodParameter("F", null, null)), + "V", + AccessFlags.PRIVATE or AccessFlags.PRIVATE, + null, + null, + ImmutableMethodImplementation( + 4, """ + const/4 v0, 0x0 + cmpg-float v0, v3, v0 + if-lez v0, :cond_0 + iget-object v0, v2, ${parentClassDef.type}->${firstRef.name}:${firstRef.type} + check-cast v0, ${secondRef.definingClass} + iget-object v1, v0, ${secondRef.definingClass}->${secondRef.name}:${secondRef.type} + invoke-virtual {v1, v3}, $thirdRef + :cond_0 + return-void + """.toInstructions(), null, null + ) + ).toMutable() + ) + + } ?: return VideoSpeedParentFingerprint.toErrorResult() + + VideoSpeedSetterFingerprint.result?.let { result -> + result.mutableMethod.addInstructions( + 0, """ + invoke-static {}, $INTEGRATIONS_VIDEO_SPEED_CLASS_DESCRIPTOR->getSpeedValue()F + move-result v0 + invoke-direct {p0, v0}, ${result.classDef.type}->overrideSpeed(F)V + """, ) - ).toMutable() - ) + } ?: return VideoSpeedSetterFingerprint.toErrorResult() LegacyVideoIdPatch.injectCall("$INTEGRATIONS_VIDEO_SPEED_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V") @@ -108,4 +120,16 @@ class VideoSpeedBytecodePatch : BytecodePatch( return PatchResultSuccess() } + + private companion object { + const val INTEGRATIONS_VIDEO_SPEED_CLASS_DESCRIPTOR = + "$VIDEO_PATH/VideoSpeedPatch;" + + var startIndex: Int = 0 + var endIndex: Int = 0 + + private lateinit var firstRef: FieldReference + private lateinit var secondRef: FieldReference + private lateinit var thirdRef: DexBackedMethodReference + } } \ No newline at end of file diff --git a/src/main/resources/youtube/settings/host/values/strings.xml b/src/main/resources/youtube/settings/host/values/strings.xml index 58d8f756f..e2ee161de 100644 --- a/src/main/resources/youtube/settings/host/values/strings.xml +++ b/src/main/resources/youtube/settings/host/values/strings.xml @@ -239,6 +239,9 @@ Is it ready to submit?" Does not save video quality values even when changing video quality Save the video quality value whenever you change the video quality Enable save video quality + Does not save video speed values even when changing video speed + Save the video speed value whenever you change the video speed + Enable save video speed Seekbar tapping is enabled Enable seekbar tapping Even if the brightness is set to 0 by swiping, auto brightness is not activated @@ -507,6 +510,13 @@ Would you like to continue?" Dislikes shown with separator Dislikes with separator Hidden + Failed to set quality + No internet connection + Changing default mobile data quality to: + Failed to change default mobile data quality + Changing default Wi-Fi quality to: + Failed to change default WI-FI quality + Changing default speed to: ReVanced settings Swipe controls related settings Swipe controls settings @@ -522,12 +532,6 @@ Would you like to continue?" Video ads are shown Video ads are hidden Hide video ads - Failed to set quality - No internet connection - Changing default mobile data quality to: - Failed to change default mobile data quality - Changing default Wi-Fi quality to: - Failed to change default WI-FI quality Video related settings Video settings Failed to add channel %s to the %s whitelist diff --git a/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 3aee4d57e..c26dba799 100644 --- a/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -295,6 +295,9 @@ + +