diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DisableResumingStartupShortsPlayerPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DisableResumingStartupShortsPlayerPatch.java index 938ac54583..2e8c3cc06a 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DisableResumingStartupShortsPlayerPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DisableResumingStartupShortsPlayerPatch.java @@ -2,7 +2,7 @@ import app.revanced.extension.youtube.settings.Settings; -/** @noinspection unused*/ +@SuppressWarnings("unused") public class DisableResumingStartupShortsPlayerPatch { /** @@ -11,4 +11,11 @@ public class DisableResumingStartupShortsPlayerPatch { public static boolean disableResumingStartupShortsPlayer() { return Settings.DISABLE_RESUMING_SHORTS_PLAYER.get(); } + + /** + * Injection point. + */ + public static boolean disableResumingStartupShortsPlayer(boolean original) { + return original && !Settings.DISABLE_RESUMING_SHORTS_PLAYER.get(); + } } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DownloadsPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DownloadsPatch.java index 6da31b6a4c..bbe01ec89f 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DownloadsPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/DownloadsPatch.java @@ -23,7 +23,7 @@ public final class DownloadsPatch { /** * Injection point. */ - public static void activityCreated(Activity mainActivity) { + public static void setMainActivity(Activity mainActivity) { activityRef = new WeakReference<>(mainActivity); } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/MiniplayerPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/MiniplayerPatch.java index be27811c92..1b41e44c63 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/MiniplayerPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/MiniplayerPatch.java @@ -43,10 +43,13 @@ public enum MiniplayerType { MODERN_2(null, 2), MODERN_3(null, 3), /** - * Half broken miniplayer, that might be work in progress or left over abandoned code. - * Can force this type by editing the import/export settings. + * Works and is functional with 20.03+ */ - MODERN_4(null, 4); + MODERN_4(null, 4), + /** + * Half broken miniplayer, and in 20.02 and earlier is declared as type 4. + */ + MODERN_5(null, 5); /** * Legacy tablet hook value. @@ -126,12 +129,13 @@ public boolean isModern() { private static final boolean DRAG_AND_DROP_ENABLED = CURRENT_TYPE.isModern() && Settings.MINIPLAYER_DRAG_AND_DROP.get(); - private static final boolean HIDE_EXPAND_CLOSE_ENABLED = - Settings.MINIPLAYER_HIDE_EXPAND_CLOSE.get() - && Settings.MINIPLAYER_HIDE_EXPAND_CLOSE.isAvailable(); + private static final boolean HIDE_OVERLAY_BUTTONS_ENABLED = + Settings.MINIPLAYER_HIDE_OVERLAY_BUTTONS.get() + && Settings.MINIPLAYER_HIDE_OVERLAY_BUTTONS.isAvailable(); private static final boolean HIDE_SUBTEXT_ENABLED = - (CURRENT_TYPE == MODERN_1 || CURRENT_TYPE == MODERN_3) && Settings.MINIPLAYER_HIDE_SUBTEXT.get(); + (CURRENT_TYPE == MODERN_1 || CURRENT_TYPE == MODERN_3 || CURRENT_TYPE == MODERN_4) + && Settings.MINIPLAYER_HIDE_SUBTEXT.get(); // 19.25 is last version that has forward/back buttons for phones, // but buttons still show for tablets/foldable devices and they don't work well so always hide. @@ -139,7 +143,7 @@ public boolean isModern() { && (VersionCheckPatch.IS_19_34_OR_GREATER || Settings.MINIPLAYER_HIDE_REWIND_FORWARD.get()); private static final boolean MINIPLAYER_ROUNDED_CORNERS_ENABLED = - Settings.MINIPLAYER_ROUNDED_CORNERS.get(); + CURRENT_TYPE.isModern() && Settings.MINIPLAYER_ROUNDED_CORNERS.get(); private static final boolean MINIPLAYER_HORIZONTAL_DRAG_ENABLED = DRAG_AND_DROP_ENABLED && Settings.MINIPLAYER_HORIZONTAL_DRAG.get(); @@ -172,11 +176,12 @@ public boolean isAvailable() { } } - public static final class MiniplayerHideExpandCloseAvailability implements Setting.Availability { + public static final class MiniplayerHideOverlayButtonsAvailability implements Setting.Availability { @Override public boolean isAvailable() { MiniplayerType type = Settings.MINIPLAYER_TYPE.get(); - return (!IS_19_20_OR_GREATER && (type == MODERN_1 || type == MODERN_3)) + return type == MODERN_4 + || (!IS_19_20_OR_GREATER && (type == MODERN_1 || type == MODERN_3)) || (!IS_19_26_OR_GREATER && type == MODERN_1 && !Settings.MINIPLAYER_DOUBLE_TAP_ACTION.get() && !Settings.MINIPLAYER_DRAG_AND_DROP.get()) || (IS_19_29_OR_GREATER && type == MODERN_3); @@ -227,9 +232,13 @@ public static int getModernMiniplayerOverrideType(int original) { /** * Injection point. */ - public static void adjustMiniplayerOpacity(ImageView view) { + public static void adjustMiniplayerOpacity(View view) { if (CURRENT_TYPE == MODERN_1) { - view.setImageAlpha(OPACITY_LEVEL); + if (view instanceof ImageView imageView) { + imageView.setImageAlpha(OPACITY_LEVEL); + } else { + Logger.printException(() -> "Unknown miniplayer overlay view: " + view); + } } } @@ -247,7 +256,7 @@ public static boolean getModernFeatureFlagsActiveOverride(boolean original) { /** * Injection point. */ - public static boolean enableMiniplayerDoubleTapAction(boolean original) { + public static boolean getMiniplayerDoubleTapAction(boolean original) { if (CURRENT_TYPE == DEFAULT) { return original; } @@ -258,7 +267,7 @@ public static boolean enableMiniplayerDoubleTapAction(boolean original) { /** * Injection point. */ - public static boolean enableMiniplayerDragAndDrop(boolean original) { + public static boolean getMiniplayerDragAndDrop(boolean original) { if (CURRENT_TYPE == DEFAULT) { return original; } @@ -266,36 +275,47 @@ public static boolean enableMiniplayerDragAndDrop(boolean original) { return DRAG_AND_DROP_ENABLED; } + /** + * Injection point. + */ + public static boolean getRoundedCorners(boolean original) { + if (CURRENT_TYPE == DEFAULT) { + return original; + } + + return MINIPLAYER_ROUNDED_CORNERS_ENABLED; + } /** * Injection point. */ - public static boolean setRoundedCorners(boolean original) { - if (CURRENT_TYPE.isModern()) { - return MINIPLAYER_ROUNDED_CORNERS_ENABLED; + public static boolean getHorizontalDrag(boolean original) { + if (CURRENT_TYPE == DEFAULT) { + return original; } - return original; + return MINIPLAYER_HORIZONTAL_DRAG_ENABLED; } /** * Injection point. */ - public static int setMiniplayerDefaultSize(int original) { - if (CURRENT_TYPE.isModern()) { - return MINIPLAYER_SIZE; + public static boolean getMaximizeAnimation(boolean original) { + // This must be forced on if horizontal drag is enabled, + // otherwise the UI has visual glitches when maximizing the miniplayer. + if (MINIPLAYER_HORIZONTAL_DRAG_ENABLED) { + return true; } return original; } - /** * Injection point. */ - public static boolean setHorizontalDrag(boolean original) { + public static int getMiniplayerDefaultSize(int original) { if (CURRENT_TYPE.isModern()) { - return MINIPLAYER_HORIZONTAL_DRAG_ENABLED; + return MINIPLAYER_SIZE; } return original; @@ -304,14 +324,23 @@ public static boolean setHorizontalDrag(boolean original) { /** * Injection point. */ - public static void hideMiniplayerExpandClose(ImageView view) { - Utils.hideViewByRemovingFromParentUnderCondition(HIDE_EXPAND_CLOSE_ENABLED, view); + public static void hideMiniplayerExpandClose(View view) { + Utils.hideViewByRemovingFromParentUnderCondition(HIDE_OVERLAY_BUTTONS_ENABLED, view); + } + + /** + * Injection point. + */ + public static void hideMiniplayerActionButton(View view) { + if (CURRENT_TYPE == MODERN_4) { + Utils.hideViewByRemovingFromParentUnderCondition(HIDE_OVERLAY_BUTTONS_ENABLED, view); + } } /** * Injection point. */ - public static void hideMiniplayerRewindForward(ImageView view) { + public static void hideMiniplayerRewindForward(View view) { Utils.hideViewByRemovingFromParentUnderCondition(HIDE_REWIND_FORWARD_ENABLED, view); } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/OpenShortsInRegularPlayerPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/OpenShortsInRegularPlayerPatch.java index abe3b0cfd7..596675974b 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/OpenShortsInRegularPlayerPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/OpenShortsInRegularPlayerPatch.java @@ -20,15 +20,6 @@ public enum ShortsPlayerType { REGULAR_PLAYER_FULLSCREEN } - static { - if (!VersionCheckPatch.IS_19_46_OR_GREATER - && Settings.SHORTS_PLAYER_TYPE.get() == ShortsPlayerType.REGULAR_PLAYER_FULLSCREEN) { - // User imported newer settings to an older app target. - Logger.printInfo(() -> "Resetting " + Settings.SHORTS_PLAYER_TYPE); - Settings.SHORTS_PLAYER_TYPE.resetToDefault(); - } - } - private static WeakReference mainActivityRef = new WeakReference<>(null); /** diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/OpenVideosFullscreenHookPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/OpenVideosFullscreenHookPatch.java index 62f9bbff9c..9a7989d9a1 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/OpenVideosFullscreenHookPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/OpenVideosFullscreenHookPatch.java @@ -24,18 +24,20 @@ private static boolean isFullScreenPatchIncluded() { /** * Injection point. + * + * Returns negated value. */ - public static boolean openVideoFullscreenPortrait(boolean original) { + public static boolean doNotOpenVideoFullscreenPortrait(boolean original) { Boolean openFullscreen = openNextVideoFullscreen; if (openFullscreen != null) { openNextVideoFullscreen = null; - return openFullscreen; + return !openFullscreen; } if (!isFullScreenPatchIncluded()) { - return false; + return original; } - return Settings.OPEN_VIDEOS_FULLSCREEN_PORTRAIT.get(); + return !Settings.OPEN_VIDEOS_FULLSCREEN_PORTRAIT.get(); } } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/VersionCheckPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/VersionCheckPatch.java index c825b88d3d..74f082bf4c 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/VersionCheckPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/VersionCheckPatch.java @@ -9,5 +9,4 @@ public class VersionCheckPatch { public static final boolean IS_19_26_OR_GREATER = Utils.getAppVersionName().compareTo("19.26.00") >= 0; public static final boolean IS_19_29_OR_GREATER = Utils.getAppVersionName().compareTo("19.29.00") >= 0; public static final boolean IS_19_34_OR_GREATER = Utils.getAppVersionName().compareTo("19.34.00") >= 0; - public static final boolean IS_19_46_OR_GREATER = Utils.getAppVersionName().compareTo("19.46.00") >= 0; } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ShortsFilter.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ShortsFilter.java index 3a57fb8361..b7495e5e43 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ShortsFilter.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ShortsFilter.java @@ -373,17 +373,6 @@ private static boolean shouldHideShortsFeedItems() { }; } - /** - * Injection point. Only used if patching older than 19.03. - * This hook may be obsolete even for old versions - * as they now use a litho layout like newer versions. - */ - public static void hideShortsShelf(final View shortsShelfView) { - if (shouldHideShortsFeedItems()) { - Utils.hideViewByLayoutParams(shortsShelfView); - } - } - public static int getSoundButtonSize(int original) { if (Settings.HIDE_SHORTS_SOUND_BUTTON.get()) { return 0; 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 5ba20c7581..69c5b47340 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 @@ -11,7 +11,7 @@ import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.StartPage; import static app.revanced.extension.youtube.patches.ExitFullscreenPatch.FullscreenMode; import static app.revanced.extension.youtube.patches.ForceOriginalAudioPatch.ForceOriginalAudioAvailability; -import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHideExpandCloseAvailability; +import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHideOverlayButtonsAvailability; import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHorizontalDragAvailability; import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType; import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MINIMAL; @@ -156,8 +156,8 @@ public class Settings extends BaseSettings { public static final BooleanSetting MINIPLAYER_DOUBLE_TAP_ACTION = new BooleanSetting("revanced_miniplayer_double_tap_action", TRUE, true, MINIPLAYER_ANY_MODERN); public static final BooleanSetting MINIPLAYER_DRAG_AND_DROP = new BooleanSetting("revanced_miniplayer_drag_and_drop", TRUE, true, MINIPLAYER_ANY_MODERN); public static final BooleanSetting MINIPLAYER_HORIZONTAL_DRAG = new BooleanSetting("revanced_miniplayer_horizontal_drag", FALSE, true, new MiniplayerHorizontalDragAvailability()); - public static final BooleanSetting MINIPLAYER_HIDE_EXPAND_CLOSE = new BooleanSetting("revanced_miniplayer_hide_expand_close", FALSE, true, new MiniplayerHideExpandCloseAvailability()); - public static final BooleanSetting MINIPLAYER_HIDE_SUBTEXT = new BooleanSetting("revanced_miniplayer_hide_subtext", FALSE, true, MINIPLAYER_TYPE.availability(MODERN_1, MODERN_3)); + public static final BooleanSetting MINIPLAYER_HIDE_OVERLAY_BUTTONS = new BooleanSetting("revanced_miniplayer_hide_overlay_buttons", FALSE, true, new MiniplayerHideOverlayButtonsAvailability()); + public static final BooleanSetting MINIPLAYER_HIDE_SUBTEXT = new BooleanSetting("revanced_miniplayer_hide_subtext", FALSE, true, MINIPLAYER_TYPE.availability(MODERN_1, MODERN_3, MODERN_4)); public static final BooleanSetting MINIPLAYER_HIDE_REWIND_FORWARD = new BooleanSetting("revanced_miniplayer_hide_rewind_forward", TRUE, true, MINIPLAYER_TYPE.availability(MODERN_1)); public static final BooleanSetting MINIPLAYER_ROUNDED_CORNERS = new BooleanSetting("revanced_miniplayer_rounded_corners", TRUE, true, MINIPLAYER_ANY_MODERN); public static final IntegerSetting MINIPLAYER_WIDTH_DIP = new IntegerSetting("revanced_miniplayer_width_dip", 192, true, MINIPLAYER_ANY_MODERN); diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8588ab0f67..d9604e2892 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,8 +1,8 @@ [versions] -revanced-patcher = "21.0.0" +revanced-patcher = "22.0.0" # Tracking https://github.com/google/smali/issues/64. #noinspection GradleDependency -smali = "3.0.5" +smali = "3.0.8" # 8.3.0 causes java verifier error: https://github.com/ReVanced/revanced-patches/issues/2818. #noinspection GradleDependency agp = "8.2.2" diff --git a/patches/api/patches.api b/patches/api/patches.api index ce8c2f0a9c..15a571e0a6 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -56,10 +56,6 @@ public final class app/revanced/patches/all/misc/debugging/EnableAndroidDebuggin public static final fun getEnableAndroidDebuggingPatch ()Lapp/revanced/patcher/patch/ResourcePatch; } -public final class app/revanced/patches/all/misc/directory/ChangeDataDirectoryLocationPatchKt { - public static final fun getChangeDataDirectoryLocationPatch ()Lapp/revanced/patcher/patch/BytecodePatch; -} - public final class app/revanced/patches/all/misc/directory/documentsprovider/ExportInternalDataDocumentsProviderPatchKt { public static final fun getExportInternalDataDocumentsProviderPatch ()Lapp/revanced/patcher/patch/ResourcePatch; } @@ -288,10 +284,6 @@ public final class app/revanced/patches/music/interaction/permanentrepeat/Perman public static final fun getPermanentRepeatPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } -public final class app/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatchKt { - public static final fun getPermanentShufflePatch ()Lapp/revanced/patcher/patch/BytecodePatch; -} - public final class app/revanced/patches/music/layout/compactheader/HideCategoryBarKt { public static final fun getHideCategoryBar ()Lapp/revanced/patcher/patch/BytecodePatch; } @@ -348,10 +340,6 @@ public final class app/revanced/patches/nfctoolsse/misc/pro/UnlockProPatchKt { public static final fun getUnlockProPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } -public final class app/revanced/patches/nyx/misc/pro/UnlockProPatchKt { - public static final fun getUnlockProPatch ()Lapp/revanced/patcher/patch/BytecodePatch; -} - public final class app/revanced/patches/openinghours/misc/fix/crash/FixCrashPatchKt { public static final fun getFixCrashPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } @@ -515,10 +503,6 @@ public final class app/revanced/patches/reddit/customclients/sync/syncforreddit/ public static final fun getFixVideoDownloadsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } -public final class app/revanced/patches/reddit/customclients/syncforreddit/fix/video/FixVideoDownloadsPatchKt { - public static final fun getFixVideoDownloadsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; -} - public final class app/revanced/patches/reddit/layout/disablescreenshotpopup/DisableScreenshotPopupPatchKt { public static final fun getDisableScreenshotPopupPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } @@ -558,10 +542,6 @@ public final class app/revanced/patches/shared/misc/fix/verticalscroll/VerticalS public static final fun getVerticalScrollPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } -public final class app/revanced/patches/shared/misc/gms/FingerprintsKt { - public static final field GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME Ljava/lang/String; -} - public final class app/revanced/patches/shared/misc/gms/GmsCoreSupportPatchKt { public static final fun gmsCoreSupportPatch (Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patcher/Fingerprint;Ljava/util/Set;Lapp/revanced/patcher/Fingerprint;Lapp/revanced/patcher/patch/Patch;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/BytecodePatch; public static synthetic fun gmsCoreSupportPatch$default (Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patcher/Fingerprint;Ljava/util/Set;Lapp/revanced/patcher/Fingerprint;Lapp/revanced/patcher/patch/Patch;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/BytecodePatch; @@ -583,6 +563,7 @@ public final class app/revanced/patches/shared/misc/hex/Replacement$Companion { } public final class app/revanced/patches/shared/misc/mapping/ResourceElement { + public fun (Ljava/lang/String;Ljava/lang/String;J)V public final fun component1 ()Ljava/lang/String; public final fun component2 ()Ljava/lang/String; public final fun component3 ()J @@ -597,14 +578,16 @@ public final class app/revanced/patches/shared/misc/mapping/ResourceElement { } public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatchKt { - public static final fun get (Ljava/util/List;Ljava/lang/String;Ljava/lang/String;)J + public static final fun getResourceElements ()Ljava/util/Collection; + public static final fun getResourceId (Ljava/lang/String;Ljava/lang/String;)J public static final fun getResourceMappingPatch ()Lapp/revanced/patcher/patch/ResourcePatch; - public static final fun getResourceMappings ()Ljava/util/List; + public static final fun hasResourceId (Ljava/lang/String;Ljava/lang/String;)Z + public static final fun resourceLiteral (Ljava/lang/String;Ljava/lang/String;I)Lapp/revanced/patcher/LiteralFilter; + public static synthetic fun resourceLiteral$default (Ljava/lang/String;Ljava/lang/String;IILjava/lang/Object;)Lapp/revanced/patcher/LiteralFilter; } public final class app/revanced/patches/shared/misc/settings/SettingsPatchKt { public static final fun settingsPatch (Ljava/util/List;Ljava/util/Set;)Lapp/revanced/patcher/patch/ResourcePatch; - public static final fun settingsPatch (Lkotlin/Pair;Ljava/util/Set;)Lapp/revanced/patcher/patch/ResourcePatch; public static synthetic fun settingsPatch$default (Ljava/util/List;Ljava/util/Set;ILjava/lang/Object;)Lapp/revanced/patcher/patch/ResourcePatch; } @@ -1024,10 +1007,6 @@ public final class app/revanced/patches/twitter/misc/links/SanitizeSharingLinksP public static final fun getSanitizeSharingLinksPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } -public final class app/revanced/patches/vsco/misc/pro/UnlockProPatchKt { - public static final fun getUnlockProPatch ()Lapp/revanced/patcher/patch/BytecodePatch; -} - public final class app/revanced/patches/warnwetter/misc/firebasegetcert/FirebaseGetCertPatchKt { public static final fun getFirebaseGetCertPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } @@ -1036,10 +1015,6 @@ public final class app/revanced/patches/warnwetter/misc/promocode/PromoCodeUnloc public static final fun getPromoCodeUnlockPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } -public final class app/revanced/patches/windyapp/misc/unlockpro/UnlockProPatchKt { - public static final fun getUnlockProPatch ()Lapp/revanced/patcher/patch/BytecodePatch; -} - public final class app/revanced/patches/youtube/ad/general/HideAdsPatchKt { public static final fun getHideAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } @@ -1121,15 +1096,7 @@ public final class app/revanced/patches/youtube/layout/hide/fullscreenambientmod } public final class app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatchKt { - public static final fun getAlbumCardId ()J - public static final fun getBarContainerHeightId ()J - public static final fun getCrowdfundingBoxId ()J - public static final fun getExpandButtonDownId ()J - public static final fun getFabButtonId ()J - public static final fun getFilterBarHeightId ()J public static final fun getHideLayoutComponentsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; - public static final fun getRelatedChipCloudMarginId ()J - public static final fun getYouTubeLogo ()J } public final class app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatchKt { @@ -1161,17 +1128,7 @@ public final class app/revanced/patches/youtube/layout/hide/time/HideTimestampPa } public final class app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatchKt { - public static final fun getFloatyBarButtonTopMargin ()J - public static final fun getMiniplayerMaxSize ()J public static final fun getMiniplayerPatch ()Lapp/revanced/patcher/patch/BytecodePatch; - public static final fun getModernMiniplayerClose ()J - public static final fun getModernMiniplayerExpand ()J - public static final fun getModernMiniplayerForwardButton ()J - public static final fun getModernMiniplayerRewindButton ()J - public static final fun getPlayerOverlays ()J - public static final fun getScrimOverlay ()J - public static final fun getYtOutlinePictureInPictureWhite24 ()J - public static final fun getYtOutlineXWhite24 ()J } public final class app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatchKt { @@ -1182,10 +1139,6 @@ public final class app/revanced/patches/youtube/layout/player/background/PlayerC public static final fun getPlayerControlsBackgroundPatch ()Lapp/revanced/patcher/patch/ResourcePatch; } -public final class app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenKt { - public static final fun getOpenVideosFullscreen ()Lapp/revanced/patcher/patch/BytecodePatch; -} - public final class app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenPatchKt { public static final fun getOpenVideosFullscreenPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } @@ -1240,10 +1193,6 @@ public final class app/revanced/patches/youtube/layout/startupshortsreset/Disabl public static final fun getDisableResumingShortsOnStartupPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } -public final class app/revanced/patches/youtube/layout/tablet/EnableTabletLayoutPatchKt { - public static final fun getEnableTabletLayoutPatch ()Lapp/revanced/patcher/patch/BytecodePatch; -} - public final class app/revanced/patches/youtube/layout/theme/LithoColorHookPatchKt { public static final fun getLithoColorHookPatch ()Lapp/revanced/patcher/patch/BytecodePatch; public static final fun getLithoColorOverrideHook ()Lkotlin/jvm/functions/Function2; @@ -1289,14 +1238,6 @@ public final class app/revanced/patches/youtube/misc/extension/SharedExtensionPa public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } -public final class app/revanced/patches/youtube/misc/fix/playback/SpoofVideoStreamsPatchKt { - public static final fun getSpoofVideoStreamsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; -} - -public final class app/revanced/patches/youtube/misc/fix/playback/UserAgentClientSpoofPatchKt { - public static final fun getUserAgentClientSpoofPatch ()Lapp/revanced/patcher/patch/BytecodePatch; -} - public final class app/revanced/patches/youtube/misc/fix/playbackspeed/FIxPlaybackSpeedWhilePlayingPatchKt { public static final fun getFixPlaybackSpeedWhilePlayingPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } @@ -1347,9 +1288,6 @@ public final class app/revanced/patches/youtube/misc/playertype/PlayerTypeHookPa public final class app/revanced/patches/youtube/misc/playservice/VersionCheckPatchKt { public static final fun getVersionCheckPatch ()Lapp/revanced/patcher/patch/ResourcePatch; - public static final fun is_19_03_or_greater ()Z - public static final fun is_19_04_or_greater ()Z - public static final fun is_19_16_or_greater ()Z public static final fun is_19_17_or_greater ()Z public static final fun is_19_18_or_greater ()Z public static final fun is_19_23_or_greater ()Z @@ -1366,6 +1304,9 @@ public final class app/revanced/patches/youtube/misc/playservice/VersionCheckPat public static final fun is_19_46_or_greater ()Z public static final fun is_19_47_or_greater ()Z public static final fun is_19_49_or_greater ()Z + public static final fun is_20_02_or_greater ()Z + public static final fun is_20_03_or_greater ()Z + public static final fun is_20_05_or_greater ()Z } public final class app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatchKt { @@ -1502,7 +1443,11 @@ public final class app/revanced/util/BytecodeUtilsKt { public static final fun indexOfFirstInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;)I public static synthetic fun indexOfFirstInstructionReversedOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;ILjava/lang/Object;)I public static synthetic fun indexOfFirstInstructionReversedOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)I + public static final fun indexOfFirstLiteralInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;D)I + public static final fun indexOfFirstLiteralInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;F)I public static final fun indexOfFirstLiteralInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;J)I + public static final fun indexOfFirstLiteralInstructionOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;D)I + public static final fun indexOfFirstLiteralInstructionOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;F)I public static final fun indexOfFirstLiteralInstructionOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;J)I public static final fun indexOfFirstLiteralInstructionReversed (Lcom/android/tools/smali/dexlib2/iface/Method;J)I public static final fun indexOfFirstLiteralInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;J)I diff --git a/patches/build.gradle.kts b/patches/build.gradle.kts index eecadbd25c..a04cb5b16f 100644 --- a/patches/build.gradle.kts +++ b/patches/build.gradle.kts @@ -12,6 +12,12 @@ patches { } } +repositories { + mavenLocal() + gradlePluginPortal() + google() +} + dependencies { // Required due to smali, or build fails. Can be removed once smali is bumped. implementation(libs.guava) diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/directory/ChangeDataDirectoryLocationPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/directory/ChangeDataDirectoryLocationPatch.kt deleted file mode 100644 index 8046c11fc3..0000000000 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/directory/ChangeDataDirectoryLocationPatch.kt +++ /dev/null @@ -1,19 +0,0 @@ -package app.revanced.patches.all.misc.directory - -import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patches.all.misc.directory.documentsprovider.exportInternalDataDocumentsProviderPatch - -@Suppress("unused") -@Deprecated( - "Superseded by internalDataDocumentsProviderPatch", - ReplaceWith("internalDataDocumentsProviderPatch"), -) -val changeDataDirectoryLocationPatch = bytecodePatch( - // name = "Change data directory location", - description = "Changes the data directory in the application from " + - "the app internal storage directory to /sdcard/android/data accessible by root-less devices." + - "Using this patch can cause unexpected issues with some apps.", - use = false, -) { - dependsOn(exportInternalDataDocumentsProviderPatch) -} diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/transformation/TransformInstructionsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/transformation/TransformInstructionsPatch.kt index 6564f4f26a..8e694f103a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/transformation/TransformInstructionsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/transformation/TransformInstructionsPatch.kt @@ -36,7 +36,7 @@ fun transformInstructionsPatch( } }.forEach { (classDef, methods) -> // And finally transform the methods... - val mutableClass = proxy(classDef).mutableClass + val mutableClass = mutableClassBy(classDef) methods.map(mutableClass::findMutableMethodOf).forEach methods@{ mutableMethod -> val patchIndices = findPatchIndices(mutableClass, mutableMethod)?.toCollection(ArrayDeque()) diff --git a/patches/src/main/kotlin/app/revanced/patches/amazon/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/amazon/Fingerprints.kt index 1339149f43..35d31a5f9e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/amazon/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/amazon/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.amazon import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val deepLinkingFingerprint = fingerprint { +internal val deepLinkingFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE) returns("Z") parameters("L") diff --git a/patches/src/main/kotlin/app/revanced/patches/backdrops/misc/pro/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/backdrops/misc/pro/Fingerprints.kt index bbe71e8c78..1b42a34033 100644 --- a/patches/src/main/kotlin/app/revanced/patches/backdrops/misc/pro/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/backdrops/misc/pro/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.backdrops.misc.pro import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.Opcode -internal val proUnlockFingerprint = fingerprint { +internal val proUnlockFingerprint by fingerprint { opcodes( Opcode.INVOKE_VIRTUAL, Opcode.MOVE_RESULT_OBJECT, diff --git a/patches/src/main/kotlin/app/revanced/patches/backdrops/misc/pro/ProUnlockPatch.kt b/patches/src/main/kotlin/app/revanced/patches/backdrops/misc/pro/ProUnlockPatch.kt index 70bbcd9fdf..19dda8b166 100644 --- a/patches/src/main/kotlin/app/revanced/patches/backdrops/misc/pro/ProUnlockPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/backdrops/misc/pro/ProUnlockPatch.kt @@ -12,12 +12,12 @@ val proUnlockPatch = bytecodePatch( compatibleWith("com.backdrops.wallpapers") execute { - val registerIndex = proUnlockFingerprint.patternMatch!!.endIndex - 1 + val registerIndex = proUnlockFingerprint.instructionMatches.last().index - 1 proUnlockFingerprint.method.apply { val register = getInstruction(registerIndex).registerA addInstruction( - proUnlockFingerprint.patternMatch!!.endIndex, + proUnlockFingerprint.instructionMatches.last().index, "const/4 v$register, 0x1", ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/bandcamp/limitations/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/bandcamp/limitations/Fingerprints.kt index 96bbab5ccc..c645943a05 100644 --- a/patches/src/main/kotlin/app/revanced/patches/bandcamp/limitations/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/bandcamp/limitations/Fingerprints.kt @@ -2,6 +2,6 @@ package app.revanced.patches.bandcamp.limitations import app.revanced.patcher.fingerprint -internal val handlePlaybackLimitsFingerprint = fingerprint { +internal val handlePlaybackLimitsFingerprint by fingerprint { strings("play limits processing track", "found play_count") } diff --git a/patches/src/main/kotlin/app/revanced/patches/cieid/restrictions/root/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/cieid/restrictions/root/Fingerprints.kt index 387b0a0be8..6f9c9c2c63 100644 --- a/patches/src/main/kotlin/app/revanced/patches/cieid/restrictions/root/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/cieid/restrictions/root/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.cieid.restrictions.root import app.revanced.patcher.fingerprint -internal val checkRootFingerprint = fingerprint { +internal val checkRootFingerprint by fingerprint { custom { method, _ -> method.name == "onResume" && method.definingClass == "Lit/ipzs/cieid/BaseActivity;" } diff --git a/patches/src/main/kotlin/app/revanced/patches/duolingo/ad/DisableAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/duolingo/ad/DisableAdsPatch.kt index a5c56ddb05..86a236d71d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/duolingo/ad/DisableAdsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/duolingo/ad/DisableAdsPatch.kt @@ -20,7 +20,7 @@ val disableAdsPatch = bytecodePatch( // // MonetizationDebugSettings seems to be the most general setting to work fine. initializeMonetizationDebugSettingsFingerprint.method.apply { - val insertIndex = initializeMonetizationDebugSettingsFingerprint.patternMatch!!.startIndex + val insertIndex = initializeMonetizationDebugSettingsFingerprint.instructionMatches.first().index val register = getInstruction(insertIndex).registerA addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/duolingo/ad/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/duolingo/ad/Fingerprints.kt index 59b0644d98..7a45d8fa5a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/duolingo/ad/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/duolingo/ad/Fingerprints.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val initializeMonetizationDebugSettingsFingerprint = fingerprint { +internal val initializeMonetizationDebugSettingsFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) returns("V") parameters( diff --git a/patches/src/main/kotlin/app/revanced/patches/duolingo/debug/EnableDebugMenuPatch.kt b/patches/src/main/kotlin/app/revanced/patches/duolingo/debug/EnableDebugMenuPatch.kt index 833f9dd7da..715bb80def 100644 --- a/patches/src/main/kotlin/app/revanced/patches/duolingo/debug/EnableDebugMenuPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/duolingo/debug/EnableDebugMenuPatch.kt @@ -14,7 +14,7 @@ val enableDebugMenuPatch = bytecodePatch( execute { initializeBuildConfigProviderFingerprint.method.apply { - val insertIndex = initializeBuildConfigProviderFingerprint.patternMatch!!.startIndex + val insertIndex = initializeBuildConfigProviderFingerprint.instructionMatches.first().index val register = getInstruction(insertIndex).registerA addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/duolingo/debug/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/duolingo/debug/Fingerprints.kt index 543e40b434..b1ec382943 100644 --- a/patches/src/main/kotlin/app/revanced/patches/duolingo/debug/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/duolingo/debug/Fingerprints.kt @@ -11,9 +11,8 @@ import com.android.tools.smali.dexlib2.Opcode * - `isDebug`: compares "release" with "debug" <-- we want to force this to `true` */ -internal val initializeBuildConfigProviderFingerprint = fingerprint { +internal val initializeBuildConfigProviderFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - returns("V") opcodes(Opcode.IPUT_BOOLEAN) strings("debug", "release", "china") } diff --git a/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/Fingerprints.kt index e84a448baa..396f44ff05 100644 --- a/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/Fingerprints.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val baseModelMapperFingerprint = fingerprint { +internal val baseModelMapperFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Lcom/facebook/graphql/modelutil/BaseModelWithTree;") parameters("Ljava/lang/Class", "I", "I") @@ -17,7 +17,7 @@ internal val baseModelMapperFingerprint = fingerprint { ) } -internal val getSponsoredDataModelTemplateFingerprint = fingerprint { +internal val getSponsoredDataModelTemplateFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("L") parameters() @@ -33,7 +33,7 @@ internal val getSponsoredDataModelTemplateFingerprint = fingerprint { } } -internal val getStoryVisibilityFingerprint = fingerprint { +internal val getStoryVisibilityFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("Ljava/lang/String;") opcodes( diff --git a/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/HideSponsoredStoriesPatch.kt b/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/HideSponsoredStoriesPatch.kt index a5a596d3ee..b2d3d6a2d8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/HideSponsoredStoriesPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/HideSponsoredStoriesPatch.kt @@ -67,7 +67,7 @@ val hideSponsoredStoriesPatch = bytecodePatch( // Check if the parameter type is GraphQLStory and if sponsoredDataModelGetter returns a non-null value. // If so, hide the story by setting the visibility to StoryVisibility.GONE. getStoryVisibilityFingerprint.method.addInstructionsWithLabels( - getStoryVisibilityFingerprint.patternMatch!!.startIndex, + getStoryVisibilityFingerprint.instructionMatches.first().index, """ instance-of v0, p0, $graphQlStoryClassDescriptor if-eqz v0, :resume_normal diff --git a/patches/src/main/kotlin/app/revanced/patches/facebook/ads/story/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/facebook/ads/story/Fingerprints.kt index 293d7ee82f..0a93699f01 100644 --- a/patches/src/main/kotlin/app/revanced/patches/facebook/ads/story/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/facebook/ads/story/Fingerprints.kt @@ -3,11 +3,11 @@ package app.revanced.patches.facebook.ads.story import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.iface.value.StringEncodedValue -internal val adsInsertionFingerprint = fieldFingerprint( +internal val adsInsertionFingerprint by fieldFingerprint( fieldValue = "AdBucketDataSourceUtil\$attemptAdsInsertion\$1", ) -internal val fetchMoreAdsFingerprint = fieldFingerprint( +internal val fetchMoreAdsFingerprint by fieldFingerprint( fieldValue = "AdBucketDataSourceUtil\$attemptFetchMoreAds\$1", ) diff --git a/patches/src/main/kotlin/app/revanced/patches/finanzonline/detection/bootloader/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/finanzonline/detection/bootloader/Fingerprints.kt index 4c8ee1c541..2347d1143d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/finanzonline/detection/bootloader/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/finanzonline/detection/bootloader/Fingerprints.kt @@ -5,7 +5,7 @@ import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint // Located @ at.gv.bmf.bmf2go.taxequalization.tools.utils.AttestationHelper#isBootStateOk (3.0.1) -internal val bootStateFingerprint = fingerprint { +internal val bootStateFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC) returns("Z") opcodes( @@ -30,7 +30,7 @@ internal val bootStateFingerprint = fingerprint { } // Located @ at.gv.bmf.bmf2go.taxequalization.tools.utils.AttestationHelper#createKey (3.0.1) -internal val createKeyFingerprint = fingerprint { +internal val createKeyFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC) returns("Z") strings("attestation", "SHA-256", "random", "EC", "AndroidKeyStore") diff --git a/patches/src/main/kotlin/app/revanced/patches/finanzonline/detection/root/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/finanzonline/detection/root/Fingerprints.kt index fec7f1249f..7460461e43 100644 --- a/patches/src/main/kotlin/app/revanced/patches/finanzonline/detection/root/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/finanzonline/detection/root/Fingerprints.kt @@ -5,7 +5,7 @@ import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint // Located @ at.gv.bmf.bmf2go.taxequalization.tools.utils.RootDetection#isRooted (3.0.1) -internal val rootDetectionFingerprint = fingerprint { +internal val rootDetectionFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("L") parameters("L") diff --git a/patches/src/main/kotlin/app/revanced/patches/googlenews/customtabs/EnableCustomTabsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/googlenews/customtabs/EnableCustomTabsPatch.kt index ee7997a54e..6057630e69 100644 --- a/patches/src/main/kotlin/app/revanced/patches/googlenews/customtabs/EnableCustomTabsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/googlenews/customtabs/EnableCustomTabsPatch.kt @@ -14,7 +14,7 @@ val enableCustomTabsPatch = bytecodePatch( execute { launchCustomTabFingerprint.method.apply { - val checkIndex = launchCustomTabFingerprint.patternMatch!!.endIndex + 1 + val checkIndex = launchCustomTabFingerprint.instructionMatches.last().index + 1 val register = getInstruction(checkIndex).registerA replaceInstruction(checkIndex, "const/4 v$register, 0x1") diff --git a/patches/src/main/kotlin/app/revanced/patches/googlenews/customtabs/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/googlenews/customtabs/Fingerprints.kt index 8880c010e9..387d1cbf61 100644 --- a/patches/src/main/kotlin/app/revanced/patches/googlenews/customtabs/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/googlenews/customtabs/Fingerprints.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val launchCustomTabFingerprint = fingerprint { +internal val launchCustomTabFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) opcodes( Opcode.IPUT_OBJECT, diff --git a/patches/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/Fingerprints.kt index 6ddeb3e07f..e23ac4bc48 100644 --- a/patches/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.googlenews.misc.gms import app.revanced.patcher.fingerprint -internal val magazinesActivityOnCreateFingerprint = fingerprint { +internal val magazinesActivityOnCreateFingerprint by fingerprint { custom { methodDef, classDef -> methodDef.name == "onCreate" && classDef.endsWith("/StartActivity;") } diff --git a/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/features/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/features/Fingerprints.kt index 95f2a3dba7..bd63a4a409 100644 --- a/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/features/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/features/Fingerprints.kt @@ -2,6 +2,6 @@ package app.revanced.patches.googlephotos.misc.features import app.revanced.patcher.fingerprint -internal val initializeFeaturesEnumFingerprint = fingerprint { +internal val initializeFeaturesEnumFingerprint by fingerprint { strings("com.google.android.apps.photos.NEXUS_PRELOAD") } diff --git a/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/gms/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/gms/Fingerprints.kt index f47c1a3d94..cbd720730a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/gms/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/gms/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.googlephotos.misc.gms import app.revanced.patcher.fingerprint -internal val homeActivityOnCreateFingerprint = fingerprint { +internal val homeActivityOnCreateFingerprint by fingerprint { custom { methodDef, classDef -> methodDef.name == "onCreate" && classDef.endsWith("/HomeActivity;") } diff --git a/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/preferences/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/preferences/Fingerprints.kt index 54c20a7f8c..712a352a15 100644 --- a/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/preferences/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/preferences/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.googlephotos.misc.preferences import app.revanced.patcher.fingerprint -internal val backupPreferencesFingerprint = fingerprint { +internal val backupPreferencesFingerprint by fingerprint { returns("Lcom/google/android/apps/photos/backup/data/BackupPreferences;") strings("backup_prefs_had_backup_only_when_charging_enabled") } diff --git a/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/preferences/RestoreHiddenBackUpWhileChargingTogglePatch.kt b/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/preferences/RestoreHiddenBackUpWhileChargingTogglePatch.kt index 04fe297156..c3e892b7fe 100644 --- a/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/preferences/RestoreHiddenBackUpWhileChargingTogglePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/googlephotos/misc/preferences/RestoreHiddenBackUpWhileChargingTogglePatch.kt @@ -14,7 +14,7 @@ val restoreHiddenBackUpWhileChargingTogglePatch = bytecodePatch( execute { // Patches 'backup_prefs_had_backup_only_when_charging_enabled' to always be true. - val chargingPrefStringIndex = backupPreferencesFingerprint.stringMatches!!.first().index + val chargingPrefStringIndex = backupPreferencesFingerprint.stringMatches.first().index backupPreferencesFingerprint.method.apply { // Get the register of move-result. val resultRegister = getInstruction(chargingPrefStringIndex + 2).registerA diff --git a/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/Fingerprints.kt index 62e1e5f16b..431ea6c26c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.googlerecorder.restrictions import app.revanced.patcher.fingerprint -internal val onApplicationCreateFingerprint = fingerprint { +internal val onApplicationCreateFingerprint by fingerprint { strings("com.google.android.feature.PIXEL_2017_EXPERIENCE") custom { method, classDef -> if (method.name != "onCreate") return@custom false diff --git a/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/RemoveDeviceRestrictions.kt b/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/RemoveDeviceRestrictions.kt index bd6921bfb0..6aec4c6000 100644 --- a/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/RemoveDeviceRestrictions.kt +++ b/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/RemoveDeviceRestrictions.kt @@ -14,7 +14,7 @@ val removeDeviceRestrictionsPatch = bytecodePatch( compatibleWith("com.google.android.apps.recorder") execute { - val featureStringIndex = onApplicationCreateFingerprint.stringMatches!!.first().index + val featureStringIndex = onApplicationCreateFingerprint.stringMatches.first().index onApplicationCreateFingerprint.method.apply { // Remove check for device restrictions. diff --git a/patches/src/main/kotlin/app/revanced/patches/hexeditor/ad/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/hexeditor/ad/Fingerprints.kt index 2fa2c5b851..bed5ce6300 100644 --- a/patches/src/main/kotlin/app/revanced/patches/hexeditor/ad/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/hexeditor/ad/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.hexeditor.ad import app.revanced.patcher.fingerprint -internal val primaryAdsFingerprint = fingerprint { +internal val primaryAdsFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("PreferencesHelper;") && method.name == "isAdsDisabled" } diff --git a/patches/src/main/kotlin/app/revanced/patches/iconpackstudio/misc/pro/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/iconpackstudio/misc/pro/Fingerprints.kt index 84db554572..fe15366f40 100644 --- a/patches/src/main/kotlin/app/revanced/patches/iconpackstudio/misc/pro/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/iconpackstudio/misc/pro/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.iconpackstudio.misc.pro import app.revanced.patcher.fingerprint -internal val checkProFingerprint = fingerprint { +internal val checkProFingerprint by fingerprint { returns("Z") custom { _, classDef -> classDef.endsWith("IPSPurchaseRepository;") } } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/idaustria/detection/root/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/idaustria/detection/root/Fingerprints.kt index 38f814f6d4..48c0f31ff1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/idaustria/detection/root/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/idaustria/detection/root/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.idaustria.detection.root import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val attestationSupportedCheckFingerprint = fingerprint { +internal val attestationSupportedCheckFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC) returns("V") custom { method, classDef -> @@ -12,7 +12,7 @@ internal val attestationSupportedCheckFingerprint = fingerprint { } } -internal val bootloaderCheckFingerprint = fingerprint { +internal val bootloaderCheckFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC) returns("Z") custom { method, classDef -> @@ -21,7 +21,7 @@ internal val bootloaderCheckFingerprint = fingerprint { } } -internal val rootCheckFingerprint = fingerprint { +internal val rootCheckFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC) returns("V") custom { method, classDef -> diff --git a/patches/src/main/kotlin/app/revanced/patches/idaustria/detection/signature/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/idaustria/detection/signature/Fingerprints.kt index 61cd9605f1..23e2a12edd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/idaustria/detection/signature/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/idaustria/detection/signature/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.idaustria.detection.signature import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val spoofSignatureFingerprint = fingerprint { +internal val spoofSignatureFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE) returns("L") parameters("L") diff --git a/patches/src/main/kotlin/app/revanced/patches/inshorts/ad/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/inshorts/ad/Fingerprints.kt index 573bd72e35..151718de57 100644 --- a/patches/src/main/kotlin/app/revanced/patches/inshorts/ad/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/inshorts/ad/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.inshorts.ad import app.revanced.patcher.fingerprint -internal val inshortsAdsFingerprint = fingerprint { +internal val inshortsAdsFingerprint by fingerprint { returns("V") strings("GoogleAdLoader", "exception in requestAd") } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/ads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/ads/Fingerprints.kt index 65d0527297..1bd1777e82 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/ads/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/ads/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.instagram.ads import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val adInjectorFingerprint = fingerprint { +internal val adInjectorFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE) returns("Z") parameters("L", "L") diff --git a/patches/src/main/kotlin/app/revanced/patches/irplus/ad/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/irplus/ad/Fingerprints.kt index 30242b8d94..431bbd99a2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/irplus/ad/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/irplus/ad/Fingerprints.kt @@ -3,9 +3,8 @@ package app.revanced.patches.irplus.ad import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val irplusAdsFingerprint = fingerprint { +internal val irplusAdsFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - returns("V") parameters("L", "Z") strings("TAGGED") } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/lightroom/misc/login/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/lightroom/misc/login/Fingerprints.kt index 6345541e14..aefb36de6f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/lightroom/misc/login/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/lightroom/misc/login/Fingerprints.kt @@ -4,7 +4,7 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val isLoggedInFingerprint = fingerprint { +internal val isLoggedInFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC, AccessFlags.FINAL) returns("Z") opcodes( diff --git a/patches/src/main/kotlin/app/revanced/patches/lightroom/misc/premium/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/lightroom/misc/premium/Fingerprints.kt index 5a00dc68c1..3d001bb99f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/lightroom/misc/premium/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/lightroom/misc/premium/Fingerprints.kt @@ -4,7 +4,7 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val hasPurchasedFingerprint = fingerprint { +internal val hasPurchasedFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL) returns("Z") opcodes( diff --git a/patches/src/main/kotlin/app/revanced/patches/memegenerator/detection/license/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/memegenerator/detection/license/Fingerprints.kt index 0dfbf5cdab..3914e00b12 100644 --- a/patches/src/main/kotlin/app/revanced/patches/memegenerator/detection/license/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/memegenerator/detection/license/Fingerprints.kt @@ -4,7 +4,7 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val licenseValidationFingerprint = fingerprint { +internal val licenseValidationFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("Z") parameters("Landroid/content/Context;") diff --git a/patches/src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/Fingerprints.kt index 75912318ba..396e7267d4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/Fingerprints.kt @@ -4,7 +4,7 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val verifySignatureFingerprint = fingerprint(fuzzyPatternScanThreshold = 2) { +internal val verifySignatureFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("Z") parameters("Landroid/app/Activity;") diff --git a/patches/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/Fingerprints.kt index 1f16bb10ec..f6faf995af 100644 --- a/patches/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/Fingerprints.kt @@ -4,7 +4,7 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val isFreeVersionFingerprint = fingerprint { +internal val isFreeVersionFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("Ljava/lang/Boolean;") parameters("Landroid/content/Context;") diff --git a/patches/src/main/kotlin/app/revanced/patches/messenger/inbox/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/messenger/inbox/Fingerprints.kt index a2fa6329c1..814922824b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/messenger/inbox/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/messenger/inbox/Fingerprints.kt @@ -5,7 +5,7 @@ import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.value.StringEncodedValue -internal val createInboxSubTabsFingerprint = fingerprint { +internal val createInboxSubTabsFingerprint by fingerprint { returns("V") accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) opcodes( @@ -22,7 +22,7 @@ internal val createInboxSubTabsFingerprint = fingerprint { } } -internal val loadInboxAdsFingerprint = fingerprint { +internal val loadInboxAdsFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("V") strings( diff --git a/patches/src/main/kotlin/app/revanced/patches/messenger/inputfield/DisableSwitchingEmojiToStickerPatch.kt b/patches/src/main/kotlin/app/revanced/patches/messenger/inputfield/DisableSwitchingEmojiToStickerPatch.kt index 19f5c12515..417e49d596 100644 --- a/patches/src/main/kotlin/app/revanced/patches/messenger/inputfield/DisableSwitchingEmojiToStickerPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/messenger/inputfield/DisableSwitchingEmojiToStickerPatch.kt @@ -14,7 +14,7 @@ val disableSwitchingEmojiToStickerPatch = bytecodePatch( execute { switchMessengeInputEmojiButtonFingerprint.method.apply { - val setStringIndex = switchMessengeInputEmojiButtonFingerprint.patternMatch!!.startIndex + 2 + val setStringIndex = switchMessengeInputEmojiButtonFingerprint.instructionMatches.first().index + 2 val targetRegister = getInstruction(setStringIndex).registerA replaceInstruction(setStringIndex, "const-string v$targetRegister, \"expression\"") diff --git a/patches/src/main/kotlin/app/revanced/patches/messenger/inputfield/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/messenger/inputfield/Fingerprints.kt index 75fd54f7da..a2ca3c0597 100644 --- a/patches/src/main/kotlin/app/revanced/patches/messenger/inputfield/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/messenger/inputfield/Fingerprints.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.dexbacked.value.DexBackedStringEncodedValue -internal val sendTypingIndicatorFingerprint = fingerprint { +internal val sendTypingIndicatorFingerprint by fingerprint { returns("V") parameters() custom { method, classDef -> @@ -16,7 +16,7 @@ internal val sendTypingIndicatorFingerprint = fingerprint { } } -internal val switchMessengeInputEmojiButtonFingerprint = fingerprint { +internal val switchMessengeInputEmojiButtonFingerprint by fingerprint { returns("V") parameters("L", "Z") opcodes( diff --git a/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/Fingerprints.kt index 14105f762a..021e320fcb 100644 --- a/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.mifitness.misc.locale import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.Opcode -internal val syncBluetoothLanguageFingerprint = fingerprint { +internal val syncBluetoothLanguageFingerprint by fingerprint { opcodes(Opcode.MOVE_RESULT_OBJECT) custom { method, _ -> method.name == "syncBluetoothLanguage" && diff --git a/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch.kt b/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch.kt index a2a53cabaf..676df651e0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch.kt @@ -17,7 +17,7 @@ val forceEnglishLocalePatch = bytecodePatch( execute { syncBluetoothLanguageFingerprint.method.apply { - val resolvePhoneLocaleInstruction = syncBluetoothLanguageFingerprint.patternMatch!!.startIndex + val resolvePhoneLocaleInstruction = syncBluetoothLanguageFingerprint.instructionMatches.first().index val registerIndexToUpdate = getInstruction(resolvePhoneLocaleInstruction).registerA replaceInstruction( diff --git a/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/login/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/login/Fingerprints.kt index e3eee24991..d3083e8fb9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/login/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/login/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.mifitness.misc.login import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val xiaomiAccountManagerConstructorFingerprint = fingerprint { +internal val xiaomiAccountManagerConstructorFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.CONSTRUCTOR) parameters("Landroid/content/Context;", "Z") custom { method, _ -> diff --git a/patches/src/main/kotlin/app/revanced/patches/music/ad/video/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/ad/video/Fingerprints.kt index 6ce0519ada..202a2d8897 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/ad/video/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/ad/video/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.music.ad.video import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.Opcode -internal val showVideoAdsParentFingerprint = fingerprint { +internal val showVideoAdsParentFingerprint by fingerprint { opcodes( Opcode.MOVE_RESULT_OBJECT, Opcode.INVOKE_VIRTUAL, diff --git a/patches/src/main/kotlin/app/revanced/patches/music/ad/video/HideVideoAds.kt b/patches/src/main/kotlin/app/revanced/patches/music/ad/video/HideVideoAds.kt index ed4b0ead28..4a7930188f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/ad/video/HideVideoAds.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/ad/video/HideVideoAds.kt @@ -17,7 +17,7 @@ val hideVideoAdsPatch = bytecodePatch( execute { navigate(showVideoAdsParentFingerprint.originalMethod) - .to(showVideoAdsParentFingerprint.patternMatch!!.startIndex + 1) + .to(showVideoAdsParentFingerprint.instructionMatches.first().index + 1) .stop() .addInstruction(0, "const/4 p1, 0x0") } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/Fingerprints.kt index 4ac10dd9bd..0883a218f2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/Fingerprints.kt @@ -4,7 +4,7 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val allowExclusiveAudioPlaybackFingerprint = fingerprint { +internal val allowExclusiveAudioPlaybackFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") parameters() diff --git a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/Fingerprints.kt index 13820d29d8..4ede1cadc3 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/Fingerprints.kt @@ -4,7 +4,7 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val repeatTrackFingerprint = fingerprint { +internal val repeatTrackFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L", "L") diff --git a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/PermanentRepeatPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/PermanentRepeatPatch.kt index 89178d6aea..dd4dd3ae21 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/PermanentRepeatPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/PermanentRepeatPatch.kt @@ -19,7 +19,7 @@ val permanentRepeatPatch = bytecodePatch( ) execute { - val startIndex = repeatTrackFingerprint.patternMatch!!.endIndex + val startIndex = repeatTrackFingerprint.instructionMatches.last().index val repeatIndex = startIndex + 1 repeatTrackFingerprint.method.apply { diff --git a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentshuffle/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentshuffle/Fingerprints.kt deleted file mode 100644 index f2169744fe..0000000000 --- a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentshuffle/Fingerprints.kt +++ /dev/null @@ -1,19 +0,0 @@ -package app.revanced.patches.music.interaction.permanentshuffle - -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.AccessFlags -import app.revanced.patcher.fingerprint - -internal val disableShuffleFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("V") - parameters() - opcodes( - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL - ) -} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch.kt deleted file mode 100644 index e27749495b..0000000000 --- a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch.kt +++ /dev/null @@ -1,26 +0,0 @@ -package app.revanced.patches.music.interaction.permanentshuffle - -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.patch.bytecodePatch - -@Deprecated("This patch no longer works and will be removed in the future.") -@Suppress("unused") -val permanentShufflePatch = bytecodePatch( - description = "Permanently remember your shuffle preference " + - "even if the playlist ends or another track is played.", - use = false, -) { - compatibleWith( - "com.google.android.apps.youtube.music"( - "6.45.54", - "6.51.53", - "7.01.53", - "7.02.52", - "7.03.52", - ), - ) - - execute { - disableShuffleFingerprint.method.addInstruction(0, "return-void") - } -} diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/Fingerprints.kt index 234078c2a6..2cefcc63ce 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/Fingerprints.kt @@ -4,9 +4,8 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val constructCategoryBarFingerprint = fingerprint { +internal val constructCategoryBarFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - returns("V") parameters("Landroid/content/Context;", "L", "L", "L") opcodes( Opcode.IPUT_OBJECT, diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt index 8c5ed8139c..626683376f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt @@ -20,7 +20,7 @@ val hideCategoryBar = bytecodePatch( execute { constructCategoryBarFingerprint.method.apply { - val insertIndex = constructCategoryBarFingerprint.patternMatch!!.startIndex + val insertIndex = constructCategoryBarFingerprint.instructionMatches.first().index val register = getInstruction(insertIndex - 1).registerA addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/Fingerprints.kt index 29558ab4be..42dbc6bcbe 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/Fingerprints.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val hideGetPremiumFingerprint = fingerprint { +internal val hideGetPremiumFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters() @@ -16,7 +16,7 @@ internal val hideGetPremiumFingerprint = fingerprint { strings("FEmusic_history", "FEmusic_offline") } -internal val membershipSettingsFingerprint = fingerprint { +internal val membershipSettingsFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Ljava/lang/CharSequence;") opcodes( diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt index e45a90426f..380197e3c1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt @@ -20,7 +20,7 @@ val hideGetPremiumPatch = bytecodePatch( execute { hideGetPremiumFingerprint.method.apply { - val insertIndex = hideGetPremiumFingerprint.patternMatch!!.endIndex + val insertIndex = hideGetPremiumFingerprint.instructionMatches.last().index val setVisibilityInstruction = getInstruction(insertIndex) val getPremiumViewRegister = setVisibilityInstruction.registerC diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/Fingerprints.kt index f3c96dc44a..7012360a51 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/Fingerprints.kt @@ -4,9 +4,8 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val pivotBarConstructorFingerprint = fingerprint { +internal val pivotBarConstructorFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - returns("V") parameters("L", "Z") opcodes( Opcode.CHECK_CAST, diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/RemoveUpgradeButtonPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/RemoveUpgradeButtonPatch.kt index 12b81b9a0d..1812576cff 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/RemoveUpgradeButtonPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/RemoveUpgradeButtonPatch.kt @@ -28,7 +28,7 @@ val removeUpgradeButtonPatch = bytecodePatch( execute { pivotBarConstructorFingerprint.method.apply { val pivotBarElementFieldReference = - getInstruction(pivotBarConstructorFingerprint.patternMatch!!.endIndex - 1) + getInstruction(pivotBarConstructorFingerprint.instructionMatches.last().index - 1) .getReference() val register = getInstruction(0).registerC @@ -42,7 +42,7 @@ val removeUpgradeButtonPatch = bytecodePatch( iput-object v0, v$register, $pivotBarElementFieldReference """.toInstructions().toMutableList() - val endIndex = pivotBarConstructorFingerprint.patternMatch!!.endIndex + val endIndex = pivotBarConstructorFingerprint.instructionMatches.last().index // Replace the instruction to retain the label at given index. replaceInstruction( diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/androidauto/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/androidauto/Fingerprints.kt index 97dea56502..30c0ec0cbb 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/androidauto/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/androidauto/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.music.misc.androidauto import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val checkCertificateFingerprint = fingerprint { +internal val checkCertificateFingerprint by fingerprint { returns("Z") parameters("Ljava/lang/String;") strings( diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/Fingerprints.kt index e1cf24e1a2..7e408aaa91 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/Fingerprints.kt @@ -4,7 +4,7 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val backgroundPlaybackDisableFingerprint = fingerprint { +internal val backgroundPlaybackDisableFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("Z") parameters("L") @@ -21,7 +21,7 @@ internal val backgroundPlaybackDisableFingerprint = fingerprint { ) } -internal val kidsBackgroundPlaybackPolicyControllerFingerprint = fingerprint { +internal val kidsBackgroundPlaybackPolicyControllerFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("I", "L", "Z") diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/extension/hooks/ApplicationInitHook.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/extension/hooks/ApplicationInitHook.kt index 1e1a43f9aa..869174c45f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/extension/hooks/ApplicationInitHook.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/extension/hooks/ApplicationInitHook.kt @@ -1,10 +1,13 @@ package app.revanced.patches.music.misc.extension.hooks +import app.revanced.patcher.string import app.revanced.patches.shared.misc.extension.extensionHook internal val applicationInitHook = extensionHook { returns("V") parameters() - strings("activity") + instructions( + string("activity") + ) custom { method, _ -> method.name == "onCreate" } } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/gms/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/gms/Fingerprints.kt index 7131e143df..9ad55f01d6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/gms/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/gms/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.music.misc.gms import app.revanced.patcher.fingerprint -internal val musicActivityOnCreateFingerprint = fingerprint { +internal val musicActivityOnCreateFingerprint by fingerprint { returns("V") parameters("Landroid/os/Bundle;") custom { method, classDef -> diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/Fingerprints.kt index abf19cc958..22cf63b849 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/Fingerprints.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val playerRequestConstructorFingerprint = fingerprint { +internal val playerRequestConstructorFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) strings("player") } @@ -12,7 +12,7 @@ internal val playerRequestConstructorFingerprint = fingerprint { /** * Matches using the class found in [playerRequestConstructorFingerprint]. */ -internal val createPlayerRequestBodyFingerprint = fingerprint { +internal val createPlayerRequestBodyFingerprint by fingerprint { parameters("L") returns("V") opcodes( @@ -26,7 +26,7 @@ internal val createPlayerRequestBodyFingerprint = fingerprint { /** * Used to get a reference to other clientInfo fields. */ -internal val setClientInfoFieldsFingerprint = fingerprint { +internal val setClientInfoFieldsFingerprint by fingerprint { returns("L") strings("Google Inc.") } @@ -34,6 +34,6 @@ internal val setClientInfoFieldsFingerprint = fingerprint { /** * Used to get a reference to the clientInfo and clientInfo.clientVersion field. */ -internal val setClientInfoClientVersionFingerprint = fingerprint { +internal val setClientInfoClientVersionFingerprint by fingerprint { strings("10.29") } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofClientPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofClientPatch.kt index 88ab2ceb8e..c9bacc4997 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofClientPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofClientPatch.kt @@ -44,7 +44,7 @@ val spoofClientPatch = bytecodePatch( val createPlayerRequestBodyMatch = createPlayerRequestBodyFingerprint.match(playerRequestClass) val clientInfoContainerClass = createPlayerRequestBodyMatch.method - .getInstruction(createPlayerRequestBodyMatch.patternMatch!!.startIndex) + .getInstruction(createPlayerRequestBodyMatch.instructionMatches.first().index) .getReference()!!.type val clientInfoField = setClientInfoClientVersionFingerprint.method.instructions.first { @@ -61,7 +61,7 @@ val spoofClientPatch = bytecodePatch( val clientModelField = setClientInfoFieldInstructions[5] val osVersionField = setClientInfoFieldInstructions[7] val clientVersionField = setClientInfoClientVersionFingerprint.method - .getInstruction(setClientInfoClientVersionFingerprint.stringMatches!!.first().index + 1) + .getInstruction(setClientInfoClientVersionFingerprint.stringMatches.first().index + 1) .getReference() // Helper method to spoof the client info. @@ -101,7 +101,7 @@ val spoofClientPatch = bytecodePatch( } createPlayerRequestBodyMatch.method.apply { - val checkCastIndex = createPlayerRequestBodyMatch.patternMatch!!.startIndex + val checkCastIndex = createPlayerRequestBodyMatch.instructionMatches.first().index val clientInfoContainerRegister = getInstruction(checkCastIndex).registerA addInstruction(checkCastIndex + 1, "invoke-static {v$clientInfoContainerRegister}, $spoofClientInfoMethod") diff --git a/patches/src/main/kotlin/app/revanced/patches/myexpenses/misc/pro/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/myexpenses/misc/pro/Fingerprints.kt index 6bc4c21e5c..a118f681a4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/myexpenses/misc/pro/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/myexpenses/misc/pro/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.myexpenses.misc.pro import app.revanced.patcher.fingerprint -internal val isEnabledFingerprint = fingerprint { +internal val isEnabledFingerprint by fingerprint { returns("Z") strings("feature", "feature.licenceStatus") } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/myfitnesspal/ads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/myfitnesspal/ads/Fingerprints.kt index 160e2db274..6afea3462f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/myfitnesspal/ads/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/myfitnesspal/ads/Fingerprints.kt @@ -3,14 +3,14 @@ package app.revanced.patches.myfitnesspal.ads import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val isPremiumUseCaseImplFingerprint = fingerprint { +internal val isPremiumUseCaseImplFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC) custom { method, classDef -> classDef.endsWith("IsPremiumUseCaseImpl;") && method.name == "doWork" } } -internal val mainActivityNavigateToNativePremiumUpsellFingerprint = fingerprint { +internal val mainActivityNavigateToNativePremiumUpsellFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL) returns("V") custom { method, classDef -> diff --git a/patches/src/main/kotlin/app/revanced/patches/nfctoolsse/misc/pro/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/nfctoolsse/misc/pro/Fingerprints.kt index f4f5d48c02..bf070df088 100644 --- a/patches/src/main/kotlin/app/revanced/patches/nfctoolsse/misc/pro/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/nfctoolsse/misc/pro/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.nfctoolsse.misc.pro import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val isLicenseRegisteredFingerprint = fingerprint { +internal val isLicenseRegisteredFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC) returns("Z") strings("kLicenseCheck") diff --git a/patches/src/main/kotlin/app/revanced/patches/nyx/misc/pro/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/nyx/misc/pro/Fingerprints.kt deleted file mode 100644 index e2bffa451a..0000000000 --- a/patches/src/main/kotlin/app/revanced/patches/nyx/misc/pro/Fingerprints.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.nyx.misc.pro - -import app.revanced.patcher.fingerprint - -internal val checkProFingerprint = fingerprint { - custom { method, classDef -> - classDef.endsWith("BillingManager;") && method.name == "isProVersion" - } -} diff --git a/patches/src/main/kotlin/app/revanced/patches/nyx/misc/pro/UnlockProPatch.kt b/patches/src/main/kotlin/app/revanced/patches/nyx/misc/pro/UnlockProPatch.kt deleted file mode 100644 index 179e745e08..0000000000 --- a/patches/src/main/kotlin/app/revanced/patches/nyx/misc/pro/UnlockProPatch.kt +++ /dev/null @@ -1,20 +0,0 @@ -package app.revanced.patches.nyx.misc.pro - -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.patch.bytecodePatch - -@Deprecated("This patch will be removed in the future.") -@Suppress("unused") -val unlockProPatch = bytecodePatch { - compatibleWith("com.awedea.nyx") - - execute { - checkProFingerprint.method.addInstructions( - 0, - """ - const/4 v0, 0x1 - return v0 - """, - ) - } -} diff --git a/patches/src/main/kotlin/app/revanced/patches/openinghours/misc/fix/crash/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/openinghours/misc/fix/crash/Fingerprints.kt index 69463c510d..56fcf73d74 100644 --- a/patches/src/main/kotlin/app/revanced/patches/openinghours/misc/fix/crash/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/openinghours/misc/fix/crash/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.openinghours.misc.fix.crash import app.revanced.patcher.fingerprint -internal val setPlaceFingerprint = fingerprint { +internal val setPlaceFingerprint by fingerprint { returns("V") parameters("Lde/simon/openinghours/models/Place;") custom { method, _ -> diff --git a/patches/src/main/kotlin/app/revanced/patches/photomath/detection/deviceid/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/photomath/detection/deviceid/Fingerprints.kt index 90c0bbb919..d37351f8e2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/photomath/detection/deviceid/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/photomath/detection/deviceid/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.photomath.detection.deviceid import com.android.tools.smali.dexlib2.Opcode import app.revanced.patcher.fingerprint -internal val getDeviceIdFingerprint = fingerprint { +internal val getDeviceIdFingerprint by fingerprint { returns("Ljava/lang/String;") parameters() opcodes( diff --git a/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/Fingerprints.kt index 5d7a20783f..1750b88a04 100644 --- a/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.photomath.detection.signature import com.android.tools.smali.dexlib2.Opcode import app.revanced.patcher.fingerprint -internal val checkSignatureFingerprint = fingerprint { +internal val checkSignatureFingerprint by fingerprint { opcodes( Opcode.CONST_STRING, Opcode.INVOKE_STATIC, diff --git a/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/SignatureDetectionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/SignatureDetectionPatch.kt index 00b47e5161..96eb3ba0fb 100644 --- a/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/SignatureDetectionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/photomath/detection/signature/SignatureDetectionPatch.kt @@ -10,7 +10,7 @@ val signatureDetectionPatch = bytecodePatch( ) { execute { - val replacementIndex = checkSignatureFingerprint.patternMatch!!.endIndex + val replacementIndex = checkSignatureFingerprint.instructionMatches.last().index val checkRegister = checkSignatureFingerprint.method.getInstruction(replacementIndex).registerA checkSignatureFingerprint.method.replaceInstruction(replacementIndex, "const/4 v$checkRegister, 0x1") diff --git a/patches/src/main/kotlin/app/revanced/patches/photomath/misc/annoyances/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/photomath/misc/annoyances/Fingerprints.kt index 301f2f9a52..694573b433 100644 --- a/patches/src/main/kotlin/app/revanced/patches/photomath/misc/annoyances/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/photomath/misc/annoyances/Fingerprints.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val hideUpdatePopupFingerprint = fingerprint { +internal val hideUpdatePopupFingerprint by fingerprint { accessFlags(AccessFlags.FINAL, AccessFlags.PUBLIC) returns("V") opcodes( diff --git a/patches/src/main/kotlin/app/revanced/patches/photomath/misc/unlock/bookpoint/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/photomath/misc/unlock/bookpoint/Fingerprints.kt index 6722f4223e..d0565792d5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/photomath/misc/unlock/bookpoint/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/photomath/misc/unlock/bookpoint/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.photomath.misc.unlock.bookpoint import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val isBookpointEnabledFingerprint = fingerprint { +internal val isBookpointEnabledFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") parameters() diff --git a/patches/src/main/kotlin/app/revanced/patches/photomath/misc/unlock/plus/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/photomath/misc/unlock/plus/Fingerprints.kt index f6c282cbd4..bc153d400c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/photomath/misc/unlock/plus/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/photomath/misc/unlock/plus/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.photomath.misc.unlock.plus import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val isPlusUnlockedFingerprint = fingerprint{ +internal val isPlusUnlockedFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") strings("genius") diff --git a/patches/src/main/kotlin/app/revanced/patches/piccomafr/misc/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/piccomafr/misc/Fingerprints.kt index 8c2d579ef5..199cd01af7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/piccomafr/misc/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/piccomafr/misc/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.piccomafr.misc import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val getAndroidIdFingerprint = fingerprint { +internal val getAndroidIdFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Ljava/lang/String;") parameters("Landroid/content/Context;") diff --git a/patches/src/main/kotlin/app/revanced/patches/piccomafr/tracking/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/piccomafr/tracking/Fingerprints.kt index 794f21bcb6..e757223dd3 100644 --- a/patches/src/main/kotlin/app/revanced/patches/piccomafr/tracking/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/piccomafr/tracking/Fingerprints.kt @@ -3,19 +3,18 @@ package app.revanced.patches.piccomafr.tracking import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val appMeasurementFingerprint = fingerprint { +internal val appMeasurementFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL) returns("V") strings("config/app/", "Fetching remote configuration") } -internal val facebookSDKFingerprint = fingerprint { +internal val facebookSDKFingerprint by fingerprint { accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR) - returns("V") strings("instagram.com", "facebook.com") } -internal val firebaseInstallFingerprint = fingerprint { +internal val firebaseInstallFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE) strings( "https://%s/%s/%s", diff --git a/patches/src/main/kotlin/app/revanced/patches/pixiv/ads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/pixiv/ads/Fingerprints.kt index 3e2addaa06..825a834b62 100644 --- a/patches/src/main/kotlin/app/revanced/patches/pixiv/ads/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/pixiv/ads/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.pixiv.ads import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val shouldShowAdsFingerprint = fingerprint { +internal val shouldShowAdsFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") custom { methodDef, classDef -> diff --git a/patches/src/main/kotlin/app/revanced/patches/rar/misc/annoyances/purchasereminder/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/rar/misc/annoyances/purchasereminder/Fingerprints.kt index a4d2c9e221..d63bbce862 100644 --- a/patches/src/main/kotlin/app/revanced/patches/rar/misc/annoyances/purchasereminder/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/rar/misc/annoyances/purchasereminder/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.rar.misc.annoyances.purchasereminder import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val showReminderFingerprint = fingerprint { +internal val showReminderFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("V") custom { method, _ -> diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/ad/comments/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/ad/comments/Fingerprints.kt index c99df5707a..91ea04763e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/ad/comments/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/ad/comments/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.reddit.ad.comments import app.revanced.patcher.fingerprint -internal val hideCommentAdsFingerprint = fingerprint { +internal val hideCommentAdsFingerprint by fingerprint { strings( "link", // CommentPageRepository is not returning a link object diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/ad/general/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/ad/general/Fingerprints.kt index e7dd789123..93310ce7e9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/ad/general/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/ad/general/Fingerprints.kt @@ -3,14 +3,14 @@ package app.revanced.patches.reddit.ad.general import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.Opcode -internal val adPostFingerprint = fingerprint { +internal val adPostFingerprint by fingerprint { returns("V") // "children" are present throughout multiple versions strings("children") custom { _, classDef -> classDef.endsWith("Listing;") } } -internal val newAdPostFingerprint = fingerprint { +internal val newAdPostFingerprint by fingerprint { opcodes(Opcode.INVOKE_VIRTUAL) strings("chain", "feedElement") custom { _, classDef -> classDef.sourceFile == "AdElementConverter.kt" } diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/Fingerprints.kt index bb87c21148..b3c0a957b8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/Fingerprints.kt @@ -2,10 +2,10 @@ package app.revanced.patches.reddit.customclients.baconreader.api import app.revanced.patcher.fingerprint -internal val getAuthorizationUrlFingerprint = fingerprint { +internal val getAuthorizationUrlFingerprint by fingerprint { strings("client_id=zACVn0dSFGdWqQ") } -internal val getClientIdFingerprint = fingerprint { +internal val getClientIdFingerprint by fingerprint { strings("client_id=zACVn0dSFGdWqQ") custom { method, classDef -> if (!classDef.endsWith("RedditOAuth;")) return@custom false @@ -14,6 +14,6 @@ internal val getClientIdFingerprint = fingerprint { } } -internal val requestTokenFingerprint = fingerprint { +internal val requestTokenFingerprint by fingerprint { strings("zACVn0dSFGdWqQ", "kDm2tYpu9DqyWFFyPlNcXGEni4k") // App ID and secret. } diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/ads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/ads/Fingerprints.kt index 618e2f1456..3462a91942 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/ads/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/ads/Fingerprints.kt @@ -2,10 +2,10 @@ package app.revanced.patches.reddit.customclients.boostforreddit.ads import app.revanced.patcher.fingerprint -internal val maxMediationFingerprint = fingerprint { +internal val maxMediationFingerprint by fingerprint { strings("MaxMediation: Attempting to initialize SDK") } -internal val admobMediationFingerprint = fingerprint { +internal val admobMediationFingerprint by fingerprint { strings("AdmobMediation: Attempting to initialize SDK") } diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/Fingerprints.kt index cc06fd3968..a6d4543043 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/Fingerprints.kt @@ -2,11 +2,11 @@ package app.revanced.patches.reddit.customclients.boostforreddit.api import app.revanced.patcher.fingerprint -internal val buildUserAgentFingerprint = fingerprint { +internal val buildUserAgentFingerprint by fingerprint { strings("%s:%s:%s (by /u/%s)") } -internal val getClientIdFingerprint = fingerprint { +internal val getClientIdFingerprint by fingerprint { custom { method, classDef -> if (!classDef.endsWith("Credentials;")) return@custom false diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/Fingerprints.kt index a2b1530b8b..f7a3ea815b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/Fingerprints.kt @@ -2,6 +2,6 @@ package app.revanced.patches.reddit.customclients.boostforreddit.fix.downloads import app.revanced.patcher.fingerprint -internal val downloadAudioFingerprint = fingerprint { +internal val downloadAudioFingerprint by fingerprint { strings("/DASH_audio.mp4", "/audio") } diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/FixAudioMissingInDownloadsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/FixAudioMissingInDownloadsPatch.kt index 8cb3f55186..c5b548f93f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/FixAudioMissingInDownloadsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/downloads/FixAudioMissingInDownloadsPatch.kt @@ -19,7 +19,7 @@ val fixAudioMissingInDownloadsPatch = bytecodePatch( ) downloadAudioFingerprint.method.apply { - downloadAudioFingerprint.stringMatches!!.forEach { match -> + downloadAudioFingerprint.stringMatches.forEach { match -> val replacement = endpointReplacements[match.string] val register = getInstruction(match.index).registerA diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/Fingerprints.kt index 665dba5a40..e690af53d9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/Fingerprints.kt @@ -3,14 +3,14 @@ package app.revanced.patches.reddit.customclients.boostforreddit.fix.slink import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val getOAuthAccessTokenFingerprint = fingerprint { +internal val getOAuthAccessTokenFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC) returns("Ljava/lang/String") strings("access_token") custom { method, _ -> method.definingClass == "Lnet/dean/jraw/http/oauth/OAuthData;" } } -internal val handleNavigationFingerprint = fingerprint { +internal val handleNavigationFingerprint by fingerprint { strings( "android.intent.action.SEARCH", "subscription", diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/Fingerprints.kt index 4bce1362c2..0d7f124f61 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/Fingerprints.kt @@ -2,6 +2,6 @@ package app.revanced.patches.reddit.customclients.infinityforreddit.api import app.revanced.patcher.fingerprint -internal val apiUtilsFingerprint = fingerprint { +internal val apiUtilsFingerprint by fingerprint { strings("native-lib") } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/subscription/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/subscription/Fingerprints.kt index 36fe062796..22842f81ec 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/subscription/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/subscription/Fingerprints.kt @@ -1,15 +1,14 @@ package app.revanced.patches.reddit.customclients.infinityforreddit.subscription import app.revanced.patcher.fingerprint -import app.revanced.util.literal +import app.revanced.patcher.literal -internal val billingClientOnServiceConnectedFingerprint = fingerprint { +internal val billingClientOnServiceConnectedFingerprint by fingerprint { strings("Billing service connected") } -internal val startSubscriptionActivityFingerprint = fingerprint { - literal { - // Intent start flag only used in the subscription activity - 0x10008000 - } +internal val startSubscriptionActivityFingerprint by fingerprint { + instructions( + literal(0x10008000) // Intent start flag only used in the subscription activity + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/joeyforreddit/ads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/joeyforreddit/ads/Fingerprints.kt index 465faf1200..e136d57ec7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/joeyforreddit/ads/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/joeyforreddit/ads/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.reddit.customclients.joeyforreddit.ads import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val isAdFreeUserFingerprint = fingerprint { +internal val isAdFreeUserFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC) returns("Z") strings("AD_FREE_USER") diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/joeyforreddit/api/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/joeyforreddit/api/Fingerprints.kt index e6c591748c..c6c5c0abb7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/joeyforreddit/api/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/joeyforreddit/api/Fingerprints.kt @@ -4,7 +4,7 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val authUtilityUserAgentFingerprint = fingerprint { +internal val authUtilityUserAgentFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("Ljava/lang/String;") opcodes(Opcode.APUT_OBJECT) @@ -13,7 +13,7 @@ internal val authUtilityUserAgentFingerprint = fingerprint { } } -internal val getClientIdFingerprint = fingerprint { +internal val getClientIdFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("L") opcodes( diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/joeyforreddit/detection/piracy/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/joeyforreddit/detection/piracy/Fingerprints.kt index 76343a5309..d8ae7417a7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/joeyforreddit/detection/piracy/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/joeyforreddit/detection/piracy/Fingerprints.kt @@ -4,7 +4,7 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val piracyDetectionFingerprint = fingerprint { +internal val piracyDetectionFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC) returns("V") opcodes( diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/redditisfun/api/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/redditisfun/api/Fingerprints.kt index 5b3029094f..a976c7b50d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/redditisfun/api/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/redditisfun/api/Fingerprints.kt @@ -8,15 +8,15 @@ internal fun baseClientIdFingerprint(string: String) = fingerprint { strings("yyOCBp.RHJhDKd", string) } -internal val basicAuthorizationFingerprint = baseClientIdFingerprint( +internal val basicAuthorizationFingerprint by baseClientIdFingerprint( string = "fJOxVwBUyo*=f: - val clientIdIndex = fingerprint.stringMatches!!.first().index + val clientIdIndex = fingerprint.stringMatches.first().index fingerprint.method.apply { val clientIdRegister = getInstruction(clientIdIndex).registerA @@ -45,7 +45,7 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "dbrady://relay") { setRemoteConfigFingerprint.method.addInstructions(0, "return-void") // Prevent OAuth login being disabled remotely. - val checkIsOAuthRequestIndex = redditCheckDisableAPIFingerprint.patternMatch!!.startIndex + val checkIsOAuthRequestIndex = redditCheckDisableAPIFingerprint.instructionMatches.first().index redditCheckDisableAPIFingerprint.method.apply { val returnNextChain = getInstruction(checkIsOAuthRequestIndex).target diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/slide/api/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/slide/api/Fingerprints.kt index 4ff8be4615..79f3179afe 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/slide/api/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/slide/api/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.reddit.customclients.slide.api import app.revanced.patcher.fingerprint -internal val getClientIdFingerprint = fingerprint { +internal val getClientIdFingerprint by fingerprint { custom { method, classDef -> if (!classDef.endsWith("Credentials;")) return@custom false diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/ads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/ads/Fingerprints.kt index e055493bdd..0290c185be 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/ads/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/ads/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.reddit.customclients.sync.ads import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val isAdsEnabledFingerprint = fingerprint { +internal val isAdsEnabledFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("Z") strings("SyncIapHelper") diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/detection/piracy/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/detection/piracy/Fingerprints.kt index e83e914d75..46a98af1af 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/detection/piracy/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/detection/piracy/Fingerprints.kt @@ -7,7 +7,7 @@ import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.reference.Reference -internal val piracyDetectionFingerprint = fingerprint { +internal val piracyDetectionFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL) returns("V") opcodes( diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/annoyances/startup/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/annoyances/startup/Fingerprints.kt index 21c788a89c..0e243f97c1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/annoyances/startup/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/annoyances/startup/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.reddit.customclients.sync.syncforreddit.annoyances. import app.revanced.patcher.fingerprint -internal val mainActivityOnCreateFingerprint = fingerprint { +internal val mainActivityOnCreateFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("MainActivity;") && method.name == "onCreate" } diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/Fingerprints.kt index c7902b1f4d..41e7d5f928 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/Fingerprints.kt @@ -2,18 +2,18 @@ package app.revanced.patches.reddit.customclients.sync.syncforreddit.api import app.revanced.patcher.fingerprint -internal val getAuthorizationStringFingerprint = fingerprint { +internal val getAuthorizationStringFingerprint by fingerprint { strings("authorize.compact?client_id") } -internal val getBearerTokenFingerprint = fingerprint { +internal val getBearerTokenFingerprint by fingerprint { strings("Basic") } -internal val getUserAgentFingerprint = fingerprint { +internal val getUserAgentFingerprint by fingerprint { strings("android:com.laurencedawson.reddit_sync") } -internal val imgurImageAPIFingerprint = fingerprint { +internal val imgurImageAPIFingerprint by fingerprint { strings("https://imgur-apiv3.p.rapidapi.com/3/image") } diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/SpoofClientPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/SpoofClientPatch.kt index 481d9c3d1e..86ea4c8923 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/SpoofClientPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/SpoofClientPatch.kt @@ -36,7 +36,7 @@ val spoofClientPatch = spoofClientPatch( """, ) val occurrenceIndex = - getAuthorizationStringFingerprint.stringMatches!!.first().index + getAuthorizationStringFingerprint.stringMatches.first().index getAuthorizationStringFingerprint.method.apply { val authorizationStringInstruction = getInstruction(occurrenceIndex) @@ -75,7 +75,7 @@ val spoofClientPatch = spoofClientPatch( // region Patch Imgur API URL. - val apiUrlIndex = imgurImageAPIFingerprint.stringMatches!!.first().index + val apiUrlIndex = imgurImageAPIFingerprint.stringMatches.first().index imgurImageAPIFingerprint.method.replaceInstruction( apiUrlIndex, "const-string v1, \"https://api.imgur.com/3/image\"", diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/slink/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/slink/Fingerprints.kt index f7287fcc39..641a3e99e1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/slink/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/slink/Fingerprints.kt @@ -2,11 +2,11 @@ package app.revanced.patches.reddit.customclients.sync.syncforreddit.fix.slink import app.revanced.patcher.fingerprint -internal val linkHelperOpenLinkFingerprint = fingerprint { +internal val linkHelperOpenLinkFingerprint by fingerprint { strings("Link title: ") } -internal val setAuthorizationHeaderFingerprint = fingerprint { +internal val setAuthorizationHeaderFingerprint by fingerprint { returns("Ljava/util/HashMap;") strings("Authorization", "bearer ") custom { method, _ -> method.definingClass == "Lcom/laurencedawson/reddit_sync/singleton/a;" } diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/user/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/user/Fingerprints.kt index 4bac74de77..94a9adb2ba 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/user/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/user/Fingerprints.kt @@ -9,28 +9,28 @@ internal fun userEndpointFingerprint(source: String, accessFlags: Set - fingerprint.stringMatches!!.first().index to fingerprint.method + fingerprint.stringMatches.first().index to fingerprint.method }.forEach { (userPathStringIndex, method) -> val userPathStringInstruction = method.getInstruction(userPathStringIndex) diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/Fingerprints.kt index 9ddeaf9cf5..9da9830cff 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.reddit.customclients.sync.syncforreddit.fix.video import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.Opcode -internal val parseRedditVideoNetworkResponseFingerprint = fingerprint { +internal val parseRedditVideoNetworkResponseFingerprint by fingerprint { opcodes( Opcode.NEW_INSTANCE, Opcode.IGET_OBJECT, diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/FixVideoDownloadsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/FixVideoDownloadsPatch.kt index 64c33f308b..cb4fa24651 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/FixVideoDownloadsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/video/FixVideoDownloadsPatch.kt @@ -24,9 +24,9 @@ val fixVideoDownloadsPatch = bytecodePatch( ) execute { - val scanResult = parseRedditVideoNetworkResponseFingerprint.patternMatch!! - val newInstanceIndex = scanResult.startIndex - val invokeDirectIndex = scanResult.endIndex - 1 + val scanResult = parseRedditVideoNetworkResponseFingerprint.instructionMatches + val newInstanceIndex = scanResult.first().index + val invokeDirectIndex = scanResult.last().index - 1 val buildResponseInstruction = parseRedditVideoNetworkResponseFingerprint.method.getInstruction(invokeDirectIndex) diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/video/FixVideoDownloadsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/video/FixVideoDownloadsPatch.kt deleted file mode 100644 index 28ad4a0dbe..0000000000 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/video/FixVideoDownloadsPatch.kt +++ /dev/null @@ -1,18 +0,0 @@ -package app.revanced.patches.reddit.customclients.syncforreddit.fix.video - -import app.revanced.patcher.patch.bytecodePatch - -@Deprecated( - message = "Patch was move to a different package", - ReplaceWith("app.revanced.patches.reddit.customclients.sync.syncforreddit.fix.video.fixVideoDownloadsPatch") -) -@Suppress("unused") -val fixVideoDownloadsPatch = bytecodePatch { - dependsOn(app.revanced.patches.reddit.customclients.sync.syncforreddit.fix.video.fixVideoDownloadsPatch) - - compatibleWith( - "com.laurencedawson.reddit_sync", - "com.laurencedawson.reddit_sync.pro", - "com.laurencedawson.reddit_sync.dev", - ) -} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/disablescreenshotpopup/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/disablescreenshotpopup/Fingerprints.kt index 09fe16247e..3127bbbc6d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/disablescreenshotpopup/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/disablescreenshotpopup/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.reddit.layout.disablescreenshotpopup import app.revanced.patcher.fingerprint -internal val disableScreenshotPopupFingerprint = fingerprint { +internal val disableScreenshotPopupFingerprint by fingerprint { returns("V") parameters("Landroidx/compose/runtime/", "I") custom { method, classDef -> diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/Fingerprints.kt index 2eac1cbe26..803192a909 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.reddit.layout.premiumicon import app.revanced.patcher.fingerprint -internal val hasPremiumIconAccessFingerprint = fingerprint { +internal val hasPremiumIconAccessFingerprint by fingerprint { returns("Z") custom { method, classDef -> classDef.endsWith("MyAccount;") && method.name == "isPremiumSubscriber" diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/misc/tracking/url/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/misc/tracking/url/Fingerprints.kt index 3381fd2bb2..b861b79408 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/misc/tracking/url/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/misc/tracking/url/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.reddit.misc.tracking.url import app.revanced.patcher.fingerprint -internal val shareLinkFormatterFingerprint = fingerprint { +internal val shareLinkFormatterFingerprint by fingerprint { custom { _, classDef -> classDef.startsWith("Lcom/reddit/sharing/") && classDef.sourceFile == "UrlUtil.kt" } diff --git a/patches/src/main/kotlin/app/revanced/patches/serviceportalbund/detection/root/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/serviceportalbund/detection/root/Fingerprints.kt index f7efe3103f..f1b352b037 100644 --- a/patches/src/main/kotlin/app/revanced/patches/serviceportalbund/detection/root/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/serviceportalbund/detection/root/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.serviceportalbund.detection.root import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val rootDetectionFingerprint = fingerprint { +internal val rootDetectionFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC) returns("V") custom { _, classDef -> diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/Fingerprints.kt index df927dd4a7..a83f3b1d2c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/Fingerprints.kt @@ -1,11 +1,17 @@ package app.revanced.patches.shared import app.revanced.patcher.fingerprint +import app.revanced.patcher.string -internal val castContextFetchFingerprint = fingerprint { - strings("Error fetching CastContext.") +internal val castContextFetchFingerprint by fingerprint { + instructions( + string("Error fetching CastContext.") + ) } -internal val primeMethodFingerprint = fingerprint { - strings("com.google.android.GoogleCamera", "com.android.vending") +internal val primeMethodFingerprint by fingerprint { + instructions( + string("com.android.vending"), + string("com.google.android.GoogleCamera") + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/checks/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/checks/Fingerprints.kt index 0eabd2f547..b63e5c04ad 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/checks/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/checks/Fingerprints.kt @@ -2,10 +2,10 @@ package app.revanced.patches.shared.misc.checks import app.revanced.patcher.fingerprint -internal val patchInfoFingerprint = fingerprint { +internal val patchInfoFingerprint by fingerprint { custom { _, classDef -> classDef.type == "Lapp/revanced/extension/shared/checks/PatchInfo;" } } -internal val patchInfoBuildFingerprint = fingerprint { +internal val patchInfoBuildFingerprint by fingerprint { custom { _, classDef -> classDef.type == "Lapp/revanced/extension/shared/checks/PatchInfo\$Build;" } } diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/Fingerprints.kt index 58cc5082f1..b61a6763da 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.shared.misc.extension import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val revancedUtilsPatchesVersionFingerprint = fingerprint { +internal val revancedUtilsPatchesVersionFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("Ljava/lang/String;") parameters() diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt index 5233f186f1..45acf6cc01 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/extension/SharedExtensionPatch.kt @@ -4,9 +4,7 @@ import app.revanced.patcher.Fingerprint import app.revanced.patcher.FingerprintBuilder import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.fingerprint import app.revanced.patcher.patch.BytecodePatchContext -import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.bytecodePatch import com.android.tools.smali.dexlib2.iface.Method import java.net.URLDecoder @@ -40,11 +38,8 @@ fun sharedExtensionPatch( extendWith("extensions/shared.rve") execute { - if (classes.none { EXTENSION_CLASS_DESCRIPTOR == it.type }) { - throw PatchException( - "Shared extension has not been merged yet. This patch can not succeed without merging it.", - ) - } + // Verify the extension class exists. + classBy(EXTENSION_CLASS_DESCRIPTOR) hooks.forEach { hook -> hook(EXTENSION_CLASS_DESCRIPTOR) } @@ -113,4 +108,10 @@ fun extensionHook( insertIndexResolver: ((Method) -> Int) = { 0 }, contextRegisterResolver: (Method) -> String = { "p0" }, fingerprintBuilderBlock: FingerprintBuilder.() -> Unit, -) = ExtensionHook(fingerprint(block = fingerprintBuilderBlock), insertIndexResolver, contextRegisterResolver) +) = ExtensionHook( + FingerprintBuilder("extension").also { + it.fingerprintBuilderBlock() + }.build(), + insertIndexResolver, + contextRegisterResolver +) diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/Fingerprints.kt index 80d041ada8..8b784b2db6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/Fingerprints.kt @@ -4,7 +4,7 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val canScrollVerticallyFingerprint = fingerprint { +internal val canScrollVerticallyFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") parameters() diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/VerticalScrollPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/VerticalScrollPatch.kt index a01839c100..b4bc540a9e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/VerticalScrollPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/VerticalScrollPatch.kt @@ -10,15 +10,17 @@ val verticalScrollPatch = bytecodePatch( ) { execute { - canScrollVerticallyFingerprint.method.apply { - val moveResultIndex = canScrollVerticallyFingerprint.patternMatch!!.endIndex - val moveResultRegister = getInstruction(moveResultIndex).registerA + canScrollVerticallyFingerprint.let { + it.method.apply { + val moveResultIndex = it.instructionMatches.last().index + val moveResultRegister = getInstruction(moveResultIndex).registerA - val insertIndex = moveResultIndex + 1 - addInstruction( - insertIndex, - "const/4 v$moveResultRegister, 0x0", - ) + val insertIndex = moveResultIndex + 1 + addInstruction( + insertIndex, + "const/4 v$moveResultRegister, 0x0", + ) + } } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/Fingerprints.kt index b5f613d541..355a07ba81 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/Fingerprints.kt @@ -3,15 +3,15 @@ package app.revanced.patches.shared.misc.gms import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -const val GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME = "getGmsCoreVendorGroupId" - -internal val gmsCoreSupportFingerprint = fingerprint { - custom { _, classDef -> - classDef.endsWith("GmsCoreSupport;") +internal val gmsCoreSupportFingerprint by fingerprint { + accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC) + custom { method, classDef -> + method.name == "getGmsCoreVendorGroupId" + && classDef.endsWith("/GmsCoreSupport;") } } -internal val googlePlayUtilityFingerprint = fingerprint { +internal val googlePlayUtilityFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("I") parameters("L", "I") @@ -22,7 +22,7 @@ internal val googlePlayUtilityFingerprint = fingerprint { ) } -internal val serviceCheckFingerprint = fingerprint { +internal val serviceCheckFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("V") parameters("L", "I") diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt index 0e54bb6919..8761677497 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt @@ -79,7 +79,7 @@ fun gmsCoreSupportPatch( execute { fun transformStringReferences(transform: (str: String) -> String?) = classes.forEach { val mutableClass by lazy { - proxy(it).mutableClass + mutableClassBy(it) } it.methods.forEach classLoop@{ method -> @@ -89,12 +89,12 @@ fun gmsCoreSupportPatch( mutableClass.methods.first { MethodUtil.methodSignaturesMatch(it, method) } } - implementation.instructions.forEachIndexed insnLoop@{ index, instruction -> + implementation.instructions.forEachIndexed { index, instruction -> val string = ((instruction as? Instruction21c)?.reference as? StringReference)?.string - ?: return@insnLoop + ?: return@forEachIndexed // Apply transformation. - val transformedString = transform(string) ?: return@insnLoop + val transformedString = transform(string) ?: return@forEachIndexed mutableMethod.replaceInstruction( index, @@ -221,9 +221,7 @@ fun gmsCoreSupportPatch( } // Change the vendor of GmsCore in the extension. - gmsCoreSupportFingerprint.classDef.methods - .single { it.name == GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME } - .replaceInstruction(0, "const-string v0, \"$gmsCoreVendorGroupId\"") + gmsCoreSupportFingerprint.method.replaceInstruction(0, "const-string v0, \"$gmsCoreVendorGroupId\"") executeBlock() } diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt index 8a9e499ddb..36b0ce0920 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt @@ -1,64 +1,70 @@ package app.revanced.patches.shared.misc.mapping +import app.revanced.patcher.InstructionFilter.Companion.METHOD_MAX_INSTRUCTIONS +import app.revanced.patcher.LiteralFilter +import app.revanced.patcher.literal import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.resourcePatch import org.w3c.dom.Element -import java.util.* -import java.util.concurrent.Executors -import java.util.concurrent.TimeUnit +import java.util.Collections -// TODO: Probably renaming the patch/this is a good idea. -lateinit var resourceMappings: List - private set +data class ResourceElement(val type: String, val name: String, val id: Long) -val resourceMappingPatch = resourcePatch { - val resourceMappings = Collections.synchronizedList(mutableListOf()) - - execute { - val threadCount = Runtime.getRuntime().availableProcessors() - val threadPoolExecutor = Executors.newFixedThreadPool(threadCount) +private lateinit var resourceMappings: MutableMap - // Save the file in memory to concurrently read from it. - val resourceXmlFile = get("res/values/public.xml").readBytes() - - for (threadIndex in 0 until threadCount) { - threadPoolExecutor.execute thread@{ - document(resourceXmlFile.inputStream()).use { document -> +private fun setResourceId(type: String, name: String, id: Long) { + resourceMappings[type + name] = ResourceElement(type, name, id) +} - val resources = document.documentElement.childNodes - val resourcesLength = resources.length - val jobSize = resourcesLength / threadCount +/** + * @return A resource id of the given resource type and name. + * @throws PatchException if the resource is not found. + */ +fun getResourceId(type: String, name: String) = resourceMappings[type + name]?.id + ?: throw PatchException("Could not find resource type: $type name: $name") + +/** + * @return All resource elements. If a single resource id is needed instead use [getResourceId]. + */ +fun getResourceElements() = Collections.unmodifiableCollection(resourceMappings.values) + +/** + * @return If the resource exists. + */ +fun hasResourceId(type: String, name: String) = resourceMappings[type + name] != null + +/** + * Identical to [LiteralFilter] except uses a decoded resource literal value. + * + * Any patch with fingerprints of this filter must + * also declare [resourceMappingPatch] as a dependency. + */ +fun resourceLiteral( + type: String, + name: String, + maxBefore: Int = METHOD_MAX_INSTRUCTIONS, +) = literal({ getResourceId(type, name) }, null, maxBefore) - val batchStart = jobSize * threadIndex - val batchEnd = jobSize * (threadIndex + 1) - element@ for (i in batchStart until batchEnd) { - // Prevent out of bounds. - if (i >= resourcesLength) return@thread - val node = resources.item(i) - if (node !is Element) continue +val resourceMappingPatch = resourcePatch { + execute { + document("res/values/public.xml").use { document -> + val resources = document.documentElement.childNodes + val resourcesLength = resources.length + resourceMappings = HashMap(2 * resourcesLength) - val nameAttribute = node.getAttribute("name") - val typeAttribute = node.getAttribute("type") + for (i in 0 until resourcesLength) { + val node = resources.item(i) as? Element ?: continue + if (node.nodeName != "public") continue - if (node.nodeName != "public" || nameAttribute.startsWith("APKTOOL")) continue + val nameAttribute = node.getAttribute("name") + if (nameAttribute.startsWith("APKTOOL")) continue - val id = node.getAttribute("id").substring(2).toLong(16) + val typeAttribute = node.getAttribute("type") + val id = node.getAttribute("id").substring(2).toLong(16) - resourceMappings.add(ResourceElement(typeAttribute, nameAttribute, id)) - } - } + setResourceId(typeAttribute, nameAttribute, id) } } - - threadPoolExecutor.also { it.shutdown() }.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS) - - app.revanced.patches.shared.misc.mapping.resourceMappings = resourceMappings } } - -operator fun List.get(type: String, name: String) = resourceMappings.firstOrNull { - it.type == type && it.name == name -}?.id ?: throw PatchException("Could not find resource type: $type name: $name") - -data class ResourceElement internal constructor(val type: String, val name: String, val id: Long) diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/settings/SettingsPatch.kt index d6d9df94cc..6566992957 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/settings/SettingsPatch.kt @@ -6,20 +6,12 @@ import app.revanced.patches.all.misc.resources.addResource import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.shared.misc.settings.preference.BasePreference -import app.revanced.patches.shared.misc.settings.preference.IntentPreference import app.revanced.util.ResourceGroup import app.revanced.util.copyResources import app.revanced.util.getNode import app.revanced.util.insertFirst import org.w3c.dom.Node -// TODO: Delete this on next major version bump. -@Deprecated("Use non deprecated settings patch function") -fun settingsPatch ( - rootPreference: Pair, - preferences: Set, -) = settingsPatch(listOf(rootPreference), preferences) - /** * A resource patch that adds settings to a settings fragment. * diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/Fingerprints.kt index 164d67b1ad..7fee85218d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/Fingerprints.kt @@ -1,11 +1,13 @@ package app.revanced.patches.shared.misc.spoof import app.revanced.patcher.fingerprint -import app.revanced.util.literal +import app.revanced.patcher.literal +import app.revanced.patcher.methodCall +import app.revanced.patcher.string import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val buildInitPlaybackRequestFingerprint = fingerprint { +internal val buildInitPlaybackRequestFingerprint by fingerprint { returns("Lorg/chromium/net/UrlRequest\$Builder;") opcodes( Opcode.MOVE_RESULT_OBJECT, @@ -17,7 +19,7 @@ internal val buildInitPlaybackRequestFingerprint = fingerprint { ) } -internal val buildPlayerRequestURIFingerprint = fingerprint { +internal val buildPlayerRequestURIFingerprint by fingerprint { returns("Ljava/lang/String;") opcodes( Opcode.INVOKE_VIRTUAL, // Register holds player request URI. @@ -33,9 +35,12 @@ internal val buildPlayerRequestURIFingerprint = fingerprint { ) } -internal val buildRequestFingerprint = fingerprint { +internal val buildRequestFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("Lorg/chromium/net/UrlRequest;") + instructions( + methodCall(name = "newUrlRequestBuilder") + ) custom { methodDef, _ -> // Different targets have slightly different parameters @@ -64,7 +69,7 @@ internal val buildRequestFingerprint = fingerprint { } } -internal val protobufClassParseByteBufferFingerprint = fingerprint { +internal val protobufClassParseByteBufferFingerprint by fingerprint { accessFlags(AccessFlags.PROTECTED, AccessFlags.STATIC) returns("L") parameters("L", "Ljava/nio/ByteBuffer;") @@ -77,9 +82,8 @@ internal val protobufClassParseByteBufferFingerprint = fingerprint { custom { method, _ -> method.name == "parseFrom" } } -internal val createStreamingDataFingerprint = fingerprint { +internal val createStreamingDataFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - returns("V") parameters("L") opcodes( Opcode.IPUT_OBJECT, @@ -95,9 +99,8 @@ internal val createStreamingDataFingerprint = fingerprint { } } -internal val buildMediaDataSourceFingerprint = fingerprint { +internal val buildMediaDataSourceFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - returns("V") parameters( "Landroid/net/Uri;", "J", @@ -112,28 +115,28 @@ internal val buildMediaDataSourceFingerprint = fingerprint { ) } -internal const val HLS_CURRENT_TIME_FEATURE_FLAG = 45355374L - -internal val hlsCurrentTimeFingerprint = fingerprint { +internal val hlsCurrentTimeFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters("Z", "L") - literal { - HLS_CURRENT_TIME_FEATURE_FLAG - } + instructions( + literal(45355374L) // HLS current time feature flag. + ) } -internal val nerdsStatsVideoFormatBuilderFingerprint = fingerprint { +internal val nerdsStatsVideoFormatBuilderFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("Ljava/lang/String;") parameters("L") - strings("codecs=\"") + instructions( + string("codecs=\"") + ) } -internal val patchIncludedExtensionMethodFingerprint = fingerprint { +internal val patchIncludedExtensionMethodFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC) returns("Z") parameters() custom { method, classDef -> - classDef.type == EXTENSION_CLASS_DESCRIPTOR && method.name == "isPatchIncluded" + method.name == "isPatchIncluded" && classDef.type == EXTENSION_CLASS_DESCRIPTOR } } diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt index c6628f5cbd..678d7e691e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt @@ -22,7 +22,6 @@ 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.MethodReference import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter @@ -49,7 +48,7 @@ fun spoofVideoStreamsPatch( // region Block /initplayback requests to fall back to /get_watch requests. - val moveUriStringIndex = buildInitPlaybackRequestFingerprint.patternMatch!!.startIndex + val moveUriStringIndex = buildInitPlaybackRequestFingerprint.instructionMatches.first().index buildInitPlaybackRequestFingerprint.method.apply { val targetRegister = getInstruction(moveUriStringIndex).registerA @@ -67,39 +66,39 @@ fun spoofVideoStreamsPatch( // region Block /get_watch requests to fall back to /player requests. - val invokeToStringIndex = buildPlayerRequestURIFingerprint.patternMatch!!.startIndex + buildPlayerRequestURIFingerprint.let { + val invokeToStringIndex = it.instructionMatches.first().index + it.method.apply { + val uriRegister = getInstruction(invokeToStringIndex).registerC - buildPlayerRequestURIFingerprint.method.apply { - val uriRegister = getInstruction(invokeToStringIndex).registerC - - addInstructions( - invokeToStringIndex, - """ - invoke-static { v$uriRegister }, $EXTENSION_CLASS_DESCRIPTOR->blockGetWatchRequest(Landroid/net/Uri;)Landroid/net/Uri; - move-result-object v$uriRegister - """, - ) + addInstructions( + invokeToStringIndex, + """ + invoke-static { v$uriRegister }, $EXTENSION_CLASS_DESCRIPTOR->blockGetWatchRequest(Landroid/net/Uri;)Landroid/net/Uri; + move-result-object v$uriRegister + """ + ) + } } // endregion // region Get replacement streams at player requests. - buildRequestFingerprint.method.apply { - val newRequestBuilderIndex = indexOfFirstInstructionOrThrow { - opcode == Opcode.INVOKE_VIRTUAL && - getReference()?.name == "newUrlRequestBuilder" - } - val urlRegister = getInstruction(newRequestBuilderIndex).registerD - val freeRegister = getInstruction(newRequestBuilderIndex + 1).registerA + buildRequestFingerprint.let { + it.method.apply { + val builderIndex = it.instructionMatches.first().index + val urlRegister = getInstruction(builderIndex).registerD + val freeRegister = getInstruction(builderIndex + 1).registerA - addInstructions( - newRequestBuilderIndex, - """ - move-object v$freeRegister, p1 - invoke-static { v$urlRegister, v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->fetchStreams(Ljava/lang/String;Ljava/util/Map;)V - """, - ) + addInstructions( + builderIndex, + """ + move-object v$freeRegister, p1 + invoke-static { v$urlRegister, v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->fetchStreams(Ljava/lang/String;Ljava/util/Map;)V + """ + ) + } } // endregion @@ -109,7 +108,7 @@ fun spoofVideoStreamsPatch( createStreamingDataFingerprint.method.apply { val setStreamDataMethodName = "patch_setStreamingData" val resultMethodType = createStreamingDataFingerprint.classDef.type - val videoDetailsIndex = createStreamingDataFingerprint.patternMatch!!.endIndex + val videoDetailsIndex = createStreamingDataFingerprint.instructionMatches.last().index val videoDetailsRegister = getInstruction(videoDetailsIndex).registerA val videoDetailsClass = getInstruction(videoDetailsIndex).getReference()!!.type @@ -120,7 +119,7 @@ fun spoofVideoStreamsPatch( ) val protobufClass = protobufClassParseByteBufferFingerprint.method.definingClass - val setStreamingDataIndex = createStreamingDataFingerprint.patternMatch!!.startIndex + val setStreamingDataIndex = createStreamingDataFingerprint.instructionMatches.first().index val playerProtoClass = getInstruction(setStreamingDataIndex + 1) .getReference()!!.definingClass @@ -231,10 +230,12 @@ fun spoofVideoStreamsPatch( // region Fix iOS livestream current time. - hlsCurrentTimeFingerprint.method.insertFeatureFlagBooleanOverride( - HLS_CURRENT_TIME_FEATURE_FLAG, - "$EXTENSION_CLASS_DESCRIPTOR->fixHLSCurrentTime(Z)Z" - ) + hlsCurrentTimeFingerprint.let { + it.method.insertFeatureFlagBooleanOverride( + it.instructionMatches.first().index, + "$EXTENSION_CLASS_DESCRIPTOR->fixHLSCurrentTime(Z)Z" + ) + } // endregion diff --git a/patches/src/main/kotlin/app/revanced/patches/solidexplorer2/functionality/filesize/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/solidexplorer2/functionality/filesize/Fingerprints.kt index 0e81d7e592..3b03634434 100644 --- a/patches/src/main/kotlin/app/revanced/patches/solidexplorer2/functionality/filesize/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/solidexplorer2/functionality/filesize/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.solidexplorer2.functionality.filesize import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.Opcode -internal val onReadyFingerprint = fingerprint { +internal val onReadyFingerprint by fingerprint { opcodes( Opcode.CONST_WIDE_32, // Constant storing the 2MB limit Opcode.CMP_LONG, diff --git a/patches/src/main/kotlin/app/revanced/patches/solidexplorer2/functionality/filesize/RemoveFileSizeLimitPatch.kt b/patches/src/main/kotlin/app/revanced/patches/solidexplorer2/functionality/filesize/RemoveFileSizeLimitPatch.kt index 7ef5093015..c75a12b119 100644 --- a/patches/src/main/kotlin/app/revanced/patches/solidexplorer2/functionality/filesize/RemoveFileSizeLimitPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/solidexplorer2/functionality/filesize/RemoveFileSizeLimitPatch.kt @@ -14,7 +14,7 @@ val removeFileSizeLimitPatch = bytecodePatch( execute { onReadyFingerprint.method.apply { - val cmpIndex = onReadyFingerprint.patternMatch!!.startIndex + 1 + val cmpIndex = onReadyFingerprint.instructionMatches.first().index + 1 val cmpResultRegister = getInstruction(cmpIndex).registerA replaceInstruction(cmpIndex, "const/4 v$cmpResultRegister, 0x0") diff --git a/patches/src/main/kotlin/app/revanced/patches/songpal/badge/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/songpal/badge/Fingerprints.kt index c52174f2c5..48ef210a78 100644 --- a/patches/src/main/kotlin/app/revanced/patches/songpal/badge/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/songpal/badge/Fingerprints.kt @@ -8,7 +8,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodReference // Located @ ub.i0.h#p (9.5.0) -internal val createTabsFingerprint = fingerprint { +internal val createTabsFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE) returns("Ljava/util/List;") custom { method, _ -> @@ -26,7 +26,7 @@ internal val createTabsFingerprint = fingerprint { } // Located @ com.sony.songpal.mdr.vim.activity.MdrRemoteBaseActivity.e#run (9.5.0) -internal val showNotificationFingerprint = fingerprint { +internal val showNotificationFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC) returns("V") custom { method, _ -> diff --git a/patches/src/main/kotlin/app/revanced/patches/soundcloud/ad/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/soundcloud/ad/Fingerprints.kt index 28780ea578..f6f442306f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/soundcloud/ad/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/soundcloud/ad/Fingerprints.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val interceptFingerprint = fingerprint { +internal val interceptFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC) returns("L") parameters("L") @@ -16,9 +16,8 @@ internal val interceptFingerprint = fingerprint { strings("SC-Mob-UserPlan", "Configuration") } -internal val userConsumerPlanConstructorFingerprint = fingerprint { +internal val userConsumerPlanConstructorFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - returns("V") parameters( "Ljava/lang/String;", "Z", diff --git a/patches/src/main/kotlin/app/revanced/patches/soundcloud/ad/HideAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/soundcloud/ad/HideAdsPatch.kt index 3e56ed7275..76104a4230 100644 --- a/patches/src/main/kotlin/app/revanced/patches/soundcloud/ad/HideAdsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/soundcloud/ad/HideAdsPatch.kt @@ -54,7 +54,7 @@ val hideAdsPatch = bytecodePatch( // Prevent verification of an HTTP header containing the user's current plan, which would contradict the previous patch. - val conditionIndex = interceptFingerprint.patternMatch!!.endIndex + 1 + val conditionIndex = interceptFingerprint.instructionMatches.last().index + 1 interceptFingerprint.method.addInstruction( conditionIndex, "return-object p1", diff --git a/patches/src/main/kotlin/app/revanced/patches/soundcloud/analytics/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/soundcloud/analytics/Fingerprints.kt index 2954b4d99c..1b18832b71 100644 --- a/patches/src/main/kotlin/app/revanced/patches/soundcloud/analytics/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/soundcloud/analytics/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.soundcloud.analytics import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val createTrackingApiFingerprint = fingerprint { +internal val createTrackingApiFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC) returns("L") custom { methodDef, _ -> diff --git a/patches/src/main/kotlin/app/revanced/patches/soundcloud/offlinesync/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/soundcloud/offlinesync/Fingerprints.kt index 688fe36044..fe2aab19a5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/soundcloud/offlinesync/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/soundcloud/offlinesync/Fingerprints.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val downloadOperationsURLBuilderFingerprint = fingerprint { +internal val downloadOperationsURLBuilderFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Ljava/lang/String") parameters("L", "L") @@ -15,7 +15,7 @@ internal val downloadOperationsURLBuilderFingerprint = fingerprint { ) } -internal val downloadOperationsHeaderVerificationFingerprint = fingerprint { +internal val downloadOperationsHeaderVerificationFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L", "L") diff --git a/patches/src/main/kotlin/app/revanced/patches/soundcloud/shared/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/soundcloud/shared/Fingerprints.kt index 3a50ae407e..646bb929a7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/soundcloud/shared/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/soundcloud/shared/Fingerprints.kt @@ -4,8 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val featureConstructorFingerprint = fingerprint { - returns("V") +internal val featureConstructorFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) parameters("Ljava/lang/String;", "Z", "Ljava/util/List;") opcodes( diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/Fingerprints.kt index 365235bee0..e2f70ff1de 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.spotify.lite.ondemand import com.android.tools.smali.dexlib2.Opcode import app.revanced.patcher.fingerprint -internal val onDemandFingerprint = fingerprint(fuzzyPatternScanThreshold = 2) { +internal val onDemandFingerprint by fingerprint { returns("L") parameters() opcodes( diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/OnDemandPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/OnDemandPatch.kt index 6444ff7fb5..491820dac0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/OnDemandPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/OnDemandPatch.kt @@ -14,7 +14,7 @@ val onDemandPatch = bytecodePatch( // Spoof a premium account onDemandFingerprint.method.addInstruction( - onDemandFingerprint.patternMatch!!.endIndex - 1, + onDemandFingerprint.instructionMatches.last().index - 1, "const/4 v0, 0x2", ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/navbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/navbar/Fingerprints.kt index 761e322060..65431b214e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/navbar/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/navbar/Fingerprints.kt @@ -1,11 +1,13 @@ package app.revanced.patches.spotify.navbar import app.revanced.patcher.fingerprint -import app.revanced.util.literal +import app.revanced.patches.shared.misc.mapping.resourceLiteral import com.android.tools.smali.dexlib2.AccessFlags -internal val addNavBarItemFingerprint = fingerprint { +internal val addNavBarItemFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") - literal { showBottomNavigationItemsTextId } + instructions( + resourceLiteral("bool", "show_bottom_navigation_items_text") + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/navbar/PremiumNavbarTabPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/navbar/PremiumNavbarTabPatch.kt index c191c676b7..4f194c582e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/navbar/PremiumNavbarTabPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/navbar/PremiumNavbarTabPatch.kt @@ -3,12 +3,9 @@ package app.revanced.patches.spotify.navbar import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.resourcePatch -import app.revanced.patches.shared.misc.mapping.get +import app.revanced.patches.shared.misc.mapping.getResourceId import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings -internal var showBottomNavigationItemsTextId = -1L - private set internal var premiumTabId = -1L private set @@ -16,12 +13,7 @@ private val premiumNavbarTabResourcePatch = resourcePatch { dependsOn(resourceMappingPatch) execute { - premiumTabId = resourceMappings["id", "premium_tab"] - - showBottomNavigationItemsTextId = resourceMappings[ - "bool", - "show_bottom_navigation_items_text", - ] + premiumTabId = getResourceId("id", "premium_tab") } } diff --git a/patches/src/main/kotlin/app/revanced/patches/strava/subscription/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/strava/subscription/Fingerprints.kt index 0458f45d3e..58047cc4cf 100644 --- a/patches/src/main/kotlin/app/revanced/patches/strava/subscription/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/strava/subscription/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.strava.subscription import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.Opcode -internal val getSubscribedFingerprint = fingerprint { +internal val getSubscribedFingerprint by fingerprint { opcodes(Opcode.IGET_BOOLEAN) custom { method, classDef -> classDef.endsWith("/SubscriptionDetailResponse;") && method.name == "getSubscribed" diff --git a/patches/src/main/kotlin/app/revanced/patches/strava/subscription/UnlockSubscriptionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/strava/subscription/UnlockSubscriptionPatch.kt index e59660472d..d0e061b9c6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/strava/subscription/UnlockSubscriptionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/strava/subscription/UnlockSubscriptionPatch.kt @@ -12,7 +12,7 @@ val unlockSubscriptionPatch = bytecodePatch( execute { getSubscribedFingerprint.method.replaceInstruction( - getSubscribedFingerprint.patternMatch!!.startIndex, + getSubscribedFingerprint.instructionMatches.first().index, "const/4 v0, 0x1", ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/strava/upselling/DisableSubscriptionSuggestionsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/strava/upselling/DisableSubscriptionSuggestionsPatch.kt index 73246fa216..751c720e6a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/strava/upselling/DisableSubscriptionSuggestionsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/strava/upselling/DisableSubscriptionSuggestionsPatch.kt @@ -52,7 +52,7 @@ val disableSubscriptionSuggestionsPatch = bytecodePatch( }, ) - val getModulesIndex = getModulesFingerprint.patternMatch!!.startIndex + val getModulesIndex = getModulesFingerprint.instructionMatches.first().index with(originalMethod) { removeInstruction(getModulesIndex) addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/strava/upselling/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/strava/upselling/Fingerprints.kt index 1204a36f21..134c108692 100644 --- a/patches/src/main/kotlin/app/revanced/patches/strava/upselling/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/strava/upselling/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.strava.upselling import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.Opcode -internal val getModulesFingerprint = fingerprint { +internal val getModulesFingerprint by fingerprint { opcodes(Opcode.IGET_OBJECT) custom { method, classDef -> classDef.endsWith("/GenericLayoutEntry;") && method.name == "getModules" diff --git a/patches/src/main/kotlin/app/revanced/patches/swissid/integritycheck/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/swissid/integritycheck/Fingerprints.kt index 0efa845fbe..6e55bd5f41 100644 --- a/patches/src/main/kotlin/app/revanced/patches/swissid/integritycheck/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/swissid/integritycheck/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.swissid.integritycheck import app.revanced.patcher.fingerprint -internal val checkIntegrityFingerprint = fingerprint { +internal val checkIntegrityFingerprint by fingerprint { returns("V") parameters("Lcom/swisssign/deviceintegrity/model/DeviceIntegrityResult;") strings("it", "result") diff --git a/patches/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/Fingerprints.kt index 4bd688de49..e198d21b18 100644 --- a/patches/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/Fingerprints.kt @@ -2,13 +2,13 @@ package app.revanced.patches.ticktick.misc.themeunlock import app.revanced.patcher.fingerprint -internal val checkLockedThemesFingerprint = fingerprint { +internal val checkLockedThemesFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("Theme;") && method.name == "isLockedTheme" } } -internal val setThemeFingerprint = fingerprint { +internal val setThemeFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("ThemePreviewActivity;") && method.name == "lambda\$updateUserBtn\$1" } diff --git a/patches/src/main/kotlin/app/revanced/patches/tiktok/feedfilter/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tiktok/feedfilter/Fingerprints.kt index 4f899661eb..f097734703 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tiktok/feedfilter/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tiktok/feedfilter/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.tiktok.feedfilter import app.revanced.patcher.fingerprint -internal val feedApiServiceLIZFingerprint = fingerprint { +internal val feedApiServiceLIZFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("/FeedApiService;") && method.name == "fetchFeedList" } diff --git a/patches/src/main/kotlin/app/revanced/patches/tiktok/interaction/cleardisplay/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tiktok/interaction/cleardisplay/Fingerprints.kt index eb28683743..43aab883c0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tiktok/interaction/cleardisplay/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tiktok/interaction/cleardisplay/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.tiktok.interaction.cleardisplay import app.revanced.patcher.fingerprint -internal val onClearDisplayEventFingerprint = fingerprint { +internal val onClearDisplayEventFingerprint by fingerprint { custom { method, classDef -> // Internally the feature is called "Clear mode". classDef.endsWith("/ClearModePanelComponent;") && method.name == "onClearModeEvent" diff --git a/patches/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/Fingerprints.kt index 160b49c158..5ab0efbbb6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.tiktok.interaction.downloads import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val aclCommonShareFingerprint = fingerprint { +internal val aclCommonShareFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("I") custom { method, classDef -> @@ -12,7 +12,7 @@ internal val aclCommonShareFingerprint = fingerprint { } } -internal val aclCommonShare2Fingerprint = fingerprint { +internal val aclCommonShare2Fingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("I") custom { method, classDef -> @@ -21,7 +21,7 @@ internal val aclCommonShare2Fingerprint = fingerprint { } } -internal val aclCommonShare3Fingerprint = fingerprint { +internal val aclCommonShare3Fingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("I") custom { method, classDef -> @@ -30,7 +30,7 @@ internal val aclCommonShare3Fingerprint = fingerprint { } } -internal val downloadUriFingerprint = fingerprint { +internal val downloadUriFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("Landroid/net/Uri;") parameters( diff --git a/patches/src/main/kotlin/app/revanced/patches/tiktok/interaction/seekbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tiktok/interaction/seekbar/Fingerprints.kt index ce372ea421..66fef7177f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tiktok/interaction/seekbar/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tiktok/interaction/seekbar/Fingerprints.kt @@ -2,10 +2,10 @@ package app.revanced.patches.tiktok.interaction.seekbar import app.revanced.patcher.fingerprint -internal val setSeekBarShowTypeFingerprint = fingerprint { +internal val setSeekBarShowTypeFingerprint by fingerprint { strings("seekbar show type change, change to:") } -internal val shouldShowSeekBarFingerprint = fingerprint { +internal val shouldShowSeekBarFingerprint by fingerprint { strings("can not show seekbar, state: 1, not in resume") } diff --git a/patches/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/Fingerprints.kt index 221036bb96..ab224a1cca 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/Fingerprints.kt @@ -3,13 +3,13 @@ package app.revanced.patches.tiktok.interaction.speed import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val getSpeedFingerprint = fingerprint { +internal val getSpeedFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("/BaseListFragmentPanel;") && method.name == "onFeedSpeedSelectedEvent" } } -internal val setSpeedFingerprint = fingerprint { +internal val setSpeedFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("V") parameters("Ljava/lang/String;", "Lcom/ss/android/ugc/aweme/feed/model/Aweme;", "F") diff --git a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/Fingerprints.kt index 929ef86729..439f63862b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/Fingerprints.kt @@ -2,14 +2,14 @@ package app.revanced.patches.tiktok.misc.login.disablerequirement import app.revanced.patcher.fingerprint -internal val mandatoryLoginServiceFingerprint = fingerprint { +internal val mandatoryLoginServiceFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("/MandatoryLoginService;") && method.name == "enableForcedLogin" } } -internal val mandatoryLoginService2Fingerprint = fingerprint { +internal val mandatoryLoginService2Fingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("/MandatoryLoginService;") && method.name == "shouldShowForcedLogin" diff --git a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/login/fixgoogle/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/login/fixgoogle/Fingerprints.kt index a40f5251f5..19d045db01 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/login/fixgoogle/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/login/fixgoogle/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.tiktok.misc.login.fixgoogle import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val googleAuthAvailableFingerprint = fingerprint { +internal val googleAuthAvailableFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") parameters() @@ -12,7 +12,7 @@ internal val googleAuthAvailableFingerprint = fingerprint { } } -internal val googleOneTapAuthAvailableFingerprint = fingerprint { +internal val googleOneTapAuthAvailableFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") parameters() diff --git a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/Fingerprints.kt index d1c4d6de68..4317948c41 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/Fingerprints.kt @@ -2,32 +2,32 @@ package app.revanced.patches.tiktok.misc.settings import app.revanced.patcher.fingerprint -internal val addSettingsEntryFingerprint = fingerprint { +internal val addSettingsEntryFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("/SettingNewVersionFragment;") && method.name == "initUnitManger" } } -internal val adPersonalizationActivityOnCreateFingerprint = fingerprint { +internal val adPersonalizationActivityOnCreateFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("/AdPersonalizationActivity;") && method.name == "onCreate" } } -internal val settingsEntryFingerprint = fingerprint { +internal val settingsEntryFingerprint by fingerprint { strings("pls pass item or extends the EventUnit") } -internal val settingsEntryInfoFingerprint = fingerprint { +internal val settingsEntryInfoFingerprint by fingerprint { strings( "ExposeItem(title=", ", icon=", ) } -internal val settingsStatusLoadFingerprint = fingerprint { +internal val settingsStatusLoadFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("Lapp/revanced/extension/tiktok/settings/SettingsStatus;") && method.name == "load" diff --git a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/spoof/sim/SpoofSimPatch.kt b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/spoof/sim/SpoofSimPatch.kt index 40a45650de..b069b88f55 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/spoof/sim/SpoofSimPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/spoof/sim/SpoofSimPatch.kt @@ -69,7 +69,7 @@ val spoofSimPatch = bytecodePatch( } } }.forEach { (classDef, methods) -> - with(proxy(classDef).mutableClass) { + with(mutableClassBy(classDef)) { methods.forEach { (method, patches) -> with(findMutableMethodOf(method)) { while (!patches.isEmpty()) { diff --git a/patches/src/main/kotlin/app/revanced/patches/tiktok/shared/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tiktok/shared/Fingerprints.kt index 3e98d213e5..508d469645 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tiktok/shared/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tiktok/shared/Fingerprints.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val getEnterFromFingerprint = fingerprint { +internal val getEnterFromFingerprint by fingerprint { returns("Ljava/lang/String;") accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters("Z") @@ -22,7 +22,7 @@ internal val getEnterFromFingerprint = fingerprint { } } -internal val onRenderFirstFrameFingerprint = fingerprint { +internal val onRenderFirstFrameFingerprint by fingerprint { strings("method_enable_viewpager_preload_duration") custom { _, classDef -> classDef.endsWith("/BaseListFragmentPanel;") diff --git a/patches/src/main/kotlin/app/revanced/patches/trakt/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/trakt/Fingerprints.kt index 4a02c62215..0d985d88c7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/trakt/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/trakt/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.trakt import app.revanced.patcher.fingerprint -internal val isVIPEPFingerprint = fingerprint { +internal val isVIPEPFingerprint by fingerprint { custom { method, classDef -> if (!classDef.endsWith("RemoteUser;")) return@custom false @@ -10,7 +10,7 @@ internal val isVIPEPFingerprint = fingerprint { } } -internal val isVIPFingerprint = fingerprint { +internal val isVIPFingerprint by fingerprint { custom { method, classDef -> if (!classDef.endsWith("RemoteUser;")) return@custom false @@ -18,7 +18,7 @@ internal val isVIPFingerprint = fingerprint { } } -internal val remoteUserFingerprint = fingerprint { +internal val remoteUserFingerprint by fingerprint { custom { _, classDef -> classDef.endsWith("RemoteUser;") } diff --git a/patches/src/main/kotlin/app/revanced/patches/tudortmund/lockscreen/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tudortmund/lockscreen/Fingerprints.kt index 12ffa15c15..0cd634ee1b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tudortmund/lockscreen/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tudortmund/lockscreen/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.tudortmund.lockscreen import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val brightnessFingerprint = fingerprint { +internal val brightnessFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC) returns("V") parameters() diff --git a/patches/src/main/kotlin/app/revanced/patches/tumblr/annoyances/notifications/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tumblr/annoyances/notifications/Fingerprints.kt index 67e051a7ba..525f5a5e74 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tumblr/annoyances/notifications/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tumblr/annoyances/notifications/Fingerprints.kt @@ -6,6 +6,6 @@ import app.revanced.patcher.fingerprint // It shows whenever you visit a certain blog for the second time and disables itself // if it was shown a total of 3 times (stored in app storage). // This targets the BlogNotifyCtaDialog.isEnabled() method to let it always return false. -internal val isBlogNotifyEnabledFingerprint = fingerprint { +internal val isBlogNotifyEnabledFingerprint by fingerprint { strings("isEnabled --> ", "blog_notify_enabled") } diff --git a/patches/src/main/kotlin/app/revanced/patches/tumblr/annoyances/popups/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tumblr/annoyances/popups/Fingerprints.kt index 7d00f2f1bd..2be1a3cefb 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tumblr/annoyances/popups/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tumblr/annoyances/popups/Fingerprints.kt @@ -4,7 +4,7 @@ import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint // This method is responsible for loading and displaying the visual Layout of the Gift Message Popup. -internal val showGiftMessagePopupFingerprint = fingerprint { +internal val showGiftMessagePopupFingerprint by fingerprint { accessFlags(AccessFlags.FINAL, AccessFlags.PUBLIC) returns("V") strings("activity", "anchorView", "textMessage") diff --git a/patches/src/main/kotlin/app/revanced/patches/tumblr/featureflags/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tumblr/featureflags/Fingerprints.kt index e24ca2884a..742a8fd4d2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tumblr/featureflags/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tumblr/featureflags/Fingerprints.kt @@ -13,7 +13,7 @@ import app.revanced.patcher.fingerprint // Some features seem to be very old and never removed, though, such as Google Login. // The startIndex of the opcode pattern is at the start of the function after the arg null check. // we want to insert our instructions there. -internal val getFeatureValueFingerprint = fingerprint { +internal val getFeatureValueFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Ljava/lang/String;") parameters("L", "Z") diff --git a/patches/src/main/kotlin/app/revanced/patches/tumblr/featureflags/OverrideFeatureFlagsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/tumblr/featureflags/OverrideFeatureFlagsPatch.kt index c2da658aad..06f7d44379 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tumblr/featureflags/OverrideFeatureFlagsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tumblr/featureflags/OverrideFeatureFlagsPatch.kt @@ -69,7 +69,7 @@ val overrideFeatureFlagsPatch = bytecodePatch( // This is equivalent to // String forcedValue = getValueOverride(feature) // if (forcedValue != null) return forcedValue - val getFeatureIndex = getFeatureValueFingerprint.patternMatch!!.startIndex + val getFeatureIndex = getFeatureValueFingerprint.instructionMatches.first().index getFeatureValueFingerprint.method.addInstructionsWithLabels( getFeatureIndex, """ diff --git a/patches/src/main/kotlin/app/revanced/patches/tumblr/fixes/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tumblr/fixes/Fingerprints.kt index 11616fcc92..8d9f4cfd3d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tumblr/fixes/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tumblr/fixes/Fingerprints.kt @@ -6,7 +6,7 @@ import app.revanced.patcher.fingerprint // Fingerprint for the addQueryParam method from retrofit2 // https://github.com/square/retrofit/blob/trunk/retrofit/src/main/java/retrofit2/RequestBuilder.java#L186 // Injecting here allows modifying dynamically set query parameters -internal val addQueryParamFingerprint = fingerprint { +internal val addQueryParamFingerprint by fingerprint { parameters("Ljava/lang/String;", "Ljava/lang/String;", "Z") strings("Malformed URL. Base: ", ", Relative: ") } @@ -14,7 +14,7 @@ internal val addQueryParamFingerprint = fingerprint { // Fingerprint for the parseHttpMethodAndPath method from retrofit2 // https://github.com/square/retrofit/blob/ebf87b10997e2136af4d335276fa950221852c64/retrofit/src/main/java/retrofit2/RequestFactory.java#L270-L302 // Injecting here allows modifying the path/query params of API endpoints defined via annotations -internal val httpPathParserFingerprint = fingerprint { +internal val httpPathParserFingerprint by fingerprint { opcodes( Opcode.IPUT_OBJECT, Opcode.IPUT_BOOLEAN, diff --git a/patches/src/main/kotlin/app/revanced/patches/tumblr/fixes/FixOldVersionsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/tumblr/fixes/FixOldVersionsPatch.kt index dbe75d5f8b..ad9f52f4b0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tumblr/fixes/FixOldVersionsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tumblr/fixes/FixOldVersionsPatch.kt @@ -21,7 +21,7 @@ val fixOldVersionsPatch = bytecodePatch( // Remove the live query parameters from the path when it's specified via a @METHOD annotation. for (liveQueryParameter in liveQueryParameters) { httpPathParserFingerprint.method.addInstructions( - httpPathParserFingerprint.patternMatch!!.endIndex + 1, + httpPathParserFingerprint.instructionMatches.last().index + 1, """ # urlPath = urlPath.replace(liveQueryParameter, "") const-string p1, "$liveQueryParameter" diff --git a/patches/src/main/kotlin/app/revanced/patches/tumblr/timelinefilter/FilterTimelineObjectsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/tumblr/timelinefilter/FilterTimelineObjectsPatch.kt index c4ab799e85..68f3022f6d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tumblr/timelinefilter/FilterTimelineObjectsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tumblr/timelinefilter/FilterTimelineObjectsPatch.kt @@ -24,7 +24,7 @@ val filterTimelineObjectsPatch = bytecodePatch( dependsOn(sharedExtensionPatch) execute { - val filterInsertIndex = timelineFilterExtensionFingerprint.patternMatch!!.startIndex + val filterInsertIndex = timelineFilterExtensionFingerprint.instructionMatches.first().index timelineFilterExtensionFingerprint.method.apply { val addInstruction = getInstruction(filterInsertIndex + 1) diff --git a/patches/src/main/kotlin/app/revanced/patches/tumblr/timelinefilter/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tumblr/timelinefilter/Fingerprints.kt index b8ed3bfc4e..75be30004a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tumblr/timelinefilter/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tumblr/timelinefilter/Fingerprints.kt @@ -6,7 +6,7 @@ import com.android.tools.smali.dexlib2.Opcode // This is the constructor of the PostsResponse class. // The same applies here as with the TimelineConstructorFingerprint. -internal val postsResponseConstructorFingerprint = fingerprint { +internal val postsResponseConstructorFingerprint by fingerprint { accessFlags(AccessFlags.CONSTRUCTOR, AccessFlags.PUBLIC) custom { method, classDef -> classDef.endsWith("/PostsResponse;") && method.parameters.size == 4 } } @@ -14,7 +14,7 @@ internal val postsResponseConstructorFingerprint = fingerprint { // This is the constructor of the Timeline class. // It receives the List as an argument with a @Json annotation, so this should be the first time // that the List is exposed in non-library code. -internal val timelineConstructorFingerprint = fingerprint { +internal val timelineConstructorFingerprint by fingerprint { strings("timelineObjectsList") custom { method, classDef -> classDef.endsWith("/Timeline;") && method.parameters[0].type == "Ljava/util/List;" @@ -24,7 +24,7 @@ internal val timelineConstructorFingerprint = fingerprint { // This fingerprints the extension TimelineFilterPatch.filterTimeline method. // The opcode fingerprint is searching for // if ("BLOCKED_OBJECT_DUMMY".equals(elementType)) iterator.remove(); -internal val timelineFilterExtensionFingerprint = fingerprint { +internal val timelineFilterExtensionFingerprint by fingerprint { opcodes( Opcode.CONST_STRING, // "BLOCKED_OBJECT_DUMMY" Opcode.INVOKE_VIRTUAL, // HashSet.add(^) diff --git a/patches/src/main/kotlin/app/revanced/patches/twitch/ad/audio/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/twitch/ad/audio/Fingerprints.kt index 21e9cb6d2a..3bae02166c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitch/ad/audio/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitch/ad/audio/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.twitch.ad.audio import app.revanced.patcher.fingerprint -internal val audioAdsPresenterPlayFingerprint = fingerprint { +internal val audioAdsPresenterPlayFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("AudioAdsPlayerPresenter;") && method.name == "playAd" } diff --git a/patches/src/main/kotlin/app/revanced/patches/twitch/ad/embedded/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/twitch/ad/embedded/Fingerprints.kt index 3e9853bd61..209f91d2b2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitch/ad/embedded/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitch/ad/embedded/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.twitch.ad.embedded import app.revanced.patcher.fingerprint -internal val createsUsherClientFingerprint = fingerprint { +internal val createsUsherClientFingerprint by fingerprint { custom { method, _ -> method.name == "buildOkHttpClient" && method.definingClass.endsWith("Ltv/twitch/android/network/OkHttpClientFactory;") } diff --git a/patches/src/main/kotlin/app/revanced/patches/twitch/ad/shared/util/AdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/twitch/ad/shared/util/AdPatch.kt index 48ecefba8e..2cf8e55925 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitch/ad/shared/util/AdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitch/ad/shared/util/AdPatch.kt @@ -29,7 +29,7 @@ fun adPatch( classDefType: String, methodNames: Set, returnMethod: ReturnMethod, - ) = with(classBy { classDefType == it.type }?.mutableClass) { + ) = with(mutableClassByOrNull(classDefType)) { this ?: return false methods.filter { it.name in methodNames }.forEach { diff --git a/patches/src/main/kotlin/app/revanced/patches/twitch/ad/video/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/twitch/ad/video/Fingerprints.kt index d03449733f..4bd8abb2a0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitch/ad/video/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitch/ad/video/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.twitch.ad.video import app.revanced.patcher.fingerprint -internal val checkAdEligibilityLambdaFingerprint = fingerprint { +internal val checkAdEligibilityLambdaFingerprint by fingerprint { returns("Lio/reactivex/Single;") parameters("L") custom { method, _ -> @@ -11,7 +11,7 @@ internal val checkAdEligibilityLambdaFingerprint = fingerprint { } } -internal val contentConfigShowAdsFingerprint = fingerprint { +internal val contentConfigShowAdsFingerprint by fingerprint { returns("Z") parameters() custom { method, _ -> @@ -19,7 +19,7 @@ internal val contentConfigShowAdsFingerprint = fingerprint { } } -internal val getReadyToShowAdFingerprint = fingerprint { +internal val getReadyToShowAdFingerprint by fingerprint { returns("Ltv/twitch/android/core/mvp/presenter/StateAndAction;") parameters("L", "L") custom { method, _ -> diff --git a/patches/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/Fingerprints.kt index 21da99a5bb..04ef723432 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/Fingerprints.kt @@ -3,21 +3,20 @@ package app.revanced.patches.twitch.chat.antidelete import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val chatUtilCreateDeletedSpanFingerprint = fingerprint { +internal val chatUtilCreateDeletedSpanFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("ChatUtil\$Companion;") && method.name == "createDeletedSpanFromChatMessageSpan" } } -internal val deletedMessageClickableSpanCtorFingerprint = fingerprint { +internal val deletedMessageClickableSpanCtorFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - returns("V") custom { _, classDef -> classDef.endsWith("DeletedMessageClickableSpan;") } } -internal val setHasModAccessFingerprint = fingerprint { +internal val setHasModAccessFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("DeletedMessageClickableSpan;") && method.name == "setHasModAccess" } diff --git a/patches/src/main/kotlin/app/revanced/patches/twitch/chat/autoclaim/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/twitch/chat/autoclaim/Fingerprints.kt index 80abc9ac41..59986152c0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitch/chat/autoclaim/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitch/chat/autoclaim/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.twitch.chat.autoclaim import app.revanced.patcher.fingerprint -internal val communityPointsButtonViewDelegateFingerprint = fingerprint { +internal val communityPointsButtonViewDelegateFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("CommunityPointsButtonViewDelegate;") && method.name == "showClaimAvailable" diff --git a/patches/src/main/kotlin/app/revanced/patches/twitch/debug/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/twitch/debug/Fingerprints.kt index 665180c19b..49a8601f26 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitch/debug/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitch/debug/Fingerprints.kt @@ -2,19 +2,19 @@ package app.revanced.patches.twitch.debug import app.revanced.patcher.fingerprint -internal val isDebugConfigEnabledFingerprint = fingerprint { +internal val isDebugConfigEnabledFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("/BuildConfigUtil;") && method.name == "isDebugConfigEnabled" } } -internal val isOmVerificationEnabledFingerprint = fingerprint { +internal val isOmVerificationEnabledFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("/BuildConfigUtil;") && method.name == "isOmVerificationEnabled" } } -internal val shouldShowDebugOptionsFingerprint = fingerprint { +internal val shouldShowDebugOptionsFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("/BuildConfigUtil;") && method.name == "shouldShowDebugOptions" } diff --git a/patches/src/main/kotlin/app/revanced/patches/twitch/misc/settings/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/twitch/misc/settings/Fingerprints.kt index 43d5bb39bf..f39c762e94 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitch/misc/settings/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitch/misc/settings/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.twitch.misc.settings import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val menuGroupsOnClickFingerprint = fingerprint { +internal val menuGroupsOnClickFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC, AccessFlags.FINAL) returns("V") parameters("L", "L", "L") @@ -13,21 +13,21 @@ internal val menuGroupsOnClickFingerprint = fingerprint { } } -internal val menuGroupsUpdatedFingerprint = fingerprint { +internal val menuGroupsUpdatedFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("/SettingsMenuPresenter\$Event\$MenuGroupsUpdated;") && method.name == "" } } -internal val settingsActivityOnCreateFingerprint = fingerprint { +internal val settingsActivityOnCreateFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("/SettingsActivity;") && method.name == "onCreate" } } -internal val settingsMenuItemEnumFingerprint = fingerprint { +internal val settingsMenuItemEnumFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("/SettingsMenuItem;") && method.name == "" } diff --git a/patches/src/main/kotlin/app/revanced/patches/twitter/interaction/downloads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/twitter/interaction/downloads/Fingerprints.kt index dc100acb10..b01f75081f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitter/interaction/downloads/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitter/interaction/downloads/Fingerprints.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val buildMediaOptionsSheetFingerprint = fingerprint { +internal val buildMediaOptionsSheetFingerprint by fingerprint { opcodes( Opcode.IF_EQ, Opcode.SGET_OBJECT, @@ -14,13 +14,12 @@ internal val buildMediaOptionsSheetFingerprint = fingerprint { strings("mediaEntity", "media_options_sheet") } -internal val constructMediaOptionsSheetFingerprint = fingerprint { +internal val constructMediaOptionsSheetFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - returns("V") strings("captionsState") } -internal val showDownloadVideoUpsellBottomSheetFingerprint = fingerprint { +internal val showDownloadVideoUpsellBottomSheetFingerprint by fingerprint { returns("Z") strings("mediaEntity", "url") opcodes(Opcode.IF_EQZ) diff --git a/patches/src/main/kotlin/app/revanced/patches/twitter/interaction/downloads/UnlockDownloadsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/twitter/interaction/downloads/UnlockDownloadsPatch.kt index 6f2b9c12c7..945f0a47b9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitter/interaction/downloads/UnlockDownloadsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitter/interaction/downloads/UnlockDownloadsPatch.kt @@ -27,7 +27,7 @@ val unlockDownloadsPatch = bytecodePatch( // Allow downloads for non-premium users. showDownloadVideoUpsellBottomSheetFingerprint.patch { - val checkIndex = patternMatch!!.startIndex + val checkIndex = instructionMatches.first().index val register = method.getInstruction(checkIndex).registerA checkIndex to register @@ -42,25 +42,26 @@ val unlockDownloadsPatch = bytecodePatch( } // Make GIFs downloadable. - val patternMatch = buildMediaOptionsSheetFingerprint.patternMatch!! - buildMediaOptionsSheetFingerprint.method.apply { - val checkMediaTypeIndex = patternMatch.startIndex - val checkMediaTypeInstruction = getInstruction(checkMediaTypeIndex) + buildMediaOptionsSheetFingerprint.let { + it.method.apply { + val checkMediaTypeIndex = it.instructionMatches.first().index + val checkMediaTypeInstruction = getInstruction(checkMediaTypeIndex) - // Treat GIFs as videos. - addInstructionsWithLabels( - checkMediaTypeIndex + 1, - """ + // Treat GIFs as videos. + addInstructionsWithLabels( + checkMediaTypeIndex + 1, + """ const/4 v${checkMediaTypeInstruction.registerB}, 0x2 # GIF if-eq v${checkMediaTypeInstruction.registerA}, v${checkMediaTypeInstruction.registerB}, :video """, - ExternalLabel("video", getInstruction(patternMatch.endIndex)), - ) + ExternalLabel("video", getInstruction(it.instructionMatches.last().index)), + ) - // Remove media.isDownloadable check. - removeInstruction( - instructions.first { it.opcode == Opcode.IGET_BOOLEAN }.location.index + 1, - ) + // Remove media.isDownloadable check. + removeInstruction( + instructions.first { it.opcode == Opcode.IGET_BOOLEAN }.location.index + 1, + ) + } } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/twitter/layout/viewcount/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/twitter/layout/viewcount/Fingerprints.kt index 625b6f0bb7..199ef49c2a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitter/layout/viewcount/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitter/layout/viewcount/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.twitter.layout.viewcount import app.revanced.patcher.fingerprint -internal val viewCountsEnabledFingerprint = fingerprint { +internal val viewCountsEnabledFingerprint by fingerprint { returns("Z") strings("view_counts_public_visibility_enabled") } diff --git a/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/Fingerprints.kt index 337aeb5670..1158df15d5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.twitter.misc.hook.json import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.Opcode -internal val jsonHookPatchFingerprint = fingerprint { +internal val jsonHookPatchFingerprint by fingerprint { opcodes( Opcode.INVOKE_INTERFACE, // Add dummy hook to hooks list. // Add hooks to the hooks list. @@ -12,7 +12,7 @@ internal val jsonHookPatchFingerprint = fingerprint { custom { method, _ -> method.name == "" } } -internal val jsonInputStreamFingerprint = fingerprint { +internal val jsonInputStreamFingerprint by fingerprint { custom { method, _ -> if (method.parameterTypes.isEmpty()) { false @@ -22,6 +22,6 @@ internal val jsonInputStreamFingerprint = fingerprint { } } -internal val loganSquareFingerprint = fingerprint { +internal val loganSquareFingerprint by fingerprint { custom { _, classDef -> classDef.endsWith("LoganSquare;") } } diff --git a/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/JsonHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/JsonHookPatch.kt index 56785cae4c..d3e95102fa 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/JsonHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/JsonHookPatch.kt @@ -22,7 +22,7 @@ fun addJsonHook( jsonHookPatchFingerprint.method.apply { // Insert hooks right before calling buildList. - val insertIndex = jsonHookPatchFingerprint.patternMatch!!.endIndex + val insertIndex = jsonHookPatchFingerprint.instructionMatches.last().index addInstructions( insertIndex, @@ -48,11 +48,9 @@ val jsonHookPatch = bytecodePatch( execute { jsonHookPatchFingerprint.apply { - // Make sure the extension is present. - val jsonHookPatch = classBy { classDef -> classDef.type == JSON_HOOK_PATCH_CLASS_DESCRIPTOR } - ?: throw PatchException("Could not find the extension.") + val jsonHookPatch = classBy(JSON_HOOK_PATCH_CLASS_DESCRIPTOR) - matchOrNull(jsonHookPatch.immutableClass) + matchOrNull(jsonHookPatch) ?: throw PatchException("Unexpected extension.") } @@ -61,7 +59,7 @@ val jsonHookPatch = bytecodePatch( .fields .firstOrNull { it.name == "JSON_FACTORY" } ?.type - .let { type -> classes.find { it.type == type } } + ?.let { type -> classes.classBy(type) } ?: throw PatchException("Could not find required class.") // Hook the methods first parameter. @@ -77,7 +75,7 @@ val jsonHookPatch = bytecodePatch( finalize { // Remove hooks.add(dummyHook). jsonHookPatchFingerprint.method.apply { - val addDummyHookIndex = jsonHookPatchFingerprint.patternMatch!!.endIndex - 2 + val addDummyHookIndex = jsonHookPatchFingerprint.instructionMatches.last().index - 2 removeInstructions(addDummyHookIndex, 2) } @@ -99,8 +97,8 @@ class JsonHook( internal var added = false init { - classBy { it.type == descriptor }?.let { - it.mutableClass.also { classDef -> + mutableClassBy(descriptor).let { + it.also { classDef -> if ( classDef.superclass != JSON_HOOK_CLASS_DESCRIPTOR || !classDef.fields.any { field -> field.name == "INSTANCE" } @@ -108,6 +106,6 @@ class JsonHook( throw InvalidClassException(classDef.type, "Not a hook class") } } - } ?: throw ClassNotFoundException("Failed to find hook class $descriptor") + } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/twitter/misc/links/ChangeLinkSharingDomainPatch.kt b/patches/src/main/kotlin/app/revanced/patches/twitter/misc/links/ChangeLinkSharingDomainPatch.kt index 6780f25aa8..c5026315d4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitter/misc/links/ChangeLinkSharingDomainPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitter/misc/links/ChangeLinkSharingDomainPatch.kt @@ -6,9 +6,8 @@ import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.patch.stringOption -import app.revanced.patches.shared.misc.mapping.get +import app.revanced.patches.shared.misc.mapping.getResourceId import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.twitter.misc.extension.sharedExtensionPatch import app.revanced.util.indexOfFirstLiteralInstructionOrThrow import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction @@ -21,7 +20,7 @@ internal val changeLinkSharingDomainResourcePatch = resourcePatch { dependsOn(resourceMappingPatch) execute { - tweetShareLinkTemplateId = resourceMappings["string", "tweet_share_link"] + tweetShareLinkTemplateId = getResourceId("string", "tweet_share_link") } } @@ -49,7 +48,7 @@ val changeLinkSharingDomainPatch = bytecodePatch( execute { val replacementIndex = - linkSharingDomainFingerprint.stringMatches!!.first().index + linkSharingDomainFingerprint.stringMatches.first().index val domainRegister = linkSharingDomainFingerprint.method.getInstruction(replacementIndex).registerA diff --git a/patches/src/main/kotlin/app/revanced/patches/twitter/misc/links/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/twitter/misc/links/Fingerprints.kt index 0d5d0e6f80..abbf40e890 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitter/misc/links/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitter/misc/links/Fingerprints.kt @@ -4,28 +4,28 @@ import app.revanced.patcher.fingerprint import app.revanced.util.literal import com.android.tools.smali.dexlib2.AccessFlags -internal val openLinkFingerprint = fingerprint { +internal val openLinkFingerprint by fingerprint { returns("V") parameters("Landroid/content/Context;", "Landroid/content/Intent;", "Landroid/os/Bundle;") } -internal val sanitizeSharingLinksFingerprint = fingerprint { +internal val sanitizeSharingLinksFingerprint by fingerprint { returns("Ljava/lang/String;") strings("", "shareParam", "sessionToken") } // Returns a shareable link string based on a tweet ID and a username. -internal val linkBuilderFingerprint = fingerprint { +internal val linkBuilderFingerprint by fingerprint { strings("/%1\$s/status/%2\$d") } // Gets Resource string for share link view available by pressing "Share via" button. -internal val linkResourceGetterFingerprint = fingerprint { +internal val linkResourceGetterFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters("Landroid/content/res/Resources;") literal { tweetShareLinkTemplateId } } -internal val linkSharingDomainFingerprint = fingerprint { +internal val linkSharingDomainFingerprint by fingerprint { strings("https://fxtwitter.com") } diff --git a/patches/src/main/kotlin/app/revanced/patches/vsco/misc/pro/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/vsco/misc/pro/Fingerprints.kt deleted file mode 100644 index 0809324c7f..0000000000 --- a/patches/src/main/kotlin/app/revanced/patches/vsco/misc/pro/Fingerprints.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.vsco.misc.pro - -import app.revanced.patcher.fingerprint - -internal val revCatSubscriptionFingerprint = fingerprint { - returns("V") - strings("use_debug_subscription_settings") - custom { _, classDef -> - classDef.endsWith("/RevCatSubscriptionSettingsRepository;") - } -} diff --git a/patches/src/main/kotlin/app/revanced/patches/vsco/misc/pro/UnlockProPatch.kt b/patches/src/main/kotlin/app/revanced/patches/vsco/misc/pro/UnlockProPatch.kt deleted file mode 100644 index be0278dd9e..0000000000 --- a/patches/src/main/kotlin/app/revanced/patches/vsco/misc/pro/UnlockProPatch.kt +++ /dev/null @@ -1,17 +0,0 @@ -package app.revanced.patches.vsco.misc.pro - -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.patch.bytecodePatch - -@Deprecated("This patch is deprecated because it does not work anymore and will be removed in the future.") -@Suppress("unused") -val unlockProPatch = bytecodePatch( - description = "Unlocks pro features.", -) { - compatibleWith("com.vsco.cam"("345")) - - execute { - // Set isSubscribed to true. - revCatSubscriptionFingerprint.method.addInstruction(0, "const p1, 0x1") - } -} diff --git a/patches/src/main/kotlin/app/revanced/patches/warnwetter/misc/firebasegetcert/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/warnwetter/misc/firebasegetcert/Fingerprints.kt index 6eb7bd176b..03ff60e0c0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/warnwetter/misc/firebasegetcert/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/warnwetter/misc/firebasegetcert/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.warnwetter.misc.firebasegetcert import app.revanced.patcher.fingerprint -internal val getMessagingCertFingerprint = fingerprint { +internal val getMessagingCertFingerprint by fingerprint { returns("Ljava/lang/String;") strings( "ContentValues", @@ -11,7 +11,7 @@ internal val getMessagingCertFingerprint = fingerprint { ) } -internal val getRegistrationCertFingerprint = fingerprint { +internal val getRegistrationCertFingerprint by fingerprint { returns("Ljava/lang/String;") strings( "FirebaseRemoteConfig", diff --git a/patches/src/main/kotlin/app/revanced/patches/warnwetter/misc/promocode/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/warnwetter/misc/promocode/Fingerprints.kt index d33880de70..0249856381 100644 --- a/patches/src/main/kotlin/app/revanced/patches/warnwetter/misc/promocode/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/warnwetter/misc/promocode/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.warnwetter.misc.promocode import app.revanced.patcher.fingerprint -internal val promoCodeUnlockFingerprint = fingerprint { +internal val promoCodeUnlockFingerprint by fingerprint { custom { method, classDef -> classDef.endsWith("PromoTokenVerification;") && method.name == "isValid" } diff --git a/patches/src/main/kotlin/app/revanced/patches/willhaben/ads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/willhaben/ads/Fingerprints.kt index e326c26825..19fdb02d85 100644 --- a/patches/src/main/kotlin/app/revanced/patches/willhaben/ads/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/willhaben/ads/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.willhaben.ads import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val adResolverFingerprint = fingerprint { +internal val adResolverFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("L") parameters("L", "L") @@ -15,7 +15,7 @@ internal val adResolverFingerprint = fingerprint { ) } -internal val whAdViewInjectorFingerprint = fingerprint { +internal val whAdViewInjectorFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L", "L", "L", "Z") diff --git a/patches/src/main/kotlin/app/revanced/patches/windyapp/misc/unlockpro/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/windyapp/misc/unlockpro/Fingerprints.kt deleted file mode 100644 index f199f127c7..0000000000 --- a/patches/src/main/kotlin/app/revanced/patches/windyapp/misc/unlockpro/Fingerprints.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.windyapp.misc.unlockpro - -import app.revanced.patcher.fingerprint - -internal val checkProFingerprint = fingerprint { - returns("I") - custom { method, classDef -> - classDef.endsWith("RawUserData;") && method.name == "isPro" - } -} diff --git a/patches/src/main/kotlin/app/revanced/patches/windyapp/misc/unlockpro/UnlockProPatch.kt b/patches/src/main/kotlin/app/revanced/patches/windyapp/misc/unlockpro/UnlockProPatch.kt deleted file mode 100644 index c0323c72ed..0000000000 --- a/patches/src/main/kotlin/app/revanced/patches/windyapp/misc/unlockpro/UnlockProPatch.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.windyapp.misc.unlockpro - -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.patch.bytecodePatch - -@Deprecated("This patch no longer works and will be removed in the future.") -@Suppress("unused") -val unlockProPatch = bytecodePatch( - description = "Unlocks all pro features.", -) { - compatibleWith("co.windyapp.android") - - execute { - checkProFingerprint.method.addInstructions( - 0, - """ - const/16 v0, 0x1 - return v0 - """, - ) - } -} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/Fingerprints.kt index 254b440f39..8091108cfc 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/Fingerprints.kt @@ -8,7 +8,7 @@ import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.reference.MethodReference -internal val fullScreenEngagementAdContainerFingerprint = fingerprint { +internal val fullScreenEngagementAdContainerFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters() diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt index a36d3ff5d1..ae6cc33bd0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt @@ -7,9 +7,8 @@ import app.revanced.patcher.patch.resourcePatch import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.shared.misc.fix.verticalscroll.verticalScrollPatch -import app.revanced.patches.shared.misc.mapping.get +import app.revanced.patches.shared.misc.mapping.getResourceId import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.ad.getpremium.hideGetPremiumPatch import app.revanced.patches.youtube.misc.fix.backtoexitgesture.fixBackToExitGesturePatch @@ -59,8 +58,8 @@ private val hideAdsResourcePatch = resourcePatch { addLithoFilter("Lapp/revanced/extension/youtube/patches/components/AdsFilter;") - adAttributionId = resourceMappings["id", "ad_attribution"] - fullScreenEngagementAdContainer = resourceMappings["id", "fullscreen_engagement_ad_container"] + adAttributionId = getResourceId("id", "ad_attribution") + fullScreenEngagementAdContainer = getResourceId("id", "fullscreen_engagement_ad_container") } } @@ -128,8 +127,7 @@ val hideAdsPatch = bytecodePatch( // Hide the view val viewRegister = (this as Instruction35c).registerC - proxy(classDef) - .mutableClass + mutableClassBy(classDef) .findMutableMethodOf(method) .injectHideViewCall( insertIndex, diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/Fingerprints.kt index 7629d1760d..284567fec7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/Fingerprints.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val getPremiumViewFingerprint = fingerprint { +internal val getPremiumViewFingerprint by fingerprint { accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL) returns("V") parameters("I", "I") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt index c4fb21b15c..8f82b1a93d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt @@ -43,7 +43,7 @@ val hideGetPremiumPatch = bytecodePatch( ) getPremiumViewFingerprint.method.apply { - val startIndex = getPremiumViewFingerprint.patternMatch!!.startIndex + val startIndex = getPremiumViewFingerprint.instructionMatches.first().index val measuredWidthRegister = getInstruction(startIndex).registerA val measuredHeightInstruction = getInstruction(startIndex + 1) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/video/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/video/Fingerprints.kt index 91cc0e8dfa..bbed5305ee 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/video/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/video/Fingerprints.kt @@ -2,7 +2,7 @@ package app.revanced.patches.youtube.ad.video import app.revanced.patcher.fingerprint -internal val loadVideoAdsFingerprint = fingerprint { +internal val loadVideoAdsFingerprint by fingerprint { strings( "TriggerBundle doesn't have the required metadata specified by the trigger ", "Tried to enter slot with no assigned slotAdapter", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/Fingerprints.kt index b252875901..4e010f2ada 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/Fingerprints.kt @@ -4,7 +4,7 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val createDialogFingerprint = fingerprint { +internal val createDialogFingerprint by fingerprint { accessFlags(AccessFlags.PROTECTED) returns("V") parameters("L", "L", "Ljava/lang/String;") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt index 8e5c95f244..dbfc483db4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt @@ -14,7 +14,7 @@ import app.revanced.patches.shared.misc.settings.preference.TextPreference import app.revanced.patches.youtube.misc.playercontrols.* import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch -import app.revanced.patches.youtube.shared.mainActivityFingerprint +import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint import app.revanced.patches.youtube.video.information.videoInformationPatch import app.revanced.util.ResourceGroup import app.revanced.util.copyResources @@ -83,12 +83,10 @@ val downloadsPatch = bytecodePatch( injectVisibilityCheckCall(BUTTON_DESCRIPTOR) // Main activity is used to launch downloader intent. - mainActivityFingerprint.method.apply { - addInstruction( - implementation!!.instructions.lastIndex, - "invoke-static { p0 }, $EXTENSION_CLASS_DESCRIPTOR->activityCreated(Landroid/app/Activity;)V", - ) - } + mainActivityOnCreateFingerprint.method.addInstruction( + 1, + "invoke-static/range { p0 .. p0 }, ${EXTENSION_CLASS_DESCRIPTOR}->setMainActivity(Landroid/app/Activity;)V", + ) offlineVideoEndpointFingerprint.method.apply { addInstructionsWithLabels( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/Fingerprints.kt index f10fc8e834..abd9a1e125 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/Fingerprints.kt @@ -1,9 +1,10 @@ package app.revanced.patches.youtube.interaction.downloads -import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint +import app.revanced.patcher.string +import com.android.tools.smali.dexlib2.AccessFlags -internal val offlineVideoEndpointFingerprint = fingerprint { +internal val offlineVideoEndpointFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters( @@ -12,5 +13,7 @@ internal val offlineVideoEndpointFingerprint = fingerprint { "Ljava/lang/String", // VideoId "L", ) - strings("Object is not an offlineable video: ") + instructions( + string("Object is not an offlineable video: ") + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt index 48c4b74685..32cea58d56 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt @@ -44,17 +44,17 @@ val enableSeekbarTappingPatch = bytecodePatch( ) // Find the required methods to tap the seekbar. - val patternMatch = onTouchEventHandlerFingerprint.patternMatch!! + val instructionMatches = onTouchEventHandlerFingerprint.instructionMatches fun getReference(index: Int) = onTouchEventHandlerFingerprint.method.getInstruction(index) .reference as MethodReference val seekbarTappingMethods = buildMap { - put("N", getReference(patternMatch.startIndex)) - put("O", getReference(patternMatch.endIndex)) + put("N", getReference(instructionMatches.first().index)) + put("O", getReference(instructionMatches.last().index)) } - val insertIndex = seekbarTappingFingerprint.patternMatch!!.endIndex - 1 + val insertIndex = seekbarTappingFingerprint.instructionMatches.last().index - 1 seekbarTappingFingerprint.method.apply { val thisInstanceRegister = getInstruction(insertIndex - 1).registerC diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSlideToSeekPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSlideToSeekPatch.kt index 2fb0425670..5059a5bcbc 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSlideToSeekPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSlideToSeekPatch.kt @@ -56,7 +56,7 @@ val enableSlideToSeekPatch = bytecodePatch( // Restore the behaviour to slide to seek. - val checkIndex = slideToSeekFingerprint.patternMatch!!.startIndex + val checkIndex = slideToSeekFingerprint.instructionMatches.first().index val checkReference = slideToSeekFingerprint.method.getInstruction(checkIndex) .getReference()!! @@ -90,7 +90,7 @@ val enableSlideToSeekPatch = bytecodePatch( disableFastForwardNoticeFingerprint, ).forEach { fingerprint -> fingerprint.method.apply { - val targetIndex = fingerprint.patternMatch!!.endIndex + val targetIndex = fingerprint.instructionMatches.last().index val targetRegister = getInstruction(targetIndex).registerA addInstructions( @@ -103,17 +103,19 @@ val enableSlideToSeekPatch = bytecodePatch( } } } else { - disableFastForwardLegacyFingerprint.method.apply { - val insertIndex = disableFastForwardLegacyFingerprint.patternMatch!!.endIndex + 1 - val targetRegister = getInstruction(insertIndex).registerA - - addInstructions( - insertIndex, - """ - invoke-static { v$targetRegister }, $EXTENSION_METHOD_DESCRIPTOR - move-result v$targetRegister - """, - ) + disableFastForwardLegacyFingerprint.let { + it.method.apply { + val insertIndex = it.instructionMatches.last().index + 1 + val targetRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex, + """ + invoke-static { v$targetRegister }, $EXTENSION_METHOD_DESCRIPTOR + move-result v$targetRegister + """, + ) + } } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/Fingerprints.kt index 968ba89db3..61041439de 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/Fingerprints.kt @@ -1,6 +1,9 @@ package app.revanced.patches.youtube.interaction.seekbar import app.revanced.patcher.fingerprint +import app.revanced.patcher.literal +import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater +import app.revanced.patches.youtube.misc.playservice.is_19_47_or_greater import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstruction import app.revanced.util.literal @@ -8,39 +11,44 @@ import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.reference.StringReference -internal val swipingUpGestureParentFingerprint = fingerprint { +internal val swipingUpGestureParentFingerprint by fingerprint { returns("Z") parameters() - literal { 45379021 } + instructions( + literal(45379021) // Swipe up fullscreen feature flag + ) } /** * Resolves using the class found in [swipingUpGestureParentFingerprint]. */ -internal val showSwipingUpGuideFingerprint = fingerprint { +internal val showSwipingUpGuideFingerprint by fingerprint { accessFlags(AccessFlags.FINAL) returns("Z") parameters() - literal { 1 } + instructions( + literal(1) + ) } /** * Resolves using the class found in [swipingUpGestureParentFingerprint]. */ -internal val allowSwipingUpGestureFingerprint = fingerprint { +internal val allowSwipingUpGestureFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L") } -internal val disableFastForwardLegacyFingerprint = fingerprint { +internal val disableFastForwardLegacyFingerprint by fingerprint { returns("Z") parameters() opcodes(Opcode.MOVE_RESULT) - literal { 45411330 } + // Intent start flag only used in the subscription activity + literal {45411330} } -internal val disableFastForwardGestureFingerprint = fingerprint { +internal val disableFastForwardGestureFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") parameters() @@ -55,7 +63,7 @@ internal val disableFastForwardGestureFingerprint = fingerprint { } } -internal val disableFastForwardNoticeFingerprint = fingerprint { +internal val disableFastForwardNoticeFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters() @@ -66,15 +74,17 @@ internal val disableFastForwardNoticeFingerprint = fingerprint { Opcode.MOVE_RESULT, ) custom { method, _ -> + // Code is found in different methods with different strings. + val findSearchLandingKey = is_19_34_or_greater && !is_19_47_or_greater + method.name == "run" && method.indexOfFirstInstruction { - // In later targets the code is found in different methods with different strings. val string = getReference()?.string - string == "Failed to easy seek haptics vibrate." || string == "search_landing_cache_key" + string == "Failed to easy seek haptics vibrate." || (findSearchLandingKey && string == "search_landing_cache_key") } >= 0 } } -internal val onTouchEventHandlerFingerprint = fingerprint { +internal val onTouchEventHandlerFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.PUBLIC) returns("Z") parameters("L") @@ -97,7 +107,7 @@ internal val onTouchEventHandlerFingerprint = fingerprint { custom { method, _ -> method.name == "onTouchEvent" } } -internal val seekbarTappingFingerprint = fingerprint { +internal val seekbarTappingFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") parameters("L") @@ -111,7 +121,7 @@ internal val seekbarTappingFingerprint = fingerprint { literal { Integer.MAX_VALUE.toLong() } } -internal val slideToSeekFingerprint = fingerprint { +internal val slideToSeekFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL) returns("V") parameters("Landroid/view/View;", "F") @@ -124,9 +134,11 @@ internal val slideToSeekFingerprint = fingerprint { literal { 67108864 } } -internal val fullscreenSeekbarThumbnailsQualityFingerprint = fingerprint { +internal val fullscreenSeekbarThumbnailsQualityFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") parameters() - literal { 45399684L } + instructions( + literal(45399684L) // Video stream seekbar thumbnails feature flag. + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/Fingerprints.kt index e1161ea13d..2c7dc336b6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/Fingerprints.kt @@ -1,10 +1,10 @@ package app.revanced.patches.youtube.interaction.swipecontrols import app.revanced.patcher.fingerprint -import app.revanced.util.literal +import app.revanced.patcher.literal import com.android.tools.smali.dexlib2.AccessFlags -internal val swipeControlsHostActivityFingerprint = fingerprint { +internal val swipeControlsHostActivityFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) parameters() custom { method, _ -> @@ -12,12 +12,9 @@ internal val swipeControlsHostActivityFingerprint = fingerprint { } } -internal const val SWIPE_CHANGE_VIDEO_FEATURE_FLAG = 45631116L - -internal val swipeChangeVideoFingerprint = fingerprint { +internal val swipeChangeVideoFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - parameters("L") - literal { - SWIPE_CHANGE_VIDEO_FEATURE_FLAG - } + instructions( + literal(45631116L) // Swipe to change fullscreen video feature flag. + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsPatch.kt index f127357d46..8610184f5b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsPatch.kt @@ -13,7 +13,7 @@ import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch import app.revanced.patches.youtube.misc.playservice.is_19_43_or_greater import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch -import app.revanced.patches.youtube.shared.mainActivityFingerprint +import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint import app.revanced.util.* import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.immutable.ImmutableMethod @@ -92,7 +92,7 @@ val swipeControlsPatch = bytecodePatch( execute { val wrapperClass = swipeControlsHostActivityFingerprint.classDef - val targetClass = mainActivityFingerprint.classDef + val targetClass = mainActivityOnCreateFingerprint.classDef // Inject the wrapper class from the extension into the class hierarchy of MainActivity. wrapperClass.setSuperClass(targetClass.superclass) @@ -118,10 +118,12 @@ val swipeControlsPatch = bytecodePatch( // region patch to enable/disable swipe to change video. if (is_19_43_or_greater) { - swipeChangeVideoFingerprint.method.insertFeatureFlagBooleanOverride( - SWIPE_CHANGE_VIDEO_FEATURE_FLAG, - "$EXTENSION_CLASS_DESCRIPTOR->allowSwipeChangeVideo(Z)Z" - ) + swipeChangeVideoFingerprint.let { + it.method.insertFeatureFlagBooleanOverride( + it.instructionMatches.last().index, + "$EXTENSION_CLASS_DESCRIPTOR->allowSwipeChangeVideo(Z)Z" + ) + } } // endregion diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/Fingerprints.kt index 3e1c156291..c279f2ff7d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/Fingerprints.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val startVideoInformerFingerprint = fingerprint { +internal val startVideoInformerFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") opcodes( @@ -14,7 +14,7 @@ internal val startVideoInformerFingerprint = fingerprint { strings("pc") } -internal val subtitleTrackFingerprint = fingerprint { +internal val subtitleTrackFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") parameters() diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/Fingerprints.kt index a4e65eb28b..5f0449db73 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/Fingerprints.kt @@ -1,53 +1,60 @@ package app.revanced.patches.youtube.layout.buttons.navigation -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -import app.revanced.util.literal - -internal const val ANDROID_AUTOMOTIVE_STRING = "Android Automotive" +import app.revanced.patcher.literal +import app.revanced.patcher.methodCall +import app.revanced.patcher.opcode +import app.revanced.patcher.string +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode -internal val addCreateButtonViewFingerprint = fingerprint { - strings("Android Wear", ANDROID_AUTOMOTIVE_STRING) +internal val addCreateButtonViewFingerprint by fingerprint { + instructions( + string("Android Wear"), + opcode(Opcode.IF_EQZ), + string("Android Automotive", maxAfter = 0), + ) } -internal val createPivotBarFingerprint = fingerprint { +internal val createPivotBarFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - returns("V") parameters( "Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;", "Landroid/widget/TextView;", "Ljava/lang/CharSequence;", ) - opcodes( - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID, + instructions( + methodCall(definingClass = "Landroid/widget/TextView;", name = "setText"), + opcode(Opcode.RETURN_VOID) ) } -internal const val TRANSLUCENT_NAVIGATION_STATUS_BAR_FEATURE_FLAG = 45400535L - -internal val translucentNavigationStatusBarFeatureFlagFingerprint = fingerprint { +internal val translucentNavigationStatusBarFeatureFlagFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") - literal { TRANSLUCENT_NAVIGATION_STATUS_BAR_FEATURE_FLAG } + instructions( + literal(45400535L) // Translucent status bar feature flag. + ) } -internal const val TRANSLUCENT_NAVIGATION_BUTTONS_FEATURE_FLAG = 45630927L - -internal val translucentNavigationButtonsFeatureFlagFingerprint = fingerprint { +/** + * YouTube nav buttons. + */ +internal val translucentNavigationButtonsFeatureFlagFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") - literal { TRANSLUCENT_NAVIGATION_BUTTONS_FEATURE_FLAG } + instructions( + literal(45630927L) // Translucent navigation bar buttons feature flag. + ) } /** - * The device on screen back/home/recent buttons. + * Device on screen back/home/recent buttons. */ -internal const val TRANSLUCENT_NAVIGATION_BUTTONS_SYSTEM_FEATURE_FLAG = 45632194L - -internal val translucentNavigationButtonsSystemFeatureFlagFingerprint = fingerprint { +internal val translucentNavigationButtonsSystemFeatureFlagFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") - literal { TRANSLUCENT_NAVIGATION_BUTTONS_SYSTEM_FEATURE_FLAG } + instructions( + literal(45632194L) // Translucent system buttons feature flag. + ) } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt index 6e560cf3f3..0efefbb3e1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt @@ -16,12 +16,9 @@ import app.revanced.patches.youtube.misc.playservice.is_19_25_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 -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.insertFeatureFlagBooleanOverride 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.reference.MethodReference internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/NavigationButtonsPatch;" @@ -81,37 +78,34 @@ val navigationButtonsPatch = bytecodePatch( ) // Switch create with notifications button. - addCreateButtonViewFingerprint.method.apply { - val stringIndex = addCreateButtonViewFingerprint.stringMatches!!.find { match -> - match.string == ANDROID_AUTOMOTIVE_STRING - }!!.index - - val conditionalCheckIndex = stringIndex - 1 - val conditionRegister = - getInstruction(conditionalCheckIndex).registerA - - addInstructions( - conditionalCheckIndex, - """ - invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->switchCreateWithNotificationButton()Z - move-result v$conditionRegister - """, - ) + addCreateButtonViewFingerprint.let { + it.method.apply { + val conditionalCheckIndex = it.instructionMatches[1].index + val conditionRegister = + getInstruction(conditionalCheckIndex).registerA + + addInstructions( + conditionalCheckIndex, + """ + invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->switchCreateWithNotificationButton()Z + move-result v$conditionRegister + """, + ) + } } // Hide navigation button labels. - createPivotBarFingerprint.method.apply { - val setTextIndex = indexOfFirstInstructionOrThrow { - getReference()?.name == "setText" + createPivotBarFingerprint.let { + it.method.apply { + val setTextIndex = it.instructionMatches.first().index + val targetRegister = getInstruction(setTextIndex).registerC + + addInstruction( + setTextIndex, + "invoke-static { v$targetRegister }, " + + "$EXTENSION_CLASS_DESCRIPTOR->hideNavigationButtonLabels(Landroid/widget/TextView;)V", + ) } - - val targetRegister = getInstruction(setTextIndex).registerC - - addInstruction( - setTextIndex, - "invoke-static { v$targetRegister }, " + - "$EXTENSION_CLASS_DESCRIPTOR->hideNavigationButtonLabels(Landroid/widget/TextView;)V", - ) } // Hook navigation button created, in order to hide them. @@ -120,20 +114,26 @@ val navigationButtonsPatch = bytecodePatch( // Force on/off translucent effect on status bar and navigation buttons. if (is_19_25_or_greater) { - translucentNavigationStatusBarFeatureFlagFingerprint.method.insertFeatureFlagBooleanOverride( - TRANSLUCENT_NAVIGATION_STATUS_BAR_FEATURE_FLAG, - "$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationStatusBar(Z)Z", - ) + translucentNavigationStatusBarFeatureFlagFingerprint.let { + it.method.insertFeatureFlagBooleanOverride( + it.instructionMatches.first().index, + "$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationStatusBar(Z)Z", + ) + } - translucentNavigationButtonsFeatureFlagFingerprint.method.insertFeatureFlagBooleanOverride( - TRANSLUCENT_NAVIGATION_BUTTONS_FEATURE_FLAG, - "$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z", - ) + translucentNavigationButtonsFeatureFlagFingerprint.let { + it.method.insertFeatureFlagBooleanOverride( + it.instructionMatches.first().index, + "$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z", + ) + } - translucentNavigationButtonsSystemFeatureFlagFingerprint.method.insertFeatureFlagBooleanOverride( - TRANSLUCENT_NAVIGATION_BUTTONS_SYSTEM_FEATURE_FLAG, - "$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z", - ) + translucentNavigationButtonsSystemFeatureFlagFingerprint.let { + it.method.insertFeatureFlagBooleanOverride( + it.instructionMatches.first().index, + "$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z", + ) + } } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/Fingerprints.kt index 323603b507..6fc08a1e36 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/Fingerprints.kt @@ -1,20 +1,23 @@ package app.revanced.patches.youtube.layout.buttons.overlay import app.revanced.patcher.fingerprint -import app.revanced.util.containsLiteralInstruction +import app.revanced.patcher.methodCall +import app.revanced.patcher.string +import app.revanced.patches.shared.misc.mapping.resourceLiteral import com.android.tools.smali.dexlib2.AccessFlags -internal val playerControlsPreviousNextOverlayTouchFingerprint = fingerprint { +internal val playerControlsPreviousNextOverlayTouchFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") - strings("1.0x") - custom { methodDef, _ -> - methodDef.containsLiteralInstruction(playerControlPreviousButtonTouchArea) && - methodDef.containsLiteralInstruction(playerControlNextButtonTouchArea) - } + instructions( + string("1.0x"), + resourceLiteral("id", "player_control_previous_button_touch_area"), + resourceLiteral("id", "player_control_next_button_touch_area"), + methodCall(parameters = listOf("Landroid/view/View;", "I")) + ) } -internal val mediaRouteButtonFingerprint = fingerprint { +internal val mediaRouteButtonFingerprint by fingerprint { parameters("I") custom { methodDef, _ -> methodDef.definingClass.endsWith("/MediaRouteButton;") && methodDef.name == "setVisibility" diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch.kt index 76cd99d15f..1753748901 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch.kt @@ -5,13 +5,10 @@ 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.patch.bytecodePatch -import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch -import app.revanced.patches.shared.misc.mapping.get import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen @@ -24,20 +21,6 @@ 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.reference.MethodReference -internal var playerControlPreviousButtonTouchArea = -1L - private set -internal var playerControlNextButtonTouchArea = -1L - private set - -private val hidePlayerOverlayButtonsResourcePatch = resourcePatch { - dependsOn(resourceMappingPatch) - - execute { - playerControlPreviousButtonTouchArea = resourceMappings["id", "player_control_previous_button_touch_area"] - playerControlNextButtonTouchArea = resourceMappings["id", "player_control_next_button_touch_area"] - } -} - private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/HidePlayerOverlayButtonsPatch;" @@ -49,7 +32,7 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch( sharedExtensionPatch, settingsPatch, addResourcesPatch, - hidePlayerOverlayButtonsResourcePatch, + resourceMappingPatch // Used by fingerprints ) compatibleWith( @@ -76,21 +59,17 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch( // region Hide player next/previous button. - playerControlsPreviousNextOverlayTouchFingerprint.method.apply { - val resourceIndex = indexOfFirstLiteralInstructionOrThrow(playerControlPreviousButtonTouchArea) + playerControlsPreviousNextOverlayTouchFingerprint.let { + it.method.apply { + val insertIndex = it.instructionMatches.last().index + val viewRegister = getInstruction(insertIndex).registerC - val insertIndex = indexOfFirstInstructionOrThrow(resourceIndex) { - opcode == Opcode.INVOKE_STATIC && - getReference()?.parameterTypes?.firstOrNull() == "Landroid/view/View;" + addInstruction( + insertIndex, + "invoke-static { v$viewRegister }, $EXTENSION_CLASS_DESCRIPTOR" + + "->hidePreviousNextButtons(Landroid/view/View;)V", + ) } - - val viewRegister = getInstruction(insertIndex).registerC - - addInstruction( - insertIndex, - "invoke-static { v$viewRegister }, $EXTENSION_CLASS_DESCRIPTOR" + - "->hidePreviousNextButtons(Landroid/view/View;)V", - ) } // endregion diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/ChangeFormFactorPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/ChangeFormFactorPatch.kt index bf800b6432..05790162d6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/ChangeFormFactorPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/ChangeFormFactorPatch.kt @@ -9,13 +9,9 @@ import app.revanced.patches.shared.misc.settings.preference.ListPreference import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstructionOrThrow -import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.FieldReference -internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/ChangeFormFactorPatch;" +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/ChangeFormFactorPatch;" @Suppress("unused") val changeFormFactorPatch = bytecodePatch( @@ -50,24 +46,19 @@ val changeFormFactorPatch = bytecodePatch( ) ) - createPlayerRequestBodyWithModelFingerprint.method.apply { - val formFactorEnumClass = formFactorEnumConstructorFingerprint.originalClassDef.type + createPlayerRequestBodyWithModelFingerprint.let { + it.method.apply { + val index = it.instructionMatches.last().index + val register = getInstruction(index).registerA - val index = indexOfFirstInstructionOrThrow { - val reference = getReference() - opcode == Opcode.IGET && - reference?.definingClass == formFactorEnumClass && - reference.type == "I" + addInstructions( + index + 1, + """ + invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getFormFactor(I)I + move-result v$register + """ + ) } - val register = getInstruction(index).registerA - - addInstructions( - index + 1, - """ - invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getFormFactor(I)I - move-result v$register - """ - ) } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/Fingerprints.kt index d1f1535ebf..8e4a005858 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/Fingerprints.kt @@ -1,14 +1,11 @@ package app.revanced.patches.youtube.layout.formfactor +import app.revanced.patcher.fieldAccess import app.revanced.patcher.fingerprint -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstruction +import app.revanced.patches.youtube.layout.formfactor.formFactorEnumConstructorFingerprint 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.FieldReference -internal val formFactorEnumConstructorFingerprint = fingerprint { +internal val formFactorEnumConstructorFingerprint by fingerprint { accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR) strings( "UNKNOWN_FORM_FACTOR", @@ -18,32 +15,16 @@ internal val formFactorEnumConstructorFingerprint = fingerprint { ) } -internal val createPlayerRequestBodyWithModelFingerprint = fingerprint { +internal val createPlayerRequestBodyWithModelFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("L") parameters() - opcodes(Opcode.OR_INT_LIT16) - custom { method, _ -> - method.indexOfModelInstruction() >= 0 && - method.indexOfReleaseInstruction() >= 0 - } + instructions( + fieldAccess("Landroid/os/Build;", "MODEL", "Ljava/lang/String;"), + fieldAccess( + definingClass = { context -> with(context) { formFactorEnumConstructorFingerprint.originalClassDef.type } }, + type = { "I" }, + maxAfter = 50 + ) + ) } - -private fun Method.indexOfModelInstruction() = - indexOfFirstInstruction { - val reference = getReference() - - reference?.definingClass == "Landroid/os/Build;" && - reference.name == "MODEL" && - reference.type == "Ljava/lang/String;" - } - -internal fun Method.indexOfReleaseInstruction(): Int = - indexOfFirstInstruction { - val reference = getReference() - - reference?.definingClass == "Landroid/os/Build${'$'}VERSION;" && - reference.name == "RELEASE" && - reference.type == "Ljava/lang/String;" - } - diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/Fingerprints.kt index 59d859e800..dfd8f3110e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/Fingerprints.kt @@ -2,9 +2,12 @@ package app.revanced.patches.youtube.layout.hide.endscreencards import app.revanced.patcher.fingerprint import app.revanced.util.literal +import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val layoutCircleFingerprint = fingerprint { +internal val layoutCircleFingerprint by fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + parameters() returns("Landroid/view/View;") opcodes( Opcode.CONST, @@ -16,7 +19,9 @@ internal val layoutCircleFingerprint = fingerprint { literal { layoutCircle } } -internal val layoutIconFingerprint = fingerprint { +internal val layoutIconFingerprint by fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + parameters() returns("Landroid/view/View;") opcodes( Opcode.INVOKE_VIRTUAL, @@ -27,7 +32,9 @@ internal val layoutIconFingerprint = fingerprint { literal { layoutIcon } } -internal val layoutVideoFingerprint = fingerprint { +internal val layoutVideoFingerprint by fingerprint { + accessFlags(AccessFlags.PUBLIC) + parameters() returns("Landroid/view/View;") opcodes( Opcode.CONST, diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatch.kt index e33732c1d8..155e7d7c05 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatch.kt @@ -6,9 +6,8 @@ import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.resourcePatch import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch -import app.revanced.patches.shared.misc.mapping.get +import app.revanced.patches.shared.misc.mapping.getResourceId import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen @@ -36,7 +35,7 @@ private val hideEndscreenCardsResourcePatch = resourcePatch { SwitchPreference("revanced_hide_endscreen_cards"), ) - fun idOf(name: String) = resourceMappings["layout", "endscreen_element_layout_$name"] + fun idOf(name: String) = getResourceId("layout", "endscreen_element_layout_$name") layoutCircle = idOf("circle") layoutIcon = idOf("icon") @@ -73,7 +72,7 @@ val hideEndscreenCardsPatch = bytecodePatch( layoutVideoFingerprint, ).forEach { fingerprint -> fingerprint.method.apply { - val insertIndex = fingerprint.patternMatch!!.endIndex + 1 + val insertIndex = fingerprint.instructionMatches.last().index + 1 val viewRegister = getInstruction(insertIndex - 1).registerA addInstruction( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/Fingerprints.kt index b619020878..fff4d86218 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.youtube.layout.hide.fullscreenambientmode import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val setFullScreenBackgroundColorFingerprint = fingerprint { +internal val setFullScreenBackgroundColorFingerprint by fingerprint { returns("V") accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL) parameters("Z", "I", "I", "I", "I") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/Fingerprints.kt index 463e4cdc6d..10d0521e86 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/Fingerprints.kt @@ -1,50 +1,59 @@ package app.revanced.patches.youtube.layout.hide.general +import app.revanced.patcher.checkCast import app.revanced.patcher.fingerprint +import app.revanced.patcher.methodCall +import app.revanced.patcher.opcode +import app.revanced.patcher.string +import app.revanced.patches.shared.misc.mapping.resourceLiteral import app.revanced.util.literal import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val hideShowMoreButtonFingerprint = fingerprint { - opcodes( - Opcode.CONST, - Opcode.CONST_4, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, +internal val hideShowMoreButtonFingerprint by fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) + instructions( + resourceLiteral("layout", "expand_button_down"), + methodCall(smali = "Landroid/view/View;->inflate(Landroid/content/Context;ILandroid/view/ViewGroup;)Landroid/view/View;"), + opcode(Opcode.MOVE_RESULT_OBJECT) ) - literal { expandButtonDownId } } -internal val parseElementFromBufferFingerprint = fingerprint { +internal val parseElementFromBufferFingerprint by fingerprint { parameters("L", "L", "[B", "L", "L") - opcodes( - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, + instructions( + opcode(Opcode.IGET_OBJECT), + // IGET_BOOLEAN // 20.07+ + opcode(Opcode.INVOKE_INTERFACE, maxAfter = 1), + opcode(Opcode.MOVE_RESULT_OBJECT, maxAfter = 0), + string("Failed to parse Element", partialMatch = true) ) - strings("Failed to parse Element") // String is a partial match. } -internal val playerOverlayFingerprint = fingerprint { +internal val playerOverlayFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("L") - strings("player_overlay_in_video_programming") + instructions( + string("player_overlay_in_video_programming") + ) } -internal val showWatermarkFingerprint = fingerprint { +internal val showWatermarkFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L", "L") } -internal val yoodlesImageViewFingerprint = fingerprint { +internal val yoodlesImageViewFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Landroid/view/View;") parameters("L", "L") - literal { youTubeLogo } + instructions( + resourceLiteral("id", "youtube_logo") + ) } -internal val crowdfundingBoxFingerprint = fingerprint { +internal val crowdfundingBoxFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) opcodes( Opcode.INVOKE_VIRTUAL, @@ -54,7 +63,7 @@ internal val crowdfundingBoxFingerprint = fingerprint { literal { crowdfundingBoxId } } -internal val albumCardsFingerprint = fingerprint { +internal val albumCardsFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) opcodes( Opcode.MOVE_RESULT_OBJECT, @@ -67,9 +76,8 @@ internal val albumCardsFingerprint = fingerprint { literal { albumCardId } } -internal val filterBarHeightFingerprint = fingerprint { +internal val filterBarHeightFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - returns("V") opcodes( Opcode.CONST, Opcode.INVOKE_VIRTUAL, @@ -79,9 +87,8 @@ internal val filterBarHeightFingerprint = fingerprint { literal { filterBarHeightId } } -internal val relatedChipCloudFingerprint = fingerprint { +internal val relatedChipCloudFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - returns("V") opcodes( Opcode.CONST, Opcode.INVOKE_VIRTUAL, @@ -90,9 +97,8 @@ internal val relatedChipCloudFingerprint = fingerprint { literal { relatedChipCloudMarginId } } -internal val searchResultsChipBarFingerprint = fingerprint { +internal val searchResultsChipBarFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - returns("V") opcodes( Opcode.CONST, Opcode.INVOKE_VIRTUAL, @@ -103,14 +109,13 @@ internal val searchResultsChipBarFingerprint = fingerprint { literal { barContainerHeightId } } -internal val showFloatingMicrophoneButtonFingerprint = fingerprint { +internal val showFloatingMicrophoneButtonFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters() - opcodes( - Opcode.IGET_BOOLEAN, - Opcode.IF_EQZ, - Opcode.RETURN_VOID, + instructions( + resourceLiteral("id", "fab"), + checkCast("/FloatingActionButton;", maxAfter = 10), + opcode(Opcode.IGET_BOOLEAN, maxAfter = 10) ) - literal { fabButtonId } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt index 9354115c5c..bf7238a53a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt @@ -13,9 +13,8 @@ import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch -import app.revanced.patches.shared.misc.mapping.get +import app.revanced.patches.shared.misc.mapping.getResourceId import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.shared.misc.settings.preference.* import app.revanced.patches.youtube.misc.litho.filter.addLithoFilter import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch @@ -33,68 +32,45 @@ 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.MethodReference -var expandButtonDownId = -1L +internal var albumCardId = -1L private set -var albumCardId = -1L +internal var crowdfundingBoxId = -1L private set -var crowdfundingBoxId = -1L +internal var filterBarHeightId = -1L private set -var youTubeLogo = -1L +internal var relatedChipCloudMarginId = -1L private set - -var filterBarHeightId = -1L - private set -var relatedChipCloudMarginId = -1L - private set -var barContainerHeightId = -1L - private set - -var fabButtonId = -1L +internal var barContainerHeightId = -1L private set private val hideLayoutComponentsResourcePatch = resourcePatch { dependsOn(resourceMappingPatch) execute { - expandButtonDownId = resourceMappings[ - "layout", - "expand_button_down", - ] - - albumCardId = resourceMappings[ + albumCardId = getResourceId( "layout", "album_card", - ] + ) - crowdfundingBoxId = resourceMappings[ + crowdfundingBoxId = getResourceId( "layout", "donation_companion", - ] - - youTubeLogo = resourceMappings[ - "id", - "youtube_logo", - ] + ) - relatedChipCloudMarginId = resourceMappings[ + relatedChipCloudMarginId = getResourceId( "layout", "related_chip_cloud_reduced_margins", - ] + ) - filterBarHeightId = resourceMappings[ + filterBarHeightId = getResourceId( "dimen", "filter_bar_height", - ] + ) - barContainerHeightId = resourceMappings[ + barContainerHeightId = getResourceId( "dimen", "bar_container_height", - ] - - fabButtonId = resourceMappings[ - "id", - "fab", - ] + ) } } @@ -120,7 +96,8 @@ val hideLayoutComponentsPatch = bytecodePatch( addResourcesPatch, hideLayoutComponentsResourcePatch, navigationBarHookPatch, - versionCheckPatch + versionCheckPatch, + resourceMappingPatch ) compatibleWith( @@ -246,7 +223,7 @@ val hideLayoutComponentsPatch = bytecodePatch( // region Mix playlists parseElementFromBufferFingerprint.method.apply { - val startIndex = parseElementFromBufferFingerprint.patternMatch!!.startIndex + val startIndex = parseElementFromBufferFingerprint.instructionMatches.first().index // Target code is a mess with a lot of register moves. // There is no simple way to find a free register for all versions so this is hard coded. val freeRegister = if (is_19_47_or_greater) 6 else 0 @@ -294,7 +271,7 @@ val hideLayoutComponentsPatch = bytecodePatch( // region Show more button hideShowMoreButtonFingerprint.method.apply { - val moveRegisterIndex = hideShowMoreButtonFingerprint.patternMatch!!.endIndex + val moveRegisterIndex = hideShowMoreButtonFingerprint.instructionMatches.last().index val viewRegister = getInstruction(moveRegisterIndex).registerA val insertIndex = moveRegisterIndex + 1 @@ -310,7 +287,7 @@ val hideLayoutComponentsPatch = bytecodePatch( // region crowdfunding box crowdfundingBoxFingerprint.let { it.method.apply { - val insertIndex = it.patternMatch!!.endIndex + val insertIndex = it.instructionMatches.last().index val objectRegister = getInstruction(insertIndex).registerA addInstruction( @@ -327,7 +304,7 @@ val hideLayoutComponentsPatch = bytecodePatch( albumCardsFingerprint.let { it.method.apply { - val checkCastAnchorIndex = it.patternMatch!!.endIndex + val checkCastAnchorIndex = it.instructionMatches.last().index val insertIndex = checkCastAnchorIndex + 1 val register = getInstruction(checkCastAnchorIndex).registerA @@ -345,15 +322,15 @@ val hideLayoutComponentsPatch = bytecodePatch( showFloatingMicrophoneButtonFingerprint.let { it.method.apply { - val startIndex = it.patternMatch!!.startIndex - val register = getInstruction(startIndex).registerA + val index = it.instructionMatches.last().index + val register = getInstruction(index).registerA addInstructions( - startIndex + 1, + index + 1, """ - invoke-static { v$register }, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->hideFloatingMicrophoneButton(Z)Z - move-result v$register - """, + invoke-static { v$register }, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->hideFloatingMicrophoneButton(Z)Z + move-result v$register + """, ) } } @@ -397,11 +374,9 @@ val hideLayoutComponentsPatch = bytecodePatch( hookRegisterOffset: Int = 0, instructions: (Int) -> String, ) = method.apply { - val endIndex = patternMatch!!.endIndex - + val endIndex = instructionMatches.last().index val insertIndex = endIndex + insertIndexOffset - val register = - getInstruction(endIndex + hookRegisterOffset).registerA + val register = getInstruction(endIndex + hookRegisterOffset).registerA addInstructions(insertIndex, instructions(register)) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/Fingerprints.kt index 5088472a1b..6b1b09d585 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/Fingerprints.kt @@ -1,24 +1,29 @@ package app.revanced.patches.youtube.layout.hide.infocards import app.revanced.patcher.fingerprint +import app.revanced.patcher.string import app.revanced.util.literal import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val infocardsIncognitoFingerprint = fingerprint { +internal val infocardsIncognitoFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Ljava/lang/Boolean;") parameters("L", "J") - strings("vibrator") + instructions( + string("vibrator") + ) } -internal val infocardsIncognitoParentFingerprint = fingerprint { +internal val infocardsIncognitoParentFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Ljava/lang/String;") - strings("player_overlay_info_card_teaser") + instructions( + string("player_overlay_info_card_teaser") + ) } -internal val infocardsMethodCallFingerprint = fingerprint { +internal val infocardsMethodCallFingerprint by fingerprint { opcodes( Opcode.INVOKE_VIRTUAL, Opcode.IGET_OBJECT, diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt index 8c9e5bec9b..2b98425d8b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt @@ -8,9 +8,8 @@ import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch -import app.revanced.patches.shared.misc.mapping.get +import app.revanced.patches.shared.misc.mapping.getResourceId import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.litho.filter.addLithoFilter @@ -37,10 +36,10 @@ private val hideInfocardsResourcePatch = resourcePatch { SwitchPreference("revanced_hide_info_cards"), ) - drawerResourceId = resourceMappings[ + drawerResourceId = getResourceId( "id", "info_cards_drawer_header", - ] + ) } } @@ -83,7 +82,7 @@ val hideInfoCardsPatch = bytecodePatch( val hideInfoCardsCallMethod = infocardsMethodCallFingerprint.method - val invokeInterfaceIndex = infocardsMethodCallFingerprint.patternMatch!!.endIndex + val invokeInterfaceIndex = infocardsMethodCallFingerprint.instructionMatches.last().index val toggleRegister = infocardsMethodCallFingerprint.method.implementation!!.registerCount - 1 hideInfoCardsCallMethod.addInstructionsWithLabels( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt index f689fe3c81..752e3263cc 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt @@ -48,27 +48,27 @@ val disableRollingNumberAnimationPatch = bytecodePatch( // Animations are disabled by preventing an Image from being applied to the text span, // which prevents the animations from appearing. + rollingNumberTextViewAnimationUpdateFingerprint.let { + val blockStartIndex = it.instructionMatches.first().index + val blockEndIndex = it.instructionMatches.last().index + 1 + it.method.apply { + val freeRegister = getInstruction(blockStartIndex).registerA - val patternMatch = rollingNumberTextViewAnimationUpdateFingerprint.patternMatch!! - val blockStartIndex = patternMatch.startIndex - val blockEndIndex = patternMatch.endIndex + 1 - rollingNumberTextViewAnimationUpdateFingerprint.method.apply { - val freeRegister = getInstruction(blockStartIndex).registerA + // ReturnYouTubeDislike also makes changes to this same method, + // and must add control flow label to a noop instruction to + // ensure RYD patch adds its changes after the control flow label. + addInstructions(blockEndIndex, "nop") - // ReturnYouTubeDislike also makes changes to this same method, - // and must add control flow label to a noop instruction to - // ensure RYD patch adds its changes after the control flow label. - addInstructions(blockEndIndex, "nop") - - addInstructionsWithLabels( - blockStartIndex, - """ + addInstructionsWithLabels( + blockStartIndex, + """ invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->disableRollingNumberAnimations()Z move-result v$freeRegister if-nez v$freeRegister, :disable_animations """, - ExternalLabel("disable_animations", getInstruction(blockEndIndex)), - ) + ExternalLabel("disable_animations", getInstruction(blockEndIndex)), + ) + } } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/Fingerprints.kt index 7d563f3c76..9bfdaf1bdf 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/Fingerprints.kt @@ -1,11 +1,14 @@ package app.revanced.patches.youtube.layout.hide.shorts import app.revanced.patcher.fingerprint -import app.revanced.util.literal +import app.revanced.patcher.methodCall +import app.revanced.patcher.opcode +import app.revanced.patcher.string +import app.revanced.patches.shared.misc.mapping.resourceLiteral import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val legacyRenderBottomNavigationBarParentFingerprint = fingerprint { +internal val legacyRenderBottomNavigationBarParentFingerprint by fingerprint { parameters( "I", "I", @@ -14,23 +17,31 @@ internal val legacyRenderBottomNavigationBarParentFingerprint = fingerprint { "J", "L", ) - strings("aa") + instructions( + string("aa") + ) } -internal val shortsBottomBarContainerFingerprint = fingerprint { +internal val shortsBottomBarContainerFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("Landroid/view/View;", "Landroid/os/Bundle;") - strings("r_pfvc") - literal { bottomBarContainer } + instructions( + string("r_pfvc"), + resourceLiteral("id", "bottom_bar_container"), + methodCall(name = "getHeight"), + opcode(Opcode.MOVE_RESULT) + ) } -internal val createShortsButtonsFingerprint = fingerprint { +internal val createShortsButtonsFingerprint by fingerprint { returns("V") - literal { reelPlayerRightCellButtonHeight } + instructions( + resourceLiteral("dimen", "reel_player_right_cell_button_height") + ) } -internal val renderBottomNavigationBarFingerprint = fingerprint { +internal val renderBottomNavigationBarFingerprint by fingerprint { returns("V") parameters("Ljava/lang/String;") opcodes( @@ -51,7 +62,7 @@ internal val renderBottomNavigationBarFingerprint = fingerprint { * Identical to [legacyRenderBottomNavigationBarParentFingerprint] * except this has an extra parameter. */ -internal val renderBottomNavigationBarParentFingerprint = fingerprint { +internal val renderBottomNavigationBarParentFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters( "I", @@ -62,10 +73,12 @@ internal val renderBottomNavigationBarParentFingerprint = fingerprint { "Ljava/lang/String;", "L", ) - strings("aa") + instructions( + string("aa") + ) } -internal val setPivotBarVisibilityFingerprint = fingerprint { +internal val setPivotBarVisibilityFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL) returns("V") parameters("Z") @@ -75,7 +88,9 @@ internal val setPivotBarVisibilityFingerprint = fingerprint { ) } -internal val setPivotBarVisibilityParentFingerprint = fingerprint { +internal val setPivotBarVisibilityParentFingerprint by fingerprint { parameters("Z") - strings("FEnotifications_inbox") + instructions( + string("FEnotifications_inbox") + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt index e41cc727cc..7f2d154af0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt @@ -9,9 +9,8 @@ import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch -import app.revanced.patches.shared.misc.mapping.get +import app.revanced.patches.shared.misc.mapping.getResourceId import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch @@ -28,13 +27,6 @@ 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.reference.MethodReference -internal var reelPlayerRightCellButtonHeight = -1L - private set -internal var bottomBarContainer = -1L - private set -internal var reelPlayerRightPivotV2Size = -1L - private set - internal val hideShortsAppShortcutOption = booleanOption( key = "hideShortsAppShortcut", default = false, @@ -136,21 +128,6 @@ private val hideShortsComponentsResourcePatch = resourcePatch { shortsItem.parentNode.removeChild(shortsItem) } } - - reelPlayerRightCellButtonHeight = resourceMappings[ - "dimen", - "reel_player_right_cell_button_height", - ] - - bottomBarContainer = resourceMappings[ - "id", - "bottom_bar_container", - ] - - reelPlayerRightPivotV2Size = resourceMappings[ - "dimen", - "reel_player_right_pivot_v2_size", - ] } } @@ -198,7 +175,7 @@ val hideShortsComponentsPatch = bytecodePatch( addLithoFilter(FILTER_CLASS_DESCRIPTOR) forEachLiteralValueInstruction( - reelPlayerRightPivotV2Size, + getResourceId("dimen", "reel_player_right_pivot_v2_size") ) { literalInstructionIndex -> val targetIndex = indexOfFirstInstructionOrThrow(literalInstructionIndex) { getReference()?.name == "getDimensionPixelSize" @@ -224,7 +201,7 @@ val hideShortsComponentsPatch = bytecodePatch( setPivotBarVisibilityParentFingerprint.originalClassDef, ).let { result -> result.method.apply { - val insertIndex = result.patternMatch!!.endIndex + val insertIndex = result.instructionMatches.last().index val viewRegister = getInstruction(insertIndex - 1).registerA addInstruction( insertIndex, @@ -247,22 +224,19 @@ val hideShortsComponentsPatch = bytecodePatch( ) // Hide the bottom bar container of the Shorts player. - shortsBottomBarContainerFingerprint.method.apply { - val resourceIndex = indexOfFirstLiteralInstruction(bottomBarContainer) - - val targetIndex = indexOfFirstInstructionOrThrow(resourceIndex) { - getReference()?.name == "getHeight" - } + 1 - - val heightRegister = getInstruction(targetIndex).registerA - - addInstructions( - targetIndex + 1, - """ - invoke-static { v$heightRegister }, $FILTER_CLASS_DESCRIPTOR->getNavigationBarHeight(I)I - move-result v$heightRegister - """, - ) + shortsBottomBarContainerFingerprint.let { + it.method.apply { + val targetIndex = it.instructionMatches.last().index + val heightRegister = getInstruction(targetIndex).registerA + + addInstructions( + targetIndex + 1, + """ + invoke-static { v$heightRegister }, $FILTER_CLASS_DESCRIPTOR->getNavigationBarHeight(I)I + move-result v$heightRegister + """ + ) + } } // endregion @@ -274,8 +248,7 @@ private enum class ShortsButtons(private val resourceName: String, private val m DISLIKE("reel_dyn_dislike", "hideDislikeButton"), COMMENTS("reel_dyn_comment", "hideShortsCommentsButton"), REMIX("reel_dyn_remix", "hideShortsRemixButton"), - SHARE("reel_dyn_share", "hideShortsShareButton"), - ; + SHARE("reel_dyn_share", "hideShortsShareButton"); fun injectHideCall(method: MutableMethod) { val referencedIndex = method.indexOfFirstResourceIdOrThrow(resourceName) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/suggestedvideoendscreen/DisableSuggestedVideoEndScreenPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/suggestedvideoendscreen/DisableSuggestedVideoEndScreenPatch.kt index 822de89943..f3f4d47f9a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/suggestedvideoendscreen/DisableSuggestedVideoEndScreenPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/suggestedvideoendscreen/DisableSuggestedVideoEndScreenPatch.kt @@ -6,9 +6,8 @@ import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.resourcePatch import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch -import app.revanced.patches.shared.misc.mapping.get +import app.revanced.patches.shared.misc.mapping.getResourceId import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen @@ -32,10 +31,10 @@ internal val disableSuggestedVideoEndScreenResourcePatch = resourcePatch { SwitchPreference("revanced_disable_suggested_video_end_screen"), ) - sizeAdjustableLiteAutoNavOverlay = resourceMappings[ + sizeAdjustableLiteAutoNavOverlay = getResourceId( "layout", "size_adjustable_lite_autonav_overlay", - ] + ) } } @@ -66,7 +65,7 @@ val disableSuggestedVideoEndScreenPatch = bytecodePatch( execute { createEndScreenViewFingerprint.method.apply { - val addOnClickEventListenerIndex = createEndScreenViewFingerprint.patternMatch!!.endIndex - 1 + val addOnClickEventListenerIndex = createEndScreenViewFingerprint.instructionMatches.last().index - 1 val viewRegister = getInstruction(addOnClickEventListenerIndex).registerC addInstruction( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/suggestedvideoendscreen/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/suggestedvideoendscreen/Fingerprints.kt index 78efc0680c..7734a80462 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/suggestedvideoendscreen/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/suggestedvideoendscreen/Fingerprints.kt @@ -5,7 +5,7 @@ import app.revanced.util.literal import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val createEndScreenViewFingerprint = fingerprint { +internal val createEndScreenViewFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Landroid/view/View;") parameters("Landroid/content/Context;") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/Fingerprints.kt index d109c6455f..2708fdb0bf 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/Fingerprints.kt @@ -4,9 +4,7 @@ import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import app.revanced.patcher.fingerprint -internal val timeCounterFingerprint = fingerprint( - fuzzyPatternScanThreshold = 1, -) { +internal val timeCounterFingerprint by fingerprint { returns("V") accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters() diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/Fingerprints.kt index 5a2f47239f..75c935e4d5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/Fingerprints.kt @@ -2,23 +2,56 @@ package app.revanced.patches.youtube.layout.miniplayer +import app.revanced.patcher.checkCast import app.revanced.patcher.fingerprint -import app.revanced.util.containsLiteralInstruction -import app.revanced.util.literal +import app.revanced.patcher.literal +import app.revanced.patcher.opcode +import app.revanced.patcher.string +import app.revanced.patches.shared.misc.mapping.resourceLiteral import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val miniplayerDimensionsCalculatorParentFingerprint = fingerprint { +internal const val MINIPLAYER_MODERN_FEATURE_KEY = 45622882L +// In later targets this feature flag does nothing and is dead code. +internal const val MINIPLAYER_MODERN_FEATURE_LEGACY_KEY = 45630429L +internal const val MINIPLAYER_DOUBLE_TAP_FEATURE_KEY = 45628823L +internal const val MINIPLAYER_DRAG_DROP_FEATURE_KEY = 45628752L +internal const val MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY = 45658112L +internal const val MINIPLAYER_ROUNDED_CORNERS_FEATURE_KEY = 45652224L +internal const val MINIPLAYER_INITIAL_SIZE_FEATURE_KEY = 45640023L +internal const val MINIPLAYER_DISABLED_FEATURE_KEY = 45657015L +internal const val MINIPLAYER_ANIMATED_EXPAND_FEATURE_KEY = 45644360L + +internal val miniplayerModernConstructorFingerprint by fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) + instructions( + literal(45623000L) // Magic number found in the constructor. + ) +} + +internal val miniplayerDimensionsCalculatorParentFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L") - literal { floatyBarButtonTopMargin } + instructions( + resourceLiteral("dimen", "floaty_bar_button_top_margin") + ) +} + + +internal val miniplayerModernViewParentFingerprint by fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("Ljava/lang/String;") + parameters() + instructions( + string("player_overlay_modern_mini_player_controls") + ) } /** * Matches using the class found in [miniplayerModernViewParentFingerprint]. */ -internal val miniplayerModernAddViewListenerFingerprint = fingerprint { +internal val miniplayerModernAddViewListenerFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("Landroid/view/View;") @@ -27,115 +60,115 @@ internal val miniplayerModernAddViewListenerFingerprint = fingerprint { /** * Matches using the class found in [miniplayerModernViewParentFingerprint]. */ - -internal val miniplayerModernCloseButtonFingerprint = fingerprint { +internal val miniplayerModernCloseButtonFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("Landroid/widget/ImageView;") + returns("L") parameters() - literal { modernMiniplayerClose } -} - -internal const val MINIPLAYER_MODERN_FEATURE_KEY = 45622882L -// In later targets this feature flag does nothing and is dead code. -internal const val MINIPLAYER_MODERN_FEATURE_LEGACY_KEY = 45630429L -internal const val MINIPLAYER_DOUBLE_TAP_FEATURE_KEY = 45628823L -internal const val MINIPLAYER_DRAG_DROP_FEATURE_KEY = 45628752L -internal const val MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY = 45658112L -internal const val MINIPLAYER_ROUNDED_CORNERS_FEATURE_KEY = 45652224L -internal const val MINIPLAYER_INITIAL_SIZE_FEATURE_KEY = 45640023L -internal const val MINIPLAYER_DISABLED_FEATURE_KEY = 45657015L - -internal val miniplayerModernConstructorFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - parameters("L") - literal { 45623000L } -} - -internal val miniplayerOnCloseHandlerFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("Z") - literal { MINIPLAYER_DISABLED_FEATURE_KEY } + instructions( + resourceLiteral("id", "modern_miniplayer_close"), + checkCast("Landroid/widget/ImageView;") + ) } /** * Matches using the class found in [miniplayerModernViewParentFingerprint]. */ -internal val miniplayerModernExpandButtonFingerprint = fingerprint { +internal val miniplayerModernExpandButtonFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("Landroid/widget/ImageView;") + returns("L") parameters() - literal { modernMiniplayerExpand } + instructions( + resourceLiteral("id", "modern_miniplayer_expand"), + checkCast("Landroid/widget/ImageView;") + ) } /** * Matches using the class found in [miniplayerModernViewParentFingerprint]. */ -internal val miniplayerModernExpandCloseDrawablesFingerprint = fingerprint { +internal val miniplayerModernExpandCloseDrawablesFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L") - literal { ytOutlinePictureInPictureWhite24 } + instructions( + literal(ytOutlinePictureInPictureWhite24) + ) } /** * Matches using the class found in [miniplayerModernViewParentFingerprint]. */ -internal val miniplayerModernForwardButtonFingerprint = fingerprint { +internal val miniplayerModernForwardButtonFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("Landroid/widget/ImageView;") + returns("L") parameters() - literal { modernMiniplayerForwardButton } + instructions( + resourceLiteral("id", "modern_miniplayer_forward_button"), + opcode(Opcode.MOVE_RESULT_OBJECT, maxAfter = 5) + ) } -/** - * Matches using the class found in [miniplayerModernViewParentFingerprint]. - */ -internal val miniplayerModernOverlayViewFingerprint = fingerprint { +internal val miniplayerModernOverlayViewFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("V") parameters() - literal { scrimOverlay } + instructions( + resourceLiteral("id", "scrim_overlay"), + opcode(Opcode.MOVE_RESULT_OBJECT, maxAfter = 5) + ) } /** * Matches using the class found in [miniplayerModernViewParentFingerprint]. */ -internal val miniplayerModernRewindButtonFingerprint = fingerprint { +internal val miniplayerModernRewindButtonFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("Landroid/widget/ImageView;") + returns("L") parameters() - literal { modernMiniplayerRewindButton } + instructions( + resourceLiteral("id", "modern_miniplayer_rewind_button"), + opcode(Opcode.MOVE_RESULT_OBJECT, maxAfter = 5) + ) } -internal val miniplayerModernViewParentFingerprint = fingerprint { +/** + * Matches using the class found in [miniplayerModernViewParentFingerprint]. + */ +internal val miniplayerModernActionButtonFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("Ljava/lang/String;") + returns("L") parameters() - strings("player_overlay_modern_mini_player_controls") + instructions( + resourceLiteral("id", "modern_miniplayer_overlay_action_button"), + opcode(Opcode.MOVE_RESULT_OBJECT, maxAfter = 5) + ) } -internal val miniplayerMinimumSizeFingerprint = fingerprint { +internal val miniplayerMinimumSizeFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - custom { method, _ -> - method.containsLiteralInstruction(192) && - method.containsLiteralInstruction(128) && - method.containsLiteralInstruction(miniplayerMaxSize) - } + instructions( + resourceLiteral("dimen", "miniplayer_max_size"), + literal(192), // Default miniplayer width constant. + literal(128) // Default miniplayer height constant. + ) } -internal val miniplayerOverrideFingerprint = fingerprint { +internal val miniplayerOverrideFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("L") - strings("appName") + instructions( + string("appName") + ) } -internal val miniplayerOverrideNoContextFingerprint = fingerprint { +internal val miniplayerOverrideNoContextFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL) returns("Z") - opcodes(Opcode.IGET_BOOLEAN) // Anchor to insert the instruction. + instructions( + opcode(Opcode.IGET_BOOLEAN) // Anchor to insert the instruction. + ) } -internal val miniplayerResponseModelSizeCheckFingerprint = fingerprint { +internal val miniplayerResponseModelSizeCheckFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("L") parameters("Ljava/lang/Object;", "Ljava/lang/Object;") @@ -149,10 +182,18 @@ internal val miniplayerResponseModelSizeCheckFingerprint = fingerprint { ) } +internal val miniplayerOnCloseHandlerFingerprint by fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("Z") + instructions( + literal(MINIPLAYER_DISABLED_FEATURE_KEY) + ) +} + internal const val YOUTUBE_PLAYER_OVERLAYS_LAYOUT_CLASS_NAME = "Lcom/google/android/apps/youtube/app/common/player/overlay/YouTubePlayerOverlaysLayout;" -internal val playerOverlaysLayoutFingerprint = fingerprint { +internal val playerOverlaysLayoutFingerprint by fingerprint { custom { method, _ -> method.definingClass == YOUTUBE_PLAYER_OVERLAYS_LAYOUT_CLASS_NAME } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt index 086c2c8bf0..ee0b0b44d6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt @@ -13,9 +13,8 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch -import app.revanced.patches.shared.misc.mapping.get +import app.revanced.patches.shared.misc.mapping.getResourceId import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.shared.misc.settings.preference.* import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.playservice.* @@ -26,35 +25,16 @@ 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.Method -import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction 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 -var floatyBarButtonTopMargin = -1L - private set - // Only available in 19.15 and upwards. -var ytOutlineXWhite24 = -1L - private set -var ytOutlinePictureInPictureWhite24 = -1L - private set -var scrimOverlay = -1L - private set -var modernMiniplayerClose = -1L - private set -var modernMiniplayerExpand = -1L - private set -var modernMiniplayerRewindButton = -1L - private set -var modernMiniplayerForwardButton = -1L - private set -var playerOverlays = -1L +internal var ytOutlineXWhite24 = -1L private set -var miniplayerMaxSize = -1L +internal var ytOutlinePictureInPictureWhite24 = -1L private set private val miniplayerResourcePatch = resourcePatch { @@ -64,67 +44,24 @@ private val miniplayerResourcePatch = resourcePatch { ) execute { - floatyBarButtonTopMargin = resourceMappings[ - "dimen", - "floaty_bar_button_top_margin", - ] - - scrimOverlay = resourceMappings[ - "id", - "scrim_overlay", - ] - - playerOverlays = resourceMappings[ - "layout", - "player_overlays", - ] - - - modernMiniplayerClose = resourceMappings[ - "id", - "modern_miniplayer_close", - ] - - modernMiniplayerExpand = resourceMappings[ - "id", - "modern_miniplayer_expand", - ] - - modernMiniplayerRewindButton = resourceMappings[ - "id", - "modern_miniplayer_rewind_button", - ] - - modernMiniplayerForwardButton = resourceMappings[ - "id", - "modern_miniplayer_forward_button", - ] - // Resource id is not used during patching, but is used by extension. // Verify the resource is present while patching. - resourceMappings[ + getResourceId( "id", "modern_miniplayer_subtitle_text", - ] + ) // Only required for exactly 19.16 if (!is_19_17_or_greater) { - ytOutlinePictureInPictureWhite24 = resourceMappings[ + ytOutlinePictureInPictureWhite24 = getResourceId( "drawable", "yt_outline_picture_in_picture_white_24", - ] + ) - ytOutlineXWhite24 = resourceMappings[ + ytOutlineXWhite24 = getResourceId( "drawable", "yt_outline_x_white_24", - ] - } - - if (is_19_26_or_greater) { - miniplayerMaxSize = resourceMappings[ - "dimen", - "miniplayer_max_size", - ] + ) } } } @@ -161,7 +98,6 @@ val miniplayerPatch = bytecodePatch( // 19.30.39 // Modern 3 is less broken when double tap expand is enabled, but cannot swipe to expand when double tap is off. // 19.31.36 // All Modern 1 buttons are missing. Unusable. // 19.32.36 // 19.32+ and beyond all work without issues. - // 19.33.35 "19.34.42", "19.43.41", "19.45.38", @@ -177,17 +113,24 @@ val miniplayerPatch = bytecodePatch( preferences += - if (is_19_43_or_greater) { + if (is_20_03_or_greater) { + ListPreference( + "revanced_miniplayer_type", + summaryKey = null, + ) + } else if (is_19_43_or_greater) { ListPreference( "revanced_miniplayer_type", summaryKey = null, + entriesKey = "revanced_miniplayer_type_legacy_19_43_entries", + entryValuesKey = "revanced_miniplayer_type_legacy_19_43_entry_values", ) } else { ListPreference( "revanced_miniplayer_type", summaryKey = null, - entriesKey = "revanced_miniplayer_type_legacy_entries", - entryValuesKey = "revanced_miniplayer_type_legacy_entry_values", + entriesKey = "revanced_miniplayer_type_legacy_19_16_entries", + entryValuesKey = "revanced_miniplayer_type_legacy_19_16_entry_values", ) } @@ -209,13 +152,13 @@ val miniplayerPatch = bytecodePatch( preferences += SwitchPreference("revanced_miniplayer_hide_subtext") preferences += if (is_19_26_or_greater) { - SwitchPreference("revanced_miniplayer_hide_expand_close") + SwitchPreference("revanced_miniplayer_hide_overlay_buttons") } else { SwitchPreference( - key = "revanced_miniplayer_hide_expand_close", - titleKey = "revanced_miniplayer_hide_expand_close_legacy_title", - summaryOnKey = "revanced_miniplayer_hide_expand_close_legacy_summary_on", - summaryOffKey = "revanced_miniplayer_hide_expand_close_legacy_summary_off", + key = "revanced_miniplayer_hide_overlay_buttons", + titleKey = "revanced_miniplayer_hide_overlay_buttons_legacy_title", + summaryOnKey = "revanced_miniplayer_hide_overlay_buttons_legacy_summary_on", + summaryOffKey = "revanced_miniplayer_hide_overlay_buttons_legacy_summary_off", ) } @@ -306,24 +249,6 @@ val miniplayerPatch = bytecodePatch( ) } - fun MutableMethod.hookInflatedView( - literalValue: Long, - hookedClassType: String, - extensionMethodName: String, - ) { - val imageViewIndex = indexOfFirstInstructionOrThrow( - indexOfFirstLiteralInstructionOrThrow(literalValue), - ) { - opcode == Opcode.CHECK_CAST && getReference()?.type == hookedClassType - } - - val register = getInstruction(imageViewIndex).registerA - addInstruction( - imageViewIndex + 1, - "invoke-static { v$register }, $extensionMethodName", - ) - } - // region Enable tablet miniplayer. miniplayerOverrideNoContextFingerprint.match( @@ -335,13 +260,13 @@ val miniplayerPatch = bytecodePatch( // endregion // region Legacy tablet miniplayer hooks. - val appNameStringIndex = miniplayerOverrideFingerprint.stringMatches!!.first().index + 2 + val appNameStringIndex = miniplayerOverrideFingerprint.instructionMatches.first().index + 2 navigate(miniplayerOverrideFingerprint.originalMethod).to(appNameStringIndex).stop().apply { findReturnIndicesReversed().forEach { index -> insertLegacyTabletMiniplayerOverride(index) } } miniplayerResponseModelSizeCheckFingerprint.let { - it.method.insertLegacyTabletMiniplayerOverride(it.patternMatch!!.endIndex) + it.method.insertLegacyTabletMiniplayerOverride(it.instructionMatches.last().index) } // endregion @@ -365,7 +290,7 @@ val miniplayerPatch = bytecodePatch( if (is_19_23_or_greater) { miniplayerModernConstructorFingerprint.insertMiniplayerFeatureFlagBooleanOverride( MINIPLAYER_DRAG_DROP_FEATURE_KEY, - "enableMiniplayerDragAndDrop", + "getMiniplayerDragAndDrop", ) } @@ -382,7 +307,7 @@ val miniplayerPatch = bytecodePatch( miniplayerModernConstructorFingerprint.insertMiniplayerFeatureFlagBooleanOverride( MINIPLAYER_DOUBLE_TAP_FEATURE_KEY, - "enableMiniplayerDoubleTapAction", + "getMiniplayerDoubleTapAction", ) } @@ -392,36 +317,35 @@ val miniplayerPatch = bytecodePatch( MINIPLAYER_INITIAL_SIZE_FEATURE_KEY, ) val targetIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.LONG_TO_INT) - val register = getInstruction(targetIndex).registerA addInstructions( targetIndex + 1, """ - invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->setMiniplayerDefaultSize(I)I + invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getMiniplayerDefaultSize(I)I move-result v$register """, ) } // Override a minimum size constant. - miniplayerMinimumSizeFingerprint.method.apply { - val index = indexOfFirstInstructionOrThrow { - opcode == Opcode.CONST_16 && (this as NarrowLiteralInstruction).narrowLiteral == 192 + miniplayerMinimumSizeFingerprint.let { + it.method.apply { + val index = it.instructionMatches[1].index + val register = getInstruction(index).registerA + + // Smaller sizes can be used, but the miniplayer will always start in size 170 if set any smaller. + // The 170 initial limit probably could be patched to allow even smaller initial sizes, + // but 170 is already half the horizontal space and smaller does not seem useful. + replaceInstruction(index, "const/16 v$register, 170") } - val register = getInstruction(index).registerA - - // Smaller sizes can be used, but the miniplayer will always start in size 170 if set any smaller. - // The 170 initial limit probably could be patched to allow even smaller initial sizes, - // but 170 is already half the horizontal space and smaller does not seem useful. - replaceInstruction(index, "const/16 v$register, 170") } } if (is_19_36_or_greater) { miniplayerModernConstructorFingerprint.insertMiniplayerFeatureFlagBooleanOverride( MINIPLAYER_ROUNDED_CORNERS_FEATURE_KEY, - "setRoundedCorners", + "getRoundedCorners", ) } @@ -433,7 +357,12 @@ val miniplayerPatch = bytecodePatch( miniplayerModernConstructorFingerprint.insertMiniplayerFeatureFlagBooleanOverride( MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY, - "setHorizontalDrag", + "getHorizontalDrag", + ) + + miniplayerModernConstructorFingerprint.insertMiniplayerFeatureFlagBooleanOverride( + MINIPLAYER_ANIMATED_EXPAND_FEATURE_KEY, + "getMaximizeAnimation", ) } @@ -442,7 +371,7 @@ val miniplayerPatch = bytecodePatch( // region Fix 19.16 using mixed up drawables for tablet modern. // YT fixed this mistake in 19.17. // Fix this, by swapping the drawable resource values with each other. - if (ytOutlinePictureInPictureWhite24 >= 0) { + if (!is_19_17_or_greater) { miniplayerModernExpandCloseDrawablesFingerprint.match( miniplayerModernViewParentFingerprint.originalClassDef, ).method.apply { @@ -463,39 +392,24 @@ val miniplayerPatch = bytecodePatch( // region Add hooks to hide modern miniplayer buttons. listOf( - Triple( - miniplayerModernExpandButtonFingerprint, - modernMiniplayerExpand, - "hideMiniplayerExpandClose", - ), - Triple( - miniplayerModernCloseButtonFingerprint, - modernMiniplayerClose, - "hideMiniplayerExpandClose", - ), - Triple( - miniplayerModernRewindButtonFingerprint, - modernMiniplayerRewindButton, - "hideMiniplayerRewindForward", - ), - Triple( - miniplayerModernForwardButtonFingerprint, - modernMiniplayerForwardButton, - "hideMiniplayerRewindForward", - ), - Triple( - miniplayerModernOverlayViewFingerprint, - scrimOverlay, - "adjustMiniplayerOpacity", - ), - ).forEach { (fingerprint, literalValue, methodName) -> + miniplayerModernExpandButtonFingerprint to "hideMiniplayerExpandClose", + miniplayerModernCloseButtonFingerprint to "hideMiniplayerExpandClose", + miniplayerModernActionButtonFingerprint to "hideMiniplayerActionButton", + miniplayerModernRewindButtonFingerprint to "hideMiniplayerRewindForward", + miniplayerModernForwardButtonFingerprint to "hideMiniplayerRewindForward", + miniplayerModernOverlayViewFingerprint to "adjustMiniplayerOpacity" + ).forEach { (fingerprint, methodName) -> fingerprint.match( miniplayerModernViewParentFingerprint.classDef, - ).method.hookInflatedView( - literalValue, - "Landroid/widget/ImageView;", - "$EXTENSION_CLASS_DESCRIPTOR->$methodName(Landroid/widget/ImageView;)V", - ) + ).method.apply { + val index = fingerprint.instructionMatches.last().index + val register = getInstruction(index).registerA + + addInstruction( + index + 1, + "invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->$methodName(Landroid/view/View;)V", + ) + } } miniplayerModernAddViewListenerFingerprint.match( @@ -510,33 +424,40 @@ val miniplayerPatch = bytecodePatch( // Modern 2 uses the same overlay controls as the regular video player, // and the overlay views are added at runtime. // Add a hook to the overlay class, and pass the added views to extension. + // Problem is fixed in 19.21+ // // NOTE: Modern 2 uses the same video UI as the regular player except resized to smaller. // This patch code could be used to hide other player overlays that do not use Litho. - playerOverlaysLayoutFingerprint.classDef.methods.add( - ImmutableMethod( - YOUTUBE_PLAYER_OVERLAYS_LAYOUT_CLASS_NAME, - "addView", - listOf( - ImmutableMethodParameter("Landroid/view/View;", null, null), - ImmutableMethodParameter("I", null, null), - ImmutableMethodParameter("Landroid/view/ViewGroup\$LayoutParams;", null, null), - ), - "V", - AccessFlags.PUBLIC.value, - null, - null, - MutableMethodImplementation(4), - ).toMutable().apply { - addInstructions( - """ + if (!is_19_17_or_greater) { + playerOverlaysLayoutFingerprint.classDef.methods.add( + ImmutableMethod( + YOUTUBE_PLAYER_OVERLAYS_LAYOUT_CLASS_NAME, + "addView", + listOf( + ImmutableMethodParameter("Landroid/view/View;", null, null), + ImmutableMethodParameter("I", null, null), + ImmutableMethodParameter( + "Landroid/view/ViewGroup\$LayoutParams;", + null, + null + ), + ), + "V", + AccessFlags.PUBLIC.value, + null, + null, + MutableMethodImplementation(4), + ).toMutable().apply { + addInstructions( + """ invoke-super { p0, p1, p2, p3 }, Landroid/view/ViewGroup;->addView(Landroid/view/View;ILandroid/view/ViewGroup${'$'}LayoutParams;)V invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->playerOverlayGroupCreated(Landroid/view/View;)V return-void """ - ) - } - ) + ) + } + ) + } // endregion } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/Fingerprints.kt index 0c31cc83bd..7ac0ce2a11 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/Fingerprints.kt @@ -3,7 +3,7 @@ package app.revanced.patches.youtube.layout.panels.popup import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val engagementPanelControllerFingerprint = fingerprint { +internal val engagementPanelControllerFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL) returns("L") strings( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/Fingerprints.kt index 096ed695da..1ac5c307f0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/Fingerprints.kt @@ -1,24 +1,52 @@ package app.revanced.patches.youtube.layout.player.fullscreen import app.revanced.patcher.fingerprint -import app.revanced.util.literal +import app.revanced.patcher.literal +import app.revanced.patcher.opcode import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode -internal const val OPEN_VIDEOS_FULLSCREEN_PORTRAIT_FEATURE_FLAG = 45666112L +/** + * 19.46+ + */ +internal val openVideosFullscreenPortraitFingerprint by fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("V") + parameters("L", "Lj\$/util/Optional;") + instructions( + opcode(Opcode.MOVE_RESULT), // Conditional check to modify. + // Open videos fullscreen portrait feature flag. + literal(45666112L, maxAfter = 5), // Cannot be more than 5. + opcode(Opcode.MOVE_RESULT, maxAfter = 10), + ) +} -internal val openVideosFullscreenPortraitFingerprint = fingerprint { +/** + * Pre 19.46. + */ +internal val openVideosFullscreenPortraitLegacyFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L", "Lj\$/util/Optional;") - literal { - OPEN_VIDEOS_FULLSCREEN_PORTRAIT_FEATURE_FLAG - } + opcodes( + Opcode.GOTO, + Opcode.SGET_OBJECT, + Opcode.GOTO, + Opcode.SGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.IF_EQ, + Opcode.IF_EQ, + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT // Conditional check to modify. + ) } /** * Used to enable opening regular videos fullscreen. */ -internal val openVideosFullscreenHookPatchExtensionFingerprint = fingerprint { +internal val openVideosFullscreenHookPatchExtensionFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC) returns("Z") parameters() diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreen.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreen.kt deleted file mode 100644 index 89311b08c0..0000000000 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreen.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.youtube.layout.player.fullscreen - -import app.revanced.patcher.patch.bytecodePatch - -@Suppress("unused") -@Deprecated("Renamed to openVideosFullscreenPatch", ReplaceWith("openVideosFullscreenPatch")) -val openVideosFullscreen = bytecodePatch{ - dependsOn(openVideosFullscreenPatch) -} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenHookPatch.kt index 24896be997..5742949f5e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenHookPatch.kt @@ -1,11 +1,15 @@ package app.revanced.patches.youtube.layout.player.fullscreen +import app.revanced.patcher.Fingerprint +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.youtube.layout.shortsplayer.openShortsInRegularPlayerPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater import app.revanced.patches.youtube.misc.playservice.versionCheckPatch -import app.revanced.util.insertFeatureFlagBooleanOverride +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/OpenVideosFullscreenHookPatch;" @@ -20,13 +24,42 @@ internal val openVideosFullscreenHookPatch = bytecodePatch { ) execute { - if (!is_19_46_or_greater) { - return@execute + var fingerprint: Fingerprint + var insertIndex: Int + + if (is_19_46_or_greater) { + fingerprint = openVideosFullscreenPortraitFingerprint + insertIndex = fingerprint.instructionMatches.first().index + + openVideosFullscreenPortraitFingerprint.let { + it.method.apply { + // Remove A/B feature call that forces what this patch already does. + // Cannot use the A/B flag to accomplish the same goal because 19.50+ + // Shorts fullscreen regular player does not use fullscreen + // if the player is minimized and it must be forced using other conditional check. + val featureFlagIndex = it.instructionMatches.last().index + val featureFlagRegister = getInstruction(featureFlagIndex).registerA + + addInstruction(featureFlagIndex + 1, "const/4 v$featureFlagRegister, 0x0") + } + } + } else { + fingerprint = openVideosFullscreenPortraitLegacyFingerprint + insertIndex = fingerprint.instructionMatches.last().index } - openVideosFullscreenPortraitFingerprint.method.insertFeatureFlagBooleanOverride( - OPEN_VIDEOS_FULLSCREEN_PORTRAIT_FEATURE_FLAG, - "$EXTENSION_CLASS_DESCRIPTOR->openVideoFullscreenPortrait(Z)Z" - ) + fingerprint.let { + it.method.apply { + val register = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex + 1, + """ + invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->doNotOpenVideoFullscreenPortrait(Z)Z + move-result v$register + """ + ) + } + } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenPatch.kt index 7f117ca9b9..4df8784b58 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenPatch.kt @@ -1,12 +1,9 @@ package app.revanced.patches.youtube.layout.player.fullscreen -import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.shared.misc.settings.preference.SwitchPreference -import app.revanced.patches.youtube.misc.playservice.is_19_46_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 import app.revanced.util.returnEarly @@ -20,21 +17,23 @@ val openVideosFullscreenPatch = bytecodePatch( openVideosFullscreenHookPatch, settingsPatch, addResourcesPatch, - versionCheckPatch ) compatibleWith( "com.google.android.youtube"( + "18.38.44", + "18.49.37", + "19.16.39", + "19.25.37", + "19.34.42", + "19.43.41", + "19.45.38", "19.46.42", "19.47.53", ) ) execute { - if (!is_19_46_or_greater) { - throw PatchException("'Open videos fullscreen' requires 19.46.42 or greater") - } - addResources("youtube", "layout.player.fullscreen.openVideosFullscreen") PreferenceScreen.PLAYER.addPreferences( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/CustomPlayerOverlayOpacityPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/CustomPlayerOverlayOpacityPatch.kt index 98cb3eb00b..52378615be 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/CustomPlayerOverlayOpacityPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/CustomPlayerOverlayOpacityPatch.kt @@ -6,9 +6,8 @@ import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.resourcePatch import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch -import app.revanced.patches.shared.misc.mapping.get +import app.revanced.patches.shared.misc.mapping.getResourceId import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.shared.misc.settings.preference.InputType import app.revanced.patches.shared.misc.settings.preference.TextPreference import app.revanced.patches.youtube.misc.settings.PreferenceScreen @@ -33,10 +32,10 @@ private val customPlayerOverlayOpacityResourcePatch = resourcePatch { TextPreference("revanced_player_overlay_opacity", inputType = InputType.NUMBER), ) - scrimOverlayId = resourceMappings[ + scrimOverlayId = getResourceId( "id", "scrim_overlay", - ] + ) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/Fingerprints.kt index 7269868402..b2bfd80aae 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/Fingerprints.kt @@ -5,7 +5,7 @@ import app.revanced.util.literal import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val createPlayerOverviewFingerprint = fingerprint { +internal val createPlayerOverviewFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL) returns("V") opcodes( 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 2dd73ecc4c..b090ca96a9 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 @@ -1,10 +1,11 @@ package app.revanced.patches.youtube.layout.returnyoutubedislike import app.revanced.patcher.fingerprint +import app.revanced.patcher.string import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val conversionContextFingerprint = fingerprint { +internal val conversionContextFingerprint by fingerprint { returns("Ljava/lang/String;") parameters() strings( @@ -16,22 +17,28 @@ internal val conversionContextFingerprint = fingerprint { ) } -internal val dislikeFingerprint = fingerprint { +internal val dislikeFingerprint by fingerprint { returns("V") - strings("like/dislike") + instructions( + string("like/dislike") + ) } -internal val likeFingerprint = fingerprint { +internal val likeFingerprint by fingerprint { returns("V") - strings("like/like") + instructions( + string("like/like") + ) } -internal val removeLikeFingerprint = fingerprint { +internal val removeLikeFingerprint by fingerprint { returns("V") - strings("like/removelike") + instructions( + string("like/removelike") + ) } -internal val rollingNumberMeasureAnimatedTextFingerprint = fingerprint { +internal val rollingNumberMeasureAnimatedTextFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("Lj\$/util/Optional;") parameters("L", "Ljava/lang/String;", "L") @@ -52,7 +59,7 @@ internal val rollingNumberMeasureAnimatedTextFingerprint = fingerprint { /** * Matches to class found in [rollingNumberMeasureStaticLabelParentFingerprint]. */ -internal val rollingNumberMeasureStaticLabelFingerprint = fingerprint { +internal val rollingNumberMeasureStaticLabelFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("F") parameters("Ljava/lang/String;") @@ -64,14 +71,16 @@ internal val rollingNumberMeasureStaticLabelFingerprint = fingerprint { ) } -internal val rollingNumberMeasureStaticLabelParentFingerprint = fingerprint { +internal val rollingNumberMeasureStaticLabelParentFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Ljava/lang/String;") parameters() - strings("RollingNumberFontProperties{paint=") + instructions( + string("RollingNumberFontProperties{paint=") + ) } -internal val rollingNumberSetterFingerprint = fingerprint { +internal val rollingNumberSetterFingerprint by fingerprint { opcodes( Opcode.INVOKE_DIRECT, Opcode.IGET_OBJECT, @@ -80,7 +89,7 @@ internal val rollingNumberSetterFingerprint = fingerprint { strings("RollingNumberType required properties missing! Need") } -internal val rollingNumberTextViewFingerprint = fingerprint { +internal val rollingNumberTextViewFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L", "F", "F") @@ -98,7 +107,7 @@ internal val rollingNumberTextViewFingerprint = fingerprint { } } -internal val shortsTextViewFingerprint = fingerprint { +internal val shortsTextViewFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L", "L") @@ -112,15 +121,19 @@ internal val shortsTextViewFingerprint = fingerprint { ) } -internal val textComponentConstructorFingerprint = fingerprint { +internal val textComponentConstructorFingerprint by fingerprint { accessFlags(AccessFlags.CONSTRUCTOR, AccessFlags.PRIVATE) - strings("TextComponent") + instructions( + string("TextComponent") + ) } -internal val textComponentDataFingerprint = fingerprint { +internal val textComponentDataFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) parameters("L", "L") - strings("text") + instructions( + string("text") + ) custom { _, classDef -> classDef.fields.find { it.type == "Ljava/util/BitSet;" } != null } @@ -129,9 +142,11 @@ internal val textComponentDataFingerprint = fingerprint { /** * Matches against the same class found in [textComponentConstructorFingerprint]. */ -internal val textComponentLookupFingerprint = fingerprint { +internal val textComponentLookupFingerprint by fingerprint { accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL) returns("L") parameters("L") - strings("…") + instructions( + string("…") + ) } 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 84d48468a4..26b6fb6f39 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 @@ -106,7 +106,7 @@ val returnYouTubeDislikePatch = bytecodePatch( // region Hook code for creation and cached lookup of text Spans. // Alternatively the hook can be made at tht it fails to update the Span when the user dislikes, - // // since the underlying (likes only) tee creation of Spans in TextComponentSpec, + // since the underlying (likes only) tee creation of Spans in TextComponentSpec, // And it works in all situations excepxt did not change. // This hook handles all situations, as it's where the created Spans are stored and later reused. // Find the field name of the conversion context. @@ -171,7 +171,7 @@ val returnYouTubeDislikePatch = bytecodePatch( // region Hook for non-litho Short videos. shortsTextViewFingerprint.method.apply { - val insertIndex = shortsTextViewFingerprint.patternMatch!!.endIndex + 1 + val insertIndex = shortsTextViewFingerprint.instructionMatches.last().index + 1 // If the field is true, the TextView is for a dislike button. val isDisLikesBooleanInstruction = instructions.first { instruction -> @@ -225,14 +225,9 @@ val returnYouTubeDislikePatch = bytecodePatch( // region Hook rolling numbers. - // Do this last to allow patching old unsupported versions (if the user really wants), - // On older unsupported version this will fail to match and throw an exception, - // but everything will still work correctly anyway. - val dislikesIndex = rollingNumberSetterFingerprint.patternMatch!!.endIndex - rollingNumberSetterFingerprint.method.apply { val insertIndex = 1 - + val dislikesIndex = rollingNumberSetterFingerprint.instructionMatches.last().index val charSequenceInstanceRegister = getInstruction(0).registerA val charSequenceFieldReference = @@ -257,20 +252,22 @@ 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 { + // Additional check to verify the opcodes are at the start of the method + if (it.instructionMatches.first().index != 0) throw PatchException("Unexpected opcode location") + val endIndex = it.instructionMatches.last().index - 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 @@ -278,7 +275,7 @@ val returnYouTubeDislikePatch = bytecodePatch( rollingNumberMeasureStaticLabelFingerprint.match( rollingNumberMeasureStaticLabelParentFingerprint.originalClassDef, ).let { - val measureTextIndex = it.patternMatch!!.startIndex + 1 + val measureTextIndex = it.instructionMatches.first().index + 1 it.method.apply { val freeRegister = getInstruction(0).registerA @@ -291,15 +288,15 @@ 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, + rollingNumberTextViewFingerprint.method, rollingNumberTextViewAnimationUpdateFingerprint.method, ).forEach { insertMethod -> insertMethod.apply { @@ -307,17 +304,15 @@ val returnYouTubeDislikePatch = bytecodePatch( getReference()?.name == "setText" } - val textViewRegister = - getInstruction(setTextIndex).registerC - val textSpanRegister = - getInstruction(setTextIndex).registerD + val textViewRegister = getInstruction(setTextIndex).registerC + val textSpanRegister = getInstruction(setTextIndex).registerD 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/searchbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/Fingerprints.kt index 69fc26daeb..9fe5712d84 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/Fingerprints.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val createSearchSuggestionsFingerprint = fingerprint { +internal val createSearchSuggestionsFingerprint by fingerprint { opcodes( Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT, @@ -13,7 +13,7 @@ internal val createSearchSuggestionsFingerprint = fingerprint { strings("ss_rds") } -internal val setWordmarkHeaderFingerprint = fingerprint { +internal val setWordmarkHeaderFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("Landroid/widget/ImageView;") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt index f7eda01f9b..58692dc60f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt @@ -74,7 +74,7 @@ val wideSearchbarPatch = bytecodePatch( mapOf( setWordmarkHeaderFingerprint to 1, - createSearchSuggestionsFingerprint to createSearchSuggestionsFingerprint.patternMatch!!.startIndex, + createSearchSuggestionsFingerprint to createSearchSuggestionsFingerprint.instructionMatches.first().index, ).forEach { (fingerprint, callIndex) -> walkMutable(callIndex, fingerprint).injectSearchBarHook() } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt index 4f7c8eaba3..56fe3d9f82 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt @@ -1,56 +1,76 @@ package app.revanced.patches.youtube.layout.seekbar import app.revanced.patcher.fingerprint -import app.revanced.util.containsLiteralInstruction -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstruction -import app.revanced.util.literal +import app.revanced.patcher.literal +import app.revanced.patcher.methodCall +import app.revanced.patcher.opcode +import app.revanced.patcher.string +import app.revanced.patches.shared.misc.mapping.resourceLiteral import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.reference.MethodReference -internal val fullscreenSeekbarThumbnailsFingerprint = fingerprint { +internal val fullscreenSeekbarThumbnailsFingerprint by fingerprint { returns("Z") accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters() - literal { 45398577 } + instructions( + literal(45398577) + ) } -internal val playerSeekbarColorFingerprint = fingerprint { +internal val playerSeekbarColorFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - custom { method, _ -> - method.containsLiteralInstruction(inlineTimeBarColorizedBarPlayedColorDarkId) && - method.containsLiteralInstruction(inlineTimeBarPlayedNotHighlightedColorId) - } + instructions( + resourceLiteral("color", "inline_time_bar_played_not_highlighted_color"), + resourceLiteral("color", "inline_time_bar_colorized_bar_played_color_dark") + ) } -internal val setSeekbarClickedColorFingerprint = fingerprint { +internal val setSeekbarClickedColorFingerprint by fingerprint { opcodes(Opcode.CONST_HIGH16) strings("YOUTUBE", "PREROLL", "POSTROLL") custom { _, classDef -> - classDef.endsWith("ControlsOverlayStyle;") + classDef.endsWith("/ControlsOverlayStyle;") } } -internal val shortsSeekbarColorFingerprint = fingerprint { +internal val shortsSeekbarColorFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - literal { reelTimeBarPlayedColorId } + instructions( + resourceLiteral("color", "reel_time_bar_played_color") + ) } -internal val playerSeekbarHandleColorFingerprint = fingerprint { +internal val playerSeekbarHandle1ColorFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) parameters("Landroid/content/Context;") - literal { ytStaticBrandRedId } + instructions( + resourceLiteral("attr", "ytTextSecondary"), + resourceLiteral("attr", "ytStaticBrandRed"), + ) } -internal val watchHistoryMenuUseProgressDrawableFingerprint = fingerprint { +internal val playerSeekbarHandle2ColorFingerprint by fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) + parameters("Landroid/content/Context;") + instructions( + resourceLiteral("color", "inline_time_bar_live_seekable_range"), + resourceLiteral("attr", "ytStaticBrandRed"), + ) +} + +internal val watchHistoryMenuUseProgressDrawableFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L") - literal { -1712394514 } + instructions( + methodCall("Landroid/widget/ProgressBar;", "setMax"), + opcode(Opcode.MOVE_RESULT), + literal(-1712394514) + ) } -internal val lithoLinearGradientFingerprint = fingerprint { +internal val lithoLinearGradientFingerprint by fingerprint { accessFlags(AccessFlags.STATIC) returns("Landroid/graphics/LinearGradient;") parameters("F", "F", "F", "F", "[I", "[F") @@ -59,93 +79,112 @@ internal val lithoLinearGradientFingerprint = fingerprint { /** * 19.49+ */ -internal val playerLinearGradientFingerprint = fingerprint { +internal val playerLinearGradientFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) parameters("I", "I", "I", "I", "Landroid/content/Context;", "I") returns("Landroid/graphics/LinearGradient;") - opcodes( - Opcode.FILLED_NEW_ARRAY, - Opcode.MOVE_RESULT_OBJECT + instructions( + resourceLiteral("color", "yt_youtube_magenta"), + + opcode(Opcode.FILLED_NEW_ARRAY, maxAfter = 5), + opcode(Opcode.MOVE_RESULT_OBJECT, maxAfter = 0) ) - literal { ytYoutubeMagentaColorId } } /** * 19.46 - 19.47 */ -internal val playerLinearGradientLegacy1946Fingerprint = fingerprint { +internal val playerLinearGradientLegacy1946Fingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters("I", "I", "I", "I") returns("V") - opcodes( - Opcode.FILLED_NEW_ARRAY, - Opcode.MOVE_RESULT_OBJECT + instructions( + resourceLiteral("color", "yt_youtube_magenta"), + + opcode(Opcode.FILLED_NEW_ARRAY), + opcode(Opcode.MOVE_RESULT_OBJECT, maxAfter = 0), ) custom { method, _ -> - method.name == "setBounds" && method.containsLiteralInstruction(ytYoutubeMagentaColorId) + method.name == "setBounds" } } /** * 19.25 - 19.45 */ -internal val playerLinearGradientLegacy1925Fingerprint = fingerprint { +internal val playerLinearGradientLegacy1925Fingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) parameters("Landroid/content/Context;") - opcodes( - Opcode.FILLED_NEW_ARRAY, - Opcode.MOVE_RESULT_OBJECT + instructions( + resourceLiteral("color", "yt_youtube_magenta"), + + opcode(Opcode.FILLED_NEW_ARRAY, maxAfter = 10), + opcode(Opcode.MOVE_RESULT_OBJECT, maxAfter = 0), ) - literal { ytYoutubeMagentaColorId } } internal const val launchScreenLayoutTypeLotteFeatureFlag = 268507948L -internal val launchScreenLayoutTypeFingerprint = fingerprint { +internal val launchScreenLayoutTypeFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - returns("V") + instructions( + literal(launchScreenLayoutTypeLotteFeatureFlag) + ) custom { method, _ -> val firstParameter = method.parameterTypes.firstOrNull() // 19.25 - 19.45 - (firstParameter == "Lcom/google/android/apps/youtube/app/watchwhile/MainActivity;" - || firstParameter == "Landroid/app/Activity;") // 19.46+ - && method.containsLiteralInstruction(launchScreenLayoutTypeLotteFeatureFlag) + firstParameter == "Lcom/google/android/apps/youtube/app/watchwhile/MainActivity;" + || firstParameter == "Landroid/app/Activity;" // 19.46+ + } +} + +internal val mainActivityOnCreateSplashScreenImageViewFingerprint by fingerprint { + returns("V") + parameters("Landroid/os/Bundle;") + instructions( + methodCall(definingClass = "Landroid/widget/ImageView;", name = "getDrawable"), + opcode(Opcode.CHECK_CAST) + ) + custom { method, classDef -> + method.name == "onCreate" && classDef.endsWith("/MainActivity;") } } internal const val LOTTIE_ANIMATION_VIEW_CLASS_TYPE = "Lcom/airbnb/lottie/LottieAnimationView;" -internal val lottieAnimationViewSetAnimationIntFingerprint = fingerprint { +internal val lottieAnimationViewSetAnimationIntFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters("I") returns("V") - custom { methodDef, classDef -> - classDef.type == LOTTIE_ANIMATION_VIEW_CLASS_TYPE && methodDef.indexOfFirstInstruction { - val reference = getReference() - reference?.definingClass == "Lcom/airbnb/lottie/LottieAnimationView;" - && reference.name == "isInEditMode" - } >= 0 + instructions( + methodCall("this", "isInEditMode") + ) + custom { _, classDef -> + classDef.type == LOTTIE_ANIMATION_VIEW_CLASS_TYPE } } -internal val lottieAnimationViewSetAnimationStreamFingerprint = fingerprint { +internal val lottieAnimationViewSetAnimationStreamFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters("L") returns("V") - custom { methodDef, classDef -> - classDef.type == LOTTIE_ANIMATION_VIEW_CLASS_TYPE && methodDef.indexOfFirstInstruction { - val reference = getReference() - reference?.definingClass == "Ljava/util/Set;" - && reference.name == "add" - } >= 0 && methodDef.containsLiteralInstruction(0) + instructions( + methodCall("Ljava/util/Set;", "add"), + literal(0) + ) + custom { _, classDef -> + classDef.type == LOTTIE_ANIMATION_VIEW_CLASS_TYPE } } -internal val lottieCompositionFactoryZipFingerprint = fingerprint { +internal val lottieCompositionFactoryZipFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) parameters("Landroid/content/Context;", "Ljava/lang/String;", "Ljava/lang/String;") returns("L") - strings(".zip", ".lottie") + instructions( + string(".zip"), + string(".lottie") + ) } /** @@ -153,11 +192,12 @@ internal val lottieCompositionFactoryZipFingerprint = fingerprint { * * [Original method](https://github.com/airbnb/lottie-android/blob/26ad8bab274eac3f93dccccfa0cafc39f7408d13/lottie/src/main/java/com/airbnb/lottie/LottieCompositionFactory.java#L386) */ -internal val lottieCompositionFactoryFromJsonInputStreamFingerprint = fingerprint { +internal val lottieCompositionFactoryFromJsonInputStreamFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) parameters("Ljava/io/InputStream;", "Ljava/lang/String;") returns("L") - literal { 2 } + instructions( + literal(2) + ) } - diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatch.kt index daf11528d1..23f1a557e4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatch.kt @@ -9,9 +9,7 @@ import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable -import app.revanced.patches.shared.misc.mapping.get import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.youtube.layout.theme.lithoColorHookPatch import app.revanced.patches.youtube.layout.theme.lithoColorOverrideHook import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch @@ -20,14 +18,11 @@ import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater import app.revanced.patches.youtube.misc.playservice.is_19_49_or_greater import app.revanced.patches.youtube.misc.playservice.versionCheckPatch -import app.revanced.patches.youtube.misc.settings.settingsPatch -import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint import app.revanced.util.copyXmlNode import app.revanced.util.findElementByAttributeValueOrThrow import app.revanced.util.findInstructionIndicesReversedOrThrow import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionOrThrow -import app.revanced.util.indexOfFirstLiteralInstructionOrThrow import app.revanced.util.inputStreamFromBundledResource import app.revanced.util.insertFeatureFlagBooleanOverride import com.android.tools.smali.dexlib2.AccessFlags @@ -43,40 +38,15 @@ import org.w3c.dom.Element import java.io.ByteArrayInputStream import kotlin.use -internal var reelTimeBarPlayedColorId = -1L - private set -internal var inlineTimeBarColorizedBarPlayedColorDarkId = -1L - private set -internal var inlineTimeBarPlayedNotHighlightedColorId = -1L - private set -internal var ytYoutubeMagentaColorId = -1L - private set -internal var ytStaticBrandRedId = -1L - private set - -internal const val splashSeekbarColorAttributeName = "splash_custom_seekbar_color" +private const val splashSeekbarColorAttributeName = "splash_custom_seekbar_color" private val seekbarColorResourcePatch = resourcePatch { dependsOn( - settingsPatch, resourceMappingPatch, versionCheckPatch, ) execute { - reelTimeBarPlayedColorId = resourceMappings[ - "color", - "reel_time_bar_played_color", - ] - inlineTimeBarColorizedBarPlayedColorDarkId = resourceMappings[ - "color", - "inline_time_bar_colorized_bar_played_color_dark", - ] - inlineTimeBarPlayedNotHighlightedColorId = resourceMappings[ - "color", - "inline_time_bar_played_not_highlighted_color", - ] - // Modify the resume playback drawable and replace the progress bar with a custom drawable. document("res/drawable/resume_playback_progressbar_drawable.xml").use { document -> val layerList = document.getElementsByTagName("layer-list").item(0) as Element @@ -97,15 +67,6 @@ private val seekbarColorResourcePatch = resourcePatch { return@execute } - ytYoutubeMagentaColorId = resourceMappings[ - "color", - "yt_youtube_magenta", - ] - ytStaticBrandRedId = resourceMappings[ - "attr", - "ytStaticBrandRed", - ] - // Add attribute and styles for splash screen custom color. // Using a style is the only way to selectively change just the seekbar fill color. // @@ -207,35 +168,37 @@ val seekbarColorPatch = bytecodePatch( sharedExtensionPatch, lithoColorHookPatch, seekbarColorResourcePatch, + resourceMappingPatch, versionCheckPatch ) execute { - fun MutableMethod.addColorChangeInstructions(resourceId: Long, methodName: String) { - val index = indexOfFirstLiteralInstructionOrThrow(resourceId) - val insertIndex = indexOfFirstInstructionOrThrow(index, Opcode.MOVE_RESULT) - val register = getInstruction(insertIndex).registerA + fun MutableMethod.addColorChangeInstructions(resourceIndex: Int) { + val moveResultIndex = indexOfFirstInstructionOrThrow(resourceIndex, Opcode.MOVE_RESULT) + val register = getInstruction(moveResultIndex).registerA addInstructions( - insertIndex + 1, + moveResultIndex + 1, """ - invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->$methodName(I)I + invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getVideoPlayerSeekbarColor(I)I move-result v$register """ ) } - playerSeekbarColorFingerprint.method.apply { - addColorChangeInstructions(inlineTimeBarColorizedBarPlayedColorDarkId, "getVideoPlayerSeekbarColor") - addColorChangeInstructions(inlineTimeBarPlayedNotHighlightedColorId, "getVideoPlayerSeekbarColor") + playerSeekbarColorFingerprint.let { + it.method.apply { + addColorChangeInstructions(it.instructionMatches.last().index) + addColorChangeInstructions(it.instructionMatches.first().index) + } } - shortsSeekbarColorFingerprint.method.apply { - addColorChangeInstructions(reelTimeBarPlayedColorId, "getVideoPlayerSeekbarColor") + shortsSeekbarColorFingerprint.let { + it.method.addColorChangeInstructions(it.instructionMatches.first().index) } setSeekbarClickedColorFingerprint.originalMethod.let { - val setColorMethodIndex = setSeekbarClickedColorFingerprint.patternMatch!!.startIndex + 1 + val setColorMethodIndex = setSeekbarClickedColorFingerprint.instructionMatches.first().index + 1 navigate(it).to(setColorMethodIndex).stop().apply { val colorRegister = getInstruction(0).registerA @@ -244,7 +207,7 @@ val seekbarColorPatch = bytecodePatch( """ invoke-static { v$colorRegister }, $EXTENSION_CLASS_DESCRIPTOR->getVideoPlayerSeekbarClickedColor(I)I move-result v$colorRegister - """, + """ ) } } @@ -257,29 +220,30 @@ val seekbarColorPatch = bytecodePatch( // 19.25+ changes - playerSeekbarHandleColorFingerprint.method.apply { - addColorChangeInstructions(ytStaticBrandRedId, "getVideoPlayerSeekbarColor") + arrayOf( + playerSeekbarHandle1ColorFingerprint, + playerSeekbarHandle2ColorFingerprint + ).forEach { + it.method.addColorChangeInstructions(it.instructionMatches.last().index) } // If hiding feed seekbar thumbnails, then turn off the cairo gradient // of the watch history menu items as they use the same gradient as the // player and there is no easy way to distinguish which to use a transparent color. if (is_19_34_or_greater) { - watchHistoryMenuUseProgressDrawableFingerprint.method.apply { - val progressIndex = indexOfFirstInstructionOrThrow { - val reference = getReference() - reference?.definingClass == "Landroid/widget/ProgressBar;" && reference.name == "setMax" + watchHistoryMenuUseProgressDrawableFingerprint.let { + it.method.apply { + val index = it.instructionMatches[1].index + val register = getInstruction(index).registerA + + addInstructions( + index + 1, + """ + invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->showWatchHistoryProgressDrawable(Z)Z + move-result v$register + """ + ) } - val index = indexOfFirstInstructionOrThrow(progressIndex, Opcode.MOVE_RESULT) - val register = getInstruction(index).registerA - - addInstructions( - index + 1, - """ - invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->showWatchHistoryProgressDrawable(Z)Z - move-result v$register - """ - ) } } @@ -302,7 +266,7 @@ val seekbarColorPatch = bytecodePatch( playerFingerprint.let { it.method.apply { - val index = it.patternMatch!!.endIndex + val index = it.instructionMatches.last().index val register = getInstruction(index).registerA addInstructions( @@ -321,58 +285,46 @@ val seekbarColorPatch = bytecodePatch( return@execute // 19.25 does not have a cairo launch animation. } - // Add development hook to force old drawable splash animation. - arrayOf( - launchScreenLayoutTypeFingerprint, - mainActivityOnCreateFingerprint - ).forEach { fingerprint -> - fingerprint.method.insertFeatureFlagBooleanOverride( - launchScreenLayoutTypeLotteFeatureFlag, - "$EXTENSION_CLASS_DESCRIPTOR->useLotteLaunchSplashScreen(Z)Z" - ) - } + // Hook the splash animation to set a seekbar color. + mainActivityOnCreateSplashScreenImageViewFingerprint.let { + it.method.apply { + val checkCastIndex = it.instructionMatches.last().index + val drawableRegister = + getInstruction(checkCastIndex).registerA + + addInstruction( + checkCastIndex + 1, + "invoke-static { v$drawableRegister }, $EXTENSION_CLASS_DESCRIPTOR->" + + "setSplashAnimationDrawableTheme(Landroid/graphics/drawable/AnimatedVectorDrawable;)V" + ) - // Hook the splash animation to set the a seekbar color. - mainActivityOnCreateFingerprint.method.apply { - val drawableIndex = indexOfFirstInstructionOrThrow { - val reference = getReference() - reference?.definingClass == "Landroid/widget/ImageView;" - && reference.name == "getDrawable" - } - val checkCastIndex = indexOfFirstInstructionOrThrow(drawableIndex, Opcode.CHECK_CAST) - val drawableRegister = getInstruction(checkCastIndex).registerA + // Replace the Lottie animation view setAnimation(int) call. + val setAnimationIntMethodName = + lottieAnimationViewSetAnimationIntFingerprint.originalMethod.name - addInstruction( - checkCastIndex + 1, - "invoke-static { v$drawableRegister }, $EXTENSION_CLASS_DESCRIPTOR->" + - "setSplashAnimationDrawableTheme(Landroid/graphics/drawable/AnimatedVectorDrawable;)V" - ) - - // Replace the Lottie animation view setAnimation(int) call. - val setAnimationIntMethodName = lottieAnimationViewSetAnimationIntFingerprint.originalMethod.name - - findInstructionIndicesReversedOrThrow { - val reference = getReference() - reference?.definingClass == "Lcom/airbnb/lottie/LottieAnimationView;" - && reference.name == setAnimationIntMethodName - }.forEach { index -> - val instruction = getInstruction(index) - - replaceInstruction( - index, - "invoke-static { v${instruction.registerC}, v${instruction.registerD} }, " + - "$EXTENSION_CLASS_DESCRIPTOR->setSplashAnimationLottie" + - "(Lcom/airbnb/lottie/LottieAnimationView;I)V" - ) + findInstructionIndicesReversedOrThrow { + val reference = getReference() + reference?.definingClass == LOTTIE_ANIMATION_VIEW_CLASS_TYPE + && reference.name == setAnimationIntMethodName + }.forEach { index -> + val instruction = getInstruction(index) + + replaceInstruction( + index, + "invoke-static { v${instruction.registerC}, v${instruction.registerD} }, " + + "$EXTENSION_CLASS_DESCRIPTOR->setSplashAnimationLottie" + + "(Lcom/airbnb/lottie/LottieAnimationView;I)V" + ) + } } } - // Add non obfuscated method aliases for `setAnimation(int)` // and `setAnimation(InputStream, String)` so extension code can call them. lottieAnimationViewSetAnimationIntFingerprint.classDef.methods.apply { val addedMethodName = "patch_setAnimation" - val setAnimationIntName = lottieAnimationViewSetAnimationIntFingerprint.originalMethod.name + val setAnimationIntName = lottieAnimationViewSetAnimationIntFingerprint + .originalMethod.name add(ImmutableMethod( LOTTIE_ANIMATION_VIEW_CLASS_TYPE, @@ -392,9 +344,9 @@ val seekbarColorPatch = bytecodePatch( ) }) - val factoryStreamClass : CharSequence - val factoryStreamName : CharSequence - val factoryStreamReturnType : CharSequence + val factoryStreamClass: CharSequence + val factoryStreamName: CharSequence + val factoryStreamReturnType: CharSequence lottieCompositionFactoryFromJsonInputStreamFingerprint.match( lottieCompositionFactoryZipFingerprint.originalClassDef ).originalMethod.apply { @@ -430,6 +382,17 @@ val seekbarColorPatch = bytecodePatch( }) } + // Add development hook to force old drawable splash animation. + arrayOf( + launchScreenLayoutTypeFingerprint, + mainActivityOnCreateSplashScreenImageViewFingerprint + ).forEach { fingerprint -> + fingerprint.method.insertFeatureFlagBooleanOverride( + launchScreenLayoutTypeLotteFeatureFlag, + "$EXTENSION_CLASS_DESCRIPTOR->useLotteLaunchSplashScreen(Z)Z" + ) + } + // endregion } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/Fingerprints.kt index cd48868f57..63342e9d78 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/Fingerprints.kt @@ -1,10 +1,11 @@ package app.revanced.patches.youtube.layout.shortsautoplay import app.revanced.patcher.fingerprint +import app.revanced.patcher.string import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val reelEnumConstructorFingerprint = fingerprint { +internal val reelEnumConstructorFingerprint by fingerprint { accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR) opcodes(Opcode.RETURN_VOID) strings( @@ -15,8 +16,10 @@ internal val reelEnumConstructorFingerprint = fingerprint { ) } -internal val reelPlaybackRepeatFingerprint = fingerprint { +internal val reelPlaybackRepeatFingerprint by fingerprint { returns("V") parameters("L") - strings("YoutubePlayerState is in throwing an Error.") + instructions( + string("YoutubePlayerState is in throwing an Error.") + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt index 63f598576a..1e15483897 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt @@ -66,7 +66,7 @@ val shortsAutoplayPatch = bytecodePatch( val reelEnumClass = reelEnumConstructorFingerprint.originalClassDef.type reelEnumConstructorFingerprint.method.apply { - val insertIndex = reelEnumConstructorFingerprint.patternMatch!!.startIndex + val insertIndex = reelEnumConstructorFingerprint.instructionMatches.first().index addInstructions( insertIndex, diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/Fingerprints.kt index 961ddef023..680d8c86a7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/Fingerprints.kt @@ -1,25 +1,31 @@ package app.revanced.patches.youtube.layout.shortsplayer import app.revanced.patcher.fingerprint -import app.revanced.util.literal +import app.revanced.patcher.literal +import app.revanced.patcher.methodCall +import app.revanced.patcher.string import com.android.tools.smali.dexlib2.AccessFlags /** * Purpose of this method is not clear, and it's only used to identify * the obfuscated name of the videoId() method in PlaybackStartDescriptor. */ -internal val playbackStartFeatureFlagFingerprint = fingerprint { +internal val playbackStartFeatureFlagFingerprint by fingerprint { returns("Z") parameters( "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;", ) - literal { - 45380134L - } + instructions( + methodCall( + definingClass = "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;", + returnType = "Ljava/lang/String;" + ), + literal(45380134L) + ) } // Pre 19.25 -internal val shortsPlaybackIntentLegacyFingerprint = fingerprint { +internal val shortsPlaybackIntentLegacyFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters( @@ -30,15 +36,16 @@ internal val shortsPlaybackIntentLegacyFingerprint = fingerprint { "Z", "Ljava/util/Map;" ) - strings( + instructions( + methodCall(returnType = "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;"), // None of these strings are unique. - "com.google.android.apps.youtube.app.endpoint.flags", - "ReelWatchFragmentArgs", - "reels_fragment_descriptor" + string("com.google.android.apps.youtube.app.endpoint.flags"), + string("ReelWatchFragmentArgs"), + string("reels_fragment_descriptor") ) } -internal val shortsPlaybackIntentFingerprint = fingerprint { +internal val shortsPlaybackIntentFingerprint by fingerprint { accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL) returns("V") parameters( @@ -47,10 +54,10 @@ internal val shortsPlaybackIntentFingerprint = fingerprint { "J", "Ljava/lang/String;" ) - strings( + instructions( // None of these strings are unique. - "com.google.android.apps.youtube.app.endpoint.flags", - "ReelWatchFragmentArgs", - "reels_fragment_descriptor" + string("com.google.android.apps.youtube.app.endpoint.flags"), + string("ReelWatchFragmentArgs"), + string("reels_fragment_descriptor") ) } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt index 8ef8585901..fbdae9ee85 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt @@ -11,8 +11,6 @@ import app.revanced.patches.youtube.layout.player.fullscreen.openVideosFullscree import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.navigation.navigationBarHookPatch import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater -import app.revanced.patches.youtube.misc.playservice.is_19_46_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 import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint @@ -36,7 +34,6 @@ val openShortsInRegularPlayerPatch = bytecodePatch( addResourcesPatch, openVideosFullscreenHookPatch, navigationBarHookPatch, - versionCheckPatch ) compatibleWith( @@ -55,19 +52,10 @@ val openShortsInRegularPlayerPatch = bytecodePatch( addResources("youtube", "layout.shortsplayer.shortsPlayerTypePatch") PreferenceScreen.SHORTS.addPreferences( - if (is_19_46_or_greater) { - ListPreference( - key = "revanced_shorts_player_type", - summaryKey = null, - ) - } else { - ListPreference( - key = "revanced_shorts_player_type", - summaryKey = null, - entriesKey = "revanced_shorts_player_type_legacy_entries", - entryValuesKey = "revanced_shorts_player_type_legacy_entry_values" - ) - } + ListPreference( + key = "revanced_shorts_player_type", + summaryKey = null + ) ) // Activity is used as the context to launch an Intent. @@ -78,14 +66,11 @@ val openShortsInRegularPlayerPatch = bytecodePatch( ) // Find the obfuscated method name for PlaybackStartDescriptor.videoId() - val playbackStartVideoIdMethodName = playbackStartFeatureFlagFingerprint.method.let { - val stringMethodIndex = it.indexOfFirstInstructionOrThrow { - val reference = getReference() - reference?.definingClass == "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;" - && reference.returnType == "Ljava/lang/String;" + val playbackStartVideoIdMethodName = playbackStartFeatureFlagFingerprint.let { + val stringMethodIndex = it.instructionMatches.first().index + it.method.let { + navigate(it).to(stringMethodIndex).stop().name } - - navigate(it).to(stringMethodIndex).stop().name } fun extensionInstructions(playbackStartRegister: Int, freeRegister: Int) = @@ -101,30 +86,27 @@ val openShortsInRegularPlayerPatch = bytecodePatch( nop """ - if (!is_19_25_or_greater) { - shortsPlaybackIntentLegacyFingerprint.method.apply { - val index = indexOfFirstInstructionOrThrow { - getReference()?.returnType == - "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;" - } - val freeRegister = getInstruction(index).registerC - val playbackStartRegister = getInstruction(index + 1).registerA + if (is_19_25_or_greater) { + shortsPlaybackIntentFingerprint.method.addInstructionsWithLabels( + 0, + """ + move-object/from16 v0, p1 + ${extensionInstructions(0, 1)} + """ + ) + } else { + shortsPlaybackIntentLegacyFingerprint.let { + it.method.apply { + val index = it.instructionMatches.first().index + val freeRegister = getInstruction(index).registerC + val playbackStartRegister = getInstruction(index + 1).registerA - addInstructionsWithLabels( - index + 2, - extensionInstructions(playbackStartRegister, freeRegister) - ) + addInstructionsWithLabels( + index + 2, + extensionInstructions(playbackStartRegister, freeRegister) + ) + } } - - return@execute } - - shortsPlaybackIntentFingerprint.method.addInstructionsWithLabels( - 0, - """ - move-object/from16 v0, p1 - ${extensionInstructions(0, 1)} - """ - ) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/Fingerprints.kt index 612ceb6c8f..9d5445a380 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/Fingerprints.kt @@ -1,12 +1,15 @@ package app.revanced.patches.youtube.layout.sponsorblock import app.revanced.patcher.fingerprint +import app.revanced.patches.youtube.shared.seekbarFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionReversed import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.reference.MethodReference -internal val appendTimeFingerprint = fingerprint { +internal val appendTimeFingerprint by fingerprint { returns("V") accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters("Ljava/lang/CharSequence;", "Ljava/lang/CharSequence;", "Ljava/lang/CharSequence;") @@ -29,7 +32,7 @@ internal val appendTimeFingerprint = fingerprint { ) } -internal val controlsOverlayFingerprint = fingerprint { +internal val controlsOverlayFingerprint by fingerprint { returns("V") accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL) parameters() @@ -47,18 +50,29 @@ internal val controlsOverlayFingerprint = fingerprint { ) } -internal val rectangleFieldInvalidatorFingerprint = fingerprint { +/** + * Resolves to the class found in [seekbarFingerprint]. + */ +internal val rectangleFieldInvalidatorFingerprint by fingerprint { returns("V") - custom { method, _ -> - val instructions = method.implementation?.instructions!! - val instructionCount = instructions.count() - - // the method has definitely more than 5 instructions - if (instructionCount < 5) return@custom false - - val referenceInstruction = instructions.elementAt(instructionCount - 2) // the second to last instruction - val reference = ((referenceInstruction as? ReferenceInstruction)?.reference as? MethodReference) + parameters() + custom { method, _ -> + indexOfInvalidateInstruction(method) >= 0 + } +} - reference?.parameterTypes?.size == 1 && reference.name == "invalidate" // the reference is the invalidate(..) method +internal val segmentPlaybackControllerFingerprint by fingerprint { + returns("V") + accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) + parameters("Ljava/lang/Object;") + opcodes(Opcode.CONST_STRING) + custom { method, _ -> + method.name == "setSponsorBarRect" && + method.definingClass == EXTENSION_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR } } + +internal fun indexOfInvalidateInstruction(method: Method) = + method.indexOfFirstInstructionReversed { + getReference()?.name == "invalidate" + } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt index 3c9571f47e..3759ffff90 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt @@ -3,12 +3,9 @@ package app.revanced.patches.youtube.layout.sponsorblock import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction -import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.resourcePatch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.shared.misc.mapping.resourceMappingPatch @@ -30,7 +27,6 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.* import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference -import com.android.tools.smali.dexlib2.iface.reference.StringReference private val sponsorBlockResourcePatch = resourcePatch { dependsOn( @@ -79,7 +75,7 @@ private val sponsorBlockResourcePatch = resourcePatch { } } -private const val EXTENSION_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR = +internal const val EXTENSION_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/sponsorblock/SegmentPlaybackController;" private const val EXTENSION_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/sponsorblock/ui/CreateSegmentButton;" @@ -174,7 +170,7 @@ val sponsorBlockPatch = bytecodePatch( injectVisibilityCheckCall(EXTENSION_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR) // Append the new time to the player layout. - val appendTimePatternScanStartIndex = appendTimeFingerprint.patternMatch!!.startIndex + val appendTimePatternScanStartIndex = appendTimeFingerprint.instructionMatches.first().index appendTimeFingerprint.method.apply { val register = getInstruction(appendTimePatternScanStartIndex + 1).registerA @@ -192,7 +188,7 @@ val sponsorBlockPatch = bytecodePatch( // Initialize the SponsorBlock view. controlsOverlayFingerprint.match(layoutConstructorFingerprint.originalClassDef).let { - val startIndex = it.patternMatch!!.startIndex + val startIndex = it.instructionMatches.first().index it.method.apply { val frameLayoutRegister = (getInstruction(startIndex + 2) as OneRegisterInstruction).registerA addInstruction( @@ -203,35 +199,25 @@ val sponsorBlockPatch = bytecodePatch( } // Set seekbar draw rectangle. - rectangleFieldInvalidatorFingerprint.match(seekbarOnDrawFingerprint.originalClassDef).method.apply { - val fieldIndex = instructions.count() - 3 - val fieldReference = getInstruction(fieldIndex).reference as FieldReference - - // replace the "replaceMeWith*" strings - proxy(classes.first { it.type.endsWith("SegmentPlaybackController;") }) - .mutableClass - .methods - .find { it.name == "setSponsorBarRect" } - ?.let { method -> - fun MutableMethod.replaceStringInstruction(index: Int, instruction: Instruction, with: String) { - val register = (instruction as OneRegisterInstruction).registerA - this.replaceInstruction( - index, - "const-string v$register, \"$with\"", - ) - } - for ((index, it) in method.instructions.withIndex()) { - if (it.opcode.ordinal != Opcode.CONST_STRING.ordinal) continue - - when (((it as ReferenceInstruction).reference as StringReference).string) { - "replaceMeWithsetSponsorBarRect" -> method.replaceStringInstruction( - index, - it, - fieldReference.name, - ) - } - } - } ?: throw PatchException("Could not find the method which contains the replaceMeWith* strings") + rectangleFieldInvalidatorFingerprint.match(seekbarFingerprint.originalClassDef).method.apply { + val invalidateIndex = indexOfInvalidateInstruction(this) + val rectangleIndex = indexOfFirstInstructionReversedOrThrow(invalidateIndex + 1) { + getReference()?.type == "Landroid/graphics/Rect;" + } + val rectangleFieldName = (getInstruction(rectangleIndex).reference as FieldReference).name + + segmentPlaybackControllerFingerprint.let { + it.method.apply { + val replaceIndex = it.instructionMatches.first().index + val replaceRegister = + getInstruction(replaceIndex).registerA + + replaceInstruction( + replaceIndex, + "const-string v$replaceRegister, \"$rectangleFieldName\"" + ) + } + } } // The vote and create segment buttons automatically change their visibility when appropriate, diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/Fingerprints.kt index ac458cec26..855486174a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/Fingerprints.kt @@ -1,31 +1,28 @@ package app.revanced.patches.youtube.layout.spoofappversion +import app.revanced.patcher.fieldAccess import app.revanced.patcher.fingerprint -import app.revanced.util.containsLiteralInstruction -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstruction +import app.revanced.patcher.methodCall +import app.revanced.patcher.opcode +import app.revanced.patches.shared.misc.mapping.resourceLiteral 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 val toolBarButtonFingerprint = fingerprint { +internal val toolBarButtonFingerprint by fingerprint { returns("V") accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters("Landroid/view/MenuItem;") - custom { method, _ -> - method.containsLiteralInstruction(menuItemView) && - indexOfGetDrawableInstruction(method) >= 0 - } -} - -internal fun indexOfGetDrawableInstruction(method: Method) = method.indexOfFirstInstruction { - val reference = getReference() - reference?.definingClass == "Landroid/content/res/Resources;" && - reference.name == "getDrawable" + instructions( + resourceLiteral("id", "menu_item_view"), + methodCall(returnType = "I", opcode = Opcode.INVOKE_INTERFACE), + opcode(Opcode.MOVE_RESULT, maxAfter = 0), // Value is zero if resource does not exist. + fieldAccess(type = "Landroid/widget/ImageView;", opcode = Opcode.IGET_OBJECT, maxAfter = 6), + methodCall("Landroid/content/res/Resources;", "getDrawable", maxAfter = 8), + methodCall("Landroid/widget/ImageView;", "setImageDrawable", maxAfter = 4) + ) } -internal val spoofAppVersionFingerprint = fingerprint { +internal val spoofAppVersionFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("L") parameters("L") 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 48caf9c1b7..7cac670faa 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 @@ -4,13 +4,10 @@ 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.patch.bytecodePatch -import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch -import app.revanced.patches.shared.misc.mapping.get import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.shared.misc.settings.preference.ListPreference import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch @@ -18,25 +15,7 @@ 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 -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstructionOrThrow -import app.revanced.util.indexOfFirstInstructionReversedOrThrow -import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference - -internal var menuItemView = -1L - private set - -internal val spoofAppVersionResourcePatch = resourcePatch { - dependsOn( - resourceMappingPatch - ) - - execute { - menuItemView = resourceMappings["id", "menu_item_view"] - } -} private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/spoof/SpoofAppVersionPatch;" @@ -48,7 +27,7 @@ val spoofAppVersionPatch = bytecodePatch( "Patching 19.16.39 includes additional older spoofing targets.", ) { dependsOn( - spoofAppVersionResourcePatch, + resourceMappingPatch, sharedExtensionPatch, settingsPatch, addResourcesPatch, @@ -88,41 +67,39 @@ val spoofAppVersionPatch = bytecodePatch( ) /** - * If a user really wants to spoof to very old versions with the latest app target - * they can modify the import/export spoof version. But when spoofing the 19.20.xx - * or earlier the Library tab can crash due to missing image resources trying to load. - * As a temporary workaround, do not set an image in the toolbar when the enum name is UNKNOWN. + * Shorts player is broken when spoofing to very old versions. + * But if a user still really wants to they can modify the import/export spoof version. + * But when spoofing the 19.20.xx or earlier the Library tab can crash due to missing + * image resources trying to load. As a temporary workaround, do not set an image + * in the toolbar when the enum name is UNKNOWN. */ - toolBarButtonFingerprint.method.apply { - val getDrawableIndex = indexOfGetDrawableInstruction(this) - val enumOrdinalIndex = indexOfFirstInstructionReversedOrThrow(getDrawableIndex) { - opcode == Opcode.INVOKE_INTERFACE && - getReference()?.returnType == "I" - } - val insertIndex = enumOrdinalIndex + 2 - val insertRegister = getInstruction(insertIndex - 1).registerA - val jumpIndex = indexOfFirstInstructionOrThrow(insertIndex) { - opcode == Opcode.INVOKE_VIRTUAL && - getReference()?.name == "setImageDrawable" - } + 1 + toolBarButtonFingerprint.let { + it.method.apply { + val imageResourceIndex = it.instructionMatches[2].index + val register = getInstruction(imageResourceIndex).registerA + val jumpIndex = it.instructionMatches.last().index + 1 - addInstructionsWithLabels( - insertIndex, - "if-eqz v$insertRegister, :ignore", - ExternalLabel("ignore", getInstruction(jumpIndex)) - ) + addInstructionsWithLabels( + imageResourceIndex + 1, + "if-eqz v$register, :ignore", + ExternalLabel("ignore", getInstruction(jumpIndex)) + ) + } } - val insertIndex = spoofAppVersionFingerprint.patternMatch!!.startIndex + 1 - val buildOverrideNameRegister = - spoofAppVersionFingerprint.method.getInstruction(insertIndex - 1).registerA + spoofAppVersionFingerprint.let { + it.method.apply { + val index = it.instructionMatches.first().index + val register = getInstruction(index).registerA - spoofAppVersionFingerprint.method.addInstructions( - insertIndex, - """ - invoke-static {v$buildOverrideNameRegister}, $EXTENSION_CLASS_DESCRIPTOR->getYouTubeVersionOverride(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$buildOverrideNameRegister - """ - ) + addInstructions( + index + 1, + """ + invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getYouTubeVersionOverride(Ljava/lang/String;)Ljava/lang/String; + move-result-object v$register + """ + ) + } + } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/Fingerprints.kt index 0220840203..bf6722d1fe 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/Fingerprints.kt @@ -1,14 +1,17 @@ package app.revanced.patches.youtube.layout.startpage import app.revanced.patcher.fingerprint +import app.revanced.patcher.string import com.android.tools.smali.dexlib2.Opcode -internal val intentActionFingerprint = fingerprint { +internal val intentActionFingerprint by fingerprint { parameters("Landroid/content/Intent;") - strings("has_handled_intent") + instructions( + string("has_handled_intent") + ) } -internal val browseIdFingerprint = fingerprint { +internal val browseIdFingerprint by fingerprint { returns("Lcom/google/android/apps/youtube/app/common/ui/navigation/PaneDescriptor;") parameters() opcodes( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt index 60ba9483e7..b63a759976 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt @@ -7,6 +7,8 @@ import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch 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_20_03_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 import app.revanced.util.addInstructionsAtControlFlowLabel @@ -27,6 +29,7 @@ val disableResumingShortsOnStartupPatch = bytecodePatch( sharedExtensionPatch, settingsPatch, addResourcesPatch, + versionCheckPatch ) compatibleWith( @@ -48,25 +51,43 @@ val disableResumingShortsOnStartupPatch = bytecodePatch( SwitchPreference("revanced_disable_resuming_shorts_player"), ) - userWasInShortsFingerprint.method.apply { - val listenableInstructionIndex = indexOfFirstInstructionOrThrow { - opcode == Opcode.INVOKE_INTERFACE && - getReference()?.definingClass == "Lcom/google/common/util/concurrent/ListenableFuture;" && - getReference()?.name == "isDone" + if (is_20_03_or_greater) { + userWasInShortsAlternativeFingerprint.let { + it.method.apply { + val match = it.instructionMatches[2] + val insertIndex = match.index + 1 + val register = match.getInstruction().registerA + + addInstructions( + insertIndex, + """ + invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer(Z)Z + move-result v$register + """ + ) + } } - val freeRegister = getInstruction(listenableInstructionIndex + 1).registerA + } else { + userWasInShortsLegacyFingerprint.method.apply { + val listenableInstructionIndex = indexOfFirstInstructionOrThrow { + opcode == Opcode.INVOKE_INTERFACE && + getReference()?.definingClass == "Lcom/google/common/util/concurrent/ListenableFuture;" && + getReference()?.name == "isDone" + } + val freeRegister = getInstruction(listenableInstructionIndex + 1).registerA - addInstructionsAtControlFlowLabel( - listenableInstructionIndex, - """ - invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z - move-result v$freeRegister - if-eqz v$freeRegister, :show_startup_shorts_player - return-void - :show_startup_shorts_player - nop - """, - ) + addInstructionsAtControlFlowLabel( + listenableInstructionIndex, + """ + invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z + move-result v$freeRegister + if-eqz v$freeRegister, :show_startup_shorts_player + return-void + :show_startup_shorts_player + nop + """, + ) + } } userWasInShortsConfigFingerprint.method.addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/Fingerprints.kt index 1ae9ce7fe6..d668510541 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/Fingerprints.kt @@ -1,23 +1,49 @@ package app.revanced.patches.youtube.layout.startupshortsreset +import app.revanced.patcher.checkCast import app.revanced.patcher.fingerprint -import app.revanced.util.literal +import app.revanced.patcher.literal +import app.revanced.patcher.methodCall +import app.revanced.patcher.opcode +import app.revanced.patcher.string import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode -internal val userWasInShortsFingerprint = fingerprint { +/** + * 20.02+ + */ +internal val userWasInShortsAlternativeFingerprint by fingerprint { + returns("V") + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + parameters("Ljava/lang/Object;") + instructions( + checkCast("Ljava/lang/Boolean;"), + methodCall(smali = "Ljava/lang/Boolean;->booleanValue()Z", maxAfter = 0), + opcode(Opcode.MOVE_RESULT, maxAfter = 0), + string("userIsInShorts: ", maxAfter = 5) + ) +} + +/** + * Pre 20.02 + */ +internal val userWasInShortsLegacyFingerprint by fingerprint { returns("V") accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters("Ljava/lang/Object;") - strings("Failed to read user_was_in_shorts proto after successful warmup") + instructions( + string("Failed to read user_was_in_shorts proto after successful warmup") + ) } /** * 18.15.40+ */ -internal val userWasInShortsConfigFingerprint = fingerprint { +internal val userWasInShortsConfigFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") - literal { - 45358360L - } + parameters() + instructions( + literal(45358360L) + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/tablet/EnableTabletLayoutPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/tablet/EnableTabletLayoutPatch.kt deleted file mode 100644 index c04f5e99c7..0000000000 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/tablet/EnableTabletLayoutPatch.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.youtube.layout.tablet - -import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patches.youtube.layout.formfactor.changeFormFactorPatch - -@Deprecated("Use 'Change form factor' instead.") -val enableTabletLayoutPatch = bytecodePatch { - dependsOn(changeFormFactorPatch) -} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt index 9ed098a1bf..35fbf5bf02 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt @@ -1,11 +1,11 @@ package app.revanced.patches.youtube.layout.theme import app.revanced.patcher.fingerprint -import app.revanced.util.literal +import app.revanced.patcher.literal import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val lithoThemeFingerprint = fingerprint { +internal val lithoThemeFingerprint by fingerprint { accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL) returns("V") parameters("Landroid/graphics/Rect;") @@ -31,7 +31,7 @@ internal val lithoThemeFingerprint = fingerprint { } } -internal val themeHelperDarkColorFingerprint = fingerprint { +internal val themeHelperDarkColorFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC) returns("Ljava/lang/String;") parameters() @@ -41,7 +41,7 @@ internal val themeHelperDarkColorFingerprint = fingerprint { } } -internal val themeHelperLightColorFingerprint = fingerprint { +internal val themeHelperLightColorFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC) returns("Ljava/lang/String;") parameters() @@ -51,6 +51,8 @@ internal val themeHelperLightColorFingerprint = fingerprint { } } -internal val useGradientLoadingScreenFingerprint = fingerprint { - literal { GRADIENT_LOADING_SCREEN_AB_CONSTANT } +internal val useGradientLoadingScreenFingerprint by fingerprint { + instructions( + literal(45412406L) + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/LithoColorHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/LithoColorHookPatch.kt index fdab6c4b8b..531db33c8f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/LithoColorHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/LithoColorHookPatch.kt @@ -12,7 +12,7 @@ val lithoColorHookPatch = bytecodePatch( execute { - var insertionIndex = lithoThemeFingerprint.patternMatch!!.endIndex - 1 + var insertionIndex = lithoThemeFingerprint.instructionMatches.last().index - 1 lithoColorOverrideHook = { targetMethodClass, targetMethodName -> lithoThemeFingerprint.method.addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt index 587e56c123..a7eab130ba 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt @@ -24,8 +24,6 @@ import org.w3c.dom.Element private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/theme/ThemePatch;" -internal const val GRADIENT_LOADING_SCREEN_AB_CONSTANT = 45412406L - val themePatch = bytecodePatch( name = "Theme", description = "Adds options for theming and applies a custom background theme (dark background theme defaults to amoled black).", @@ -225,10 +223,12 @@ val themePatch = bytecodePatch( SwitchPreference("revanced_gradient_loading_screen"), ) - useGradientLoadingScreenFingerprint.method.insertFeatureFlagBooleanOverride( - GRADIENT_LOADING_SCREEN_AB_CONSTANT, - "$EXTENSION_CLASS_DESCRIPTOR->gradientLoadingScreenEnabled(Z)Z" - ) + useGradientLoadingScreenFingerprint.let { + it.method.insertFeatureFlagBooleanOverride( + it.instructionMatches.first().index, + "$EXTENSION_CLASS_DESCRIPTOR->gradientLoadingScreenEnabled(Z)Z" + ) + } mapOf( themeHelperLightColorFingerprint to lightThemeBackgroundColor, diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt index a817b68da7..36bdf010af 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt @@ -6,9 +6,8 @@ import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.resourcePatch import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch -import app.revanced.patches.shared.misc.mapping.get +import app.revanced.patches.shared.misc.mapping.getResourceId import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch @@ -27,7 +26,7 @@ private val backgroundPlaybackResourcePatch = resourcePatch { dependsOn(resourceMappingPatch, addResourcesPatch) execute { - prefBackgroundAndOfflineCategoryId = resourceMappings["string", "pref_background_and_offline_category"] + prefBackgroundAndOfflineCategoryId = getResourceId("string", "pref_background_and_offline_category") } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/Fingerprints.kt index b12c8157c6..06985c0564 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/Fingerprints.kt @@ -5,7 +5,7 @@ import app.revanced.util.literal import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val backgroundPlaybackManagerFingerprint = fingerprint { +internal val backgroundPlaybackManagerFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("Z") parameters("L") @@ -38,7 +38,7 @@ internal val backgroundPlaybackManagerFingerprint = fingerprint { ) } -internal val backgroundPlaybackSettingsFingerprint = fingerprint { +internal val backgroundPlaybackSettingsFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Ljava/lang/String;") parameters() @@ -54,7 +54,7 @@ internal val backgroundPlaybackSettingsFingerprint = fingerprint { literal { prefBackgroundAndOfflineCategoryId } } -internal val kidsBackgroundPlaybackPolicyControllerFingerprint = fingerprint { +internal val kidsBackgroundPlaybackPolicyControllerFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("I", "L", "L") @@ -71,16 +71,20 @@ internal val kidsBackgroundPlaybackPolicyControllerFingerprint = fingerprint { literal { 5 } } -internal val backgroundPlaybackManagerShortsFingerprint = fingerprint { +internal val backgroundPlaybackManagerShortsFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("Z") parameters("L") - literal { 151635310 } + instructions( + app.revanced.patcher.literal(151635310) + ) } -internal val shortsBackgroundPlaybackFeatureFlagFingerprint = fingerprint { +internal val shortsBackgroundPlaybackFeatureFlagFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") parameters() - literal { 45415425 } + instructions( + app.revanced.patcher.literal(45415425) + ) } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/Fingerprints.kt index fe3f75eb11..79ad7eab9b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/Fingerprints.kt @@ -1,34 +1,37 @@ package app.revanced.patches.youtube.misc.debugging import app.revanced.patcher.fingerprint +import app.revanced.patcher.string import com.android.tools.smali.dexlib2.AccessFlags -internal val experimentalFeatureFlagParentFingerprint = fingerprint { +internal val experimentalFeatureFlagParentFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("L") parameters("L", "J", "[B") - strings("Unable to parse proto typed experiment flag: ") + instructions( + string("Unable to parse proto typed experiment flag: ") + ) } -internal val experimentalBooleanFeatureFlagFingerprint = fingerprint { +internal val experimentalBooleanFeatureFlagFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") parameters("J", "Z") } -internal val experimentalDoubleFeatureFlagFingerprint = fingerprint { +internal val experimentalDoubleFeatureFlagFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("D") parameters("J", "D") } -internal val experimentalLongFeatureFlagFingerprint = fingerprint { +internal val experimentalLongFeatureFlagFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("J") parameters("J", "J") } -internal val experimentalStringFeatureFlagFingerprint = fingerprint { +internal val experimentalStringFeatureFlagFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Ljava/lang/String;") parameters("J", "Ljava/lang/String;") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/Fingerprints.kt index 4f99a4cf54..6d772c5169 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/Fingerprints.kt @@ -1,8 +1,12 @@ package app.revanced.patches.youtube.misc.dimensions.spoof import app.revanced.patcher.fingerprint +import app.revanced.patcher.string -internal val deviceDimensionsModelToStringFingerprint = fingerprint { +internal val deviceDimensionsModelToStringFingerprint by fingerprint { returns("L") - strings("minh.", ";maxh.") + instructions( + string("minh."), + string(";maxh.") + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/extension/hooks/ApplicationInitHook.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/extension/hooks/ApplicationInitHook.kt index 6a0e7d1f48..8f2274d83d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/extension/hooks/ApplicationInitHook.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/extension/hooks/ApplicationInitHook.kt @@ -1,5 +1,6 @@ package app.revanced.patches.youtube.misc.extension.hooks +import app.revanced.patcher.string import app.revanced.patches.shared.misc.extension.extensionHook /** @@ -7,5 +8,8 @@ import app.revanced.patches.shared.misc.extension.extensionHook */ // Extension context is the Activity itself. internal val applicationInitHook = extensionHook { - strings("Application creation", "Application.onCreate") + instructions( + string("Application.onCreate"), + string("Application creation") + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/Fingerprints.kt index fe8f4684a2..17b0e48565 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/Fingerprints.kt @@ -4,7 +4,7 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val onBackPressedFingerprint = fingerprint { +internal val onBackPressedFingerprint by fingerprint { returns("V") accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) opcodes(Opcode.RETURN_VOID) @@ -15,7 +15,7 @@ internal val onBackPressedFingerprint = fingerprint { } } -internal val scrollPositionFingerprint = fingerprint { +internal val scrollPositionFingerprint by fingerprint { accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL) returns("V") parameters("L") @@ -27,7 +27,7 @@ internal val scrollPositionFingerprint = fingerprint { strings("scroll_position") } -internal val recyclerViewTopScrollingFingerprint = fingerprint { +internal val recyclerViewTopScrollingFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters() @@ -51,7 +51,7 @@ internal val recyclerViewTopScrollingFingerprint = fingerprint { ) } -internal val recyclerViewTopScrollingParentFingerprint = fingerprint { +internal val recyclerViewTopScrollingParentFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) parameters("L", "L", "Landroid/view/ViewGroup;", "Landroid/view/ViewGroup;") opcodes( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/FixBackToExitGesturePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/FixBackToExitGesturePatch.kt index 3154b36681..e5f14935fe 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/FixBackToExitGesturePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/FixBackToExitGesturePatch.kt @@ -17,14 +17,14 @@ internal val fixBackToExitGesturePatch = bytecodePatch( recyclerViewTopScrollingFingerprint.match(recyclerViewTopScrollingParentFingerprint.originalClassDef) .let { it.method.addInstruction( - it.patternMatch!!.endIndex, + it.instructionMatches.last().index, "invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->onTopView()V" ) } scrollPositionFingerprint.let { navigate(it.originalMethod) - .to(it.patternMatch!!.startIndex + 1) + .to(it.instructionMatches.first().index + 1) .stop().apply { val index = indexOfFirstInstructionOrThrow { opcode == Opcode.INVOKE_VIRTUAL && getReference()?.definingClass == @@ -41,7 +41,7 @@ internal val fixBackToExitGesturePatch = bytecodePatch( onBackPressedFingerprint.let { it.method.addInstruction( - it.patternMatch!!.endIndex, + it.instructionMatches.last().index, "invoke-static { p0 }, $EXTENSION_CLASS_DESCRIPTOR->onBackPressed(Landroid/app/Activity;)V" ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofVideoStreamsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofVideoStreamsPatch.kt deleted file mode 100644 index 89e7cc08f8..0000000000 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofVideoStreamsPatch.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.youtube.misc.fix.playback - -import app.revanced.patcher.patch.bytecodePatch - -@Deprecated("Use app.revanced.patches.youtube.misc.spoof.spoofVideoStreamsPatch instead.") -@Suppress("unused") -val spoofVideoStreamsPatch = bytecodePatch { - dependsOn(app.revanced.patches.youtube.misc.spoof.spoofVideoStreamsPatch) -} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/UserAgentClientSpoofPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/UserAgentClientSpoofPatch.kt deleted file mode 100644 index eb4c9492be..0000000000 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/UserAgentClientSpoofPatch.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.youtube.misc.fix.playback - -import app.revanced.patcher.patch.bytecodePatch - -@Deprecated("Use app.revanced.patches.youtube.misc.spoof.userAgentClientSpoofPatch instead.") -@Suppress("unused") -val userAgentClientSpoofPatch = bytecodePatch { - dependsOn(app.revanced.patches.youtube.misc.spoof.userAgentClientSpoofPatch) -} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playbackspeed/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playbackspeed/Fingerprints.kt index d5a255ca5f..9ae70b23be 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playbackspeed/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playbackspeed/Fingerprints.kt @@ -12,7 +12,7 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference * This method is usually used to set the initial speed (1.0x) when playback starts from the feed. * For some reason, in the latest YouTube, it is invoked even after the video has already started. */ -internal val playbackSpeedInFeedsFingerprint = fingerprint { +internal val playbackSpeedInFeedsFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/Fingerprints.kt index fcd5298acf..52315bc699 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/Fingerprints.kt @@ -1,9 +1,10 @@ package app.revanced.patches.youtube.misc.imageurlhook import app.revanced.patcher.fingerprint +import app.revanced.patcher.string import com.android.tools.smali.dexlib2.AccessFlags -internal val onFailureFingerprint = fingerprint { +internal val onFailureFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters( @@ -17,7 +18,7 @@ internal val onFailureFingerprint = fingerprint { } // Acts as a parent fingerprint. -internal val onResponseStartedFingerprint = fingerprint { +internal val onResponseStartedFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("Lorg/chromium/net/UrlRequest;", "Lorg/chromium/net/UrlResponseInfo;") @@ -32,7 +33,7 @@ internal val onResponseStartedFingerprint = fingerprint { } } -internal val onSucceededFingerprint = fingerprint { +internal val onSucceededFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("Lorg/chromium/net/UrlRequest;", "Lorg/chromium/net/UrlResponseInfo;") @@ -43,22 +44,23 @@ internal val onSucceededFingerprint = fingerprint { internal const val CRONET_URL_REQUEST_CLASS_DESCRIPTOR = "Lorg/chromium/net/impl/CronetUrlRequest;" -internal val requestFingerprint = fingerprint { +internal val requestFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - returns("V") custom { _, classDef -> classDef.type == CRONET_URL_REQUEST_CLASS_DESCRIPTOR } } -internal val messageDigestImageUrlFingerprint = fingerprint { +internal val messageDigestImageUrlFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) parameters("Ljava/lang/String;", "L") } -internal val messageDigestImageUrlParentFingerprint = fingerprint { +internal val messageDigestImageUrlParentFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Ljava/lang/String;") parameters() - strings("@#&=*+-_.,:!?()/~'%;\$") + instructions( + string("@#&=*+-_.,:!?()/~'%;\$"), + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt index 53e7615646..2e13c6f12f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt @@ -7,15 +7,11 @@ import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch 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_33_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 -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstruction -import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/BypassURLRedirectsPatch;" val bypassURLRedirectsPatch = bytecodePatch( name = "Bypass URL redirects", @@ -25,7 +21,6 @@ val bypassURLRedirectsPatch = bytecodePatch( sharedExtensionPatch, settingsPatch, addResourcesPatch, - versionCheckPatch, ) compatibleWith( @@ -47,36 +42,20 @@ val bypassURLRedirectsPatch = bytecodePatch( SwitchPreference("revanced_bypass_url_redirects"), ) - val fingerprints = if (is_19_33_or_greater) { - arrayOf( - abUriParserFingerprint, - httpUriParserFingerprint, - ) - } else { - arrayOf( - abUriParserLegacyFingerprint, - httpUriParserLegacyFingerprint, - ) - } - - fingerprints.forEach { - it.method.apply { - val insertIndex = findUriParseIndex() + arrayOf( + abUriParserFingerprint, + httpUriParserFingerprint, + ).forEach { fingerprint -> + fingerprint.method.apply { + val insertIndex = fingerprint.instructionMatches.first().index val uriStringRegister = getInstruction(insertIndex).registerC replaceInstruction( insertIndex, - "invoke-static {v$uriStringRegister}," + - "Lapp/revanced/extension/youtube/patches/BypassURLRedirectsPatch;" + - "->" + - "parseRedirectUri(Ljava/lang/String;)Landroid/net/Uri;", + "invoke-static { v$uriStringRegister }, ${EXTENSION_CLASS_DESCRIPTOR}->" + + "parseRedirectUri(Ljava/lang/String;)Landroid/net/Uri;", ) } } } } - -internal fun Method.findUriParseIndex() = indexOfFirstInstruction { - val reference = getReference() - reference?.returnType == "Landroid/net/Uri;" && reference.name == "parse" -} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/Fingerprints.kt index 73f6fae75b..7ad6cab6d7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/Fingerprints.kt @@ -1,72 +1,35 @@ package app.revanced.patches.youtube.misc.links +import app.revanced.patcher.checkCast +import app.revanced.patcher.fieldAccess import app.revanced.patcher.fingerprint +import app.revanced.patcher.methodCall +import app.revanced.patcher.string import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode -/** - * Target 19.33+ - */ -internal val abUriParserFingerprint = fingerprint { +internal val abUriParserFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("Ljava/lang/Object") - parameters("Ljava/lang/Object") - strings( - "Found entityKey=`", - "` that does not contain a PlaylistVideoEntityId message as it's identifier.", + returns("Ljava/lang/Object;") + parameters("Ljava/lang/Object;") + instructions( + methodCall(smali = "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;"), + fieldAccess( + definingClass = "/WebviewEndpointOuterClass${'$'}WebviewEndpoint;", + name = "webviewEndpoint" + ), + checkCast("/WebviewEndpointOuterClass${'$'}WebviewEndpoint;"), ) - custom { method, _ -> - method.findUriParseIndex() >= 0 - } } -internal val abUriParserLegacyFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("Ljava/lang/Object") - parameters("Ljava/lang/Object") - opcodes( - Opcode.RETURN_OBJECT, - Opcode.CHECK_CAST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.RETURN_OBJECT, - Opcode.CHECK_CAST, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.RETURN_OBJECT, - Opcode.CHECK_CAST, - ) - custom { methodDef, classDef -> - // This method is always called "a" because this kind of class always has a single (non-synthetic) method. - - if (methodDef.name != "a") return@custom false - - val count = classDef.methods.count() - count == 2 || count == 3 - } -} - -/** - * Target 19.33+ - */ -internal val httpUriParserFingerprint = fingerprint { +internal val httpUriParserFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) - returns("Landroid/net/Uri") - parameters("Ljava/lang/String") - strings("https", "https:", "://") - custom { methodDef, _ -> - methodDef.findUriParseIndex() >= 0 - } -} - -internal val httpUriParserLegacyFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) - returns("Landroid/net/Uri") - parameters("Ljava/lang/String") - opcodes( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, + returns("Landroid/net/Uri;") + parameters("Ljava/lang/String;") + instructions( + methodCall(smali = "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;"), + string("https"), + string("://"), + string("https:"), ) - strings("://") } + diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt index ac158ee120..d23a34ee4a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt @@ -1,7 +1,8 @@ package app.revanced.patches.youtube.misc.litho.filter import app.revanced.patcher.fingerprint -import app.revanced.util.literal +import app.revanced.patcher.literal +import app.revanced.patcher.string import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode @@ -9,19 +10,22 @@ import com.android.tools.smali.dexlib2.Opcode * In 19.17 and earlier, this resolves to the same method as [readComponentIdentifierFingerprint]. * In 19.18+ this resolves to a different method. */ -internal val componentContextParserFingerprint = fingerprint { - strings("Component was not found %s because it was removed due to duplicate converter bindings.") +internal val componentContextParserFingerprint by fingerprint { + instructions( + string("TreeNode result must be set."), + // String changed slightly in 20.03+ + string("it was removed due to duplicate converter bindings.", partialMatch = true) + ) } -internal val lithoFilterFingerprint = fingerprint { +internal val lithoFilterFingerprint by fingerprint { accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR) - returns("V") custom { _, classDef -> - classDef.endsWith("LithoFilterPatch;") + classDef.endsWith("/LithoFilterPatch;") } } -internal val protobufBufferReferenceFingerprint = fingerprint { +internal val protobufBufferReferenceFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("I", "Ljava/nio/ByteBuffer;") @@ -37,29 +41,37 @@ internal val protobufBufferReferenceFingerprint = fingerprint { * In 19.17 and earlier, this resolves to the same method as [componentContextParserFingerprint]. * In 19.18+ this resolves to a different method. */ -internal val readComponentIdentifierFingerprint = fingerprint { - strings("Number of bits must be positive") +internal val readComponentIdentifierFingerprint by fingerprint { + instructions( + string("Number of bits must be positive") + ) } -internal val emptyComponentFingerprint = fingerprint { +internal val emptyComponentFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.CONSTRUCTOR) parameters() - strings("EmptyComponent") + instructions( + string("EmptyComponent") + ) custom { _, classDef -> classDef.methods.filter { AccessFlags.STATIC.isSet(it.accessFlags) }.size == 1 } } -internal val lithoComponentNameUpbFeatureFlagFingerprint = fingerprint { +internal val lithoComponentNameUpbFeatureFlagFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") parameters() - literal { 45631264L } + instructions( + literal(45631264L) + ) } -internal val lithoConverterBufferUpbFeatureFlagFingerprint = fingerprint { +internal val lithoConverterBufferUpbFeatureFlagFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("L") parameters("L") - literal { 45419603L } + instructions( + literal(45419603L) + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt index 16a8340830..18c424497d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt @@ -14,6 +14,7 @@ import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.playservice.is_19_18_or_greater import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater +import app.revanced.patches.youtube.misc.playservice.is_20_05_or_greater import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionOrThrow @@ -126,9 +127,7 @@ val lithoFilterPatch = bytecodePatch( AccessFlags.STATIC.isSet(method.accessFlags) } // Only one field. - val emptyComponentField = classBy { classDef -> - builderMethodDescriptor.returnType == classDef.type - }!!.immutableClass.fields.single() + val emptyComponentField = classBy(builderMethodDescriptor.returnType).fields.single() // Returns an empty component instead of the original component. fun createReturnEmptyComponentInstructions(register: Int): String = @@ -235,7 +234,10 @@ val lithoFilterPatch = bytecodePatch( // Turn off native code that handles litho component names. If this feature is on then nearly // all litho components have a null name and identifier/path filtering is completely broken. - if (is_19_25_or_greater) { + // + // Flag was removed in 20.05. It appears a new flag might be used instead (45660109L), + // but if the flag is forced on then litho filtering still works correctly. + if (is_19_25_or_greater && !is_20_05_or_greater) { lithoComponentNameUpbFeatureFlagFingerprint.method.apply { // Don't use return early, so the debug patch logs if this was originally on. val insertIndex = indexOfFirstInstructionOrThrow(Opcode.RETURN) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/Fingerprints.kt index c64cf75940..2beddc1f05 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/Fingerprints.kt @@ -1,31 +1,35 @@ package app.revanced.patches.youtube.misc.navigation import app.revanced.patcher.fingerprint +import app.revanced.patcher.methodCall +import app.revanced.patcher.opcode +import app.revanced.patcher.string +import app.revanced.patches.shared.misc.mapping.resourceLiteral import app.revanced.patches.youtube.layout.buttons.navigation.navigationButtonsPatch -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstruction -import app.revanced.util.literal 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 val actionBarSearchResultsFingerprint = fingerprint { +internal val actionBarSearchResultsFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Landroid/view/View;") - literal { actionBarSearchResultsViewMicId } + instructions( + resourceLiteral("layout", "action_bar_search_results_view_mic"), + methodCall(name = "setLayoutDirection") + ) } /** * Matches to the class found in [pivotBarConstructorFingerprint]. */ -internal val initializeButtonsFingerprint = fingerprint { +internal val initializeButtonsFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") - literal { imageOnlyTabResourceId } + instructions( + resourceLiteral("layout", "image_only_tab") + ) } -internal val mainActivityOnBackPressedFingerprint = fingerprint { +internal val mainActivityOnBackPressedFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters() @@ -42,7 +46,7 @@ internal val mainActivityOnBackPressedFingerprint = fingerprint { * Extension method, used for callback into to other patches. * Specifically, [navigationButtonsPatch]. */ -internal val navigationBarHookCallbackFingerprint = fingerprint { +internal val navigationBarHookCallbackFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC) returns("V") parameters(EXTENSION_NAVIGATION_BUTTON_DESCRIPTOR, "Landroid/view/View;") @@ -55,7 +59,7 @@ internal val navigationBarHookCallbackFingerprint = fingerprint { /** * Matches to the Enum class that looks up ordinal -> instance. */ -internal val navigationEnumFingerprint = fingerprint { +internal val navigationEnumFingerprint by fingerprint { accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR) strings( "PIVOT_HOME", @@ -68,7 +72,7 @@ internal val navigationEnumFingerprint = fingerprint { ) } -internal val pivotBarButtonsCreateDrawableViewFingerprint = fingerprint { +internal val pivotBarButtonsCreateDrawableViewFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Landroid/view/View;") custom { method, _ -> @@ -78,7 +82,7 @@ internal val pivotBarButtonsCreateDrawableViewFingerprint = fingerprint { } } -internal val pivotBarButtonsCreateResourceViewFingerprint = fingerprint { +internal val pivotBarButtonsCreateResourceViewFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Landroid/view/View;") parameters("L", "Z", "I", "L") @@ -87,33 +91,36 @@ internal val pivotBarButtonsCreateResourceViewFingerprint = fingerprint { } } -internal fun indexOfSetViewSelectedInstruction(method: Method) = method.indexOfFirstInstruction { - opcode == Opcode.INVOKE_VIRTUAL && getReference()?.name == "setSelected" -} - -internal val pivotBarButtonsViewSetSelectedFingerprint = fingerprint { +internal val pivotBarButtonsViewSetSelectedFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("I", "Z") + instructions( + methodCall(name = "setSelected") + ) custom { method, _ -> - indexOfSetViewSelectedInstruction(method) >= 0 && - method.definingClass == "Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;" + method.definingClass == "Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;" } } -internal val pivotBarConstructorFingerprint = fingerprint { +internal val pivotBarConstructorFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - strings("com.google.android.apps.youtube.app.endpoint.flags") + instructions( + string("com.google.android.apps.youtube.app.endpoint.flags"), + ) } -internal val imageEnumConstructorFingerprint = fingerprint { +internal val imageEnumConstructorFingerprint by fingerprint { accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR) - strings("TAB_ACTIVITY_CAIRO") + instructions( + string("TAB_ACTIVITY_CAIRO"), + opcode(Opcode.SPUT_OBJECT) + ) } -internal val setEnumMapFingerprint = fingerprint { +internal val setEnumMapFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - literal { - ytFillBellId - } + instructions( + resourceLiteral("drawable", "yt_fill_bell_black_24") + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt index 902567eb89..e3feda75c4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt @@ -6,18 +6,13 @@ 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.patcher.patch.resourcePatch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.shared.misc.mapping.get import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch import app.revanced.patches.youtube.misc.playservice.is_19_35_or_greater import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow -import app.revanced.util.indexOfFirstLiteralInstructionOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.Instruction @@ -26,23 +21,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.util.MethodUtil -internal var imageOnlyTabResourceId = -1L - private set -internal var actionBarSearchResultsViewMicId = -1L - private set -internal var ytFillBellId = -1L - private set - -private val navigationBarHookResourcePatch = resourcePatch { - dependsOn(resourceMappingPatch) - - execute { - imageOnlyTabResourceId = resourceMappings["layout", "image_only_tab"] - actionBarSearchResultsViewMicId = resourceMappings["layout", "action_bar_search_results_view_mic"] - ytFillBellId = resourceMappings["drawable", "yt_fill_bell_black_24"] - } -} - internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/shared/NavigationBar;" internal const val EXTENSION_NAVIGATION_BUTTON_DESCRIPTOR = @@ -53,8 +31,8 @@ lateinit var hookNavigationButtonCreated: (String) -> Unit val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navigation or search bar.") { dependsOn( sharedExtensionPatch, - navigationBarHookResourcePatch, playerTypeHookPatch, // Required to detect the search bar in all situations. + resourceMappingPatch // Used by fingerprints ) execute { @@ -99,17 +77,19 @@ val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navig } } - pivotBarButtonsViewSetSelectedFingerprint.method.apply { - val index = indexOfSetViewSelectedInstruction(this) - val instruction = getInstruction(index) - val viewRegister = instruction.registerC - val isSelectedRegister = instruction.registerD + pivotBarButtonsViewSetSelectedFingerprint.let { + it.method.apply { + val index = it.instructionMatches.first().index + val instruction = getInstruction(index) + val viewRegister = instruction.registerC + val isSelectedRegister = instruction.registerD - addInstruction( - index + 1, - "invoke-static { v$viewRegister, v$isSelectedRegister }, " + - "$EXTENSION_CLASS_DESCRIPTOR->navigationTabSelected(Landroid/view/View;Z)V", - ) + addInstruction( + index + 1, + "invoke-static { v$viewRegister, v$isSelectedRegister }, " + + "$EXTENSION_CLASS_DESCRIPTOR->navigationTabSelected(Landroid/view/View;Z)V", + ) + } } // Hook onto back button pressed. Needed to fix race problem with @@ -125,22 +105,17 @@ val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navig // Two different layouts are used at the hooked code. // Insert before the first ViewGroup method call after inflating, // so this works regardless which layout is used. - actionBarSearchResultsFingerprint.method.apply { - val searchBarResourceId = indexOfFirstLiteralInstructionOrThrow( - actionBarSearchResultsViewMicId, - ) + actionBarSearchResultsFingerprint.let { + it.method.apply { + val instructionIndex = it.instructionMatches.last().index + val viewRegister = getInstruction(instructionIndex).registerC - val instructionIndex = indexOfFirstInstructionOrThrow(searchBarResourceId) { - opcode == Opcode.INVOKE_VIRTUAL && getReference()?.name == "setLayoutDirection" + addInstruction( + instructionIndex, + "invoke-static { v$viewRegister }, " + + "$EXTENSION_CLASS_DESCRIPTOR->searchBarResultsViewLoaded(Landroid/view/View;)V", + ) } - - val viewRegister = getInstruction(instructionIndex).registerC - - addInstruction( - instructionIndex, - "invoke-static { v$viewRegister }, " + - "$EXTENSION_CLASS_DESCRIPTOR->searchBarResultsViewLoaded(Landroid/view/View;)V", - ) } hookNavigationButtonCreated = { extensionClassDescriptor -> @@ -154,13 +129,8 @@ val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navig // Fix YT bug of notification tab missing the filled icon. if (is_19_35_or_greater) { - val cairoNotificationEnumReference = with(imageEnumConstructorFingerprint) { - val stringIndex = stringMatches!!.first().index - val cairoNotificationEnumIndex = method.indexOfFirstInstructionOrThrow(stringIndex) { - opcode == Opcode.SPUT_OBJECT - } - method.getInstruction(cairoNotificationEnumIndex).reference - } + val cairoNotificationEnumReference = imageEnumConstructorFingerprint + .instructionMatches.last().getInstruction().reference setEnumMapFingerprint.method.apply { val enumMapIndex = indexOfFirstInstructionReversedOrThrow { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/Fingerprints.kt index 95dbd54ecb..10fb649a69 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/Fingerprints.kt @@ -1,18 +1,15 @@ package app.revanced.patches.youtube.misc.playercontrols +import app.revanced.patcher.checkCast import app.revanced.patcher.fingerprint -import app.revanced.util.containsLiteralInstruction -import app.revanced.util.literal +import app.revanced.patcher.literal +import app.revanced.patcher.methodCall +import app.revanced.patcher.opcode +import app.revanced.patches.shared.misc.mapping.resourceLiteral import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode -internal val playerTopControlsInflateFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("V") - parameters() - literal { controlsLayoutStub } -} - -internal val playerControlsExtensionHookListenersExistFingerprint = fingerprint { +internal val playerControlsExtensionHookListenersExistFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC) returns("Z") parameters() @@ -22,7 +19,7 @@ internal val playerControlsExtensionHookListenersExistFingerprint = fingerprint } } -internal val playerControlsExtensionHookFingerprint = fingerprint { +internal val playerControlsExtensionHookFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC) returns("V") parameters("Z") @@ -32,42 +29,62 @@ internal val playerControlsExtensionHookFingerprint = fingerprint { } } -internal val playerBottomControlsInflateFingerprint = fingerprint { +internal val playerTopControlsInflateFingerprint by fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("V") + parameters() + instructions( + resourceLiteral("id", "controls_layout_stub"), + methodCall("Landroid/view/ViewStub;", "inflate"), + opcode(Opcode.MOVE_RESULT_OBJECT, maxAfter = 0) + ) +} + +internal val playerBottomControlsInflateFingerprint by fingerprint { returns("Ljava/lang/Object;") parameters() - literal { bottomUiContainerResourceId } + instructions( + resourceLiteral("id", "bottom_ui_container_stub"), + methodCall("Landroid/view/ViewStub;", "inflate"), + opcode(Opcode.MOVE_RESULT_OBJECT, maxAfter = 0) + ) } -internal val overlayViewInflateFingerprint = fingerprint { +internal val overlayViewInflateFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("Landroid/view/View;") - custom { methodDef, _ -> - methodDef.containsLiteralInstruction(fullscreenButton) && - methodDef.containsLiteralInstruction(heatseekerViewstub) - } + instructions( + resourceLiteral("id", "heatseeker_viewstub"), + resourceLiteral("id", "fullscreen_button"), + checkCast("Landroid/widget/ImageView;") + ) } /** * Resolves to the class found in [playerTopControlsInflateFingerprint]. */ -internal val controlsOverlayVisibilityFingerprint = fingerprint { +internal val controlsOverlayVisibilityFingerprint by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL) returns("V") parameters("Z", "Z") } -internal val playerBottomControlsExploderFeatureFlagFingerprint = fingerprint { +internal val playerBottomControlsExploderFeatureFlagFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") parameters() - literal { 45643739L } + instructions( + literal(45643739L) + ) } -internal val playerTopControlsExperimentalLayoutFeatureFlagFingerprint = fingerprint { +internal val playerTopControlsExperimentalLayoutFeatureFlagFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("I") parameters() - literal { 45629424L } + instructions( + literal(45629424L) + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsPatch.kt index 7db8de5b2b..ae93adf5a0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsPatch.kt @@ -8,9 +8,8 @@ import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.util.Document import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.shared.misc.mapping.get +import app.revanced.patches.shared.misc.mapping.getResourceId import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater import app.revanced.patches.youtube.misc.playservice.is_19_35_or_greater @@ -40,18 +39,7 @@ internal lateinit var addTopControl: (String) -> Unit lateinit var addBottomControl: (String) -> Unit private set -internal var bottomUiContainerResourceId = -1L - private set -internal var controlsLayoutStub = -1L - private set -internal var heatseekerViewstub = -1L - private set -internal var fullscreenButton = -1L - private set - val playerControlsResourcePatch = resourcePatch { - dependsOn(resourceMappingPatch) - /** * The element to the left of the element being added. */ @@ -65,11 +53,6 @@ val playerControlsResourcePatch = resourcePatch { execute { val targetResourceName = "youtube_controls_bottom_ui_container.xml" - bottomUiContainerResourceId = resourceMappings["id", "bottom_ui_container_stub"] - controlsLayoutStub = resourceMappings["id", "controls_layout_stub"] - heatseekerViewstub = resourceMappings["id", "heatseeker_viewstub"] - fullscreenButton = resourceMappings["id", "fullscreen_button"] - bottomTargetDocument = document("res/layout/$targetResourceName") val bottomTargetElement: Node = bottomTargetDocument.getElementsByTagName( @@ -226,29 +209,28 @@ val playerControlsPatch = bytecodePatch( dependsOn( playerControlsResourcePatch, sharedExtensionPatch, + resourceMappingPatch // Used by fingerprints. ) execute { - fun MutableMethod.indexOfFirstViewInflateOrThrow() = indexOfFirstInstructionOrThrow { - val reference = getReference() - reference?.definingClass == "Landroid/view/ViewStub;" && - reference.name == "inflate" - } + playerBottomControlsInflateFingerprint.let { + it.method.apply { + inflateBottomControlMethod = this - playerBottomControlsInflateFingerprint.method.apply { - inflateBottomControlMethod = this - - val inflateReturnObjectIndex = indexOfFirstViewInflateOrThrow() + 1 - inflateBottomControlRegister = getInstruction(inflateReturnObjectIndex).registerA - inflateBottomControlInsertIndex = inflateReturnObjectIndex + 1 + val inflateReturnObjectIndex = it.instructionMatches.last().index + inflateBottomControlRegister = getInstruction(inflateReturnObjectIndex).registerA + inflateBottomControlInsertIndex = inflateReturnObjectIndex + 1 + } } - playerTopControlsInflateFingerprint.method.apply { - inflateTopControlMethod = this + playerTopControlsInflateFingerprint.let { + it.method.apply { + inflateTopControlMethod = this - val inflateReturnObjectIndex = indexOfFirstViewInflateOrThrow() + 1 - inflateTopControlRegister = getInstruction(inflateReturnObjectIndex).registerA - inflateTopControlInsertIndex = inflateReturnObjectIndex + 1 + val inflateReturnObjectIndex = it.instructionMatches.last().index + inflateTopControlRegister = getInstruction(inflateReturnObjectIndex).registerA + inflateTopControlInsertIndex = inflateReturnObjectIndex + 1 + } } visibilityMethod = controlsOverlayVisibilityFingerprint.match( @@ -257,21 +239,17 @@ val playerControlsPatch = bytecodePatch( // Hook the fullscreen close button. Used to fix visibility // when seeking and other situations. - overlayViewInflateFingerprint.method.apply { - val resourceIndex = indexOfFirstLiteralInstructionReversedOrThrow(fullscreenButton) + overlayViewInflateFingerprint.let { + it.method.apply { + val index = it.instructionMatches.last().index + val register = getInstruction(index).registerA - val index = indexOfFirstInstructionOrThrow(resourceIndex) { - opcode == Opcode.CHECK_CAST && - getReference()?.type == - "Landroid/widget/ImageView;" + addInstruction( + index + 1, + "invoke-static { v$register }, " + + "$EXTENSION_CLASS_DESCRIPTOR->setFullscreenCloseButton(Landroid/widget/ImageView;)V", + ) } - val register = getInstruction(index).registerA - - addInstruction( - index + 1, - "invoke-static { v$register }, " + - "$EXTENSION_CLASS_DESCRIPTOR->setFullscreenCloseButton(Landroid/widget/ImageView;)V", - ) } visibilityImmediateCallbacksExistMethod = playerControlsExtensionHookListenersExistFingerprint.method diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/Fingerprints.kt index 2faae3acc4..27d72d7be3 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/Fingerprints.kt @@ -1,10 +1,13 @@ package app.revanced.patches.youtube.misc.playertype +import app.revanced.patcher.fieldAccess import app.revanced.patcher.fingerprint +import app.revanced.patcher.literal +import app.revanced.patcher.patch.BytecodePatchContext import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val playerTypeFingerprint = fingerprint { +internal val playerTypeFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L") @@ -15,14 +18,31 @@ internal val playerTypeFingerprint = fingerprint { custom { _, classDef -> classDef.endsWith("/YouTubePlayerOverlaysLayout;") } } -internal val videoStateFingerprint = fingerprint { +internal val videoStateEnumFingerprint by fingerprint { + accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR) + parameters() + strings( + "NEW", + "PLAYING", + "PAUSED", + "RECOVERABLE_ERROR", + "UNRECOVERABLE_ERROR", + "ENDED" + ) +} + +internal val videoStateFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("Lcom/google/android/libraries/youtube/player/features/overlay/controls/ControlsState;") - opcodes( - Opcode.CONST_4, - Opcode.IF_EQZ, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, // obfuscated parameter field name + instructions( + literal(1), + literal(literal = 0, maxAfter = 10), + // Obfuscated parameter field name. + fieldAccess( + definingClass = { "Lcom/google/android/libraries/youtube/player/features/overlay/controls/ControlsState;"}, + type = { context: BytecodePatchContext -> with(context) { videoStateEnumFingerprint.originalClassDef.type } }, + maxAfter = 5 + ) ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/PlayerTypeHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/PlayerTypeHookPatch.kt index e021928a8b..ed43d15413 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/PlayerTypeHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/PlayerTypeHookPatch.kt @@ -20,17 +20,20 @@ val playerTypeHookPatch = bytecodePatch( "invoke-static {p1}, $EXTENSION_CLASS_DESCRIPTOR->setPlayerType(Ljava/lang/Enum;)V", ) - videoStateFingerprint.method.apply { - val endIndex = videoStateFingerprint.patternMatch!!.endIndex - val videoStateFieldName = getInstruction(endIndex).reference + videoStateFingerprint.let { + it.method.apply { + val videoStateFieldName = getInstruction( + it.instructionMatches.last().index + ).reference - addInstructions( - 0, - """ + addInstructions( + 0, + """ iget-object v0, p1, $videoStateFieldName # copy VideoState parameter field invoke-static {v0}, $EXTENSION_CLASS_DESCRIPTOR->setVideoState(Ljava/lang/Enum;)V - """, - ) + """ + ) + } } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playservice/VersionCheckPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playservice/VersionCheckPatch.kt index bb1e3558e0..f02b377cfd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playservice/VersionCheckPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playservice/VersionCheckPatch.kt @@ -5,15 +5,6 @@ package app.revanced.patches.youtube.misc.playservice import app.revanced.patcher.patch.resourcePatch import app.revanced.util.findElementByAttributeValueOrThrow -@Deprecated("19.16.39 is the lowest supported version") -var is_19_03_or_greater = false - private set -@Deprecated("19.16.39 is the lowest supported version") -var is_19_04_or_greater = false - private set -@Deprecated("19.16.39 is the lowest supported version") -var is_19_16_or_greater = false - private set var is_19_17_or_greater = false private set var is_19_18_or_greater = false @@ -46,6 +37,12 @@ var is_19_47_or_greater = false private set var is_19_49_or_greater = false private set +var is_20_02_or_greater = false + private set +var is_20_03_or_greater = false + private set +var is_20_05_or_greater = false + private set val versionCheckPatch = resourcePatch( description = "Uses the Play Store service version to find the major/minor version of the YouTube target app.", @@ -61,9 +58,6 @@ val versionCheckPatch = resourcePatch( } // All bug fix releases always seem to use the same play store version as the minor version. - is_19_03_or_greater = 240402000 <= playStoreServicesVersion - is_19_04_or_greater = 240502000 <= playStoreServicesVersion - is_19_16_or_greater = 241702000 <= playStoreServicesVersion is_19_17_or_greater = 241802000 <= playStoreServicesVersion is_19_18_or_greater = 241902000 <= playStoreServicesVersion is_19_23_or_greater = 242402000 <= playStoreServicesVersion @@ -80,5 +74,8 @@ val versionCheckPatch = resourcePatch( is_19_46_or_greater = 244705000 <= playStoreServicesVersion is_19_47_or_greater = 244799000 <= playStoreServicesVersion is_19_49_or_greater = 245005000 <= playStoreServicesVersion + is_20_02_or_greater = 250299000 <= playStoreServicesVersion + is_20_03_or_greater = 250405000 <= playStoreServicesVersion + is_20_05_or_greater = 250605000 <= playStoreServicesVersion } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/Fingerprints.kt index 72734bba70..7e9e67a285 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/Fingerprints.kt @@ -4,7 +4,7 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint -internal val copyTextFingerprint = fingerprint { +internal val copyTextFingerprint by fingerprint { returns("V") parameters("L", "Ljava/util/Map;") opcodes( @@ -21,7 +21,7 @@ internal val copyTextFingerprint = fingerprint { strings("text/plain") } -internal val systemShareSheetFingerprint = fingerprint { +internal val systemShareSheetFingerprint by fingerprint { returns("V") parameters("L", "Ljava/util/Map;") opcodes( @@ -31,7 +31,7 @@ internal val systemShareSheetFingerprint = fingerprint { strings("YTShare_Logging_Share_Intent_Endpoint_Byte_Array") } -internal val youtubeShareSheetFingerprint = fingerprint { +internal val youtubeShareSheetFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L", "Ljava/util/Map;") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/recyclerviewtree/hook/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/recyclerviewtree/hook/Fingerprints.kt index 09aa7bf4cd..a2bf2ee303 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/recyclerviewtree/hook/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/recyclerviewtree/hook/Fingerprints.kt @@ -4,9 +4,8 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val recyclerViewTreeObserverFingerprint = fingerprint { +internal val recyclerViewTreeObserverFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - returns("V") opcodes( Opcode.CHECK_CAST, Opcode.NEW_INSTANCE, diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/recyclerviewtree/hook/RecyclerViewTreeHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/recyclerviewtree/hook/RecyclerViewTreeHookPatch.kt index 86588df099..1044c7d2f2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/recyclerviewtree/hook/RecyclerViewTreeHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/recyclerviewtree/hook/RecyclerViewTreeHookPatch.kt @@ -13,7 +13,7 @@ val recyclerViewTreeHookPatch = bytecodePatch { execute { recyclerViewTreeObserverFingerprint.method.apply { - val insertIndex = recyclerViewTreeObserverFingerprint.patternMatch!!.startIndex + 1 + val insertIndex = recyclerViewTreeObserverFingerprint.instructionMatches.first().index + 1 val recyclerViewParameter = 2 addRecyclerViewTreeHook = { classDescriptor -> diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/Fingerprints.kt index c866203849..845db2b5b8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/Fingerprints.kt @@ -1,11 +1,13 @@ package app.revanced.patches.youtube.misc.settings import app.revanced.patcher.fingerprint -import app.revanced.util.literal +import app.revanced.patcher.literal +import app.revanced.patcher.opcode +import app.revanced.patches.shared.misc.mapping.resourceLiteral import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val licenseActivityOnCreateFingerprint = fingerprint { +internal val licenseActivityOnCreateFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L") @@ -14,21 +16,23 @@ internal val licenseActivityOnCreateFingerprint = fingerprint { } } -internal val setThemeFingerprint = fingerprint { +internal val setThemeFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("L") parameters() - opcodes(Opcode.RETURN_OBJECT) - literal { appearanceStringId } + instructions( + resourceLiteral("string", "app_theme_appearance_dark"), + ) } /** * Added in YouTube v19.04.38. */ -internal const val CAIRO_CONFIG_LITERAL_VALUE = 45532100L - -internal val cairoFragmentConfigFingerprint = fingerprint { +internal val cairoFragmentConfigFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") - literal { CAIRO_CONFIG_LITERAL_VALUE } -} + instructions( + literal(45532100L), + opcode(Opcode.MOVE_RESULT, 10) + ) +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt index 6830628635..5ff9ca33a4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt @@ -1,18 +1,14 @@ package app.revanced.patches.youtube.misc.settings -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable import app.revanced.patches.all.misc.packagename.setOrGetFallbackPackageName import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch -import app.revanced.patches.shared.misc.mapping.get import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.shared.misc.settings.preference.* import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting import app.revanced.patches.shared.misc.settings.settingsPatch @@ -30,10 +26,6 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter import com.android.tools.smali.dexlib2.util.MethodUtil -// Used by a fingerprint() from SettingsPatch. -internal var appearanceStringId = -1L - private set - private val preferences = mutableSetOf() fun addSettingPreference(screen: BasePreference) { @@ -69,9 +61,6 @@ private val settingsResourcePatch = resourcePatch { ) execute { - // Used for a fingerprint from SettingsPatch. - appearanceStringId = resourceMappings["string", "app_theme_appearance_dark"] - arrayOf( ResourceGroup("drawable", "revanced_settings_icon.xml"), ResourceGroup("layout", "revanced_settings_with_toolbar.xml"), @@ -184,24 +173,13 @@ val settingsPatch = bytecodePatch( ) ) - setThemeFingerprint.method.let { setThemeMethod -> - setThemeMethod.implementation!!.instructions.mapIndexedNotNull { i, instruction -> - if (instruction.opcode == Opcode.RETURN_OBJECT) i else null - }.asReversed().forEach { returnIndex -> - // The following strategy is to replace the return instruction with the setTheme instruction, - // then add a return instruction after the setTheme instruction. - // This is done because the return instruction is a target of another instruction. - - setThemeMethod.apply { - // This register is returned by the setTheme method. - val register = getInstruction(returnIndex).registerA - replaceInstruction( - returnIndex, - "invoke-static { v$register }, " + - "$themeHelperDescriptor->$setThemeMethodName(Ljava/lang/Enum;)V", - ) - addInstruction(returnIndex + 1, "return-object v$register") - } + setThemeFingerprint.method.apply { + findInstructionIndicesReversedOrThrow(Opcode.RETURN_OBJECT).forEach { returnIndex -> + val register = getInstruction(returnIndex).registerA + addInstructionsAtControlFlowLabel( + returnIndex, + "invoke-static { v$register }, $themeHelperDescriptor->$setThemeMethodName(Ljava/lang/Enum;)V", + ) } } @@ -248,11 +226,13 @@ val settingsPatch = bytecodePatch( } // Add setting to force cairo settings fragment on/off. - cairoFragmentConfigFingerprint.method.insertFeatureFlagBooleanOverride( - CAIRO_CONFIG_LITERAL_VALUE, - "$activityHookClassDescriptor->useCairoSettingsFragment(Z)Z" - ) - } + cairoFragmentConfigFingerprint.let { + it.method.insertFeatureFlagBooleanOverride( + it.instructionMatches.last().index, + "$activityHookClassDescriptor->useCairoSettingsFragment(Z)Z" + ) + } + } finalize { PreferenceScreen.close() diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/Fingerprints.kt index 65cb707693..530359cab8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/Fingerprints.kt @@ -1,7 +1,10 @@ package app.revanced.patches.youtube.misc.zoomhaptics import app.revanced.patcher.fingerprint +import app.revanced.patcher.string -internal val zoomHapticsFingerprint = fingerprint { - strings("Failed to haptics vibrate for video zoom") +internal val zoomHapticsFingerprint by fingerprint { + instructions( + string("Failed to haptics vibrate for video zoom"), + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt index a242d6fad9..a396d8c460 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt @@ -1,10 +1,15 @@ package app.revanced.patches.youtube.shared +import app.revanced.patcher.fieldAccess import app.revanced.patcher.fingerprint +import app.revanced.patcher.newInstance +import app.revanced.patcher.opcode +import app.revanced.patcher.string import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val autoRepeatFingerprint = fingerprint { + +internal val autoRepeatFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters() @@ -13,32 +18,25 @@ internal val autoRepeatFingerprint = fingerprint { } } -internal val autoRepeatParentFingerprint = fingerprint { +internal val autoRepeatParentFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") - strings( - "play() called when the player wasn't loaded.", - "play() blocked because Background Playability failed", + instructions( + string("play() called when the player wasn't loaded."), + string("play() blocked because Background Playability failed") ) } -internal val layoutConstructorFingerprint = fingerprint { +internal val layoutConstructorFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters() - strings("1.0x") -} - -internal val mainActivityFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - parameters() - custom { _, classDef -> - // Old versions of YouTube called this class "WatchWhileActivity" instead. - classDef.endsWith("MainActivity;") || classDef.endsWith("WatchWhileActivity;") - } + instructions( + string("1.0x"), + ) } -internal val mainActivityOnCreateFingerprint = fingerprint { +internal val mainActivityOnCreateFingerprint by fingerprint { returns("V") parameters("Landroid/os/Bundle;") custom { method, classDef -> @@ -51,7 +49,7 @@ internal val mainActivityOnCreateFingerprint = fingerprint { } } -internal val rollingNumberTextViewAnimationUpdateFingerprint = fingerprint { +internal val rollingNumberTextViewAnimationUpdateFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("Landroid/graphics/Bitmap;") @@ -77,16 +75,18 @@ internal val rollingNumberTextViewAnimationUpdateFingerprint = fingerprint { } } -internal val seekbarFingerprint = fingerprint { +internal val seekbarFingerprint by fingerprint { returns("V") - strings("timed_markers_width") + instructions( + string("timed_markers_width"), + ) } -internal val seekbarOnDrawFingerprint = fingerprint { +internal val seekbarOnDrawFingerprint by fingerprint { custom { method, _ -> method.name == "onDraw" } } -internal val subtitleButtonControllerFingerprint = fingerprint { +internal val subtitleButtonControllerFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("Lcom/google/android/libraries/youtube/player/subtitles/model/SubtitleTrack;") @@ -103,28 +103,15 @@ internal val subtitleButtonControllerFingerprint = fingerprint { ) } -internal val newVideoQualityChangedFingerprint = fingerprint { +internal val newVideoQualityChangedFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("L") parameters("L") - opcodes( - Opcode.IGET, // Video resolution (human readable). - Opcode.IGET_OBJECT, - Opcode.IGET_BOOLEAN, - Opcode.IGET_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_DIRECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.GOTO, - Opcode.CONST_4, - Opcode.IF_NE, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IGET, + instructions( + newInstance("Lcom/google/android/libraries/youtube/innertube/model/media/VideoQuality;"), + opcode(Opcode.IGET_OBJECT), + opcode(Opcode.CHECK_CAST), + fieldAccess(type = "I", opcode = Opcode.IGET, maxAfter = 0), // Video resolution (human readable). + fieldAccess(type = "Ljava/lang/String;", opcode = Opcode.IGET_OBJECT, maxAfter = 0), ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/Fingerprints.kt index a338ea6b7d..16dbc07f73 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/Fingerprints.kt @@ -1,23 +1,30 @@ package app.revanced.patches.youtube.video.audio import app.revanced.patcher.fingerprint +import app.revanced.patcher.string import com.android.tools.smali.dexlib2.AccessFlags -internal val streamingModelBuilderFingerprint = fingerprint { +internal val streamingModelBuilderFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("L") - strings("vprng") + instructions( + string("vprng") + ) } -internal val menuItemAudioTrackFingerprint = fingerprint { +internal val menuItemAudioTrackFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters("L") returns("V") - strings("menu_item_audio_track") + instructions( + string("menu_item_audio_track") + ) } -internal val audioStreamingTypeSelector = fingerprint { +internal val audioStreamingTypeSelector by fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL) returns("L") - strings("raw") // String is not unique + instructions( + string("raw") // String is not unique + ) } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatch.kt index 32bfeadd6d..9e1c5ea88a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatch.kt @@ -79,9 +79,7 @@ val forceOriginalAudioPatch = bytecodePatch( val isDefaultMethod = streamingModelBuilderFingerprint.originalMethod.firstFormatStreamingModelCall("Z") val audioTrackIdMethod = menuItemAudioTrackFingerprint.originalMethod.firstFormatStreamingModelCall() val audioTrackDisplayNameMethod = audioStreamingTypeSelector.originalMethod.firstFormatStreamingModelCall() - val formatStreamModelClass = proxy(classes.first { - it.type == audioTrackIdMethod.definingClass - }).mutableClass + val formatStreamModelClass = mutableClassBy(audioTrackIdMethod.definingClass) formatStreamModelClass.apply { // Add a new field to store the override. diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/hdr/DisableHdrPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/hdr/DisableHdrPatch.kt index c9f4383f02..8b217e024f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/hdr/DisableHdrPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/hdr/DisableHdrPatch.kt @@ -8,9 +8,6 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstructionOrThrow -import com.android.tools.smali.dexlib2.iface.reference.MethodReference private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/DisableHdrPatch;" @@ -47,14 +44,9 @@ val disableHdrPatch = bytecodePatch( hdrCapabilityFingerprint.let { it.originalMethod.apply { - val stringIndex = it.stringMatches!!.first().index - val navigateIndex = indexOfFirstInstructionOrThrow(stringIndex) { - val reference = getReference() - reference?.parameterTypes == listOf("I", "Landroid/view/Display;") && - reference.returnType == "Z" - } + val navigateIndex = it.instructionMatches.last().index - // Modify the HDR lookup method (Method is in the same class as the fingerprint). + // Modify the HDR lookup method (Method is in the same class as the fingerprint class). navigate(this).to(navigateIndex).stop().addInstructionsWithLabels( 0, """ diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/hdr/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/hdr/Fingerprints.kt index fe8d2dce3c..1dc39914de 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/hdr/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/hdr/Fingerprints.kt @@ -1,12 +1,15 @@ package app.revanced.patches.youtube.video.hdr import app.revanced.patcher.fingerprint +import app.revanced.patcher.methodCall +import app.revanced.patcher.string import com.android.tools.smali.dexlib2.AccessFlags -internal val hdrCapabilityFingerprint = fingerprint { +internal val hdrCapabilityFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - strings( - "av1_profile_main_10_hdr_10_plus_supported", - "video/av01" + instructions( + string("av1_profile_main_10_hdr_10_plus_supported"), + string("video/av01"), + methodCall(returnType = "Z", parameters = listOf("I", "Landroid/view/Display;")) ) } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/Fingerprints.kt index d0c961c9d4..9c13357665 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/Fingerprints.kt @@ -1,18 +1,21 @@ package app.revanced.patches.youtube.video.information import app.revanced.patcher.fingerprint +import app.revanced.patcher.string import app.revanced.patches.youtube.shared.newVideoQualityChangedFingerprint import app.revanced.util.getReference import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.reference.FieldReference -internal val createVideoPlayerSeekbarFingerprint = fingerprint { +internal val createVideoPlayerSeekbarFingerprint by fingerprint { returns("V") - strings("timed_markers_width") + instructions( + string("timed_markers_width"), + ) } -internal val onPlaybackSpeedItemClickFingerprint = fingerprint { +internal val onPlaybackSpeedItemClickFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L", "L", "I", "J") @@ -25,23 +28,27 @@ internal val onPlaybackSpeedItemClickFingerprint = fingerprint { } } -internal val playerControllerSetTimeReferenceFingerprint = fingerprint { +internal val playerControllerSetTimeReferenceFingerprint by fingerprint { opcodes(Opcode.INVOKE_DIRECT_RANGE, Opcode.IGET_OBJECT) strings("Media progress reported outside media playback: ") } -internal val playerInitFingerprint = fingerprint { - strings("playVideo called on player response with no videoStreamingData.") +internal val playerInitFingerprint by fingerprint { + instructions( + string("playVideo called on player response with no videoStreamingData."), + ) } /** * Matched using class found in [playerInitFingerprint]. */ -internal val seekFingerprint = fingerprint { - strings("Attempting to seek during an ad") +internal val seekFingerprint by fingerprint { + instructions( + string("Attempting to seek during an ad"), + ) } -internal val videoLengthFingerprint = fingerprint { +internal val videoLengthFingerprint by fingerprint { opcodes( Opcode.MOVE_RESULT_WIDE, Opcode.CMP_LONG, @@ -61,7 +68,7 @@ internal val videoLengthFingerprint = fingerprint { /** * Matches using class found in [mdxPlayerDirectorSetVideoStageFingerprint]. */ -internal val mdxSeekFingerprint = fingerprint { +internal val mdxSeekFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") parameters("J", "L") @@ -78,19 +85,20 @@ internal val mdxSeekFingerprint = fingerprint { } } -internal val mdxPlayerDirectorSetVideoStageFingerprint = fingerprint { - strings("MdxDirector setVideoStage ad should be null when videoStage is not an Ad state ") +internal val mdxPlayerDirectorSetVideoStageFingerprint by fingerprint { + instructions( + string("MdxDirector setVideoStage ad should be null when videoStage is not an Ad state "), + ) } /** * Matches using class found in [mdxPlayerDirectorSetVideoStageFingerprint]. */ -internal val mdxSeekRelativeFingerprint = fingerprint { +internal val mdxSeekRelativeFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) // Return type is boolean up to 19.39, and void with 19.39+. parameters("J", "L") opcodes( - Opcode.IGET_OBJECT, Opcode.INVOKE_INTERFACE, ) @@ -99,7 +107,7 @@ internal val mdxSeekRelativeFingerprint = fingerprint { /** * Matches using class found in [playerInitFingerprint]. */ -internal val seekRelativeFingerprint = fingerprint { +internal val seekRelativeFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) // Return type is boolean up to 19.39, and void with 19.39+. parameters("J", "L") @@ -112,7 +120,7 @@ internal val seekRelativeFingerprint = fingerprint { /** * Resolves with the class found in [newVideoQualityChangedFingerprint]. */ -internal val playbackSpeedMenuSpeedChangedFingerprint = fingerprint { +internal val playbackSpeedMenuSpeedChangedFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("L") parameters("L") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt index a22934d1ca..0a586e7235 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt @@ -125,12 +125,12 @@ val videoInformationPatch = bytecodePatch( val videoLengthMethodMatch = videoLengthFingerprint.match(originalClassDef) videoLengthMethodMatch.method.apply { - val videoLengthRegisterIndex = videoLengthMethodMatch.patternMatch!!.endIndex - 2 + val videoLengthRegisterIndex = videoLengthMethodMatch.instructionMatches.last().index - 2 val videoLengthRegister = getInstruction(videoLengthRegisterIndex).registerA val dummyRegisterForLong = videoLengthRegister + 1 // required for long values since they are wide addInstruction( - videoLengthMethodMatch.patternMatch!!.endIndex, + videoLengthMethodMatch.instructionMatches.last().index, "invoke-static {v$videoLengthRegister, v$dummyRegisterForLong}, " + "$EXTENSION_CLASS_DESCRIPTOR->setVideoLength(J)V", ) @@ -159,7 +159,7 @@ val videoInformationPatch = bytecodePatch( * Set the video time method */ timeMethod = navigate(playerControllerSetTimeReferenceFingerprint.originalMethod) - .to(playerControllerSetTimeReferenceFingerprint.patternMatch!!.startIndex) + .to(playerControllerSetTimeReferenceFingerprint.instructionMatches.first().index) .stop() /* @@ -186,8 +186,8 @@ val videoInformationPatch = bytecodePatch( getInstruction(indexOfFirstInstructionOrThrow(Opcode.IF_EQZ) - 1).reference as FieldReference setPlaybackSpeedMethod = - proxy(classes.first { it.type == setPlaybackSpeedMethodReference.definingClass }) - .mutableClass.methods.first { it.name == setPlaybackSpeedMethodReference.name } + mutableClassBy(setPlaybackSpeedMethodReference.definingClass) + .methods.first { it.name == setPlaybackSpeedMethodReference.name } setPlaybackSpeedMethodIndex = 0 } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/Fingerprints.kt index 603329de7d..c62753f09b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/Fingerprints.kt @@ -1,12 +1,42 @@ package app.revanced.patches.youtube.video.playerresponse import app.revanced.patcher.fingerprint +import app.revanced.patcher.string import com.android.tools.smali.dexlib2.AccessFlags + +/** + * For targets 20.02 and later. + */ +internal val playerParameterBuilderFingerprint by fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("L") + parameters( + "Ljava/lang/String;", // VideoId. + "[B", + "Ljava/lang/String;", // Player parameters proto buffer. + "Ljava/lang/String;", + "I", + "I", + "L", // 19.25+ parameter + "Ljava/util/Set;", + "Ljava/lang/String;", + "Ljava/lang/String;", + "L", + "Z", // Appears to indicate if the video id is being opened or is currently playing. + "Z", + "Z", + "Z", + ) + instructions( + string("psps"), + ) +} + /** - * For targets 19.25 and later. + * For targets 19.25 to 19.50. */ -internal val playerParameterBuilderFingerprint = fingerprint { +internal val playerParameterBuilder1925Fingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("L") parameters( @@ -25,13 +55,15 @@ internal val playerParameterBuilderFingerprint = fingerprint { "Z", "Z", ) - strings("psps") + instructions( + string("psps"), + ) } /** * For targets 19.24 and earlier. */ -internal val playerParameterBuilderLegacyFingerprint = fingerprint { +internal val playerParameterBuilderLegacyFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("L") parameters( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/PlayerResponseMethodHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/PlayerResponseMethodHookPatch.kt index b990d74afa..a56d22008a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/PlayerResponseMethodHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/PlayerResponseMethodHookPatch.kt @@ -1,11 +1,13 @@ package app.revanced.patches.youtube.video.playerresponse +import app.revanced.patcher.Fingerprint import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.playservice.is_19_23_or_greater +import app.revanced.patches.youtube.misc.playservice.is_20_02_or_greater import app.revanced.patches.youtube.misc.playservice.versionCheckPatch private val hooks = mutableSetOf() @@ -35,15 +37,18 @@ val playerResponseMethodHookPatch = bytecodePatch { ) execute { - playerResponseMethod = if (is_19_23_or_greater) { + val fingerprint : Fingerprint + if (is_20_02_or_greater) { parameterIsShortAndOpeningOrPlaying = 12 - - playerParameterBuilderFingerprint + fingerprint = playerParameterBuilderFingerprint + } else if (is_19_23_or_greater) { + parameterIsShortAndOpeningOrPlaying = 12 + fingerprint = playerParameterBuilder1925Fingerprint } else { parameterIsShortAndOpeningOrPlaying = 11 - - playerParameterBuilderLegacyFingerprint - }.method + fingerprint = playerParameterBuilderLegacyFingerprint + } + playerResponseMethod = fingerprint.method // On some app targets the method has too many registers pushing the parameters past v15. // If needed, move the parameters to 4-bit registers, so they can be passed to the extension. diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/Fingerprints.kt index e33674a389..e831d790e9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/Fingerprints.kt @@ -1,13 +1,14 @@ package app.revanced.patches.youtube.video.quality import app.revanced.patcher.fingerprint +import app.revanced.patcher.string import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode /** * Matches with the class found in [videoQualitySetterFingerprint]. */ -internal val setQualityByIndexMethodClassFieldReferenceFingerprint = fingerprint { +internal val setQualityByIndexMethodClassFieldReferenceFingerprint by fingerprint { returns("V") parameters("L") opcodes( @@ -17,12 +18,14 @@ internal val setQualityByIndexMethodClassFieldReferenceFingerprint = fingerprint ) } -internal val videoQualityItemOnClickParentFingerprint = fingerprint { +internal val videoQualityItemOnClickParentFingerprint by fingerprint { returns("V") - strings("VIDEO_QUALITIES_MENU_BOTTOM_SHEET_FRAGMENT") + instructions( + string("VIDEO_QUALITIES_MENU_BOTTOM_SHEET_FRAGMENT"), + ) } -internal val videoQualitySetterFingerprint = fingerprint { +internal val videoQualitySetterFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("[L", "I", "Z") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt index f4299dc657..ea468fbc69 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt @@ -88,11 +88,9 @@ val rememberVideoQualityPatch = bytecodePatch( val setQualityByIndexMethodClassFieldReference = getSetQualityByIndexMethodClassFieldReference as FieldReference - val setQualityByIndexMethodClass = classes - .find { classDef -> classDef.type == setQualityByIndexMethodClassFieldReference.type }!! - // Get the name of the setQualityByIndex method. - val setQualityByIndexMethod = setQualityByIndexMethodClass.methods + val setQualityByIndexMethod = classBy(setQualityByIndexMethodClassFieldReference.type) + .methods .find { method -> method.parameterTypes.first() == "I" } ?: throw PatchException("Could not find setQualityByIndex method") @@ -131,7 +129,7 @@ val rememberVideoQualityPatch = bytecodePatch( // Remember video quality if not using old layout menu. newVideoQualityChangedFingerprint.method.apply { - val index = newVideoQualityChangedFingerprint.patternMatch!!.startIndex + val index = newVideoQualityChangedFingerprint.instructionMatches[3].index val qualityRegister = getInstruction(index).registerA addInstruction( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/CustomPlaybackSpeedPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/CustomPlaybackSpeedPatch.kt index 695642c5af..1c1eb4fd7b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/CustomPlaybackSpeedPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/CustomPlaybackSpeedPatch.kt @@ -7,13 +7,10 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch -import app.revanced.patches.shared.misc.mapping.get import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.shared.misc.settings.preference.InputType import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.shared.misc.settings.preference.TextPreference @@ -31,28 +28,12 @@ import app.revanced.util.* import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.FieldReference -import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.immutable.ImmutableField -internal var speedUnavailableId = -1L - private set - -private val customPlaybackSpeedResourcePatch = resourcePatch { - dependsOn(resourceMappingPatch) - - execute { - speedUnavailableId = resourceMappings[ - "string", - "varispeed_unavailable_message", - ] - } -} - private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/components/PlaybackSpeedMenuFilterPatch;" -private const val EXTENSION_CLASS_DESCRIPTOR = +internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/playback/speed/CustomPlaybackSpeedPatch;" internal val customPlaybackSpeedPatch = bytecodePatch( @@ -63,8 +44,8 @@ internal val customPlaybackSpeedPatch = bytecodePatch( lithoFilterPatch, settingsPatch, recyclerViewTreeHookPatch, - customPlaybackSpeedResourcePatch, addResourcesPatch, + resourceMappingPatch, versionCheckPatch ) @@ -83,44 +64,42 @@ internal val customPlaybackSpeedPatch = bytecodePatch( } // Replace the speeds float array with custom speeds. - speedArrayGeneratorFingerprint.method.apply { - val sizeCallIndex = indexOfFirstInstructionOrThrow { getReference()?.name == "size" } - val sizeCallResultRegister = getInstruction(sizeCallIndex + 1).registerA - - replaceInstruction(sizeCallIndex + 1, "const/4 v$sizeCallResultRegister, 0x0") - - val arrayLengthConstIndex = indexOfFirstLiteralInstructionOrThrow(7) - val arrayLengthConstDestination = getInstruction(arrayLengthConstIndex).registerA - val playbackSpeedsArrayType = "$EXTENSION_CLASS_DESCRIPTOR->customPlaybackSpeeds:[F" + speedArrayGeneratorFingerprint.let { + val matches = it.instructionMatches + it.method.apply { + val playbackSpeedsArrayType = "$EXTENSION_CLASS_DESCRIPTOR->customPlaybackSpeeds:[F" + // Apply changes from last index to first to preserve indexes. + + val originalArrayFetchIndex = matches[5].index + val originalArrayFetchDestination = matches[5].getInstruction().registerA + replaceInstruction( + originalArrayFetchIndex, + "sget-object v$originalArrayFetchDestination, $playbackSpeedsArrayType" + ) - addInstructions( - arrayLengthConstIndex + 1, - """ - sget-object v$arrayLengthConstDestination, $playbackSpeedsArrayType - array-length v$arrayLengthConstDestination, v$arrayLengthConstDestination - """, - ) + val arrayLengthConstDestination = matches[3].getInstruction().registerA + val newArrayIndex = matches[4].index + addInstructions( + newArrayIndex, + """ + sget-object v$arrayLengthConstDestination, $playbackSpeedsArrayType + array-length v$arrayLengthConstDestination, v$arrayLengthConstDestination + """ + ) - val originalArrayFetchIndex = indexOfFirstInstructionOrThrow { - val reference = getReference() - reference?.type == "[F" && reference.definingClass.endsWith("/PlayerConfigModel;") + val sizeCallIndex = matches[0].index + 1 + val sizeCallResultRegister = getInstruction(sizeCallIndex).registerA + replaceInstruction(sizeCallIndex, "const/4 v$sizeCallResultRegister, 0x0") } - val originalArrayFetchDestination = - getInstruction(originalArrayFetchIndex).registerA - - replaceInstruction( - originalArrayFetchIndex, - "sget-object v$originalArrayFetchDestination, $playbackSpeedsArrayType", - ) } // Override the min/max speeds that can be used. speedLimiterFingerprint.method.apply { - val limitMinIndex = indexOfFirstLiteralInstructionOrThrow(0.25f.toRawBits().toLong()) - var limitMaxIndex = indexOfFirstLiteralInstruction(2.0f.toRawBits().toLong()) + val limitMinIndex = indexOfFirstLiteralInstructionOrThrow(0.25f) + var limitMaxIndex = indexOfFirstLiteralInstruction(2.0f) // Newer targets have 4x max speed. if (limitMaxIndex < 0) { - limitMaxIndex = indexOfFirstLiteralInstructionOrThrow(4.0f.toRawBits().toLong()) + limitMaxIndex = indexOfFirstLiteralInstructionOrThrow(4.0f) } val limitMinRegister = getInstruction(limitMinIndex).registerA @@ -183,9 +162,7 @@ internal val customPlaybackSpeedPatch = bytecodePatch( if (is_19_25_or_greater) { disableFastForwardNoticeFingerprint.method.apply { - val index = indexOfFirstInstructionOrThrow { - (this as? NarrowLiteralInstruction)?.narrowLiteral == 2.0f.toRawBits() - } + val index = indexOfFirstLiteralInstruction(2.0f) val register = getInstruction(index).registerA addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/Fingerprints.kt index d3aa805d8c..73ed6dc884 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/Fingerprints.kt @@ -1,39 +1,53 @@ package app.revanced.patches.youtube.video.speed.custom +import app.revanced.patcher.fieldAccess import app.revanced.patcher.fingerprint -import app.revanced.util.literal +import app.revanced.patcher.literal +import app.revanced.patcher.methodCall +import app.revanced.patcher.newInstance +import app.revanced.patcher.opcode +import app.revanced.patcher.string +import app.revanced.patches.shared.misc.mapping.resourceLiteral import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val getOldPlaybackSpeedsFingerprint = fingerprint { +internal val getOldPlaybackSpeedsFingerprint by fingerprint { parameters("[L", "I") - strings("menu_item_playback_speed") + instructions( + string("menu_item_playback_speed"), + ) } -internal val showOldPlaybackSpeedMenuFingerprint = fingerprint { - literal { speedUnavailableId } +internal val showOldPlaybackSpeedMenuFingerprint by fingerprint { + instructions( + resourceLiteral("string", "varispeed_unavailable_message") + ) } -internal val showOldPlaybackSpeedMenuExtensionFingerprint = fingerprint { - custom { method, _ -> method.name == "showOldPlaybackSpeedMenu" } +internal val showOldPlaybackSpeedMenuExtensionFingerprint by fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) + returns("V") + parameters() + custom { method, classDef -> + method.name == "showOldPlaybackSpeedMenu" && classDef.type == EXTENSION_CLASS_DESCRIPTOR + } } -internal val speedArrayGeneratorFingerprint = fingerprint { +internal val speedArrayGeneratorFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("[L") parameters("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;") - opcodes( - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.GOTO_16, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IGET_OBJECT, + instructions( + methodCall(name = "size", returnType = "I"), + newInstance("Ljava/text/DecimalFormat;"), + string("0.0#"), + literal(7), + opcode(Opcode.NEW_ARRAY), + fieldAccess(definingClass = "/PlayerConfigModel;", type = "[F") ) - strings("0.0#") } -internal val speedLimiterFingerprint = fingerprint { +internal val speedLimiterFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("F") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/remember/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/remember/Fingerprints.kt index 3924588b42..5c73615f71 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/remember/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/remember/Fingerprints.kt @@ -1,8 +1,11 @@ package app.revanced.patches.youtube.video.speed.remember import app.revanced.patcher.fingerprint +import app.revanced.patcher.string -internal val initializePlaybackSpeedValuesFingerprint = fingerprint { +internal val initializePlaybackSpeedValuesFingerprint by fingerprint { parameters("[L", "I") - strings("menu_item_playback_speed") + instructions( + string("menu_item_playback_speed"), + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/Fingerprints.kt index 6d4a3c6cb8..9c8fbbc23c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/Fingerprints.kt @@ -1,55 +1,54 @@ package app.revanced.patches.youtube.video.videoid import app.revanced.patcher.fingerprint -import app.revanced.util.literal +import app.revanced.patcher.literal +import app.revanced.patcher.methodCall +import app.revanced.patcher.opcode import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val videoIdFingerprint = fingerprint { +internal val videoIdFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("L") - opcodes( - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, + instructions( + methodCall( + definingClass = "Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;", + returnType = "Ljava/lang/String;" + ), + opcode(Opcode.MOVE_RESULT_OBJECT), ) - custom { method, _ -> - method.indexOfPlayerResponseModelString() >= 0 - } } -internal val videoIdBackgroundPlayFingerprint = fingerprint { +internal val videoIdBackgroundPlayFingerprint by fingerprint { accessFlags(AccessFlags.DECLARED_SYNCHRONIZED, AccessFlags.FINAL, AccessFlags.PUBLIC) returns("V") parameters("L") - opcodes( - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.MONITOR_EXIT, - Opcode.RETURN_VOID, - Opcode.MONITOR_EXIT, - Opcode.RETURN_VOID + instructions( + methodCall( + definingClass = "Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;", + returnType = "Ljava/lang/String;" + ), + opcode(Opcode.MOVE_RESULT_OBJECT), + opcode(Opcode.IPUT_OBJECT), + opcode(Opcode.MONITOR_EXIT), + opcode(Opcode.RETURN_VOID), + opcode(Opcode.MONITOR_EXIT), + opcode(Opcode.RETURN_VOID) ) // The target snippet of code is buried in a huge switch block and the target method // has been changed many times by YT which makes identifying it more difficult than usual. custom { method, classDef -> - // Access flags changed in 19.36 - AccessFlags.FINAL.isSet(method.accessFlags) && - AccessFlags.DECLARED_SYNCHRONIZED.isSet(method.accessFlags) && - classDef.methods.count() == 17 && - method.implementation != null && - method.indexOfPlayerResponseModelString() >= 0 + classDef.methods.count() == 17 && + method.implementation != null } - } -internal val videoIdParentFingerprint = fingerprint { +internal val videoIdParentFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("[L") parameters("L") - literal { 524288L } + instructions( + literal(524288L) + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/VideoIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/VideoIdPatch.kt index 6d69381cd3..7ffdb3b2e0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/VideoIdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/VideoIdPatch.kt @@ -9,11 +9,7 @@ import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch import app.revanced.patches.youtube.video.playerresponse.Hook import app.revanced.patches.youtube.video.playerresponse.addPlayerResponseMethodHook import app.revanced.patches.youtube.video.playerresponse.playerResponseMethodHookPatch -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstruction -import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference /** * Hooks the new video id when the video changes. @@ -96,24 +92,22 @@ val videoIdPatch = bytecodePatch( ) execute { - videoIdFingerprint.match(videoIdParentFingerprint.originalClassDef).method.apply { - videoIdMethod = this - val index = indexOfPlayerResponseModelString() - videoIdRegister = getInstruction(index + 1).registerA - videoIdInsertIndex = index + 2 + videoIdFingerprint.match(videoIdParentFingerprint.originalClassDef).let { + it.method.apply { + videoIdMethod = this + val index = it.instructionMatches.first().index + videoIdRegister = getInstruction(index + 1).registerA + videoIdInsertIndex = index + 2 + } } - videoIdBackgroundPlayFingerprint.method.apply { - backgroundPlaybackMethod = this - val index = indexOfPlayerResponseModelString() - backgroundPlaybackVideoIdRegister = getInstruction(index + 1).registerA - backgroundPlaybackInsertIndex = index + 2 + videoIdBackgroundPlayFingerprint.let { + it.method.apply { + backgroundPlaybackMethod = this + val index = it.instructionMatches.first().index + backgroundPlaybackVideoIdRegister = getInstruction(index + 1).registerA + backgroundPlaybackInsertIndex = index + 2 + } } } -} - -internal fun Method.indexOfPlayerResponseModelString() = indexOfFirstInstruction { - val reference = getReference() - reference?.definingClass == "Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;" && - reference.returnType == "Ljava/lang/String;" -} +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/Fingerprints.kt index 7f5469da33..1367bf682c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/Fingerprints.kt @@ -5,7 +5,7 @@ import app.revanced.util.literal import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val videoQualityMenuOptionsFingerprint = fingerprint { +internal val videoQualityMenuOptionsFingerprint by fingerprint { accessFlags(AccessFlags.STATIC) returns("[L") parameters("Landroid/content/Context", "L", "L") @@ -19,7 +19,7 @@ internal val videoQualityMenuOptionsFingerprint = fingerprint { literal { videoQualityQuickMenuAdvancedMenuDescription } } -internal val videoQualityMenuViewInflateFingerprint = fingerprint { +internal val videoQualityMenuViewInflateFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("L") parameters("L", "L", "L") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/RestoreOldVideoQualityMenuPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/RestoreOldVideoQualityMenuPatch.kt index a10e916f73..11e95b6bab 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/RestoreOldVideoQualityMenuPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/RestoreOldVideoQualityMenuPatch.kt @@ -3,14 +3,12 @@ package app.revanced.patches.youtube.video.videoqualitymenu import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.resourcePatch import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch -import app.revanced.patches.shared.misc.mapping.get +import app.revanced.patches.shared.misc.mapping.getResourceId import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.litho.filter.addLithoFilter @@ -41,15 +39,15 @@ private val restoreOldVideoQualityMenuResourcePatch = resourcePatch { ) // Used for the old type of the video quality menu. - videoQualityBottomSheetListFragmentTitle = resourceMappings[ + videoQualityBottomSheetListFragmentTitle = getResourceId( "layout", "video_quality_bottom_sheet_list_fragment_title", - ] + ) - videoQualityQuickMenuAdvancedMenuDescription = resourceMappings[ + videoQualityQuickMenuAdvancedMenuDescription = getResourceId( "string", "video_quality_quick_menu_advanced_menu_description", - ] + ) } } @@ -90,7 +88,7 @@ val restoreOldVideoQualityMenuPatch = bytecodePatch( // and for the Shorts quality flyout on newer app versions. videoQualityMenuViewInflateFingerprint.method.apply { - val checkCastIndex = videoQualityMenuViewInflateFingerprint.patternMatch!!.endIndex + val checkCastIndex = videoQualityMenuViewInflateFingerprint.instructionMatches.last().index val listViewRegister = getInstruction(checkCastIndex).registerA addInstruction( @@ -102,10 +100,9 @@ val restoreOldVideoQualityMenuPatch = bytecodePatch( } // Force YT to add the 'advanced' quality menu for Shorts. - val patternMatch = videoQualityMenuOptionsFingerprint.patternMatch!! - val startIndex = patternMatch.startIndex - if (startIndex != 0) throw PatchException("Unexpected opcode start index: $startIndex") - val insertIndex = patternMatch.endIndex + val instructionMatches = videoQualityMenuOptionsFingerprint.instructionMatches + val startIndex = instructionMatches.first().index + val insertIndex = instructionMatches.last().index videoQualityMenuOptionsFingerprint.method.apply { val register = getInstruction(insertIndex).registerA diff --git a/patches/src/main/kotlin/app/revanced/patches/yuka/misc/unlockpremium/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/yuka/misc/unlockpremium/Fingerprints.kt index af38f28f4d..99f3a4f224 100644 --- a/patches/src/main/kotlin/app/revanced/patches/yuka/misc/unlockpremium/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/yuka/misc/unlockpremium/Fingerprints.kt @@ -3,8 +3,9 @@ package app.revanced.patches.yuka.misc.unlockpremium import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.patcher.fingerprint +import app.revanced.patcher.string -internal val isPremiumFingerprint = fingerprint { +internal val isPremiumFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") opcodes( @@ -13,8 +14,9 @@ internal val isPremiumFingerprint = fingerprint { ) } -internal val yukaUserConstructorFingerprint = fingerprint { +internal val yukaUserConstructorFingerprint by fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) - returns("V") - strings("premiumProvider") + instructions( + string("premiumProvider"), + ) } diff --git a/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt index 8e5a85056a..d41d70d8e5 100644 --- a/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt +++ b/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt @@ -11,9 +11,8 @@ import app.revanced.patcher.patch.BytecodePatchContext import app.revanced.patcher.patch.PatchException import app.revanced.patcher.util.proxy.mutableTypes.MutableClass import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.shared.misc.mapping.get +import app.revanced.patches.shared.misc.mapping.getResourceId import app.revanced.patches.shared.misc.mapping.resourceMappingPatch -import app.revanced.patches.shared.misc.mapping.resourceMappings import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.instruction.Instruction @@ -104,7 +103,7 @@ internal fun MutableMethod.addInstructionsAtControlFlowLabel( * @see [indexOfFirstResourceIdOrThrow], [indexOfFirstLiteralInstructionReversed] */ fun Method.indexOfFirstResourceId(resourceName: String): Int { - val resourceId = resourceMappings["id", resourceName] + val resourceId = getResourceId("id", resourceName) return indexOfFirstLiteralInstruction(resourceId) } @@ -145,7 +144,57 @@ fun Method.indexOfFirstLiteralInstruction(literal: Long) = implementation?.let { */ fun Method.indexOfFirstLiteralInstructionOrThrow(literal: Long): Int { val index = indexOfFirstLiteralInstruction(literal) - if (index < 0) throw PatchException("Could not find literal value: $literal") + if (index < 0) throw PatchException("Could not find literal long: $literal") + return index +} + +/** + * Find the index of the first literal instruction with the given float value. + * + * @return the first literal instruction with the value, or -1 if not found. + * @see indexOfFirstLiteralInstructionOrThrow + */ +fun Method.indexOfFirstLiteralInstruction(literal: Float) = implementation?.let { + val floatBits = literal.toRawBits().toLong() + it.instructions.indexOfFirst { instruction -> + (instruction as? WideLiteralInstruction)?.wideLiteral == floatBits + } +} ?: -1 + +/** + * Find the index of the first literal instruction with the given float value, + * or throw an exception if not found. + * + * @return the first literal instruction with the value, or throws [PatchException] if not found. + */ +fun Method.indexOfFirstLiteralInstructionOrThrow(literal: Float): Int { + val index = indexOfFirstLiteralInstruction(literal) + if (index < 0) throw PatchException("Could not find literal float: $literal") + return index +} + +/** + * Find the index of the first literal instruction with the given double value. + * + * @return the first literal instruction with the value, or -1 if not found. + * @see indexOfFirstLiteralInstructionOrThrow + */ +fun Method.indexOfFirstLiteralInstruction(literal: Double) = implementation?.let { + val floatBits = literal.toRawBits().toLong() + it.instructions.indexOfFirst { instruction -> + (instruction as? WideLiteralInstruction)?.wideLiteral == floatBits + } +} ?: -1 + +/** + * Find the index of the first literal instruction with the given double value, + * or throw an exception if not found. + * + * @return the first literal instruction with the value, or throws [PatchException] if not found. + */ +fun Method.indexOfFirstLiteralInstructionOrThrow(literal: Double): Int { + val index = indexOfFirstLiteralInstruction(literal) + if (index < 0) throw PatchException("Could not find literal double: $literal") return index } @@ -192,7 +241,7 @@ fun BytecodePatchContext.traverseClassHierarchy(targetClass: MutableClass, callb targetClass.superclass ?: return - classBy { targetClass.superclass == it.type }?.mutableClass?.let { + mutableClassByOrNull(targetClass.superclass!!)?.let { traverseClassHierarchy(it, callback) } } @@ -405,6 +454,10 @@ fun Method.findInstructionIndicesReversedOrThrow(opcode: Opcode): List { internal fun MutableMethod.insertFeatureFlagBooleanOverride(literal: Long, extensionsMethod: String) { val literalIndex = indexOfFirstLiteralInstructionOrThrow(literal) + insertFeatureFlagBooleanOverride(literalIndex, extensionsMethod) +} + +internal fun MutableMethod.insertFeatureFlagBooleanOverride(literalIndex: Int, extensionsMethod: String) { val index = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT) val register = getInstruction(index).registerA @@ -430,7 +483,7 @@ fun BytecodePatchContext.forEachLiteralValueInstruction( if (instruction.opcode == Opcode.CONST && (instruction as WideLiteralInstruction).wideLiteral == literal ) { - val mutableMethod = proxy(classDef).mutableClass.findMutableMethodOf(method) + val mutableMethod = mutableClassBy(classDef).findMutableMethodOf(method) block.invoke(mutableMethod, index) } } @@ -469,7 +522,7 @@ fun MutableMethod.returnEarly(bool: Boolean = false) { * * @param literalSupplier The supplier for the literal value to check for. */ -// TODO: add a way for subclasses to also use their own custom fingerprint. +@Deprecated("Instead use instruction filters and `literal()`") fun FingerprintBuilder.literal(literalSupplier: () -> Long) { custom { method, _ -> method.containsLiteralInstruction(literalSupplier()) diff --git a/patches/src/main/resources/addresources/values/arrays.xml b/patches/src/main/resources/addresources/values/arrays.xml index 22cfc21cb5..005c0a1eb4 100644 --- a/patches/src/main/resources/addresources/values/arrays.xml +++ b/patches/src/main/resources/addresources/values/arrays.xml @@ -189,6 +189,7 @@ @string/revanced_miniplayer_type_entry_4 @string/revanced_miniplayer_type_entry_5 @string/revanced_miniplayer_type_entry_6 + @string/revanced_miniplayer_type_entry_7 @@ -199,8 +200,10 @@ MODERN_1 MODERN_2 MODERN_3 + MODERN_4 - + + @string/revanced_miniplayer_type_entry_0 @string/revanced_miniplayer_type_entry_1 @string/revanced_miniplayer_type_entry_2 @string/revanced_miniplayer_type_entry_3 @@ -208,8 +211,24 @@ @string/revanced_miniplayer_type_entry_5 @string/revanced_miniplayer_type_entry_6 - - + + DISABLED + DEFAULT + MINIMAL + TABLET + MODERN_1 + MODERN_2 + MODERN_3 + + + @string/revanced_miniplayer_type_entry_1 + @string/revanced_miniplayer_type_entry_2 + @string/revanced_miniplayer_type_entry_3 + @string/revanced_miniplayer_type_entry_4 + @string/revanced_miniplayer_type_entry_5 + @string/revanced_miniplayer_type_entry_6 + + DEFAULT MINIMAL TABLET @@ -275,15 +294,6 @@ - - @string/revanced_shorts_player_type_shorts - @string/revanced_shorts_player_type_regular_player - - - - SHORTS_PLAYER - REGULAR_PLAYER - @string/revanced_shorts_player_type_shorts @string/revanced_shorts_player_type_regular_player diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index 737608cde7..a8a1de737c 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -1212,6 +1212,7 @@ If later turned off, it is recommended to clear the app data to prevent UI bugs. Modern 1 Modern 2 Modern 3 + Modern 4 Enable rounded corners Corners are rounded Corners are square @@ -1231,14 +1232,14 @@ Miniplayer can be dragged to any corner of the screen" Miniplayer can be dragged off screen to the left or right" Horizontal drag gesture disabled - Hide close button - Close button is hidden - Close button is shown - Hide expand and close buttons - "Buttons are hidden + Hide overlay buttons + Overlay buttons are hidden + Overlay buttons are shown + Hide expand and close buttons + "Buttons are hidden Swipe to expand or close" - Expand and close buttons are shown + Expand and close buttons are shown Hide subtexts Subtexts are hidden Subtexts are shown