From b9018ad7eb968073428b378c560de62efdd44ba4 Mon Sep 17 00:00:00 2001 From: OLAF74 Date: Sun, 14 Jul 2024 08:15:02 +0500 Subject: [PATCH] feat(YouTube Music): add `Alternative domain` patch (#64) * Adaptation of the patch from YouTube * Copy unchanged translations from YouTube Translations * feat: apply code review suggestions * fix: arrange lexicographic settings using `Closeable` --------- Co-authored-by: inotia00 <108592928+inotia00@users.noreply.github.com> --- .../AlternativeDomainBytecodePatch.kt | 6 ++++ .../AlternativeDomainPatch.kt | 35 +++++++++++++++++++ .../BaseAlternativeDomainPatch.kt | 30 ++++++++++++++++ .../MessageDigestImageUrlFingerprint.kt | 2 +- .../MessageDigestImageUrlParentFingerprint.kt | 2 +- .../general/AlternativeDomainBytecodePatch.kt | 6 ++++ .../general/AlternativeThumbnailsPatch.kt | 29 +-------------- .../music/settings/host/values/strings.xml | 5 +++ .../music/translations/ru-rRU/strings.xml | 4 +++ 9 files changed, 89 insertions(+), 30 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/music/misc/alternativedomain/AlternativeDomainBytecodePatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/misc/alternativedomain/AlternativeDomainPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/shared/alternativedomain/BaseAlternativeDomainPatch.kt rename src/main/kotlin/app/revanced/patches/{youtube/alternativethumbnails/general => shared/alternativedomain}/fingerprints/MessageDigestImageUrlFingerprint.kt (80%) rename src/main/kotlin/app/revanced/patches/{youtube/alternativethumbnails/general => shared/alternativedomain}/fingerprints/MessageDigestImageUrlParentFingerprint.kt (83%) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/AlternativeDomainBytecodePatch.kt diff --git a/src/main/kotlin/app/revanced/patches/music/misc/alternativedomain/AlternativeDomainBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/alternativedomain/AlternativeDomainBytecodePatch.kt new file mode 100644 index 000000000..0e59cd47d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/misc/alternativedomain/AlternativeDomainBytecodePatch.kt @@ -0,0 +1,6 @@ +package app.revanced.patches.music.misc.alternativedomain + +import app.revanced.patches.shared.alternativedomain.BaseAlternativeDomainPatch +import app.revanced.patches.music.utils.integrations.Constants.MISC_PATH + +object AlternativeDomainBytecodePatch : BaseAlternativeDomainPatch("$MISC_PATH/AlternativeDomainPatch;") \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/alternativedomain/AlternativeDomainPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/alternativedomain/AlternativeDomainPatch.kt new file mode 100644 index 000000000..9e57c97e1 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/misc/alternativedomain/AlternativeDomainPatch.kt @@ -0,0 +1,35 @@ +package app.revanced.patches.music.misc.alternativedomain + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.music.utils.settings.CategoryType +import app.revanced.patches.music.utils.settings.SettingsPatch +import app.revanced.util.patch.BaseBytecodePatch +import java.io.Closeable + +@Suppress("unused") +object AlternativeDomainPatch : BaseBytecodePatch( + name = "Alternative domain", + description = "Adds options to replace static images(avatars, playlist covers, etc.) domain.", + dependencies = setOf( + AlternativeDomainBytecodePatch::class, + SettingsPatch::class + ), + compatiblePackages = COMPATIBLE_PACKAGE +), Closeable { + override fun execute(context: BytecodeContext) { + } + // Use Closeable for lexicographic arrangement of settings. + override fun close() { + SettingsPatch.addSwitchPreference( + CategoryType.MISC, + "revanced_use_alternative_domain", + "false" + ) + SettingsPatch.addPreferenceWithIntent( + CategoryType.MISC, + "revanced_alternative_domain", + "revanced_use_alternative_domain" + ) + } +} diff --git a/src/main/kotlin/app/revanced/patches/shared/alternativedomain/BaseAlternativeDomainPatch.kt b/src/main/kotlin/app/revanced/patches/shared/alternativedomain/BaseAlternativeDomainPatch.kt new file mode 100644 index 000000000..71b7cbe8a --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/shared/alternativedomain/BaseAlternativeDomainPatch.kt @@ -0,0 +1,30 @@ +package app.revanced.patches.shared.alternativedomain + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patches.shared.alternativedomain.fingerprints.MessageDigestImageUrlFingerprint +import app.revanced.patches.shared.alternativedomain.fingerprints.MessageDigestImageUrlParentFingerprint +import app.revanced.util.resultOrThrow + +abstract class BaseAlternativeDomainPatch( + private val classDescriptor: String +) : BytecodePatch( + setOf(MessageDigestImageUrlParentFingerprint) +) { + override fun execute(context: BytecodeContext) { + + MessageDigestImageUrlFingerprint.resolve( + context, + MessageDigestImageUrlParentFingerprint.resultOrThrow().classDef + ) + + MessageDigestImageUrlFingerprint.resultOrThrow().mutableMethod.addInstructions( + 0, """ + invoke-static { p1 }, $classDescriptor->overrideImageURL(Ljava/lang/String;)Ljava/lang/String; + move-result-object p1 + """ + ) + + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/fingerprints/MessageDigestImageUrlFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/alternativedomain/fingerprints/MessageDigestImageUrlFingerprint.kt similarity index 80% rename from src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/fingerprints/MessageDigestImageUrlFingerprint.kt rename to src/main/kotlin/app/revanced/patches/shared/alternativedomain/fingerprints/MessageDigestImageUrlFingerprint.kt index 7ab7efbd1..3f1384d1a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/fingerprints/MessageDigestImageUrlFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/shared/alternativedomain/fingerprints/MessageDigestImageUrlFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.alternativethumbnails.general.fingerprints +package app.revanced.patches.shared.alternativedomain.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/fingerprints/MessageDigestImageUrlParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/alternativedomain/fingerprints/MessageDigestImageUrlParentFingerprint.kt similarity index 83% rename from src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/fingerprints/MessageDigestImageUrlParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/shared/alternativedomain/fingerprints/MessageDigestImageUrlParentFingerprint.kt index bf1c8337b..79def6369 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/fingerprints/MessageDigestImageUrlParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/shared/alternativedomain/fingerprints/MessageDigestImageUrlParentFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.alternativethumbnails.general.fingerprints +package app.revanced.patches.shared.alternativedomain.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/AlternativeDomainBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/AlternativeDomainBytecodePatch.kt new file mode 100644 index 000000000..76d0f0b58 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/AlternativeDomainBytecodePatch.kt @@ -0,0 +1,6 @@ +package app.revanced.patches.youtube.alternativethumbnails.general + +import app.revanced.patches.shared.alternativedomain.BaseAlternativeDomainPatch +import app.revanced.patches.youtube.utils.integrations.Constants.ALTERNATIVE_THUMBNAILS_CLASS_DESCRIPTOR + +object AlternativeDomainBytecodePatch : BaseAlternativeDomainPatch(ALTERNATIVE_THUMBNAILS_CLASS_DESCRIPTOR) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/AlternativeThumbnailsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/AlternativeThumbnailsPatch.kt index 9816bace3..ea79f77c0 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/AlternativeThumbnailsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/alternativethumbnails/general/AlternativeThumbnailsPatch.kt @@ -7,8 +7,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstructions import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable -import app.revanced.patches.youtube.alternativethumbnails.general.fingerprints.MessageDigestImageUrlFingerprint -import app.revanced.patches.youtube.alternativethumbnails.general.fingerprints.MessageDigestImageUrlParentFingerprint import app.revanced.patches.youtube.alternativethumbnails.general.fingerprints.cronet.RequestFingerprint import app.revanced.patches.youtube.alternativethumbnails.general.fingerprints.cronet.request.callback.OnFailureFingerprint import app.revanced.patches.youtube.alternativethumbnails.general.fingerprints.cronet.request.callback.OnResponseStartedFingerprint @@ -32,41 +30,23 @@ object AlternativeThumbnailsPatch : BaseBytecodePatch( name = "Alternative thumbnails", description = "Adds options to replace video thumbnails using the DeArrow API or image captures from the video.", dependencies = setOf( + AlternativeDomainBytecodePatch::class, NavigationBarHookPatch::class, PlayerTypeHookPatch::class, SettingsPatch::class, ), compatiblePackages = COMPATIBLE_PACKAGE, fingerprints = setOf( - MessageDigestImageUrlParentFingerprint, OnResponseStartedFingerprint, RequestFingerprint, ) ) { - private lateinit var loadImageUrlMethod: MutableMethod - private var loadImageUrlIndex = 0 - private lateinit var loadImageSuccessCallbackMethod: MutableMethod private var loadImageSuccessCallbackIndex = 0 private lateinit var loadImageErrorCallbackMethod: MutableMethod private var loadImageErrorCallbackIndex = 0 - /** - * @param highPriority If the hook should be called before all other hooks. - */ - @Suppress("SameParameterValue") - private fun addImageUrlHook(targetMethodClass: String, highPriority: Boolean) { - loadImageUrlMethod.addInstructions( - if (highPriority) 0 else loadImageUrlIndex, - """ - invoke-static { p1 }, $targetMethodClass->overrideImageURL(Ljava/lang/String;)Ljava/lang/String; - move-result-object p1 - """ - ) - loadImageUrlIndex += 2 - } - /** * If a connection completed, which includes normal 200 responses but also includes * status 404 and other error like http responses. @@ -102,13 +82,6 @@ object AlternativeThumbnailsPatch : BaseBytecodePatch( block: (MutableMethod) -> Unit ) = alsoResolve(fingerprint).also { block(it.mutableMethod) } - MessageDigestImageUrlFingerprint.resolveAndLetMutableMethod( - MessageDigestImageUrlParentFingerprint - ) { - loadImageUrlMethod = it - addImageUrlHook(ALTERNATIVE_THUMBNAILS_CLASS_DESCRIPTOR, true) - } - OnSucceededFingerprint.resolveAndLetMutableMethod(OnResponseStartedFingerprint) { loadImageSuccessCallbackMethod = it addImageUrlSuccessCallbackHook(ALTERNATIVE_THUMBNAILS_CLASS_DESCRIPTOR) diff --git a/src/main/resources/music/settings/host/values/strings.xml b/src/main/resources/music/settings/host/values/strings.xml index 1faf21011..55a3d2c88 100644 --- a/src/main/resources/music/settings/host/values/strings.xml +++ b/src/main/resources/music/settings/host/values/strings.xml @@ -391,6 +391,11 @@ Tap on the continue button and disable battery optimizations." Sanitize sharing links Removes tracking query parameters from URLs when sharing links. + Use alternative domain for images + Replaces the domain that is blocked in some regions so that playlist thumbnails, channel avatars, etc. can be received. + Alternative domain + The domain to fetch images from.\nNote: Only enter the domain name, i.e., without the \"https\:\/\/\" prefix. + Import / Export settings Import or export settings. diff --git a/src/main/resources/music/translations/ru-rRU/strings.xml b/src/main/resources/music/translations/ru-rRU/strings.xml index 5fc2577b6..1341eac4f 100644 --- a/src/main/resources/music/translations/ru-rRU/strings.xml +++ b/src/main/resources/music/translations/ru-rRU/strings.xml @@ -350,6 +350,10 @@ Продолжить Подчищать ссылки Убирает параметры отслеживания запросов из адресов при отправке ссылки. + Использовать альтернативный домен картинок + Заменяет домен, заблокированный в некоторых регионах, чтобы можно было получать миниатюры плейлистов, аватары каналов и т.д. + Альтернативный домен + Домен для получения картинок.\nВажно: Вводите только название домена без префикса \"https\:\/\/\". Восстановить / Извлечь настройки Восстановить или извлечь настройки. Извлечь настройки в файл