feat(music/enable-opus-codec): change to abstract patch

This commit is contained in:
inotia00 2023-06-20 14:42:38 +09:00
parent 5b476eca33
commit 89358f86a0
5 changed files with 84 additions and 71 deletions

View File

@ -1,18 +0,0 @@
package app.revanced.patches.music.misc.codecs.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 AllCodecsFingerprint : MethodFingerprint(
returnType = "J",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf(
Opcode.IF_NEZ,
Opcode.GOTO,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.INVOKE_STATIC
)
)

View File

@ -1,29 +1,18 @@
package app.revanced.patches.music.misc.codecs.patch package app.revanced.patches.music.misc.codecs.patch
import app.revanced.extensions.toErrorResult
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.data.toMethodWalker
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
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.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.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.misc.codecs.fingerprints.AllCodecsFingerprint
import app.revanced.patches.music.misc.codecs.fingerprints.AllCodecsParentFingerprint
import app.revanced.patches.music.misc.codecs.fingerprints.CodecsLockFingerprint
import app.revanced.patches.music.utils.settings.resource.patch.MusicSettingsPatch import app.revanced.patches.music.utils.settings.resource.patch.MusicSettingsPatch
import app.revanced.patches.shared.annotation.YouTubeMusicCompatibility import app.revanced.patches.shared.annotation.YouTubeMusicCompatibility
import app.revanced.patches.shared.patch.opus.AbstractOpusCodecsPatch
import app.revanced.util.enum.CategoryType import app.revanced.util.enum.CategoryType
import app.revanced.util.integrations.Constants.MUSIC_MISC_PATH import app.revanced.util.integrations.Constants.MUSIC_MISC_PATH
import org.jf.dexlib2.iface.Method
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Patch @Patch
@Name("enable-opus-codec") @Name("enable-opus-codec")
@ -31,45 +20,14 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@DependsOn([MusicSettingsPatch::class]) @DependsOn([MusicSettingsPatch::class])
@YouTubeMusicCompatibility @YouTubeMusicCompatibility
@Version("0.0.1") @Version("0.0.1")
class CodecsUnlockPatch : BytecodePatch( class CodecsUnlockPatch : AbstractOpusCodecsPatch(
listOf( "$MUSIC_MISC_PATH/OpusCodecPatch;->enableOpusCodec()Z"
AllCodecsParentFingerprint,
CodecsLockFingerprint
)
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
super.execute(context)
AllCodecsParentFingerprint.result?.let { parentResult ->
AllCodecsFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let {
allCodecsMethod = context.toMethodWalker(it.method)
.nextMethod(it.scanResult.patternScanResult!!.endIndex)
.getMethod()
} ?: return AllCodecsFingerprint.toErrorResult()
} ?: return AllCodecsParentFingerprint.toErrorResult()
CodecsLockFingerprint.result?.let {
it.mutableMethod.apply {
val targetIndex = it.scanResult.patternScanResult!!.endIndex
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstructionsWithLabels(
targetIndex + 1, """
invoke-static {}, $MUSIC_MISC_PATH/OpusCodecPatch;->enableOpusCodec()Z
move-result v7
if-eqz v7, :mp4a
invoke-static {}, ${allCodecsMethod.definingClass}->${allCodecsMethod.name}()Ljava/util/Set;
move-result-object v$targetRegister
""", ExternalLabel("mp4a", getInstruction(targetIndex + 1))
)
}
} ?: return CodecsLockFingerprint.toErrorResult()
MusicSettingsPatch.addMusicPreference(CategoryType.MISC, "revanced_enable_opus_codec", "true") MusicSettingsPatch.addMusicPreference(CategoryType.MISC, "revanced_enable_opus_codec", "true")
return PatchResultSuccess() return PatchResultSuccess()
} }
private companion object {
lateinit var allCodecsMethod: Method
}
} }

View File

@ -1,16 +1,14 @@
package app.revanced.patches.music.misc.codecs.fingerprints package app.revanced.patches.shared.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
object AllCodecsParentFingerprint : MethodFingerprint( object CodecReferenceFingerprint : MethodFingerprint(
returnType = "J", returnType = "J",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("L"), parameters = listOf("L"),
opcodes = listOf( opcodes = listOf(Opcode.INVOKE_SUPER),
Opcode.INVOKE_SUPER
),
strings = listOf("itag") strings = listOf("itag")
) )

View File

@ -1,11 +1,11 @@
package app.revanced.patches.music.misc.codecs.fingerprints package app.revanced.patches.shared.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
object CodecsLockFingerprint : MethodFingerprint( object CodecSelectorFingerprint : MethodFingerprint(
returnType = "L", returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
opcodes = listOf( opcodes = listOf(

View File

@ -0,0 +1,75 @@
package app.revanced.patches.shared.patch.opus
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.fingerprints.CodecReferenceFingerprint
import app.revanced.patches.shared.fingerprints.CodecSelectorFingerprint
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.Reference
@Name("abstract-opus-codec")
@Version("0.0.1")
abstract class AbstractOpusCodecsPatch(
private val descriptor: String
) : BytecodePatch(
listOf(
CodecReferenceFingerprint,
CodecSelectorFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
CodecReferenceFingerprint.result?.mutableMethod?.let {
it.implementation!!.instructions.apply {
var targetIndex = 0
for ((index, instruction) in withIndex()) {
if (instruction.opcode != Opcode.INVOKE_STATIC) continue
val targetParameter = it.getInstruction<ReferenceInstruction>(index).reference
if (targetParameter.toString().endsWith("Ljava/util/Set;")) {
targetReference = targetParameter
targetIndex = index
break
}
}
if (targetIndex == 0)
throw PatchResultError("Target method not found!")
}
} ?: return CodecReferenceFingerprint.toErrorResult()
CodecSelectorFingerprint.result?.let {
it.mutableMethod.apply {
val targetIndex = it.scanResult.patternScanResult!!.endIndex
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstructionsWithLabels(
targetIndex + 1, """
invoke-static {}, $descriptor
move-result v7
if-eqz v7, :mp4a
invoke-static {}, $targetReference
move-result-object v$targetRegister
""", ExternalLabel("mp4a", getInstruction(targetIndex + 1))
)
}
} ?: return CodecSelectorFingerprint.toErrorResult()
return PatchResultSuccess()
}
companion object {
lateinit var targetReference: Reference
}
}