Compare commits
3 Commits
Author | SHA1 | Date |
---|---|---|
Li | a441bfe929 | |
Li | 9a8acbdd1d | |
Li | e0d10ff685 |
5
LICENSE
5
LICENSE
|
@ -1,5 +0,0 @@
|
||||||
All code is hereby entered into the Public Domain
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- Abolish Interlectual Property -
|
|
|
@ -1,9 +1,11 @@
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace McCrypt
|
namespace McCrypt
|
||||||
{
|
{
|
||||||
|
@ -129,35 +131,23 @@ namespace McCrypt
|
||||||
|
|
||||||
contentList.Add(content);
|
contentList.Add(content);
|
||||||
}
|
}
|
||||||
|
private static void handleEntitlements(dynamic entitlements, byte[] userKey)
|
||||||
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
|
// Derive content keys
|
||||||
int totalEntitlements = recData.Receipt.Entitlements.Count;
|
int totalEntitlements = entitlements.Count;
|
||||||
|
|
||||||
for (int i = 0; i < totalEntitlements; i++)
|
for (int i = 0; i < totalEntitlements; i++)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string friendlyId = recData.Receipt.Entitlements[i].FriendlyId;
|
string friendlyId = entitlements[i].FriendlyId;
|
||||||
string contentKeyB64 = recData.Receipt.Entitlements[i].ContentKey;
|
if (friendlyId == null)
|
||||||
|
friendlyId = entitlements[i].PackId;
|
||||||
|
|
||||||
|
if (friendlyId == null) continue;
|
||||||
|
|
||||||
|
string contentKeyB64 = entitlements[i].ContentKey;
|
||||||
if (contentKeyB64 == null)
|
if (contentKeyB64 == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -169,7 +159,38 @@ namespace McCrypt
|
||||||
}
|
}
|
||||||
catch (Exception) { continue; }
|
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)
|
public static void ReadOptionsTxt(string optionsTxtPath)
|
||||||
|
@ -246,29 +267,36 @@ namespace McCrypt
|
||||||
}
|
}
|
||||||
catch (Exception) { return; }
|
catch (Exception) { return; }
|
||||||
|
|
||||||
string receiptB64 = entData.Receipt;
|
string receiptB64 = entData.GetValue("Receipt", StringComparison.InvariantCultureIgnoreCase);
|
||||||
|
|
||||||
if (receiptB64 == null)
|
if (receiptB64 == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
string receiptData = null;
|
||||||
if (receiptB64.Split('.').Length <= 1)
|
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;
|
return;
|
||||||
|
|
||||||
string receiptData = Encoding.UTF8.GetString(Utils.ForceDecodeBase64(receiptB64.Split('.')[1]));
|
|
||||||
readReceipt(receiptData);
|
readReceipt(receiptData);
|
||||||
int totalItems = entData.Items.Count;
|
if(entData.Items != null)
|
||||||
for (int i = 0; i < totalItems; i++)
|
|
||||||
{
|
{
|
||||||
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)
|
if (b64Data == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (b64Data.Split('.').Length <= 1)
|
if (b64Data.Split('.').Length <= 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
string recept = Encoding.UTF8.GetString(Utils.ForceDecodeBase64(b64Data.Split('.')[1]));
|
string recept = Encoding.UTF8.GetString(Utils.ForceDecodeBase64(b64Data.Split('.')[1]));
|
||||||
readReceipt(recept);
|
readReceipt(recept);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static void ReadKeysDb(string keyFile)
|
public static void ReadKeysDb(string keyFile)
|
||||||
|
|
|
@ -224,6 +224,9 @@ namespace McCrypt
|
||||||
if (decKey == null)
|
if (decKey == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (Path.GetFileName(relPath).ToLowerInvariant() == "manifest.json")
|
||||||
|
continue;
|
||||||
|
|
||||||
Thread thrd = new Thread(() =>
|
Thread thrd = new Thread(() =>
|
||||||
{
|
{
|
||||||
string filePath = Path.Combine(baseDirectory, relPath); // Combine pack dir, with file relative path
|
string filePath = Path.Combine(baseDirectory, relPath); // Combine pack dir, with file relative path
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -8,7 +9,7 @@ namespace McCrypt
|
||||||
internal class Utils
|
internal class Utils
|
||||||
{
|
{
|
||||||
|
|
||||||
internal static object JsonDecodeCloserToMinecraft(string json)
|
internal static Object JsonDecodeCloserToMinecraft(string json)
|
||||||
{
|
{
|
||||||
for (int i = json.Length; i > 0; i--)
|
for (int i = json.Length; i > 0; i--)
|
||||||
{
|
{
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace McDecryptor
|
||||||
searchModules.Add("skin_packs");
|
searchModules.Add("skin_packs");
|
||||||
searchModules.Add("world_templates");
|
searchModules.Add("world_templates");
|
||||||
searchModules.Add("persona");
|
searchModules.Add("persona");
|
||||||
searchModules.Add("behaviour_packs");
|
searchModules.Add("behavior_packs");
|
||||||
searchModules.Add("resource");
|
searchModules.Add("resource");
|
||||||
}
|
}
|
||||||
private static void rebaseLocalData()
|
private static void rebaseLocalData()
|
||||||
|
|
|
@ -176,7 +176,7 @@ namespace McDecryptor
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (Exception) { }
|
catch (Exception e) { Console.WriteLine("Error: " + e.Message); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -194,51 +194,62 @@ namespace McDecryptor
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
new Thread(() =>
|
|
||||||
|
Console.WriteLine("Decrypting: " + cListing.Name);
|
||||||
|
Directory.CreateDirectory(outFolder);
|
||||||
|
CopyDirectory(cListing.Path, outFolder);
|
||||||
|
try
|
||||||
{
|
{
|
||||||
Console.WriteLine("Decrypting: " + cListing.Name);
|
string levelDatFile = Path.Combine(outFolder, "level.dat");
|
||||||
Directory.CreateDirectory(outFolder);
|
string skinsJsonFile = Path.Combine(outFolder, "skins.json");
|
||||||
CopyDirectory(cListing.Path, outFolder);
|
string oldSchoolZipe = Path.Combine(outFolder, "content.zipe");
|
||||||
try
|
|
||||||
|
Marketplace.DecryptContents(outFolder);
|
||||||
|
|
||||||
|
if (Config.CrackPacks)
|
||||||
{
|
{
|
||||||
string levelDatFile = Path.Combine(outFolder, "level.dat");
|
if (File.Exists(oldSchoolZipe))
|
||||||
string skinsJsonFile = Path.Combine(outFolder, "skins.json");
|
Marketplace.CrackZipe(oldSchoolZipe);
|
||||||
string oldSchoolZipe = Path.Combine(outFolder, "content.zipe");
|
|
||||||
|
|
||||||
Marketplace.DecryptContents(outFolder);
|
if (File.Exists(levelDatFile))
|
||||||
|
Marketplace.CrackLevelDat(levelDatFile);
|
||||||
|
|
||||||
if (Config.CrackPacks)
|
if (File.Exists(skinsJsonFile))
|
||||||
{
|
Marketplace.CrackSkinsJson(skinsJsonFile);
|
||||||
if (File.Exists(oldSchoolZipe))
|
|
||||||
Marketplace.CrackZipe(oldSchoolZipe);
|
|
||||||
|
|
||||||
if (File.Exists(levelDatFile))
|
|
||||||
Marketplace.CrackLevelDat(levelDatFile);
|
|
||||||
|
|
||||||
if (File.Exists(skinsJsonFile))
|
|
||||||
Marketplace.CrackSkinsJson(skinsJsonFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Config.ZipPacks)
|
|
||||||
{
|
|
||||||
string ext = "";
|
|
||||||
if (File.Exists(levelDatFile))
|
|
||||||
ext += ".mctemplate";
|
|
||||||
else
|
|
||||||
ext += ".mcpack";
|
|
||||||
|
|
||||||
ZipFile.CreateFromDirectory(outFolder, outFolder + ext, CompressionLevel.NoCompression, false);
|
|
||||||
Directory.Delete(outFolder, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception)
|
|
||||||
|
if (Config.ZipPacks)
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine("Failed to decrypt: " + cListing.Name);
|
Console.WriteLine("Zipping: " + cListing.Name);
|
||||||
|
|
||||||
|
string ext = "";
|
||||||
|
if (File.Exists(levelDatFile))
|
||||||
|
ext += ".mctemplate";
|
||||||
|
else if (false)
|
||||||
|
ext += ".mcaddon";
|
||||||
|
else
|
||||||
|
ext += ".mcpack";
|
||||||
|
|
||||||
|
string fname = outFolder + ext;
|
||||||
|
|
||||||
|
if (File.Exists(fname))
|
||||||
|
File.Delete(fname);
|
||||||
|
|
||||||
|
ZipFile.CreateFromDirectory(outFolder, fname, CompressionLevel.NoCompression, false);
|
||||||
Directory.Delete(outFolder, true);
|
Directory.Delete(outFolder, true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Failed to decrypt: " + cListing.Name+ " "+e.Message);
|
||||||
|
Directory.Delete(outFolder, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}).Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Finished.");
|
||||||
|
Console.ReadKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,17 +28,17 @@ RealmsPremiumCache: $LOCALCACHE\premiumcache
|
||||||
CrackThePacks: yes
|
CrackThePacks: yes
|
||||||
|
|
||||||
# Should i zip packs to .mcpack/.mctemplate
|
# Should i zip packs to .mcpack/.mctemplate
|
||||||
ZipThePacks: no
|
ZipThePacks: yes
|
||||||
|
|
||||||
# Where to output the decrypted data, (deafult to install into the game)
|
# Where to output the decrypted data, (deafult to install into the game)
|
||||||
OutputFolder: $LOCALSTATE\games\com.mojang
|
OutputFolder: $EXECDIR\output_packs
|
||||||
|
|
||||||
# You can also add more search locations ontop of the default ones.
|
# You can also add more search locations ontop of the default ones.
|
||||||
# Do this by using AdditionalSearchDir and a path, it will look there
|
# Do this by using AdditionalSearchDir and a path, it will look there
|
||||||
# for packs.
|
# for packs.
|
||||||
|
|
||||||
# You can use AdditionalModuleDir to add new folders to look for encrypted data inside of the search folders
|
# You can use AdditionalModuleDir to add new folders to look for encrypted data inside of the search folders
|
||||||
# normally it'll just look inside say "resource_packs" "skin_packs" "persona" etc
|
# normally it'll just look inside say "resource_packs" "skin_packs" "persona", "behaviour packs" etc
|
||||||
|
|
||||||
#AdditionalSearchDir: C:\Some\Folder\With\ResourcePacks
|
#AdditionalSearchDir: C:\Some\Folder\With\ResourcePacks
|
||||||
#AdditionalSearchDir: C:\Some\Other\Folder\With\ResourcePacks
|
#AdditionalSearchDir: C:\Some\Other\Folder\With\ResourcePacks
|
||||||
|
|
Loading…
Reference in New Issue