summaryrefslogtreecommitdiff
path: root/src/StardewModdingAPI/Framework
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2017-07-10 22:10:27 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2017-07-10 22:10:27 -0400
commit674ad0d90f8780130a5fcefb3869acfe2315df2a (patch)
treeeb79fa170a0b74a34061ea1d6838ae5589131c85 /src/StardewModdingAPI/Framework
parent1edd98aef027faa768f56cf0b3591e64e20ba096 (diff)
parent834aee92f222fa739d7daa6c71f48b7e0df47ffe (diff)
downloadSMAPI-674ad0d90f8780130a5fcefb3869acfe2315df2a.tar.gz
SMAPI-674ad0d90f8780130a5fcefb3869acfe2315df2a.tar.bz2
SMAPI-674ad0d90f8780130a5fcefb3869acfe2315df2a.zip
Merge branch 'develop' into stable
Diffstat (limited to 'src/StardewModdingAPI/Framework')
-rw-r--r--src/StardewModdingAPI/Framework/CursorPosition.cs2
-rw-r--r--src/StardewModdingAPI/Framework/DeprecationManager.cs2
-rw-r--r--src/StardewModdingAPI/Framework/ModLoading/ModResolver.cs29
-rw-r--r--src/StardewModdingAPI/Framework/ModRegistry.cs14
-rw-r--r--src/StardewModdingAPI/Framework/Models/Manifest.cs2
-rw-r--r--src/StardewModdingAPI/Framework/Models/ManifestDependency.cs6
-rw-r--r--src/StardewModdingAPI/Framework/Monitor.cs8
-rw-r--r--src/StardewModdingAPI/Framework/SGame.cs22
-rw-r--r--src/StardewModdingAPI/Framework/Serialisation/ManifestFieldConverter.cs6
9 files changed, 61 insertions, 30 deletions
diff --git a/src/StardewModdingAPI/Framework/CursorPosition.cs b/src/StardewModdingAPI/Framework/CursorPosition.cs
index 4f256da5..0fb2309b 100644
--- a/src/StardewModdingAPI/Framework/CursorPosition.cs
+++ b/src/StardewModdingAPI/Framework/CursorPosition.cs
@@ -1,4 +1,4 @@
-#if SMAPI_2_0
+#if !SMAPI_1_x
using Microsoft.Xna.Framework;
namespace StardewModdingAPI.Framework
diff --git a/src/StardewModdingAPI/Framework/DeprecationManager.cs b/src/StardewModdingAPI/Framework/DeprecationManager.cs
index 153d8829..43e82d74 100644
--- a/src/StardewModdingAPI/Framework/DeprecationManager.cs
+++ b/src/StardewModdingAPI/Framework/DeprecationManager.cs
@@ -54,7 +54,7 @@ namespace StardewModdingAPI.Framework
// show SMAPI 2.0 meta-warning
if(this.MarkWarned("SMAPI", "SMAPI 2.0 meta-warning", "2.0"))
- this.Monitor.Log("Some mods may stop working in SMAPI 2.0 (but they'll work fine for now). Try updating mods with 'deprecated code' warnings; if that doesn't remove the warnings, let the mod authors know about this message or see http://community.playstarbound.com/threads/135000 for details.", LogLevel.Warn);
+ this.Monitor.Log("Some mods may stop working in SMAPI 2.0 (but they'll work fine for now). Try updating mods with 'deprecated code' warnings; if that doesn't remove the warnings, let the mod authors know about this message or see http://stardewvalleywiki.com/Modding:SMAPI_2.0 for details.", LogLevel.Warn);
// build message
string message = $"{source ?? "An unknown mod"} uses deprecated code ({nounPhrase}).";
diff --git a/src/StardewModdingAPI/Framework/ModLoading/ModResolver.cs b/src/StardewModdingAPI/Framework/ModLoading/ModResolver.cs
index 38dddce7..b75453b7 100644
--- a/src/StardewModdingAPI/Framework/ModLoading/ModResolver.cs
+++ b/src/StardewModdingAPI/Framework/ModLoading/ModResolver.cs
@@ -95,6 +95,9 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <param name="apiVersion">The current SMAPI version.</param>
public void ValidateManifests(IEnumerable<IModMetadata> mods, ISemanticVersion apiVersion)
{
+ mods = mods.ToArray();
+
+ // validate each manifest
foreach (IModMetadata mod in mods)
{
// skip if already failed
@@ -137,7 +140,7 @@ namespace StardewModdingAPI.Framework.ModLoading
}
// validate required fields
-#if SMAPI_2_0
+#if !SMAPI_1_x
{
List<string> missingFields = new List<string>(3);
@@ -153,6 +156,24 @@ namespace StardewModdingAPI.Framework.ModLoading
}
#endif
}
+
+ // validate IDs are unique
+#if !SMAPI_1_x
+ {
+ var duplicatesByID = mods
+ .GroupBy(mod => mod.Manifest.UniqueID?.Trim(), mod => mod, StringComparer.InvariantCultureIgnoreCase)
+ .Where(p => p.Count() > 1);
+ foreach (var group in duplicatesByID)
+ {
+ foreach (IModMetadata mod in group)
+ {
+ if (mod.Status == ModMetadataStatus.Failed)
+ continue; // don't replace metadata error
+ mod.SetStatus(ModMetadataStatus.Failed, $"its unique ID '{mod.Manifest.UniqueID}' is used by multiple mods ({string.Join(", ", group.Select(p => p.DisplayName))}).");
+ }
+ }
+ }
+#endif
}
/// <summary>Sort the given mods by the order they should be loaded.</summary>
@@ -234,10 +255,10 @@ namespace StardewModdingAPI.Framework.ModLoading
MinVersion = entry.MinimumVersion,
Mod = dependencyMod,
IsRequired =
-#if SMAPI_2_0
- entry.IsRequired
-#else
+#if SMAPI_1_x
true
+#else
+ entry.IsRequired
#endif
}
)
diff --git a/src/StardewModdingAPI/Framework/ModRegistry.cs b/src/StardewModdingAPI/Framework/ModRegistry.cs
index a427bdb7..8f30d813 100644
--- a/src/StardewModdingAPI/Framework/ModRegistry.cs
+++ b/src/StardewModdingAPI/Framework/ModRegistry.cs
@@ -36,14 +36,24 @@ namespace StardewModdingAPI.Framework
/// <returns>Returns the matching mod's metadata, or <c>null</c> if not found.</returns>
public IManifest Get(string uniqueID)
{
- return this.GetAll().FirstOrDefault(p => p.UniqueID == uniqueID);
+ // normalise search ID
+ if (string.IsNullOrWhiteSpace(uniqueID))
+ return null;
+ uniqueID = uniqueID.Trim();
+
+ // find match
+ return this.GetAll().FirstOrDefault(p =>
+#if SMAPI_1_x
+ p.UniqueID != null &&
+#endif
+ p.UniqueID.Trim().Equals(uniqueID, StringComparison.InvariantCultureIgnoreCase));
}
/// <summary>Get whether a mod has been loaded.</summary>
/// <param name="uniqueID">The mod's unique ID.</param>
public bool IsLoaded(string uniqueID)
{
- return this.GetAll().Any(p => p.UniqueID == uniqueID);
+ return this.Get(uniqueID) != null;
}
/****
diff --git a/src/StardewModdingAPI/Framework/Models/Manifest.cs b/src/StardewModdingAPI/Framework/Models/Manifest.cs
index 08b88025..1b5c2646 100644
--- a/src/StardewModdingAPI/Framework/Models/Manifest.cs
+++ b/src/StardewModdingAPI/Framework/Models/Manifest.cs
@@ -38,7 +38,7 @@ namespace StardewModdingAPI.Framework.Models
/// <summary>The unique mod ID.</summary>
public string UniqueID { get; set; }
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Whether the mod uses per-save config files.</summary>
[Obsolete("Use " + nameof(Mod) + "." + nameof(Mod.Helper) + "." + nameof(IModHelper.ReadConfig) + " instead")]
public bool PerSaveConfigs { get; set; }
diff --git a/src/StardewModdingAPI/Framework/Models/ManifestDependency.cs b/src/StardewModdingAPI/Framework/Models/ManifestDependency.cs
index 25d92a29..67f906e3 100644
--- a/src/StardewModdingAPI/Framework/Models/ManifestDependency.cs
+++ b/src/StardewModdingAPI/Framework/Models/ManifestDependency.cs
@@ -12,7 +12,7 @@
/// <summary>The minimum required version (if any).</summary>
public ISemanticVersion MinimumVersion { get; set; }
-#if SMAPI_2_0
+#if !SMAPI_1_x
/// <summary>Whether the dependency must be installed to use the mod.</summary>
public bool IsRequired { get; set; }
#endif
@@ -25,7 +25,7 @@
/// <param name="minimumVersion">The minimum required version (if any).</param>
/// <param name="required">Whether the dependency must be installed to use the mod.</param>
public ManifestDependency(string uniqueID, string minimumVersion
-#if SMAPI_2_0
+#if !SMAPI_1_x
, bool required = true
#endif
)
@@ -34,7 +34,7 @@
this.MinimumVersion = !string.IsNullOrWhiteSpace(minimumVersion)
? new SemanticVersion(minimumVersion)
: null;
-#if SMAPI_2_0
+#if !SMAPI_1_x
this.IsRequired = required;
#endif
}
diff --git a/src/StardewModdingAPI/Framework/Monitor.cs b/src/StardewModdingAPI/Framework/Monitor.cs
index 6359b454..5ae24a73 100644
--- a/src/StardewModdingAPI/Framework/Monitor.cs
+++ b/src/StardewModdingAPI/Framework/Monitor.cs
@@ -45,7 +45,7 @@ namespace StardewModdingAPI.Framework
/// <summary>Whether SMAPI is aborting. Mods don't need to worry about this unless they have background tasks.</summary>
public bool IsExiting => this.ExitTokenSource.IsCancellationRequested;
-#if SMAPI_2_0
+#if !SMAPI_1_x
/// <summary>Whether to show the full log stamps (with time/level/logger) in the console. If false, shows a simplified stamp with only the logger.</summary>
internal bool ShowFullStampInConsole { get; set; }
#endif
@@ -97,7 +97,7 @@ namespace StardewModdingAPI.Framework
this.ExitTokenSource.Cancel();
}
-#if SMAPI_2_0
+#if !SMAPI_1_x
/// <summary>Write a newline to the console and log file.</summary>
internal void Newline()
{
@@ -108,7 +108,7 @@ namespace StardewModdingAPI.Framework
}
#endif
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Log a message for the player or developer, using the specified console color.</summary>
/// <param name="source">The name of the mod logging the message.</param>
/// <param name="message">The message to log.</param>
@@ -144,7 +144,7 @@ namespace StardewModdingAPI.Framework
string levelStr = level.ToString().ToUpper().PadRight(Monitor.MaxLevelLength);
string fullMessage = $"[{DateTime.Now:HH:mm:ss} {levelStr} {source}] {message}";
-#if SMAPI_2_0
+#if !SMAPI_1_x
string consoleMessage = this.ShowFullStampInConsole ? fullMessage : $"[{source}] {message}";
#else
string consoleMessage = fullMessage;
diff --git a/src/StardewModdingAPI/Framework/SGame.cs b/src/StardewModdingAPI/Framework/SGame.cs
index c7784c60..d6f1a05b 100644
--- a/src/StardewModdingAPI/Framework/SGame.cs
+++ b/src/StardewModdingAPI/Framework/SGame.cs
@@ -118,7 +118,7 @@ namespace StardewModdingAPI.Framework
/// <summary>The time of day (in 24-hour military format) at last check.</summary>
private int PreviousTime;
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>The day of month (1–28) at last check.</summary>
private int PreviousDay;
@@ -292,7 +292,7 @@ namespace StardewModdingAPI.Framework
if (this.FirstUpdate)
{
GameEvents.InvokeInitialize(this.Monitor);
-#if !SMAPI_2_0
+#if SMAPI_1_x
GameEvents.InvokeLoadContent(this.Monitor);
#endif
GameEvents.InvokeGameLoaded(this.Monitor);
@@ -324,7 +324,7 @@ namespace StardewModdingAPI.Framework
Context.IsWorldReady = true;
SaveEvents.InvokeAfterLoad(this.Monitor);
-#if !SMAPI_2_0
+#if SMAPI_1_x
PlayerEvents.InvokeLoadedGame(this.Monitor, new EventArgsLoadedGameChanged(Game1.hasLoadedGame));
#endif
TimeEvents.InvokeAfterDayStarted(this.Monitor);
@@ -382,7 +382,7 @@ namespace StardewModdingAPI.Framework
bool isClick = framePressedKeys.Contains(SButton.MouseLeft) || (framePressedKeys.Contains(SButton.ControllerA) && !currentlyPressedKeys.Contains(SButton.ControllerX));
// get cursor position
-#if SMAPI_2_0
+#if !SMAPI_1_x
ICursorPosition cursor;
{
// cursor position
@@ -398,7 +398,7 @@ namespace StardewModdingAPI.Framework
// raise button pressed
foreach (SButton button in framePressedKeys)
{
-#if SMAPI_2_0
+#if !SMAPI_1_x
InputEvents.InvokeButtonPressed(this.Monitor, button, cursor, isClick);
#endif
@@ -420,7 +420,7 @@ namespace StardewModdingAPI.Framework
// raise button released
foreach (SButton button in frameReleasedKeys)
{
-#if SMAPI_2_0
+#if !SMAPI_1_x
bool wasClick =
(button == SButton.MouseLeft && previousPressedKeys.Contains(SButton.MouseLeft)) // released left click
|| (button == SButton.ControllerA && previousPressedKeys.Contains(SButton.ControllerA) && !previousPressedKeys.Contains(SButton.ControllerX));
@@ -503,7 +503,7 @@ namespace StardewModdingAPI.Framework
if (this.GetHash(Game1.locations) != this.PreviousGameLocations)
LocationEvents.InvokeLocationsChanged(this.Monitor, Game1.locations);
-#if !SMAPI_2_0
+#if SMAPI_1_x
// raise player changed
if (Game1.player != this.PreviousFarmer)
PlayerEvents.InvokeFarmerChanged(this.Monitor, this.PreviousFarmer, Game1.player);
@@ -538,7 +538,7 @@ namespace StardewModdingAPI.Framework
// raise time changed
if (Game1.timeOfDay != this.PreviousTime)
TimeEvents.InvokeTimeOfDayChanged(this.Monitor, this.PreviousTime, Game1.timeOfDay);
-#if !SMAPI_2_0
+#if SMAPI_1_x
if (Game1.dayOfMonth != this.PreviousDay)
TimeEvents.InvokeDayOfMonthChanged(this.Monitor, this.PreviousDay, Game1.dayOfMonth);
if (Game1.currentSeason != this.PreviousSeason)
@@ -566,7 +566,7 @@ namespace StardewModdingAPI.Framework
this.PreviousTime = Game1.timeOfDay;
this.PreviousMineLevel = Game1.mine?.mineLevel ?? 0;
this.PreviousSaveID = Game1.uniqueIDForThisGame;
-#if !SMAPI_2_0
+#if SMAPI_1_x
this.PreviousFarmer = Game1.player;
this.PreviousDay = Game1.dayOfMonth;
this.PreviousSeason = Game1.currentSeason;
@@ -577,7 +577,7 @@ namespace StardewModdingAPI.Framework
/*********
** Game day transition event (obsolete)
*********/
-#if !SMAPI_2_0
+#if SMAPI_1_x
if (Game1.newDay != this.PreviousIsNewDay)
{
TimeEvents.InvokeOnNewDay(this.Monitor, this.PreviousDay, Game1.dayOfMonth, Game1.newDay);
@@ -603,7 +603,7 @@ namespace StardewModdingAPI.Framework
GameEvents.InvokeUpdateTick(this.Monitor);
if (this.FirstUpdate)
{
-#if !SMAPI_2_0
+#if SMAPI_1_x
GameEvents.InvokeFirstUpdateTick(this.Monitor);
#endif
this.FirstUpdate = false;
diff --git a/src/StardewModdingAPI/Framework/Serialisation/ManifestFieldConverter.cs b/src/StardewModdingAPI/Framework/Serialisation/ManifestFieldConverter.cs
index 5be0f0b6..6947311b 100644
--- a/src/StardewModdingAPI/Framework/Serialisation/ManifestFieldConverter.cs
+++ b/src/StardewModdingAPI/Framework/Serialisation/ManifestFieldConverter.cs
@@ -73,11 +73,11 @@ namespace StardewModdingAPI.Framework.Serialisation
{
string uniqueID = obj.Value<string>(nameof(IManifestDependency.UniqueID));
string minVersion = obj.Value<string>(nameof(IManifestDependency.MinimumVersion));
-#if SMAPI_2_0
+#if SMAPI_1_x
+ result.Add(new ManifestDependency(uniqueID, minVersion));
+#else
bool required = obj.Value<bool?>(nameof(IManifestDependency.IsRequired)) ?? true;
result.Add(new ManifestDependency(uniqueID, minVersion, required));
-#else
- result.Add(new ManifestDependency(uniqueID, minVersion));
#endif
}
return result.ToArray();