feat(youtube/hide-button-container): changed to expose 'Experimental Flags' on YouTube v18.20.39 https://github.com/inotia00/ReVanced_Extended/issues/1103

This commit is contained in:
inotia00 2023-07-11 21:44:21 +09:00
parent 16a918a74c
commit 6346699d8d
5 changed files with 87 additions and 10 deletions

View File

@ -44,6 +44,9 @@ class ComponentParserPatch : BytecodePatch(
EmptyComponentBuilderFingerprint.result?.let {
it.mutableMethod.apply {
val byteBufferClassIndex = it.scanResult.patternScanResult!!.startIndex
byteBufferClassLabel = getInstruction<ReferenceInstruction>(byteBufferClassIndex).reference.toString()
val targetIndex = getStringIndex("Failed to convert Element to Flatbuffers: %s") + 2
val builderMethodDescriptor =
getInstruction<ReferenceInstruction>(targetIndex).reference
@ -120,6 +123,7 @@ class ComponentParserPatch : BytecodePatch(
}
internal companion object {
lateinit var byteBufferClassLabel: String
lateinit var emptyComponentLabel: String
lateinit var insertMethod: MutableMethod
@ -163,18 +167,23 @@ class ComponentParserPatch : BytecodePatch(
}
}
fun objectHook(
// only for YouTube v18.20.39
fun legacyHook(
descriptor: String
) {
insertMethod.apply {
addInstructionsWithLabels(
0, """
move-object/from16 v0, p2
sget-object v1, $definingClass->buffer:Ljava/nio/ByteBuffer;
invoke-static {v0, v1}, $descriptor(Ljava/lang/Object;Ljava/nio/ByteBuffer;)Z
move-result v0
if-eqz v0, :unfiltered
""" + emptyComponentLabel, ExternalLabel("unfiltered", getInstruction(0))
insertIndex,
"""
move-object/from16 v$freeRegister, p3
iget-object v$freeRegister, v$freeRegister, ${parameters[2]}->b:Ljava/lang/Object;
if-eqz v$freeRegister, :unfiltered
check-cast v$freeRegister, $byteBufferClassLabel
iget-object v$freeRegister, v$freeRegister, $byteBufferClassLabel->b:Ljava/nio/ByteBuffer;
invoke-static {v$stringBuilderRegister, v$identifierRegister, v$objectRegister, v$freeRegister}, $descriptor(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/Object;Ljava/nio/ByteBuffer;)Z
move-result v$freeRegister
if-eqz v$freeRegister, :unfiltered
""" + emptyComponentLabel, ExternalLabel("unfiltered", getInstruction(insertIndex))
)
}
}

View File

@ -12,6 +12,7 @@ import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility
import app.revanced.patches.youtube.utils.litho.patch.LithoFilterPatch
import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch
import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch.Companion.belowAndroid1820
import app.revanced.util.integrations.Constants.PATCHES_PATH
@Patch
@ -28,6 +29,16 @@ import app.revanced.util.integrations.Constants.PATCHES_PATH
class ButtonContainerPatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
if (belowAndroid1820) {
LithoFilterPatch.addFilter("$PATCHES_PATH/ads/ActionButtonsFilter;")
SettingsPatch.addPreference(
arrayOf(
"PREFERENCE: BOTTOM_PLAYER_SETTINGS",
"SETTINGS: EXPERIMENTAL_BUTTON_CONTAINER"
)
)
}
LithoFilterPatch.addFilter("$PATCHES_PATH/ads/ButtonsFilter;")
/**

View File

@ -13,17 +13,20 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.patch.litho.ComponentParserPatch
import app.revanced.patches.shared.patch.litho.ComponentParserPatch.Companion.generalHook
import app.revanced.patches.shared.patch.litho.ComponentParserPatch.Companion.legacyHook
import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility
import app.revanced.patches.youtube.utils.litho.fingerprints.ByteBufferFingerprint
import app.revanced.patches.youtube.utils.litho.fingerprints.LithoFilterFingerprint
import app.revanced.patches.youtube.utils.playertype.patch.PlayerTypeHookPatch
import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch
import app.revanced.util.integrations.Constants.ADS_PATH
import java.io.Closeable
@DependsOn(
[
ComponentParserPatch::class,
PlayerTypeHookPatch::class
PlayerTypeHookPatch::class,
SettingsPatch::class
]
)
@YouTubeCompatibility
@ -42,7 +45,10 @@ class LithoFilterPatch : BytecodePatch(
"sput-object p0, $ADS_PATH/LowLevelFilter;->byteBuffer:Ljava/nio/ByteBuffer;"
) ?: return ByteBufferFingerprint.toErrorResult()
generalHook("$ADS_PATH/LithoFilterPatch;->filters")
if (SettingsPatch.belowAndroid1820)
legacyHook("$ADS_PATH/LithoFilterPatch;->filters")
else
generalHook("$ADS_PATH/LithoFilterPatch;->filters")
LithoFilterFingerprint.result?.mutableMethod?.apply {
removeInstructions(2, 4) // Remove dummy filter.

View File

@ -24,6 +24,8 @@ import app.revanced.util.resources.ResourceUtils.copyResources
import org.w3c.dom.Element
import java.io.File
import java.nio.file.Paths
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
@Patch
@Name("settings")
@ -46,6 +48,41 @@ class SettingsPatch : AbstractSettingsResourcePatch(
super.execute(context)
contexts = context
/**
* Check if the YouTube version is v18.20.39
*/
val resourceXmlFile = context["res/values/integers.xml"].readBytes()
for (threadIndex in 0 until THREAD_COUNT) {
threadPoolExecutor.execute thread@{
context.xmlEditor[resourceXmlFile.inputStream()].use { editor ->
val resources = editor.file.documentElement.childNodes
val resourcesLength = resources.length
val jobSize = resourcesLength / THREAD_COUNT
val batchStart = jobSize * threadIndex
val batchEnd = jobSize * (threadIndex + 1)
element@ for (i in batchStart until batchEnd) {
if (i >= resourcesLength) return@thread
val node = resources.item(i)
if (node !is Element) continue
if (node.nodeName != "integer" || !node.getAttribute("name").startsWith("google_play_services_version"))
continue
belowAndroid1820 = node.textContent.toInt() <= 232100000
break
}
}
}
}
threadPoolExecutor
.also { it.shutdown() }
.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS)
/**
* create directory for the untranslated language resources
*/
@ -139,7 +176,11 @@ class SettingsPatch : AbstractSettingsResourcePatch(
}
companion object {
private val THREAD_COUNT = Runtime.getRuntime().availableProcessors()
private val threadPoolExecutor = Executors.newFixedThreadPool(THREAD_COUNT)
internal lateinit var contexts: ResourceContext
internal var belowAndroid1820: Boolean = false
internal fun addPreference(settingArray: Array<String>) {
contexts.addPreference(settingArray)

View File

@ -38,6 +38,16 @@
<SwitchPreference android:title="@string/revanced_hide_button_playlist_title" android:key="revanced_hide_button_playlist" android:defaultValue="false" android:summaryOn="@string/revanced_hide_button_playlist_summary_on" android:summaryOff="@string/revanced_hide_button_playlist_summary_off" />
<SwitchPreference android:title="@string/revanced_hide_button_rewards_title" android:key="revanced_hide_button_rewards" android:defaultValue="false" android:summaryOn="@string/revanced_hide_button_rewards_summary_on" android:summaryOff="@string/revanced_hide_button_rewards_summary_off" />SETTINGS: BUTTON_CONTAINER -->
<!-- SETTINGS: EXPERIMENTAL_BUTTON_CONTAINER
<Preference android:title=" " android:selectable="false" android:summary="@string/revanced_experimental_flag" />
<SwitchPreference android:title="@string/revanced_hide_button_live_chat_title" android:key="revanced_hide_button_live_chat" android:defaultValue="false" android:summaryOn="@string/revanced_hide_button_live_chat_summary_on" android:summaryOff="@string/revanced_hide_button_live_chat_summary_off" />
<SwitchPreference android:title="@string/revanced_hide_button_remix_title" android:key="revanced_hide_button_remix" android:defaultValue="false" android:summaryOn="@string/revanced_hide_button_remix_summary_on" android:summaryOff="@string/revanced_hide_button_remix_summary_off" />
<SwitchPreference android:title="@string/revanced_hide_button_report_title" android:key="revanced_hide_button_report" android:defaultValue="false" android:summaryOn="@string/revanced_hide_button_report_summary_on" android:summaryOff="@string/revanced_hide_button_report_summary_off" />
<SwitchPreference android:title="@string/revanced_hide_button_share_title" android:key="revanced_hide_button_share" android:defaultValue="false" android:summaryOn="@string/revanced_hide_button_share_summary_on" android:summaryOff="@string/revanced_hide_button_share_summary_off" />
<SwitchPreference android:title="@string/revanced_hide_button_shop_title" android:key="revanced_hide_button_shop" android:defaultValue="false" android:summaryOn="@string/revanced_hide_button_shop_summary_on" android:summaryOff="@string/revanced_hide_button_shop_summary_off" />
<SwitchPreference android:title="@string/revanced_hide_button_thanks_title" android:key="revanced_hide_button_thanks" android:defaultValue="false" android:summaryOn="@string/revanced_hide_button_thanks_summary_on" android:summaryOff="@string/revanced_hide_button_thanks_summary_off" />SETTINGS: EXPERIMENTAL_BUTTON_CONTAINER -->
<!-- SETTINGS: COMMENT_COMPONENTS
<Preference android:title=" " android:selectable="false" android:summary="@string/revanced_comments_title" />
<SwitchPreference android:title="@string/revanced_hide_channel_guidelines_title" android:key="revanced_hide_channel_guidelines" android:defaultValue="true" android:summaryOn="@string/revanced_hide_channel_guidelines_summary_on" android:summaryOff="@string/revanced_hide_channel_guidelines_summary_off" />