fix content packs always failing to load if they declare a dependency on a SMAPI mod
This commit is contained in:
parent
ba0acf89c1
commit
dcfae980bf
|
@ -44,7 +44,8 @@
|
|||
* added support for overlaying image assets with semi-transparency;
|
||||
* mods can now load PNGs even if the game is currently drawing.
|
||||
* When comparing mod versions, SMAPI now considers `-unofficial` to be lower-precedence than any other value (e.g. `1.0-beta` is now considered newer than `1.0-unofficial` regardless of normal sorting).
|
||||
* Fixed `IContentPack.ReadJsonFile` allowing non-relative paths.
|
||||
* Fixed content packs' `ReadJsonFile` allowing non-relative paths.
|
||||
* Fixed content pack always failing to load if they declare a dependency on a SMAPI mod.
|
||||
* Fixed trace logs not showing path for invalid mods.
|
||||
* Fixed 'no update keys' warning not shown for mods with only invalid update keys.
|
||||
* Fixed `Context.IsPlayerFree` being true before the player finishes transitioning to a new location in multiplayer.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/****
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue