From 883fbe71233c57cb1241e57c122b43f40722acc7 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Wed, 19 Mar 2025 18:08:51 +0100 Subject: [PATCH] fix(YouTube - Spoof app version): Remove broken spoof targets that YouTube no longer supports (#4610) --- .../patches/ReturnYouTubeDislikePatch.java | 144 +----------------- .../ReturnYouTubeDislike.java | 13 -- .../extension/youtube/settings/Settings.java | 22 +-- ...eturnYouTubeDislikePreferenceFragment.java | 4 +- .../returnyoutubedislike/Fingerprints.kt | 14 -- .../ReturnYouTubeDislikePatch.kt | 100 ++++-------- .../spoofappversion/SpoofAppVersionPatch.kt | 23 +-- .../resources/addresources/values/arrays.xml | 15 -- .../resources/addresources/values/strings.xml | 6 - 9 files changed, 43 insertions(+), 298 deletions(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ReturnYouTubeDislikePatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ReturnYouTubeDislikePatch.java index 752fdaf8b..5c54985bb 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ReturnYouTubeDislikePatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/ReturnYouTubeDislikePatch.java @@ -21,7 +21,6 @@ import java.util.Objects; import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Utils; import app.revanced.extension.youtube.patches.components.ReturnYouTubeDislikeFilterPatch; -import app.revanced.extension.youtube.patches.spoof.SpoofAppVersionPatch; import app.revanced.extension.youtube.returnyoutubedislike.ReturnYouTubeDislike; import app.revanced.extension.youtube.returnyoutubedislike.requests.ReturnYouTubeDislikeApi; import app.revanced.extension.youtube.settings.Settings; @@ -47,9 +46,6 @@ import app.revanced.extension.youtube.shared.PlayerType; @SuppressWarnings("unused") public class ReturnYouTubeDislikePatch { - public static final boolean IS_SPOOFING_TO_NON_LITHO_SHORTS_PLAYER = - SpoofAppVersionPatch.isSpoofingToLessThan("18.34.00"); - /** * RYD data for the current video on screen. */ @@ -347,137 +343,6 @@ public class ReturnYouTubeDislikePatch { } } - // - // Non litho Shorts player. - // - - /** - * Replacement text to use for "Dislikes" while RYD is fetching. - */ - private static final Spannable SHORTS_LOADING_SPAN = new SpannableString("-"); - - /** - * Dislikes TextViews used by Shorts. - * - * Multiple TextViews are loaded at once (for the prior and next videos to swipe to). - * Keep track of all of them, and later pick out the correct one based on their on screen position. - */ - private static final List> shortsTextViewRefs = new ArrayList<>(); - - private static void clearRemovedShortsTextViews() { - shortsTextViewRefs.removeIf(ref -> ref.get() == null); - } - - /** - * Injection point. Called when a Shorts dislike is updated. Always on main thread. - * Handles update asynchronously, otherwise Shorts video will be frozen while the UI thread is blocked. - * - * @return if RYD is enabled and the TextView was updated. - */ - public static boolean setShortsDislikes(@NonNull View likeDislikeView) { - try { - if (!Settings.RYD_ENABLED.get()) { - return false; - } - if (!Settings.RYD_SHORTS.get() || Settings.HIDE_SHORTS_DISLIKE_BUTTON.get()) { - // Must clear the data here, in case a new video was loaded while PlayerType - // suggested the video was not a short (can happen when spoofing to an old app version). - clearData(); - return false; - } - Logger.printDebug(() -> "setShortsDislikes"); - - TextView textView = (TextView) likeDislikeView; - textView.setText(SHORTS_LOADING_SPAN); // Change 'Dislike' text to the loading text. - shortsTextViewRefs.add(new WeakReference<>(textView)); - - if (likeDislikeView.isSelected() && isShortTextViewOnScreen(textView)) { - Logger.printDebug(() -> "Shorts dislike is already selected"); - ReturnYouTubeDislike videoData = currentVideoData; - if (videoData != null) videoData.setUserVote(Vote.DISLIKE); - } - - // For the first short played, the Shorts dislike hook is called after the video id hook. - // But for most other times this hook is called before the video id (which is not ideal). - // Must update the TextViews here, and also after the videoId changes. - updateOnScreenShortsTextViews(false); - - return true; - } catch (Exception ex) { - Logger.printException(() -> "setShortsDislikes failure", ex); - return false; - } - } - - /** - * @param forceUpdate if false, then only update the 'loading text views. - * If true, update all on screen text views. - */ - private static void updateOnScreenShortsTextViews(boolean forceUpdate) { - try { - clearRemovedShortsTextViews(); - if (shortsTextViewRefs.isEmpty()) { - return; - } - ReturnYouTubeDislike videoData = currentVideoData; - if (videoData == null) { - return; - } - - Logger.printDebug(() -> "updateShortsTextViews"); - - Runnable update = () -> { - Spanned shortsDislikesSpan = videoData.getDislikeSpanForShort(SHORTS_LOADING_SPAN); - Utils.runOnMainThreadNowOrLater(() -> { - String videoId = videoData.getVideoId(); - if (!videoId.equals(VideoInformation.getVideoId())) { - // User swiped to new video before fetch completed - Logger.printDebug(() -> "Ignoring stale dislikes data for short: " + videoId); - return; - } - - // Update text views that appear to be visible on screen. - // Only 1 will be the actual textview for the current Short, - // but discarded and not yet garbage collected views can remain. - // So must set the dislike span on all views that match. - for (WeakReference textViewRef : shortsTextViewRefs) { - TextView textView = textViewRef.get(); - if (textView == null) { - continue; - } - if (isShortTextViewOnScreen(textView) - && (forceUpdate || textView.getText().toString().equals(SHORTS_LOADING_SPAN.toString()))) { - Logger.printDebug(() -> "Setting Shorts TextView to: " + shortsDislikesSpan); - textView.setText(shortsDislikesSpan); - } - } - }); - }; - if (videoData.fetchCompleted()) { - update.run(); // Network call is completed, no need to wait on background thread. - } else { - Utils.runOnBackgroundThread(update); - } - } catch (Exception ex) { - Logger.printException(() -> "updateOnScreenShortsTextViews failure", ex); - } - } - - /** - * Check if a view is within the screen bounds. - */ - private static boolean isShortTextViewOnScreen(@NonNull View view) { - final int[] location = new int[2]; - view.getLocationInWindow(location); - if (location[0] <= 0 && location[1] <= 0) { // Lower bound - return false; - } - Rect windowRect = new Rect(); - view.getWindowVisibleDisplayFrame(windowRect); // Upper bound - return location[0] < windowRect.width() && location[1] < windowRect.height(); - } - - // // Video Id and voting hooks (all players). // @@ -503,8 +368,7 @@ public class ReturnYouTubeDislikePatch { if (videoIdIsShort && (!isShortAndOpeningOrPlaying || !Settings.RYD_SHORTS.get())) { return; } - final boolean waitForFetchToComplete = !IS_SPOOFING_TO_NON_LITHO_SHORTS_PLAYER - && videoIdIsShort && !lastPlayerResponseWasShort; + final boolean waitForFetchToComplete = videoIdIsShort && !lastPlayerResponseWasShort; Logger.printDebug(() -> "Prefetching RYD for video: " + videoId); ReturnYouTubeDislike fetch = ReturnYouTubeDislike.getFetchForVideoId(videoId); @@ -557,12 +421,6 @@ public class ReturnYouTubeDislikePatch { data.setVideoIdIsShort(true); } currentVideoData = data; - - // Current video id hook can be called out of order with the non litho Shorts text view hook. - // Must manually update again here. - if (isNoneHiddenOrSlidingMinimized) { - updateOnScreenShortsTextViews(true); - } } catch (Exception ex) { Logger.printException(() -> "newVideoLoaded failure", ex); } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/returnyoutubedislike/ReturnYouTubeDislike.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/returnyoutubedislike/ReturnYouTubeDislike.java index 36623c522..6752840ec 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/returnyoutubedislike/ReturnYouTubeDislike.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/returnyoutubedislike/ReturnYouTubeDislike.java @@ -37,7 +37,6 @@ import java.util.concurrent.*; import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Utils; import app.revanced.extension.youtube.ThemeHelper; -import app.revanced.extension.youtube.patches.spoof.SpoofAppVersionPatch; import app.revanced.extension.youtube.returnyoutubedislike.requests.RYDVoteData; import app.revanced.extension.youtube.returnyoutubedislike.requests.ReturnYouTubeDislikeApi; import app.revanced.extension.youtube.settings.Settings; @@ -87,9 +86,6 @@ public class ReturnYouTubeDislike { */ private static final char MIDDLE_SEPARATOR_CHARACTER = '◎'; // 'bullseye' - private static final boolean IS_SPOOFING_TO_OLD_SEPARATOR_COLOR - = SpoofAppVersionPatch.isSpoofingToLessThan("18.10.00"); - /** * Cached lookup of all video ids. */ @@ -184,17 +180,8 @@ public class ReturnYouTubeDislike { * Color of the left and middle separator, based on the color of the right separator. * It's unknown where YT gets the color from, and the values here are approximated by hand. * Ideally, this would be the actual color YT uses at runtime. - * - * Older versions before the 'Me' library tab use a slightly different color. - * If spoofing was previously used and is now turned off, - * or an old version was recently upgraded then the old colors are sometimes still used. */ private static int getSeparatorColor() { - if (IS_SPOOFING_TO_OLD_SEPARATOR_COLOR) { - return ThemeHelper.isDarkTheme() - ? 0x29AAAAAA // transparent dark gray - : 0xFFD9D9D9; // light gray - } return ThemeHelper.isDarkTheme() ? 0x33FFFFFF : 0xFFD9D9D9; diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java index c0c20842b..ef1ecdd65 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -3,7 +3,6 @@ package app.revanced.extension.youtube.settings; import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; import static app.revanced.extension.shared.settings.Setting.Availability; -import static app.revanced.extension.shared.settings.Setting.migrateFromOldPreferences; import static app.revanced.extension.shared.settings.Setting.migrateOldSettingToNew; import static app.revanced.extension.shared.settings.Setting.parent; import static app.revanced.extension.shared.settings.Setting.parentsAny; @@ -21,7 +20,6 @@ import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerT import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_4; import static app.revanced.extension.youtube.patches.OpenShortsInRegularPlayerPatch.ShortsPlayerType; import static app.revanced.extension.youtube.patches.SeekbarThumbnailsPatch.SeekbarThumbnailsHighQualityAvailability; -import static app.revanced.extension.youtube.patches.VersionCheckPatch.IS_19_17_OR_GREATER; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.IGNORE; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.MANUAL_SKIP; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY; @@ -38,7 +36,6 @@ import app.revanced.extension.shared.settings.IntegerSetting; import app.revanced.extension.shared.settings.LongSetting; import app.revanced.extension.shared.settings.Setting; import app.revanced.extension.shared.settings.StringSetting; -import app.revanced.extension.shared.settings.preference.SharedPrefCategory; import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.DeArrowAvailability; import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.StillImagesAvailability; import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailOption; @@ -221,7 +218,7 @@ public class Settings extends BaseSettings { public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", FALSE, true, "revanced_spoof_app_version_user_dialog_message"); public static final BooleanSetting WIDE_SEARCHBAR = new BooleanSetting("revanced_wide_searchbar", FALSE, true); public static final EnumSetting CHANGE_START_PAGE = new EnumSetting<>("revanced_change_start_page", StartPage.DEFAULT, true); - public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", IS_19_17_OR_GREATER ? "19.26.42" : "17.33.42", true, parent(SPOOF_APP_VERSION)); + public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", "19.26.42", true, parent(SPOOF_APP_VERSION)); // Custom filter public static final BooleanSetting CUSTOM_FILTER = new BooleanSetting("revanced_custom_filter", FALSE); public static final StringSetting CUSTOM_FILTER_STRINGS = new StringSetting("revanced_custom_filter_strings", "", true, parent(CUSTOM_FILTER)); @@ -395,7 +392,6 @@ public class Settings extends BaseSettings { public static final FloatSetting SB_CATEGORY_UNSUBMITTED_OPACITY = new FloatSetting("sb_unsubmitted_opacity", 1.0f); // Deprecated migrations - private static final StringSetting DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING = new StringSetting("uuid", ""); // Delete sometime in 2024 private static final BooleanSetting DEPRECATED_HIDE_PLAYER_BUTTONS = new BooleanSetting("revanced_hide_player_buttons", FALSE, true); private static final BooleanSetting DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER = new BooleanSetting("revanced_hide_video_quality_menu_footer", FALSE); private static final IntegerSetting DEPRECATED_SWIPE_OVERLAY_BACKGROUND_ALPHA = new IntegerSetting("revanced_swipe_overlay_background_alpha", 127); @@ -406,16 +402,6 @@ public class Settings extends BaseSettings { static { // region Migration - // Do _not_ delete this SB private user id migration property until sometime in early 2025. - // This is the only setting that cannot be reconfigured if lost, - // and more time should be given for users who rarely upgrade. - SharedPrefCategory sbPrefs = new SharedPrefCategory("sponsor-block"); - // Remove the "sb_" prefix, as old settings are saved without it. - String key = DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING.key.substring(3); - migrateFromOldPreferences(sbPrefs, DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, key); - - migrateOldSettingToNew(DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, SB_PRIVATE_USER_ID); - migrateOldSettingToNew(DEPRECATED_HIDE_PLAYER_BUTTONS, HIDE_PLAYER_PREVIOUS_NEXT_BUTTONS); migrateOldSettingToNew(DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER, HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER); @@ -459,6 +445,12 @@ public class Settings extends BaseSettings { DEPRECATED_SWIPE_OVERLAY_BACKGROUND_ALPHA.resetToDefault(); } + // Old spoof versions that no longer work. + if (SPOOF_APP_VERSION_TARGET.get().compareTo(SPOOF_APP_VERSION_TARGET.defaultValue) < 0) { + Logger.printInfo(() -> "Resetting spoof app version target"); + SPOOF_APP_VERSION_TARGET.resetToDefault(); + } + // endregion // region SB import/export callbacks diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReturnYouTubeDislikePreferenceFragment.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReturnYouTubeDislikePreferenceFragment.java index 7c367f87b..bb62386ac 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReturnYouTubeDislikePreferenceFragment.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReturnYouTubeDislikePreferenceFragment.java @@ -86,9 +86,7 @@ public class ReturnYouTubeDislikePreferenceFragment extends PreferenceFragment { shortsPreference = new SwitchPreference(context); shortsPreference.setChecked(Settings.RYD_SHORTS.get()); shortsPreference.setTitle(str("revanced_ryd_shorts_title")); - String shortsSummary = ReturnYouTubeDislikePatch.IS_SPOOFING_TO_NON_LITHO_SHORTS_PLAYER - ? str("revanced_ryd_shorts_summary_on") - : str("revanced_ryd_shorts_summary_on_disclaimer"); + String shortsSummary = str("revanced_ryd_shorts_summary_on_disclaimer"); shortsPreference.setSummaryOn(shortsSummary); shortsPreference.setSummaryOff(str("revanced_ryd_shorts_summary_off")); shortsPreference.setOnPreferenceChangeListener((pref, newValue) -> { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/Fingerprints.kt index 2dd73ecc4..23abbd2b1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/Fingerprints.kt @@ -98,20 +98,6 @@ internal val rollingNumberTextViewFingerprint = fingerprint { } } -internal val shortsTextViewFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("V") - parameters("L", "L") - opcodes( - Opcode.INVOKE_SUPER, // first instruction of method - Opcode.IF_NEZ, - null, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - ) -} - internal val textComponentConstructorFingerprint = fingerprint { accessFlags(AccessFlags.CONSTRUCTOR, AccessFlags.PRIVATE) strings("TextComponent") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt index 84d48468a..037f0875c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt @@ -1,9 +1,7 @@ package app.revanced.patches.youtube.layout.returnyoutubedislike 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.instructions import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.all.misc.resources.addResources @@ -169,51 +167,7 @@ val returnYouTubeDislikePatch = bytecodePatch( // endregion - // region Hook for non-litho Short videos. - shortsTextViewFingerprint.method.apply { - val insertIndex = shortsTextViewFingerprint.patternMatch!!.endIndex + 1 - - // If the field is true, the TextView is for a dislike button. - val isDisLikesBooleanInstruction = instructions.first { instruction -> - instruction.opcode == Opcode.IGET_BOOLEAN - } as ReferenceInstruction - - val isDisLikesBooleanReference = isDisLikesBooleanInstruction.reference - - // Like/Dislike button TextView field. - val textViewFieldInstruction = instructions.first { instruction -> - instruction.opcode == Opcode.IGET_OBJECT - } as ReferenceInstruction - - val textViewFieldReference = textViewFieldInstruction.reference - - // Check if the hooked TextView object is that of the dislike button. - // If RYD is disabled, or the TextView object is not that of the dislike button, the execution flow is not interrupted. - // Otherwise, the TextView object is modified, and the execution flow is interrupted to prevent it from being changed afterward. - addInstructionsWithLabels( - insertIndex, - """ - # Check, if the TextView is for a dislike button - iget-boolean v0, p0, $isDisLikesBooleanReference - if-eqz v0, :is_like - - # Hook the TextView, if it is for the dislike button - iget-object v0, p0, $textViewFieldReference - invoke-static {v0}, $EXTENSION_CLASS_DESCRIPTOR->setShortsDislikes(Landroid/view/View;)Z - move-result v0 - if-eqz v0, :ryd_disabled - return-void - - :is_like - :ryd_disabled - nop - """, - ) - } - - // endregion - - // region Hook for litho Shorts + // region Hook Shorts // Filter that parses the video id from the UI addLithoFilter(FILTER_CLASS_DESCRIPTOR) @@ -255,22 +209,25 @@ val returnYouTubeDislikePatch = bytecodePatch( ) } - // Rolling Number text views use the measured width of the raw string for layout. - // Modify the measure text calculation to include the left drawable separator if needed. - val patternMatch = rollingNumberMeasureAnimatedTextFingerprint.patternMatch!! - // Additional check to verify the opcodes are at the start of the method - if (patternMatch.startIndex != 0) throw PatchException("Unexpected opcode location") - val endIndex = patternMatch.endIndex - rollingNumberMeasureAnimatedTextFingerprint.method.apply { - val measuredTextWidthRegister = getInstruction(endIndex).registerA + rollingNumberMeasureAnimatedTextFingerprint.let { + // Rolling Number text views use the measured width of the raw string for layout. + // Modify the measure text calculation to include the left drawable separator if needed. + val patternMatch = it.patternMatch!! + // Verify the opcodes are at the start of the method. + if (patternMatch.startIndex != 0) throw PatchException("Unexpected opcode location") + val endIndex = patternMatch.endIndex - addInstructions( - endIndex + 1, - """ - invoke-static {p1, v$measuredTextWidthRegister}, $EXTENSION_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F - move-result v$measuredTextWidthRegister - """, - ) + it.method.apply { + val measuredTextWidthRegister = getInstruction(endIndex).registerA + + addInstructions( + endIndex + 1, + """ + invoke-static {p1, v$measuredTextWidthRegister}, $EXTENSION_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F + move-result v$measuredTextWidthRegister + """ + ) + } } // Additional text measurement method. Used if YouTube decides not to animate the likes count @@ -291,15 +248,14 @@ val returnYouTubeDislikePatch = bytecodePatch( ) } } - // The rolling number Span is missing styling since it's initially set as a String. - // Modify the UI text view and use the styled like/dislike Span. - // Initial TextView is set in this method. - val initiallyCreatedTextViewMethod = rollingNumberTextViewFingerprint.method - // Videos less than 24 hours after uploaded, like counts will be updated in real time. - // Whenever like counts are updated, TextView is set in this method. arrayOf( - initiallyCreatedTextViewMethod, + // The rolling number Span is missing styling since it's initially set as a String. + // Modify the UI text view and use the styled like/dislike Span. + // Initial TextView is set in this method. + rollingNumberTextViewFingerprint.method, + // Videos less than 24 hours after uploaded, like counts will be updated in real time. + // Whenever like counts are updated, TextView is set in this method. rollingNumberTextViewAnimationUpdateFingerprint.method, ).forEach { insertMethod -> insertMethod.apply { @@ -315,9 +271,9 @@ val returnYouTubeDislikePatch = bytecodePatch( addInstructions( setTextIndex, """ - invoke-static {v$textViewRegister, v$textSpanRegister}, $EXTENSION_CLASS_DESCRIPTOR->updateRollingNumber(Landroid/widget/TextView;Ljava/lang/CharSequence;)Ljava/lang/CharSequence; - move-result-object v$textSpanRegister - """, + invoke-static {v$textViewRegister, v$textSpanRegister}, $EXTENSION_CLASS_DESCRIPTOR->updateRollingNumber(Landroid/widget/TextView;Ljava/lang/CharSequence;)Ljava/lang/CharSequence; + move-result-object v$textSpanRegister + """ ) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt index 0deffb506..2095b1f30 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt @@ -16,7 +16,6 @@ import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch -import app.revanced.patches.youtube.misc.playservice.is_19_17_or_greater import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch @@ -46,8 +45,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR = val spoofAppVersionPatch = bytecodePatch( name = "Spoof app version", description = "Adds an option to trick YouTube into thinking you are running an older version of the app. " + - "This can be used to restore old UI elements and features. " + - "Patching 19.16.39 includes additional older spoofing targets.", + "This can be used to restore old UI elements and features." ) { dependsOn( spoofAppVersionResourcePatch, @@ -59,7 +57,7 @@ val spoofAppVersionPatch = bytecodePatch( compatibleWith( "com.google.android.youtube"( - "19.16.39", + // "19.16.39", // Cannot be supported because the lowest spoof target is higher. // "19.25.37", // Cannot be supported because the lowest spoof target is higher. // "19.34.42", // Cannot be supported because the lowest spoof target is higher. "19.43.41", @@ -81,19 +79,10 @@ val spoofAppVersionPatch = bytecodePatch( tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory", preferences = setOf( SwitchPreference("revanced_spoof_app_version"), - if (is_19_17_or_greater) { - ListPreference( - key = "revanced_spoof_app_version_target", - summaryKey = null, - ) - } else { - ListPreference( - key = "revanced_spoof_app_version_target", - summaryKey = null, - entriesKey = "revanced_spoof_app_version_target_legacy_entries", - entryValuesKey = "revanced_spoof_app_version_target_legacy_entry_values" - ) - } + ListPreference( + key = "revanced_spoof_app_version_target", + summaryKey = null, + ) ) ) ) diff --git a/patches/src/main/resources/addresources/values/arrays.xml b/patches/src/main/resources/addresources/values/arrays.xml index a62906a68..332541633 100644 --- a/patches/src/main/resources/addresources/values/arrays.xml +++ b/patches/src/main/resources/addresources/values/arrays.xml @@ -143,24 +143,9 @@ @string/revanced_spoof_app_version_target_entry_2 - 19.35.36 19.26.42 - - @string/revanced_spoof_app_version_target_legacy_entry_1 - @string/revanced_spoof_app_version_target_legacy_entry_2 - @string/revanced_spoof_app_version_target_legacy_entry_3 - @string/revanced_spoof_app_version_target_legacy_entry_4 - - - 18.33.40 - 18.20.39 - 18.09.39 - 17.33.42 - diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index 41648df70..44f730ac6 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -868,7 +868,6 @@ Settings → Playback → Autoplay next video" Dislikes are shown Dislikes are not shown Show dislikes on Shorts - Dislikes on Shorts are shown "Dislikes on Shorts are shown Limitation: Dislikes may not appear in incognito mode" @@ -1157,11 +1156,6 @@ If later turned off, it is recommended to clear the app data to prevent UI bugs. Spoof app version target 19.35.36 - Restore old Shorts player icons 19.26.42 - Restore old navigation icons - - 18.33.40 - Restore RYD on Shorts incognito mode - 18.20.39 - Restore wide video speed & quality menu - 18.09.39 - Restore library tab - 17.33.42 - Restore old playlist shelf Set start page