mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-06-12 05:07:41 +02:00
feat(youtube): add save-video-speed
settings
This commit is contained in:
@ -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" }
|
||||
)
|
@ -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")
|
||||
)
|
@ -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
|
||||
)
|
||||
)
|
@ -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
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user