From b3a80a479a9b6b695dbaf36cdc9e162e6cf047e8 Mon Sep 17 00:00:00 2001
From: Li
Date: Fri, 12 Aug 2022 00:55:31 +1200
Subject: [PATCH] Upload v1.0
---
.gitignore | 10 +
LibMcCrypt/Crypto.cs | 73 +
LibMcCrypt/Keys.cs | 289 +
LibMcCrypt/LibMcCrypt.csproj | 59 +
LibMcCrypt/Manifest.cs | 125 +
LibMcCrypt/Marketplace.cs | 329 +
LibMcCrypt/Properties/AssemblyInfo.cs | 36 +
LibMcCrypt/Utils.cs | 97 +
LibMcCrypt/packages.config | 4 +
PremiumPackInstaller.sln | 31 +
PremiumPackInstaller/App.config | 6 +
PremiumPackInstaller/MainWindow.Designer.cs | 147 +
PremiumPackInstaller/MainWindow.cs | 216 +
PremiumPackInstaller/MainWindow.resx | 197 +
PremiumPackInstaller/PlayFab/Config.cs | 65 +
PremiumPackInstaller/PlayFab/McClient.cs | 18 +
PremiumPackInstaller/PlayFab/PlayFab.cs | 234 +
.../PremiumPackInstaller.csproj | 147 +
.../PremiumPackInstaller.csproj.user | 13 +
.../PremiumPackInstaller_TemporaryKey.pfx | Bin 0 -> 1660 bytes
PremiumPackInstaller/Program.cs | 19 +
.../Properties/AssemblyInfo.cs | 36 +
.../Properties/Resources.Designer.cs | 71 +
.../Properties/Resources.resx | 117 +
.../Properties/Settings.Designer.cs | 30 +
.../Properties/Settings.settings | 7 +
PremiumPackInstaller/packages.config | 4 +
PremiumPackInstaller/skins.ico | Bin 0 -> 4286 bytes
.../Newtonsoft.Json.13.0.1/.signature.p7s | Bin 0 -> 18122 bytes
packages/Newtonsoft.Json.13.0.1/LICENSE.md | 20 +
.../Newtonsoft.Json.13.0.1.nupkg | Bin 0 -> 2065787 bytes
.../lib/net20/Newtonsoft.Json.dll | Bin 0 -> 571944 bytes
.../lib/net20/Newtonsoft.Json.xml | 10335 ++++++++++++++
.../lib/net35/Newtonsoft.Json.dll | Bin 0 -> 506920 bytes
.../lib/net35/Newtonsoft.Json.xml | 9483 +++++++++++++
.../lib/net40/Newtonsoft.Json.dll | Bin 0 -> 576040 bytes
.../lib/net40/Newtonsoft.Json.xml | 9683 +++++++++++++
.../lib/net45/Newtonsoft.Json.dll | Bin 0 -> 701992 bytes
.../lib/net45/Newtonsoft.Json.xml | 11305 ++++++++++++++++
.../lib/netstandard1.0/Newtonsoft.Json.dll | Bin 0 -> 670760 bytes
.../lib/netstandard1.0/Newtonsoft.Json.xml | 10993 +++++++++++++++
.../lib/netstandard1.3/Newtonsoft.Json.dll | Bin 0 -> 689704 bytes
.../lib/netstandard1.3/Newtonsoft.Json.xml | 11115 +++++++++++++++
.../lib/netstandard2.0/Newtonsoft.Json.dll | Bin 0 -> 695336 bytes
.../lib/netstandard2.0/Newtonsoft.Json.xml | 11280 +++++++++++++++
.../Newtonsoft.Json.13.0.1/packageIcon.png | Bin 0 -> 8956 bytes
46 files changed, 76594 insertions(+)
create mode 100644 .gitignore
create mode 100644 LibMcCrypt/Crypto.cs
create mode 100644 LibMcCrypt/Keys.cs
create mode 100644 LibMcCrypt/LibMcCrypt.csproj
create mode 100644 LibMcCrypt/Manifest.cs
create mode 100644 LibMcCrypt/Marketplace.cs
create mode 100644 LibMcCrypt/Properties/AssemblyInfo.cs
create mode 100644 LibMcCrypt/Utils.cs
create mode 100644 LibMcCrypt/packages.config
create mode 100644 PremiumPackInstaller.sln
create mode 100644 PremiumPackInstaller/App.config
create mode 100644 PremiumPackInstaller/MainWindow.Designer.cs
create mode 100644 PremiumPackInstaller/MainWindow.cs
create mode 100644 PremiumPackInstaller/MainWindow.resx
create mode 100644 PremiumPackInstaller/PlayFab/Config.cs
create mode 100644 PremiumPackInstaller/PlayFab/McClient.cs
create mode 100644 PremiumPackInstaller/PlayFab/PlayFab.cs
create mode 100644 PremiumPackInstaller/PremiumPackInstaller.csproj
create mode 100644 PremiumPackInstaller/PremiumPackInstaller.csproj.user
create mode 100644 PremiumPackInstaller/PremiumPackInstaller_TemporaryKey.pfx
create mode 100644 PremiumPackInstaller/Program.cs
create mode 100644 PremiumPackInstaller/Properties/AssemblyInfo.cs
create mode 100644 PremiumPackInstaller/Properties/Resources.Designer.cs
create mode 100644 PremiumPackInstaller/Properties/Resources.resx
create mode 100644 PremiumPackInstaller/Properties/Settings.Designer.cs
create mode 100644 PremiumPackInstaller/Properties/Settings.settings
create mode 100644 PremiumPackInstaller/packages.config
create mode 100644 PremiumPackInstaller/skins.ico
create mode 100644 packages/Newtonsoft.Json.13.0.1/.signature.p7s
create mode 100644 packages/Newtonsoft.Json.13.0.1/LICENSE.md
create mode 100644 packages/Newtonsoft.Json.13.0.1/Newtonsoft.Json.13.0.1.nupkg
create mode 100644 packages/Newtonsoft.Json.13.0.1/lib/net20/Newtonsoft.Json.dll
create mode 100644 packages/Newtonsoft.Json.13.0.1/lib/net20/Newtonsoft.Json.xml
create mode 100644 packages/Newtonsoft.Json.13.0.1/lib/net35/Newtonsoft.Json.dll
create mode 100644 packages/Newtonsoft.Json.13.0.1/lib/net35/Newtonsoft.Json.xml
create mode 100644 packages/Newtonsoft.Json.13.0.1/lib/net40/Newtonsoft.Json.dll
create mode 100644 packages/Newtonsoft.Json.13.0.1/lib/net40/Newtonsoft.Json.xml
create mode 100644 packages/Newtonsoft.Json.13.0.1/lib/net45/Newtonsoft.Json.dll
create mode 100644 packages/Newtonsoft.Json.13.0.1/lib/net45/Newtonsoft.Json.xml
create mode 100644 packages/Newtonsoft.Json.13.0.1/lib/netstandard1.0/Newtonsoft.Json.dll
create mode 100644 packages/Newtonsoft.Json.13.0.1/lib/netstandard1.0/Newtonsoft.Json.xml
create mode 100644 packages/Newtonsoft.Json.13.0.1/lib/netstandard1.3/Newtonsoft.Json.dll
create mode 100644 packages/Newtonsoft.Json.13.0.1/lib/netstandard1.3/Newtonsoft.Json.xml
create mode 100644 packages/Newtonsoft.Json.13.0.1/lib/netstandard2.0/Newtonsoft.Json.dll
create mode 100644 packages/Newtonsoft.Json.13.0.1/lib/netstandard2.0/Newtonsoft.Json.xml
create mode 100644 packages/Newtonsoft.Json.13.0.1/packageIcon.png
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5c27fa3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+.vs/*
+
+LibMcCrypt/bin/*
+LibMcCrypt/obj/*
+
+PremiumPackInstaller/obj/*
+PremiumPackInstaller/bin/*
+
+obj/*
+bin/*
diff --git a/LibMcCrypt/Crypto.cs b/LibMcCrypt/Crypto.cs
new file mode 100644
index 0000000..a7f5803
--- /dev/null
+++ b/LibMcCrypt/Crypto.cs
@@ -0,0 +1,73 @@
+using System;
+using System.IO;
+using System.Security.Cryptography;
+
+namespace McCrypt
+{
+ internal class Crypto
+ {
+ internal static byte[] Sha256(byte[] data)
+ {
+ SHA256 sha256 = SHA256.Create();
+ byte[] hash = sha256.ComputeHash(data);
+ sha256.Dispose();
+ return hash;
+ }
+ internal static byte[] Aes256CfbEncrypt(byte[] key, byte[] iv, byte[] data)
+ {
+ Aes aes = Aes.Create();
+ aes.Mode = CipherMode.CFB;
+ aes.Padding = PaddingMode.None;
+ aes.BlockSize = 128;
+ aes.KeySize = 256;
+
+ ICryptoTransform aesEncryptor = aes.CreateEncryptor(key, iv);
+ using (MemoryStream msEncrypt = new MemoryStream())
+ {
+ using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, aesEncryptor, CryptoStreamMode.Write))
+ {
+ csEncrypt.Write(data, 0, data.Length);
+
+ long totalWritten = data.Length;
+ while ((totalWritten % 16 != 0))
+ {
+ csEncrypt.WriteByte(0);
+ totalWritten++;
+ }
+
+ msEncrypt.Seek(0x00, SeekOrigin.Begin);
+ return msEncrypt.ToArray();
+ }
+ }
+ }
+
+ internal static byte[] Aes256CfbDecrypt(byte[] key, byte[] iv, byte[] data)
+ {
+ Aes aes = Aes.Create();
+ aes.Mode = CipherMode.CFB;
+ aes.Padding = PaddingMode.Zeros;
+ aes.BlockSize = 128;
+ aes.KeySize = 256;
+
+ ICryptoTransform aesDecryptor = aes.CreateDecryptor(key, iv);
+ using (MemoryStream msDecrypt = new MemoryStream())
+ {
+ msDecrypt.Write(data, 0, data.Length);
+
+ while (msDecrypt.Length % 16 != 0)
+ msDecrypt.WriteByte(0);
+
+ msDecrypt.Seek(0x00, SeekOrigin.Begin);
+ using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, aesDecryptor, CryptoStreamMode.Read))
+ {
+ byte[] plaintext = new byte[msDecrypt.Length];
+ csDecrypt.Read(plaintext, 0x00, plaintext.Length);
+
+ Array.Copy(plaintext, data, data.Length);
+ return data;
+ }
+ }
+ }
+
+ }
+}
diff --git a/LibMcCrypt/Keys.cs b/LibMcCrypt/Keys.cs
new file mode 100644
index 0000000..ddba3ca
--- /dev/null
+++ b/LibMcCrypt/Keys.cs
@@ -0,0 +1,289 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace McCrypt
+{
+ public class Keys
+ {
+ private static Random rng = new Random();
+ public static string KeyDbFile = "";
+ internal struct content
+ {
+ public string FriendlyId;
+ public byte[] ContentKey;
+ }
+ public struct keysJsonStruct
+ {
+ public string id;
+ public string contentKey;
+ }
+
+ public static string lastTitleAccountId = "";
+ public static string lastMinecraftId = "";
+
+ private static string lastDeviceId = "";
+ private static List contentList = new List();
+ public static string ExportKeysJson()
+ {
+ List keysJson = new List();
+ foreach (content key in contentList.ToArray())
+ {
+ string ckey = Encoding.UTF8.GetString(key.ContentKey);
+ if (ckey == "s5s5ejuDru4uchuF2drUFuthaspAbepE")
+ continue;
+
+ keysJsonStruct kjs = new keysJsonStruct();
+ kjs.id = key.FriendlyId;
+ kjs.contentKey = ckey;
+ keysJson.Add(kjs);
+ }
+
+ return JsonConvert.SerializeObject(keysJson);
+ }
+ private static byte[] deriveUserKey(string UserId, string DeviceId)
+ {
+ byte[] userBytes = Encoding.Unicode.GetBytes(UserId);
+ byte[] deviceBytes = Encoding.Unicode.GetBytes(DeviceId);
+
+ int kLen = userBytes.Length;
+ if (deviceBytes.Length < kLen)
+ kLen = deviceBytes.Length;
+
+ byte[] key = new byte[kLen];
+
+ for (int i = 0; i < kLen; i++)
+ {
+ key[i] = (byte)(deviceBytes[i] ^ userBytes[i]);
+ }
+
+ return key;
+ }
+ internal static string GenerateKey()
+ {
+ string allowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
+ string key = "";
+ for (int i = 0; i < 32; i++)
+ {
+ key += allowedChars[rng.Next(0, allowedChars.Length)];
+ }
+ return key;
+ }
+
+ private static byte[] deriveEntKey(byte[] versionkey, byte[] titleaccountId)
+ {
+ int kLen = versionkey.Length;
+ if (titleaccountId.Length < kLen)
+ kLen = titleaccountId.Length;
+
+ byte[] key = new byte[kLen];
+
+ for (int i = 0; i < kLen; i++)
+ {
+ key[i] = (byte)(versionkey[i] ^ titleaccountId[i]);
+ }
+
+ return key;
+ }
+
+ private static byte[] deriveContentKey(byte[] UserKey, byte[] ContentKey)
+ {
+ int kLen = UserKey.Length;
+ if (ContentKey.Length < kLen)
+ kLen = ContentKey.Length;
+
+ byte[] key = new byte[kLen];
+
+ for (int i = 0; i < kLen; i++)
+ {
+ key[i] = (byte)(UserKey[i] ^ ContentKey[i]);
+ }
+
+ int ckLen = kLen / 2;
+ byte[] contentKey = new byte[ckLen];
+
+ for (int i = 0; i < kLen; i += 2)
+ {
+ contentKey[i / 2] = key[i];
+ }
+
+ return contentKey;
+ }
+
+ public static void AddKey(string FriendlyId, byte[] ContentKey, bool addToKeyCache = true)
+ {
+ if (LookupKey(FriendlyId) != null)
+ return;
+
+ string keyCacheEntry = FriendlyId + "=" + Encoding.UTF8.GetString(ContentKey);
+
+ if (addToKeyCache && KeyDbFile != "")
+ File.AppendAllText(KeyDbFile, keyCacheEntry + "\n");
+
+ content content = new content();
+ content.FriendlyId = FriendlyId;
+ content.ContentKey = ContentKey;
+
+ contentList.Add(content);
+ }
+
+ private static void readReceipt(string receiptData)
+ {
+ 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;
+
+ for (int i = 0; i < totalEntitlements; i++)
+ {
+ try
+ {
+ string friendlyId = recData.Receipt.Entitlements[i].FriendlyId;
+ string contentKeyB64 = recData.Receipt.Entitlements[i].ContentKey;
+ if (contentKeyB64 == null)
+ continue;
+
+ byte[] contentKey = Utils.ForceDecodeBase64(contentKeyB64);
+ byte[] realContentKey = deriveContentKey(userKey, contentKey);
+
+ AddKey(friendlyId, realContentKey);
+
+ }
+ catch (Exception) { continue; }
+ }
+
+ }
+
+ public static void ReadOptionsTxt(string optionsTxtPath)
+ {
+ string[] optionsTxt = File.ReadAllLines(optionsTxtPath);
+ foreach (string option in optionsTxt)
+ {
+ string opt = option.Replace("\r", "").Replace("\n", "").Trim();
+
+ string[] kvpair = opt.Split(':');
+ if (kvpair.Length >= 2)
+ {
+ if (kvpair[0].Trim() == "last_minecraft_id")
+ {
+ lastMinecraftId = kvpair[1].Trim().ToUpper();
+ }
+
+ if (kvpair[0].Trim() == "last_title_account_id")
+ {
+ lastTitleAccountId = kvpair[1].Trim().ToUpper();
+ }
+
+ }
+ }
+ }
+
+ private static string decryptEntitlementFile(string encryptedEnt)
+ {
+ int version = Int32.Parse(encryptedEnt.Substring(7, 1));
+ byte[] versionkey;
+ switch (version)
+ {
+ case 2:
+ default:
+ versionkey = Encoding.UTF8.GetBytes("X(nG*ejm&E8)m+8c;-SkLTjF)*QdN6_Y");
+ break;
+ }
+ string deriveText = lastTitleAccountId + lastTitleAccountId;
+ byte[] entKey = deriveEntKey(versionkey, Encoding.UTF8.GetBytes(deriveText));
+
+ string entBase64 = encryptedEnt.Substring(8);
+ byte[] entCiphertext = Utils.ForceDecodeBase64(entBase64);
+
+ byte[] entPlaintext = Marketplace.decryptEntitlementBuffer(entCiphertext, entKey);
+
+ return Encoding.UTF8.GetString(entPlaintext);
+ }
+ public static void ReadEntitlementFile(string entPath)
+ {
+ string jsonData = File.ReadAllText(entPath);
+
+
+ if(jsonData.StartsWith("Version")) // Thanks mojang, this was a fun challange <3
+ {
+ jsonData = decryptEntitlementFile(jsonData);
+ }
+ dynamic entData;
+ try
+ {
+ entData = Utils.JsonDecodeCloserToMinecraft(jsonData);
+ }
+ catch (Exception) { return; }
+
+ string receiptB64 = entData.Receipt;
+
+ if (receiptB64 == null)
+ return;
+
+ if (receiptB64.Split('.').Length <= 1)
+ 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++)
+ {
+ string b64Data = entData.Items[i].Receipt;
+
+ if (b64Data == null)
+ continue;
+
+ if (b64Data.Split('.').Length <= 1)
+ continue;
+
+ string recept = Encoding.UTF8.GetString(Utils.ForceDecodeBase64(b64Data.Split('.')[1]));
+ readReceipt(recept);
+ }
+ }
+ public static void ReadKeysDb(string keyFile)
+ {
+ KeyDbFile = keyFile;
+ string[] keyList = File.ReadAllLines(keyFile);
+ foreach (string key in keyList)
+ {
+ if (key.Contains('='))
+ {
+ string[] keys = key.Split('=');
+ if (keys.Length >= 2)
+ {
+ string friendlyId = keys[0];
+ byte[] contentKey = Encoding.UTF8.GetBytes(keys[1]);
+ AddKey(friendlyId, contentKey, false);
+ }
+ }
+ }
+ }
+ public static byte[] LookupKey(string FriendlyId)
+ {
+ foreach (content content in contentList)
+ {
+ if (content.FriendlyId == FriendlyId)
+ return content.ContentKey;
+ }
+ return null;
+ }
+ }
+}
diff --git a/LibMcCrypt/LibMcCrypt.csproj b/LibMcCrypt/LibMcCrypt.csproj
new file mode 100644
index 0000000..fa99f59
--- /dev/null
+++ b/LibMcCrypt/LibMcCrypt.csproj
@@ -0,0 +1,59 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {4BEF6F52-6545-4BB9-8053-50335A1C6789}
+ Library
+ Properties
+ McCrypt
+ LibMcCrypt
+ v4.8
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ none
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LibMcCrypt/Manifest.cs b/LibMcCrypt/Manifest.cs
new file mode 100644
index 0000000..7a3fc6c
--- /dev/null
+++ b/LibMcCrypt/Manifest.cs
@@ -0,0 +1,125 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Newtonsoft.Json;
+using System.IO;
+using System.Text;
+
+namespace McCrypt
+{
+ public class Manifest
+ {
+ private struct signatureBlock
+ {
+ public string hash;
+ public string path;
+ }
+
+ public static string SignManifestString(string manifestJson, string setPath)
+ {
+ signatureBlock signBlock = new signatureBlock();
+ signBlock.path = setPath;
+ signBlock.hash = Convert.ToBase64String(Crypto.Sha256(Encoding.UTF8.GetBytes(manifestJson)));
+
+ List signatureData = new List();
+ signatureData.Add(signBlock);
+
+ string signatureJson = JsonConvert.SerializeObject(signatureData);
+ return signatureJson;
+ }
+
+ public static void SignManifest(string basePath)
+ {
+ string manifestPath = Path.Combine(basePath, "manifest.json");
+
+ signatureBlock signBlock = new signatureBlock();
+ signBlock.path = manifestPath.Remove(0, basePath.Length + 1);
+ signBlock.hash = Convert.ToBase64String(Crypto.Sha256(File.ReadAllBytes(manifestPath)));
+
+ List signatureData = new List();
+ signatureData.Add(signBlock);
+
+ string signatureJson = JsonConvert.SerializeObject(signatureData);
+ string signaturesJsonFile = Path.Combine(basePath, "signatures.json");
+ File.WriteAllText(signaturesJsonFile, signatureJson);
+ }
+ public static string ReadName(string manifestFile)
+ {
+ string defaultName = Path.GetFileName(Path.GetDirectoryName(manifestFile));
+ if (!File.Exists(manifestFile))
+ return Utils.TrimName(defaultName);
+
+ string manifestStr = File.ReadAllText(manifestFile);
+ dynamic manifestData = JsonConvert.DeserializeObject(manifestStr);
+ if (manifestData.header != null)
+ {
+ if (manifestData.header.name != null)
+ {
+ string name = manifestData.header.name;
+ string englishLanguageFile = Path.Combine(Path.GetDirectoryName(manifestFile), "texts", "en_US.lang");
+
+ if (File.Exists(englishLanguageFile))
+ {
+ string[] lines = File.ReadAllLines(englishLanguageFile);
+ foreach (string line in lines)
+ {
+ if (!line.Contains('='))
+ continue;
+
+ string[] values = line.Split('=');
+
+ // How tf does this work??!!
+
+ if (values.Length <= 0)
+ continue;
+
+ if (values[0] == name)
+ return Utils.TrimName(values[1]);
+
+ if (values[0] == "pack.name")
+ return Utils.TrimName(values[1]);
+
+ if (values[0].Contains('.'))
+ {
+ string[] values2 = values[0].Split('.');
+ if (values2.Length <= 0)
+ return Utils.TrimName(defaultName);
+
+ if (values[0].Split('.').Last() == name)
+ return Utils.TrimName(values[1]);
+
+ if (values2[0] == "skinpack")
+ return Utils.TrimName(values[1]);
+
+ }
+
+ if (values[0].Contains(name))
+ return Utils.TrimName(values[1]);
+ }
+ if (name.Contains("."))
+ return Utils.TrimName(defaultName);
+ else
+ return Utils.TrimName(name);
+ }
+ else
+ return Utils.TrimName(defaultName);
+
+ }
+ }
+
+ return Utils.TrimName(defaultName);
+ }
+ public static string ReadUUID(string manifestPath)
+ {
+ dynamic manifest = JsonConvert.DeserializeObject(File.ReadAllText(manifestPath));
+ return manifest.header.uuid.ToString();
+ }
+
+ public static void ChangeUUID(string manifestPath, string newUUID)
+ {
+ dynamic manifest = JsonConvert.DeserializeObject(File.ReadAllText(manifestPath));
+ manifest.header.uuid = newUUID;
+ File.WriteAllText(manifestPath, JsonConvert.SerializeObject(manifest));
+ }
+ }
+}
diff --git a/LibMcCrypt/Marketplace.cs b/LibMcCrypt/Marketplace.cs
new file mode 100644
index 0000000..abee3d7
--- /dev/null
+++ b/LibMcCrypt/Marketplace.cs
@@ -0,0 +1,329 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.IO.Compression;
+using System.Linq;
+using System.Text;
+using System.Threading;
+
+namespace McCrypt
+{
+ public class Marketplace
+ {
+ // Hi mojang <3
+ // https://www.youtube.com/watch?v=jIM6dN3ogbk
+ // https://www.youtube.com/watch?v=mnnYCJNhw7w
+
+ private static string[] dontEncrypt = new string[] { "manifest.json", "contents.json", "texts", "pack_icon.png", "ui"};
+ private struct contentsJson
+ {
+ public int version;
+ public List