Skip to content

Commit

Permalink
fix(Spoof Streaming Data): Use DroidGuard PoToken to pass into IOS cl…
Browse files Browse the repository at this point in the history
…ient
  • Loading branch information
YT-Advanced committed Jan 1, 2025
1 parent 234695d commit 9c3b574
Show file tree
Hide file tree
Showing 6 changed files with 16 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,6 @@ object AppClient {
*/
@JvmField
val clientVersion: String,
/**
* If the client can access the API logged in.
*/
@JvmField
val canLogin: Boolean? = true,
/**
* If a poToken should be used.
*/
Expand Down Expand Up @@ -259,7 +254,6 @@ object AppClient {
osVersion = OS_VERSION_IOS,
userAgent = USER_AGENT_IOS,
clientVersion = CLIENT_VERSION_IOS,
canLogin = false,
usePoToken = true,
friendlyName = if (forceAVC())
"iOS Force AVC"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@
@SuppressWarnings("unused")
public class SpoofStreamingDataPatch {
private static final boolean SPOOF_STREAMING_DATA = SpoofStreamingData() && BaseSettings.SPOOF_STREAMING_DATA.get();
private static final String PO_TOKEN =
BaseSettings.SPOOF_STREAMING_DATA_PO_TOKEN.get();
private static final String VISITOR_DATA =
BaseSettings.SPOOF_STREAMING_DATA_VISITOR_DATA.get();

/**
* Any unreachable ip address. Used to intentionally fail requests.
Expand Down Expand Up @@ -144,7 +140,7 @@ public static void fetchStreams(String url, Map<String, String> requestHeaders)
return;
}

StreamingDataRequest.fetchRequest(id, requestHeaders, VISITOR_DATA, PO_TOKEN, droidGuardPoToken);
StreamingDataRequest.fetchRequest(id, requestHeaders, droidGuardPoToken);
} catch (Exception ex) {
Logger.printException(() -> "buildRequest failure", ex);
}
Expand Down Expand Up @@ -222,7 +218,6 @@ public static long getApproxDurationMs(String videoId) {
final Long approxDurationMs = approxDurationMsMap.get(videoId);
if (approxDurationMs != null) {
Logger.printDebug(() -> "Replacing video length: " + approxDurationMs + " for videoId: " + videoId);
approxDurationMsMap.remove(videoId);
return approxDurationMs;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,7 @@ public static JSONObject createInnertubeBody(ClientType clientType) {
client.put("deviceMake", "Apple");
client.put("osName", "iOS");
}
if (!clientType.canLogin) {
client.put("hl", LOCALE_LANGUAGE);
}
client.put("hl", LOCALE_LANGUAGE);

JSONObject context = new JSONObject();
context.put("client", client);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,10 @@
public class StreamingDataRequest {

private static final ClientType[] CLIENT_ORDER_TO_USE;
private static final String AUTHORIZATION_HEADER = "Authorization";
private static final String VISITOR_ID_HEADER = "X-Goog-Visitor-Id";
private static final String[] REQUEST_HEADER_KEYS = {
AUTHORIZATION_HEADER, // Available only to logged-in users.
"Authorization", // Available only to logged-in users.
"X-GOOG-API-FORMAT-VERSION",
VISITOR_ID_HEADER
"X-Goog-Visitor-Id"
};
private static ClientType lastSpoofedClientType;

Expand Down Expand Up @@ -106,17 +104,15 @@ public static String getLastSpoofedClientName() {
private final String videoId;
private final Future<ByteBuffer> future;

private StreamingDataRequest(String videoId, Map<String, String> playerHeaders, String visitorId,
String botGuardPoToken, String droidGuardPoToken) {
private StreamingDataRequest(String videoId, Map<String, String> playerHeaders, String droidGuardPoToken) {
Objects.requireNonNull(playerHeaders);
this.videoId = videoId;
this.future = Utils.submitOnBackgroundThread(() -> fetch(videoId, playerHeaders, visitorId, botGuardPoToken, droidGuardPoToken));
this.future = Utils.submitOnBackgroundThread(() -> fetch(videoId, playerHeaders, droidGuardPoToken));
}

public static void fetchRequest(String videoId, Map<String, String> fetchHeaders, String visitorId,
String botGuardPoToken, String droidGuardPoToken) {
public static void fetchRequest(String videoId, Map<String, String> fetchHeaders, String droidGuardPoToken) {
// Always fetch, even if there is an existing request for the same video.
cache.put(videoId, new StreamingDataRequest(videoId, fetchHeaders, visitorId, botGuardPoToken, droidGuardPoToken));
cache.put(videoId, new StreamingDataRequest(videoId, fetchHeaders, droidGuardPoToken));
}

@Nullable
Expand All @@ -129,8 +125,8 @@ private static void handleConnectionError(String toastMessage, @Nullable Excepti
}

@Nullable
private static HttpURLConnection send(ClientType clientType, String videoId, Map<String, String> playerHeaders,
String visitorId, String botGuardPoToken, String droidGuardPoToken) {
private static HttpURLConnection send(ClientType clientType, String videoId,
Map<String, String> playerHeaders, String droidGuardPoToken) {
Objects.requireNonNull(clientType);
Objects.requireNonNull(videoId);
Objects.requireNonNull(playerHeaders);
Expand All @@ -145,36 +141,15 @@ private static HttpURLConnection send(ClientType clientType, String videoId, Map

for (String key : REQUEST_HEADER_KEYS) {
String value = playerHeaders.get(key);
if (value != null) {
if (key.equals(AUTHORIZATION_HEADER)) {
if (!clientType.canLogin) {
Logger.printDebug(() -> "Not including request header: " + key);
continue;
}
}
if (key.equals(VISITOR_ID_HEADER) &&
clientType.usePoToken &&
!botGuardPoToken.isEmpty() &&
!visitorId.isEmpty()) {
String originalVisitorId = value;
Logger.printDebug(() -> "Original visitor id:\n" + originalVisitorId);
Logger.printDebug(() -> "Replaced visitor id:\n" + visitorId);
value = visitorId;
}

connection.setRequestProperty(key, value);
}
if (value != null) connection.setRequestProperty(key, value);
}

JSONObject innerTubeBodyJson = PlayerRoutes.createInnertubeBody(clientType);
if (clientType.usePoToken && !botGuardPoToken.isEmpty() && !visitorId.isEmpty()) {
if (clientType.usePoToken && !droidGuardPoToken.isEmpty()) {
JSONObject serviceIntegrityDimensions = new JSONObject();
serviceIntegrityDimensions.put("poToken", botGuardPoToken);
serviceIntegrityDimensions.put("poToken", droidGuardPoToken);
innerTubeBodyJson.put("serviceIntegrityDimensions", serviceIntegrityDimensions);
if (!droidGuardPoToken.isEmpty()) {
Logger.printDebug(() -> "Original poToken (droidGuardPoToken):\n" + droidGuardPoToken);
}
Logger.printDebug(() -> "Replaced poToken (botGuardPoToken):\n" + botGuardPoToken);
Logger.printDebug(() -> "Replaced poToken (droidGuardPoToken):\n" + droidGuardPoToken);
}

String innerTubeBody = String.format(innerTubeBodyJson.toString(), videoId);
Expand Down Expand Up @@ -203,13 +178,12 @@ private static HttpURLConnection send(ClientType clientType, String videoId, Map
return null;
}

private static ByteBuffer fetch(String videoId, Map<String, String> playerHeaders, String visitorId,
String botGuardPoToken, String droidGuardPoToken) {
private static ByteBuffer fetch(String videoId, Map<String, String> playerHeaders, String droidGuardPoToken) {
lastSpoofedClientType = null;

// Retry with different client if empty response body is received.
for (ClientType clientType : CLIENT_ORDER_TO_USE) {
HttpURLConnection connection = send(clientType, videoId, playerHeaders, visitorId, botGuardPoToken, droidGuardPoToken);
HttpURLConnection connection = send(clientType, videoId, playerHeaders, droidGuardPoToken);
if (connection != null) {
try {
// gzip encoding doesn't response with content length (-1),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ public class BaseSettings {
// Client type must be last spoof setting due to cyclic references.
public static final EnumSetting<ClientType> SPOOF_STREAMING_DATA_TYPE = new EnumSetting<>("revanced_spoof_streaming_data_type", ClientType.ANDROID_VR, true);

public static final StringSetting SPOOF_STREAMING_DATA_PO_TOKEN = new StringSetting("revanced_spoof_streaming_data_po_token", "", true);
public static final StringSetting SPOOF_STREAMING_DATA_VISITOR_DATA = new StringSetting("revanced_spoof_streaming_data_visitor_data", "", true);

/**
* @noinspection DeprecatedIsStillUsed
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -791,12 +791,6 @@
<app.revanced.extension.youtube.settings.preference.SpoofStreamingDataSideEffectsPreference android:title="@string/revanced_spoof_streaming_data_side_effects_title" />
<SwitchPreference android:title="@string/revanced_spoof_streaming_data_ios_force_avc_title" android:key="revanced_spoof_streaming_data_ios_force_avc" android:summaryOn="@string/revanced_spoof_streaming_data_ios_force_avc_summary_on" android:summaryOff="@string/revanced_spoof_streaming_data_ios_force_avc_summary_off" android:dependency="revanced_spoof_streaming_data" />
<SwitchPreference android:title="@string/revanced_spoof_streaming_data_stats_for_nerds_title" android:key="revanced_spoof_streaming_data_stats_for_nerds" android:summaryOn="@string/revanced_spoof_streaming_data_stats_for_nerds_summary_on" android:summaryOff="@string/revanced_spoof_streaming_data_stats_for_nerds_summary_off" android:dependency="revanced_spoof_streaming_data" />
<PreferenceCategory android:title="@string/revanced_preference_category_po_token_visitor_data" android:layout="@layout/revanced_settings_preferences_category" />
<app.revanced.extension.shared.settings.preference.ResettableEditTextPreference android:title="@string/revanced_spoof_streaming_data_po_token_title" android:key="revanced_spoof_streaming_data_po_token" android:summary="@string/revanced_spoof_streaming_data_po_token_summary" android:inputType="text" android:dependency="revanced_spoof_streaming_data" />
<app.revanced.extension.shared.settings.preference.ResettableEditTextPreference android:title="@string/revanced_spoof_streaming_data_visitor_data_title" android:key="revanced_spoof_streaming_data_visitor_data" android:summary="@string/revanced_spoof_streaming_data_visitor_data_summary" android:inputType="text" android:dependency="revanced_spoof_streaming_data" />
<Preference android:title="@string/revanced_spoof_streaming_data_po_token_visitor_data_about_title" android:summary="@string/revanced_spoof_streaming_data_po_token_visitor_data_about_summary" android:dependency="revanced_spoof_streaming_data">
<intent android:action="android.intent.action.VIEW" android:data="https://github.com/iv-org/youtube-trusted-session-generator?tab=readme-ov-file#youtube-trusted-session-generator" />
</Preference>
</PreferenceScreen>SETTINGS: SPOOF_STREAMING_DATA -->

<!-- SETTINGS: WATCH_HISTORY
Expand Down

0 comments on commit 9c3b574

Please sign in to comment.