Skip to content
This repository has been archived by the owner on Dec 11, 2024. It is now read-only.

Commit

Permalink
fix(YouTube - Spoof client): Partial fix for watch history issue of b…
Browse files Browse the repository at this point in the history
…rand accounts on iOS clients
  • Loading branch information
inotia00 authored and Francesco146 committed Aug 7, 2024
1 parent 9bd14d2 commit bd1db99
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -252,6 +254,104 @@ public static boolean forceCreatePlaybackSpeedMenuReversed(boolean original) {
return original;
}

private static final Uri VIDEO_STATS_PLAYBACK_URI = Uri.parse("https://www.youtube.com/api/stats/playback?ns=yt&ver=2&final=1");

private static final String PARAM_DOC_ID = "docid";
private static final String PARAM_LEN = "len";
private static final String PARAM_CPN = "cpn";

private static final String PARAM_EVENT_ID = "ei";
private static final String PARAM_VM = "vm";
private static final String PARAM_OF = "of";

private static String mDocId;
private static String mLen;
private static String mCpn;
private static String mEventId;
private static String mVisitorMonitoringData;
private static String mOfParam;

/**
* Injection point.
*/
public static void setCpn(String cpn) {
if (SPOOF_CLIENT_ENABLED && !Objects.equals(mCpn, cpn)) {
mCpn = cpn;
}
}

/**
* Injection point.
*
* Parse parameters from the Tracking URL.
* See <a href="https://github.com/yuliskov/MediaServiceCore/blob/d83b56d98f75ba24eef0bf31073c72c3db2f9cb0/youtubeapi/src/main/java/com/liskovsoft/youtubeapi/videoinfo/models/VideoInfo.java#L327">yuliskov/MediaServiceCore</a>.
*/
public static void setTrackingUriParameter(Uri trackingUri) {
try {
if (SPOOF_CLIENT_ENABLED) {
String path = trackingUri.getPath();

if (path == null || (!path.contains("playback") && !path.contains("watchtime"))) {
return;
}

mDocId = getQueryParameter(trackingUri, PARAM_DOC_ID);
mLen = getQueryParameter(trackingUri, PARAM_LEN);
mEventId = getQueryParameter(trackingUri, PARAM_EVENT_ID);
mVisitorMonitoringData = getQueryParameter(trackingUri, PARAM_VM);
mOfParam = getQueryParameter(trackingUri, PARAM_OF);

Logger.printDebug(() -> "docId: " + mDocId + ", len: " + mLen + ", eventId: " + mEventId + ", visitorMonitoringData: " + mVisitorMonitoringData + ", of: " + mOfParam);
}
} catch (Exception ex) {
Logger.printException(() -> "setTrackingUriParameter failure", ex);
}
}

/**
* Injection point.
* This only works on YouTube 18.38.45 or earlier.
*
* Build a Tracking URL.
* This does not include the last watched time.
* See <a href="https://github.com/yuliskov/MediaServiceCore/blob/d83b56d98f75ba24eef0bf31073c72c3db2f9cb0/youtubeapi/src/main/java/com/liskovsoft/youtubeapi/track/TrackingService.java#L72">yuliskov/MediaServiceCore</a>.
*/
public static Uri overrideTrackingUrl(Uri trackingUrl) {
try {
if (SPOOF_CLIENT_ENABLED &&
getSpoofClientType() == ClientType.IOS &&
trackingUrl.toString().contains("youtube.com/csi") &&
!StringUtils.isAnyEmpty(mDocId, mLen, mCpn, mEventId, mVisitorMonitoringData, mOfParam)
) {
final Uri videoStatsPlaybackUri = VIDEO_STATS_PLAYBACK_URI
.buildUpon()
.appendQueryParameter(PARAM_DOC_ID, mDocId)
.appendQueryParameter(PARAM_LEN, mLen)
.appendQueryParameter(PARAM_CPN, mCpn)
.appendQueryParameter(PARAM_EVENT_ID, mEventId)
.appendQueryParameter(PARAM_VM, mVisitorMonitoringData)
.appendQueryParameter(PARAM_OF, mOfParam)
.build();

Logger.printDebug(() -> "Replaced: '" + trackingUrl + "' with: '" + videoStatsPlaybackUri + "'");
return videoStatsPlaybackUri;
}
} catch (Exception ex) {
Logger.printException(() -> "overrideTrackingUrl failure", ex);
}

return trackingUrl;
}

private static String getQueryParameter(Uri uri, String key) {
List<String> queryParams = uri.getQueryParameters(key);
if (queryParams == null || queryParams.isEmpty()) {
return "";
} else {
return queryParams.get(0);
}
}

/**
* Injection point.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package app.revanced.integrations.youtube.patches.misc;

import android.net.Uri;

import app.revanced.integrations.shared.utils.Logger;
import app.revanced.integrations.youtube.settings.Settings;

Expand All @@ -12,32 +14,24 @@ public enum WatchHistoryType {
BLOCK
}

private static final String UNREACHABLE_HOST_URI_STRING = "https://127.0.0.0";
private static final String YOUTUBE_DOMAIN = "www.youtube.com";
private static final String YOUTUBE_TRACKING_DOMAIN = "s.youtube.com";
private static final Uri UNREACHABLE_HOST_URI = Uri.parse("https://127.0.0.0");
private static final String WWW_TRACKING_URL_AUTHORITY = "www.youtube.com";

public static String replaceTrackingUrl(String originalUrl) {
public static Uri replaceTrackingUrl(Uri trackingUrl) {
final WatchHistoryType watchHistoryType = Settings.WATCH_HISTORY_TYPE.get();
if (watchHistoryType != WatchHistoryType.ORIGINAL) {
try {
if (originalUrl.contains(YOUTUBE_TRACKING_DOMAIN)) {
if (watchHistoryType == WatchHistoryType.REPLACE) {
final String replacement = originalUrl.replaceAll(YOUTUBE_TRACKING_DOMAIN, YOUTUBE_DOMAIN);
if (!replacement.equals(originalUrl)) {
Logger.printDebug(() -> "Replaced: '" + originalUrl + "'\nwith: '" + replacement + "'");
}
return replacement;
} else if (watchHistoryType == WatchHistoryType.BLOCK) {
Logger.printDebug(() -> "Blocking: " + originalUrl + " by returning: " + UNREACHABLE_HOST_URI_STRING);
return UNREACHABLE_HOST_URI_STRING;
}
if (watchHistoryType == WatchHistoryType.REPLACE) {
return trackingUrl.buildUpon().authority(WWW_TRACKING_URL_AUTHORITY).build();
} else if (watchHistoryType == WatchHistoryType.BLOCK) {
return UNREACHABLE_HOST_URI;
}
} catch (Exception ex) {
Logger.printException(() -> "replaceTrackingUrl failure", ex);
}
}

return originalUrl;
return trackingUrl;
}

}

0 comments on commit bd1db99

Please sign in to comment.