feat(YouTube): Support version 19.12
, 19.13
, 19.14
, 19.15
and 19.16
(#3239)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
parent
999cf733f7
commit
99b07e0e18
|
@ -1889,7 +1889,11 @@ public final class app/revanced/util/BytecodeUtilsKt {
|
||||||
public static final fun containsWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z
|
public static final fun containsWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z
|
||||||
public static final fun findMutableMethodOf (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;
|
public static final fun findMutableMethodOf (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;
|
||||||
public static final fun getException (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/patch/PatchException;
|
public static final fun getException (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/patch/PatchException;
|
||||||
|
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;)I
|
||||||
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I
|
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I
|
||||||
|
public static synthetic fun indexOfFirstInstruction$default (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)I
|
||||||
|
public static final fun indexOfFirstInstructionOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;)I
|
||||||
|
public static synthetic fun indexOfFirstInstructionOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)I
|
||||||
public static final fun indexOfFirstWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
|
public static final fun indexOfFirstWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
|
||||||
public static final fun indexOfIdResource (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
|
public static final fun indexOfIdResource (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
|
||||||
public static final fun indexOfIdResourceOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
|
public static final fun indexOfIdResourceOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
|
||||||
|
|
|
@ -11,7 +11,7 @@ import app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints.Ba
|
||||||
import app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints.BuildAuthorizationStringFingerprint
|
import app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints.BuildAuthorizationStringFingerprint
|
||||||
import app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints.GetUserAgentFingerprint
|
import app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints.GetUserAgentFingerprint
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
|
@ -68,7 +68,7 @@ object SpoofClientPatch : BaseSpoofClientPatch(
|
||||||
// Reddit messed up and does not append a redirect uri to the authorization url to old.reddit.com/login.
|
// Reddit messed up and does not append a redirect uri to the authorization url to old.reddit.com/login.
|
||||||
// Replace old.reddit.com with ssl.reddit.com to fix this.
|
// Replace old.reddit.com with ssl.reddit.com to fix this.
|
||||||
BuildAuthorizationStringFingerprint.result!!.mutableMethod.apply {
|
BuildAuthorizationStringFingerprint.result!!.mutableMethod.apply {
|
||||||
val index = indexOfFirstInstruction {
|
val index = indexOfFirstInstructionOrThrow {
|
||||||
getReference<StringReference>()?.contains("old.reddit.com") == true
|
getReference<StringReference>()?.contains("old.reddit.com") == true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
import app.revanced.patches.tiktok.interaction.cleardisplay.fingerprints.OnClearDisplayEventFingerprint
|
import app.revanced.patches.tiktok.interaction.cleardisplay.fingerprints.OnClearDisplayEventFingerprint
|
||||||
import app.revanced.patches.tiktok.interaction.cleardisplay.fingerprints.OnRenderFirstFrameFingerprint
|
import app.revanced.patches.tiktok.interaction.cleardisplay.fingerprints.OnRenderFirstFrameFingerprint
|
||||||
import app.revanced.util.exception
|
import app.revanced.util.exception
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c
|
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ object RememberClearDisplayPatch : BytecodePatch(
|
||||||
OnClearDisplayEventFingerprint.result?.mutableMethod?.let {
|
OnClearDisplayEventFingerprint.result?.mutableMethod?.let {
|
||||||
// region Hook the "Clear display" configuration save event to remember the state of clear display.
|
// region Hook the "Clear display" configuration save event to remember the state of clear display.
|
||||||
|
|
||||||
val isEnabledIndex = it.indexOfFirstInstruction { opcode == Opcode.IGET_BOOLEAN } + 1
|
val isEnabledIndex = it.indexOfFirstInstructionOrThrow { opcode == Opcode.IGET_BOOLEAN } + 1
|
||||||
val isEnabledRegister = it.getInstruction<Instruction22c>(isEnabledIndex - 1).registerA
|
val isEnabledRegister = it.getInstruction<Instruction22c>(isEnabledIndex - 1).registerA
|
||||||
|
|
||||||
it.addInstructions(
|
it.addInstructions(
|
||||||
|
|
|
@ -18,7 +18,7 @@ import app.revanced.patches.tiktok.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.tiktok.misc.settings.SettingsPatch
|
import app.revanced.patches.tiktok.misc.settings.SettingsPatch
|
||||||
import app.revanced.patches.tiktok.misc.settings.fingerprints.SettingsStatusLoadFingerprint
|
import app.revanced.patches.tiktok.misc.settings.fingerprints.SettingsStatusLoadFingerprint
|
||||||
import app.revanced.util.exception
|
import app.revanced.util.exception
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
@ -81,16 +81,16 @@ object DownloadsPatch : BytecodePatch(
|
||||||
},
|
},
|
||||||
// Change the download path patch.
|
// Change the download path patch.
|
||||||
DownloadPathParentFingerprint to {
|
DownloadPathParentFingerprint to {
|
||||||
val targetIndex = indexOfFirstInstruction { opcode == Opcode.INVOKE_STATIC }
|
val targetIndex = indexOfFirstInstructionOrThrow { opcode == Opcode.INVOKE_STATIC }
|
||||||
val downloadUriMethod = context
|
val downloadUriMethod = context
|
||||||
.toMethodWalker(this)
|
.toMethodWalker(this)
|
||||||
.nextMethod(targetIndex, true)
|
.nextMethod(targetIndex, true)
|
||||||
.getMethod() as MutableMethod
|
.getMethod() as MutableMethod
|
||||||
|
|
||||||
val firstIndex = downloadUriMethod.indexOfFirstInstruction {
|
val firstIndex = downloadUriMethod.indexOfFirstInstructionOrThrow {
|
||||||
opcode == Opcode.INVOKE_DIRECT && ((this as Instruction35c).reference as MethodReference).name == "<init>"
|
opcode == Opcode.INVOKE_DIRECT && ((this as Instruction35c).reference as MethodReference).name == "<init>"
|
||||||
}
|
}
|
||||||
val secondIndex = downloadUriMethod.indexOfFirstInstruction {
|
val secondIndex = downloadUriMethod.indexOfFirstInstructionOrThrow {
|
||||||
opcode == Opcode.INVOKE_STATIC && ((this as Instruction35c).reference as MethodReference).returnType.contains(
|
opcode == Opcode.INVOKE_STATIC && ((this as Instruction35c).reference as MethodReference).returnType.contains(
|
||||||
"Uri"
|
"Uri"
|
||||||
)
|
)
|
||||||
|
|
|
@ -14,6 +14,7 @@ import app.revanced.patches.tiktok.interaction.speed.fingerprints.SetSpeedFinger
|
||||||
import app.revanced.util.exception
|
import app.revanced.util.exception
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction11x
|
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction11x
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ object PlaybackSpeedPatch : BytecodePatch(
|
||||||
SetSpeedFingerprint.result?.let { onVideoSwiped ->
|
SetSpeedFingerprint.result?.let { onVideoSwiped ->
|
||||||
// Remember the playback speed of the current video.
|
// Remember the playback speed of the current video.
|
||||||
GetSpeedFingerprint.result?.mutableMethod?.apply {
|
GetSpeedFingerprint.result?.mutableMethod?.apply {
|
||||||
val injectIndex = indexOfFirstInstruction { getReference<MethodReference>()?.returnType == "F" } + 2
|
val injectIndex = indexOfFirstInstructionOrThrow { getReference<MethodReference>()?.returnType == "F" } + 2
|
||||||
val register = getInstruction<Instruction11x>(injectIndex - 1).registerA
|
val register = getInstruction<Instruction11x>(injectIndex - 1).registerA
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
|
|
|
@ -44,7 +44,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -38,7 +38,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -43,7 +43,12 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -31,7 +31,12 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -40,7 +40,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -37,7 +37,12 @@ import app.revanced.util.resultOrThrow
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -40,7 +40,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -42,7 +42,12 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -38,7 +38,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
|
@ -44,10 +44,12 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43", // 19.12.x has an issue with opening YT using external links,
|
"19.11.43",
|
||||||
// and the app then crashes if double tap to skip forward/back is immediately used.
|
"19.12.41",
|
||||||
// The stack trace shows a call coming from integrations SwipeController,
|
"19.13.37",
|
||||||
// but it may be a bug in YT itself as other target versions do not have this issue.
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -42,7 +42,12 @@ import app.revanced.util.exception
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
|
@ -41,7 +41,12 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -13,11 +13,12 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
import app.revanced.patches.youtube.shared.fingerprints.LayoutConstructorFingerprint
|
import app.revanced.patches.youtube.shared.fingerprints.LayoutConstructorFingerprint
|
||||||
import app.revanced.util.exception
|
import app.revanced.util.getReference
|
||||||
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import app.revanced.util.indexOfIdResourceOrThrow
|
import app.revanced.util.indexOfIdResourceOrThrow
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
import app.revanced.util.resultOrThrow
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
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.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
|
@ -52,6 +53,11 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43",
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -60,6 +66,10 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
object HideAutoplayButtonPatch : BytecodePatch(
|
object HideAutoplayButtonPatch : BytecodePatch(
|
||||||
setOf(LayoutConstructorFingerprint),
|
setOf(LayoutConstructorFingerprint),
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/integrations/youtube/patches/HideAutoplayButtonPatch;"
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
AddResourcesPatch(this::class)
|
AddResourcesPatch(this::class)
|
||||||
|
|
||||||
|
@ -67,33 +77,27 @@ object HideAutoplayButtonPatch : BytecodePatch(
|
||||||
SwitchPreference("revanced_hide_autoplay_button"),
|
SwitchPreference("revanced_hide_autoplay_button"),
|
||||||
)
|
)
|
||||||
|
|
||||||
LayoutConstructorFingerprint.result?.mutableMethod?.apply {
|
LayoutConstructorFingerprint.resultOrThrow().mutableMethod.apply {
|
||||||
val layoutGenMethodInstructions = implementation!!.instructions
|
val constIndex = indexOfIdResourceOrThrow("autonav_toggle")
|
||||||
|
val constRegister = getInstruction<OneRegisterInstruction>(constIndex).registerA
|
||||||
|
|
||||||
// resolve the offsets of where to insert the branch instructions and ...
|
// Add a conditional branch around the code that inflates and adds the auto repeat button.
|
||||||
val insertIndex = indexOfIdResourceOrThrow("autonav_preview_stub")
|
val gotoIndex = indexOfFirstInstructionOrThrow(constIndex) {
|
||||||
|
val parameterTypes = getReference<MethodReference>()?.parameterTypes
|
||||||
// where to branch away
|
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||||
val branchIndex =
|
parameterTypes?.size == 2 &&
|
||||||
layoutGenMethodInstructions.subList(insertIndex + 1, layoutGenMethodInstructions.size - 1)
|
parameterTypes.first() == "Landroid/view/ViewStub;"
|
||||||
.indexOfFirst {
|
} + 1
|
||||||
((it as? ReferenceInstruction)?.reference as? MethodReference)?.name == "addOnLayoutChangeListener"
|
|
||||||
} + 2
|
|
||||||
|
|
||||||
val jumpInstruction = layoutGenMethodInstructions[insertIndex + branchIndex] as Instruction
|
|
||||||
|
|
||||||
// can be clobbered because this register is overwritten after the injected code
|
|
||||||
val clobberRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
insertIndex,
|
constIndex,
|
||||||
"""
|
"""
|
||||||
invoke-static {}, Lapp/revanced/integrations/youtube/patches/HideAutoplayButtonPatch;->isButtonShown()Z
|
invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->hideAutoPlayButton()Z
|
||||||
move-result v$clobberRegister
|
move-result v$constRegister
|
||||||
if-eqz v$clobberRegister, :hidden
|
if-nez v$constRegister, :hidden
|
||||||
""",
|
""",
|
||||||
ExternalLabel("hidden", jumpInstruction),
|
ExternalLabel("hidden", getInstruction(gotoIndex)),
|
||||||
)
|
)
|
||||||
} ?: throw LayoutConstructorFingerprint.exception
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,12 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -19,7 +19,7 @@ import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
import app.revanced.util.exception
|
import app.revanced.util.exception
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
@ -56,6 +56,11 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43",
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -111,7 +116,7 @@ object NavigationButtonsPatch : BytecodePatch(
|
||||||
|
|
||||||
// Hide navigation button labels.
|
// Hide navigation button labels.
|
||||||
CreatePivotBarFingerprint.result?.mutableMethod?.apply {
|
CreatePivotBarFingerprint.result?.mutableMethod?.apply {
|
||||||
val setTextIndex = indexOfFirstInstruction {
|
val setTextIndex = indexOfFirstInstructionOrThrow {
|
||||||
getReference<MethodReference>()?.name == "setText"
|
getReference<MethodReference>()?.name == "setText"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction3rc
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -40,7 +40,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -40,7 +40,12 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -40,7 +40,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -43,7 +43,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -40,7 +40,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -36,7 +36,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -36,7 +36,12 @@ import app.revanced.util.exception
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -23,7 +23,6 @@ import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
import app.revanced.util.resultOrThrow
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
|
|
||||||
|
@ -59,7 +58,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -164,20 +168,21 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
||||||
// region Mix playlists
|
// region Mix playlists
|
||||||
|
|
||||||
ParseElementFromBufferFingerprint.resultOrThrow().let { result ->
|
ParseElementFromBufferFingerprint.resultOrThrow().let { result ->
|
||||||
val consumeByteBufferIndex = result.scanResult.patternScanResult!!.startIndex
|
val startIndex = result.scanResult.patternScanResult!!.startIndex
|
||||||
|
|
||||||
result.mutableMethod.apply {
|
result.mutableMethod.apply {
|
||||||
val conversionContextRegister =
|
val freeRegister = "v0"
|
||||||
getInstruction<TwoRegisterInstruction>(consumeByteBufferIndex - 2).registerA
|
val byteArrayParameter = "p3"
|
||||||
val byteBufferRegister = getInstruction<FiveRegisterInstruction>(consumeByteBufferIndex).registerD
|
val conversionContextRegister = getInstruction<TwoRegisterInstruction>(startIndex).registerA
|
||||||
val returnEmptyComponentInstruction = getInstructions().last { it.opcode == Opcode.INVOKE_STATIC }
|
val returnEmptyComponentInstruction = getInstructions().last { it.opcode == Opcode.INVOKE_STATIC }
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
consumeByteBufferIndex,
|
startIndex + 1,
|
||||||
"""
|
"""
|
||||||
invoke-static {v$conversionContextRegister, v$byteBufferRegister}, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->filterMixPlaylists(Ljava/lang/Object;[B)Z
|
invoke-static { v$conversionContextRegister, $byteArrayParameter }, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->filterMixPlaylists(Ljava/lang/Object;[B)Z
|
||||||
move-result v0 # Conveniently same register happens to be free.
|
move-result $freeRegister
|
||||||
if-nez v0, :return_empty_component
|
if-nez $freeRegister, :return_empty_component
|
||||||
|
const/4 $freeRegister, 0x0 # Restore register, required for 19.16
|
||||||
""",
|
""",
|
||||||
ExternalLabel("return_empty_component", returnEmptyComponentInstruction),
|
ExternalLabel("return_empty_component", returnEmptyComponentInstruction),
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,7 +4,11 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
internal object ParseElementFromBufferFingerprint : MethodFingerprint(
|
internal object ParseElementFromBufferFingerprint : MethodFingerprint(
|
||||||
parameters = listOf("L","L","[B", "L","L"),
|
parameters = listOf("L", "L", "[B", "L", "L"),
|
||||||
opcodes = listOf(Opcode.INVOKE_INTERFACE, Opcode.MOVE_RESULT_OBJECT),
|
opcodes = listOf(
|
||||||
strings = listOf("Failed to parse Element")
|
Opcode.IGET_OBJECT,
|
||||||
|
Opcode.INVOKE_INTERFACE,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT
|
||||||
|
),
|
||||||
|
strings = listOf("Failed to parse Element") // String is a partial match.
|
||||||
)
|
)
|
|
@ -47,7 +47,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -41,7 +41,12 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -38,7 +38,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -43,7 +43,12 @@ import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -55,6 +55,11 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43",
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -35,7 +35,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -36,7 +36,12 @@ import app.revanced.util.exception
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -37,7 +37,12 @@ import app.revanced.util.exception
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -32,7 +32,12 @@ import org.w3c.dom.Element
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -31,7 +31,7 @@ import app.revanced.patches.youtube.shared.fingerprints.RollingNumberTextViewAni
|
||||||
import app.revanced.patches.youtube.video.videoid.VideoIdPatch
|
import app.revanced.patches.youtube.video.videoid.VideoIdPatch
|
||||||
import app.revanced.util.exception
|
import app.revanced.util.exception
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import app.revanced.util.resultOrThrow
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
|
@ -66,7 +66,12 @@ import com.android.tools.smali.dexlib2.iface.reference.TypeReference
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
@ -142,11 +147,10 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||||
TextComponentLookupFingerprint.resultOrThrow().mutableMethod.apply {
|
TextComponentLookupFingerprint.resultOrThrow().mutableMethod.apply {
|
||||||
// Find the instruction for creating the text data object.
|
// Find the instruction for creating the text data object.
|
||||||
val textDataClassType = TextComponentDataFingerprint.resultOrThrow().classDef.type
|
val textDataClassType = TextComponentDataFingerprint.resultOrThrow().classDef.type
|
||||||
val insertIndex = indexOfFirstInstruction {
|
val insertIndex = indexOfFirstInstructionOrThrow {
|
||||||
opcode == Opcode.NEW_INSTANCE &&
|
opcode == Opcode.NEW_INSTANCE &&
|
||||||
getReference<TypeReference>()?.type == textDataClassType
|
getReference<TypeReference>()?.type == textDataClassType
|
||||||
}
|
}
|
||||||
if (insertIndex < 0) throw PatchException("Could not find data creation instruction")
|
|
||||||
val tempRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
val tempRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
// Find the instruction that sets the span to an instance field.
|
// Find the instruction that sets the span to an instance field.
|
||||||
|
@ -335,7 +339,7 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||||
realTimeUpdateTextViewMethod
|
realTimeUpdateTextViewMethod
|
||||||
).forEach { insertMethod ->
|
).forEach { insertMethod ->
|
||||||
insertMethod.apply {
|
insertMethod.apply {
|
||||||
val setTextIndex = indexOfFirstInstruction {
|
val setTextIndex = indexOfFirstInstructionOrThrow {
|
||||||
getReference<MethodReference>()?.name == "setText"
|
getReference<MethodReference>()?.name == "setText"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -37,7 +37,12 @@ import app.revanced.util.exception
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -52,6 +52,11 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43",
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -40,7 +40,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -5,7 +5,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.PatchException
|
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
||||||
|
@ -15,7 +14,7 @@ import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
import app.revanced.util.exception
|
import app.revanced.util.exception
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
@ -46,7 +45,12 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
@ -67,12 +71,11 @@ object DisableResumingShortsOnStartupPatch : BytecodePatch(
|
||||||
)
|
)
|
||||||
|
|
||||||
UserWasInShortsFingerprint.result?.mutableMethod?.apply {
|
UserWasInShortsFingerprint.result?.mutableMethod?.apply {
|
||||||
val listenableInstructionIndex = indexOfFirstInstruction {
|
val listenableInstructionIndex = indexOfFirstInstructionOrThrow {
|
||||||
opcode == Opcode.INVOKE_INTERFACE &&
|
opcode == Opcode.INVOKE_INTERFACE &&
|
||||||
getReference<MethodReference>()?.definingClass == "Lcom/google/common/util/concurrent/ListenableFuture;" &&
|
getReference<MethodReference>()?.definingClass == "Lcom/google/common/util/concurrent/ListenableFuture;" &&
|
||||||
getReference<MethodReference>()?.name == "isDone"
|
getReference<MethodReference>()?.name == "isDone"
|
||||||
}
|
}
|
||||||
if (listenableInstructionIndex < 0) throw PatchException("Could not find instruction index")
|
|
||||||
val originalInstructionRegister = getInstruction<FiveRegisterInstruction>(listenableInstructionIndex).registerC
|
val originalInstructionRegister = getInstruction<FiveRegisterInstruction>(listenableInstructionIndex).registerC
|
||||||
val freeRegister = getInstruction<OneRegisterInstruction>(listenableInstructionIndex + 1).registerA
|
val freeRegister = getInstruction<OneRegisterInstruction>(listenableInstructionIndex + 1).registerA
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -52,7 +52,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -63,7 +63,12 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -41,7 +41,12 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -36,7 +36,12 @@ import app.revanced.util.exception
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -24,6 +24,7 @@ import app.revanced.patches.youtube.misc.fix.playback.fingerprints.PlayerGesture
|
||||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.SetPlayerRequestClientTypeFingerprint
|
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.SetPlayerRequestClientTypeFingerprint
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import app.revanced.util.resultOrThrow
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
@ -65,6 +66,11 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43",
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -195,15 +201,14 @@ object SpoofClientPatch : BytecodePatch(
|
||||||
|
|
||||||
val clientInfoClientModelField = CreatePlayerRequestBodyWithModelFingerprint.resultOrThrow().let {
|
val clientInfoClientModelField = CreatePlayerRequestBodyWithModelFingerprint.resultOrThrow().let {
|
||||||
val getClientModelIndex = CreatePlayerRequestBodyWithModelFingerprint.indexOfBuildModelInstruction(it.method)
|
val getClientModelIndex = CreatePlayerRequestBodyWithModelFingerprint.indexOfBuildModelInstruction(it.method)
|
||||||
val instructions = it.mutableMethod.getInstructions()
|
|
||||||
|
|
||||||
// The next IPUT_OBJECT instruction after getting the client model is setting the client model field.
|
// The next IPUT_OBJECT instruction after getting the client model is setting the client model field.
|
||||||
instructions.subList(
|
val index = it.mutableMethod.indexOfFirstInstructionOrThrow(getClientModelIndex) {
|
||||||
getClientModelIndex,
|
opcode == Opcode.IPUT_OBJECT
|
||||||
instructions.size,
|
}
|
||||||
).find { instruction ->
|
|
||||||
instruction.opcode == Opcode.IPUT_OBJECT
|
it.mutableMethod.getInstruction(index).getReference<FieldReference>()
|
||||||
}?.getReference<FieldReference>() ?: throw PatchException("Could not find clientInfoClientModelField")
|
?: throw PatchException("Could not find clientInfoClientModelField")
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
|
@ -52,6 +52,11 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43",
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.links.fingerprints.ABUriParserFingerprint
|
import app.revanced.patches.youtube.misc.links.fingerprints.ABUriParserFingerprint
|
||||||
import app.revanced.patches.youtube.misc.links.fingerprints.HTTPUriParserFingerprint
|
import app.revanced.patches.youtube.misc.links.fingerprints.HTTPUriParserFingerprint
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
import app.revanced.util.exception
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
|
@ -38,27 +38,32 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
]
|
"19.12.41",
|
||||||
)
|
"19.13.37",
|
||||||
]
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object BypassURLRedirectsPatch : BytecodePatch(
|
object BypassURLRedirectsPatch : BytecodePatch(
|
||||||
setOf(ABUriParserFingerprint, HTTPUriParserFingerprint)
|
setOf(ABUriParserFingerprint, HTTPUriParserFingerprint),
|
||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
AddResourcesPatch(this::class)
|
AddResourcesPatch(this::class)
|
||||||
|
|
||||||
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||||
SwitchPreference("revanced_bypass_url_redirects")
|
SwitchPreference("revanced_bypass_url_redirects"),
|
||||||
)
|
)
|
||||||
|
|
||||||
mapOf(
|
mapOf(
|
||||||
ABUriParserFingerprint to 7, // Offset to Uri.parse.
|
ABUriParserFingerprint to 7, // Offset to Uri.parse.
|
||||||
HTTPUriParserFingerprint to 0 // Offset to Uri.parse.
|
HTTPUriParserFingerprint to 0, // Offset to Uri.parse.
|
||||||
).map { (fingerprint, offset) ->
|
).map { (fingerprint, offset) ->
|
||||||
(fingerprint.result ?: throw fingerprint.exception) to offset
|
fingerprint.resultOrThrow() to offset
|
||||||
}.forEach { (result, offset) ->
|
}.forEach { (result, offset) ->
|
||||||
result.mutableMethod.apply {
|
result.mutableMethod.apply {
|
||||||
val insertIndex = result.scanResult.patternScanResult!!.startIndex + offset
|
val insertIndex = result.scanResult.patternScanResult!!.startIndex + offset
|
||||||
|
@ -67,11 +72,11 @@ object BypassURLRedirectsPatch : BytecodePatch(
|
||||||
replaceInstruction(
|
replaceInstruction(
|
||||||
insertIndex,
|
insertIndex,
|
||||||
"invoke-static {v$uriStringRegister}," +
|
"invoke-static {v$uriStringRegister}," +
|
||||||
"Lapp/revanced/integrations/youtube/patches/BypassURLRedirectsPatch;" +
|
"Lapp/revanced/integrations/youtube/patches/BypassURLRedirectsPatch;" +
|
||||||
"->" +
|
"->" +
|
||||||
"parseRedirectUri(Ljava/lang/String;)Landroid/net/Uri;"
|
"parseRedirectUri(Ljava/lang/String;)Landroid/net/Uri;",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,12 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -20,10 +20,14 @@ internal object ABUriParserFingerprint : MethodFingerprint(
|
||||||
Opcode.INVOKE_STATIC,
|
Opcode.INVOKE_STATIC,
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
Opcode.RETURN_OBJECT,
|
Opcode.RETURN_OBJECT,
|
||||||
Opcode.CHECK_CAST
|
Opcode.CHECK_CAST,
|
||||||
),
|
),
|
||||||
customFingerprint = { methodDef, classDef ->
|
customFingerprint = custom@{ methodDef, classDef ->
|
||||||
// This method is always called "a" because this kind of class always has a single method.
|
// This method is always called "a" because this kind of class always has a single (non synthetic) method.
|
||||||
methodDef.name == "a" && classDef.methods.count() == 3
|
|
||||||
}
|
if (methodDef.name != "a") return@custom false
|
||||||
)
|
|
||||||
|
val count = classDef.methods.count()
|
||||||
|
count == 2 || count == 3
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
|
@ -10,20 +10,18 @@ import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.PatchException
|
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patcher.util.smali.ExternalLabel
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.*
|
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.*
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
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.Instruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
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.ReferenceInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.TypeReference
|
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
|
@ -108,11 +106,10 @@ object LithoFilterPatch : BytecodePatch(
|
||||||
val emptyComponentFieldIndex = builderMethodIndex + 2
|
val emptyComponentFieldIndex = builderMethodIndex + 2
|
||||||
|
|
||||||
bytesToComponentContextMethod.mutableMethod.apply {
|
bytesToComponentContextMethod.mutableMethod.apply {
|
||||||
val insertHookIndex = indexOfFirstInstruction {
|
val insertHookIndex = indexOfFirstInstructionOrThrow {
|
||||||
opcode == Opcode.IPUT_OBJECT &&
|
opcode == Opcode.IPUT_OBJECT &&
|
||||||
getReference<FieldReference>()?.type == "Ljava/lang/StringBuilder;"
|
getReference<FieldReference>()?.type == "Ljava/lang/StringBuilder;"
|
||||||
} + 1
|
} + 1
|
||||||
if (insertHookIndex <= 0) throw PatchException("Could not find insert index")
|
|
||||||
|
|
||||||
// region Get free registers that this patch uses.
|
// region Get free registers that this patch uses.
|
||||||
// Registers are overwritten right after they are used in this patch, therefore free to clobber.
|
// Registers are overwritten right after they are used in this patch, therefore free to clobber.
|
||||||
|
|
|
@ -13,7 +13,6 @@ import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.KidsMinimizedPlaybackPolicyControllerFingerprint
|
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.KidsMinimizedPlaybackPolicyControllerFingerprint
|
||||||
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint
|
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint
|
||||||
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackSettingsFingerprint
|
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackSettingsFingerprint
|
||||||
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackSettingsParentFingerprint
|
|
||||||
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
|
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||||
|
@ -25,6 +24,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
name = "Minimized playback",
|
name = "Minimized playback",
|
||||||
description = "Unlocks options for picture-in-picture and background playback.",
|
description = "Unlocks options for picture-in-picture and background playback.",
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
MinimizedPlaybackResourcePatch::class,
|
||||||
IntegrationsPatch::class,
|
IntegrationsPatch::class,
|
||||||
PlayerTypeHookPatch::class,
|
PlayerTypeHookPatch::class,
|
||||||
VideoInformationPatch::class,
|
VideoInformationPatch::class,
|
||||||
|
@ -47,7 +47,12 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
@ -56,7 +61,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
object MinimizedPlaybackPatch : BytecodePatch(
|
object MinimizedPlaybackPatch : BytecodePatch(
|
||||||
setOf(
|
setOf(
|
||||||
MinimizedPlaybackManagerFingerprint,
|
MinimizedPlaybackManagerFingerprint,
|
||||||
MinimizedPlaybackSettingsParentFingerprint,
|
MinimizedPlaybackSettingsFingerprint,
|
||||||
KidsMinimizedPlaybackPolicyControllerFingerprint
|
KidsMinimizedPlaybackPolicyControllerFingerprint
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
@ -82,11 +87,6 @@ object MinimizedPlaybackPatch : BytecodePatch(
|
||||||
} ?: throw MinimizedPlaybackManagerFingerprint.exception
|
} ?: throw MinimizedPlaybackManagerFingerprint.exception
|
||||||
|
|
||||||
// Enable minimized playback option in YouTube settings
|
// Enable minimized playback option in YouTube settings
|
||||||
MinimizedPlaybackSettingsParentFingerprint.result ?: throw MinimizedPlaybackSettingsParentFingerprint.exception
|
|
||||||
MinimizedPlaybackSettingsFingerprint.resolve(
|
|
||||||
context,
|
|
||||||
MinimizedPlaybackSettingsParentFingerprint.result!!.classDef
|
|
||||||
)
|
|
||||||
MinimizedPlaybackSettingsFingerprint.result?.apply {
|
MinimizedPlaybackSettingsFingerprint.result?.apply {
|
||||||
val booleanCalls = method.implementation!!.instructions.withIndex()
|
val booleanCalls = method.implementation!!.instructions.withIndex()
|
||||||
.filter { ((it.value as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z" }
|
.filter { ((it.value as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z" }
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package app.revanced.patches.youtube.misc.minimizedplayback
|
||||||
|
|
||||||
|
import app.revanced.patcher.data.ResourceContext
|
||||||
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
|
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
|
||||||
|
|
||||||
|
@Patch(
|
||||||
|
dependencies = [ResourceMappingPatch::class],
|
||||||
|
)
|
||||||
|
internal object MinimizedPlaybackResourcePatch : ResourcePatch() {
|
||||||
|
internal var prefBackgroundAndOfflineCategoryId: Long = -1
|
||||||
|
|
||||||
|
override fun execute(context: ResourceContext) {
|
||||||
|
prefBackgroundAndOfflineCategoryId = ResourceMappingPatch["string", "pref_background_and_offline_category"]
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,12 @@
|
||||||
package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints
|
package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patches.youtube.misc.minimizedplayback.MinimizedPlaybackResourcePatch
|
||||||
|
import app.revanced.util.patch.LiteralValueFingerprint
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
internal object MinimizedPlaybackSettingsFingerprint : MethodFingerprint(
|
internal object MinimizedPlaybackSettingsFingerprint : LiteralValueFingerprint(
|
||||||
returnType = "Ljava/lang/String;",
|
returnType = "Ljava/lang/String;",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
parameters = listOf(),
|
parameters = listOf(),
|
||||||
|
@ -16,8 +17,7 @@ internal object MinimizedPlaybackSettingsFingerprint : MethodFingerprint(
|
||||||
Opcode.MOVE_RESULT,
|
Opcode.MOVE_RESULT,
|
||||||
Opcode.IF_EQZ,
|
Opcode.IF_EQZ,
|
||||||
Opcode.IF_NEZ,
|
Opcode.IF_NEZ,
|
||||||
Opcode.GOTO,
|
Opcode.GOTO
|
||||||
Opcode.IGET_OBJECT,
|
|
||||||
Opcode.CHECK_CAST
|
|
||||||
),
|
),
|
||||||
|
literalSupplier = { MinimizedPlaybackResourcePatch.prefBackgroundAndOfflineCategoryId }
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints
|
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class fingerprint for [MinimizedPlaybackSettingsFingerprint]
|
|
||||||
*/
|
|
||||||
internal object MinimizedPlaybackSettingsParentFingerprint : MethodFingerprint(
|
|
||||||
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
|
||||||
returnType = "I",
|
|
||||||
parameters = listOf(),
|
|
||||||
strings = listOf("BiometricManager", "Failure in canAuthenticate(). FingerprintManager was null.")
|
|
||||||
)
|
|
|
@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.navigation.fingerprints.*
|
import app.revanced.patches.youtube.misc.navigation.fingerprints.*
|
||||||
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
|
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import app.revanced.util.resultOrThrow
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
|
@ -121,7 +121,7 @@ object NavigationBarHookPatch : BytecodePatch(
|
||||||
// Insert before the first ViewGroup method call after inflating,
|
// Insert before the first ViewGroup method call after inflating,
|
||||||
// so this works regardless which layout is used.
|
// so this works regardless which layout is used.
|
||||||
ActionBarSearchResultsFingerprint.resultOrThrow().mutableMethod.apply {
|
ActionBarSearchResultsFingerprint.resultOrThrow().mutableMethod.apply {
|
||||||
val instructionIndex = indexOfFirstInstruction {
|
val instructionIndex = indexOfFirstInstructionOrThrow {
|
||||||
opcode == Opcode.INVOKE_VIRTUAL && getReference<MethodReference>()?.name == "setLayoutDirection"
|
opcode == Opcode.INVOKE_VIRTUAL && getReference<MethodReference>()?.name == "setLayoutDirection"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -47,7 +47,12 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -27,7 +27,12 @@ import app.revanced.patches.youtube.video.speed.remember.RememberPlaybackSpeedPa
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -2,12 +2,12 @@ package app.revanced.patches.youtube.video.videoqualitymenu
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchException
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patcher.util.smali.ExternalLabel
|
|
||||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
|
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
|
||||||
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.RecyclerViewTreeHookPatch
|
import app.revanced.patches.youtube.misc.recyclerviewtree.hook.RecyclerViewTreeHookPatch
|
||||||
|
@ -23,7 +23,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
IntegrationsPatch::class,
|
IntegrationsPatch::class,
|
||||||
RestoreOldVideoQualityMenuResourcePatch::class,
|
RestoreOldVideoQualityMenuResourcePatch::class,
|
||||||
LithoFilterPatch::class,
|
LithoFilterPatch::class,
|
||||||
RecyclerViewTreeHookPatch::class
|
RecyclerViewTreeHookPatch::class,
|
||||||
],
|
],
|
||||||
compatiblePackages = [
|
compatiblePackages = [
|
||||||
CompatiblePackage(
|
CompatiblePackage(
|
||||||
|
@ -47,20 +47,25 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.38",
|
"19.09.38",
|
||||||
"19.10.39",
|
"19.10.39",
|
||||||
"19.11.43"
|
"19.11.43",
|
||||||
]
|
"19.12.41",
|
||||||
)
|
"19.13.37",
|
||||||
]
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object RestoreOldVideoQualityMenuPatch : BytecodePatch(
|
object RestoreOldVideoQualityMenuPatch : BytecodePatch(
|
||||||
setOf(VideoQualityMenuViewInflateFingerprint, VideoQualityMenuOptionsFingerprint)
|
setOf(VideoQualityMenuViewInflateFingerprint, VideoQualityMenuOptionsFingerprint),
|
||||||
) {
|
) {
|
||||||
private const val FILTER_CLASS_DESCRIPTOR =
|
private const val FILTER_CLASS_DESCRIPTOR =
|
||||||
"Lapp/revanced/integrations/youtube/patches/components/VideoQualityMenuFilterPatch;"
|
"Lapp/revanced/integrations/youtube/patches/components/VideoQualityMenuFilterPatch;"
|
||||||
|
|
||||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||||
"Lapp/revanced/integrations/youtube/patches/playback/quality/RestoreOldVideoQualityMenuPatch;"
|
"Lapp/revanced/integrations/youtube/patches/playback/quality/RestoreOldVideoQualityMenuPatch;"
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
// region Patch for the old type of the video quality menu.
|
// region Patch for the old type of the video quality menu.
|
||||||
|
@ -75,31 +80,30 @@ object RestoreOldVideoQualityMenuPatch : BytecodePatch(
|
||||||
addInstruction(
|
addInstruction(
|
||||||
checkCastIndex + 1,
|
checkCastIndex + 1,
|
||||||
"invoke-static { v$listViewRegister }, " +
|
"invoke-static { v$listViewRegister }, " +
|
||||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->" +
|
"$INTEGRATIONS_CLASS_DESCRIPTOR->" +
|
||||||
"showOldVideoQualityMenu(Landroid/widget/ListView;)V"
|
"showOldVideoQualityMenu(Landroid/widget/ListView;)V",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force YT to add the 'advanced' quality menu for Shorts.
|
// Force YT to add the 'advanced' quality menu for Shorts.
|
||||||
VideoQualityMenuOptionsFingerprint.resultOrThrow().let {
|
VideoQualityMenuOptionsFingerprint.resultOrThrow().let {
|
||||||
val result = it.scanResult.patternScanResult!!
|
val scanResult = it.scanResult.patternScanResult!!
|
||||||
val startIndex = result.startIndex
|
val startIndex = scanResult.startIndex
|
||||||
val endIndex = result.endIndex
|
if (startIndex != 0) throw PatchException("Unexpected opcode start index: $startIndex")
|
||||||
|
val insertIndex = scanResult.endIndex
|
||||||
|
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val freeRegister = getInstruction<OneRegisterInstruction>(startIndex).registerA
|
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
// A condition controls whether to show the three or four items quality menu.
|
// A condition controls whether to show the three or four items quality menu.
|
||||||
// Force the four items quality menu to make the "Advanced" item visible, necessary for the patch.
|
// Force the four items quality menu to make the "Advanced" item visible, necessary for the patch.
|
||||||
addInstructionsWithLabels(
|
addInstructions(
|
||||||
startIndex + 1,
|
insertIndex,
|
||||||
"""
|
"""
|
||||||
invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->forceAdvancedVideoQualityMenuCreation()Z
|
invoke-static { v$register }, $INTEGRATIONS_CLASS_DESCRIPTOR->forceAdvancedVideoQualityMenuCreation(Z)Z
|
||||||
move-result v$freeRegister
|
move-result v$register
|
||||||
if-nez v$freeRegister, :includeAdvancedMenu
|
|
||||||
""",
|
""",
|
||||||
ExternalLabel("includeAdvancedMenu", getInstruction(endIndex))
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,4 +119,4 @@ object RestoreOldVideoQualityMenuPatch : BytecodePatch(
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,11 @@ internal object VideoQualityMenuOptionsFingerprint : LiteralValueFingerprint(
|
||||||
parameters = listOf("Landroid/content/Context", "L", "L"),
|
parameters = listOf("Landroid/content/Context", "L", "L"),
|
||||||
returnType = "[L",
|
returnType = "[L",
|
||||||
opcodes = listOf(
|
opcodes = listOf(
|
||||||
Opcode.IF_EQZ, // Check if advanced menu should be shown.
|
Opcode.CONST_4, // First instruction of method.
|
||||||
Opcode.NEW_ARRAY,
|
Opcode.CONST_4,
|
||||||
Opcode.APUT_OBJECT,
|
Opcode.IF_EQZ,
|
||||||
Opcode.APUT_OBJECT,
|
Opcode.IGET_BOOLEAN, // Use the quality menu, that contains the advanced menu.
|
||||||
Opcode.APUT_OBJECT,
|
Opcode.IF_NEZ
|
||||||
Opcode.RETURN_OBJECT,
|
|
||||||
Opcode.CONST_4 // Advanced menu code path.
|
|
||||||
),
|
),
|
||||||
literalSupplier = { RestoreOldVideoQualityMenuResourcePatch.videoQualityQuickMenuAdvancedMenuDescription }
|
literalSupplier = { RestoreOldVideoQualityMenuResourcePatch.videoQualityQuickMenuAdvancedMenuDescription }
|
||||||
)
|
)
|
|
@ -143,8 +143,41 @@ inline fun <reified T : Reference> Instruction.getReference() = (this as? Refere
|
||||||
* @param predicate The predicate to match.
|
* @param predicate The predicate to match.
|
||||||
* @return The index of the first [Instruction] that matches the predicate.
|
* @return The index of the first [Instruction] that matches the predicate.
|
||||||
*/
|
*/
|
||||||
fun Method.indexOfFirstInstruction(predicate: Instruction.() -> Boolean) =
|
// TODO: delete this on next major release, the overloaded method with an optional start index serves the same purposes.
|
||||||
this.implementation!!.instructions.indexOfFirst(predicate)
|
@Deprecated("Use the overloaded method with an optional start index.", ReplaceWith("indexOfFirstInstruction(predicate)"))
|
||||||
|
fun Method.indexOfFirstInstruction(predicate: Instruction.() -> Boolean) = indexOfFirstInstruction(0, predicate)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the index of the first [Instruction] that matches the predicate, starting from [startIndex].
|
||||||
|
*
|
||||||
|
* @param startIndex Optional starting index to start searching from.
|
||||||
|
* @return -1 if the instruction is not found.
|
||||||
|
* @see indexOfFirstInstructionOrThrow
|
||||||
|
*/
|
||||||
|
fun Method.indexOfFirstInstruction(startIndex: Int = 0, predicate: Instruction.() -> Boolean): Int {
|
||||||
|
val index = this.implementation!!.instructions.drop(startIndex).indexOfFirst(predicate)
|
||||||
|
|
||||||
|
return if (index >= 0) {
|
||||||
|
startIndex + index
|
||||||
|
} else {
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the index of the first [Instruction] that matches the predicate, starting from [startIndex].
|
||||||
|
*
|
||||||
|
* @return the index of the instruction
|
||||||
|
* @throws PatchException
|
||||||
|
* @see indexOfFirstInstruction
|
||||||
|
*/
|
||||||
|
fun Method.indexOfFirstInstructionOrThrow(startIndex: Int = 0, predicate: Instruction.() -> Boolean): Int {
|
||||||
|
val index = indexOfFirstInstruction(startIndex, predicate)
|
||||||
|
if (index < 0) {
|
||||||
|
throw PatchException("Could not find instruction index")
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the resolved methods of [MethodFingerprint]s early.
|
* Return the resolved methods of [MethodFingerprint]s early.
|
||||||
|
|
Loading…
Reference in a new issue