diff options
Diffstat (limited to 'src/SMAPI')
-rw-r--r-- | src/SMAPI/Framework/ModHelpers/ModHelper.cs | 9 | ||||
-rw-r--r-- | src/SMAPI/Framework/ModRegistry.cs | 3 | ||||
-rw-r--r-- | src/SMAPI/Framework/SCore.cs | 32 |
3 files changed, 24 insertions, 20 deletions
diff --git a/src/SMAPI/Framework/ModHelpers/ModHelper.cs b/src/SMAPI/Framework/ModHelpers/ModHelper.cs index ae0368f0..5e190e55 100644 --- a/src/SMAPI/Framework/ModHelpers/ModHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/ModHelper.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using StardewModdingAPI.Events; using StardewModdingAPI.Framework.Input; using StardewModdingAPI.Toolkit.Serialisation; @@ -17,7 +16,7 @@ namespace StardewModdingAPI.Framework.ModHelpers ** Properties *********/ /// <summary>The content packs loaded for this mod.</summary> - private readonly IContentPack[] ContentPacks; + private readonly Lazy<IContentPack[]> ContentPacks; /// <summary>Create a transitional content pack.</summary> private readonly Func<string, IManifest, IContentPack> CreateContentPack; @@ -84,7 +83,7 @@ namespace StardewModdingAPI.Framework.ModHelpers /// <param name="deprecationManager">Manages deprecation warnings.</param> /// <exception cref="ArgumentNullException">An argument is null or empty.</exception> /// <exception cref="InvalidOperationException">The <paramref name="modDirectory"/> path does not exist on disk.</exception> - public ModHelper(string modID, string modDirectory, JsonHelper jsonHelper, SInputState inputState, IModEvents events, IContentHelper contentHelper, ICommandHelper commandHelper, IDataHelper dataHelper, IModRegistry modRegistry, IReflectionHelper reflectionHelper, IMultiplayerHelper multiplayer, ITranslationHelper translationHelper, IEnumerable<IContentPack> contentPacks, Func<string, IManifest, IContentPack> createContentPack, DeprecationManager deprecationManager) + public ModHelper(string modID, string modDirectory, JsonHelper jsonHelper, SInputState inputState, IModEvents events, IContentHelper contentHelper, ICommandHelper commandHelper, IDataHelper dataHelper, IModRegistry modRegistry, IReflectionHelper reflectionHelper, IMultiplayerHelper multiplayer, ITranslationHelper translationHelper, Func<IContentPack[]> contentPacks, Func<string, IManifest, IContentPack> createContentPack, DeprecationManager deprecationManager) : base(modID) { // validate directory @@ -104,7 +103,7 @@ namespace StardewModdingAPI.Framework.ModHelpers this.Reflection = reflectionHelper ?? throw new ArgumentNullException(nameof(reflectionHelper)); this.Multiplayer = multiplayer ?? throw new ArgumentNullException(nameof(multiplayer)); this.Translation = translationHelper ?? throw new ArgumentNullException(nameof(translationHelper)); - this.ContentPacks = contentPacks.ToArray(); + this.ContentPacks = new Lazy<IContentPack[]>(contentPacks); this.CreateContentPack = createContentPack; this.DeprecationManager = deprecationManager; this.Events = events; @@ -204,7 +203,7 @@ namespace StardewModdingAPI.Framework.ModHelpers /// <summary>Get all content packs loaded for this mod.</summary> public IEnumerable<IContentPack> GetContentPacks() { - return this.ContentPacks; + return this.ContentPacks.Value; } /**** diff --git a/src/SMAPI/Framework/ModRegistry.cs b/src/SMAPI/Framework/ModRegistry.cs index da68fce3..8ce3172c 100644 --- a/src/SMAPI/Framework/ModRegistry.cs +++ b/src/SMAPI/Framework/ModRegistry.cs @@ -18,6 +18,9 @@ namespace StardewModdingAPI.Framework /// <summary>An assembly full name => mod lookup.</summary> private readonly IDictionary<string, IModMetadata> ModNamesByAssembly = new Dictionary<string, IModMetadata>(); + /// <summary>Whether all mod assemblies have been loaded.</summary> + public bool AreAllModsLoaded { get; set; } + /// <summary>Whether all mods have been initialised and their <see cref="IMod.Entry"/> method called.</summary> public bool AreAllModsInitialised { get; set; } diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index 128659c7..4b95917b 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -713,15 +713,8 @@ namespace StardewModdingAPI.Framework mod.SetStatus(ModMetadataStatus.Failed, errorPhrase); } - // load content packs first (so they're available to mods) - foreach (IModMetadata contentPack in mods.Where(p => p.IsContentPack)) - { - if (!this.TryLoadMod(contentPack, mods, modAssemblyLoader, proxyFactory, jsonHelper, contentCore, modDatabase, suppressUpdateChecks, out string errorPhrase, out string errorDetails)) - LogSkip(contentPack, errorPhrase, errorDetails); - } - - // load SMAPI mods - foreach (IModMetadata contentPack in mods.Where(p => !p.IsContentPack)) + // load mods + foreach (IModMetadata contentPack in mods) { if (!this.TryLoadMod(contentPack, mods, modAssemblyLoader, proxyFactory, jsonHelper, contentCore, modDatabase, suppressUpdateChecks, out string errorPhrase, out string errorDetails)) LogSkip(contentPack, errorPhrase, errorDetails); @@ -730,6 +723,9 @@ namespace StardewModdingAPI.Framework IModMetadata[] loadedContentPacks = this.ModRegistry.GetAll(assemblyMods: false).ToArray(); IModMetadata[] loadedMods = this.ModRegistry.GetAll(contentPacks: false).ToArray(); + // unlock content packs + this.ModRegistry.AreAllModsLoaded = true; + // log loaded mods this.Monitor.Log($"Loaded {loadedMods.Length} mods" + (loadedMods.Length > 0 ? ":" : "."), LogLevel.Info); foreach (IModMetadata metadata in loadedMods.OrderBy(p => p.DisplayName)) @@ -972,11 +968,17 @@ namespace StardewModdingAPI.Framework return false; // get content packs - IContentPack[] contentPacks = this.ModRegistry - .GetAll(assemblyMods: false) - .Where(p => p.IsContentPack && mod.HasID(p.Manifest.ContentPackFor.UniqueID)) - .Select(p => p.ContentPack) - .ToArray(); + IContentPack[] GetContentPacks() + { + if (!this.ModRegistry.AreAllModsLoaded) + throw new InvalidOperationException("Can't access content packs before SMAPI finishes loading mods."); + + return this.ModRegistry + .GetAll(assemblyMods: false) + .Where(p => p.IsContentPack && mod.HasID(p.Manifest.ContentPackFor.UniqueID)) + .Select(p => p.ContentPack) + .ToArray(); + } // init mod helpers IMonitor monitor = this.GetSecondaryMonitor(mod.DisplayName); @@ -998,7 +1000,7 @@ namespace StardewModdingAPI.Framework return new ContentPack(packDirPath, packManifest, packContentHelper, this.Toolkit.JsonHelper); } - modHelper = new ModHelper(manifest.UniqueID, mod.DirectoryPath, this.Toolkit.JsonHelper, this.GameInstance.Input, events, contentHelper, commandHelper, dataHelper, modRegistryHelper, reflectionHelper, multiplayerHelper, translationHelper, contentPacks, CreateTransitionalContentPack, this.DeprecationManager); + modHelper = new ModHelper(manifest.UniqueID, mod.DirectoryPath, this.Toolkit.JsonHelper, this.GameInstance.Input, events, contentHelper, commandHelper, dataHelper, modRegistryHelper, reflectionHelper, multiplayerHelper, translationHelper, GetContentPacks, CreateTransitionalContentPack, this.DeprecationManager); } // init mod |