diff --git a/src/main/kotlin/app/revanced/patches/shared/litho/LithoFilterPatch.kt b/src/main/kotlin/app/revanced/patches/shared/litho/LithoFilterPatch.kt index 5f3092409..44f846c43 100644 --- a/src/main/kotlin/app/revanced/patches/shared/litho/LithoFilterPatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/litho/LithoFilterPatch.kt @@ -96,17 +96,20 @@ object LithoFilterPatch : BytecodePatch( } .map { (index, _) -> index } .reversed() - .forEach { - val insertRegister = - getInstruction(it + 1).registerA - val insertIndex = it + 2 + .forEach { index -> + val insertInstruction = getInstruction(index + 1) + if (insertInstruction is OneRegisterInstruction) { + val insertRegister = + insertInstruction.registerA + val insertIndex = index + 2 - addInstructionsWithLabels( - insertIndex, """ + addInstructionsWithLabels( + insertIndex, """ if-nez v$insertRegister, :ignore """ + emptyComponentLabel, - ExternalLabel("ignore", getInstruction(insertIndex)) - ) + ExternalLabel("ignore", getInstruction(insertIndex)) + ) + } } emptyComponentLabel = """ diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt index eca7754ce..e87f246ba 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt @@ -50,6 +50,7 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT import app.revanced.util.findMethodOrThrow import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow @@ -147,13 +148,15 @@ object PlayerComponentsPatch : BaseBytecodePatch( hookInitVideoPanel(1) } else { val syntheticIndex = - indexOfFirstInstructionOrThrow(Opcode.NEW_INSTANCE) - val syntheticReference = - getInstruction(syntheticIndex).reference.toString() + indexOfFirstInstruction(0, Opcode.NEW_INSTANCE) + if (syntheticIndex >= 0) { + val syntheticReference = + getInstruction(syntheticIndex).reference.toString() - context.findMethodOrThrow(syntheticReference) { - name == "onClick" - }.hookInitVideoPanel(0) + context.findMethodOrThrow(syntheticReference) { + name == "onClick" + }.hookInitVideoPanel(0) + } } } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/fingerprints/BuildBrowseRequestFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/fingerprints/BuildBrowseRequestFingerprint.kt index d59e46819..1d6862602 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/fingerprints/BuildBrowseRequestFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/fingerprints/BuildBrowseRequestFingerprint.kt @@ -25,7 +25,7 @@ internal object BuildBrowseRequestFingerprint : MethodFingerprint( fun indexOfRequestFinishedListenerInstruction(methodDef: Method) = methodDef.indexOfFirstInstruction { opcode == Opcode.INVOKE_VIRTUAL && - getReference().toString() == "Lorg/chromium/net/ExperimentalUrlRequest${'$'}Builder;->setRequestFinishedListener(Lorg/chromium/net/RequestFinishedInfo${'$'}Listener;)Lorg/chromium/net/ExperimentalUrlRequest${'$'}Builder;" + getReference()?.name == "setRequestFinishedListener" } fun indexOfNewUrlRequestBuilderInstruction(methodDef: Method) = diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/suggestedvideoendscreen/SuggestedVideoEndScreenPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/suggestedvideoendscreen/SuggestedVideoEndScreenPatch.kt index a4b297c0b..b078d06c2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/suggestedvideoendscreen/SuggestedVideoEndScreenPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/suggestedvideoendscreen/SuggestedVideoEndScreenPatch.kt @@ -6,20 +6,28 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.youtube.utils.fix.suggestedvideoendscreen.fingerprints.AutoNavConstructorFingerprint +import app.revanced.patches.youtube.utils.fix.suggestedvideoendscreen.fingerprints.AutoNavStatusFingerprint import app.revanced.patches.youtube.utils.fix.suggestedvideoendscreen.fingerprints.RemoveOnLayoutChangeListenerFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR +import app.revanced.util.alsoResolve +import app.revanced.util.getReference import app.revanced.util.getWalkerMethod import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow import app.revanced.util.resultOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference @Patch( description = "Fixes an issue where the suggested video end screen is always visible regardless of whether autoplay is set or not." ) object SuggestedVideoEndScreenPatch : BytecodePatch( - setOf(RemoveOnLayoutChangeListenerFingerprint) + setOf( + AutoNavConstructorFingerprint, + RemoveOnLayoutChangeListenerFingerprint + ) ) { override fun execute(context: BytecodeContext) { @@ -36,15 +44,23 @@ object SuggestedVideoEndScreenPatch : BytecodePatch( it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex) walkerIndex.apply { - val invokeInterfaceIndex = - indexOfFirstInstructionOrThrow(opcode = Opcode.INVOKE_INTERFACE) + val autoNavStatusMethodName = AutoNavStatusFingerprint.alsoResolve( + context, AutoNavConstructorFingerprint + ).mutableMethod.name + val invokeIndex = + indexOfFirstInstructionOrThrow { + val reference = getReference() + reference?.returnType == "Z" && + reference.parameterTypes.size == 0 && + reference.name == autoNavStatusMethodName + } val iGetObjectIndex = - indexOfFirstInstructionReversedOrThrow(invokeInterfaceIndex, Opcode.IGET_OBJECT) + indexOfFirstInstructionReversedOrThrow(invokeIndex, Opcode.IGET_OBJECT) - val invokeInterfaceReference = - getInstruction(invokeInterfaceIndex).reference + val invokeReference = getInstruction(invokeIndex).reference val iGetObjectReference = getInstruction(iGetObjectIndex).reference + val opcodeName = getInstruction(invokeIndex).opcode.name addInstructionsWithLabels( 0, @@ -56,7 +72,7 @@ object SuggestedVideoEndScreenPatch : BytecodePatch( iget-object v0, p0, $iGetObjectReference # This reference checks whether autoplay is turned on. - invoke-interface {v0}, $invokeInterfaceReference + $opcodeName {v0}, $invokeReference move-result v0 # Hide suggested video end screen only when autoplay is turned off. diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/suggestedvideoendscreen/fingerprints/AutoNavConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/suggestedvideoendscreen/fingerprints/AutoNavConstructorFingerprint.kt new file mode 100644 index 000000000..348ffbaad --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/suggestedvideoendscreen/fingerprints/AutoNavConstructorFingerprint.kt @@ -0,0 +1,11 @@ +package app.revanced.patches.youtube.utils.fix.suggestedvideoendscreen.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object AutoNavConstructorFingerprint : MethodFingerprint( + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + strings = listOf("main_app_autonav"), +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/suggestedvideoendscreen/fingerprints/AutoNavStatusFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/suggestedvideoendscreen/fingerprints/AutoNavStatusFingerprint.kt new file mode 100644 index 000000000..818e4c5f9 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/suggestedvideoendscreen/fingerprints/AutoNavStatusFingerprint.kt @@ -0,0 +1,11 @@ +package app.revanced.patches.youtube.utils.fix.suggestedvideoendscreen.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object AutoNavStatusFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "Z", + parameters = emptyList() +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/PlayerTypeHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/PlayerTypeHookPatch.kt index 748a0f96d..aa530b0cc 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/PlayerTypeHookPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/PlayerTypeHookPatch.kt @@ -7,7 +7,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patches.youtube.utils.fingerprints.YouTubeControlsOverlayFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.SHARED_PATH import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH import app.revanced.patches.youtube.utils.playertype.fingerprint.ActionBarSearchResultsFingerprint @@ -18,7 +17,6 @@ import app.revanced.patches.youtube.utils.playertype.fingerprint.VideoStateFinge import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelWatchPlayer import app.revanced.util.addStaticFieldToIntegration -import app.revanced.util.alsoResolve import app.revanced.util.findMethodOrThrow import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionOrThrow @@ -38,7 +36,7 @@ object PlayerTypeHookPatch : BytecodePatch( BrowseIdClassFingerprint, PlayerTypeFingerprint, ReelWatchPagerFingerprint, - YouTubeControlsOverlayFingerprint + VideoStateFingerprint, ) ) { private const val INTEGRATIONS_PLAYER_TYPE_HOOK_CLASS_DESCRIPTOR = @@ -79,11 +77,9 @@ object PlayerTypeHookPatch : BytecodePatch( // region patch for set video state - VideoStateFingerprint.alsoResolve( - context, YouTubeControlsOverlayFingerprint - ).let { + VideoStateFingerprint.resultOrThrow().let { it.mutableMethod.apply { - val endIndex = it.scanResult.patternScanResult!!.endIndex + val endIndex = it.scanResult.patternScanResult!!.startIndex + 1 val videoStateFieldName = getInstruction(endIndex).reference diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/fingerprint/VideoStateFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/fingerprint/VideoStateFingerprint.kt index fffbe452b..b278da576 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/fingerprint/VideoStateFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/fingerprint/VideoStateFingerprint.kt @@ -6,22 +6,22 @@ import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstruction import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.reference.FieldReference +import com.android.tools.smali.dexlib2.iface.reference.MethodReference internal object VideoStateFingerprint : MethodFingerprint( returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf("Lcom/google/android/libraries/youtube/player/features/overlay/controls/ControlsState;"), opcodes = listOf( - Opcode.CONST_4, - Opcode.IF_EQZ, Opcode.IF_EQZ, Opcode.IGET_OBJECT, // obfuscated parameter field name + Opcode.IGET_OBJECT, + Opcode.IF_NE, ), customFingerprint = { methodDef, _ -> methodDef.indexOfFirstInstruction { - opcode == Opcode.IGET_OBJECT && - getReference()?.definingClass == methodDef.parameterTypes.firstOrNull() + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.name == "equals" } >= 0 - } + }, ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt index bda19a0c3..8a5f61e0d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt @@ -2,7 +2,9 @@ package app.revanced.patches.youtube.video.information import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint @@ -38,6 +40,7 @@ import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHoo import app.revanced.patches.youtube.video.videoid.VideoIdPatch import app.revanced.util.addStaticFieldToIntegration import app.revanced.util.alsoResolve +import app.revanced.util.cloneMutable import app.revanced.util.getReference import app.revanced.util.getWalkerMethod import app.revanced.util.indexOfFirstInstructionOrThrow @@ -119,6 +122,7 @@ object VideoInformationPatch : BytecodePatch( private var seekSourceEnumType = "" private var seekSourceMethodName = "" private var seekRelativeSourceMethodName = "" + private var cloneSeekRelativeSourceMethod = false private lateinit var context: BytecodeContext @@ -135,6 +139,32 @@ object VideoInformationPatch : BytecodePatch( internal lateinit var speedSelectionInsertMethod: MutableMethod internal lateinit var videoEndMethod: MutableMethod + private fun cloneSeekRelativeSourceMethod(fingerprintResult: MethodFingerprintResult) { + if (!cloneSeekRelativeSourceMethod) return + + val methods = fingerprintResult.mutableClass.methods + + methods.find { method -> + method.name == seekRelativeSourceMethodName + }?.apply { + methods.add( + cloneMutable( + returnType = "Z" + ).apply { + val lastIndex = implementation!!.instructions.lastIndex + + removeInstruction(lastIndex) + addInstructions( + lastIndex, """ + move-result p1 + return p1 + """ + ) + } + ) + } + } + private fun addSeekInterfaceMethods( result: MethodFingerprintResult, seekMethodName: String, @@ -203,12 +233,16 @@ object VideoInformationPatch : BytecodePatch( // hook the player controller for use through integrations onCreateHook(INTEGRATIONS_CLASS_DESCRIPTOR, "initialize") - seekSourceEnumType = parameterTypes[1].toString() - seekSourceMethodName = name - seekRelativeSourceMethodName = SeekRelativeFingerprint.alsoResolve( + val seekRelativeMethod = SeekRelativeFingerprint.alsoResolve( context, VideoEndFingerprint - ).mutableMethod.name + ).mutableMethod + + seekSourceEnumType = parameterTypes[1].toString() + seekSourceMethodName = name + seekRelativeSourceMethodName = seekRelativeMethod.name + cloneSeekRelativeSourceMethod = seekRelativeMethod.returnType == "V" + cloneSeekRelativeSourceMethod(it) // Create integrations interface methods. addSeekInterfaceMethods( @@ -250,6 +284,8 @@ object VideoInformationPatch : BytecodePatch( // hook the MDX director for use through integrations onCreateHookMdx(INTEGRATIONS_CLASS_DESCRIPTOR, "initializeMdx") + cloneSeekRelativeSourceMethod(it) + // Create integrations interface methods. addSeekInterfaceMethods( it, diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/information/fingerprints/SeekRelativeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/information/fingerprints/SeekRelativeFingerprint.kt index a73ab1966..90146b3c7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/information/fingerprints/SeekRelativeFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/information/fingerprints/SeekRelativeFingerprint.kt @@ -11,12 +11,11 @@ import com.android.tools.smali.dexlib2.Opcode */ internal object SeekRelativeFingerprint : MethodFingerprint( accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - returnType = "Z", + // returnType = "Z", ~ YouTube 19.39.39 + // returnType = "V", YouTube 19.40.xx ~ parameters = listOf("J", "L"), opcodes = listOf( Opcode.ADD_LONG_2ADDR, Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.RETURN ) ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt index 05b26d759..c33a603d0 100644 --- a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt +++ b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt @@ -16,10 +16,12 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableClass import app.revanced.patcher.util.proxy.mutableTypes.MutableField import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable import app.revanced.util.fingerprint.MultiMethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.MethodParameter import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.Instruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @@ -30,6 +32,8 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.Reference import com.android.tools.smali.dexlib2.iface.reference.StringReference import com.android.tools.smali.dexlib2.immutable.ImmutableField +import com.android.tools.smali.dexlib2.immutable.ImmutableMethod +import com.android.tools.smali.dexlib2.immutable.ImmutableMethodImplementation import com.android.tools.smali.dexlib2.util.MethodUtil const val REGISTER_TEMPLATE_REPLACEMENT: String = "REGISTER_INDEX" @@ -55,6 +59,18 @@ val MultiMethodFingerprint.exception fun MethodFingerprint.alsoResolve(context: BytecodeContext, fingerprint: MethodFingerprint) = also { resolve(context, fingerprint.resultOrThrow().classDef) }.resultOrThrow() +fun MethodFingerprint.getMethodCall() = + resultOrThrow().mutableMethod.getMethodCall() + +fun MutableMethod.getMethodCall(): String { + var methodCall = "$definingClass->$name(" + for (i in 0 until parameters.size) { + methodCall += parameterTypes[i] + } + methodCall += ")$returnType" + return methodCall +} + /** * Find the [MutableMethod] from a given [Method] in a [MutableClass]. * @@ -371,7 +387,7 @@ fun Method.findOpcodeIndicesReversed(opcode: Opcode): List = fun Method.findOpcodeIndicesReversed(filter: Instruction.() -> Boolean): List { val indexes = implementation!!.instructions .withIndex() - .filter { (_, instruction) -> filter.invoke(instruction) } + .filter { (_, instruction) -> filter(instruction) } .map { (index, _) -> index } .reversed() @@ -573,6 +589,38 @@ fun BytecodeContext.updatePatchStatus( "const/4 v0, 0x1" ) +/** + * Taken from BiliRoamingX: + * https://github.com/BiliRoamingX/BiliRoamingX/blob/ae58109f3acdd53ec2d2b3fb439c2a2ef1886221/patches/src/main/kotlin/app/revanced/patches/bilibili/utils/Extenstions.kt#L51 + */ +fun Method.cloneMutable( + registerCount: Int = implementation?.registerCount ?: 0, + clearImplementation: Boolean = false, + name: String = this.name, + accessFlags: Int = this.accessFlags, + parameters: List = this.parameters, + returnType: String = this.returnType +): MutableMethod { + val clonedImplementation = implementation?.let { + ImmutableMethodImplementation( + registerCount, + if (clearImplementation) emptyList() else it.instructions, + if (clearImplementation) emptyList() else it.tryBlocks, + if (clearImplementation) emptyList() else it.debugItems, + ) + } + return ImmutableMethod( + definingClass, + name, + parameters, + returnType, + accessFlags, + annotations, + hiddenApiRestrictions, + clonedImplementation + ).toMutable() +} + /** * Return the resolved methods of [MethodFingerprint]s early. */ diff --git a/src/main/kotlin/app/revanced/util/fingerprint/MultiMethodFingerprint.kt b/src/main/kotlin/app/revanced/util/fingerprint/MultiMethodFingerprint.kt index b25b53876..54927e034 100644 --- a/src/main/kotlin/app/revanced/util/fingerprint/MultiMethodFingerprint.kt +++ b/src/main/kotlin/app/revanced/util/fingerprint/MultiMethodFingerprint.kt @@ -13,6 +13,9 @@ private typealias StringMatch = MethodFingerprintResult.MethodFingerprintScanRes private typealias StringsScanResult = MethodFingerprintResult.MethodFingerprintScanResult.StringsScanResult /** + * Taken from BiliRoamingX: + * https://github.com/BiliRoamingX/BiliRoamingX/blob/ae58109f3acdd53ec2d2b3fb439c2a2ef1886221/patches/src/main/kotlin/app/revanced/patches/bilibili/patcher/fingerprint/MultiMethodFingerprint.kt + * * Represents the [MethodFingerprint] for a method. * @param returnType The return type of the method. * @param accessFlags The access flags of the method. diff --git a/src/main/kotlin/app/revanced/util/patch/MultiMethodBytecodePatch.kt b/src/main/kotlin/app/revanced/util/patch/MultiMethodBytecodePatch.kt index fa137319a..fc3e5d18d 100644 --- a/src/main/kotlin/app/revanced/util/patch/MultiMethodBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/util/patch/MultiMethodBytecodePatch.kt @@ -6,6 +6,10 @@ import app.revanced.patcher.patch.BytecodePatch import app.revanced.util.fingerprint.MultiMethodFingerprint import app.revanced.util.fingerprint.MultiMethodFingerprint.Companion.resolve +/** + * Taken from BiliRoamingX: + * https://github.com/BiliRoamingX/BiliRoamingX/blob/ae58109f3acdd53ec2d2b3fb439c2a2ef1886221/patches/src/main/kotlin/app/revanced/patches/bilibili/patcher/patch/MultiMethodBytecodePatch.kt + */ abstract class MultiMethodBytecodePatch( val fingerprints: Set = setOf(), val multiFingerprints: Set = setOf()