From bbce3a649b50fed23842169f213dba6ba661210c Mon Sep 17 00:00:00 2001 From: Herp Derpinstine Date: Mon, 4 Nov 2024 00:11:12 -0600 Subject: [PATCH] Reworked Melon Folder Scanning to be manifest json aware --- MelonLoader/Melons/MelonFolderHandler.cs | 80 +++++++++++++----------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/MelonLoader/Melons/MelonFolderHandler.cs b/MelonLoader/Melons/MelonFolderHandler.cs index de455f0f..9eeb86af 100644 --- a/MelonLoader/Melons/MelonFolderHandler.cs +++ b/MelonLoader/Melons/MelonFolderHandler.cs @@ -9,6 +9,13 @@ internal class MelonFolderHandler { private static bool firstSpacer = false; + internal enum eScanType + { + UserLibs, + Plugins, + Mods, + } + internal static void ScanUserLibs(string path) { // Get Full Directory Path @@ -22,7 +29,7 @@ internal static void ScanUserLibs(string path) // Parse Folders bool hasWroteLine = false; List melonAssemblies = new(); - ProcessFolder(false, path, true, ref hasWroteLine, ref melonAssemblies); + ProcessFolder(eScanType.UserLibs, path, ref hasWroteLine, ref melonAssemblies); } internal static void ScanMelons(string path) where T : MelonTypeBase @@ -40,7 +47,7 @@ internal static void ScanMelons(string path) where T : MelonTypeBase bool isMod = melonType == typeof(MelonMod); bool hasWroteLine = false; List melonAssemblies = new(); - ProcessFolder(isMod, path, false, ref hasWroteLine, ref melonAssemblies); + ProcessFolder(isMod ? eScanType.Mods : eScanType.Plugins, path, ref hasWroteLine, ref melonAssemblies); // Parse Queue var melons = new List(); @@ -118,9 +125,8 @@ private static void LoadFolder(string path, } } - private static void ProcessFolder(bool isMod, + private static void ProcessFolder(eScanType scanType, string path, - bool userLibsOnly, ref bool hasWroteLine, ref List melonAssemblies) { @@ -131,10 +137,10 @@ private static void ProcessFolder(bool isMod, // Scan Directories List melonDirectories = new(); List userLibDirectories = new(); - ScanFolder(isMod, path, userLibsOnly, ref melonDirectories, ref userLibDirectories); + ScanFolder(scanType, path, ref melonDirectories, ref userLibDirectories); // Add Base Path to End of Directories List - if (userLibsOnly) + if (scanType == eScanType.UserLibs) userLibDirectories.Add(path); else melonDirectories.Add(path); @@ -145,7 +151,7 @@ private static void ProcessFolder(bool isMod, MelonUtils.AddNativeDLLDirectory(directory); Resolver.MelonAssemblyResolver.AddSearchDirectory(directory); } - if (!userLibsOnly) + if (scanType != eScanType.UserLibs) foreach (string directory in melonDirectories) Resolver.MelonAssemblyResolver.AddSearchDirectory(directory); @@ -154,15 +160,14 @@ private static void ProcessFolder(bool isMod, LoadFolder(dir, false, ref hasWroteLine, ref melonAssemblies); // Load Melons from Folders - if (!userLibsOnly) + if (scanType != eScanType.UserLibs) foreach (var dir in melonDirectories) LoadFolder(dir, true, ref hasWroteLine, ref melonAssemblies); } - private static void ScanFolder(bool isMod, + private static void ScanFolder(eScanType scanType, string path, - bool userLibsOnly, - ref List melonDirectories, + ref List melonDirectories, ref List userLibDirectories) { // Get Directories @@ -175,40 +180,39 @@ private static void ScanFolder(bool isMod, foreach (var dir in directories) { // Validate Path - if (!Directory.Exists(dir) - || userLibDirectories.Contains(dir) - || melonDirectories.Contains(dir)) + if (!Directory.Exists(dir)) continue; - // Validate Folder - if (IsDisabledFolder(dir, out string dirNameLower)) + // Validate Manifest + string manifestPath = Path.Combine(dir, "manifest.json"); + if (!File.Exists(manifestPath)) continue; - // Check for UserLibs - if (userLibsOnly || IsUserLibsFolder(dirNameLower)) - userLibDirectories.Add(dir); + // Check for Deeper UserLibs + string userLibsPath = Path.Combine(dir, "UserLibs"); + if (Directory.Exists(userLibsPath)) + { + userLibDirectories.Add(userLibsPath); + ScanFolder(eScanType.UserLibs, userLibsPath, ref melonDirectories, ref userLibDirectories); + } + + // Is UserLibs Scan? + if (scanType == eScanType.UserLibs) + userLibDirectories.Add(dir); // Add to Directories List else - melonDirectories.Add(dir); + { + // Check for Deeper Melon Folder + string melonPath = Path.Combine(dir, (scanType == eScanType.Plugins) ? "Plugins" : "Mods"); + if (Directory.Exists(melonPath)) + { + melonDirectories.Add(melonPath); + ScanFolder(scanType, melonPath, ref melonDirectories, ref userLibDirectories); + } - ScanFolder(isMod, dir, userLibsOnly, ref melonDirectories, ref userLibDirectories); + // Add to Directories List + melonDirectories.Add(dir); + } } } - - private static bool StartsOrEndsWith(string dirNameLower, string target) - => dirNameLower.StartsWith(target) - || dirNameLower.EndsWith(target); - - private static bool IsUserLibsFolder(string dirNameLower) - => StartsOrEndsWith(dirNameLower, "userlibs"); - - private static bool IsDisabledFolder(string path, - out string dirNameLower) - { - string dirName = new DirectoryInfo(path).Name; - dirNameLower = dirName.ToLowerInvariant(); - return StartsOrEndsWith(dirNameLower, "disabled") - || StartsOrEndsWith(dirNameLower, "old") - || StartsOrEndsWith(dirNameLower, "~"); - } } } \ No newline at end of file