From 6c5ff0c1b6176b2c15ca64b42693b518eb004225 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 31 May 2024 00:16:36 +0900 Subject: [PATCH] feat(YouTube - Spoof client): Add `Show in Stats for nerds` settings --- .../patches/misc/SpoofClientPatch.java | 39 ++++++++++++++++--- .../patches/misc/requests/PlayerRoutes.java | 4 ++ .../youtube/settings/Settings.java | 1 + 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/misc/SpoofClientPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/SpoofClientPatch.java index 62e6f283fa..2bfac14862 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/misc/SpoofClientPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/SpoofClientPatch.java @@ -4,6 +4,7 @@ import static app.revanced.integrations.youtube.patches.misc.requests.LiveStreamRendererRequester.getLiveStreamRenderer; import android.net.Uri; +import android.text.TextUtils; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -45,11 +46,16 @@ public class SpoofClientPatch { private static final String UNREACHABLE_HOST_URI_STRING = "https://127.0.0.0"; private static final Uri UNREACHABLE_HOST_URI = Uri.parse(UNREACHABLE_HOST_URI_STRING); + /** + * Last spoofed client type. + */ + private static volatile ClientType lastSpoofedClientType; + /** * Last video id loaded. Used to prevent reloading the same spec multiple times. */ - @Nullable - private static volatile String lastPlayerResponseVideoId; + @NonNull + private static volatile String lastPlayerResponseVideoId = ""; @Nullable private static volatile Future rendererFuture; @@ -113,18 +119,22 @@ public static String blockInitPlaybackRequest(String originalUrlString) { private static ClientType getSpoofClientType() { if (isShortsOrClips) { - return Settings.SPOOF_CLIENT_SHORTS.get(); + lastSpoofedClientType = Settings.SPOOF_CLIENT_SHORTS.get(); + return lastSpoofedClientType; } LiveStreamRenderer renderer = getRenderer(false); if (renderer != null) { if (renderer.isLive) { - return Settings.SPOOF_CLIENT_LIVESTREAM.get(); + lastSpoofedClientType = Settings.SPOOF_CLIENT_LIVESTREAM.get(); + return lastSpoofedClientType; } if (!renderer.playabilityOk) { - return Settings.SPOOF_CLIENT_FALLBACK.get(); + lastSpoofedClientType = Settings.SPOOF_CLIENT_FALLBACK.get(); + return lastSpoofedClientType; } } - return Settings.SPOOF_CLIENT_GENERAL.get(); + lastSpoofedClientType = Settings.SPOOF_CLIENT_GENERAL.get(); + return lastSpoofedClientType; } /** @@ -174,6 +184,23 @@ public static boolean enablePlayerGesture(boolean original) { return SPOOF_CLIENT_ENABLED || original; } + /** + * Injection point. + */ + public static String appendSpoofedClient(String videoFormat) { + try { + if (SPOOF_CLIENT_ENABLED && Settings.SPOOF_CLIENT_STATS_FOR_NERDS.get() + && !TextUtils.isEmpty(videoFormat)) { + // Force LTR layout, to match the same LTR video time/length layout YouTube uses for all languages + return "\u202D" + videoFormat + String.format("\u2009(%s)", lastSpoofedClientType.friendlyName); // u202D = left to right override + } + } catch (Exception ex) { + Logger.printException(() -> "appendSpoofedClient failure", ex); + } + + return videoFormat; + } + /** * Injection point. */ diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/misc/requests/PlayerRoutes.java b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/requests/PlayerRoutes.java index a84ed4d93f..b1726d3d9d 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/misc/requests/PlayerRoutes.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/misc/requests/PlayerRoutes.java @@ -1,5 +1,7 @@ package app.revanced.integrations.youtube.patches.misc.requests; +import static app.revanced.integrations.shared.utils.StringRef.str; + import android.os.Build; import org.json.JSONException; @@ -372,6 +374,7 @@ public enum ClientType { // No suitable model name was found for WEB. Use the model name of ANDROID. WEB(1, ANDROID_DEVICE_MODEL, WEB_CLIENT_VERSION, WEB_INNER_TUBE_BODY, WEB_USER_AGENT); + public final String friendlyName; public final int id; public final String model; public final String version; @@ -380,6 +383,7 @@ public enum ClientType { ClientType(int id, String model, String version, String innerTubeBody, String userAgent) { + this.friendlyName = str("revanced_spoof_client_options_entry_" + name().toLowerCase()); this.id = id; this.model = model; this.version = version; diff --git a/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java b/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java index ef1a2d4e02..fc6bfc802a 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java +++ b/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java @@ -421,6 +421,7 @@ public class Settings extends BaseSettings { public static final BooleanSetting DISABLE_QUIC_PROTOCOL = new BooleanSetting("revanced_disable_quic_protocol", FALSE, true); public static final BooleanSetting SPOOF_FORMAT_STREAM_DATA = new BooleanSetting("revanced_spoof_format_stream_data", FALSE, true); public static final BooleanSetting SPOOF_CLIENT = new BooleanSetting("revanced_spoof_client", FALSE, true); + public static final BooleanSetting SPOOF_CLIENT_STATS_FOR_NERDS = new BooleanSetting("revanced_spoof_client_stats_for_nerds", TRUE, parent(SPOOF_CLIENT)); public static final EnumSetting SPOOF_CLIENT_GENERAL = new EnumSetting<>("revanced_spoof_client_general", ClientType.IOS); public static final EnumSetting SPOOF_CLIENT_LIVESTREAM = new EnumSetting<>("revanced_spoof_client_livestream",