diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/resources/AddResourcesPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/resources/AddResourcesPatch.kt
index cc94674e8..a77dd364f 100644
--- a/patches/src/main/kotlin/app/revanced/patches/all/misc/resources/AddResourcesPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/resources/AddResourcesPatch.kt
@@ -366,7 +366,7 @@ val addResourcesPatch = resourcePatch(
it.writeText("\n\n")
}
}
-
+
document("res/$value/$resourceFileName.xml").let { document ->
// Save the target node here as well
diff --git a/patches/src/main/kotlin/app/revanced/patches/angulus/ads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/angulus/ads/Fingerprints.kt
index 282441aaf..66ed3fc67 100644
--- a/patches/src/main/kotlin/app/revanced/patches/angulus/ads/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/angulus/ads/Fingerprints.kt
@@ -12,7 +12,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
// dailyAdResetCount
// MeasurementPrefs
-// This fingerprint targets a method that returns the daily measurement count.
+// This targets a method that returns the daily measurement count.
// This method is used to determine if the user has reached the daily limit of measurements.
internal val BytecodePatchContext.getDailyMeasurementCountMethod by gettingFirstMutableMethodDeclaratively("dailyMeasurementCount") {
accessFlags(AccessFlags.PRIVATE)
diff --git a/patches/src/main/kotlin/app/revanced/patches/crunchyroll/ads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/crunchyroll/ads/Fingerprints.kt
index 98250799f..43bd86dbd 100644
--- a/patches/src/main/kotlin/app/revanced/patches/crunchyroll/ads/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/crunchyroll/ads/Fingerprints.kt
@@ -1,9 +1,10 @@
package app.revanced.patches.crunchyroll.ads
-import app.revanced.patcher.firstMethodComposite
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.instructions
import app.revanced.patcher.invoke
+import app.revanced.patcher.patch.BytecodePatchContext
-internal val videoUrlReadyToStringMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.videoUrlReadyToStringMethodMatch by composingFirstMethod {
instructions("VideoUrlReady(url="(), ", enableAds="())
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/crunchyroll/ads/HideAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/crunchyroll/ads/HideAdsPatch.kt
index 51b4322c1..718d9fdc6 100644
--- a/patches/src/main/kotlin/app/revanced/patches/crunchyroll/ads/HideAdsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/crunchyroll/ads/HideAdsPatch.kt
@@ -19,7 +19,7 @@ val hideAdsPatch = bytecodePatch("Hide ads") {
apply {
// Get obfuscated "enableAds" field from toString method.
val enableAdsField = videoUrlReadyToStringMethodMatch.method.apply {
- val stringIndex = videoUrlReadyToStringMethodMatch.indices.last()
+ val stringIndex = videoUrlReadyToStringMethodMatch[-1]
val fieldIndex = indexOfFirstInstruction(stringIndex, Opcode.IGET_BOOLEAN)
getInstruction(fieldIndex).getReference()!!
diff --git a/patches/src/main/kotlin/app/revanced/patches/duolingo/ad/DisableAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/duolingo/ad/DisableAdsPatch.kt
index 0143f4f3c..b83834c67 100644
--- a/patches/src/main/kotlin/app/revanced/patches/duolingo/ad/DisableAdsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/duolingo/ad/DisableAdsPatch.kt
@@ -3,6 +3,7 @@ package app.revanced.patches.duolingo.ad
import app.revanced.patcher.classDef
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.getInstruction
+import app.revanced.patcher.immutableClassDef
import app.revanced.patcher.patch.bytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
@@ -19,16 +20,16 @@ val disableAdsPatch = bytecodePatch("Disable ads") {
// SharedPreferences has a debug boolean value with key "disable_ads", which maps to "DebugCategory.DISABLE_ADS".
//
// MonetizationDebugSettings seems to be the most general setting to work fine.
- initializeMonetizationDebugSettingsMethodMatch.match(
- monetizationDebugSettingsToStringMethod.classDef,
- ).method.apply {
- val insertIndex = initializeMonetizationDebugSettingsMethodMatch.indices.first()
- val register = getInstruction(insertIndex).registerA
+ monetizationDebugSettingsToStringMethod.immutableClassDef.initializeMonetizationDebugSettingsMethodMatch.let {
+ it.method.apply {
+ val insertIndex = it[0]
+ val register = getInstruction(insertIndex).registerA
- addInstructions(
- insertIndex,
- "const/4 v$register, 0x1",
- )
+ addInstructions(
+ insertIndex,
+ "const/4 v$register, 0x1",
+ )
+ }
}
}
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/duolingo/ad/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/duolingo/ad/Fingerprints.kt
index 20b047f9f..6d0cebeb2 100644
--- a/patches/src/main/kotlin/app/revanced/patches/duolingo/ad/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/duolingo/ad/Fingerprints.kt
@@ -4,11 +4,12 @@ import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
+import com.android.tools.smali.dexlib2.iface.ClassDef
-internal val initializeMonetizationDebugSettingsMethodMatch = firstMethodComposite {
+internal val ClassDef.initializeMonetizationDebugSettingsMethodMatch by ClassDefComposing.composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
returnType("V")
- // Parameters have not been reliable for fingerprinting between versions.
+ // Parameters have not been reliable for matching between versions.
opcodes(Opcode.IPUT_BOOLEAN)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/duolingo/debug/EnableDebugMenuPatch.kt b/patches/src/main/kotlin/app/revanced/patches/duolingo/debug/EnableDebugMenuPatch.kt
index 56892c0fb..0d9681e8f 100644
--- a/patches/src/main/kotlin/app/revanced/patches/duolingo/debug/EnableDebugMenuPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/duolingo/debug/EnableDebugMenuPatch.kt
@@ -3,6 +3,7 @@ package app.revanced.patches.duolingo.debug
import app.revanced.patcher.classDef
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.getInstruction
+import app.revanced.patcher.immutableClassDef
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.util.returnEarly
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@@ -19,10 +20,8 @@ val enableDebugMenuPatch = bytecodePatch(
debugCategoryAllowOnReleaseBuildsMethod.returnEarly(true)
// Change build config debug build flag.
- buildConfigProviderConstructorMethodMatch.match(
- buildConfigProviderToStringMethod.classDef,
- ).let {
- val index = it.indices.first()
+ buildConfigProviderToStringMethod.immutableClassDef.buildConfigProviderConstructorMethodMatch.let {
+ val index = it[0]
val register = it.method.getInstruction(index).registerA
it.method.addInstruction(index + 1, "const/4 v$register, 0x1")
diff --git a/patches/src/main/kotlin/app/revanced/patches/duolingo/debug/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/duolingo/debug/Fingerprints.kt
index 312333ec5..a92b68890 100644
--- a/patches/src/main/kotlin/app/revanced/patches/duolingo/debug/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/duolingo/debug/Fingerprints.kt
@@ -4,6 +4,7 @@ import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
+import com.android.tools.smali.dexlib2.iface.ClassDef
internal val BytecodePatchContext.debugCategoryAllowOnReleaseBuildsMethod by gettingFirstMutableMethodDeclaratively {
name("getAllowOnReleaseBuilds")
@@ -12,8 +13,7 @@ internal val BytecodePatchContext.debugCategoryAllowOnReleaseBuildsMethod by get
parameterTypes()
}
-internal val buildConfigProviderConstructorMethodMatch = firstMethodComposite {
-
+internal val ClassDef.buildConfigProviderConstructorMethodMatch by ClassDefComposing.composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
parameterTypes()
opcodes(Opcode.CONST_4)
diff --git a/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/Fingerprints.kt
index abdd634eb..da434e0fe 100644
--- a/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/Fingerprints.kt
@@ -4,8 +4,9 @@ import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
+import com.android.tools.smali.dexlib2.iface.ClassDef
-internal val initializeEnergyConfigMethodMatch = firstMethodComposite {
+internal val ClassDef.initializeEnergyConfigMethodMatch by ClassDefComposing.composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
opcodes(Opcode.RETURN_VOID)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/SkipEnergyRechargeAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/SkipEnergyRechargeAdsPatch.kt
index c8e16b332..cb7be5566 100644
--- a/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/SkipEnergyRechargeAdsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/SkipEnergyRechargeAdsPatch.kt
@@ -2,6 +2,7 @@ package app.revanced.patches.duolingo.energy
import app.revanced.patcher.classDef
import app.revanced.patcher.extensions.addInstructions
+import app.revanced.patcher.immutableClassDef
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.util.findFieldFromToString
@@ -13,17 +14,19 @@ val skipEnergyRechargeAdsPatch = bytecodePatch(
compatibleWith("com.duolingo")
apply {
- initializeEnergyConfigMethodMatch.match(energyConfigToStringMethod.classDef).method.apply {
- val energyField = energyConfigToStringMethod.findFieldFromToString("energy=")
- val insertIndex = initializeEnergyConfigMethodMatch.indices.first() // TODO
+ energyConfigToStringMethod.immutableClassDef.initializeEnergyConfigMethodMatch.let {
+ it.method.apply {
+ val energyField = energyConfigToStringMethod.findFieldFromToString("energy=")
+ val insertIndex = it[0]
- addInstructions(
- insertIndex,
- """
+ addInstructions(
+ insertIndex,
+ """
const/16 v0, 99
iput v0, p0, $energyField
""",
- )
+ )
+ }
}
}
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/Fingerprints.kt
index 3ec53872b..bc75d4eb8 100644
--- a/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/Fingerprints.kt
@@ -30,7 +30,7 @@ internal val BytecodePatchContext.getSponsoredDataModelTemplateMethod by getting
Opcode.RETURN_OBJECT,
)
}
-internal val getStoryVisibilityMethodMatch = firstMethodComposite("This should not be called for base class object") {
+internal val BytecodePatchContext.getStoryVisibilityMethodMatch by composingFirstMethod("This should not be called for base class object") {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returnType("Ljava/lang/String;")
opcodes(
diff --git a/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/HideSponsoredStoriesPatch.kt b/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/HideSponsoredStoriesPatch.kt
index 92ab63516..8a2647eb5 100644
--- a/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/HideSponsoredStoriesPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/HideSponsoredStoriesPatch.kt
@@ -64,7 +64,7 @@ val hideSponsoredStoriesPatch = bytecodePatch("Hide 'Sponsored Stories'") {
// Check if the parameter type is GraphQLStory and if sponsoredDataModelGetter returns a non-null value.
// If so, hide the story by setting the visibility to StoryVisibility.GONE.
getStoryVisibilityMethodMatch.method.addInstructionsWithLabels(
- getStoryVisibilityMethodMatch.indices.first(),
+ getStoryVisibilityMethodMatch[0],
"""
instance-of v0, p0, $graphQlStoryClassDescriptor
if-eqz v0, :resume_normal
diff --git a/patches/src/main/kotlin/app/revanced/patches/googlenews/customtabs/EnableCustomTabsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/googlenews/customtabs/EnableCustomTabsPatch.kt
index e09afa967..a095f0d74 100644
--- a/patches/src/main/kotlin/app/revanced/patches/googlenews/customtabs/EnableCustomTabsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/googlenews/customtabs/EnableCustomTabsPatch.kt
@@ -14,7 +14,7 @@ val enableCustomTabsPatch = bytecodePatch(
apply {
launchCustomTabMethodMatch.method.apply {
- val checkIndex = launchCustomTabMethodMatch.indices.last() + 1
+ val checkIndex = launchCustomTabMethodMatch[-1] + 1
val register = getInstruction(checkIndex).registerA
replaceInstruction(checkIndex, "const/4 v$register, 0x1")
diff --git a/patches/src/main/kotlin/app/revanced/patches/googlenews/customtabs/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/googlenews/customtabs/Fingerprints.kt
index 74ffbb3e8..9e387f898 100644
--- a/patches/src/main/kotlin/app/revanced/patches/googlenews/customtabs/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/googlenews/customtabs/Fingerprints.kt
@@ -1,13 +1,14 @@
package app.revanced.patches.googlenews.customtabs
import app.revanced.patcher.accessFlags
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.definingClass
-import app.revanced.patcher.firstMethodComposite
import app.revanced.patcher.opcodes
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
-internal val launchCustomTabMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.launchCustomTabMethodMatch by composingFirstMethod {
definingClass { endsWith("CustomTabsArticleLauncher;") }
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
opcodes(
diff --git a/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/Fingerprints.kt
index 7b2e615be..219574f1c 100644
--- a/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/Fingerprints.kt
@@ -1,8 +1,9 @@
package app.revanced.patches.googlerecorder.restrictions
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
-internal val onApplicationCreateMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.onApplicationCreateMethodMatch by composingFirstMethod {
name("onCreate")
definingClass { endsWith("RecorderApplication") }
instructions("com.google.android.feature.PIXEL_2017_EXPERIENCE"())
diff --git a/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/RemoveDeviceRestrictions.kt b/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/RemoveDeviceRestrictions.kt
index 8c65e1194..ee67ea3ce 100644
--- a/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/RemoveDeviceRestrictions.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/RemoveDeviceRestrictions.kt
@@ -14,7 +14,7 @@ val removeDeviceRestrictionsPatch = bytecodePatch(
compatibleWith("com.google.android.apps.recorder")
apply {
- val featureStringIndex = onApplicationCreateMethodMatch.indices.first()
+ val featureStringIndex = onApplicationCreateMethodMatch[0]
onApplicationCreateMethodMatch.method.apply {
// Remove check for device restrictions.
diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/Fingerprints.kt
index cfaaa2604..a9b705dd4 100644
--- a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/Fingerprints.kt
@@ -1,11 +1,12 @@
package app.revanced.patches.instagram.hide.explore
-import app.revanced.patcher.firstMethodComposite
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.instructions
import app.revanced.patcher.invoke
import app.revanced.patcher.name
+import app.revanced.patcher.patch.BytecodePatchContext
-internal val exploreResponseJsonParserMethodMatch = firstMethodComposite("ExploreTopicalFeedResponse") {
+internal val BytecodePatchContext.exploreResponseJsonParserMethodMatch by composingFirstMethod("ExploreTopicalFeedResponse") {
name("parseFromJson")
instructions("sectional_items"())
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/HideExploreFeed.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/HideExploreFeed.kt
index b8789fc4d..dbab25ba4 100644
--- a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/HideExploreFeed.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/HideExploreFeed.kt
@@ -15,7 +15,7 @@ val hideExploreFeedPatch = bytecodePatch(
apply {
exploreResponseJsonParserMethodMatch.method.apply {
- val targetStringIndex = exploreResponseJsonParserMethodMatch.indices.first()
+ val targetStringIndex = exploreResponseJsonParserMethodMatch[0]
val targetStringRegister = getInstruction(targetStringIndex).registerA
replaceInstruction(targetStringIndex, "const-string v$targetStringRegister, \"BOGUS\"")
diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/stories/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/stories/Fingerprints.kt
index d5609e89a..3c9e11833 100644
--- a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/stories/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/stories/Fingerprints.kt
@@ -1,9 +1,10 @@
package app.revanced.patches.instagram.hide.stories
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
-internal val getOrCreateAvatarViewMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.getOrCreateAvatarViewMethodMatch by composingFirstMethod {
definingClass("Lcom/instagram/reels/ui/views/reelavatar/RecyclerReelAvatarView;")
parameterTypes()
returnType("L")
diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/stories/HideStories.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/stories/HideStories.kt
index 51bc3e8d6..fed889d77 100644
--- a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/stories/HideStories.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/stories/HideStories.kt
@@ -13,7 +13,7 @@ val hideStoriesFromHomePatch = bytecodePatch(
apply {
getOrCreateAvatarViewMethodMatch.let {
- val addStoryEndIndex = it.indices.last()
+ val addStoryEndIndex = it[-1]
// Remove addView of Story.
it.method.removeInstruction(addStoryEndIndex)
diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/suggestions/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/suggestions/Fingerprints.kt
index 5093f7aba..df3c70678 100644
--- a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/suggestions/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/suggestions/Fingerprints.kt
@@ -1,8 +1,9 @@
package app.revanced.patches.instagram.hide.suggestions
-import app.revanced.patcher.firstMethodComposite
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.instructions
import app.revanced.patcher.invoke
+import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.unorderedAllOf
internal val FEED_ITEM_KEYS_TO_BE_HIDDEN = arrayOf(
@@ -15,7 +16,7 @@ internal val FEED_ITEM_KEYS_TO_BE_HIDDEN = arrayOf(
"suggested_users",
)
-internal val feedItemParseFromJsonMethodMatch = firstMethodComposite("FeedItem") {
+internal val BytecodePatchContext.feedItemParseFromJsonMethodMatch by composingFirstMethod("FeedItem") {
instructions(
predicates = unorderedAllOf(
predicates =
diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/suggestions/HideSuggestedContent.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/suggestions/HideSuggestedContent.kt
index d9e2b7d59..f82335e18 100644
--- a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/suggestions/HideSuggestedContent.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/suggestions/HideSuggestedContent.kt
@@ -15,7 +15,7 @@ val hideSuggestedContentPatch = bytecodePatch(
apply {
feedItemParseFromJsonMethodMatch.method.apply {
- feedItemParseFromJsonMethodMatch.indices.forEach { targetStringIndex ->
+ feedItemParseFromJsonMethodMatch.indices[0].forEach { targetStringIndex ->
val targetStringRegister = getInstruction(targetStringIndex).registerA
replaceInstruction(targetStringIndex, "const-string v$targetStringRegister, \"BOGUS\"")
diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/devmenu/EnableDeveloperMenuPatch.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/devmenu/EnableDeveloperMenuPatch.kt
index 13825e54e..1d44ac825 100644
--- a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/devmenu/EnableDeveloperMenuPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/devmenu/EnableDeveloperMenuPatch.kt
@@ -21,7 +21,7 @@ val enableDeveloperMenuPatch = bytecodePatch(
apply {
clearNotificationReceiverMethodMatch.let {
- val stringIndex = it.indices.first()
+ val stringIndex = it[0]
it.immutableMethod.indexOfFirstInstructionReversedOrThrow(stringIndex) {
val reference = methodReference
diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/devmenu/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/devmenu/Fingerprints.kt
index 1ba3c4fd5..13d455eff 100644
--- a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/devmenu/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/devmenu/Fingerprints.kt
@@ -1,8 +1,9 @@
package app.revanced.patches.instagram.misc.devmenu
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
-internal val clearNotificationReceiverMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.clearNotificationReceiverMethodMatch by composingFirstMethod {
name("onReceive")
definingClass("Lcom/instagram/notifications/push/ClearNotificationReceiver;")
instructions("NOTIFICATION_DISMISSED"())
diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/links/Fingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/links/Fingerprint.kt
index 3a06dfec7..676a94241 100644
--- a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/links/Fingerprint.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/links/Fingerprint.kt
@@ -1,13 +1,14 @@
package app.revanced.patches.instagram.misc.links
-import app.revanced.patcher.firstMethodComposite
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.instructions
import app.revanced.patcher.invoke
+import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
internal const val TARGET_STRING = "Tracking.ARG_CLICK_SOURCE"
-internal val inAppBrowserFunctionMethodMatch = firstMethodComposite("TrackingInfo.ARG_MODULE_NAME") {
+internal val BytecodePatchContext.inAppBrowserFunctionMethodMatch by composingFirstMethod("TrackingInfo.ARG_MODULE_NAME") {
instructions(TARGET_STRING())
returnType("Z")
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/links/OpenLinksExternallyPatch.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/links/OpenLinksExternallyPatch.kt
index b4acecc16..f97fde3e4 100644
--- a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/links/OpenLinksExternallyPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/links/OpenLinksExternallyPatch.kt
@@ -23,7 +23,7 @@ val openLinksExternallyPatch = bytecodePatch(
apply {
inAppBrowserFunctionMethodMatch.let {
- val stringMatchIndex = it.indices.first()
+ val stringMatchIndex = it[0]
it.method.apply {
val urlResultObjIndex = indexOfFirstInstructionOrThrow(
diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/EditShareLinksPatch.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/EditShareLinksPatch.kt
index 812bae23c..5f31a6034 100644
--- a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/EditShareLinksPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/EditShareLinksPatch.kt
@@ -18,7 +18,7 @@ internal fun BytecodePatchContext.editShareLinksPatch(block: MutableMethod.(inde
for (match in methodsToPatch) {
match.method.apply {
val putSharingUrlIndex = indexOfFirstInstruction(
- match.indices.first(),
+ match[0],
Opcode.IPUT_OBJECT,
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/Fingerprints.kt
index 50a13daf6..23b82882e 100644
--- a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/Fingerprints.kt
@@ -1,32 +1,33 @@
package app.revanced.patches.instagram.misc.share
-import app.revanced.patcher.firstMethodComposite
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.instructions
import app.revanced.patcher.invoke
import app.revanced.patcher.name
+import app.revanced.patcher.patch.BytecodePatchContext
-internal val permalinkResponseJsonParserMethodMatch = firstMethodComposite(
+internal val BytecodePatchContext.permalinkResponseJsonParserMethodMatch by composingFirstMethod(
"PermalinkResponse",
) {
name("parseFromJson")
instructions("permalink"())
}
-internal val storyUrlResponseJsonParserMethodMatch = firstMethodComposite(
+internal val BytecodePatchContext.storyUrlResponseJsonParserMethodMatch by composingFirstMethod(
"StoryItemUrlResponse",
) {
name("parseFromJson")
instructions("story_item_to_share_url"())
}
-internal val profileUrlResponseJsonParserMethodMatch = firstMethodComposite(
+internal val BytecodePatchContext.profileUrlResponseJsonParserMethodMatch by composingFirstMethod(
"ProfileUrlResponse",
) {
name("parseFromJson")
instructions("profile_to_share_url"())
}
-internal val liveUrlResponseJsonParserMethodMatch = firstMethodComposite(
+internal val BytecodePatchContext.liveUrlResponseJsonParserMethodMatch by composingFirstMethod(
"LiveItemLinkUrlResponse",
) {
name("parseFromJson")
diff --git a/patches/src/main/kotlin/app/revanced/patches/lightroom/misc/version/DisableVersionCheckPatch.kt b/patches/src/main/kotlin/app/revanced/patches/lightroom/misc/version/DisableVersionCheckPatch.kt
index 86916848c..114765540 100644
--- a/patches/src/main/kotlin/app/revanced/patches/lightroom/misc/version/DisableVersionCheckPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/lightroom/misc/version/DisableVersionCheckPatch.kt
@@ -11,7 +11,7 @@ val disableVersionCheckPatch = bytecodePatch(
compatibleWith("com.adobe.lrmobile"("9.3.0"))
apply {
- val igetIndex = refreshRemoteConfigurationMethodMatch.indices.last()
+ val igetIndex = refreshRemoteConfigurationMethodMatch[-1]
// This value represents the server command to clear all version restrictions.
val statusForceReset = "-0x2"
diff --git a/patches/src/main/kotlin/app/revanced/patches/lightroom/misc/version/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/lightroom/misc/version/Fingerprints.kt
index 3921d0e06..f8be83517 100644
--- a/patches/src/main/kotlin/app/revanced/patches/lightroom/misc/version/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/lightroom/misc/version/Fingerprints.kt
@@ -1,12 +1,13 @@
package app.revanced.patches.lightroom.misc.version
import app.revanced.patcher.accessFlags
-import app.revanced.patcher.firstMethodComposite
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.opcodes
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
-internal val refreshRemoteConfigurationMethodMatch = firstMethodComposite(
+internal val BytecodePatchContext.refreshRemoteConfigurationMethodMatch by composingFirstMethod(
"com.adobe.lrmobile.denylisted_version_set_key",
"com.adobe.lrmobile.app_min_version_key",
) {
diff --git a/patches/src/main/kotlin/app/revanced/patches/messenger/metaai/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/messenger/metaai/Fingerprints.kt
index 96753309a..9901339b3 100644
--- a/patches/src/main/kotlin/app/revanced/patches/messenger/metaai/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/messenger/metaai/Fingerprints.kt
@@ -1,20 +1,21 @@
package app.revanced.patches.messenger.metaai
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
-internal val getMobileConfigBoolMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.getMobileConfigBoolMethodMatch by composingFirstMethod {
parameterTypes("J")
returnType("Z")
opcodes(Opcode.RETURN)
custom { "Lcom/facebook/mobileconfig/factory/MobileConfigUnsafeContext;" in immutableClassDef.interfaces }
}
-internal val metaAIKillSwitchCheckMethodMatch = firstMethodComposite("SearchAiagentImplementationsKillSwitch") {
+internal val BytecodePatchContext.metaAIKillSwitchCheckMethodMatch by composingFirstMethod("SearchAiagentImplementationsKillSwitch") {
opcodes(Opcode.CONST_WIDE)
}
-internal val extensionMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.extensionMethodMatch by composingFirstMethod {
name(EXTENSION_METHOD_NAME)
definingClass(EXTENSION_CLASS_DESCRIPTOR)
instructions("REPLACED_BY_PATCH"())
diff --git a/patches/src/main/kotlin/app/revanced/patches/messenger/metaai/RemoveMetaAIPatch.kt b/patches/src/main/kotlin/app/revanced/patches/messenger/metaai/RemoveMetaAIPatch.kt
index aaa490979..7b0d74908 100644
--- a/patches/src/main/kotlin/app/revanced/patches/messenger/metaai/RemoveMetaAIPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/messenger/metaai/RemoveMetaAIPatch.kt
@@ -22,7 +22,7 @@ val removeMetaAIPatch = bytecodePatch(
apply {
getMobileConfigBoolMethodMatch.let {
- val returnIndex = it.indices.first()
+ val returnIndex = it[0]
val returnRegister = it.method.getInstruction(returnIndex).registerA
it.method.addInstructions(
@@ -36,13 +36,13 @@ val removeMetaAIPatch = bytecodePatch(
// Extract the common starting digits of Meta AI flag IDs from a flag found in code.
val relevantDigits = metaAIKillSwitchCheckMethodMatch.let {
- it.method.getInstruction(it.indices.first()).wideLiteral
+ it.method.getInstruction(it[0]).wideLiteral
}.toString().substring(0, 7)
// Replace placeholder in the extension method.
extensionMethodMatch.let {
it.method.replaceInstruction(
- it.indices.first(),
+ it[0],
"const-string v1, \"$relevantDigits\"",
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/Fingerprints.kt
index 9264dd37a..6187e2215 100644
--- a/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/Fingerprints.kt
@@ -1,9 +1,10 @@
package app.revanced.patches.mifitness.misc.locale
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
-internal val syncBluetoothLanguageMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.syncBluetoothLanguageMethodMatch by composingFirstMethod {
name("syncBluetoothLanguage")
definingClass("Lcom/xiaomi/fitness/devicesettings/DeviceSettingsSyncer")
opcodes(Opcode.MOVE_RESULT_OBJECT)
diff --git a/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch.kt b/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch.kt
index 95c41208d..1e65344c5 100644
--- a/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch.kt
@@ -17,7 +17,7 @@ val forceEnglishLocalePatch = bytecodePatch(
apply {
syncBluetoothLanguageMethodMatch.let {
- val resolvePhoneLocaleInstruction = it.indices.first()
+ val resolvePhoneLocaleInstruction = it[0]
val registerIndexToUpdate = it.method.getInstruction(resolvePhoneLocaleInstruction).registerA
it.method.replaceInstruction(
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/ad/video/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/ad/video/Fingerprints.kt
index 41573b7e5..1d2f125f0 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/ad/video/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/ad/video/Fingerprints.kt
@@ -1,10 +1,11 @@
package app.revanced.patches.music.ad.video
-import app.revanced.patcher.firstMethodComposite
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.opcodes
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
-internal val showVideoAdsParentMethodMatch = firstMethodComposite(
+internal val BytecodePatchContext.showVideoAdsParentMethodMatch by composingFirstMethod(
"maybeRegenerateCpnAndStatsClient called unexpectedly, but no error.",
) {
opcodes(
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/ad/video/HideVideoAds.kt b/patches/src/main/kotlin/app/revanced/patches/music/ad/video/HideVideoAds.kt
index 5b1366cdc..410a6aff3 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/ad/video/HideVideoAds.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/ad/video/HideVideoAds.kt
@@ -37,7 +37,7 @@ val hideMusicVideoAdsPatch = bytecodePatch(
)
navigate(showVideoAdsParentMethodMatch.immutableMethod)
- .to(showVideoAdsParentMethodMatch.indices.first() + 1)
+ .to(showVideoAdsParentMethodMatch[0] + 1)
.stop()
.addInstructions(
0,
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/Fingerprints.kt
index b5dfe5703..704a2c88a 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/Fingerprints.kt
@@ -1,10 +1,11 @@
package app.revanced.patches.music.interaction.permanentrepeat
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
-internal val repeatTrackMethodMatch = firstMethodComposite("w_st") {
+internal val BytecodePatchContext.repeatTrackMethodMatch by composingFirstMethod("w_st") {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes("L", "L")
@@ -14,6 +15,6 @@ internal val repeatTrackMethodMatch = firstMethodComposite("w_st") {
Opcode.SGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
- Opcode.IF_NEZ
+ Opcode.IF_NEZ,
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/PermanentRepeatPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/PermanentRepeatPatch.kt
index 9f6a50e37..aa8a0449d 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/PermanentRepeatPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/PermanentRepeatPatch.kt
@@ -40,7 +40,7 @@ val permanentRepeatPatch = bytecodePatch(
)
repeatTrackMethodMatch.method.apply {
- val startIndex = repeatTrackMethodMatch.indices.last()
+ val startIndex = repeatTrackMethodMatch[-1]
val repeatIndex = startIndex + 1
// Start index is at a branch, but the same
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/buttons/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/buttons/Fingerprints.kt
index ca113c236..9db60e4af 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/layout/buttons/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/buttons/Fingerprints.kt
@@ -18,7 +18,7 @@ internal val BytecodePatchContext.playerOverlayChipMethod by gettingFirstMutable
instructions(playerOverlayChip())
}
-internal val historyMenuItemMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.historyMenuItemMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes("Landroid/view/Menu;")
@@ -32,7 +32,7 @@ internal val historyMenuItemMethodMatch = firstMethodComposite {
}
}
-internal val historyMenuItemOfflineTabMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.historyMenuItemOfflineTabMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes("Landroid/view/Menu;")
@@ -40,9 +40,9 @@ internal val historyMenuItemOfflineTabMethodMatch = firstMethodComposite {
Opcode.INVOKE_INTERFACE,
Opcode.RETURN_VOID,
)
- custom {
- instructions.matchIndexed("literals", items = unorderedAllOf(historyMenuItem(), offlineSettingsMenuItem()))
- }
+
+ val match = indexedMatcher(items = unorderedAllOf(historyMenuItem(), offlineSettingsMenuItem()))
+ custom { match(instructions) }
}
internal val BytecodePatchContext.searchActionViewMethod by gettingFirstMutableMethodDeclaratively {
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/buttons/HideButtons.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/buttons/HideButtons.kt
index cc858dab5..e6dd9e169 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/layout/buttons/HideButtons.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/buttons/HideButtons.kt
@@ -74,7 +74,7 @@ val hideButtonsPatch = bytecodePatch(
historyMenuItemOfflineTabMethodMatch,
).forEach { match ->
match.method.apply {
- val targetIndex = match.indices.first()
+ val targetIndex = match[0]
val targetRegister = getInstruction(targetIndex).registerD
addInstructions(
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/Fingerprints.kt
index 9d7fe75ca..00daa527d 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/Fingerprints.kt
@@ -1,10 +1,11 @@
package app.revanced.patches.music.layout.compactheader
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.Opcode
-internal val chipCloudMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.chipCloudMethodMatch by composingFirstMethod {
returnType("V")
opcodes(
Opcode.CONST,
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt
index d56322c10..7bc195419 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt
@@ -45,7 +45,7 @@ val hideCategoryBarPatch = bytecodePatch(
chipCloud = ResourceType.LAYOUT["chip_cloud"]
chipCloudMethodMatch.let {
- val targetIndex = it.indices.last()
+ val targetIndex = it[-1]
val targetRegister = it.method.getInstruction(targetIndex).registerA
it.method.addInstruction(
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/miniplayercolor/ChangeMiniplayerColor.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/miniplayercolor/ChangeMiniplayerColor.kt
index 138fc99a0..0b3153aa1 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/layout/miniplayercolor/ChangeMiniplayerColor.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/miniplayercolor/ChangeMiniplayerColor.kt
@@ -50,8 +50,8 @@ val changeMiniplayerColorPatch = bytecodePatch(
SwitchPreference("revanced_music_change_miniplayer_color"),
)
- switchToggleColorMethodMatch.match(miniPlayerConstructorMethodMatch.immutableClassDef).let {
- val relativeIndex = it.indices.last() + 1
+ miniPlayerConstructorMethodMatch.immutableClassDef.switchToggleColorMethodMatch.let {
+ val relativeIndex = it[-1] + 1
val invokeVirtualIndex = it.method.indexOfFirstInstructionOrThrow(
relativeIndex,
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/miniplayercolor/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/miniplayercolor/Fingerprints.kt
index 95d32778a..5a3ee206e 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/layout/miniplayercolor/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/miniplayercolor/Fingerprints.kt
@@ -7,7 +7,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.ClassDef
-internal val miniPlayerConstructorMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.miniPlayerConstructorMethodMatch by composingFirstMethod {
returnType("V")
instructions(
ResourceType.ID("mpp_player_bottom_sheet"),
@@ -18,7 +18,7 @@ internal val miniPlayerConstructorMethodMatch = firstMethodComposite {
/**
* Matches to the class found in [miniPlayerConstructorMethodMatch].
*/
-internal val switchToggleColorMethodMatch = firstMethodComposite {
+internal val ClassDef.switchToggleColorMethodMatch by ClassDefComposing.composingFirstMethod {
accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL)
returnType("V")
parameterTypes("L", "J")
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/navigationbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/navigationbar/Fingerprints.kt
index de0949c06..00984d1e0 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/layout/navigationbar/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/navigationbar/Fingerprints.kt
@@ -1,6 +1,7 @@
package app.revanced.patches.music.layout.navigationbar
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.util.containsLiteralInstruction
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
@@ -9,7 +10,7 @@ import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
-internal val tabLayoutTextMethodMatch = firstMethodComposite("FEmusic_search") {
+internal val BytecodePatchContext.tabLayoutTextMethodMatch by composingFirstMethod("FEmusic_search") {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes("L")
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/navigationbar/NavigationBarPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/navigationbar/NavigationBarPatch.kt
index aaa61566b..f977920b3 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/layout/navigationbar/NavigationBarPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/navigationbar/NavigationBarPatch.kt
@@ -100,7 +100,7 @@ val navigationBarPatch = bytecodePatch(
)
// Set navigation enum and hide navigation buttons.
- val enumIndex = tabLayoutTextMethodMatch.indices.first() + 3
+ val enumIndex = tabLayoutTextMethodMatch[0] + 3
val enumRegister = getInstruction(enumIndex).registerA
val insertEnumIndex = indexOfFirstInstructionOrThrow(Opcode.AND_INT_LIT8) - 2
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/Fingerprints.kt
index d5ae2ae65..bfa49bdeb 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/Fingerprints.kt
@@ -5,9 +5,9 @@ import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
-internal val hideGetPremiumMethodMatch = firstMethodComposite(
+internal val BytecodePatchContext.hideGetPremiumMethodMatch by composingFirstMethod(
"FEmusic_history",
- "FEmusic_offline"
+ "FEmusic_offline",
) {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt
index 9348dbe9a..d6f1c0092 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt
@@ -41,7 +41,7 @@ val hideGetMusicPremiumPatch = bytecodePatch(
)
hideGetPremiumMethodMatch.let {
- val insertIndex = it.indices.last()
+ val insertIndex = it[-1]
it.method.apply {
val setVisibilityInstruction = getInstruction(insertIndex)
diff --git a/patches/src/main/kotlin/app/revanced/patches/nunl/ads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/nunl/ads/Fingerprints.kt
index 3b9652a35..173b849e0 100644
--- a/patches/src/main/kotlin/app/revanced/patches/nunl/ads/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/nunl/ads/Fingerprints.kt
@@ -14,7 +14,7 @@ import com.android.tools.smali.dexlib2.Opcode val BytecodePatchContext.jwPlayerC
accessFlags(AccessFlags.PUBLIC)
}
-internal val screenMapperMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.screenMapperMethodMatch by composingFirstMethod {
name("map")
definingClass("Lnl/nu/android/bff/data/mappers/ScreenMapper;")
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
@@ -27,7 +27,7 @@ internal val screenMapperMethodMatch = firstMethodComposite {
)
}
-internal val nextPageRepositoryImplMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.nextPageRepositoryImplMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL)
returnType("Lnl/nu/android/bff/domain/models/Page;")
parameterTypes("Lnl/nu/performance/api/client/PacResponse;", "Ljava/lang/String;")
diff --git a/patches/src/main/kotlin/app/revanced/patches/nunl/ads/HideAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/nunl/ads/HideAdsPatch.kt
index 56296c9c0..b2eea685c 100644
--- a/patches/src/main/kotlin/app/revanced/patches/nunl/ads/HideAdsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/nunl/ads/HideAdsPatch.kt
@@ -27,7 +27,7 @@ val hideAdsPatch = bytecodePatch(
// Filter injected content from API calls out of lists.
arrayOf(screenMapperMethodMatch, nextPageRepositoryImplMethodMatch).forEach { match ->
// Index of instruction moving result of BlockPage;->getBlocks(...).
- val moveGetBlocksResultObjectIndex = match.indices.first()
+ val moveGetBlocksResultObjectIndex = match[0]
val moveInstruction = match.method.getInstruction(moveGetBlocksResultObjectIndex)
val listRegister = moveInstruction.registerA
diff --git a/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/Fingerprints.kt
index 23074c935..f00827eac 100644
--- a/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/Fingerprints.kt
@@ -1,11 +1,12 @@
package app.revanced.patches.photomath.detection.signature
-import app.revanced.patcher.firstMethodComposite
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.instructions
import app.revanced.patcher.invoke
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
-internal val checkSignatureMethodMatch = firstMethodComposite("SHA") {
+internal val BytecodePatchContext.checkSignatureMethodMatch by composingFirstMethod("SHA") {
instructions(
Opcode.CONST_STRING(),
Opcode.INVOKE_STATIC(),
diff --git a/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/SignatureDetectionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/SignatureDetectionPatch.kt
index 5114f034f..4bdeaf882 100644
--- a/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/SignatureDetectionPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/SignatureDetectionPatch.kt
@@ -10,7 +10,7 @@ val signatureDetectionPatch = bytecodePatch(
description = "Disables detection of incorrect signature.",
) {
apply {
- val replacementIndex = checkSignatureMethodMatch.indices.last()
+ val replacementIndex = checkSignatureMethodMatch[-1]
val checkRegister = checkSignatureMethodMatch.method.getInstruction(replacementIndex)
.registerA
diff --git a/patches/src/main/kotlin/app/revanced/patches/protonvpn/splittunneling/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/protonvpn/splittunneling/Fingerprints.kt
index 0ecc20d44..b68dda1e5 100644
--- a/patches/src/main/kotlin/app/revanced/patches/protonvpn/splittunneling/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/protonvpn/splittunneling/Fingerprints.kt
@@ -4,14 +4,14 @@ import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
-internal val enableSplitTunnelingUiMethodMatch = firstMethodComposite("currentModeAppNames") {
+internal val BytecodePatchContext.enableSplitTunnelingUiMethodMatch by composingFirstMethod("currentModeAppNames") {
opcodes(
Opcode.MOVE_OBJECT,
Opcode.MOVE_FROM16,
- Opcode.INVOKE_DIRECT_RANGE
+ Opcode.INVOKE_DIRECT_RANGE,
)
}
internal val BytecodePatchContext.initializeSplitTunnelingSettingsUIMethod by gettingFirstMutableMethodDeclaratively {
name("applyRestrictions")
-}
\ No newline at end of file
+}
diff --git a/patches/src/main/kotlin/app/revanced/patches/protonvpn/splittunneling/UnlockSplitTunneling.kt b/patches/src/main/kotlin/app/revanced/patches/protonvpn/splittunneling/UnlockSplitTunneling.kt
index 9839de45c..79bc78ec1 100644
--- a/patches/src/main/kotlin/app/revanced/patches/protonvpn/splittunneling/UnlockSplitTunneling.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/protonvpn/splittunneling/UnlockSplitTunneling.kt
@@ -15,7 +15,7 @@ val unlockSplitTunnelingPatch = bytecodePatch("Unlock split tunneling") {
apply {
enableSplitTunnelingUiMethodMatch.let {
- val registerIndex = it.indices.last() - 1
+ val registerIndex = it[-1] - 1
val register = it.method.getInstruction(registerIndex).registerA
it.method.replaceInstruction(registerIndex, "const/4 v$register, 0x0")
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/SpoofClientPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/SpoofClientPatch.kt
index 8306b362f..a4148df75 100644
--- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/SpoofClientPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/SpoofClientPatch.kt
@@ -15,7 +15,7 @@ fun spoofClientPatch(
redirectUri: String,
block: BytecodePatchBuilder.(Option) -> Unit = {},
) = bytecodePatch(
- name = "Spoof client", // TODO
+ name = "Spoof client",
description = "Restores functionality of the app by using custom client ID.",
) {
block(
@@ -23,9 +23,9 @@ fun spoofClientPatch(
name = "OAuth client ID",
values = null,
description = "The Reddit OAuth client ID. " +
- "You can get your client ID from https://www.reddit.com/prefs/apps. " +
- "The application type has to be \"Installed app\" " +
- "and the redirect URI has to be set to \"$redirectUri\".",
+ "You can get your client ID from https://www.reddit.com/prefs/apps. " +
+ "The application type has to be \"Installed app\" " +
+ "and the redirect URI has to be set to \"$redirectUri\".",
required = true,
),
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/Fingerprints.kt
index 9bbb82557..07fed4280 100644
--- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/Fingerprints.kt
@@ -1,16 +1,17 @@
package app.revanced.patches.reddit.customclients.baconreader.api
-import app.revanced.patcher.firstMethodComposite
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.instructions
import app.revanced.patcher.invoke
+import app.revanced.patcher.patch.BytecodePatchContext
-internal val getAuthorizationUrlMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.getAuthorizationUrlMethodMatch by composingFirstMethod {
instructions("client_id=zACVn0dSFGdWqQ"())
}
-internal val requestTokenMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.requestTokenMethodMatch by composingFirstMethod {
instructions(
"zACVn0dSFGdWqQ"(),
- "kDm2tYpu9DqyWFFyPlNcXGEni4k"(String::contains)
+ "kDm2tYpu9DqyWFFyPlNcXGEni4k"(String::contains),
)
-}
\ No newline at end of file
+}
diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/SpoofClientPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/SpoofClientPatch.kt
index 8e753ee4e..5dba2ef80 100644
--- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/SpoofClientPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/SpoofClientPatch.kt
@@ -1,6 +1,6 @@
package app.revanced.patches.reddit.customclients.baconreader.api
-import app.revanced.patcher.MatchBuilder
+import app.revanced.patcher.Match
import app.revanced.patcher.extensions.getInstruction
import app.revanced.patcher.extensions.replaceInstruction
import app.revanced.patches.reddit.customclients.spoofClientPatch
@@ -11,7 +11,7 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "http://baconreader.com/au
dependsOn(
// Redirects from SSL to WWW domain are bugged causing auth problems.
// Manually rewrite the URLs to fix this.
- replaceStringPatch("ssl.reddit.com", "www.reddit.com")
+ replaceStringPatch("ssl.reddit.com", "www.reddit.com"),
)
compatibleWith(
@@ -22,8 +22,8 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "http://baconreader.com/au
val clientId by clientIdOption
apply {
- fun MatchBuilder.patch(replacementString: String) {
- val clientIdIndex = indices.first()
+ fun Match.patch(replacementString: String) {
+ val clientIdIndex = get(0)
val clientIdRegister = method.getInstruction(clientIdIndex).registerA
method.replaceInstruction(
diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/Fingerprints.kt
index 126bc84c8..b8cdd1d63 100644
--- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/Fingerprints.kt
@@ -1,12 +1,13 @@
package app.revanced.patches.reddit.customclients.boostforreddit.fix.downloads
-import app.revanced.patcher.firstMethodComposite
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.instructions
import app.revanced.patcher.invoke
+import app.revanced.patcher.patch.BytecodePatchContext
-internal val downloadAudioMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.downloadAudioMethodMatch by composingFirstMethod {
instructions(
"/DASH_audio.mp4"(),
- "/audio"()
+ "/audio"(),
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/FixAudioMissingInDownloadsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/FixAudioMissingInDownloadsPatch.kt
index 7483aff27..518700ed1 100644
--- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/FixAudioMissingInDownloadsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/FixAudioMissingInDownloadsPatch.kt
@@ -18,7 +18,7 @@ val fixMissingAudioInVideoDownloadsPatch = bytecodePatch(
"/DASH_AUDIO_64.mp4",
)
- downloadAudioMethodMatch.indices.forEachIndexed { index, i ->
+ downloadAudioMethodMatch.indices[0].forEachIndexed { index, i ->
val replacement = endpointReplacements[i]
val register = downloadAudioMethodMatch.method.getInstruction(index).registerA
diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/redditisfun/api/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/redditisfun/api/Fingerprints.kt
index ac3c389a4..3850b2967 100644
--- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/redditisfun/api/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/redditisfun/api/Fingerprints.kt
@@ -6,17 +6,17 @@ import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
-internal val basicAuthorizationMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.basicAuthorizationMethodMatch by composingFirstMethod {
instructions(
"yyOCBp.RHJhDKd"(),
- "fJOxVwBUyo*=f:.() -> Int,
) = method.apply {
- val replacementIndex = indices.getReplacementIndex()
+ val replacementIndex = indices[0].getReplacementIndex()
val clientIdRegister = getInstruction(replacementIndex).registerA
replaceInstruction(replacementIndex, "const-string v$clientIdRegister, \"$string\"")
diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/Fingerprints.kt
index 6b081e008..50c39b628 100644
--- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/Fingerprints.kt
@@ -1,28 +1,28 @@
package app.revanced.patches.reddit.customclients.relayforreddit.api
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
-import app.revanced.patcher.firstMethodComposite
import app.revanced.patcher.instructions
import app.revanced.patcher.invoke
import app.revanced.patcher.parameterTypes
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
+import org.stringtemplate.v4.compiler.Bytecode
-
-internal fun baseClientIdMethod(string: String) = firstMethodComposite {
+internal fun baseClientIdMethod(string: String) = composingFirstMethod {
instructions(
"dj-xCIZQYiLbEg"(),
- string()
+ string(),
)
}
-internal val getLoggedInBearerTokenMethodMatch = baseClientIdMethod("authorization_code")
+internal val BytecodePatchContext.getLoggedInBearerTokenMethodMatch by baseClientIdMethod("authorization_code")
-internal val getLoggedOutBearerTokenMethodMatch = baseClientIdMethod("https://oauth.reddit.com/grants/installed_client")
+internal val BytecodePatchContext.getLoggedOutBearerTokenMethodMatch by baseClientIdMethod("https://oauth.reddit.com/grants/installed_client")
-internal val getRefreshTokenMethodMatch = baseClientIdMethod("refresh_token")
+internal val BytecodePatchContext.getRefreshTokenMethodMatch by baseClientIdMethod("refresh_token")
-internal val loginActivityClientIdMethodMatch = baseClientIdMethod("&duration=permanent")
+internal val BytecodePatchContext.loginActivityClientIdMethodMatch by baseClientIdMethod("&duration=permanent")
internal val BytecodePatchContext.redditCheckDisableAPIMethod by gettingFirstMutableMethodDeclaratively("Reddit Disabled") {
instructions(Opcode.IF_EQZ())
diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/SpoofClientPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/SpoofClientPatch.kt
index fa0f6fbf2..df4c381ad 100644
--- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/SpoofClientPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/SpoofClientPatch.kt
@@ -28,7 +28,7 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "dbrady://relay") { client
getLoggedOutBearerTokenMethodMatch,
getRefreshTokenMethodMatch,
).forEach { match ->
- val clientIdIndex = match.indices.first()
+ val clientIdIndex = match[0]
val clientIdRegister = match.method.getInstruction(clientIdIndex).registerA
match.method.replaceInstruction(clientIdIndex, "const-string v$clientIdRegister, \"$clientId\"")
diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/detection/piracy/DisablePiracyDetectionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/detection/piracy/DisablePiracyDetectionPatch.kt
index bd90bd127..e84f4cc9e 100644
--- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/detection/piracy/DisablePiracyDetectionPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/detection/piracy/DisablePiracyDetectionPatch.kt
@@ -8,7 +8,7 @@ val disablePiracyDetectionPatch = bytecodePatch(
) {
apply {
- // Do not throw an error if the fingerprint is not resolved.
+ // Do not throw an error if the method can't be found.
// This is fine because new versions of the target app do not need this patch.
detectPiracyMethodOrNull?.returnEarly()
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/Fingerprints.kt
index 5ca6baf3c..1db407111 100644
--- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/Fingerprints.kt
@@ -1,17 +1,19 @@
package app.revanced.patches.reddit.customclients.sync.syncforreddit.api
-import app.revanced.patcher.firstMethodComposite
+import app.revanced.patcher.ClassDefComposing
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.gettingFirstMutableMethod
import app.revanced.patcher.instructions
import app.revanced.patcher.invoke
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.string
+import com.android.tools.smali.dexlib2.iface.ClassDef
-internal val getAuthorizationStringMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.getAuthorizationStringMethodMatch by composingFirstMethod {
instructions(string { startsWith("authorize.compact?client_id") })
}
-internal val getBearerTokenMethodMatch = firstMethodComposite {
+internal val ClassDef.getBearerTokenMethodMatch by ClassDefComposing.composingFirstMethod {
instructions(string { startsWith("Basic") })
}
@@ -19,6 +21,6 @@ internal val BytecodePatchContext.getUserAgentMethod by gettingFirstMutableMetho
"android:com.laurencedawson.reddit_sync",
)
-internal val imgurImageAPIMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.imgurImageAPIMethodMatch by composingFirstMethod {
instructions("https://imgur-apiv3.p.rapidapi.com/3/image"())
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/SpoofClientPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/SpoofClientPatch.kt
index 0d03b7210..4422cdc10 100644
--- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/SpoofClientPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/SpoofClientPatch.kt
@@ -18,7 +18,7 @@ val spoofClientPatch = spoofClientPatch(
disablePiracyDetectionPatch,
// Redirects from SSL to WWW domain are bugged causing auth problems.
// Manually rewrite the URLs to fix this.
- replaceStringPatch("ssl.reddit.com", "www.reddit.com")
+ replaceStringPatch("ssl.reddit.com", "www.reddit.com"),
)
compatibleWith(
@@ -32,11 +32,11 @@ val spoofClientPatch = spoofClientPatch(
apply {
// region Patch client id.
- getBearerTokenMethodMatch.match(getAuthorizationStringMethodMatch.immutableClassDef).method.apply {
+ getAuthorizationStringMethodMatch.immutableClassDef.getBearerTokenMethodMatch.method.apply {
val auth = Base64.getEncoder().encodeToString("$clientId:".toByteArray(Charsets.UTF_8))
returnEarly("Basic $auth")
- val occurrenceIndex = getAuthorizationStringMethodMatch.indices.first()
+ val occurrenceIndex = getAuthorizationStringMethodMatch[0]
getAuthorizationStringMethodMatch.method.apply {
val authorizationStringInstruction = getInstruction(occurrenceIndex)
@@ -68,7 +68,7 @@ val spoofClientPatch = spoofClientPatch(
// region Patch Imgur API URL.
- val apiUrlIndex = imgurImageAPIMethodMatch.indices.first()
+ val apiUrlIndex = imgurImageAPIMethodMatch[0]
imgurImageAPIMethodMatch.method.replaceInstruction(
apiUrlIndex,
"const-string v1, \"https://api.imgur.com/3/image\"",
diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/redgifs/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/redgifs/Fingerprints.kt
index 600a591fd..8938b850e 100644
--- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/redgifs/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/redgifs/Fingerprints.kt
@@ -15,7 +15,7 @@ internal val BytecodePatchContext.createOkHttpClientMethod by gettingFirstMutabl
returnType("V")
parameterTypes()
custom {
- // There are four functions (each creating a client) defined in this file with very similar fingerprints.
+ // There are four functions (each creating a client) defined in this file with very similar methods.
// We're looking for the one that only creates one object (the builder) and sets client options true
// (thus never reloading the register with a 0).
immutableClassDef.sourceFile == "OkHttpHelper.java" && instructions.count {
diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/user/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/user/Fingerprints.kt
index e9fa43f09..5aa03483d 100644
--- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/user/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/user/Fingerprints.kt
@@ -1,39 +1,40 @@
package app.revanced.patches.reddit.customclients.sync.syncforreddit.fix.user
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
internal fun userEndpointMethodMatch(
source: String,
- accessFlags: Set? = null
-) = firstMethodComposite {
+ accessFlags: Set? = null,
+) = composingFirstMethod {
instructions("u/"(String::contains))
custom { immutableClassDef.sourceFile == source }
- accessFlags(*accessFlags?.toTypedArray() ?: return@firstMethodComposite)
+ accessFlags(*accessFlags?.toTypedArray() ?: return@composingFirstMethod)
}
-internal val oAuthFriendRequestMethodMatch = userEndpointMethodMatch(
+internal val BytecodePatchContext.oAuthFriendRequestMethodMatch by userEndpointMethodMatch(
"OAuthFriendRequest.java",
)
-internal val oAuthUnfriendRequestMethodMatch = userEndpointMethodMatch(
+internal val BytecodePatchContext.oAuthUnfriendRequestMethodMatch by userEndpointMethodMatch(
"OAuthUnfriendRequest.java",
)
-internal val oAuthUserIdRequestMethodMatch = userEndpointMethodMatch(
+internal val BytecodePatchContext.oAuthUserIdRequestMethodMatch by userEndpointMethodMatch(
"OAuthUserIdRequest.java",
)
-internal val oAuthUserInfoRequestMethodMatch = userEndpointMethodMatch(
+internal val BytecodePatchContext.oAuthUserInfoRequestMethodMatch by userEndpointMethodMatch(
"OAuthUserInfoRequest.java",
)
-internal val oAuthSubredditInfoRequestConstructorMethodMatch = userEndpointMethodMatch(
+internal val BytecodePatchContext.oAuthSubredditInfoRequestConstructorMethodMatch by userEndpointMethodMatch(
"OAuthSubredditInfoRequest.java",
setOf(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR),
)
-internal val oAuthSubredditInfoRequestHelperMethodMatch = userEndpointMethodMatch(
+internal val BytecodePatchContext.oAuthSubredditInfoRequestHelperMethodMatch by userEndpointMethodMatch(
"OAuthSubredditInfoRequest.java",
setOf(AccessFlags.PRIVATE, AccessFlags.STATIC),
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/user/UseUserEndpointPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/user/UseUserEndpointPatch.kt
index 376191ba5..5c0dbf941 100644
--- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/user/UseUserEndpointPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/user/UseUserEndpointPatch.kt
@@ -28,7 +28,7 @@ val useUserEndpointPatch = bytecodePatch(
oAuthUserIdRequestMethodMatch,
oAuthUserInfoRequestMethodMatch,
).map { match ->
- match.indices.first() to match.method
+ match[0] to match.method
}.forEach { (userPathStringIndex, method) ->
val userPathStringInstruction = method.getInstruction(userPathStringIndex)
diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/Fingerprints.kt
index a34ef7b71..7f11752ae 100644
--- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/Fingerprints.kt
@@ -1,9 +1,10 @@
package app.revanced.patches.reddit.customclients.sync.syncforreddit.fix.video
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
-internal val parseRedditVideoNetworkResponseMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.parseRedditVideoNetworkResponseMethodMatch by composingFirstMethod {
name("parseNetworkResponse")
opcodes(
Opcode.NEW_INSTANCE,
diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/FixVideoDownloadsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/FixVideoDownloadsPatch.kt
index aa0fe5389..0baae8ab9 100644
--- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/FixVideoDownloadsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/FixVideoDownloadsPatch.kt
@@ -24,7 +24,7 @@ val fixVideoDownloadsPatch = bytecodePatch(
)
apply {
- val scanResult = parseRedditVideoNetworkResponseMethodMatch.indices
+ val scanResult = parseRedditVideoNetworkResponseMethodMatch.indices[0]
val newInstanceIndex = scanResult.first()
val invokeDirectIndex = scanResult.last() - 1
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/layout/branding/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/layout/branding/Fingerprints.kt
index add3716a6..fd41b8a61 100644
--- a/patches/src/main/kotlin/app/revanced/patches/shared/layout/branding/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/layout/branding/Fingerprints.kt
@@ -12,8 +12,8 @@ internal val BytecodePatchContext.numberOfPresetAppNamesExtensionMethod by getti
parameterTypes()
}
-// A much simpler fingerprint exists that can set the small icon (contains string "414843287017"),
-// but that has limited usage and this fingerprint allows changing any part of the notification.
+// A much simpler method exists that can set the small icon (contains string "414843287017"),
+// but that has limited usage and this one allows changing any part of the notification.
internal val BytecodePatchContext.notificationMethod by gettingFirstMutableMethodDeclaratively(
"key_action_priority",
) {
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/layout/theme/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/layout/theme/Fingerprints.kt
index c0ea184c6..cd9fc2b79 100644
--- a/patches/src/main/kotlin/app/revanced/patches/shared/layout/theme/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/layout/theme/Fingerprints.kt
@@ -1,10 +1,11 @@
package app.revanced.patches.shared.layout.theme
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
-internal val lithoOnBoundsChangeMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.lithoOnBoundsChangeMethodMatch by composingFirstMethod {
name("onBoundsChange")
accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL)
returnType("V")
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/layout/theme/LithoColorHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/layout/theme/LithoColorHookPatch.kt
index f373d593c..6844d9db4 100644
--- a/patches/src/main/kotlin/app/revanced/patches/shared/layout/theme/LithoColorHookPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/layout/theme/LithoColorHookPatch.kt
@@ -11,7 +11,7 @@ val lithoColorHookPatch = bytecodePatch(
) {
apply {
- var insertionIndex = lithoOnBoundsChangeMethodMatch.indices.last() - 1
+ var insertionIndex = lithoOnBoundsChangeMethodMatch[-1] - 1
lithoColorOverrideHook = { targetMethodClass, targetMethodName ->
lithoOnBoundsChangeMethodMatch.method.addInstructions(
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/audio/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/audio/Fingerprints.kt
index 5e9d1f2ac..50f48aaf2 100644
--- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/audio/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/audio/Fingerprints.kt
@@ -1,18 +1,19 @@
package app.revanced.patches.shared.misc.audio
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
-internal val formatStreamModelToStringMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.formatStreamModelToStringMethodMatch by composingFirstMethod {
name("toString")
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("Ljava/lang/String;")
instructions(
"isDefaultAudioTrack="(String::contains),
- "audioTrackId="(String::contains)
+ "audioTrackId="(String::contains),
)
}
-internal val selectAudioStreamMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.selectAudioStreamMethodMatch by composingFirstMethod {
instructions(45666189L())
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/audio/ForceOriginalAudioPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/audio/ForceOriginalAudioPatch.kt
index 702cfc22f..636070951 100644
--- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/audio/ForceOriginalAudioPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/audio/ForceOriginalAudioPatch.kt
@@ -39,7 +39,7 @@ internal fun forceOriginalAudioPatch(
subclassExtensionClassDescriptor: String,
preferenceScreen: BasePreferenceScreen.Screen,
) = bytecodePatch(
- name = "Force original audio", // TODO
+ name = "Force original audio",
description = "Adds an option to always use the original audio track.",
) {
block()
@@ -65,7 +65,7 @@ internal fun forceOriginalAudioPatch(
// and instead overrides to the user region language.
if (fixUseLocalizedAudioTrackFlag()) {
selectAudioStreamMethodMatch.method.insertLiteralOverride(
- selectAudioStreamMethodMatch.indices.first(),
+ selectAudioStreamMethodMatch[0],
"$EXTENSION_CLASS_DESCRIPTOR->ignoreDefaultAudioStream(Z)Z",
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/debugging/EnableDebuggingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/debugging/EnableDebuggingPatch.kt
index 491e27927..3aafba1dc 100644
--- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/debugging/EnableDebuggingPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/debugging/EnableDebuggingPatch.kt
@@ -26,12 +26,11 @@ internal fun enableDebuggingPatch(
executeBlock: BytecodePatchContext.() -> Unit = {},
hookStringFeatureFlag: Boolean,
preferenceScreen: BasePreferenceScreen.Screen,
- additionalDebugPreferences: List = emptyList()
+ additionalDebugPreferences: List = emptyList(),
) = bytecodePatch(
- name = "Enable debugging", // TODO
+ name = "Enable debugging",
description = "Adds options for debugging and exporting ReVanced logs to the clipboard.",
) {
-
dependsOn(
addResourcesPatch,
resourcePatch {
@@ -48,11 +47,11 @@ internal fun enableDebuggingPatch(
"revanced_settings_arrow_left_double.xml",
"revanced_settings_arrow_left_one.xml",
"revanced_settings_arrow_right_double.xml",
- "revanced_settings_arrow_right_one.xml"
- )
+ "revanced_settings_arrow_right_one.xml",
+ ),
)
}
- }
+ },
)
block()
@@ -75,19 +74,19 @@ internal fun enableDebuggingPatch(
NonInteractivePreference(
"revanced_debug_export_logs_to_clipboard",
tag = "app.revanced.extension.shared.settings.preference.ExportLogToClipboardPreference",
- selectable = true
+ selectable = true,
),
NonInteractivePreference(
"revanced_debug_logs_clear_buffer",
tag = "app.revanced.extension.shared.settings.preference.ClearLogBufferPreference",
- selectable = true
+ selectable = true,
),
NonInteractivePreference(
"revanced_debug_feature_flags_manager",
tag = "app.revanced.extension.shared.settings.preference.FeatureFlagsManagerPreference",
- selectable = true
- )
- )
+ selectable = true,
+ ),
+ ),
)
preferenceScreen.addPreferences(
@@ -95,7 +94,7 @@ internal fun enableDebuggingPatch(
key = "revanced_debug_screen",
sorting = Sorting.UNSORTED,
preferences = preferences,
- )
+ ),
)
// Hook the methods that look up if a feature flag is active.
@@ -108,7 +107,7 @@ internal fun enableDebuggingPatch(
"""
invoke-static { v$register, p1 }, $EXTENSION_CLASS_DESCRIPTOR->isBooleanFeatureFlagEnabled(ZLjava/lang/Long;)Z
move-result v$register
- """
+ """,
)
}
}
@@ -123,7 +122,7 @@ internal fun enableDebuggingPatch(
invoke-static/range { v0 .. v5 }, $EXTENSION_CLASS_DESCRIPTOR->isDoubleFeatureFlagEnabled(DJD)D
move-result-wide v0
return-wide v0
- """
+ """,
)
}
@@ -137,11 +136,11 @@ internal fun enableDebuggingPatch(
invoke-static/range { v0 .. v5 }, $EXTENSION_CLASS_DESCRIPTOR->isLongFeatureFlagEnabled(JJJ)J
move-result-wide v0
return-wide v0
- """
+ """,
)
}
- if (hookStringFeatureFlag)
+ if (hookStringFeatureFlag) {
experimentalFeatureFlagParentMethod.immutableClassDef.getExperimentalStringFeatureFlagMethod().apply {
val insertIndex = indexOfFirstInstructionReversedOrThrow(Opcode.MOVE_RESULT_OBJECT)
@@ -152,9 +151,10 @@ internal fun enableDebuggingPatch(
invoke-static { v0, p1, p2, p3 }, $EXTENSION_CLASS_DESCRIPTOR->isStringFeatureFlagEnabled(Ljava/lang/String;JLjava/lang/String;)Ljava/lang/String;
move-result-object v0
return-object v0
- """
+ """,
)
}
+ }
// There exists other experimental accessor methods for byte[]
// and wrappers for obfuscated classes, but currently none of those are hooked.
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt
index afec7080c..d355b3837 100644
--- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt
@@ -18,7 +18,7 @@ internal fun checkWatchHistoryDomainNameResolutionPatch(
executeBlock: BytecodePatchContext.() -> Unit = {},
getMainActivityMethod: BytecodePatchContext.() -> MutableMethod,
) = bytecodePatch(
- name = "Check watch history domain name resolution", // TODO
+ name = "Check watch history domain name resolution",
description = "Checks if the device DNS server is preventing user watch history from being saved.",
) {
block()
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt
index 8d485bcf8..7f493623a 100644
--- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt
@@ -1,9 +1,8 @@
package app.revanced.patches.shared.misc.extension
import app.revanced.patcher.*
-import app.revanced.patcher.firstMutableClassDef
-import app.revanced.patcher.firstMutableMethodDeclaratively
import app.revanced.patcher.extensions.addInstruction
+import app.revanced.patcher.firstMutableClassDef
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.util.returnEarly
@@ -85,18 +84,18 @@ fun sharedExtensionPatch(
class ExtensionHook internal constructor(
private val getInsertIndex: Method.() -> Int,
private val getContextRegister: Method.() -> String,
- private val predicate: DeclarativePredicate,
+ private val build: context(MutableList) MutablePredicateList.() -> Unit,
) {
- context(_: BytecodePatchContext)
+ context(context: BytecodePatchContext)
operator fun invoke(extensionClassDescriptor: String) {
- val method = firstMutableMethodDeclaratively(predicate = predicate)
+ val method = context.firstMutableMethodDeclaratively(build = build)
val insertIndex = method.getInsertIndex()
val contextRegister = method.getContextRegister()
method.addInstruction(
insertIndex,
"invoke-static/range { $contextRegister .. $contextRegister }, " +
- "$extensionClassDescriptor->setContext(Landroid/content/Context;)V",
+ "$extensionClassDescriptor->setContext(Landroid/content/Context;)V",
)
}
}
@@ -104,8 +103,8 @@ class ExtensionHook internal constructor(
fun extensionHook(
getInsertIndex: Method.() -> Int = { 0 },
getContextRegister: Method.() -> String = { "p0" },
- predicate: DeclarativePredicate,
-) = ExtensionHook(getInsertIndex, getContextRegister, predicate)
+ build: context(MutableList) MutablePredicateList.() -> Unit,
+) = ExtensionHook(getInsertIndex, getContextRegister, build)
/**
* Creates an extension hook from a non-obfuscated activity, which typically is the main activity
@@ -124,8 +123,11 @@ fun activityOnCreateExtensionHook(activityClassType: String): ExtensionHook {
return extensionHook {
name("onCreate")
- if (fullClassType) definingClass(activityClassType)
- else definingClass { endsWith(activityClassType) }
+ if (fullClassType) {
+ definingClass(activityClassType)
+ } else {
+ definingClass { endsWith(activityClassType) }
+ }
returnType("V")
parameterTypes("Landroid/os/Bundle;")
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/Fingerprints.kt
index cf7e2aa6d..2037efcdf 100644
--- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/Fingerprints.kt
@@ -1,10 +1,11 @@
package app.revanced.patches.shared.misc.fix.verticalscroll
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
-internal val canScrollVerticallyMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.canScrollVerticallyMethodMatch by composingFirstMethod {
definingClass { endsWith("SwipeRefreshLayout;") }
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("Z")
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/VerticalScrollPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/VerticalScrollPatch.kt
index 210447c25..54a396d47 100644
--- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/VerticalScrollPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/VerticalScrollPatch.kt
@@ -12,7 +12,7 @@ val verticalScrollPatch = bytecodePatch(
apply {
canScrollVerticallyMethodMatch.let {
it.method.apply {
- val moveResultIndex = it.indices.last()
+ val moveResultIndex = it[-1]
val moveResultRegister = getInstruction(moveResultIndex).registerA
val insertIndex = moveResultIndex + 1
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt
index 91586cf4e..6e481b805 100644
--- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt
@@ -54,7 +54,7 @@ fun gmsCoreSupportPatch(
executeBlock: BytecodePatchContext.() -> Unit = {},
block: BytecodePatchBuilder.() -> Unit = {},
) = bytecodePatch(
- name = "GmsCore support", // TODO
+ name = "GmsCore support",
description = "Allows the app to work without root by using a different package name when patched " +
"using a GmsCore instead of Google Play Services.",
) {
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/privacy/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/privacy/Fingerprints.kt
index 3f0a6c5f1..4dfdc92a6 100644
--- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/privacy/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/privacy/Fingerprints.kt
@@ -1,9 +1,10 @@
package app.revanced.patches.shared.misc.privacy
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
-internal val youTubeCopyTextFingerprintMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.youTubeCopyTextMethodMatch by composingFirstMethod {
returnType("V")
parameterTypes("L", "Ljava/util/Map;")
instructions(
@@ -11,22 +12,22 @@ internal val youTubeCopyTextFingerprintMethodMatch = firstMethodComposite {
after(0..2, "text/plain"()),
after(0..2, method("newPlainText")),
after(0..2, Opcode.MOVE_RESULT_OBJECT()),
- after(0..2, method("setPrimaryClip"))
+ after(0..2, method("setPrimaryClip")),
)
}
-internal val youTubeSystemShareSheetMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.youTubeSystemShareSheetMethodMatch by composingFirstMethod {
returnType("V")
parameterTypes("L", "Ljava/util/Map;")
instructions(
method("setClassName"),
after(0..4, method("iterator")),
after(0..15, allOf(Opcode.IGET_OBJECT(), type("Ljava/lang/String;"))),
- after(0..15, method("putExtra"))
+ after(0..15, method("putExtra")),
)
}
-internal val youTubeShareSheetMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.youTubeShareSheetMethodMatch by composingFirstMethod {
returnType("V")
parameterTypes("L", "Ljava/util/Map;")
instructions(
@@ -34,6 +35,6 @@ internal val youTubeShareSheetMethodMatch = firstMethodComposite {
after(allOf(Opcode.CHECK_CAST(), type("Ljava/lang/String;"))),
after(Opcode.GOTO()),
method("putExtra"),
- "YTShare_Logging_Share_Intent_Endpoint_Byte_Array"()
+ "YTShare_Logging_Share_Intent_Endpoint_Byte_Array"(),
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/privacy/SanitizeSharingLinksPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/privacy/SanitizeSharingLinksPatch.kt
index 84ccc8b75..88462b2b4 100644
--- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/privacy/SanitizeSharingLinksPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/privacy/SanitizeSharingLinksPatch.kt
@@ -1,6 +1,6 @@
package app.revanced.patches.shared.misc.privacy
-import app.revanced.patcher.MatchBuilder
+import app.revanced.patcher.Match
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.getInstruction
import app.revanced.patcher.patch.BytecodePatchBuilder
@@ -28,7 +28,7 @@ internal fun sanitizeSharingLinksPatch(
preferenceScreen: BasePreferenceScreen.Screen,
replaceMusicLinksWithYouTube: Boolean = false,
) = bytecodePatch(
- name = "Sanitize sharing links", // TODO
+ name = "Sanitize sharing links",
description = "Removes the tracking query parameters from shared links.",
) {
block()
@@ -58,8 +58,9 @@ internal fun sanitizeSharingLinksPatch(
},
)
- fun MatchBuilder.hookUrlString(matchIndex: Int) {
- val index = indices[matchIndex]
+ fun Match.hookUrlString(matchIndex: Int) {
+ val index = get(matchIndex)
+
val urlRegister = method.getInstruction(index).registerA
method.addInstructions(
@@ -71,8 +72,8 @@ internal fun sanitizeSharingLinksPatch(
)
}
- fun MatchBuilder.hookIntentPutExtra(matchIndex: Int) {
- val index = indices[matchIndex]
+ fun Match.hookIntentPutExtra(matchIndex: Int) {
+ val index = get(matchIndex)
val urlRegister = method.getInstruction(index).registerE
method.addInstructionsAtControlFlowLabel(
@@ -85,7 +86,7 @@ internal fun sanitizeSharingLinksPatch(
}
// YouTube share sheet copy link.
- youTubeCopyTextFingerprintMethodMatch.hookUrlString(0)
+ youTubeCopyTextMethodMatch.hookUrlString(0)
// YouTube share sheet other apps.
youTubeShareSheetMethodMatch.hookIntentPutExtra(3)
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/Fingerprints.kt
index 40adaa3d8..7e3253ebd 100644
--- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/Fingerprints.kt
@@ -1,10 +1,10 @@
package app.revanced.patches.shared.misc.spoof
import app.revanced.patcher.accessFlags
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.custom
import app.revanced.patcher.definingClass
import app.revanced.patcher.extensions.methodReference
-import app.revanced.patcher.firstMethodComposite
import app.revanced.patcher.gettingFirstMethodDeclaratively
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.immutableClassDef
@@ -21,15 +21,15 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.Method
-internal val buildInitPlaybackRequestMatch = firstMethodComposite("Content-Type", "Range") {
- returnType("Lorg/chromium/net/UrlRequest\$Builder;")
+internal val BytecodePatchContext.buildInitPlaybackRequestMethodMatch by composingFirstMethod("Content-Type", "Range") {
+ returnType($$"Lorg/chromium/net/UrlRequest$Builder;")
instructions(
Opcode.MOVE_RESULT_OBJECT(),
Opcode.IGET_OBJECT(), // Moves the request URI string to a register to build the request with.
)
}
-internal val buildPlayerRequestURIMethodMatch = firstMethodComposite("key", "asig") {
+internal val BytecodePatchContext.buildPlayerRequestURIMethodMatch by composingFirstMethod("key", "asig") {
returnType("Ljava/lang/String;")
instructions(
Opcode.INVOKE_VIRTUAL(), // Register holds player request URI.
@@ -41,7 +41,7 @@ internal val buildPlayerRequestURIMethodMatch = firstMethodComposite("key", "asi
)
}
-internal val buildRequestMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.buildRequestMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returnType("Lorg/chromium/net/UrlRequest") // UrlRequest; or UrlRequest$Builder;
instructions(
@@ -80,8 +80,8 @@ internal val buildRequestMethodMatch = firstMethodComposite {
val parameterTypes = parameterTypes
val parameterTypesSize = parameterTypes.size
(parameterTypesSize == 6 || parameterTypesSize == 7 || parameterTypesSize == 8) &&
- parameterTypes[1] == "Ljava/util/Map;" && // URL headers.
- indexOfNewUrlRequestBuilderInstruction(this) >= 0
+ parameterTypes[1] == "Ljava/util/Map;" && // URL headers.
+ indexOfNewUrlRequestBuilderInstruction(this) >= 0
}
}
@@ -98,7 +98,7 @@ internal val BytecodePatchContext.protobufClassParseByteBufferMethod by gettingF
)
}
-internal val createStreamingDataMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.createStreamingDataMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
parameterTypes("L")
instructions(
@@ -131,7 +131,7 @@ internal val BytecodePatchContext.buildMediaDataSourceMethod by gettingFirstMuta
)
}
-internal val hlsCurrentTimeMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.hlsCurrentTimeMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
parameterTypes("Z", "L")
instructions(
@@ -141,7 +141,7 @@ internal val hlsCurrentTimeMethodMatch = firstMethodComposite {
internal const val DISABLED_BY_SABR_STREAMING_URI_STRING = "DISABLED_BY_SABR_STREAMING_URI"
-internal val mediaFetchEnumConstructorMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.mediaFetchEnumConstructorMethodMatch by composingFirstMethod {
returnType("V")
instructions(
"ENABLED"(),
@@ -170,13 +170,13 @@ internal val BytecodePatchContext.patchIncludedExtensionMethodMethod by gettingF
// This code appears to replace the player config after the streams are loaded.
// Flag is present in YouTube 19.34, but is missing Platypus stream replacement code until 19.43.
// Flag and Platypus code is also present in newer versions of YouTube Music.
-internal val mediaFetchHotConfigMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.mediaFetchHotConfigMethodMatch by composingFirstMethod {
instructions(45645570L())
}
// YT 20.10+, YT Music 8.11 - 8.14.
// Flag is missing in YT Music 8.15+, and it is not known if a replacement flag/feature exists.
-internal val mediaFetchHotConfigAlternativeMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.mediaFetchHotConfigAlternativeMethodMatch by composingFirstMethod {
instructions(45683169L())
}
@@ -184,7 +184,7 @@ internal val mediaFetchHotConfigAlternativeMethodMatch = firstMethodComposite {
// but its exact purpose is not known. If this flag is enabled while stream spoofing
// then videos will never start playback and load forever.
// Flag does not seem to affect playback if spoofing is off.
-internal val playbackStartDescriptorFeatureFlagMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.playbackStartDescriptorFeatureFlagMethodMatch by composingFirstMethod {
parameterTypes()
returnType("Z")
instructions(45665455L())
@@ -194,9 +194,9 @@ internal fun indexOfNewUrlRequestBuilderInstruction(method: Method) = method.ind
val reference = methodReference ?: return@indexOfFirstInstruction false
opcode == Opcode.INVOKE_VIRTUAL && reference.definingClass == "Lorg/chromium/net/CronetEngine;" &&
- reference.name == "newUrlRequestBuilder" &&
- reference.parameterTypes.size == 3 &&
- reference.parameterTypes[0] == "Ljava/lang/String;" &&
- reference.parameterTypes[1] == "Lorg/chromium/net/UrlRequest\$Callback;" &&
- reference.parameterTypes[2] == "Ljava/util/concurrent/Executor;"
+ reference.name == "newUrlRequestBuilder" &&
+ reference.parameterTypes.size == 3 &&
+ reference.parameterTypes[0] == "Ljava/lang/String;" &&
+ reference.parameterTypes[1] == "Lorg/chromium/net/UrlRequest\$Callback;" &&
+ reference.parameterTypes[2] == "Ljava/util/concurrent/Executor;"
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt
index 33944f0d9..77d4139ae 100644
--- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt
@@ -39,7 +39,7 @@ internal fun spoofVideoStreamsPatch(
block: BytecodePatchBuilder.() -> Unit,
executeBlock: BytecodePatchContext.() -> Unit = {},
) = bytecodePatch(
- name = "Spoof video streams", // TODO
+ name = "Spoof video streams",
description = "Adds options to spoof the client video streams to fix playback.",
) {
block()
@@ -64,8 +64,8 @@ internal fun spoofVideoStreamsPatch(
// region Block /initplayback requests to fall back to /get_watch requests.
- buildInitPlaybackRequestMatch.method.apply {
- val moveUriStringIndex = buildInitPlaybackRequestMatch.indices.first()
+ buildInitPlaybackRequestMethodMatch.method.apply {
+ val moveUriStringIndex = buildInitPlaybackRequestMethodMatch[0]
val targetRegister = getInstruction(moveUriStringIndex).registerA
addInstructions(
@@ -82,7 +82,7 @@ internal fun spoofVideoStreamsPatch(
// region Block /get_watch requests to fall back to /player requests.
buildPlayerRequestURIMethodMatch.method.apply {
- val invokeToStringIndex = buildPlayerRequestURIMethodMatch.indices.first()
+ val invokeToStringIndex = buildPlayerRequestURIMethodMatch[0]
val uriRegister = getInstruction(invokeToStringIndex).registerC
addInstructions(
@@ -101,7 +101,7 @@ internal fun spoofVideoStreamsPatch(
buildRequestMethodMatch.method.apply {
buildRequestMethod = this
- val newRequestBuilderIndex = buildRequestMethodMatch.indices.first()
+ val newRequestBuilderIndex = buildRequestMethodMatch[0]
buildRequestMethodUrlRegister = getInstruction(newRequestBuilderIndex).registerD
val freeRegister = findFreeRegister(newRequestBuilderIndex, buildRequestMethodUrlRegister)
@@ -121,7 +121,7 @@ internal fun spoofVideoStreamsPatch(
createStreamingDataMethodMatch.method.apply {
val setStreamDataMethodName = "patch_setStreamingData"
val resultMethodType = createStreamingDataMethodMatch.classDef.type
- val videoDetailsIndex = createStreamingDataMethodMatch.indices.last()
+ val videoDetailsIndex = createStreamingDataMethodMatch[-1]
val videoDetailsRegister = getInstruction(videoDetailsIndex).registerA
val videoDetailsClass = getInstruction(videoDetailsIndex).getReference()!!.type
@@ -132,7 +132,7 @@ internal fun spoofVideoStreamsPatch(
)
val protobufClass = protobufClassParseByteBufferMethod.definingClass
- val setStreamingDataIndex = createStreamingDataMethodMatch.indices.first()
+ val setStreamingDataIndex = createStreamingDataMethodMatch[0]
val playerProtoClass = getInstruction(setStreamingDataIndex + 1)
.getReference()!!.definingClass
@@ -260,7 +260,7 @@ internal fun spoofVideoStreamsPatch(
// region Fix iOS livestream current time.
hlsCurrentTimeMethodMatch.method.insertLiteralOverride(
- hlsCurrentTimeMethodMatch.indices.first(),
+ hlsCurrentTimeMethodMatch[0],
"$EXTENSION_CLASS_DESCRIPTOR->fixHLSCurrentTime(Z)Z",
)
@@ -270,7 +270,7 @@ internal fun spoofVideoStreamsPatch(
// If SABR is disabled, it seems 'MediaFetchHotConfig' may no longer need an override (not confirmed).
val (mediaFetchEnumClass, sabrFieldReference) = with(mediaFetchEnumConstructorMethodMatch.method) {
- val disabledBySABRStreamingUrlString = mediaFetchEnumConstructorMethodMatch.indices.last()
+ val disabledBySABRStreamingUrlString = mediaFetchEnumConstructorMethodMatch[-1]
val mediaFetchEnumClass = definingClass
val sabrFieldIndex = indexOfFirstInstructionOrThrow(disabledBySABRStreamingUrlString) {
@@ -311,21 +311,21 @@ internal fun spoofVideoStreamsPatch(
if (fixMediaFetchHotConfig()) {
mediaFetchHotConfigMethodMatch.method.insertLiteralOverride(
- mediaFetchHotConfigMethodMatch.indices.first(),
+ mediaFetchHotConfigMethodMatch[0],
"$EXTENSION_CLASS_DESCRIPTOR->useMediaFetchHotConfigReplacement(Z)Z",
)
}
if (fixMediaFetchHotConfigAlternative()) {
mediaFetchHotConfigAlternativeMethodMatch.method.insertLiteralOverride(
- mediaFetchHotConfigAlternativeMethodMatch.indices.first(),
+ mediaFetchHotConfigAlternativeMethodMatch[0],
"$EXTENSION_CLASS_DESCRIPTOR->useMediaFetchHotConfigReplacement(Z)Z",
)
}
if (fixParsePlaybackResponseFeatureFlag()) {
playbackStartDescriptorFeatureFlagMethodMatch.method.insertLiteralOverride(
- playbackStartDescriptorFeatureFlagMethodMatch.indices.first(),
+ playbackStartDescriptorFeatureFlagMethodMatch[0],
"$EXTENSION_CLASS_DESCRIPTOR->usePlaybackStartFeatureFlag(Z)Z",
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/solidexplorer2/functionality/filesize/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/solidexplorer2/functionality/filesize/Fingerprints.kt
index d53aba8a2..81992f067 100644
--- a/patches/src/main/kotlin/app/revanced/patches/solidexplorer2/functionality/filesize/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/solidexplorer2/functionality/filesize/Fingerprints.kt
@@ -1,12 +1,13 @@
package app.revanced.patches.solidexplorer2.functionality.filesize
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.definingClass
-import app.revanced.patcher.firstMethodComposite
import app.revanced.patcher.name
import app.revanced.patcher.opcodes
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
-internal val onReadyMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.onReadyMethodMatch by composingFirstMethod {
name("onReady")
definingClass("Lpl/solidexplorer/plugins/texteditor/TextEditor;")
opcodes(
diff --git a/patches/src/main/kotlin/app/revanced/patches/solidexplorer2/functionality/filesize/RemoveFileSizeLimitPatch.kt b/patches/src/main/kotlin/app/revanced/patches/solidexplorer2/functionality/filesize/RemoveFileSizeLimitPatch.kt
index d588291aa..3119eb9b4 100644
--- a/patches/src/main/kotlin/app/revanced/patches/solidexplorer2/functionality/filesize/RemoveFileSizeLimitPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/solidexplorer2/functionality/filesize/RemoveFileSizeLimitPatch.kt
@@ -14,7 +14,7 @@ val removeFileSizeLimitPatch = bytecodePatch(
apply {
onReadyMethodMatch.let {
- val cmpIndex = it.indices.first() + 1
+ val cmpIndex = it[0] + 1
val cmpResultRegister = it.method.getInstruction(cmpIndex).registerA
it.method.replaceInstruction(cmpIndex, "const/4 v$cmpResultRegister, 0x0")
diff --git a/patches/src/main/kotlin/app/revanced/patches/soundcloud/ad/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/soundcloud/ad/Fingerprints.kt
index e914de5c3..2efebb875 100644
--- a/patches/src/main/kotlin/app/revanced/patches/soundcloud/ad/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/soundcloud/ad/Fingerprints.kt
@@ -5,7 +5,7 @@ import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
-internal val interceptMethodMatch = firstMethodComposite("SC-Mob-UserPlan", "Configuration") {
+internal val BytecodePatchContext.interceptMethodMatch by composingFirstMethod("SC-Mob-UserPlan", "Configuration") {
accessFlags(AccessFlags.PUBLIC)
returnType("L")
parameterTypes("L")
diff --git a/patches/src/main/kotlin/app/revanced/patches/soundcloud/ad/HideAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/soundcloud/ad/HideAdsPatch.kt
index e1a1ed870..8364062aa 100644
--- a/patches/src/main/kotlin/app/revanced/patches/soundcloud/ad/HideAdsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/soundcloud/ad/HideAdsPatch.kt
@@ -48,7 +48,7 @@ val hideAdsPatch = bytecodePatch("Hide ads") {
// Prevent verification of an HTTP header containing the user's current plan, which would contradict the previous patch.
- val conditionIndex = interceptMethodMatch.indices.last() + 1 // TODO
+ val conditionIndex = interceptMethodMatch[-1] + 1
interceptMethodMatch.method.addInstruction(
conditionIndex,
"return-object p1",
diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Fingerprints.kt
index 8359bd7b0..065fdfa42 100644
--- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Fingerprints.kt
@@ -1,10 +1,11 @@
package app.revanced.patches.spotify.misc.extension
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
-internal val loadOrbitLibraryMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.loadOrbitLibraryMethodMatch by composingFirstMethod {
instructions(
"orbit_library_load"(),
- "orbit-jni-spotify"()
+ "orbit-jni-spotify"(),
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/strava/upselling/DisableSubscriptionSuggestionsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/strava/upselling/DisableSubscriptionSuggestionsPatch.kt
index ff22086f0..299353813 100644
--- a/patches/src/main/kotlin/app/revanced/patches/strava/upselling/DisableSubscriptionSuggestionsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/strava/upselling/DisableSubscriptionSuggestionsPatch.kt
@@ -50,7 +50,7 @@ val disableSubscriptionSuggestionsPatch = bytecodePatch("Disable subscription su
},
)
- val getModulesIndex = getModulesMethodMatch.indices.first()
+ val getModulesIndex = getModulesMethodMatch[0]
immutableMethod.removeInstruction(getModulesIndex)
immutableMethod.addInstructions(
getModulesIndex,
diff --git a/patches/src/main/kotlin/app/revanced/patches/strava/upselling/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/strava/upselling/Fingerprints.kt
index 856db0d00..2509ba981 100644
--- a/patches/src/main/kotlin/app/revanced/patches/strava/upselling/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/strava/upselling/Fingerprints.kt
@@ -1,12 +1,13 @@
package app.revanced.patches.strava.upselling
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.definingClass
-import app.revanced.patcher.firstMethodComposite
import app.revanced.patcher.name
import app.revanced.patcher.opcodes
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
-internal val getModulesMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.getModulesMethodMatch by composingFirstMethod {
name("getModules")
definingClass { endsWith("/GenericLayoutEntry;") }
opcodes(Opcode.IGET_OBJECT)
diff --git a/patches/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/Fingerprints.kt
index 80a53fe10..7ca1dc3b9 100644
--- a/patches/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/Fingerprints.kt
@@ -5,7 +5,7 @@ import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.name
import app.revanced.patcher.patch.BytecodePatchContext
-internal val BytecodePatchContext.checkLockedThemesFingerprint by gettingFirstMutableMethodDeclaratively {
+internal val BytecodePatchContext.checkLockedThemesMethod by gettingFirstMutableMethodDeclaratively {
name("isLockedTheme")
definingClass { endsWith("Theme;") }
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/UnlockThemePatch.kt b/patches/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/UnlockThemePatch.kt
index 97954126f..3a194f97a 100644
--- a/patches/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/UnlockThemePatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/UnlockThemePatch.kt
@@ -12,7 +12,7 @@ val unlockThemesPatch = bytecodePatch(
compatibleWith("com.ticktick.task")
apply {
- checkLockedThemesFingerprint.addInstructions(
+ checkLockedThemesMethod.addInstructions(
0,
"""
const/4 v0, 0x0
diff --git a/patches/src/main/kotlin/app/revanced/patches/tumblr/featureflags/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tumblr/featureflags/Fingerprints.kt
index c7797a925..cc63899cc 100644
--- a/patches/src/main/kotlin/app/revanced/patches/tumblr/featureflags/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/tumblr/featureflags/Fingerprints.kt
@@ -1,14 +1,15 @@
package app.revanced.patches.tumblr.featureflags
import app.revanced.patcher.accessFlags
-import app.revanced.patcher.firstMethodComposite
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.opcodes
import app.revanced.patcher.parameterTypes
+import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
-// This fingerprint targets the method to get the value of a Feature in the class "com.tumblr.configuration.Feature".
+// This targets the method to get the value of a Feature in the class "com.tumblr.configuration.Feature".
// Features seem to be Tumblr's A/B testing program.
// Feature states are loaded from the server in the "api-http2.tumblr.com/v2/config" request on (first) startup.
// A lot of features are returned there, but most of them do not seem to do anything (anymore).
@@ -17,7 +18,7 @@ import com.android.tools.smali.dexlib2.Opcode
// Some features seem to be very old and never removed, though, such as Google Login.
// The startIndex of the opcode pattern is at the start of the function after the arg null check.
// we want to insert our instructions there.
-internal val getFeatureValueMethodMatch = firstMethodComposite("feature") {
+internal val BytecodePatchContext.getFeatureValueMethodMatch by composingFirstMethod("feature") {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("Ljava/lang/String;")
parameterTypes("L", "Z")
diff --git a/patches/src/main/kotlin/app/revanced/patches/tumblr/featureflags/OverrideFeatureFlagsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/tumblr/featureflags/OverrideFeatureFlagsPatch.kt
index 79bcafd3c..ed5849a77 100644
--- a/patches/src/main/kotlin/app/revanced/patches/tumblr/featureflags/OverrideFeatureFlagsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/tumblr/featureflags/OverrideFeatureFlagsPatch.kt
@@ -70,7 +70,7 @@ val overrideFeatureFlagsPatch = bytecodePatch(
// This is equivalent to
// String forcedValue = getValueOverride(feature)
// if (forcedValue != null) return forcedValue
- val getFeatureIndex = match.indices.first()
+ val getFeatureIndex = match[0]
match.method.addInstructionsWithLabels(
getFeatureIndex,
"""
diff --git a/patches/src/main/kotlin/app/revanced/patches/tumblr/fixes/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tumblr/fixes/Fingerprints.kt
index 5dc2661c3..de6147c70 100644
--- a/patches/src/main/kotlin/app/revanced/patches/tumblr/fixes/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/tumblr/fixes/Fingerprints.kt
@@ -1,23 +1,23 @@
package app.revanced.patches.tumblr.fixes
-import app.revanced.patcher.firstMethodComposite
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.opcodes
import app.revanced.patcher.parameterTypes
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
-// Fingerprint for the addQueryParam method from retrofit2:
+// Matches the addQueryParam method from retrofit2:
// https://github.com/square/retrofit/blob/trunk/retrofit/src/main/java/retrofit2/RequestBuilder.java#L186.
// Injecting here allows modifying dynamically set query parameters.
internal val BytecodePatchContext.addQueryParamMethod by gettingFirstMutableMethodDeclaratively("Malformed URL. Base: ", ", Relative: ") {
parameterTypes("Ljava/lang/String;", "Ljava/lang/String;", "Z")
}
-// Fingerprint for the parseHttpMethodAndPath method from retrofit2:
+// Matches the parseHttpMethodAndPath method from retrofit2:
// https://github.com/square/retrofit/blob/ebf87b10997e2136af4d335276fa950221852c64/retrofit/src/main/java/retrofit2/RequestFactory.java#L270-L302
// Injecting here allows modifying the path/query params of API endpoints defined via annotations.
-internal val httpPathParserMethodMatch = firstMethodComposite("Only one HTTP method is allowed. Found: %s and %s.") {
+internal val BytecodePatchContext.httpPathParserMethodMatch by composingFirstMethod("Only one HTTP method is allowed. Found: %s and %s.") {
opcodes(
Opcode.IPUT_OBJECT,
Opcode.IPUT_BOOLEAN,
diff --git a/patches/src/main/kotlin/app/revanced/patches/tumblr/fixes/FixOldVersionsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/tumblr/fixes/FixOldVersionsPatch.kt
index a3e72f3d8..b6f0174f8 100644
--- a/patches/src/main/kotlin/app/revanced/patches/tumblr/fixes/FixOldVersionsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/tumblr/fixes/FixOldVersionsPatch.kt
@@ -21,7 +21,7 @@ val fixOldVersionsPatch = bytecodePatch(
// Remove the live query parameters from the path when it's specified via a @METHOD annotation.
for (liveQueryParameter in liveQueryParameters) {
httpPathParserMethodMatch.method.addInstructions(
- httpPathParserMethodMatch.indices.last() + 1,
+ httpPathParserMethodMatch[-1] + 1,
"""
# urlPath = urlPath.replace(liveQueryParameter, "")
const-string p1, "$liveQueryParameter"
diff --git a/patches/src/main/kotlin/app/revanced/patches/tumblr/timelinefilter/FilterTimelineObjectsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/tumblr/timelinefilter/FilterTimelineObjectsPatch.kt
index a108fd1b7..f61816e0d 100644
--- a/patches/src/main/kotlin/app/revanced/patches/tumblr/timelinefilter/FilterTimelineObjectsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/tumblr/timelinefilter/FilterTimelineObjectsPatch.kt
@@ -24,7 +24,7 @@ val filterTimelineObjectsPatch = bytecodePatch(
dependsOn(sharedExtensionPatch)
apply {
- val filterInsertIndex = timelineFilterExtensionMethodMatch.indices.first()
+ val filterInsertIndex = timelineFilterExtensionMethodMatch[0]
timelineFilterExtensionMethodMatch.method.apply {
val addInstruction = getInstruction(filterInsertIndex + 1)
diff --git a/patches/src/main/kotlin/app/revanced/patches/tumblr/timelinefilter/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tumblr/timelinefilter/Fingerprints.kt
index b508b0968..e98cda794 100644
--- a/patches/src/main/kotlin/app/revanced/patches/tumblr/timelinefilter/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/tumblr/timelinefilter/Fingerprints.kt
@@ -21,10 +21,10 @@ internal val BytecodePatchContext.timelineConstructorMethod by gettingFirstMutab
custom { parameters[0].type == "Ljava/util/List;" }
}
-// This fingerprints the extension TimelineFilterPatch.filterTimeline method.
-// The opcode fingerprint is searching for
+// This gets the extension method TimelineFilterPatch.filterTimeline.
+// Looking for
// if ("BLOCKED_OBJECT_DUMMY".equals(elementType)) iterator.remove();
-internal val timelineFilterExtensionMethodMatch = firstMethodComposite("BLOCKED_OBJECT_DUMMY") {
+internal val BytecodePatchContext.timelineFilterExtensionMethodMatch by composingFirstMethod("BLOCKED_OBJECT_DUMMY") {
definingClass { endsWith("/TimelineFilterPatch;") }
opcodes(
Opcode.CONST_STRING, // "BLOCKED_OBJECT_DUMMY"
diff --git a/patches/src/main/kotlin/app/revanced/patches/twitter/interaction/downloads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/twitter/interaction/downloads/Fingerprints.kt
index 15061ac17..a8fdc19d7 100644
--- a/patches/src/main/kotlin/app/revanced/patches/twitter/interaction/downloads/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/twitter/interaction/downloads/Fingerprints.kt
@@ -1,13 +1,14 @@
package app.revanced.patches.twitter.interaction.downloads
import app.revanced.patcher.accessFlags
-import app.revanced.patcher.firstMethodComposite
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.opcodes
+import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
-internal val buildMediaOptionsSheetMethodMatch = firstMethodComposite("mediaEntity", "media_options_sheet") {
+internal val BytecodePatchContext.buildMediaOptionsSheetMethodMatch by composingFirstMethod("mediaEntity", "media_options_sheet") {
opcodes(
Opcode.IF_EQ,
Opcode.SGET_OBJECT,
@@ -16,11 +17,11 @@ internal val buildMediaOptionsSheetMethodMatch = firstMethodComposite("mediaEnti
)
}
-internal val constructMediaOptionsSheetMethodMatch = firstMethodComposite("captionsState") {
+internal val BytecodePatchContext.constructMediaOptionsSheetMethodMatch by composingFirstMethod("captionsState") {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
}
-internal val showDownloadVideoUpsellBottomSheetMethodMatch = firstMethodComposite("mediaEntity", "url") {
+internal val BytecodePatchContext.showDownloadVideoUpsellBottomSheetMethodMatch by composingFirstMethod("mediaEntity", "url") {
returnType("Z")
opcodes(Opcode.IF_EQZ)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/twitter/interaction/downloads/UnlockDownloadsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/twitter/interaction/downloads/UnlockDownloadsPatch.kt
index f3134cbdc..090d42a4b 100644
--- a/patches/src/main/kotlin/app/revanced/patches/twitter/interaction/downloads/UnlockDownloadsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/twitter/interaction/downloads/UnlockDownloadsPatch.kt
@@ -1,6 +1,6 @@
package app.revanced.patches.twitter.interaction.downloads
-import app.revanced.patcher.MatchBuilder
+import app.revanced.patcher.Match
import app.revanced.patcher.extensions.*
import app.revanced.patcher.patch.bytecodePatch
import com.android.tools.smali.dexlib2.Opcode
@@ -15,14 +15,14 @@ val unlockDownloadsPatch = bytecodePatch(
compatibleWith("com.twitter.android")
apply {
- fun MatchBuilder.patch(getRegisterAndIndex: MatchBuilder.() -> Pair) {
+ fun Match.patch(getRegisterAndIndex: Match.() -> Pair) {
val (index, register) = getRegisterAndIndex()
method.addInstruction(index, "const/4 v$register, 0x1")
}
// Allow downloads for non-premium users.
showDownloadVideoUpsellBottomSheetMethodMatch.patch {
- val checkIndex = indices.first()
+ val checkIndex = showDownloadVideoUpsellBottomSheetMethodMatch[0]
val register = method.getInstruction(checkIndex).registerA
checkIndex to register
@@ -39,7 +39,7 @@ val unlockDownloadsPatch = bytecodePatch(
// Make GIFs downloadable.
buildMediaOptionsSheetMethodMatch.let {
it.method.apply {
- val checkMediaTypeIndex = it.indices.first()
+ val checkMediaTypeIndex = it[0]
val checkMediaTypeInstruction = getInstruction(checkMediaTypeIndex)
// Treat GIFs as videos.
@@ -49,7 +49,7 @@ val unlockDownloadsPatch = bytecodePatch(
const/4 v${checkMediaTypeInstruction.registerB}, 0x2 # GIF
if-eq v${checkMediaTypeInstruction.registerA}, v${checkMediaTypeInstruction.registerB}, :video
""",
- ExternalLabel("video", getInstruction(it.indices.last())),
+ ExternalLabel("video", getInstruction(it[-1])),
)
// Remove media.isDownloadable check.
diff --git a/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/HookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/HookPatch.kt
index c545379b0..e1aac1db7 100644
--- a/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/HookPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/HookPatch.kt
@@ -8,14 +8,14 @@ import app.revanced.patches.twitter.misc.hook.json.jsonHookPatch
fun hookPatch(
name: String,
hookClassDescriptor: String,
-) = bytecodePatch(name) { // TODO: NAME
+) = bytecodePatch(name) {
dependsOn(jsonHookPatch)
compatibleWith(
"com.twitter.android"(
"10.60.0-release.0",
"10.86.0-release.0",
- )
+ ),
)
apply {
diff --git a/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/Fingerprints.kt
index 6086f87a9..ec453770c 100644
--- a/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/Fingerprints.kt
@@ -1,26 +1,32 @@
package app.revanced.patches.twitter.misc.hook.json
import app.revanced.patcher.*
-import app.revanced.patcher.gettingFirstClassDef
import app.revanced.patcher.firstMutableMethodDeclaratively
+import app.revanced.patcher.gettingFirstClassDef
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.ClassDef
+import kotlin.properties.ReadOnlyProperty
-internal val jsonHookPatchMethodMatch = firstMethodComposite {
- name("")
- instructions(
- Opcode.INVOKE_INTERFACE(), // Add dummy hook to hooks list.
- // Add hooks to the hooks list.
- Opcode.INVOKE_STATIC(), // Call buildList.
- )
+internal val BytecodePatchContext.jsonHookPatchMethodMatch by ReadOnlyProperty { context, _ ->
+ context.firstClassDef(JSON_HOOK_PATCH_CLASS_DESCRIPTOR).firstMethodComposite {
+ name("")
+ instructions(
+ Opcode.INVOKE_INTERFACE(), // Add dummy hook to hooks list.
+ // Add hooks to the hooks list.
+ Opcode.INVOKE_STATIC(), // Call buildList.
+ )
+ }
}
context(_: BytecodePatchContext)
internal fun ClassDef.getJsonInputStreamMethod() = firstMutableMethodDeclaratively {
custom {
- if (parameterTypes.isEmpty()) false
- else parameterTypes.first() == "Ljava/io/InputStream;"
+ if (parameterTypes.isEmpty()) {
+ false
+ } else {
+ parameterTypes.first() == "Ljava/io/InputStream;"
+ }
}
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/JsonHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/JsonHookPatch.kt
index 12aaeccd6..dc0b7cfbe 100644
--- a/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/JsonHookPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/JsonHookPatch.kt
@@ -1,8 +1,8 @@
package app.revanced.patches.twitter.misc.hook.json
-import app.revanced.patcher.firstClassDef
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.removeInstructions
+import app.revanced.patcher.firstClassDef
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.bytecodePatch
@@ -21,7 +21,7 @@ fun BytecodePatchContext.addJsonHook(
if (jsonHook.added) return
// Insert hooks right before calling buildList.
- val insertIndex = jsonHookPatchMethodMatch.indices.last()
+ val insertIndex = jsonHookPatchMethodMatch[-1]
jsonHookPatchMethodMatch.method.addInstructions(
insertIndex,
@@ -35,7 +35,7 @@ fun BytecodePatchContext.addJsonHook(
}
private const val JSON_HOOK_CLASS_NAMESPACE = "app/revanced/extension/twitter/patches/hook/json"
-private const val JSON_HOOK_PATCH_CLASS_DESCRIPTOR = "L$JSON_HOOK_CLASS_NAMESPACE/JsonHookPatch;"
+internal const val JSON_HOOK_PATCH_CLASS_DESCRIPTOR = "L$JSON_HOOK_CLASS_NAMESPACE/JsonHookPatch;"
private const val BASE_PATCH_CLASS_NAME = "BaseJsonHook"
private const val JSON_HOOK_CLASS_DESCRIPTOR = "L$JSON_HOOK_CLASS_NAMESPACE/$BASE_PATCH_CLASS_NAME;"
@@ -45,10 +45,8 @@ val jsonHookPatch = bytecodePatch(
dependsOn(sharedExtensionPatch)
apply {
- jsonHookPatchMethodMatch.apply {
- match(firstClassDef(JSON_HOOK_PATCH_CLASS_DESCRIPTOR)).methodOrNull
- ?: throw PatchException("Unexpected extension.")
- }
+ jsonHookPatchMethodMatch.methodOrNull
+ ?: throw PatchException("Unexpected extension.")
val jsonFactoryClassDef =
loganSquareClassDef // Conveniently find the type to hook a method in, via a named field.
@@ -70,13 +68,12 @@ val jsonHookPatch = bytecodePatch(
afterDependents {
// Remove hooks.add(dummyHook).
- val addDummyHookIndex = jsonHookPatchMethodMatch.indices.last()
+ val addDummyHookIndex = jsonHookPatchMethodMatch[-1]
jsonHookPatchMethodMatch.method.removeInstructions(addDummyHookIndex, 2)
}
}
-
class JsonHook internal constructor(
internal val descriptor: String,
) {
@@ -91,9 +88,9 @@ class JsonHook internal constructor(
* @param descriptor The class descriptor of the hook.
* @throws ClassNotFoundException If the class could not be found.
*/
-context(_: BytecodePatchContext)
+context(context: BytecodePatchContext)
fun jsonHook(descriptor: String): JsonHook {
- firstClassDef(descriptor).let {
+ context.firstClassDef(descriptor).let {
it.also { classDef ->
if (
classDef.superclass != JSON_HOOK_CLASS_DESCRIPTOR ||
@@ -105,4 +102,4 @@ fun jsonHook(descriptor: String): JsonHook {
}
return JsonHook(JSON_HOOK_CLASS_DESCRIPTOR)
-}
\ No newline at end of file
+}
diff --git a/patches/src/main/kotlin/app/revanced/patches/viber/ads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/viber/ads/Fingerprints.kt
index 134279d9a..7274ec124 100644
--- a/patches/src/main/kotlin/app/revanced/patches/viber/ads/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/viber/ads/Fingerprints.kt
@@ -1,11 +1,12 @@
package app.revanced.patches.viber.ads
-import app.revanced.patcher.firstMethodComposite
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.instructions
import app.revanced.patcher.invoke
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
-internal val findAdStringMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.findAdStringMethodMatch by composingFirstMethod {
instructions(
Opcode.NEW_INSTANCE(),
"viber_plus_debug_ads_free_flag"(),
diff --git a/patches/src/main/kotlin/app/revanced/patches/viber/ads/HideAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/viber/ads/HideAdsPatch.kt
index b6bb5deba..9a3216891 100644
--- a/patches/src/main/kotlin/app/revanced/patches/viber/ads/HideAdsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/viber/ads/HideAdsPatch.kt
@@ -18,12 +18,12 @@ val hideAdsPatch = bytecodePatch(
compatibleWith("com.viber.voip"("25.9.2.0", "26.1.2.0"))
apply {
- val referenceIndex = findAdStringMethodMatch.indices.first()
+ val referenceIndex = findAdStringMethodMatch[0]
val targetClass =
findAdStringMethodMatch.immutableMethod.getInstruction(referenceIndex).typeReference
- val adFreeFingerprint = firstMutableMethodDeclaratively {
+ val adFreeMethod = firstMutableMethodDeclaratively {
definingClass(targetClass!!.type)
returnType("I")
parameterTypes()
diff --git a/patches/src/main/kotlin/app/revanced/patches/willhaben/ads/HideAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/willhaben/ads/HideAdsPatch.kt
index 1213b4bf9..3f3c36699 100644
--- a/patches/src/main/kotlin/app/revanced/patches/willhaben/ads/HideAdsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/willhaben/ads/HideAdsPatch.kt
@@ -11,7 +11,7 @@ val hideAdsPatch = bytecodePatch(
compatibleWith("at.willhaben")
apply {
- adResolverMethod.returnEarly() // TODO
+ adResolverMethod.returnEarly()
whAdViewInjectorMethod.returnEarly()
}
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/Fingerprints.kt
index 16e2f6244..b8ce3bbb2 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/Fingerprints.kt
@@ -1,10 +1,11 @@
package app.revanced.patches.youtube.ad.getpremium
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
-internal val getPremiumViewMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.getPremiumViewMethodMatch by composingFirstMethod {
name("onMeasure")
definingClass("Lcom/google/android/apps/youtube/app/red/presenter/CompactYpcOfferModuleView;")
accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt
index aadb87f97..3b1954220 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt
@@ -40,7 +40,7 @@ val hideGetPremiumPatch = bytecodePatch(
)
getPremiumViewMethodMatch.let {
- val startIndex = it.indices.first()
+ val startIndex = it[0]
val measuredWidthRegister = it.method.getInstruction(startIndex).registerA
val measuredHeightInstruction = it.method.getInstruction(startIndex + 1)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/Fingerprints.kt
index f022f7ab8..fa5c83ebe 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/Fingerprints.kt
@@ -1,8 +1,9 @@
package app.revanced.patches.youtube.interaction.dialog
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
-internal val createDialogMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.createDialogMethodMatch by composingFirstMethod {
returnType("V")
parameterTypes("L", "L", "Ljava/lang/String;")
instructions(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt
index a0da1ff73..c0d7e173e 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt
@@ -44,7 +44,7 @@ val removeViewerDiscretionDialogPatch = bytecodePatch(
createDialogMethodMatch.let {
it.method.apply {
- val showDialogIndex = it.indices.last()
+ val showDialogIndex = it[-1]
val dialogRegister = getInstruction(showDialogIndex).registerC
replaceInstructions(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt
index a454d9dba..c3e867c49 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt
@@ -39,13 +39,13 @@ val enableSeekbarTappingPatch = bytecodePatch(
.reference as MethodReference
listOf(
- getReference(it.indices.first()),
- getReference(it.indices.last()),
+ getReference(it[0]),
+ getReference(it[-1]),
)
}
seekbarTappingMethodMatch.let {
- val insertIndex = it.indices.last() + 1
+ val insertIndex = it[-1] + 1
it.method.apply {
val thisInstanceRegister = getInstruction(
@@ -53,7 +53,7 @@ val enableSeekbarTappingPatch = bytecodePatch(
).registerC
val xAxisRegister = this.getInstruction(
- it.indices[2],
+ it[2],
).registerD
val freeRegister = findFreeRegister(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSlideToSeekPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSlideToSeekPatch.kt
index 28ac4dce5..ceefafbb9 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSlideToSeekPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSlideToSeekPatch.kt
@@ -43,7 +43,7 @@ val enableSlideToSeekPatch = bytecodePatch(
// Restore the behaviour to slide to seek.
- val checkIndex = slideToSeekMethodMatch.indices.first()
+ val checkIndex = slideToSeekMethodMatch[0]
val checkReference = slideToSeekMethodMatch.method.getInstruction(checkIndex)
.getReference()!!
@@ -76,7 +76,7 @@ val enableSlideToSeekPatch = bytecodePatch(
if (is_19_17_or_greater) {
disableFastForwardGestureMethodMatch.let {
it.method.apply {
- val targetIndex = it.indices.last()
+ val targetIndex = it[-1]
val targetRegister = getInstruction(targetIndex).registerA
addInstructions(
@@ -91,7 +91,7 @@ val enableSlideToSeekPatch = bytecodePatch(
} else {
disableFastForwardLegacyMethodMatch.let {
it.method.apply {
- val insertIndex = it.indices.last() + 1
+ val insertIndex = it[-1] + 1
val targetRegister = getInstruction(insertIndex).registerA
addInstructions(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/Fingerprints.kt
index 84104d894..c9fe13ba8 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/Fingerprints.kt
@@ -40,7 +40,7 @@ internal fun ClassDef.getAllowSwipingUpGestureMethod() = firstMutableMethodDecla
parameterTypes("L")
}
-internal val disableFastForwardLegacyMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.disableFastForwardLegacyMethodMatch by composingFirstMethod {
returnType("Z")
parameterTypes()
opcodes(Opcode.MOVE_RESULT)
@@ -48,7 +48,7 @@ internal val disableFastForwardLegacyMethodMatch = firstMethodComposite {
literal { 45411330 }
}
-internal val disableFastForwardGestureMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.disableFastForwardGestureMethodMatch by composingFirstMethod {
definingClass { endsWith("/NextGenWatchLayout;") }
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("Z")
@@ -61,7 +61,7 @@ internal val disableFastForwardGestureMethodMatch = firstMethodComposite {
custom { instructions.count() > 30 }
}
-internal val customTapAndHoldMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.customTapAndHoldMethodMatch by composingFirstMethod {
name("run")
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
@@ -80,7 +80,7 @@ internal val customTapAndHoldMethodMatch = firstMethodComposite {
}
}
-internal val onTouchEventHandlerMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.onTouchEventHandlerMethodMatch by composingFirstMethod {
name("onTouchEvent")
accessFlags(AccessFlags.PUBLIC, AccessFlags.PUBLIC)
returnType("Z")
@@ -103,7 +103,7 @@ internal val onTouchEventHandlerMethodMatch = firstMethodComposite {
)
}
-internal val seekbarTappingMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.seekbarTappingMethodMatch by composingFirstMethod {
name("onTouchEvent")
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("Z")
@@ -119,7 +119,7 @@ internal val seekbarTappingMethodMatch = firstMethodComposite {
)
}
-internal val slideToSeekMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.slideToSeekMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL)
returnType("V")
parameterTypes("Landroid/view/View;", "F")
@@ -141,7 +141,7 @@ internal val BytecodePatchContext.fullscreenSeekbarThumbnailsQualityMethod by ge
)
}
-internal val fullscreenLargeSeekbarFeatureFlagMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.fullscreenLargeSeekbarFeatureFlagMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("Z")
parameterTypes()
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/HideSeekbarPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/HideSeekbarPatch.kt
index bd9af7f2c..47b69d8b3 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/HideSeekbarPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/HideSeekbarPatch.kt
@@ -12,8 +12,8 @@ import app.revanced.patches.youtube.misc.playservice.is_20_28_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
-import app.revanced.patches.youtube.shared.getSeekbarOnDrawMethodMatch
import app.revanced.patches.youtube.shared.seekbarMethod
+import app.revanced.patches.youtube.shared.seekbarOnDrawMethodMatch
import app.revanced.util.insertLiteralOverride
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/HideSeekbarPatch;"
@@ -38,7 +38,7 @@ val hideSeekbarPatch = bytecodePatch(
SwitchPreference("revanced_fullscreen_large_seekbar"),
)
- getSeekbarOnDrawMethodMatch().match(seekbarMethod.immutableClassDef).method.addInstructionsWithLabels(
+ seekbarMethod.immutableClassDef.seekbarOnDrawMethodMatch.method.addInstructionsWithLabels(
0,
"""
const/4 v0, 0x0
@@ -54,7 +54,7 @@ val hideSeekbarPatch = bytecodePatch(
if (is_20_28_or_greater) {
fullscreenLargeSeekbarFeatureFlagMethodMatch.let {
it.method.insertLiteralOverride(
- it.indices.first(),
+ it[0],
"$EXTENSION_CLASS_DESCRIPTOR->useFullscreenLargeSeekbar(Z)Z",
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/Fingerprints.kt
index 1a2cd2379..d65723084 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/Fingerprints.kt
@@ -1,8 +1,8 @@
package app.revanced.patches.youtube.interaction.swipecontrols
import app.revanced.patcher.accessFlags
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.definingClass
-import app.revanced.patcher.firstMethodComposite
import app.revanced.patcher.gettingFirstMethodDeclaratively
import app.revanced.patcher.instructions
import app.revanced.patcher.invoke
@@ -16,7 +16,7 @@ internal val BytecodePatchContext.swipeControlsHostActivityMethod by gettingFirs
parameterTypes()
}
-internal val swipeChangeVideoMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.swipeChangeVideoMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
instructions(
45631116L(), // Swipe to change fullscreen video feature flag.
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsPatch.kt
index cd86a260d..6c49c6161 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsPatch.kt
@@ -138,7 +138,7 @@ val swipeControlsPatch = bytecodePatch(
if (is_19_43_or_greater && !is_20_34_or_greater) {
swipeChangeVideoMethodMatch.let {
it.method.insertLiteralOverride(
- it.indices.last(),
+ it[-1],
"$EXTENSION_CLASS_DESCRIPTOR->allowSwipeChangeVideo(Z)Z",
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/Fingerprints.kt
index 03c2a9cdc..35d51ba01 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/Fingerprints.kt
@@ -1,10 +1,11 @@
package app.revanced.patches.youtube.layout.buttons.navigation
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
-internal val addCreateButtonViewMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.addCreateButtonViewMethodMatch by composingFirstMethod {
instructions(
"Android Wear"(),
Opcode.IF_EQZ(),
@@ -12,7 +13,7 @@ internal val addCreateButtonViewMethodMatch = firstMethodComposite {
)
}
-internal val createPivotBarMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.createPivotBarMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
parameterTypes(
"Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;",
@@ -25,7 +26,7 @@ internal val createPivotBarMethodMatch = firstMethodComposite {
)
}
-internal val animatedNavigationTabsFeatureFlagMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.animatedNavigationTabsFeatureFlagMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("Z")
instructions(
@@ -33,7 +34,7 @@ internal val animatedNavigationTabsFeatureFlagMethodMatch = firstMethodComposite
)
}
-internal val translucentNavigationStatusBarFeatureFlagMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.translucentNavigationStatusBarFeatureFlagMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("Z")
instructions(
@@ -44,7 +45,7 @@ internal val translucentNavigationStatusBarFeatureFlagMethodMatch = firstMethodC
/**
* YouTube nav buttons.
*/
-internal val translucentNavigationButtonsFeatureFlagMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.translucentNavigationButtonsFeatureFlagMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
instructions(
@@ -55,7 +56,7 @@ internal val translucentNavigationButtonsFeatureFlagMethodMatch = firstMethodCom
/**
* Device on screen back/home/recent buttons.
*/
-internal val translucentNavigationButtonsSystemFeatureFlagMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.translucentNavigationButtonsSystemFeatureFlagMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("Z")
instructions(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
index 133acf38b..230db65c6 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
@@ -84,7 +84,7 @@ val navigationButtonsPatch = bytecodePatch(
// Switch create with notifications button.
addCreateButtonViewMethodMatch.method.apply {
- val conditionalCheckIndex = addCreateButtonViewMethodMatch.indices[1]
+ val conditionalCheckIndex = addCreateButtonViewMethodMatch[1]
val conditionRegister =
getInstruction(conditionalCheckIndex).registerA
@@ -100,7 +100,7 @@ val navigationButtonsPatch = bytecodePatch(
// Hide navigation button labels.
createPivotBarMethodMatch.let {
it.method.apply {
- val setTextIndex = it.indices.first()
+ val setTextIndex = it[0]
val targetRegister = getInstruction(setTextIndex).registerC
addInstruction(
@@ -118,21 +118,21 @@ val navigationButtonsPatch = bytecodePatch(
if (is_19_25_or_greater) {
translucentNavigationStatusBarFeatureFlagMethodMatch.let {
it.method.insertLiteralOverride(
- it.indices.first(),
+ it[0],
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationStatusBar(Z)Z",
)
}
translucentNavigationButtonsFeatureFlagMethodMatch.let {
it.method.insertLiteralOverride(
- it.indices.first(),
+ it[0],
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z",
)
}
translucentNavigationButtonsSystemFeatureFlagMethodMatch.let {
it.method.insertLiteralOverride(
- it.indices.first(),
+ it[0],
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z",
)
}
@@ -141,7 +141,7 @@ val navigationButtonsPatch = bytecodePatch(
if (is_20_15_or_greater) {
animatedNavigationTabsFeatureFlagMethodMatch.let {
it.method.insertLiteralOverride(
- it.indices.first(),
+ it[0],
"$EXTENSION_CLASS_DESCRIPTOR->useAnimatedNavigationButtons(Z)Z",
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/Fingerprints.kt
index 2002497b8..82e07852e 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/Fingerprints.kt
@@ -11,17 +11,17 @@ internal val BytecodePatchContext.mediaRouteButtonMethod by gettingFirstMutableM
parameterTypes("I")
}
-internal val castButtonPlayerFeatureFlagMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.castButtonPlayerFeatureFlagMethodMatch by composingFirstMethod {
returnType("Z")
instructions(45690091L())
}
-internal val castButtonActionFeatureFlagMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.castButtonActionFeatureFlagMethodMatch by composingFirstMethod {
returnType("Z")
instructions(45690090L())
}
-internal val inflateControlsGroupLayoutStubMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.inflateControlsGroupLayoutStubMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
parameterTypes()
returnType("V")
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch.kt
index 596909c96..4039e8a7c 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch.kt
@@ -32,7 +32,7 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
sharedExtensionPatch,
settingsPatch,
addResourcesPatch,
- resourceMappingPatch, // Used by fingerprints.
+ resourceMappingPatch, // Used for finding methods.
versionCheckPatch,
)
@@ -59,7 +59,7 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
// region Hide player next/previous button.
getLayoutConstructorMethodMatch().let {
- val insertIndex = it.indices.last()
+ val insertIndex = it[-1]
val viewRegister = it.method.getInstruction(insertIndex).registerC
it.method.addInstruction(
@@ -87,7 +87,7 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
castButtonActionFeatureFlagMethodMatch,
).forEach { match ->
match.method.insertLiteralOverride(
- match.indices.first(),
+ match[0],
"$EXTENSION_CLASS_DESCRIPTOR->getCastButtonOverrideV2(Z)Z",
)
}
@@ -139,7 +139,7 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
inflateControlsGroupLayoutStubMethodMatch.let {
it.method.apply {
- val insertIndex = it.indices.last() + 1
+ val insertIndex = it[-1] + 1
val freeRegister = findFreeRegister(insertIndex)
addInstructions(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/ChangeFormFactorPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/ChangeFormFactorPatch.kt
index f0209b0ed..e4a5d1d1a 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/ChangeFormFactorPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/ChangeFormFactorPatch.kt
@@ -61,7 +61,7 @@ val changeFormFactorPatch = bytecodePatch(
createPlayerRequestBodyWithModelMatch.let {
it.method.apply {
- val index = it.indices.last()
+ val index = it[-1]
val register = getInstruction(index).registerA
addInstructions(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/Fingerprints.kt
index 7b716ff75..2088a2cf7 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/Fingerprints.kt
@@ -10,7 +10,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
-internal val layoutCircleMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.layoutCircleMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
parameterTypes()
returnType("Landroid/view/View;")
@@ -24,7 +24,7 @@ internal val layoutCircleMethodMatch = firstMethodComposite {
literal { layoutCircle }
}
-internal val layoutIconMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.layoutIconMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
parameterTypes()
returnType("Landroid/view/View;")
@@ -37,7 +37,7 @@ internal val layoutIconMethodMatch = firstMethodComposite {
literal { layoutIcon }
}
-internal val layoutVideoMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.layoutVideoMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC)
parameterTypes()
returnType("Landroid/view/View;")
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndScreenCardsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndScreenCardsPatch.kt
index 7cc8a67ec..ca2fca5c3 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndScreenCardsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndScreenCardsPatch.kt
@@ -76,7 +76,7 @@ val hideEndScreenCardsPatch = bytecodePatch(
layoutVideoMethodMatch,
).forEach { match ->
match.method.apply {
- val insertIndex = match.indices.last() + 1
+ val insertIndex = match[-1] + 1
val viewRegister = getInstruction(insertIndex - 1).registerA
addInstruction(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreensuggestion/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreensuggestion/Fingerprints.kt
index 4fdf367e7..99233409b 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreensuggestion/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreensuggestion/Fingerprints.kt
@@ -20,7 +20,7 @@ internal fun ClassDef.getAutoNavStatusMethod() = firstMutableMethodDeclaratively
parameterTypes()
}
-internal val removeOnLayoutChangeListenerMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.removeOnLayoutChangeListenerMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes()
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreensuggestion/HideEndScreenSuggestedVideoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreensuggestion/HideEndScreenSuggestedVideoPatch.kt
index 631deb20d..979621b5e 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreensuggestion/HideEndScreenSuggestedVideoPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreensuggestion/HideEndScreenSuggestedVideoPatch.kt
@@ -46,7 +46,7 @@ val hideEndScreenSuggestedVideoPatch = bytecodePatch(
)
removeOnLayoutChangeListenerMethodMatch.let {
- val endScreenMethod = navigate(it.immutableMethod).to(it.indices.last()).stop() // TODO
+ val endScreenMethod = navigate(it.immutableMethod).to(it[-1]).stop()
endScreenMethod.apply {
val autoNavStatusMethodName = autoNavConstructorMethod.immutableClassDef.getAutoNavStatusMethod().name
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/Fingerprints.kt
index 837eacbea..d687e7155 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/Fingerprints.kt
@@ -12,7 +12,7 @@ import com.android.tools.smali.dexlib2.iface.ClassDef
/**
* 20.26+
*/
-internal val hideShowMoreButtonMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.hideShowMoreButtonMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL, AccessFlags.SYNTHETIC)
returnType("V")
parameterTypes("L", "Ljava/lang/Object;")
@@ -23,7 +23,7 @@ internal val hideShowMoreButtonMethodMatch = firstMethodComposite {
)
}
-internal val hideShowMoreLegacyButtonMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.hideShowMoreLegacyButtonMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
instructions(
ResourceType.LAYOUT("expand_button_down"),
@@ -32,7 +32,7 @@ internal val hideShowMoreLegacyButtonMethodMatch = firstMethodComposite {
)
}
-internal val parseElementFromBufferMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.parseElementFromBufferMethodMatch by composingFirstMethod {
parameterTypes("L", "L", "[B", "L", "L")
instructions(
Opcode.IGET_OBJECT(),
@@ -68,7 +68,7 @@ internal val BytecodePatchContext.yoodlesImageViewMethod by gettingFirstMutableM
instructions(ResourceType.ID("youtube_logo"))
}
-internal val crowdfundingBoxMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.crowdfundingBoxMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
opcodes(
Opcode.INVOKE_VIRTUAL,
@@ -78,7 +78,7 @@ internal val crowdfundingBoxMethodMatch = firstMethodComposite {
literal { crowdfundingBoxId }
}
-internal val albumCardsMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.albumCardsMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
opcodes(
Opcode.MOVE_RESULT_OBJECT,
@@ -91,7 +91,7 @@ internal val albumCardsMethodMatch = firstMethodComposite {
literal { albumCardId }
}
-internal val filterBarHeightMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.filterBarHeightMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
opcodes(
Opcode.CONST,
@@ -102,7 +102,7 @@ internal val filterBarHeightMethodMatch = firstMethodComposite {
literal { filterBarHeightId }
}
-internal val relatedChipCloudMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.relatedChipCloudMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
opcodes(
Opcode.CONST,
@@ -112,7 +112,7 @@ internal val relatedChipCloudMethodMatch = firstMethodComposite {
literal { relatedChipCloudMarginId }
}
-internal val searchResultsChipBarMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.searchResultsChipBarMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
opcodes(
Opcode.CONST,
@@ -124,7 +124,7 @@ internal val searchResultsChipBarMethodMatch = firstMethodComposite {
literal { barContainerHeightId }
}
-internal val showFloatingMicrophoneButtonMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.showFloatingMicrophoneButtonMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes()
@@ -135,7 +135,7 @@ internal val showFloatingMicrophoneButtonMethodMatch = firstMethodComposite {
)
}
-internal val hideViewCountMethodMatch = firstMethodComposite(
+internal val BytecodePatchContext.hideViewCountMethodMatch by composingFirstMethod(
"Has attachmentRuns but drawableRequester is missing.",
) {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
index 592625c63..c0183d365 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
@@ -1,6 +1,6 @@
package app.revanced.patches.youtube.layout.hide.general
-import app.revanced.patcher.MatchBuilder
+import app.revanced.patcher.Match
import app.revanced.patcher.extensions.*
import app.revanced.patcher.immutableClassDef
import app.revanced.patcher.patch.bytecodePatch
@@ -230,7 +230,7 @@ val hideLayoutComponentsPatch = bytecodePatch(
parseElementFromBufferMethodMatch.let {
it.method.apply {
- val startIndex = it.indices.first()
+ val startIndex = it[0]
val insertIndex = startIndex + 1
val byteArrayParameter = "p3"
@@ -280,7 +280,7 @@ val hideLayoutComponentsPatch = bytecodePatch(
(if (is_20_26_or_greater) hideShowMoreButtonMethodMatch else hideShowMoreLegacyButtonMethodMatch).let {
it.method.apply {
- val moveRegisterIndex = it.indices.last()
+ val moveRegisterIndex = it[-1]
val viewRegister = getInstruction(moveRegisterIndex).registerA
val insertIndex = moveRegisterIndex + 1
@@ -297,7 +297,7 @@ val hideLayoutComponentsPatch = bytecodePatch(
// region crowdfunding box
crowdfundingBoxMethodMatch.let {
it.method.apply {
- val insertIndex = it.indices.last()
+ val insertIndex = it[-1]
val objectRegister = getInstruction(insertIndex).registerA
addInstruction(
@@ -314,7 +314,7 @@ val hideLayoutComponentsPatch = bytecodePatch(
albumCardsMethodMatch.let {
it.method.apply {
- val checkCastAnchorIndex = it.indices.last()
+ val checkCastAnchorIndex = it[-1]
val insertIndex = checkCastAnchorIndex + 1
val register = getInstruction(checkCastAnchorIndex).registerA
@@ -332,7 +332,7 @@ val hideLayoutComponentsPatch = bytecodePatch(
showFloatingMicrophoneButtonMethodMatch.let {
it.method.apply {
- val index = it.indices.last()
+ val index = it[-1]
val register = getInstruction(index).registerA
addInstructions(
@@ -369,7 +369,7 @@ val hideLayoutComponentsPatch = bytecodePatch(
// region hide view count
hideViewCountMethodMatch.method.apply {
- val startIndex = hideViewCountMethodMatch.indices.first()
+ val startIndex = hideViewCountMethodMatch[0]
var returnStringRegister = getInstruction(startIndex).registerA
// Find the instruction where the text dimension is retrieved.
@@ -404,16 +404,16 @@ val hideLayoutComponentsPatch = bytecodePatch(
* Patch a [Method] with a given [instructions].
*
* @param RegisterInstruction The type of instruction to get the register from.
- * @param insertIndexOffset The offset to add to the end index of the [MatchBuilder.indices].
+ * @param insertIndexOffset The offset to add to the end index of the [Match.indices].
* @param hookRegisterOffset The offset to add to the register of the hook.
* @param instructions The instructions to add with the register as a parameter.
*/
- fun MatchBuilder.patch(
+ fun Match.patch(
insertIndexOffset: Int = 0,
hookRegisterOffset: Int = 0,
instructions: (Int) -> String,
) = method.apply {
- val endIndex = indices.last()
+ val endIndex = get(-1)
val insertIndex = endIndex + insertIndexOffset
val register = getInstruction(endIndex + hookRegisterOffset).registerA
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/Fingerprints.kt
index 0fe436f65..a5c135e39 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/Fingerprints.kt
@@ -23,8 +23,8 @@ internal val BytecodePatchContext.infocardsIncognitoParentMethod by gettingFirst
)
}
-internal val infocardsMethodCallMethodMatch =
- firstMethodComposite("Missing ControlsOverlayPresenter for InfoCards to work.") {
+internal val BytecodePatchContext.infocardsMethodCallMethodMatch by
+ composingFirstMethod("Missing ControlsOverlayPresenter for InfoCards to work.") {
opcodes(
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt
index da6b00d15..cb9b30f8b 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt
@@ -77,7 +77,7 @@ val hideInfoCardsPatch = bytecodePatch(
// Edit: This old non litho code may be obsolete and no longer used by any supported versions.
infocardsMethodCallMethodMatch.let {
- val invokeInterfaceIndex = it.indices.last()
+ val invokeInterfaceIndex = it[-1]
it.method.apply {
val register = implementation!!.registerCount - 1
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt
index 13812c922..0372dfb2e 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt
@@ -47,8 +47,8 @@ val disableRollingNumberAnimationsPatch = bytecodePatch(
// Animations are disabled by preventing an Image from being applied to the text span,
// which prevents the animations from appearing.
rollingNumberTextViewAnimationUpdateMethodMatch.let {
- val blockStartIndex = it.indices.first()
- val blockEndIndex = it.indices.last() + 1
+ val blockStartIndex = it[0]
+ val blockEndIndex = it[-1] + 1
it.method.apply {
val freeRegister = getInstruction(blockStartIndex).registerA
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/Fingerprints.kt
index 9ef8624f1..3076ced8d 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/Fingerprints.kt
@@ -7,7 +7,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.ClassDef
-internal val shortsBottomBarContainerMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.shortsBottomBarContainerMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes("Landroid/view/View;", "Landroid/os/Bundle;")
@@ -91,7 +91,7 @@ internal val BytecodePatchContext.renderBottomNavigationBarParentMethod by getti
)
}
-internal val setPivotBarVisibilityMethodMatch = firstMethodComposite {
+internal val ClassDef.setPivotBarVisibilityMethodMatch by ClassDefComposing.composingFirstMethod {
accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL)
returnType("V")
parameterTypes("Z")
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt
index 5352e91a4..111d2dfd4 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt
@@ -211,9 +211,9 @@ val hideShortsComponentsPatch = bytecodePatch(
// region Hide the navigation bar.
// Hook to get the pivotBar view.
- setPivotBarVisibilityMethodMatch.match(setPivotBarVisibilityParentMethod.immutableClassDef).let { match ->
+ setPivotBarVisibilityParentMethod.immutableClassDef.setPivotBarVisibilityMethodMatch.let { match ->
match.method.apply {
- val insertIndex = match.indices.last()
+ val insertIndex = match[-1]
val viewRegister = getInstruction(insertIndex - 1).registerA
addInstruction(
insertIndex,
@@ -240,7 +240,7 @@ val hideShortsComponentsPatch = bytecodePatch(
// Hide the bottom bar container of the Shorts player.
shortsBottomBarContainerMethodMatch.let {
it.method.apply {
- val targetIndex = it.indices.last()
+ val targetIndex = it[-1]
val heightRegister = getInstruction(targetIndex).registerA
addInstructions(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/Fingerprints.kt
index d5c103bb0..203b87f06 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/Fingerprints.kt
@@ -3,6 +3,7 @@
package app.revanced.patches.youtube.layout.miniplayer
import app.revanced.patcher.*
+import app.revanced.patcher.ClassDefComposing
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patches.shared.misc.mapping.ResourceType
import com.android.tools.smali.dexlib2.AccessFlags
@@ -59,7 +60,7 @@ internal fun ClassDef.getMiniplayerModernAddViewListenerMethod() = firstMutableM
/**
* Matches using the class found in [miniplayerModernViewParentMethod].
*/
-internal val miniplayerModernCloseButtonMethodMatch = firstMethodComposite {
+internal val ClassDef.miniplayerModernCloseButtonMethodMatch by ClassDefComposing.composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("L")
parameterTypes()
@@ -72,7 +73,7 @@ internal val miniplayerModernCloseButtonMethodMatch = firstMethodComposite {
/**
* Matches using the class found in [miniplayerModernViewParentMethod].
*/
-internal val miniplayerModernExpandButtonMethodMatch = firstMethodComposite {
+internal val ClassDef.miniplayerModernExpandButtonMethodMatch by ClassDefComposing.composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("L")
parameterTypes()
@@ -98,7 +99,7 @@ internal fun ClassDef.getMiniplayerModernExpandCloseDrawablesMethod() = firstMut
/**
* Matches using the class found in [miniplayerModernViewParentMethod].
*/
-internal val miniplayerModernForwardButtonMethodMatch = firstMethodComposite {
+internal val ClassDef.miniplayerModernForwardButtonMethodMatch by ClassDefComposing.composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("L")
parameterTypes()
@@ -108,7 +109,7 @@ internal val miniplayerModernForwardButtonMethodMatch = firstMethodComposite {
)
}
-internal val miniplayerModernOverlayViewMethodMatch = firstMethodComposite {
+internal val ClassDef.miniplayerModernOverlayViewMethodMatch by ClassDefComposing.composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
parameterTypes()
instructions(
@@ -120,7 +121,7 @@ internal val miniplayerModernOverlayViewMethodMatch = firstMethodComposite {
/**
* Matches using the class found in [miniplayerModernViewParentMethod].
*/
-internal val miniplayerModernRewindButtonMethodMatch = firstMethodComposite {
+internal val ClassDef.miniplayerModernRewindButtonMethodMatch by ClassDefComposing.composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("L")
parameterTypes()
@@ -133,7 +134,7 @@ internal val miniplayerModernRewindButtonMethodMatch = firstMethodComposite {
/**
* Matches using the class found in [miniplayerModernViewParentMethod].
*/
-internal val miniplayerModernActionButtonMethodMatch = firstMethodComposite {
+internal val ClassDef.miniplayerModernActionButtonMethodMatch by ClassDefComposing.composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("L")
parameterTypes()
@@ -143,7 +144,7 @@ internal val miniplayerModernActionButtonMethodMatch = firstMethodComposite {
)
}
-internal val miniplayerMinimumSizeMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.miniplayerMinimumSizeMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
instructions(
ResourceType.DIMEN("miniplayer_max_size"),
@@ -152,7 +153,7 @@ internal val miniplayerMinimumSizeMethodMatch = firstMethodComposite {
)
}
-internal val miniplayerOverrideMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.miniplayerOverrideMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("L")
instructions(
@@ -176,7 +177,7 @@ internal fun ClassDef.getMiniplayerOverrideNoContextMethod() = firstMutableMetho
/**
* 20.36 and lower. Codes appears to be removed in 20.37+
*/
-internal val miniplayerResponseModelSizeCheckMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.miniplayerResponseModelSizeCheckMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("L")
parameterTypes("Ljava/lang/Object;", "Ljava/lang/Object;")
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt
index d1fa8a77a..e17b39353 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt
@@ -25,6 +25,7 @@ import app.revanced.util.*
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
+import com.android.tools.smali.dexlib2.iface.ClassDef
import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
@@ -235,7 +236,7 @@ val Miniplayer = bytecodePatch(
// region Legacy tablet miniplayer hooks.
miniplayerOverrideMethodMatch.let {
- val appNameStringIndex = it.indices.last()
+ val appNameStringIndex = it[-1]
navigate(it.immutableMethod).to(appNameStringIndex).stop().apply {
findReturnIndicesReversed().forEach { index ->
insertLegacyTabletMiniplayerOverride(
@@ -246,7 +247,7 @@ val Miniplayer = bytecodePatch(
}
miniplayerResponseModelSizeCheckMethodMatch.let {
- it.method.insertLegacyTabletMiniplayerOverride(it.indices.last())
+ it.method.insertLegacyTabletMiniplayerOverride(it[-1])
}
}
@@ -312,7 +313,7 @@ val Miniplayer = bytecodePatch(
// Override a minimum size constant.
miniplayerMinimumSizeMethodMatch.let {
it.method.apply {
- val index = it.indices[1]
+ val index = it[1]
val register = getInstruction(index).registerA
// Smaller sizes can be used, but the miniplayer will always start in size 170 if set any smaller.
@@ -395,15 +396,17 @@ val Miniplayer = bytecodePatch(
// region Add hooks to hide modern miniplayer buttons.
listOf(
- miniplayerModernExpandButtonMethodMatch to "hideMiniplayerExpandClose",
- miniplayerModernCloseButtonMethodMatch to "hideMiniplayerExpandClose",
- miniplayerModernActionButtonMethodMatch to "hideMiniplayerActionButton",
- miniplayerModernRewindButtonMethodMatch to "hideMiniplayerRewindForward",
- miniplayerModernForwardButtonMethodMatch to "hideMiniplayerRewindForward",
- miniplayerModernOverlayViewMethodMatch to "adjustMiniplayerOpacity",
- ).forEach { (match, methodName) ->
- match.match(miniplayerModernViewParentMethod.immutableClassDef).method.apply {
- val index = match.indices.last()
+ ClassDef::miniplayerModernExpandButtonMethodMatch to "hideMiniplayerExpandClose",
+ ClassDef::miniplayerModernCloseButtonMethodMatch to "hideMiniplayerExpandClose",
+ ClassDef::miniplayerModernActionButtonMethodMatch to "hideMiniplayerActionButton",
+ ClassDef::miniplayerModernRewindButtonMethodMatch to "hideMiniplayerRewindForward",
+ ClassDef::miniplayerModernForwardButtonMethodMatch to "hideMiniplayerRewindForward",
+ ClassDef::miniplayerModernOverlayViewMethodMatch to "adjustMiniplayerOpacity",
+ ).forEach { (matching, methodName) ->
+ val match = matching.get(miniplayerModernViewParentMethod.immutableClassDef)
+
+ match.method.apply {
+ val index = match[-1]
val register = getInstruction(index).registerA
addInstruction(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/Fingerprints.kt
index 7322a252f..5947817dc 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/Fingerprints.kt
@@ -8,7 +8,7 @@ import com.android.tools.smali.dexlib2.Opcode
/**
* 19.46+
*/
-internal val openVideosFullscreenPortraitMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.openVideosFullscreenPortraitMethodMatch by composingFirstMethod {
returnType("V")
parameterTypes("L", "Lj\$/util/Optional;")
instructions(
@@ -22,7 +22,7 @@ internal val openVideosFullscreenPortraitMethodMatch = firstMethodComposite {
/**
* Pre 19.46.
*/
-internal val openVideosFullscreenPortraitLegacyMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.openVideosFullscreenPortraitLegacyMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes("L", "Lj\$/util/Optional;")
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenHookPatch.kt
index bcb81d383..3db908d03 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenHookPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenHookPatch.kt
@@ -1,6 +1,6 @@
package app.revanced.patches.youtube.layout.player.fullscreen
-import app.revanced.patcher.MatchBuilder
+import app.revanced.patcher.Match
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
@@ -25,12 +25,12 @@ internal val openVideosFullscreenHookPatch = bytecodePatch {
)
apply {
- var match: MatchBuilder
+ var match: Match
var insertIndex: Int
if (is_19_46_or_greater) {
match = openVideosFullscreenPortraitMethodMatch
- insertIndex = match.indices.first()
+ insertIndex = match[0]
openVideosFullscreenPortraitMethodMatch.let {
// Remove A/B feature call that forces what this patch already does.
@@ -38,13 +38,13 @@ internal val openVideosFullscreenHookPatch = bytecodePatch {
// Shorts fullscreen regular player does not use fullscreen
// if the player is minimized and it must be forced using other conditional check.
it.method.insertLiteralOverride(
- it.indices.last(),
+ it[-1],
false,
)
}
} else {
match = openVideosFullscreenPortraitLegacyMethodMatch
- insertIndex = match.indices.last()
+ insertIndex = match[-1]
}
match.method.apply {
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/CustomPlayerOverlayOpacityPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/CustomPlayerOverlayOpacityPatch.kt
index 4160feaf3..4bb4c275d 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/CustomPlayerOverlayOpacityPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/CustomPlayerOverlayOpacityPatch.kt
@@ -44,7 +44,7 @@ val customPlayerOverlayOpacityPatch = bytecodePatch(
createPlayerOverviewMethodMatch.let {
it.method.apply {
- val viewRegisterIndex = it.indices.last()
+ val viewRegisterIndex = it[-1]
val viewRegister = getInstruction(viewRegisterIndex).registerA
addInstruction(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/Fingerprints.kt
index 62c49c774..7756cda08 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/Fingerprints.kt
@@ -1,10 +1,11 @@
package app.revanced.patches.youtube.layout.player.overlay
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patches.shared.misc.mapping.ResourceType
import com.android.tools.smali.dexlib2.Opcode
-internal val createPlayerOverviewMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.createPlayerOverviewMethodMatch by composingFirstMethod {
returnType("V")
instructions(
ResourceType.ID("scrim_overlay"),
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/Fingerprints.kt
index 551f5977a..a52c897c0 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/Fingerprints.kt
@@ -22,7 +22,7 @@ internal val BytecodePatchContext.removeLikeMethod by gettingFirstMutableMethodD
instructions("like/removelike"())
}
-internal val rollingNumberMeasureAnimatedTextMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.rollingNumberMeasureAnimatedTextMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returnType("Lj\$/util/Optional;")
parameterTypes("L", "Ljava/lang/String;", "L")
@@ -43,7 +43,7 @@ internal val rollingNumberMeasureAnimatedTextMethodMatch = firstMethodComposite
/**
* Matches to class found in [rollingNumberMeasureStaticLabelParentMethod].
*/
-internal val rollingNumberMeasureStaticLabelMethod = firstMethodComposite {
+internal val ClassDef.rollingNumberMeasureStaticLabelMethodMatch by ClassDefComposing.composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("F")
parameterTypes("Ljava/lang/String;")
@@ -64,17 +64,14 @@ internal val BytecodePatchContext.rollingNumberMeasureStaticLabelParentMethod by
)
}
-internal val rollingNumberSetterMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.rollingNumberSetterMethodMatch by composingFirstMethod {
opcodes(
Opcode.INVOKE_DIRECT,
Opcode.IGET_OBJECT,
)
- custom {
- instructions.matchIndexed(
- "string",
- "RollingNumberType required properties missing! Need"(String::contains),
- )
- }
+
+ val match = indexedMatcher("RollingNumberType required properties missing! Need"(String::contains))
+ custom { match(instructions) }
}
internal val BytecodePatchContext.rollingNumberTextViewMethod by gettingFirstMutableMethodDeclaratively {
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt
index 0a37bf68e..13d1f613b 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt
@@ -226,7 +226,7 @@ val returnYouTubeDislikePatch = bytecodePatch(
rollingNumberSetterMethodMatch.method.apply {
val insertIndex = 1
- val dislikesIndex = rollingNumberSetterMethodMatch.indices.last()
+ val dislikesIndex = rollingNumberSetterMethodMatch[-1]
val charSequenceInstanceRegister = getInstruction(0).registerA
val charSequenceFieldReference = getInstruction(dislikesIndex).reference
@@ -249,8 +249,8 @@ val returnYouTubeDislikePatch = bytecodePatch(
// Modify the measure text calculation to include the left drawable separator if needed.
rollingNumberMeasureAnimatedTextMethodMatch.let {
// Additional check to verify the opcodes are at the start of the method
- if (it.indices.first() != 0) throw PatchException("Unexpected opcode location")
- val endIndex = it.indices.last()
+ if (it[0] != 0) throw PatchException("Unexpected opcode location")
+ val endIndex = it[-1]
it.method.apply {
val measuredTextWidthRegister = getInstruction(endIndex).registerA
@@ -267,10 +267,8 @@ val returnYouTubeDislikePatch = bytecodePatch(
// Additional text measurement method. Used if YouTube decides not to animate the likes count
// and sometimes used for initial video load.
- rollingNumberMeasureStaticLabelMethod.match(
- rollingNumberMeasureStaticLabelParentMethod.immutableClassDef,
- ).let {
- val measureTextIndex = it.indices.first() + 1
+ rollingNumberMeasureStaticLabelParentMethod.immutableClassDef.rollingNumberMeasureStaticLabelMethodMatch.let {
+ val measureTextIndex = it[0] + 1
it.method.apply {
val freeRegister = getInstruction(0).registerA
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt
index 46c910abb..42f9c0a4e 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt
@@ -16,7 +16,7 @@ internal val BytecodePatchContext.fullscreenSeekbarThumbnailsMethod by gettingFi
)
}
-internal val playerSeekbarColorMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.playerSeekbarColorMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
instructions(
ResourceType.COLOR("inline_time_bar_played_not_highlighted_color"),
@@ -25,7 +25,7 @@ internal val playerSeekbarColorMethodMatch = firstMethodComposite {
}
// class is ControlsOverlayStyle in 20.32 and lower, and obfuscated in 20.33+
-internal val setSeekbarClickedColorMethodMatch = firstMethodComposite(
+internal val BytecodePatchContext.setSeekbarClickedColorMethodMatch by composingFirstMethod(
"YOUTUBE",
"PREROLL",
"POSTROLL",
@@ -35,14 +35,14 @@ internal val setSeekbarClickedColorMethodMatch = firstMethodComposite(
opcodes(Opcode.CONST_HIGH16)
}
-internal val shortsSeekbarColorMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.shortsSeekbarColorMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
instructions(
ResourceType.COLOR("reel_time_bar_played_color"),
)
}
-internal val playerSeekbarHandle1ColorMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.playerSeekbarHandle1ColorMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
instructions(
ResourceType.COLOR("inline_time_bar_live_seekable_range"),
@@ -50,7 +50,7 @@ internal val playerSeekbarHandle1ColorMethodMatch = firstMethodComposite {
)
}
-internal val playerSeekbarHandle2ColorMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.playerSeekbarHandle2ColorMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
parameterTypes("Landroid/content/Context;")
instructions(
@@ -59,7 +59,7 @@ internal val playerSeekbarHandle2ColorMethodMatch = firstMethodComposite {
)
}
-internal val watchHistoryMenuUseProgressDrawableMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.watchHistoryMenuUseProgressDrawableMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes("L")
@@ -79,7 +79,7 @@ internal val BytecodePatchContext.lithoLinearGradientMethod by gettingFirstMutab
/**
* 19.49+
*/
-internal val playerLinearGradientMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.playerLinearGradientMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
parameterTypes("I", "I", "I", "I", "Landroid/content/Context;", "I")
returnType("Landroid/graphics/LinearGradient;")
@@ -94,7 +94,7 @@ internal val playerLinearGradientMethodMatch = firstMethodComposite {
/**
* 19.25 - 19.47
*/
-internal val playerLinearGradientLegacyMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.playerLinearGradientLegacyMethodMatch by composingFirstMethod {
returnType("V")
instructions(
ResourceType.COLOR("yt_youtube_magenta"),
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatch.kt
index 5136d43e8..9a9a0ffd2 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatch.kt
@@ -50,17 +50,17 @@ val seekbarColorPatch = bytecodePatch(
playerSeekbarColorMethodMatch.let {
it.method.apply {
- addColorChangeInstructions(it.indices.last())
- addColorChangeInstructions(it.indices.first())
+ addColorChangeInstructions(it[-1])
+ addColorChangeInstructions(it[0])
}
}
shortsSeekbarColorMethodMatch.let {
- it.method.addColorChangeInstructions(it.indices.first())
+ it.method.addColorChangeInstructions(it[0])
}
setSeekbarClickedColorMethodMatch.immutableMethod.let {
- val setColorMethodIndex = setSeekbarClickedColorMethodMatch.indices.first() + 1
+ val setColorMethodIndex = setSeekbarClickedColorMethodMatch[0] + 1
navigate(it).to(setColorMethodIndex).stop().apply {
val colorRegister = getInstruction(0).registerA
@@ -78,12 +78,12 @@ val seekbarColorPatch = bytecodePatch(
// 19.25+ changes
- var handleBarColorFingerprints = mutableListOf(playerSeekbarHandle1ColorMethodMatch)
+ var handleBarColorMethodMatches = mutableListOf(playerSeekbarHandle1ColorMethodMatch)
if (!is_20_34_or_greater) {
- handleBarColorFingerprints += playerSeekbarHandle2ColorMethodMatch
+ handleBarColorMethodMatches += playerSeekbarHandle2ColorMethodMatch
}
- handleBarColorFingerprints.forEach {
- it.method.addColorChangeInstructions(it.indices.last())
+ handleBarColorMethodMatches.forEach {
+ it.method.addColorChangeInstructions(it[-1])
}
// If hiding feed seekbar thumbnails, then turn off the cairo gradient
@@ -92,7 +92,7 @@ val seekbarColorPatch = bytecodePatch(
if (is_19_34_or_greater) {
watchHistoryMenuUseProgressDrawableMethodMatch.let {
it.method.apply {
- val index = it.indices[1]
+ val index = it[1]
val register = getInstruction(index).registerA
addInstructions(
@@ -114,7 +114,7 @@ val seekbarColorPatch = bytecodePatch(
""",
)
- val playerMatch: MatchBuilder
+ val playerMatch: Match
val checkGradientCoordinates: Boolean
if (is_19_49_or_greater) {
playerMatch = playerLinearGradientMethodMatch
@@ -126,7 +126,7 @@ val seekbarColorPatch = bytecodePatch(
playerMatch.let {
it.method.apply {
- val index = it.indices.last()
+ val index = it[-1]
val register = getInstruction(index).registerA
addInstructions(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/Fingerprints.kt
index 9c6551e70..14aecd4f9 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/Fingerprints.kt
@@ -6,7 +6,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.ClassDef
-internal val reelEnumConstructorMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.reelEnumConstructorMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR)
instructions(
"REEL_LOOP_BEHAVIOR_UNKNOWN"(),
@@ -35,7 +35,7 @@ internal fun ClassDef.getReelPlaybackRepeatMethod() = firstMutableMethodDeclarat
instructions(method { toString() == "Lcom/google/common/util/concurrent/ListenableFuture;->isDone()Z" })
}
-internal val reelPlaybackMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.reelPlaybackMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
parameterTypes("J")
returnType("V")
@@ -47,7 +47,7 @@ internal val reelPlaybackMethodMatch = firstMethodComposite {
15,
method {
name == "" &&
- parameterTypes.zip(methodParametersPrefix).all { (a, b) -> a.startsWith(b) }
+ parameterTypes.zip(methodParametersPrefix).all { (a, b) -> a.startsWith(b) }
},
),
afterAtMost(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt
index 310b2064a..988529db9 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt
@@ -80,7 +80,7 @@ val shortsAutoplayPatch = bytecodePatch(
reelEnumClass = immutableClassDef.type
method.addInstructions(
- indices.last(),
+ reelEnumConstructorMethodMatch[-1],
"""
# Pass the first enum value to extension.
# Any enum value of this type will work.
@@ -117,9 +117,9 @@ val shortsAutoplayPatch = bytecodePatch(
if (is_20_09_or_greater) {
// Variable names are only a rough guess of what these methods do.
val userActionMethodReference =
- reelPlaybackMethodMatch.method.getInstruction(reelPlaybackMethodMatch.indices[1]).methodReference!!
+ reelPlaybackMethodMatch.method.getInstruction(reelPlaybackMethodMatch[1]).methodReference!!
val reelSequenceControllerMethodReference =
- reelPlaybackMethodMatch.method.getInstruction(reelPlaybackMethodMatch.indices[2]).methodReference!!
+ reelPlaybackMethodMatch.method.getInstruction(reelPlaybackMethodMatch[2]).methodReference!!
reelPlaybackRepeatMethod.apply {
// Find the first call modified by extension code above.
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/Fingerprints.kt
index 335bf1319..5afa4e8de 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/Fingerprints.kt
@@ -11,7 +11,7 @@ import com.android.tools.smali.dexlib2.Opcode
* the obfuscated name of the videoId() method in PlaybackStartDescriptor.
* 20.38 and lower.
*/
-internal val playbackStartFeatureFlagMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.playbackStartFeatureFlagMethodMatch by composingFirstMethod {
returnType("Z")
parameterTypes("Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;")
instructions(
@@ -28,7 +28,7 @@ internal val playbackStartFeatureFlagMethodMatch = firstMethodComposite {
* the obfuscated name of the videoId() method in PlaybackStartDescriptor.
* 20.39+
*/
-internal val watchPanelVideoIdMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.watchPanelVideoIdMethodMatch by composingFirstMethod {
returnType("Ljava/lang/String;")
parameterTypes()
instructions(
@@ -53,7 +53,7 @@ internal val watchPanelVideoIdMethodMatch = firstMethodComposite {
}
// Pre 19.25
-internal val shortsPlaybackIntentLegacyMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.shortsPlaybackIntentLegacyMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt
index a440bc1d5..9b115730b 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt
@@ -70,11 +70,11 @@ val openShortsInRegularPlayerPatch = bytecodePatch(
// Find the obfuscated method name for PlaybackStartDescriptor.videoId()
val (videoIdStartMethod, videoIdIndex) = if (is_20_39_or_greater) {
watchPanelVideoIdMethodMatch.let {
- it.immutableMethod to it.indices.last()
+ it.immutableMethod to it[-1]
}
} else {
playbackStartFeatureFlagMethodMatch.let {
- it.immutableMethod to it.indices.first()
+ it.immutableMethod to it[0]
}
}
val playbackStartVideoIdMethodName = navigate(videoIdStartMethod).to(videoIdIndex).stop().name
@@ -103,7 +103,7 @@ val openShortsInRegularPlayerPatch = bytecodePatch(
} else {
shortsPlaybackIntentLegacyMethodMatch.let {
it.method.apply {
- val index = it.indices.first()
+ val index = it[0]
val playbackStartRegister = getInstruction(index + 1).registerA
val insertIndex = index + 2
val freeRegister = findFreeRegister(insertIndex, playbackStartRegister)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/Fingerprints.kt
index c8730824e..de6ee8f0e 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/Fingerprints.kt
@@ -1,12 +1,14 @@
package app.revanced.patches.youtube.layout.sponsorblock
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patches.shared.misc.mapping.ResourceType
import app.revanced.patches.youtube.shared.seekbarMethod
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
+import com.android.tools.smali.dexlib2.iface.ClassDef
-internal val appendTimeMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.appendTimeMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes("Ljava/lang/CharSequence;", "Ljava/lang/CharSequence;", "Ljava/lang/CharSequence;")
@@ -17,7 +19,7 @@ internal val appendTimeMethodMatch = firstMethodComposite {
)
}
-internal val controlsOverlayMethodMatch = firstMethodComposite {
+internal val ClassDef.controlsOverlayMethodMatch by ClassDefComposing.composingFirstMethod {
returnType("V")
parameterTypes()
instructions(
@@ -29,13 +31,13 @@ internal val controlsOverlayMethodMatch = firstMethodComposite {
/**
* Resolves to the class found in [seekbarMethod].
*/
-internal val rectangleFieldInvalidatorMethodMatch = firstMethodComposite {
+internal val ClassDef.rectangleFieldInvalidatorMethodMatch by ClassDefComposing.composingFirstMethod {
returnType("V")
parameterTypes()
instructions(method("invalidate"))
}
-internal val adProgressTextViewVisibilityMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.adProgressTextViewVisibilityMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes("Z")
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt
index ecfd45b1c..0c8559180 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt
@@ -21,8 +21,8 @@ import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.patches.youtube.shared.getLayoutConstructorMethodMatch
-import app.revanced.patches.youtube.shared.getSeekbarOnDrawMethodMatch
import app.revanced.patches.youtube.shared.seekbarMethod
+import app.revanced.patches.youtube.shared.seekbarOnDrawMethodMatch
import app.revanced.patches.youtube.video.information.onCreateHook
import app.revanced.patches.youtube.video.information.videoInformationPatch
import app.revanced.patches.youtube.video.information.videoTimeHook
@@ -149,10 +149,10 @@ val SponsorBlock = bytecodePatch(
// Set seekbar draw rectangle.
val rectangleFieldName: FieldReference
- rectangleFieldInvalidatorMethodMatch.match(seekbarMethod.immutableClassDef).let {
+ seekbarMethod.immutableClassDef.rectangleFieldInvalidatorMethodMatch.let {
it.method.apply {
val rectangleIndex = indexOfFirstInstructionReversedOrThrow(
- it.indices.first(),
+ it[0],
) {
getReference()?.type == "Landroid/graphics/Rect;"
}
@@ -164,10 +164,10 @@ val SponsorBlock = bytecodePatch(
// Cannot match using original immutable class because
// class may have been modified by other patches
- getSeekbarOnDrawMethodMatch().match(seekbarMethod.immutableClassDef).let {
+ seekbarMethod.immutableClassDef.seekbarOnDrawMethodMatch.let {
it.method.apply {
// Set seekbar thickness.
- val thicknessIndex = it.indices.last()
+ val thicknessIndex = it[-1]
val thicknessRegister = getInstruction(thicknessIndex).registerA
addInstruction(
thicknessIndex + 1,
@@ -212,7 +212,7 @@ val SponsorBlock = bytecodePatch(
// Append the new time to the player layout.
appendTimeMethodMatch.let {
it.method.apply {
- val index = it.indices.last()
+ val index = it[-1]
val register = getInstruction(index).registerA
addInstructions(
@@ -229,8 +229,8 @@ val SponsorBlock = bytecodePatch(
onCreateHook(EXTENSION_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR, "initialize")
// Initialize the SponsorBlock view.
- controlsOverlayMethodMatch.match(getLayoutConstructorMethodMatch().immutableClassDef).let {
- val checkCastIndex = it.indices.last()
+ getLayoutConstructorMethodMatch().immutableClassDef.controlsOverlayMethodMatch.let {
+ val checkCastIndex = it[-1]
it.method.apply {
val frameLayoutRegister = getInstruction(checkCastIndex).registerA
@@ -242,7 +242,7 @@ val SponsorBlock = bytecodePatch(
}
adProgressTextViewVisibilityMethodMatch.let {
- val setVisibilityIndex = it.indices.first()
+ val setVisibilityIndex = it[0]
val register = it.method.getInstruction(setVisibilityIndex).registerD
it.method.addInstructionsAtControlFlowLabel(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/Fingerprints.kt
index 06dcbbe79..1ef791ef7 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/Fingerprints.kt
@@ -6,7 +6,7 @@ import app.revanced.patches.shared.misc.mapping.ResourceType
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
-internal val toolBarButtonMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.toolBarButtonMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
instructions(
@@ -21,7 +21,7 @@ internal val toolBarButtonMethodMatch = firstMethodComposite {
custom { parameterTypes.count() in 1..2 && parameterTypes.first() == "Landroid/view/MenuItem;" }
}
-internal val spoofAppVersionMethodMatch = firstMethodComposite(
+internal val BytecodePatchContext.spoofAppVersionMethodMatch by composingFirstMethod(
// Instead of applying a bytecode patch, it might be possible to only rely on code from the extension and
// manually set the desired version string as this keyed value in the SharedPreferences.
// But, this bytecode patch is simple and it works.
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt
index 58f2590d9..cb9259325 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt
@@ -83,9 +83,9 @@ val spoofAppVersionPatch = bytecodePatch(
* toolbar when the enum name is UNKNOWN.
*/
toolBarButtonMethodMatch.let {
- val imageResourceIndex = it.indices[2]
+ val imageResourceIndex = it[2]
val register = it.method.getInstruction(imageResourceIndex).registerA
- val jumpIndex = it.indices.last() + 1
+ val jumpIndex = it[-1] + 1
it.method.addInstructionsWithLabels(
imageResourceIndex + 1,
@@ -95,7 +95,7 @@ val spoofAppVersionPatch = bytecodePatch(
}
spoofAppVersionMethodMatch.let {
- val index = it.indices.first()
+ val index = it[0]
val register = it.method.getInstruction(index).registerA
it.method.addInstructions(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/ChangeStartPagePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/ChangeStartPagePatch.kt
index dad7d40d9..ec86e1d56 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/ChangeStartPagePatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/ChangeStartPagePatch.kt
@@ -58,7 +58,7 @@ val changeStartPagePatch = bytecodePatch(
// Hook browseId.
browseIdMethodMatch.let {
it.method.apply {
- val browseIdIndex = it.indices.first()
+ val browseIdIndex = it[0]
val browseIdRegister = getInstruction(browseIdIndex).registerA
addInstructions(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/Fingerprints.kt
index 02bec111c..2bdcdf398 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/Fingerprints.kt
@@ -10,7 +10,7 @@ internal val BytecodePatchContext.intentActionMethod by gettingFirstMutableMetho
parameterTypes("Landroid/content/Intent;")
}
-internal val browseIdMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.browseIdMethodMatch by composingFirstMethod {
returnType("Lcom/google/android/apps/youtube/app/common/ui/navigation/PaneDescriptor;")
// parameterTypes() // 20.30 and earlier is no parameters. 20.31+ parameter is L.
instructions(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt
index 44051b0b3..3b8023f26 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt
@@ -53,7 +53,7 @@ val disableResumingShortsOnStartupPatch = bytecodePatch(
if (is_20_03_or_greater) {
userWasInShortsAlternativeMethodMatch.let {
it.method.apply {
- val insertIndex = it.indices[2] + 1
+ val insertIndex = it[2] + 1
val register = getInstruction(insertIndex).registerA
addInstructions(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/Fingerprints.kt
index 1a8848ce9..ed0908224 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/Fingerprints.kt
@@ -8,7 +8,7 @@ import com.android.tools.smali.dexlib2.Opcode
/**
* 20.02+
*/
-internal val userWasInShortsAlternativeMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.userWasInShortsAlternativeMethodMatch by composingFirstMethod {
returnType("V")
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
parameterTypes("Ljava/lang/Object;")
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt
index abc9268e7..c89783668 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt
@@ -1,13 +1,14 @@
package app.revanced.patches.youtube.layout.theme
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patches.youtube.shared.YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE
-internal val useGradientLoadingScreenMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.useGradientLoadingScreenMethodMatch by composingFirstMethod {
instructions(45412406L())
}
-internal val splashScreenStyleMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.splashScreenStyleMethodMatch by composingFirstMethod {
definingClass(YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE)
name("onCreate")
returnType("V")
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt
index 946f8eb8d..dad35b727 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt
@@ -200,14 +200,14 @@ val themePatch = baseThemePatch(
}
useGradientLoadingScreenMethodMatch.method.insertLiteralOverride(
- useGradientLoadingScreenMethodMatch.indices.first(),
+ useGradientLoadingScreenMethodMatch[0],
"$EXTENSION_CLASS_DESCRIPTOR->gradientLoadingScreenEnabled(Z)Z",
)
if (is_19_47_or_greater) {
// Lottie splash screen exists in earlier versions, but it may not be always on.
splashScreenStyleMethodMatch.method.insertLiteralOverride(
- splashScreenStyleMethodMatch.indices.first(),
+ splashScreenStyleMethodMatch[0],
"$EXTENSION_CLASS_DESCRIPTOR->getLoadingScreenType(I)I",
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt
index 8da25477b..6b39c04b5 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt
@@ -101,7 +101,7 @@ val removeBackgroundPlaybackRestrictionsPatch = bytecodePatch(
if (is_19_34_or_greater) {
pipInputConsumerFeatureFlagMethodMatch.let {
it.method.insertLiteralOverride(
- it.indices.first(),
+ it[0],
false,
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/Fingerprints.kt
index 1b9f07fdd..da1b03b0e 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/Fingerprints.kt
@@ -87,7 +87,7 @@ internal val BytecodePatchContext.shortsBackgroundPlaybackFeatureFlagMethod by g
}
// Fix 'E/InputDispatcher: Window handle pip_input_consumer has no registered input channel'
-internal val pipInputConsumerFeatureFlagMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.pipInputConsumerFeatureFlagMethodMatch by composingFirstMethod {
instructions(
// PiP input consumer feature flag.
45638483L(),
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/Fingerprints.kt
index 5e798a09f..f3f466007 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/Fingerprints.kt
@@ -1,10 +1,11 @@
package app.revanced.patches.youtube.misc.fix.backtoexitgesture
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
-internal val scrollPositionMethodMatch = firstMethodComposite("scroll_position") {
+internal val BytecodePatchContext.scrollPositionMethodMatch by composingFirstMethod("scroll_position") {
accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL)
returnType("V")
parameterTypes("L")
@@ -15,7 +16,7 @@ internal val scrollPositionMethodMatch = firstMethodComposite("scroll_position")
)
}
-internal val recyclerViewTopScrollingMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.recyclerViewTopScrollingMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes()
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/FixBackToExitGesturePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/FixBackToExitGesturePatch.kt
index 1e91dc580..a8615c1d5 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/FixBackToExitGesturePatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/FixBackToExitGesturePatch.kt
@@ -18,13 +18,13 @@ internal val fixBackToExitGesturePatch = bytecodePatch(
apply {
with(recyclerViewTopScrollingMethodMatch) {
method.addInstructionsAtControlFlowLabel(
- indices.last() + 1,
+ recyclerViewTopScrollingMethodMatch[-1] + 1,
"invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->onTopView()V",
)
}
with(scrollPositionMethodMatch) {
- navigate(immutableMethod).to(indices.first() + 1).stop().apply {
+ navigate(immutableMethod).to(scrollPositionMethodMatch[0] + 1).stop().apply {
val index = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_VIRTUAL && getReference()?.definingClass ==
"Landroid/support/v7/widget/RecyclerView;"
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/FIxContentProviderPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/FIxContentProviderPatch.kt
index 4ae2e5eec..e97c6725d 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/FIxContentProviderPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/FIxContentProviderPatch.kt
@@ -20,7 +20,7 @@ internal val fixContentProviderPatch = bytecodePatch {
apply {
unstableContentProviderMethodMatch.let {
- val insertIndex = it.indices.first()
+ val insertIndex = it[0]
it.method.apply {
val register = getInstruction(insertIndex).registerD
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/Fingerprints.kt
index abac7f64a..ac8772d05 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/Fingerprints.kt
@@ -1,9 +1,10 @@
package app.revanced.patches.youtube.misc.fix.contentprovider
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
-internal val unstableContentProviderMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.unstableContentProviderMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes("Landroid/content/ContentResolver;", "[Ljava/lang/String;")
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/AccountCredentialsInvalidTextPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/AccountCredentialsInvalidTextPatch.kt
index 452b01ea6..6b07ea5be 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/AccountCredentialsInvalidTextPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/AccountCredentialsInvalidTextPatch.kt
@@ -33,7 +33,7 @@ internal val accountCredentialsInvalidTextPatch = bytecodePatch {
specificNetworkErrorViewControllerMethodMatch,
loadingFrameLayoutControllerMethodMatch,
).forEach { match ->
- val index = match.indices.last()
+ val index = match[-1]
val register = match.method.getInstruction(index).registerA
match.method.addInstructions(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/Fingerprints.kt
index 23f6c1149..78ab4b951 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/Fingerprints.kt
@@ -1,11 +1,12 @@
package app.revanced.patches.youtube.misc.gms
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patches.shared.misc.mapping.ResourceType
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
-internal val specificNetworkErrorViewControllerMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.specificNetworkErrorViewControllerMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes()
@@ -18,8 +19,8 @@ internal val specificNetworkErrorViewControllerMethodMatch = firstMethodComposit
}
// It's not clear if this second class is ever used and it may be dead code,
-// but it the layout image/text is identical to the network error fingerprint above.
-internal val loadingFrameLayoutControllerMethodMatch = firstMethodComposite {
+// but it the layout image/text is identical to the network error match above.
+internal val BytecodePatchContext.loadingFrameLayoutControllerMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes("L")
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/Fingerprints.kt
index e45548d55..0a60c7093 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/Fingerprints.kt
@@ -17,7 +17,7 @@ internal fun ClassDef.getOnFailureMethod() = firstMutableMethodDeclaratively {
)
}
-// Acts as a parent fingerprint.
+// Acts as a parent method.
internal val BytecodePatchContext.onResponseStartedMethod by gettingFirstMutableMethodDeclaratively(
"Content-Length",
"Content-Type",
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt
index f1b0ee994..99f4a9f2c 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt
@@ -49,7 +49,7 @@ val bypassURLRedirectsPatch = bytecodePatch(
},
httpUriParserMethodMatch to 0,
).forEach { (match, index) ->
- val insertIndex = match.indices[index]
+ val insertIndex = match[index]
val uriStringRegister = match.method.getInstruction(insertIndex).registerC
match.method.replaceInstruction(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/Fingerprints.kt
index 36e96baa9..bea03da44 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/Fingerprints.kt
@@ -1,12 +1,13 @@
package app.revanced.patches.youtube.misc.links
import app.revanced.patcher.*
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
/**
* 20.36 and lower.
*/
-internal val abUriParserLegacyMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.abUriParserLegacyMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("Ljava/lang/Object;")
parameterTypes("Ljava/lang/Object;")
@@ -20,13 +21,13 @@ internal val abUriParserLegacyMethodMatch = firstMethodComposite {
/**
* 20.37+
*/
-internal val abUriParserMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.abUriParserMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("Ljava/lang/Object;")
parameterTypes("Ljava/lang/Object;")
instructions(
// Method is a switch statement of unrelated code,
- // and there's no strings or anything unique to fingerprint.
+ // and there's no strings or anything unique to match to.
method { toString() == "Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;" },
method { toString() == "Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;" },
method { toString() == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" },
@@ -34,7 +35,7 @@ internal val abUriParserMethodMatch = firstMethodComposite {
)
}
-internal val httpUriParserMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.httpUriParserMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returnType("Landroid/net/Uri;")
parameterTypes("Ljava/lang/String;")
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt
index ef5b08094..756d6eb6d 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt
@@ -17,7 +17,7 @@ internal val BytecodePatchContext.lithoFilterMethod by gettingFirstMutableMethod
accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR)
}
-internal val protobufBufferReferenceMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.protobufBufferReferenceMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes("[B")
@@ -72,7 +72,7 @@ internal val BytecodePatchContext.lithoComponentNameUpbFeatureFlagMethod by gett
instructions(45631264L())
}
-internal val lithoConverterBufferUpbFeatureFlagMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.lithoConverterBufferUpbFeatureFlagMethodMatch by composingFirstMethod {
returnType("L")
instructions(45419603L())
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt
index 834b9a65a..b7afbc0e8 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt
@@ -94,7 +94,7 @@ val lithoFilterPatch = bytecodePatch(
protobufBufferReferenceMethodMatch.let {
// Hook the buffer after the call to jniDecode().
it.method.addInstruction(
- it.indices.last() + 1,
+ it[-1] + 1,
"invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->setProtoBuffer([B)V",
)
}
@@ -201,7 +201,7 @@ val lithoFilterPatch = bytecodePatch(
// 20.22 the flag is still enabled in one location, but what it does is not known.
// Disable it anyway.
it.method.insertLiteralOverride(
- it.indices.first(),
+ it[0],
false,
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/Fingerprints.kt
index 2ddb4b0a7..cbd10c78b 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/Fingerprints.kt
@@ -8,11 +8,12 @@ import app.revanced.patcher.parameterTypes
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
import app.revanced.patches.shared.misc.mapping.ResourceType
+import app.revanced.patches.youtube.layout.buttons.navigation.navigationButtonsPatch
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.ClassDef
-internal val actionBarSearchResultsMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.actionBarSearchResultsMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("Landroid/view/View;")
instructions(
@@ -21,14 +22,14 @@ internal val actionBarSearchResultsMethodMatch = firstMethodComposite {
)
}
-internal val toolbarLayoutMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.toolbarLayoutMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PROTECTED, AccessFlags.CONSTRUCTOR)
instructions(
ResourceType.ID("toolbar_container"),
allOf(
Opcode.CHECK_CAST(),
- type("Lcom/google/android/apps/youtube/app/ui/actionbar/MainCollapsingToolbarLayout;")
- )
+ type("Lcom/google/android/apps/youtube/app/ui/actionbar/MainCollapsingToolbarLayout;"),
+ ),
)
}
@@ -49,9 +50,7 @@ context(_: BytecodePatchContext)
internal fun ClassDef.getInitializeButtonsMethod() = firstMutableMethodDeclaratively {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
- instructions(
- ResourceType.LAYOUT("image_only_tab"),
- )
+ instructions(ResourceType.LAYOUT("image_only_tab"))
}
/**
@@ -112,7 +111,7 @@ internal val BytecodePatchContext.pivotBarButtonsCreateResourceIntViewMethod by
}
}
-internal val pivotBarButtonsViewSetSelectedMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.pivotBarButtonsViewSetSelectedMethodMatch by composingFirstMethod {
definingClass("Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;")
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
@@ -122,12 +121,10 @@ internal val pivotBarButtonsViewSetSelectedMethodMatch = firstMethodComposite {
internal val BytecodePatchContext.pivotBarConstructorMethod by gettingFirstMethodDeclaratively {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
- instructions(
- "com.google.android.apps.youtube.app.endpoint.flags"(),
- )
+ instructions("com.google.android.apps.youtube.app.endpoint.flags"())
}
-internal val imageEnumConstructorMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.imageEnumConstructorMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR)
instructions(
"TAB_ACTIVITY_CAIRO"(),
@@ -136,13 +133,13 @@ internal val imageEnumConstructorMethodMatch = firstMethodComposite {
)
}
-internal val setEnumMapMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.setEnumMapMethodMatch by composingFirstMethod {
instructions(
ResourceType.DRAWABLE("yt_fill_bell_black_24"),
afterAtMost(10, method { toString() == "Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;" }),
afterAtMost(
10,
- method { toString() == "Ljava/util/EnumMap;->put(Ljava/lang/Enum;Ljava/lang/Object;)Ljava/lang/Object;" }
- )
+ method { toString() == "Ljava/util/EnumMap;->put(Ljava/lang/Enum;Ljava/lang/Object;)Ljava/lang/Object;" },
+ ),
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
index 48dd9f9c3..8e7651635 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt
@@ -28,6 +28,7 @@ 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
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
+import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction31i
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.util.MethodUtil
@@ -36,9 +37,9 @@ import java.util.logging.Logger
internal const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/shared/NavigationBar;"
internal const val EXTENSION_NAVIGATION_BUTTON_DESCRIPTOR =
- "Lapp/revanced/extension/youtube/shared/NavigationBar\$NavigationButton;"
+ $$"Lapp/revanced/extension/youtube/shared/NavigationBar$NavigationButton;"
private const val EXTENSION_TOOLBAR_INTERFACE =
- "Lapp/revanced/extension/youtube/shared/NavigationBar${'$'}AppCompatToolbarPatchInterface;"
+ $$"Lapp/revanced/extension/youtube/shared/NavigationBar$AppCompatToolbarPatchInterface;"
lateinit var hookNavigationButtonCreated: (String) -> Unit
@@ -47,7 +48,7 @@ val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navig
sharedExtensionPatch,
versionCheckPatch,
playerTypeHookPatch, // Required to detect the search bar in all situations.
- resourceMappingPatch, // Used by fingerprints
+ resourceMappingPatch, // Used to find methods
resourcePatch {
// Copy missing notification icon.
apply {
@@ -113,7 +114,7 @@ val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navig
}
pivotBarButtonsViewSetSelectedMethodMatch.method.apply {
- val index = pivotBarButtonsViewSetSelectedMethodMatch.indices.first()
+ val index = pivotBarButtonsViewSetSelectedMethodMatch[0]
val instruction = getInstruction(index)
val viewRegister = instruction.registerC
val isSelectedRegister = instruction.registerD
@@ -139,7 +140,7 @@ val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navig
// so this works regardless which layout is used.
actionBarSearchResultsMethodMatch.let {
it.method.apply {
- val instructionIndex = it.indices.last()
+ val instructionIndex = it[-1]
val viewRegister = getInstruction(instructionIndex).registerC
addInstruction(
@@ -154,7 +155,7 @@ val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navig
toolbarLayoutMethodMatch.let {
it.method.apply {
- val index = it.indices.last()
+ val index = it[-1]
val register = getInstruction(index).registerA
addInstruction(
@@ -212,10 +213,10 @@ val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navig
// Fix YT bug of notification tab missing the filled icon.
if (is_19_35_or_greater && !is_20_39_or_greater) { // FIXME: 20.39+ needs this fix.
val cairoNotificationEnumReference =
- imageEnumConstructorMethodMatch.method.getInstruction(imageEnumConstructorMethodMatch.indices.last()).reference
+ imageEnumConstructorMethodMatch.method.getInstruction(imageEnumConstructorMethodMatch[-1]).reference
setEnumMapMethodMatch.apply {
- val setEnumIntegerIndex = setEnumMapMethodMatch.indices.last()
+ val setEnumIntegerIndex = setEnumMapMethodMatch[-1]
method.apply {
val enumMapRegister = getInstruction(setEnumIntegerIndex).registerC
val insertIndex = setEnumIntegerIndex + 1
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/Fingerprints.kt
index 1a511610b..469e6b8aa 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/Fingerprints.kt
@@ -7,7 +7,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.ClassDef
-internal val playerControlsVisibilityEntityModelMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.playerControlsVisibilityEntityModelMethodMatch by composingFirstMethod {
name("getPlayerControlsVisibility")
accessFlags(AccessFlags.PUBLIC)
returnType("L")
@@ -28,7 +28,7 @@ internal val BytecodePatchContext.youtubeControlsOverlayMethod by gettingFirstMe
)
}
-internal val motionEventMethodMatch = firstMethodComposite {
+internal val ClassDef.motionEventMethodMatch by ClassDefComposing.composingFirstMethod {
returnType("V")
parameterTypes("Landroid/view/MotionEvent;")
instructions(method("setTranslationY"))
@@ -50,7 +50,7 @@ internal val BytecodePatchContext.playerControlsExtensionHookMethod by gettingFi
parameterTypes("Z")
}
-internal val playerTopControlsInflateMethod = firstMethodComposite {
+internal val BytecodePatchContext.playerTopControlsInflateMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes()
@@ -61,7 +61,7 @@ internal val playerTopControlsInflateMethod = firstMethodComposite {
)
}
-internal val playerBottomControlsInflateMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.playerBottomControlsInflateMethodMatch by composingFirstMethod {
returnType("Ljava/lang/Object;")
parameterTypes()
instructions(
@@ -71,7 +71,7 @@ internal val playerBottomControlsInflateMethodMatch = firstMethodComposite {
)
}
-internal val overlayViewInflateMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.overlayViewInflateMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes("Landroid/view/View;")
@@ -83,7 +83,7 @@ internal val overlayViewInflateMethodMatch = firstMethodComposite {
}
/**
- * Resolves to the class found in [playerTopControlsInflateMethod].
+ * Resolves to the class found in [playerTopControlsInflateMethodMatch].
*/
context(_: BytecodePatchContext)
internal fun ClassDef.getControlsOverlayVisibilityMethod() = firstMutableMethodDeclaratively {
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsOverlayVisibilityPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsOverlayVisibilityPatch.kt
index d4eaabb6b..aff5b9a4d 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsOverlayVisibilityPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsOverlayVisibilityPatch.kt
@@ -18,7 +18,7 @@ val playerControlsOverlayVisibilityPatch = bytecodePatch {
apply {
playerControlsVisibilityEntityModelMethodMatch.let {
it.method.apply {
- val startIndex = it.indices.first()
+ val startIndex = it[0]
val iGetReference = getInstruction(startIndex).reference
val staticReference = getInstruction(startIndex + 1).reference
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsPatch.kt
index b3233d512..973fa94ff 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsPatch.kt
@@ -227,7 +227,7 @@ val playerControlsPatch = bytecodePatch(
dependsOn(
playerControlsResourcePatch,
sharedExtensionPatch,
- resourceMappingPatch, // Used by fingerprints.
+ resourceMappingPatch, // Used to find methods.
playerControlsOverlayVisibilityPatch,
versionCheckPatch,
)
@@ -236,26 +236,26 @@ val playerControlsPatch = bytecodePatch(
playerBottomControlsInflateMethodMatch.method.apply {
inflateBottomControlMethod = this
- val inflateReturnObjectIndex = playerBottomControlsInflateMethodMatch.indices.last()
+ val inflateReturnObjectIndex = playerBottomControlsInflateMethodMatch[-1]
inflateBottomControlRegister = getInstruction(inflateReturnObjectIndex).registerA
inflateBottomControlInsertIndex = inflateReturnObjectIndex + 1
}
- playerTopControlsInflateMethod.method.apply {
+ playerTopControlsInflateMethodMatch.method.apply {
inflateTopControlMethod = this
- val inflateReturnObjectIndex = playerTopControlsInflateMethod.indices.last()
+ val inflateReturnObjectIndex = playerTopControlsInflateMethodMatch[-1]
inflateTopControlRegister = getInstruction(inflateReturnObjectIndex).registerA
inflateTopControlInsertIndex = inflateReturnObjectIndex + 1
}
visibilityMethod =
- playerTopControlsInflateMethod.immutableClassDef.getControlsOverlayVisibilityMethod()
+ playerTopControlsInflateMethodMatch.immutableClassDef.getControlsOverlayVisibilityMethod()
// Hook the fullscreen close button. Used to fix visibility
// when seeking and other situations.
overlayViewInflateMethodMatch.method.apply {
- val index = overlayViewInflateMethodMatch.indices.last()
+ val index = overlayViewInflateMethodMatch[-1]
val register = getInstruction(index).registerA
addInstruction(
@@ -268,9 +268,9 @@ val playerControlsPatch = bytecodePatch(
visibilityImmediateCallbacksExistMethod = playerControlsExtensionHookListenersExistMethod
visibilityImmediateMethod = playerControlsExtensionHookMethod
- motionEventMethodMatch.match(youtubeControlsOverlayMethod.immutableClassDef).let {
+ youtubeControlsOverlayMethod.immutableClassDef.motionEventMethodMatch.let {
visibilityNegatedImmediateMethod = it.method
- visibilityNegatedImmediateInsertIndex = it.indices.first() + 1
+ visibilityNegatedImmediateInsertIndex = it[0] + 1
}
// A/B test for a slightly different bottom overlay controls,
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/Fingerprints.kt
index 5b4ba07c1..fe49276ab 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/Fingerprints.kt
@@ -22,7 +22,7 @@ internal val BytecodePatchContext.playerTypeEnumMethod by gettingFirstMethodDecl
accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR)
}
-internal val reelWatchPagerMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.reelWatchPagerMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("Landroid/view/View;")
instructions(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/PlayerTypeHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/PlayerTypeHookPatch.kt
index e99afc754..a37d2d9cc 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/PlayerTypeHookPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/PlayerTypeHookPatch.kt
@@ -31,7 +31,7 @@ val playerTypeHookPatch = bytecodePatch(
)
reelWatchPagerMethodMatch.method.apply {
- val index = reelWatchPagerMethodMatch.indices.last()
+ val index = reelWatchPagerMethodMatch[-1]
val register = getInstruction(index).registerA
addInstruction(
@@ -57,7 +57,7 @@ val playerTypeHookPatch = bytecodePatch(
)
}.let {
it.method.apply {
- val videoStateFieldName = getInstruction(it.indices.first()).reference
+ val videoStateFieldName = getInstruction(it[0]).reference
addInstructions(
0,
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/recyclerviewtree/hook/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/recyclerviewtree/hook/Fingerprints.kt
index bbd73d846..efece581f 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/recyclerviewtree/hook/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/recyclerviewtree/hook/Fingerprints.kt
@@ -1,12 +1,13 @@
package app.revanced.patches.youtube.misc.recyclerviewtree.hook
import app.revanced.patcher.accessFlags
-import app.revanced.patcher.firstMethodComposite
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.opcodes
+import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
-internal val recyclerViewTreeObserverMethodMatch = firstMethodComposite("LithoRVSLCBinder") {
+internal val BytecodePatchContext.recyclerViewTreeObserverMethodMatch by composingFirstMethod("LithoRVSLCBinder") {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
opcodes(
Opcode.CHECK_CAST,
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/recyclerviewtree/hook/RecyclerViewTreeHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/recyclerviewtree/hook/RecyclerViewTreeHookPatch.kt
index ed861cb1c..70182237f 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/recyclerviewtree/hook/RecyclerViewTreeHookPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/recyclerviewtree/hook/RecyclerViewTreeHookPatch.kt
@@ -12,7 +12,7 @@ val recyclerViewTreeHookPatch = bytecodePatch {
apply {
recyclerViewTreeObserverMethodMatch.let {
- val insertIndex = it.indices.first() + 1
+ val insertIndex = it[0] + 1
val recyclerViewParameter = 2
addRecyclerViewTreeHook = { classDescriptor ->
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/Fingerprints.kt
index 7dfbacb7f..4e9d967bb 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/Fingerprints.kt
@@ -8,7 +8,7 @@ import com.android.tools.smali.dexlib2.Opcode
internal val BytecodePatchContext.licenseActivityOnCreateMethod by gettingFirstMutableMethodDeclaratively {
name("onCreate")
- definingClass("/LicenseActivity;")
+ definingClass { endsWith("/LicenseActivity;") }
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes("Landroid/os/Bundle;")
@@ -21,7 +21,7 @@ internal val BytecodePatchContext.setThemeMethod by gettingFirstMutableMethodDec
instructions(ResourceType.STRING("app_theme_appearance_dark"))
}
-internal val cairoFragmentConfigMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.cairoFragmentConfigMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("Z")
instructions(
@@ -32,7 +32,7 @@ internal val cairoFragmentConfigMethodMatch = firstMethodComposite {
// Flag is present in 20.23, but bold icons are missing and forcing them crashes the app.
// 20.31 is the first target with all the bold icons present.
-internal val boldIconsFeatureFlagMethod = firstMethodComposite {
+internal val BytecodePatchContext.boldIconsFeatureFlagMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("Z")
parameterTypes()
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt
index 920025857..38b200d4b 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt
@@ -241,16 +241,16 @@ val settingsPatch = bytecodePatch(
// Add setting to force Cairo settings fragment on/off.
cairoFragmentConfigMethodMatch.method.insertLiteralOverride(
- cairoFragmentConfigMethodMatch.indices.first(),
+ cairoFragmentConfigMethodMatch[0],
"$YOUTUBE_ACTIVITY_HOOK_CLASS_DESCRIPTOR->useCairoSettingsFragment(Z)Z",
)
// Bold icon resources are found starting in 20.23, but many YT icons are not bold.
// 20.31 is the first version that seems to have all the bold icons.
if (is_20_31_or_greater) {
- boldIconsFeatureFlagMethod.let {
+ boldIconsFeatureFlagMethodMatch.let {
it.method.insertLiteralOverride(
- it.indices.first(),
+ it[0],
"$YOUTUBE_ACTIVITY_HOOK_CLASS_DESCRIPTOR->useBoldIcons(Z)Z",
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt
index 9bb669c9d..6bb0e6075 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt
@@ -1,17 +1,17 @@
package app.revanced.patches.youtube.shared
+import app.revanced.patcher.ClassDefComposing
import app.revanced.patcher.accessFlags
import app.revanced.patcher.after
import app.revanced.patcher.allOf
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.custom
import app.revanced.patcher.definingClass
import app.revanced.patcher.field
import app.revanced.patcher.firstMethodComposite
-import app.revanced.patcher.firstMethodDeclaratively
import app.revanced.patcher.gettingFirstMethodDeclaratively
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.immutableClassDef
-import app.revanced.patcher.instruction
import app.revanced.patcher.instructions
import app.revanced.patcher.invoke
import app.revanced.patcher.method
@@ -24,6 +24,7 @@ import app.revanced.patcher.type
import app.revanced.patches.shared.misc.mapping.ResourceType
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
+import com.android.tools.smali.dexlib2.iface.ClassDef
internal const val YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE = "Lcom/google/android/apps/youtube/app/watchwhile/MainActivity;"
@@ -39,7 +40,7 @@ internal val BytecodePatchContext.conversionContextToStringMethod by gettingFirs
instructions("ConversionContext{"(String::startsWith)) // Partial string match.
}
-internal fun getLayoutConstructorMethodMatch() = firstMethodComposite {
+internal fun BytecodePatchContext.getLayoutConstructorMethodMatch() = firstMethodComposite {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes()
@@ -78,7 +79,7 @@ internal val BytecodePatchContext.mainActivityOnCreateMethod by gettingFirstMuta
parameterTypes("Landroid/os/Bundle;")
}
-internal val rollingNumberTextViewAnimationUpdateMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.rollingNumberTextViewAnimationUpdateMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
parameterTypes("Landroid/graphics/Bitmap;")
@@ -112,7 +113,7 @@ internal val BytecodePatchContext.seekbarMethod by gettingFirstMethodDeclarative
/**
* Matches to _mutable_ class found in [seekbarMethod].
*/
-internal fun getSeekbarOnDrawMethodMatch() = firstMethodComposite {
+internal val ClassDef.seekbarOnDrawMethodMatch by ClassDefComposing.composingFirstMethod {
name("onDraw")
instructions(
method { toString() == "Ljava/lang/Math;->round(F)I" },
@@ -130,7 +131,7 @@ internal val BytecodePatchContext.subtitleButtonControllerMethod by gettingFirst
)
}
-internal val videoQualityChangedMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.videoQualityChangedMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("L")
parameterTypes("L")
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/Fingerprints.kt
index 964218069..783bfc0f5 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/Fingerprints.kt
@@ -7,6 +7,7 @@ import app.revanced.patches.youtube.shared.videoQualityChangedMethodMatch
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.ClassDef
+import org.stringtemplate.v4.compiler.Bytecode
internal val BytecodePatchContext.createVideoPlayerSeekbarMethod by gettingFirstMethodDeclaratively {
returnType("V")
@@ -21,15 +22,16 @@ internal val BytecodePatchContext.onPlaybackSpeedItemClickMethod by gettingFirst
instructions(
allOf(
Opcode.IGET_OBJECT(),
- field { type == "Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;" })
+ field { type == "Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;" },
+ ),
)
}
-internal val playerControllerSetTimeReferenceMethodMatch =
- firstMethodComposite("Media progress reported outside media playback: ") {
+internal val BytecodePatchContext.playerControllerSetTimeReferenceMethodMatch by
+ composingFirstMethod("Media progress reported outside media playback: ") {
opcodes(
Opcode.INVOKE_DIRECT_RANGE,
- Opcode.IGET_OBJECT
+ Opcode.IGET_OBJECT,
)
}
@@ -44,7 +46,7 @@ internal fun ClassDef.getSeekMethod() = firstMethodDeclaratively {
instructions("Attempting to seek during an ad"())
}
-internal val videoLengthMethodMatch = firstMethodComposite {
+internal val ClassDef.videoLengthMethodMatch by ClassDefComposing.composingFirstMethod {
opcodes(
Opcode.MOVE_RESULT_WIDE,
Opcode.CMP_LONG,
@@ -114,7 +116,7 @@ internal fun ClassDef.getSeekRelativeMethod() = firstMutableMethodDeclaratively
)
}
-internal val videoEndMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.videoEndMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("Z")
parameterTypes("J", "L")
@@ -128,7 +130,7 @@ internal val videoEndMethodMatch = firstMethodComposite {
/**
* Matches with the class found in [videoQualityChangedMethodMatch].
*/
-internal val playbackSpeedMenuSpeedChangedMethodMatch = firstMethodComposite {
+internal val ClassDef.playbackSpeedMenuSpeedChangedMethodMatch by ClassDefComposing.composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("L")
parameterTypes("L")
@@ -136,7 +138,7 @@ internal val playbackSpeedMenuSpeedChangedMethodMatch = firstMethodComposite {
}
internal val BytecodePatchContext.playbackSpeedClassMethod by gettingFirstMutableMethodDeclaratively(
- "PLAYBACK_RATE_MENU_BOTTOM_SHEET_FRAGMENT"
+ "PLAYBACK_RATE_MENU_BOTTOM_SHEET_FRAGMENT",
) {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returnType("L")
@@ -144,7 +146,6 @@ internal val BytecodePatchContext.playbackSpeedClassMethod by gettingFirstMutabl
opcodes(Opcode.RETURN_OBJECT)
}
-
internal const val YOUTUBE_VIDEO_QUALITY_CLASS_TYPE =
"Lcom/google/android/libraries/youtube/innertube/model/media/VideoQuality;"
@@ -158,7 +159,7 @@ internal val BytecodePatchContext.videoQualityLegacyMethod by gettingFirstMutabl
"I", // Resolution.
"Ljava/lang/String;", // Human readable resolution: "480p", "1080p Premium", etc
"Z",
- "L"
+ "L",
)
}
@@ -170,12 +171,12 @@ internal val BytecodePatchContext.videoQualityMethod by gettingFirstMutableMetho
"L",
"Ljava/lang/String;", // Human readable resolution: "480p", "1080p Premium", etc
"Z",
- "L"
+ "L",
)
}
internal val BytecodePatchContext.videoQualitySetterMethod by gettingFirstMutableMethodDeclaratively(
- "menu_item_video_quality"
+ "menu_item_video_quality",
) {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("V")
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt
index d7a8f2d4c..f573e45de 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt
@@ -130,15 +130,15 @@ val videoInformationPatch = bytecodePatch(
}
with(createVideoPlayerSeekbarMethod) {
- val videoLengthMethodMatch = videoLengthMethodMatch.match(immutableClassDef)
+ val videoLengthMethodMatch = immutableClassDef.videoLengthMethodMatch
videoLengthMethodMatch.method.apply {
- val videoLengthRegisterIndex = videoLengthMethodMatch.indices.last()
+ val videoLengthRegisterIndex = videoLengthMethodMatch[-1]
val videoLengthRegister = getInstruction(videoLengthRegisterIndex).registerA
val dummyRegisterForLong = videoLengthRegister + 1 // required for long values since they are wide
addInstruction(
- videoLengthMethodMatch.indices.last(),
+ videoLengthMethodMatch[-1],
"invoke-static {v$videoLengthRegister, v$dummyRegisterForLong}, " +
"$EXTENSION_CLASS_DESCRIPTOR->setVideoLength(J)V",
)
@@ -146,7 +146,7 @@ val videoInformationPatch = bytecodePatch(
}
videoEndMethod = navigate(videoEndMethodMatch.immutableMethod)
- .to(videoEndMethodMatch.indices.first()).stop()
+ .to(videoEndMethodMatch[0]).stop()
/*
* Inject call for video ids
@@ -170,7 +170,7 @@ val videoInformationPatch = bytecodePatch(
* Set the video time method
*/
timeMethod = navigate(playerControllerSetTimeReferenceMethodMatch.immutableMethod)
- .to(playerControllerSetTimeReferenceMethodMatch.indices.first()).stop()
+ .to(playerControllerSetTimeReferenceMethodMatch[0]).stop()
/*
* Hook the methods which set the time
@@ -270,9 +270,9 @@ val videoInformationPatch = bytecodePatch(
}
// Handle new playback speed menu.
- playbackSpeedMenuSpeedChangedMethodMatch.match(videoQualityChangedMethodMatch.immutableClassDef).let {
+ videoQualityChangedMethodMatch.immutableClassDef.playbackSpeedMenuSpeedChangedMethodMatch.let {
it.method.apply {
- val index = it.indices.first()
+ val index = it[0]
speedSelectionInsertMethod = this
speedSelectionInsertIndex = index + 1
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/AdvancedVideoQualityMenuPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/AdvancedVideoQualityMenuPatch.kt
index 8ed829f26..5f10870c0 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/AdvancedVideoQualityMenuPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/AdvancedVideoQualityMenuPatch.kt
@@ -57,7 +57,7 @@ internal val advancedVideoQualityMenuPatch = bytecodePatch {
// and for the Shorts quality flyout on newer app versions.
videoQualityMenuViewInflateMethodMatch.let {
it.method.apply {
- val checkCastIndex = it.indices.last()
+ val checkCastIndex = it[-1]
val listViewRegister = getInstruction(checkCastIndex).registerA
addInstruction(
@@ -70,8 +70,8 @@ internal val advancedVideoQualityMenuPatch = bytecodePatch {
// Force YT to add the 'advanced' quality menu for Shorts.
videoQualityMenuOptionsMethodMatch.let {
- val startIndex = it.indices.first()
- val insertIndex = it.indices.last()
+ val startIndex = it[0]
+ val insertIndex = it[-1]
if (startIndex != 0) throw PatchException("Unexpected opcode start index: $startIndex")
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/Fingerprints.kt
index ad37bdb17..093a759b2 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/Fingerprints.kt
@@ -1,7 +1,7 @@
package app.revanced.patches.youtube.video.quality
import app.revanced.patcher.accessFlags
-import app.revanced.patcher.firstMethodComposite
+import app.revanced.patcher.composingFirstMethod
import app.revanced.patcher.firstMutableMethodDeclaratively
import app.revanced.patcher.gettingFirstMethodDeclaratively
import app.revanced.patcher.name
@@ -32,7 +32,7 @@ internal fun ClassDef.getVideoQualityItemOnClickMethod() = firstMutableMethodDec
)
}
-internal val videoQualityMenuOptionsMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.videoQualityMenuOptionsMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.STATIC)
returnType("[L")
parameterTypes("Landroid/content/Context", "L", "L")
@@ -46,7 +46,7 @@ internal val videoQualityMenuOptionsMethodMatch = firstMethodComposite {
literal { videoQualityQuickMenuAdvancedMenuDescription }
}
-internal val videoQualityMenuViewInflateMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.videoQualityMenuViewInflateMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("L")
parameterTypes("L", "L", "L")
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt
index f7893c686..9b38ead45 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt
@@ -72,7 +72,7 @@ val rememberVideoQualityPatch = bytecodePatch {
// Inject a call to remember the user selected quality for regular videos.
videoQualityChangedMethodMatch.let { match ->
- val index = match.indices[3]
+ val index = match[3]
val register = match.method.getInstruction(index).registerA
match.method.addInstruction(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/CustomPlaybackSpeedPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/CustomPlaybackSpeedPatch.kt
index 88b557bdf..c55a3d95c 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/CustomPlaybackSpeedPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/CustomPlaybackSpeedPatch.kt
@@ -97,15 +97,15 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
val playbackSpeedsArrayType = "$EXTENSION_CLASS_DESCRIPTOR->customPlaybackSpeeds:[F"
// Apply changes from last index to first to preserve indexes.
- val originalArrayFetchIndex = it.indices[5]
- val originalArrayFetchDestination = getInstruction(it.indices[5]).registerA
+ val originalArrayFetchIndex = it[5]
+ val originalArrayFetchDestination = getInstruction(it[5]).registerA
replaceInstruction(
originalArrayFetchIndex,
"sget-object v$originalArrayFetchDestination, $playbackSpeedsArrayType",
)
- val arrayLengthConstDestination = getInstruction(it.indices[3]).registerA
- val newArrayIndex = it.indices[4]
+ val arrayLengthConstDestination = getInstruction(it[3]).registerA
+ val newArrayIndex = it[4]
addInstructions(
newArrayIndex,
"""
@@ -114,7 +114,7 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
""",
)
- val sizeCallIndex = it.indices[0] + 1
+ val sizeCallIndex = it[0] + 1
val sizeCallResultRegister = getInstruction(sizeCallIndex).registerA
replaceInstruction(sizeCallIndex, "const/4 v$sizeCallResultRegister, 0x0")
}
@@ -172,7 +172,7 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
if (is_19_47_or_greater) {
customTapAndHoldMethodMatch.let {
it.method.apply {
- val index = it.indices.first()
+ val index = it[0]
val register = getInstruction(index).registerA
addInstructions(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/Fingerprints.kt
index 43ce7443d..f7c0cdbce 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/Fingerprints.kt
@@ -32,7 +32,7 @@ internal val BytecodePatchContext.serverSideMaxSpeedFeatureFlagMethod by getting
)
}
-internal val speedArrayGeneratorMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.speedArrayGeneratorMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returnType("[L")
parameterTypes("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;")
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/Fingerprints.kt
index b3ed07bbf..535f38abc 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/Fingerprints.kt
@@ -23,7 +23,7 @@ internal fun ClassDef.getVideoIdMethodMatch() = firstMethodComposite {
)
}
-internal val videoIdBackgroundPlayMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.videoIdBackgroundPlayMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.DECLARED_SYNCHRONIZED, AccessFlags.FINAL, AccessFlags.PUBLIC)
returnType("V")
parameterTypes("L")
@@ -45,7 +45,7 @@ internal val videoIdBackgroundPlayMethodMatch = firstMethodComposite {
}
}
-internal val videoIdParentMethodMatch = firstMethodComposite {
+internal val BytecodePatchContext.videoIdParentMethodMatch by composingFirstMethod {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returnType("[L")
parameterTypes("L")
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/VideoIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/VideoIdPatch.kt
index 6fc87aa3b..76465dd9e 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/VideoIdPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/VideoIdPatch.kt
@@ -95,7 +95,7 @@ val videoIdPatch = bytecodePatch(
videoIdParentMethodMatch.immutableClassDef.getVideoIdMethodMatch().let {
videoIdMethod = it.method
- val index = it.indices.first()
+ val index = it[0]
videoIdRegister = it.method.getInstruction(index + 1).registerA
videoIdInsertIndex = index + 2
}
@@ -103,7 +103,7 @@ val videoIdPatch = bytecodePatch(
videoIdBackgroundPlayMethodMatch.let {
backgroundPlaybackMethod = it.method
- val index = it.indices.first()
+ val index = it[0]
backgroundPlaybackVideoIdRegister = it.method.getInstruction(index + 1).registerA
backgroundPlaybackInsertIndex = index + 2
}
diff --git a/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt
index 9e18d21c2..78a784e89 100644
--- a/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt
+++ b/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt
@@ -1238,7 +1238,7 @@ internal fun BytecodePatchContext.addStaticFieldToExtension(
}
/**
- * Set the custom condition for this fingerprint to check for a literal value.
+ * Set the custom condition for this predicate to check for a literal value.
*
* @param literalSupplier The supplier for the literal value to check for.
*/