feat(youtube/custom-playback-speed): change to abstract patch

This commit is contained in:
inotia00 2023-09-17 23:15:02 +09:00
parent 907bcb9107
commit ec1ac206fe
5 changed files with 125 additions and 112 deletions

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.video.customspeed.fingerprints
package app.revanced.patches.shared.fingerprints.customspeed
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.video.customspeed.fingerprints
package app.revanced.patches.shared.fingerprints.customspeed
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
@ -11,10 +11,8 @@ object SpeedLimiterFallBackFingerprint : MethodFingerprint(
parameters = listOf("L"),
opcodes = listOf(
Opcode.CONST_HIGH16,
Opcode.GOTO,
Opcode.CONST_HIGH16,
Opcode.CONST_HIGH16,
Opcode.INVOKE_STATIC,
Opcode.INVOKE_STATIC
),
strings = listOf("Playback rate: %f")
)

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.video.customspeed.fingerprints
package app.revanced.patches.shared.fingerprints.customspeed
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
@ -10,11 +10,6 @@ object SpeedLimiterFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("F"),
opcodes = listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.CONST_HIGH16,
Opcode.GOTO,
Opcode.CONST_HIGH16,
Opcode.CONST_HIGH16,
Opcode.INVOKE_STATIC,

View File

@ -0,0 +1,116 @@
package app.revanced.patches.shared.patch.customspeed
import app.revanced.extensions.exception
import app.revanced.patcher.data.BytecodeContext
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.patches.shared.fingerprints.customspeed.SpeedArrayGeneratorFingerprint
import app.revanced.patches.shared.fingerprints.customspeed.SpeedLimiterFallBackFingerprint
import app.revanced.patches.shared.fingerprints.customspeed.SpeedLimiterFingerprint
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
abstract class AbstractCustomPlaybackSpeedPatch(
private val descriptor: String,
private val maxSpeed: Float
) : BytecodePatch(
listOf(
SpeedArrayGeneratorFingerprint,
SpeedLimiterFallBackFingerprint
)
) {
override fun execute(context: BytecodeContext) {
SpeedArrayGeneratorFingerprint.result?.let { result ->
result.mutableMethod.apply {
val targetIndex = result.scanResult.patternScanResult!!.startIndex
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstructions(
targetIndex + 1, """
invoke-static {v$targetRegister}, $descriptor->getLength(I)I
move-result v$targetRegister
"""
)
val targetInstruction = implementation!!.instructions
for ((index, instruction) in targetInstruction.withIndex()) {
if (instruction.opcode != Opcode.INVOKE_INTERFACE) continue
val sizeInstruction = getInstruction<Instruction35c>(index)
if ((sizeInstruction.reference as MethodReference).name != "size") continue
val register = getInstruction<OneRegisterInstruction>(index + 1).registerA
addInstructions(
index + 2, """
invoke-static {v$register}, $descriptor->getSize(I)I
move-result v$register
"""
)
break
}
for ((index, instruction) in targetInstruction.withIndex()) {
if (instruction.opcode != Opcode.SGET_OBJECT) continue
val targetReference =
getInstruction<ReferenceInstruction>(index).reference.toString()
if (targetReference.endsWith(":[F")) {
val register = getInstruction<OneRegisterInstruction>(index).registerA
addInstructions(
index + 1, """
invoke-static {v$register}, $descriptor->getArray([F)[F
move-result-object v$register
"""
)
break
}
}
}
} ?: throw SpeedArrayGeneratorFingerprint.exception
val speedLimiterParentResult = SpeedLimiterFallBackFingerprint.result
?: throw SpeedLimiterFallBackFingerprint.exception
SpeedLimiterFingerprint.resolve(context, speedLimiterParentResult.classDef)
val speedLimiterResult = SpeedLimiterFingerprint.result
?: throw SpeedLimiterFingerprint.exception
arrayOf(
speedLimiterParentResult,
speedLimiterResult
).forEach { result ->
result.mutableMethod.apply {
val limiterMinConstIndex =
implementation!!.instructions.indexOfFirst { (it as? NarrowLiteralInstruction)?.narrowLiteral == 0.25f.toRawBits() }
val limiterMaxConstIndex =
implementation!!.instructions.indexOfFirst { (it as? NarrowLiteralInstruction)?.narrowLiteral == 2.0f.toRawBits() }
val limiterMinConstDestination =
getInstruction<OneRegisterInstruction>(limiterMinConstIndex).registerA
val limiterMaxConstDestination =
getInstruction<OneRegisterInstruction>(limiterMaxConstIndex).registerA
replaceInstruction(
limiterMinConstIndex,
"const/high16 v$limiterMinConstDestination, 0x0"
)
replaceInstruction(
limiterMaxConstIndex,
"const/high16 v$limiterMaxConstDestination, ${maxSpeed.toRawBits()}"
)
}
}
}
}

View File

@ -1,28 +1,15 @@
package app.revanced.patches.youtube.video.customspeed.patch
import app.revanced.extensions.exception
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.data.BytecodeContext
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.patch.BytecodePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.shared.patch.customspeed.AbstractCustomPlaybackSpeedPatch
import app.revanced.patches.youtube.flyoutpanel.oldspeedlayout.patch.OldSpeedLayoutPatch
import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility
import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch
import app.revanced.patches.youtube.video.customspeed.fingerprints.SpeedArrayGeneratorFingerprint
import app.revanced.patches.youtube.video.customspeed.fingerprints.SpeedLimiterFallBackFingerprint
import app.revanced.patches.youtube.video.customspeed.fingerprints.SpeedLimiterFingerprint
import app.revanced.util.integrations.Constants.VIDEO_PATH
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Patch
@Name("Custom playback speed")
@ -34,94 +21,12 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
]
)
@YouTubeCompatibility
class CustomPlaybackSpeedPatch : BytecodePatch(
listOf(
SpeedArrayGeneratorFingerprint,
SpeedLimiterFallBackFingerprint,
SpeedLimiterFingerprint
)
class CustomPlaybackSpeedPatch : AbstractCustomPlaybackSpeedPatch(
"$VIDEO_PATH/CustomPlaybackSpeedPatch;",
10.0f
) {
override fun execute(context: BytecodeContext) {
SpeedArrayGeneratorFingerprint.result?.let { result ->
result.mutableMethod.apply {
val targetIndex = result.scanResult.patternScanResult!!.startIndex
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstructions(
targetIndex + 1, """
invoke-static {v$targetRegister}, $VIDEO_PATH/CustomPlaybackSpeedPatch;->getLength(I)I
move-result v$targetRegister
"""
)
val targetInstruction = implementation!!.instructions
for ((index, instruction) in targetInstruction.withIndex()) {
if (instruction.opcode != Opcode.INVOKE_INTERFACE) continue
val sizeInstruction = getInstruction<Instruction35c>(index)
if ((sizeInstruction.reference as MethodReference).name != "size") continue
val register = getInstruction<OneRegisterInstruction>(index + 1).registerA
addInstructions(
index + 2, """
invoke-static {v$register}, $VIDEO_PATH/CustomPlaybackSpeedPatch;->getSize(I)I
move-result v$register
"""
)
break
}
for ((index, instruction) in targetInstruction.withIndex()) {
if (instruction.opcode != Opcode.SGET_OBJECT) continue
val targetReference =
getInstruction<ReferenceInstruction>(index).reference.toString()
if (targetReference.contains("PlayerConfigModel;") && targetReference.endsWith("[F")) {
val register = getInstruction<OneRegisterInstruction>(index).registerA
addInstructions(
index + 1, """
invoke-static {v$register}, $VIDEO_PATH/CustomPlaybackSpeedPatch;->getArray([F)[F
move-result-object v$register
"""
)
break
}
}
}
} ?: throw SpeedArrayGeneratorFingerprint.exception
arrayOf(
SpeedLimiterFallBackFingerprint,
SpeedLimiterFingerprint
).forEach { fingerprint ->
fingerprint.result?.let { result ->
result.mutableMethod.apply {
val limiterMinConstIndex =
implementation!!.instructions.indexOfFirst { (it as? NarrowLiteralInstruction)?.narrowLiteral == 0.25f.toRawBits() }
val limiterMaxConstIndex =
implementation!!.instructions.indexOfFirst { (it as? NarrowLiteralInstruction)?.narrowLiteral == 2.0f.toRawBits() }
val limiterMinConstDestination =
getInstruction<OneRegisterInstruction>(limiterMinConstIndex).registerA
val limiterMaxConstDestination =
getInstruction<OneRegisterInstruction>(limiterMaxConstIndex).registerA
replaceInstruction(
limiterMinConstIndex,
"const/high16 v$limiterMinConstDestination, 0x0"
)
replaceInstruction(
limiterMaxConstIndex,
"const/high16 v$limiterMaxConstDestination, 0x41200000 # 10.0f"
)
}
} ?: throw fingerprint.exception
}
super.execute(context)
/**
* Add settings
@ -134,6 +39,5 @@ class CustomPlaybackSpeedPatch : BytecodePatch(
)
SettingsPatch.updatePatchStatus("custom-playback-speed")
}
}