You've already forked revanced-integrations
mirror of
https://github.com/revanced/revanced-integrations
synced 2025-11-19 03:23:27 +01:00
Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
878ac2a9fa | ||
|
|
b663880741 | ||
|
|
9ab8a646ed | ||
|
|
2002bf8063 | ||
|
|
693ef08c6c | ||
|
|
84377b2da4 | ||
|
|
71e81a6473 | ||
|
|
5839f6ca4a | ||
|
|
d125d20974 | ||
|
|
5dd68e23f8 | ||
|
|
98ce2df47d | ||
|
|
0a6022c258 | ||
|
|
a550d16c3f | ||
|
|
04a89af1c9 | ||
|
|
bf368e8dd4 | ||
|
|
4afa162f46 | ||
|
|
66f5808863 | ||
|
|
57c56b630a | ||
|
|
edaf70fd10 | ||
|
|
c309646d35 | ||
|
|
934b981605 | ||
|
|
57969661dd | ||
|
|
376168fecf | ||
|
|
e8342ec15b | ||
|
|
d64a0f9599 | ||
|
|
b93b03dc19 | ||
|
|
a098594706 | ||
|
|
8805851a09 | ||
|
|
a9d24872a8 | ||
|
|
080e22b1bf | ||
|
|
5a028ab834 | ||
|
|
7840bc48ba | ||
|
|
718c5a75c1 | ||
|
|
2f32786661 | ||
|
|
3a2536a86e | ||
|
|
37869dc5b8 | ||
|
|
9dc9ce364c | ||
|
|
00ea006b8c | ||
|
|
617a4eb5d0 | ||
|
|
1351358268 | ||
|
|
35aa4f92c6 | ||
|
|
bca96cc8b4 | ||
|
|
cea3a5edc7 | ||
|
|
44dfea907d | ||
|
|
b2eab33e02 | ||
|
|
a87e366035 | ||
|
|
d4a23ed5c9 | ||
|
|
767201ce05 | ||
|
|
64cfe9c579 | ||
|
|
25978ae4a4 | ||
|
|
1f48749958 | ||
|
|
ee1f895e87 | ||
|
|
645669bbc0 | ||
|
|
d4c3b74a9a | ||
|
|
24367cea3f | ||
|
|
1e3970c3f2 | ||
|
|
c3e88c79e9 | ||
|
|
b8f0e632c1 | ||
|
|
c0c778b3e6 | ||
|
|
fe74f6d8a6 |
17
.github/workflows/release.yml
vendored
17
.github/workflows/release.yml
vendored
@@ -15,25 +15,24 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Cancel Previous Runs
|
||||
- name: Cancel previou runs
|
||||
uses: styfle/cancel-workflow-action@0.11.0
|
||||
with:
|
||||
access_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Checkout Repo
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up JDK 11
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '11'
|
||||
java-version: '17'
|
||||
distribution: 'zulu'
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "lts/*"
|
||||
node-version: "latest"
|
||||
cache: 'npm'
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew --no-daemon build
|
||||
run: ./gradlew build --no-daemon
|
||||
- name: Setup semantic-release
|
||||
run: npm install -g semantic-release @semantic-release/git @semantic-release/changelog gradle-semantic-release-plugin -D
|
||||
run: npm install semantic-release @semantic-release/git @semantic-release/changelog gradle-semantic-release-plugin -D
|
||||
- name: Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
166
CHANGELOG.md
166
CHANGELOG.md
@@ -1,3 +1,169 @@
|
||||
## [0.86.1](https://github.com/revanced/revanced-integrations/compare/v0.86.0...v0.86.1) (2022-12-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/theme:** correct background color for the shorts comment box ([#239](https://github.com/revanced/revanced-integrations/issues/239)) ([9ab8a64](https://github.com/revanced/revanced-integrations/commit/9ab8a646ed07d709c46fe7b5dd3238bc23301b8b))
|
||||
|
||||
# [0.86.0](https://github.com/revanced/revanced-integrations/compare/v0.85.1...v0.86.0) (2022-12-21)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/return-youtube-dislike:** debug connection statistics, toast on error, high priority background threads ([#236](https://github.com/revanced/revanced-integrations/issues/236)) ([693ef08](https://github.com/revanced/revanced-integrations/commit/693ef08c6c2ebb2a4dde9194583ac77ae3af9fc6))
|
||||
|
||||
## [0.85.1](https://github.com/revanced/revanced-integrations/compare/v0.85.0...v0.85.1) (2022-12-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* revert semantically incorrect simplification of ˋAdRemoverAPI.HideViewWithLayout1dpˋ ([#244](https://github.com/revanced/revanced-integrations/issues/244)) ([71e81a6](https://github.com/revanced/revanced-integrations/commit/71e81a6473b94c5a2c82a9aad340799ff174bdf7))
|
||||
|
||||
# [0.85.0](https://github.com/revanced/revanced-integrations/compare/v0.84.2...v0.85.0) (2022-12-21)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/general-ads:** hide grid of shorts ([d125d20](https://github.com/revanced/revanced-integrations/commit/d125d20974774fbe2b4a61b6ddad66f76d161e42))
|
||||
|
||||
## [0.84.2](https://github.com/revanced/revanced-integrations/compare/v0.84.1...v0.84.2) (2022-12-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* migrate old to new settings correctly ([#241](https://github.com/revanced/revanced-integrations/issues/241)) ([98ce2df](https://github.com/revanced/revanced-integrations/commit/98ce2df47dded785986dee3c64becf96956f5eb6))
|
||||
|
||||
## [0.84.1](https://github.com/revanced/revanced-integrations/compare/v0.84.0...v0.84.1) (2022-12-18)
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **youtube/general-ads-patch:** reduce amount of ignored components ([#237](https://github.com/revanced/revanced-integrations/issues/237)) ([bf368e8](https://github.com/revanced/revanced-integrations/commit/bf368e8dd49a91ba1d7a1df66344f77d8b788072))
|
||||
|
||||
# [0.84.0](https://github.com/revanced/revanced-integrations/compare/v0.83.1...v0.84.0) (2022-12-08)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/general-ads:** block new ad in home feed ([934b981](https://github.com/revanced/revanced-integrations/commit/934b981605515128c9d38f09768392f8d1c7bd98))
|
||||
|
||||
## [0.83.1](https://github.com/revanced/revanced-integrations/compare/v0.83.0...v0.83.1) (2022-12-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* inconsistencies in preference switches ([#235](https://github.com/revanced/revanced-integrations/issues/235)) ([d64a0f9](https://github.com/revanced/revanced-integrations/commit/d64a0f95995e6fbd96127941cf16133c5661dfe4))
|
||||
|
||||
# [0.83.0](https://github.com/revanced/revanced-integrations/compare/v0.82.0...v0.83.0) (2022-12-05)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **twitch:** `block-embedded-ads` patch ([#231](https://github.com/revanced/revanced-integrations/issues/231)) ([a098594](https://github.com/revanced/revanced-integrations/commit/a09859470688c88afe1e0ee1688068656feda521))
|
||||
|
||||
# [0.82.0](https://github.com/revanced/revanced-integrations/compare/v0.81.0...v0.82.0) (2022-12-05)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/debugging:** print stack traces ([a9d2487](https://github.com/revanced/revanced-integrations/commit/a9d24872a89f9039956993d8290713dcde3f0ead))
|
||||
* **youtube/return-youtube-dislike:** do not debug log when updating the text ([080e22b](https://github.com/revanced/revanced-integrations/commit/080e22b1bf18f9c09e7687aa694d6601318bd99b))
|
||||
|
||||
# [0.81.0](https://github.com/revanced/revanced-integrations/compare/v0.80.0...v0.81.0) (2022-12-03)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/return-youtube-dislike:** show dislike as a percentage ([#234](https://github.com/revanced/revanced-integrations/issues/234)) ([7840bc4](https://github.com/revanced/revanced-integrations/commit/7840bc48ba5309eebadeb0f708570bac9f7166e0))
|
||||
|
||||
# [0.80.0](https://github.com/revanced/revanced-integrations/compare/v0.79.1...v0.80.0) (2022-11-30)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **twitch:** remove `block-embedded-ads` patch ([#230](https://github.com/revanced/revanced-integrations/issues/230)) ([2f32786](https://github.com/revanced/revanced-integrations/commit/2f327866616d9449963aefb9067b35138a4f4844))
|
||||
|
||||
## [0.79.1](https://github.com/revanced/revanced-integrations/compare/v0.79.0...v0.79.1) (2022-11-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/return-youtube-dislike:** feedback when dislikes hidden ([#224](https://github.com/revanced/revanced-integrations/issues/224)) ([37869dc](https://github.com/revanced/revanced-integrations/commit/37869dc5b8b0b0cae97c6a3caf73dfb419af8f79))
|
||||
|
||||
# [0.79.0](https://github.com/revanced/revanced-integrations/compare/v0.78.1...v0.79.0) (2022-11-30)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **twitch:** `block-embedded-ads` patch support ([#227](https://github.com/revanced/revanced-integrations/issues/227)) ([00ea006](https://github.com/revanced/revanced-integrations/commit/00ea006b8c2e395ba56e8e5b90c467542849be46))
|
||||
|
||||
## [0.78.1](https://github.com/revanced/revanced-integrations/compare/v0.78.0...v0.78.1) (2022-11-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **twitch/settings:** add missing classes ([#226](https://github.com/revanced/revanced-integrations/issues/226)) ([35aa4f9](https://github.com/revanced/revanced-integrations/commit/35aa4f92c6fc36d5421d41fb005e2298e1e8ed70))
|
||||
|
||||
# [0.78.0](https://github.com/revanced/revanced-integrations/compare/v0.77.1...v0.78.0) (2022-11-25)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **tiktok:** `sim-spoof` patch ([#219](https://github.com/revanced/revanced-integrations/issues/219)) ([cea3a5e](https://github.com/revanced/revanced-integrations/commit/cea3a5edc74e96efd79d4a4f9b363694d85216a6))
|
||||
|
||||
## [0.77.1](https://github.com/revanced/revanced-integrations/compare/v0.77.0...v0.77.1) (2022-11-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/return-youtube-dislike:** don't block the UI thread ([#221](https://github.com/revanced/revanced-integrations/issues/221)) ([b2eab33](https://github.com/revanced/revanced-integrations/commit/b2eab33e02241c62122da3063c12dc17cae2611e))
|
||||
|
||||
# [0.77.0](https://github.com/revanced/revanced-integrations/compare/v0.76.0...v0.77.0) (2022-11-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* invalid syntax error ([d4a23ed](https://github.com/revanced/revanced-integrations/commit/d4a23ed5c931993e9c642d0948e9551f848f480c))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/general-ads:** hide movie ad from search ([767201c](https://github.com/revanced/revanced-integrations/commit/767201ce05f01db692828b453d2b31487f88e015))
|
||||
|
||||
# [0.76.0](https://github.com/revanced/revanced-integrations/compare/v0.75.0...v0.76.0) (2022-11-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/general-ads:** hide reels shelf ([1f48749](https://github.com/revanced/revanced-integrations/commit/1f48749958675926dd71b08e079497daed2b332b))
|
||||
* **youtube/general-ads:** make restarting mandatory when toggling shorts ([25978ae](https://github.com/revanced/revanced-integrations/commit/25978ae4a4982782bc18830a1c160b2ac1dfb7e8))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/debugging:** do not require restarting on toggle ([ee1f895](https://github.com/revanced/revanced-integrations/commit/ee1f895e877e515898118ff440066645de0a6a76))
|
||||
|
||||
# [0.75.0](https://github.com/revanced/revanced-integrations/compare/v0.74.1...v0.75.0) (2022-11-21)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **twitch:** integrations code for patches ([#216](https://github.com/revanced/revanced-integrations/issues/216)) ([d4c3b74](https://github.com/revanced/revanced-integrations/commit/d4c3b74a9a49c7595cf63e3ccedc03586bc2de8d))
|
||||
|
||||
## [0.74.1](https://github.com/revanced/revanced-integrations/compare/v0.74.0...v0.74.1) (2022-11-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/general-ads:** hide bytecode home ad view ([c3e88c7](https://github.com/revanced/revanced-integrations/commit/c3e88c79e9e7de0700c4e0ade349e47173002567))
|
||||
|
||||
# [0.74.0](https://github.com/revanced/revanced-integrations/compare/v0.73.0...v0.74.0) (2022-11-20)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube:** `disable-zoom-haptics` patch ([#217](https://github.com/revanced/revanced-integrations/issues/217)) ([fe74f6d](https://github.com/revanced/revanced-integrations/commit/fe74f6d8a6740a4d4544344474756c8ac717748f))
|
||||
|
||||
# [0.73.0](https://github.com/revanced/revanced-integrations/compare/v0.72.0...v0.73.0) (2022-11-20)
|
||||
|
||||
|
||||
|
||||
@@ -45,4 +45,7 @@ android {
|
||||
dependencies {
|
||||
compileOnly(project(mapOf("path" to ":dummy")))
|
||||
compileOnly("androidx.annotation:annotation:1.5.0")
|
||||
compileOnly("androidx.appcompat:appcompat:1.5.1")
|
||||
compileOnly("com.squareup.okhttp3:okhttp:4.10.0")
|
||||
compileOnly("com.squareup.retrofit2:retrofit:2.9.0")
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class AdRemoverAPI {
|
||||
ViewGroup.LayoutParams layoutParams5 = new ViewGroup.LayoutParams(1, 1);
|
||||
view.setLayoutParams(layoutParams5);
|
||||
} else {
|
||||
LogHelper.debug(AdRemoverAPI.class, "HideViewWithLayout1dp - Id: " + view.getId() + " Type: " + view.getClass().getName());
|
||||
LogHelper.printDebug(() -> "HideViewWithLayout1dp - Id: " + view.getId() + " Type: " + view.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import app.revanced.integrations.adremover.AdRemoverAPI;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class BrandingWaterMarkPatch {
|
||||
|
||||
//Used by: app.revanced.patches.youtube.layout.watermark.patch.HideWatermarkPatch
|
||||
// Used by: app.revanced.patches.youtube.layout.watermark.patch.HideWatermarkPatch
|
||||
public static boolean isBrandingWatermarkShown() {
|
||||
return SettingsEnum.BRANDING_SHOWN.getBoolean();
|
||||
return SettingsEnum.HIDE_VIDEO_WATERMARK.getBoolean() == false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
|
||||
final class ButtonsPatch extends Filter {
|
||||
private final BlockRule actionButtonsRule;
|
||||
private final BlockRule dislikeRule;
|
||||
private final BlockRule actionBarRule;
|
||||
|
||||
private final BlockRule[] rules;
|
||||
|
||||
public ButtonsPatch() {
|
||||
BlockRule like = new BlockRule(SettingsEnum.HIDE_LIKE_BUTTON, "|like_button");
|
||||
dislikeRule = new BlockRule(SettingsEnum.HIDE_DISLIKE_BUTTON, "dislike_button");
|
||||
BlockRule download = new BlockRule(SettingsEnum.HIDE_DOWNLOAD_BUTTON, "download_button");
|
||||
actionButtonsRule = new BlockRule(SettingsEnum.HIDE_ACTION_BUTTON, "ContainerType|video_action_button");
|
||||
BlockRule playlist = new BlockRule(SettingsEnum.HIDE_PLAYLIST_BUTTON, "save_to_playlist_button");
|
||||
rules = new BlockRule[]{like, dislikeRule, download, actionButtonsRule, playlist};
|
||||
|
||||
actionBarRule = new BlockRule(null, "video_action_bar");
|
||||
|
||||
this.pathRegister.registerAll(
|
||||
like,
|
||||
dislikeRule,
|
||||
download,
|
||||
playlist
|
||||
);
|
||||
}
|
||||
|
||||
private boolean hideActionBar() {
|
||||
for (BlockRule rule : rules) if (!rule.isEnabled()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filter(final String path, final String identifier) {
|
||||
if (hideActionBar() && actionBarRule.check(identifier).isBlocked()) return true;
|
||||
|
||||
var currentIsActionButton = actionButtonsRule.check(path).isBlocked();
|
||||
|
||||
if (dislikeRule.check(path).isBlocked()) ActionButton.doNotBlockCounter = 4;
|
||||
|
||||
if (currentIsActionButton && ActionButton.doNotBlockCounter-- > 0) {
|
||||
if (SettingsEnum.HIDE_SHARE_BUTTON.getBoolean()) {
|
||||
LogHelper.printDebug(() -> "Hiding share button");
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
if ((currentIsActionButton && ActionButton.doNotBlockCounter <= 0 && actionButtonsRule.isEnabled()) || pathRegister.contains(path)) {
|
||||
LogHelper.printDebug(() -> "Blocked: " + path);
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
static class ActionButton {
|
||||
public static int doNotBlockCounter = 4;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
|
||||
final class CommentsPatch extends Filter {
|
||||
|
||||
public CommentsPatch() {
|
||||
var comments = new BlockRule(SettingsEnum.HIDE_COMMENTS_SECTION, "video_metadata_carousel", "_comments");
|
||||
var previewComment = new BlockRule(
|
||||
SettingsEnum.HIDE_PREVIEW_COMMENT,
|
||||
"carousel_item",
|
||||
"comments_entry_point_teaser",
|
||||
"comments_entry_point_simplebox"
|
||||
);
|
||||
|
||||
this.pathRegister.registerAll(
|
||||
comments,
|
||||
previewComment
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean filter(String path, String _identifier) {
|
||||
if (!pathRegister.contains(path)) return false;
|
||||
|
||||
LogHelper.printDebug(() -> "Blocked: " + path);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ public final class FixPlaybackPatch {
|
||||
Thread.sleep(10);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
LogHelper.debug(FixPlaybackPatch.class, "Thread was interrupted");
|
||||
LogHelper.printDebug(() -> "Thread was interrupted");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import app.revanced.integrations.settings.SettingsEnum;
|
||||
public class FullscreenPanelsRemoverPatch {
|
||||
|
||||
public static int getFullscreenPanelsVisibility() {
|
||||
return SettingsEnum.FULLSCREEN_PANELS_SHOWN.getBoolean() ? View.VISIBLE : View.GONE;
|
||||
return SettingsEnum.HIDE_FULLSCREEN_PANELS.getBoolean() ? View.GONE : View.VISIBLE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import app.revanced.integrations.adremover.AdRemoverAPI;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.utils.ReVancedUtils;
|
||||
|
||||
public final class GeneralAdsPatch extends Filter {
|
||||
private final String[] IGNORE = {
|
||||
"home_video_with_context",
|
||||
"related_video_with_context",
|
||||
"comment_thread", // skip blocking anything in the comments
|
||||
"|comment.", // skip blocking anything in the comments replies
|
||||
"download_",
|
||||
"library_recent_shelf",
|
||||
"playlist_add_to_option_wrapper" // do not block on "add to playlist" flyout menu
|
||||
};
|
||||
|
||||
private final BlockRule custom = new CustomBlockRule(
|
||||
SettingsEnum.ADREMOVER_CUSTOM_ENABLED,
|
||||
SettingsEnum.ADREMOVER_CUSTOM_REMOVAL
|
||||
);
|
||||
|
||||
public GeneralAdsPatch() {
|
||||
var communityPosts = new BlockRule(SettingsEnum.ADREMOVER_COMMUNITY_POSTS_REMOVAL, "post_base_wrapper");
|
||||
var communityGuidelines = new BlockRule(SettingsEnum.ADREMOVER_COMMUNITY_GUIDELINES_REMOVAL, "community_guidelines");
|
||||
var compactBanner = new BlockRule(SettingsEnum.ADREMOVER_COMPACT_BANNER_REMOVAL, "compact_banner");
|
||||
var inFeedSurvey = new BlockRule(SettingsEnum.ADREMOVER_FEED_SURVEY_REMOVAL, "in_feed_survey");
|
||||
var medicalPanel = new BlockRule(SettingsEnum.ADREMOVER_MEDICAL_PANEL_REMOVAL, "medical_panel");
|
||||
var paidContent = new BlockRule(SettingsEnum.ADREMOVER_PAID_CONTENT_REMOVAL, "paid_content_overlay");
|
||||
var merchandise = new BlockRule(SettingsEnum.ADREMOVER_MERCHANDISE_REMOVAL, "product_carousel");
|
||||
var infoPanel = new BlockRule(SettingsEnum.ADREMOVER_INFO_PANEL_REMOVAL, "publisher_transparency_panel", "single_item_information_panel");
|
||||
var suggestions = new BlockRule(SettingsEnum.ADREMOVER_SUGGESTIONS_REMOVAL, "horizontal_video_shelf");
|
||||
var latestPosts = new BlockRule(SettingsEnum.ADREMOVER_HIDE_LATEST_POSTS, "post_shelf");
|
||||
var channelGuidelines = new BlockRule(SettingsEnum.ADREMOVER_HIDE_CHANNEL_GUIDELINES, "channel_guidelines_entry_banner");
|
||||
var artistCard = new BlockRule(SettingsEnum.HIDE_ARTIST_CARD, "official_card");
|
||||
var selfSponsor = new BlockRule(SettingsEnum.ADREMOVER_SELF_SPONSOR_REMOVAL, "cta_shelf_card");
|
||||
var chapterTeaser = new BlockRule(SettingsEnum.ADREMOVER_CHAPTER_TEASER_REMOVAL, "expandable_metadata");
|
||||
var graySeparator = new BlockRule(SettingsEnum.ADREMOVER_GRAY_SEPARATOR,
|
||||
"cell_divider" // layout residue (gray line above the buttoned ad),
|
||||
);
|
||||
var buttonedAd = new BlockRule(SettingsEnum.ADREMOVER_BUTTONED_REMOVAL,
|
||||
"video_display_full_buttoned_layout",
|
||||
"full_width_square_image_layout",
|
||||
"_ad_with",
|
||||
"landscape_image_wide_button_layout"
|
||||
);
|
||||
var generalAds = new BlockRule(
|
||||
SettingsEnum.ADREMOVER_GENERAL_ADS_REMOVAL,
|
||||
"ads_video_with_context",
|
||||
"banner_text_icon",
|
||||
"square_image_layout",
|
||||
"watch_metadata_app_promo",
|
||||
"video_display_full_layout"
|
||||
);
|
||||
var movieAds = new BlockRule(
|
||||
SettingsEnum.ADREMOVER_MOVIE_REMOVAL,
|
||||
"browsy_bar",
|
||||
"compact_movie",
|
||||
"horizontal_movie_shelf",
|
||||
"movie_and_show_upsell_card",
|
||||
"compact_tvfilm_item"
|
||||
);
|
||||
|
||||
this.pathRegister.registerAll(
|
||||
generalAds,
|
||||
buttonedAd,
|
||||
communityPosts,
|
||||
paidContent,
|
||||
suggestions,
|
||||
latestPosts,
|
||||
movieAds,
|
||||
chapterTeaser,
|
||||
communityGuidelines,
|
||||
compactBanner,
|
||||
inFeedSurvey,
|
||||
medicalPanel,
|
||||
merchandise,
|
||||
infoPanel,
|
||||
channelGuidelines,
|
||||
artistCard,
|
||||
selfSponsor
|
||||
);
|
||||
|
||||
var carouselAd = new BlockRule(SettingsEnum.ADREMOVER_GENERAL_ADS_REMOVAL,
|
||||
"carousel_ad"
|
||||
);
|
||||
var shorts = new BlockRule(SettingsEnum.ADREMOVER_SHORTS_REMOVAL,
|
||||
"reels_player_overlay",
|
||||
"shorts_shelf",
|
||||
"inline_shorts",
|
||||
"shorts_grid"
|
||||
);
|
||||
|
||||
this.identifierRegister.registerAll(
|
||||
shorts,
|
||||
graySeparator,
|
||||
carouselAd
|
||||
);
|
||||
}
|
||||
|
||||
public boolean filter(final String path, final String identifier) {
|
||||
BlockResult result;
|
||||
|
||||
if (custom.isEnabled() && custom.check(path).isBlocked())
|
||||
result = BlockResult.CUSTOM;
|
||||
else if (ReVancedUtils.containsAny(path, IGNORE))
|
||||
result = BlockResult.IGNORED;
|
||||
else if (pathRegister.contains(path) || identifierRegister.contains(identifier))
|
||||
result = BlockResult.DEFINED;
|
||||
else
|
||||
result = BlockResult.UNBLOCKED;
|
||||
|
||||
log(String.format("%s (ID: %s): %s", result.message, identifier, path));
|
||||
|
||||
return result.filter;
|
||||
}
|
||||
|
||||
private enum BlockResult {
|
||||
UNBLOCKED(false, "Unblocked"),
|
||||
IGNORED(false, "Ignored"),
|
||||
DEFINED(true, "Blocked"),
|
||||
CUSTOM(true, "Custom");
|
||||
|
||||
final Boolean filter;
|
||||
final String message;
|
||||
|
||||
BlockResult(boolean filter, String message) {
|
||||
this.filter = filter;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide a view.
|
||||
*
|
||||
* @param condition The setting to check for hiding the view.
|
||||
* @param view The view to hide.
|
||||
*/
|
||||
private static void hideView(SettingsEnum condition, View view) {
|
||||
if (!condition.getBoolean()) return;
|
||||
|
||||
log("Hiding view with setting: " + condition);
|
||||
|
||||
AdRemoverAPI.HideViewWithLayout1dp(view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the view, which shows ads in the homepage.
|
||||
*
|
||||
* @param view The view, which shows ads.
|
||||
*/
|
||||
public static void hideAdAttributionView(View view) {
|
||||
hideView(SettingsEnum.ADREMOVER_GENERAL_ADS_REMOVAL, view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the view, which shows reels in the homepage.
|
||||
*
|
||||
* @param view The view, which shows reels.
|
||||
*/
|
||||
public static void hideReelView(View view) {
|
||||
hideView(SettingsEnum.ADREMOVER_SHORTS_REMOVAL, view);
|
||||
}
|
||||
|
||||
private static void log(String message) {
|
||||
LogHelper.printDebug(() -> message);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,6 @@ import app.revanced.integrations.settings.SettingsEnum;
|
||||
public class HideAutoplayButtonPatch {
|
||||
|
||||
public static boolean isButtonShown() {
|
||||
return SettingsEnum.AUTOPLAY_BUTTON_SHOWN.getBoolean();
|
||||
return SettingsEnum.HIDE_AUTOPLAY_BUTTON.getBoolean() == false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class HideCastButtonPatch {
|
||||
|
||||
//Used by app.revanced.patches.youtube.layout.castbutton.patch.HideCastButonPatch
|
||||
// Used by app.revanced.patches.youtube.layout.castbutton.patch.HideCastButonPatch
|
||||
public static int getCastButtonOverrideV2(int original) {
|
||||
return SettingsEnum.CAST_BUTTON_SHOWN.getBoolean() ? original : View.GONE;
|
||||
return SettingsEnum.HIDE_CAST_BUTTON.getBoolean() ? View.GONE : original;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ public class HideCreateButtonPatch {
|
||||
|
||||
//Used by app.revanced.patches.youtube.layout.createbutton.patch.CreateButtonRemoverPatch
|
||||
public static void hideCreateButton(View view) {
|
||||
boolean enabled = SettingsEnum.CREATE_BUTTON_ENABLED.getBoolean();
|
||||
String message = "Create button: " + (enabled ? "shown" : "hidden");
|
||||
LogHelper.debug(HideCreateButtonPatch.class, message);
|
||||
view.setVisibility(enabled ? View.VISIBLE : View.GONE);
|
||||
boolean hidden = SettingsEnum.HIDE_CREATE_BUTTON.getBoolean();
|
||||
String message = "Create button: " + (hidden ? "hidden" : "shown");
|
||||
LogHelper.printDebug(() -> message);
|
||||
view.setVisibility(hidden ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ public class HideReelsPatch {
|
||||
* @param view
|
||||
*/
|
||||
public static void HideReel(View view) {
|
||||
if (!SettingsEnum.REEL_BUTTON_SHOWN.getBoolean()) {
|
||||
if (SettingsEnum.HIDE_REEL_BUTTON.getBoolean()) {
|
||||
AdRemoverAPI.HideViewWithLayout1dp(view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,20 +3,19 @@ package app.revanced.integrations.patches;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import app.revanced.integrations.adremover.AdRemoverAPI;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
|
||||
public class HideShortsButtonPatch {
|
||||
|
||||
//Used by app.revanced.patches.youtube.layout.shorts.button.patch.ShortsButtonRemoverPatch
|
||||
// Used by app.revanced.patches.youtube.layout.shorts.button.patch.ShortsButtonRemoverPatch
|
||||
public static void hideShortsButton(View view) {
|
||||
if (lastPivotTab != null && lastPivotTab.name() == "TAB_SHORTS") {
|
||||
boolean show = SettingsEnum.SHORTS_BUTTON_SHOWN.getBoolean();
|
||||
String message = show ? "Shorts button: shown" : "Shorts button: hidden";
|
||||
LogHelper.debug(HideShortsButtonPatch.class, message);
|
||||
if (!show) {
|
||||
view.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||
boolean hide = SettingsEnum.HIDE_SHORTS_BUTTON.getBoolean();
|
||||
String message = hide ? "Shorts button: hidden" : "Shorts button: shown";
|
||||
LogHelper.printDebug(() -> message);
|
||||
if (hide) {
|
||||
view.setVisibility(hide ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ public final class LithoFilterPatch {
|
||||
var path = pathBuilder.toString();
|
||||
if (path.isEmpty()) return false;
|
||||
|
||||
LogHelper.debug(LithoFilterPatch.class, String.format("Searching (ID: %s): %s", identifier, path));
|
||||
LogHelper.printDebug(() -> String.format("Searching (ID: %s): %s", identifier, path));
|
||||
|
||||
for (var filter : filters) {
|
||||
if (filter.filter(path, identifier)) return true;
|
||||
@@ -138,215 +138,3 @@ public final class LithoFilterPatch {
|
||||
}
|
||||
}
|
||||
|
||||
final class CommentsPatch extends Filter {
|
||||
|
||||
public CommentsPatch() {
|
||||
var comments = new BlockRule(SettingsEnum.HIDE_COMMENTS_SECTION, "video_metadata_carousel", "_comments");
|
||||
var previewComment = new BlockRule(
|
||||
SettingsEnum.HIDE_PREVIEW_COMMENT,
|
||||
"carousel_item",
|
||||
"comments_entry_point_teaser",
|
||||
"comments_entry_point_simplebox"
|
||||
);
|
||||
|
||||
this.pathRegister.registerAll(
|
||||
comments,
|
||||
previewComment
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean filter(String path, String _identifier) {
|
||||
if (!pathRegister.contains(path)) return false;
|
||||
|
||||
LogHelper.debug(CommentsPatch.class, "Blocked: " + path);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
final class ButtonsPatch extends Filter {
|
||||
private final BlockRule actionButtonsRule;
|
||||
private final BlockRule dislikeRule;
|
||||
private final BlockRule actionBarRule;
|
||||
|
||||
private final BlockRule[] rules;
|
||||
|
||||
public ButtonsPatch() {
|
||||
BlockRule like = new BlockRule(SettingsEnum.HIDE_LIKE_BUTTON, "|like_button");
|
||||
dislikeRule = new BlockRule(SettingsEnum.HIDE_DISLIKE_BUTTON, "dislike_button");
|
||||
BlockRule download = new BlockRule(SettingsEnum.HIDE_DOWNLOAD_BUTTON, "download_button");
|
||||
actionButtonsRule = new BlockRule(SettingsEnum.HIDE_ACTION_BUTTON, "ContainerType|video_action_button");
|
||||
BlockRule playlist = new BlockRule(SettingsEnum.HIDE_PLAYLIST_BUTTON, "save_to_playlist_button");
|
||||
rules = new BlockRule[]{like, dislikeRule, download, actionButtonsRule, playlist};
|
||||
|
||||
actionBarRule = new BlockRule(null, "video_action_bar");
|
||||
|
||||
this.pathRegister.registerAll(
|
||||
like,
|
||||
dislikeRule,
|
||||
download,
|
||||
playlist
|
||||
);
|
||||
}
|
||||
|
||||
private boolean hideActionBar() {
|
||||
for (BlockRule rule : rules) if (!rule.isEnabled()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filter(final String path, final String identifier) {
|
||||
if (hideActionBar() && actionBarRule.check(identifier).isBlocked()) return true;
|
||||
|
||||
var currentIsActionButton = actionButtonsRule.check(path).isBlocked();
|
||||
|
||||
if (dislikeRule.check(path).isBlocked()) ActionButton.doNotBlockCounter = 4;
|
||||
|
||||
if (currentIsActionButton && ActionButton.doNotBlockCounter-- > 0) {
|
||||
if (SettingsEnum.HIDE_SHARE_BUTTON.getBoolean()) {
|
||||
LogHelper.debug(ButtonsPatch.class, "Hiding share button");
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
if ((currentIsActionButton && ActionButton.doNotBlockCounter <= 0 && actionButtonsRule.isEnabled()) || pathRegister.contains(path)) {
|
||||
LogHelper.debug(ButtonsPatch.class, "Blocked: " + path);
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
static class ActionButton {
|
||||
public static int doNotBlockCounter = 4;
|
||||
}
|
||||
}
|
||||
|
||||
final class GeneralAdsPatch extends Filter {
|
||||
private final String[] IGNORE = {
|
||||
"home_video_with_context",
|
||||
"related_video_with_context",
|
||||
"comment_thread", // skip blocking anything in the comments
|
||||
"download_",
|
||||
"library_recent_shelf",
|
||||
"menu",
|
||||
"root",
|
||||
"-count",
|
||||
"-space",
|
||||
"-button",
|
||||
"playlist_add_to_option_wrapper" // do not block on "add to playlist" flyout menu
|
||||
};
|
||||
|
||||
private final BlockRule custom = new CustomBlockRule(
|
||||
SettingsEnum.ADREMOVER_CUSTOM_ENABLED,
|
||||
SettingsEnum.ADREMOVER_CUSTOM_REMOVAL
|
||||
);
|
||||
|
||||
public GeneralAdsPatch() {
|
||||
var communityPosts = new BlockRule(SettingsEnum.ADREMOVER_COMMUNITY_POSTS_REMOVAL, "post_base_wrapper");
|
||||
var communityGuidelines = new BlockRule(SettingsEnum.ADREMOVER_COMMUNITY_GUIDELINES_REMOVAL, "community_guidelines");
|
||||
var compactBanner = new BlockRule(SettingsEnum.ADREMOVER_COMPACT_BANNER_REMOVAL, "compact_banner");
|
||||
var inFeedSurvey = new BlockRule(SettingsEnum.ADREMOVER_FEED_SURVEY_REMOVAL, "in_feed_survey");
|
||||
var medicalPanel = new BlockRule(SettingsEnum.ADREMOVER_MEDICAL_PANEL_REMOVAL, "medical_panel");
|
||||
var paidContent = new BlockRule(SettingsEnum.ADREMOVER_PAID_CONTENT_REMOVAL, "paid_content_overlay");
|
||||
var merchandise = new BlockRule(SettingsEnum.ADREMOVER_MERCHANDISE_REMOVAL, "product_carousel");
|
||||
var infoPanel = new BlockRule(SettingsEnum.ADREMOVER_INFO_PANEL_REMOVAL, "publisher_transparency_panel", "single_item_information_panel");
|
||||
var suggestions = new BlockRule(SettingsEnum.ADREMOVER_SUGGESTIONS_REMOVAL, "horizontal_video_shelf");
|
||||
var latestPosts = new BlockRule(SettingsEnum.ADREMOVER_HIDE_LATEST_POSTS, "post_shelf");
|
||||
var channelGuidelines = new BlockRule(SettingsEnum.ADREMOVER_HIDE_CHANNEL_GUIDELINES, "channel_guidelines_entry_banner");
|
||||
var artistCard = new BlockRule(SettingsEnum.HIDE_ARTIST_CARD, "official_card");
|
||||
var selfSponsor = new BlockRule(SettingsEnum.ADREMOVER_SELF_SPONSOR_REMOVAL, "cta_shelf_card");
|
||||
var chapterTeaser = new BlockRule(SettingsEnum.ADREMOVER_CHAPTER_TEASER_REMOVAL, "expandable_metadata");
|
||||
var graySeparator = new BlockRule(SettingsEnum.ADREMOVER_GRAY_SEPARATOR,
|
||||
"cell_divider" // layout residue (gray line above the buttoned ad),
|
||||
);
|
||||
var buttonedAd = new BlockRule(SettingsEnum.ADREMOVER_BUTTONED_REMOVAL,
|
||||
"video_display_full_buttoned_layout",
|
||||
"full_width_square_image_layout",
|
||||
"_ad_with"
|
||||
);
|
||||
var generalAds = new BlockRule(
|
||||
SettingsEnum.ADREMOVER_GENERAL_ADS_REMOVAL,
|
||||
"ads_video_with_context",
|
||||
"banner_text_icon",
|
||||
"watch_metadata_app_promo",
|
||||
"video_display_full_layout"
|
||||
);
|
||||
var movieAds = new BlockRule(
|
||||
SettingsEnum.ADREMOVER_MOVIE_REMOVAL,
|
||||
"browsy_bar",
|
||||
"compact_movie",
|
||||
"horizontal_movie_shelf",
|
||||
"movie_and_show_upsell_card"
|
||||
);
|
||||
|
||||
this.pathRegister.registerAll(
|
||||
generalAds,
|
||||
buttonedAd,
|
||||
communityPosts,
|
||||
paidContent,
|
||||
suggestions,
|
||||
latestPosts,
|
||||
movieAds,
|
||||
chapterTeaser,
|
||||
communityGuidelines,
|
||||
compactBanner,
|
||||
inFeedSurvey,
|
||||
medicalPanel,
|
||||
merchandise,
|
||||
infoPanel,
|
||||
channelGuidelines,
|
||||
artistCard,
|
||||
selfSponsor
|
||||
);
|
||||
|
||||
var carouselAd = new BlockRule(SettingsEnum.ADREMOVER_GENERAL_ADS_REMOVAL,
|
||||
"carousel_ad"
|
||||
);
|
||||
var shorts = new BlockRule(SettingsEnum.ADREMOVER_SHORTS_REMOVAL,
|
||||
"reels_player_overlay",
|
||||
"shorts_shelf",
|
||||
"inline_shorts"
|
||||
);
|
||||
|
||||
this.identifierRegister.registerAll(
|
||||
shorts,
|
||||
graySeparator,
|
||||
carouselAd
|
||||
);
|
||||
}
|
||||
|
||||
public boolean filter(final String path, final String identifier) {
|
||||
BlockResult result;
|
||||
|
||||
if (custom.isEnabled() && custom.check(path).isBlocked())
|
||||
result = BlockResult.CUSTOM;
|
||||
else if (ReVancedUtils.containsAny(path, IGNORE))
|
||||
result = BlockResult.IGNORED;
|
||||
else if (pathRegister.contains(path) || identifierRegister.contains(identifier))
|
||||
result = BlockResult.DEFINED;
|
||||
else
|
||||
result = BlockResult.UNBLOCKED;
|
||||
|
||||
LogHelper.debug(
|
||||
GeneralAdsPatch.class,
|
||||
String.format("%s (ID: %s): %s", result.message, identifier, path)
|
||||
);
|
||||
|
||||
return result.filter;
|
||||
}
|
||||
|
||||
private enum BlockResult {
|
||||
UNBLOCKED(false, "Unblocked"),
|
||||
IGNORED(false, "Ignored"),
|
||||
DEFINED(true, "Blocked"),
|
||||
CUSTOM(true, "Custom");
|
||||
|
||||
final Boolean filter;
|
||||
final String message;
|
||||
|
||||
BlockResult(boolean filter, String message) {
|
||||
this.filter = filter;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.util.Log;
|
||||
import static app.revanced.integrations.utils.ReVancedUtils.getContext;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import app.revanced.integrations.utils.ThemeHelper;
|
||||
|
||||
public class LithoThemePatch {
|
||||
// color constants used in relation with litho components
|
||||
private static final int[] WHITECONSTANTS = {
|
||||
private static final int[] WHITE_VALUES = {
|
||||
-1, // comments chip background
|
||||
-394759, // music related results panel background
|
||||
-83886081, // video chapters list background
|
||||
};
|
||||
|
||||
private static final int[] DARKCONSTANTS = {
|
||||
private static final int[] DARK_VALUES = {
|
||||
-14145496, // explore drawer background
|
||||
-14606047, // comments chip background
|
||||
-15198184, // music related results panel background
|
||||
@@ -20,15 +22,51 @@ public class LithoThemePatch {
|
||||
-98492127 // video chapters list background
|
||||
};
|
||||
|
||||
// Used by app.revanced.patches.youtube.layout.theme.patch.LithoThemePatch
|
||||
public static int applyLithoTheme(int originalValue) {
|
||||
var isDarkTheme = ThemeHelper.isDarkTheme();
|
||||
// background colors
|
||||
private static int whiteColor = 0;
|
||||
private static int blackColor = 0;
|
||||
|
||||
if ((isDarkTheme && anyEquals(originalValue, DARKCONSTANTS)) || (!isDarkTheme && anyEquals(originalValue, WHITECONSTANTS)))
|
||||
return 0;
|
||||
// Used by app.revanced.patches.youtube.layout.theme.patch.LithoThemePatch
|
||||
/**
|
||||
* Change the color of Litho components.
|
||||
* If the color of the component matches one of the values, return the background color .
|
||||
*
|
||||
* @param originalValue The original color value.
|
||||
* @return The new or original color value
|
||||
*/
|
||||
public static int applyLithoTheme(int originalValue) {
|
||||
if (ThemeHelper.isDarkTheme()) {
|
||||
if (anyEquals(originalValue, DARK_VALUES)) return getBlackColor();
|
||||
} else {
|
||||
if (anyEquals(originalValue, WHITE_VALUES)) return getWhiteColor();
|
||||
}
|
||||
return originalValue;
|
||||
}
|
||||
|
||||
private static int getBlackColor() {
|
||||
if (blackColor == 0) blackColor = getColor("yt_black1");
|
||||
return blackColor;
|
||||
}
|
||||
|
||||
private static int getWhiteColor() {
|
||||
if (whiteColor == 0) whiteColor = getColor("yt_white1");
|
||||
return whiteColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the color for a color resource.
|
||||
*
|
||||
* @param name The color resource name.
|
||||
* @return The value of the color.
|
||||
*/
|
||||
private static int getColor(String name) {
|
||||
Context context = getContext();
|
||||
|
||||
return context != null ? context.getColor(context.getResources()
|
||||
.getIdentifier(name, "color", context.getPackageName())
|
||||
) : 0;
|
||||
}
|
||||
|
||||
private static boolean anyEquals(int value, int... of) {
|
||||
for (int v : of) if (value == v) return true;
|
||||
return false;
|
||||
|
||||
@@ -20,9 +20,9 @@ public class MicroGSupport {
|
||||
assert context != null;
|
||||
try {
|
||||
context.getPackageManager().getPackageInfo(MICROG_PACKAGE_NAME, PackageManager.GET_ACTIVITIES);
|
||||
LogHelper.debug(ReVancedUtils.class, "MicroG is installed on the device");
|
||||
LogHelper.printDebug(() -> "MicroG is installed on the device");
|
||||
} catch (PackageManager.NameNotFoundException exception) {
|
||||
LogHelper.printException(ReVancedUtils.class, "MicroG was not found", exception);
|
||||
LogHelper.printException(() -> ("MicroG was not found"), exception);
|
||||
Toast.makeText(context, str("microg_not_installed_warning"), Toast.LENGTH_LONG).show();
|
||||
|
||||
var intent = new Intent(Intent.ACTION_VIEW);
|
||||
|
||||
@@ -26,7 +26,7 @@ public class PlayerTypeHookPatch {
|
||||
final PlayerType newType = PlayerType.safeParseFromString(type.toString());
|
||||
if (newType != null) {
|
||||
PlayerType.setCurrent(newType);
|
||||
LogHelper.debug(PlayerTypeHookPatch.class, "YouTubePlayerOverlaysLayout player type was updated to " + newType);
|
||||
LogHelper.printDebug(() -> "YouTubePlayerOverlaysLayout player type was updated to " + newType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public final class VideoInformation {
|
||||
seekMethod = thisRef.getClass().getMethod(SEEK_METHOD_NAME, Long.TYPE);
|
||||
seekMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException ex) {
|
||||
LogHelper.debug(VideoInformation.class, "Failed to initialize: " + ex.getMessage());
|
||||
LogHelper.printDebug(() -> "Failed to initialize: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public final class VideoInformation {
|
||||
* @param length The length of the video in milliseconds.
|
||||
*/
|
||||
public static void setVideoLength(final long length) {
|
||||
LogHelper.debug(VideoInformation.class, "Setting current video length to " + length);
|
||||
LogHelper.printDebug(() -> "Setting current video length to " + length);
|
||||
videoLength = length;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public final class VideoInformation {
|
||||
* @param time The time of the video in milliseconds.
|
||||
*/
|
||||
public static void setVideoTime(final long time) {
|
||||
LogHelper.debug(VideoInformation.class, "Current video time " + time);
|
||||
LogHelper.printDebug(() -> "Current video time " + time);
|
||||
videoTime = time;
|
||||
}
|
||||
|
||||
@@ -67,15 +67,15 @@ public final class VideoInformation {
|
||||
public static void seekTo(final long millisecond) {
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
if (seekMethod == null) {
|
||||
LogHelper.debug(VideoInformation.class, "seekMethod was null");
|
||||
LogHelper.printDebug(() -> "seekMethod was null");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
LogHelper.debug(VideoInformation.class, "Seeking to " + millisecond);
|
||||
LogHelper.printDebug(() -> "Seeking to " + millisecond);
|
||||
seekMethod.invoke(playerController.get(), millisecond);
|
||||
} catch (Exception ex) {
|
||||
LogHelper.debug(VideoInformation.class, "Failed to seek: " + ex.getMessage());
|
||||
LogHelper.printDebug(() -> "Failed to seek: " + ex.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,9 +22,9 @@ public class VideoSpeedPatch {
|
||||
return speed;
|
||||
}
|
||||
ReVancedUtils.setNewVideo(false);
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed: " + speed);
|
||||
LogHelper.printDebug(() -> "Speed: " + speed);
|
||||
float preferredSpeed = SettingsEnum.PREFERRED_VIDEO_SPEED.getFloat();
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Preferred speed: " + preferredSpeed);
|
||||
LogHelper.printDebug(() -> "Preferred speed: " + preferredSpeed);
|
||||
if (preferredSpeed == -2.0f) {
|
||||
return speed;
|
||||
}
|
||||
@@ -48,18 +48,20 @@ public class VideoSpeedPatch {
|
||||
int index = 0;
|
||||
while (it.hasNext()) {
|
||||
float streamSpeed2 = it.next();
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed at index " + index + ": " + streamSpeed2);
|
||||
final int logIndex = index;
|
||||
LogHelper.printDebug(() -> "Speed at index " + logIndex + ": " + streamSpeed2);
|
||||
index++;
|
||||
}
|
||||
int speed3 = -1;
|
||||
for (float streamSpeed3 : iStreamSpeeds) {
|
||||
if (streamSpeed3 <= preferredSpeed) {
|
||||
speed3++;
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed loop at index " + speed3 + ": " + streamSpeed3);
|
||||
final int speed3ToLog = speed3;
|
||||
LogHelper.printDebug(() -> "Speed loop at index " + speed3ToLog + ": " + streamSpeed3);
|
||||
}
|
||||
}
|
||||
if (speed3 == -1) {
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed was not found");
|
||||
LogHelper.printDebug(() -> "Speed was not found");
|
||||
speed2 = 3;
|
||||
} else {
|
||||
speed2 = speed3;
|
||||
@@ -68,14 +70,13 @@ public class VideoSpeedPatch {
|
||||
Method[] declaredMethods = qInterface.getClass().getDeclaredMethods();
|
||||
for (Method method : declaredMethods) {
|
||||
if (method.getName().length() <= 2) {
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Method name: " + method.getName());
|
||||
LogHelper.printDebug(() -> "Method name: " + method.getName());
|
||||
try {
|
||||
try {
|
||||
method.invoke(qInterface, videoSpeeds[speed2]);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ignored) {
|
||||
} catch (Exception e6) {
|
||||
e = e6;
|
||||
LogHelper.printException(VideoSpeedPatch.class, e.getMessage());
|
||||
} catch (final Exception e6) {
|
||||
LogHelper.printException(() -> (e6.getMessage()));
|
||||
return speed2;
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
@@ -85,7 +86,7 @@ public class VideoSpeedPatch {
|
||||
} catch (Exception e10) {
|
||||
e = e10;
|
||||
}
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed changed to: " + speed2);
|
||||
LogHelper.printDebug(() -> "Speed changed to: " + speed2);
|
||||
return speed2;
|
||||
}
|
||||
|
||||
@@ -97,15 +98,15 @@ public class VideoSpeedPatch {
|
||||
int i = 0;
|
||||
if (!ReVancedUtils.isNewVideoStarted() || userChangedSpeed) {
|
||||
if (SettingsEnum.DEBUG.getBoolean() && userChangedSpeed) {
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Skipping speed change because user changed it: " + speed);
|
||||
LogHelper.printDebug(() -> "Skipping speed change because user changed it: " + speed);
|
||||
}
|
||||
userChangedSpeed = false;
|
||||
return -1.0f;
|
||||
}
|
||||
ReVancedUtils.setNewVideo(false);
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed: " + speed);
|
||||
LogHelper.printDebug(() -> "Speed: " + speed);
|
||||
float preferredSpeed = SettingsEnum.PREFERRED_VIDEO_SPEED.getFloat();
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Preferred speed: " + preferredSpeed);
|
||||
LogHelper.printDebug(() -> "Preferred speed: " + preferredSpeed);
|
||||
if (preferredSpeed == -2.0f) {
|
||||
return -1.0f;
|
||||
}
|
||||
@@ -136,7 +137,8 @@ public class VideoSpeedPatch {
|
||||
int index = 0;
|
||||
for (Float iStreamSpeed : iStreamSpeeds) {
|
||||
float streamSpeed2 = iStreamSpeed;
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed at index " + index + ": " + streamSpeed2);
|
||||
final int indexToLog = index;
|
||||
LogHelper.printDebug(() -> "Speed at index " + indexToLog + ": " + streamSpeed2);
|
||||
index++;
|
||||
}
|
||||
int newSpeedIndex = -1;
|
||||
@@ -144,18 +146,21 @@ public class VideoSpeedPatch {
|
||||
float streamSpeed3 = iStreamSpeed;
|
||||
if (streamSpeed3 <= preferredSpeed) {
|
||||
newSpeedIndex++;
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed loop at index " + newSpeedIndex + ": " + streamSpeed3);
|
||||
final int newSpeedIndexToLog = newSpeedIndex;
|
||||
LogHelper.printDebug(() -> "Speed loop at index " + newSpeedIndexToLog + ": " + streamSpeed3);
|
||||
}
|
||||
}
|
||||
if (newSpeedIndex == -1) {
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed was not found");
|
||||
LogHelper.printDebug(() -> "Speed was not found");
|
||||
newSpeedIndex = 3;
|
||||
}
|
||||
if (newSpeedIndex == speed) {
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Trying to set speed to what it already is, skipping...: " + newSpeedIndex);
|
||||
final int newSpeedIndexToLog = newSpeedIndex;
|
||||
LogHelper.printDebug(() -> "Trying to set speed to what it already is, skipping...: " + newSpeedIndexToLog);
|
||||
return -1.0f;
|
||||
}
|
||||
LogHelper.debug(VideoSpeedPatch.class, "Speed changed to: " + newSpeedIndex);
|
||||
final int newSpeedIndexToLog = newSpeedIndex;
|
||||
LogHelper.printDebug(() -> "Speed changed to: " + newSpeedIndexToLog);
|
||||
return getSpeedByIndex(newSpeedIndex);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class ZoomHapticsPatch {
|
||||
public static boolean shouldVibrate() {
|
||||
return !SettingsEnum.DISABLE_ZOOM_HAPTICS.getBoolean();
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ public class DownloadsPatch {
|
||||
* @param videoId The current video id
|
||||
*/
|
||||
public static void setVideoId(String videoId) {
|
||||
LogHelper.debug(DownloadsPatch.class, "newVideoLoaded - " + videoId);
|
||||
LogHelper.printDebug(() -> "newVideoLoaded - " + videoId);
|
||||
|
||||
DownloadsPatch.videoId = videoId;
|
||||
}
|
||||
|
||||
@@ -10,19 +10,19 @@ import app.revanced.integrations.utils.LogHelper;
|
||||
public class OldQualityLayoutPatch {
|
||||
public static void showOldQualityMenu(ListView listView)
|
||||
{
|
||||
if (!SettingsEnum.OLD_STYLE_QUALITY_SETTINGS.getBoolean()) return;
|
||||
if (!SettingsEnum.OLD_STYLE_VIDEO_QUALITY_PLAYER_SETTINGS.getBoolean()) return;
|
||||
|
||||
listView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
|
||||
@Override
|
||||
public void onChildViewAdded(View parent, View child) {
|
||||
LogHelper.debug(OldQualityLayoutPatch.class, "Added: " + child);
|
||||
LogHelper.printDebug(() -> "Added: " + child);
|
||||
|
||||
parent.setVisibility(View.GONE);
|
||||
|
||||
final var indexOfAdvancedQualityMenuItem = 4;
|
||||
if (listView.indexOfChild(child) != indexOfAdvancedQualityMenuItem) return;
|
||||
|
||||
LogHelper.debug(OldQualityLayoutPatch.class, "Found advanced menu: " + child);
|
||||
LogHelper.printDebug(() -> "Found advanced menu: " + child);
|
||||
|
||||
final var qualityItemMenuPosition = 4;
|
||||
listView.performItemClick(null, qualityItemMenuPosition, 0);
|
||||
|
||||
@@ -27,22 +27,22 @@ public class RememberVideoQualityPatch {
|
||||
try {
|
||||
SharedPrefHelper.saveString(context, SharedPrefHelper.SharedPrefNames.REVANCED_PREFS, "wifi_quality", defaultQuality + "");
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(RememberVideoQualityPatch.class, "Failed to change default WI-FI quality:" + ex);
|
||||
LogHelper.printException(() -> ("Failed to change default WI-FI quality:" + ex));
|
||||
Toast.makeText(context, "Failed to change default WI-FI quality:", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
LogHelper.debug(RememberVideoQualityPatch.class, "Changing default Wi-Fi quality to: " + defaultQuality);
|
||||
LogHelper.printDebug(() -> "Changing default Wi-Fi quality to: " + defaultQuality);
|
||||
Toast.makeText(context, "Changing default Wi-Fi quality to: " + defaultQuality, Toast.LENGTH_SHORT).show();
|
||||
} else if (isConnectedMobile(context)) {
|
||||
try {
|
||||
SharedPrefHelper.saveString(context, SharedPrefHelper.SharedPrefNames.REVANCED_PREFS, "mobile_quality", defaultQuality + "");
|
||||
} catch (Exception ex) {
|
||||
LogHelper.debug(RememberVideoQualityPatch.class, "Failed to change default mobile data quality" + ex);
|
||||
LogHelper.printDebug(() -> "Failed to change default mobile data quality" + ex);
|
||||
Toast.makeText(context, "Failed to change default mobile data quality", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
LogHelper.debug(RememberVideoQualityPatch.class, "Changing default mobile data quality to:" + defaultQuality);
|
||||
LogHelper.printDebug(() -> "Changing default mobile data quality to:" + defaultQuality);
|
||||
Toast.makeText(context, "Changing default mobile data quality to:" + defaultQuality, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
LogHelper.debug(RememberVideoQualityPatch.class, "No internet connection.");
|
||||
LogHelper.printDebug(() -> "No internet connection.");
|
||||
Toast.makeText(context, "No internet connection.", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
userChangedQuality = false;
|
||||
@@ -76,34 +76,37 @@ public class RememberVideoQualityPatch {
|
||||
int selectedQuality2 = qualities.length - selectedQuality1 + 1;
|
||||
index++;
|
||||
if (selectedQuality2 == index) {
|
||||
LogHelper.debug(RememberVideoQualityPatch.class, "Quality index is: " + index + " and corresponding value is: " + convertedQuality);
|
||||
final int indexToLog = index; // must be final for lambda
|
||||
LogHelper.printDebug(() -> "Quality index is: " + indexToLog + " and corresponding value is: " + convertedQuality);
|
||||
changeDefaultQuality(convertedQuality);
|
||||
return selectedQuality2;
|
||||
}
|
||||
}
|
||||
}
|
||||
newVideo = false;
|
||||
LogHelper.debug(RememberVideoQualityPatch.class, "Quality: " + quality);
|
||||
final int qualityToLog = quality;
|
||||
LogHelper.printDebug(() -> "Quality: " + qualityToLog);
|
||||
Context context = ReVancedUtils.getContext();
|
||||
if (context == null) {
|
||||
LogHelper.printException(RememberVideoQualityPatch.class, "Context is null or settings not initialized, returning quality: " + quality);
|
||||
LogHelper.printException(() -> ("Context is null or settings not initialized, returning quality: " + qualityToLog));
|
||||
return quality;
|
||||
}
|
||||
if (isConnectedWifi(context)) {
|
||||
preferredQuality = SharedPrefHelper.getInt(context, SharedPrefHelper.SharedPrefNames.REVANCED_PREFS, "wifi_quality", -2);
|
||||
LogHelper.debug(RememberVideoQualityPatch.class, "Wi-Fi connection detected, preferred quality: " + preferredQuality);
|
||||
LogHelper.printDebug(() -> "Wi-Fi connection detected, preferred quality: " + preferredQuality);
|
||||
} else if (isConnectedMobile(context)) {
|
||||
preferredQuality = SharedPrefHelper.getInt(context, SharedPrefHelper.SharedPrefNames.REVANCED_PREFS, "mobile_quality", -2);
|
||||
LogHelper.debug(RememberVideoQualityPatch.class, "Mobile data connection detected, preferred quality: " + preferredQuality);
|
||||
LogHelper.printDebug(() -> "Mobile data connection detected, preferred quality: " + preferredQuality);
|
||||
} else {
|
||||
LogHelper.debug(RememberVideoQualityPatch.class, "No Internet connection!");
|
||||
LogHelper.printDebug(() -> "No Internet connection!");
|
||||
return quality;
|
||||
}
|
||||
if (preferredQuality == -2) {
|
||||
return quality;
|
||||
}
|
||||
for (int streamQuality2 : iStreamQualities) {
|
||||
LogHelper.debug(RememberVideoQualityPatch.class, "Quality at index " + index + ": " + streamQuality2);
|
||||
final int indexToLog = index;
|
||||
LogHelper.printDebug(() -> "Quality at index " + indexToLog + ": " + streamQuality2);
|
||||
index++;
|
||||
}
|
||||
for (Integer iStreamQuality : iStreamQualities) {
|
||||
@@ -116,24 +119,25 @@ public class RememberVideoQualityPatch {
|
||||
return quality;
|
||||
}
|
||||
int qualityIndex = iStreamQualities.indexOf(quality);
|
||||
LogHelper.debug(RememberVideoQualityPatch.class, "Index of quality " + quality + " is " + qualityIndex);
|
||||
final int qualityToLog2 = quality;
|
||||
LogHelper.printDebug(() -> "Index of quality " + qualityToLog2 + " is " + qualityIndex);
|
||||
try {
|
||||
Class<?> cl = qInterface.getClass();
|
||||
Method m = cl.getMethod(qIndexMethod, Integer.TYPE);
|
||||
LogHelper.debug(RememberVideoQualityPatch.class, "Method is: " + qIndexMethod);
|
||||
LogHelper.printDebug(() -> "Method is: " + qIndexMethod);
|
||||
m.invoke(qInterface, iStreamQualities.get(qualityIndex));
|
||||
LogHelper.debug(RememberVideoQualityPatch.class, "Quality changed to: " + qualityIndex);
|
||||
LogHelper.printDebug(() -> "Quality changed to: " + qualityIndex);
|
||||
return qualityIndex;
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(RememberVideoQualityPatch.class, "Failed to set quality", ex);
|
||||
LogHelper.printException(() -> ("Failed to set quality"), ex);
|
||||
Toast.makeText(context, "Failed to set quality", Toast.LENGTH_SHORT).show();
|
||||
return qualityIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public static void userChangedQuality(int selectedQuality) {
|
||||
// Do not remember a **new** quality if REMEMBER_VIDEO_QUALITY is true
|
||||
if (SettingsEnum.REMEMBER_VIDEO_QUALITY.getBoolean()) return;
|
||||
// Do not remember a **new** quality if REMEMBER_VIDEO_QUALITY is false
|
||||
if (SettingsEnum.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.getBoolean() == false) return;
|
||||
|
||||
selectedQuality1 = selectedQuality;
|
||||
userChangedQuality = true;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package app.revanced.integrations.requests;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
@@ -24,38 +25,102 @@ public class Requester {
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the {@link HttpURLConnection}, and closes the underlying InputStream.
|
||||
*/
|
||||
public static String parseJson(HttpURLConnection connection) throws IOException {
|
||||
return parseJson(connection.getInputStream(), false);
|
||||
return parseInputStreamAndClose(connection.getInputStream(), true);
|
||||
}
|
||||
|
||||
public static String parseJson(InputStream inputStream, boolean isError) throws IOException {
|
||||
/**
|
||||
* Parse the {@link HttpURLConnection}, close the underlying InputStream, and disconnect.
|
||||
*
|
||||
* <b>Should only be used if other requests to the server are unlikely in the near future</b>
|
||||
*
|
||||
* @see #parseJson(HttpURLConnection)
|
||||
*/
|
||||
public static String parseJsonAndDisconnect(HttpURLConnection connection) throws IOException {
|
||||
String result = parseJson(connection);
|
||||
connection.disconnect();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the {@link HttpURLConnection}, and closes the underlying InputStream.
|
||||
*
|
||||
* @param stripNewLineCharacters if newline (\n) characters should be stripped from the InputStream
|
||||
*/
|
||||
public static String parseInputStreamAndClose(InputStream inputStream, boolean stripNewLineCharacters) throws IOException {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||
StringBuilder jsonBuilder = new StringBuilder();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
jsonBuilder.append(line);
|
||||
if (isError)
|
||||
if (!stripNewLineCharacters)
|
||||
jsonBuilder.append("\n");
|
||||
}
|
||||
inputStream.close();
|
||||
return jsonBuilder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the {@link HttpURLConnection}, and closes the underlying InputStream.
|
||||
*/
|
||||
public static String parseErrorJson(HttpURLConnection connection) throws IOException {
|
||||
return parseJson(connection.getErrorStream(), true);
|
||||
return parseInputStreamAndClose(connection.getErrorStream(), false);
|
||||
}
|
||||
|
||||
public static JSONObject getJSONObject(HttpURLConnection connection) throws Exception {
|
||||
return new JSONObject(parseJsonAndDisconnect(connection));
|
||||
}
|
||||
|
||||
public static JSONArray getJSONArray(HttpURLConnection connection) throws Exception {
|
||||
return new JSONArray(parseJsonAndDisconnect(connection));
|
||||
}
|
||||
|
||||
private static String parseJsonAndDisconnect(HttpURLConnection connection) throws IOException {
|
||||
String json = parseJson(connection);
|
||||
/**
|
||||
* Parse the {@link HttpURLConnection}, close the underlying InputStream, and disconnect.
|
||||
*
|
||||
* <b>Should only be used if other requests to the server are unlikely in the near future</b>
|
||||
*
|
||||
* @see #parseErrorJson(HttpURLConnection)
|
||||
*/
|
||||
public static String parseErrorJsonAndDisconnect(HttpURLConnection connection) throws IOException {
|
||||
String result = parseErrorJson(connection);
|
||||
connection.disconnect();
|
||||
return json;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the {@link HttpURLConnection}, and closes the underlying InputStream.
|
||||
*/
|
||||
public static JSONObject parseJSONObject(HttpURLConnection connection) throws JSONException, IOException {
|
||||
return new JSONObject(parseJson(connection));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the {@link HttpURLConnection}, close the underlying InputStream, and disconnect.
|
||||
*
|
||||
* <b>Should only be used if other requests to the server are unlikely in the near future</b>
|
||||
*
|
||||
* @see #parseJSONObject(HttpURLConnection)
|
||||
*/
|
||||
public static JSONObject parseJSONObjectAndDisconnect(HttpURLConnection connection) throws JSONException, IOException {
|
||||
JSONObject object = parseJSONObject(connection);
|
||||
connection.disconnect();
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the {@link HttpURLConnection}, and closes the underlying InputStream.
|
||||
*/
|
||||
public static JSONArray parseJSONArray(HttpURLConnection connection) throws JSONException, IOException {
|
||||
return new JSONArray(parseJson(connection));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the {@link HttpURLConnection}, close the underlying InputStream, and disconnect.
|
||||
*
|
||||
* <b>Should only be used if other requests to the server are unlikely in the near future</b>
|
||||
*
|
||||
* @see #parseJSONArray(HttpURLConnection)
|
||||
*/
|
||||
public static JSONArray parseJSONArrayAndDisconnect(HttpURLConnection connection) throws JSONException, IOException {
|
||||
JSONArray array = parseJSONArray(connection);
|
||||
connection.disconnect();
|
||||
return array;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
package app.revanced.integrations.returnyoutubedislike;
|
||||
|
||||
|
||||
import android.util.Base64;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.returnyoutubedislike.requests.ReturnYouTubeDislikeApi;
|
||||
|
||||
public class Registration {
|
||||
|
||||
// https://stackoverflow.com/a/157202
|
||||
private final String AB = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
private SecureRandom rnd = new SecureRandom();
|
||||
private String userId;
|
||||
|
||||
public String getUserId() {
|
||||
return userId != null ? userId : fetchUserId();
|
||||
}
|
||||
|
||||
public void saveUserId(String userId) {
|
||||
SettingsEnum.RYD_USER_ID.saveValue(userId);
|
||||
}
|
||||
|
||||
public static String solvePuzzle(String challenge, int difficulty) {
|
||||
byte[] decodedChallenge = Base64.decode(challenge, Base64.NO_WRAP);
|
||||
|
||||
byte[] buffer = new byte[20];
|
||||
for (int i = 4; i < 20; i++) {
|
||||
buffer[i] = decodedChallenge[i - 4];
|
||||
}
|
||||
|
||||
try {
|
||||
int maxCount = (int) (Math.pow(2, difficulty + 1) * 5);
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-512");
|
||||
for (int i = 0; i < maxCount; i++) {
|
||||
buffer[0] = (byte) i;
|
||||
buffer[1] = (byte) (i >> 8);
|
||||
buffer[2] = (byte) (i >> 16);
|
||||
buffer[3] = (byte) (i >> 24);
|
||||
byte[] messageDigest = md.digest(buffer);
|
||||
|
||||
if (countLeadingZeroes(messageDigest) >= difficulty) {
|
||||
String encode = Base64.encodeToString(new byte[]{buffer[0], buffer[1], buffer[2], buffer[3]}, Base64.NO_WRAP);
|
||||
return encode;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(Registration.class, "Failed to solve puzzle", ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String register() {
|
||||
String userId = randomString(36);
|
||||
LogHelper.debug(Registration.class, "Trying to register the following userId: " + userId);
|
||||
return ReturnYouTubeDislikeApi.register(userId, this);
|
||||
}
|
||||
|
||||
private String randomString(int len) {
|
||||
StringBuilder sb = new StringBuilder(len);
|
||||
for (int i = 0; i < len; i++)
|
||||
sb.append(AB.charAt(rnd.nextInt(AB.length())));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String fetchUserId() {
|
||||
this.userId = SettingsEnum.RYD_USER_ID.getString();
|
||||
if (this.userId == null) {
|
||||
this.userId = register();
|
||||
}
|
||||
|
||||
return this.userId;
|
||||
}
|
||||
|
||||
private static int countLeadingZeroes(byte[] uInt8View) {
|
||||
int zeroes = 0;
|
||||
int value = 0;
|
||||
for (int i = 0; i < uInt8View.length; i++) {
|
||||
value = uInt8View[i] & 0xFF;
|
||||
if (value == 0) {
|
||||
zeroes += 8;
|
||||
} else {
|
||||
int count = 1;
|
||||
if (value >>> 4 == 0) {
|
||||
count += 4;
|
||||
value <<= 4;
|
||||
}
|
||||
if (value >>> 6 == 0) {
|
||||
count += 2;
|
||||
value <<= 2;
|
||||
}
|
||||
zeroes += count - (value >>> 7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return zeroes;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,18 +0,0 @@
|
||||
package app.revanced.integrations.returnyoutubedislike;
|
||||
|
||||
import app.revanced.integrations.utils.LogHelper;
|
||||
import app.revanced.integrations.returnyoutubedislike.requests.ReturnYouTubeDislikeApi;
|
||||
|
||||
public class Voting {
|
||||
private Registration registration;
|
||||
|
||||
public Voting(Registration registration) {
|
||||
this.registration = registration;
|
||||
}
|
||||
|
||||
public boolean sendVote(String videoId, ReturnYouTubeDislike.Vote vote) {
|
||||
String userId = registration.getUserId();
|
||||
LogHelper.debug(Voting.class, "Trying to vote the following video: " + videoId + " with vote " + vote + " and userId: " + userId);
|
||||
return ReturnYouTubeDislikeApi.sendVote(videoId, userId, vote.value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package app.revanced.integrations.returnyoutubedislike.requests;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* ReturnYouTubeDislike API estimated like/dislike/view counts.
|
||||
*
|
||||
* ReturnYouTubeDislike does not guarantee when the counts are updated.
|
||||
* So these values may lag behind what YouTube shows.
|
||||
*/
|
||||
public final class RYDVoteData {
|
||||
|
||||
public final String videoId;
|
||||
|
||||
/**
|
||||
* Estimated number of views
|
||||
*/
|
||||
public final long viewCount;
|
||||
|
||||
/**
|
||||
* Estimated like count
|
||||
*/
|
||||
public final long likeCount;
|
||||
|
||||
/**
|
||||
* Estimated dislike count
|
||||
*/
|
||||
public final long dislikeCount;
|
||||
|
||||
/**
|
||||
* Estimated percentage of likes for all votes. Value has range of [0, 1]
|
||||
*
|
||||
* A video with 400 positive votes, and 100 negative votes, has a likePercentage of 0.8
|
||||
*/
|
||||
public final float likePercentage;
|
||||
|
||||
/**
|
||||
* Estimated percentage of dislikes for all votes. Value has range of [0, 1]
|
||||
*
|
||||
* A video with 400 positive votes, and 100 negative votes, has a dislikePercentage of 0.2
|
||||
*/
|
||||
public final float dislikePercentage;
|
||||
|
||||
/**
|
||||
* @throws JSONException if JSON parse error occurs, or if the values make no sense (ie: negative values)
|
||||
*/
|
||||
public RYDVoteData(JSONObject json) throws JSONException {
|
||||
Objects.requireNonNull(json);
|
||||
videoId = json.getString("id");
|
||||
viewCount = json.getLong("viewCount");
|
||||
likeCount = json.getLong("likes");
|
||||
dislikeCount = json.getLong("dislikes");
|
||||
if (likeCount < 0 || dislikeCount < 0 || viewCount < 0) {
|
||||
throw new JSONException("Unexpected JSON values: " + json);
|
||||
}
|
||||
likePercentage = (likeCount == 0 ? 0 : (float)likeCount / (likeCount + dislikeCount));
|
||||
dislikePercentage = (dislikeCount == 0 ? 0 : (float)dislikeCount / (likeCount + dislikeCount));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RYDVoteData{"
|
||||
+ "videoId=" + videoId
|
||||
+ ", viewCount=" + viewCount
|
||||
+ ", likeCount=" + likeCount
|
||||
+ ", dislikeCount=" + dislikeCount
|
||||
+ ", likePercentage=" + likePercentage
|
||||
+ ", dislikePercentage=" + dislikePercentage
|
||||
+ '}';
|
||||
}
|
||||
|
||||
// equals and hashcode is not implemented (currently not needed)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,15 +3,26 @@ package app.revanced.integrations.returnyoutubedislike.requests;
|
||||
import static app.revanced.integrations.requests.Route.Method.GET;
|
||||
import static app.revanced.integrations.requests.Route.Method.POST;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
|
||||
import app.revanced.integrations.requests.Requester;
|
||||
import app.revanced.integrations.requests.Route;
|
||||
|
||||
public class ReturnYouTubeDislikeRoutes {
|
||||
public static final Route SEND_VOTE = new Route(POST, "interact/vote");
|
||||
public static final Route CONFIRM_VOTE = new Route(POST, "interact/confirmVote");
|
||||
public static final Route GET_DISLIKES = new Route(GET, "votes?videoId={video_id}");
|
||||
public static final Route GET_REGISTRATION = new Route(GET, "puzzle/registration?userId={user_id}");
|
||||
public static final Route CONFIRM_REGISTRATION = new Route(POST, "puzzle/registration?userId={user_id}");
|
||||
class ReturnYouTubeDislikeRoutes {
|
||||
static final String RYD_API_URL = "https://returnyoutubedislikeapi.com/";
|
||||
|
||||
static final Route SEND_VOTE = new Route(POST, "interact/vote");
|
||||
static final Route CONFIRM_VOTE = new Route(POST, "interact/confirmVote");
|
||||
static final Route GET_DISLIKES = new Route(GET, "votes?videoId={video_id}");
|
||||
static final Route GET_REGISTRATION = new Route(GET, "puzzle/registration?userId={user_id}");
|
||||
static final Route CONFIRM_REGISTRATION = new Route(POST, "puzzle/registration?userId={user_id}");
|
||||
|
||||
private ReturnYouTubeDislikeRoutes() {
|
||||
}
|
||||
|
||||
static HttpURLConnection getRYDConnectionFromRoute(Route route, String... params) throws IOException {
|
||||
return Requester.getConnectionFromRoute(RYD_API_URL, route, params);
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user