diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2017-05-13 18:20:09 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2017-05-13 18:20:09 -0400 |
commit | 63edebaef1019ce103f5a86d55e1d1c4eb8d371c (patch) | |
tree | a61b1ebd08324477b049699b63f405a5025555d6 /src/StardewModdingAPI/Program.cs | |
parent | 66d2b5746ab063b89ca42525a78e217e71d00858 (diff) | |
download | SMAPI-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.cs | 51 |
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 |