summaryrefslogtreecommitdiff
path: root/src/SMAPI
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI')
-rw-r--r--src/SMAPI/Framework/ModHelpers/ModHelper.cs9
-rw-r--r--src/SMAPI/Framework/ModRegistry.cs3
-rw-r--r--src/SMAPI/Framework/SCore.cs32
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