mirror of
https://github.com/revanced/revanced-patches
synced 2024-11-27 11:16:48 +01:00
chore: Remove obsolete code (#3650)
This commit is contained in:
parent
a361bfb1da
commit
cf8104bfb4
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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.",
|
||||
|
@ -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 ->
|
||||
|
@ -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.",
|
||||
|
@ -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",
|
||||
|
@ -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.",
|
||||
) {
|
||||
|
@ -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.",
|
||||
) {
|
||||
|
@ -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",
|
||||
|
@ -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(
|
||||
|
@ -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.",
|
||||
) {
|
||||
|
@ -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",
|
||||
) {
|
||||
|
@ -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.",
|
||||
) {
|
||||
|
@ -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.",
|
||||
) {
|
||||
|
@ -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",
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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.",
|
||||
) {
|
||||
|
@ -22,6 +22,6 @@ internal val piracyDetectionFingerprint = fingerprint {
|
||||
val reference = (it as ReferenceInstruction).reference
|
||||
|
||||
reference.toString() == "Lcom/github/javiersantos/piracychecker/PiracyChecker;"
|
||||
} ?: false
|
||||
} == true
|
||||
}
|
||||
}
|
||||
|
@ -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 ->
|
||||
|
@ -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.",
|
||||
) {
|
||||
|
@ -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.",
|
||||
|
@ -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
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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.",
|
||||
|
@ -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.",
|
||||
) {
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
@ -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.",
|
||||
) {
|
||||
|
@ -203,6 +203,6 @@ internal object PreferenceScreen : BasePreferenceScreen() {
|
||||
}
|
||||
|
||||
override fun commit(screen: app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference) {
|
||||
preferences += screen
|
||||
addSettingPreference(screen)
|
||||
}
|
||||
}
|
||||
|
@ -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;"
|
||||
|
@ -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
|
||||
|
@ -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.",
|
||||
) {
|
||||
|
@ -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.",
|
||||
) {
|
||||
|
@ -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;"
|
||||
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 }!!
|
||||
|
@ -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).",
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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")
|
||||
}
|
@ -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)
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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,9 +93,7 @@ internal val rollingNumberTextViewFingerprint = fingerprint {
|
||||
Opcode.RETURN_VOID,
|
||||
)
|
||||
custom { _, classDef ->
|
||||
classDef.superclass ==
|
||||
"Landroid/support/v7/widget/AppCompatTextView;" ||
|
||||
classDef.superclass ==
|
||||
classDef.superclass == "Landroid/support/v7/widget/AppCompatTextView;" || classDef.superclass ==
|
||||
"Lcom/google/android/libraries/youtube/rendering/ui/spec/typography/YouTubeAppCompatTextView;"
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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" &&
|
||||
|
@ -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(
|
||||
|
@ -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.
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
|
@ -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.",
|
||||
|
@ -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.",
|
||||
) {
|
||||
|
@ -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,
|
||||
)
|
||||
|
||||
|
@ -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")
|
||||
|
@ -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.",
|
||||
|
@ -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")
|
||||
|
@ -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;")
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 &&
|
||||
|
@ -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.",
|
||||
) {
|
||||
|
@ -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.",
|
||||
) {
|
||||
|
@ -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.
|
||||
|
@ -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.",
|
||||
) {
|
||||
|
@ -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
|
||||
|
@ -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,10 +420,16 @@ fun BytecodePatchContext.forEachLiteralValueInstruction(
|
||||
/**
|
||||
* Return the matched method early.
|
||||
*/
|
||||
fun Fingerprint.returnEarly(bool: Boolean = false) {
|
||||
fun Fingerprint.returnEarly(bool: Boolean = false) =
|
||||
matchOrThrow.mutableMethod. returnEarly(bool)
|
||||
|
||||
/**
|
||||
* Return the method early.
|
||||
*/
|
||||
fun MutableMethod.returnEarly(bool: Boolean = false) {
|
||||
val const = if (bool) "0x1" else "0x0"
|
||||
match?.let { match ->
|
||||
val stringInstructions = when (match.method.returnType.first()) {
|
||||
|
||||
val stringInstructions = when (returnType.first()) {
|
||||
'L' ->
|
||||
"""
|
||||
const/4 v0, $const
|
||||
@ -430,8 +444,7 @@ fun Fingerprint.returnEarly(bool: Boolean = false) {
|
||||
else -> throw Exception("This case should never happen.")
|
||||
}
|
||||
|
||||
match.mutableMethod.addInstructions(0, stringInstructions)
|
||||
} ?: throw exception
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user