From 376dde36657d1ccc9ef16c6871ebddd34fe767bb Mon Sep 17 00:00:00 2001 From: User24kld Date: Wed, 21 May 2025 14:23:41 +0000 Subject: [PATCH] Update ofdl dl.go --- ofdl dl.go | 302 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 225 insertions(+), 77 deletions(-) diff --git a/ofdl dl.go b/ofdl dl.go index 890df7c..7ccecf9 100644 --- a/ofdl dl.go +++ b/ofdl dl.go @@ -1,77 +1,225 @@ -package main - -import ( - "fmt" - "os" - "strings" -) - -func fileExists(path string) bool { - _, err := os.Stat(path) - return err == nil -} - -func main() { - //needs changing to actual - paidMessageValue := "https://cdn3.onlyfans.com/dash/files,..." - paidMessageKey := "mediaId123" - path := "/path/to/download" - task := "download-task" - deviceFolder := "/path/to/device" - deviceName := "default" - hasSelectedUsers := true - - clientIdBlobMissing := !fileExists(fmt.Sprintf("%s/%s/device_client_id_blob", deviceFolder, deviceName)) - devicePrivateKeyMissing := !fileExists(fmt.Sprintf("%s/%s/device_private_key", deviceFolder, deviceName)) - - if strings.Contains(paidMessageValue, "cdn3.onlyfans.com/dash/files") { - parts := strings.Split(paidMessageValue, ",") - if len(parts) < 6 { - fmt.Println("Invalid media info string.") - return - } - - mpdURL := parts[0] - policy := parts[1] - signature := parts[2] - kvp := parts[3] - mediaId := parts[4] - messageId := parts[5] - - pssh, err := GetDRMMPDPSSH(mpdURL, policy, signature, kvp) - if err != nil || pssh == "" { - fmt.Println("Failed to get PSSH") - return - } - - lastModified, _ := GetDRMMPDLastModified(mpdURL, policy, signature, kvp) - - drmHeaders := GetDynamicHeaders(fmt.Sprintf("/api2/v2/users/media/%s/drm/message/%s", mediaId, messageId), "?type=widevine") - - var decryptionKey string - if clientIdBlobMissing || devicePrivateKeyMissing { - decryptionKey, err = GetDecryptionKeyOFDL(drmHeaders, fmt.Sprintf("https://onlyfans.com/api2/v2/users/media/%s/drm/message/%s?type=widevine", mediaId, messageId), pssh) - } else { - decryptionKey, err = GetDecryptionKeyCDM(drmHeaders, fmt.Sprintf("https://onlyfans.com/api2/v2/users/media/%s/drm/message/%s?type=widevine", mediaId, messageId), pssh) - } - - if err != nil { - fmt.Println("Failed to get decryption key:", err) - return - } - - err = DownloadPurchasedMessageDRMVideo(mpdURL, decryptionKey, path) - if err != nil { - fmt.Println("Failed to download DRM video:", err) - } - } else { - // Simulated. needs changing for our needs - mediaInfo := "media-metadata" - messageInfo := "message-metadata" - - err := DownloadPurchasedMedia(paidMessageValue, path, paidMessageKey, "Messages", task, "filenameFormat", messageInfo, mediaInfo, hasSelectedUsers) - if err != nil { - fmt.Println("Failed to download regular media:", err) - } - } -} +private static async Task GetDRMMPDPSSH(string mpdUrl, string policy, string signature, string kvp) +{ + try + { + HttpClient client = new HttpClient(); + var request = new HttpRequestMessage + { + RequestUri = new Uri(mpdUrl), + Method = HttpMethod.Get, + }; + request.Headers.Add("Accept", "application/dash+xml,video/vnd.mpeg.dash.mpd"); + request.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"); + request.Headers.Add("Cookie", $"CloudFront-Policy={policy}; CloudFront-Signature={signature}; CloudFront-Key-Pair-Id={kvp}"); + + var response = await client.SendAsync(request); + response.EnsureSuccessStatusCode(); + + string mpdContent = await response.Content.ReadAsStringAsync(); + XDocument mpdDoc = XDocument.Parse(mpdContent); + XNamespace ns = "urn:mpeg:dash:schema:mpd:2011"; + var psshElement = mpdDoc.Descendants(ns + "PSSH").FirstOrDefault(); + + return psshElement?.Value; + } + catch (Exception ex) + { + Log.Error("Error getting PSSH: {0}", ex.Message); + return null; + } +} + +private static async Task GetDRMMPDLastModified(string mpdUrl, string policy, string signature, string kvp) +{ + try + { + HttpClient client = new HttpClient(); + var request = new HttpRequestMessage + { + RequestUri = new Uri(mpdUrl), + Method = HttpMethod.Head, + }; + request.Headers.Add("Accept", "application/dash+xml,video/vnd.mpeg.dash.mpd"); + request.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"); + request.Headers.Add("Cookie", $"CloudFront-Policy={policy}; CloudFront-Signature={signature}; CloudFront-Key-Pair-Id={kvp}"); + + var response = await client.SendAsync(request); + response.EnsureSuccessStatusCode(); + + return response.Content.Headers.LastModified?.DateTime ?? DateTime.Now; + } + catch (Exception ex) + { + Log.Error("Error getting MPD last modified date: {0}", ex.Message); + return DateTime.Now; + } +} + +private static Dictionary GetDynamicHeaders(string url, string queryParams) +{ + var headers = new Dictionary(); + try + { + headers = auth.GetDynamicHeaders(url, queryParams); + } + catch (Exception ex) + { + Log.Error("Error getting dynamic headers: {0}", ex.Message); + } + return headers; +} + +private static async Task GetDecryptionKeyOFDL(Dictionary drmHeaders, string licenseUrl, string pssh) +{ + try + { + var client = new HttpClient(); + var request = new HttpRequestMessage(HttpMethod.Post, "https://ofdl.tools/wv") + { + Content = new FormUrlEncodedContent(new Dictionary + { + { "license_url", licenseUrl }, + { "headers", JsonConvert.SerializeObject(drmHeaders) }, + { "pssh", pssh }, + { "build_identifier", "windows_software_widevinecdm_win_x86_64" }, + { { "proxy", "" } + }) + }; + + var response = await client.SendAsync(request); + response.EnsureSuccessStatusCode(); + + var responseContent = await response.Content.ReadAsStringAsync(); + var jsonResponse = JObject.Parse(responseContent); + return jsonResponse["keys"][0]["key"].ToString(); + } + catch (Exception ex) + { + Log.Error("Error getting decryption key from OFDL: {0}", ex.Message); + throw; + } +} + +private static async Task GetDecryptionKeyCDM(Dictionary drmHeaders, string licenseUrl, string pssh) +{ + try + { + var client = new WidevineClient.Widevine.CDMClient(); + return await client.GetContentKey(licenseUrl, drmHeaders, pssh); + } + catch (Exception ex) + { + Log.Error("Error getting decryption key from CDM: {0}", ex.Message); + throw; + } +} + +private static async Task DownloadPurchasedMessageDRMVideo( + string policy, + string signature, + string kvp, + string url, + string decryptionKey, + string folder, + DateTime lastModified, + long media_id, + string api_type, + ProgressTask task, + string filenameFormat, + Purchased.List? messageInfo, + Medium? messageMedia, + User? fromUser, + Dictionary users) +{ + try + { + string filename = string.Empty; + string customFileName = string.Empty; + string path = string.Empty; + + if (messageInfo != null && messageMedia != null && fromUser != null) + { + filename = await DownloadHelper.GenerateFilename(filenameFormat, "Messages", messageInfo, messageMedia, fromUser, users, api_type); + customFileName = filename.Split('.')[0]; + path = Path.Combine(folder, filename); + } + else + { + filename = $"{media_id}.mp4"; + path = Path.Combine(folder, filename); + } + + if (File.Exists(path) && new FileInfo(path).Length > 0) + { + return false; + } + + var downloader = new DownloadHelper.DRMVideoDownloader(); + await downloader.DownloadDRMVideo( + url: url, + decryptionKey: decryptionKey, + folder: folder, + lastModified: lastModified, + policy: policy, + signature: signature, + kvp: kvp, + customFileName: customFileName, + task: task); + + return true; + } + catch (Exception ex) + { + Log.Error("Error downloading DRM video: {0}", ex.Message); + return false; + } +} + +private static async Task DownloadPurchasedMedia( + string url, + string folder, + long media_id, + string api_type, + ProgressTask task, + string filenameFormat, + Purchased.List? messageInfo, + Medium? messageMedia, + User? fromUser, + Dictionary users) +{ + try + { + string filename = string.Empty; + string path = string.Empty; + + if (messageInfo != null && messageMedia != null && fromUser != null) + { + filename = await DownloadHelper.GenerateFilename(filenameFormat, "Messages", messageInfo, messageMedia, fromUser, users, api_type); + path = Path.Combine(folder, filename); + } + else + { + filename = $"{media_id}.mp4"; + path = Path.Combine(folder, filename); + } + + if (File.Exists(path) && new FileInfo(path).Length > 0) + { + return false; + } + + var downloader = new DownloadHelper.MediaDownloader(); + await downloader.DownloadMedia( + url: url, + folder: folder, + filename: filename, + task: task); + + return true; + } + catch (Exception ex) + { + Log.Error("Error downloading media: {0}", ex.Message); + return false; + } +} \ No newline at end of file