summaryrefslogtreecommitdiff
path: root/src/StardewModdingAPI/Program.cs
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2017-05-13 18:20:09 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2017-05-13 18:20:09 -0400
commit63edebaef1019ce103f5a86d55e1d1c4eb8d371c (patch)
treea61b1ebd08324477b049699b63f405a5025555d6 /src/StardewModdingAPI/Program.cs
parent66d2b5746ab063b89ca42525a78e217e71d00858 (diff)
downloadSMAPI-63edebaef1019ce103f5a86d55e1d1c4eb8d371c.tar.gz
SMAPI-63edebaef1019ce103f5a86d55e1d1c4eb8d371c.tar.bz2
SMAPI-63edebaef1019ce103f5a86d55e1d1c4eb8d371c.zip
decouple mod metadata resolution from main SMAPI logic (#285)
This makes the logic more self-contained for eventual unit testing, and makes failed mods available during dependency resolution so we can make errors more relevant.
Diffstat (limited to 'src/StardewModdingAPI/Program.cs')
-rw-r--r--src/StardewModdingAPI/Program.cs51
1 files changed, 45 insertions, 6 deletions
diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs
index 7b421895..c8840538 100644
--- a/src/StardewModdingAPI/Program.cs
+++ b/src/StardewModdingAPI/Program.cs
@@ -313,14 +313,45 @@ namespace StardewModdingAPI
// load mods
int modsLoaded;
{
- // load mods
+ // get mod metadata (in dependency order)
+ this.Monitor.Log("Loading mod metadata...");
JsonHelper jsonHelper = new JsonHelper();
+ ModMetadata[] mods = new ModResolver(this.Settings.ModCompatibility)
+ .GetMods(Constants.ModPath, new JsonHelper())
+ .ToArray();
+
+ // check for deprecated metadata
IList<Action> deprecationWarnings = new List<Action>();
- ModMetadata[] mods = new ModResolver(this.Monitor, this.DeprecationManager, this.Settings.ModCompatibility)
- .FindMods(Constants.ModPath, new JsonHelper(), deprecationWarnings);
- modsLoaded = this.LoadMods(mods, jsonHelper, (SContentManager)Game1.content, deprecationWarnings);
+ foreach (ModMetadata mod in mods)
+ {
+ // missing unique ID
+ if (string.IsNullOrWhiteSpace(mod.Manifest.UniqueID))
+ deprecationWarnings.Add(() => this.Monitor.Log($"{mod.DisplayName} doesn't have specify a {nameof(IManifest.UniqueID)} field in its manifest. This will be required in an upcoming SMAPI release.", LogLevel.Warn));
- // log deprecation warnings together
+ // per-save directories
+ if ((mod.Manifest as Manifest)?.PerSaveConfigs == true)
+ {
+ deprecationWarnings.Add(() => this.DeprecationManager.Warn(mod.DisplayName, $"{nameof(Manifest)}.{nameof(Manifest.PerSaveConfigs)}", "1.0", DeprecationLevel.Info));
+ try
+ {
+ string psDir = Path.Combine(mod.DirectoryPath, "psconfigs");
+ Directory.CreateDirectory(psDir);
+ if (!Directory.Exists(psDir))
+ {
+ mod.Status = ModMetadataStatus.Failed;
+ mod.Error = "it requires per-save configuration files ('psconfigs') which couldn't be created for some reason.";
+ }
+ }
+ catch (Exception ex)
+ {
+ mod.Status = ModMetadataStatus.Failed;
+ mod.Error = $"it requires per-save configuration files ('psconfigs') which couldn't be created: {ex.GetLogSummary()}";
+ }
+ }
+ }
+
+ // load mods
+ modsLoaded = this.LoadMods(mods, jsonHelper, (SContentManager)Game1.content, deprecationWarnings);
foreach (Action warning in deprecationWarnings)
warning();
}
@@ -474,9 +505,17 @@ namespace StardewModdingAPI
AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => modAssemblyLoader.ResolveAssembly(e.Name);
foreach (ModMetadata metadata in mods)
{
+ // validate status
+ if (metadata.Status == ModMetadataStatus.Failed)
+ {
+ LogSkip(metadata, metadata.Error);
+ continue;
+ }
+
+ // get basic info
IManifest manifest = metadata.Manifest;
string assemblyPath = Path.Combine(metadata.DirectoryPath, metadata.Manifest.EntryDll);
-
+
// preprocess & load mod assembly
Assembly modAssembly;
try