summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/StardewModdingAPI/Framework/ModRegistry.cs30
-rw-r--r--src/StardewModdingAPI/Framework/Models/IncompatibleMod.cs40
-rw-r--r--src/StardewModdingAPI/Program.cs35
-rw-r--r--src/StardewModdingAPI/SemanticVersion.cs4
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;