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