feat(youtube): add hide-shorts-components patch

This commit is contained in:
oSumAtrIX 2023-05-10 01:04:06 +02:00
parent 6347146900
commit 64868f41be
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4
14 changed files with 265 additions and 176 deletions

View File

@ -1,6 +1,7 @@
package app.revanced.extensions
import app.revanced.patcher.extensions.MethodFingerprintExtensions.name
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
@ -41,4 +42,14 @@ fun MutableClass.transformMethods(transform: MutableMethod.() -> MutableMethod)
internal fun Node.doRecursively(action: (Node) -> Unit) {
action(this)
for (i in 0 until this.childNodes.length) this.childNodes.item(i).doRecursively(action)
}
}
fun MutableMethod.injectHideViewCall(
insertIndex: Int,
viewRegister: Int,
classDescriptor: String,
targetMethod: String
) = addInstruction(
insertIndex,
"invoke-static { v$viewRegister }, $classDescriptor->$targetMethod(Landroid/view/View;)V"
)

View File

@ -1,17 +0,0 @@
package app.revanced.patches.youtube.ad.general.bytecode.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.ad.general.resource.patch.HideAdsResourcePatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object ReelConstructorFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.INVOKE_VIRTUAL
),
customFingerprint = { method, _ ->
method.implementation?.instructions?.any {
it.opcode == Opcode.CONST && (it as WideLiteralInstruction).wideLiteral == HideAdsResourcePatch.reelMultipleItemShelfId
} ?: false
}
)

View File

@ -1,25 +1,20 @@
package app.revanced.patches.youtube.ad.general.bytecode.patch
import app.revanced.extensions.findMutableMethodOf
import app.revanced.extensions.toErrorResult
import app.revanced.extensions.injectHideViewCall
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.instruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.misc.fix.verticalscroll.patch.VerticalScrollPatch
import app.revanced.patches.youtube.ad.general.annotation.HideAdsCompatibility
import app.revanced.patches.youtube.ad.general.bytecode.fingerprints.ReelConstructorFingerprint
import app.revanced.patches.youtube.ad.general.resource.patch.HideAdsResourcePatch
import app.revanced.patches.youtube.misc.fix.backtoexitgesture.patch.FixBackToExitGesturePatch
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
import org.jf.dexlib2.iface.instruction.formats.Instruction31i
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
@ -30,18 +25,8 @@ import org.jf.dexlib2.iface.instruction.formats.Instruction35c
@Description("Removes general ads.")
@HideAdsCompatibility
@Version("0.0.1")
class HideAdsPatch : BytecodePatch(
listOf(ReelConstructorFingerprint)
) {
class HideAdsPatch : BytecodePatch() {
override fun execute(context: BytecodeContext): PatchResult {
fun String.buildHideCall(viewRegister: Int) = "invoke-static { v$viewRegister }, " +
"Lapp/revanced/integrations/patches/litho/AdsFilter;" +
"->" +
"$this(Landroid/view/View;)V"
fun MutableMethod.injectHideCall(insertIndex: Int, viewRegister: Int, method: String) =
this.addInstruction(insertIndex, method.buildHideCall(viewRegister))
context.classes.forEach { classDef ->
classDef.methods.forEach { method ->
with(method.implementation) {
@ -64,25 +49,18 @@ class HideAdsPatch : BytecodePatch(
context.proxy(classDef)
.mutableClass
.findMutableMethodOf(method)
.injectHideCall(insertIndex, viewRegister, "hideAdAttributionView")
.injectHideViewCall(
insertIndex,
viewRegister,
"Lapp/revanced/integrations/patches/components/AdsFilter;",
"hideAdAttributionView"
)
}
}
}
}
}
ReelConstructorFingerprint.result?.let {
// iput-object v$viewRegister, ...
val insertIndex = it.scanResult.patternScanResult!!.startIndex + 2
it.mutableMethod.apply {
val viewRegister = instruction<TwoRegisterInstruction>(insertIndex).registerA
injectHideCall(insertIndex, viewRegister, "hideReelView")
}
} ?: return ReelConstructorFingerprint.toErrorResult()
return PatchResultSuccess()
}
}

View File

@ -23,10 +23,6 @@ import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch.P
@HideAdsCompatibility
@Version("0.0.1")
class HideAdsResourcePatch : ResourcePatch {
internal companion object {
var adAttributionId: Long = -1
var reelMultipleItemShelfId: Long = -1
}
override fun execute(context: ResourceContext): PatchResult {
PreferenceScreen.LAYOUT.addPreferences(
@ -105,12 +101,6 @@ class HideAdsResourcePatch : ResourcePatch {
StringResource("revanced_hide_feed_survey_summary_on", "Feed surveys are hidden"),
StringResource("revanced_hide_feed_survey_summary_off", "Feed surveys are shown")
),
SwitchPreference(
"revanced_hide_shorts",
StringResource("revanced_hide_shorts_title", "Hide shorts"),
StringResource("revanced_hide_shorts_summary_on", "Shorts are hidden"),
StringResource("revanced_hide_shorts_summary_off", "Shorts are shown")
),
SwitchPreference(
"revanced_hide_community_guidelines",
StringResource("revanced_hide_community_guidelines_title", "Hide community guidelines"),
@ -263,11 +253,12 @@ class HideAdsResourcePatch : ResourcePatch {
)
)
fun String.getId() = ResourceMappingPatch.resourceMappings.single { it.name == this }.id
adAttributionId = "ad_attribution".getId()
reelMultipleItemShelfId = "reel_multiple_items_shelf".getId()
adAttributionId = ResourceMappingPatch.resourceMappings.single { it.name == "ad_attribution" }.id
return PatchResultSuccess()
}
internal companion object {
var adAttributionId: Long = -1
}
}

View File

@ -21,4 +21,4 @@ import app.revanced.patcher.annotation.Package
)]
)
@Target(AnnotationTarget.CLASS)
internal annotation class CommentsCompatibility
internal annotation class HideCommentsCompatibility

View File

@ -1,17 +0,0 @@
package app.revanced.patches.youtube.layout.hide.comments.bytecode.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hide.comments.resource.patch.CommentsResourcePatch
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object ShortsCommentsButtonFingerprint : MethodFingerprint(
"V", AccessFlags.PRIVATE or AccessFlags.FINAL, listOf("Z", "Z", "L"),
customFingerprint = { methodDef, _ ->
methodDef.implementation?.instructions?.any {
it.opcode.ordinal == Opcode.CONST.ordinal && (it as WideLiteralInstruction).wideLiteral == CommentsResourcePatch.shortsCommentsButtonId
} == true
}
)

View File

@ -1,75 +0,0 @@
package app.revanced.patches.youtube.layout.hide.comments.bytecode.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.instruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.youtube.layout.hide.comments.annotations.CommentsCompatibility
import app.revanced.patches.youtube.layout.hide.comments.bytecode.fingerprints.ShortsCommentsButtonFingerprint
import app.revanced.patches.youtube.layout.hide.comments.resource.patch.CommentsResourcePatch
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Patch
@DependsOn([IntegrationsPatch::class, CommentsResourcePatch::class])
@Name("comments")
@Description("Hides components related to comments.")
@CommentsCompatibility
@Version("0.0.1")
class CommentsPatch : BytecodePatch(
listOf(
ShortsCommentsButtonFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
val checkCastAnchorFingerprint = object : MethodFingerprint(
opcodes = listOf(
Opcode.CONST,
Opcode.CONST_HIGH16,
Opcode.IF_EQZ,
Opcode.CONST,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
)
) {}
ShortsCommentsButtonFingerprint.result?.let {
it.mutableMethod.apply {
val checkCastAnchorIndex = checkCastAnchorFingerprint.also { result ->
if (!result.resolve(context, this, it.classDef))
throw checkCastAnchorFingerprint.toErrorResult()
}.result!!.scanResult.patternScanResult!!.endIndex
val shortsCommentsButtonRegister = instruction<OneRegisterInstruction>(checkCastAnchorIndex).registerA
val insertIndex = checkCastAnchorIndex + 1
addInstructions(
insertIndex,
"""
invoke-static { v$shortsCommentsButtonRegister }, $FILTER_METHOD_DESCRIPTOR
"""
)
}
} ?: return ShortsCommentsButtonFingerprint.toErrorResult()
return PatchResultSuccess()
}
private companion object {
private const val FILTER_METHOD_DESCRIPTOR =
"Lapp/revanced/integrations/patches/HideShortsCommentsButtonPatch;" +
"->hideShortsCommentsButton(Landroid/view/View;)V"
}
}

View File

@ -1,5 +1,6 @@
package app.revanced.patches.youtube.layout.hide.comments.resource.patch
package app.revanced.patches.youtube.layout.hide.comments.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
@ -7,22 +8,21 @@ import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.PreferenceScreen
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.layout.hide.comments.annotations.CommentsCompatibility
import app.revanced.patches.youtube.layout.hide.comments.annotations.HideCommentsCompatibility
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@Name("comments-resource-patch")
@CommentsCompatibility
@Patch
@Name("comments")
@Description("Hides components related to comments.")
@HideCommentsCompatibility
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@Version("0.0.1")
class CommentsResourcePatch : ResourcePatch {
companion object {
internal var shortsCommentsButtonId: Long = -1
}
class CommentsPatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
PreferenceScreen(
@ -40,22 +40,12 @@ class CommentsResourcePatch : ResourcePatch {
StringResource("revanced_hide_preview_comment_title", "Hide preview comment"),
StringResource("revanced_hide_preview_comment_on", "Preview comment is hidden"),
StringResource("revanced_hide_preview_comment_off", "Preview comment is shown")
),
SwitchPreference(
"revanced_hide_shorts_comments_button",
StringResource("revanced_hide_shorts_comments_button_title", "Hide shorts comments button"),
StringResource("revanced_hide_shorts_comments_button_on", "Shorts comments button is hidden"),
StringResource("revanced_hide_shorts_comments_button_off", "Shorts comments button is shown")
),
)
),
StringResource("revanced_comments_preference_screen_summary", "Manage the visibility of comments section components")
)
)
shortsCommentsButtonId = ResourceMappingPatch.resourceMappings.single {
it.type == "drawable" && it.name == "ic_right_comment_32c"
}.id
return PatchResultSuccess()
}
}

View File

@ -0,0 +1,8 @@
package app.revanced.patches.youtube.layout.hide.shorts.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37"))])
@Target(AnnotationTarget.CLASS)
internal annotation class HideShortsComponentsCompatibility

View File

@ -0,0 +1,19 @@
package app.revanced.patches.youtube.layout.hide.shorts.bytecode.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hide.shorts.resource.patch.HideShortsComponentsResourcePatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object CreateShortsButtonsFingerprint : MethodFingerprint(
parameters = listOf("Z", "Z", "L"),
customFingerprint = { methodDef, _ ->
methodDef.implementation?.instructions?.any {
if (it.opcode != Opcode.CONST) return@any false
val literal = (it as WideLiteralInstruction).wideLiteral
literal == HideShortsComponentsResourcePatch.reelPlayerRightLargeIconSize
} ?: false
}
)

View File

@ -0,0 +1,19 @@
package app.revanced.patches.youtube.layout.hide.shorts.bytecode.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hide.shorts.resource.patch.HideShortsComponentsResourcePatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object ReelConstructorFingerprint : MethodFingerprint(
opcodes = listOf(Opcode.INVOKE_VIRTUAL),
customFingerprint = { method, _ ->
method.implementation?.instructions?.any {
if (it.opcode != Opcode.CONST) return@any false
val literal = (it as WideLiteralInstruction).wideLiteral
literal == HideShortsComponentsResourcePatch.reelMultipleItemShelfId
} ?: false
}
)

View File

@ -0,0 +1,93 @@
package app.revanced.patches.youtube.layout.hide.shorts.bytecode.patch
import app.revanced.extensions.injectHideViewCall
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.instruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.youtube.layout.hide.shorts.annotations.HideShortsComponentsCompatibility
import app.revanced.patches.youtube.layout.hide.shorts.bytecode.fingerprints.CreateShortsButtonsFingerprint
import app.revanced.patches.youtube.layout.hide.shorts.bytecode.fingerprints.ReelConstructorFingerprint
import app.revanced.patches.youtube.layout.hide.shorts.resource.patch.HideShortsComponentsResourcePatch
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Patch
@DependsOn(
[
IntegrationsPatch::class,
LithoFilterPatch::class,
HideShortsComponentsResourcePatch::class,
ResourceMappingPatch::class
]
)
@Name("hide-shorts-components")
@Description("Hides components from YouTube Shorts.")
@HideShortsComponentsCompatibility
@Version("0.0.1")
class HideShortsComponentsPatch : BytecodePatch(listOf(CreateShortsButtonsFingerprint, ReelConstructorFingerprint)) {
override fun execute(context: BytecodeContext): PatchResult {
// Hide the Shorts shelf.
ReelConstructorFingerprint.result?.let {
it.mutableMethod.apply {
val insertIndex = it.scanResult.patternScanResult!!.startIndex + 2
val viewRegister = instruction<TwoRegisterInstruction>(insertIndex).registerA
injectHideViewCall(
insertIndex,
viewRegister,
CLASS_DESCRIPTOR,
"hideShortsShelf"
)
}
} ?: return ReelConstructorFingerprint.toErrorResult()
// Some Shorts buttons are views, hide them by setting their visibility to GONE.
CreateShortsButtonsFingerprint.result?.let {
ShortsButtons.values().forEach { button -> button.injectHideCall(it.mutableMethod) }
} ?: return CreateShortsButtonsFingerprint.toErrorResult()
return PatchResultSuccess()
}
private companion object {
private const val CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/components/ShortsFilter;"
private enum class ShortsButtons(private val resourceName: String, private val methodName: String) {
COMMENTS("reel_dyn_comment", "hideShortsCommentsButton"),
REMIX("reel_dyn_remix", "hideShortsRemixButton"),
SHARE("reel_dyn_share", "hideShortsShareButton");
fun injectHideCall(method: MutableMethod) {
val resourceId = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == resourceName
}.id
// Get the index of the reference to the view's resource ID.
val referencedIndex = method.implementation!!.instructions.indexOfFirst {
if (it.opcode != Opcode.CONST) return@indexOfFirst false
val literal = (it as WideLiteralInstruction).wideLiteral
return@indexOfFirst resourceId == literal
}
val setIdIndex = referencedIndex + 1
val viewRegister = method.instruction<FiveRegisterInstruction>(setIdIndex).registerC
method.injectHideViewCall(setIdIndex, viewRegister, CLASS_DESCRIPTOR, methodName)
}
}
}
}

View File

@ -0,0 +1,89 @@
package app.revanced.patches.youtube.layout.hide.shorts.resource.patch
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.PreferenceScreen
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@Version("0.0.1")
class HideShortsComponentsResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
PreferenceScreen(
"revanced_shorts",
StringResource("revanced_shorts_title", "Shorts components"),
listOf(
SwitchPreference(
"revanced_hide_shorts",
StringResource("revanced_hide_shorts_enabled_title", "Hide shorts"),
StringResource("revanced_hide_shorts_on", "Shorts are hidden"),
StringResource("revanced_hide_shorts_off", "Shorts are shown")
),
SwitchPreference(
"revanced_hide_shorts_join_button",
StringResource("revanced_hide_shorts_join_button_title", "Hide join button"),
StringResource("revanced_hide_shorts_join_button_on", "Join button is hidden"),
StringResource("revanced_hide_shorts_join_button_off", "Join button is shown")
),
SwitchPreference(
"revanced_hide_shorts_subscribe_button",
StringResource("revanced_hide_shorts_subscribe_button_title", "Hide subscribe button"),
StringResource("revanced_hide_shorts_subscribe_button_on", "Subscribe button is hidden"),
StringResource("revanced_hide_shorts_subscribe_button_off", "Subscribe button is shown")
),
SwitchPreference(
"revanced_hide_shorts_thanks_button",
StringResource("revanced_hide_shorts_thanks_button_title", "Hide thanks button"),
StringResource("revanced_hide_shorts_thanks_button_on", "Thanks button is hidden"),
StringResource("revanced_hide_shorts_thanks_button_off", "Thanks button is shown")
),
SwitchPreference(
"revanced_hide_shorts_comments_button",
StringResource("revanced_hide_shorts_comments_button_title", "Hide comments button"),
StringResource("revanced_hide_shorts_comments_button_on", "Comments button is hidden"),
StringResource("revanced_hide_shorts_comments_button_off", "Comments button is shown")
),
SwitchPreference(
"revanced_hide_shorts_remix_button",
StringResource("revanced_hide_shorts_remix_button_title", "Hide remix button"),
StringResource("revanced_hide_shorts_remix_button_on", "Remix button is hidden"),
StringResource("revanced_hide_shorts_remix_button_off", "Remix button is shown")
),
SwitchPreference(
"revanced_hide_shorts_share_button",
StringResource("revanced_hide_shorts_share_button_title", "Hide share button"),
StringResource("revanced_hide_shorts_share_button_on", "Share button is hidden"),
StringResource("revanced_hide_shorts_share_button_off", "Share button is shown")
),
SwitchPreference(
"revanced_hide_shorts_navigation_bar",
StringResource("revanced_hide_shorts_navigation_bar_title", "Hide navigation bar"),
StringResource("revanced_hide_shorts_navigation_bar_on", "Navigation bar is hidden"),
StringResource("revanced_hide_shorts_navigation_bar_off", "Navigation bar is shown")
),
),
StringResource("revanced_shorts_summary", "Manage the visibility of Shorts components")
)
)
fun String.getId() = ResourceMappingPatch.resourceMappings.single { it.name == this }.id
reelMultipleItemShelfId = "reel_multiple_items_shelf".getId()
reelPlayerRightLargeIconSize = "reel_player_right_large_icon_size".getId()
return PatchResultSuccess()
}
companion object {
var reelMultipleItemShelfId: Long = -1
var reelPlayerRightLargeIconSize = -1L
}
}

View File

@ -119,7 +119,7 @@ class LithoFilterPatch : BytecodePatch(
get() = (this as ReferenceInstruction).reference.toString()
const val FILTER_METHOD_DESCRIPTOR =
"Lapp/revanced/integrations/patches/litho/LithoFilterPatch;" +
"Lapp/revanced/integrations/patches/components/LithoFilterPatch;" +
"->filter(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/nio/ByteBuffer;)Z"
}
}