From 83987747e67541cd44221ede8c4020baba36c7b8 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Tue, 26 Sep 2023 05:09:01 +0400 Subject: [PATCH] fix(YouTube - Client spoof): fix storyboard fetched out of order (#481) --- .../patches/spoof/SpoofSignaturePatch.java | 39 ++++++++++++++----- .../requests/StoryBoardRendererRequester.java | 11 +++--- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/patches/spoof/SpoofSignaturePatch.java b/app/src/main/java/app/revanced/integrations/patches/spoof/SpoofSignaturePatch.java index a86f30b6..b84c6636 100644 --- a/app/src/main/java/app/revanced/integrations/patches/spoof/SpoofSignaturePatch.java +++ b/app/src/main/java/app/revanced/integrations/patches/spoof/SpoofSignaturePatch.java @@ -5,10 +5,16 @@ import static app.revanced.integrations.utils.ReVancedUtils.containsAny; import androidx.annotation.Nullable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + import app.revanced.integrations.patches.VideoInformation; import app.revanced.integrations.settings.SettingsEnum; import app.revanced.integrations.shared.PlayerType; import app.revanced.integrations.utils.LogHelper; +import app.revanced.integrations.utils.ReVancedUtils; /** @noinspection unused*/ public class SpoofSignaturePatch { @@ -43,8 +49,7 @@ public class SpoofSignaturePatch { */ private static volatile String currentVideoId; - @Nullable - private static volatile StoryboardRenderer renderer; + private static volatile Future rendererFuture; /** * Injection point. @@ -78,13 +83,27 @@ public class SpoofSignaturePatch { String videoId = VideoInformation.getVideoId(); if (!videoId.equals(currentVideoId)) { currentVideoId = videoId; - renderer = fetchStoryboardRenderer(videoId); - LogHelper.printDebug(() -> "Fetched: " + renderer); + rendererFuture = ReVancedUtils.submitOnBackgroundThread(() -> fetchStoryboardRenderer(videoId)); } return INCOGNITO_PARAMETERS; } + @Nullable + private static StoryboardRenderer getRenderer() { + if (rendererFuture != null) { + try { + return rendererFuture.get(5000, TimeUnit.MILLISECONDS); + } catch (TimeoutException ex) { + LogHelper.printDebug(() -> "Could not get renderer (get timed out)"); + } catch (ExecutionException | InterruptedException ex) { + // Should never happen. + LogHelper.printException(() -> "Could not get renderer", ex); + } + } + return null; + } + /** * Injection point. */ @@ -100,10 +119,10 @@ public class SpoofSignaturePatch { public static String getStoryboardRendererSpec(String originalStoryboardRendererSpec) { if (!SettingsEnum.SPOOF_SIGNATURE.getBoolean()) return originalStoryboardRendererSpec; - StoryboardRenderer currentRenderer = renderer; - if (currentRenderer == null) return originalStoryboardRendererSpec; + StoryboardRenderer renderer = getRenderer(); + if (renderer == null) return originalStoryboardRendererSpec; - return currentRenderer.getSpec(); + return renderer.getSpec(); } /** @@ -112,10 +131,10 @@ public class SpoofSignaturePatch { public static int getRecommendedLevel(int originalLevel) { if (!SettingsEnum.SPOOF_SIGNATURE.getBoolean()) return originalLevel; - StoryboardRenderer currentRenderer = renderer; - if (currentRenderer == null) return originalLevel; + StoryboardRenderer renderer = getRenderer(); + if (renderer == null) return originalLevel; - return currentRenderer.getRecommendedLevel(); + return renderer.getRecommendedLevel(); } } diff --git a/app/src/main/java/app/revanced/integrations/patches/spoof/requests/StoryBoardRendererRequester.java b/app/src/main/java/app/revanced/integrations/patches/spoof/requests/StoryBoardRendererRequester.java index 4e8dcddb..38369d81 100644 --- a/app/src/main/java/app/revanced/integrations/patches/spoof/requests/StoryBoardRendererRequester.java +++ b/app/src/main/java/app/revanced/integrations/patches/spoof/requests/StoryBoardRendererRequester.java @@ -53,12 +53,13 @@ public class StoryBoardRendererRequester { ? "playerLiveStoryboardSpecRenderer" : "playerStoryboardSpecRenderer"; - final var renderer = storyboards.getJSONObject(storyboardsRendererTag); - - return new StoryboardRenderer( - renderer.getString("spec"), - renderer.getInt("recommendedLevel") + final var rendererElement = storyboards.getJSONObject(storyboardsRendererTag); + StoryboardRenderer renderer = new StoryboardRenderer( + rendererElement.getString("spec"), + rendererElement.getInt("recommendedLevel") ); + LogHelper.printDebug(() -> "Fetched: " + renderer); + return renderer; } else { LogHelper.printException(() -> "API not available: " + responseCode); connection.disconnect();