feat(YouTube Music): Add Hide layout components patch (#6365)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
parent
156441d3cf
commit
71ce8230a9
43 changed files with 1114 additions and 952 deletions
|
|
@ -4,12 +4,12 @@ import static java.lang.Boolean.FALSE;
|
|||
import static java.lang.Boolean.TRUE;
|
||||
import static app.revanced.extension.shared.settings.Setting.parent;
|
||||
|
||||
import app.revanced.extension.shared.settings.BaseSettings;
|
||||
import app.revanced.extension.shared.settings.YouTubeAndMusicSettings;
|
||||
import app.revanced.extension.shared.settings.BooleanSetting;
|
||||
import app.revanced.extension.shared.settings.EnumSetting;
|
||||
import app.revanced.extension.shared.spoof.ClientType;
|
||||
|
||||
public class Settings extends BaseSettings {
|
||||
public class Settings extends YouTubeAndMusicSettings {
|
||||
|
||||
// Ads
|
||||
public static final BooleanSetting HIDE_VIDEO_ADS = new BooleanSetting("revanced_music_hide_video_ads", TRUE, true);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package app.revanced.extension.youtube.patches.components;
|
||||
package app.revanced.extension.shared.patches.components;
|
||||
|
||||
import static app.revanced.extension.shared.StringRef.str;
|
||||
|
||||
|
|
@ -15,13 +15,15 @@ import java.util.regex.Pattern;
|
|||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import app.revanced.extension.shared.ByteTrieSearch;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.StringFilterGroup;
|
||||
import app.revanced.extension.shared.settings.YouTubeAndMusicSettings;
|
||||
import app.revanced.extension.shared.patches.litho.Filter;
|
||||
|
||||
/**
|
||||
* Allows custom filtering using a path and optionally a proto buffer string.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
final class CustomFilter extends Filter {
|
||||
public final class CustomFilter extends Filter {
|
||||
|
||||
private static void showInvalidSyntaxToast(@NonNull String expression) {
|
||||
Utils.showToastLong(str("revanced_custom_filter_toast_invalid_syntax", expression));
|
||||
|
|
@ -45,7 +47,7 @@ final class CustomFilter extends Filter {
|
|||
@NonNull
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
static Collection<CustomFilterGroup> parseCustomFilterGroups() {
|
||||
String rawCustomFilterText = Settings.CUSTOM_FILTER_STRINGS.get();
|
||||
String rawCustomFilterText = YouTubeAndMusicSettings.CUSTOM_FILTER_STRINGS.get();
|
||||
if (rawCustomFilterText.isBlank()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
|
@ -100,7 +102,7 @@ final class CustomFilter extends Filter {
|
|||
ByteTrieSearch bufferSearch;
|
||||
|
||||
CustomFilterGroup(boolean startsWith, @NonNull String path) {
|
||||
super(Settings.CUSTOM_FILTER, path);
|
||||
super(YouTubeAndMusicSettings.CUSTOM_FILTER, path);
|
||||
this.startsWith = startsWith;
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +147,7 @@ final class CustomFilter extends Filter {
|
|||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
public boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
// All callbacks are custom filter groups.
|
||||
CustomFilterGroup custom = (CustomFilterGroup) matchedGroup;
|
||||
|
|
@ -159,4 +161,4 @@ final class CustomFilter extends Filter {
|
|||
|
||||
return custom.bufferSearch.matches(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,12 @@
|
|||
package app.revanced.extension.youtube.patches.components;
|
||||
package app.revanced.extension.shared.patches.litho;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.StringFilterGroup;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.ByteArrayFilterGroup;
|
||||
|
||||
/**
|
||||
* Filters litho based components.
|
||||
*
|
||||
|
|
@ -14,11 +17,11 @@ import java.util.List;
|
|||
* either an identifier or a path.
|
||||
* Then inside {@link #isFiltered(String, String, byte[], StringFilterGroup, FilterContentType, int)}
|
||||
* search for the buffer content using either a {@link ByteArrayFilterGroup} (if searching for 1 pattern)
|
||||
* or a {@link ByteArrayFilterGroupList} (if searching for more than 1 pattern).
|
||||
* or a {@link FilterGroupList.ByteArrayFilterGroupList} (if searching for more than 1 pattern).
|
||||
*
|
||||
* All callbacks must be registered before the constructor completes.
|
||||
*/
|
||||
abstract class Filter {
|
||||
public abstract class Filter {
|
||||
|
||||
public enum FilterContentType {
|
||||
IDENTIFIER,
|
||||
|
|
@ -65,7 +68,7 @@ abstract class Filter {
|
|||
* @param contentIndex Matched index of the identifier or path.
|
||||
* @return True if the litho component should be filtered out.
|
||||
*/
|
||||
boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
public boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
package app.revanced.extension.shared.patches.litho;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import app.revanced.extension.shared.ByteTrieSearch;
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.settings.BooleanSetting;
|
||||
|
||||
public abstract class FilterGroup<T> {
|
||||
public final static class FilterGroupResult {
|
||||
private BooleanSetting setting;
|
||||
private int matchedIndex;
|
||||
private int matchedLength;
|
||||
// In the future it might be useful to include which pattern matched,
|
||||
// but for now that is not needed.
|
||||
|
||||
FilterGroupResult() {
|
||||
this(null, -1, 0);
|
||||
}
|
||||
|
||||
FilterGroupResult(BooleanSetting setting, int matchedIndex, int matchedLength) {
|
||||
setValues(setting, matchedIndex, matchedLength);
|
||||
}
|
||||
|
||||
public void setValues(BooleanSetting setting, int matchedIndex, int matchedLength) {
|
||||
this.setting = setting;
|
||||
this.matchedIndex = matchedIndex;
|
||||
this.matchedLength = matchedLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* A null value if the group has no setting,
|
||||
* or if no match is returned from {@link FilterGroupList#check(Object)}.
|
||||
*/
|
||||
public BooleanSetting getSetting() {
|
||||
return setting;
|
||||
}
|
||||
|
||||
public boolean isFiltered() {
|
||||
return matchedIndex >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matched index of first pattern that matched, or -1 if nothing matched.
|
||||
*/
|
||||
public int getMatchedIndex() {
|
||||
return matchedIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Length of the matched filter pattern.
|
||||
*/
|
||||
public int getMatchedLength() {
|
||||
return matchedLength;
|
||||
}
|
||||
}
|
||||
|
||||
protected final BooleanSetting setting;
|
||||
protected final T[] filters;
|
||||
|
||||
/**
|
||||
* Initialize a new filter group.
|
||||
*
|
||||
* @param setting The associated setting.
|
||||
* @param filters The filters.
|
||||
*/
|
||||
@SafeVarargs
|
||||
public FilterGroup(final BooleanSetting setting, final T... filters) {
|
||||
this.setting = setting;
|
||||
this.filters = filters;
|
||||
if (filters.length == 0) {
|
||||
throw new IllegalArgumentException("Must use one or more filter patterns (zero specified)");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return setting == null || setting.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return If {@link FilterGroupList} should include this group when searching.
|
||||
* By default, all filters are included except non enabled settings that require reboot.
|
||||
*/
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
public boolean includeInSearch() {
|
||||
return isEnabled() || !setting.rebootApp;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + ": " + (setting == null ? "(null setting)" : setting);
|
||||
}
|
||||
|
||||
public abstract FilterGroupResult check(final T stack);
|
||||
|
||||
|
||||
public static class StringFilterGroup extends FilterGroup<String> {
|
||||
|
||||
public StringFilterGroup(final BooleanSetting setting, final String... filters) {
|
||||
super(setting, filters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FilterGroupResult check(final String string) {
|
||||
int matchedIndex = -1;
|
||||
int matchedLength = 0;
|
||||
if (isEnabled()) {
|
||||
for (String pattern : filters) {
|
||||
if (!string.isEmpty()) {
|
||||
final int indexOf = string.indexOf(pattern);
|
||||
if (indexOf >= 0) {
|
||||
matchedIndex = indexOf;
|
||||
matchedLength = pattern.length();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new FilterGroupResult(setting, matchedIndex, matchedLength);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If you have more than 1 filter patterns, then all instances of
|
||||
* this class should filtered using {@link FilterGroupList.ByteArrayFilterGroupList#check(byte[])},
|
||||
* which uses a prefix tree to give better performance.
|
||||
*/
|
||||
public static class ByteArrayFilterGroup extends FilterGroup<byte[]> {
|
||||
|
||||
private volatile int[][] failurePatterns;
|
||||
|
||||
// Modified implementation from https://stackoverflow.com/a/1507813
|
||||
private static int indexOf(final byte[] data, final byte[] pattern, final int[] failure) {
|
||||
// Finds the first occurrence of the pattern in the byte array using
|
||||
// KMP matching algorithm.
|
||||
int patternLength = pattern.length;
|
||||
for (int i = 0, j = 0, dataLength = data.length; i < dataLength; i++) {
|
||||
while (j > 0 && pattern[j] != data[i]) {
|
||||
j = failure[j - 1];
|
||||
}
|
||||
if (pattern[j] == data[i]) {
|
||||
j++;
|
||||
}
|
||||
if (j == patternLength) {
|
||||
return i - patternLength + 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static int[] createFailurePattern(byte[] pattern) {
|
||||
// Computes the failure function using a boot-strapping process,
|
||||
// where the pattern is matched against itself.
|
||||
final int patternLength = pattern.length;
|
||||
final int[] failure = new int[patternLength];
|
||||
|
||||
for (int i = 1, j = 0; i < patternLength; i++) {
|
||||
while (j > 0 && pattern[j] != pattern[i]) {
|
||||
j = failure[j - 1];
|
||||
}
|
||||
if (pattern[j] == pattern[i]) {
|
||||
j++;
|
||||
}
|
||||
failure[i] = j;
|
||||
}
|
||||
return failure;
|
||||
}
|
||||
|
||||
public ByteArrayFilterGroup(BooleanSetting setting, byte[]... filters) {
|
||||
super(setting, filters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the Strings into byte arrays. Used to search for text in binary data.
|
||||
*/
|
||||
public ByteArrayFilterGroup(BooleanSetting setting, String... filters) {
|
||||
super(setting, ByteTrieSearch.convertStringsToBytes(filters));
|
||||
}
|
||||
|
||||
private synchronized void buildFailurePatterns() {
|
||||
if (failurePatterns != null) return; // Thread race and another thread already initialized the search.
|
||||
Logger.printDebug(() -> "Building failure array for: " + this);
|
||||
int[][] failurePatterns = new int[filters.length][];
|
||||
int i = 0;
|
||||
for (byte[] pattern : filters) {
|
||||
failurePatterns[i++] = createFailurePattern(pattern);
|
||||
}
|
||||
this.failurePatterns = failurePatterns; // Must set after initialization finishes.
|
||||
}
|
||||
|
||||
@Override
|
||||
public FilterGroupResult check(final byte[] bytes) {
|
||||
int matchedLength = 0;
|
||||
int matchedIndex = -1;
|
||||
if (isEnabled()) {
|
||||
int[][] failures = failurePatterns;
|
||||
if (failures == null) {
|
||||
buildFailurePatterns(); // Lazy load.
|
||||
failures = failurePatterns;
|
||||
}
|
||||
for (int i = 0, length = filters.length; i < length; i++) {
|
||||
byte[] filter = filters[i];
|
||||
matchedIndex = indexOf(bytes, filter, failures[i]);
|
||||
if (matchedIndex >= 0) {
|
||||
matchedLength = filter.length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new FilterGroupResult(setting, matchedIndex, matchedLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +1,22 @@
|
|||
package app.revanced.extension.youtube.patches.components;
|
||||
package app.revanced.extension.shared.patches.litho;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import app.revanced.extension.shared.ByteTrieSearch;
|
||||
import app.revanced.extension.shared.StringTrieSearch;
|
||||
import app.revanced.extension.shared.TrieSearch;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.ByteArrayFilterGroup;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.StringFilterGroup;
|
||||
|
||||
abstract class FilterGroupList<V, T extends FilterGroup<V>> implements Iterable<T> {
|
||||
public abstract class FilterGroupList<V, T extends FilterGroup<V>> implements Iterable<T> {
|
||||
|
||||
private final List<T> filterGroups = new ArrayList<>();
|
||||
private final TrieSearch<V> search = createSearchGraph();
|
||||
|
||||
@SafeVarargs
|
||||
protected final void addAll(final T... groups) {
|
||||
public final void addAll(final T... groups) {
|
||||
filterGroups.addAll(Arrays.asList(groups));
|
||||
|
||||
for (T group : groups) {
|
||||
|
|
@ -41,18 +42,7 @@ abstract class FilterGroupList<V, T extends FilterGroup<V>> implements Iterable<
|
|||
return filterGroups.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(@NonNull Consumer<? super T> action) {
|
||||
filterGroups.forEach(action);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Spliterator<T> spliterator() {
|
||||
return filterGroups.spliterator();
|
||||
}
|
||||
|
||||
protected FilterGroup.FilterGroupResult check(V stack) {
|
||||
public FilterGroup.FilterGroupResult check(V stack) {
|
||||
FilterGroup.FilterGroupResult result = new FilterGroup.FilterGroupResult();
|
||||
search.matches(stack, result);
|
||||
return result;
|
||||
|
|
@ -60,21 +50,21 @@ abstract class FilterGroupList<V, T extends FilterGroup<V>> implements Iterable<
|
|||
}
|
||||
|
||||
protected abstract TrieSearch<V> createSearchGraph();
|
||||
}
|
||||
|
||||
final class StringFilterGroupList extends FilterGroupList<String, StringFilterGroup> {
|
||||
protected StringTrieSearch createSearchGraph() {
|
||||
return new StringTrieSearch();
|
||||
public static final class StringFilterGroupList extends FilterGroupList<String, StringFilterGroup> {
|
||||
protected StringTrieSearch createSearchGraph() {
|
||||
return new StringTrieSearch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If searching for a single byte pattern, then it is slightly better to use
|
||||
* {@link ByteArrayFilterGroup#check(byte[])} as it uses KMP which is faster
|
||||
* than a prefix tree to search for only 1 pattern.
|
||||
*/
|
||||
final class ByteArrayFilterGroupList extends FilterGroupList<byte[], ByteArrayFilterGroup> {
|
||||
protected ByteTrieSearch createSearchGraph() {
|
||||
return new ByteTrieSearch();
|
||||
/**
|
||||
* If searching for a single byte pattern, then it is slightly better to use
|
||||
* {@link ByteArrayFilterGroup#check(byte[])} as it uses KMP which is faster
|
||||
* than a prefix tree to search for only 1 pattern.
|
||||
*/
|
||||
public static final class ByteArrayFilterGroupList extends FilterGroupList<byte[], ByteArrayFilterGroup> {
|
||||
protected ByteTrieSearch createSearchGraph() {
|
||||
return new ByteTrieSearch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package app.revanced.extension.youtube.patches.components;
|
||||
package app.revanced.extension.shared.patches.litho;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
|
@ -7,9 +7,11 @@ import java.nio.ByteBuffer;
|
|||
import java.util.List;
|
||||
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.settings.BaseSettings;
|
||||
import app.revanced.extension.shared.StringTrieSearch;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.shared.settings.BaseSettings;
|
||||
import app.revanced.extension.shared.settings.YouTubeAndMusicSettings;
|
||||
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.StringFilterGroup;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class LithoFilterPatch {
|
||||
|
|
@ -36,7 +38,7 @@ public final class LithoFilterPatch {
|
|||
builder.append(identifier);
|
||||
builder.append(" Path: ");
|
||||
builder.append(path);
|
||||
if (Settings.DEBUG_PROTOBUFFER.get()) {
|
||||
if (YouTubeAndMusicSettings.DEBUG_PROTOBUFFER.get()) {
|
||||
builder.append(" BufferStrings: ");
|
||||
findAsciiStrings(builder, buffer);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package app.revanced.extension.shared.settings;
|
||||
|
||||
import static app.revanced.extension.shared.settings.Setting.parent;
|
||||
import static java.lang.Boolean.FALSE;
|
||||
|
||||
public class YouTubeAndMusicSettings extends BaseSettings {
|
||||
// Custom filter
|
||||
public static final BooleanSetting CUSTOM_FILTER = new BooleanSetting("revanced_custom_filter", FALSE);
|
||||
public static final StringSetting CUSTOM_FILTER_STRINGS = new StringSetting("revanced_custom_filter_strings", "", true, parent(CUSTOM_FILTER));
|
||||
|
||||
// Miscellaneous
|
||||
public static final BooleanSetting DEBUG_PROTOBUFFER = new BooleanSetting("revanced_debug_protobuffer", FALSE, false,
|
||||
"revanced_debug_protobuffer_user_dialog_message", parent(BaseSettings.DEBUG));
|
||||
}
|
||||
|
|
@ -11,6 +11,9 @@ import java.util.List;
|
|||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import app.revanced.extension.shared.StringTrieSearch;
|
||||
import app.revanced.extension.shared.patches.litho.Filter;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.ByteArrayFilterGroup;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.StringFilterGroup;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
|
@ -153,8 +156,8 @@ public final class AdsFilter extends Filter {
|
|||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
public boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
if (matchedGroup == playerShoppingShelf) {
|
||||
return contentIndex == 0 && playerShoppingShelfBuffer.check(buffer).isFiltered();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package app.revanced.extension.youtube.patches.components;
|
||||
|
||||
import app.revanced.extension.shared.patches.litho.Filter;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.StringFilterGroup;
|
||||
import app.revanced.extension.youtube.patches.playback.quality.AdvancedVideoQualityMenuPatch;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
|
||||
|
|
@ -19,7 +21,7 @@ public final class AdvancedVideoQualityMenuFilter extends Filter {
|
|||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
public boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
isVideoQualityMenuVisible = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
package app.revanced.extension.youtube.patches.components;
|
||||
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroupList.ByteArrayFilterGroupList;
|
||||
import app.revanced.extension.shared.patches.litho.Filter;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.ByteArrayFilterGroup;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.StringFilterGroup;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
final class ButtonsFilter extends Filter {
|
||||
public final class ButtonsFilter extends Filter {
|
||||
private static final String COMPACT_CHANNEL_BAR_PATH_PREFIX = "compact_channel_bar.e";
|
||||
private static final String VIDEO_ACTION_BAR_PATH_PREFIX = "video_action_bar.e";
|
||||
private static final String VIDEO_ACTION_BAR_PATH = "video_action_bar.e";
|
||||
|
|
@ -118,7 +122,7 @@ final class ButtonsFilter extends Filter {
|
|||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
public boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
if (matchedGroup == likeSubscribeGlow) {
|
||||
return (path.startsWith(VIDEO_ACTION_BAR_PATH_PREFIX) || path.startsWith(COMPACT_CHANNEL_BAR_PATH_PREFIX))
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
package app.revanced.extension.youtube.patches.components;
|
||||
|
||||
import app.revanced.extension.shared.patches.litho.Filter;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.*;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.youtube.shared.PlayerType;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
final class CommentsFilter extends Filter {
|
||||
public final class CommentsFilter extends Filter {
|
||||
|
||||
private static final String COMMENT_COMPOSER_PATH = "comment_composer.e";
|
||||
|
||||
|
|
@ -88,8 +90,8 @@ final class CommentsFilter extends Filter {
|
|||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
public boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
if (matchedGroup == chipBar) {
|
||||
// Playlist sort button uses same components and must only filter if the player is opened.
|
||||
return PlayerType.getCurrent().isMaximizedOrFullscreen()
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
package app.revanced.extension.youtube.patches.components;
|
||||
|
||||
import app.revanced.extension.shared.StringTrieSearch;
|
||||
import app.revanced.extension.shared.patches.litho.Filter;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.*;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroupList.*;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.youtube.shared.PlayerType;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
final class DescriptionComponentsFilter extends Filter {
|
||||
public final class DescriptionComponentsFilter extends Filter {
|
||||
|
||||
private static final String INFOCARDS_SECTION_PATH = "infocards_section.e";
|
||||
|
||||
|
|
@ -128,8 +131,8 @@ final class DescriptionComponentsFilter extends Filter {
|
|||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
public boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
|
||||
if (matchedGroup == aiGeneratedVideoSummarySection || matchedGroup == hypePoints) {
|
||||
// Only hide if player is open, in case this component is used somewhere else.
|
||||
|
|
|
|||
|
|
@ -1,214 +0,0 @@
|
|||
package app.revanced.extension.youtube.patches.components;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.settings.BooleanSetting;
|
||||
import app.revanced.extension.shared.ByteTrieSearch;
|
||||
|
||||
abstract class FilterGroup<T> {
|
||||
final static class FilterGroupResult {
|
||||
private BooleanSetting setting;
|
||||
private int matchedIndex;
|
||||
private int matchedLength;
|
||||
// In the future it might be useful to include which pattern matched,
|
||||
// but for now that is not needed.
|
||||
|
||||
FilterGroupResult() {
|
||||
this(null, -1, 0);
|
||||
}
|
||||
|
||||
FilterGroupResult(BooleanSetting setting, int matchedIndex, int matchedLength) {
|
||||
setValues(setting, matchedIndex, matchedLength);
|
||||
}
|
||||
|
||||
public void setValues(BooleanSetting setting, int matchedIndex, int matchedLength) {
|
||||
this.setting = setting;
|
||||
this.matchedIndex = matchedIndex;
|
||||
this.matchedLength = matchedLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* A null value if the group has no setting,
|
||||
* or if no match is returned from {@link FilterGroupList#check(Object)}.
|
||||
*/
|
||||
public BooleanSetting getSetting() {
|
||||
return setting;
|
||||
}
|
||||
|
||||
public boolean isFiltered() {
|
||||
return matchedIndex >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matched index of first pattern that matched, or -1 if nothing matched.
|
||||
*/
|
||||
public int getMatchedIndex() {
|
||||
return matchedIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Length of the matched filter pattern.
|
||||
*/
|
||||
public int getMatchedLength() {
|
||||
return matchedLength;
|
||||
}
|
||||
}
|
||||
|
||||
protected final BooleanSetting setting;
|
||||
protected final T[] filters;
|
||||
|
||||
/**
|
||||
* Initialize a new filter group.
|
||||
*
|
||||
* @param setting The associated setting.
|
||||
* @param filters The filters.
|
||||
*/
|
||||
@SafeVarargs
|
||||
public FilterGroup(final BooleanSetting setting, final T... filters) {
|
||||
this.setting = setting;
|
||||
this.filters = filters;
|
||||
if (filters.length == 0) {
|
||||
throw new IllegalArgumentException("Must use one or more filter patterns (zero specified)");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return setting == null || setting.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return If {@link FilterGroupList} should include this group when searching.
|
||||
* By default, all filters are included except non enabled settings that require reboot.
|
||||
*/
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
public boolean includeInSearch() {
|
||||
return isEnabled() || !setting.rebootApp;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + ": " + (setting == null ? "(null setting)" : setting);
|
||||
}
|
||||
|
||||
public abstract FilterGroupResult check(final T stack);
|
||||
}
|
||||
|
||||
class StringFilterGroup extends FilterGroup<String> {
|
||||
|
||||
public StringFilterGroup(final BooleanSetting setting, final String... filters) {
|
||||
super(setting, filters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FilterGroupResult check(final String string) {
|
||||
int matchedIndex = -1;
|
||||
int matchedLength = 0;
|
||||
if (isEnabled()) {
|
||||
for (String pattern : filters) {
|
||||
if (!string.isEmpty()) {
|
||||
final int indexOf = string.indexOf(pattern);
|
||||
if (indexOf >= 0) {
|
||||
matchedIndex = indexOf;
|
||||
matchedLength = pattern.length();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new FilterGroupResult(setting, matchedIndex, matchedLength);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If you have more than 1 filter patterns, then all instances of
|
||||
* this class should filtered using {@link ByteArrayFilterGroupList#check(byte[])},
|
||||
* which uses a prefix tree to give better performance.
|
||||
*/
|
||||
class ByteArrayFilterGroup extends FilterGroup<byte[]> {
|
||||
|
||||
private volatile int[][] failurePatterns;
|
||||
|
||||
// Modified implementation from https://stackoverflow.com/a/1507813
|
||||
private static int indexOf(final byte[] data, final byte[] pattern, final int[] failure) {
|
||||
// Finds the first occurrence of the pattern in the byte array using
|
||||
// KMP matching algorithm.
|
||||
int patternLength = pattern.length;
|
||||
for (int i = 0, j = 0, dataLength = data.length; i < dataLength; i++) {
|
||||
while (j > 0 && pattern[j] != data[i]) {
|
||||
j = failure[j - 1];
|
||||
}
|
||||
if (pattern[j] == data[i]) {
|
||||
j++;
|
||||
}
|
||||
if (j == patternLength) {
|
||||
return i - patternLength + 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static int[] createFailurePattern(byte[] pattern) {
|
||||
// Computes the failure function using a boot-strapping process,
|
||||
// where the pattern is matched against itself.
|
||||
final int patternLength = pattern.length;
|
||||
final int[] failure = new int[patternLength];
|
||||
|
||||
for (int i = 1, j = 0; i < patternLength; i++) {
|
||||
while (j > 0 && pattern[j] != pattern[i]) {
|
||||
j = failure[j - 1];
|
||||
}
|
||||
if (pattern[j] == pattern[i]) {
|
||||
j++;
|
||||
}
|
||||
failure[i] = j;
|
||||
}
|
||||
return failure;
|
||||
}
|
||||
|
||||
public ByteArrayFilterGroup(BooleanSetting setting, byte[]... filters) {
|
||||
super(setting, filters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the Strings into byte arrays. Used to search for text in binary data.
|
||||
*/
|
||||
public ByteArrayFilterGroup(BooleanSetting setting, String... filters) {
|
||||
super(setting, ByteTrieSearch.convertStringsToBytes(filters));
|
||||
}
|
||||
|
||||
private synchronized void buildFailurePatterns() {
|
||||
if (failurePatterns != null) return; // Thread race and another thread already initialized the search.
|
||||
Logger.printDebug(() -> "Building failure array for: " + this);
|
||||
int[][] failurePatterns = new int[filters.length][];
|
||||
int i = 0;
|
||||
for (byte[] pattern : filters) {
|
||||
failurePatterns[i++] = createFailurePattern(pattern);
|
||||
}
|
||||
this.failurePatterns = failurePatterns; // Must set after initialization finishes.
|
||||
}
|
||||
|
||||
@Override
|
||||
public FilterGroupResult check(final byte[] bytes) {
|
||||
int matchedLength = 0;
|
||||
int matchedIndex = -1;
|
||||
if (isEnabled()) {
|
||||
int[][] failures = failurePatterns;
|
||||
if (failures == null) {
|
||||
buildFailurePatterns(); // Lazy load.
|
||||
failures = failurePatterns;
|
||||
}
|
||||
for (int i = 0, length = filters.length; i < length; i++) {
|
||||
byte[] filter = filters[i];
|
||||
matchedIndex = indexOf(bytes, filter, failures[i]);
|
||||
if (matchedIndex >= 0) {
|
||||
matchedLength = filter.length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new FilterGroupResult(setting, matchedIndex, matchedLength);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
package app.revanced.extension.youtube.patches.components;
|
||||
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.shared.patches.litho.Filter;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.*;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class HideInfoCardsFilter extends Filter {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ import app.revanced.extension.shared.Utils;
|
|||
import app.revanced.extension.shared.ByteTrieSearch;
|
||||
import app.revanced.extension.shared.StringTrieSearch;
|
||||
import app.revanced.extension.shared.TrieSearch;
|
||||
import app.revanced.extension.shared.patches.litho.Filter;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.*;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.youtube.shared.NavigationBar;
|
||||
import app.revanced.extension.youtube.shared.PlayerType;
|
||||
|
|
@ -41,7 +43,7 @@ import app.revanced.extension.youtube.shared.PlayerType;
|
|||
* - When using whole word syntax, some keywords may need additional pluralized variations.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
final class KeywordContentFilter extends Filter {
|
||||
public final class KeywordContentFilter extends Filter {
|
||||
|
||||
/**
|
||||
* Strings found in the buffer for every videos. Full strings should be specified.
|
||||
|
|
@ -554,8 +556,8 @@ final class KeywordContentFilter extends Filter {
|
|||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
public boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
if (contentIndex != 0 && matchedGroup == startsWithFilter) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ import androidx.annotation.Nullable;
|
|||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import app.revanced.extension.shared.StringTrieSearch;
|
||||
import app.revanced.extension.shared.patches.litho.Filter;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.*;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroupList.*;
|
||||
import app.revanced.extension.youtube.patches.ChangeHeaderPatch;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.youtube.shared.NavigationBar;
|
||||
|
|
@ -342,7 +345,7 @@ public final class LayoutComponentsFilter extends Filter {
|
|||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
public boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
// This identifier is used not only in players but also in search results:
|
||||
// https://github.com/ReVanced/revanced-patches/issues/3245
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package app.revanced.extension.youtube.patches.components;
|
||||
|
||||
import app.revanced.extension.shared.patches.litho.Filter;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.*;
|
||||
import app.revanced.extension.youtube.patches.playback.speed.CustomPlaybackSpeedPatch;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
|
||||
|
|
@ -36,7 +38,7 @@ public final class PlaybackSpeedMenuFilter extends Filter {
|
|||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
public boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
if (matchedGroup == oldPlaybackMenuGroup) {
|
||||
isOldPlaybackSpeedMenuVisible = true;
|
||||
|
|
|
|||
|
|
@ -3,13 +3,16 @@ package app.revanced.extension.youtube.patches.components;
|
|||
import app.revanced.extension.shared.settings.BaseSettings;
|
||||
import app.revanced.extension.shared.settings.Setting;
|
||||
import app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch;
|
||||
import app.revanced.extension.shared.patches.litho.Filter;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.*;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroupList.*;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.youtube.shared.ShortsPlayerState;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class PlayerFlyoutMenuItemsFilter extends Filter {
|
||||
public final class PlayerFlyoutMenuItemsFilter extends Filter {
|
||||
|
||||
public static final class HideAudioFlyoutMenuAvailability implements Setting.Availability {
|
||||
@Override
|
||||
|
|
@ -94,7 +97,7 @@ public class PlayerFlyoutMenuItemsFilter extends Filter {
|
|||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
public boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
if (matchedGroup == videoQualityMenuFooter) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ import app.revanced.extension.youtube.patches.VideoInformation;
|
|||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.TrieSearch;
|
||||
import app.revanced.extension.shared.patches.litho.Filter;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.*;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroupList.*;
|
||||
|
||||
/**
|
||||
* Searches for video id's in the proto buffer of Shorts dislike.
|
||||
|
|
@ -84,13 +87,13 @@ public final class ReturnYouTubeDislikeFilter extends Filter {
|
|||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
public boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
if (!Settings.RYD_ENABLED.get() || !Settings.RYD_SHORTS.get()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FilterGroup.FilterGroupResult result = videoIdFilterGroup.check(buffer);
|
||||
FilterGroupResult result = videoIdFilterGroup.check(buffer);
|
||||
if (result.isFiltered()) {
|
||||
String matchedVideoId = findVideoId(buffer);
|
||||
// Matched video will be null if in incognito mode.
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ import java.util.Arrays;
|
|||
import java.util.List;
|
||||
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.patches.litho.Filter;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroup.*;
|
||||
import app.revanced.extension.shared.patches.litho.FilterGroupList.*;
|
||||
import app.revanced.extension.youtube.settings.Settings;
|
||||
import app.revanced.extension.youtube.shared.NavigationBar;
|
||||
import app.revanced.extension.youtube.shared.PlayerType;
|
||||
|
|
@ -339,7 +342,7 @@ public final class ShortsFilter extends Filter {
|
|||
}
|
||||
|
||||
@Override
|
||||
boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
public boolean isFiltered(String identifier, String path, byte[] buffer,
|
||||
StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) {
|
||||
if (contentType == FilterContentType.PATH) {
|
||||
if (matchedGroup == subscribeButton || matchedGroup == joinButton
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import android.graphics.Color;
|
|||
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.Utils;
|
||||
import app.revanced.extension.shared.settings.YouTubeAndMusicSettings;
|
||||
import app.revanced.extension.shared.settings.BaseSettings;
|
||||
import app.revanced.extension.shared.settings.BooleanSetting;
|
||||
import app.revanced.extension.shared.settings.EnumSetting;
|
||||
|
|
@ -49,7 +50,7 @@ import app.revanced.extension.youtube.patches.MiniplayerPatch;
|
|||
import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings;
|
||||
import app.revanced.extension.youtube.swipecontrols.SwipeControlsConfigurationProvider.SwipeOverlayStyle;
|
||||
|
||||
public class Settings extends BaseSettings {
|
||||
public class Settings extends YouTubeAndMusicSettings {
|
||||
// Video
|
||||
public static final BooleanSetting ADVANCED_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_advanced_video_quality_menu", TRUE);
|
||||
public static final BooleanSetting DISABLE_HDR_VIDEO = new BooleanSetting("revanced_disable_hdr_video", FALSE);
|
||||
|
|
@ -274,11 +275,6 @@ public class Settings extends BaseSettings {
|
|||
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));
|
||||
|
||||
// Custom filter
|
||||
public static final BooleanSetting CUSTOM_FILTER = new BooleanSetting("revanced_custom_filter", FALSE);
|
||||
public static final StringSetting CUSTOM_FILTER_STRINGS = new StringSetting("revanced_custom_filter_strings", "", true, parent(CUSTOM_FILTER));
|
||||
|
||||
// Navigation buttons
|
||||
public static final BooleanSetting HIDE_HOME_BUTTON = new BooleanSetting("revanced_hide_home_button", FALSE, true);
|
||||
public static final BooleanSetting HIDE_CREATE_BUTTON = new BooleanSetting("revanced_hide_create_button", TRUE, true);
|
||||
|
|
@ -368,8 +364,6 @@ public class Settings extends BaseSettings {
|
|||
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client_type", ClientType.ANDROID_VR_1_43_32, true, parent(SPOOF_VIDEO_STREAMS));
|
||||
public static final BooleanSetting SPOOF_VIDEO_STREAMS_AV1 = new BooleanSetting("revanced_spoof_video_streams_av1", FALSE, true,
|
||||
"revanced_spoof_video_streams_av1_user_dialog_message", new SpoofClientAv1Availability());
|
||||
public static final BooleanSetting DEBUG_PROTOBUFFER = new BooleanSetting("revanced_debug_protobuffer", FALSE, false,
|
||||
"revanced_debug_protobuffer_user_dialog_message", parent(BaseSettings.DEBUG));
|
||||
|
||||
// Swipe controls
|
||||
public static final BooleanSetting SWIPE_CHANGE_VIDEO = new BooleanSetting("revanced_swipe_change_video", FALSE, true);
|
||||
|
|
@ -382,7 +376,7 @@ public class Settings extends BaseSettings {
|
|||
public static final IntegerSetting SWIPE_MAGNITUDE_THRESHOLD = new IntegerSetting("revanced_swipe_threshold", 30, true,
|
||||
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
||||
public static final IntegerSetting SWIPE_VOLUME_SENSITIVITY = new IntegerSetting("revanced_swipe_volume_sensitivity", 1, true, parent(SWIPE_VOLUME));
|
||||
public static final EnumSetting<SwipeOverlayStyle> SWIPE_OVERLAY_STYLE = new EnumSetting<>("revanced_swipe_overlay_style", SwipeOverlayStyle.HORIZONTAL,true,
|
||||
public static final EnumSetting<SwipeOverlayStyle> SWIPE_OVERLAY_STYLE = new EnumSetting<>("revanced_swipe_overlay_style", SwipeOverlayStyle.HORIZONTAL, true,
|
||||
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
||||
public static final IntegerSetting SWIPE_OVERLAY_TEXT_SIZE = new IntegerSetting("revanced_swipe_text_overlay_size", 14, true,
|
||||
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
||||
|
|
@ -411,7 +405,9 @@ public class Settings extends BaseSettings {
|
|||
|
||||
// SponsorBlock
|
||||
public static final BooleanSetting SB_ENABLED = new BooleanSetting("sb_enabled", TRUE);
|
||||
/** Do not use id setting directly. Instead use {@link SponsorBlockSettings}. */
|
||||
/**
|
||||
* Do not use id setting directly. Instead use {@link SponsorBlockSettings}.
|
||||
*/
|
||||
public static final StringSetting SB_PRIVATE_USER_ID = new StringSetting("sb_private_user_id_Do_Not_Share", "", parent(SB_ENABLED));
|
||||
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));
|
||||
|
|
@ -460,7 +456,7 @@ public class Settings extends BaseSettings {
|
|||
public static final StringSetting SB_CATEGORY_UNSUBMITTED_COLOR = new StringSetting("sb_unsubmitted_color", "#FFFFFFFF", false, false);
|
||||
|
||||
// Deprecated migrations
|
||||
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 FloatSetting DEPRECATED_SB_CATEGORY_SPONSOR_OPACITY = new FloatSetting("sb_sponsor_opacity", 0.8f, false, false);
|
||||
private static final FloatSetting DEPRECATED_SB_CATEGORY_SELF_PROMO_OPACITY = new FloatSetting("sb_selfpromo_opacity", 0.8f, false, false);
|
||||
|
|
@ -512,7 +508,7 @@ public class Settings extends BaseSettings {
|
|||
// or is spoofing to a version the same or newer than this app.
|
||||
if (!SPOOF_APP_VERSION_TARGET.isSetToDefault() &&
|
||||
(SPOOF_APP_VERSION_TARGET.get().compareTo(SPOOF_APP_VERSION_TARGET.defaultValue) < 0
|
||||
|| (Utils.getAppVersionName().compareTo(SPOOF_APP_VERSION_TARGET.get()) <= 0))) {
|
||||
|| (Utils.getAppVersionName().compareTo(SPOOF_APP_VERSION_TARGET.get()) <= 0))) {
|
||||
Logger.printInfo(() -> "Resetting spoof app version");
|
||||
SPOOF_APP_VERSION_TARGET.resetToDefault();
|
||||
SPOOF_APP_VERSION.resetToDefault();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue