forked from sim0n00ps/OF-DL
Address compiler warning
This commit is contained in:
parent
f7f1fad92d
commit
487de58274
@ -37,7 +37,7 @@ public class Padding
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[]? AddPSSPadding(byte[] hash)
|
||||
public static byte[] AddPssPadding(byte[] hash)
|
||||
{
|
||||
int modBits = 2048;
|
||||
int hLen = 20;
|
||||
@ -49,10 +49,11 @@ public class Padding
|
||||
lmask = (lmask >> 1) | 0x80;
|
||||
}
|
||||
|
||||
if (emLen < hLen + hLen + 2)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// Commented out since the condition will always be false while emLen = 256 and hLen = 20
|
||||
// if (emLen < hLen + hLen + 2)
|
||||
// {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
byte[] salt = new byte[hLen];
|
||||
new Random().NextBytes(salt);
|
||||
@ -102,7 +103,7 @@ public class Padding
|
||||
db[i] = (byte)(maskedDB[i] ^ dbMask[i]);
|
||||
}
|
||||
|
||||
int onePos = BitConverter.ToString(db[hLen..]).Replace("-", "").IndexOf("01") / 2;
|
||||
int onePos = BitConverter.ToString(db[hLen..]).Replace("-", "").IndexOf("01", StringComparison.Ordinal) / 2;
|
||||
byte[] unpadded = db[(hLen + onePos + 1)..];
|
||||
|
||||
return unpadded;
|
||||
|
||||
@ -115,22 +115,22 @@ public class Config : IFileNameFormatConfig
|
||||
|
||||
if (CreatorConfigs.TryGetValue(username, out CreatorConfig? creatorConfig))
|
||||
{
|
||||
if (creatorConfig?.PaidPostFileNameFormat != null)
|
||||
if (creatorConfig.PaidPostFileNameFormat != null)
|
||||
{
|
||||
combinedFilenameFormatConfig.PaidPostFileNameFormat = creatorConfig.PaidPostFileNameFormat;
|
||||
}
|
||||
|
||||
if (creatorConfig?.PostFileNameFormat != null)
|
||||
if (creatorConfig.PostFileNameFormat != null)
|
||||
{
|
||||
combinedFilenameFormatConfig.PostFileNameFormat = creatorConfig.PostFileNameFormat;
|
||||
}
|
||||
|
||||
if (creatorConfig?.PaidMessageFileNameFormat != null)
|
||||
if (creatorConfig.PaidMessageFileNameFormat != null)
|
||||
{
|
||||
combinedFilenameFormatConfig.PaidMessageFileNameFormat = creatorConfig.PaidMessageFileNameFormat;
|
||||
}
|
||||
|
||||
if (creatorConfig?.MessageFileNameFormat != null)
|
||||
if (creatorConfig.MessageFileNameFormat != null)
|
||||
{
|
||||
combinedFilenameFormatConfig.MessageFileNameFormat = creatorConfig.MessageFileNameFormat;
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using OF_DL.Models.Dtos.Archived;
|
||||
|
||||
namespace OF_DL.Models.Dtos.Common;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -136,6 +136,11 @@ public class AuthService(IServiceProvider serviceProvider) : IAuthService
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(CurrentAuth.Cookie))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string pattern = @"(auth_id=\d+)|(sess=[^;]+)";
|
||||
MatchCollection matches = Regex.Matches(CurrentAuth.Cookie, pattern);
|
||||
|
||||
@ -176,7 +181,7 @@ public class AuthService(IServiceProvider serviceProvider) : IAuthService
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<Auth?> GetAuthFromBrowser(bool isDocker = false)
|
||||
private async Task<Auth?> GetAuthFromBrowser()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@ -44,7 +44,7 @@ public class ConfigService(ILoggingService loggingService) : IConfigService
|
||||
}
|
||||
|
||||
// Check for command-line arguments
|
||||
if (args != null && args.Length > 0)
|
||||
if (args.Length > 0)
|
||||
{
|
||||
const string NON_INTERACTIVE_ARG = "--non-interactive";
|
||||
if (args.Any(a => a.Equals(NON_INTERACTIVE_ARG, StringComparison.OrdinalIgnoreCase)))
|
||||
@ -71,12 +71,6 @@ public class ConfigService(ILoggingService loggingService) : IConfigService
|
||||
|
||||
public async Task SaveConfigurationAsync(string filePath = "config.conf")
|
||||
{
|
||||
if (CurrentConfig == null)
|
||||
{
|
||||
Log.Warning("Attempted to save null config to file");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
string hoconConfig = BuildHoconFromConfig(CurrentConfig);
|
||||
@ -409,7 +403,13 @@ public class ConfigService(ILoggingService loggingService) : IConfigService
|
||||
ToggleableConfigAttribute? attr = propInfo.GetCustomAttribute<ToggleableConfigAttribute>();
|
||||
if (attr != null)
|
||||
{
|
||||
result.Add((propInfo.Name, (bool)propInfo.GetValue(CurrentConfig)!));
|
||||
bool? value = (bool?)propInfo.GetValue(CurrentConfig);
|
||||
if (value == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
result.Add((propInfo.Name, value.Value));
|
||||
}
|
||||
}
|
||||
|
||||
@ -427,10 +427,16 @@ public class ConfigService(ILoggingService loggingService) : IConfigService
|
||||
if (attr != null)
|
||||
{
|
||||
bool newValue = selectedNames.Contains(propInfo.Name);
|
||||
bool oldValue = (bool)propInfo.GetValue(CurrentConfig)!;
|
||||
bool? oldValue = (bool?)propInfo.GetValue(CurrentConfig);
|
||||
|
||||
if (oldValue == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
propInfo.SetValue(newConfig, newValue);
|
||||
|
||||
if (newValue != oldValue)
|
||||
if (newValue != oldValue.Value)
|
||||
{
|
||||
configChanged = true;
|
||||
}
|
||||
|
||||
@ -219,17 +219,17 @@ public class DBService(IConfigService configService) : IDBService
|
||||
connection))
|
||||
{
|
||||
checkCmd.Parameters.AddWithValue("@userId", user.Value);
|
||||
using (SqliteDataReader reader = await checkCmd.ExecuteReaderAsync())
|
||||
await using (SqliteDataReader reader = await checkCmd.ExecuteReaderAsync())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
long storedUserId = reader.GetInt64(0);
|
||||
string storedUsername = reader.GetString(1);
|
||||
|
||||
if (storedUsername != user.Key)
|
||||
{
|
||||
using (SqliteCommand updateCmd =
|
||||
new("UPDATE users SET username = @newUsername WHERE user_id = @userId;", connection))
|
||||
await using (SqliteCommand updateCmd =
|
||||
new("UPDATE users SET username = @newUsername WHERE user_id = @userId;",
|
||||
connection))
|
||||
{
|
||||
updateCmd.Parameters.AddWithValue("@newUsername", user.Key);
|
||||
updateCmd.Parameters.AddWithValue("@userId", user.Value);
|
||||
@ -278,13 +278,13 @@ public class DBService(IConfigService configService) : IDBService
|
||||
if (count == 0)
|
||||
{
|
||||
// If the record doesn't exist, insert a new one
|
||||
using SqliteCommand insertCmd =
|
||||
await using SqliteCommand insertCmd =
|
||||
new(
|
||||
"INSERT INTO messages(post_id, text, price, paid, archived, created_at, user_id, record_created_at) VALUES(@post_id, @message_text, @price, @is_paid, @is_archived, @created_at, @user_id, @record_created_at)",
|
||||
connection);
|
||||
insertCmd.Parameters.AddWithValue("@post_id", post_id);
|
||||
insertCmd.Parameters.AddWithValue("@message_text", message_text ?? (object)DBNull.Value);
|
||||
insertCmd.Parameters.AddWithValue("@price", price ?? (object)DBNull.Value);
|
||||
insertCmd.Parameters.AddWithValue("@message_text", message_text);
|
||||
insertCmd.Parameters.AddWithValue("@price", price);
|
||||
insertCmd.Parameters.AddWithValue("@is_paid", is_paid);
|
||||
insertCmd.Parameters.AddWithValue("@is_archived", is_archived);
|
||||
insertCmd.Parameters.AddWithValue("@created_at", created_at);
|
||||
@ -328,8 +328,8 @@ public class DBService(IConfigService configService) : IDBService
|
||||
"INSERT INTO posts(post_id, text, price, paid, archived, created_at, record_created_at) VALUES(@post_id, @message_text, @price, @is_paid, @is_archived, @created_at, @record_created_at)",
|
||||
connection);
|
||||
insertCmd.Parameters.AddWithValue("@post_id", post_id);
|
||||
insertCmd.Parameters.AddWithValue("@message_text", message_text ?? (object)DBNull.Value);
|
||||
insertCmd.Parameters.AddWithValue("@price", price ?? (object)DBNull.Value);
|
||||
insertCmd.Parameters.AddWithValue("@message_text", message_text);
|
||||
insertCmd.Parameters.AddWithValue("@price", price);
|
||||
insertCmd.Parameters.AddWithValue("@is_paid", is_paid);
|
||||
insertCmd.Parameters.AddWithValue("@is_archived", is_archived);
|
||||
insertCmd.Parameters.AddWithValue("@created_at", created_at);
|
||||
@ -372,8 +372,8 @@ public class DBService(IConfigService configService) : IDBService
|
||||
"INSERT INTO stories(post_id, text, price, paid, archived, created_at, record_created_at) VALUES(@post_id, @message_text, @price, @is_paid, @is_archived, @created_at, @record_created_at)",
|
||||
connection);
|
||||
insertCmd.Parameters.AddWithValue("@post_id", post_id);
|
||||
insertCmd.Parameters.AddWithValue("@message_text", message_text ?? (object)DBNull.Value);
|
||||
insertCmd.Parameters.AddWithValue("@price", price ?? (object)DBNull.Value);
|
||||
insertCmd.Parameters.AddWithValue("@message_text", message_text);
|
||||
insertCmd.Parameters.AddWithValue("@price", price);
|
||||
insertCmd.Parameters.AddWithValue("@is_paid", is_paid);
|
||||
insertCmd.Parameters.AddWithValue("@is_archived", is_archived);
|
||||
insertCmd.Parameters.AddWithValue("@created_at", created_at);
|
||||
@ -445,10 +445,9 @@ public class DBService(IConfigService configService) : IDBService
|
||||
{
|
||||
try
|
||||
{
|
||||
bool downloaded = false;
|
||||
bool downloaded;
|
||||
|
||||
using (SqliteConnection connection = new($"Data Source={folder}/Metadata/user_data.db"))
|
||||
{
|
||||
await using SqliteConnection connection = new($"Data Source={folder}/Metadata/user_data.db");
|
||||
StringBuilder sql = new("SELECT downloaded FROM medias WHERE media_id=@media_id");
|
||||
if (configService.CurrentConfig.DownloadDuplicatedMedia)
|
||||
{
|
||||
@ -456,11 +455,10 @@ public class DBService(IConfigService configService) : IDBService
|
||||
}
|
||||
|
||||
connection.Open();
|
||||
using SqliteCommand cmd = new(sql.ToString(), connection);
|
||||
await using SqliteCommand cmd = new(sql.ToString(), connection);
|
||||
cmd.Parameters.AddWithValue("@media_id", media_id);
|
||||
cmd.Parameters.AddWithValue("@api_type", api_type);
|
||||
downloaded = Convert.ToBoolean(await cmd.ExecuteScalarAsync());
|
||||
}
|
||||
|
||||
return downloaded;
|
||||
}
|
||||
|
||||
@ -144,9 +144,9 @@ public class DownloadOrchestrationService(
|
||||
counts.PaidPostCount = await DownloadContentTypeAsync("Paid Posts",
|
||||
async statusReporter =>
|
||||
await apiService.GetPaidPosts("/posts/paid/post", path, username, PaidPostIds, statusReporter),
|
||||
posts => posts?.PaidPosts?.Count ?? 0,
|
||||
posts => posts?.PaidPostObjects?.Count ?? 0,
|
||||
posts => posts?.PaidPosts?.Values?.ToList(),
|
||||
posts => posts.PaidPosts.Count,
|
||||
posts => posts.PaidPostObjects.Count,
|
||||
posts => posts.PaidPosts.Values.ToList(),
|
||||
async (posts, reporter) => await downloadService.DownloadPaidPosts(username, userId, path, users,
|
||||
clientIdBlobMissing, devicePrivateKeyMissing, posts, reporter),
|
||||
eventHandler);
|
||||
@ -161,9 +161,9 @@ public class DownloadOrchestrationService(
|
||||
counts.PostCount = await DownloadContentTypeAsync("Posts",
|
||||
async statusReporter =>
|
||||
await apiService.GetPosts($"/users/{userId}/posts", path, PaidPostIds, statusReporter),
|
||||
posts => posts?.Posts?.Count ?? 0,
|
||||
posts => posts?.PostObjects?.Count ?? 0,
|
||||
posts => posts?.Posts?.Values?.ToList(),
|
||||
posts => posts.Posts.Count,
|
||||
posts => posts.PostObjects.Count,
|
||||
posts => posts.Posts.Values.ToList(),
|
||||
async (posts, reporter) => await downloadService.DownloadFreePosts(username, userId, path, users,
|
||||
clientIdBlobMissing, devicePrivateKeyMissing, posts, reporter),
|
||||
eventHandler);
|
||||
@ -174,9 +174,9 @@ public class DownloadOrchestrationService(
|
||||
counts.ArchivedCount = await DownloadContentTypeAsync("Archived Posts",
|
||||
async statusReporter =>
|
||||
await apiService.GetArchived($"/users/{userId}/posts", path, statusReporter),
|
||||
archived => archived?.ArchivedPosts?.Count ?? 0,
|
||||
archived => archived?.ArchivedPostObjects?.Count ?? 0,
|
||||
archived => archived?.ArchivedPosts?.Values?.ToList(),
|
||||
archived => archived.ArchivedPosts.Count,
|
||||
archived => archived.ArchivedPostObjects.Count,
|
||||
archived => archived.ArchivedPosts.Values.ToList(),
|
||||
async (archived, reporter) => await downloadService.DownloadArchived(username, userId, path, users,
|
||||
clientIdBlobMissing, devicePrivateKeyMissing, archived, reporter),
|
||||
eventHandler);
|
||||
@ -187,9 +187,9 @@ public class DownloadOrchestrationService(
|
||||
counts.StreamsCount = await DownloadContentTypeAsync("Streams",
|
||||
async statusReporter =>
|
||||
await apiService.GetStreams($"/users/{userId}/posts/streams", path, PaidPostIds, statusReporter),
|
||||
streams => streams?.Streams?.Count ?? 0,
|
||||
streams => streams?.StreamObjects?.Count ?? 0,
|
||||
streams => streams?.Streams?.Values?.ToList(),
|
||||
streams => streams.Streams.Count,
|
||||
streams => streams.StreamObjects.Count,
|
||||
streams => streams.Streams.Values.ToList(),
|
||||
async (streams, reporter) => await downloadService.DownloadStreams(username, userId, path, users,
|
||||
clientIdBlobMissing, devicePrivateKeyMissing, streams, reporter),
|
||||
eventHandler);
|
||||
@ -256,9 +256,9 @@ public class DownloadOrchestrationService(
|
||||
counts.MessagesCount = await DownloadContentTypeAsync("Messages",
|
||||
async statusReporter =>
|
||||
await apiService.GetMessages($"/chats/{userId}/messages", path, statusReporter),
|
||||
messages => messages.Messages?.Count ?? 0,
|
||||
messages => messages.MessageObjects?.Count ?? 0,
|
||||
messages => messages?.Messages.Values.ToList(),
|
||||
messages => messages.Messages.Count,
|
||||
messages => messages.MessageObjects.Count,
|
||||
messages => messages.Messages.Values.ToList(),
|
||||
async (messages, reporter) => await downloadService.DownloadMessages(username, userId, path, users,
|
||||
clientIdBlobMissing, devicePrivateKeyMissing, messages, reporter),
|
||||
eventHandler);
|
||||
@ -269,9 +269,9 @@ public class DownloadOrchestrationService(
|
||||
counts.PaidMessagesCount = await DownloadContentTypeAsync("Paid Messages",
|
||||
async statusReporter =>
|
||||
await apiService.GetPaidMessages("/posts/paid/chat", path, username, statusReporter),
|
||||
paidMessages => paidMessages?.PaidMessages?.Count ?? 0,
|
||||
paidMessages => paidMessages?.PaidMessageObjects?.Count ?? 0,
|
||||
paidMessages => paidMessages?.PaidMessages?.Values?.ToList(),
|
||||
paidMessages => paidMessages.PaidMessages.Count,
|
||||
paidMessages => paidMessages.PaidMessageObjects.Count,
|
||||
paidMessages => paidMessages.PaidMessages.Values.ToList(),
|
||||
async (paidMessages, reporter) => await downloadService.DownloadPaidMessages(username, path, users,
|
||||
clientIdBlobMissing, devicePrivateKeyMissing, paidMessages, reporter),
|
||||
eventHandler);
|
||||
@ -368,7 +368,7 @@ public class DownloadOrchestrationService(
|
||||
int paidMessagesCount = 0;
|
||||
|
||||
// Download paid posts
|
||||
if (purchasedTabCollection.PaidPosts?.PaidPosts?.Count > 0)
|
||||
if (purchasedTabCollection.PaidPosts.PaidPosts.Count > 0)
|
||||
{
|
||||
eventHandler.OnContentFound("Paid Posts",
|
||||
purchasedTabCollection.PaidPosts.PaidPosts.Count,
|
||||
@ -396,7 +396,7 @@ public class DownloadOrchestrationService(
|
||||
}
|
||||
|
||||
// Download paid messages
|
||||
if (purchasedTabCollection.PaidMessages?.PaidMessages?.Count > 0)
|
||||
if (purchasedTabCollection.PaidMessages.PaidMessages.Count > 0)
|
||||
{
|
||||
eventHandler.OnContentFound("Paid Messages",
|
||||
purchasedTabCollection.PaidMessages.PaidMessages.Count,
|
||||
|
||||
@ -25,7 +25,7 @@ public class DownloadService(
|
||||
IAPIService apiService)
|
||||
: IDownloadService
|
||||
{
|
||||
private TaskCompletionSource<bool> _completionSource;
|
||||
private TaskCompletionSource<bool> _completionSource = new();
|
||||
|
||||
public async Task DownloadAvatarHeader(string? avatarUrl, string? headerUrl, string folder, string username)
|
||||
{
|
||||
@ -201,7 +201,7 @@ public class DownloadService(
|
||||
|
||||
Engine ffmpeg = new(configService.CurrentConfig.FFmpegPath);
|
||||
ffmpeg.Error += OnError;
|
||||
ffmpeg.Complete += async (sender, args) =>
|
||||
ffmpeg.Complete += async (_, _) =>
|
||||
{
|
||||
_completionSource.TrySetResult(true);
|
||||
await OnFFMPEGDownloadComplete(tempFilename, lastModified, folder, path, customFileName, filename,
|
||||
@ -275,14 +275,14 @@ public class DownloadService(
|
||||
}
|
||||
}
|
||||
|
||||
private void OnError(object sender, ConversionErrorEventArgs e)
|
||||
private void OnError(object? sender, ConversionErrorEventArgs e)
|
||||
{
|
||||
// Guard all fields to avoid NullReference exceptions from FFmpeg.NET
|
||||
string input = e?.Input?.Name ?? "<none>";
|
||||
string output = e?.Output?.Name ?? "<none>";
|
||||
string exitCode = e?.Exception?.ExitCode.ToString() ?? "<unknown>";
|
||||
string message = e?.Exception?.Message ?? "<no message>";
|
||||
string inner = e?.Exception?.InnerException?.Message ?? "<no inner>";
|
||||
string input = e.Input?.Name ?? "<none>";
|
||||
string output = e.Output?.Name ?? "<none>";
|
||||
string exitCode = e.Exception?.ExitCode.ToString() ?? "<unknown>";
|
||||
string message = e.Exception?.Message ?? "<no message>";
|
||||
string inner = e.Exception?.InnerException?.Message ?? "<no inner>";
|
||||
|
||||
Log.Error("FFmpeg failed. Input={Input} Output={Output} ExitCode={ExitCode} Message={Message} Inner={Inner}",
|
||||
input, output, exitCode, message, inner);
|
||||
@ -310,7 +310,7 @@ public class DownloadService(
|
||||
string body = await response.Content.ReadAsStringAsync();
|
||||
XDocument doc = XDocument.Parse(body);
|
||||
XNamespace ns = "urn:mpeg:dash:schema:mpd:2011";
|
||||
XNamespace cenc = "urn:mpeg:cenc:2013";
|
||||
// XNamespace cenc = "urn:mpeg:cenc:2013";
|
||||
XElement? videoAdaptationSet = doc
|
||||
.Descendants(ns + "AdaptationSet")
|
||||
.FirstOrDefault(e => (string?)e.Attribute("mimeType") == "video/mp4");
|
||||
@ -392,7 +392,6 @@ public class DownloadService(
|
||||
{
|
||||
try
|
||||
{
|
||||
string customFileName = "";
|
||||
if (!Directory.Exists(folder + path))
|
||||
{
|
||||
Directory.CreateDirectory(folder + path);
|
||||
@ -580,19 +579,19 @@ public class DownloadService(
|
||||
public static async Task<DateTime> GetDRMVideoLastModified(string url, Auth auth)
|
||||
{
|
||||
string[] messageUrlParsed = url.Split(',');
|
||||
string mpdURL = messageUrlParsed[0];
|
||||
string mpdUrl = messageUrlParsed[0];
|
||||
string policy = messageUrlParsed[1];
|
||||
string signature = messageUrlParsed[2];
|
||||
string kvp = messageUrlParsed[3];
|
||||
|
||||
mpdURL = mpdURL.Replace(".mpd", "_source.mp4");
|
||||
mpdUrl = mpdUrl.Replace(".mpd", "_source.mp4");
|
||||
|
||||
using HttpClient client = new();
|
||||
client.DefaultRequestHeaders.Add("Cookie",
|
||||
$"CloudFront-Policy={policy}; CloudFront-Signature={signature}; CloudFront-Key-Pair-Id={kvp}; {auth.Cookie}");
|
||||
client.DefaultRequestHeaders.Add("User-Agent", auth.UserAgent);
|
||||
|
||||
using HttpResponseMessage response = await client.GetAsync(mpdURL, HttpCompletionOption.ResponseHeadersRead);
|
||||
using HttpResponseMessage response = await client.GetAsync(mpdUrl, HttpCompletionOption.ResponseHeadersRead);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
if (response.Content.Headers.LastModified != null)
|
||||
@ -624,8 +623,8 @@ public class DownloadService(
|
||||
/// Processes the download and database update of media.
|
||||
/// </summary>
|
||||
/// <param name="folder">The folder where the media is stored.</param>
|
||||
/// <param name="media_id">The ID of the media.</param>
|
||||
/// <param name="api_type"></param>
|
||||
/// <param name="mediaId">The ID of the media.</param>
|
||||
/// <param name="apiType"></param>
|
||||
/// <param name="url">The URL from where to download the media.</param>
|
||||
/// <param name="path">The relative path to the media.</param>
|
||||
/// <param name="serverFilename"></param>
|
||||
@ -634,8 +633,8 @@ public class DownloadService(
|
||||
/// <param name="progressReporter"></param>
|
||||
/// <returns>A Task resulting in a boolean indicating whether the media is newly downloaded or not.</returns>
|
||||
public async Task<bool> ProcessMediaDownload(string folder,
|
||||
long media_id,
|
||||
string api_type,
|
||||
long mediaId,
|
||||
string apiType,
|
||||
string url,
|
||||
string path,
|
||||
string serverFilename,
|
||||
@ -645,11 +644,11 @@ public class DownloadService(
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!await dbService.CheckDownloaded(folder, media_id, api_type))
|
||||
if (!await dbService.CheckDownloaded(folder, mediaId, apiType))
|
||||
{
|
||||
return await HandleNewMedia(folder,
|
||||
media_id,
|
||||
api_type,
|
||||
mediaId,
|
||||
apiType,
|
||||
url,
|
||||
path,
|
||||
serverFilename,
|
||||
@ -658,11 +657,11 @@ public class DownloadService(
|
||||
progressReporter);
|
||||
}
|
||||
|
||||
bool status = await HandlePreviouslyDownloadedMediaAsync(folder, media_id, api_type, progressReporter);
|
||||
bool status = await HandlePreviouslyDownloadedMediaAsync(folder, mediaId, apiType, progressReporter);
|
||||
if (configService.CurrentConfig.RenameExistingFilesWhenCustomFormatIsSelected &&
|
||||
serverFilename != resolvedFilename)
|
||||
{
|
||||
await HandleRenamingOfExistingFilesAsync(folder, media_id, api_type, path, serverFilename,
|
||||
await HandleRenamingOfExistingFilesAsync(folder, mediaId, apiType, path, serverFilename,
|
||||
resolvedFilename, extension);
|
||||
}
|
||||
|
||||
@ -677,9 +676,9 @@ public class DownloadService(
|
||||
}
|
||||
|
||||
|
||||
private async Task<bool> HandleRenamingOfExistingFilesAsync(string folder,
|
||||
long media_id,
|
||||
string api_type,
|
||||
private async Task HandleRenamingOfExistingFilesAsync(string folder,
|
||||
long mediaId,
|
||||
string apiType,
|
||||
string path,
|
||||
string serverFilename,
|
||||
string resolvedFilename,
|
||||
@ -689,7 +688,7 @@ public class DownloadService(
|
||||
string fullPathWithTheNewFileName = $"{folder}{path}/{resolvedFilename}{extension}";
|
||||
if (!File.Exists(fullPathWithTheServerFileName))
|
||||
{
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
@ -699,14 +698,13 @@ public class DownloadService(
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"An error occurred: {ex.Message}");
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
long size = await dbService.GetStoredFileSize(folder, media_id, api_type);
|
||||
long size = await dbService.GetStoredFileSize(folder, mediaId, apiType);
|
||||
DateTime lastModified = File.GetLastWriteTime(fullPathWithTheNewFileName);
|
||||
await dbService.UpdateMedia(folder, media_id, api_type, folder + path, resolvedFilename + extension, size, true,
|
||||
await dbService.UpdateMedia(folder, mediaId, apiType, folder + path, resolvedFilename + extension, size, true,
|
||||
lastModified);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -1084,17 +1082,13 @@ public class DownloadService(
|
||||
}
|
||||
|
||||
public async Task<(string decryptionKey, DateTime lastModified)?> GetDecryptionInfo(
|
||||
string mpdURL, string policy, string signature, string kvp,
|
||||
string mpdUrl, string policy, string signature, string kvp,
|
||||
string mediaId, string contentId, string drmType,
|
||||
bool clientIdBlobMissing, bool devicePrivateKeyMissing)
|
||||
{
|
||||
string? pssh = await apiService.GetDRMMPDPSSH(mpdURL, policy, signature, kvp);
|
||||
if (pssh == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
string pssh = await apiService.GetDRMMPDPSSH(mpdUrl, policy, signature, kvp);
|
||||
|
||||
DateTime lastModified = await apiService.GetDRMMPDLastModified(mpdURL, policy, signature, kvp);
|
||||
DateTime lastModified = await apiService.GetDRMMPDLastModified(mpdUrl, policy, signature, kvp);
|
||||
Dictionary<string, string> drmHeaders =
|
||||
apiService.GetDynamicHeaders($"/api2/v2/users/media/{mediaId}/drm/{drmType}/{contentId}",
|
||||
"?type=widevine");
|
||||
@ -1220,7 +1214,7 @@ public class DownloadService(
|
||||
{
|
||||
Log.Debug($"Calling DownloadArchived - {username}");
|
||||
|
||||
if (archived == null || archived.ArchivedPosts.Count == 0)
|
||||
if (archived.ArchivedPosts.Count == 0)
|
||||
{
|
||||
Log.Debug("Found 0 Archived Posts");
|
||||
return new DownloadResult
|
||||
@ -1244,8 +1238,9 @@ public class DownloadService(
|
||||
bool isNew;
|
||||
ArchivedEntities.Medium? mediaInfo =
|
||||
archived.ArchivedPostMedia.FirstOrDefault(m => m.Id == archivedKVP.Key);
|
||||
ArchivedEntities.ListItem? postInfo =
|
||||
archived.ArchivedPostObjects.FirstOrDefault(p => p?.Media?.Contains(mediaInfo) == true);
|
||||
ArchivedEntities.ListItem? postInfo = mediaInfo == null
|
||||
? null
|
||||
: archived.ArchivedPostObjects.FirstOrDefault(p => p.Media?.Contains(mediaInfo) == true);
|
||||
string filenameFormat =
|
||||
configService.CurrentConfig.GetCreatorFileNameFormatConfig(username).PostFileNameFormat ?? "";
|
||||
|
||||
@ -1300,7 +1295,7 @@ public class DownloadService(
|
||||
{
|
||||
Log.Debug($"Calling DownloadMessages - {username}");
|
||||
|
||||
if (messages == null || messages.Messages.Count == 0)
|
||||
if (messages.Messages.Count == 0)
|
||||
{
|
||||
Log.Debug("Found 0 Messages");
|
||||
return new DownloadResult
|
||||
@ -1323,11 +1318,11 @@ public class DownloadService(
|
||||
bool isNew;
|
||||
MessageEntities.Medium? mediaInfo = messages.MessageMedia.FirstOrDefault(m => m.Id == messageKVP.Key);
|
||||
MessageEntities.ListItem? messageInfo = messages.MessageObjects.FirstOrDefault(p =>
|
||||
p?.Media?.Any(m => m.Id == messageKVP.Key) == true);
|
||||
p.Media?.Any(m => m.Id == messageKVP.Key) == true);
|
||||
string filenameFormat =
|
||||
configService.CurrentConfig.GetCreatorFileNameFormatConfig(username).MessageFileNameFormat ?? "";
|
||||
string messagePath = configService.CurrentConfig.FolderPerMessage && messageInfo != null &&
|
||||
messageInfo?.Id is not null && messageInfo?.CreatedAt is not null
|
||||
messageInfo.Id != 0 && messageInfo.CreatedAt is not null
|
||||
? $"/Messages/Free/{messageInfo.Id} {messageInfo.CreatedAt.Value:yyyy-MM-dd HH-mm-ss}"
|
||||
: "/Messages/Free";
|
||||
|
||||
@ -1383,7 +1378,7 @@ public class DownloadService(
|
||||
{
|
||||
Log.Debug($"Calling DownloadPaidMessages - {username}");
|
||||
|
||||
if (paidMessageCollection == null || paidMessageCollection.PaidMessages.Count == 0)
|
||||
if (paidMessageCollection.PaidMessages.Count == 0)
|
||||
{
|
||||
Log.Debug("Found 0 Paid Messages");
|
||||
return new DownloadResult
|
||||
@ -1408,11 +1403,11 @@ public class DownloadService(
|
||||
MessageEntities.Medium? mediaInfo =
|
||||
paidMessageCollection.PaidMessageMedia.FirstOrDefault(m => m.Id == kvpEntry.Key);
|
||||
PurchasedEntities.ListItem? messageInfo = paidMessageCollection.PaidMessageObjects.FirstOrDefault(p =>
|
||||
p?.Media?.Any(m => m.Id == kvpEntry.Key) == true);
|
||||
p.Media?.Any(m => m.Id == kvpEntry.Key) == true);
|
||||
string filenameFormat =
|
||||
configService.CurrentConfig.GetCreatorFileNameFormatConfig(username).MessageFileNameFormat ?? "";
|
||||
string paidMsgPath = configService.CurrentConfig.FolderPerPaidMessage && messageInfo != null &&
|
||||
messageInfo?.Id is not null && messageInfo?.CreatedAt is not null
|
||||
messageInfo.Id != 0 && messageInfo.CreatedAt is not null
|
||||
? $"/Messages/Paid/{messageInfo.Id} {messageInfo.CreatedAt.Value:yyyy-MM-dd HH-mm-ss}"
|
||||
: "/Messages/Paid";
|
||||
|
||||
@ -1465,7 +1460,7 @@ public class DownloadService(
|
||||
{
|
||||
Log.Debug($"Calling DownloadStreams - {username}");
|
||||
|
||||
if (streams == null || streams.Streams.Count == 0)
|
||||
if (streams.Streams.Count == 0)
|
||||
{
|
||||
Log.Debug("Found 0 Streams");
|
||||
return new DownloadResult
|
||||
@ -1487,12 +1482,12 @@ public class DownloadService(
|
||||
{
|
||||
bool isNew;
|
||||
StreamEntities.Medium? mediaInfo = streams.StreamMedia.FirstOrDefault(m => m.Id == kvpEntry.Key);
|
||||
StreamEntities.ListItem? streamInfo =
|
||||
streams.StreamObjects.FirstOrDefault(p => p.Media?.Contains(mediaInfo) == true);
|
||||
StreamEntities.ListItem? streamInfo = mediaInfo == null
|
||||
? null
|
||||
: streams.StreamObjects.FirstOrDefault(p => p.Media?.Contains(mediaInfo) == true);
|
||||
string filenameFormat =
|
||||
configService.CurrentConfig.GetCreatorFileNameFormatConfig(username).PostFileNameFormat ?? "";
|
||||
string streamPath = configService.CurrentConfig.FolderPerPost && streamInfo != null &&
|
||||
streamInfo?.Id is not null && streamInfo?.PostedAt is not null
|
||||
string streamPath = configService.CurrentConfig.FolderPerPost && streamInfo != null && streamInfo.Id != 0
|
||||
? $"/Posts/Free/{streamInfo.Id} {streamInfo.PostedAt:yyyy-MM-dd HH-mm-ss}"
|
||||
: "/Posts/Free";
|
||||
|
||||
@ -1546,7 +1541,7 @@ public class DownloadService(
|
||||
{
|
||||
Log.Debug($"Calling DownloadFreePosts - {username}");
|
||||
|
||||
if (posts == null || posts.Posts.Count == 0)
|
||||
if (posts.Posts.Count == 0)
|
||||
{
|
||||
Log.Debug("Found 0 Posts");
|
||||
return new DownloadResult
|
||||
@ -1566,13 +1561,13 @@ public class DownloadService(
|
||||
foreach (KeyValuePair<long, string> postKVP in posts.Posts)
|
||||
{
|
||||
bool isNew;
|
||||
PostEntities.Medium? mediaInfo = posts.PostMedia.FirstOrDefault(m => m?.Id == postKVP.Key);
|
||||
PostEntities.ListItem? postInfo =
|
||||
posts.PostObjects.FirstOrDefault(p => p.Media?.Contains(mediaInfo) == true);
|
||||
PostEntities.Medium? mediaInfo = posts.PostMedia.FirstOrDefault(m => m.Id == postKVP.Key);
|
||||
PostEntities.ListItem? postInfo = mediaInfo == null
|
||||
? null
|
||||
: posts.PostObjects.FirstOrDefault(p => p.Media?.Contains(mediaInfo) == true);
|
||||
string filenameFormat =
|
||||
configService.CurrentConfig.GetCreatorFileNameFormatConfig(username).PostFileNameFormat ?? "";
|
||||
string postPath = configService.CurrentConfig.FolderPerPost && postInfo != null &&
|
||||
postInfo?.Id is not null && postInfo?.PostedAt is not null
|
||||
string postPath = configService.CurrentConfig.FolderPerPost && postInfo != null && postInfo.Id != 0
|
||||
? $"/Posts/Free/{postInfo.Id} {postInfo.PostedAt:yyyy-MM-dd HH-mm-ss}"
|
||||
: "/Posts/Free";
|
||||
|
||||
@ -1625,7 +1620,7 @@ public class DownloadService(
|
||||
{
|
||||
Log.Debug($"Calling DownloadPaidPosts - {username}");
|
||||
|
||||
if (purchasedPosts == null || purchasedPosts.PaidPosts.Count == 0)
|
||||
if (purchasedPosts.PaidPosts.Count == 0)
|
||||
{
|
||||
Log.Debug("Found 0 Paid Posts");
|
||||
return new DownloadResult
|
||||
@ -1649,11 +1644,11 @@ public class DownloadService(
|
||||
MessageEntities.Medium? mediaInfo =
|
||||
purchasedPosts.PaidPostMedia.FirstOrDefault(m => m.Id == postKVP.Key);
|
||||
PurchasedEntities.ListItem? postInfo =
|
||||
purchasedPosts.PaidPostObjects.FirstOrDefault(p => p?.Media?.Any(m => m.Id == postKVP.Key) == true);
|
||||
purchasedPosts.PaidPostObjects.FirstOrDefault(p => p.Media?.Any(m => m.Id == postKVP.Key) == true);
|
||||
string filenameFormat =
|
||||
configService.CurrentConfig.GetCreatorFileNameFormatConfig(username).PostFileNameFormat ?? "";
|
||||
string paidPostPath = configService.CurrentConfig.FolderPerPaidPost && postInfo != null &&
|
||||
postInfo?.Id is not null && postInfo?.PostedAt is not null
|
||||
postInfo.Id != 0 && postInfo.PostedAt is not null
|
||||
? $"/Posts/Paid/{postInfo.Id} {postInfo.PostedAt.Value:yyyy-MM-dd HH-mm-ss}"
|
||||
: "/Posts/Paid";
|
||||
|
||||
@ -1706,7 +1701,7 @@ public class DownloadService(
|
||||
{
|
||||
Log.Debug($"Calling DownloadPaidPostsPurchasedTab - {username}");
|
||||
|
||||
if (purchasedPosts == null || purchasedPosts.PaidPosts.Count == 0)
|
||||
if (purchasedPosts.PaidPosts.Count == 0)
|
||||
{
|
||||
Log.Debug("Found 0 Paid Posts");
|
||||
return new DownloadResult { TotalCount = 0, MediaType = "Paid Posts", Success = true };
|
||||
@ -1721,12 +1716,12 @@ public class DownloadService(
|
||||
purchasedPosts?.PaidPostMedia?.FirstOrDefault(m => m.Id == purchasedPostKVP.Key);
|
||||
PurchasedEntities.ListItem? postInfo = mediaInfo != null
|
||||
? purchasedPosts?.PaidPostObjects?.FirstOrDefault(p =>
|
||||
p?.Media?.Any(m => m.Id == purchasedPostKVP.Key) == true)
|
||||
p.Media?.Any(m => m.Id == purchasedPostKVP.Key) == true)
|
||||
: null;
|
||||
string filenameFormat = configService.CurrentConfig.GetCreatorFileNameFormatConfig(username)
|
||||
.PaidPostFileNameFormat ?? "";
|
||||
string paidPostPath = configService.CurrentConfig.FolderPerPaidPost && postInfo != null &&
|
||||
postInfo?.Id is not null && postInfo?.PostedAt is not null
|
||||
postInfo.Id != 0 && postInfo.PostedAt is not null
|
||||
? $"/Posts/Paid/{postInfo.Id} {postInfo.PostedAt.Value:yyyy-MM-dd HH-mm-ss}"
|
||||
: "/Posts/Paid";
|
||||
|
||||
@ -1766,7 +1761,7 @@ public class DownloadService(
|
||||
Log.Debug($"Paid Posts Already Downloaded: {oldCount} New Paid Posts Downloaded: {newCount}");
|
||||
return new DownloadResult
|
||||
{
|
||||
TotalCount = purchasedPosts.PaidPosts.Count,
|
||||
TotalCount = purchasedPosts?.PaidPosts.Count ?? 0,
|
||||
NewDownloads = newCount,
|
||||
ExistingDownloads = oldCount,
|
||||
MediaType = "Paid Posts",
|
||||
@ -1780,7 +1775,7 @@ public class DownloadService(
|
||||
{
|
||||
Log.Debug($"Calling DownloadPaidMessagesPurchasedTab - {username}");
|
||||
|
||||
if (paidMessageCollection == null || paidMessageCollection.PaidMessages.Count == 0)
|
||||
if (paidMessageCollection.PaidMessages.Count == 0)
|
||||
{
|
||||
Log.Debug("Found 0 Paid Messages");
|
||||
return new DownloadResult { TotalCount = 0, MediaType = "Paid Messages", Success = true };
|
||||
@ -1795,11 +1790,11 @@ public class DownloadService(
|
||||
paidMessageCollection.PaidMessageMedia.FirstOrDefault(m => m.Id == paidMessageKVP.Key);
|
||||
PurchasedEntities.ListItem? messageInfo =
|
||||
paidMessageCollection.PaidMessageObjects.FirstOrDefault(p =>
|
||||
p?.Media?.Any(m => m.Id == paidMessageKVP.Key) == true);
|
||||
p.Media?.Any(m => m.Id == paidMessageKVP.Key) == true);
|
||||
string filenameFormat = configService.CurrentConfig.GetCreatorFileNameFormatConfig(username)
|
||||
.PaidMessageFileNameFormat ?? "";
|
||||
string paidMsgPath = configService.CurrentConfig.FolderPerPaidMessage && messageInfo != null &&
|
||||
messageInfo?.Id is not null && messageInfo?.CreatedAt is not null
|
||||
messageInfo.Id != 0 && messageInfo.CreatedAt is not null
|
||||
? $"/Messages/Paid/{messageInfo.Id} {messageInfo.CreatedAt.Value:yyyy-MM-dd HH-mm-ss}"
|
||||
: "/Messages/Paid";
|
||||
|
||||
@ -1853,7 +1848,7 @@ public class DownloadService(
|
||||
{
|
||||
Log.Debug($"Calling DownloadSinglePost - {username}");
|
||||
|
||||
if (post == null || post.SinglePosts.Count == 0)
|
||||
if (post.SinglePosts.Count == 0)
|
||||
{
|
||||
Log.Debug("Couldn't find post");
|
||||
return new DownloadResult { TotalCount = 0, MediaType = "Posts", Success = true };
|
||||
@ -1864,12 +1859,12 @@ public class DownloadService(
|
||||
foreach (KeyValuePair<long, string> postKVP in post.SinglePosts)
|
||||
{
|
||||
PostEntities.Medium? mediaInfo = post.SinglePostMedia.FirstOrDefault(m => m.Id == postKVP.Key);
|
||||
PostEntities.SinglePost? postInfo =
|
||||
post.SinglePostObjects.FirstOrDefault(p => p?.Media?.Contains(mediaInfo) == true);
|
||||
PostEntities.SinglePost? postInfo = mediaInfo == null
|
||||
? null
|
||||
: post.SinglePostObjects.FirstOrDefault(p => p.Media?.Contains(mediaInfo) == true);
|
||||
string filenameFormat = configService.CurrentConfig.GetCreatorFileNameFormatConfig(username)
|
||||
.PostFileNameFormat ?? "";
|
||||
string postPath = configService.CurrentConfig.FolderPerPost && postInfo != null &&
|
||||
postInfo?.Id is not null && postInfo?.PostedAt is not null
|
||||
string postPath = configService.CurrentConfig.FolderPerPost && postInfo != null && postInfo.Id != 0
|
||||
? $"/Posts/Free/{postInfo.Id} {postInfo.PostedAt:yyyy-MM-dd HH-mm-ss}"
|
||||
: "/Posts/Free";
|
||||
|
||||
@ -1930,12 +1925,7 @@ public class DownloadService(
|
||||
PurchasedEntities.SinglePaidMessageCollection singlePaidMessageCollection,
|
||||
IProgressReporter progressReporter)
|
||||
{
|
||||
Log.Debug($"Calling DownloadSinglePaidMessage - {username}");
|
||||
|
||||
if (singlePaidMessageCollection == null)
|
||||
{
|
||||
return new DownloadResult { TotalCount = 0, MediaType = "Paid Messages", Success = true };
|
||||
}
|
||||
Log.Debug("Calling DownloadSinglePaidMessage - {Username}", username);
|
||||
|
||||
int totalNew = 0, totalOld = 0;
|
||||
|
||||
@ -1949,11 +1939,11 @@ public class DownloadService(
|
||||
m.Id == paidMessageKVP.Key);
|
||||
MessageEntities.SingleMessage? messageInfo =
|
||||
singlePaidMessageCollection.SingleMessageObjects.FirstOrDefault(p =>
|
||||
p?.Media?.Any(m => m.Id == paidMessageKVP.Key) == true);
|
||||
p.Media?.Any(m => m.Id == paidMessageKVP.Key) == true);
|
||||
string filenameFormat = configService.CurrentConfig.GetCreatorFileNameFormatConfig(username)
|
||||
.PaidMessageFileNameFormat ?? "";
|
||||
string previewMsgPath = configService.CurrentConfig.FolderPerMessage && messageInfo != null &&
|
||||
messageInfo?.Id is not null && messageInfo?.CreatedAt is not null
|
||||
messageInfo.Id != 0 && messageInfo.CreatedAt is not null
|
||||
? $"/Messages/Free/{messageInfo.Id} {messageInfo.CreatedAt.Value:yyyy-MM-dd HH-mm-ss}"
|
||||
: "/Messages/Free";
|
||||
|
||||
@ -2002,12 +1992,12 @@ public class DownloadService(
|
||||
m.Id == paidMessageKVP.Key);
|
||||
MessageEntities.SingleMessage? messageInfo =
|
||||
singlePaidMessageCollection.SingleMessageObjects.FirstOrDefault(p =>
|
||||
p?.Media?.Any(m => m.Id == paidMessageKVP.Key) == true);
|
||||
p.Media?.Any(m => m.Id == paidMessageKVP.Key) == true);
|
||||
string filenameFormat = configService.CurrentConfig.GetCreatorFileNameFormatConfig(username)
|
||||
.PaidMessageFileNameFormat ?? "";
|
||||
string singlePaidMsgPath = configService.CurrentConfig.FolderPerPaidMessage &&
|
||||
messageInfo != null && messageInfo?.Id is not null &&
|
||||
messageInfo?.CreatedAt is not null
|
||||
messageInfo != null && messageInfo.Id != 0 &&
|
||||
messageInfo.CreatedAt is not null
|
||||
? $"/Messages/Paid/{messageInfo.Id} {messageInfo.CreatedAt.Value:yyyy-MM-dd HH-mm-ss}"
|
||||
: "/Messages/Paid";
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ public class StartupService(IConfigService configService, IAuthService authServi
|
||||
!result.FfmpegPath.Contains(@":\\"))
|
||||
{
|
||||
result.FfmpegPath = result.FfmpegPath.Replace(@"\", @"\\");
|
||||
configService.CurrentConfig!.FFmpegPath = result.FfmpegPath;
|
||||
configService.CurrentConfig.FFmpegPath = result.FfmpegPath;
|
||||
}
|
||||
|
||||
// Get FFmpeg version
|
||||
@ -144,7 +144,7 @@ public class StartupService(IConfigService configService, IAuthService authServi
|
||||
|
||||
private void DetectFfmpeg(StartupResult result)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(configService.CurrentConfig!.FFmpegPath) &&
|
||||
if (!string.IsNullOrEmpty(configService.CurrentConfig.FFmpegPath) &&
|
||||
ValidateFilePath(configService.CurrentConfig.FFmpegPath))
|
||||
{
|
||||
result.FfmpegFound = true;
|
||||
|
||||
@ -67,7 +67,7 @@ public class ThrottledStream : Stream
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task ThrottleAsync(int bytes)
|
||||
private async Task ThrottleAsync(int bytes)
|
||||
{
|
||||
if (!shouldThrottle)
|
||||
{
|
||||
|
||||
@ -21,6 +21,7 @@ internal static class XmlUtils
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
return "";
|
||||
|
||||
@ -112,7 +112,7 @@ public class CDM
|
||||
{
|
||||
//needed for HBO Max
|
||||
|
||||
PSSHBox psshBox = PSSHBox.FromByteArray(initData);
|
||||
PsshBox psshBox = PsshBox.FromByteArray(initData);
|
||||
cencHeader = Serializer.Deserialize<WidevineCencHeader>(new MemoryStream(psshBox.Data));
|
||||
}
|
||||
catch
|
||||
@ -278,7 +278,7 @@ public class CDM
|
||||
encryptedClientIdProto.EncryptedClientId = mstream.ToArray();
|
||||
|
||||
using RSACryptoServiceProvider RSA = new();
|
||||
RSA.ImportRSAPublicKey(session.ServiceCertificate.DeviceCertificate.PublicKey, out int bytesRead);
|
||||
RSA.ImportRSAPublicKey(session.ServiceCertificate.DeviceCertificate.PublicKey, out int _);
|
||||
encryptedClientIdProto.EncryptedPrivacyKey = RSA.Encrypt(aesProvider.Key, RSAEncryptionPadding.OaepSHA1);
|
||||
encryptedClientIdProto.EncryptedClientIdIv = aesProvider.IV;
|
||||
encryptedClientIdProto.ServiceId =
|
||||
|
||||
@ -29,5 +29,13 @@ public class CDMApi
|
||||
CDM.ProvideLicense(SessionId, Convert.FromBase64String(licenseB64));
|
||||
}
|
||||
|
||||
public List<ContentKey> GetKeys() => CDM.GetKeys(SessionId);
|
||||
public List<ContentKey> GetKeys()
|
||||
{
|
||||
if (SessionId == null)
|
||||
{
|
||||
throw new Exception("No session ID set. Could not get keys");
|
||||
}
|
||||
|
||||
return CDM.GetKeys(SessionId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,6 +43,10 @@ public class CDMDevice
|
||||
using StreamReader reader = File.OpenText(privateKeyPath);
|
||||
DeviceKeys = (AsymmetricCipherKeyPair)new PemReader(reader).ReadObject();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("No device private key found");
|
||||
}
|
||||
|
||||
if (vmpBytes != null)
|
||||
{
|
||||
|
||||
@ -1,34 +1,34 @@
|
||||
namespace OF_DL.Widevine;
|
||||
|
||||
internal class PSSHBox
|
||||
internal class PsshBox
|
||||
{
|
||||
private static readonly byte[] PSSH_HEADER = new byte[] { 0x70, 0x73, 0x73, 0x68 };
|
||||
private static readonly byte[] s_psshHeader = [0x70, 0x73, 0x73, 0x68];
|
||||
|
||||
private PSSHBox(List<byte[]> kids, byte[] data)
|
||||
private PsshBox(List<byte[]> kids, byte[] data)
|
||||
{
|
||||
KIDs = kids;
|
||||
Data = data;
|
||||
}
|
||||
|
||||
public List<byte[]> KIDs { get; set; } = new();
|
||||
public List<byte[]> KIDs { get; set; }
|
||||
public byte[] Data { get; set; }
|
||||
|
||||
public static PSSHBox FromByteArray(byte[] psshbox)
|
||||
public static PsshBox FromByteArray(byte[] psshbox)
|
||||
{
|
||||
using MemoryStream stream = new(psshbox);
|
||||
|
||||
stream.Seek(4, SeekOrigin.Current);
|
||||
byte[] header = new byte[4];
|
||||
stream.Read(header, 0, 4);
|
||||
stream.ReadExactly(header, 0, 4);
|
||||
|
||||
if (!header.SequenceEqual(PSSH_HEADER))
|
||||
if (!header.SequenceEqual(s_psshHeader))
|
||||
{
|
||||
throw new Exception("Not a pssh box");
|
||||
}
|
||||
|
||||
stream.Seek(20, SeekOrigin.Current);
|
||||
byte[] kidCountBytes = new byte[4];
|
||||
stream.Read(kidCountBytes, 0, 4);
|
||||
stream.ReadExactly(kidCountBytes, 0, 4);
|
||||
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
@ -41,12 +41,12 @@ internal class PSSHBox
|
||||
for (int i = 0; i < kidCount; i++)
|
||||
{
|
||||
byte[] kid = new byte[16];
|
||||
stream.Read(kid);
|
||||
stream.ReadExactly(kid);
|
||||
kids.Add(kid);
|
||||
}
|
||||
|
||||
byte[] dataLengthBytes = new byte[4];
|
||||
stream.Read(dataLengthBytes);
|
||||
stream.ReadExactly(dataLengthBytes);
|
||||
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
@ -57,12 +57,12 @@ internal class PSSHBox
|
||||
|
||||
if (dataLength == 0)
|
||||
{
|
||||
return new PSSHBox(kids, []);
|
||||
return new PsshBox(kids, []);
|
||||
}
|
||||
|
||||
byte[] data = new byte[dataLength];
|
||||
stream.Read(data);
|
||||
stream.ReadExactly(data);
|
||||
|
||||
return new PSSHBox(kids, data);
|
||||
return new PsshBox(kids, data);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user