From 7db88c2dc892b7dc428e21a9eeb1b495da96b428 Mon Sep 17 00:00:00 2001 From: inotia00 Date: Tue, 10 Jan 2023 04:30:54 +0900 Subject: [PATCH] cleanup --- .../shuffle/patch/EnforceShufflePatch.kt | 2 +- .../general/resource/patch/GeneralAdsPatch.kt | 26 ++- .../button/whitelist/patch/WhitelistPatch.kt | 111 +++++---- .../fingerprints/LayoutSwitchFingerprint.kt | 5 +- .../patch/LayoutSwitchBytecodePatch.kt | 5 +- .../fingerprints/OldLayoutFingerprint.kt | 5 +- .../bytecode/patch/OldLayoutBytecodePatch.kt | 23 +- .../QualityMenuViewInflateFingerprint.kt | 6 +- .../patch/OldQualityLayoutBytecodePatch.kt | 26 +-- .../fingerprints/ScrubbingLabelFingerprint.kt | 6 +- .../HideFilmstripOverlayBytecodePatch.kt | 51 ++-- .../patch/HapticFeedBackBytecodePatch.kt | 67 +++--- .../StartVideoInformerFingerprint.kt | 19 +- .../fingerprints/SubtitleTrackFingerprint.kt | 5 +- .../patch/AutoCaptionsBytecodePatch.kt | 33 ++- .../EngagementPanelControllerFingerprint.kt | 4 +- .../patch/PlayerPopupPanelsBytecodePatch.kt | 24 +- .../CreateMixPlaylistFingerprint.kt | 5 +- .../FourthCreateMixPlaylistFingerprint.kt | 6 +- .../SecondCreateMixPlaylistFingerprint.kt | 5 +- .../ThirdCreateMixPlaylistFingerprint.kt | 6 +- .../patch/MixPlaylistsBytecodePatch.kt | 48 ++-- ...ntSwitcherAccessibilityLabelFingerprint.kt | 8 +- .../patch/HideEmailAddressBytecodePatch.kt | 28 ++- .../PivotBarCreateButtonViewFingerprint.kt | 6 +- .../fingerprints/PivotBarFingerprint.kt | 6 +- .../patch/CreateButtonRemoverBytecodePatch.kt | 6 +- .../patch/ShortsButtonRemoverBytecodePatch.kt | 75 +++--- .../patch/WideSearchbarBytecodePatch.kt | 9 +- .../LayoutConstructorFingerprint.kt | 4 +- .../patch/HideAutoplayButtonBytecodePatch.kt | 43 ++-- .../patch/HideCaptionsButtonBytecodePatch.kt | 32 +-- .../InfocardsIncognitoFingerprint.kt | 4 +- .../InfocardsIncognitoParentFingerprint.kt | 4 +- .../patch/HideInfoCardsBytecodePatch.kt | 16 +- .../UserAgentHeaderBuilderFingerprint.kt | 5 +- .../patch/ClientSpoofBytecodePatch.kt | 15 +- .../fingerprints/MaxBufferFingerprint.kt | 21 +- .../fingerprints/PlaybackBufferFingerprint.kt | 17 +- .../fingerprints/ReBufferFingerprint.kt | 17 +- .../ExternalBrowserPrimaryFingerprint.kt | 4 +- .../ExternalBrowserSecondaryFingerprint.kt | 4 +- .../ExternalBrowserTertiaryFingerprint.kt | 4 +- .../patch/ExternalBrowserBytecodePatch.kt | 22 +- .../OpenLinksDirectlyFingerprintPrimary.kt | 5 +- .../OpenLinksDirectlyFingerprintSecondary.kt | 5 +- .../patch/OpenLinksDirectlyBytecodePatch.kt | 35 +-- .../fingerprints/PrimaryPiPFingerprint.kt | 5 +- .../fingerprints/SecondaryPiPFingerprint.kt | 5 +- .../patch/PlayerControlsBytecodePatch.kt | 55 +++-- .../BottomControlsInflateFingerprint.kt | 6 +- .../ControlsLayoutInflateFingerprint.kt | 6 +- .../PlayerControlsVisibilityFingerprint.kt | 6 +- .../VisibilityNegatedFingerprint.kt | 5 +- .../VisibilityNegatedParentFingerprint.kt | 6 +- ...layerOverlaysOnFinishInflateFingerprint.kt | 4 +- .../patch/PlayerOverlaysHookPatch.kt | 13 +- .../playertype/patch/PlayerTypeHookPatch.kt | 6 +- .../ThemeSetterSystemFingerprint.kt | 8 +- .../bytecode/patch/SettingsBytecodePatch.kt | 30 +-- .../patch/SettingsSecondaryBytecodePatch.kt | 45 ---- .../swiperefresh/patch/SwipeRefreshPatch.kt | 16 +- .../fingerprint/LegacyVideoIdFingerprint.kt | 8 +- .../legacy/patch/LegacyVideoIdPatch.kt | 20 +- .../MainstreamVideoIdFingerprint.kt | 8 +- .../PlayerControllerFingerprint.kt | 3 +- .../fingerprint/VideoTimeFingerprint.kt | 5 +- .../patch/MainstreamVideoIdPatch.kt | 217 +++++++++--------- .../SwipeControlsHostActivityFingerprint.kt | 3 +- .../WatchWhileActivityFingerprint.kt | 3 +- .../patch/SwipeControlsBytecodePatch.kt | 7 +- .../resource/patch/SwipeControlsPatch.kt | 4 +- .../VideoQualityReferenceFingerprint.kt | 8 +- .../VideoQualitySetterFingerprint.kt | 8 +- .../VideoUserQualityChangeFingerprint.kt | 8 +- .../patch/VideoQualityBytecodePatch.kt | 66 +++--- .../integrations/AbstractIntegrationsPatch.kt | 3 +- 77 files changed, 807 insertions(+), 663 deletions(-) delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/patch/SettingsSecondaryBytecodePatch.kt diff --git a/src/main/kotlin/app/revanced/patches/music/layout/shuffle/patch/EnforceShufflePatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/shuffle/patch/EnforceShufflePatch.kt index b847eeaa5..f8fa5789a 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/shuffle/patch/EnforceShufflePatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/shuffle/patch/EnforceShufflePatch.kt @@ -101,7 +101,7 @@ class EnforceShufflePatch : BytecodePatch( ImmutableField( mutableMethod.definingClass, "shuffleclass", - "$SHUFFLE_CLASS", + SHUFFLE_CLASS, AccessFlags.PUBLIC or AccessFlags.STATIC, null, null, diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/general/resource/patch/GeneralAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/general/resource/patch/GeneralAdsPatch.kt index 63c36a26c..dee9553fd 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ads/general/resource/patch/GeneralAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ads/general/resource/patch/GeneralAdsPatch.kt @@ -38,6 +38,7 @@ class GeneralAdsPatch : ResourcePatch { "promotion_", "compact_premium_", "compact_promoted_", + "simple_text_section", ) private val replacements = arrayOf( @@ -46,6 +47,13 @@ class GeneralAdsPatch : ResourcePatch { "marginTop" ) + private val additionalReplacements = arrayOf( + "Bottom", + "End", + "Start", + "Top" + ) + override fun execute(context: ResourceContext): PatchResult { context.forEach { @@ -53,11 +61,11 @@ class GeneralAdsPatch : ResourcePatch { // for each file in the "layouts" directory replace all necessary attributes content context.xmlEditor[it.absolutePath].use { editor -> - editor.file.doRecursively { node -> + editor.file.doRecursively { replacements.forEach replacement@{ replacement -> - if (node !is Element) return@replacement + if (it !is Element) return@replacement - node.getAttributeNode("android:layout_$replacement")?.let { attribute -> + it.getAttributeNode("android:layout_$replacement")?.let { attribute -> attribute.textContent = "0.0dip" } } @@ -65,6 +73,18 @@ class GeneralAdsPatch : ResourcePatch { } } + context.xmlEditor["res/layout/simple_text_section.xml"].use { editor -> + editor.file.doRecursively { + additionalReplacements.forEach replacement@{ replacement -> + if (it !is Element) return@replacement + + it.getAttributeNode("android:padding_$replacement")?.let { attribute -> + attribute.textContent = "0.0dip" + } + } + } + } + /* add settings */ diff --git a/src/main/kotlin/app/revanced/patches/youtube/button/whitelist/patch/WhitelistPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/button/whitelist/patch/WhitelistPatch.kt index e6a864f53..5d9237f67 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/button/whitelist/patch/WhitelistPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/button/whitelist/patch/WhitelistPatch.kt @@ -4,18 +4,18 @@ 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.MethodFingerprintExtensions.name import app.revanced.patcher.extensions.or import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable import app.revanced.patcher.util.smali.toInstructions import app.revanced.patches.youtube.button.whitelist.fingerprint.* import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.util.integrations.Constants.VIDEO_PATH import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode import org.jf.dexlib2.builder.instruction.BuilderInstruction21c import org.jf.dexlib2.dexbacked.reference.DexBackedMethodReference import org.jf.dexlib2.iface.instruction.ReferenceInstruction @@ -23,7 +23,6 @@ import org.jf.dexlib2.iface.reference.FieldReference import org.jf.dexlib2.iface.reference.MethodReference import org.jf.dexlib2.immutable.ImmutableMethod import org.jf.dexlib2.immutable.ImmutableMethodImplementation -import org.jf.dexlib2.Opcode @Name("channel-whitelist") @YouTubeCompatibility @@ -37,34 +36,67 @@ class WhitelistPatch : BytecodePatch( ) ) { override fun execute(context: BytecodeContext): PatchResult { - val PlayerResponseModelParentResult = PlayerResponseModelParentFingerprint.result!! - val PlayerResponseModelParentInstructions = PlayerResponseModelParentResult.mutableMethod.implementation!!.instructions - val injectIndex = PlayerResponseModelParentInstructions.indexOfFirst { - it.opcode == Opcode.CONST_STRING && - (it as BuilderInstruction21c).reference.toString() == "Person" - } + 2 + PlayerResponseModelParentFingerprint.result?.mutableMethod?.let { method -> + val instructions = method.implementation!!.instructions + val injectIndex = instructions.indexOfFirst { + it.opcode == Opcode.CONST_STRING && + (it as BuilderInstruction21c).reference.toString() == "Person" + } + 2 + fourthRef = (instructions.elementAt(injectIndex) as ReferenceInstruction).reference as DexBackedMethodReference + } ?: return PlayerResponseModelParentFingerprint.toErrorResult() - val PlayerResponseModelReference = - PlayerResponseModelParentResult.method.let { method -> - (method.implementation!!.instructions.elementAt(injectIndex) as ReferenceInstruction).reference as DexBackedMethodReference + PlayerResponseModelFingerprint.result?.let { result -> + + with (result.method.implementation!!.instructions) { + firstRef = (elementAt(2) as ReferenceInstruction).reference as FieldReference + secondRef = (elementAt(3) as ReferenceInstruction).reference as FieldReference + thirdRef = (elementAt(4) as ReferenceInstruction).reference as MethodReference } + with (result.mutableClass) { + methods.add( + ImmutableMethod( + type, + "setCurrentVideoInformation", + listOf(), + "V", + AccessFlags.PRIVATE or AccessFlags.FINAL, + null, + null, + ImmutableMethodImplementation( + 2, """ + iget-object v0, v1, ${result.classDef.type}->${firstRef.name}:${firstRef.type} + iget-object v0, v0, ${firstRef.type}->${secondRef.name}:${secondRef.type} + invoke-interface {v0}, $thirdRef + move-result-object v0 + invoke-interface {v0}, $fourthRef + move-result-object v0 + invoke-static {v0}, $VIDEO_PATH/VideoInformation;->setChannelName(Ljava/lang/String;)V + return-void + """.toInstructions(), null, null + ) + ).toMutable() + ) + } + + listOf( + PrimaryInjectFingerprint, + SecondaryInjectFingerprint + ).map { + it.result ?: return it.toErrorResult() + }.forEach { + val method = it.mutableMethod + val index = it.scanResult.patternScanResult!!.endIndex + 1 + method.addInstruction( + index, + "invoke-direct {p0}, ${result.classDef.type}->setCurrentVideoInformation()V" + ) + } + } ?: return PlayerResponseModelFingerprint.toErrorResult() + val PlayerResponseModelResult = PlayerResponseModelFingerprint.result!! - val PrimaryReference = - PlayerResponseModelResult.method.let { method -> - (method.implementation!!.instructions.elementAt(2) as ReferenceInstruction).reference as FieldReference - } - val SecondaryReference = - PlayerResponseModelResult.method.let { method -> - (method.implementation!!.instructions.elementAt(3) as ReferenceInstruction).reference as FieldReference - } - val TertiaryReference = - PlayerResponseModelResult.method.let { method -> - (method.implementation!!.instructions.elementAt(4) as ReferenceInstruction).reference as MethodReference - } - val classDef = PlayerResponseModelResult.mutableClass classDef.methods.add( ImmutableMethod( @@ -77,11 +109,11 @@ class WhitelistPatch : BytecodePatch( null, ImmutableMethodImplementation( 2, """ - iget-object v0, v1, ${PlayerResponseModelResult.classDef.type}->${PrimaryReference.name}:${PrimaryReference.type} - iget-object v0, v0, ${PrimaryReference.type}->${SecondaryReference.name}:${SecondaryReference.type} - invoke-interface {v0}, $TertiaryReference + iget-object v0, v1, ${PlayerResponseModelResult.classDef.type}->${firstRef.name}:${firstRef.type} + iget-object v0, v0, ${firstRef.type}->${secondRef.name}:${secondRef.type} + invoke-interface {v0}, $thirdRef move-result-object v0 - invoke-interface {v0}, $PlayerResponseModelReference + invoke-interface {v0}, $fourthRef move-result-object v0 invoke-static {v0}, $VIDEO_PATH/VideoInformation;->setChannelName(Ljava/lang/String;)V return-void @@ -90,20 +122,13 @@ class WhitelistPatch : BytecodePatch( ).toMutable() ) - - listOf( - PrimaryInjectFingerprint, - SecondaryInjectFingerprint - ).forEach { fingerprint -> - val result = fingerprint.result ?: return PatchResultError("${fingerprint.name} not found") - val method = result.mutableMethod - val index = result.scanResult.patternScanResult!!.endIndex + 1 - method.addInstruction( - index, - "invoke-direct {p0}, ${PlayerResponseModelResult.classDef.type}->setCurrentVideoInformation()V" - ) - } - return PatchResultSuccess() } + + companion object { + private lateinit var firstRef: FieldReference + private lateinit var secondRef: FieldReference + private lateinit var thirdRef: MethodReference + private lateinit var fourthRef: DexBackedMethodReference + } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/extended/layoutswitch/bytecode/fingerprints/LayoutSwitchFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/extended/layoutswitch/bytecode/fingerprints/LayoutSwitchFingerprint.kt index 13e3cc57c..0153574bf 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/extended/layoutswitch/bytecode/fingerprints/LayoutSwitchFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/extended/layoutswitch/bytecode/fingerprints/LayoutSwitchFingerprint.kt @@ -6,7 +6,10 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object LayoutSwitchFingerprint : MethodFingerprint( - "I", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L"), listOf( + returnType = "I", + access = AccessFlags.PUBLIC or AccessFlags.STATIC, + parameters = listOf("L"), + opcodes = listOf( Opcode.INVOKE_VIRTUAL, Opcode.MOVE_RESULT_OBJECT, Opcode.INVOKE_STATIC, diff --git a/src/main/kotlin/app/revanced/patches/youtube/extended/layoutswitch/bytecode/patch/LayoutSwitchBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/extended/layoutswitch/bytecode/patch/LayoutSwitchBytecodePatch.kt index ebd92c4d4..33e458092 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/extended/layoutswitch/bytecode/patch/LayoutSwitchBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/extended/layoutswitch/bytecode/patch/LayoutSwitchBytecodePatch.kt @@ -9,6 +9,7 @@ import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patches.youtube.extended.layoutswitch.bytecode.fingerprints.LayoutSwitchFingerprint import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.util.integrations.Constants.EXTENDED_PATH @Name("layout-switch-bytecode-patch") @@ -21,12 +22,12 @@ class LayoutSwitchBytecodePatch : BytecodePatch( ) { override fun execute(context: BytecodeContext): PatchResult { - LayoutSwitchFingerprint.result!!.mutableMethod.addInstructions( + LayoutSwitchFingerprint.result?.mutableMethod?.addInstructions( 4, """ invoke-static {p0}, $EXTENDED_PATH/LayoutOverridePatch;->getLayoutOverride(I)I move-result p0 """ - ) + ) ?: return LayoutSwitchFingerprint.toErrorResult() return PatchResultSuccess() } diff --git a/src/main/kotlin/app/revanced/patches/youtube/extended/oldlayout/bytecode/fingerprints/OldLayoutFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/extended/oldlayout/bytecode/fingerprints/OldLayoutFingerprint.kt index 3f9a4267c..95b840212 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/extended/oldlayout/bytecode/fingerprints/OldLayoutFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/extended/oldlayout/bytecode/fingerprints/OldLayoutFingerprint.kt @@ -6,7 +6,10 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object OldLayoutFingerprint : MethodFingerprint( - "L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L"), listOf( + returnType = "L", + access = AccessFlags.PUBLIC or AccessFlags.STATIC, + parameters = listOf("L"), + opcodes = listOf( Opcode.IGET_OBJECT, Opcode.GOTO, Opcode.CONST_STRING, diff --git a/src/main/kotlin/app/revanced/patches/youtube/extended/oldlayout/bytecode/patch/OldLayoutBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/extended/oldlayout/bytecode/patch/OldLayoutBytecodePatch.kt index 10db84dde..b2a045c04 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/extended/oldlayout/bytecode/patch/OldLayoutBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/extended/oldlayout/bytecode/patch/OldLayoutBytecodePatch.kt @@ -9,6 +9,7 @@ import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patches.youtube.extended.oldlayout.bytecode.fingerprints.OldLayoutFingerprint import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.util.integrations.Constants.EXTENDED_PATH import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @@ -22,17 +23,19 @@ class OldLayoutBytecodePatch : BytecodePatch( ) { override fun execute(context: BytecodeContext): PatchResult { - val result = OldLayoutFingerprint.result!! - val method = result.mutableMethod - val index = result.scanResult.patternScanResult!!.startIndex - val register = (method.implementation!!.instructions[index] as OneRegisterInstruction).registerA + OldLayoutFingerprint.result?.let { + val insertIndex = it.scanResult.patternScanResult!!.startIndex - method.addInstructions( - index + 1, """ - invoke-static {v$register}, $EXTENDED_PATH/VersionOverridePatch;->getVersionOverride(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$register - """ - ) + with (it.mutableMethod) { + val register = (this.implementation!!.instructions[insertIndex] as OneRegisterInstruction).registerA + addInstructions( + insertIndex + 1, """ + invoke-static {v$register}, $EXTENDED_PATH/VersionOverridePatch;->getVersionOverride(Ljava/lang/String;)Ljava/lang/String; + move-result-object v$register + """ + ) + } + } ?: return OldLayoutFingerprint.toErrorResult() return PatchResultSuccess() } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/flyoutpanel/oldqualitylayout/bytecode/fingerprints/QualityMenuViewInflateFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/flyoutpanel/oldqualitylayout/bytecode/fingerprints/QualityMenuViewInflateFingerprint.kt index 053dd6d84..bfd6753b8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/flyoutpanel/oldqualitylayout/bytecode/fingerprints/QualityMenuViewInflateFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/flyoutpanel/oldqualitylayout/bytecode/fingerprints/QualityMenuViewInflateFingerprint.kt @@ -8,9 +8,9 @@ import org.jf.dexlib2.Opcode object QualityMenuViewInflateFingerprint : MethodFingerprint( opcodes = listOf(Opcode.INVOKE_SUPER), customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.videoqualityfragmentLabelId + methodDef.implementation?.instructions?.any { + it.opcode.ordinal == Opcode.CONST.ordinal && + (it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.videoqualityfragmentLabelId } == true } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/flyoutpanel/oldqualitylayout/bytecode/patch/OldQualityLayoutBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/flyoutpanel/oldqualitylayout/bytecode/patch/OldQualityLayoutBytecodePatch.kt index 3abf75d26..2defce33e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/flyoutpanel/oldqualitylayout/bytecode/patch/OldQualityLayoutBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/flyoutpanel/oldqualitylayout/bytecode/patch/OldQualityLayoutBytecodePatch.kt @@ -3,12 +3,13 @@ package app.revanced.patches.youtube.layout.flyoutpanel.oldqualitylayout.bytecod 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.addInstructions import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patches.youtube.layout.flyoutpanel.oldqualitylayout.bytecode.fingerprints.QualityMenuViewInflateFingerprint import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.util.integrations.Constants.FLYOUTPANEL_LAYOUT import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction @@ -19,21 +20,18 @@ class OldQualityLayoutBytecodePatch : BytecodePatch( listOf(QualityMenuViewInflateFingerprint) ) { override fun execute(context: BytecodeContext): PatchResult { - val inflateFingerprintResult = QualityMenuViewInflateFingerprint.result!! - val method = inflateFingerprintResult.mutableMethod - val instructions = method.implementation!!.instructions - // at this index the listener is added to the list view - val listenerInvokeRegister = instructions.size - 1 - 1 + QualityMenuViewInflateFingerprint.result?.mutableMethod?.let { + with (it.implementation!!.instructions) { + val insertIndex = this.size - 1 - 1 + val register = (this[insertIndex] as FiveRegisterInstruction).registerC - // get the register which stores the quality menu list view - val onItemClickViewRegister = (instructions[listenerInvokeRegister] as FiveRegisterInstruction).registerC - - // insert the integrations method - method.addInstruction( - listenerInvokeRegister, // insert the integrations instructions right before the listener - "invoke-static { v$onItemClickViewRegister }, $FLYOUTPANEL_LAYOUT->enableOldQualityMenu(Landroid/widget/ListView;)V" - ) + it.addInstructions( + insertIndex, // insert the integrations instructions right before the listener + "invoke-static { v$register }, $FLYOUTPANEL_LAYOUT->enableOldQualityMenu(Landroid/widget/ListView;)V" + ) + } + } ?: return QualityMenuViewInflateFingerprint.toErrorResult() return PatchResultSuccess() } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/fullscreen/flimstripoverlay/bytecode/fingerprints/ScrubbingLabelFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/fullscreen/flimstripoverlay/bytecode/fingerprints/ScrubbingLabelFingerprint.kt index 85378ad19..d555aa00c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/fullscreen/flimstripoverlay/bytecode/fingerprints/ScrubbingLabelFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/fullscreen/flimstripoverlay/bytecode/fingerprints/ScrubbingLabelFingerprint.kt @@ -8,9 +8,9 @@ import org.jf.dexlib2.Opcode object ScrubbingLabelFingerprint : MethodFingerprint( opcodes = listOf(Opcode.IPUT_BOOLEAN), customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.scrubbingLabelId + methodDef.implementation?.instructions?.any { + it.opcode.ordinal == Opcode.CONST.ordinal && + (it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.scrubbingLabelId } == true } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/fullscreen/flimstripoverlay/bytecode/patch/HideFilmstripOverlayBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/fullscreen/flimstripoverlay/bytecode/patch/HideFilmstripOverlayBytecodePatch.kt index 9739bc807..7b49ca7e1 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/fullscreen/flimstripoverlay/bytecode/patch/HideFilmstripOverlayBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/fullscreen/flimstripoverlay/bytecode/patch/HideFilmstripOverlayBytecodePatch.kt @@ -7,14 +7,16 @@ import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.removeInstruction import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patches.youtube.layout.fullscreen.flimstripoverlay.bytecode.fingerprints.ScrubbingLabelFingerprint import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.util.integrations.Constants.FULLSCREEN_LAYOUT +import org.jf.dexlib2.Opcode import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction import org.jf.dexlib2.iface.reference.FieldReference -import org.jf.dexlib2.Opcode @Name("hide-filmstrip-overlay-bytecode-patch") @YouTubeCompatibility @@ -25,32 +27,33 @@ class HideFilmstripOverlayBytecodePatch : BytecodePatch( ) ) { override fun execute(context: BytecodeContext): PatchResult { - val scrubbingLabelResult = ScrubbingLabelFingerprint.result!! - val scrubbingLabelMethod = scrubbingLabelResult.mutableMethod - val scrubbingLabelMethodInstructions = scrubbingLabelMethod.implementation!!.instructions + ScrubbingLabelFingerprint.result?.mutableMethod?.let { + with (it.implementation!!.instructions) { + for ((index, instruction) in this.withIndex()) { + if (instruction.opcode != Opcode.IPUT_BOOLEAN) continue + val primaryRegister = (instruction as TwoRegisterInstruction).registerA + val secondaryRegister = (instruction as TwoRegisterInstruction).registerB + val dummyRegister = primaryRegister + 2 + val fieldReference = (instruction as ReferenceInstruction).reference as FieldReference - for ((index, instruction) in scrubbingLabelMethodInstructions.withIndex()) { - if (instruction.opcode != Opcode.IPUT_BOOLEAN) continue - val scrubbingLabelRegisterA = (instruction as TwoRegisterInstruction).registerA - val scrubbingLabelRegisterB = scrubbingLabelRegisterA + 2 - val scrubbingLabelRegisterC = (instruction as TwoRegisterInstruction).registerB - val scrubbingLabelReference = (instruction as ReferenceInstruction).reference as FieldReference + it.addInstructions( + index + 1, """ + invoke-static {}, $FULLSCREEN_LAYOUT->hideFilmstripOverlay()Z + move-result v$dummyRegister + if-eqz v$dummyRegister, :show + const/4 v$primaryRegister, 0x0 + :show + iput-boolean v$primaryRegister, v$secondaryRegister, ${fieldReference.definingClass}->${fieldReference.name}:${fieldReference.type} + """ + ) - scrubbingLabelMethod.addInstructions( - index + 1, """ - invoke-static {}, $FULLSCREEN_LAYOUT->hideFilmstripOverlay()Z - move-result v$scrubbingLabelRegisterB - if-eqz v$scrubbingLabelRegisterB, :show - const/4 v$scrubbingLabelRegisterA, 0x0 - :show - iput-boolean v$scrubbingLabelRegisterA, v$scrubbingLabelRegisterC, ${scrubbingLabelReference.definingClass}->${scrubbingLabelReference.name}:${scrubbingLabelReference.type} - """ - ) + it.removeInstruction(index) - scrubbingLabelMethod.removeInstruction(index) - break - } + return PatchResultSuccess() + } + } + } ?: return ScrubbingLabelFingerprint.toErrorResult() - return PatchResultSuccess() + return PatchResultError("Could not find the method to hook.") } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/fullscreen/hapticfeedback/bytecode/patch/HapticFeedBackBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/fullscreen/hapticfeedback/bytecode/patch/HapticFeedBackBytecodePatch.kt index 8b5233b81..76017aa44 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/fullscreen/hapticfeedback/bytecode/patch/HapticFeedBackBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/fullscreen/hapticfeedback/bytecode/patch/HapticFeedBackBytecodePatch.kt @@ -6,13 +6,14 @@ import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.instruction import app.revanced.patcher.extensions.removeInstruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.youtube.layout.fullscreen.hapticfeedback.bytecode.fingerprints.* import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.util.integrations.Constants.FULLSCREEN_LAYOUT import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @@ -29,27 +30,36 @@ class HapticFeedBackBytecodePatch : BytecodePatch( ) { override fun execute(context: BytecodeContext): PatchResult { - SeekHapticsFingerprint.disableHaptics("disableSeekVibrate") - ScrubbingHapticsFingerprint.voidHaptics("disableScrubbingVibrate") - MarkerHapticsFingerprint.voidHaptics("disableChapterVibrate") - ZoomHapticsFingerprint.voidHaptics("disableZoomVibrate") + arrayOf( + SeekHapticsFingerprint to "disableSeekVibrate", + ScrubbingHapticsFingerprint to "disableScrubbingVibrate", + MarkerHapticsFingerprint to "disableChapterVibrate", + ZoomHapticsFingerprint to "disableZoomVibrate" + ).map { (fingerprint, name) -> + fingerprint.result?.let { + if (fingerprint == SeekHapticsFingerprint) + it.disableHaptics(name) + else + it.voidHaptics(name) + } ?: return fingerprint.toErrorResult() + } return PatchResultSuccess() } private companion object { - fun MethodFingerprint.disableHaptics(targetMethodName: String) { - with(this.result!!) { - val startIndex = scanResult.patternScanResult!!.startIndex - val endIndex = scanResult.patternScanResult!!.endIndex - val insertIndex = endIndex + 4 - val targetRegister = (method.implementation!!.instructions.elementAt(insertIndex) as OneRegisterInstruction).registerA - val dummyRegister = targetRegister + 1 + fun MethodFingerprintResult.disableHaptics(targetMethodName: String) { + val startIndex = scanResult.patternScanResult!!.startIndex + val endIndex = scanResult.patternScanResult!!.endIndex + val insertIndex = endIndex + 4 + val targetRegister = (method.implementation!!.instructions.elementAt(insertIndex) as OneRegisterInstruction).registerA + val dummyRegister = targetRegister + 1 - mutableMethod.removeInstruction(insertIndex) + with (mutableMethod) { + removeInstruction(insertIndex) - mutableMethod.addInstructions( - insertIndex, """ + addInstructions( + insertIndex, """ invoke-static {}, $FULLSCREEN_LAYOUT->$targetMethodName()Z move-result v$dummyRegister if-eqz v$dummyRegister, :vibrate @@ -57,31 +67,30 @@ class HapticFeedBackBytecodePatch : BytecodePatch( goto :exit :vibrate const-wide/16 v$targetRegister, 0x19 - """, listOf(ExternalLabel("exit", mutableMethod.instruction(insertIndex))) - ) + """, listOf(ExternalLabel("exit", mutableMethod.instruction(insertIndex))) + ) - mutableMethod.addInstructions( - startIndex, """ + addInstructions( + startIndex, """ invoke-static {}, $FULLSCREEN_LAYOUT->$targetMethodName()Z move-result v$dummyRegister if-eqz v$dummyRegister, :vibrate return-void - """, listOf(ExternalLabel("vibrate", mutableMethod.instruction(startIndex))) - ) + """, listOf(ExternalLabel("vibrate", mutableMethod.instruction(startIndex))) + ) } } - fun MethodFingerprint.voidHaptics(targetMethodName: String) { - with(this.result!!) { - mutableMethod.addInstructions( - 0, """ + fun MethodFingerprintResult.voidHaptics(targetMethodName: String) { + mutableMethod.addInstructions( + 0, """ invoke-static {}, $FULLSCREEN_LAYOUT->$targetMethodName()Z move-result v0 if-eqz v0, :vibrate return-void - """, listOf(ExternalLabel("vibrate", mutableMethod.instruction(0))) - ) - } + """, listOf(ExternalLabel("vibrate", mutableMethod.instruction(0))) + ) } } -} \ No newline at end of file +} + diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/autocaptions/bytecode/fingerprints/StartVideoInformerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/autocaptions/bytecode/fingerprints/StartVideoInformerFingerprint.kt index dfea63c3c..40e48972c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/general/autocaptions/bytecode/fingerprints/StartVideoInformerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/autocaptions/bytecode/fingerprints/StartVideoInformerFingerprint.kt @@ -6,18 +6,11 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object StartVideoInformerFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L", "L", "L", "L"), listOf( - Opcode.INVOKE_STATIC, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + opcodes = listOf( Opcode.INVOKE_INTERFACE, - Opcode.IF_EQZ, - Opcode.CONST_STRING, - Opcode.INVOKE_INTERFACE, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - ) + Opcode.RETURN_VOID, + ), + strings = listOf("pc") ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/autocaptions/bytecode/fingerprints/SubtitleTrackFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/autocaptions/bytecode/fingerprints/SubtitleTrackFingerprint.kt index 5176bb937..a64c4b610 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/general/autocaptions/bytecode/fingerprints/SubtitleTrackFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/autocaptions/bytecode/fingerprints/SubtitleTrackFingerprint.kt @@ -6,7 +6,10 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object SubtitleTrackFingerprint : MethodFingerprint( - "Z", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf( + returnType = "Z", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf(), + opcodes = listOf( Opcode.CONST_STRING, Opcode.INVOKE_VIRTUAL, Opcode.MOVE_RESULT_OBJECT, diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/autocaptions/bytecode/patch/AutoCaptionsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/autocaptions/bytecode/patch/AutoCaptionsBytecodePatch.kt index 4db27afd5..cefdabc01 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/general/autocaptions/bytecode/patch/AutoCaptionsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/autocaptions/bytecode/patch/AutoCaptionsBytecodePatch.kt @@ -7,13 +7,12 @@ import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.instruction import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.extensions.MethodFingerprintExtensions.name import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.youtube.layout.general.autocaptions.bytecode.fingerprints.* import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.fingerprints.SubtitleButtonControllerFingerprint import app.revanced.shared.util.integrations.Constants.GENERAL_LAYOUT @@ -32,8 +31,8 @@ class AutoCaptionsBytecodePatch : BytecodePatch( StartVideoInformerFingerprint.toPatch(Status.DISABLED), SubtitleButtonControllerFingerprint.toPatch(Status.ENABLED) ).forEach { (fingerprint, status) -> - with(fingerprint.result ?: return PatchResultError("Failed to find ${fingerprint.name} method.")) { - mutableMethod.addInstructions( + with(fingerprint.result?.mutableMethod ?: return fingerprint.toErrorResult()) { + addInstructions( 0, """ const/4 v0, ${status.value} @@ -43,19 +42,19 @@ class AutoCaptionsBytecodePatch : BytecodePatch( } } - val subtitleTrackMethod = SubtitleTrackFingerprint.result!!.mutableMethod - - subtitleTrackMethod.addInstructions( - 0, """ - invoke-static {}, $GENERAL_LAYOUT->hideAutoCaptions()Z - move-result v0 - if-eqz v0, :auto_captions_shown - sget-boolean v0, $GENERAL_LAYOUT->captionsButtonStatus:Z - if-nez v0, :auto_captions_shown - const/4 v0, 0x1 - return v0 - """, listOf(ExternalLabel("auto_captions_shown", subtitleTrackMethod.instruction(0))) - ) + SubtitleTrackFingerprint.result?.mutableMethod?.let { + it.addInstructions( + 0, """ + invoke-static {}, $GENERAL_LAYOUT->hideAutoCaptions()Z + move-result v0 + if-eqz v0, :auto_captions_shown + sget-boolean v0, $GENERAL_LAYOUT->captionsButtonStatus:Z + if-nez v0, :auto_captions_shown + const/4 v0, 0x1 + return v0 + """, listOf(ExternalLabel("auto_captions_shown", it.instruction(0))) + ) + } ?: return SubtitleTrackFingerprint.toErrorResult() return PatchResultSuccess() } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/autopopuppanels/bytecode/fingerprints/EngagementPanelControllerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/autopopuppanels/bytecode/fingerprints/EngagementPanelControllerFingerprint.kt index 75b979f34..12c6e8ff3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/general/autopopuppanels/bytecode/fingerprints/EngagementPanelControllerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/autopopuppanels/bytecode/fingerprints/EngagementPanelControllerFingerprint.kt @@ -5,8 +5,8 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import org.jf.dexlib2.AccessFlags object EngagementPanelControllerFingerprint : MethodFingerprint( - "L", - AccessFlags.PRIVATE or AccessFlags.FINAL, + returnType = "L", + access = AccessFlags.PRIVATE or AccessFlags.FINAL, strings = listOf( "EngagementPanelController: cannot show EngagementPanel before EngagementPanelController.init() has been called.", "[EngagementPanel] Cannot show EngagementPanel before EngagementPanelController.init() has been called." diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/autopopuppanels/bytecode/patch/PlayerPopupPanelsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/autopopuppanels/bytecode/patch/PlayerPopupPanelsBytecodePatch.kt index c56f9bda9..e247f7bc2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/general/autopopuppanels/bytecode/patch/PlayerPopupPanelsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/autopopuppanels/bytecode/patch/PlayerPopupPanelsBytecodePatch.kt @@ -11,6 +11,7 @@ import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.youtube.layout.general.autopopuppanels.bytecode.fingerprints.EngagementPanelControllerFingerprint import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.util.integrations.Constants.GENERAL_LAYOUT @Name("hide-auto-player-popup-panels-bytecode-patch") @@ -22,18 +23,19 @@ class PlayerPopupPanelsBytecodePatch : BytecodePatch( ) ) { override fun execute(context: BytecodeContext): PatchResult { - val engagementPanelControllerMethod = EngagementPanelControllerFingerprint.result!!.mutableMethod - engagementPanelControllerMethod.addInstructions( - 0, """ - invoke-static { }, $GENERAL_LAYOUT->hideAutoPlayerPopupPanels()Z - move-result v0 - if-eqz v0, :player_popup_panels_shown - if-eqz p4, :player_popup_panels_shown - const/4 v0, 0x0 - return-object v0 - """, listOf(ExternalLabel("player_popup_panels_shown", engagementPanelControllerMethod.instruction(0))) - ) + EngagementPanelControllerFingerprint.result?.mutableMethod?.let { + it.addInstructions( + 0, """ + invoke-static {}, $GENERAL_LAYOUT->hideAutoPlayerPopupPanels()Z + move-result v0 + if-eqz v0, :player_popup_panels_shown + if-eqz p4, :player_popup_panels_shown + const/4 v0, 0x0 + return-object v0 + """, listOf(ExternalLabel("player_popup_panels_shown", it.instruction(0))) + ) + } ?: return EngagementPanelControllerFingerprint.toErrorResult() return PatchResultSuccess() } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/fingerprints/CreateMixPlaylistFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/fingerprints/CreateMixPlaylistFingerprint.kt index adda6b0de..07fcc5ef8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/fingerprints/CreateMixPlaylistFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/fingerprints/CreateMixPlaylistFingerprint.kt @@ -12,7 +12,10 @@ import org.jf.dexlib2.Opcode @YouTubeCompatibility @Version("0.0.1") object CreateMixPlaylistFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L", "L", "L", "L", "L"), listOf( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + parameters = listOf("L", "L", "L", "L", "L", "L", "L"), + opcodes = listOf( Opcode.INVOKE_DIRECT, Opcode.IPUT_OBJECT, Opcode.INVOKE_VIRTUAL, diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/fingerprints/FourthCreateMixPlaylistFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/fingerprints/FourthCreateMixPlaylistFingerprint.kt index df82ff6f5..fa70e701d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/fingerprints/FourthCreateMixPlaylistFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/fingerprints/FourthCreateMixPlaylistFingerprint.kt @@ -21,9 +21,9 @@ object FourthCreateMixPlaylistFingerprint : MethodFingerprint( Opcode.CHECK_CAST ), customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.abclistmenuitemLabelId + methodDef.implementation?.instructions?.any { + it.opcode.ordinal == Opcode.CONST.ordinal && + (it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.abclistmenuitemLabelId } == true } ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/fingerprints/SecondCreateMixPlaylistFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/fingerprints/SecondCreateMixPlaylistFingerprint.kt index c164710ca..d3148ca82 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/fingerprints/SecondCreateMixPlaylistFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/fingerprints/SecondCreateMixPlaylistFingerprint.kt @@ -12,7 +12,10 @@ import org.jf.dexlib2.Opcode @YouTubeCompatibility @Version("0.0.1") object SecondCreateMixPlaylistFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L", "L", "L", "L"), listOf( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + parameters = listOf("L", "L", "L", "L", "L", "L"), + opcodes = listOf( Opcode.INVOKE_DIRECT, Opcode.IPUT_OBJECT, Opcode.INVOKE_VIRTUAL, diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/fingerprints/ThirdCreateMixPlaylistFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/fingerprints/ThirdCreateMixPlaylistFingerprint.kt index f7fba27cc..7117f7194 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/fingerprints/ThirdCreateMixPlaylistFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/fingerprints/ThirdCreateMixPlaylistFingerprint.kt @@ -21,9 +21,9 @@ object ThirdCreateMixPlaylistFingerprint : MethodFingerprint( Opcode.IPUT_OBJECT ), customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.bottompaneloverlaytextLabelId + methodDef.implementation?.instructions?.any { + it.opcode.ordinal == Opcode.CONST.ordinal && + (it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.bottompaneloverlaytextLabelId } == true } ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/patch/MixPlaylistsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/patch/MixPlaylistsBytecodePatch.kt index 998c6ebe4..e75567b44 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/patch/MixPlaylistsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/mixplaylists/bytecode/patch/MixPlaylistsBytecodePatch.kt @@ -4,13 +4,14 @@ 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.fingerprint.method.impl.MethodFingerprint +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patches.youtube.layout.general.mixplaylists.bytecode.fingerprints.* import app.revanced.shared.annotation.YouTubeCompatibility import app.revanced.shared.extensions.injectHideCall +import app.revanced.shared.extensions.toErrorResult import org.jf.dexlib2.iface.instruction.Instruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction @@ -29,34 +30,41 @@ class MixPlaylistsBytecodePatch : BytecodePatch( ) { override fun execute(context: BytecodeContext): PatchResult { - arrayOf(CreateMixPlaylistFingerprint, SecondCreateMixPlaylistFingerprint).forEach(::addHook) - ThirdCreateMixPlaylistFingerprint.hookMixPlaylists(true) - FourthCreateMixPlaylistFingerprint.hookMixPlaylists(false) + arrayOf( + CreateMixPlaylistFingerprint, + SecondCreateMixPlaylistFingerprint + ).map { + it.result ?: return it.toErrorResult() + }.forEach { + it.addHook() + } + + arrayOf( + ThirdCreateMixPlaylistFingerprint to true, + FourthCreateMixPlaylistFingerprint to false + ).map { (fingerprint, boolean) -> + fingerprint.result?.hookMixPlaylists(boolean) ?: return fingerprint.toErrorResult() + } return PatchResultSuccess() } - private fun addHook(fingerprint: MethodFingerprint) { - with (fingerprint.result!!) { - val insertIndex = scanResult.patternScanResult!!.endIndex - 3 + private fun MethodFingerprintResult.addHook() { + val insertIndex = scanResult.patternScanResult!!.endIndex - 3 + val register = (mutableMethod.instruction(insertIndex - 2) as OneRegisterInstruction).registerA - val register = (mutableMethod.instruction(insertIndex - 2) as OneRegisterInstruction).registerA - - mutableMethod.implementation!!.injectHideCall(insertIndex, register, "layout/GeneralLayoutPatch", "hideMixPlaylists") - } + mutableMethod.implementation!!.injectHideCall(insertIndex, register, "layout/GeneralLayoutPatch", "hideMixPlaylists") } - fun MethodFingerprint.hookMixPlaylists(isThirdFingerprint: Boolean) { + private fun MethodFingerprintResult.hookMixPlaylists(isThirdFingerprint: Boolean) { fun getRegister(instruction: Instruction): Int { - if (isThirdFingerprint) return (instruction as TwoRegisterInstruction).registerA - return (instruction as Instruction21c).registerA + if (isThirdFingerprint) return (instruction as TwoRegisterInstruction).registerA + return (instruction as Instruction21c).registerA } - with(this.result!!) { - val endIndex = scanResult.patternScanResult!!.endIndex - val instruction = method.implementation!!.instructions.elementAt(endIndex) - val register = getRegister(instruction) + val endIndex = scanResult.patternScanResult!!.endIndex + val instruction = method.implementation!!.instructions.elementAt(endIndex) + val register = getRegister(instruction) - mutableMethod.implementation!!.injectHideCall(endIndex, register, "layout/GeneralLayoutPatch", "hideMixPlaylists") - } + mutableMethod.implementation!!.injectHideCall(endIndex, register, "layout/GeneralLayoutPatch", "hideMixPlaylists") } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/personalinformation/bytecode/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/personalinformation/bytecode/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt index 974a0da4d..71be141f7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/general/personalinformation/bytecode/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/personalinformation/bytecode/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt @@ -19,12 +19,12 @@ object AccountSwitcherAccessibilityLabelFingerprint : MethodFingerprint( Opcode.NEW_ARRAY, Opcode.CONST_4, Opcode.APUT_OBJECT, - Opcode.CONST, + Opcode.CONST ), customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.accountSwitcherAccessibilityLabelId + methodDef.implementation?.instructions?.any { it -> + it.opcode.ordinal == Opcode.CONST.ordinal && + (it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.accountSwitcherAccessibilityLabelId } == true } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/personalinformation/bytecode/patch/HideEmailAddressBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/personalinformation/bytecode/patch/HideEmailAddressBytecodePatch.kt index 7581a7215..d1955cbd3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/general/personalinformation/bytecode/patch/HideEmailAddressBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/personalinformation/bytecode/patch/HideEmailAddressBytecodePatch.kt @@ -10,6 +10,7 @@ import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patches.youtube.layout.general.personalinformation.bytecode.fingerprints.AccountSwitcherAccessibilityLabelFingerprint import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.util.integrations.Constants.GENERAL_LAYOUT import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @@ -22,23 +23,20 @@ class HideEmailAddressBytecodePatch : BytecodePatch( ) ) { override fun execute(context: BytecodeContext): PatchResult { - val accountSwitcherAccessibilityLabelResult = AccountSwitcherAccessibilityLabelFingerprint.result!! - val accountSwitcherAccessibilityLabelMethod = accountSwitcherAccessibilityLabelResult.mutableMethod - val setVisibilityConstIndex = - accountSwitcherAccessibilityLabelResult.scanResult.patternScanResult!!.endIndex + AccountSwitcherAccessibilityLabelFingerprint.result?.let { + with (it.mutableMethod) { + val insertIndex = it.scanResult.patternScanResult!!.endIndex + val register = (instruction(insertIndex - 2) as OneRegisterInstruction).registerA - val setVisibilityConstRegister = ( - accountSwitcherAccessibilityLabelMethod.instruction - (setVisibilityConstIndex - 2) as OneRegisterInstruction - ).registerA - - accountSwitcherAccessibilityLabelMethod.addInstructions( - setVisibilityConstIndex, """ - invoke-static {v$setVisibilityConstRegister}, $GENERAL_LAYOUT->hideEmailAddress(I)I - move-result v$setVisibilityConstRegister - """ - ) + addInstructions( + insertIndex, """ + invoke-static {v$register}, $GENERAL_LAYOUT->hideEmailAddress(I)I + move-result v$register + """ + ) + } + } ?: return AccountSwitcherAccessibilityLabelFingerprint.toErrorResult() return PatchResultSuccess() } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/pivotbar/createbutton/bytecode/fingerprints/PivotBarCreateButtonViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/pivotbar/createbutton/bytecode/fingerprints/PivotBarCreateButtonViewFingerprint.kt index 66389ffae..aae868865 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/general/pivotbar/createbutton/bytecode/fingerprints/PivotBarCreateButtonViewFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/pivotbar/createbutton/bytecode/fingerprints/PivotBarCreateButtonViewFingerprint.kt @@ -12,9 +12,9 @@ object PivotBarCreateButtonViewFingerprint : MethodFingerprint( access = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf("Z"), customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.imageOnlyTabId + methodDef.implementation?.instructions?.any { + it.opcode.ordinal == Opcode.CONST.ordinal && + (it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.imageOnlyTabId } == true } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/pivotbar/createbutton/bytecode/fingerprints/PivotBarFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/pivotbar/createbutton/bytecode/fingerprints/PivotBarFingerprint.kt index 0c7fdce04..7cdda8665 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/general/pivotbar/createbutton/bytecode/fingerprints/PivotBarFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/pivotbar/createbutton/bytecode/fingerprints/PivotBarFingerprint.kt @@ -17,9 +17,9 @@ object PivotBarFingerprint : MethodFingerprint( ), customFingerprint = { methodDef -> methodDef.definingClass == "Lcom/google/android/apps/youtube/app/ui/pivotbar/PivotBar;" && - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.imageWithTextTabId + methodDef.implementation?.instructions?.any { + it.opcode.ordinal == Opcode.CONST.ordinal && + (it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.imageWithTextTabId } == true } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/pivotbar/createbutton/bytecode/patch/CreateButtonRemoverBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/pivotbar/createbutton/bytecode/patch/CreateButtonRemoverBytecodePatch.kt index a758843af..fdddcf93a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/general/pivotbar/createbutton/bytecode/patch/CreateButtonRemoverBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/pivotbar/createbutton/bytecode/patch/CreateButtonRemoverBytecodePatch.kt @@ -65,14 +65,14 @@ class CreateButtonRemoverBytecodePatch : BytecodePatch( } ?: return PivotBarCreateButtonViewFingerprint.toErrorResult() } - internal companion object { + private companion object { const val hook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, $GENERAL_LAYOUT" + "->" + "hideCreateButton(Landroid/view/View;)V" - private lateinit var createRef: DexBackedMethodReference + lateinit var createRef: DexBackedMethodReference - private var isSeondary: Boolean = false + var isSeondary: Boolean = false } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/pivotbar/shortsbutton/bytecode/patch/ShortsButtonRemoverBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/pivotbar/shortsbutton/bytecode/patch/ShortsButtonRemoverBytecodePatch.kt index 7388a62a6..bfba94737 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/general/pivotbar/shortsbutton/bytecode/patch/ShortsButtonRemoverBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/pivotbar/shortsbutton/bytecode/patch/ShortsButtonRemoverBytecodePatch.kt @@ -3,19 +3,18 @@ package app.revanced.patches.youtube.layout.general.pivotbar.shortsbutton.byteco import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.MethodFingerprintExtensions.name 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.PatchResultError import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patches.youtube.layout.general.pivotbar.shortsbutton.bytecode.fingerprints.PivotBarEnumFingerprint import app.revanced.patches.youtube.layout.general.pivotbar.shortsbutton.bytecode.fingerprints.PivotBarShortsButtonViewFingerprint import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.fingerprints.PivotBarFingerprint import app.revanced.shared.util.integrations.Constants.GENERAL_LAYOUT -import app.revanced.shared.util.pivotbar.InjectionUtils.injectHook import app.revanced.shared.util.pivotbar.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT +import app.revanced.shared.util.pivotbar.InjectionUtils.injectHook @Name("hide-shorts-button") @YouTubeCompatibility @@ -29,42 +28,48 @@ class ShortsButtonRemoverBytecodePatch : BytecodePatch( * Resolve fingerprints */ - val pivotBarResult = PivotBarFingerprint.result ?: return PatchResultError("PivotBarFingerprint failed") - val fingerprintResults = arrayOf(PivotBarEnumFingerprint, PivotBarShortsButtonViewFingerprint) - .onEach { - val resolutionSucceeded = it.resolve( - context, - pivotBarResult.mutableMethod, - pivotBarResult.mutableClass - ) + PivotBarFingerprint.result?.let { parentResult -> + with ( + arrayOf( + PivotBarEnumFingerprint, + PivotBarShortsButtonViewFingerprint + ).onEach { + it.resolve( + context, + parentResult.mutableMethod, + parentResult.mutableClass + ) + }.map { + it.result?.scanResult?.patternScanResult ?: return it.toErrorResult() + } + ) { + val enumScanResult = this[0] + val buttonViewResult = this[1] - if (!resolutionSucceeded) return PatchResultError("${it.name} failed") + val enumHookInsertIndex = enumScanResult.startIndex + 2 + val buttonHookInsertIndex = buttonViewResult.endIndex + + mapOf( + buttonHook to buttonHookInsertIndex, + enumHook to enumHookInsertIndex + ).forEach { (hook, insertIndex) -> + parentResult.mutableMethod.injectHook(hook, insertIndex) + } } - .map { it.result!!.scanResult.patternScanResult!! } - val enumScanResult = fingerprintResults[0] - val buttonViewResult = fingerprintResults[1] - - val enumHookInsertIndex = enumScanResult.startIndex + 2 - val buttonHookInsertIndex = buttonViewResult.endIndex - - /* - * Inject hooks - */ - - val enumHook = - "sput-object v$REGISTER_TEMPLATE_REPLACEMENT, $GENERAL_LAYOUT->lastPivotTab:Ljava/lang/Enum;" - val buttonHook = - "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, $GENERAL_LAYOUT->hideShortsButton(Landroid/view/View;)V" - - // Inject bottom to top to not mess up the indices - mapOf( - buttonHook to buttonHookInsertIndex, - enumHook to enumHookInsertIndex - ).forEach { (hook, insertIndex) -> - pivotBarResult.mutableMethod.injectHook(hook, insertIndex) - } + } ?: return PivotBarFingerprint.toErrorResult() return PatchResultSuccess() } + private companion object { + const val enumHook = + "sput-object v$REGISTER_TEMPLATE_REPLACEMENT, $GENERAL_LAYOUT" + + "->" + + "lastPivotTab:Ljava/lang/Enum;" + + const val buttonHook = + "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, $GENERAL_LAYOUT" + + "->" + + "hideShortsButton(Landroid/view/View;)V" + } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/widesearchbar/bytecode/patch/WideSearchbarBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/widesearchbar/bytecode/patch/WideSearchbarBytecodePatch.kt index 4d40273ea..ed42fee3a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/general/widesearchbar/bytecode/patch/WideSearchbarBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/widesearchbar/bytecode/patch/WideSearchbarBytecodePatch.kt @@ -30,12 +30,15 @@ class WideSearchbarBytecodePatch : BytecodePatch( WideSearchbarOneParentFingerprint to WideSearchbarOneFingerprint, WideSearchbarTwoParentFingerprint to WideSearchbarTwoFingerprint ).map { (parentFingerprint, fingerprint) -> - parentFingerprint.result?.let { parentResult -> - fingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let { + parentFingerprint.result?.classDef?.let { classDef -> + fingerprint.also { it.resolve(context, classDef) }.result?.let { + val index = if (fingerprint == WideSearchbarOneFingerprint) it.scanResult.patternScanResult!!.endIndex + else it.scanResult.patternScanResult!!.startIndex + val targetMethod = context .toMethodWalker(it.method) - .nextMethod(it.scanResult.patternScanResult!!.endIndex, true) + .nextMethod(index, true) .getMethod() as MutableMethod injectSearchBarHook(targetMethod) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/player/autoplaybutton/bytecode/fingerprints/LayoutConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/player/autoplaybutton/bytecode/fingerprints/LayoutConstructorFingerprint.kt index 6596b7147..eb40f510a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/player/autoplaybutton/bytecode/fingerprints/LayoutConstructorFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/player/autoplaybutton/bytecode/fingerprints/LayoutConstructorFingerprint.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint object LayoutConstructorFingerprint : MethodFingerprint( strings = listOf("1.0x"), - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("YouTubeControlsOverlay;") + customFingerprint = { + it.definingClass.endsWith("YouTubeControlsOverlay;") } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/player/autoplaybutton/bytecode/patch/HideAutoplayButtonBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/player/autoplaybutton/bytecode/patch/HideAutoplayButtonBytecodePatch.kt index 7cd816c99..222b2c8bb 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/player/autoplaybutton/bytecode/patch/HideAutoplayButtonBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/player/autoplaybutton/bytecode/patch/HideAutoplayButtonBytecodePatch.kt @@ -11,6 +11,7 @@ import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.youtube.layout.player.autoplaybutton.bytecode.fingerprints.LayoutConstructorFingerprint import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.patches.mapping.ResourceMappingPatch import app.revanced.shared.util.integrations.Constants.PLAYER_LAYOUT import org.jf.dexlib2.iface.instruction.Instruction @@ -28,31 +29,33 @@ class HideAutoplayButtonBytecodePatch : BytecodePatch( ) ) { override fun execute(context: BytecodeContext): PatchResult { - val layoutGenMethodResult = LayoutConstructorFingerprint.result!! - val layoutGenMethod = layoutGenMethodResult.mutableMethod - val layoutGenMethodInstructions = layoutGenMethod.implementation!!.instructions - // resolve the offsets such as ... val autoNavPreviewStubId = ResourceMappingPatch.resourceMappings.single { it.name == "autonav_preview_stub" }.id - // where to insert the branch instructions and ... - val insertIndex = layoutGenMethodInstructions.indexOfFirst { - (it as? WideLiteralInstruction)?.wideLiteral == autoNavPreviewStubId - } - // where to branch away - val branchIndex = layoutGenMethodInstructions.subList(insertIndex + 1, layoutGenMethodInstructions.size - 1).indexOfFirst { - ((it as? ReferenceInstruction)?.reference as? MethodReference)?.name == "addOnLayoutChangeListener" - } + 2 - val jumpInstruction = layoutGenMethodInstructions[insertIndex + branchIndex] as Instruction - layoutGenMethod.addInstructions( - insertIndex, """ - invoke-static {}, $PLAYER_LAYOUT->hideAutoPlayButton()Z - move-result v15 - if-nez v15, :hidden - """, listOf(ExternalLabel("hidden", jumpInstruction)) - ) + LayoutConstructorFingerprint.result?.mutableMethod?.let { method -> + with (method.implementation!!.instructions) { + // where to insert the branch instructions and ... + val insertIndex = this.indexOfFirst { + (it as? WideLiteralInstruction)?.wideLiteral == autoNavPreviewStubId + } + // where to branch away + val branchIndex = this.subList(insertIndex + 1, this.size - 1).indexOfFirst { + ((it as? ReferenceInstruction)?.reference as? MethodReference)?.name == "addOnLayoutChangeListener" + } + 2 + + val jumpInstruction = this[insertIndex + branchIndex] as Instruction + + method.addInstructions( + insertIndex, """ + invoke-static {}, $PLAYER_LAYOUT->hideAutoPlayButton()Z + move-result v15 + if-nez v15, :hidden + """, listOf(ExternalLabel("hidden", jumpInstruction)) + ) + } + } ?: return LayoutConstructorFingerprint.toErrorResult() return PatchResultSuccess() } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/player/captionsbutton/bytecode/patch/HideCaptionsButtonBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/player/captionsbutton/bytecode/patch/HideCaptionsButtonBytecodePatch.kt index 28c2c339d..bf2f33ddd 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/player/captionsbutton/bytecode/patch/HideCaptionsButtonBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/player/captionsbutton/bytecode/patch/HideCaptionsButtonBytecodePatch.kt @@ -8,6 +8,7 @@ import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.fingerprints.SubtitleButtonControllerFingerprint import app.revanced.shared.util.integrations.Constants.PLAYER_LAYOUT import org.jf.dexlib2.Opcode @@ -15,24 +16,27 @@ import org.jf.dexlib2.Opcode @Name("hide-captions-button-bytecode-patch") @YouTubeCompatibility @Version("0.0.1") -class HideCaptionsButtonBytecodePatch : BytecodePatch(listOf( - SubtitleButtonControllerFingerprint, -)) { +class HideCaptionsButtonBytecodePatch : BytecodePatch( + listOf( + SubtitleButtonControllerFingerprint + ) +) { override fun execute(context: BytecodeContext): PatchResult { - val subtitleButtonControllerMethod = SubtitleButtonControllerFingerprint.result!!.mutableMethod - val subtitleButtonControllerMethodInstructions = subtitleButtonControllerMethod.implementation!!.instructions + SubtitleButtonControllerFingerprint.result?.mutableMethod?.let { + with (it.implementation!!.instructions) { + for ((index, instruction) in this.withIndex()) { + if (instruction.opcode != Opcode.IGET_BOOLEAN) continue - for ((index, instruction) in subtitleButtonControllerMethodInstructions.withIndex()) { - if (instruction.opcode != Opcode.IGET_BOOLEAN) continue + it.addInstruction( + index + 1, + "invoke-static {v0}, $PLAYER_LAYOUT->hideCaptionsButton(Landroid/widget/ImageView;)V" + ) - subtitleButtonControllerMethod.addInstruction( - index + 1, - "invoke-static {v0}, $PLAYER_LAYOUT->hideCaptionsButton(Landroid/widget/ImageView;)V" - ) - - break - } + break + } + } + } ?: return SubtitleButtonControllerFingerprint.toErrorResult() return PatchResultSuccess() } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/player/infocards/bytecode/fingerprints/InfocardsIncognitoFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/player/infocards/bytecode/fingerprints/InfocardsIncognitoFingerprint.kt index bf368fede..07f5cde54 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/player/infocards/bytecode/fingerprints/InfocardsIncognitoFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/player/infocards/bytecode/fingerprints/InfocardsIncognitoFingerprint.kt @@ -11,7 +11,7 @@ import org.jf.dexlib2.AccessFlags @YouTubeCompatibility @Version("0.0.1") object InfocardsIncognitoFingerprint : MethodFingerprint( - "Ljava/lang/Boolean;", - AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "Ljava/lang/Boolean;", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, strings = listOf("vibrator") ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/player/infocards/bytecode/fingerprints/InfocardsIncognitoParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/player/infocards/bytecode/fingerprints/InfocardsIncognitoParentFingerprint.kt index e49c66a34..b1d2c2496 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/player/infocards/bytecode/fingerprints/InfocardsIncognitoParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/player/infocards/bytecode/fingerprints/InfocardsIncognitoParentFingerprint.kt @@ -11,7 +11,7 @@ import org.jf.dexlib2.AccessFlags @YouTubeCompatibility @Version("0.0.1") object InfocardsIncognitoParentFingerprint : MethodFingerprint( - "Ljava/lang/String;", - AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "Ljava/lang/String;", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, strings = listOf("player_overlay_info_card_teaser"), ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/player/infocards/bytecode/patch/HideInfoCardsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/player/infocards/bytecode/patch/HideInfoCardsBytecodePatch.kt index 807270a27..a0bbdd695 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/player/infocards/bytecode/patch/HideInfoCardsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/player/infocards/bytecode/patch/HideInfoCardsBytecodePatch.kt @@ -11,6 +11,7 @@ import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patches.youtube.layout.player.infocards.bytecode.fingerprints.InfocardsIncognitoFingerprint import app.revanced.patches.youtube.layout.player.infocards.bytecode.fingerprints.InfocardsIncognitoParentFingerprint import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.util.integrations.Constants.PLAYER_LAYOUT @Name("hide-info-cards-bytecode-patch") @@ -20,16 +21,17 @@ class HideInfoCardsBytecodePatch : BytecodePatch( listOf(InfocardsIncognitoParentFingerprint) ) { override fun execute(context: BytecodeContext): PatchResult { - with(InfocardsIncognitoFingerprint.also { - it.resolve(context, InfocardsIncognitoParentFingerprint.result!!.classDef) - }.result!!.mutableMethod) { - addInstructions( + InfocardsIncognitoParentFingerprint.result?.classDef?.let { classDef -> + InfocardsIncognitoFingerprint.also { + it.resolve(context, classDef) + }.result?.mutableMethod?. + addInstructions( 1, """ invoke-static {v0}, $PLAYER_LAYOUT->hideInfoCard(Z)Z move-result v0 - """ - ) - } + """ + ) ?: return InfocardsIncognitoFingerprint.toErrorResult() + } ?: return InfocardsIncognitoParentFingerprint.toErrorResult() return PatchResultSuccess() } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/clientspoof/bytecode/fingerprints/UserAgentHeaderBuilderFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/clientspoof/bytecode/fingerprints/UserAgentHeaderBuilderFingerprint.kt index 8ac6f34f0..c9a6817d3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/clientspoof/bytecode/fingerprints/UserAgentHeaderBuilderFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/clientspoof/bytecode/fingerprints/UserAgentHeaderBuilderFingerprint.kt @@ -5,6 +5,9 @@ import org.jf.dexlib2.Opcode object UserAgentHeaderBuilderFingerprint : MethodFingerprint( parameters = listOf("L", "L", "L"), - opcodes = listOf(Opcode.MOVE_RESULT_OBJECT, Opcode.INVOKE_VIRTUAL), + opcodes = listOf( + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL + ), strings = listOf("(Linux; U; Android "), ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/clientspoof/bytecode/patch/ClientSpoofBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/clientspoof/bytecode/patch/ClientSpoofBytecodePatch.kt index 320e9e194..f1436c157 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/clientspoof/bytecode/patch/ClientSpoofBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/clientspoof/bytecode/patch/ClientSpoofBytecodePatch.kt @@ -9,7 +9,9 @@ import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patches.youtube.misc.clientspoof.bytecode.fingerprints.UserAgentHeaderBuilderFingerprint +import app.revanced.patches.youtube.misc.microg.shared.Constants.PACKAGE_NAME import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction @Name("client-spoof-bytecode-patch") @@ -19,14 +21,15 @@ class ClientSpoofBytecodePatch : BytecodePatch( listOf(UserAgentHeaderBuilderFingerprint) ) { override fun execute(context: BytecodeContext): PatchResult { - val result = UserAgentHeaderBuilderFingerprint.result!! - val method = result.mutableMethod - val insertIndex = result.scanResult.patternScanResult!!.endIndex - val packageNameRegister = (method.instruction(insertIndex) as FiveRegisterInstruction).registerD + UserAgentHeaderBuilderFingerprint.result?.let { + val insertIndex = it.scanResult.patternScanResult!!.endIndex - val originalPackageName = "com.google.android.youtube" - method.addInstruction(insertIndex, "const-string v$packageNameRegister, \"$originalPackageName\"") + with (it.mutableMethod) { + val packageNameRegister = (instruction(insertIndex) as FiveRegisterInstruction).registerD + addInstruction(insertIndex, "const-string v$packageNameRegister, \"$PACKAGE_NAME\"") + } + } ?: return UserAgentHeaderBuilderFingerprint.toErrorResult() return PatchResultSuccess() } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/customvideobuffer/bytecode/fingerprints/MaxBufferFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/customvideobuffer/bytecode/fingerprints/MaxBufferFingerprint.kt index ee65c07aa..8e721addd 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/customvideobuffer/bytecode/fingerprints/MaxBufferFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/customvideobuffer/bytecode/fingerprints/MaxBufferFingerprint.kt @@ -7,13 +7,20 @@ import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction import org.jf.dexlib2.Opcode object MaxBufferFingerprint : MethodFingerprint( - "I", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), - listOf(Opcode.SGET_OBJECT, Opcode.IGET, Opcode.IF_EQZ, Opcode.RETURN), - customFingerprint = { methodDef -> - methodDef.definingClass == "Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;" - && methodDef.implementation!!.instructions.any { - ((it as? NarrowLiteralInstruction)?.narrowLiteral == 120000) - && methodDef.name == "r" + returnType = "I", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf(), + opcodes = listOf( + Opcode.SGET_OBJECT, + Opcode.IGET, + Opcode.IF_EQZ, + Opcode.RETURN + ), + customFingerprint = { + it.definingClass == "Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;" + && it.implementation!!.instructions.any { instruction -> + ((instruction as? NarrowLiteralInstruction)?.narrowLiteral == 120000) + && it.name == "r" } } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/customvideobuffer/bytecode/fingerprints/PlaybackBufferFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/customvideobuffer/bytecode/fingerprints/PlaybackBufferFingerprint.kt index 6feb1bad2..fe70e94c0 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/customvideobuffer/bytecode/fingerprints/PlaybackBufferFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/customvideobuffer/bytecode/fingerprints/PlaybackBufferFingerprint.kt @@ -7,12 +7,17 @@ import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction import org.jf.dexlib2.Opcode object PlaybackBufferFingerprint : MethodFingerprint( - "I", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), - listOf(Opcode.IF_LEZ, Opcode.RETURN), - customFingerprint = { methodDef -> - methodDef.definingClass == "Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;" - && methodDef.implementation!!.instructions.any { - ((it as? NarrowLiteralInstruction)?.narrowLiteral == 1600) + returnType = "I", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf(), + opcodes = listOf( + Opcode.IF_LEZ, + Opcode.RETURN + ), + customFingerprint = { + it.definingClass == "Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;" + && it.implementation!!.instructions.any { instruction -> + ((instruction as? NarrowLiteralInstruction)?.narrowLiteral == 1600) } } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/customvideobuffer/bytecode/fingerprints/ReBufferFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/customvideobuffer/bytecode/fingerprints/ReBufferFingerprint.kt index 904430796..3e5f13938 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/customvideobuffer/bytecode/fingerprints/ReBufferFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/customvideobuffer/bytecode/fingerprints/ReBufferFingerprint.kt @@ -7,12 +7,17 @@ import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction import org.jf.dexlib2.Opcode object ReBufferFingerprint : MethodFingerprint( - "I", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), - listOf(Opcode.IF_LEZ, Opcode.RETURN), - customFingerprint = { methodDef -> - methodDef.definingClass == "Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;" - && methodDef.implementation!!.instructions.any { - ((it as? NarrowLiteralInstruction)?.narrowLiteral == 5000) + returnType = "I", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf(), + opcodes = listOf( + Opcode.IF_LEZ, + Opcode.RETURN + ), + customFingerprint = { + it.definingClass == "Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;" + && it.implementation!!.instructions.any { instruction -> + ((instruction as? NarrowLiteralInstruction)?.narrowLiteral == 5000) } } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/bytecode/fingerprints/ExternalBrowserPrimaryFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/bytecode/fingerprints/ExternalBrowserPrimaryFingerprint.kt index 8920a6b99..d9ffcc3a2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/bytecode/fingerprints/ExternalBrowserPrimaryFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/bytecode/fingerprints/ExternalBrowserPrimaryFingerprint.kt @@ -6,7 +6,9 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object ExternalBrowserPrimaryFingerprint : MethodFingerprint( - "L", AccessFlags.PUBLIC or AccessFlags.STATIC, opcodes = listOf( + returnType = "L", + access = AccessFlags.PUBLIC or AccessFlags.STATIC, + opcodes = listOf( Opcode.CHECK_CAST, Opcode.NEW_INSTANCE, Opcode.INVOKE_DIRECT, diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/bytecode/fingerprints/ExternalBrowserSecondaryFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/bytecode/fingerprints/ExternalBrowserSecondaryFingerprint.kt index 7ee275dc3..ba99acd1d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/bytecode/fingerprints/ExternalBrowserSecondaryFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/bytecode/fingerprints/ExternalBrowserSecondaryFingerprint.kt @@ -6,7 +6,9 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object ExternalBrowserSecondaryFingerprint : MethodFingerprint( - "L", AccessFlags.PUBLIC or AccessFlags.FINAL, opcodes = listOf( + returnType = "L", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + opcodes = listOf( Opcode.IPUT_OBJECT, Opcode.NEW_INSTANCE, Opcode.CONST_STRING diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/bytecode/fingerprints/ExternalBrowserTertiaryFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/bytecode/fingerprints/ExternalBrowserTertiaryFingerprint.kt index 2f9c7a7cd..eafbe88dd 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/bytecode/fingerprints/ExternalBrowserTertiaryFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/bytecode/fingerprints/ExternalBrowserTertiaryFingerprint.kt @@ -6,7 +6,9 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object ExternalBrowserTertiaryFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, opcodes = listOf( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + opcodes = listOf( Opcode.CHECK_CAST, Opcode.NEW_INSTANCE, Opcode.INVOKE_DIRECT, diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/bytecode/patch/ExternalBrowserBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/bytecode/patch/ExternalBrowserBytecodePatch.kt index a8f317433..97f4a3896 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/bytecode/patch/ExternalBrowserBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/externalbrowser/bytecode/patch/ExternalBrowserBytecodePatch.kt @@ -9,6 +9,7 @@ import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patches.youtube.misc.externalbrowser.bytecode.fingerprints.* import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.util.integrations.Constants.MISC_PATH import org.jf.dexlib2.iface.instruction.formats.Instruction21c @@ -28,19 +29,20 @@ class ExternalBrowserBytecodePatch : BytecodePatch( ExternalBrowserPrimaryFingerprint, ExternalBrowserSecondaryFingerprint, ExternalBrowserTertiaryFingerprint - ).forEach { fingerprint -> - val result = fingerprint.result!! - val method = result.mutableMethod + ).forEach { + val result = it.result?: return it.toErrorResult() val endIndex = result.scanResult.patternScanResult!!.endIndex - val register = (method.implementation!!.instructions[endIndex] as Instruction21c).registerA - - method.addInstructions( + with (result.mutableMethod) { + val register = (implementation!!.instructions[endIndex] as Instruction21c).registerA + addInstructions( endIndex + 1, """ - invoke-static {v$register}, $MISC_PATH/ExternalBrowserPatch;->enableExternalBrowser(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$register - """ - ) + invoke-static {v$register}, $MISC_PATH/ExternalBrowserPatch;->enableExternalBrowser(Ljava/lang/String;)Ljava/lang/String; + move-result-object v$register + """ + ) + } } + return PatchResultSuccess() } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/bytecode/fingerprints/OpenLinksDirectlyFingerprintPrimary.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/bytecode/fingerprints/OpenLinksDirectlyFingerprintPrimary.kt index c78cd823f..f77355eae 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/bytecode/fingerprints/OpenLinksDirectlyFingerprintPrimary.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/bytecode/fingerprints/OpenLinksDirectlyFingerprintPrimary.kt @@ -6,7 +6,10 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object OpenLinksDirectlyFingerprintPrimary : MethodFingerprint( - "Ljava/lang/Object", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf( + returnType = "Ljava/lang/Object", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L"), + opcodes = listOf( Opcode.CHECK_CAST, Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT_OBJECT, diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/bytecode/fingerprints/OpenLinksDirectlyFingerprintSecondary.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/bytecode/fingerprints/OpenLinksDirectlyFingerprintSecondary.kt index b25356e0e..3d1d6bf9d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/bytecode/fingerprints/OpenLinksDirectlyFingerprintSecondary.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/bytecode/fingerprints/OpenLinksDirectlyFingerprintSecondary.kt @@ -6,7 +6,10 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object OpenLinksDirectlyFingerprintSecondary : MethodFingerprint( - "L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L"), listOf( + returnType = "L", + access = AccessFlags.PUBLIC or AccessFlags.STATIC, + parameters = listOf("L"), + opcodes = listOf( Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT_OBJECT, Opcode.INVOKE_STATIC, diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/bytecode/patch/OpenLinksDirectlyBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/bytecode/patch/OpenLinksDirectlyBytecodePatch.kt index e1fbf03e0..8882b018a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/bytecode/patch/OpenLinksDirectlyBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/bytecode/patch/OpenLinksDirectlyBytecodePatch.kt @@ -4,12 +4,13 @@ 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.fingerprint.method.impl.MethodFingerprint +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patches.youtube.misc.openlinksdirectly.bytecode.fingerprints.* import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.util.integrations.Constants.MISC_PATH import org.jf.dexlib2.iface.instruction.Instruction import org.jf.dexlib2.iface.instruction.formats.Instruction11x @@ -26,29 +27,31 @@ class OpenLinksDirectlyBytecodePatch : BytecodePatch( ) { override fun execute(context: BytecodeContext): PatchResult { - OpenLinksDirectlyFingerprintPrimary.hookUriParser(true) - OpenLinksDirectlyFingerprintSecondary.hookUriParser(false) + arrayOf( + OpenLinksDirectlyFingerprintPrimary to true, + OpenLinksDirectlyFingerprintSecondary to false + ).map { (fingerprint, boolean) -> + fingerprint.result?.hookUriParser(boolean) ?: return fingerprint.toErrorResult() + } return PatchResultSuccess() } } -fun MethodFingerprint.hookUriParser(isPrimaryFingerprint: Boolean) { +fun MethodFingerprintResult.hookUriParser(isPrimaryFingerprint: Boolean) { fun getTargetRegister(instruction: Instruction): Int { if (isPrimaryFingerprint) return (instruction as Instruction35c).registerC return (instruction as Instruction11x).registerA } - with(this.result!!) { - val startIndex = scanResult.patternScanResult!!.startIndex - val instruction = method.implementation!!.instructions.elementAt(startIndex + 1) - val insertIndex = if (isPrimaryFingerprint) 1 else 2 - val targetRegister = getTargetRegister(instruction) + val startIndex = scanResult.patternScanResult!!.startIndex + val instruction = method.implementation!!.instructions.elementAt(startIndex + 1) + val insertIndex = if (isPrimaryFingerprint) 1 else 2 + val targetRegister = getTargetRegister(instruction) - mutableMethod.addInstructions( - startIndex + insertIndex, """ - invoke-static {v$targetRegister}, $MISC_PATH/OpenLinksDirectlyPatch;->enableBypassRedirect(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$targetRegister - """ - ) - } + mutableMethod.addInstructions( + startIndex + insertIndex, """ + invoke-static {v$targetRegister}, $MISC_PATH/OpenLinksDirectlyPatch;->enableBypassRedirect(Ljava/lang/String;)Ljava/lang/String; + move-result-object v$targetRegister + """ + ) } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/pipnotification/bytecode/fingerprints/PrimaryPiPFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/pipnotification/bytecode/fingerprints/PrimaryPiPFingerprint.kt index ee9aebd95..5270ad7cf 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/pipnotification/bytecode/fingerprints/PrimaryPiPFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/pipnotification/bytecode/fingerprints/PrimaryPiPFingerprint.kt @@ -6,7 +6,10 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object PrimaryPiPFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L"), + opcodes = listOf( Opcode.IGET_OBJECT, Opcode.CHECK_CAST, Opcode.INVOKE_VIRTUAL, diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/pipnotification/bytecode/fingerprints/SecondaryPiPFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/pipnotification/bytecode/fingerprints/SecondaryPiPFingerprint.kt index 2fa31e22c..07bb53a78 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/pipnotification/bytecode/fingerprints/SecondaryPiPFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/pipnotification/bytecode/fingerprints/SecondaryPiPFingerprint.kt @@ -6,7 +6,10 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object SecondaryPiPFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L"), + opcodes = listOf( Opcode.IGET_OBJECT, Opcode.CHECK_CAST, Opcode.INVOKE_VIRTUAL, diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/bytecode/patch/PlayerControlsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/bytecode/patch/PlayerControlsBytecodePatch.kt index 859269ea4..99c450631 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/bytecode/patch/PlayerControlsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/bytecode/patch/PlayerControlsBytecodePatch.kt @@ -15,6 +15,7 @@ import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patches.youtube.misc.playercontrols.fingerprints.* import app.revanced.patches.youtube.misc.resourceid.patch.SharedResourcdIdPatch import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @Name("player-controls-bytecode-patch") @@ -31,24 +32,33 @@ class PlayerControlsBytecodePatch : BytecodePatch( ) ) { override fun execute(context: BytecodeContext): PatchResult { - showPlayerControlsFingerprintResult = PlayerControlsVisibilityFingerprint.result!! - controlsLayoutInflateFingerprintResult = ControlsLayoutInflateFingerprint.result!! - // TODO: another solution is required, this is hacky - listOf(BottomControlsInflateFingerprint).resolve(context, context.classes) - inflateFingerprintResult = BottomControlsInflateFingerprint.result!! + PlayerControlsVisibilityFingerprint.result?.let { + showPlayerControlsResult = it + } ?: return PlayerControlsVisibilityFingerprint.toErrorResult() - VisibilityNegatedFingerprint.resolve(context, VisibilityNegatedParentFingerprint.result!!.classDef) - visibilityNegatedFingerprintResult = VisibilityNegatedFingerprint.result!! + ControlsLayoutInflateFingerprint.result?.let { + controlsLayoutInflateResult = it + } ?: return ControlsLayoutInflateFingerprint.toErrorResult() + + BottomControlsInflateFingerprint.result?.let { + inflateResult = it + } ?: return BottomControlsInflateFingerprint.toErrorResult() + + VisibilityNegatedParentFingerprint.result?.let { parentResult -> + VisibilityNegatedFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let { + visibilityNegatedResult = it + } ?: return VisibilityNegatedFingerprint.toErrorResult() + } ?: return VisibilityNegatedParentFingerprint.toErrorResult() return PatchResultSuccess() } internal companion object { - lateinit var showPlayerControlsFingerprintResult: MethodFingerprintResult - lateinit var controlsLayoutInflateFingerprintResult: MethodFingerprintResult - lateinit var inflateFingerprintResult: MethodFingerprintResult - lateinit var visibilityNegatedFingerprintResult: MethodFingerprintResult + lateinit var showPlayerControlsResult: MethodFingerprintResult + lateinit var controlsLayoutInflateResult: MethodFingerprintResult + lateinit var inflateResult: MethodFingerprintResult + lateinit var visibilityNegatedResult: MethodFingerprintResult fun MethodFingerprintResult.injectVisibilityCall( descriptor: String, @@ -60,32 +70,33 @@ class PlayerControlsBytecodePatch : BytecodePatch( ) } - fun MethodFingerprintResult.injectCalls( + private fun MethodFingerprintResult.injectCalls( descriptor: String ) { val endIndex = scanResult.patternScanResult!!.endIndex - val viewRegister = (mutableMethod.instruction(endIndex) as OneRegisterInstruction).registerA - - mutableMethod.addInstruction( - endIndex + 1, - "invoke-static {v$viewRegister}, $descriptor->initialize(Ljava/lang/Object;)V" - ) + with (mutableMethod) { + val viewRegister = (instruction(endIndex) as OneRegisterInstruction).registerA + addInstruction( + endIndex + 1, + "invoke-static {v$viewRegister}, $descriptor->initialize(Ljava/lang/Object;)V" + ) + } } fun injectVisibility(descriptor: String) { - showPlayerControlsFingerprintResult.injectVisibilityCall(descriptor, "changeVisibility") + showPlayerControlsResult.injectVisibilityCall(descriptor, "changeVisibility") } fun injectVisibilityNegated(descriptor: String) { - visibilityNegatedFingerprintResult.injectVisibilityCall(descriptor, "changeVisibilityNegatedImmediate") + visibilityNegatedResult.injectVisibilityCall(descriptor, "changeVisibilityNegatedImmediate") } fun initializeSB(descriptor: String) { - controlsLayoutInflateFingerprintResult.injectCalls(descriptor) + controlsLayoutInflateResult.injectCalls(descriptor) } fun initializeControl(descriptor: String) { - inflateFingerprintResult.injectCalls(descriptor) + inflateResult.injectCalls(descriptor) } } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/BottomControlsInflateFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/BottomControlsInflateFingerprint.kt index 3de482da6..6d6efdda1 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/BottomControlsInflateFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/BottomControlsInflateFingerprint.kt @@ -12,9 +12,9 @@ object BottomControlsInflateFingerprint : MethodFingerprint( Opcode.MOVE_RESULT_OBJECT ), customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.bottomUiContainerResourceId + methodDef.implementation?.instructions?.any { + it.opcode.ordinal == Opcode.CONST.ordinal && + (it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.bottomUiContainerResourceId } == true } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/ControlsLayoutInflateFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/ControlsLayoutInflateFingerprint.kt index 9b04242a7..6e3fb9234 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/ControlsLayoutInflateFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/ControlsLayoutInflateFingerprint.kt @@ -14,9 +14,9 @@ object ControlsLayoutInflateFingerprint : MethodFingerprint( Opcode.MOVE_RESULT_OBJECT ), customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.controlsLayoutStubResourceId + methodDef.implementation?.instructions?.any { + it.opcode.ordinal == Opcode.CONST.ordinal && + (it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.controlsLayoutStubResourceId } == true } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/PlayerControlsVisibilityFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/PlayerControlsVisibilityFingerprint.kt index 6c7f87be0..7aa907ad4 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/PlayerControlsVisibilityFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/PlayerControlsVisibilityFingerprint.kt @@ -3,9 +3,9 @@ package app.revanced.patches.youtube.misc.playercontrols.fingerprints import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint object PlayerControlsVisibilityFingerprint : MethodFingerprint( - "V", + returnType = "V", parameters = listOf("Z", "Z"), - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("YouTubeControlsOverlay;") + customFingerprint = { + it.definingClass.endsWith("YouTubeControlsOverlay;") } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/VisibilityNegatedFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/VisibilityNegatedFingerprint.kt index 85e9b0d3c..cfe0ce9ed 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/VisibilityNegatedFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/VisibilityNegatedFingerprint.kt @@ -6,7 +6,10 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object VisibilityNegatedFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("Z"), opcodes = listOf( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("Z"), + opcodes = listOf( Opcode.IF_EQZ ) ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/VisibilityNegatedParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/VisibilityNegatedParentFingerprint.kt index 1929e0390..fe0c9ae20 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/VisibilityNegatedParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/VisibilityNegatedParentFingerprint.kt @@ -11,9 +11,9 @@ object VisibilityNegatedParentFingerprint : MethodFingerprint( returnType = "V", access = AccessFlags.PUBLIC or AccessFlags.FINAL, customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.educationTextViewResourceId + methodDef.implementation?.instructions?.any { + it.opcode.ordinal == Opcode.CONST.ordinal && + (it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.educationTextViewResourceId } == true } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/fingerprint/PlayerOverlaysOnFinishInflateFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/fingerprint/PlayerOverlaysOnFinishInflateFingerprint.kt index dab2e0677..1fb5f9811 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/fingerprint/PlayerOverlaysOnFinishInflateFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/fingerprint/PlayerOverlaysOnFinishInflateFingerprint.kt @@ -3,7 +3,7 @@ package app.revanced.patches.youtube.misc.playeroverlay.fingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint object PlayerOverlaysOnFinishInflateFingerprint : MethodFingerprint( - null, null, null, null, null, { methodDef -> - methodDef.definingClass.endsWith("YouTubePlayerOverlaysLayout;") && methodDef.name == "onFinishInflate" + customFingerprint = { + it.definingClass.endsWith("YouTubePlayerOverlaysLayout;") && it.name == "onFinishInflate" } ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/patch/PlayerOverlaysHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/patch/PlayerOverlaysHookPatch.kt index 83cabc5f5..b73842c43 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/patch/PlayerOverlaysHookPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/patch/PlayerOverlaysHookPatch.kt @@ -10,6 +10,7 @@ import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patches.youtube.misc.playeroverlay.fingerprint.PlayerOverlaysOnFinishInflateFingerprint import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.util.integrations.Constants.UTILS_PATH @Name("player-overlays-hook") @@ -23,11 +24,13 @@ class PlayerOverlaysHookPatch : BytecodePatch( ) { override fun execute(context: BytecodeContext): PatchResult { // hook YouTubePlayerOverlaysLayout.onFinishInflate() - val method = PlayerOverlaysOnFinishInflateFingerprint.result!!.mutableMethod - method.addInstruction( - method.implementation!!.instructions.size - 2, - "invoke-static { p0 }, $UTILS_PATH/PlayerOverlaysHookPatch;->YouTubePlayerOverlaysLayout_onFinishInflateHook(Ljava/lang/Object;)V" - ) + PlayerOverlaysOnFinishInflateFingerprint.result?.mutableMethod?.let { + it.addInstruction( + it.implementation!!.instructions.size - 2, + "invoke-static { p0 }, $UTILS_PATH/PlayerOverlaysHookPatch;->YouTubePlayerOverlaysLayout_onFinishInflateHook(Ljava/lang/Object;)V" + ) + } ?: return PlayerOverlaysOnFinishInflateFingerprint.toErrorResult() + return PatchResultSuccess() } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/patch/PlayerTypeHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/patch/PlayerTypeHookPatch.kt index d23948bd2..8cdd7553a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/patch/PlayerTypeHookPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/patch/PlayerTypeHookPatch.kt @@ -10,6 +10,7 @@ import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patches.youtube.misc.playertype.fingerprint.UpdatePlayerTypeFingerprint import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.util.integrations.Constants.UTILS_PATH @Name("player-type-hook") @@ -23,10 +24,11 @@ class PlayerTypeHookPatch : BytecodePatch( ) { override fun execute(context: BytecodeContext): PatchResult { // hook YouTubePlayerOverlaysLayout.updatePlayerLayout() - UpdatePlayerTypeFingerprint.result!!.mutableMethod.addInstruction( + UpdatePlayerTypeFingerprint.result?.mutableMethod?.addInstruction( 0, "invoke-static { p1 }, $UTILS_PATH/PlayerTypeHookPatch;->YouTubePlayerOverlaysLayout_updatePlayerTypeHookEX(Ljava/lang/Object;)V" - ) + ) ?: return UpdatePlayerTypeFingerprint.toErrorResult() + return PatchResultSuccess() } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/ThemeSetterSystemFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/ThemeSetterSystemFingerprint.kt index 6cd9c89f4..d6a28412f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/ThemeSetterSystemFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/ThemeSetterSystemFingerprint.kt @@ -6,12 +6,12 @@ import org.jf.dexlib2.iface.instruction.WideLiteralInstruction import org.jf.dexlib2.Opcode object ThemeSetterSystemFingerprint : MethodFingerprint( - "L", + returnType = "L", opcodes = listOf(Opcode.RETURN_OBJECT), customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.appearanceStringId + methodDef.implementation?.instructions?.any { + it.opcode.ordinal == Opcode.CONST.ordinal && + (it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.appearanceStringId } == true } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/patch/SettingsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/patch/SettingsBytecodePatch.kt index 1050ae5aa..fff62693b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/patch/SettingsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/patch/SettingsBytecodePatch.kt @@ -4,20 +4,21 @@ 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.patch.annotations.DependsOn 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.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.resourceid.patch.SharedResourcdIdPatch import app.revanced.patches.youtube.misc.settings.bytecode.fingerprints.ThemeSetterSystemFingerprint +import app.revanced.shared.annotation.YouTubeCompatibility import app.revanced.shared.extensions.findMutableMethodOf import app.revanced.shared.extensions.injectTheme +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.patches.mapping.ResourceMappingPatch -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.shared.annotation.YouTubeCompatibility import app.revanced.shared.util.integrations.Constants.INTEGRATIONS_PATH -import org.jf.dexlib2.iface.instruction.formats.Instruction31i import org.jf.dexlib2.Opcode +import org.jf.dexlib2.iface.instruction.formats.Instruction31i @Name("settings-bytecode-patch") @DependsOn( @@ -80,21 +81,24 @@ class SettingsBytecodePatch : BytecodePatch( } // apply the current theme of the settings page - with(ThemeSetterSystemFingerprint.result!!) { - with(mutableMethod) { - val call = "invoke-static {v0}, $INTEGRATIONS_PATH/utils/ThemeHelper;->setTheme(Ljava/lang/Object;)V" - + ThemeSetterSystemFingerprint.result?.let { + with(it.mutableMethod) { addInstruction( - scanResult.patternScanResult!!.startIndex, - call + it.scanResult.patternScanResult!!.startIndex, + SET_THEME ) addInstruction( - mutableMethod.implementation!!.instructions.size - 1, - call + this.implementation!!.instructions.size - 1, + SET_THEME ) } - } + } ?: return ThemeSetterSystemFingerprint.toErrorResult() + return PatchResultSuccess() } + companion object { + const val SET_THEME = + "invoke-static {v0}, $INTEGRATIONS_PATH/utils/ThemeHelper;->setTheme(Ljava/lang/Object;)V" + } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/patch/SettingsSecondaryBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/patch/SettingsSecondaryBytecodePatch.kt deleted file mode 100644 index 505057f5c..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/patch/SettingsSecondaryBytecodePatch.kt +++ /dev/null @@ -1,45 +0,0 @@ -package app.revanced.patches.youtube.misc.settings.bytecode.patch - -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.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.youtube.misc.resourceid.patch.SharedResourcdIdPatch -import app.revanced.patches.youtube.misc.settings.bytecode.fingerprints.ThemeSetterSystemFingerprint -import app.revanced.shared.annotation.YouTubeCompatibility -import app.revanced.shared.util.integrations.Constants.INTEGRATIONS_PATH - -@Name("settings-secondary-bytecode-patch") -@DependsOn([SharedResourcdIdPatch::class]) -@YouTubeCompatibility -@Version("0.0.1") -class SettingsSecondaryBytecodePatch : BytecodePatch( - listOf(ThemeSetterSystemFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - val ThemeHelper = "$INTEGRATIONS_PATH/utils/ThemeHelper;" - - // apply the current theme of the settings page - with(ThemeSetterSystemFingerprint.result!!) { - with(mutableMethod) { - val call = "invoke-static {v0}, $ThemeHelper->setTheme(Ljava/lang/Object;)V" - - addInstruction( - scanResult.patternScanResult!!.startIndex, - call - ) - - addInstruction( - mutableMethod.implementation!!.instructions.size - 1, - call - ) - } - } - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/swiperefresh/patch/SwipeRefreshPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/swiperefresh/patch/SwipeRefreshPatch.kt index 7a5169c98..5c8eb73a1 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/swiperefresh/patch/SwipeRefreshPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/swiperefresh/patch/SwipeRefreshPatch.kt @@ -24,12 +24,18 @@ class SwipeRefreshPatch : BytecodePatch( ) ) { override fun execute(context: BytecodeContext): PatchResult { - val result = SwipeRefreshLayoutFingerprint.result ?:return SwipeRefreshLayoutFingerprint.toErrorResult() - val method = result.mutableMethod - val index = result.scanResult.patternScanResult!!.endIndex - val register = (method.instruction(index) as OneRegisterInstruction).registerA - method.addInstruction(index, "const/4 v$register, 0x0") + SwipeRefreshLayoutFingerprint.result?.let { + with (it.mutableMethod) { + val insertIndex = it.scanResult.patternScanResult!!.endIndex + val register = (instruction(insertIndex) as OneRegisterInstruction).registerA + + addInstruction( + insertIndex, + "const/4 v$register, 0x0" + ) + } + } ?: return SwipeRefreshLayoutFingerprint.toErrorResult() return PatchResultSuccess() } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/legacy/fingerprint/LegacyVideoIdFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/legacy/fingerprint/LegacyVideoIdFingerprint.kt index f69620b4a..30ca9f748 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/legacy/fingerprint/LegacyVideoIdFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/legacy/fingerprint/LegacyVideoIdFingerprint.kt @@ -6,10 +6,10 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object LegacyVideoIdFingerprint : MethodFingerprint( - "V", - AccessFlags.DECLARED_SYNCHRONIZED or AccessFlags.FINAL or AccessFlags.PUBLIC, - listOf("L"), - listOf(Opcode.INVOKE_INTERFACE), + returnType = "V", + access = AccessFlags.DECLARED_SYNCHRONIZED or AccessFlags.FINAL or AccessFlags.PUBLIC, + parameters = listOf("L"), + opcodes = listOf(Opcode.INVOKE_INTERFACE), customFingerprint = { it.definingClass.endsWith("PlaybackLifecycleMonitor;") } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/legacy/patch/LegacyVideoIdPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/legacy/patch/LegacyVideoIdPatch.kt index 9ca92a2a3..b1ca41eac 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/legacy/patch/LegacyVideoIdPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/legacy/patch/LegacyVideoIdPatch.kt @@ -5,13 +5,13 @@ 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.fingerprint.method.impl.MethodFingerprintResult import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.youtube.misc.videoid.legacy.fingerprint.LegacyVideoIdFingerprint import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @Name("video-id-hook-legacy") @@ -24,13 +24,16 @@ class LegacyVideoIdPatch : BytecodePatch( ) ) { override fun execute(context: BytecodeContext): PatchResult { - result = LegacyVideoIdFingerprint.result!! - insertMethod = result.mutableMethod - videoIdRegister = - (insertMethod.implementation!!.instructions[result.scanResult.patternScanResult!!.endIndex + 1] as OneRegisterInstruction).registerA + LegacyVideoIdFingerprint.result?.let { + insertIndex = it.scanResult.patternScanResult!!.endIndex - offset++ // offset so setCurrentVideoId is called before any injected call + with (it.mutableMethod) { + insertMethod = this + videoIdRegister = (implementation!!.instructions[insertIndex + 1] as OneRegisterInstruction).registerA + } + offset++ // offset so setCurrentVideoId is called before any injected call + } ?: return LegacyVideoIdFingerprint.toErrorResult() return PatchResultSuccess() } @@ -38,10 +41,11 @@ class LegacyVideoIdPatch : BytecodePatch( companion object { private var offset = 2 + private var insertIndex: Int = 0 private var videoIdRegister: Int = 0 - private lateinit var result: MethodFingerprintResult private lateinit var insertMethod: MutableMethod + /** * Adds an invoke-static instruction, called with the new id when the video changes * @param methodDescriptor which method to call. Params have to be `Ljava/lang/String;` @@ -50,7 +54,7 @@ class LegacyVideoIdPatch : BytecodePatch( methodDescriptor: String ) { insertMethod.addInstructions( - result.scanResult.patternScanResult!!.endIndex + offset, // move-result-object offset + insertIndex + offset, // move-result-object offset "invoke-static {v$videoIdRegister}, $methodDescriptor" ) } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/mainstream/fingerprint/MainstreamVideoIdFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/mainstream/fingerprint/MainstreamVideoIdFingerprint.kt index 55c6cfa79..18dad5537 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/mainstream/fingerprint/MainstreamVideoIdFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/mainstream/fingerprint/MainstreamVideoIdFingerprint.kt @@ -6,10 +6,10 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object MainstreamVideoIdFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("L"), - listOf( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L"), + opcodes = listOf( Opcode.IF_EQZ, Opcode.INVOKE_VIRTUAL, Opcode.MOVE_RESULT_OBJECT, diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/mainstream/fingerprint/PlayerControllerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/mainstream/fingerprint/PlayerControllerFingerprint.kt index 315229dc5..5938548a5 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/mainstream/fingerprint/PlayerControllerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/mainstream/fingerprint/PlayerControllerFingerprint.kt @@ -4,6 +4,7 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint object PlayerControllerFingerprint : MethodFingerprint( customFingerprint = { methodDef -> - methodDef.definingClass == "Lapp/revanced/integrations/sponsorblock/PlayerController;" && methodDef.name == "setSponsorBarRect" + methodDef.definingClass == "Lapp/revanced/integrations/sponsorblock/PlayerController;" + && methodDef.name == "setSponsorBarRect" } ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/mainstream/fingerprint/VideoTimeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/mainstream/fingerprint/VideoTimeFingerprint.kt index febb57515..69b85aedc 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/mainstream/fingerprint/VideoTimeFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/mainstream/fingerprint/VideoTimeFingerprint.kt @@ -6,7 +6,10 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object VideoTimeFingerprint : MethodFingerprint ( - "V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("J", "J", "J", "J", "I", "L"), listOf( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + parameters = listOf("J", "J", "J", "J", "I", "L"), + opcodes = listOf( Opcode.INVOKE_DIRECT, Opcode.IPUT_WIDE, Opcode.IPUT_WIDE, diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/mainstream/patch/MainstreamVideoIdPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/mainstream/patch/MainstreamVideoIdPatch.kt index efdc7ffd4..af5f1168c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/mainstream/patch/MainstreamVideoIdPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/videoid/mainstream/patch/MainstreamVideoIdPatch.kt @@ -7,7 +7,6 @@ import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.toMethodWalker import app.revanced.patcher.extensions.* import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess @@ -17,6 +16,7 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMu import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.videoid.mainstream.fingerprint.* import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.patches.timebar.HookTimebarPatch import app.revanced.shared.util.integrations.Constants.VIDEO_PATH import org.jf.dexlib2.AccessFlags @@ -54,137 +54,146 @@ class MainstreamVideoIdPatch : BytecodePatch( ) ) { override fun execute(context: BytecodeContext): PatchResult { - val VideoInformation = "$VIDEO_PATH/VideoInformation;" - val RepeatListenerResult = RepeatListenerFingerprint.result!! - val RepeatListenerMethod = RepeatListenerResult.mutableMethod - val removeIndex = RepeatListenerResult.scanResult.patternScanResult!!.startIndex + RepeatListenerFingerprint.result?.let { + val removeIndex = it.scanResult.patternScanResult!!.startIndex + with (it.mutableMethod) { + // removeInstruction(removeIndex) + removeInstruction(removeIndex - 1) + } + } ?: return RepeatListenerFingerprint.toErrorResult() - // RepeatListenerMethod.removeInstruction(removeIndex) - RepeatListenerMethod.removeInstruction(removeIndex - 1) - with(PlayerInitFingerprint.result!!) { - PlayerInitMethod = mutableClass.methods.first { MethodUtil.isConstructor(it) } + PlayerInitFingerprint.result?.let { parentResult -> + playerInitMethod = parentResult.mutableClass.methods.first { MethodUtil.isConstructor(it) } - // seek method - val seekFingerprintResultMethod = SeekFingerprint.also { it.resolve(context, classDef) }.result!!.method + SeekFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let { + val resultMethod = it.method - // create helper method - val seekHelperMethod = ImmutableMethod( - seekFingerprintResultMethod.definingClass, - "seekTo", - listOf(ImmutableMethodParameter("J", null, "time")), - "Z", - AccessFlags.PUBLIC or AccessFlags.FINAL, - null, null, - MutableMethodImplementation(4) - ).toMutable() + with (it.mutableMethod) { + val seekHelperMethod = ImmutableMethod( + resultMethod.definingClass, + "seekTo", + listOf(ImmutableMethodParameter("J", null, "time")), + "Z", + AccessFlags.PUBLIC or AccessFlags.FINAL, + null, null, + MutableMethodImplementation(4) + ).toMutable() - // get enum type for the seek helper method - val seekSourceEnumType = seekFingerprintResultMethod.parameterTypes[1].toString() + val seekSourceEnumType = resultMethod.parameterTypes[1].toString() - // insert helper method instructions - seekHelperMethod.addInstructions( + seekHelperMethod.addInstructions( + 0, + """ + sget-object v0, $seekSourceEnumType->a:$seekSourceEnumType + invoke-virtual {p0, p1, p2, v0}, ${resultMethod.definingClass}->${resultMethod.name}(J$seekSourceEnumType)Z + move-result p1 + return p1 + """ + ) + + parentResult.mutableClass.methods.add(seekHelperMethod) + } + } ?: return SeekFingerprint.toErrorResult() + } ?: return PlayerInitFingerprint.toErrorResult() + + + VideoTimeParentFingerprint.result?.let { parentResult -> + VideoTimeFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.mutableMethod?.addInstruction( 0, - """ - sget-object v0, $seekSourceEnumType->a:$seekSourceEnumType - invoke-virtual {p0, p1, p2, v0}, ${seekFingerprintResultMethod.definingClass}->${seekFingerprintResultMethod.name}(J$seekSourceEnumType)Z - move-result p1 - return p1 - """ - ) + "invoke-static {p1, p2}, $VideoInformation->setCurrentVideoTimeHighPrecision(J)V" + ) ?: return VideoTimeFingerprint.toErrorResult() + } ?: return VideoTimeParentFingerprint.toErrorResult() - // add the seekTo method to the class for the integrations to call - mutableClass.methods.add(seekHelperMethod) - } - - val VideoTimeParentResult = VideoTimeParentFingerprint.result!! - VideoTimeFingerprint.resolve(context, VideoTimeParentResult.classDef) - val VideoTimeMethod = VideoTimeFingerprint.result!!.mutableMethod - VideoTimeMethod.addInstruction( - 0, - "invoke-static {p1, p2}, $VideoInformation->setCurrentVideoTimeHighPrecision(J)V" - ) /* Set current video time */ - val referenceResult = PlayerControllerSetTimeReferenceFingerprint.result!! - val PlayerControllerSetTimeMethod = - context.toMethodWalker(referenceResult.method) - .nextMethod(referenceResult.scanResult.patternScanResult!!.startIndex, true) + PlayerControllerSetTimeReferenceFingerprint.result?.let { + with(context + .toMethodWalker(it.method) + .nextMethod(it.scanResult.patternScanResult!!.startIndex, true) .getMethod() as MutableMethod - PlayerControllerSetTimeMethod.addInstruction( - 2, - "invoke-static {p1, p2}, $VideoInformation->setCurrentVideoTime(J)V" - ) + ) { + addInstruction( + 2, + "invoke-static {p1, p2}, $VideoInformation->setCurrentVideoTime(J)V" + ) + } + } ?: return PlayerControllerSetTimeReferenceFingerprint.toErrorResult() - val EmptyColorMethod = HookTimebarPatch.EmptyColorFingerprintResult.mutableMethod - val EmptyColorMethodInstructions = EmptyColorMethod.implementation!!.instructions - val methodReference = - HookTimebarPatch.TimbarFingerprintResult.method.let { method -> - (method.implementation!!.instructions.elementAt(2) as ReferenceInstruction).reference as MethodReference + with (HookTimebarPatch.EmptyColorFingerprintResult.mutableMethod) { + val methodReference = + HookTimebarPatch.TimbarFingerprintResult.method.let { + (it.implementation!!.instructions.elementAt(2) as ReferenceInstruction).reference as MethodReference + } + + val instructions = implementation!!.instructions + + reactReference = + ((instructions.elementAt(instructions.count() - 3) as ReferenceInstruction).reference as FieldReference).name + + + for ((index, instruction) in instructions.withIndex()) { + if (instruction.opcode != Opcode.CHECK_CAST) continue + val primaryRegister = (instruction as Instruction21c).registerA + 1 + val secondaryRegister = primaryRegister + 1 + addInstructions( + index, """ + invoke-virtual {p0}, $methodReference + move-result-wide v$primaryRegister + invoke-static {v$primaryRegister, v$secondaryRegister}, $VideoInformation->setCurrentVideoLength(J)V + """ + ) + break + } + } + + + PlayerControllerFingerprint.result?.mutableMethod?.let { + val instructions = it.implementation!!.instructions + + for ((index, instruction) in instructions.withIndex()) { + if (instruction.opcode != Opcode.CONST_STRING) continue + val register = (instruction as OneRegisterInstruction).registerA + it.replaceInstruction( + index, + "const-string v$register, \"$reactReference\"" + ) + break } - for ((index, instruction) in EmptyColorMethodInstructions.withIndex()) { - if (instruction.opcode != Opcode.CHECK_CAST) continue - val primaryRegister = (instruction as Instruction21c).registerA + 1 - val secondaryRegister = primaryRegister + 1 - EmptyColorMethod.addInstructions( - index, """ - invoke-virtual {p0}, $methodReference - move-result-wide v$primaryRegister - invoke-static {v$primaryRegister, v$secondaryRegister}, $VideoInformation->setCurrentVideoLength(J)V - """ - ) - break - } - - val reactReference = - ((EmptyColorMethodInstructions.elementAt(EmptyColorMethodInstructions.count() - 3) as ReferenceInstruction).reference as FieldReference).name - - val PlayerContrallerResult = PlayerControllerFingerprint.result!! - val PlayerContrallerMethod = PlayerContrallerResult.mutableMethod - val PlayerContrallerInstructions = PlayerContrallerMethod.implementation!!.instructions - - /* - Get the instance of the seekbar rectangle - */ - for ((index, instruction) in PlayerContrallerInstructions.withIndex()) { - if (instruction.opcode != Opcode.CONST_STRING) continue - val register = (instruction as OneRegisterInstruction).registerA - PlayerContrallerMethod.replaceInstruction( - index, - "const-string v$register, \"$reactReference\"" - ) - break - } + } ?: return PlayerControllerFingerprint.toErrorResult() - InsertResult = MainstreamVideoIdFingerprint.result!! - InsertMethod = InsertResult.mutableMethod - InsertIndex = InsertResult.scanResult.patternScanResult!!.endIndex + MainstreamVideoIdFingerprint.result?.let { + insertIndex = it.scanResult.patternScanResult!!.endIndex - videoIdRegister = - (InsertMethod.implementation!!.instructions[InsertIndex] as OneRegisterInstruction).registerA + with (it.mutableMethod) { + insertMethod = this + videoIdRegister = (implementation!!.instructions[insertIndex] as OneRegisterInstruction).registerA + } + offset++ // offset so setCurrentVideoId is called before any injected call + } ?: return MainstreamVideoIdFingerprint.toErrorResult() + injectCall("$VideoInformation->setCurrentVideoId(Ljava/lang/String;)V") injectCallonCreate(VideoInformation, "onCreate") - offset++ // offset so setCurrentVideoId is called before any injected call - return PatchResultSuccess() } companion object { - private var offset = 1 + const val VideoInformation = "$VIDEO_PATH/VideoInformation;" + private var offset = 0 + private var insertIndex: Int = 0 + private var reactReference: String? = null private var videoIdRegister: Int = 0 - private var InsertIndex: Int = 0 - private lateinit var InsertResult: MethodFingerprintResult - private lateinit var InsertMethod: MutableMethod - private lateinit var PlayerInitMethod: MutableMethod + private lateinit var insertMethod: MutableMethod + private lateinit var playerInitMethod: MutableMethod /** * Adds an invoke-static instruction, called with the new id when the video changes @@ -193,14 +202,14 @@ class MainstreamVideoIdPatch : BytecodePatch( fun injectCall( methodDescriptor: String ) { - InsertMethod.addInstructions( - InsertIndex + offset, // move-result-object offset + insertMethod.addInstructions( + insertIndex + offset, // move-result-object offset "invoke-static {v$videoIdRegister}, $methodDescriptor" ) } fun injectCallonCreate(MethodClass: String, MethodName: String) = - PlayerInitMethod.addInstruction( + playerInitMethod.addInstruction( 4, "invoke-static {v0}, $MethodClass->$MethodName(Ljava/lang/Object;)V" ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/swipe/swipecontrols/bytecode/fingerprints/SwipeControlsHostActivityFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/swipe/swipecontrols/bytecode/fingerprints/SwipeControlsHostActivityFingerprint.kt index b8043b007..c4e67fb04 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/swipe/swipecontrols/bytecode/fingerprints/SwipeControlsHostActivityFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/swipe/swipecontrols/bytecode/fingerprints/SwipeControlsHostActivityFingerprint.kt @@ -4,6 +4,7 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint object SwipeControlsHostActivityFingerprint : MethodFingerprint( customFingerprint = { methodDef -> - methodDef.definingClass == "Lapp/revanced/integrations/swipecontrols/SwipeControlsHostActivity;" && methodDef.name == "" + methodDef.definingClass == "Lapp/revanced/integrations/swipecontrols/SwipeControlsHostActivity;" + && methodDef.name == "" } ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/swipe/swipecontrols/bytecode/fingerprints/WatchWhileActivityFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/swipe/swipecontrols/bytecode/fingerprints/WatchWhileActivityFingerprint.kt index e1a0e17c5..cb654b60a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/swipe/swipecontrols/bytecode/fingerprints/WatchWhileActivityFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/swipe/swipecontrols/bytecode/fingerprints/WatchWhileActivityFingerprint.kt @@ -4,6 +4,7 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint object WatchWhileActivityFingerprint : MethodFingerprint( customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("WatchWhileActivity;") && methodDef.name == "" + methodDef.definingClass.endsWith("WatchWhileActivity;") + && methodDef.name == "" } ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/swipe/swipecontrols/bytecode/patch/SwipeControlsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/swipe/swipecontrols/bytecode/patch/SwipeControlsBytecodePatch.kt index 034d28fe1..d3680e7ed 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/swipe/swipecontrols/bytecode/patch/SwipeControlsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/swipe/swipecontrols/bytecode/patch/SwipeControlsBytecodePatch.kt @@ -9,11 +9,11 @@ import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.util.TypeUtil.traverseClassHierarchy import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable -import app.revanced.patches.youtube.misc.hdrbrightness.bytecode.patch.HDRBrightnessBytecodePatch import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch import app.revanced.patches.youtube.swipe.swipecontrols.bytecode.fingerprints.SwipeControlsHostActivityFingerprint import app.revanced.patches.youtube.swipe.swipecontrols.bytecode.fingerprints.WatchWhileActivityFingerprint import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.extensions.transformMethods import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.immutable.ImmutableMethod @@ -23,7 +23,6 @@ import org.jf.dexlib2.immutable.ImmutableMethod @Version("0.0.3") @DependsOn( [ - HDRBrightnessBytecodePatch::class, PlayerTypeHookPatch::class ] ) @@ -34,8 +33,8 @@ class SwipeControlsBytecodePatch : BytecodePatch( ) ) { override fun execute(context: BytecodeContext): PatchResult { - val wrapperClass = SwipeControlsHostActivityFingerprint.result!!.mutableClass - val targetClass = WatchWhileActivityFingerprint.result!!.mutableClass + val wrapperClass = SwipeControlsHostActivityFingerprint.result?.mutableClass ?: return SwipeControlsHostActivityFingerprint.toErrorResult() + val targetClass = WatchWhileActivityFingerprint.result?.mutableClass ?: return WatchWhileActivityFingerprint.toErrorResult() // inject the wrapper class from integrations into the class hierarchy of WatchWhileActivity wrapperClass.setSuperClass(targetClass.superclass) diff --git a/src/main/kotlin/app/revanced/patches/youtube/swipe/swipecontrols/resource/patch/SwipeControlsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/swipe/swipecontrols/resource/patch/SwipeControlsPatch.kt index 37222d88c..70eb4a1fd 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/swipe/swipecontrols/resource/patch/SwipeControlsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/swipe/swipecontrols/resource/patch/SwipeControlsPatch.kt @@ -10,6 +10,7 @@ import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.ResourcePatch import app.revanced.patches.youtube.swipe.swipecontrols.bytecode.patch.SwipeControlsBytecodePatch +import app.revanced.patches.youtube.swipe.swipebrightnessinhdr.bytecode.patch.SwipeGestureBrightnessInHDRPatch import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsPatch import app.revanced.shared.annotation.YouTubeCompatibility import app.revanced.shared.util.resources.ResourceHelper @@ -22,7 +23,8 @@ import app.revanced.shared.util.resources.ResourceUtils.copyResources @DependsOn( [ SettingsPatch::class, - SwipeControlsBytecodePatch::class + SwipeControlsBytecodePatch::class, + SwipeGestureBrightnessInHDRPatch::class ] ) @YouTubeCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/quality/bytecode/fingerprints/VideoQualityReferenceFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/quality/bytecode/fingerprints/VideoQualityReferenceFingerprint.kt index ae6cdc4c8..ceb107e32 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/quality/bytecode/fingerprints/VideoQualityReferenceFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/quality/bytecode/fingerprints/VideoQualityReferenceFingerprint.kt @@ -6,7 +6,11 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object VideoQualityReferenceFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf( - Opcode.IPUT_OBJECT, Opcode.RETURN_VOID + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L"), + opcodes = listOf( + Opcode.IPUT_OBJECT, + Opcode.RETURN_VOID ) ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/quality/bytecode/fingerprints/VideoQualitySetterFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/quality/bytecode/fingerprints/VideoQualitySetterFingerprint.kt index 92c86bbf8..c87e6e5ed 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/quality/bytecode/fingerprints/VideoQualitySetterFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/quality/bytecode/fingerprints/VideoQualitySetterFingerprint.kt @@ -6,10 +6,10 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object VideoQualitySetterFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("[L", "I", "I", "Z", "I"), - listOf( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("[L", "I", "I", "Z", "I"), + opcodes = listOf( Opcode.IF_EQZ, Opcode.INVOKE_VIRTUAL, Opcode.MOVE_RESULT_OBJECT, diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/quality/bytecode/fingerprints/VideoUserQualityChangeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/quality/bytecode/fingerprints/VideoUserQualityChangeFingerprint.kt index 811c0a6f2..a1d41b955 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/quality/bytecode/fingerprints/VideoUserQualityChangeFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/quality/bytecode/fingerprints/VideoUserQualityChangeFingerprint.kt @@ -6,10 +6,10 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object VideoUserQualityChangeFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("L","L","I","J"), - listOf( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L","L","I","J"), + opcodes = listOf( Opcode.MOVE, Opcode.MOVE_WIDE, Opcode.INVOKE_INTERFACE_RANGE, diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/quality/bytecode/patch/VideoQualityBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/quality/bytecode/patch/VideoQualityBytecodePatch.kt index 530847023..511adf2bb 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/quality/bytecode/patch/VideoQualityBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/quality/bytecode/patch/VideoQualityBytecodePatch.kt @@ -15,6 +15,7 @@ import app.revanced.patches.youtube.video.quality.bytecode.fingerprints.VideoQua import app.revanced.patches.youtube.video.quality.bytecode.fingerprints.VideoQualitySetterFingerprint import app.revanced.patches.youtube.video.quality.bytecode.fingerprints.VideoUserQualityChangeFingerprint import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult import app.revanced.shared.util.integrations.Constants.VIDEO_PATH import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.reference.FieldReference @@ -28,42 +29,39 @@ class VideoQualityBytecodePatch : BytecodePatch( VideoQualitySetterFingerprint ) ) { + override fun execute(context: BytecodeContext): PatchResult { + VideoQualitySetterFingerprint.result?.let { parentResult -> + VideoQualityReferenceFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let { result -> + val instructions = result.method.implementation!!.instructions + val qualityFieldReference = + (instructions.elementAt(0) as ReferenceInstruction).reference as FieldReference + + val qIndexMethodName = + context.classes.single { it.type == qualityFieldReference.type }.methods.single { it.parameterTypes.first() == "I" }.name + + parentResult.mutableMethod.addInstructions( + 0, """ + iget-object v0, p0, ${result.classDef.type}->${qualityFieldReference.name}:${qualityFieldReference.type} + const-string v1, "$qIndexMethodName" + invoke-static {p1, p2, v0, v1}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->setVideoQuality([Ljava/lang/Object;ILjava/lang/Object;Ljava/lang/String;)I + move-result p2 + """, + ) + } ?: return VideoQualityReferenceFingerprint.toErrorResult() + + VideoUserQualityChangeFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.mutableMethod?.addInstruction( + 0, + "invoke-static {p3}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->userChangedQuality(I)V" + ) ?: return VideoUserQualityChangeFingerprint.toErrorResult() + + } ?: return VideoQualitySetterFingerprint.toErrorResult() + + LegacyVideoIdPatch.injectCall("$INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V") + + return PatchResultSuccess() + } private companion object { const val INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR = "$VIDEO_PATH/VideoQualityPatch;" } - override fun execute(context: BytecodeContext): PatchResult { - val setterMethod = VideoQualitySetterFingerprint.result!! - - VideoUserQualityChangeFingerprint.resolve(context, setterMethod.classDef) - val userQualityResult = VideoUserQualityChangeFingerprint.result!! - - VideoQualityReferenceFingerprint.resolve(context, setterMethod.classDef) - val qualityFieldReference = - VideoQualityReferenceFingerprint.result!!.method.let { method -> - (method.implementation!!.instructions.elementAt(0) as ReferenceInstruction).reference as FieldReference - } - - LegacyVideoIdPatch.injectCall("$INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V") - - val qIndexMethodName = - context.classes.single { it.type == qualityFieldReference.type }.methods.single { it.parameterTypes.first() == "I" }.name - - setterMethod.mutableMethod.addInstructions( - 0, - """ - iget-object v0, p0, ${setterMethod.classDef.type}->${qualityFieldReference.name}:${qualityFieldReference.type} - const-string v1, "$qIndexMethodName" - invoke-static {p1, p2, v0, v1}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->setVideoQuality([Ljava/lang/Object;ILjava/lang/Object;Ljava/lang/String;)I - move-result p2 - """, - ) - - userQualityResult.mutableMethod.addInstruction( - 0, - "invoke-static {p3}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->userChangedQuality(I)V" - ) - - return PatchResultSuccess() - } } diff --git a/src/main/kotlin/app/revanced/shared/patches/integrations/AbstractIntegrationsPatch.kt b/src/main/kotlin/app/revanced/shared/patches/integrations/AbstractIntegrationsPatch.kt index ff0708ba1..2cb8ee5eb 100644 --- a/src/main/kotlin/app/revanced/shared/patches/integrations/AbstractIntegrationsPatch.kt +++ b/src/main/kotlin/app/revanced/shared/patches/integrations/AbstractIntegrationsPatch.kt @@ -9,6 +9,7 @@ import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.shared.extensions.toErrorResult import org.jf.dexlib2.iface.Method @Description("Applies mandatory patches to implement the ReVanced integrations into the application.") @@ -37,7 +38,7 @@ abstract class AbstractIntegrationsPatch( "sput-object v$contextRegister, " + "$integrationsDescriptor->context:Landroid/content/Context;" ) - } ?: return PatchResultError("Could not find hook target fingerprint.") + } ?: return toErrorResult() return PatchResultSuccess() }