Add world decrypt // and package addons to .mcaddon

This commit is contained in:
Li 2025-01-21 22:58:26 +13:00
parent a441bfe929
commit b67526b2cc
15 changed files with 565 additions and 125 deletions

View file

@ -0,0 +1 @@
{"RootPath":"C:\\Users\\Li\\Desktop\\git\\McTools\\McCrypt","ProjectFileName":"LibMcCrypt.csproj","Configuration":"Debug|AnyCPU","FrameworkPath":"","Sources":[{"SourceFile":"Crypto.cs"},{"SourceFile":"Keys.cs"},{"SourceFile":"Manifest.cs"},{"SourceFile":"Marketplace.cs"},{"SourceFile":"Properties\\AssemblyInfo.cs"},{"SourceFile":"Utils.cs"},{"SourceFile":"obj\\Debug\\.NETFramework,Version=v4.8.AssemblyAttributes.cs"}],"References":[{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\Microsoft.CSharp.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\mscorlib.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Users\\Li\\Desktop\\git\\McTools\\packages\\Newtonsoft.Json.13.0.1\\lib\\net45\\Newtonsoft.Json.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Core.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Data.DataSetExtensions.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Data.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.IO.Compression.FileSystem.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Net.Http.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Xml.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Xml.Linq.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""}],"Analyzers":[],"Outputs":[{"OutputItemFullPath":"C:\\Users\\Li\\Desktop\\git\\McTools\\McCrypt\\bin\\Debug\\LibMcCrypt.dll","OutputItemRelativePath":"LibMcCrypt.dll"},{"OutputItemFullPath":"C:\\Users\\Li\\Desktop\\git\\McTools\\McCrypt\\bin\\Debug\\LibMcCrypt.pdb","OutputItemRelativePath":"LibMcCrypt.pdb"}],"CopyToOutputEntries":[]}

221
McCrypt/Config.cs Normal file
View file

@ -0,0 +1,221 @@
using McCrypt.Properties;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace McCrypt
{
public class Config
{
public static string LocalAppdata = Environment.GetEnvironmentVariable("LOCALAPPDATA");
public static string RoamingAppdata = Environment.GetEnvironmentVariable("APPDATA");
public static string ApplicationDirectory;
private static List<string> searchFolders = new List<string>();
private static List<string> searchModules = new List<string>();
public static string MinecraftFolder;
public static string LocalState;
public static string LocalCache;
public static string ComMojang;
public static string KeysDbPath;
public static string PremiumCache;
public static string ServerPackCache;
public static string RealmsPremiumCache;
public static string WorldsFolder;
public static string OptionsTxt;
public static string OutFolder;
public static bool CrackPacks;
public static bool ZipPacks;
public static bool MultiThread;
public static bool DecryptExistingWorlds;
public static string[] SearchFolders
{
get
{
return searchFolders.ToArray();
}
}
public static string[] SearchModules
{
get
{
return searchModules.ToArray();
}
}
private static void rebaseSearchFolders()
{
searchFolders.Clear();
searchFolders.Add(ApplicationDirectory);
searchFolders.Add(PremiumCache);
searchFolders.Add(ServerPackCache);
searchFolders.Add(RealmsPremiumCache);
searchModules.Clear();
searchModules.Add("resource_packs");
searchModules.Add("skin_packs");
searchModules.Add("world_templates");
searchModules.Add("persona");
searchModules.Add("behavior_packs");
searchModules.Add("resource");
searchModules.Add("minecraftWorlds");
}
private static void rebaseLocalData()
{
PremiumCache = Path.Combine(LocalState, "premium_cache");
ServerPackCache = Path.Combine(LocalCache, "packcache");
RealmsPremiumCache = Path.Combine(LocalCache, "premiumcache");
ComMojang = Path.Combine(LocalState, "games", "com.mojang");
OptionsTxt = Path.Combine(ComMojang, "minecraftpe", "options.txt");
WorldsFolder = Path.Combine(ComMojang, "minecraftWorlds");
rebaseSearchFolders();
}
private static void rebaseAll()
{
LocalState = Path.Combine(MinecraftFolder, "LocalState");
LocalCache = Path.Combine(MinecraftFolder, "LocalCache", "minecraftpe");
rebaseLocalData();
}
private static string resolve(string str)
{
str = str.Trim();
str = str.Replace("$LOCALAPPDATA", LocalAppdata);
str = str.Replace("$APPDATA", RoamingAppdata);
str = str.Replace("$MCDIR", MinecraftFolder);
str = str.Replace("$EXECDIR", ApplicationDirectory);
str = str.Replace("$LOCALSTATE", LocalState);
str = str.Replace("$LOCALCACHE", LocalCache);
str = str.Replace("$COMMOJANG", ComMojang);
str = str.Replace("$PREMIUMCACHE", PremiumCache);
str = str.Replace("$SERVERPACKCACHE", ServerPackCache);
str = str.Replace("$REALMSPREMIUMCACHE", RealmsPremiumCache);
str = str.Replace("$OUTFOLDER", OutFolder);
return str;
}
public static void Init()
{
CrackPacks = true;
ZipPacks = false;
ApplicationDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
KeysDbPath = Path.Combine(ApplicationDirectory, "keys.db");
MinecraftFolder = Path.Combine(LocalAppdata, "Packages", "Microsoft.MinecraftUWP_8wekyb3d8bbwe");
rebaseAll();
}
public static void ReadConfig(string configFile)
{
if (File.Exists(configFile))
{
string[] configLines = File.ReadAllLines(configFile);
foreach(string line in configLines)
{
if (line.Trim().StartsWith("#"))
continue;
if (!line.Contains(":"))
continue;
string[] keyvalpair = line.Trim().Split(':');
if (keyvalpair.Length < 2)
continue;
switch(keyvalpair[0])
{
case "MinecraftFolder":
MinecraftFolder = resolve(keyvalpair[1]);
rebaseAll();
break;
case "LocalState":
LocalState = resolve(keyvalpair[1]);
rebaseLocalData();
break;
case "LocalCache":
LocalCache = resolve(keyvalpair[1]);
rebaseLocalData();
break;
case "PremiumCache":
PremiumCache = resolve(keyvalpair[1]);
rebaseSearchFolders();
break;
case "ServerPackCache":
ServerPackCache = resolve(keyvalpair[1]);
rebaseSearchFolders();
break;
case "RealmsPremiumCache":
RealmsPremiumCache = resolve(keyvalpair[1]);
rebaseSearchFolders();
break;
case "ComMojang":
ComMojang = resolve(keyvalpair[1]);
break;
case "WorldsFolder":
WorldsFolder = resolve(keyvalpair[1]);
break;
case "OutputFolder":
OutFolder = resolve(keyvalpair[1]);
break;
case "KeysDb":
KeysDbPath = resolve(keyvalpair[1]);
break;
case "OptionsTxt":
OptionsTxt = resolve(keyvalpair[1]);
break;
case "AdditionalSearchDir":
searchFolders.Add(resolve(keyvalpair[1]));
break;
case "AdditionalModuleDir":
searchModules.Add(resolve(keyvalpair[1]));
break;
case "CrackThePacks":
CrackPacks = (resolve(keyvalpair[1]).ToLower() == "yes");
break;
case "ZipThePacks":
ZipPacks = (resolve(keyvalpair[1]).ToLower() == "yes");
break;
case "MultiThread":
MultiThread = (resolve(keyvalpair[1]).ToLower() == "yes");
break;
case "DecryptExistingWorlds":
DecryptExistingWorlds = (resolve(keyvalpair[1]).ToLower() == "yes");
break;
}
}
}
else
{
File.WriteAllBytes(configFile, Resources.DefaultConfigFile);
ReadConfig(configFile);
}
}
}
}

View file

@ -45,15 +45,30 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Config.cs" />
<Compile Include="Crypto.cs" />
<Compile Include="Keys.cs" />
<Compile Include="Manifest.cs" />
<Compile Include="Marketplace.cs" />
<Compile Include="PackData\PEntry.cs" />
<Compile Include="PackData\PReader.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<DependentUpon>Resources.resx</DependentUpon>
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
</Compile>
<Compile Include="Utils.cs" />
</ItemGroup>
<ItemGroup>
<None Include="default.cfg" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -4,6 +4,7 @@ using System.Linq;
using Newtonsoft.Json;
using System.IO;
using System.Text;
using Newtonsoft.Json.Linq;
namespace McCrypt
{
@ -43,6 +44,66 @@ namespace McCrypt
string signaturesJsonFile = Path.Combine(basePath, "signatures.json");
File.WriteAllText(signaturesJsonFile, signatureJson);
}
public static string ReadType(string manifestFile)
{
string manifestStr = File.ReadAllText(manifestFile);
dynamic manifestData = JsonConvert.DeserializeObject(manifestStr);
if(manifestData.modules != null)
{
if(manifestData.modules.Count >= 1)
{
return manifestData.modules[0].type;
}
}
return Path.GetFileName(Path.GetDirectoryName(Path.GetDirectoryName(manifestFile)));
}
public static string ReadProductType(string manifestFile)
{
string manifestStr = File.ReadAllText(manifestFile);
dynamic manifestData = JsonConvert.DeserializeObject(manifestStr);
if (manifestData.metadata != null)
{
if (manifestData.metadata.product_type != null)
{
return manifestData.metadata.product_type;
}
}
return null;
}
public static string[] ReadWorldPackList(string packListFile)
{
List<string> depUuidList = new List<string>();
string packStr = File.ReadAllText(packListFile);
dynamic packListData = JsonConvert.DeserializeObject(packStr);
for (int i = 0; i < packListData.Count; i++)
{
dynamic packData = packListData[i];
if(packData.pack_id != null) depUuidList.Add(packData.pack_id.ToString());
}
return depUuidList.ToArray();
}
public static string[] ReadDependancyUuids(string manifestFile)
{
List<string> depUuidList = new List<string>();
string manifestStr = File.ReadAllText(manifestFile);
dynamic manifestData = JsonConvert.DeserializeObject(manifestStr);
if (manifestData.dependencies != null)
{
for(int i = 0; i < manifestData.dependencies.Count; i++)
{
dynamic manifestDependancy = manifestData.dependencies[i];
if(manifestDependancy.uuid != null)
{
depUuidList.Add(manifestDependancy.uuid.ToString());
}
}
}
return depUuidList.ToArray();
}
public static string ReadName(string manifestFile)
{
string defaultName = Path.GetFileName(Path.GetDirectoryName(manifestFile));

View file

@ -12,8 +12,6 @@ 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
@ -58,6 +56,37 @@ namespace McCrypt
}
}
// check if prid tag is present in a world
// can be used to check if its encrypted.
public static bool IsLevelEncrypted(string levelPath)
{
string ldbPath = Path.Combine(levelPath, "db");
if (!Directory.Exists(ldbPath)) return false;
string[] ldbFiles = Directory.GetFiles(ldbPath, "*.ldb", SearchOption.TopDirectoryOnly);
foreach (string ldbFile in ldbFiles)
{
string file = Path.Combine(ldbPath, ldbFile);
using (FileStream fs = File.OpenRead(file)) // Open file for reading
{
using (BinaryReader br = new BinaryReader(fs)) // Create a binary reader overlay of it
{
if (fs.Length <= 0x10)
continue;
uint version = br.ReadUInt32();
uint magic = br.ReadUInt32();
UInt64 unk = br.ReadUInt64();
if (version == 0 && magic == 0x9bcfb9fc) // is valid header?
return true;
}
}
}
return false;
}
// Change all skins type to "free" instead of "paid"
// This makes the game let you actually apply them
public static void CrackSkinsJson(string skinsJsonFile)
@ -160,54 +189,53 @@ namespace McCrypt
// For the file types that have a header-
private static byte[] worldOrContentsJsonDecrypt(string file)
{
FileStream fs = File.OpenRead(file); // Open file for reading
BinaryReader br = new BinaryReader(fs); // Create a binary reader overlay of it
using (FileStream fs = File.OpenRead(file))
{ // Open file for reading
using (BinaryReader br = new BinaryReader(fs))
{
// Create a binary reader overlay of it
if (fs.Length <= 0)
{
fs.Dispose();
return new byte[0] { };
}
if (fs.Length <= 0)
return new byte[0] { };
uint version = br.ReadUInt32();
uint magic = br.ReadUInt32();
UInt64 unk = br.ReadUInt64();
uint version = br.ReadUInt32();
uint magic = br.ReadUInt32();
UInt64 unk = br.ReadUInt64();
if (version == 0 && magic == 0x9bcfb9fc) // is valid header?
{
if (version == 0 && magic == 0x9bcfb9fc) // is valid header?
{
int len = fs.ReadByte();
string uuid = Utils.ReadString(fs, len); // Read the pack UUID for this file
byte[] key = Keys.LookupKey(uuid); // Look for key inside .ent / keys.db
int len = fs.ReadByte();
string uuid = Utils.ReadString(fs, len); // Read the pack UUID for this file
byte[] key = Keys.LookupKey(uuid); // Look for key inside .ent / keys.db
if (key == null)
key = Encoding.UTF8.GetBytes("s5s5ejuDru4uchuF2drUFuthaspAbepE"); // Generic skinpack key
// Every skinpack has the same key lol
// This might be wrong, but hey! if it works, it works :D
fs.Seek(0x100, SeekOrigin.Begin); // Read ciphertext
byte[] ciphertext = new byte[fs.Length - 0x100];
fs.Read(ciphertext, 0x00, ciphertext.Length);
if (key == null)
key = Encoding.UTF8.GetBytes("s5s5ejuDru4uchuF2drUFuthaspAbepE"); // Generic skinpack key
// Every skinpack has the same key lol
// This might be wrong, but hey! if it works, it works :D
fs.Seek(0x100, SeekOrigin.Begin); // Read ciphertext
byte[] ciphertext = new byte[fs.Length - 0x100];
fs.Read(ciphertext, 0x00, ciphertext.Length);
byte[] iv = new byte[16]; // Copy first 16 bytes of Key for IV
Array.Copy(key, iv, iv.Length);
byte[] iv = new byte[16]; // Copy first 16 bytes of Key for IV
Array.Copy(key, iv, iv.Length);
byte[] plaintext = Crypto.Aes256CfbDecrypt(key, iv, ciphertext); // Decrypt data
byte[] plaintext = Crypto.Aes256CfbDecrypt(key, iv, ciphertext); // Decrypt data
fs.Dispose();
return plaintext;
return plaintext;
}
else
{
fs.Dispose();
throw new InvalidDataException("Not a valid LEVELDB or CONTENTS.JSON file.");
}
else
{
throw new InvalidDataException("Not a valid LEVELDB or CONTENTS.JSON file.");
}
}
}
}
// Read contents.json, and decrypt all files inside
// Now Multi-Threaded for speed!
private static void decryptContentsJsonFiles(string contentsJsonPath, List<Thread> threadList)
@ -239,8 +267,9 @@ namespace McCrypt
File.WriteAllBytes(filePath, plainText); // Write back decrypted filie
});
thrd.Priority = ThreadPriority.Highest;
threadList.Add(thrd);
thrd.Start();
if (!Config.MultiThread) thrd.Join();
else threadList.Add(thrd);
}
}
@ -311,13 +340,12 @@ namespace McCrypt
File.WriteAllBytes(fileToDecrypt, decryptedData); // Write to disk
}
catch (InvalidDataException)
{
Console.Error.WriteLine("Failed to decrypt db/" + Path.GetFileName(levelDbFile));
}
{ }
});
thrd.Priority = ThreadPriority.Highest;
threadList.Add(thrd);
thrd.Start();
if (!Config.MultiThread) thrd.Join();
else threadList.Add(thrd);
}
}
}

184
McCrypt/PackData/PEntry.cs Normal file
View file

@ -0,0 +1,184 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace McCrypt.PackData
{
public class PEntry
{
private string originalPath;
public String FilePath
{
get
{
return originalPath;
}
}
public String ManifestPath
{
get
{
return Path.Combine(originalPath, "manifest.json");
}
}
public String WorldResourcePacksPath
{
get
{
return Path.Combine(this.FilePath, "world_resource_packs.json");
}
}
public String WorldBehaviourPacksPath
{
get
{
return Path.Combine(this.FilePath, "world_behavior_packs.json");
}
}
public String SubResourcePacks
{
get
{
return Path.Combine(this.FilePath, "resource_packs");
}
}
public String SubBehaviourPacks
{
get
{
return Path.Combine(this.FilePath, "behavior_packs");
}
}
public bool IsEncrypted
{
get
{
if (this.ProductType != "minecraftWorlds") return true;
else return Marketplace.IsLevelEncrypted(this.FilePath);
}
}
public bool HasDependancies
{
get
{
return DependsUUID.Length >= 1;
}
}
public String[] DependsUUID
{
get
{
if (File.Exists(this.ManifestPath))
{
return Manifest.ReadDependancyUuids(this.ManifestPath);
}
else if(this.ProductType == "minecraftWorlds")
{
List<String> uuids = new List<String>();
if(File.Exists(WorldResourcePacksPath)) uuids.AddRange(Manifest.ReadWorldPackList(WorldResourcePacksPath));
if(File.Exists(WorldBehaviourPacksPath)) uuids.AddRange(Manifest.ReadWorldPackList(WorldBehaviourPacksPath));
return uuids.ToArray();
}
else
{
return new String[0] { };
}
}
}
public String Name
{
get
{
if (File.Exists(this.ManifestPath))
return Manifest.ReadName(this.ManifestPath);
else if (File.Exists(Path.Combine(FilePath, "levelname.txt")))
return File.ReadAllText(Path.Combine(FilePath, "levelname.txt"));
else
return "Untitled";
}
}
public String Type {
get
{
if(File.Exists(this.ManifestPath))
return Manifest.ReadType(this.ManifestPath);
else if (File.Exists(Path.Combine(FilePath, "levelname.txt")))
return "minecraftWorlds";
else
return Path.GetFileName(Path.GetDirectoryName(this.FilePath));
}
}
public String ProductType
{
get
{
if (File.Exists(this.ManifestPath))
{
string ptype = Manifest.ReadProductType(this.ManifestPath);
if (ptype == null)
{
string type = Manifest.ReadType(this.ManifestPath);
switch (type)
{
case "resources":
return "resource_packs";
case "skin_pack":
return "skin_packs";
case "world_template":
return "world_templates";
case "data":
return "behaviour_packs";
case "persona_piece":
return "persona";
}
}
return ptype;
}
else if (File.Exists(Path.Combine(FilePath, "levelname.txt")))
{
return "minecraftWorlds";
}
else if (this.HasDependancies)
{
return "addon";
}
else
{
return Path.GetFileName(Path.GetDirectoryName(this.FilePath));
}
}
}
public String Uuid
{
get
{
if(File.Exists(this.ManifestPath))
{
return Manifest.ReadUUID(this.ManifestPath);
}
else
{
return new Guid().ToString();
}
}
}
public PEntry(string path)
{
this.originalPath = path;
}
}
}

104
McCrypt/PackData/PReader.cs Normal file
View file

@ -0,0 +1,104 @@
using McCrypt.PackData;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace McCrypt.PackData
{
public class PReader
{
private List<PEntry> entries = new List<PEntry>();
private HashSet<string> hiddenUuids = new HashSet<String>();
public PEntry[] GetDependancies(PEntry baseentry)
{
List<PEntry> dependancyList = new List<PEntry>();
foreach (PEntry pentry in entries)
{
if (baseentry.DependsUUID.Contains<string>(pentry.Uuid))
dependancyList.Add(pentry);
// check sub packs in world templates ..
if(pentry.ProductType == "world_templates")
{
if (Directory.Exists(pentry.SubResourcePacks))
{
foreach (string resourcePack in Directory.GetDirectories(pentry.SubResourcePacks, "*", SearchOption.TopDirectoryOnly))
{
PEntry subPentry = new PEntry(Path.Combine(pentry.SubResourcePacks, resourcePack));
if (baseentry.DependsUUID.Contains<string>(subPentry.Uuid))
dependancyList.Add(subPentry);
}
}
if (Directory.Exists(pentry.SubBehaviourPacks))
{
foreach (string behaviourPack in Directory.GetDirectories(pentry.SubBehaviourPacks, "*", SearchOption.TopDirectoryOnly))
{
PEntry subPentry = new PEntry(Path.Combine(pentry.SubBehaviourPacks, behaviourPack));
if (baseentry.DependsUUID.Contains<string>(subPentry.Uuid))
dependancyList.Add(subPentry);
}
}
}
}
return dependancyList.ToArray();
}
public PEntry[] PEntryList
{
get
{
List<PEntry> publicEntries = new List<PEntry>();
foreach (PEntry entry in entries)
{
if (!hiddenUuids.Contains(entry.Uuid))
{
publicEntries.Add(entry);
}
}
return publicEntries.ToArray();
}
}
public PReader()
{
// search premium cache
foreach (string searchFolder in Config.SearchFolders)
{
foreach (string searchModule in Config.SearchModules)
{
string moduleFolder = Path.Combine(searchFolder, searchModule);
if (Directory.Exists(moduleFolder))
{
foreach (string moduleItem in Directory.GetDirectories(moduleFolder, "*", SearchOption.TopDirectoryOnly))
{
PEntry entry = new PEntry(moduleItem);
if (entry.ProductType == "minecraftWorlds" && !Config.DecryptExistingWorlds) continue;
if (entry.ProductType != "minecraftWorlds" && !hiddenUuids.Contains(entry.Uuid)) foreach (string uuid in entry.DependsUUID) hiddenUuids.Add(uuid);
if (!entry.IsEncrypted) continue;
entries.Add(entry);
}
}
}
}
if (Config.DecryptExistingWorlds && Directory.Exists(Config.WorldsFolder))
{
foreach (string moduleItem in Directory.GetDirectories(Config.WorldsFolder, "*", SearchOption.TopDirectoryOnly))
{
PEntry entry = new PEntry(moduleItem);
if (entry.ProductType != "minecraftWorlds" && !hiddenUuids.Contains(entry.Uuid)) foreach (string uuid in entry.DependsUUID) hiddenUuids.Add(uuid);
if (!entry.IsEncrypted) continue;
entries.Add(entry);
}
}
}
}
}

73
McCrypt/Properties/Resources.Designer.cs generated Normal file
View file

@ -0,0 +1,73 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace McCrypt.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("McCrypt.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
internal static byte[] DefaultConfigFile {
get {
object obj = ResourceManager.GetObject("DefaultConfigFile", resourceCulture);
return ((byte[])(obj));
}
}
}
}

View file

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="DefaultConfigFile" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\default.cfg;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
</root>

68
McCrypt/default.cfg Normal file
View file

@ -0,0 +1,68 @@
# The Pillager Bay's McDecryptor Configuration File
# The path at which Minecraft keeps its resource packs and other data
# May need to change if your using a different version of bedrock (eg education edition)
# Otherwise this default is probably fine
MinecraftFolder: $LOCALAPPDATA\Packages\Microsoft.MinecraftUWP_8wekyb3d8bbwe
KeysDb: $EXECDIR\keys.db
# LocalState and LocalCache folders
# These folders only exist in UWP Versions of Bedrock
# On WIN32 versions it may be under "internalStorage"
LocalState: $MCDIR\LocalState
LocalCache: $MCDIR\LocalCache
# location of games/com.mojang folder
ComMojang: $LOCALSTATE\games\com.mojang
# Path to options.txt
# needed to decrypt .ent files since beta 1.19.
OptionsTxt: $COMMOJANG\minecraftpe\options.txt
# Locations of Premium Cache (marketplace contents)
# Server Pack Cache (server resource packs)
# Realms Premium Cache (realms resource packs)
PremiumCache: $LOCALSTATE\premium_cache
ServerPackCache: $LOCALCACHE\packcache
RealmsPremiumCache: $LOCALCACHE\premiumcache
WorldsFolder: $COMMOJANG\minecraftWorlds
# Should i allow decrypting pre-existing world files
DecryptExistingWorlds: yes
# Should it crack the packs (change skin packs to free, remove prid from worlds)
CrackThePacks: yes
# Should i zip packs to .mcpack/.mctemplate
ZipThePacks: yes
# Use Multiple threads to decrypt (faster, but requires good CPU)
MultiThread: yes
# Where to output the decrypted data, (deafult to install into the game)
OutputFolder: $EXECDIR\output_packs
# You can also add more search locations ontop of the default ones.
# Do this by using AdditionalSearchDir and a path, it will look there
# for packs.
# 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", "behaviour_packs" etc
#AdditionalSearchDir: C:\Some\Folder\With\ResourcePacks
#AdditionalSearchDir: C:\Some\Other\Folder\With\ResourcePacks
#AdditionalModuleDir: worlds
# All Macros
# $LOCALAPPDATA - Local Application Data folder
# $APPDATA - Roaming Application Data folder
# $MCDIR - Minecraft Install Folder
# $EXECDIR - Folder the program is running in
# $LOCALSTATE - LocalState Folder
# $LOCALCACHE - LocalCache Folder.
# $COMMOJANG - ComMojang Folder.
# $PREMIUMCACHE - Premium Cache Folder
# $SERVERPACKCACHE - Server Pack Cache Folder
# $REALMSPREMIUMCACHE - Realms Pack Cache Folder
# $OUTFOLDER - Output folder