diff --git a/McCrypt/Keys.cs b/McCrypt/Keys.cs index 2c48f80..845253b 100644 --- a/McCrypt/Keys.cs +++ b/McCrypt/Keys.cs @@ -1,9 +1,11 @@ using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using System.Xml.Linq; namespace McCrypt { @@ -129,35 +131,23 @@ namespace McCrypt contentList.Add(content); } - - private static void readReceipt(string receiptData) + private static void handleEntitlements(dynamic entitlements, byte[] userKey) { - dynamic recData = Utils.JsonDecodeCloserToMinecraft(receiptData); - string userId = recData.Receipt.EntityId; - string deviceId = ""; - - if (recData.Receipt.ReceiptData != null) - deviceId = recData.Receipt.ReceiptData.DeviceId; - - if (deviceId == "" || deviceId == null) - deviceId = lastDeviceId; - - if (deviceId == "" || deviceId == null) - return; - - lastDeviceId = deviceId; - - byte[] userKey = deriveUserKey(userId, deviceId); // Derive content keys - int totalEntitlements = recData.Receipt.Entitlements.Count; + int totalEntitlements = entitlements.Count; for (int i = 0; i < totalEntitlements; i++) { try { - string friendlyId = recData.Receipt.Entitlements[i].FriendlyId; - string contentKeyB64 = recData.Receipt.Entitlements[i].ContentKey; + string friendlyId = entitlements[i].FriendlyId; + if (friendlyId == null) + friendlyId = entitlements[i].PackId; + + if (friendlyId == null) continue; + + string contentKeyB64 = entitlements[i].ContentKey; if (contentKeyB64 == null) continue; @@ -169,7 +159,38 @@ namespace McCrypt } catch (Exception) { continue; } } + } + private static void readInnerReceipt(dynamic recData) + { + string userId = recData.EntityId; + string deviceId = ""; + if (recData.ReceiptData != null) + deviceId = recData.ReceiptData.DeviceId; + + if (deviceId == "" || deviceId == null) + deviceId = lastDeviceId; + + if (deviceId == "" || deviceId == null) + return; + + lastDeviceId = deviceId; + + byte[] userKey = deriveUserKey(userId, deviceId); + + if (recData.Entitlements != null) + handleEntitlements(recData.Entitlements, userKey); + else + handleEntitlements(recData.EntitlementReceipts, userKey); + } + + private static void readReceipt(string receiptData) + { + dynamic recData = Utils.JsonDecodeCloserToMinecraft(receiptData); + if (recData.Receipt != null) + readInnerReceipt(recData.Receipt); + else + readInnerReceipt(recData); } public static void ReadOptionsTxt(string optionsTxtPath) @@ -246,29 +267,36 @@ namespace McCrypt } catch (Exception) { return; } - string receiptB64 = entData.Receipt; + string receiptB64 = entData.GetValue("Receipt", StringComparison.InvariantCultureIgnoreCase); if (receiptB64 == null) return; + string receiptData = null; if (receiptB64.Split('.').Length <= 1) + receiptData = Encoding.UTF8.GetString(Utils.ForceDecodeBase64(receiptB64)); + else + receiptData = Encoding.UTF8.GetString(Utils.ForceDecodeBase64(receiptB64.Split('.')[1])); + if (receiptData == null) return; - string receiptData = Encoding.UTF8.GetString(Utils.ForceDecodeBase64(receiptB64.Split('.')[1])); readReceipt(receiptData); - int totalItems = entData.Items.Count; - for (int i = 0; i < totalItems; i++) + if(entData.Items != null) { - string b64Data = entData.Items[i].Receipt; + int totalItems = entData.Items.Count; + for (int i = 0; i < totalItems; i++) + { + string b64Data = entData.Items[i].Receipt; - if (b64Data == null) - continue; + if (b64Data == null) + continue; - if (b64Data.Split('.').Length <= 1) - continue; + if (b64Data.Split('.').Length <= 1) + continue; - string recept = Encoding.UTF8.GetString(Utils.ForceDecodeBase64(b64Data.Split('.')[1])); - readReceipt(recept); + string recept = Encoding.UTF8.GetString(Utils.ForceDecodeBase64(b64Data.Split('.')[1])); + readReceipt(recept); + } } } public static void ReadKeysDb(string keyFile) diff --git a/McCrypt/Utils.cs b/McCrypt/Utils.cs index f61f67c..d6d8d5f 100644 --- a/McCrypt/Utils.cs +++ b/McCrypt/Utils.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System; using System.IO; using System.Text; @@ -8,7 +9,7 @@ namespace McCrypt internal class Utils { - internal static object JsonDecodeCloserToMinecraft(string json) + internal static Object JsonDecodeCloserToMinecraft(string json) { for (int i = json.Length; i > 0; i--) {