From 2781c27786739abc6f8f948e3068b0c997296524 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 19 May 2017 23:49:59 -0400 Subject: fix error when loading a mod with no version --- release-notes.md | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'release-notes.md') diff --git a/release-notes.md b/release-notes.md index 641071e5..ce91c693 100644 --- a/release-notes.md +++ b/release-notes.md @@ -10,6 +10,12 @@ For mod developers: images). --> +## 1.13.1 +See [log](https://github.com/Pathoschild/SMAPI/compare/1.13...1.13.1). + +For players: +* Fixed error when loading a mod with no version. + ## 1.13 See [log](https://github.com/Pathoschild/SMAPI/compare/1.12...1.13). -- cgit From 9ef4876c5e7de02d17785ebe7950f0edc57ae194 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 20 May 2017 00:29:04 -0400 Subject: add metadata to internal mod registry & use mod display name everywhere --- release-notes.md | 3 +- src/StardewModdingAPI.Tests/ModResolverTests.cs | 1 + src/StardewModdingAPI/Framework/IModMetadata.cs | 47 ++++++++++++++++++++++ src/StardewModdingAPI/Framework/ModHelper.cs | 7 ++-- .../Framework/ModLoading/IModMetadata.cs | 39 ------------------ .../Framework/ModLoading/ModMetadata.cs | 11 +++++ src/StardewModdingAPI/Framework/ModRegistry.cs | 14 +++---- src/StardewModdingAPI/Program.cs | 23 ++++++----- src/StardewModdingAPI/StardewModdingAPI.csproj | 2 +- 9 files changed, 86 insertions(+), 61 deletions(-) create mode 100644 src/StardewModdingAPI/Framework/IModMetadata.cs delete mode 100644 src/StardewModdingAPI/Framework/ModLoading/IModMetadata.cs (limited to 'release-notes.md') diff --git a/release-notes.md b/release-notes.md index ce91c693..b7f5f1f7 100644 --- a/release-notes.md +++ b/release-notes.md @@ -14,7 +14,8 @@ For mod developers: See [log](https://github.com/Pathoschild/SMAPI/compare/1.13...1.13.1). For players: -* Fixed error when loading a mod with no version. +* Fixed errors when loading a mod with no name or version. +* Fixed mods with no manifest `Name` field having no name (SMAPI will now shows their filename). ## 1.13 See [log](https://github.com/Pathoschild/SMAPI/compare/1.12...1.13). diff --git a/src/StardewModdingAPI.Tests/ModResolverTests.cs b/src/StardewModdingAPI.Tests/ModResolverTests.cs index efa6fa06..8cf5a29e 100644 --- a/src/StardewModdingAPI.Tests/ModResolverTests.cs +++ b/src/StardewModdingAPI.Tests/ModResolverTests.cs @@ -5,6 +5,7 @@ using System.Linq; using Moq; using Newtonsoft.Json; using NUnit.Framework; +using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.Models; using StardewModdingAPI.Framework.ModLoading; using StardewModdingAPI.Framework.Serialisation; diff --git a/src/StardewModdingAPI/Framework/IModMetadata.cs b/src/StardewModdingAPI/Framework/IModMetadata.cs new file mode 100644 index 00000000..56ac25f1 --- /dev/null +++ b/src/StardewModdingAPI/Framework/IModMetadata.cs @@ -0,0 +1,47 @@ +using StardewModdingAPI.Framework.Models; +using StardewModdingAPI.Framework.ModLoading; + +namespace StardewModdingAPI.Framework +{ + /// Metadata for a mod. + internal interface IModMetadata + { + /********* + ** Accessors + *********/ + /// The mod's display name. + string DisplayName { get; } + + /// The mod's full directory path. + string DirectoryPath { get; } + + /// The mod manifest. + IManifest Manifest { get; } + + /// Optional metadata about a mod version that SMAPI should assume is compatible or broken, regardless of whether it detects incompatible code. + ModCompatibility Compatibility { get; } + + /// The metadata resolution status. + ModMetadataStatus Status { get; } + + /// The reason the metadata is invalid, if any. + string Error { get; } + + /// The mod instance (if it was loaded). + IMod Mod { get; } + + + /********* + ** Public methods + *********/ + /// Set the mod status. + /// The metadata resolution status. + /// The reason the metadata is invalid, if any. + /// Return the instance for chaining. + IModMetadata SetStatus(ModMetadataStatus status, string error = null); + + /// Set the mod instance. + /// The mod instance to set. + IModMetadata SetMod(IMod mod); + } +} diff --git a/src/StardewModdingAPI/Framework/ModHelper.cs b/src/StardewModdingAPI/Framework/ModHelper.cs index 7810148c..f939b83c 100644 --- a/src/StardewModdingAPI/Framework/ModHelper.cs +++ b/src/StardewModdingAPI/Framework/ModHelper.cs @@ -37,6 +37,7 @@ namespace StardewModdingAPI.Framework ** Public methods *********/ /// Construct an instance. + /// The mod's display name. /// The manifest for the associated mod. /// The full path to the mod's folder. /// Encapsulate SMAPI's JSON parsing. @@ -46,7 +47,7 @@ namespace StardewModdingAPI.Framework /// Simplifies access to private game code. /// An argument is null or empty. /// The path does not exist on disk. - public ModHelper(IManifest manifest, string modDirectory, JsonHelper jsonHelper, IModRegistry modRegistry, CommandManager commandManager, SContentManager contentManager, IReflectionHelper reflection) + public ModHelper(string displayName, IManifest manifest, string modDirectory, JsonHelper jsonHelper, IModRegistry modRegistry, CommandManager commandManager, SContentManager contentManager, IReflectionHelper reflection) { // validate if (string.IsNullOrWhiteSpace(modDirectory)) @@ -61,9 +62,9 @@ namespace StardewModdingAPI.Framework // initialise this.DirectoryPath = modDirectory; this.JsonHelper = jsonHelper; - this.Content = new ContentHelper(contentManager, modDirectory, manifest.Name); + this.Content = new ContentHelper(contentManager, modDirectory, displayName); this.ModRegistry = modRegistry; - this.ConsoleCommands = new CommandHelper(manifest.Name, commandManager); + this.ConsoleCommands = new CommandHelper(displayName, commandManager); this.Reflection = reflection; } diff --git a/src/StardewModdingAPI/Framework/ModLoading/IModMetadata.cs b/src/StardewModdingAPI/Framework/ModLoading/IModMetadata.cs deleted file mode 100644 index 3771ffdd..00000000 --- a/src/StardewModdingAPI/Framework/ModLoading/IModMetadata.cs +++ /dev/null @@ -1,39 +0,0 @@ -using StardewModdingAPI.Framework.Models; - -namespace StardewModdingAPI.Framework.ModLoading -{ - /// Metadata for a mod. - internal interface IModMetadata - { - /********* - ** Accessors - *********/ - /// The mod's display name. - string DisplayName { get; } - - /// The mod's full directory path. - string DirectoryPath { get; } - - /// The mod manifest. - IManifest Manifest { get; } - - /// Optional metadata about a mod version that SMAPI should assume is compatible or broken, regardless of whether it detects incompatible code. - ModCompatibility Compatibility { get; } - - /// The metadata resolution status. - ModMetadataStatus Status { get; } - - /// The reason the metadata is invalid, if any. - string Error { get; } - - - /********* - ** Public methods - *********/ - /// Set the mod status. - /// The metadata resolution status. - /// The reason the metadata is invalid, if any. - /// Return the instance for chaining. - IModMetadata SetStatus(ModMetadataStatus status, string error = null); - } -} diff --git a/src/StardewModdingAPI/Framework/ModLoading/ModMetadata.cs b/src/StardewModdingAPI/Framework/ModLoading/ModMetadata.cs index 7b25e090..ab590e10 100644 --- a/src/StardewModdingAPI/Framework/ModLoading/ModMetadata.cs +++ b/src/StardewModdingAPI/Framework/ModLoading/ModMetadata.cs @@ -26,6 +26,9 @@ namespace StardewModdingAPI.Framework.ModLoading /// The reason the metadata is invalid, if any. public string Error { get; private set; } + /// The mod instance (if it was loaded). + public IMod Mod { get; private set; } + /********* ** Public methods @@ -53,5 +56,13 @@ namespace StardewModdingAPI.Framework.ModLoading this.Error = error; return this; } + + /// Set the mod instance. + /// The mod instance to set. + public IModMetadata SetMod(IMod mod) + { + this.Mod = mod; + return this; + } } } diff --git a/src/StardewModdingAPI/Framework/ModRegistry.cs b/src/StardewModdingAPI/Framework/ModRegistry.cs index 3899aa3f..62063fbd 100644 --- a/src/StardewModdingAPI/Framework/ModRegistry.cs +++ b/src/StardewModdingAPI/Framework/ModRegistry.cs @@ -13,7 +13,7 @@ namespace StardewModdingAPI.Framework ** Properties *********/ /// The registered mod data. - private readonly List Mods = new List(); + private readonly List Mods = new List(); /// The friendly mod names treated as deprecation warning sources (assembly full name => mod name). private readonly IDictionary ModNamesByAssembly = new Dictionary(); @@ -28,7 +28,7 @@ namespace StardewModdingAPI.Framework /// Get metadata for all loaded mods. public IEnumerable GetAll() { - return this.Mods.Select(p => p.ModManifest); + return this.Mods.Select(p => p.Manifest); } /// Get metadata for a loaded mod. @@ -50,15 +50,15 @@ namespace StardewModdingAPI.Framework ** Internal methods ****/ /// Register a mod as a possible source of deprecation warnings. - /// The mod instance. - public void Add(IMod mod) + /// The mod metadata. + public void Add(IModMetadata metadata) { - this.Mods.Add(mod); - this.ModNamesByAssembly[mod.GetType().Assembly.FullName] = mod.ModManifest.Name; + this.Mods.Add(metadata); + this.ModNamesByAssembly[metadata.Mod.GetType().Assembly.FullName] = metadata.DisplayName; } /// Get all enabled mods. - public IEnumerable GetMods() + public IEnumerable GetMods() { return (from mod in this.Mods select mod); } diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs index ada05320..06523144 100644 --- a/src/StardewModdingAPI/Program.cs +++ b/src/StardewModdingAPI/Program.cs @@ -237,15 +237,15 @@ namespace StardewModdingAPI this.IsDisposed = true; // dispose mod data - foreach (IMod mod in this.ModRegistry.GetMods()) + foreach (IModMetadata mod in this.ModRegistry.GetMods()) { try { - (mod as IDisposable)?.Dispose(); + (mod.Mod as IDisposable)?.Dispose(); } catch (Exception ex) { - this.Monitor.Log($"The {mod.ModManifest.Name} mod failed during disposal: {ex.GetLogSummary()}.", LogLevel.Warn); + this.Monitor.Log($"The {mod.DisplayName} mod failed during disposal: {ex.GetLogSummary()}.", LogLevel.Warn); } } @@ -580,14 +580,15 @@ namespace StardewModdingAPI // inject data mod.ModManifest = manifest; - mod.Helper = new ModHelper(manifest, metadata.DirectoryPath, jsonHelper, this.ModRegistry, this.CommandManager, contentManager, this.Reflection); - mod.Monitor = this.GetSecondaryMonitor(manifest.Name); + mod.Helper = new ModHelper(metadata.DisplayName, manifest, metadata.DirectoryPath, jsonHelper, this.ModRegistry, this.CommandManager, contentManager, this.Reflection); + mod.Monitor = this.GetSecondaryMonitor(metadata.DisplayName); mod.PathOnDisk = metadata.DirectoryPath; // track mod - this.ModRegistry.Add(mod); + metadata.SetMod(mod); + this.ModRegistry.Add(metadata); modsLoaded += 1; - this.Monitor.Log($"Loaded {manifest.Name} by {manifest.Author}, v{manifest.Version} | {manifest.Description}", LogLevel.Info); + this.Monitor.Log($"Loaded {metadata.DisplayName} by {manifest.Author}, v{manifest.Version} | {manifest.Description}", LogLevel.Info); } catch (Exception ex) { @@ -596,21 +597,23 @@ namespace StardewModdingAPI } // initialise loaded mods - foreach (IMod mod in this.ModRegistry.GetMods()) + foreach (IModMetadata metadata in this.ModRegistry.GetMods()) { try { + IMod mod = metadata.Mod; + // call entry methods (mod as Mod)?.Entry(); // deprecated since 1.0 mod.Entry(mod.Helper); // raise deprecation warning for old Entry() methods if (this.DeprecationManager.IsVirtualMethodImplemented(mod.GetType(), typeof(Mod), nameof(Mod.Entry), new[] { typeof(object[]) })) - deprecationWarnings.Add(() => this.DeprecationManager.Warn(mod.ModManifest.Name, $"{nameof(Mod)}.{nameof(Mod.Entry)}(object[]) instead of {nameof(Mod)}.{nameof(Mod.Entry)}({nameof(IModHelper)})", "1.0", DeprecationLevel.Info)); + deprecationWarnings.Add(() => this.DeprecationManager.Warn(metadata.DisplayName, $"{nameof(Mod)}.{nameof(Mod.Entry)}(object[]) instead of {nameof(Mod)}.{nameof(Mod.Entry)}({nameof(IModHelper)})", "1.0", DeprecationLevel.Info)); } catch (Exception ex) { - this.Monitor.Log($"The {mod.ModManifest.Name} mod failed on entry initialisation. It will still be loaded, but may not function correctly.\n{ex.GetLogSummary()}", LogLevel.Warn); + this.Monitor.Log($"The {metadata.DisplayName} mod failed on entry initialisation. It will still be loaded, but may not function correctly.\n{ex.GetLogSummary()}", LogLevel.Warn); } } diff --git a/src/StardewModdingAPI/StardewModdingAPI.csproj b/src/StardewModdingAPI/StardewModdingAPI.csproj index 60171493..d8bfd473 100644 --- a/src/StardewModdingAPI/StardewModdingAPI.csproj +++ b/src/StardewModdingAPI/StardewModdingAPI.csproj @@ -122,7 +122,7 @@ - + -- cgit