chore: Remove obsolete code (#3650)

This commit is contained in:
LisoUseInAIKyrios 2024-10-26 15:39:45 -04:00 committed by oSumAtrIX
parent a361bfb1da
commit cf8104bfb4
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4
84 changed files with 214 additions and 773 deletions

View File

@ -1,42 +0,0 @@
package app.revanced.extension.youtube.patches;
import android.view.WindowManager;
import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.swipecontrols.SwipeControlsHostActivity;
/**
* Patch class for 'hdr-auto-brightness' patch.
*
* Edit: This patch no longer does anything, as YT already uses BRIGHTNESS_OVERRIDE_NONE
* as the default brightness level. The hooked code was also removed from YT 19.09+ as well.
*/
@Deprecated
@SuppressWarnings("unused")
public class HDRAutoBrightnessPatch {
/**
* get brightness override for HDR brightness
*
* @param original brightness youtube would normally set
* @return brightness to set on HRD video
*/
public static float getHDRBrightness(float original) {
// do nothing if disabled
if (!Settings.HDR_AUTO_BRIGHTNESS.get()) {
return original;
}
// override with brightness set by swipe-controls
// only when swipe-controls is active and has overridden the brightness
final SwipeControlsHostActivity swipeControlsHost = SwipeControlsHostActivity.getCurrentHost().get();
if (swipeControlsHost != null
&& swipeControlsHost.getScreen() != null
&& swipeControlsHost.getConfig().getEnableBrightnessControl()
&& !swipeControlsHost.getScreen().isDefaultBrightness()) {
return swipeControlsHost.getScreen().getRawScreenBrightness();
}
// otherwise, set the brightness to auto
return WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
}
}

View File

@ -1,17 +0,0 @@
package app.revanced.extension.youtube.patches;
import app.revanced.extension.youtube.settings.Settings;
/**
* Patch is obsolete and will be deleted in a future release
*/
@SuppressWarnings("unused")
@Deprecated()
public class HideEmailAddressPatch {
//Used by app.revanced.patches.youtube.layout.personalinformation.patch.HideEmailAddressPatch
public static int hideEmailAddress(int originalValue) {
if (Settings.HIDE_EMAIL_ADDRESS.get())
return 8;
return originalValue;
}
}

View File

@ -1,29 +1,32 @@
package app.revanced.extension.youtube.patches;
import static app.revanced.extension.youtube.returnyoutubedislike.ReturnYouTubeDislike.Vote;
import android.graphics.Rect;
import android.graphics.drawable.ShapeDrawable;
import android.os.Build;
import android.text.*;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.revanced.extension.youtube.patches.components.ReturnYouTubeDislikeFilterPatch;
import app.revanced.extension.youtube.patches.spoof.SpoofAppVersionPatch;
import app.revanced.extension.youtube.returnyoutubedislike.ReturnYouTubeDislike;
import app.revanced.extension.youtube.returnyoutubedislike.requests.ReturnYouTubeDislikeApi;
import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.shared.PlayerType;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import static app.revanced.extension.youtube.returnyoutubedislike.ReturnYouTubeDislike.Vote;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.patches.components.ReturnYouTubeDislikeFilterPatch;
import app.revanced.extension.youtube.patches.spoof.SpoofAppVersionPatch;
import app.revanced.extension.youtube.returnyoutubedislike.ReturnYouTubeDislike;
import app.revanced.extension.youtube.returnyoutubedislike.requests.ReturnYouTubeDislikeApi;
import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.shared.PlayerType;
/**
* Handles all interaction of UI patch components.
@ -91,98 +94,6 @@ public class ReturnYouTubeDislikePatch {
// while a regular video is on screen.
}
//
// 17.x non litho regular video player.
//
/**
* Resource identifier of old UI dislike button.
*/
private static final int OLD_UI_DISLIKE_BUTTON_RESOURCE_ID
= Utils.getResourceIdentifier("dislike_button", "id");
/**
* Dislikes text label used by old UI.
*/
@NonNull
private static WeakReference<TextView> oldUITextViewRef = new WeakReference<>(null);
/**
* Original old UI 'Dislikes' text before patch modifications.
* Required to reset the dislikes when changing videos and RYD is not available.
* Set only once during the first load.
*/
private static Spanned oldUIOriginalSpan;
/**
* Replacement span that contains dislike value. Used by {@link #oldUiTextWatcher}.
*/
@Nullable
private static Spanned oldUIReplacementSpan;
/**
* Old UI dislikes can be set multiple times by YouTube.
* To prevent reverting changes made here, this listener overrides any future changes YouTube makes.
*/
private static final TextWatcher oldUiTextWatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
public void afterTextChanged(Editable s) {
if (oldUIReplacementSpan == null || oldUIReplacementSpan.toString().equals(s.toString())) {
return;
}
s.replace(0, s.length(), oldUIReplacementSpan); // Causes a recursive call back into this listener
}
};
private static void updateOldUIDislikesTextView() {
ReturnYouTubeDislike videoData = currentVideoData;
if (videoData == null) {
return;
}
TextView oldUITextView = oldUITextViewRef.get();
if (oldUITextView == null) {
return;
}
oldUIReplacementSpan = videoData.getDislikesSpanForRegularVideo(oldUIOriginalSpan, false, false);
if (!oldUIReplacementSpan.equals(oldUITextView.getText())) {
oldUITextView.setText(oldUIReplacementSpan);
}
}
/**
* Injection point. Called on main thread.
*
* Used when spoofing to 16.x and 17.x versions.
*/
public static void setOldUILayoutDislikes(int buttonViewResourceId, @Nullable TextView textView) {
try {
if (!Settings.RYD_ENABLED.get()
|| buttonViewResourceId != OLD_UI_DISLIKE_BUTTON_RESOURCE_ID
|| textView == null) {
return;
}
Logger.printDebug(() -> "setOldUILayoutDislikes");
if (oldUIOriginalSpan == null) {
// Use value of the first instance, as it appears TextViews can be recycled
// and might contain dislikes previously added by the patch.
oldUIOriginalSpan = (Spanned) textView.getText();
}
oldUITextViewRef = new WeakReference<>(textView);
// No way to check if a listener is already attached, so remove and add again.
textView.removeTextChangedListener(oldUiTextWatcher);
textView.addTextChangedListener(oldUiTextWatcher);
updateOldUIDislikesTextView();
} catch (Exception ex) {
Logger.printException(() -> "setOldUILayoutDislikes failure", ex);
}
}
//
// Litho player for both regular videos and Shorts.
@ -719,7 +630,6 @@ public class ReturnYouTubeDislikePatch {
if (lastLithoShortsVideoData != null) {
lithoShortsShouldUseCurrentData = true;
}
updateOldUIDislikesTextView();
}
return;

View File

@ -1,29 +1,29 @@
package app.revanced.extension.youtube.patches.announcements;
import static android.text.Html.FROM_HTML_MODE_COMPACT;
import static app.revanced.extension.shared.StringRef.str;
import static app.revanced.extension.youtube.patches.announcements.requests.AnnouncementsRoutes.GET_LATEST_ANNOUNCEMENT;
import android.app.Activity;
import android.app.AlertDialog;
import android.os.Build;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.widget.TextView;
import androidx.annotation.RequiresApi;
import org.json.JSONObject;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.Locale;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.patches.announcements.requests.AnnouncementsRoutes;
import app.revanced.extension.youtube.requests.Requester;
import app.revanced.extension.youtube.settings.Settings;
import org.json.JSONObject;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Locale;
import static android.text.Html.FROM_HTML_MODE_COMPACT;
import static app.revanced.extension.shared.StringRef.str;
import static app.revanced.extension.youtube.patches.announcements.requests.AnnouncementsRoutes.GET_LATEST_ANNOUNCEMENT;
@SuppressWarnings("unused")
public final class AnnouncementsPatch {
@ -56,15 +56,12 @@ public final class AnnouncementsPatch {
return;
}
} catch (IOException ex) {
final var message = "Failed connecting to announcements provider";
Logger.printException(() -> message, ex);
Logger.printException(() -> "Could not connect to announcements provider", ex);
return;
}
var jsonString = Requester.parseStringAndDisconnect(connection);
// Parse the announcement. Fall-back to raw string if it fails.
int id = Settings.ANNOUNCEMENT_LAST_ID.defaultValue;
String title;
@ -85,22 +82,6 @@ public final class AnnouncementsPatch {
message = jsonString;
}
// TODO: Remove this migration code after a few months.
if (!Settings.DEPRECATED_ANNOUNCEMENT_LAST_HASH.isSetToDefault()){
final byte[] hashBytes = MessageDigest
.getInstance("SHA-256")
.digest(jsonString.getBytes(StandardCharsets.UTF_8));
final var hash = java.util.Base64.getEncoder().encodeToString(hashBytes);
// Migrate to saving the id instead of the hash.
if (hash.equals(Settings.DEPRECATED_ANNOUNCEMENT_LAST_HASH.get())) {
Settings.ANNOUNCEMENT_LAST_ID.save(id);
}
Settings.DEPRECATED_ANNOUNCEMENT_LAST_HASH.resetToDefault();
}
// Do not show the announcement, if the last announcement id is the same as the current one.
if (Settings.ANNOUNCEMENT_LAST_ID.get() == id) return;

View File

@ -9,10 +9,6 @@ import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerT
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.*;
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.settings.*;
import app.revanced.extension.shared.settings.preference.SharedPrefCategory;
@ -36,8 +32,6 @@ public class Settings extends BaseSettings {
public static final FloatSetting PLAYBACK_SPEED_DEFAULT = new FloatSetting("revanced_playback_speed_default", 1.0f);
public static final StringSetting CUSTOM_PLAYBACK_SPEEDS = new StringSetting("revanced_custom_playback_speeds",
"0.25\n0.5\n0.75\n0.9\n0.95\n1.0\n1.05\n1.1\n1.25\n1.5\n1.75\n2.0\n3.0\n4.0\n5.0", true);
@Deprecated // Patch is obsolete and no longer works with 19.09+
public static final BooleanSetting HDR_AUTO_BRIGHTNESS = new BooleanSetting("revanced_hdr_auto_brightness", TRUE);
// Ads
public static final BooleanSetting HIDE_FULLSCREEN_ADS = new BooleanSetting("revanced_hide_fullscreen_ads", TRUE);
@ -92,7 +86,6 @@ public class Settings extends BaseSettings {
public static final BooleanSetting HIDE_COMMUNITY_POSTS = new BooleanSetting("revanced_hide_community_posts", FALSE);
public static final BooleanSetting HIDE_COMPACT_BANNER = new BooleanSetting("revanced_hide_compact_banner", TRUE);
public static final BooleanSetting HIDE_CROWDFUNDING_BOX = new BooleanSetting("revanced_hide_crowdfunding_box", FALSE, true);
@Deprecated public static final BooleanSetting HIDE_EMAIL_ADDRESS = new BooleanSetting("revanced_hide_email_address", FALSE);
public static final BooleanSetting HIDE_EMERGENCY_BOX = new BooleanSetting("revanced_hide_emergency_box", TRUE);
public static final BooleanSetting HIDE_ENDSCREEN_CARDS = new BooleanSetting("revanced_hide_endscreen_cards", FALSE);
public static final BooleanSetting HIDE_FEED_SURVEY = new BooleanSetting("revanced_hide_feed_survey", TRUE);
@ -107,7 +100,6 @@ public class Settings extends BaseSettings {
public static final BooleanSetting HIDE_IMAGE_SHELF = new BooleanSetting("revanced_hide_image_shelf", TRUE);
public static final BooleanSetting HIDE_INFO_CARDS = new BooleanSetting("revanced_hide_info_cards", FALSE);
public static final BooleanSetting HIDE_JOIN_MEMBERSHIP_BUTTON = new BooleanSetting("revanced_hide_join_membership_button", TRUE);
@Deprecated public static final BooleanSetting HIDE_LOAD_MORE_BUTTON = new BooleanSetting("revanced_hide_load_more_button", TRUE);
public static final BooleanSetting HIDE_SHOW_MORE_BUTTON = new BooleanSetting("revanced_hide_show_more_button", TRUE, true);
public static final BooleanSetting HIDE_MEDICAL_PANELS = new BooleanSetting("revanced_hide_medical_panels", TRUE);
public static final BooleanSetting HIDE_MIX_PLAYLISTS = new BooleanSetting("revanced_hide_mix_playlists", TRUE);
@ -276,8 +268,6 @@ public class Settings extends BaseSettings {
public static final BooleanSetting SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_video_streams_ios_force_avc", FALSE, true,
"revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofVideoStreamsPatch.ForceiOSAVCAvailability());
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client", ClientType.ANDROID_VR, true, parent(SPOOF_VIDEO_STREAMS));
@Deprecated
public static final StringSetting DEPRECATED_ANNOUNCEMENT_LAST_HASH = new StringSetting("revanced_announcement_last_hash", "");
public static final IntegerSetting ANNOUNCEMENT_LAST_ID = new IntegerSetting("revanced_announcement_last_id", -1);
public static final BooleanSetting CHECK_WATCH_HISTORY_DOMAIN_NAME = new BooleanSetting("revanced_check_watch_history_domain_name", TRUE, false, false);
public static final BooleanSetting REMOVE_TRACKING_QUERY_PARAMETER = new BooleanSetting("revanced_remove_tracking_query_parameter", TRUE);
@ -290,14 +280,6 @@ public class Settings extends BaseSettings {
*/
public static final BooleanSetting DEBUG_PROTOBUFFER = new BooleanSetting("revanced_debug_protobuffer", FALSE, parent(BaseSettings.DEBUG));
// Old deprecated signature spoofing
@Deprecated public static final BooleanSetting SPOOF_SIGNATURE = new BooleanSetting("revanced_spoof_signature_verification_enabled", TRUE, true, false,
"revanced_spoof_signature_verification_enabled_user_dialog_message", null);
@Deprecated public static final BooleanSetting SPOOF_SIGNATURE_IN_FEED = new BooleanSetting("revanced_spoof_signature_in_feed_enabled", FALSE, false, false, null,
parent(SPOOF_SIGNATURE));
@Deprecated public static final BooleanSetting SPOOF_STORYBOARD_RENDERER = new BooleanSetting("revanced_spoof_storyboard", TRUE, true, false, null,
parent(SPOOF_SIGNATURE));
// Swipe controls
public static final BooleanSetting SWIPE_BRIGHTNESS = new BooleanSetting("revanced_swipe_brightness", TRUE);
public static final BooleanSetting SWIPE_VOLUME = new BooleanSetting("revanced_swipe_volume", TRUE);
@ -331,7 +313,6 @@ public class Settings extends BaseSettings {
* Do not use directly, instead use {@link SponsorBlockSettings}
*/
public static final StringSetting SB_PRIVATE_USER_ID = new StringSetting("sb_private_user_id_Do_Not_Share", "");
@Deprecated
public static final StringSetting DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING = new StringSetting("uuid", ""); // Delete sometime in 2024
public static final IntegerSetting SB_CREATE_NEW_SEGMENT_STEP = new IntegerSetting("sb_create_new_segment_step", 150, parent(SB_ENABLED));
public static final BooleanSetting SB_VOTING_BUTTON = new BooleanSetting("sb_voting_button", FALSE, parent(SB_ENABLED));
@ -375,59 +356,15 @@ public class Settings extends BaseSettings {
static {
// region Migration
// Migrate settings from old Preference categories into replacement "revanced_prefs" category.
// This region must run before all other migration code.
// The YT and RYD migration portion of this can be removed anytime,
// but the SB migration should remain until late 2024 or early 2025
// because it migrates the SB private user id which cannot be recovered if lost.
// Categories were previously saved without a 'sb_' key prefix, so they need an additional adjustment.
Set<Setting<?>> sbCategories = new HashSet<>(Arrays.asList(
SB_CATEGORY_SPONSOR,
SB_CATEGORY_SPONSOR_COLOR,
SB_CATEGORY_SELF_PROMO,
SB_CATEGORY_SELF_PROMO_COLOR,
SB_CATEGORY_INTERACTION,
SB_CATEGORY_INTERACTION_COLOR,
SB_CATEGORY_HIGHLIGHT,
SB_CATEGORY_HIGHLIGHT_COLOR,
SB_CATEGORY_INTRO,
SB_CATEGORY_INTRO_COLOR,
SB_CATEGORY_OUTRO,
SB_CATEGORY_OUTRO_COLOR,
SB_CATEGORY_PREVIEW,
SB_CATEGORY_PREVIEW_COLOR,
SB_CATEGORY_FILLER,
SB_CATEGORY_FILLER_COLOR,
SB_CATEGORY_MUSIC_OFFTOPIC,
SB_CATEGORY_MUSIC_OFFTOPIC_COLOR,
SB_CATEGORY_UNSUBMITTED,
SB_CATEGORY_UNSUBMITTED_COLOR));
SharedPrefCategory ytPrefs = new SharedPrefCategory("youtube");
SharedPrefCategory rydPrefs = new SharedPrefCategory("ryd");
SharedPrefCategory sbPrefs = new SharedPrefCategory("sponsor-block");
for (Setting<?> setting : Setting.allLoadedSettings()) {
String key = setting.key;
if (setting.key.startsWith("sb_")) {
if (sbCategories.contains(setting)) {
key = key.substring(3); // Remove the "sb_" prefix, as old categories are saved without it.
}
migrateFromOldPreferences(sbPrefs, setting, key);
} else if (setting.key.startsWith("ryd_")) {
migrateFromOldPreferences(rydPrefs, setting, key);
} else {
migrateFromOldPreferences(ytPrefs, setting, key);
}
}
// Do _not_ delete this SB private user id migration property until sometime in 2024.
// Do _not_ delete this SB private user id migration property until sometime in early 2025.
// This is the only setting that cannot be reconfigured if lost,
// and more time should be given for users who rarely upgrade.
migrateOldSettingToNew(DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, SB_PRIVATE_USER_ID);
SharedPrefCategory sbPrefs = new SharedPrefCategory("sponsor-block");
// Remove the "sb_" prefix, as old settings are saved without it.
String key = DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING.key.substring(3);
migrateFromOldPreferences(sbPrefs, DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, key);
migrateOldSettingToNew(DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, SB_PRIVATE_USER_ID);
// Old spoof versions that no longer work reliably.
if (SpoofAppVersionPatch.isSpoofingToLessThan("17.33.00")) {
@ -435,12 +372,6 @@ public class Settings extends BaseSettings {
Settings.SPOOF_APP_VERSION_TARGET.resetToDefault();
}
// Remove any previously saved announcement consumer (a random generated string).
Setting.preferences.removeKey("revanced_announcement_consumer");
migrateOldSettingToNew(HIDE_LOAD_MORE_BUTTON, HIDE_SHOW_MORE_BUTTON);
migrateOldSettingToNew(HIDE_PLAYER_BUTTONS, HIDE_PLAYER_PREVIOUS_NEXT_BUTTONS);
// endregion

View File

@ -888,10 +888,6 @@ public final class app/revanced/patches/tumblr/fixes/FixOldVersionsPatchKt {
public static final fun getFixOldVersionsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/tumblr/live/DisableTumblrLivePatchKt {
public static final fun getDisableTumblrLivePatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/tumblr/misc/extension/ExtensionPatchKt {
public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
@ -1085,10 +1081,6 @@ public final class app/revanced/patches/youtube/layout/buttons/overlay/HidePlaye
public static final fun getHidePlayerOverlayButtonsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/youtube/layout/hide/breakingnews/BreakingNewsPatchKt {
public static final fun getBreakingNewsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatchKt {
public static final fun getHideEndscreenCardsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
@ -1459,17 +1451,18 @@ public final class app/revanced/patches/yuka/misc/unlockpremium/UnlockPremiumPat
public final class app/revanced/util/BytecodeUtilsKt {
public static final fun applyMatch (Lapp/revanced/patcher/Fingerprint;Lapp/revanced/patcher/patch/BytecodePatchContext;Lapp/revanced/patcher/Match;)Lapp/revanced/patcher/Match;
public static final fun containsWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z
public static final fun containsLiteralInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z
public static final fun findInstructionIndicesReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)Ljava/util/List;
public static final fun findInstructionIndicesReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Ljava/util/List;
public static final fun findInstructionIndicesReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)Ljava/util/List;
public static final fun findInstructionIndicesReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Ljava/util/List;
public static final fun findMutableMethodOf (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;
public static final fun findOpcodeIndicesReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)Ljava/util/List;
public static final fun findOpcodeIndicesReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Ljava/util/List;
public static final fun forEachLiteralValueInstruction (Lapp/revanced/patcher/patch/BytecodePatchContext;JLkotlin/jvm/functions/Function2;)V
public static final fun getException (Lapp/revanced/patcher/Fingerprint;)Lapp/revanced/patcher/patch/PatchException;
public static final fun getMatchOrThrow (Lapp/revanced/patcher/Fingerprint;)Lapp/revanced/patcher/Match;
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;ILcom/android/tools/smali/dexlib2/Opcode;)I
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;)I
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)I
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I
public static synthetic fun indexOfFirstInstruction$default (Lcom/android/tools/smali/dexlib2/iface/Method;ILcom/android/tools/smali/dexlib2/Opcode;ILjava/lang/Object;)I
public static synthetic fun indexOfFirstInstruction$default (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)I
public static final fun indexOfFirstInstructionOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;ILcom/android/tools/smali/dexlib2/Opcode;)I
@ -1485,20 +1478,20 @@ 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 indexOfFirstWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
public static final fun indexOfFirstWideLiteralInstructionValueOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
public static final fun indexOfFirstWideLiteralInstructionValueReversed (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
public static final fun indexOfFirstWideLiteralInstructionValueReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
public static final fun indexOfIdResource (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
public static final fun indexOfIdResourceOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)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;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
public static final fun indexOfFirstResourceId (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
public static final fun indexOfFirstResourceIdOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
public static final fun injectHideViewCall (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;IILjava/lang/String;Ljava/lang/String;)V
public static final fun literal (Lapp/revanced/patcher/FingerprintBuilder;Lkotlin/jvm/functions/Function0;)V
public static final fun returnEarly (Lapp/revanced/patcher/Fingerprint;Z)V
public static final fun returnEarly (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Z)V
public static final fun returnEarly (Ljava/lang/Iterable;Z)V
public static final fun returnEarly (Ljava/util/List;Z)V
public static synthetic fun returnEarly$default (Lapp/revanced/patcher/Fingerprint;ZILjava/lang/Object;)V
public static synthetic fun returnEarly$default (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ZILjava/lang/Object;)V
public static synthetic fun returnEarly$default (Ljava/lang/Iterable;ZILjava/lang/Object;)V
public static synthetic fun returnEarly$default (Ljava/util/List;ZILjava/lang/Object;)V
public static final fun transformMethods (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lkotlin/jvm/functions/Function1;)V
public static final fun traverseClassHierarchy (Lapp/revanced/patcher/patch/BytecodePatchContext;Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lkotlin/jvm/functions/Function1;)V
}

View File

@ -3,7 +3,6 @@ package app.revanced.patches.all.misc.debugging
import app.revanced.patcher.patch.resourcePatch
import org.w3c.dom.Element
@Suppress("unused")
val enableAndroidDebuggingPatch = resourcePatch(
name = "Enable Android debugging",
description = "Enables Android debugging capabilities. This can slow down the app.",

View File

@ -15,7 +15,7 @@ val overrideCertificatePinningPatch = resourcePatch(
dependsOn(enableAndroidDebuggingPatch)
execute { context ->
val resXmlDirectory = context.get("res/xml")
val resXmlDirectory = context["res/xml"]
// Add android:networkSecurityConfig="@xml/network_security_config" and the "networkSecurityConfig" attribute if it does not exist.
context.document["AndroidManifest.xml"].use { document ->

View File

@ -1,7 +1,6 @@
package app.revanced.patches.all.misc.packagename
import app.revanced.patcher.patch.Option
import app.revanced.patcher.patch.OptionException
import app.revanced.patcher.patch.resourcePatch
import app.revanced.patcher.patch.stringOption
import org.w3c.dom.Element
@ -26,7 +25,6 @@ fun setOrGetFallbackPackageName(fallbackPackageName: String): String {
}
}
@Suppress("unused")
val changePackageNamePatch = resourcePatch(
name = "Change package name",
description = "Appends \".revanced\" to the package name by default. Changing the package name of the app can lead to unexpected issues.",

View File

@ -4,7 +4,6 @@ import app.revanced.patches.all.misc.build.BuildInfo
import app.revanced.patches.all.misc.build.baseSpoofBuildInfoPatch
// Spoof build info to Google Pixel XL.
@Suppress("unused")
val spoofBuildInfoPatch = baseSpoofBuildInfoPatch {
BuildInfo(
brand = "google",

View File

@ -3,7 +3,6 @@ package app.revanced.patches.memegenerator.detection.license
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
import app.revanced.patcher.patch.bytecodePatch
@Suppress("unused")
val licenseValidationPatch = bytecodePatch(
description = "Disables Firebase license validation.",
) {

View File

@ -3,7 +3,6 @@ package app.revanced.patches.memegenerator.detection.signature
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
import app.revanced.patcher.patch.bytecodePatch
@Suppress("unused")
val signatureVerificationPatch = bytecodePatch(
description = "Disables detection of incorrect signature.",
) {

View File

@ -3,7 +3,6 @@ package app.revanced.patches.mifitness.misc.login
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.bytecodePatch
@Suppress("unused")
val fixLoginPatch = bytecodePatch(
name = "Fix login",
description = "Fixes login for uncertified Mi Fitness app",

View File

@ -4,7 +4,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith
import app.revanced.patcher.extensions.InstructionExtensions.instructions
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.util.smali.ExternalLabel
import org.stringtemplate.v4.compiler.Bytecode.instructions
@Suppress("unused")
val permanentRepeatPatch = bytecodePatch(

View File

@ -5,7 +5,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.bytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Suppress("unused")
val signatureDetectionPatch = bytecodePatch(
description = "Disables detection of incorrect signature.",
) {

View File

@ -3,7 +3,6 @@ package app.revanced.patches.photomath.misc.unlock.bookpoint
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
import app.revanced.patcher.patch.bytecodePatch
@Suppress("unused")
val enableBookpointPatch = bytecodePatch(
description = "Enables textbook access",
) {

View File

@ -5,7 +5,6 @@ import app.revanced.patcher.patch.resourcePatch
// Note that for now, this patch and anything using it will only work on
// Reddit 2024.17.0 or older. Newer versions will crash during patching.
// See https://github.com/ReVanced/revanced-patches/issues/3099
@Suppress("unused")
val hideBannerPatch = resourcePatch(
description = "Hides banner ads from comments on subreddits.",
) {

View File

@ -3,7 +3,6 @@ package app.revanced.patches.reddit.ad.comments
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.bytecodePatch
@Suppress("unused")
val hideCommentAdsPatch = bytecodePatch(
description = "Removes ads in the comments.",
) {

View File

@ -6,7 +6,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patches.reddit.customclients.spoofClientPatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Suppress("unused")
val spoofClientPatch = spoofClientPatch(redirectUri = "http://baconreader.com/auth") { clientIdOption ->
compatibleWith(
"com.onelouder.baconreader",

View File

@ -3,7 +3,6 @@ package app.revanced.patches.reddit.customclients.boostforreddit.api
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patches.reddit.customclients.spoofClientPatch
@Suppress("unused")
val spoofClientPatch = spoofClientPatch(redirectUri = "http://rubenmayayo.com") { clientIdOption ->
compatibleWith("com.rubenmayayo.reddit")

View File

@ -7,7 +7,6 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodImplementation
@Suppress("unused")
val spoofClientPatch = spoofClientPatch(redirectUri = "infinity://localhost") { clientIdOption ->
compatibleWith("ml.docilealligator.infinityforreddit")

View File

@ -5,7 +5,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
import app.revanced.patches.reddit.customclients.joeyforreddit.detection.piracy.disablePiracyDetectionPatch
import app.revanced.patches.reddit.customclients.spoofClientPatch
@Suppress("unused")
val spoofClientPatch = spoofClientPatch(redirectUri = "https://127.0.0.1:65023/authorize_callback") { clientIdOption ->
dependsOn(disablePiracyDetectionPatch)

View File

@ -3,7 +3,6 @@ package app.revanced.patches.reddit.customclients.joeyforreddit.detection.piracy
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.bytecodePatch
@Suppress("unused")
val disablePiracyDetectionPatch = bytecodePatch {
val piracyDetectionMatch by piracyDetectionFingerprint()

View File

@ -10,7 +10,6 @@ import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.StringReference
@Suppress("unused")
val spoofClientPatch = spoofClientPatch(redirectUri = "redditisfun://auth") { clientIdOption ->
compatibleWith(
"com.andrewshu.android.reddit",

View File

@ -9,7 +9,6 @@ import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction10t
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21t
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Suppress("unused")
val spoofClientPatch = spoofClientPatch(redirectUri = "dbrady://relay") {
compatibleWith(
"free.reddit.news",

View File

@ -3,7 +3,6 @@ package app.revanced.patches.reddit.customclients.slide.api
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patches.reddit.customclients.spoofClientPatch
@Suppress("unused")
val spoofClientPatch = spoofClientPatch(redirectUri = "http://www.ccrama.me") { clientIdOption ->
compatibleWith("me.ccrama.redditslide")

View File

@ -3,7 +3,6 @@ package app.revanced.patches.reddit.customclients.sync.detection.piracy
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.bytecodePatch
@Suppress("unused")
val disablePiracyDetectionPatch = bytecodePatch(
description = "Disables detection of modified versions.",
) {

View File

@ -22,6 +22,6 @@ internal val piracyDetectionFingerprint = fingerprint {
val reference = (it as ReferenceInstruction).reference
reference.toString() == "Lcom/github/javiersantos/piracychecker/PiracyChecker;"
} ?: false
} == true
}
}

View File

@ -11,7 +11,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.StringReference
import java.util.*
@Suppress("unused")
val spoofClientPatch = spoofClientPatch(
redirectUri = "http://redditsync/auth",
) { clientIdOption ->

View File

@ -5,7 +5,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Suppress("unused")
val verticalScrollPatch = bytecodePatch(
description = "Fixes issues with refreshing the feed when the first component is of type EmptyComponent.",
) {

View File

@ -3,6 +3,7 @@ package app.revanced.patches.soundcloud.analytics
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.bytecodePatch
@Suppress("unused")
val disableTelemetryPatch = bytecodePatch(
name = "Disable telemetry",
description = "Disables SoundCloud's telemetry system.",

View File

@ -15,7 +15,7 @@ val hideOffersTabPatch = resourcePatch(
document.getNode("menu").apply {
removeChild(
childElementsSequence().first {
it.attributes.getNamedItem("android:id")?.nodeValue?.contains("offer") ?: false
it.attributes.getNamedItem("android:id")?.nodeValue?.contains("offer") == true
},
)
}

View File

@ -2,7 +2,6 @@ package app.revanced.patches.tiktok.interaction.downloads
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal val aclCommonShareFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)

View File

@ -14,7 +14,6 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
internal const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/tiktok/settings/AdPersonalizationActivityHook;"
@Suppress("unused")
val settingsPatch = bytecodePatch(
name = "Settings",
description = "Adds ReVanced settings to TikTok.",

View File

@ -19,7 +19,6 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
internal lateinit var addFeatureFlagOverride: (name: String, value: String) -> Unit
private set
@Suppress("unused")
val overrideFeatureFlagsPatch = bytecodePatch(
description = "Forcibly set the value of A/B testing features of your choice.",
) {

View File

@ -1,29 +0,0 @@
package app.revanced.patches.tumblr.live
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.tumblr.featureflags.addFeatureFlagOverride
import app.revanced.patches.tumblr.featureflags.overrideFeatureFlagsPatch
import app.revanced.patches.tumblr.timelinefilter.addTimelineObjectTypeFilter
import app.revanced.patches.tumblr.timelinefilter.filterTimelineObjectsPatch
@Suppress("unused")
@Deprecated("Tumblr Live was removed and is no longer served in the feed, making this patch useless.")
val disableTumblrLivePatch = bytecodePatch(
description = "Disable the Tumblr Live tab button and dashboard carousel.",
) {
dependsOn(
overrideFeatureFlagsPatch,
filterTimelineObjectsPatch,
)
compatibleWith("com.tumblr")
execute {
// Hide the LIVE_MARQUEE timeline element that appears in the feed
// Called "live_marquee" in api response
addTimelineObjectTypeFilter("LIVE_MARQUEE")
// Hide the Tab button for Tumblr Live by forcing the feature flag to false
addFeatureFlagOverride("liveStreaming", "false")
}
}

View File

@ -18,7 +18,6 @@ import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction35c
@Suppress("KDocUnresolvedReference")
lateinit var addTimelineObjectTypeFilter: (typeName: String) -> Unit
@Suppress("unused")
val filterTimelineObjectsPatch = bytecodePatch(
description = "Filter timeline objects.",
) {

View File

@ -203,6 +203,6 @@ internal object PreferenceScreen : BasePreferenceScreen() {
}
override fun commit(screen: app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference) {
preferences += screen
addSettingPreference(screen)
}
}

View File

@ -14,7 +14,7 @@ internal val jsonHookPatchFingerprint = fingerprint {
internal val jsonInputStreamFingerprint = fingerprint {
custom { method, _ ->
if (method.parameterTypes.size == 0) {
if (method.parameterTypes.isEmpty()) {
false
} else {
method.parameterTypes.first() == "Ljava/io/InputStream;"

View File

@ -9,7 +9,7 @@ import app.revanced.patcher.patch.stringOption
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.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
@ -80,7 +80,7 @@ val changeLinkSharingDomainPatch = bytecodePatch(
// Used in the Share via... dialog.
linkResourceGetterMatch.mutableMethod.apply {
val templateIdConstIndex = indexOfFirstWideLiteralInstructionValueOrThrow(tweetShareLinkTemplateId)
val templateIdConstIndex = indexOfFirstLiteralInstructionOrThrow(tweetShareLinkTemplateId)
// Format the link with the new domain name register (1 instruction below the const).
val formatLinkCallIndex = templateIdConstIndex + 1

View File

@ -3,7 +3,6 @@ package app.revanced.patches.warnwetter.misc.firebasegetcert
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.bytecodePatch
@Suppress("unused")
val firebaseGetCertPatch = bytecodePatch(
description = "Spoofs the X-Android-Cert header.",
) {

View File

@ -14,7 +14,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
internal const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/HideGetPremiumPatch;"
@Suppress("unused")
val hideGetPremiumPatch = bytecodePatch(
description = "Hides YouTube Premium signup promotions under the video player.",
) {

View File

@ -16,7 +16,6 @@ import app.revanced.util.getReference
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
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/SlideToSeekPatch;"

View File

@ -1,7 +1,7 @@
package app.revanced.patches.youtube.interaction.seekbar
import app.revanced.patcher.fingerprint
import app.revanced.util.containsWideLiteralInstructionValue
import app.revanced.util.containsLiteralInstruction
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
@ -101,7 +101,7 @@ internal val seekbarTappingFingerprint = fingerprint {
Opcode.INVOKE_VIRTUAL,
)
custom { method, _ ->
method.containsWideLiteralInstructionValue(Integer.MAX_VALUE.toLong())
method.containsLiteralInstruction(Integer.MAX_VALUE.toLong())
}
}

View File

@ -115,7 +115,7 @@ val changeHeaderPatch = resourcePatch(
// For each source folder, copy the files to the target resource directories.
sourceFolders.forEach { dpiSourceFolder ->
val targetDpiFolder = context.get("res").resolve(dpiSourceFolder.name)
val targetDpiFolder = context["res"].resolve(dpiSourceFolder.name)
if (!targetDpiFolder.exists()) return@forEach
val imgSourceFiles = dpiSourceFolder.listFiles { file -> file.isFile }!!

View File

@ -23,7 +23,6 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/NavigationButtonsPatch;"
@Suppress("unused")
val navigationButtonsPatch = bytecodePatch(
name = "Navigation buttons",
description = "Adds options to hide and change navigation buttons (such as the Shorts button).",

View File

@ -1,7 +1,7 @@
package app.revanced.patches.youtube.layout.buttons.overlay
import app.revanced.patcher.fingerprint
import app.revanced.util.containsWideLiteralInstructionValue
import app.revanced.util.containsLiteralInstruction
import com.android.tools.smali.dexlib2.AccessFlags
internal val playerControlsPreviousNextOverlayTouchFingerprint = fingerprint {
@ -9,8 +9,8 @@ internal val playerControlsPreviousNextOverlayTouchFingerprint = fingerprint {
returns("V")
strings("1.0x")
custom { methodDef, _ ->
methodDef.containsWideLiteralInstructionValue(playerControlPreviousButtonTouchArea) &&
methodDef.containsWideLiteralInstructionValue(playerControlNextButtonTouchArea)
methodDef.containsLiteralInstruction(playerControlPreviousButtonTouchArea) &&
methodDef.containsLiteralInstruction(playerControlNextButtonTouchArea)
}
}

View File

@ -20,8 +20,8 @@ import app.revanced.patches.youtube.shared.layoutConstructorFingerprint
import app.revanced.patches.youtube.shared.subtitleButtonControllerFingerprint
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.indexOfIdResourceOrThrow
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
import app.revanced.util.indexOfFirstResourceIdOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@ -44,7 +44,6 @@ private val hidePlayerOverlayButtonsResourcePatch = resourcePatch {
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/HidePlayerOverlayButtonsPatch;"
@Suppress("unused")
val hidePlayerOverlayButtonsPatch = bytecodePatch(
name = "Hide player overlay buttons",
description = "Adds options to hide the player cast, autoplay, caption button and next/ previous buttons.",
@ -84,7 +83,7 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
// region Hide player next/previous button.
playerControlsPreviousNextOverlayTouchMatch.mutableMethod.apply {
val resourceIndex = indexOfFirstWideLiteralInstructionValueOrThrow(playerControlPreviousButtonTouchArea)
val resourceIndex = indexOfFirstLiteralInstructionOrThrow(playerControlPreviousButtonTouchArea)
val insertIndex = indexOfFirstInstructionOrThrow(resourceIndex) {
opcode == Opcode.INVOKE_STATIC &&
@ -131,7 +130,7 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
// region Hide autoplay button.
layoutConstructorMatch.mutableMethod.apply {
val constIndex = indexOfIdResourceOrThrow("autonav_toggle")
val constIndex = indexOfFirstResourceIdOrThrow("autonav_toggle")
val constRegister = getInstruction<OneRegisterInstruction>(constIndex).registerA
// Add a conditional branch around the code that inflates and adds the auto-repeat button.

View File

@ -1,9 +0,0 @@
package app.revanced.patches.youtube.layout.buttons.player.hide
import com.android.tools.smali.dexlib2.Opcode
import app.revanced.patcher.fingerprint
internal val playerControlsVisibilityModelFingerprint = fingerprint {
opcodes(Opcode.INVOKE_DIRECT_RANGE)
strings("Missing required properties:", "hasNext", "hasPrevious")
}

View File

@ -1,10 +0,0 @@
package app.revanced.patches.youtube.layout.hide.breakingnews
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.youtube.layout.hide.general.hideLayoutComponentsPatch
@Deprecated("This patch has been merged to HideLayoutComponentsPatch.")
@Suppress("unused")
val breakingNewsPatch = bytecodePatch {
dependsOn(hideLayoutComponentsPatch)
}

View File

@ -22,7 +22,7 @@ import app.revanced.patches.youtube.misc.navigation.navigationBarHookPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.util.applyMatch
import app.revanced.util.findOpcodeIndicesReversed
import app.revanced.util.findInstructionIndicesReversedOrThrow
import app.revanced.util.getReference
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.Method
@ -30,7 +30,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.MethodReference
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
var expandButtonDownId = -1L
private set
@ -368,7 +367,7 @@ val hideLayoutComponentsPatch = bytecodePatch(
// region 'Yoodles'
yoodlesImageViewMatch.mutableMethod.apply {
findOpcodeIndicesReversed {
findInstructionIndicesReversedOrThrow {
getReference<MethodReference>()?.name == "setImageDrawable"
}.forEach { insertIndex ->
val register = getInstruction<FiveRegisterInstruction>(insertIndex).registerD

View File

@ -21,7 +21,6 @@ import app.revanced.util.applyMatch
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
internal var drawerResourceId = -1L
private set

View File

@ -5,22 +5,6 @@ import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal val bottomNavigationBarFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V")
parameters("Landroid/view/View;", "Landroid/os/Bundle;")
opcodes(
Opcode.CONST, // R.id.app_engagement_panel_wrapper
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
)
strings("ReelWatchPaneFragmentViewModelKey")
}
internal val legacyRenderBottomNavigationBarParentFingerprint = fingerprint {
parameters(
"I",

View File

@ -286,7 +286,7 @@ val hideShortsComponentsPatch = bytecodePatch(
// Hide the bottom bar container of the Shorts player.
shortsBottomBarContainerMatch.mutableMethod.apply {
val resourceIndex = indexOfFirstWideLiteralInstructionValue(bottomBarContainer)
val resourceIndex = indexOfFirstLiteralInstruction(bottomBarContainer)
val targetIndex = indexOfFirstInstructionOrThrow(resourceIndex) {
getReference<MethodReference>()?.name == "getHeight"
@ -316,7 +316,7 @@ private enum class ShortsButtons(private val resourceName: String, private val m
;
fun injectHideCall(method: MutableMethod) {
val referencedIndex = method.indexOfIdResourceOrThrow(resourceName)
val referencedIndex = method.indexOfFirstResourceIdOrThrow(resourceName)
val setIdIndex = method.indexOfFirstInstructionOrThrow(referencedIndex) {
opcode == Opcode.INVOKE_VIRTUAL && getReference<MethodReference>()?.name == "setId"

View File

@ -1,7 +1,7 @@
package app.revanced.patches.youtube.layout.miniplayer
import app.revanced.patcher.fingerprint
import app.revanced.util.containsWideLiteralInstructionValue
import app.revanced.util.containsLiteralInstruction
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
@ -110,9 +110,9 @@ internal val miniplayerModernViewParentFingerprint = fingerprint {
internal val miniplayerMinimumSizeFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
custom { method, _ ->
method.containsWideLiteralInstructionValue(192) &&
method.containsWideLiteralInstructionValue(128) &&
method.containsWideLiteralInstructionValue(miniplayerMaxSize)
method.containsLiteralInstruction(192) &&
method.containsLiteralInstruction(128) &&
method.containsLiteralInstruction(miniplayerMaxSize)
}
}

View File

@ -250,7 +250,7 @@ val miniplayerPatch = bytecodePatch(
)
}
fun Method.findReturnIndicesReversed() = findOpcodeIndicesReversed(Opcode.RETURN)
fun Method.findReturnIndicesReversed() = findInstructionIndicesReversedOrThrow(Opcode.RETURN)
/**
* Adds an override to force legacy tablet miniplayer to be used or not used.
@ -271,7 +271,7 @@ val miniplayerPatch = bytecodePatch(
extensionMethod: String,
) {
mutableMethod.apply {
val literalIndex = indexOfFirstWideLiteralInstructionValueOrThrow(literal)
val literalIndex = indexOfFirstLiteralInstructionOrThrow(literal)
val targetIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
insertBooleanOverride(targetIndex + 1, extensionMethod)
@ -283,7 +283,7 @@ val miniplayerPatch = bytecodePatch(
extensionMethod: String,
) {
mutableMethod.apply {
val literalIndex = indexOfFirstWideLiteralInstructionValueOrThrow(literal)
val literalIndex = indexOfFirstLiteralInstructionOrThrow(literal)
val targetIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.DOUBLE_TO_FLOAT)
val register = getInstruction<OneRegisterInstruction>(targetIndex).registerA
@ -318,7 +318,7 @@ val miniplayerPatch = bytecodePatch(
extensionMethodName: String,
) {
val imageViewIndex = indexOfFirstInstructionOrThrow(
indexOfFirstWideLiteralInstructionValueOrThrow(literalValue),
indexOfFirstLiteralInstructionOrThrow(literalValue),
) {
opcode == Opcode.CHECK_CAST && getReference<TypeReference>()?.type == hookedClassType
}
@ -401,7 +401,7 @@ val miniplayerPatch = bytecodePatch(
if (is_19_26_or_greater) {
miniplayerModernConstructorMatch.mutableMethod.apply {
val literalIndex = indexOfFirstWideLiteralInstructionValueOrThrow(
val literalIndex = indexOfFirstLiteralInstructionOrThrow(
INITIAL_SIZE_FEATURE_KEY_LITERAL,
)
val targetIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.LONG_TO_INT)
@ -465,7 +465,7 @@ val miniplayerPatch = bytecodePatch(
ytOutlinePictureInPictureWhite24 to ytOutlineXWhite24,
ytOutlineXWhite24 to ytOutlinePictureInPictureWhite24,
).forEach { (originalResource, replacementResource) ->
val imageResourceIndex = indexOfFirstWideLiteralInstructionValueOrThrow(originalResource)
val imageResourceIndex = indexOfFirstLiteralInstructionOrThrow(originalResource)
val register = getInstruction<OneRegisterInstruction>(imageResourceIndex).registerA
replaceInstruction(imageResourceIndex, "const v$register, $replacementResource")

View File

@ -13,7 +13,7 @@ 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
import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
internal var scrimOverlayId = -1L
@ -56,7 +56,7 @@ val customPlayerOverlayOpacityPatch = bytecodePatch(
execute {
createPlayerOverviewMatch.mutableMethod.apply {
val viewRegisterIndex =
indexOfFirstWideLiteralInstructionValueOrThrow(scrimOverlayId) + 3
indexOfFirstLiteralInstructionOrThrow(scrimOverlayId) + 3
val viewRegister =
getInstruction<OneRegisterInstruction>(viewRegisterIndex).registerA

View File

@ -1,7 +1,7 @@
package app.revanced.patches.youtube.layout.player.overlay
import app.revanced.patcher.fingerprint
import app.revanced.util.containsWideLiteralInstructionValue
import app.revanced.util.containsLiteralInstruction
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
@ -15,6 +15,6 @@ internal val createPlayerOverviewFingerprint = fingerprint {
Opcode.CHECK_CAST,
)
custom { method, _ ->
method.containsWideLiteralInstructionValue(scrimOverlayId)
method.containsLiteralInstruction(scrimOverlayId)
}
}

View File

@ -1,7 +1,6 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike
import app.revanced.patcher.fingerprint
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
@ -22,21 +21,6 @@ internal val dislikeFingerprint = fingerprint {
strings("like/dislike")
}
internal val dislikesOldLayoutTextViewFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V")
parameters("L")
opcodes(
Opcode.CONST, // resource identifier register
Opcode.INVOKE_VIRTUAL,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ, // textview register
Opcode.GOTO,
)
literal { oldUIDislikeId }
}
internal val likeFingerprint = fingerprint {
returns("V")
strings("like/like")
@ -109,10 +93,8 @@ internal val rollingNumberTextViewFingerprint = fingerprint {
Opcode.RETURN_VOID,
)
custom { _, classDef ->
classDef.superclass ==
"Landroid/support/v7/widget/AppCompatTextView;" ||
classDef.superclass ==
"Lcom/google/android/libraries/youtube/rendering/ui/spec/typography/YouTubeAppCompatTextView;"
classDef.superclass == "Landroid/support/v7/widget/AppCompatTextView;" || classDef.superclass ==
"Lcom/google/android/libraries/youtube/rendering/ui/spec/typography/YouTubeAppCompatTextView;"
}
}

View File

@ -1,18 +1,14 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike
import app.revanced.patcher.Match
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.instructions
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.resourceMappings
import app.revanced.patches.shared.misc.settings.preference.IntentPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.litho.filter.addLithoFilter
@ -36,35 +32,6 @@ 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.iface.reference.TypeReference
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
internal var oldUIDislikeId = -1L
private set
private val returnYouTubeDislikeResourcePatch = resourcePatch {
dependsOn(
settingsPatch,
addResourcesPatch,
)
execute {
addResources("youtube", "layout.returnyoutubedislike.returnYouTubeDislikeResourcePatch")
addSettingPreference(
IntentPreference(
key = "revanced_settings_screen_09",
titleKey = "revanced_ryd_settings_title",
summaryKey = null,
intent = newIntent("revanced_ryd_settings_intent"),
),
)
oldUIDislikeId = resourceMappings[
"id",
"dislike_button",
]
}
}
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/ReturnYouTubeDislikePatch;"
@ -78,10 +45,11 @@ val returnYouTubeDislikePatch = bytecodePatch(
description = "Adds an option to show the dislike count of videos with Return YouTube Dislike.",
) {
dependsOn(
settingsPatch,
sharedExtensionPatch,
addResourcesPatch,
lithoFilterPatch,
videoIdPatch,
returnYouTubeDislikeResourcePatch,
playerTypeHookPatch,
versionCheckPatch,
)
@ -99,7 +67,6 @@ val returnYouTubeDislikePatch = bytecodePatch(
val textComponentConstructorMatch by textComponentConstructorFingerprint()
val textComponentDataMatch by textComponentDataFingerprint()
val shortsTextViewMatch by shortsTextViewFingerprint()
val dislikesOldLayoutTextViewMatch by dislikesOldLayoutTextViewFingerprint()
val likeMatch by likeFingerprint()
val dislikeMatch by dislikeFingerprint()
val removeLikeMatch by removeLikeFingerprint()
@ -110,6 +77,17 @@ val returnYouTubeDislikePatch = bytecodePatch(
val rollingNumberTextViewAnimationUpdateMatch by rollingNumberTextViewAnimationUpdateFingerprint()
execute { context ->
addResources("youtube", "layout.returnyoutubedislike.returnYouTubeDislikePatch")
addSettingPreference(
IntentPreference(
key = "revanced_settings_screen_09",
titleKey = "revanced_ryd_settings_title",
summaryKey = null,
intent = newIntent("revanced_ryd_settings_intent"),
),
)
// region Inject newVideoLoaded event handler to update dislikes when a new video is loaded.
hookVideoId("$EXTENSION_CLASS_DESCRIPTOR->newVideoLoaded(Ljava/lang/String;)V")
@ -260,23 +238,6 @@ val returnYouTubeDislikePatch = bytecodePatch(
// endregion
// region Hook old UI layout dislikes, for the older app spoofs used with spoof-app-version.
dislikesOldLayoutTextViewMatch.mutableMethod.apply {
val startIndex = dislikesOldLayoutTextViewMatch.patternMatch!!.startIndex
val resourceIdentifierRegister = getInstruction<OneRegisterInstruction>(startIndex).registerA
val textViewRegister = getInstruction<OneRegisterInstruction>(startIndex + 4).registerA
addInstruction(
startIndex + 4,
"invoke-static {v$resourceIdentifierRegister, v$textViewRegister}, " +
"$EXTENSION_CLASS_DESCRIPTOR->setOldUILayoutDislikes(ILandroid/widget/TextView;)V",
)
}
// endregion
// region Hook rolling numbers.
// Do this last to allow patching old unsupported versions (if the user really wants),

View File

@ -1,7 +1,7 @@
package app.revanced.patches.youtube.layout.seekbar
import app.revanced.patcher.fingerprint
import app.revanced.util.containsWideLiteralInstructionValue
import app.revanced.util.containsLiteralInstruction
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
@ -16,8 +16,8 @@ internal val fullscreenSeekbarThumbnailsFingerprint = fingerprint {
internal val playerSeekbarColorFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
custom { method, _ ->
method.containsWideLiteralInstructionValue(inlineTimeBarColorizedBarPlayedColorDarkId) &&
method.containsWideLiteralInstructionValue(inlineTimeBarPlayedNotHighlightedColorId)
method.containsLiteralInstruction(inlineTimeBarColorizedBarPlayedColorDarkId) &&
method.containsLiteralInstruction(inlineTimeBarPlayedNotHighlightedColorId)
}
}

View File

@ -17,11 +17,10 @@ import app.revanced.patches.youtube.misc.playservice.is_19_23_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
import org.w3c.dom.Element
internal var reelTimeBarPlayedColorId = -1L
@ -89,7 +88,7 @@ val seekbarColorPatch = bytecodePatch(
execute { context ->
fun MutableMethod.addColorChangeInstructions(resourceId: Long) {
val registerIndex = indexOfFirstWideLiteralInstructionValueOrThrow(resourceId) + 2
val registerIndex = indexOfFirstLiteralInstructionOrThrow(resourceId) + 2
val colorRegister = getInstruction<OneRegisterInstruction>(registerIndex).registerA
addInstructions(
registerIndex + 1,
@ -127,7 +126,7 @@ val seekbarColorPatch = bytecodePatch(
if (is_19_23_or_greater) {
playerSeekbarGradientConfigMatch.mutableMethod.apply {
val literalIndex = indexOfFirstWideLiteralInstructionValueOrThrow(PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG)
val literalIndex = indexOfFirstLiteralInstructionOrThrow(PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG)
val resultIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
val register = getInstruction<OneRegisterInstruction>(resultIndex).registerA

View File

@ -12,7 +12,7 @@ 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
import app.revanced.util.findOpcodeIndicesReversed
import app.revanced.util.findInstructionIndicesReversedOrThrow
import app.revanced.util.getReference
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@ -82,7 +82,7 @@ val shortsAutoplayPatch = bytecodePatch(
reelPlaybackRepeatMatch.mutableMethod.apply {
// The behavior enums are looked up from an ordinal value to an enum type.
findOpcodeIndicesReversed {
findInstructionIndicesReversedOrThrow {
val reference = getReference<MethodReference>()
reference?.definingClass == reelEnumClass &&
reference.parameterTypes.firstOrNull() == "I" &&

View File

@ -32,7 +32,6 @@ 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
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
private val sponsorBlockResourcePatch = resourcePatch {
dependsOn(

View File

@ -57,7 +57,7 @@ val disableResumingShortsOnStartupPatch = bytecodePatch(
opcode == Opcode.INVOKE_VIRTUAL &&
reference?.returnType == "Z" &&
reference.definingClass != "Lj${'$'}/util/Optional;" &&
reference.parameterTypes.size == 0
reference.parameterTypes.isEmpty()
}
// Presumably a method that processes the ProtoDataStore value (boolean) for the 'user_was_in_shorts' key.

View File

@ -17,7 +17,7 @@ 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.forEachChildElement
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import org.w3c.dom.Element
@ -214,7 +214,7 @@ val themePatch = bytecodePatch(
useGradientLoadingScreenMatch.mutableMethod.apply {
val isEnabledIndex = indexOfFirstWideLiteralInstructionValueOrThrow(GRADIENT_LOADING_SCREEN_AB_CONSTANT) + 3
val isEnabledIndex = indexOfFirstLiteralInstructionOrThrow(GRADIENT_LOADING_SCREEN_AB_CONSTANT) + 3
val isEnabledRegister = getInstruction<OneRegisterInstruction>(isEnabledIndex - 1).registerA
addInstructions(

View File

@ -14,7 +14,7 @@ import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.patches.youtube.video.information.videoInformationPatch
import app.revanced.util.addInstructionsAtControlFlowLabel
import app.revanced.util.findOpcodeIndicesReversed
import app.revanced.util.findInstructionIndicesReversedOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@ -34,7 +34,6 @@ private val backgroundPlaybackResourcePatch = resourcePatch {
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/BackgroundPlaybackPatch;"
@Suppress("unused")
val backgroundPlaybackPatch = bytecodePatch(
name = "Remove background playback restrictions",
description = "Removes restrictions on background playback, including playing kids videos in the background.",
@ -63,7 +62,7 @@ val backgroundPlaybackPatch = bytecodePatch(
execute { context ->
backgroundPlaybackManagerMatch.mutableMethod.apply {
findOpcodeIndicesReversed(Opcode.RETURN).forEach { index ->
findInstructionIndicesReversedOrThrow(Opcode.RETURN).forEach { index ->
val register = getInstruction<OneRegisterInstruction>(index).registerA
addInstructionsAtControlFlowLabel(

View File

@ -4,7 +4,6 @@ import app.revanced.patches.shared.misc.checks.checkEnvironmentPatch
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
@Suppress("unused")
val checkEnvironmentPatch = checkEnvironmentPatch(
mainActivityOnCreateFingerprint = mainActivityOnCreateFingerprint,
extensionPatch = sharedExtensionPatch,

View File

@ -10,6 +10,7 @@ import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
@Suppress("unused")
val enableDebuggingPatch = resourcePatch(
name = "Enable debugging",
description = "Adds options for debugging.",

View File

@ -5,7 +5,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.util.matchOrThrow
@Suppress("unused")
internal val fixBackToExitGesturePatch = bytecodePatch(
description = "Fixes the swipe back to exit gesture.",
) {

View File

@ -7,10 +7,9 @@ import app.revanced.patches.youtube.misc.backgroundplayback.backgroundPlaybackPa
import app.revanced.patches.youtube.misc.playservice.is_19_04_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
internal val disableCairoSettingsPatch = bytecodePatch(
description = "Disables Cairo Fragment from being used.",
@ -37,7 +36,7 @@ internal val disableCairoSettingsPatch = bytecodePatch(
* <a href="https://github.com/qnblackcat/uYouPlus/issues/1468">uYouPlus#1468</a>.
*/
cairoFragmentConfigMatch.mutableMethod.apply {
val literalIndex = indexOfFirstWideLiteralInstructionValueOrThrow(
val literalIndex = indexOfFirstLiteralInstructionOrThrow(
CAIRO_CONFIG_LITERAL_VALUE,
)

View File

@ -1,15 +1,8 @@
package app.revanced.patches.youtube.misc.fix.playback
import app.revanced.patcher.fingerprint
import app.revanced.util.containsWideLiteralInstructionValue
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.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal val buildInitPlaybackRequestFingerprint = fingerprint {
returns("Lorg/chromium/net/UrlRequest\$Builder;")
@ -40,128 +33,6 @@ internal val buildPlayerRequestURIFingerprint = fingerprint {
)
}
internal val createPlaybackSpeedMenuItemFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V")
opcodes(
Opcode.IGET_OBJECT, // First instruction of the method
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.INVOKE_INTERFACE,
null, // MOVE_RESULT or MOVE_RESULT_OBJECT, Return value controls the creation of the playback speed menu item.
)
// 19.01 and earlier is missing the second parameter.
// Since this fingerprint is somewhat weak, work around by checking for both method parameter signatures.
custom { method, _ ->
// 19.01 and earlier parameters are: "[L"
// 19.02+ parameters are "[L", "F"
val parameterTypes = method.parameterTypes
val firstParameter = parameterTypes.firstOrNull()
if (firstParameter == null || !firstParameter.startsWith("[L")) {
return@custom false
}
parameterTypes.size == 1 || (parameterTypes.size == 2 && parameterTypes[1] == "F")
}
}
internal val createPlayerRequestBodyFingerprint = fingerprint {
returns("V")
parameters("L")
opcodes(
Opcode.CHECK_CAST,
Opcode.IGET,
Opcode.AND_INT_LIT16,
)
strings("ms")
}
internal fun indexOfBuildModelInstruction(method: Method) =
method.indexOfFirstInstruction {
val reference = getReference<FieldReference>()
reference?.definingClass == "Landroid/os/Build;" &&
reference.name == "MODEL" &&
reference.type == "Ljava/lang/String;"
}
internal val createPlayerRequestBodyWithModelFingerprint = fingerprint {
returns("L")
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
parameters()
custom { method, _ ->
method.containsWideLiteralInstructionValue(1073741824) && indexOfBuildModelInstruction(method) >= 0
}
}
internal val playerGestureConfigSyntheticFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V")
parameters("Ljava/lang/Object;")
opcodes(
Opcode.SGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL, // playerGestureConfig.downAndOutLandscapeAllowed.
Opcode.MOVE_RESULT,
Opcode.CHECK_CAST,
Opcode.IPUT_BOOLEAN,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL, // playerGestureConfig.downAndOutPortraitAllowed.
Opcode.MOVE_RESULT,
Opcode.IPUT_BOOLEAN,
Opcode.RETURN_VOID,
)
custom { method, classDef ->
fun indexOfDownAndOutAllowedInstruction() =
method.indexOfFirstInstruction {
val reference = getReference<MethodReference>()
reference?.definingClass == "Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;" &&
reference.parameterTypes.isEmpty() &&
reference.returnType == "Z"
}
// This method is always called "a" because this kind of class always has a single method.
method.name == "a" &&
classDef.methods.count() == 2 &&
indexOfDownAndOutAllowedInstruction() >= 0
}
}
internal val setPlayerRequestClientTypeFingerprint = fingerprint {
opcodes(
Opcode.IGET,
Opcode.IPUT, // Sets ClientInfo.clientId.
)
strings("10.29")
literal { 134217728 }
}
internal fun indexOfBuildVersionReleaseInstruction(methodDef: Method) =
methodDef.indexOfFirstInstruction {
val reference = getReference<FieldReference>()
reference?.definingClass == "Landroid/os/Build\$VERSION;" &&
reference.name == "RELEASE" &&
reference.type == "Ljava/lang/String;"
}
internal val createPlayerRequestBodyWithVersionReleaseFingerprint = fingerprint {
returns("L")
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
parameters()
custom { method, _ ->
method.containsWideLiteralInstructionValue(1073741824) && indexOfBuildVersionReleaseInstruction(method) >= 0
}
}
internal val buildRequestFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returns("Lorg/chromium/net/UrlRequest;")
@ -193,25 +64,6 @@ internal val buildRequestFingerprint = fingerprint {
}
}
internal val playerResponseModelBackgroundAudioPlaybackFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returns("Z")
parameters("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;")
opcodes(
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.GOTO,
Opcode.RETURN,
null, // Opcode.CONST_4 or Opcode.MOVE
Opcode.RETURN,
)
}
internal val protobufClassParseByteBufferFingerprint = fingerprint {
accessFlags(AccessFlags.PROTECTED, AccessFlags.STATIC)
returns("L")

View File

@ -31,7 +31,6 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch;"
@Suppress("unused")
val spoofVideoStreamsPatch = bytecodePatch(
name = "Spoof video streams",
description = "Spoofs the client video streams to allow video playback.",

View File

@ -12,13 +12,6 @@ internal val componentContextParserFingerprint = fingerprint {
strings("Component was not found %s because it was removed due to duplicate converter bindings.")
}
internal val emptyComponentBuilderFingerprint = fingerprint {
opcodes(
Opcode.INVOKE_INTERFACE,
Opcode.INVOKE_STATIC_RANGE,
)
}
internal val lithoFilterFingerprint = fingerprint {
accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR)
returns("V")

View File

@ -41,7 +41,6 @@ internal const val EXTENSION_NAVIGATION_BUTTON_DESCRIPTOR =
lateinit var hookNavigationButtonCreated: (String) -> Unit
@Suppress("unused")
val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navigation or search bar.") {
dependsOn(
sharedExtensionPatch,
@ -127,7 +126,7 @@ val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navig
// Insert before the first ViewGroup method call after inflating,
// so this works regardless which layout is used.
actionBarSearchResultsMatch.mutableMethod.apply {
val searchBarResourceId = indexOfFirstWideLiteralInstructionValueOrThrow(
val searchBarResourceId = indexOfFirstLiteralInstructionOrThrow(
actionBarSearchResultsViewMicId,
)
@ -158,6 +157,5 @@ val navigationBarHookPatch = bytecodePatch(description = "Hooks the active navig
private enum class Hook(val methodName: String, val parameters: String) {
SET_LAST_APP_NAVIGATION_ENUM("setLastAppNavigationEnum", "Ljava/lang/Enum;"),
NAVIGATION_TAB_LOADED("navigationTabLoaded", "Landroid/view/View;"),
NAVIGATION_IMAGE_RESOURCE_TAB_LOADED("navigationImageResourceTabLoaded", "Landroid/view/View;"),
SEARCH_BAR_RESULTS_VIEW_LOADED("searchBarResultsViewLoaded", "Landroid/view/View;"),
NAVIGATION_IMAGE_RESOURCE_TAB_LOADED("navigationImageResourceTabLoaded", "Landroid/view/View;")
}

View File

@ -1,7 +1,7 @@
package app.revanced.patches.youtube.misc.playercontrols
import app.revanced.patcher.fingerprint
import app.revanced.util.containsWideLiteralInstructionValue
import app.revanced.util.containsLiteralInstruction
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags
@ -33,8 +33,8 @@ internal val overlayViewInflateFingerprint = fingerprint {
returns("V")
parameters("Landroid/view/View;")
custom { methodDef, _ ->
methodDef.containsWideLiteralInstructionValue(fullscreenButton) &&
methodDef.containsWideLiteralInstructionValue(heatseekerViewstub)
methodDef.containsLiteralInstruction(fullscreenButton) &&
methodDef.containsLiteralInstruction(heatseekerViewstub)
}
}

View File

@ -252,7 +252,7 @@ val playerControlsPatch = bytecodePatch(
// Hook the fullscreen close button. Used to fix visibility
// when seeking and other situations.
overlayViewInflateMatch.mutableMethod.apply {
val resourceIndex = indexOfFirstWideLiteralInstructionValueReversedOrThrow(fullscreenButton)
val resourceIndex = indexOfFirstLiteralInstructionReversedOrThrow(fullscreenButton)
val index = indexOfFirstInstructionOrThrow(resourceIndex) {
opcode == Opcode.CHECK_CAST &&

View File

@ -9,7 +9,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/PlayerTypeHookPatch;"
@Suppress("unused")
val playerTypeHookPatch = bytecodePatch(
description = "Hook to get the current player type and video playback state.",
) {

View File

@ -36,7 +36,6 @@ var is_19_41_or_greater = false
var is_19_43_or_greater = false
private set
@Suppress("unused")
val versionCheckPatch = resourcePatch(
description = "Uses the Play Store service version to find the major/minor version of the YouTube target app.",
) {

View File

@ -32,7 +32,6 @@ 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
import com.android.tools.smali.dexlib2.util.MethodUtil
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/VideoInformation;"
private const val EXTENSION_PLAYER_INTERFACE = "Lapp/revanced/extension/youtube/patches/VideoInformation${'$'}PlaybackController;"
@ -171,20 +170,21 @@ val videoInformationPatch = bytecodePatch(
* Hook the user playback speed selection
*/
onPlaybackSpeedItemClickMatch.mutableMethod.apply {
speedSelectionInsertMethod = this
val speedSelectionMethodInstructions = this.implementation!!.instructions
val speedSelectionMethodInstructions = implementation!!.instructions
val speedSelectionValueInstructionIndex = speedSelectionMethodInstructions.indexOfFirst {
it.opcode == Opcode.IGET
}
legacySpeedSelectionInsertMethod = this
legacySpeedSelectionInsertIndex = speedSelectionValueInstructionIndex + 1
legacySpeedSelectionValueRegister =
getInstruction<TwoRegisterInstruction>(speedSelectionValueInstructionIndex).registerA
setPlaybackSpeedClassFieldReference =
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 1).reference.toString()
setPlaybackSpeedMethodReference =
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 2).reference.toString()
setPlaybackSpeedContainerClassFieldReference =
getReference(speedSelectionMethodInstructions, -1, Opcode.IF_EQZ)
legacySpeedSelectionInsertIndex = speedSelectionValueInstructionIndex + 1
}
// Handle new playback speed menu.

View File

@ -31,7 +31,6 @@ private val playbackSpeedButtonResourcePatch = resourcePatch {
private const val SPEED_BUTTON_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/videoplayer/PlaybackSpeedDialogButton;"
@Suppress("unused")
val playbackSpeedButtonPatch = bytecodePatch(
description = "Adds the option to display playback speed dialog button in the video player.",
) {

View File

@ -81,7 +81,7 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
replaceInstruction(sizeCallIndex + 1, "const/4 v$sizeCallResultRegister, 0x0")
val arrayLengthConstIndex = indexOfFirstWideLiteralInstructionValueOrThrow(7)
val arrayLengthConstIndex = indexOfFirstLiteralInstructionOrThrow(7)
val arrayLengthConstDestination = getInstruction<OneRegisterInstruction>(arrayLengthConstIndex).registerA
val playbackSpeedsArrayType = "$EXTENSION_CLASS_DESCRIPTOR->customPlaybackSpeeds:[F"
@ -108,11 +108,11 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
// Override the min/max speeds that can be used.
speedLimiterMatch.mutableMethod.apply {
val limiterMinConstIndex = indexOfFirstWideLiteralInstructionValueOrThrow(0.25f.toRawBits().toLong())
var limiterMaxConstIndex = indexOfFirstWideLiteralInstructionValue(2.0f.toRawBits().toLong())
val limiterMinConstIndex = indexOfFirstLiteralInstructionOrThrow(0.25f.toRawBits().toLong())
var limiterMaxConstIndex = indexOfFirstLiteralInstruction(2.0f.toRawBits().toLong())
// Newer targets have 4x max speed.
if (limiterMaxConstIndex < 0) {
limiterMaxConstIndex = indexOfFirstWideLiteralInstructionValueOrThrow(4.0f.toRawBits().toLong())
limiterMaxConstIndex = indexOfFirstLiteralInstructionOrThrow(4.0f.toRawBits().toLong())
}
val limiterMinConstDestination = getInstruction<OneRegisterInstruction>(limiterMinConstIndex).registerA

View File

@ -106,18 +106,18 @@ internal fun MutableMethod.addInstructionsAtControlFlowLabel(
}
/**
* Get the index of the first instruction with the id of the given resource name.
* Get the index of the first instruction with the id of the given resource id name.
*
* Requires [resourceMappingPatch] as a dependency.
*
* @param resourceName the name of the resource to find the id for.
* @return the index of the first instruction with the id of the given resource name, or -1 if not found.
* @throws PatchException if the resource cannot be found.
* @see [indexOfIdResourceOrThrow], [indexOfFirstWideLiteralInstructionValueReversed]
* @see [indexOfFirstResourceIdOrThrow], [indexOfFirstLiteralInstructionReversed]
*/
fun Method.indexOfIdResource(resourceName: String): Int {
fun Method.indexOfFirstResourceId(resourceName: String): Int {
val resourceId = resourceMappings["id", resourceName]
return indexOfFirstWideLiteralInstructionValue(resourceId)
return indexOfFirstLiteralInstruction(resourceId)
}
/**
@ -126,10 +126,10 @@ fun Method.indexOfIdResource(resourceName: String): Int {
* Requires [resourceMappingPatch] as a dependency.
*
* @throws [PatchException] if the resource is not found, or the method does not contain the resource id literal value.
* @see [indexOfIdResource], [indexOfFirstWideLiteralInstructionValueReversedOrThrow]
* @see [indexOfFirstResourceId], [indexOfFirstLiteralInstructionReversedOrThrow]
*/
fun Method.indexOfIdResourceOrThrow(resourceName: String): Int {
val index = indexOfIdResource(resourceName)
fun Method.indexOfFirstResourceIdOrThrow(resourceName: String): Int {
val index = indexOfFirstResourceId(resourceName)
if (index < 0) {
throw PatchException("Found resource id for: '$resourceName' but method does not contain the id: $this")
}
@ -137,40 +137,37 @@ fun Method.indexOfIdResourceOrThrow(resourceName: String): Int {
return index
}
// TODO Rename these from 'FirstWideLiteralInstruction' to 'FirstLiteralInstruction',
// since NarrowLiteralInstruction is a subclass of WideLiteralInstruction.
/**
* Find the index of the first wide literal instruction with the given value.
* Find the index of the first literal instruction with the given value.
*
* @return the first literal instruction with the value, or -1 if not found.
* @see indexOfFirstWideLiteralInstructionValueOrThrow
* @see indexOfFirstLiteralInstructionOrThrow
*/
fun Method.indexOfFirstWideLiteralInstructionValue(literal: Long) = implementation?.let {
fun Method.indexOfFirstLiteralInstruction(literal: Long) = implementation?.let {
it.instructions.indexOfFirst { instruction ->
(instruction as? WideLiteralInstruction)?.wideLiteral == literal
}
} ?: -1
/**
* Find the index of the first wide literal instruction with the given value,
* Find the index of the first literal instruction with the given value,
* or throw an exception if not found.
*
* @return the first literal instruction with the value, or throws [PatchException] if not found.
*/
fun Method.indexOfFirstWideLiteralInstructionValueOrThrow(literal: Long): Int {
val index = indexOfFirstWideLiteralInstructionValue(literal)
fun Method.indexOfFirstLiteralInstructionOrThrow(literal: Long): Int {
val index = indexOfFirstLiteralInstruction(literal)
if (index < 0) throw PatchException("Could not find literal value: $literal")
return index
}
/**
* Find the index of the last wide literal instruction with the given value.
* Find the index of the last literal instruction with the given value.
*
* @return the last literal instruction with the value, or -1 if not found.
* @see indexOfFirstWideLiteralInstructionValueOrThrow
* @see indexOfFirstLiteralInstructionOrThrow
*/
fun Method.indexOfFirstWideLiteralInstructionValueReversed(literal: Long) = implementation?.let {
fun Method.indexOfFirstLiteralInstructionReversed(literal: Long) = implementation?.let {
it.instructions.indexOfLast { instruction ->
(instruction as? WideLiteralInstruction)?.wideLiteral == literal
}
@ -182,8 +179,8 @@ fun Method.indexOfFirstWideLiteralInstructionValueReversed(literal: Long) = impl
*
* @return the last literal instruction with the value, or throws [PatchException] if not found.
*/
fun Method.indexOfFirstWideLiteralInstructionValueReversedOrThrow(literal: Long): Int {
val index = indexOfFirstWideLiteralInstructionValueReversed(literal)
fun Method.indexOfFirstLiteralInstructionReversedOrThrow(literal: Long): Int {
val index = indexOfFirstLiteralInstructionReversed(literal)
if (index < 0) throw PatchException("Could not find literal value: $literal")
return index
}
@ -193,8 +190,8 @@ fun Method.indexOfFirstWideLiteralInstructionValueReversedOrThrow(literal: Long)
*
* @return if the method contains a literal with the given value.
*/
fun Method.containsWideLiteralInstructionValue(literal: Long) =
indexOfFirstWideLiteralInstructionValue(literal) >= 0
fun Method.containsLiteralInstruction(literal: Long) =
indexOfFirstLiteralInstruction(literal) >= 0
/**
* Traverse the class hierarchy starting from the given root class.
@ -220,19 +217,8 @@ fun BytecodePatchContext.traverseClassHierarchy(targetClass: MutableClass, callb
* if the [Instruction] is not a [ReferenceInstruction] or the [Reference] is not of type [T].
* @see ReferenceInstruction
*/
inline fun <reified T : Reference> Instruction.getReference() = (this as? ReferenceInstruction)?.reference as? T
/**
* Get the index of the first [Instruction] that matches the predicate.
*
* @param predicate The predicate to match.
* @return The index of the first [Instruction] that matches the predicate.
*/
// TODO: delete this on next major release, the overloaded method with an optional start index serves the same purposes.
// Method is deprecated, but annotation is commented out otherwise during compilation usage of the replacement is
// incorrectly flagged as deprecated.
// @Deprecated("Use the overloaded method with an optional start index.", ReplaceWith("indexOfFirstInstruction(predicate)"))
fun Method.indexOfFirstInstruction(predicate: Instruction.() -> Boolean) = indexOfFirstInstruction(0, predicate)
inline fun <reified T : Reference> Instruction.getReference() =
(this as? ReferenceInstruction)?.reference as? T
/**
* @return The index of the first opcode specified, or -1 if not found.
@ -258,12 +244,12 @@ fun Method.indexOfFirstInstruction(startIndex: Int = 0, targetOpcode: Opcode): I
* @return -1 if the instruction is not found.
* @see indexOfFirstInstructionOrThrow
*/
fun Method.indexOfFirstInstruction(startIndex: Int = 0, predicate: Instruction.() -> Boolean): Int {
fun Method.indexOfFirstInstruction(startIndex: Int = 0, filter: Instruction.() -> Boolean): Int {
var instructions = this.implementation!!.instructions
if (startIndex != 0) {
instructions = instructions.drop(startIndex)
}
val index = instructions.indexOfFirst(predicate)
val index = instructions.indexOfFirst(filter)
return if (index >= 0) {
startIndex + index
@ -297,8 +283,8 @@ fun Method.indexOfFirstInstructionOrThrow(startIndex: Int = 0, targetOpcode: Opc
* @throws PatchException
* @see indexOfFirstInstruction
*/
fun Method.indexOfFirstInstructionOrThrow(startIndex: Int = 0, predicate: Instruction.() -> Boolean): Int {
val index = indexOfFirstInstruction(startIndex, predicate)
fun Method.indexOfFirstInstructionOrThrow(startIndex: Int = 0, filter: Instruction.() -> Boolean): Int {
val index = indexOfFirstInstruction(startIndex, filter)
if (index < 0) {
throw PatchException("Could not find instruction index")
}
@ -327,13 +313,13 @@ fun Method.indexOfFirstInstructionReversed(startIndex: Int? = null, targetOpcode
* @return -1 if the instruction is not found.
* @see indexOfFirstInstructionReversedOrThrow
*/
fun Method.indexOfFirstInstructionReversed(startIndex: Int? = null, predicate: Instruction.() -> Boolean): Int {
fun Method.indexOfFirstInstructionReversed(startIndex: Int? = null, filter: Instruction.() -> Boolean): Int {
var instructions = this.implementation!!.instructions
if (startIndex != null) {
instructions = instructions.take(startIndex + 1)
}
return instructions.indexOfLast(predicate)
return instructions.indexOfLast(filter)
}
/**
@ -357,8 +343,8 @@ fun Method.indexOfFirstInstructionReversedOrThrow(startIndex: Int? = null, targe
* @return -1 if the instruction is not found.
* @see indexOfFirstInstructionReversed
*/
fun Method.indexOfFirstInstructionReversedOrThrow(startIndex: Int? = null, predicate: Instruction.() -> Boolean): Int {
val index = indexOfFirstInstructionReversed(startIndex, predicate)
fun Method.indexOfFirstInstructionReversedOrThrow(startIndex: Int? = null, filter: Instruction.() -> Boolean): Int {
val index = indexOfFirstInstructionReversed(startIndex, filter)
if (index < 0) {
throw PatchException("Could not find instruction index")
@ -368,26 +354,48 @@ fun Method.indexOfFirstInstructionReversedOrThrow(startIndex: Int? = null, predi
}
/**
* @return The list of indices of the opcode in reverse order.
* @return An immutable list of indices of the instructions in reverse order.
* _Returns an empty list if no indices are found_
* @see findInstructionIndicesReversedOrThrow
*/
fun Method.findOpcodeIndicesReversed(opcode: Opcode): List<Int> =
findOpcodeIndicesReversed { this.opcode == opcode }
/**
* @return The list of indices of the opcode in reverse order.
*/
fun Method.findOpcodeIndicesReversed(filter: Instruction.() -> Boolean): List<Int> {
val indexes = instructions
fun Method.findInstructionIndicesReversed(filter: Instruction.() -> Boolean): List<Int> {
return instructions
.withIndex()
.filter { (_, instruction) -> filter(instruction) }
.map { (index, _) -> index }
.reversed() // TODO: Use asReversed here to avoid creating a new list.
.asReversed()
}
/**
* @return An immutable list of indices of the instructions in reverse order.
* @throws PatchException if no matching indices are found.
*/
fun Method.findInstructionIndicesReversedOrThrow(filter: Instruction.() -> Boolean): List<Int> {
val indexes = findInstructionIndicesReversed(filter)
if (indexes.isEmpty()) throw PatchException("No matching instructions found in: $this")
return indexes
}
/**
* @return An immutable list of indices of the opcode in reverse order.
* _Returns an empty list if no indices are found_
* @see findInstructionIndicesReversedOrThrow
*/
fun Method.findInstructionIndicesReversed(opcode: Opcode): List<Int> =
findInstructionIndicesReversed { this.opcode == opcode }
/**
* @return An immutable list of indices of the opcode in reverse order.
* @throws PatchException if no matching indices are found.
*/
fun Method.findInstructionIndicesReversedOrThrow(opcode: Opcode): List<Int> {
val instructions = findInstructionIndicesReversed(opcode)
if (instructions.isEmpty()) throw PatchException("Could not find opcode: $opcode in: $this")
return instructions
}
/**
* Called for _all_ instructions with the given literal value.
*/
@ -412,26 +420,31 @@ fun BytecodePatchContext.forEachLiteralValueInstruction(
/**
* Return the matched method early.
*/
fun Fingerprint.returnEarly(bool: Boolean = false) {
val const = if (bool) "0x1" else "0x0"
match?.let { match ->
val stringInstructions = when (match.method.returnType.first()) {
'L' ->
"""
const/4 v0, $const
return-object v0
"""
'V' -> "return-void"
'I', 'Z' ->
"""
const/4 v0, $const
return v0
"""
else -> throw Exception("This case should never happen.")
}
fun Fingerprint.returnEarly(bool: Boolean = false) =
matchOrThrow.mutableMethod. returnEarly(bool)
match.mutableMethod.addInstructions(0, stringInstructions)
} ?: throw exception
/**
* Return the method early.
*/
fun MutableMethod.returnEarly(bool: Boolean = false) {
val const = if (bool) "0x1" else "0x0"
val stringInstructions = when (returnType.first()) {
'L' ->
"""
const/4 v0, $const
return-object v0
"""
'V' -> "return-void"
'I', 'Z' ->
"""
const/4 v0, $const
return v0
"""
else -> throw Exception("This case should never happen.")
}
addInstructions(0, stringInstructions)
}
/**
@ -441,14 +454,6 @@ fun Iterable<Fingerprint>.returnEarly(bool: Boolean = false) = forEach { fingerp
fingerprint.returnEarly(bool)
}
/**
* Return the matched methods early.
*/
@Deprecated("Use the Iterable version")
fun List<Fingerprint>.returnEarly(bool: Boolean = false) = forEach { fingerprint ->
fingerprint.returnEarly(bool)
}
/**
* Matches this fingerprint using the classDef of a parent fingerprint match.
*/
@ -463,6 +468,6 @@ fun Fingerprint.applyMatch(context: BytecodePatchContext, parentMatch: Match) =
// TODO: add a way for subclasses to also use their own custom fingerprint.
fun FingerprintBuilder.literal(literalSupplier: () -> Long) {
custom { method, _ ->
method.containsWideLiteralInstructionValue(literalSupplier())
method.containsLiteralInstruction(literalSupplier())
}
}

View File

@ -710,7 +710,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
<string name="revanced_player_overlay_opacity_summary">Opacity value between 0-100, where 0 is transparent</string>
<string name="revanced_player_overlay_opacity_invalid_toast">Player overlay opacity must be between 0-100</string>
</patch>
<patch id="layout.returnyoutubedislike.returnYouTubeDislikeResourcePatch">
<patch id="layout.returnyoutubedislike.returnYouTubeDislikePatch">
<string name="revanced_ryd_settings_title">Return YouTube Dislike</string>
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
<string name="revanced_ryd_failure_connection_timeout">Dislikes temporarily not available (API timed out)</string>