diff --git a/api/revanced-patches.api b/api/revanced-patches.api
index 4b518d1d4..35e283213 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 86b7a4925..095d567c7 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 000000000..132f5c96a
--- /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 000000000..d300327f2
--- /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 52f9005bb..3eff257b1 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 44902cb06..8b3af75bd 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 b66ab5971..18f5e0dcf 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 5848810e7..4214fe7d4 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 1021d243a..f50dc16f0 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 ed8523c82..295c91ec0 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 480c43f2c..85588efc1 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