Compare commits

..

26 Commits

Author SHA1 Message Date
semantic-release-bot
3174047223 chore: Release v5.21.0-dev.9 [skip ci]
# [5.21.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v5.21.0-dev.8...v5.21.0-dev.9) (2025-04-21)

### Bug Fixes

* **YouTube - Hide video action buttons:** Hide A/B layout buttons ([15053e2](15053e2b68))
2025-04-21 20:16:36 +00:00
LisoUseInAIKyrios
15053e2b68 fix(YouTube - Hide video action buttons): Hide A/B layout buttons 2025-04-21 22:13:04 +02:00
semantic-release-bot
e5b6aac018 chore: Release v5.21.0-dev.8 [skip ci]
# [5.21.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.21.0-dev.7...v5.21.0-dev.8) (2025-04-20)

### Bug Fixes

* **Wide search bar:** Fix patching `19.16.39` ([d7c9dd0](d7c9dd0f77))
2025-04-20 11:31:26 +00:00
LisoUseInAIKyrios
d7c9dd0f77 fix(Wide search bar): Fix patching 19.16.39 2025-04-20 13:27:55 +02:00
github-actions[bot]
a0eb6d5fdb chore: Sync translations (#4833) 2025-04-20 13:27:33 +02:00
semantic-release-bot
55c5eb3d14 chore: Release v5.21.0-dev.7 [skip ci]
# [5.21.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.21.0-dev.6...v5.21.0-dev.7) (2025-04-20)

### Bug Fixes

* **YouTube - Change start page:** Add option to always override start page on app launch ([#4832](https://github.com/ReVanced/revanced-patches/issues/4832)) ([896de89](896de8910a))
2025-04-20 08:24:42 +00:00
LisoUseInAIKyrios
896de8910a fix(YouTube - Change start page): Add option to always override start page on app launch (#4832) 2025-04-20 10:21:03 +02:00
semantic-release-bot
e2a7e25c66 chore: Release v5.21.0-dev.6 [skip ci]
# [5.21.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.21.0-dev.5...v5.21.0-dev.6) (2025-04-19)

### Bug Fixes

* **YouTube - Wide search bar:** Do not force phone layout for tablet devices ([#4827](https://github.com/ReVanced/revanced-patches/issues/4827)) ([77ea5c4](77ea5c4033))
2025-04-19 16:36:29 +00:00
LisoUseInAIKyrios
77ea5c4033 fix(YouTube - Wide search bar): Do not force phone layout for tablet devices (#4827) 2025-04-19 18:33:12 +02:00
github-actions[bot]
6eea2354f5 chore: Sync translations (#4828) 2025-04-19 12:00:28 +02:00
semantic-release-bot
cce21c4d4a chore: Release v5.21.0-dev.5 [skip ci]
# [5.21.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.21.0-dev.4...v5.21.0-dev.5) (2025-04-18)

### Bug Fixes

* `Hide ADB status` patch ([#4814](https://github.com/ReVanced/revanced-patches/issues/4814)) ([5e069bd](5e069bde90))
2025-04-18 09:18:56 +00:00
1fexd
5e069bde90 fix: Hide ADB status patch (#4814) 2025-04-18 11:15:05 +02:00
github-actions[bot]
6a49208982 chore: Sync translations (#4822) 2025-04-18 09:55:15 +02:00
Snow
404bb2e86e chore(YouTube - Return YouTube Dislike): Clarify settings text for estimated likes (#4818) 2025-04-17 19:10:37 +02:00
github-actions[bot]
bc869fe359 chore: Sync translations (#4820) 2025-04-17 19:09:35 +02:00
semantic-release-bot
7d166cf82c chore: Release v5.21.0-dev.4 [skip ci]
# [5.21.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.21.0-dev.3...v5.21.0-dev.4) (2025-04-17)

### Bug Fixes

* **YouTube - Disable auto captions:** Correctly hide captions with YT 20.12 ([8efbaae](8efbaae65c))
2025-04-17 17:06:19 +00:00
LisoUseInAIKyrios
8efbaae65c fix(YouTube - Disable auto captions): Correctly hide captions with YT 20.12 2025-04-17 19:02:52 +02:00
LisoUseInAIKyrios
e27ab23279 chore(YouTube): Add debug text to toast text if user forgot they enabled debugging 2025-04-16 14:56:31 +02:00
semantic-release-bot
ce42604083 chore: Release v5.21.0-dev.3 [skip ci]
# [5.21.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.21.0-dev.2...v5.21.0-dev.3) (2025-04-16)

### Features

* **X / Twitter:** Support version `10.86.0-release.0` ([#4805](https://github.com/ReVanced/revanced-patches/issues/4805)) ([fc6282d](fc6282d0cb))
2025-04-16 11:09:43 +00:00
cyberboh
fc6282d0cb feat(X / Twitter): Support version 10.86.0-release.0 (#4805) 2025-04-16 13:06:30 +02:00
semantic-release-bot
0559fc7fd0 chore: Release v5.21.0-dev.2 [skip ci]
# [5.21.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.21.0-dev.1...v5.21.0-dev.2) (2025-04-16)

### Features

* Add `Hide ADB status` patch ([#4585](https://github.com/ReVanced/revanced-patches/issues/4585)) ([7cc6995](7cc6995682))
2025-04-16 08:58:30 +00:00
1fexd
7cc6995682 feat: Add Hide ADB status patch (#4585)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2025-04-16 10:55:07 +02:00
semantic-release-bot
476f13bf98 chore: Release v5.21.0-dev.1 [skip ci]
# [5.21.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.20.1...v5.21.0-dev.1) (2025-04-16)

### Features

* **YouTube:** Support version `20.12.46` ([#4779](https://github.com/ReVanced/revanced-patches/issues/4779)) ([f216e16](f216e16c0b))
2025-04-16 08:28:15 +00:00
LisoUseInAIKyrios
f216e16c0b feat(YouTube): Support version 20.12.46 (#4779) 2025-04-16 10:24:35 +02:00
semantic-release-bot
f2a8789649 chore: Release v5.20.1 [skip ci]
## [5.20.1](https://github.com/ReVanced/revanced-patches/compare/v5.20.0...v5.20.1) (2025-04-15)

### Bug Fixes

* **Spotify - Custom theme:** Support latest app target ([#4800](https://github.com/ReVanced/revanced-patches/issues/4800)) ([2393d0a](2393d0a8f5))
2025-04-15 16:41:52 +00:00
LisoUseInAIKyrios
5973b64f52 chore: Merge branch dev to main (#4801) 2025-04-15 18:38:29 +02:00
143 changed files with 1348 additions and 678 deletions

View File

@@ -1,3 +1,73 @@
# [5.21.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v5.21.0-dev.8...v5.21.0-dev.9) (2025-04-21)
### Bug Fixes
* **YouTube - Hide video action buttons:** Hide A/B layout buttons ([4db5d3c](https://github.com/ReVanced/revanced-patches/commit/4db5d3c3d5ac04faf70cc07fb309b324d752e7e3))
# [5.21.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.21.0-dev.7...v5.21.0-dev.8) (2025-04-20)
### Bug Fixes
* **Wide search bar:** Fix patching `19.16.39` ([433dbc3](https://github.com/ReVanced/revanced-patches/commit/433dbc3bf81823369e146035c954281e84d3a436))
# [5.21.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.21.0-dev.6...v5.21.0-dev.7) (2025-04-20)
### Bug Fixes
* **YouTube - Change start page:** Add option to always override start page on app launch ([#4832](https://github.com/ReVanced/revanced-patches/issues/4832)) ([5062e24](https://github.com/ReVanced/revanced-patches/commit/5062e24433ba38eba397438e8fde32099109d3c3))
# [5.21.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.21.0-dev.5...v5.21.0-dev.6) (2025-04-19)
### Bug Fixes
* **YouTube - Wide search bar:** Do not force phone layout for tablet devices ([#4827](https://github.com/ReVanced/revanced-patches/issues/4827)) ([0cb38f9](https://github.com/ReVanced/revanced-patches/commit/0cb38f9f367a7fe742d8ca336150049181d637b6))
# [5.21.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.21.0-dev.4...v5.21.0-dev.5) (2025-04-18)
### Bug Fixes
* `Hide ADB status` patch ([#4814](https://github.com/ReVanced/revanced-patches/issues/4814)) ([dc89be0](https://github.com/ReVanced/revanced-patches/commit/dc89be0e94880733f862b250d95d4848f02c594d))
# [5.21.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.21.0-dev.3...v5.21.0-dev.4) (2025-04-17)
### Bug Fixes
* **YouTube - Disable auto captions:** Correctly hide captions with YT 20.12 ([5ecbe82](https://github.com/ReVanced/revanced-patches/commit/5ecbe823ed5197533328cc37f1de5cd1f048a217))
# [5.21.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.21.0-dev.2...v5.21.0-dev.3) (2025-04-16)
### Features
* **X / Twitter:** Support version `10.86.0-release.0` ([#4805](https://github.com/ReVanced/revanced-patches/issues/4805)) ([655b390](https://github.com/ReVanced/revanced-patches/commit/655b39043ad77efcb4380de67c3f603666e7bc49))
# [5.21.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.21.0-dev.1...v5.21.0-dev.2) (2025-04-16)
### Features
* Add `Hide ADB status` patch ([#4585](https://github.com/ReVanced/revanced-patches/issues/4585)) ([1ea8047](https://github.com/ReVanced/revanced-patches/commit/1ea8047aefdaa358e9af8038923ac54d68a39176))
# [5.21.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.20.1...v5.21.0-dev.1) (2025-04-16)
### Features
* **YouTube:** Support version `20.12.46` ([#4779](https://github.com/ReVanced/revanced-patches/issues/4779)) ([703359f](https://github.com/ReVanced/revanced-patches/commit/703359f0c16b613c204cf16cf42227b628f664fa))
## [5.20.1](https://github.com/ReVanced/revanced-patches/compare/v5.20.0...v5.20.1) (2025-04-15)
### Bug Fixes
* **Spotify - Custom theme:** Support latest app target ([#4800](https://github.com/ReVanced/revanced-patches/issues/4800)) ([03d0eb2](https://github.com/ReVanced/revanced-patches/commit/03d0eb2f8c0f3e48d53bdab38d34057f2020bb65))
## [5.20.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.20.0...v5.20.1-dev.1) (2025-04-15) ## [5.20.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.20.0...v5.20.1-dev.1) (2025-04-15)

View File

@@ -0,0 +1,16 @@
android {
namespace = "app.revanced.extension"
defaultConfig {
minSdk = 21
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
}
dependencies {
compileOnly(libs.annotation)
}

View File

@@ -0,0 +1 @@
<manifest/>

View File

@@ -0,0 +1,28 @@
package app.revanced.extension.all.misc.hide.adb;
import android.content.ContentResolver;
import android.provider.Settings;
import java.util.Arrays;
import java.util.List;
@SuppressWarnings("unused")
public final class HideAdbPatch {
private static final List<String> SPOOF_SETTINGS = Arrays.asList("adb_enabled", "adb_wifi_enabled", "development_settings_enabled");
public static int getInt(ContentResolver cr, String name) throws Settings.SettingNotFoundException {
if (SPOOF_SETTINGS.contains(name)) {
return 0;
}
return Settings.Global.getInt(cr, name);
}
public static int getInt(ContentResolver cr, String name, int def) {
if (SPOOF_SETTINGS.contains(name)) {
return 0;
}
return Settings.Global.getInt(cr, name, def);
}
}

View File

@@ -1,4 +1,4 @@
package app.revanced.extension.all.connectivity.wifi.spoof; package app.revanced.extension.all.misc.connectivity.wifi.spoof;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Context; import android.content.Context;

View File

@@ -1,4 +1,4 @@
package app.revanced.extension.all.screencapture.removerestriction; package app.revanced.extension.all.misc.screencapture.removerestriction;
import android.media.AudioAttributes; import android.media.AudioAttributes;
import android.os.Build; import android.os.Build;

View File

@@ -1,4 +1,4 @@
package app.revanced.extension.all.screenshot.removerestriction; package app.revanced.extension.all.misc.screenshot.removerestriction;
import android.view.Window; import android.view.Window;
import android.view.WindowManager; import android.view.WindowManager;

View File

@@ -204,7 +204,7 @@ public class StreamingDataRequest {
// but empty response body does. // but empty response body does.
if (connection.getContentLength() == 0) { if (connection.getContentLength() == 0) {
if (BaseSettings.DEBUG.get() && BaseSettings.DEBUG_TOAST_ON_ERROR.get()) { if (BaseSettings.DEBUG.get() && BaseSettings.DEBUG_TOAST_ON_ERROR.get()) {
Utils.showToastShort("Ignoring empty spoof stream client: " + clientType); Utils.showToastShort("Debug: Ignoring empty spoof stream client " + clientType);
} }
} else { } else {
try (InputStream inputStream = new BufferedInputStream(connection.getInputStream()); try (InputStream inputStream = new BufferedInputStream(connection.getInputStream());

View File

@@ -9,6 +9,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.settings.Setting;
import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@@ -81,6 +82,13 @@ public final class ChangeStartPagePatch {
} }
} }
public static class ChangeStartPageTypeAvailability implements Setting.Availability {
@Override
public boolean isAvailable() {
return Settings.CHANGE_START_PAGE.get() != StartPage.DEFAULT;
}
}
/** /**
* Intent action when YouTube is cold started from the launcher. * Intent action when YouTube is cold started from the launcher.
* <p> * <p>
@@ -93,6 +101,8 @@ public final class ChangeStartPagePatch {
private static final StartPage START_PAGE = Settings.CHANGE_START_PAGE.get(); private static final StartPage START_PAGE = Settings.CHANGE_START_PAGE.get();
private static final boolean CHANGE_START_PAGE_ALWAYS = Settings.CHANGE_START_PAGE_ALWAYS.get();
/** /**
* There is an issue where the back button on the toolbar doesn't work properly. * There is an issue where the back button on the toolbar doesn't work properly.
* As a workaround for this issue, instead of overriding the browserId multiple times, just override it once. * As a workaround for this issue, instead of overriding the browserId multiple times, just override it once.
@@ -104,13 +114,13 @@ public final class ChangeStartPagePatch {
return original; return original;
} }
if (appLaunched) { if (!CHANGE_START_PAGE_ALWAYS && appLaunched) {
Logger.printDebug(() -> "Ignore override browseId as the app already launched"); Logger.printDebug(() -> "Ignore override browseId as the app already launched");
return original; return original;
} }
appLaunched = true; appLaunched = true;
Logger.printDebug(() -> "Changing browseId to " + START_PAGE.id); Logger.printDebug(() -> "Changing browseId to: " + START_PAGE.id);
return START_PAGE.id; return START_PAGE.id;
} }
@@ -125,14 +135,14 @@ public final class ChangeStartPagePatch {
return; return;
} }
if (appLaunched) { if (!CHANGE_START_PAGE_ALWAYS && appLaunched) {
Logger.printDebug(() -> "Ignore override intent action as the app already launched"); Logger.printDebug(() -> "Ignore override intent action as the app already launched");
return; return;
} }
appLaunched = true; appLaunched = true;
String intentAction = START_PAGE.id; String intentAction = START_PAGE.id;
Logger.printDebug(() -> "Changing intent action to " + intentAction); Logger.printDebug(() -> "Changing intent action to: " + intentAction);
intent.setAction(intentAction); intent.setAction(intentAction);
} }
} }

View File

@@ -1,20 +1,23 @@
package app.revanced.extension.youtube.patches; package app.revanced.extension.youtube.patches;
import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.shared.ShortsPlayerState;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class DisableAutoCaptionsPatch { public class DisableAutoCaptionsPatch {
/** private static volatile boolean captionsButtonStatus;
* Used by injected code. Do not delete.
*/
public static boolean captionsButtonDisabled;
public static boolean autoCaptionsEnabled() { /**
return Settings.AUTO_CAPTIONS.get() * Injection point.
// Do not use auto captions for Shorts. */
&& ShortsPlayerState.isOpen(); public static boolean disableAutoCaptions() {
return Settings.DISABLE_AUTO_CAPTIONS.get() && !captionsButtonStatus;
} }
/**
* Injection point.
*/
public static void setCaptionsButtonStatus(boolean status) {
captionsButtonStatus = status;
}
} }

View File

@@ -1,11 +1,48 @@
package app.revanced.extension.youtube.patches; package app.revanced.extension.youtube.patches;
import android.content.res.Resources;
import android.util.TypedValue;
import android.view.View;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class WideSearchbarPatch { public final class WideSearchbarPatch {
private static final Boolean WIDE_SEARCHBAR_ENABLED = Settings.WIDE_SEARCHBAR.get();
/**
* Injection point.
*/
public static boolean enableWideSearchbar(boolean original) { public static boolean enableWideSearchbar(boolean original) {
return Settings.WIDE_SEARCHBAR.get() || original; return WIDE_SEARCHBAR_ENABLED || original;
}
/**
* Injection point.
*/
public static void setActionBar(View view) {
try {
if (!WIDE_SEARCHBAR_ENABLED) return;
View searchBarView = Utils.getChildViewByResourceName(view, "search_bar");
final int paddingLeft = searchBarView.getPaddingLeft();
final int paddingRight = searchBarView.getPaddingRight();
final int paddingTop = searchBarView.getPaddingTop();
final int paddingBottom = searchBarView.getPaddingBottom();
final int paddingStart = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
8, Resources.getSystem().getDisplayMetrics());
if (Utils.isRightToLeftTextLayout()) {
searchBarView.setPadding(paddingLeft, paddingTop, paddingStart, paddingBottom);
} else {
searchBarView.setPadding(paddingStart, paddingTop, paddingRight, paddingBottom);
}
} catch (Exception ex) {
Logger.printException(() -> "setActionBar failure", ex);
}
} }
} }

View File

@@ -31,7 +31,7 @@ final class ButtonsFilter extends Filter {
bufferFilterPathGroup = new StringFilterGroup( bufferFilterPathGroup = new StringFilterGroup(
null, null,
"|ContainerType|button.eml|" "|ContainerType|button.eml"
); );
addPathCallbacks( addPathCallbacks(
@@ -43,7 +43,7 @@ final class ButtonsFilter extends Filter {
), ),
new StringFilterGroup( new StringFilterGroup(
Settings.HIDE_DOWNLOAD_BUTTON, Settings.HIDE_DOWNLOAD_BUTTON,
"|download_button.eml|" "|download_button.eml"
), ),
new StringFilterGroup( new StringFilterGroup(
Settings.HIDE_PLAYLIST_BUTTON, Settings.HIDE_PLAYLIST_BUTTON,
@@ -51,7 +51,7 @@ final class ButtonsFilter extends Filter {
), ),
new StringFilterGroup( new StringFilterGroup(
Settings.HIDE_CLIP_BUTTON, Settings.HIDE_CLIP_BUTTON,
"|clip_button.eml|" "|clip_button.eml"
) )
); );

View File

@@ -211,7 +211,7 @@ public final class LayoutComponentsFilter extends Filter {
compactChannelBarInnerButton = new StringFilterGroup( compactChannelBarInnerButton = new StringFilterGroup(
null, null,
"|button.eml|" "|button.eml"
); );
joinMembershipButton = new ByteArrayFilterGroup( joinMembershipButton = new ByteArrayFilterGroup(

View File

@@ -40,7 +40,7 @@ public class PlayerFlyoutMenuItemsFilter extends Filter {
addPathCallbacks( addPathCallbacks(
videoQualityMenuFooter, videoQualityMenuFooter,
new StringFilterGroup(null, "overflow_menu_item.eml|") new StringFilterGroup(null, "overflow_menu_item.eml")
); );
flyoutFilterGroupList.addAll( flyoutFilterGroupList.addAll(

View File

@@ -7,6 +7,7 @@ import static app.revanced.extension.shared.settings.Setting.migrateOldSettingTo
import static app.revanced.extension.shared.settings.Setting.parent; import static app.revanced.extension.shared.settings.Setting.parent;
import static app.revanced.extension.shared.settings.Setting.parentsAny; import static app.revanced.extension.shared.settings.Setting.parentsAny;
import static app.revanced.extension.youtube.patches.ChangeFormFactorPatch.FormFactor; import static app.revanced.extension.youtube.patches.ChangeFormFactorPatch.FormFactor;
import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.ChangeStartPageTypeAvailability;
import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.StartPage; import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.StartPage;
import static app.revanced.extension.youtube.patches.ExitFullscreenPatch.FullscreenMode; import static app.revanced.extension.youtube.patches.ExitFullscreenPatch.FullscreenMode;
import static app.revanced.extension.youtube.patches.ForceOriginalAudioPatch.ForceOriginalAudioAvailability; import static app.revanced.extension.youtube.patches.ForceOriginalAudioPatch.ForceOriginalAudioAvailability;
@@ -124,6 +125,7 @@ public class Settings extends BaseSettings {
// Player // Player
public static final BooleanSetting COPY_VIDEO_URL = new BooleanSetting("revanced_copy_video_url", FALSE); public static final BooleanSetting COPY_VIDEO_URL = new BooleanSetting("revanced_copy_video_url", FALSE);
public static final BooleanSetting COPY_VIDEO_URL_TIMESTAMP = new BooleanSetting("revanced_copy_video_url_timestamp", TRUE); public static final BooleanSetting COPY_VIDEO_URL_TIMESTAMP = new BooleanSetting("revanced_copy_video_url_timestamp", TRUE);
public static final BooleanSetting DISABLE_AUTO_CAPTIONS = new BooleanSetting("revanced_disable_auto_captions", FALSE, true);
public static final BooleanSetting DISABLE_FULLSCREEN_AMBIENT_MODE = new BooleanSetting("revanced_disable_fullscreen_ambient_mode", TRUE, true); public static final BooleanSetting DISABLE_FULLSCREEN_AMBIENT_MODE = new BooleanSetting("revanced_disable_fullscreen_ambient_mode", TRUE, true);
public static final BooleanSetting DISABLE_ROLLING_NUMBER_ANIMATIONS = new BooleanSetting("revanced_disable_rolling_number_animations", FALSE); public static final BooleanSetting DISABLE_ROLLING_NUMBER_ANIMATIONS = new BooleanSetting("revanced_disable_rolling_number_animations", FALSE);
public static final EnumSetting<FullscreenMode> EXIT_FULLSCREEN = new EnumSetting<>("revanced_exit_fullscreen", FullscreenMode.DISABLED); public static final EnumSetting<FullscreenMode> EXIT_FULLSCREEN = new EnumSetting<>("revanced_exit_fullscreen", FullscreenMode.DISABLED);
@@ -221,6 +223,8 @@ public class Settings extends BaseSettings {
public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", FALSE, true, "revanced_spoof_app_version_user_dialog_message"); public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", FALSE, true, "revanced_spoof_app_version_user_dialog_message");
public static final BooleanSetting WIDE_SEARCHBAR = new BooleanSetting("revanced_wide_searchbar", FALSE, true); public static final BooleanSetting WIDE_SEARCHBAR = new BooleanSetting("revanced_wide_searchbar", FALSE, true);
public static final EnumSetting<StartPage> CHANGE_START_PAGE = new EnumSetting<>("revanced_change_start_page", StartPage.DEFAULT, true); public static final EnumSetting<StartPage> CHANGE_START_PAGE = new EnumSetting<>("revanced_change_start_page", StartPage.DEFAULT, true);
public static final BooleanSetting CHANGE_START_PAGE_ALWAYS = new BooleanSetting("revanced_change_start_page_always", FALSE, true,
new ChangeStartPageTypeAvailability());
public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", "19.01.34", true, parent(SPOOF_APP_VERSION)); public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", "19.01.34", true, parent(SPOOF_APP_VERSION));
// Custom filter // Custom filter
public static final BooleanSetting CUSTOM_FILTER = new BooleanSetting("revanced_custom_filter", FALSE); public static final BooleanSetting CUSTOM_FILTER = new BooleanSetting("revanced_custom_filter", FALSE);
@@ -294,7 +298,6 @@ public class Settings extends BaseSettings {
// Misc // Misc
public static final BooleanSetting ANNOUNCEMENTS = new BooleanSetting("revanced_announcements", TRUE); public static final BooleanSetting ANNOUNCEMENTS = new BooleanSetting("revanced_announcements", TRUE);
public static final IntegerSetting ANNOUNCEMENT_LAST_ID = new IntegerSetting("revanced_announcement_last_id", -1, false, false); public static final IntegerSetting ANNOUNCEMENT_LAST_ID = new IntegerSetting("revanced_announcement_last_id", -1, false, false);
public static final BooleanSetting AUTO_CAPTIONS = new BooleanSetting("revanced_auto_captions", FALSE);
public static final BooleanSetting AUTO_REPEAT = new BooleanSetting("revanced_auto_repeat", FALSE); public static final BooleanSetting AUTO_REPEAT = new BooleanSetting("revanced_auto_repeat", FALSE);
public static final BooleanSetting BYPASS_URL_REDIRECTS = new BooleanSetting("revanced_bypass_url_redirects", TRUE); public static final BooleanSetting BYPASS_URL_REDIRECTS = new BooleanSetting("revanced_bypass_url_redirects", TRUE);
public static final BooleanSetting CHECK_WATCH_HISTORY_DOMAIN_NAME = new BooleanSetting("revanced_check_watch_history_domain_name", TRUE, false, false); public static final BooleanSetting CHECK_WATCH_HISTORY_DOMAIN_NAME = new BooleanSetting("revanced_check_watch_history_domain_name", TRUE, false, false);
@@ -403,6 +406,7 @@ public class Settings extends BaseSettings {
private static final StringSetting DEPRECATED_SEEKBAR_CUSTOM_COLOR_PRIMARY = new StringSetting("revanced_seekbar_custom_color_value", "#FF0033"); private static final StringSetting DEPRECATED_SEEKBAR_CUSTOM_COLOR_PRIMARY = new StringSetting("revanced_seekbar_custom_color_value", "#FF0033");
private static final BooleanSetting DEPRECATED_DISABLE_SUGGESTED_VIDEO_END_SCREEN = new BooleanSetting("revanced_disable_suggested_video_end_screen", FALSE); private static final BooleanSetting DEPRECATED_DISABLE_SUGGESTED_VIDEO_END_SCREEN = new BooleanSetting("revanced_disable_suggested_video_end_screen", FALSE);
private static final BooleanSetting DEPRECATED_RESTORE_OLD_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_restore_old_video_quality_menu", TRUE); private static final BooleanSetting DEPRECATED_RESTORE_OLD_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_restore_old_video_quality_menu", TRUE);
private static final BooleanSetting DEPRECATED_AUTO_CAPTIONS = new BooleanSetting("revanced_auto_captions", FALSE);
static { static {
// region Migration // region Migration
@@ -456,6 +460,11 @@ public class Settings extends BaseSettings {
SPOOF_APP_VERSION_TARGET.resetToDefault(); SPOOF_APP_VERSION_TARGET.resetToDefault();
} }
if (!DEPRECATED_AUTO_CAPTIONS.isSetToDefault()) {
DISABLE_AUTO_CAPTIONS.save(true);
DEPRECATED_AUTO_CAPTIONS.resetToDefault();
}
// endregion // endregion
// region SB import/export callbacks // region SB import/export callbacks

View File

@@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
org.gradle.parallel = true org.gradle.parallel = true
android.useAndroidX = true android.useAndroidX = true
kotlin.code.style = official kotlin.code.style = official
version = 5.20.1-dev.1 version = 5.21.0-dev.9

View File

@@ -2,6 +2,10 @@ public final class app/revanced/patches/all/misc/activity/exportall/ExportAllAct
public static final fun getExportAllActivitiesPatch ()Lapp/revanced/patcher/patch/ResourcePatch; public static final fun getExportAllActivitiesPatch ()Lapp/revanced/patcher/patch/ResourcePatch;
} }
public final class app/revanced/patches/all/misc/adb/HideAdbPatchKt {
public static final fun getHideAdbStatusPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/all/misc/build/BaseSpoofBuildInfoPatchKt { public final class app/revanced/patches/all/misc/build/BaseSpoofBuildInfoPatchKt {
public static final fun baseSpoofBuildInfoPatch (Lkotlin/jvm/functions/Function0;)Lapp/revanced/patcher/patch/BytecodePatch; public static final fun baseSpoofBuildInfoPatch (Lkotlin/jvm/functions/Function0;)Lapp/revanced/patcher/patch/BytecodePatch;
} }
@@ -1416,6 +1420,8 @@ public final class app/revanced/patches/youtube/misc/playservice/VersionCheckPat
public static final fun is_20_07_or_greater ()Z public static final fun is_20_07_or_greater ()Z
public static final fun is_20_09_or_greater ()Z public static final fun is_20_09_or_greater ()Z
public static final fun is_20_10_or_greater ()Z public static final fun is_20_10_or_greater ()Z
public static final fun is_20_14_or_greater ()Z
public static final fun is_20_15_or_greater ()Z
} }
public final class app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatchKt { public final class app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatchKt {

View File

@@ -0,0 +1,75 @@
package app.revanced.patches.all.misc.adb
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
import app.revanced.util.getReference
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodReference
import com.android.tools.smali.dexlib2.util.MethodUtil
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/all/misc/hide/adb/HideAdbPatch;"
private val SETTINGS_GLOBAL_GET_INT_OR_THROW_METHOD_REFERENCE = ImmutableMethodReference(
"Landroid/provider/Settings\$Global;",
"getInt",
listOf("Landroid/content/ContentResolver;", "Ljava/lang/String;"),
"I"
)
private val SETTINGS_GLOBAL_GET_INT_OR_DEFAULT_METHOD_REFERENCE = ImmutableMethodReference(
"Landroid/provider/Settings\$Global;",
"getInt",
listOf("Landroid/content/ContentResolver;", "Ljava/lang/String;", "I"),
"I"
)
private fun MethodReference.anyMethodSignatureMatches(vararg anyOf: MethodReference): Boolean {
return anyOf.any {
MethodUtil.methodSignaturesMatch(it, this)
}
}
@Suppress("unused")
val hideAdbStatusPatch = bytecodePatch(
name = "Hide ADB status",
description = "Hides enabled development settings and/or ADB.",
use = false,
) {
extendWith("extensions/all/misc/adb/hide-adb.rve")
dependsOn(
transformInstructionsPatch(
filterMap = filterMap@{ classDef, method, instruction, instructionIndex ->
val reference = instruction
.takeIf { it.opcode == Opcode.INVOKE_STATIC }
?.getReference<MethodReference>()
?.takeIf {
it.anyMethodSignatureMatches(it,
SETTINGS_GLOBAL_GET_INT_OR_THROW_METHOD_REFERENCE,
SETTINGS_GLOBAL_GET_INT_OR_DEFAULT_METHOD_REFERENCE
)
}
?: return@filterMap null
Triple(instruction as Instruction35c, instructionIndex, reference.parameterTypes)
},
transform = { method, entry ->
val (instruction, index, parameterTypes) = entry
val parameterString = parameterTypes.joinToString(separator = "")
val registerString = when (parameterTypes.size) {
2 -> "v${instruction.registerC}, v${instruction.registerD}"
else -> "v${instruction.registerC}, v${instruction.registerD}, v${instruction.registerE}"
}
method.replaceInstruction(
index,
"invoke-static { $registerString }, $EXTENSION_CLASS_DESCRIPTOR->getInt($parameterString)I"
)
}
)
)
}

View File

@@ -6,7 +6,7 @@ import app.revanced.patches.all.misc.transformation.filterMapInstruction35c
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
private const val EXTENSION_CLASS_DESCRIPTOR_PREFIX = private const val EXTENSION_CLASS_DESCRIPTOR_PREFIX =
"Lapp/revanced/extension/all/connectivity/wifi/spoof/SpoofWifiPatch" "Lapp/revanced/extension/all/misc/connectivity/wifi/spoof/SpoofWifiPatch"
private const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;" private const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;"

View File

@@ -25,7 +25,7 @@ private val removeCaptureRestrictionResourcePatch = resourcePatch(
} }
private const val EXTENSION_CLASS_DESCRIPTOR_PREFIX = private const val EXTENSION_CLASS_DESCRIPTOR_PREFIX =
"Lapp/revanced/extension/all/screencapture/removerestriction/RemoveScreenCaptureRestrictionPatch" "Lapp/revanced/extension/all/misc/screencapture/removerestriction/RemoveScreenCaptureRestrictionPatch"
private const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;" private const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;"
@Suppress("unused") @Suppress("unused")

View File

@@ -10,7 +10,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c
import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.FieldReference
private const val EXTENSION_CLASS_DESCRIPTOR_PREFIX = private const val EXTENSION_CLASS_DESCRIPTOR_PREFIX =
"Lapp/revanced/extension/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch" "Lapp/revanced/extension/all/misc/screenshot/removerestriction/RemoveScreenshotRestrictionPatch"
private const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;" private const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;"
@Suppress("unused") @Suppress("unused")

View File

@@ -12,7 +12,7 @@ val dynamicColorPatch = resourcePatch(
) { ) {
compatibleWith( compatibleWith(
"com.twitter.android"( "com.twitter.android"(
"10.84.0-release.0", "10.86.0-release.0",
"10.60.0-release.0", "10.60.0-release.0",
"10.48.0-release.0" "10.48.0-release.0"
) )

View File

@@ -13,8 +13,8 @@ fun hookPatch(
compatibleWith( compatibleWith(
"com.twitter.android"( "com.twitter.android"(
// 10.85+ uses Pairip and requires additional changes to work. // Only v10.85 uses Pairip and requires additional changes to work.
"10.84.0-release.0", "10.86.0-release.0",
// Confirmed to not show reply ads. Slightly newer versions may also work. // Confirmed to not show reply ads. Slightly newer versions may also work.
"10.60.0-release.0", "10.60.0-release.0",
"10.48.0-release.0" "10.48.0-release.0"

View File

@@ -39,7 +39,7 @@ val changeLinkSharingDomainPatch = bytecodePatch(
compatibleWith( compatibleWith(
"com.twitter.android"( "com.twitter.android"(
"10.84.0-release.0", "10.86.0-release.0",
"10.60.0-release.0", "10.60.0-release.0",
"10.48.0-release.0" "10.48.0-release.0"
) )

View File

@@ -10,7 +10,7 @@ val sanitizeSharingLinksPatch = bytecodePatch(
) { ) {
compatibleWith( compatibleWith(
"com.twitter.android"( "com.twitter.android"(
"10.84.0-release.0", "10.86.0-release.0",
"10.60.0-release.0", "10.60.0-release.0",
"10.48.0-release.0" "10.48.0-release.0"
) )

View File

@@ -84,7 +84,8 @@ val hideAdsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -31,7 +31,8 @@ val hideGetPremiumPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -29,7 +29,8 @@ val videoAdsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -59,7 +59,8 @@ val copyVideoUrlPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -30,7 +30,8 @@ val removeViewerDiscretionDialogPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
val extensionMethodDescriptor = val extensionMethodDescriptor =

View File

@@ -74,7 +74,8 @@ val downloadsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -10,10 +10,15 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.util.findFreeRegister
import app.revanced.util.indexOfFirstInstructionOrThrow
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.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/SeekbarTappingPatch;"
val enableSeekbarTappingPatch = bytecodePatch( val enableSeekbarTappingPatch = bytecodePatch(
description = "Adds an option to enable tap to seek on the seekbar of the video player.", description = "Adds an option to enable tap to seek on the seekbar of the video player.",
) { ) {
@@ -31,39 +36,37 @@ val enableSeekbarTappingPatch = bytecodePatch(
) )
// Find the required methods to tap the seekbar. // Find the required methods to tap the seekbar.
val patternMatch = onTouchEventHandlerFingerprint.patternMatch!! val seekbarTappingMethods = onTouchEventHandlerFingerprint.let {
fun getMethodReference(index: Int) = it.method.getInstruction<ReferenceInstruction>(index)
.reference as MethodReference
fun getReference(index: Int) = onTouchEventHandlerFingerprint.method.getInstruction<ReferenceInstruction>(index) listOf(
.reference as MethodReference getMethodReference(it.patternMatch!!.startIndex),
getMethodReference(it.patternMatch!!.endIndex)
val seekbarTappingMethods = buildMap { )
put("N", getReference(patternMatch.startIndex))
put("O", getReference(patternMatch.endIndex))
} }
val insertIndex = seekbarTappingFingerprint.patternMatch!!.endIndex - 1
seekbarTappingFingerprint.method.apply { seekbarTappingFingerprint.method.apply {
val thisInstanceRegister = getInstruction<Instruction35c>(insertIndex - 1).registerC val pointIndex = indexOfNewPointInstruction(this)
val invokeIndex = indexOfFirstInstructionOrThrow(pointIndex, Opcode.INVOKE_VIRTUAL)
val insertIndex = invokeIndex + 1
val freeRegister = 0 val thisInstanceRegister = getInstruction<FiveRegisterInstruction>(invokeIndex).registerC
val xAxisRegister = 2 val xAxisRegister = this.getInstruction<FiveRegisterInstruction>(pointIndex).registerD
val freeRegister = findFreeRegister(insertIndex, thisInstanceRegister, xAxisRegister)
val oMethod = seekbarTappingMethods["O"]!! val oMethod = seekbarTappingMethods[0]
val nMethod = seekbarTappingMethods["N"]!! val nMethod = seekbarTappingMethods[1]
fun MethodReference.toInvokeInstructionString() =
"invoke-virtual { v$thisInstanceRegister, v$xAxisRegister }, $this"
addInstructionsWithLabels( addInstructionsWithLabels(
insertIndex, insertIndex,
""" """
invoke-static { }, Lapp/revanced/extension/youtube/patches/SeekbarTappingPatch;->seekbarTappingEnabled()Z invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->seekbarTappingEnabled()Z
move-result v$freeRegister move-result v$freeRegister
if-eqz v$freeRegister, :disabled if-eqz v$freeRegister, :disabled
${oMethod.toInvokeInstructionString()} invoke-virtual { v$thisInstanceRegister, v$xAxisRegister }, $oMethod
${nMethod.toInvokeInstructionString()} invoke-virtual { v$thisInstanceRegister, v$xAxisRegister }, $nMethod
""", """,
ExternalLabel("disabled", getInstruction(insertIndex)), ExternalLabel("disabled", getInstruction(insertIndex)),
) )
} }

View File

@@ -1,11 +1,15 @@
package app.revanced.patches.youtube.interaction.seekbar package app.revanced.patches.youtube.interaction.seekbar
import app.revanced.patcher.fingerprint import app.revanced.patcher.fingerprint
import app.revanced.util.containsLiteralInstruction
import app.revanced.util.getReference import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.indexOfFirstInstructionReversed
import app.revanced.util.literal import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.iface.reference.StringReference import com.android.tools.smali.dexlib2.iface.reference.StringReference
internal val swipingUpGestureParentFingerprint = fingerprint { internal val swipingUpGestureParentFingerprint = fingerprint {
@@ -101,14 +105,17 @@ internal val seekbarTappingFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("Z") returns("Z")
parameters("L") parameters("L")
opcodes( custom { method, _ ->
Opcode.IPUT_OBJECT, method.name == "onTouchEvent"
Opcode.INVOKE_VIRTUAL, && method.containsLiteralInstruction(Integer.MAX_VALUE.toLong())
// Insert seekbar tapping instructions here. && indexOfNewPointInstruction(method) >= 0
Opcode.RETURN, }
Opcode.INVOKE_VIRTUAL, }
)
literal { Integer.MAX_VALUE.toLong() } internal fun indexOfNewPointInstruction(method: Method) = method.indexOfFirstInstructionReversed {
val reference = getReference<MethodReference>()
reference?.definingClass == "Landroid/graphics/Point;"
&& reference.name == "<init>"
} }
internal val slideToSeekFingerprint = fingerprint { internal val slideToSeekFingerprint = fingerprint {

View File

@@ -26,6 +26,7 @@ val seekbarPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
"20.12.46",
) )
) )
} }

View File

@@ -87,7 +87,8 @@ val swipeControlsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -8,7 +8,9 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.patches.youtube.shared.subtitleButtonControllerFingerprint
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/DisableAutoCaptionsPatch;"
val autoCaptionsPatch = bytecodePatch( val autoCaptionsPatch = bytecodePatch(
name = "Disable auto captions", name = "Disable auto captions",
@@ -28,42 +30,41 @@ val autoCaptionsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {
addResources("youtube", "layout.autocaptions.autoCaptionsPatch") addResources("youtube", "layout.autocaptions.autoCaptionsPatch")
PreferenceScreen.PLAYER.addPreferences( PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_auto_captions"), SwitchPreference("revanced_disable_auto_captions"),
)
subtitleTrackFingerprint.method.addInstructions(
0,
"""
invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->disableAutoCaptions()Z
move-result v0
if-eqz v0, :auto_captions_enabled
const/4 v0, 0x1
return v0
:auto_captions_enabled
nop
"""
) )
mapOf( mapOf(
startVideoInformerFingerprint to 0, startVideoInformerFingerprint to 0,
subtitleButtonControllerFingerprint to 1, storyboardRendererDecoderRecommendedLevelFingerprint to 1
).forEach { (fingerprint, enabled) -> ).forEach { (fingerprint, enabled) ->
fingerprint.method.addInstructions( fingerprint.method.addInstructions(
0, 0,
""" """
const/4 v0, 0x$enabled const/4 v0, 0x$enabled
sput-boolean v0, Lapp/revanced/extension/youtube/patches/DisableAutoCaptionsPatch;->captionsButtonDisabled:Z invoke-static { v0 }, $EXTENSION_CLASS_DESCRIPTOR->setCaptionsButtonStatus(Z)V
""", """
) )
} }
subtitleTrackFingerprint.method.addInstructions(
0,
"""
invoke-static {}, Lapp/revanced/extension/youtube/patches/DisableAutoCaptionsPatch;->autoCaptionsEnabled()Z
move-result v0
if-eqz v0, :auto_captions_enabled
sget-boolean v0, Lapp/revanced/extension/youtube/patches/DisableAutoCaptionsPatch;->captionsButtonDisabled:Z
if-nez v0, :auto_captions_enabled
const/4 v0, 0x1
return v0
:auto_captions_enabled
nop
""",
)
} }
} }

View File

@@ -14,6 +14,13 @@ internal val startVideoInformerFingerprint = fingerprint {
strings("pc") strings("pc")
} }
internal val storyboardRendererDecoderRecommendedLevelFingerprint = fingerprint {
returns("V")
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
parameters("L")
strings("#-1#")
}
internal val subtitleTrackFingerprint = fingerprint { internal val subtitleTrackFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("Z") returns("Z")
@@ -28,6 +35,6 @@ internal val subtitleTrackFingerprint = fingerprint {
) )
strings("DISABLE_CAPTIONS_OPTION") strings("DISABLE_CAPTIONS_OPTION")
custom { _, classDef -> custom { _, classDef ->
classDef.endsWith("SubtitleTrack;") classDef.endsWith("/SubtitleTrack;")
} }
} }

View File

@@ -49,7 +49,8 @@ val customBrandingPatch = resourcePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
val appName by stringOption( val appName by stringOption(

View File

@@ -47,6 +47,7 @@ val changeHeaderPatch = resourcePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
"20.12.46",
) )
) )

View File

@@ -28,7 +28,8 @@ val hideButtonsPatch = resourcePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -46,7 +46,8 @@ val navigationButtonsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -60,7 +60,8 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -39,7 +39,8 @@ val changeFormFactorPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -65,7 +65,8 @@ val hideEndscreenCardsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -37,7 +37,8 @@ val hideEndScreenSuggestedVideoPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -35,7 +35,8 @@ val disableFullscreenAmbientModePatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -1,6 +1,7 @@
package app.revanced.patches.youtube.layout.hide.general package app.revanced.patches.youtube.layout.hide.general
import app.revanced.patcher.fingerprint import app.revanced.patcher.fingerprint
import app.revanced.patches.youtube.layout.searchbar.wideSearchbarLayoutFingerprint
import app.revanced.util.literal import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@@ -16,9 +17,22 @@ internal val hideShowMoreButtonFingerprint = fingerprint {
} }
/** /**
* 20.07+ * 20.12+
*/ */
internal val parseElementFromBufferFingerprint = fingerprint { internal val parseElementFromBufferFingerprint = fingerprint {
parameters("L", "L", "[B", "L", "L")
opcodes(
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
)
strings("Failed to parse Element") // String is a partial match.
}
/**
* 20.07+
*/
internal val parseElementFromBufferLegacy2007Fingerprint = fingerprint {
parameters("L", "L", "[B", "L", "L") parameters("L", "L", "[B", "L", "L")
opcodes( opcodes(
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
@@ -29,7 +43,10 @@ internal val parseElementFromBufferFingerprint = fingerprint {
strings("Failed to parse Element") // String is a partial match. strings("Failed to parse Element") // String is a partial match.
} }
internal val parseElementFromBufferLegacyFingerprint = fingerprint { /**
* 19.01 - 20.06
*/
internal val parseElementFromBufferLegacy1901Fingerprint = fingerprint {
parameters("L", "L", "[B", "L", "L") parameters("L", "L", "[B", "L", "L")
opcodes( opcodes(
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
@@ -51,6 +68,9 @@ internal val showWatermarkFingerprint = fingerprint {
parameters("L", "L") parameters("L", "L")
} }
/**
* Matches same method as [wideSearchbarLayoutFingerprint].
*/
internal val yoodlesImageViewFingerprint = fingerprint { internal val yoodlesImageViewFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("Landroid/view/View;") returns("Landroid/view/View;")

View File

@@ -21,6 +21,7 @@ import app.revanced.patches.youtube.misc.litho.filter.addLithoFilter
import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch
import app.revanced.patches.youtube.misc.navigation.navigationBarHookPatch import app.revanced.patches.youtube.misc.navigation.navigationBarHookPatch
import app.revanced.patches.youtube.misc.playservice.is_20_07_or_greater import app.revanced.patches.youtube.misc.playservice.is_20_07_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_09_or_greater
import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.util.findFreeRegister import app.revanced.util.findFreeRegister
@@ -43,14 +44,12 @@ var crowdfundingBoxId = -1L
private set private set
var youTubeLogo = -1L var youTubeLogo = -1L
private set private set
var filterBarHeightId = -1L var filterBarHeightId = -1L
private set private set
var relatedChipCloudMarginId = -1L var relatedChipCloudMarginId = -1L
private set private set
var barContainerHeightId = -1L var barContainerHeightId = -1L
private set private set
var fabButtonId = -1L var fabButtonId = -1L
private set private set
@@ -132,7 +131,8 @@ val hideLayoutComponentsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {
@@ -247,8 +247,9 @@ val hideLayoutComponentsPatch = bytecodePatch(
// region Mix playlists // region Mix playlists
(if (is_20_07_or_greater) parseElementFromBufferFingerprint (if (is_20_09_or_greater) parseElementFromBufferFingerprint
else parseElementFromBufferLegacyFingerprint).let { else if (is_20_07_or_greater) parseElementFromBufferLegacy2007Fingerprint
else parseElementFromBufferLegacy1901Fingerprint).let {
it.method.apply { it.method.apply {
val byteArrayParameter = "p3" val byteArrayParameter = "p3"
val startIndex = it.patternMatch!!.startIndex val startIndex = it.patternMatch!!.startIndex

View File

@@ -63,7 +63,8 @@ val hideInfoCardsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -30,7 +30,8 @@ val hidePlayerFlyoutMenuPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -35,7 +35,8 @@ val disableRollingNumberAnimationPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -178,7 +178,8 @@ val hideShortsComponentsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
hideShortsAppShortcutOption() hideShortsAppShortcutOption()

View File

@@ -1,24 +1,16 @@
package app.revanced.patches.youtube.layout.hide.time package app.revanced.patches.youtube.layout.hide.time
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import app.revanced.patcher.fingerprint
internal val timeCounterFingerprint = fingerprint( internal val timeCounterFingerprint = fingerprint {
fuzzyPatternScanThreshold = 1,
) {
returns("V")
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V")
parameters() parameters()
opcodes( opcodes(
Opcode.SUB_LONG_2ADDR, Opcode.SUB_LONG_2ADDR,
Opcode.IGET_WIDE, Opcode.IGET_WIDE,
Opcode.SUB_LONG_2ADDR,
Opcode.IGET_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_WIDE,
Opcode.IGET_WIDE,
Opcode.SUB_LONG_2ADDR Opcode.SUB_LONG_2ADDR
) )
} }

View File

@@ -27,7 +27,8 @@ val hideTimestampPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -30,6 +30,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstructio
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction 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.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference 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.android.tools.smali.dexlib2.iface.reference.TypeReference
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
@@ -172,7 +173,8 @@ val miniplayerPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {
@@ -346,7 +348,12 @@ val miniplayerPatch = bytecodePatch(
// endregion // endregion
// region Legacy tablet miniplayer hooks. // region Legacy tablet miniplayer hooks.
val appNameStringIndex = miniplayerOverrideFingerprint.stringMatches!!.first().index + 2 val appNameStringIndex = miniplayerOverrideFingerprint.let {
it.method.indexOfFirstInstructionOrThrow(it.stringMatches!!.first().index) {
val reference = getReference<MethodReference>()
reference?.parameterTypes?.firstOrNull() == "Landroid/content/Context;"
}
}
navigate(miniplayerOverrideFingerprint.originalMethod).to(appNameStringIndex).stop().apply { navigate(miniplayerOverrideFingerprint.originalMethod).to(appNameStringIndex).stop().apply {
findReturnIndicesReversed().forEach { index -> insertLegacyTabletMiniplayerOverride(index) } findReturnIndicesReversed().forEach { index -> insertLegacyTabletMiniplayerOverride(index) }
} }

View File

@@ -27,7 +27,8 @@ val playerPopupPanelsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -18,7 +18,8 @@ val playerControlsBackgroundPatch = resourcePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -27,6 +27,7 @@ internal val exitFullscreenPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
"20.12.46",
) )
) )

View File

@@ -27,6 +27,7 @@ val openVideosFullscreenPatch = bytecodePatch(
"com.google.android.youtube"( "com.google.android.youtube"(
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
"20.12.46",
) )
) )

View File

@@ -58,7 +58,8 @@ val customPlayerOverlayOpacityPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -1,6 +1,7 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike package app.revanced.patches.youtube.layout.returnyoutubedislike
import app.revanced.patcher.fingerprint import app.revanced.patcher.fingerprint
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@@ -121,3 +122,12 @@ internal val textComponentLookupFingerprint = fingerprint {
parameters("L") parameters("L")
strings("") strings("")
} }
internal const val LITHO_NEW_TEXT_COMPONENT_FEATURE_FLAG = 45675738L
internal val textComponentFeatureFlagFingerprint = fingerprint {
accessFlags(AccessFlags.FINAL)
returns("Z")
parameters()
literal { LITHO_NEW_TEXT_COMPONENT_FEATURE_FLAG }
}

View File

@@ -12,6 +12,7 @@ import app.revanced.patches.youtube.misc.litho.filter.addLithoFilter
import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch import app.revanced.patches.youtube.misc.litho.filter.lithoFilterPatch
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
import app.revanced.patches.youtube.misc.playservice.is_19_33_or_greater import app.revanced.patches.youtube.misc.playservice.is_19_33_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_07_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_10_or_greater import app.revanced.patches.youtube.misc.playservice.is_20_10_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.addSettingPreference import app.revanced.patches.youtube.misc.settings.addSettingPreference
@@ -59,7 +60,8 @@ val returnYouTubeDislikePatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {
@@ -174,6 +176,14 @@ val returnYouTubeDislikePatch = bytecodePatch(
// Filter that parses the video id from the UI // Filter that parses the video id from the UI
addLithoFilter(FILTER_CLASS_DESCRIPTOR) addLithoFilter(FILTER_CLASS_DESCRIPTOR)
if (is_20_07_or_greater) {
// Turn off a/b flag that enables new code for creating litho spans.
// If enabled then the litho text span hook is never called.
// Target code is very obfuscated and exactly what the code does is not clear.
// Return late so debug patch logs if the flag is enabled.
textComponentFeatureFlagFingerprint.method.returnLate(false)
}
// Player response video id is needed to search for the video ids in Shorts litho components. // Player response video id is needed to search for the video ids in Shorts litho components.
hookPlayerResponseVideoId("$FILTER_CLASS_DESCRIPTOR->newPlayerResponseVideoId(Ljava/lang/String;Z)V") hookPlayerResponseVideoId("$FILTER_CLASS_DESCRIPTOR->newPlayerResponseVideoId(Ljava/lang/String;Z)V")

View File

@@ -1,31 +1,27 @@
package app.revanced.patches.youtube.layout.searchbar package app.revanced.patches.youtube.layout.searchbar
import app.revanced.patcher.fingerprint import app.revanced.patcher.fingerprint
import app.revanced.patches.youtube.layout.hide.general.yoodlesImageViewFingerprint
import app.revanced.util.containsLiteralInstruction
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal val createSearchSuggestionsFingerprint = fingerprint {
opcodes(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.CONST_4,
)
strings("ss_rds")
}
internal val setWordmarkHeaderFingerprint = fingerprint { internal val setWordmarkHeaderFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V") returns("V")
parameters("Landroid/widget/ImageView;") parameters("Landroid/widget/ImageView;")
opcodes( custom { methodDef, _ ->
Opcode.IGET_OBJECT, methodDef.containsLiteralInstruction(ytPremiumWordmarkHeaderId) &&
Opcode.INVOKE_STATIC, methodDef.containsLiteralInstruction(ytWordmarkHeaderId)
Opcode.MOVE_RESULT, }
Opcode.IF_NEZ, }
Opcode.IGET_BOOLEAN,
Opcode.IF_EQZ, /**
Opcode.IGET_OBJECT, * Matches the same method as [yoodlesImageViewFingerprint].
Opcode.CONST, */
null, // invoke-static or invoke-virtual. internal val wideSearchbarLayoutFingerprint = fingerprint {
) accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("Landroid/view/View;")
parameters("L", "L")
literal { actionBarRingoId }
} }

View File

@@ -1,30 +1,67 @@
package app.revanced.patches.youtube.layout.searchbar package app.revanced.patches.youtube.layout.searchbar
import app.revanced.patcher.Fingerprint import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.patch.resourcePatch
import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.mapping.get
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
import app.revanced.patches.shared.misc.mapping.resourceMappings
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.util.addInstructionsAtControlFlowLabel
import app.revanced.util.findInstructionIndicesReversedOrThrow
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
private const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/WideSearchbarPatch;" "Lapp/revanced/extension/youtube/patches/WideSearchbarPatch;"
internal var ytWordmarkHeaderId = -1L
private set
internal var ytPremiumWordmarkHeaderId = -1L
private set
internal var actionBarRingoId = -1L
private set
private val wideSearchbarResourcePatch = resourcePatch {
dependsOn(resourceMappingPatch)
execute {
ytWordmarkHeaderId = resourceMappings[
"attr",
"ytWordmarkHeader",
]
ytPremiumWordmarkHeaderId = resourceMappings[
"attr",
"ytPremiumWordmarkHeader",
]
actionBarRingoId = resourceMappings[
"layout",
"action_bar_ringo",
]
}
}
val wideSearchbarPatch = bytecodePatch( val wideSearchbarPatch = bytecodePatch(
name = "Wide search bar", name = "Wide search bar",
description = "Adds an option to replace the search icon with a wide search bar. This will hide the YouTube logo when active.", description = "Adds an option to replace the search icon with a wide search bar. " +
"This will hide the YouTube logo when active.",
) { ) {
dependsOn( dependsOn(
sharedExtensionPatch, sharedExtensionPatch,
settingsPatch, settingsPatch,
addResourcesPatch, addResourcesPatch,
wideSearchbarResourcePatch,
) )
compatibleWith( compatibleWith(
@@ -35,7 +72,8 @@ val wideSearchbarPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {
@@ -45,37 +83,45 @@ val wideSearchbarPatch = bytecodePatch(
SwitchPreference("revanced_wide_searchbar"), SwitchPreference("revanced_wide_searchbar"),
) )
/** setWordmarkHeaderFingerprint.let {
* Navigate a fingerprints method at a given index mutably. // Navigate to the method that checks if the YT logo is shown beside the search bar.
* val shouldShowLogoMethod = with(it.originalMethod) {
* @param index The index to navigate to. val invokeStaticIndex = indexOfFirstInstructionOrThrow {
* @param from The fingerprint to navigate the method on. opcode == Opcode.INVOKE_STATIC &&
* @return The [MutableMethod] which was navigated on. getReference<MethodReference>()?.returnType == "Z"
*/ }
fun BytecodePatchContext.walkMutable(index: Int, from: Fingerprint) = navigate(this).to(invokeStaticIndex).stop()
navigate(from.originalMethod).to(index).stop() }
/** shouldShowLogoMethod.apply {
* Injects instructions required for certain methods. findInstructionIndicesReversedOrThrow(Opcode.RETURN).forEach { index ->
*/ val register = getInstruction<OneRegisterInstruction>(index).registerA
fun MutableMethod.injectSearchBarHook() {
val insertIndex = implementation!!.instructions.size - 1
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions( addInstructionsAtControlFlowLabel(
insertIndex, index,
""" """
invoke-static {v$insertRegister}, $EXTENSION_CLASS_DESCRIPTOR->enableWideSearchbar(Z)Z invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->enableWideSearchbar(Z)Z
move-result v$insertRegister move-result v$register
""", """
) )
}
}
} }
mapOf( // Fix missing left padding when using wide searchbar.
setWordmarkHeaderFingerprint to 1, wideSearchbarLayoutFingerprint.method.apply {
createSearchSuggestionsFingerprint to createSearchSuggestionsFingerprint.patternMatch!!.startIndex, findInstructionIndicesReversedOrThrow {
).forEach { (fingerprint, callIndex) -> val reference = getReference<MethodReference>()
walkMutable(callIndex, fingerprint).injectSearchBarHook() reference?.definingClass == "Landroid/view/LayoutInflater;"
&& reference.name == "inflate"
}.forEach { inflateIndex ->
val register = getInstruction<OneRegisterInstruction>(inflateIndex + 1).registerA
addInstruction(
inflateIndex + 2,
"invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->setActionBar(Landroid/view/View;)V"
)
}
} }
} }
} }

View File

@@ -39,7 +39,8 @@ val shortsAutoplayPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -47,7 +47,8 @@ val openShortsInRegularPlayerPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -20,12 +20,6 @@ internal val appendTimeFingerprint = fingerprint {
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID,
) )
} }

View File

@@ -114,7 +114,8 @@ val sponsorBlockPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -64,7 +64,8 @@ val spoofAppVersionPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -7,6 +7,9 @@ import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.ListPreference import app.revanced.patches.shared.misc.settings.preference.ListPreference
import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
@@ -35,17 +38,26 @@ val changeStartPagePatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {
addResources("youtube", "layout.startpage.changeStartPagePatch") addResources("youtube", "layout.startpage.changeStartPagePatch")
PreferenceScreen.GENERAL_LAYOUT.addPreferences( PreferenceScreen.GENERAL_LAYOUT.addPreferences(
ListPreference( PreferenceCategory(
key = "revanced_change_start_page", titleKey = null,
summaryKey = null, sorting = Sorting.UNSORTED,
), tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory",
preferences = setOf(
ListPreference(
key = "revanced_change_start_page",
summaryKey = null,
),
SwitchPreference("revanced_change_start_page_always")
)
)
) )
// Hook browseId. // Hook browseId.

View File

@@ -40,7 +40,8 @@ val disableResumingShortsOnStartupPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -10,13 +10,6 @@ internal val lithoThemeFingerprint = fingerprint {
returns("V") returns("V")
parameters("Landroid/graphics/Rect;") parameters("Landroid/graphics/Rect;")
opcodes( opcodes(
Opcode.APUT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IGET_OBJECT,
Opcode.SGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IPUT_OBJECT,
Opcode.IGET, Opcode.IGET,
Opcode.IF_EQZ, Opcode.IF_EQZ,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,

View File

@@ -223,7 +223,8 @@ val themePatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -39,7 +39,8 @@ val alternativeThumbnailsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -33,7 +33,8 @@ val bypassImageRegionRestrictionsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -29,7 +29,8 @@ val announcementsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -30,7 +30,8 @@ val autoRepeatPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -57,7 +57,8 @@ val backgroundPlaybackPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -40,7 +40,8 @@ val enableDebuggingPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -30,7 +30,8 @@ val spoofDeviceDimensionsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -27,7 +27,8 @@ val checkWatchHistoryDomainNameResolutionPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -9,9 +9,7 @@ internal val onBackPressedFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
opcodes(Opcode.RETURN_VOID) opcodes(Opcode.RETURN_VOID)
custom { method, classDef -> custom { method, classDef ->
method.name == "onBackPressed" && method.name == "onBackPressed" && classDef.endsWith("MainActivity;")
// Old versions of YouTube called this class "WatchWhileActivity" instead.
(classDef.endsWith("MainActivity;") || classDef.endsWith("WatchWhileActivity;"))
} }
} }
@@ -27,6 +25,9 @@ internal val scrollPositionFingerprint = fingerprint {
strings("scroll_position") strings("scroll_position")
} }
/**
* Resolves using class found in [recyclerViewTopScrollingParentFingerprint].
*/
internal val recyclerViewTopScrollingFingerprint = fingerprint { internal val recyclerViewTopScrollingFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V") returns("V")

View File

@@ -41,7 +41,8 @@ val gmsCoreSupportPatch = gmsCoreSupportPatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
} }

View File

@@ -38,7 +38,8 @@ val bypassURLRedirectsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -47,7 +47,8 @@ val openLinksExternallyPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -47,11 +47,7 @@ internal val mainActivityOnBackPressedFingerprint = fingerprint {
returns("V") returns("V")
parameters() parameters()
custom { method, classDef -> custom { method, classDef ->
val matchesClass = classDef.endsWith("MainActivity;") || method.name == "onBackPressed" && classDef.endsWith("MainActivity;")
// Old versions of YouTube called this class "WatchWhileActivity" instead.
classDef.endsWith("WatchWhileActivity;")
matchesClass && method.name == "onBackPressed"
} }
} }

View File

@@ -58,6 +58,10 @@ var is_20_09_or_greater = false
private set private set
var is_20_10_or_greater = false var is_20_10_or_greater = false
private set private set
var is_20_14_or_greater = false
private set
var is_20_15_or_greater = false
private set
val versionCheckPatch = resourcePatch( val versionCheckPatch = resourcePatch(
description = "Uses the Play Store service version to find the major/minor version of the YouTube target app.", description = "Uses the Play Store service version to find the major/minor version of the YouTube target app.",
@@ -98,5 +102,7 @@ val versionCheckPatch = resourcePatch(
is_20_07_or_greater = 250805000 <= playStoreServicesVersion is_20_07_or_greater = 250805000 <= playStoreServicesVersion
is_20_09_or_greater = 251006000 <= playStoreServicesVersion is_20_09_or_greater = 251006000 <= playStoreServicesVersion
is_20_10_or_greater = 251105000 <= playStoreServicesVersion is_20_10_or_greater = 251105000 <= playStoreServicesVersion
is_20_14_or_greater = 251505000 <= playStoreServicesVersion
is_20_15_or_greater = 251605000 <= playStoreServicesVersion
} }
} }

View File

@@ -36,7 +36,8 @@ val removeTrackingQueryParameterPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -9,6 +9,7 @@ import app.revanced.patches.shared.misc.spoof.spoofVideoStreamsPatch
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_03_or_greater import app.revanced.patches.youtube.misc.playservice.is_20_03_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_10_or_greater import app.revanced.patches.youtube.misc.playservice.is_20_10_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_14_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
@@ -22,7 +23,8 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
dependsOn( dependsOn(
@@ -33,7 +35,8 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
}, { }, {
is_19_34_or_greater is_19_34_or_greater
}, { }, {
is_20_10_or_greater // In 20.14 the flag was merged with 20.03 start playback flag.
is_20_10_or_greater && !is_20_14_or_greater
}, { }, {
is_20_03_or_greater is_20_03_or_greater
}, { }, {

View File

@@ -27,7 +27,8 @@ val zoomHapticsPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -33,8 +33,7 @@ internal val mainActivityFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
parameters() parameters()
custom { _, classDef -> custom { _, classDef ->
// Old versions of YouTube called this class "WatchWhileActivity" instead. classDef.endsWith("MainActivity;")
classDef.endsWith("MainActivity;") || classDef.endsWith("WatchWhileActivity;")
} }
} }
@@ -42,12 +41,7 @@ internal val mainActivityOnCreateFingerprint = fingerprint {
returns("V") returns("V")
parameters("Landroid/os/Bundle;") parameters("Landroid/os/Bundle;")
custom { method, classDef -> custom { method, classDef ->
method.name == "onCreate" && method.name == "onCreate" && classDef.endsWith("MainActivity;")
(
classDef.endsWith("MainActivity;") ||
// Old versions of YouTube called this class "WatchWhileActivity" instead.
classDef.endsWith("WatchWhileActivity;")
)
} }
} }

View File

@@ -47,7 +47,8 @@ val forceOriginalAudioPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -34,7 +34,8 @@ val disableHdrPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
), "20.12.46",
)
) )
execute { execute {

View File

@@ -117,13 +117,6 @@ internal val playbackSpeedMenuSpeedChangedFingerprint = fingerprint {
returns("L") returns("L")
parameters("L") parameters("L")
opcodes( opcodes(
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET, Opcode.IGET,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.SGET_OBJECT, Opcode.SGET_OBJECT,

View File

@@ -5,9 +5,35 @@ import com.android.tools.smali.dexlib2.AccessFlags
import org.stringtemplate.v4.compiler.Bytecode.instructions import org.stringtemplate.v4.compiler.Bytecode.instructions
/** /**
* For targets 20.10 and later. * For targets 20.15 and later.
*/ */
internal val playerParameterBuilderFingerprint = fingerprint { internal val playerParameterBuilderFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("L")
parameters(
"Ljava/lang/String;", // VideoId.
"[B",
"Ljava/lang/String;", // Player parameters proto buffer.
"Ljava/lang/String;",
"I",
"Z",
"I",
"L",
"Ljava/util/Set;",
"Ljava/lang/String;",
"Ljava/lang/String;",
"L",
"Z", // Appears to indicate if the video id is being opened or is currently playing.
"Z",
"Z"
)
strings("psps")
}
/**
* For targets 20.10 to 20.14.
*/
internal val playerParameterBuilder2010Fingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("L") returns("L")
parameters( parameters(

View File

@@ -9,6 +9,7 @@ import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_19_23_or_greater import app.revanced.patches.youtube.misc.playservice.is_19_23_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_02_or_greater import app.revanced.patches.youtube.misc.playservice.is_20_02_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_10_or_greater import app.revanced.patches.youtube.misc.playservice.is_20_10_or_greater
import app.revanced.patches.youtube.misc.playservice.is_20_15_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
private val hooks = mutableSetOf<Hook>() private val hooks = mutableSetOf<Hook>()
@@ -39,9 +40,12 @@ val playerResponseMethodHookPatch = bytecodePatch {
execute { execute {
val fingerprint : Fingerprint val fingerprint : Fingerprint
if (is_20_10_or_greater) { if (is_20_15_or_greater) {
parameterIsShortAndOpeningOrPlaying = 13 parameterIsShortAndOpeningOrPlaying = 13
fingerprint = playerParameterBuilderFingerprint fingerprint = playerParameterBuilderFingerprint
} else if (is_20_10_or_greater) {
parameterIsShortAndOpeningOrPlaying = 13
fingerprint = playerParameterBuilder2010Fingerprint
} else if (is_20_02_or_greater) { } else if (is_20_02_or_greater) {
parameterIsShortAndOpeningOrPlaying = 12 parameterIsShortAndOpeningOrPlaying = 12
fingerprint = playerParameterBuilder2002Fingerprint fingerprint = playerParameterBuilder2002Fingerprint

View File

@@ -29,6 +29,7 @@ val videoQualityPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
"20.12.46",
) )
) )

View File

@@ -34,6 +34,7 @@ val playbackSpeedPatch = bytecodePatch(
"19.43.41", "19.43.41",
"19.47.53", "19.47.53",
"20.07.39", "20.07.39",
"20.12.46",
) )
) )

View File

@@ -698,29 +698,54 @@ fun BytecodePatchContext.forEachLiteralValueInstruction(
} }
/** /**
* Return the method early. * Overrides the first instruction of a method with a constant return value.
* None of the method code will ever execute.
*/ */
fun MutableMethod.returnEarly(bool: Boolean = false) { fun MutableMethod.returnEarly(overrideValue: Boolean = false) = overrideReturnValue(overrideValue, false)
/**
* Overrides all return statements with a constant value.
* All method code is executed the same as unpatched.
*
* @see returnEarly
*/
internal fun MutableMethod.returnLate(overrideValue: Boolean = false) = overrideReturnValue(overrideValue, true)
private fun MutableMethod.overrideReturnValue(bool: Boolean, returnLate: Boolean) {
val const = if (bool) "0x1" else "0x0" val const = if (bool) "0x1" else "0x0"
val stringInstructions = when (returnType.first()) { val instructions = when (returnType.first()) {
'L' -> 'L' -> {
""" """
const/4 v0, $const const/4 v0, $const
return-object v0 return-object v0
""" """
}
'V' -> "return-void" 'V' -> {
'I', 'Z' -> if (returnLate) throw IllegalArgumentException("Cannot return late for method of void type")
"return-void"
}
'I', 'Z' -> {
""" """
const/4 v0, $const const/4 v0, $const
return v0 return v0
""" """
}
else -> throw Exception("Return type is not supported: $this") else -> throw Exception("Return type is not supported: $this")
} }
addInstructions(0, stringInstructions) if (returnLate) {
findInstructionIndicesReversed {
opcode == RETURN || opcode == RETURN_OBJECT
}.forEach { index ->
addInstructionsAtControlFlowLabel(index, instructions)
}
} else {
addInstructions(0, instructions)
}
} }
/** /**

View File

@@ -479,9 +479,9 @@ Second \"item\" text"</string>
<string name="revanced_swipe_change_video_summary_off">لن يؤدي التمرير في وضع ملء الشاشة إلى التغيير للفيديو التالي/السابق</string> <string name="revanced_swipe_change_video_summary_off">لن يؤدي التمرير في وضع ملء الشاشة إلى التغيير للفيديو التالي/السابق</string>
</patch> </patch>
<patch id="layout.autocaptions.autoCaptionsPatch"> <patch id="layout.autocaptions.autoCaptionsPatch">
<string name="revanced_auto_captions_title">تعطيل التَّرْجَمَة التلقائية</string> <string name="revanced_disable_auto_captions_title">تعطيل التَّرْجَمَة التلقائية</string>
<string name="revanced_auto_captions_summary_on">تم تعطيل التَّرْجَمَة التلقائية</string> <string name="revanced_disable_auto_captions_summary_on">تم تعطيل التَّرْجَمَة التلقائية</string>
<string name="revanced_auto_captions_summary_off">تم تمكين التَّرْجَمَة التلقائية</string> <string name="revanced_disable_auto_captions_summary_off">تم تمكين التَّرْجَمَة التلقائية</string>
</patch> </patch>
<patch id="layout.buttons.action.hideButtonsPatch"> <patch id="layout.buttons.action.hideButtonsPatch">
<string name="revanced_hide_buttons_screen_title">أزرار الإجراء</string> <string name="revanced_hide_buttons_screen_title">أزرار الإجراء</string>
@@ -832,8 +832,8 @@ Second \"item\" text"</string>
<string name="revanced_ryd_compact_layout_summary_on">زر أعجبني مصمم لأدنى عرض</string> <string name="revanced_ryd_compact_layout_summary_on">زر أعجبني مصمم لأدنى عرض</string>
<string name="revanced_ryd_compact_layout_summary_off">زر أعجبني مصمم لأفضل مظهر</string> <string name="revanced_ryd_compact_layout_summary_off">زر أعجبني مصمم لأفضل مظهر</string>
<string name="revanced_ryd_estimated_like_title">عرض الإعجابات المقدرة</string> <string name="revanced_ryd_estimated_like_title">عرض الإعجابات المقدرة</string>
<string name="revanced_ryd_estimated_like_summary_on">يتم عرض الإعجابات المقدرة</string> <string name="revanced_ryd_estimated_like_summary_on">يتم عرض عدد تقديري للإعجابات في مقاطع الفيديو التي تم تعطيل الإعجابات فيها</string>
<string name="revanced_ryd_estimated_like_summary_off">تم إخفاء الإعجابات المقدرة</string> <string name="revanced_ryd_estimated_like_summary_off">لا يتم عرض عدد الإعجابات المقدرة</string>
<string name="revanced_ryd_toast_on_connection_error_title">عرض ملاحظة إذا كان API غير متاح</string> <string name="revanced_ryd_toast_on_connection_error_title">عرض ملاحظة إذا كان API غير متاح</string>
<string name="revanced_ryd_toast_on_connection_error_summary_on">يتم عرض الملاحظة في حالة عدم توفر Return YouTube Dislike</string> <string name="revanced_ryd_toast_on_connection_error_summary_on">يتم عرض الملاحظة في حالة عدم توفر Return YouTube Dislike</string>
<string name="revanced_ryd_toast_on_connection_error_summary_off">لا يتم عرض الملاحظة في حالة عدم توفر Return YouTube Dislike</string> <string name="revanced_ryd_toast_on_connection_error_summary_off">لا يتم عرض الملاحظة في حالة عدم توفر Return YouTube Dislike</string>
@@ -1107,7 +1107,7 @@ Second \"item\" text"</string>
<string name="revanced_spoof_app_version_target_entry_2">19.01.34 - استعادة أيقونات التنقل القديمة</string> <string name="revanced_spoof_app_version_target_entry_2">19.01.34 - استعادة أيقونات التنقل القديمة</string>
</patch> </patch>
<patch id="layout.startpage.changeStartPagePatch"> <patch id="layout.startpage.changeStartPagePatch">
<string name="revanced_change_start_page_title">تعيين صفحة البداية</string> <string name="revanced_change_start_page_title">تغيير صفحة البداية</string>
<string name="revanced_change_start_page_entry_default">الافتراضي</string> <string name="revanced_change_start_page_entry_default">الافتراضي</string>
<string name="revanced_change_start_page_entry_all_subscriptions">كلّ الاشتراكات</string> <string name="revanced_change_start_page_entry_all_subscriptions">كلّ الاشتراكات</string>
<string name="revanced_change_start_page_entry_browse">تصفح القنوات</string> <string name="revanced_change_start_page_entry_browse">تصفح القنوات</string>
@@ -1132,6 +1132,11 @@ Second \"item\" text"</string>
<string name="revanced_change_start_page_entry_virtual_reality">الواقع الافتراضي</string> <string name="revanced_change_start_page_entry_virtual_reality">الواقع الافتراضي</string>
<string name="revanced_change_start_page_entry_watch_later">شاهد لاحقًا</string> <string name="revanced_change_start_page_entry_watch_later">شاهد لاحقًا</string>
<string name="revanced_change_start_page_entry_your_clips">فيديوهاتك</string> <string name="revanced_change_start_page_entry_your_clips">فيديوهاتك</string>
<string name="revanced_change_start_page_always_title">تغيير الصفحة الرئيسية دائمًا</string>
<string name="revanced_change_start_page_always_summary_on">"يتم تغيير صفحة البداية دائمًا
قيود: قد لا يعمل استخدام زر الرجوع على شريط الأدوات"</string>
<string name="revanced_change_start_page_always_summary_off">يتم تغيير الصفحة الرئيسية فقط عند بدء تشغيل التطبيق</string>
</patch> </patch>
<patch id="layout.startupshortsreset.disableResumingShortsOnStartupPatch"> <patch id="layout.startupshortsreset.disableResumingShortsOnStartupPatch">
<string name="revanced_disable_resuming_shorts_player_title">تعطيل استئناف مشغل Shorts</string> <string name="revanced_disable_resuming_shorts_player_title">تعطيل استئناف مشغل Shorts</string>

Some files were not shown because too many files have changed in this diff Show More