diff --git a/api/revanced-patches.api b/api/revanced-patches.api index 4b518d1d47..35e2832131 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -1724,6 +1724,12 @@ public final class app/revanced/patches/youtube/layout/thumbnails/AlternativeThu public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public final class app/revanced/patches/youtube/layout/thumbnails/BypassImageRegionRestrictions : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/youtube/layout/thumbnails/BypassImageRegionRestrictions; + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + public final class app/revanced/patches/youtube/misc/announcements/AnnouncementsPatch : app/revanced/patcher/patch/BytecodePatch { public static final field INSTANCE Lapp/revanced/patches/youtube/misc/announcements/AnnouncementsPatch; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V @@ -1790,6 +1796,16 @@ public final class app/revanced/patches/youtube/misc/gms/GmsCoreSupportResourceP public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V } +public final class app/revanced/patches/youtube/misc/imageurlhook/CronetImageUrlHook : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/youtube/misc/imageurlhook/CronetImageUrlHook; + public final fun addImageUrlErrorCallbackHook (Ljava/lang/String;)V + public final fun addImageUrlHook (Ljava/lang/String;Z)V + public static synthetic fun addImageUrlHook$default (Lapp/revanced/patches/youtube/misc/imageurlhook/CronetImageUrlHook;Ljava/lang/String;ZILjava/lang/Object;)V + public final fun addImageUrlSuccessCallbackHook (Ljava/lang/String;)V + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + public final class app/revanced/patches/youtube/misc/integrations/IntegrationsPatch : app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch { public static final field INSTANCE Lapp/revanced/patches/youtube/misc/integrations/IntegrationsPatch; } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt index 86b7a4925b..095d567c72 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt @@ -1,36 +1,18 @@ package app.revanced.patches.youtube.layout.thumbnails import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstructions -import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable import app.revanced.patches.all.misc.resources.AddResourcesPatch import app.revanced.patches.shared.misc.settings.preference.ListPreference import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.shared.misc.settings.preference.TextPreference -import app.revanced.patches.youtube.layout.thumbnails.fingerprints.MessageDigestImageUrlFingerprint -import app.revanced.patches.youtube.layout.thumbnails.fingerprints.MessageDigestImageUrlParentFingerprint -import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.RequestFingerprint -import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.request.callback.OnFailureFingerprint -import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.request.callback.OnResponseStartedFingerprint -import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.request.callback.OnSucceededFingerprint +import app.revanced.patches.youtube.misc.imageurlhook.CronetImageUrlHook import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.reference.FieldReference -import com.android.tools.smali.dexlib2.immutable.ImmutableMethod @Patch( name = "Alternative thumbnails", @@ -39,7 +21,8 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod IntegrationsPatch::class, SettingsPatch::class, AddResourcesPatch::class, - NavigationBarHookPatch::class + NavigationBarHookPatch::class, + CronetImageUrlHook::class ], compatiblePackages = [ CompatiblePackage( @@ -74,65 +57,10 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod ], ) @Suppress("unused") -object AlternativeThumbnailsPatch : BytecodePatch( - setOf( - MessageDigestImageUrlParentFingerprint, - OnResponseStartedFingerprint, - RequestFingerprint, - ), -) { +object AlternativeThumbnailsPatch : BytecodePatch(emptySet()) { private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/AlternativeThumbnailsPatch;" - 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. - */ - @Suppress("SameParameterValue") - private fun addImageUrlSuccessCallbackHook(targetMethodClass: String) { - loadImageSuccessCallbackMethod.addInstruction( - loadImageSuccessCallbackIndex++, - "invoke-static { p1, p2 }, $targetMethodClass->handleCronetSuccess(" + - "Lorg/chromium/net/UrlRequest;Lorg/chromium/net/UrlResponseInfo;)V", - ) - } - - /** - * If a connection outright failed to complete any connection. - */ - @Suppress("SameParameterValue") - private fun addImageUrlErrorCallbackHook(targetMethodClass: String) { - loadImageErrorCallbackMethod.addInstruction( - loadImageErrorCallbackIndex++, - "invoke-static { p1, p2, p3 }, $targetMethodClass->handleCronetFailure(" + - "Lorg/chromium/net/UrlRequest;Lorg/chromium/net/UrlResponseInfo;Ljava/io/IOException;)V", - ) - } - override fun execute(context: BytecodeContext) { AddResourcesPatch(this::class) @@ -177,62 +105,8 @@ object AlternativeThumbnailsPatch : BytecodePatch( ListPreference("revanced_alt_thumbnail_stills_time", summaryKey = null) ) - fun MethodFingerprint.alsoResolve(fingerprint: MethodFingerprint) = - also { resolve(context, fingerprint.resultOrThrow().classDef) }.resultOrThrow() - - fun MethodFingerprint.resolveAndLetMutableMethod( - fingerprint: MethodFingerprint, - block: (MutableMethod) -> Unit, - ) = alsoResolve(fingerprint).also { block(it.mutableMethod) } - - MessageDigestImageUrlFingerprint.resolveAndLetMutableMethod(MessageDigestImageUrlParentFingerprint) { - loadImageUrlMethod = it - addImageUrlHook(INTEGRATIONS_CLASS_DESCRIPTOR, true) - } - - OnSucceededFingerprint.resolveAndLetMutableMethod(OnResponseStartedFingerprint) { - loadImageSuccessCallbackMethod = it - addImageUrlSuccessCallbackHook(INTEGRATIONS_CLASS_DESCRIPTOR) - } - - OnFailureFingerprint.resolveAndLetMutableMethod(OnResponseStartedFingerprint) { - loadImageErrorCallbackMethod = it - addImageUrlErrorCallbackHook(INTEGRATIONS_CLASS_DESCRIPTOR) - } - - // The URL is required for the failure callback hook, but the URL field is obfuscated. - // Add a helper get method that returns the URL field. - RequestFingerprint.resultOrThrow().apply { - // The url is the only string field that is set inside the constructor. - val urlFieldInstruction = mutableMethod.getInstructions().first { - if (it.opcode != Opcode.IPUT_OBJECT) return@first false - - val reference = (it as ReferenceInstruction).reference as FieldReference - reference.type == "Ljava/lang/String;" - } as ReferenceInstruction - - val urlFieldName = (urlFieldInstruction.reference as FieldReference).name - val definingClass = RequestFingerprint.IMPLEMENTATION_CLASS_NAME - val addedMethodName = "getHookedUrl" - mutableClass.methods.add( - ImmutableMethod( - definingClass, - addedMethodName, - emptyList(), - "Ljava/lang/String;", - AccessFlags.PUBLIC.value, - null, - null, - MutableMethodImplementation(2), - ).toMutable().apply { - addInstructions( - """ - iget-object v0, p0, $definingClass->$urlFieldName:Ljava/lang/String; - return-object v0 - """, - ) - }, - ) - } + CronetImageUrlHook.addImageUrlHook(INTEGRATIONS_CLASS_DESCRIPTOR) + CronetImageUrlHook.addImageUrlSuccessCallbackHook(INTEGRATIONS_CLASS_DESCRIPTOR) + CronetImageUrlHook.addImageUrlErrorCallbackHook(INTEGRATIONS_CLASS_DESCRIPTOR) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/BypassImageRegionRestrictions.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/BypassImageRegionRestrictions.kt new file mode 100644 index 0000000000..132f5c96a8 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/BypassImageRegionRestrictions.kt @@ -0,0 +1,71 @@ +package app.revanced.patches.youtube.layout.thumbnails + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.all.misc.resources.AddResourcesPatch +import app.revanced.patches.shared.misc.settings.preference.SwitchPreference +import app.revanced.patches.youtube.misc.imageurlhook.CronetImageUrlHook +import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch +import app.revanced.patches.youtube.misc.settings.SettingsPatch + +@Patch( + name = "Bypass image region restrictions", + description = "Adds an option to use a different host for user avatar and channel images," + + "and can fix missing images that are blocked in some countries.", + dependencies = [ + IntegrationsPatch::class, + SettingsPatch::class, + AddResourcesPatch::class, + CronetImageUrlHook::class + ], + compatiblePackages = [ + CompatiblePackage( + "com.google.android.youtube", + [ + "18.32.39", + "18.37.36", + "18.38.44", + "18.43.45", + "18.44.41", + "18.45.43", + "18.48.39", + "18.49.37", + "19.01.34", + "19.02.39", + "19.03.36", + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.38", + "19.10.39", + "19.11.43", + "19.12.41", + "19.13.37", + "19.14.43", + "19.15.36", + "19.16.39", + ] + ) + ] +) +@Suppress("unused") +object BypassImageRegionRestrictions : BytecodePatch(emptySet()) { + private const val INTEGRATIONS_CLASS_DESCRIPTOR = + "Lapp/revanced/integrations/youtube/patches/BypassImageRegionRestrictionsPatch;" + + override fun execute(context: BytecodeContext) { + AddResourcesPatch(this::class) + + SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences( + SwitchPreference("revanced_bypass_image_region_restrictions") + ) + + // A priority hook is not needed, as the image urls of interest are not modified + // by AlternativeThumbnails or any other patch in this repo. + CronetImageUrlHook.addImageUrlHook(INTEGRATIONS_CLASS_DESCRIPTOR) + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/CronetImageUrlHook.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/CronetImageUrlHook.kt new file mode 100644 index 0000000000..d300327f2f --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/CronetImageUrlHook.kt @@ -0,0 +1,134 @@ +package app.revanced.patches.youtube.misc.imageurlhook + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstructions +import app.revanced.patcher.fingerprint.MethodFingerprint +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable +import app.revanced.patches.youtube.misc.imageurlhook.fingerprints.MessageDigestImageUrlFingerprint +import app.revanced.patches.youtube.misc.imageurlhook.fingerprints.MessageDigestImageUrlParentFingerprint +import app.revanced.patches.youtube.misc.imageurlhook.fingerprints.cronet.RequestFingerprint +import app.revanced.patches.youtube.misc.imageurlhook.fingerprints.cronet.request.callback.OnFailureFingerprint +import app.revanced.patches.youtube.misc.imageurlhook.fingerprints.cronet.request.callback.OnResponseStartedFingerprint +import app.revanced.patches.youtube.misc.imageurlhook.fingerprints.cronet.request.callback.OnSucceededFingerprint +import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch +import app.revanced.util.resultOrThrow +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.reference.FieldReference +import com.android.tools.smali.dexlib2.immutable.ImmutableMethod + +@Patch( + description = "Hooks Cronet image urls", + dependencies = [ + IntegrationsPatch::class + ] +) +object CronetImageUrlHook : BytecodePatch( + 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. + */ + fun addImageUrlHook(targetMethodClass: String, highPriority: Boolean = false) { + 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. + */ + fun addImageUrlSuccessCallbackHook(targetMethodClass: String) { + loadImageSuccessCallbackMethod.addInstruction( + loadImageSuccessCallbackIndex++, + "invoke-static { p1, p2 }, $targetMethodClass->handleCronetSuccess(" + + "Lorg/chromium/net/UrlRequest;Lorg/chromium/net/UrlResponseInfo;)V", + ) + } + + /** + * If a connection outright failed to complete any connection. + */ + fun addImageUrlErrorCallbackHook(targetMethodClass: String) { + loadImageErrorCallbackMethod.addInstruction( + loadImageErrorCallbackIndex++, + "invoke-static { p1, p2, p3 }, $targetMethodClass->handleCronetFailure(" + + "Lorg/chromium/net/UrlRequest;Lorg/chromium/net/UrlResponseInfo;Ljava/io/IOException;)V", + ) + } + + override fun execute(context: BytecodeContext) { + fun MethodFingerprint.alsoResolve(fingerprint: MethodFingerprint) = + also { resolve(context, fingerprint.resultOrThrow().classDef) }.resultOrThrow() + + loadImageUrlMethod = MessageDigestImageUrlFingerprint + .alsoResolve(MessageDigestImageUrlParentFingerprint).mutableMethod + + loadImageSuccessCallbackMethod = OnSucceededFingerprint + .alsoResolve(OnResponseStartedFingerprint).mutableMethod + + loadImageErrorCallbackMethod = OnFailureFingerprint + .alsoResolve(OnResponseStartedFingerprint).mutableMethod + + // The URL is required for the failure callback hook, but the URL field is obfuscated. + // Add a helper get method that returns the URL field. + RequestFingerprint.resultOrThrow().apply { + // The url is the only string field that is set inside the constructor. + val urlFieldInstruction = mutableMethod.getInstructions().single { + if (it.opcode != Opcode.IPUT_OBJECT) return@single false + + val reference = (it as ReferenceInstruction).reference as FieldReference + reference.type == "Ljava/lang/String;" + } as ReferenceInstruction + + val urlFieldName = (urlFieldInstruction.reference as FieldReference).name + val definingClass = RequestFingerprint.IMPLEMENTATION_CLASS_NAME + val addedMethodName = "getHookedUrl" + mutableClass.methods.add( + ImmutableMethod( + definingClass, + addedMethodName, + emptyList(), + "Ljava/lang/String;", + AccessFlags.PUBLIC.value, + null, + null, + MutableMethodImplementation(2), + ).toMutable().apply { + addInstructions( + """ + iget-object v0, p0, $definingClass->$urlFieldName:Ljava/lang/String; + return-object v0 + """, + ) + } + ) + } + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/MessageDigestImageUrlFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/MessageDigestImageUrlFingerprint.kt similarity index 84% rename from src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/MessageDigestImageUrlFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/MessageDigestImageUrlFingerprint.kt index 52f9005bbe..3eff257b16 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/MessageDigestImageUrlFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/MessageDigestImageUrlFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.layout.thumbnails.fingerprints +package app.revanced.patches.youtube.misc.imageurlhook.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/MessageDigestImageUrlParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/MessageDigestImageUrlParentFingerprint.kt similarity index 86% rename from src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/MessageDigestImageUrlParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/MessageDigestImageUrlParentFingerprint.kt index 44902cb06b..8b3af75bd2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/MessageDigestImageUrlParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/MessageDigestImageUrlParentFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.layout.thumbnails.fingerprints +package app.revanced.patches.youtube.misc.imageurlhook.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/cronet/RequestFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/cronet/RequestFingerprint.kt similarity index 81% rename from src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/cronet/RequestFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/cronet/RequestFingerprint.kt index b66ab59711..18f5e0dcf2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/cronet/RequestFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/cronet/RequestFingerprint.kt @@ -1,8 +1,8 @@ -package app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet +package app.revanced.patches.youtube.misc.imageurlhook.fingerprints.cronet import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint -import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.RequestFingerprint.IMPLEMENTATION_CLASS_NAME +import app.revanced.patches.youtube.misc.imageurlhook.fingerprints.cronet.RequestFingerprint.IMPLEMENTATION_CLASS_NAME import com.android.tools.smali.dexlib2.AccessFlags internal object RequestFingerprint : MethodFingerprint( diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/cronet/request/callback/OnFailureFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/cronet/request/callback/OnFailureFingerprint.kt similarity index 89% rename from src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/cronet/request/callback/OnFailureFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/cronet/request/callback/OnFailureFingerprint.kt index 5848810e7f..4214fe7d4d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/cronet/request/callback/OnFailureFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/cronet/request/callback/OnFailureFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.request.callback +package app.revanced.patches.youtube.misc.imageurlhook.fingerprints.cronet.request.callback import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/cronet/request/callback/OnResponseStartedFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/cronet/request/callback/OnResponseStartedFingerprint.kt similarity index 91% rename from src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/cronet/request/callback/OnResponseStartedFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/cronet/request/callback/OnResponseStartedFingerprint.kt index 1021d243a5..f50dc16f0c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/cronet/request/callback/OnResponseStartedFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/cronet/request/callback/OnResponseStartedFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.request.callback +package app.revanced.patches.youtube.misc.imageurlhook.fingerprints.cronet.request.callback import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/cronet/request/callback/OnSucceededFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/cronet/request/callback/OnSucceededFingerprint.kt similarity index 88% rename from src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/cronet/request/callback/OnSucceededFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/cronet/request/callback/OnSucceededFingerprint.kt index ed8523c826..295c91ec06 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/fingerprints/cronet/request/callback/OnSucceededFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/fingerprints/cronet/request/callback/OnSucceededFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.request.callback +package app.revanced.patches.youtube.misc.imageurlhook.fingerprints.cronet.request.callback import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml index 480c43f2ce..85588efc1c 100644 --- a/src/main/resources/addresources/values/strings.xml +++ b/src/main/resources/addresources/values/strings.xml @@ -998,6 +998,11 @@ This is because Crowdin requires temporarily flattening this file and removing t The color of the seekbar Invalid seekbar color value. Using default value. + + Bypass image region restrictions + Using image host yt4.ggpht.com + Using original image host\n\nEnabling this can fix missing images that are blocked in some regions + Home tab