diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/StardewModdingAPI/Framework/ModRegistry.cs | 30 | ||||
-rw-r--r-- | src/StardewModdingAPI/Framework/Models/IncompatibleMod.cs | 40 | ||||
-rw-r--r-- | src/StardewModdingAPI/Program.cs | 35 | ||||
-rw-r--r-- | src/StardewModdingAPI/SemanticVersion.cs | 4 |
4 files changed, 73 insertions, 36 deletions
diff --git a/src/StardewModdingAPI/Framework/ModRegistry.cs b/src/StardewModdingAPI/Framework/ModRegistry.cs index 209f1928..233deb3c 100644 --- a/src/StardewModdingAPI/Framework/ModRegistry.cs +++ b/src/StardewModdingAPI/Framework/ModRegistry.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; +using System.Text.RegularExpressions; +using StardewModdingAPI.Framework.Models; namespace StardewModdingAPI.Framework { @@ -18,10 +20,21 @@ namespace StardewModdingAPI.Framework /// <summary>The friendly mod names treated as deprecation warning sources (assembly full name => mod name).</summary> private readonly IDictionary<string, string> ModNamesByAssembly = new Dictionary<string, string>(); + /// <summary>The mod versions which should be disabled due to incompatibility.</summary> + private readonly IncompatibleMod[] IncompatibleMods; + /********* ** Public methods *********/ + /// <summary>Construct an instance.</summary> + /// <param name="incompatibleMods">The mod versions which should be disabled due to incompatibility.</param> + public ModRegistry(IEnumerable<IncompatibleMod> incompatibleMods) + { + this.IncompatibleMods = incompatibleMods.ToArray(); + } + + /**** ** IModRegistry ****/ @@ -113,5 +126,22 @@ namespace StardewModdingAPI.Framework // no known assembly found return null; } + + /// <summary>Get a record indicating why a mod is incompatible (if applicable).</summary> + /// <param name="manifest">The mod manifest.</param> + /// <returns>Returns the incompatibility record if applicable, else <c>null</c>.</returns> + internal IncompatibleMod GetIncompatibilityRecord(IManifest manifest) + { + string key = !string.IsNullOrWhiteSpace(manifest.UniqueID) ? manifest.UniqueID : manifest.EntryDll; + return ( + from mod in this.IncompatibleMods + where + mod.ID == key + && (mod.LowerSemanticVersion == null || !manifest.Version.IsOlderThan(mod.LowerSemanticVersion)) + && !manifest.Version.IsNewerThan(mod.UpperSemanticVersion) + && (string.IsNullOrWhiteSpace(mod.ForceCompatibleVersion) || !Regex.IsMatch(manifest.Version.ToString(), mod.ForceCompatibleVersion, RegexOptions.IgnoreCase)) + select mod + ).FirstOrDefault(); + } } }
\ No newline at end of file diff --git a/src/StardewModdingAPI/Framework/Models/IncompatibleMod.cs b/src/StardewModdingAPI/Framework/Models/IncompatibleMod.cs index bcf5639c..29e18ddb 100644 --- a/src/StardewModdingAPI/Framework/Models/IncompatibleMod.cs +++ b/src/StardewModdingAPI/Framework/Models/IncompatibleMod.cs @@ -1,4 +1,5 @@ -using System.Text.RegularExpressions; +using System.Runtime.Serialization; +using Newtonsoft.Json; namespace StardewModdingAPI.Framework.Models { @@ -8,6 +9,9 @@ namespace StardewModdingAPI.Framework.Models /********* ** Accessors *********/ + /**** + ** From config + ****/ /// <summary>The unique mod ID.</summary> public string ID { get; set; } @@ -34,24 +38,28 @@ namespace StardewModdingAPI.Framework.Models public string ReasonPhrase { get; set; } + /**** + ** Injected + ****/ + /// <summary>The semantic version corresponding to <see cref="LowerVersion"/>.</summary> + [JsonIgnore] + public ISemanticVersion LowerSemanticVersion { get; set; } + + /// <summary>The semantic version corresponding to <see cref="UpperVersion"/>.</summary> + [JsonIgnore] + public ISemanticVersion UpperSemanticVersion { get; set; } + + /********* - ** Public methods + ** Private methods *********/ - /// <summary>Get whether the specified version is compatible according to this metadata.</summary> - /// <param name="version">The current version of the matching mod.</param> - public bool IsCompatible(ISemanticVersion version) + /// <summary>The method called when the model finishes deserialising.</summary> + /// <param name="context">The deserialisation context.</param> + [OnDeserialized] + private void OnDeserialized(StreamingContext context) { - ISemanticVersion lowerVersion = this.LowerVersion != null ? new SemanticVersion(this.LowerVersion) : null; - ISemanticVersion upperVersion = new SemanticVersion(this.UpperVersion); - - // ignore versions not in range - if (lowerVersion != null && version.IsOlderThan(lowerVersion)) - return true; - if (version.IsNewerThan(upperVersion)) - return true; - - // allow versions matching override - return !string.IsNullOrWhiteSpace(this.ForceCompatibleVersion) && Regex.IsMatch(version.ToString(), this.ForceCompatibleVersion, RegexOptions.IgnoreCase); + this.LowerSemanticVersion = this.LowerVersion != null ? new SemanticVersion(this.LowerVersion) : null; + this.UpperSemanticVersion = this.UpperVersion != null ? new SemanticVersion(this.UpperVersion) : null; } } } diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs index 9a6f07ef..3b6d1702 100644 --- a/src/StardewModdingAPI/Program.cs +++ b/src/StardewModdingAPI/Program.cs @@ -64,7 +64,7 @@ namespace StardewModdingAPI internal SGame GameInstance; /// <summary>Tracks the installed mods.</summary> - internal readonly ModRegistry ModRegistry = new ModRegistry(); + internal readonly ModRegistry ModRegistry; /// <summary>Manages deprecation warnings.</summary> internal readonly DeprecationManager DeprecationManager; @@ -92,6 +92,7 @@ namespace StardewModdingAPI // initialise this.Monitor = new Monitor("SMAPI", this.ConsoleManager, this.LogFile, this.ExitGameImmediately) { WriteToConsole = writeToConsole }; + this.ModRegistry = new ModRegistry(this.Settings.IncompatibleMods); this.DeprecationManager = new DeprecationManager(this.Monitor, this.ModRegistry); } @@ -388,28 +389,22 @@ namespace StardewModdingAPI continue; } - // validate known incompatible mods + // validate compatibility + IncompatibleMod compatibility = this.ModRegistry.GetIncompatibilityRecord(manifest); + if (compatibility != null) { - string modKey = !string.IsNullOrWhiteSpace(manifest.UniqueID) ? manifest.UniqueID : manifest.EntryDll; - IncompatibleMod compatibility = this.Settings.IncompatibleMods.FirstOrDefault(p => p.ID == modKey); - if(compatibility != null) - { - if (!compatibility.IsCompatible(manifest.Version)) - { - bool hasOfficialUrl = !string.IsNullOrWhiteSpace(compatibility.UpdateUrl); - bool hasUnofficialUrl = !string.IsNullOrWhiteSpace(compatibility.UnofficialUpdateUrl); + bool hasOfficialUrl = !string.IsNullOrWhiteSpace(compatibility.UpdateUrl); + bool hasUnofficialUrl = !string.IsNullOrWhiteSpace(compatibility.UnofficialUpdateUrl); - string reasonPhrase = compatibility.ReasonPhrase ?? "it isn't compatible with the latest version of the game"; - string warning = $"Skipped {compatibility.Name} because {reasonPhrase}. Please check for a version newer than {compatibility.UpperVersion} here:"; - if (hasOfficialUrl) - warning += !hasUnofficialUrl ? $" {compatibility.UpdateUrl}" : $"{Environment.NewLine}- official mod: {compatibility.UpdateUrl}"; - if (hasUnofficialUrl) - warning += $"{Environment.NewLine}- unofficial update: {compatibility.UnofficialUpdateUrl}"; + string reasonPhrase = compatibility.ReasonPhrase ?? "it isn't compatible with the latest version of the game"; + string warning = $"Skipped {compatibility.Name} because {reasonPhrase}. Please check for a version newer than {compatibility.UpperVersion} here:"; + if (hasOfficialUrl) + warning += !hasUnofficialUrl ? $" {compatibility.UpdateUrl}" : $"{Environment.NewLine}- official mod: {compatibility.UpdateUrl}"; + if (hasUnofficialUrl) + warning += $"{Environment.NewLine}- unofficial update: {compatibility.UnofficialUpdateUrl}"; - this.Monitor.Log(warning, LogLevel.Error); - continue; - } - } + this.Monitor.Log(warning, LogLevel.Error); + continue; } // validate SMAPI version diff --git a/src/StardewModdingAPI/SemanticVersion.cs b/src/StardewModdingAPI/SemanticVersion.cs index 3cb592e2..9610562f 100644 --- a/src/StardewModdingAPI/SemanticVersion.cs +++ b/src/StardewModdingAPI/SemanticVersion.cs @@ -63,9 +63,13 @@ namespace StardewModdingAPI /// <summary>Get an integer indicating whether this version precedes (less than 0), supercedes (more than 0), or is equivalent to (0) the specified version.</summary> /// <param name="other">The version to compare with this instance.</param> + /// <exception cref="ArgumentNullException">The <paramref name="other"/> value is null.</exception> /// <remarks>The implementation is defined by Semantic Version 2.0 (http://semver.org/).</remarks> public int CompareTo(ISemanticVersion other) { + if(other == null) + throw new ArgumentNullException(nameof(other)); + const int same = 0; const int curNewer = 1; const int curOlder = -1; |