From a441bfe92955c2a2be269ad6d9d67098040a44c0 Mon Sep 17 00:00:00 2001
From: Li <li@silica.codes>
Date: Wed, 28 Feb 2024 14:01:08 +1300
Subject: [PATCH 1/6] Fix spelling of behavior

---
 McDecryptor/Config.cs   |  2 +-
 McDecryptor/Program.cs  | 83 +++++++++++++++++++++++------------------
 McDecryptor/default.cfg |  6 +--
 3 files changed, 51 insertions(+), 40 deletions(-)

diff --git a/McDecryptor/Config.cs b/McDecryptor/Config.cs
index 39aef83..07eb148 100644
--- a/McDecryptor/Config.cs
+++ b/McDecryptor/Config.cs
@@ -64,7 +64,7 @@ namespace McDecryptor
             searchModules.Add("skin_packs");
             searchModules.Add("world_templates");
             searchModules.Add("persona");
-            searchModules.Add("behaviour_packs");
+            searchModules.Add("behavior_packs");
             searchModules.Add("resource");
         }
         private static void rebaseLocalData()
diff --git a/McDecryptor/Program.cs b/McDecryptor/Program.cs
index 709f9f8..9e8dbcc 100644
--- a/McDecryptor/Program.cs
+++ b/McDecryptor/Program.cs
@@ -176,7 +176,7 @@ namespace McDecryptor
 
                     break;
                 }
-                catch (Exception) { }
+                catch (Exception e) { Console.WriteLine("Error: " + e.Message); }
             }
 
             
@@ -194,51 +194,62 @@ namespace McDecryptor
                     counter++;
                 }
 
-                new Thread(() =>
+
+                Console.WriteLine("Decrypting: " + cListing.Name);
+                Directory.CreateDirectory(outFolder);
+                CopyDirectory(cListing.Path, outFolder);
+                try 
                 {
-                    Console.WriteLine("Decrypting: " + cListing.Name);
-                    Directory.CreateDirectory(outFolder);
-                    CopyDirectory(cListing.Path, outFolder);
-                    try 
+                    string levelDatFile = Path.Combine(outFolder, "level.dat");
+                    string skinsJsonFile = Path.Combine(outFolder, "skins.json");
+                    string oldSchoolZipe = Path.Combine(outFolder, "content.zipe");
+
+                    Marketplace.DecryptContents(outFolder);
+
+                    if (Config.CrackPacks)
                     {
-                        string levelDatFile = Path.Combine(outFolder, "level.dat");
-                        string skinsJsonFile = Path.Combine(outFolder, "skins.json");
-                        string oldSchoolZipe = Path.Combine(outFolder, "content.zipe");
+                        if (File.Exists(oldSchoolZipe))
+                            Marketplace.CrackZipe(oldSchoolZipe);
 
-                        Marketplace.DecryptContents(outFolder);
+                        if (File.Exists(levelDatFile))
+                            Marketplace.CrackLevelDat(levelDatFile);
 
-                        if (Config.CrackPacks)
-                        {
-                            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);
-                        }
+                        if (File.Exists(skinsJsonFile))
+                            Marketplace.CrackSkinsJson(skinsJsonFile);
                     }
-                    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);
                     }
+                }
+                catch (Exception e)
+                {
+                    Console.Error.WriteLine("Failed to decrypt: " + cListing.Name+ " "+e.Message);
+                    Directory.Delete(outFolder, true);
+                }
+
 
-                }).Start();
             }
+
+            Console.WriteLine("Finished.");
+            Console.ReadKey();
         }
 
     }
diff --git a/McDecryptor/default.cfg b/McDecryptor/default.cfg
index 01490b8..8bdc072 100644
--- a/McDecryptor/default.cfg
+++ b/McDecryptor/default.cfg
@@ -28,17 +28,17 @@ RealmsPremiumCache: $LOCALCACHE\premiumcache
 CrackThePacks: yes
 
 # Should i zip packs to .mcpack/.mctemplate
-ZipThePacks: no
+ZipThePacks: yes
 
 # 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.
 # 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" 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\Other\Folder\With\ResourcePacks

From b67526b2cc7db59c1203b5e00e3cb318c3ec9799 Mon Sep 17 00:00:00 2001
From: Li <li@silica.codes>
Date: Tue, 21 Jan 2025 22:58:26 +1300
Subject: [PATCH 2/6] Add world decrypt // and package addons to .mcaddon

---
 McCrypt/.vs/LibMcCrypt.csproj.dtbcache.json   |   1 +
 {McDecryptor => McCrypt}/Config.cs            |  34 +++-
 McCrypt/LibMcCrypt.csproj                     |  15 ++
 McCrypt/Manifest.cs                           |  61 ++++++
 McCrypt/Marketplace.cs                        | 108 ++++++----
 McCrypt/PackData/PEntry.cs                    | 184 ++++++++++++++++++
 McCrypt/PackData/PReader.cs                   | 104 ++++++++++
 .../Properties/Resources.Designer.cs          |   4 +-
 .../Properties/Resources.resx                 |   0
 {McDecryptor => McCrypt}/default.cfg          |  19 +-
 .../.vs/McDecryptor.csproj.dtbcache.json      |   1 +
 McDecryptor/App.config                        |   6 -
 McDecryptor/McDecryptor.csproj                |  16 --
 McDecryptor/Program.cs                        | 136 ++++++++-----
 .../.vs/McEncryptor.csproj.dtbcache.json      |   1 +
 15 files changed, 565 insertions(+), 125 deletions(-)
 create mode 100644 McCrypt/.vs/LibMcCrypt.csproj.dtbcache.json
 rename {McDecryptor => McCrypt}/Config.cs (84%)
 create mode 100644 McCrypt/PackData/PEntry.cs
 create mode 100644 McCrypt/PackData/PReader.cs
 rename {McDecryptor => McCrypt}/Properties/Resources.Designer.cs (95%)
 rename {McDecryptor => McCrypt}/Properties/Resources.resx (100%)
 rename {McDecryptor => McCrypt}/default.cfg (81%)
 create mode 100644 McDecryptor/.vs/McDecryptor.csproj.dtbcache.json
 delete mode 100644 McDecryptor/App.config
 create mode 100644 McEncryptor/.vs/McEncryptor.csproj.dtbcache.json

diff --git a/McCrypt/.vs/LibMcCrypt.csproj.dtbcache.json b/McCrypt/.vs/LibMcCrypt.csproj.dtbcache.json
new file mode 100644
index 0000000..63804fc
--- /dev/null
+++ b/McCrypt/.vs/LibMcCrypt.csproj.dtbcache.json
@@ -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":[]}
\ No newline at end of file
diff --git a/McDecryptor/Config.cs b/McCrypt/Config.cs
similarity index 84%
rename from McDecryptor/Config.cs
rename to McCrypt/Config.cs
index 07eb148..664e342 100644
--- a/McDecryptor/Config.cs
+++ b/McCrypt/Config.cs
@@ -1,4 +1,4 @@
-using McDecryptor.Properties;
+using McCrypt.Properties;
 using System;
 using System.Collections.Generic;
 using System.IO;
@@ -7,9 +7,9 @@ using System.Reflection;
 using System.Text;
 using System.Threading.Tasks;
 
-namespace McDecryptor
+namespace McCrypt
 {
-    internal class Config
+    public class Config
     {
         public static string LocalAppdata = Environment.GetEnvironmentVariable("LOCALAPPDATA");
         public static string RoamingAppdata = Environment.GetEnvironmentVariable("APPDATA");
@@ -23,18 +23,21 @@ namespace McDecryptor
 
         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
@@ -66,13 +69,17 @@ namespace McDecryptor
             searchModules.Add("persona");
             searchModules.Add("behavior_packs");
             searchModules.Add("resource");
+            searchModules.Add("minecraftWorlds");
         }
         private static void rebaseLocalData()
         {
-            OutFolder = Path.Combine(LocalState, "games", "com.mojang");
             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()
@@ -92,6 +99,7 @@ namespace McDecryptor
 
             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);
@@ -109,6 +117,7 @@ namespace McDecryptor
             ApplicationDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
             KeysDbPath = Path.Combine(ApplicationDirectory, "keys.db");
             MinecraftFolder = Path.Combine(LocalAppdata, "Packages", "Microsoft.MinecraftUWP_8wekyb3d8bbwe");
+            
             rebaseAll();
         }
 
@@ -159,6 +168,14 @@ namespace McDecryptor
                             rebaseSearchFolders();
                             break;
 
+                        case "ComMojang":
+                            ComMojang = resolve(keyvalpair[1]);
+                            break;
+
+                        case "WorldsFolder":
+                            WorldsFolder = resolve(keyvalpair[1]);
+                            break;
+
                         case "OutputFolder":
                             OutFolder = resolve(keyvalpair[1]);
                             break;
@@ -184,7 +201,12 @@ namespace McDecryptor
                         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;
                     }
                 }
             }
diff --git a/McCrypt/LibMcCrypt.csproj b/McCrypt/LibMcCrypt.csproj
index d4a6c1d..3487bee 100644
--- a/McCrypt/LibMcCrypt.csproj
+++ b/McCrypt/LibMcCrypt.csproj
@@ -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>
\ No newline at end of file
diff --git a/McCrypt/Manifest.cs b/McCrypt/Manifest.cs
index 1b2f228..60ab598 100644
--- a/McCrypt/Manifest.cs
+++ b/McCrypt/Manifest.cs
@@ -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));
diff --git a/McCrypt/Marketplace.cs b/McCrypt/Marketplace.cs
index c9c17c8..16bd3db 100644
--- a/McCrypt/Marketplace.cs
+++ b/McCrypt/Marketplace.cs
@@ -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);
                     }
                 }
             }
diff --git a/McCrypt/PackData/PEntry.cs b/McCrypt/PackData/PEntry.cs
new file mode 100644
index 0000000..829d9f9
--- /dev/null
+++ b/McCrypt/PackData/PEntry.cs
@@ -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;
+        }
+    }
+}
diff --git a/McCrypt/PackData/PReader.cs b/McCrypt/PackData/PReader.cs
new file mode 100644
index 0000000..907c3d9
--- /dev/null
+++ b/McCrypt/PackData/PReader.cs
@@ -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);
+                }
+            }
+        }
+    }
+}
diff --git a/McDecryptor/Properties/Resources.Designer.cs b/McCrypt/Properties/Resources.Designer.cs
similarity index 95%
rename from McDecryptor/Properties/Resources.Designer.cs
rename to McCrypt/Properties/Resources.Designer.cs
index d455984..8220686 100644
--- a/McDecryptor/Properties/Resources.Designer.cs
+++ b/McCrypt/Properties/Resources.Designer.cs
@@ -8,7 +8,7 @@
 // </auto-generated>
 //------------------------------------------------------------------------------
 
-namespace McDecryptor.Properties {
+namespace McCrypt.Properties {
     using System;
     
     
@@ -39,7 +39,7 @@ namespace McDecryptor.Properties {
         internal static global::System.Resources.ResourceManager ResourceManager {
             get {
                 if (object.ReferenceEquals(resourceMan, null)) {
-                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("McDecryptor.Properties.Resources", typeof(Resources).Assembly);
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("McCrypt.Properties.Resources", typeof(Resources).Assembly);
                     resourceMan = temp;
                 }
                 return resourceMan;
diff --git a/McDecryptor/Properties/Resources.resx b/McCrypt/Properties/Resources.resx
similarity index 100%
rename from McDecryptor/Properties/Resources.resx
rename to McCrypt/Properties/Resources.resx
diff --git a/McDecryptor/default.cfg b/McCrypt/default.cfg
similarity index 81%
rename from McDecryptor/default.cfg
rename to McCrypt/default.cfg
index 8bdc072..fc88b23 100644
--- a/McDecryptor/default.cfg
+++ b/McCrypt/default.cfg
@@ -11,11 +11,14 @@ KeysDb: $EXECDIR\keys.db
 # These folders only exist in UWP Versions of Bedrock
 # On WIN32 versions it may be under "internalStorage"
 LocalState: $MCDIR\LocalState
-LocalCache: $MCDIR\LocalCache\McDecryptor
+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: $LOCALSTATE\games\com.mojang\minecraftpe\options.txt
+OptionsTxt: $COMMOJANG\minecraftpe\options.txt
 
 # Locations of Premium Cache (marketplace contents)
 # Server Pack Cache (server resource packs)
@@ -23,6 +26,10 @@ OptionsTxt: $LOCALSTATE\games\com.mojang\minecraftpe\options.txt
 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
@@ -30,6 +37,9 @@ 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
 
@@ -38,7 +48,7 @@ OutputFolder: $EXECDIR\output_packs
 # 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
+# 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
@@ -51,7 +61,8 @@ OutputFolder: $EXECDIR\output_packs
 # $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
\ No newline at end of file
+# $OUTFOLDER - Output folder
diff --git a/McDecryptor/.vs/McDecryptor.csproj.dtbcache.json b/McDecryptor/.vs/McDecryptor.csproj.dtbcache.json
new file mode 100644
index 0000000..a654af2
--- /dev/null
+++ b/McDecryptor/.vs/McDecryptor.csproj.dtbcache.json
@@ -0,0 +1 @@
+{"RootPath":"C:\\Users\\Li\\Desktop\\git\\McTools\\McDecryptor","ProjectFileName":"McDecryptor.csproj","Configuration":"Debug|AnyCPU","FrameworkPath":"","Sources":[{"SourceFile":"Config.cs"},{"SourceFile":"Program.cs"},{"SourceFile":"Properties\\AssemblyInfo.cs"},{"SourceFile":"Properties\\Resources.Designer.cs"},{"SourceFile":"obj\\Debug\\.NETFramework,Version=v4.8.AssemblyAttributes.cs"}],"References":[{"Reference":"C:\\Users\\Li\\Desktop\\git\\McTools\\McCrypt\\bin\\Debug\\LibMcCrypt.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":true,"ProjectPath":""},{"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:\\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\\McDecryptor\\bin\\Debug\\McDecryptor.exe","OutputItemRelativePath":"McDecryptor.exe"},{"OutputItemFullPath":"C:\\Users\\Li\\Desktop\\git\\McTools\\McDecryptor\\bin\\Debug\\McDecryptor.pdb","OutputItemRelativePath":"McDecryptor.pdb"}],"CopyToOutputEntries":[]}
\ No newline at end of file
diff --git a/McDecryptor/App.config b/McDecryptor/App.config
deleted file mode 100644
index 92c094c..0000000
--- a/McDecryptor/App.config
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-    <startup> 
-        
-    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup>
-</configuration>
diff --git a/McDecryptor/McDecryptor.csproj b/McDecryptor/McDecryptor.csproj
index 3514bdc..6c588cf 100644
--- a/McDecryptor/McDecryptor.csproj
+++ b/McDecryptor/McDecryptor.csproj
@@ -49,18 +49,8 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Config.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Properties\Resources.Designer.cs">
-      <AutoGen>True</AutoGen>
-      <DesignTime>True</DesignTime>
-      <DependentUpon>Resources.resx</DependentUpon>
-    </Compile>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="App.config" />
-    <None Include="default.cfg" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\McCrypt\LibMcCrypt.csproj">
@@ -68,12 +58,6 @@
       <Name>LibMcCrypt</Name>
     </ProjectReference>
   </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="Properties\Resources.resx">
-      <Generator>ResXFileCodeGenerator</Generator>
-      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
-    </EmbeddedResource>
-  </ItemGroup>
   <ItemGroup>
     <Content Include="illager.ico" />
   </ItemGroup>
diff --git a/McDecryptor/Program.cs b/McDecryptor/Program.cs
index 9e8dbcc..8714c50 100644
--- a/McDecryptor/Program.cs
+++ b/McDecryptor/Program.cs
@@ -2,8 +2,11 @@
 using System.Collections.Generic;
 using System.IO;
 using System.IO.Compression;
+using System.Net.Configuration;
+using System.Runtime.Remoting.Messaging;
 using System.Threading;
 using McCrypt;
+using McCrypt.PackData;
 
 namespace McDecryptor
 {
@@ -45,7 +48,8 @@ namespace McDecryptor
                 });
                 thrd.Priority = ThreadPriority.Highest;
                 thrd.Start();
-                threads.Add(thrd);
+                if (!Config.MultiThread) thrd.Join();
+                else threads.Add(thrd);
             }
 
             foreach (Thread t in threads.ToArray())
@@ -62,7 +66,8 @@ namespace McDecryptor
                 });
                 thrd.Priority = ThreadPriority.Highest;
                 thrd.Start();
-                threads.Add(thrd);
+                if (!Config.MultiThread) thrd.Join();
+                else threads.Add(thrd);
 
             }
 
@@ -72,6 +77,28 @@ namespace McDecryptor
             threads.Clear();
         }
 
+        static void DecryptPack(string filePath)
+        {
+            string levelDatFile = Path.Combine(filePath, "level.dat");
+            string skinsJsonFile = Path.Combine(filePath, "skins.json");
+            string oldSchoolZipe = Path.Combine(filePath, "content.zipe");
+
+            Marketplace.DecryptContents(filePath);
+
+            if (Config.CrackPacks)
+            {
+                if (File.Exists(oldSchoolZipe))
+                    Marketplace.CrackZipe(oldSchoolZipe);
+
+                if (File.Exists(levelDatFile))
+                    Marketplace.CrackLevelDat(levelDatFile);
+
+                if (File.Exists(skinsJsonFile))
+                    Marketplace.CrackSkinsJson(skinsJsonFile);
+            }
+        }
+
+
         static void Main(string[] args)
         {
             Console.WriteLine("-- McDecryptor --");
@@ -118,39 +145,21 @@ namespace McDecryptor
             }
 
             
-            List<ContentListing> premiumContents = new List<ContentListing>();
             Console.WriteLine("\n\n");
             Console.WriteLine("Select what to decrypt: ");
             int total = 1;
 
+            PReader pReader = new PReader();
+            PEntry[] entries = pReader.PEntryList;
 
-            foreach (string searchFolder in Config.SearchFolders)
+            foreach (PEntry entry in entries)
             {
-                foreach(string searchModule in Config.SearchModules)
-                {
-                    string moduleFolder = Path.Combine(searchFolder, searchModule);
+                Console.WriteLine(total.ToString() + ") (" + entry.ProductType + ") " + entry.Name);
 
-                    if (Directory.Exists(moduleFolder))
-                    {
-                        foreach (string moduleItem in Directory.GetDirectories(moduleFolder, "*", SearchOption.TopDirectoryOnly))
-                        {
-                            ContentListing cList = new ContentListing();
-                            cList.Name = Manifest.ReadName(Path.Combine(moduleItem, "manifest.json"));
-                            cList.Type = searchModule;
-                            cList.Id = total;
-                            cList.Path = moduleItem;
-
-                            premiumContents.Add(cList);
-
-                            Console.WriteLine(cList.Id.ToString() + ") (" + cList.Type + ") " + cList.Name);
-
-                            total++;
-                        }
-                    }
-                }
+                total++;
             }
 
-            Console.WriteLine("Select multiple (seperated by ',') or write \"ALL\"");
+            Console.WriteLine("Select one or multiple (seperated by ',') or write \"ALL\", numerical values");
 
             List<int> toDecrypt = new List<int>();
             while (true)
@@ -165,9 +174,9 @@ namespace McDecryptor
                             toDecrypt.Add(i);
                         break;
                     }
-                    string[] entries = readText.Split(',');
+                    string[] txtentries = readText.Split(',');
 
-                    foreach(string entry in entries) {
+                    foreach(string entry in txtentries) {
                         int tdc = Convert.ToInt32(entry.Trim())-1;
                         if (tdc < 0 || tdc >= total)
                             continue;
@@ -183,8 +192,8 @@ namespace McDecryptor
 
             foreach (int decryptMe in toDecrypt.ToArray())
             {
-                ContentListing cListing = premiumContents.ToArray()[decryptMe];
-                string outFolder = Path.Combine(Config.OutFolder, cListing.Type, EscapeFilename(cListing.Name));
+                PEntry cEntry = entries[decryptMe];
+                string outFolder = Path.Combine(Config.OutFolder, cEntry.ProductType, EscapeFilename(cEntry.Name));
 
                 int counter = 1;
                 string ogOutFolder = outFolder;
@@ -194,38 +203,62 @@ namespace McDecryptor
                     counter++;
                 }
 
-
-                Console.WriteLine("Decrypting: " + cListing.Name);
+                Console.WriteLine("Decrypting: " + cEntry.Name);
                 Directory.CreateDirectory(outFolder);
-                CopyDirectory(cListing.Path, outFolder);
-                try 
+                try
                 {
-                    string levelDatFile = Path.Combine(outFolder, "level.dat");
-                    string skinsJsonFile = Path.Combine(outFolder, "skins.json");
-                    string oldSchoolZipe = Path.Combine(outFolder, "content.zipe");
-
-                    Marketplace.DecryptContents(outFolder);
-
-                    if (Config.CrackPacks)
+                    if (cEntry.ProductType == "addon")
                     {
-                        if (File.Exists(oldSchoolZipe))
-                            Marketplace.CrackZipe(oldSchoolZipe);
+                        // copy & decrypt main file
+                        string subDir = Path.Combine(outFolder, cEntry.Type);
+                        Directory.CreateDirectory(subDir);
+                        CopyDirectory(cEntry.FilePath, subDir);
+                        DecryptPack(subDir);
 
-                        if (File.Exists(levelDatFile))
-                            Marketplace.CrackLevelDat(levelDatFile);
+                        // copy & decrypt file dependancies
+                        PEntry[] deps = pReader.GetDependancies(cEntry);
+                        foreach (PEntry dependancy in deps)
+                        {
+                            string newDir = Path.Combine(outFolder, dependancy.Type);
+                            Console.WriteLine("Decrypting dependancy: " + dependancy.Type + "/" + dependancy.Name);
+                            Directory.CreateDirectory(newDir);
 
-                        if (File.Exists(skinsJsonFile))
-                            Marketplace.CrackSkinsJson(skinsJsonFile);
+                            CopyDirectory(dependancy.FilePath, newDir);
+                            DecryptPack(newDir);
+                        }
+
+                    }
+                    else if(cEntry.ProductType == "minecraftWorlds")
+                    {
+                        CopyDirectory(cEntry.FilePath, outFolder);
+                        DecryptPack(outFolder);
+
+                        PEntry[] deps = pReader.GetDependancies(cEntry);
+                        foreach (PEntry dependancy in deps)
+                        {
+                            Console.WriteLine("Decrypting dependancy: " + dependancy.ProductType+"/"+dependancy.Name);
+                            string newDir = Path.Combine(outFolder, dependancy.ProductType, Path.GetFileName(dependancy.FilePath));
+
+                            CopyDirectory(dependancy.FilePath, newDir);
+                            DecryptPack(newDir);
+                        }
+                    }
+                    else
+                    {
+                        CopyDirectory(cEntry.FilePath, outFolder);
+                        DecryptPack(outFolder);
                     }
 
                     if (Config.ZipPacks)
                     {
-                        Console.WriteLine("Zipping: " + cListing.Name);
+                        Console.WriteLine("Zipping: " + cEntry.Name);
 
                         string ext = "";
-                        if (File.Exists(levelDatFile))
+                        if (cEntry.ProductType == "world_templates")
                             ext += ".mctemplate";
-                        else if (false)
+                        else if (cEntry.ProductType == "minecraftWorlds")
+                            ext += ".mcworld";
+                        else if (cEntry.ProductType == "addon")
                             ext += ".mcaddon";
                         else
                             ext += ".mcpack";
@@ -241,9 +274,10 @@ namespace McDecryptor
                 }
                 catch (Exception e)
                 {
-                    Console.Error.WriteLine("Failed to decrypt: " + cListing.Name+ " "+e.Message);
+                    Console.Error.WriteLine("Failed to decrypt: " + cEntry.Name + " " + e.Message);
                     Directory.Delete(outFolder, true);
                 }
+                
 
 
             }
diff --git a/McEncryptor/.vs/McEncryptor.csproj.dtbcache.json b/McEncryptor/.vs/McEncryptor.csproj.dtbcache.json
new file mode 100644
index 0000000..b97d324
--- /dev/null
+++ b/McEncryptor/.vs/McEncryptor.csproj.dtbcache.json
@@ -0,0 +1 @@
+{"RootPath":"C:\\Users\\Li\\Desktop\\git\\McTools\\McEncryptor","ProjectFileName":"McEncryptor.csproj","Configuration":"Debug|AnyCPU","FrameworkPath":"","Sources":[{"SourceFile":"Program.cs"},{"SourceFile":"Properties\\AssemblyInfo.cs"},{"SourceFile":"obj\\Debug\\.NETFramework,Version=v4.8.AssemblyAttributes.cs"}],"References":[{"Reference":"C:\\Users\\Li\\Desktop\\git\\McTools\\McCrypt\\bin\\Debug\\LibMcCrypt.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":true,"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:\\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.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\\McEncryptor\\bin\\Debug\\McEncryptor.exe","OutputItemRelativePath":"McEncryptor.exe"},{"OutputItemFullPath":"C:\\Users\\Li\\Desktop\\git\\McTools\\McEncryptor\\bin\\Debug\\McEncryptor.pdb","OutputItemRelativePath":"McEncryptor.pdb"}],"CopyToOutputEntries":[]}
\ No newline at end of file

From a018445d40c8b313a32d33bbe2a911ea0b20d2a7 Mon Sep 17 00:00:00 2001
From: Li <li@silica.codes>
Date: Tue, 21 Jan 2025 22:59:46 +1300
Subject: [PATCH 3/6] Update thing

---
 .gitignore                                       | 4 +++-
 McDecryptor/.vs/McDecryptor.csproj.dtbcache.json | 1 -
 McEncryptor/.vs/McEncryptor.csproj.dtbcache.json | 1 -
 3 files changed, 3 insertions(+), 3 deletions(-)
 delete mode 100644 McDecryptor/.vs/McDecryptor.csproj.dtbcache.json
 delete mode 100644 McEncryptor/.vs/McEncryptor.csproj.dtbcache.json

diff --git a/.gitignore b/.gitignore
index 61f7f67..9081b05 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,6 @@
 *.suo
 */bin/*
 */obj/*
-.vs/*
\ No newline at end of file
+.vs/*
+McEncryptor/.vs/*
+McDecryptor/.vs/*
\ No newline at end of file
diff --git a/McDecryptor/.vs/McDecryptor.csproj.dtbcache.json b/McDecryptor/.vs/McDecryptor.csproj.dtbcache.json
deleted file mode 100644
index a654af2..0000000
--- a/McDecryptor/.vs/McDecryptor.csproj.dtbcache.json
+++ /dev/null
@@ -1 +0,0 @@
-{"RootPath":"C:\\Users\\Li\\Desktop\\git\\McTools\\McDecryptor","ProjectFileName":"McDecryptor.csproj","Configuration":"Debug|AnyCPU","FrameworkPath":"","Sources":[{"SourceFile":"Config.cs"},{"SourceFile":"Program.cs"},{"SourceFile":"Properties\\AssemblyInfo.cs"},{"SourceFile":"Properties\\Resources.Designer.cs"},{"SourceFile":"obj\\Debug\\.NETFramework,Version=v4.8.AssemblyAttributes.cs"}],"References":[{"Reference":"C:\\Users\\Li\\Desktop\\git\\McTools\\McCrypt\\bin\\Debug\\LibMcCrypt.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":true,"ProjectPath":""},{"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:\\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\\McDecryptor\\bin\\Debug\\McDecryptor.exe","OutputItemRelativePath":"McDecryptor.exe"},{"OutputItemFullPath":"C:\\Users\\Li\\Desktop\\git\\McTools\\McDecryptor\\bin\\Debug\\McDecryptor.pdb","OutputItemRelativePath":"McDecryptor.pdb"}],"CopyToOutputEntries":[]}
\ No newline at end of file
diff --git a/McEncryptor/.vs/McEncryptor.csproj.dtbcache.json b/McEncryptor/.vs/McEncryptor.csproj.dtbcache.json
deleted file mode 100644
index b97d324..0000000
--- a/McEncryptor/.vs/McEncryptor.csproj.dtbcache.json
+++ /dev/null
@@ -1 +0,0 @@
-{"RootPath":"C:\\Users\\Li\\Desktop\\git\\McTools\\McEncryptor","ProjectFileName":"McEncryptor.csproj","Configuration":"Debug|AnyCPU","FrameworkPath":"","Sources":[{"SourceFile":"Program.cs"},{"SourceFile":"Properties\\AssemblyInfo.cs"},{"SourceFile":"obj\\Debug\\.NETFramework,Version=v4.8.AssemblyAttributes.cs"}],"References":[{"Reference":"C:\\Users\\Li\\Desktop\\git\\McTools\\McCrypt\\bin\\Debug\\LibMcCrypt.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":true,"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:\\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.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\\McEncryptor\\bin\\Debug\\McEncryptor.exe","OutputItemRelativePath":"McEncryptor.exe"},{"OutputItemFullPath":"C:\\Users\\Li\\Desktop\\git\\McTools\\McEncryptor\\bin\\Debug\\McEncryptor.pdb","OutputItemRelativePath":"McEncryptor.pdb"}],"CopyToOutputEntries":[]}
\ No newline at end of file

From 1637fdf8b82121bb137019d6fb231eae74266864 Mon Sep 17 00:00:00 2001
From: Li <li@silica.codes>
Date: Tue, 21 Jan 2025 23:00:56 +1300
Subject: [PATCH 4/6] add .mcpersona file extension

---
 McDecryptor/Program.cs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/McDecryptor/Program.cs b/McDecryptor/Program.cs
index 8714c50..f52c5c8 100644
--- a/McDecryptor/Program.cs
+++ b/McDecryptor/Program.cs
@@ -260,6 +260,8 @@ namespace McDecryptor
                             ext += ".mcworld";
                         else if (cEntry.ProductType == "addon")
                             ext += ".mcaddon";
+                        else if (cEntry.ProductType == "persona")
+                            ext += ".mcpersona";
                         else
                             ext += ".mcpack";
 

From 5b6fefa8e6abac3aaab37d4c8b039587b97cdca4 Mon Sep 17 00:00:00 2001
From: Li <li@silica.codes>
Date: Wed, 19 Feb 2025 18:03:31 +1300
Subject: [PATCH 5/6] Fix infinite recursion

---
 McCrypt/PackData/PEntry.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/McCrypt/PackData/PEntry.cs b/McCrypt/PackData/PEntry.cs
index 829d9f9..0c9aee1 100644
--- a/McCrypt/PackData/PEntry.cs
+++ b/McCrypt/PackData/PEntry.cs
@@ -83,7 +83,7 @@ namespace McCrypt.PackData
                 {
                     return Manifest.ReadDependancyUuids(this.ManifestPath);
                 }
-                else if(this.ProductType == "minecraftWorlds")
+                else if(Path.GetFileName(Path.GetDirectoryName(this.FilePath)) == "minecraftWorlds")
                 {
                     List<String> uuids = new List<String>();
                     if(File.Exists(WorldResourcePacksPath)) uuids.AddRange(Manifest.ReadWorldPackList(WorldResourcePacksPath));

From 1c3ccf029a4ff90bcd500b65175e83e84a2cd302 Mon Sep 17 00:00:00 2001
From: Li <li@silica.codes>
Date: Wed, 19 Feb 2025 18:15:41 +1300
Subject: [PATCH 6/6] Change it to use .Type

---
 McCrypt/PackData/PEntry.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/McCrypt/PackData/PEntry.cs b/McCrypt/PackData/PEntry.cs
index 0c9aee1..baf3dee 100644
--- a/McCrypt/PackData/PEntry.cs
+++ b/McCrypt/PackData/PEntry.cs
@@ -83,7 +83,7 @@ namespace McCrypt.PackData
                 {
                     return Manifest.ReadDependancyUuids(this.ManifestPath);
                 }
-                else if(Path.GetFileName(Path.GetDirectoryName(this.FilePath)) == "minecraftWorlds")
+                else if(this.Type == "minecraftWorlds")
                 {
                     List<String> uuids = new List<String>();
                     if(File.Exists(WorldResourcePacksPath)) uuids.AddRange(Manifest.ReadWorldPackList(WorldResourcePacksPath));