diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/general/bytecode/patch/GeneralAdsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/general/bytecode/patch/GeneralAdsBytecodePatch.kt
index 8131fa90e..3a9ae3238 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/ads/general/bytecode/patch/GeneralAdsBytecodePatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/ads/general/bytecode/patch/GeneralAdsBytecodePatch.kt
@@ -2,68 +2,46 @@ package app.revanced.patches.youtube.ads.general.bytecode.patch
import app.revanced.extensions.findMutableMethodOf
import app.revanced.extensions.injectHideCall
-import app.revanced.extensions.toResult
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
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.shared.annotation.YouTubeCompatibility
-import app.revanced.patches.shared.patch.mapping.ResourceMappingPatch
+import app.revanced.patches.youtube.misc.resourceid.patch.SharedResourceIdPatch
import app.revanced.util.bytecode.BytecodeHelper.updatePatchStatus
-import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.formats.*
+import org.jf.dexlib2.iface.instruction.formats.Instruction31i
+import org.jf.dexlib2.iface.instruction.formats.Instruction35c
@Name("hide-general-ads-bytecode-patch")
-@DependsOn([ResourceMappingPatch::class])
-@YouTubeCompatibility
+@DependsOn([SharedResourceIdPatch::class])
@Version("0.0.1")
class GeneralAdsBytecodePatch : BytecodePatch() {
- private val resourceIds = arrayOf(
- "id" to "ad_attribution",
- "layout" to "horizontal_card_list"
- ).map { (type, name) ->
- ResourceMappingPatch
- .resourceMappings
- .single { it.type == type && it.name == name }.id
- }
- private var patchSuccessArray = Array(resourceIds.size) {false}
-
override fun execute(context: BytecodeContext): PatchResult {
context.classes.forEach { classDef ->
classDef.methods.forEach { method ->
with(method.implementation) {
this?.instructions?.forEachIndexed { index, instruction ->
- when (instruction.opcode) {
- Opcode.CONST -> {
- when ((instruction as Instruction31i).wideLiteral) {
- resourceIds[0] -> { // general ads
- val insertIndex = index + 1
- val invokeInstruction = instructions.elementAt(insertIndex)
- if (invokeInstruction.opcode != Opcode.INVOKE_VIRTUAL) return@forEachIndexed
+ if (instruction.opcode != org.jf.dexlib2.Opcode.CONST)
+ return@forEachIndexed
+ // Instruction to store the id adAttribution into a register
+ if ((instruction as Instruction31i).wideLiteral != SharedResourceIdPatch.adAttributionLabelId)
+ return@forEachIndexed
- val mutableMethod = context.proxy(classDef).mutableClass.findMutableMethodOf(method)
+ val insertIndex = index + 1
- val viewRegister = (invokeInstruction as Instruction35c).registerC
- mutableMethod.implementation!!.injectHideCall(insertIndex, viewRegister, "ads/GeneralAdsPatch", "hideAdAttributionView")
- patchSuccessArray[0] = true
- }
+ // Call to get the view with the id adAttribution
+ with(instructions.elementAt(insertIndex)) {
+ if (opcode != org.jf.dexlib2.Opcode.INVOKE_VIRTUAL)
+ return@forEachIndexed
- resourceIds[1] -> { // breaking news
- val insertIndex = index + 4
- val invokeInstruction = instructions.elementAt(insertIndex)
- if (invokeInstruction.opcode != Opcode.CHECK_CAST) return@forEachIndexed
-
- val mutableMethod = context.proxy(classDef).mutableClass.findMutableMethodOf(method)
-
- val viewRegister = (invokeInstruction as Instruction21c).registerA
- mutableMethod.implementation!!.injectHideCall(insertIndex, viewRegister, "ads/GeneralAdsPatch", "hideBreakingNewsShelf")
- patchSuccessArray[1] = true
- }
- }
- }
- else -> return@forEachIndexed
+ // Hide the view
+ val viewRegister = (this as Instruction35c).registerC
+ context.proxy(classDef)
+ .mutableClass
+ .findMutableMethodOf(method)
+ .implementation!!.injectHideCall(insertIndex, viewRegister, "ads/GeneralAdsPatch", "hideAdAttributionView")
}
}
}
@@ -71,6 +49,6 @@ class GeneralAdsBytecodePatch : BytecodePatch() {
}
context.updatePatchStatus("GeneralAds")
- return toResult(patchSuccessArray.indexOf(false))
+ return PatchResultSuccess()
}
}
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/breakingnews/fingerprints/BreakingNewsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/breakingnews/fingerprints/BreakingNewsFingerprint.kt
new file mode 100644
index 000000000..2ae095107
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/breakingnews/fingerprints/BreakingNewsFingerprint.kt
@@ -0,0 +1,21 @@
+package app.revanced.patches.youtube.layout.general.breakingnews.fingerprints
+
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import app.revanced.patches.youtube.misc.resourceid.patch.SharedResourceIdPatch
+import org.jf.dexlib2.Opcode
+import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
+
+object BreakingNewsFingerprint : MethodFingerprint(
+ opcodes = listOf(
+ Opcode.CONST,
+ Opcode.CONST_4,
+ Opcode.INVOKE_VIRTUAL,
+ Opcode.MOVE_RESULT_OBJECT
+ ),
+ customFingerprint = { methodDef ->
+ methodDef.implementation?.instructions?.any { instruction ->
+ instruction.opcode.ordinal == Opcode.CONST.ordinal &&
+ (instruction as? WideLiteralInstruction)?.wideLiteral == SharedResourceIdPatch.horizontalCardListId
+ } == true
+ }
+)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/general/breakingnews/patch/BreakingNewsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/general/breakingnews/patch/BreakingNewsPatch.kt
new file mode 100644
index 000000000..b2b046d53
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/general/breakingnews/patch/BreakingNewsPatch.kt
@@ -0,0 +1,64 @@
+package app.revanced.patches.youtube.layout.general.breakingnews.patch
+
+import app.revanced.extensions.toErrorResult
+import app.revanced.patcher.annotation.Description
+import app.revanced.patcher.annotation.Name
+import app.revanced.patcher.annotation.Version
+import app.revanced.patcher.data.BytecodeContext
+import app.revanced.patcher.extensions.addInstruction
+import app.revanced.patcher.extensions.instruction
+import app.revanced.patcher.patch.BytecodePatch
+import app.revanced.patcher.patch.PatchResult
+import app.revanced.patcher.patch.PatchResultSuccess
+import app.revanced.patcher.patch.annotations.DependsOn
+import app.revanced.patcher.patch.annotations.Patch
+import app.revanced.patches.shared.annotation.YouTubeCompatibility
+import app.revanced.patches.youtube.layout.general.breakingnews.fingerprints.BreakingNewsFingerprint
+import app.revanced.patches.youtube.misc.resourceid.patch.SharedResourceIdPatch
+import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsPatch
+import app.revanced.util.integrations.Constants.GENERAL
+import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
+
+@Patch
+@Name("hide-breaking-news-shelf")
+@Description("Hides the breaking news shelf on the homepage tab.")
+@DependsOn(
+ [
+ SettingsPatch::class,
+ SharedResourceIdPatch::class,
+ ]
+)
+@YouTubeCompatibility
+@Version("0.0.1")
+class BreakingNewsPatch : BytecodePatch(
+ listOf(
+ BreakingNewsFingerprint,
+ )
+) {
+ override fun execute(context: BytecodeContext): PatchResult {
+ BreakingNewsFingerprint.result?.let {
+ it.mutableMethod.apply {
+ val targetIndex = it.scanResult.patternScanResult!!.endIndex
+ val targetRegister = (instruction(targetIndex) as OneRegisterInstruction).registerA
+ addInstruction(
+ targetIndex + 1,
+ "invoke-static {v$targetRegister}, $GENERAL->hideBreakingNewsShelf(Landroid/view/View;)V"
+ )
+ }
+ }?: return BreakingNewsFingerprint.toErrorResult()
+
+ /**
+ * Add settings
+ */
+ SettingsPatch.addPreference(
+ arrayOf(
+ "PREFERENCE: GENERAL_SETTINGS",
+ "SETTINGS: HIDE_BREAKING_NEWS_SHELF"
+ )
+ )
+
+ SettingsPatch.updatePatchStatus("hide-breaking-news-shelf")
+
+ return PatchResultSuccess()
+ }
+}
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/resourceid/patch/SharedResourceIdPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/resourceid/patch/SharedResourceIdPatch.kt
index 41f2cd511..b85052b51 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/resourceid/patch/SharedResourceIdPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/resourceid/patch/SharedResourceIdPatch.kt
@@ -20,6 +20,7 @@ class SharedResourceIdPatch : ResourcePatch {
internal companion object {
var accessibilityProgressTimeLabelId: Long = -1
var accountSwitcherAccessibilityLabelId: Long = -1
+ var adAttributionLabelId: Long = -1
var appearanceStringId: Long = -1
var backgroundCategoryLabelId: Long = -1
var barContainerHeightLabelId: Long = -1
@@ -33,6 +34,7 @@ class SharedResourceIdPatch : ResourcePatch {
var fabLabelId: Long = -1
var filterBarHeightLabelId: Long = -1
var floatyBarTopMarginLabelId: Long = -1
+ var horizontalCardListId: Long = -1
var imageOnlyTabId: Long = -1
var inlineTimeBarColorizedBarPlayedColorDarkId: Long = -1
var inlineTimeBarPlayedNotHighlightedColorId: Long = -1
@@ -64,6 +66,7 @@ class SharedResourceIdPatch : ResourcePatch {
accessibilityProgressTimeLabelId = find(STRING, "accessibility_player_progress_time")
accountSwitcherAccessibilityLabelId = find(STRING, "account_switcher_accessibility_label")
+ adAttributionLabelId = find(ID, "ad_attribution")
appearanceStringId = find(STRING, "app_theme_appearance_dark")
backgroundCategoryLabelId = find(STRING, "pref_background_and_offline_category")
barContainerHeightLabelId = find(DIMEN, "bar_container_height")
@@ -77,6 +80,7 @@ class SharedResourceIdPatch : ResourcePatch {
fabLabelId = find(ID, "fab")
filterBarHeightLabelId = find(DIMEN, "filter_bar_height")
floatyBarTopMarginLabelId = find(DIMEN, "floaty_bar_button_top_margin")
+ horizontalCardListId = find(LAYOUT, "horizontal_card_list")
imageOnlyTabId = find(LAYOUT, "image_only_tab")
inlineTimeBarColorizedBarPlayedColorDarkId = find(COLOR, "inline_time_bar_colorized_bar_played_color_dark")
inlineTimeBarPlayedNotHighlightedColorId = find(COLOR, "inline_time_bar_played_not_highlighted_color")
diff --git a/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/src/main/resources/youtube/settings/xml/revanced_prefs.xml
index ed20fac40..56e879893 100644
--- a/src/main/resources/youtube/settings/xml/revanced_prefs.xml
+++ b/src/main/resources/youtube/settings/xml/revanced_prefs.xml
@@ -135,10 +135,12 @@
-
SETTINGS: HIDE_GENERAL_ADS -->
+
+
@@ -479,6 +481,7 @@
+