From 0d29ed623a71d04f64d9967a81510142577f3191 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 1 Sep 2024 02:08:06 +0900 Subject: [PATCH] feat(YouTube): remove `Spoof client` patch --- .../visual/VisualPreferencesIconsPatch.kt | 1 - .../utils/fix/client/SpoofClientPatch.kt | 496 ------------------ .../utils/fix/client/SpoofUserAgentPatch.kt | 5 - .../BuildInitPlaybackRequestFingerprint.kt | 16 - ...BuildPlaybackStatsRequestURIFingerprint.kt | 17 - .../BuildPlayerRequestURIFingerprint.kt | 20 - .../CreatePlaybackSpeedMenuItemFingerprint.kt | 34 -- .../CreatePlayerRequestBodyFingerprint.kt | 15 - ...equestBodyWithVersionReleaseFingerprint.kt | 30 -- ...NerdsStatsVideoFormatBuilderFingerprint.kt | 12 - .../OrganicPlaybackContextModelFingerprint.kt | 24 - ...PlayerGestureConfigSyntheticFingerprint.kt | 55 -- ...ModelBackgroundAudioPlaybackFingerprint.kt | 43 -- .../SetPlayerRequestClientTypeFingerprint.kt | 12 - .../UserAgentHeaderBuilderFingerprint.kt | 19 - .../parameter/SpoofPlayerParameterPatch.kt | 53 -- .../youtube/utils/gms/GmsCoreSupportPatch.kt | 4 - .../utils/storyboard/StoryboardHookPatch.kt | 154 ------ ...delGeneralStoryboardRendererFingerprint.kt | 24 - ...LiveStreamStoryboardRendererFingerprint.kt | 24 - ...elStoryboardRecommendedLevelFingerprint.kt | 24 - ...dererDecoderRecommendedLevelFingerprint.kt | 23 - ...toryboardRendererDecoderSpecFingerprint.kt | 23 - .../StoryboardRendererSpecFingerprint.kt | 12 - .../StoryboardThumbnailFingerprint.kt | 23 - .../StoryboardThumbnailParentFingerprint.kt | 17 - .../youtube/settings/host/values/arrays.xml | 40 -- .../youtube/settings/host/values/strings.xml | 104 +--- .../youtube/settings/xml/revanced_prefs.xml | 31 -- ...ed_preference_screen_spoof_client_icon.xml | 18 - 30 files changed, 2 insertions(+), 1371 deletions(-) delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/SpoofClientPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/SpoofUserAgentPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/BuildInitPlaybackRequestFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/BuildPlaybackStatsRequestURIFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/BuildPlayerRequestURIFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/CreatePlaybackSpeedMenuItemFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/CreatePlayerRequestBodyFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/CreatePlayerRequestBodyWithVersionReleaseFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/NerdsStatsVideoFormatBuilderFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/OrganicPlaybackContextModelFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/PlayerGestureConfigSyntheticFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/PlayerResponseModelBackgroundAudioPlaybackFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/SetPlayerRequestClientTypeFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/UserAgentHeaderBuilderFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fix/parameter/SpoofPlayerParameterPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/StoryboardHookPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/PlayerResponseModelGeneralStoryboardRendererFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/PlayerResponseModelLiveStreamStoryboardRendererFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/PlayerResponseModelStoryboardRecommendedLevelFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardRendererDecoderRecommendedLevelFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardRendererDecoderSpecFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardRendererSpecFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardThumbnailFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardThumbnailParentFingerprint.kt delete mode 100644 src/main/resources/youtube/visual/shared/drawable/revanced_preference_screen_spoof_client_icon.xml diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/visual/VisualPreferencesIconsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/visual/VisualPreferencesIconsPatch.kt index f8c918721b..a026e50a89 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/visual/VisualPreferencesIconsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/visual/VisualPreferencesIconsPatch.kt @@ -276,7 +276,6 @@ object VisualPreferencesIconsPatch : BaseResourcePatch( "revanced_preference_screen_seekbar", "revanced_preference_screen_settings_menu", "revanced_preference_screen_shorts_player", - "revanced_preference_screen_spoof_client", "revanced_preference_screen_toolbar", "revanced_preference_screen_video_description", "revanced_preference_screen_video_filter", diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/SpoofClientPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/SpoofClientPatch.kt deleted file mode 100644 index 53f1723569..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/SpoofClientPatch.kt +++ /dev/null @@ -1,496 +0,0 @@ -package app.revanced.patches.youtube.utils.fix.client - -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.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstructions -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.PatchException -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.shared.fingerprints.CreatePlayerRequestBodyWithModelFingerprint -import app.revanced.patches.shared.fingerprints.CreatePlayerRequestBodyWithModelFingerprint.indexOfModelInstruction -import app.revanced.patches.youtube.misc.backgroundplayback.BackgroundPlaybackPatch -import app.revanced.patches.youtube.utils.compatibility.Constants -import app.revanced.patches.youtube.utils.fingerprints.PlaybackRateBottomSheetBuilderFingerprint -import app.revanced.patches.youtube.utils.fix.client.fingerprints.BuildInitPlaybackRequestFingerprint -import app.revanced.patches.youtube.utils.fix.client.fingerprints.BuildPlaybackStatsRequestURIFingerprint -import app.revanced.patches.youtube.utils.fix.client.fingerprints.BuildPlayerRequestURIFingerprint -import app.revanced.patches.youtube.utils.fix.client.fingerprints.CreatePlaybackSpeedMenuItemFingerprint -import app.revanced.patches.youtube.utils.fix.client.fingerprints.CreatePlayerRequestBodyFingerprint -import app.revanced.patches.youtube.utils.fix.client.fingerprints.CreatePlayerRequestBodyWithVersionReleaseFingerprint -import app.revanced.patches.youtube.utils.fix.client.fingerprints.CreatePlayerRequestBodyWithVersionReleaseFingerprint.indexOfBuildInstruction -import app.revanced.patches.youtube.utils.fix.client.fingerprints.NerdsStatsVideoFormatBuilderFingerprint -import app.revanced.patches.youtube.utils.fix.client.fingerprints.OrganicPlaybackContextModelFingerprint -import app.revanced.patches.youtube.utils.fix.client.fingerprints.PlayerGestureConfigSyntheticFingerprint -import app.revanced.patches.youtube.utils.fix.client.fingerprints.PlayerResponseModelBackgroundAudioPlaybackFingerprint -import app.revanced.patches.youtube.utils.fix.client.fingerprints.SetPlayerRequestClientTypeFingerprint -import app.revanced.patches.youtube.utils.fix.client.fingerprints.UserAgentHeaderBuilderFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH -import app.revanced.patches.youtube.utils.integrations.Constants.PATCH_STATUS_CLASS_DESCRIPTOR -import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.patches.youtube.utils.storyboard.StoryboardHookPatch -import app.revanced.patches.youtube.utils.trackingurlhook.TrackingUrlHookPatch -import app.revanced.patches.youtube.video.information.VideoInformationPatch -import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch -import app.revanced.util.getReference -import app.revanced.util.getStringInstructionIndex -import app.revanced.util.getWalkerMethod -import app.revanced.util.indexOfFirstInstructionOrThrow -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import app.revanced.util.updatePatchStatus -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.FiveRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.FieldReference -import com.android.tools.smali.dexlib2.iface.reference.TypeReference -import com.android.tools.smali.dexlib2.immutable.ImmutableMethod -import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter - -object SpoofClientPatch : BaseBytecodePatch( - name = "Spoof client", - description = "Adds options to spoof the client to allow video playback.", - dependencies = setOf( - // Required since iOS livestream fix partially enables background playback. - BackgroundPlaybackPatch::class, - PlayerTypeHookPatch::class, - - TrackingUrlHookPatch::class, - PlayerResponseMethodHookPatch::class, - SettingsPatch::class, - VideoInformationPatch::class, - SpoofUserAgentPatch::class, - StoryboardHookPatch::class, - ), - compatiblePackages = Constants.COMPATIBLE_PACKAGE, - fingerprints = setOf( - // Client type spoof. - BuildInitPlaybackRequestFingerprint, - BuildPlayerRequestURIFingerprint, - SetPlayerRequestClientTypeFingerprint, - CreatePlayerRequestBodyFingerprint, - CreatePlayerRequestBodyWithModelFingerprint, - CreatePlayerRequestBodyWithVersionReleaseFingerprint, - UserAgentHeaderBuilderFingerprint, - - // Player gesture config. - PlayerGestureConfigSyntheticFingerprint, - - // Player speed menu item. - CreatePlaybackSpeedMenuItemFingerprint, - PlaybackRateBottomSheetBuilderFingerprint, - - // Livestream audio only background playback. - PlayerResponseModelBackgroundAudioPlaybackFingerprint, - - // Watch history. - BuildPlaybackStatsRequestURIFingerprint, - OrganicPlaybackContextModelFingerprint, - - // Nerds stats video format. - NerdsStatsVideoFormatBuilderFingerprint, - ) -) { - private const val INTEGRATIONS_CLASS_DESCRIPTOR = - "$MISC_PATH/SpoofClientPatch;" - private const val CLIENT_INFO_CLASS_DESCRIPTOR = - "Lcom/google/protos/youtube/api/innertube/InnertubeContext\$ClientInfo;" - - override fun execute(context: BytecodeContext) { - - var settingArray = arrayOf( - "SETTINGS: SPOOF_CLIENT" - ) - - // region Block /initplayback requests to fall back to /get_watch requests. - - BuildInitPlaybackRequestFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val moveUriStringIndex = it.scanResult.patternScanResult!!.startIndex - val targetRegister = - getInstruction(moveUriStringIndex).registerA - - addInstructions( - moveUriStringIndex + 1, - """ - invoke-static { v$targetRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->blockInitPlaybackRequest(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$targetRegister - """, - ) - } - } - - // endregion - - // region Block /get_watch requests to fall back to /player requests. - - BuildPlayerRequestURIFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val invokeToStringIndex = it.scanResult.patternScanResult!!.startIndex - val uriRegister = - getInstruction(invokeToStringIndex).registerC - - addInstructions( - invokeToStringIndex, - """ - invoke-static { v$uriRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->blockGetWatchRequest(Landroid/net/Uri;)Landroid/net/Uri; - move-result-object v$uriRegister - """, - ) - } - } - - // endregion - - // region Get field references to be used below. - - val (clientInfoField, clientInfoClientTypeField, clientInfoClientVersionField) = - SetPlayerRequestClientTypeFingerprint.resultOrThrow().let { result -> - with(result.mutableMethod) { - // Field in the player request object that holds the client info object. - val clientInfoField = getInstructions().find { instruction -> - // requestMessage.clientInfo = clientInfoBuilder.build(); - instruction.opcode == Opcode.IPUT_OBJECT && - instruction.getReference()?.type == CLIENT_INFO_CLASS_DESCRIPTOR - }?.getReference() - ?: throw PatchException("Could not find clientInfoField") - - // Client info object's client type field. - val clientInfoClientTypeField = - getInstruction(result.scanResult.patternScanResult!!.endIndex) - .getReference() - ?: throw PatchException("Could not find clientInfoClientTypeField") - - val clientInfoVersionIndex = getStringInstructionIndex("10.29") - val clientInfoVersionRegister = - getInstruction(clientInfoVersionIndex).registerA - val clientInfoClientVersionFieldIndex = implementation!!.instructions.let { - clientInfoVersionIndex + it.subList(clientInfoVersionIndex, it.size - 1) - .indexOfFirst { instruction -> - instruction.opcode == Opcode.IPUT_OBJECT - && (instruction as TwoRegisterInstruction).registerA == clientInfoVersionRegister - } - } - - // Client info object's client version field. - val clientInfoClientVersionField = - getInstruction(clientInfoClientVersionFieldIndex) - .getReference() - ?: throw PatchException("Could not find clientInfoClientVersionField") - - Triple(clientInfoField, clientInfoClientTypeField, clientInfoClientVersionField) - } - } - - val clientInfoClientModelField = - CreatePlayerRequestBodyWithModelFingerprint.resultOrThrow().mutableMethod.let { - val instructions = it.getInstructions() - val getClientModelIndex = indexOfModelInstruction(it) - - // The next IPUT_OBJECT instruction after getting the client model is setting the client model field. - instructions.subList( - getClientModelIndex, - instructions.size, - ).find { instruction -> - val reference = instruction.getReference() - instruction.opcode == Opcode.IPUT_OBJECT - && reference?.definingClass == CLIENT_INFO_CLASS_DESCRIPTOR - && reference.type == "Ljava/lang/String;" - }?.getReference() - ?: throw PatchException("Could not find clientInfoClientModelField") - } - - val clientInfoOsVersionField = - CreatePlayerRequestBodyWithVersionReleaseFingerprint.resultOrThrow().mutableMethod.let { - val buildIndex = indexOfBuildInstruction(it) - val instructions = it.getInstructions() - - instructions.subList( - buildIndex - 5, - buildIndex, - ).find { instruction -> - val reference = instruction.getReference() - instruction.opcode == Opcode.IPUT_OBJECT - && reference?.definingClass == CLIENT_INFO_CLASS_DESCRIPTOR - && reference.type == "Ljava/lang/String;" - }?.getReference() - ?: throw PatchException("Could not find clientInfoOsVersionField") - } - - // endregion - - // region Spoof client type for /player requests. - - CreatePlayerRequestBodyFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val setClientInfoMethodName = "setClientInfo" - val checkCastIndex = it.scanResult.patternScanResult!!.startIndex - - val checkCastInstruction = getInstruction(checkCastIndex) - val requestMessageInstanceRegister = checkCastInstruction.registerA - val clientInfoContainerClassName = - checkCastInstruction.getReference()!!.type - - addInstruction( - checkCastIndex + 1, - "invoke-static { v$requestMessageInstanceRegister }," + - " $definingClass->$setClientInfoMethodName($clientInfoContainerClassName)V", - ) - - // Change client info to use the spoofed values. - // Do this in a helper method, to remove the need of picking out multiple free registers from the hooked code. - it.mutableClass.methods.add( - ImmutableMethod( - definingClass, - setClientInfoMethodName, - listOf( - ImmutableMethodParameter( - clientInfoContainerClassName, - annotations, - "clientInfoContainer" - ) - ), - "V", - AccessFlags.PRIVATE or AccessFlags.STATIC, - annotations, - null, - MutableMethodImplementation(3), - ).toMutable().apply { - addInstructions( - """ - invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->isClientSpoofingEnabled()Z - move-result v0 - if-eqz v0, :disabled - - iget-object v0, p0, $clientInfoField - - # Set client type to the spoofed value. - iget v1, v0, $clientInfoClientTypeField - invoke-static { v1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getClientTypeId(I)I - move-result v1 - iput v1, v0, $clientInfoClientTypeField - - # Set client model to the spoofed value. - iget-object v1, v0, $clientInfoClientModelField - invoke-static { v1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getClientModel(Ljava/lang/String;)Ljava/lang/String; - move-result-object v1 - iput-object v1, v0, $clientInfoClientModelField - - # Set client version to the spoofed value. - iget-object v1, v0, $clientInfoClientVersionField - invoke-static { v1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getClientVersion(Ljava/lang/String;)Ljava/lang/String; - move-result-object v1 - iput-object v1, v0, $clientInfoClientVersionField - - # Set client os version to the spoofed value. - iget-object v1, v0, $clientInfoOsVersionField - invoke-static { v1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getOsVersion(Ljava/lang/String;)Ljava/lang/String; - move-result-object v1 - iput-object v1, v0, $clientInfoOsVersionField - - :disabled - return-void - """, - ) - }, - ) - } - } - - // endregion - - // region Spoof user-agent - - UserAgentHeaderBuilderFingerprint.resultOrThrow().mutableMethod.apply { - val insertIndex = implementation!!.instructions.lastIndex - val insertRegister = getInstruction(insertIndex).registerA - - addInstructions( - insertIndex, """ - invoke-static { v$insertRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getUserAgent(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$insertRegister - """ - ) - } - - // endregion - - // region check whether video is Shorts or Clips. - - PlayerResponseMethodHookPatch += PlayerResponseMethodHookPatch.Hook.PlayerParameter( - "$INTEGRATIONS_CLASS_DESCRIPTOR->setPlayerResponseVideoId(" + - "Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;", - ) - - // endregion - - // region fix player gesture. - - PlayerGestureConfigSyntheticFingerprint.resultOrThrow().let { - val endIndex = it.scanResult.patternScanResult!!.endIndex - val downAndOutLandscapeAllowedIndex = endIndex - 3 - val downAndOutPortraitAllowedIndex = endIndex - 9 - - arrayOf( - downAndOutLandscapeAllowedIndex, - downAndOutPortraitAllowedIndex, - ).forEach { index -> - val gestureAllowedMethod = it.getWalkerMethod(context, index) - - gestureAllowedMethod.apply { - val isAllowedIndex = getInstructions().lastIndex - val isAllowed = getInstruction(isAllowedIndex).registerA - - addInstructions( - isAllowedIndex, - """ - invoke-static { v$isAllowed }, $INTEGRATIONS_CLASS_DESCRIPTOR->enablePlayerGesture(Z)Z - move-result v$isAllowed - """, - ) - } - } - } - - // endregion - - // region fix playback speed menu item. - - // fix for iOS, Android Testsuite - CreatePlaybackSpeedMenuItemFingerprint.resultOrThrow().let { - val scanResult = it.scanResult.patternScanResult!! - if (scanResult.startIndex != 0) throw PatchException("Unexpected start index: ${scanResult.startIndex}") - - it.mutableMethod.apply { - // Find the conditional check if the playback speed menu item is not created. - val shouldCreateMenuIndex = - indexOfFirstInstructionOrThrow(scanResult.endIndex) { opcode == Opcode.IF_EQZ } - val shouldCreateMenuRegister = - getInstruction(shouldCreateMenuIndex).registerA - - addInstructions( - shouldCreateMenuIndex, - """ - invoke-static { v$shouldCreateMenuRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->forceCreatePlaybackSpeedMenu(Z)Z - move-result v$shouldCreateMenuRegister - """, - ) - } - } - - // fix for Android TV - PlaybackRateBottomSheetBuilderFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.endIndex - val targetRegister = getInstruction(targetIndex).registerA - - addInstructions( - targetIndex, - """ - invoke-static { v$targetRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->forceCreatePlaybackSpeedMenuReversed(Z)Z - move-result v$targetRegister - """, - ) - } - } - - // endregion - - // region fix background playback in live stream, if spoofing to iOS - // This force enables audio background playback. - PlayerResponseModelBackgroundAudioPlaybackFingerprint.resultOrThrow().mutableMethod.apply { - addInstructionsWithLabels( - 0, """ - invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->overrideBackgroundAudioPlayback()Z - move-result v0 - if-eqz v0, :disabled - return v0 - """, ExternalLabel("disabled", getInstruction(0)) - ) - } - - // endregion - - // region watch history if spoofing to iOS - - if (!SettingsPatch.upward1839) { - BuildPlaybackStatsRequestURIFingerprint.resultOrThrow().let { - val walkerMethod = - it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex) - - walkerMethod.addInstructions( - 0, """ - invoke-static {p0}, $INTEGRATIONS_CLASS_DESCRIPTOR->overrideTrackingUrl(Landroid/net/Uri;)Landroid/net/Uri; - move-result-object p0 - """ - ) - } - - OrganicPlaybackContextModelFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = it.scanResult.patternScanResult!!.endIndex - val insertRegister = - getInstruction(insertIndex).registerA - - addInstruction( - insertIndex, - "invoke-static { v$insertRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->setCpn(Ljava/lang/String;)V" - ) - } - } - - TrackingUrlHookPatch.hookTrackingUrl("$INTEGRATIONS_CLASS_DESCRIPTOR->setTrackingUriParameter(Landroid/net/Uri;)V") - } - - // endregion - - // region append spoof info. - - NerdsStatsVideoFormatBuilderFingerprint.resultOrThrow().mutableMethod.apply { - for (index in implementation!!.instructions.size - 1 downTo 0) { - val instruction = getInstruction(index) - if (instruction.opcode != Opcode.RETURN_OBJECT) - continue - - val register = (instruction as OneRegisterInstruction).registerA - - addInstructions( - index, """ - invoke-static {v$register}, $INTEGRATIONS_CLASS_DESCRIPTOR->appendSpoofedClient(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$register - """ - ) - } - } - - // endregion - - // region hook storyboard. - - StoryboardHookPatch.hook(INTEGRATIONS_CLASS_DESCRIPTOR) - - // endregion - - if (!SettingsPatch.upward1839) { - settingArray += "SETTINGS: IOS_CLIENT_SIDE_EFFECT_1838" - } else { - settingArray += "SETTINGS: IOS_CLIENT_SIDE_EFFECT_1839" - - context.updatePatchStatus(PATCH_STATUS_CLASS_DESCRIPTOR, "SpoofClient") - } - - /** - * Add settings - */ - SettingsPatch.addPreference(settingArray) - - SettingsPatch.updatePatchStatus(this) - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/SpoofUserAgentPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/SpoofUserAgentPatch.kt deleted file mode 100644 index 06a2a0ca8f..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/SpoofUserAgentPatch.kt +++ /dev/null @@ -1,5 +0,0 @@ -package app.revanced.patches.youtube.utils.fix.client - -import app.revanced.patches.shared.spoofuseragent.BaseSpoofUserAgentPatch - -object SpoofUserAgentPatch : BaseSpoofUserAgentPatch("com.google.android.youtube") \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/BuildInitPlaybackRequestFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/BuildInitPlaybackRequestFingerprint.kt deleted file mode 100644 index 9437ab1a07..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/BuildInitPlaybackRequestFingerprint.kt +++ /dev/null @@ -1,16 +0,0 @@ -package app.revanced.patches.youtube.utils.fix.client.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode - -internal object BuildInitPlaybackRequestFingerprint : MethodFingerprint( - returnType = "Lorg/chromium/net/UrlRequest\$Builder;", - opcodes = listOf( - Opcode.MOVE_RESULT_OBJECT, - Opcode.IGET_OBJECT, // Moves the request URI string to a register to build the request with. - ), - strings = listOf( - "Content-Type", - "Range", - ), -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/BuildPlaybackStatsRequestURIFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/BuildPlaybackStatsRequestURIFingerprint.kt deleted file mode 100644 index 7a212b6b79..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/BuildPlaybackStatsRequestURIFingerprint.kt +++ /dev/null @@ -1,17 +0,0 @@ -package app.revanced.patches.youtube.utils.fix.client.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -internal object BuildPlaybackStatsRequestURIFingerprint : MethodFingerprint( - accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, - returnType = "L", - opcodes = listOf( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST_STRING, - ), - strings = listOf("event", "streamingstats"), -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/BuildPlayerRequestURIFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/BuildPlayerRequestURIFingerprint.kt deleted file mode 100644 index 563fbdaeaa..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/BuildPlayerRequestURIFingerprint.kt +++ /dev/null @@ -1,20 +0,0 @@ -package app.revanced.patches.youtube.utils.fix.client.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode - -internal object BuildPlayerRequestURIFingerprint : MethodFingerprint( - returnType = "Ljava/lang/String;", - opcodes = listOf( - Opcode.INVOKE_VIRTUAL, // Register holds player request URI. - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.MONITOR_EXIT, - Opcode.RETURN_OBJECT, - ), - strings = listOf( - "key", - "asig", - ), -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/CreatePlaybackSpeedMenuItemFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/CreatePlaybackSpeedMenuItemFingerprint.kt deleted file mode 100644 index 0e79e54403..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/CreatePlaybackSpeedMenuItemFingerprint.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.youtube.utils.fix.client.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -internal object CreatePlaybackSpeedMenuItemFingerprint : MethodFingerprint( - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - returnType = "V", - opcodes = listOf( - Opcode.IGET_OBJECT, // First instruction of the method - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST_4, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - null // MOVE_RESULT or MOVE_RESULT_OBJECT, Return value controls the creation of the playback speed menu item. - ), - // 19.01 and earlier is missing the second parameter. - // Since this fingerprint is somewhat weak, work around by checking for both method parameter signatures. - customFingerprint = custom@{ methodDef, _ -> - // 19.01 and earlier parameters are: "[L" - // 19.02+ parameters are "[L", "F" - val parameterTypes = methodDef.parameterTypes - val firstParameter = parameterTypes.firstOrNull() - - if (firstParameter == null || !firstParameter.startsWith("[L")) { - return@custom false - } - - parameterTypes.size == 1 || (parameterTypes.size == 2 && parameterTypes[1] == "F") - }, -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/CreatePlayerRequestBodyFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/CreatePlayerRequestBodyFingerprint.kt deleted file mode 100644 index a631f4140d..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/CreatePlayerRequestBodyFingerprint.kt +++ /dev/null @@ -1,15 +0,0 @@ -package app.revanced.patches.youtube.utils.fix.client.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode - -internal object CreatePlayerRequestBodyFingerprint : MethodFingerprint( - returnType = "V", - parameters = listOf("L"), - opcodes = listOf( - Opcode.CHECK_CAST, - Opcode.IGET, - Opcode.AND_INT_LIT16, - ), - strings = listOf("ms"), -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/CreatePlayerRequestBodyWithVersionReleaseFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/CreatePlayerRequestBodyWithVersionReleaseFingerprint.kt deleted file mode 100644 index a4157fdc41..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/CreatePlayerRequestBodyWithVersionReleaseFingerprint.kt +++ /dev/null @@ -1,30 +0,0 @@ -package app.revanced.patches.youtube.utils.fix.client.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import app.revanced.patches.youtube.utils.fix.client.fingerprints.CreatePlayerRequestBodyWithVersionReleaseFingerprint.indexOfBuildInstruction -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstruction -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.Method -import com.android.tools.smali.dexlib2.iface.reference.MethodReference - -internal object CreatePlayerRequestBodyWithVersionReleaseFingerprint : MethodFingerprint( - returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = listOf("L"), - strings = listOf("Google Inc."), - customFingerprint = { methodDef, _ -> - indexOfBuildInstruction(methodDef) >= 0 - }, -) { - fun indexOfBuildInstruction(methodDef: Method) = - methodDef.indexOfFirstInstruction { - val reference = getReference() - opcode == Opcode.INVOKE_VIRTUAL && - reference?.name == "build" && - reference.parameterTypes.isEmpty() && - reference.returnType.startsWith("L") - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/NerdsStatsVideoFormatBuilderFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/NerdsStatsVideoFormatBuilderFingerprint.kt deleted file mode 100644 index 7521265d35..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/NerdsStatsVideoFormatBuilderFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.youtube.utils.fix.client.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags - -internal object NerdsStatsVideoFormatBuilderFingerprint : MethodFingerprint( - returnType = "Ljava/lang/String;", - accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, - parameters = listOf("Lcom/google/android/libraries/youtube/innertube/model/media/FormatStreamModel;"), - strings = listOf("codecs=\""), -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/OrganicPlaybackContextModelFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/OrganicPlaybackContextModelFingerprint.kt deleted file mode 100644 index fe1c98f179..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/OrganicPlaybackContextModelFingerprint.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.youtube.utils.fix.client.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -internal object OrganicPlaybackContextModelFingerprint : MethodFingerprint( - returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - parameters = listOf( - "Ljava/lang/String;", // cpn - "Z", - "Z", - "Z", - "Z" - ), - opcodes = listOf( - Opcode.INVOKE_DIRECT, - Opcode.IF_EQZ, - Opcode.IPUT_OBJECT, - ), - strings = listOf("Null contentCpn") -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/PlayerGestureConfigSyntheticFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/PlayerGestureConfigSyntheticFingerprint.kt deleted file mode 100644 index 0ae82b307f..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/PlayerGestureConfigSyntheticFingerprint.kt +++ /dev/null @@ -1,55 +0,0 @@ -package app.revanced.patches.youtube.utils.fix.client.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstruction -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.Method -import com.android.tools.smali.dexlib2.iface.reference.MethodReference - -/** - * [FuzzyPatternScanMethod] was added to maintain compatibility for YouTube v18.29.38 to v18.32.39. - * TODO: Remove this annotation if support for YouTube v18.29.38 to v18.32.39 is dropped. - */ -@FuzzyPatternScanMethod(5) -internal object PlayerGestureConfigSyntheticFingerprint : MethodFingerprint( - returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = listOf("Ljava/lang/Object;"), - opcodes = listOf( - Opcode.SGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, // playerGestureConfig.downAndOutLandscapeAllowed. - Opcode.MOVE_RESULT, - Opcode.CHECK_CAST, - Opcode.IPUT_BOOLEAN, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, // playerGestureConfig.downAndOutPortraitAllowed. - Opcode.MOVE_RESULT, - Opcode.IPUT_BOOLEAN, - Opcode.RETURN_VOID, - ), - customFingerprint = { methodDef, classDef -> - fun indexOfDownAndOutAllowedInstruction(methodDef: Method) = - methodDef.indexOfFirstInstruction { - val reference = getReference() - reference?.definingClass == "Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;" && - reference.parameterTypes.isEmpty() && - reference.returnType == "Z" - } - - // This method is always called "a" because this kind of class always has a single method. - methodDef.name == "a" && classDef.methods.count() == 2 && - indexOfDownAndOutAllowedInstruction(methodDef) >= 0 - }, -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/PlayerResponseModelBackgroundAudioPlaybackFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/PlayerResponseModelBackgroundAudioPlaybackFingerprint.kt deleted file mode 100644 index 30ec622e1f..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/PlayerResponseModelBackgroundAudioPlaybackFingerprint.kt +++ /dev/null @@ -1,43 +0,0 @@ -package app.revanced.patches.youtube.utils.fix.client.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -/** - * On iOS clients, this method always returns false in live streams. - * - * This fingerprint seems to break easily because there are many [Opcode] patterns, but it is not. - * This fingerprint has been tested on all versions from YouTube 17.34.36 to YouTube 19.29.42. - */ -internal object PlayerResponseModelBackgroundAudioPlaybackFingerprint : MethodFingerprint( - returnType = "Z", - accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, - parameters = listOf("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;"), - opcodes = listOf( - Opcode.CONST_4, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.CONST_4, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_NEZ, - Opcode.GOTO, - Opcode.RETURN, - null, // Opcode.CONST_4 or Opcode.MOVE - Opcode.RETURN, - ), -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/SetPlayerRequestClientTypeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/SetPlayerRequestClientTypeFingerprint.kt deleted file mode 100644 index 4620492391..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/SetPlayerRequestClientTypeFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.youtube.utils.fix.client.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode - -internal object SetPlayerRequestClientTypeFingerprint : MethodFingerprint( - strings = listOf("10.29"), - opcodes = listOf( - Opcode.IGET, - Opcode.IPUT, // Sets ClientInfo.clientId. - ), -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/UserAgentHeaderBuilderFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/UserAgentHeaderBuilderFingerprint.kt deleted file mode 100644 index c724a6718e..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/client/fingerprints/UserAgentHeaderBuilderFingerprint.kt +++ /dev/null @@ -1,19 +0,0 @@ -package app.revanced.patches.youtube.utils.fix.client.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -/** - * This is the fingerprint used in the 'client-spoof' patch around 2022. - * (Integrated into 'UserAgentClientSpoofPatch' now.) - * - * This method is modified by 'UserAgentClientSpoofPatch', so the fingerprint does not check the [Opcode]. - */ -internal object UserAgentHeaderBuilderFingerprint : MethodFingerprint( - accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, - returnType = "Ljava/lang/String;", - parameters = listOf("Landroid/content/Context;", "Ljava/lang/String;", "Ljava/lang/String;"), - strings = listOf("(Linux; U; Android "), -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/parameter/SpoofPlayerParameterPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/parameter/SpoofPlayerParameterPatch.kt deleted file mode 100644 index b6c57c7047..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/parameter/SpoofPlayerParameterPatch.kt +++ /dev/null @@ -1,53 +0,0 @@ -package app.revanced.patches.youtube.utils.fix.parameter - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH -import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.patches.youtube.utils.storyboard.StoryboardHookPatch -import app.revanced.patches.youtube.video.information.VideoInformationPatch -import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch -import app.revanced.util.patch.BaseBytecodePatch - -@Suppress("unused") -@Deprecated("This patch will be removed in the future.") -object SpoofPlayerParameterPatch : BaseBytecodePatch( - // name = "Spoof player parameters", - description = "Adds options to spoof player parameters to prevent playback issues.", - dependencies = setOf( - PlayerTypeHookPatch::class, - PlayerResponseMethodHookPatch::class, - SettingsPatch::class, - VideoInformationPatch::class, - StoryboardHookPatch::class, - ), - compatiblePackages = COMPATIBLE_PACKAGE, - use = false -) { - private const val INTEGRATIONS_CLASS_DESCRIPTOR = - "$MISC_PATH/SpoofPlayerParameterPatch;" - - override fun execute(context: BytecodeContext) { - - // Hook the player parameters. - PlayerResponseMethodHookPatch += PlayerResponseMethodHookPatch.Hook.PlayerParameter( - "$INTEGRATIONS_CLASS_DESCRIPTOR->spoofParameter(Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;" - ) - - // Hook storyboard. - StoryboardHookPatch.hook(INTEGRATIONS_CLASS_DESCRIPTOR) - - /** - * Add settings - */ - SettingsPatch.addPreference( - arrayOf( - "PREFERENCE_CATEGORY: MISC_EXPERIMENTAL_FLAGS", - "SETTINGS: SPOOF_PLAYER_PARAMETER" - ) - ) - - SettingsPatch.updatePatchStatus(this) - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/gms/GmsCoreSupportPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/gms/GmsCoreSupportPatch.kt index 169e5d4308..a9345b9f31 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/gms/GmsCoreSupportPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/gms/GmsCoreSupportPatch.kt @@ -3,8 +3,6 @@ package app.revanced.patches.youtube.utils.gms import app.revanced.patches.shared.gms.BaseGmsCoreSupportPatch import app.revanced.patches.shared.gms.BaseGmsCoreSupportResourcePatch.Companion.ORIGINAL_PACKAGE_NAME_YOUTUBE import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.youtube.utils.fix.client.SpoofClientPatch -import app.revanced.patches.youtube.utils.fix.client.SpoofUserAgentPatch import app.revanced.patches.youtube.utils.integrations.IntegrationsPatch import app.revanced.patches.youtube.utils.mainactivity.fingerprints.MainActivityFingerprint import app.revanced.patches.youtube.utils.settings.SettingsPatch @@ -15,8 +13,6 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( mainActivityOnCreateFingerprint = MainActivityFingerprint, integrationsPatchDependency = IntegrationsPatch::class, dependencies = setOf( - SpoofClientPatch::class, - SpoofUserAgentPatch::class, SettingsPatch::class ), gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch, diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/StoryboardHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/StoryboardHookPatch.kt deleted file mode 100644 index d0b9d10f44..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/StoryboardHookPatch.kt +++ /dev/null @@ -1,154 +0,0 @@ -package app.revanced.patches.youtube.utils.storyboard - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.storyboard.fingerprints.PlayerResponseModelGeneralStoryboardRendererFingerprint -import app.revanced.patches.youtube.utils.storyboard.fingerprints.PlayerResponseModelLiveStreamStoryboardRendererFingerprint -import app.revanced.patches.youtube.utils.storyboard.fingerprints.PlayerResponseModelStoryboardRecommendedLevelFingerprint -import app.revanced.patches.youtube.utils.storyboard.fingerprints.StoryboardRendererDecoderRecommendedLevelFingerprint -import app.revanced.patches.youtube.utils.storyboard.fingerprints.StoryboardRendererDecoderSpecFingerprint -import app.revanced.patches.youtube.utils.storyboard.fingerprints.StoryboardRendererSpecFingerprint -import app.revanced.patches.youtube.utils.storyboard.fingerprints.StoryboardThumbnailFingerprint -import app.revanced.patches.youtube.utils.storyboard.fingerprints.StoryboardThumbnailParentFingerprint -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Patch( - description = "Force inject the Storyboard by fetching YouTube API.", - dependencies = [SharedResourceIdPatch::class], -) -object StoryboardHookPatch : BytecodePatch( - setOf( - PlayerResponseModelGeneralStoryboardRendererFingerprint, - PlayerResponseModelLiveStreamStoryboardRendererFingerprint, - PlayerResponseModelStoryboardRecommendedLevelFingerprint, - StoryboardRendererDecoderRecommendedLevelFingerprint, - StoryboardRendererDecoderSpecFingerprint, - StoryboardRendererSpecFingerprint, - StoryboardThumbnailParentFingerprint, - ) -) { - private lateinit var context: BytecodeContext - - override fun execute(context: BytecodeContext) { - this.context = context - } - - internal fun hook(classDescriptor: String) { - - // Force the seekbar time and chapters to always show up. - // This is used if the storyboard spec fetch fails, for viewing paid videos, - // or if storyboard spoofing is turned off. - StoryboardThumbnailFingerprint.resolve( - context, - StoryboardThumbnailParentFingerprint.resultOrThrow().classDef - ) - StoryboardThumbnailFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.endIndex - val targetRegister = - getInstruction(targetIndex).registerA - - // Since this is end of the method must replace one line then add the rest. - addInstructions( - targetIndex + 1, - """ - invoke-static {}, $classDescriptor->getSeekbarThumbnailOverrideValue()Z - move-result v$targetRegister - return v$targetRegister - """ - ) - removeInstruction(targetIndex) - } - } - - // Hook storyboard renderer url. - arrayOf( - PlayerResponseModelGeneralStoryboardRendererFingerprint, - PlayerResponseModelLiveStreamStoryboardRendererFingerprint - ).forEach { fingerprint -> - fingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val getStoryboardIndex = it.scanResult.patternScanResult!!.endIndex - val getStoryboardRegister = - getInstruction(getStoryboardIndex).registerA - - addInstructions( - getStoryboardIndex, - """ - invoke-static { v$getStoryboardRegister }, $classDescriptor->getStoryboardRendererSpec(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$getStoryboardRegister - """ - ) - } - } - } - - // Hook recommended seekbar thumbnails quality level. - StoryboardRendererDecoderRecommendedLevelFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val moveOriginalRecommendedValueIndex = it.scanResult.patternScanResult!!.endIndex - val originalValueRegister = - getInstruction(moveOriginalRecommendedValueIndex).registerA - - addInstructions( - moveOriginalRecommendedValueIndex + 1, """ - invoke-static { v$originalValueRegister }, $classDescriptor->getStoryboardRecommendedLevel(I)I - move-result v$originalValueRegister - """ - ) - } - } - - // Hook the recommended precise seeking thumbnails quality level. - PlayerResponseModelStoryboardRecommendedLevelFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val moveOriginalRecommendedValueIndex = it.scanResult.patternScanResult!!.endIndex - val originalValueRegister = - getInstruction(moveOriginalRecommendedValueIndex).registerA - - addInstructions( - moveOriginalRecommendedValueIndex, """ - invoke-static { v$originalValueRegister }, $classDescriptor->getStoryboardRecommendedLevel(I)I - move-result v$originalValueRegister - """ - ) - } - } - - StoryboardRendererSpecFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val storyBoardUrlParams = 0 - - addInstructionsWithLabels( - 0, """ - if-nez p$storyBoardUrlParams, :ignore - invoke-static { p$storyBoardUrlParams }, $classDescriptor->getStoryboardRendererSpec(Ljava/lang/String;)Ljava/lang/String; - move-result-object p$storyBoardUrlParams - """, ExternalLabel("ignore", getInstruction(0)) - ) - } - } - - // Hook the seekbar thumbnail decoder and use a NULL spec for live streams. - StoryboardRendererDecoderSpecFingerprint.resultOrThrow().let { - val storyBoardUrlIndex = it.scanResult.patternScanResult!!.startIndex + 1 - val storyboardUrlRegister = - it.mutableMethod.getInstruction(storyBoardUrlIndex).registerA - - it.mutableMethod.addInstructions( - storyBoardUrlIndex + 1, """ - invoke-static { v$storyboardUrlRegister }, $classDescriptor->getStoryboardDecoderRendererSpec(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$storyboardUrlRegister - """ - ) - } - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/PlayerResponseModelGeneralStoryboardRendererFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/PlayerResponseModelGeneralStoryboardRendererFingerprint.kt deleted file mode 100644 index 0bcb7867dd..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/PlayerResponseModelGeneralStoryboardRendererFingerprint.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.youtube.utils.storyboard.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import app.revanced.util.containsWideLiteralInstructionIndex -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -internal object PlayerResponseModelGeneralStoryboardRendererFingerprint : MethodFingerprint( - returnType = "Ljava/lang/String;", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = emptyList(), - opcodes = listOf( - Opcode.RETURN_OBJECT, - Opcode.CONST_4, - Opcode.RETURN_OBJECT - ), - customFingerprint = handler@{ methodDef, _ -> - if (!methodDef.definingClass.endsWith("/PlayerResponseModelImpl;")) - return@handler false - - methodDef.containsWideLiteralInstructionIndex(55735497) - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/PlayerResponseModelLiveStreamStoryboardRendererFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/PlayerResponseModelLiveStreamStoryboardRendererFingerprint.kt deleted file mode 100644 index 6fe94ccec3..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/PlayerResponseModelLiveStreamStoryboardRendererFingerprint.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.youtube.utils.storyboard.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import app.revanced.util.containsWideLiteralInstructionIndex -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -internal object PlayerResponseModelLiveStreamStoryboardRendererFingerprint : MethodFingerprint( - returnType = "Ljava/lang/String;", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = emptyList(), - opcodes = listOf( - Opcode.RETURN_OBJECT, - Opcode.CONST_4, - Opcode.RETURN_OBJECT - ), - customFingerprint = handler@{ methodDef, _ -> - if (!methodDef.definingClass.endsWith("/PlayerResponseModelImpl;")) - return@handler false - - methodDef.containsWideLiteralInstructionIndex(70276274) - } -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/PlayerResponseModelStoryboardRecommendedLevelFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/PlayerResponseModelStoryboardRecommendedLevelFingerprint.kt deleted file mode 100644 index c7709b79e3..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/PlayerResponseModelStoryboardRecommendedLevelFingerprint.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.youtube.utils.storyboard.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import app.revanced.util.containsWideLiteralInstructionIndex -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -internal object PlayerResponseModelStoryboardRecommendedLevelFingerprint : MethodFingerprint( - returnType = "I", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = emptyList(), - opcodes = listOf( - Opcode.SGET_OBJECT, - Opcode.IGET, - Opcode.RETURN - ), - customFingerprint = handler@{ methodDef, _ -> - if (!methodDef.definingClass.endsWith("/PlayerResponseModelImpl;")) - return@handler false - - methodDef.containsWideLiteralInstructionIndex(55735497) - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardRendererDecoderRecommendedLevelFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardRendererDecoderRecommendedLevelFingerprint.kt deleted file mode 100644 index b8e9daa36a..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardRendererDecoderRecommendedLevelFingerprint.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.utils.storyboard.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -/** - * Resolves to the same method as [StoryboardRendererDecoderSpecFingerprint]. - */ -internal object StoryboardRendererDecoderRecommendedLevelFingerprint : MethodFingerprint( - returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = listOf("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;"), - opcodes = listOf( - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT - ), - strings = listOf("#-1#") -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardRendererDecoderSpecFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardRendererDecoderSpecFingerprint.kt deleted file mode 100644 index e5271661ce..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardRendererDecoderSpecFingerprint.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.utils.storyboard.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -/** - * Resolves to the same method as [StoryboardRendererDecoderRecommendedLevelFingerprint]. - */ -internal object StoryboardRendererDecoderSpecFingerprint : MethodFingerprint( - returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = listOf("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;"), - opcodes = listOf( - Opcode.INVOKE_INTERFACE, // First instruction of the method. - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST_4, - Opcode.CONST_4, - Opcode.IF_NEZ, - ), - strings = listOf("#-1#") -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardRendererSpecFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardRendererSpecFingerprint.kt deleted file mode 100644 index 191bd7a17d..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardRendererSpecFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.youtube.utils.storyboard.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags - -internal object StoryboardRendererSpecFingerprint : MethodFingerprint( - accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, - returnType = "L", - parameters = listOf("Ljava/lang/String;", "J"), - strings = listOf("\\|"), -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardThumbnailFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardThumbnailFingerprint.kt deleted file mode 100644 index 1211b12dab..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardThumbnailFingerprint.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.utils.storyboard.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -/** - * Resolves using the class found in [StoryboardThumbnailParentFingerprint]. - */ -internal object StoryboardThumbnailFingerprint : MethodFingerprint( - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - returnType = "Z", - parameters = listOf(), - opcodes = listOf( - Opcode.MOVE_RESULT, - Opcode.IF_GTZ, - Opcode.GOTO, - Opcode.CONST_4, - Opcode.RETURN, - Opcode.RETURN, // Last instruction of method. - ), -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardThumbnailParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardThumbnailParentFingerprint.kt deleted file mode 100644 index 9e5ec469c7..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/storyboard/fingerprints/StoryboardThumbnailParentFingerprint.kt +++ /dev/null @@ -1,17 +0,0 @@ -package app.revanced.patches.youtube.utils.storyboard.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags - -/** - * Here lies code that creates the seekbar thumbnails. - * - * An additional change here might force the thumbnails to be created, - * or possibly a change somewhere else (maybe involving YouTube 18.23.35 class `hte`) - */ -internal object StoryboardThumbnailParentFingerprint : MethodFingerprint( - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - returnType = "Landroid/graphics/Bitmap;", - strings = listOf("Storyboard regionDecoder.decodeRegion exception - "), -) \ No newline at end of file diff --git a/src/main/resources/youtube/settings/host/values/arrays.xml b/src/main/resources/youtube/settings/host/values/arrays.xml index e58e3ff003..5351620964 100644 --- a/src/main/resources/youtube/settings/host/values/arrays.xml +++ b/src/main/resources/youtube/settings/host/values/arrays.xml @@ -163,46 +163,6 @@ HEART_TINT HIDDEN - - @string/revanced_spoof_client_options_entry_ios - @string/revanced_spoof_client_options_entry_android_testsuite - @string/revanced_spoof_client_options_entry_android_unplugged - @string/revanced_spoof_client_options_entry_android_vr - - - IOS - ANDROID_TESTSUITE - ANDROID_UNPLUGGED - ANDROID_VR - - - @string/revanced_spoof_client_options_entry_ios - @string/revanced_spoof_client_options_entry_android_unplugged - @string/revanced_spoof_client_options_entry_android_vr - - - IOS - ANDROID_UNPLUGGED - ANDROID_VR - - - @string/revanced_spoof_client_options_entry_ios - @string/revanced_spoof_client_options_entry_android_vr - - - IOS - ANDROID_VR - - - @string/revanced_spoof_client_options_entry_ios - @string/revanced_spoof_client_options_entry_android_testsuite - @string/revanced_spoof_client_options_entry_android_vr - - - IOS - ANDROID_TESTSUITE - ANDROID_VR - @string/revanced_spoof_app_version_target_entry_18_17_43 @string/revanced_spoof_app_version_target_entry_18_05_40 diff --git a/src/main/resources/youtube/settings/host/values/strings.xml b/src/main/resources/youtube/settings/host/values/strings.xml index 4bb7628215..fffed21921 100644 --- a/src/main/resources/youtube/settings/host/values/strings.xml +++ b/src/main/resources/youtube/settings/host/values/strings.xml @@ -1551,22 +1551,6 @@ Tap on the continue button and disable battery optimizations." Enable OPUS codec Enable the OPUS codec if the player response includes the OPUS codec. - Spoof player parameter - "Spoofs player parameters to prevent playback issues. - -Limitations: -• Enhanced bitrate is not available. -• No seekbar thumbnails for paid videos. -• Offline downloads may not work. -• Video may not start from the last watched time." - Spoof player parameter in feed - "Player parameter spoofed for feed videos. - -Limitation: Automatically played feed videos will show up in your watch history." - "Player parameter not spoofed for feed videos. - -Limitation: Feed videos will play for less than 1 minute before encountering playback issues." - Import / Export settings Import or export settings. @@ -1593,83 +1577,6 @@ Limitation: Feed videos will play for less than 1 minute before encountering pla Reset Settings copied to clipboard. - - Spoof client - Spoof the client to prevent playback issues. - Spoof client - Client is spoofed. - "Client is not spoofed. Video playback may not work." - Turning off this setting may cause video playback issues. - Spoof client type - Force iOS AVC (H.264) - iOS video codec is AVC (H.264). - iOS video codec is AVC (H.264), VP9, or AV1. - "Enabling this might improve battery life and fix playback stuttering. - -AVC (H.264) has a maximum resolution of 1080p, and video playback will use more internet data than VP9 or AV1." - Show in Stats for nerds - Spoofed client is shown in Stats for nerds. - Spoofed client is hidden in Stats for nerds. - - - Spoof client options - General - Live streams - Shorts, Clips - Unplayable video - iOS - Android - Android Embedded Player - Android Testsuite - Android TV - Android VR - TV HTML5 - Web - - - About - - iOS - "Spoof client to iOS. - -Side effects include: -• HDR is supported only with AV1 codec. -• Watch time is not saved in watch history on brand account." - "Spoof client to iOS. - -Side effects include: -• HDR is supported only with AV1 codec. -• Watch history does not work with a brand account." - Android Testsuite - "Spoof client to Android Testsuite. - -Side effects include: -• No HDR video. -• Audio track menu is missing. -• Captions may not be available. -• Download button is missing. -• End screen cards are missing. -• Low quality seekbar thumbnail." - Android TV - "Spoof client to Android TV (YouTube TV). - -Side effects include: -• No HDR video. -• Audio track menu is missing. -• Captions may not be available. -• Download button is missing. -• Low quality seekbar thumbnail. -• Some live streams are not supported for playback." - Android VR - "Spoof client to Android VR. - -Side effects include: -• No HDR video. -• Download button of video action bar is missing. -• Paused videos can randomly resume. -• Low quality Shorts seekbar thumbnails. -• Kids videos do not play." - Watch history Change settings related with watch history. @@ -1682,15 +1589,8 @@ Side effects include: Block watch history Status of watch history • Watch history is blocked. - "• Follows the watch history settings of Google account. -• Watch history may not work with a brand account. -(Spoof client setting is enabled and iOS client is selected)" - "• Follows the watch history settings of Google account. -• Watch history may not work due to DNS or VPN. -• Watch history may not work with a brand account. -(Spoof client setting is enabled and iOS client is selected)" - • Follows the watch history settings of Google account. - "• Follows the watch history settings of Google account. + • Follows the watch history settings of Google account. + "• Follows the watch history settings of Google account. • Watch history may not work due to DNS or VPN." diff --git a/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 592a75c59d..4d9dc746c9 100644 --- a/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -610,32 +610,6 @@ - - - - - - - - - - @@ -756,7 +726,6 @@ - diff --git a/src/main/resources/youtube/visual/shared/drawable/revanced_preference_screen_spoof_client_icon.xml b/src/main/resources/youtube/visual/shared/drawable/revanced_preference_screen_spoof_client_icon.xml deleted file mode 100644 index 8d08d6d160..0000000000 --- a/src/main/resources/youtube/visual/shared/drawable/revanced_preference_screen_spoof_client_icon.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - -