diff --git a/OF DL/Services/DownloadService.cs b/OF DL/Services/DownloadService.cs index 113be78..ab6cd7e 100644 --- a/OF DL/Services/DownloadService.cs +++ b/OF DL/Services/DownloadService.cs @@ -41,7 +41,7 @@ public class DownloadService( string avatarpath = $"{path}/Avatars"; if (!Directory.Exists(folder + avatarpath)) Directory.CreateDirectory(folder + avatarpath); - List avatarMD5Hashes = WidevineClient.Utils.CalculateFolderMD5(folder + avatarpath); + List avatarMD5Hashes = CalculateFolderMD5(folder + avatarpath); Uri uri = new(avatarUrl); string destinationPath = $"{folder}{avatarpath}/"; @@ -86,7 +86,7 @@ public class DownloadService( string headerpath = $"{path}/Headers"; if (!Directory.Exists(folder + headerpath)) Directory.CreateDirectory(folder + headerpath); - List headerMD5Hashes = WidevineClient.Utils.CalculateFolderMD5(folder + headerpath); + List headerMD5Hashes = CalculateFolderMD5(folder + headerpath); Uri uri = new(headerUrl); string destinationPath = $"{folder}{headerpath}/"; @@ -2626,4 +2626,33 @@ public class DownloadService( } #endregion + + private static List CalculateFolderMD5(string folder) + { + List md5Hashes = new List(); + if (Directory.Exists(folder)) + { + string[] files = Directory.GetFiles(folder); + + foreach (string file in files) + { + md5Hashes.Add(CalculateMD5(file)); + } + } + + return md5Hashes; + } + + private static string CalculateMD5(string filePath) + { + using (var md5 = MD5.Create()) + { + using (var stream = File.OpenRead(filePath)) + { + byte[] hash = md5.ComputeHash(stream); + return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); + } + } + } + } diff --git a/OF DL/Services/FileNameService.cs b/OF DL/Services/FileNameService.cs index 584df74..f97a1d5 100644 --- a/OF DL/Services/FileNameService.cs +++ b/OF DL/Services/FileNameService.cs @@ -169,7 +169,13 @@ namespace OF_DL.Services fileFormat = fileFormat.Replace(placeholder, kvp.Value); } - return WidevineClient.Utils.RemoveInvalidFileNameChars($"{fileFormat}"); + return RemoveInvalidFileNameChars($"{fileFormat}"); } + + private static string RemoveInvalidFileNameChars(string fileName) + { + return string.IsNullOrEmpty(fileName) ? fileName : string.Concat(fileName.Split(Path.GetInvalidFileNameChars())); + } + } } diff --git a/OF DL/Utils.cs b/OF DL/Utils.cs deleted file mode 100644 index 86ce297..0000000 --- a/OF DL/Utils.cs +++ /dev/null @@ -1,189 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Diagnostics; -using System.Linq; -using System.Security.Cryptography; -using System.Text; -using System.Text.RegularExpressions; - -namespace WidevineClient -{ - class Utils - { - public static double EvaluateEquation(string equation, int decimals = 3) - { - var dataTable = new DataTable(); - return Math.Round((double)dataTable.Compute(equation, ""), decimals); - } - - public static string RunCommand(string command, string args) - { - Process p = new Process(); - p.StartInfo.UseShellExecute = false; - p.StartInfo.RedirectStandardOutput = true; - p.StartInfo.FileName = command; - p.StartInfo.Arguments = args; - p.StartInfo.CreateNoWindow = true; - p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; - p.Start(); - string output = p.StandardOutput.ReadToEnd(); - p.WaitForExit(); - return output; - } - - public static int RunCommandCode(string command, string args) - { - Process p = new Process(); - p.StartInfo.UseShellExecute = false; - p.StartInfo.RedirectStandardOutput = false; - p.StartInfo.FileName = command; - p.StartInfo.Arguments = args; - p.Start(); - p.WaitForExit(); - return p.ExitCode; - } - - public static byte[] Xor(byte[] a, byte[] b) - { - byte[] x = new byte[Math.Min(a.Length, b.Length)]; - - for (int i = 0; i < x.Length; i++) - { - x[i] = (byte)(a[i] ^ b[i]); - } - - return x; - } - - public static string GenerateRandomId() - { - return BytesToHex(RandomBytes(3)).ToLower(); - } - - public static byte[] RandomBytes(int length) - { - var bytes = new byte[length]; - new Random().NextBytes(bytes); - return bytes; - } - - public static string[] GetElementsInnerTextByAttribute(string html, string element, string attribute) - { - List content = new List(); - - foreach (string line in html.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None)) - { - if (line.Contains("<" + element) && line.Contains(attribute)) - { - string contentPart = line.Substring(0, line.LastIndexOf("<")); - if (contentPart.EndsWith(">")) - contentPart = contentPart[..^1]; - - contentPart = contentPart[(contentPart.LastIndexOf(">") + 1)..]; - - if (contentPart.Contains("<")) - contentPart = contentPart[..contentPart.IndexOf("<")]; - - content.Add(contentPart); - } - } - return content.ToArray(); - } - - public static string BytesToHex(byte[] data) - { - return BitConverter.ToString(data).Replace("-", ""); - } - public static byte[] HexToBytes(string hex) - { - hex = hex.Trim(); - byte[] bytes = new byte[hex.Length / 2]; - - for (int i = 0; i < hex.Length; i += 2) - bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); - - return bytes; - } - - public static bool IsBase64Encoded(string str) - { - try - { - byte[] data = Convert.FromBase64String(str); - return true; - } - catch - { - return false; - } - } - - public static string Base64Pad(string base64) - { - if (base64.Length % 4 != 0) - { - base64 = base64.PadRight(base64.Length + (4 - (base64.Length % 4)), '='); - } - return base64; - } - public static string Base64ToString(string base64) - { - return Encoding.UTF8.GetString(Convert.FromBase64String(base64)); - } - public static string StringToBase64(string str) - { - return Convert.ToBase64String(Encoding.UTF8.GetBytes(str)); - } - - public static void TitleProgress(long read, long length) - { - long readMB = read / 1024 / 1024; - long lengthMB = length / 1024 / 1024; - Console.Title = $"{readMB}/{lengthMB}MB"; - } - - public static void TitleProgressNoConversion(long read, long length) - { - Console.Title = $"{read}/{length}MB"; - } - - public static string Version() - { - return System.Reflection.Assembly.GetCallingAssembly().GetName().Version.ToString(); - } - - public static string? RemoveInvalidFileNameChars(string? fileName) - { - return string.IsNullOrEmpty(fileName) ? fileName : string.Concat(fileName.Split(Path.GetInvalidFileNameChars())); - } - - public static List CalculateFolderMD5(string folder) - { - List md5Hashes = new List(); - if (Directory.Exists(folder)) - { - string[] files = Directory.GetFiles(folder); - - foreach (string file in files) - { - md5Hashes.Add(CalculateMD5(file)); - } - } - - return md5Hashes; - } - - public static string CalculateMD5(string filePath) - { - using (var md5 = MD5.Create()) - { - using (var stream = File.OpenRead(filePath)) - { - byte[] hash = md5.ComputeHash(stream); - return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); - } - } - } - } -} diff --git a/OF DL/Widevine/CDM.cs b/OF DL/Widevine/CDM.cs index 963da77..ffe25cc 100644 --- a/OF DL/Widevine/CDM.cs +++ b/OF DL/Widevine/CDM.cs @@ -90,9 +90,9 @@ namespace OF_DL.Widevine return null; } - Sessions.Add(Utils.BytesToHex(sessionId), session); + Sessions.Add(BytesToHex(sessionId), session); - return Utils.BytesToHex(sessionId); + return BytesToHex(sessionId); } static WidevineCencHeader ParseInitData(byte[] initData) @@ -124,7 +124,7 @@ namespace OF_DL.Widevine public static bool CloseSession(string sessionId) { - //Logger.Debug($"CloseSession(session_id={Utils.BytesToHex(sessionId)})"); + //Logger.Debug($"CloseSession(session_id={BytesToHex(sessionId)})"); //Logger.Verbose("Closing CDM session"); if (Sessions.ContainsKey(sessionId)) @@ -142,7 +142,7 @@ namespace OF_DL.Widevine public static bool SetServiceCertificate(string sessionId, byte[] certData) { - //Logger.Debug($"SetServiceCertificate(sessionId={Utils.BytesToHex(sessionId)}, cert={certB64})"); + //Logger.Debug($"SetServiceCertificate(sessionId={BytesToHex(sessionId)}, cert={certB64})"); //Logger.Verbose($"Setting service certificate"); if (!Sessions.ContainsKey(sessionId)) @@ -190,7 +190,7 @@ namespace OF_DL.Widevine public static byte[] GetLicenseRequest(string sessionId) { - //Logger.Debug($"GetLicenseRequest(sessionId={Utils.BytesToHex(sessionId)})"); + //Logger.Debug($"GetLicenseRequest(sessionId={BytesToHex(sessionId)})"); //Logger.Verbose($"Getting license request"); if (!Sessions.ContainsKey(sessionId)) @@ -318,7 +318,7 @@ namespace OF_DL.Widevine public static void ProvideLicense(string sessionId, byte[] license) { - //Logger.Debug($"ProvideLicense(sessionId={Utils.BytesToHex(sessionId)}, licenseB64={licenseB64})"); + //Logger.Debug($"ProvideLicense(sessionId={BytesToHex(sessionId)}, licenseB64={licenseB64})"); //Logger.Verbose("Decrypting provided license"); if (!Sessions.ContainsKey(sessionId)) @@ -365,7 +365,7 @@ namespace OF_DL.Widevine throw new Exception("Unable to decrypt session key"); } - //Logger.Debug("Session key: " + Utils.BytesToHex(session.SessionKey)); + //Logger.Debug("Session key: " + BytesToHex(session.SessionKey)); session.DerivedKeys = DeriveKeys(session.LicenseRequest, session.SessionKey); @@ -476,6 +476,11 @@ namespace OF_DL.Widevine throw new Exception("Session not found"); } } + + private static string BytesToHex(byte[] data) + { + return BitConverter.ToString(data).Replace("-", ""); + } } } @@ -529,7 +534,7 @@ namespace OF_DL.Widevine byte[] encryptionKey = encCmacKey; List keys = new List(); - + foreach (License.KeyContainer key in signedLicense.Msg.Keys) { string type = key.Type.ToString();