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>
This commit is contained in:
OLAF74 2024-07-14 08:15:02 +05:00 committed by GitHub
parent d410f29f7a
commit b9018ad7eb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 89 additions and 30 deletions

View File

@ -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;")

View File

@ -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"
)
}
}

View File

@ -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
"""
)
}
}

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -391,6 +391,11 @@ Tap on the continue button and disable battery optimizations."</string>
<string name="revanced_sanitize_sharing_links_title">Sanitize sharing links</string>
<string name="revanced_sanitize_sharing_links_summary">Removes tracking query parameters from URLs when sharing links.</string>
<string name="revanced_use_alternative_domain_title">Use alternative domain for images</string>
<string name="revanced_use_alternative_domain_summary">Replaces the domain that is blocked in some regions so that playlist thumbnails, channel avatars, etc. can be received.</string>
<string name="revanced_alternative_domain_title">Alternative domain</string>
<string name="revanced_alternative_domain_summary">The domain to fetch images from.\nNote: Only enter the domain name, i.e., without the \"https\:\/\/\" prefix.</string>
<string name="revanced_extended_settings_import_export_title">Import/Export settings</string>
<string name="revanced_extended_settings_import_export_summary">Import or export settings.</string>

View File

@ -350,6 +350,10 @@
<string name="gms_core_dialog_continue_text">Продолжить</string>
<string name="revanced_sanitize_sharing_links_title">Подчищать ссылки</string>
<string name="revanced_sanitize_sharing_links_summary">Убирает параметры отслеживания запросов из адресов при отправке ссылки.</string>
<string name="revanced_use_alternative_domain_title">Использовать альтернативный домен картинок</string>
<string name="revanced_use_alternative_domain_summary">Заменяет домен, заблокированный в некоторых регионах, чтобы можно было получать миниатюры плейлистов, аватары каналов и т.д.</string>
<string name="revanced_alternative_domain_title">Альтернативный домен</string>
<string name="revanced_alternative_domain_summary">Домен для получения картинок.\nВажно: Вводите только название домена без префикса \"https\:\/\/\".</string>
<string name="revanced_extended_settings_import_export_title">Восстановить / Извлечь настройки</string>
<string name="revanced_extended_settings_import_export_summary">Восстановить или извлечь настройки.</string>
<string name="revanced_extended_settings_export_as_file">Извлечь настройки в файл</string>