diff --git a/Dalamud/Plugin/PluginManager.cs b/Dalamud/Plugin/PluginManager.cs index 810bc1ca3..d08c85f11 100644 --- a/Dalamud/Plugin/PluginManager.cs +++ b/Dalamud/Plugin/PluginManager.cs @@ -68,8 +68,44 @@ namespace Dalamud.Plugin } public void LoadPlugins() { - LoadPluginsAt(new DirectoryInfo(this.pluginDirectory), false); - LoadPluginsAt(new DirectoryInfo(this.devPluginDirectory), true); + var loadDirectories = new List<(DirectoryInfo dirInfo, bool isRaw)> { + (new DirectoryInfo(this.pluginDirectory), false), + (new DirectoryInfo(this.devPluginDirectory), true) + }; + + var pluginDefs = new List<(FileInfo dllFile, PluginDefinition definition, bool isRaw)>(); + foreach (var (dirInfo, isRaw) in loadDirectories) { + if (!dirInfo.Exists) continue; + + var pluginDlls = dirInfo.GetFiles("*.dll", SearchOption.AllDirectories).Where(x => x.Extension == ".dll"); + + // Preload definitions to be able to determine load order + foreach (var dllFile in pluginDlls) { + var defJson = new FileInfo(Path.Combine(dllFile.Directory.FullName, $"{Path.GetFileNameWithoutExtension(dllFile.Name)}.json")); + PluginDefinition def = null; + if (defJson.Exists) + def = JsonConvert.DeserializeObject(File.ReadAllText(defJson.FullName)); + pluginDefs.Add((dllFile, def, isRaw)); + } + } + + // Sort for load order - unloaded definitions have default priority of 0 + pluginDefs.Sort( + (info1, info2) => { + var prio1 = info1.definition?.LoadPriority ?? 0; + var prio2 = info2.definition?.LoadPriority ?? 0; + return prio2.CompareTo(prio1); + }); + + // Pass preloaded definitions to LoadPluginFromAssembly, because we already loaded them anyways + foreach (var (dllFile, definition, isRaw) in pluginDefs) { + try { + LoadPluginFromAssembly(dllFile, isRaw, PluginLoadReason.Boot, true, definition); + } + catch (Exception ex) { + Log.Error(ex, $"Plugin load for {dllFile.FullName} failed."); + } + } } public void DisablePlugin(PluginDefinition definition) { @@ -95,12 +131,12 @@ namespace Dalamud.Plugin this.Plugins.Remove(thisPlugin); } - public bool LoadPluginFromAssembly(FileInfo dllFile, bool raw, PluginLoadReason reason, bool preloaded = false, PluginDefinition preloadedDef = null) { + public bool LoadPluginFromAssembly(FileInfo dllFile, bool isRaw, PluginLoadReason reason, bool preloaded = false, PluginDefinition preloadedDef = null) { Log.Information("Loading plugin at {0}", dllFile.Directory.FullName); // If this entire folder has been marked as a disabled plugin, don't even try to load anything var disabledFile = new FileInfo(Path.Combine(dllFile.Directory.FullName, ".disabled")); - if (disabledFile.Exists && !raw) // should raw/dev plugins really not respect this? + if (disabledFile.Exists && !isRaw) // should raw/dev plugins really not respect this? { Log.Information("Plugin {0} is disabled.", dllFile.FullName); return false; @@ -116,7 +152,7 @@ namespace Dalamud.Plugin // Preloaded if (preloaded) { - if (preloadedDef == null && !raw) + if (preloadedDef == null && !isRaw) { Log.Information("Plugin DLL {0} has no definition.", dllFile.FullName); return false; @@ -149,7 +185,7 @@ namespace Dalamud.Plugin } } // but developer plugins don't require one to load - else if (!raw) + else if (!isRaw) { Log.Information("Plugin DLL {0} has no definition.", dllFile.FullName); return false; @@ -206,7 +242,7 @@ namespace Dalamud.Plugin plugin.Initialize(dalamudInterface); Log.Information("Loaded plugin: {0}", plugin.Name); - this.Plugins.Add((plugin, pluginDef, dalamudInterface, raw)); + this.Plugins.Add((plugin, pluginDef, dalamudInterface, isRaw)); return true; } @@ -217,41 +253,6 @@ namespace Dalamud.Plugin return false; } - private void LoadPluginsAt(DirectoryInfo folder, bool raw) { - if (folder.Exists) - { - Log.Information("Loading plugins at {0}", folder); - var pluginDlls = folder.GetFiles("*.dll", SearchOption.AllDirectories); - - // Preload definitions to be able to determine load order - var pluginDefs = new List<(FileInfo dllFile, PluginDefinition definition)>(); - foreach (var dllFile in pluginDlls) { - var defJson = new FileInfo(Path.Combine(dllFile.Directory.FullName, $"{Path.GetFileNameWithoutExtension(dllFile.Name)}.json")); - PluginDefinition def = null; - if (defJson.Exists) - def = JsonConvert.DeserializeObject(File.ReadAllText(defJson.FullName)); - pluginDefs.Add((dllFile, def)); - } - - // Sort for load order - unloaded definitions have default priority of 0 - pluginDefs.Sort( - (info1, info2) => { - var prio1 = info1.definition?.LoadPriority ?? 0; - var prio2 = info2.definition?.LoadPriority ?? 0; - return prio2.CompareTo(prio1); - }); - - // Pass preloaded definitions to LoadPluginFromAssembly, because we already loaded them anyways - foreach (var infos in pluginDefs) { - try { - LoadPluginFromAssembly(infos.dllFile, raw, PluginLoadReason.Boot, true, infos.definition); - } catch (Exception ex) { - Log.Error(ex, $"Plugin load for {infos.dllFile.FullName} failed."); - } - } - } - } - public void ReloadPlugins() { UnloadPlugins(); LoadPlugins();