summaryrefslogtreecommitdiff
path: root/src
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
parent1edd98aef027faa768f56cf0b3591e64e20ba096 (diff)
parent834aee92f222fa739d7daa6c71f48b7e0df47ffe (diff)
downloadSMAPI-674ad0d90f8780130a5fcefb3869acfe2315df2a.tar.gz
SMAPI-674ad0d90f8780130a5fcefb3869acfe2315df2a.tar.bz2
SMAPI-674ad0d90f8780130a5fcefb3869acfe2315df2a.zip
Merge branch 'develop' into stable
Diffstat (limited to 'src')
-rw-r--r--src/GlobalAssemblyInfo.cs4
-rw-r--r--src/StardewModdingAPI.Tests/Core/ModResolverTests.cs70
-rw-r--r--src/StardewModdingAPI/Command.cs2
-rw-r--r--src/StardewModdingAPI/Config.cs2
-rw-r--r--src/StardewModdingAPI/Constants.cs8
-rw-r--r--src/StardewModdingAPI/Events/EventArgsCommand.cs2
-rw-r--r--src/StardewModdingAPI/Events/EventArgsFarmerChanged.cs2
-rw-r--r--src/StardewModdingAPI/Events/EventArgsInput.cs2
-rw-r--r--src/StardewModdingAPI/Events/EventArgsLoadedGameChanged.cs2
-rw-r--r--src/StardewModdingAPI/Events/EventArgsNewDay.cs2
-rw-r--r--src/StardewModdingAPI/Events/EventArgsStringChanged.cs2
-rw-r--r--src/StardewModdingAPI/Events/GameEvents.cs20
-rw-r--r--src/StardewModdingAPI/Events/InputEvents.cs2
-rw-r--r--src/StardewModdingAPI/Events/PlayerEvents.cs6
-rw-r--r--src/StardewModdingAPI/Events/TimeEvents.cs8
-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
-rw-r--r--src/StardewModdingAPI/ICursorPosition.cs2
-rw-r--r--src/StardewModdingAPI/IManifestDependency.cs2
-rw-r--r--src/StardewModdingAPI/Log.cs2
-rw-r--r--src/StardewModdingAPI/Mod.cs8
-rw-r--r--src/StardewModdingAPI/Program.cs60
-rw-r--r--src/StardewModdingAPI/Utilities/SButton.cs18
-rw-r--r--src/TrainerMod/TrainerMod.csproj2
-rw-r--r--src/TrainerMod/manifest.json2
-rw-r--r--src/crossplatform.targets3
33 files changed, 196 insertions, 128 deletions
diff --git a/src/GlobalAssemblyInfo.cs b/src/GlobalAssemblyInfo.cs
index d2f2597f..d9a01635 100644
--- a/src/GlobalAssemblyInfo.cs
+++ b/src/GlobalAssemblyInfo.cs
@@ -2,5 +2,5 @@
using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.15.0.0")]
-[assembly: AssemblyFileVersion("1.15.0.0")] \ No newline at end of file
+[assembly: AssemblyVersion("1.15.1.0")]
+[assembly: AssemblyFileVersion("1.15.1.0")]
diff --git a/src/StardewModdingAPI.Tests/Core/ModResolverTests.cs b/src/StardewModdingAPI.Tests/Core/ModResolverTests.cs
index b451465e..eda3a425 100644
--- a/src/StardewModdingAPI.Tests/Core/ModResolverTests.cs
+++ b/src/StardewModdingAPI.Tests/Core/ModResolverTests.cs
@@ -126,7 +126,7 @@ namespace StardewModdingAPI.Tests.Core
public void ValidateManifests_Skips_Failed()
{
// arrange
- Mock<IModMetadata> mock = new Mock<IModMetadata>(MockBehavior.Strict);
+ Mock<IModMetadata> mock = this.GetMetadata("Mod A");
mock.Setup(p => p.Status).Returns(ModMetadataStatus.Failed);
// act
@@ -140,10 +140,8 @@ namespace StardewModdingAPI.Tests.Core
public void ValidateManifests_ModCompatibility_AssumeBroken_Fails()
{
// arrange
- Mock<IModMetadata> mock = new Mock<IModMetadata>(MockBehavior.Strict);
- mock.Setup(p => p.Status).Returns(ModMetadataStatus.Found);
- mock.Setup(p => p.Compatibility).Returns(new ModCompatibility { Compatibility = ModCompatibilityType.AssumeBroken });
- mock.Setup(p => p.SetStatus(ModMetadataStatus.Failed, It.IsAny<string>())).Returns(() => mock.Object);
+ Mock<IModMetadata> mock = this.GetMetadata("Mod A", new string[0], allowStatusChange: true);
+ this.SetupMetadataForValidation(mock, new ModCompatibility { Compatibility = ModCompatibilityType.AssumeBroken });
// act
new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"));
@@ -156,11 +154,9 @@ namespace StardewModdingAPI.Tests.Core
public void ValidateManifests_MinimumApiVersion_Fails()
{
// arrange
- Mock<IModMetadata> mock = new Mock<IModMetadata>(MockBehavior.Strict);
- mock.Setup(p => p.Status).Returns(ModMetadataStatus.Found);
- mock.Setup(p => p.Compatibility).Returns(() => null);
+ Mock<IModMetadata> mock = this.GetMetadata("Mod A", new string[0], allowStatusChange: true);
mock.Setup(p => p.Manifest).Returns(this.GetManifest(m => m.MinimumApiVersion = new SemanticVersion("1.1")));
- mock.Setup(p => p.SetStatus(ModMetadataStatus.Failed, It.IsAny<string>())).Returns(() => mock.Object);
+ this.SetupMetadataForValidation(mock);
// act
new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"));
@@ -173,12 +169,8 @@ namespace StardewModdingAPI.Tests.Core
public void ValidateManifests_MissingEntryDLL_Fails()
{
// arrange
- Mock<IModMetadata> mock = new Mock<IModMetadata>(MockBehavior.Strict);
- mock.Setup(p => p.Status).Returns(ModMetadataStatus.Found);
- mock.Setup(p => p.Compatibility).Returns(() => null);
- mock.Setup(p => p.Manifest).Returns(this.GetManifest());
- mock.Setup(p => p.DirectoryPath).Returns(Path.GetTempPath());
- mock.Setup(p => p.SetStatus(ModMetadataStatus.Failed, It.IsAny<string>())).Returns(() => mock.Object);
+ Mock<IModMetadata> mock = this.GetMetadata(this.GetManifest("Mod A", "1.0", manifest => manifest.EntryDll = "Missing.dll"), allowStatusChange: true);
+ this.SetupMetadataForValidation(mock);
// act
new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"));
@@ -187,6 +179,26 @@ namespace StardewModdingAPI.Tests.Core
mock.Verify(p => p.SetStatus(ModMetadataStatus.Failed, It.IsAny<string>()), Times.Once, "The validation did not fail the metadata.");
}
+#if !SMAPI_1_x
+ [Test(Description = "Assert that validation fails when multiple mods have the same unique ID.")]
+ public void ValidateManifests_DuplicateUniqueID_Fails()
+ {
+ // arrange
+ Mock<IModMetadata> modA = this.GetMetadata("Mod A", new string[0], allowStatusChange: true);
+ Mock<IModMetadata> modB = this.GetMetadata(this.GetManifest("Mod A", "1.0", manifest => manifest.Name = "Mod B"), allowStatusChange: true);
+ Mock<IModMetadata> modC = this.GetMetadata("Mod C", new string[0], allowStatusChange: false);
+ foreach (Mock<IModMetadata> mod in new[] { modA, modB, modC })
+ this.SetupMetadataForValidation(mod);
+
+ // act
+ new ModResolver().ValidateManifests(new[] { modA.Object, modB.Object }, apiVersion: new SemanticVersion("1.0"));
+
+ // assert
+ modA.Verify(p => p.SetStatus(ModMetadataStatus.Failed, It.IsAny<string>()), Times.Once, "The validation did not fail the first mod with a unique ID.");
+ modB.Verify(p => p.SetStatus(ModMetadataStatus.Failed, It.IsAny<string>()), Times.Once, "The validation did not fail the second mod with a unique ID.");
+ }
+#endif
+
[Test(Description = "Assert that validation fails when the manifest references a DLL that does not exist.")]
public void ValidateManifests_Valid_Passes()
{
@@ -411,7 +423,7 @@ namespace StardewModdingAPI.Tests.Core
Assert.AreSame(modB.Object, mods[1], "The load order is incorrect: mod B should be second since it needs mod A.");
}
-#if SMAPI_2_0
+#if !SMAPI_1_x
[Test(Description = "Assert that optional dependencies are sorted correctly if present.")]
public void ProcessDependencies_IfOptional()
{
@@ -469,8 +481,9 @@ namespace StardewModdingAPI.Tests.Core
/// <summary>Get a randomised basic manifest.</summary>
/// <param name="uniqueID">The mod's name and unique ID.</param>
/// <param name="version">The mod version.</param>
+ /// <param name="adjust">Adjust the generated manifest.</param>
/// <param name="dependencies">The dependencies this mod requires.</param>
- private IManifest GetManifest(string uniqueID, string version, params IManifestDependency[] dependencies)
+ private IManifest GetManifest(string uniqueID, string version, Action<Manifest> adjust, params IManifestDependency[] dependencies)
{
return this.GetManifest(manifest =>
{
@@ -478,11 +491,21 @@ namespace StardewModdingAPI.Tests.Core
manifest.UniqueID = uniqueID;
manifest.Version = new SemanticVersion(version);
manifest.Dependencies = dependencies;
+ adjust?.Invoke(manifest);
});
}
/// <summary>Get a randomised basic manifest.</summary>
/// <param name="uniqueID">The mod's name and unique ID.</param>
+ /// <param name="version">The mod version.</param>
+ /// <param name="dependencies">The dependencies this mod requires.</param>
+ private IManifest GetManifest(string uniqueID, string version, params IManifestDependency[] dependencies)
+ {
+ return this.GetManifest(uniqueID, version, null, dependencies);
+ }
+
+ /// <summary>Get a randomised basic manifest.</summary>
+ /// <param name="uniqueID">The mod's name and unique ID.</param>
private Mock<IModMetadata> GetMetadata(string uniqueID)
{
return this.GetMetadata(this.GetManifest(uniqueID, "1.0"));
@@ -504,6 +527,7 @@ namespace StardewModdingAPI.Tests.Core
private Mock<IModMetadata> GetMetadata(IManifest manifest, bool allowStatusChange = false)
{
Mock<IModMetadata> mod = new Mock<IModMetadata>(MockBehavior.Strict);
+ mod.Setup(p => p.Compatibility).Returns(() => null);
mod.Setup(p => p.Status).Returns(ModMetadataStatus.Found);
mod.Setup(p => p.DisplayName).Returns(manifest.UniqueID);
mod.Setup(p => p.Manifest).Returns(manifest);
@@ -516,5 +540,17 @@ namespace StardewModdingAPI.Tests.Core
}
return mod;
}
+
+ /// <summary>Set up a mock mod metadata for <see cref="ModResolver.ValidateManifests"/>.</summary>
+ /// <param name="mod">The mock mod metadata.</param>
+ /// <param name="compatibility">The compatibility record to set.</param>
+ private void SetupMetadataForValidation(Mock<IModMetadata> mod, ModCompatibility compatibility = null)
+ {
+ mod.Setup(p => p.Status).Returns(ModMetadataStatus.Found);
+ mod.Setup(p => p.Compatibility).Returns(() => null);
+ mod.Setup(p => p.Manifest).Returns(this.GetManifest());
+ mod.Setup(p => p.DirectoryPath).Returns(Path.GetTempPath());
+ mod.Setup(p => p.Compatibility).Returns(compatibility);
+ }
}
}
diff --git a/src/StardewModdingAPI/Command.cs b/src/StardewModdingAPI/Command.cs
index 689bb18b..76c85287 100644
--- a/src/StardewModdingAPI/Command.cs
+++ b/src/StardewModdingAPI/Command.cs
@@ -1,4 +1,4 @@
-#if !SMAPI_2_0
+#if SMAPI_1_x
using System;
using System.Collections.Generic;
using StardewModdingAPI.Events;
diff --git a/src/StardewModdingAPI/Config.cs b/src/StardewModdingAPI/Config.cs
index e166f414..734c04e8 100644
--- a/src/StardewModdingAPI/Config.cs
+++ b/src/StardewModdingAPI/Config.cs
@@ -1,4 +1,4 @@
-#if !SMAPI_2_0
+#if SMAPI_1_x
using System;
using System.IO;
using System.Linq;
diff --git a/src/StardewModdingAPI/Constants.cs b/src/StardewModdingAPI/Constants.cs
index 586cadeb..3bd31c2d 100644
--- a/src/StardewModdingAPI/Constants.cs
+++ b/src/StardewModdingAPI/Constants.cs
@@ -34,10 +34,10 @@ namespace StardewModdingAPI
****/
/// <summary>SMAPI's current semantic version.</summary>
public static ISemanticVersion ApiVersion { get; } =
-#if SMAPI_2_0
- new SemanticVersion(2, 0, 0, $"alpha-{DateTime.UtcNow:yyyyMMddHHmm}");
+#if SMAPI_1_x
+ new SemanticVersion(1, 15, 1); // alpha-{DateTime.UtcNow:yyyyMMddHHmm}
#else
- new SemanticVersion(1, 15, 0); // alpha-{DateTime.UtcNow:yyyyMMddHHmm}
+ new SemanticVersion(2, 0, 0, $"alpha-{DateTime.UtcNow:yyyyMMddHHmm}");
#endif
/// <summary>The minimum supported version of Stardew Valley.</summary>
@@ -175,7 +175,7 @@ namespace StardewModdingAPI
new EventFinder("StardewModdingAPI.Events.GraphicsEvents", "OnPreRenderGuiEventNoCheck"),
// APIs removed in SMAPI 2.0
-#if SMAPI_2_0
+#if !SMAPI_1_x
new TypeFinder("StardewModdingAPI.Command"),
new TypeFinder("StardewModdingAPI.Config"),
new TypeFinder("StardewModdingAPI.Log"),
diff --git a/src/StardewModdingAPI/Events/EventArgsCommand.cs b/src/StardewModdingAPI/Events/EventArgsCommand.cs
index f0435904..35370139 100644
--- a/src/StardewModdingAPI/Events/EventArgsCommand.cs
+++ b/src/StardewModdingAPI/Events/EventArgsCommand.cs
@@ -1,4 +1,4 @@
-#if !SMAPI_2_0
+#if SMAPI_1_x
using System;
namespace StardewModdingAPI.Events
diff --git a/src/StardewModdingAPI/Events/EventArgsFarmerChanged.cs b/src/StardewModdingAPI/Events/EventArgsFarmerChanged.cs
index c34fc4ab..4c359939 100644
--- a/src/StardewModdingAPI/Events/EventArgsFarmerChanged.cs
+++ b/src/StardewModdingAPI/Events/EventArgsFarmerChanged.cs
@@ -1,4 +1,4 @@
-#if !SMAPI_2_0
+#if SMAPI_1_x
using System;
using SFarmer = StardewValley.Farmer;
diff --git a/src/StardewModdingAPI/Events/EventArgsInput.cs b/src/StardewModdingAPI/Events/EventArgsInput.cs
index e5eb7372..31368555 100644
--- a/src/StardewModdingAPI/Events/EventArgsInput.cs
+++ b/src/StardewModdingAPI/Events/EventArgsInput.cs
@@ -1,4 +1,4 @@
-#if SMAPI_2_0
+#if !SMAPI_1_x
using System;
using System.Linq;
using Microsoft.Xna.Framework;
diff --git a/src/StardewModdingAPI/Events/EventArgsLoadedGameChanged.cs b/src/StardewModdingAPI/Events/EventArgsLoadedGameChanged.cs
index d6fc4594..688b4b3d 100644
--- a/src/StardewModdingAPI/Events/EventArgsLoadedGameChanged.cs
+++ b/src/StardewModdingAPI/Events/EventArgsLoadedGameChanged.cs
@@ -1,4 +1,4 @@
-#if !SMAPI_2_0
+#if SMAPI_1_x
using System;
namespace StardewModdingAPI.Events
diff --git a/src/StardewModdingAPI/Events/EventArgsNewDay.cs b/src/StardewModdingAPI/Events/EventArgsNewDay.cs
index 5bd2ba66..b8cbe9e3 100644
--- a/src/StardewModdingAPI/Events/EventArgsNewDay.cs
+++ b/src/StardewModdingAPI/Events/EventArgsNewDay.cs
@@ -1,4 +1,4 @@
-#if !SMAPI_2_0
+#if SMAPI_1_x
using System;
namespace StardewModdingAPI.Events
diff --git a/src/StardewModdingAPI/Events/EventArgsStringChanged.cs b/src/StardewModdingAPI/Events/EventArgsStringChanged.cs
index 1498cb71..f580a2ce 100644
--- a/src/StardewModdingAPI/Events/EventArgsStringChanged.cs
+++ b/src/StardewModdingAPI/Events/EventArgsStringChanged.cs
@@ -1,4 +1,4 @@
-#if !SMAPI_2_0
+#if SMAPI_1_x
using System;
namespace StardewModdingAPI.Events
diff --git a/src/StardewModdingAPI/Events/GameEvents.cs b/src/StardewModdingAPI/Events/GameEvents.cs
index 557b451f..5610e67a 100644
--- a/src/StardewModdingAPI/Events/GameEvents.cs
+++ b/src/StardewModdingAPI/Events/GameEvents.cs
@@ -11,7 +11,7 @@ namespace StardewModdingAPI.Events
/*********
** Properties
*********/
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Manages deprecation warnings.</summary>
private static DeprecationManager DeprecationManager;
@@ -42,7 +42,7 @@ namespace StardewModdingAPI.Events
/// <summary>Raised during launch after configuring Stardew Valley, loading it into memory, and opening the game window. The window is still blank by this point.</summary>
internal static event EventHandler GameLoadedInternal;
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Raised during launch after configuring XNA or MonoGame. The game window hasn't been opened by this point. Called after <see cref="Microsoft.Xna.Framework.Game.Initialize"/>.</summary>
[Obsolete("The " + nameof(Mod) + "." + nameof(Mod.Entry) + " method is now called after the " + nameof(GameEvents.Initialize) + " event, so any contained logic can be done directly in " + nameof(Mod.Entry) + ".")]
public static event EventHandler Initialize
@@ -117,7 +117,7 @@ namespace StardewModdingAPI.Events
/*********
** Internal methods
*********/
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Injects types required for backwards compatibility.</summary>
/// <param name="deprecationManager">Manages deprecation warnings.</param>
internal static void Shim(DeprecationManager deprecationManager)
@@ -126,17 +126,17 @@ namespace StardewModdingAPI.Events
}
#endif
- /// <summary>Raise an <see cref="InitializeInternal"/> event.</summary>
- /// <param name="monitor">Encapsulates logging and monitoring.</param>
- internal static void InvokeInitialize(IMonitor monitor)
+ /// <summary>Raise an <see cref="InitializeInternal"/> event.</summary>
+ /// <param name="monitor">Encapsulates logging and monitoring.</param>
+ internal static void InvokeInitialize(IMonitor monitor)
{
monitor.SafelyRaisePlainEvent($"{nameof(GameEvents)}.{nameof(GameEvents.InitializeInternal)}", GameEvents.InitializeInternal?.GetInvocationList());
-#if !SMAPI_2_0
+#if SMAPI_1_x
monitor.SafelyRaisePlainEvent($"{nameof(GameEvents)}.{nameof(GameEvents.Initialize)}", GameEvents._Initialize?.GetInvocationList());
#endif
}
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Raise a <see cref="LoadContent"/> event.</summary>
/// <param name="monitor">Encapsulates logging and monitoring.</param>
internal static void InvokeLoadContent(IMonitor monitor)
@@ -150,12 +150,12 @@ namespace StardewModdingAPI.Events
internal static void InvokeGameLoaded(IMonitor monitor)
{
monitor.SafelyRaisePlainEvent($"{nameof(GameEvents)}.{nameof(GameEvents.GameLoadedInternal)}", GameEvents.GameLoadedInternal?.GetInvocationList());
-#if !SMAPI_2_0
+#if SMAPI_1_x
monitor.SafelyRaisePlainEvent($"{nameof(GameEvents)}.{nameof(GameEvents.GameLoaded)}", GameEvents._GameLoaded?.GetInvocationList());
#endif
}
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Raise a <see cref="FirstUpdateTick"/> event.</summary>
/// <param name="monitor">Encapsulates monitoring and logging.</param>
internal static void InvokeFirstUpdateTick(IMonitor monitor)
diff --git a/src/StardewModdingAPI/Events/InputEvents.cs b/src/StardewModdingAPI/Events/InputEvents.cs
index 285487af..b99b49e0 100644
--- a/src/StardewModdingAPI/Events/InputEvents.cs
+++ b/src/StardewModdingAPI/Events/InputEvents.cs
@@ -1,4 +1,4 @@
-#if SMAPI_2_0
+#if !SMAPI_1_x
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Utilities;
diff --git a/src/StardewModdingAPI/Events/PlayerEvents.cs b/src/StardewModdingAPI/Events/PlayerEvents.cs
index acbdc562..72826330 100644
--- a/src/StardewModdingAPI/Events/PlayerEvents.cs
+++ b/src/StardewModdingAPI/Events/PlayerEvents.cs
@@ -15,7 +15,7 @@ namespace StardewModdingAPI.Events
/*********
** Properties
*********/
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Manages deprecation warnings.</summary>
private static DeprecationManager DeprecationManager;
@@ -32,7 +32,7 @@ namespace StardewModdingAPI.Events
/*********
** Events
*********/
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Raised after the player loads a saved game.</summary>
[Obsolete("Use " + nameof(SaveEvents) + "." + nameof(SaveEvents.AfterLoad) + " instead")]
public static event EventHandler<EventArgsLoadedGameChanged> LoadedGame
@@ -68,7 +68,7 @@ namespace StardewModdingAPI.Events
/*********
** Internal methods
*********/
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Injects types required for backwards compatibility.</summary>
/// <param name="deprecationManager">Manages deprecation warnings.</param>
internal static void Shim(DeprecationManager deprecationManager)
diff --git a/src/StardewModdingAPI/Events/TimeEvents.cs b/src/StardewModdingAPI/Events/TimeEvents.cs
index f0fdb4f2..d5ab9fb7 100644
--- a/src/StardewModdingAPI/Events/TimeEvents.cs
+++ b/src/StardewModdingAPI/Events/TimeEvents.cs
@@ -11,7 +11,7 @@ namespace StardewModdingAPI.Events
/*********
** Properties
*********/
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Manages deprecation warnings.</summary>
private static DeprecationManager DeprecationManager;
@@ -42,7 +42,7 @@ namespace StardewModdingAPI.Events
/// <summary>Raised after the in-game clock changes.</summary>
public static event EventHandler<EventArgsIntChanged> TimeOfDayChanged;
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Raised after the day-of-month value changes, including when loading a save. This may happen before save; in most cases you should use <see cref="AfterDayStarted"/> instead.</summary>
[Obsolete("Use " + nameof(TimeEvents) + "." + nameof(TimeEvents.AfterDayStarted) + " or " + nameof(SaveEvents) + " instead")]
public static event EventHandler<EventArgsIntChanged> DayOfMonthChanged
@@ -96,7 +96,7 @@ namespace StardewModdingAPI.Events
/*********
** Internal methods
*********/
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Injects types required for backwards compatibility.</summary>
/// <param name="deprecationManager">Manages deprecation warnings.</param>
internal static void Shim(DeprecationManager deprecationManager)
@@ -121,7 +121,7 @@ namespace StardewModdingAPI.Events
monitor.SafelyRaiseGenericEvent($"{nameof(TimeEvents)}.{nameof(TimeEvents.TimeOfDayChanged)}", TimeEvents.TimeOfDayChanged?.GetInvocationList(), null, new EventArgsIntChanged(priorTime, newTime));
}
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Raise a <see cref="DayOfMonthChanged"/> event.</summary>
/// <param name="monitor">Encapsulates monitoring and logging.</param>
/// <param name="priorDay">The previous day value.</param>
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();
diff --git a/src/StardewModdingAPI/ICursorPosition.cs b/src/StardewModdingAPI/ICursorPosition.cs
index d03cda71..8fbc115f 100644
--- a/src/StardewModdingAPI/ICursorPosition.cs
+++ b/src/StardewModdingAPI/ICursorPosition.cs
@@ -1,4 +1,4 @@
-#if SMAPI_2_0
+#if !SMAPI_1_x
using Microsoft.Xna.Framework;
namespace StardewModdingAPI
diff --git a/src/StardewModdingAPI/IManifestDependency.cs b/src/StardewModdingAPI/IManifestDependency.cs
index 027c1d59..1fa6c812 100644
--- a/src/StardewModdingAPI/IManifestDependency.cs
+++ b/src/StardewModdingAPI/IManifestDependency.cs
@@ -12,7 +12,7 @@
/// <summary>The minimum required version (if any).</summary>
ISemanticVersion MinimumVersion { get; }
-#if SMAPI_2_0
+#if !SMAPI_1_x
/// <summary>Whether the dependency must be installed to use the mod.</summary>
bool IsRequired { get; }
#endif
diff --git a/src/StardewModdingAPI/Log.cs b/src/StardewModdingAPI/Log.cs
index 46f1caae..60220ad8 100644
--- a/src/StardewModdingAPI/Log.cs
+++ b/src/StardewModdingAPI/Log.cs
@@ -1,4 +1,4 @@
-#if !SMAPI_2_0
+#if SMAPI_1_x
using System;
using System.Threading;
using StardewModdingAPI.Framework;
diff --git a/src/StardewModdingAPI/Mod.cs b/src/StardewModdingAPI/Mod.cs
index cb36c596..b5607234 100644
--- a/src/StardewModdingAPI/Mod.cs
+++ b/src/StardewModdingAPI/Mod.cs
@@ -11,7 +11,7 @@ namespace StardewModdingAPI
/*********
** Properties
*********/
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Manages deprecation warnings.</summary>
private static DeprecationManager DeprecationManager;
@@ -33,7 +33,7 @@ namespace StardewModdingAPI
/// <summary>The mod's manifest.</summary>
public IManifest ModManifest { get; internal set; }
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>The full path to the mod's directory on the disk.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.DirectoryPath) + " instead")]
public string PathOnDisk
@@ -79,7 +79,7 @@ namespace StardewModdingAPI
/*********
** Public methods
*********/
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Injects types required for backwards compatibility.</summary>
/// <param name="deprecationManager">Manages deprecation warnings.</param>
internal static void Shim(DeprecationManager deprecationManager)
@@ -108,7 +108,7 @@ namespace StardewModdingAPI
/*********
** Private methods
*********/
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Get the full path to the per-save configuration file for the current save (if <see cref="Manifest.PerSaveConfigs"/> is <c>true</c>).</summary>
[Obsolete]
private string GetPerSaveConfigFolder()
diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs
index 97e18322..08bd2b84 100644
--- a/src/StardewModdingAPI/Program.cs
+++ b/src/StardewModdingAPI/Program.cs
@@ -127,7 +127,7 @@ namespace StardewModdingAPI
// init logging
this.Monitor.Log($"SMAPI {Constants.ApiVersion} with Stardew Valley {Constants.GetGameDisplayVersion(Constants.GameVersion)} on {this.GetFriendlyPlatformName()}", LogLevel.Info);
this.Monitor.Log($"Mods go here: {Constants.ModPath}");
-#if !SMAPI_2_0
+#if SMAPI_1_x
this.Monitor.Log("Preparing SMAPI...");
#endif
@@ -213,10 +213,10 @@ namespace StardewModdingAPI
}
// start game
-#if SMAPI_2_0
- this.Monitor.Log("Starting game...", LogLevel.Trace);
-#else
+#if SMAPI_1_x
this.Monitor.Log("Starting game...");
+#else
+ this.Monitor.Log("Starting game...", LogLevel.Trace);
#endif
try
{
@@ -234,7 +234,7 @@ namespace StardewModdingAPI
}
}
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <summary>Get a monitor for legacy code which doesn't have one passed in.</summary>
[Obsolete("This method should only be used when needed for backwards compatibility.")]
internal IMonitor GetLegacyMonitorForMod()
@@ -333,7 +333,7 @@ namespace StardewModdingAPI
this.DeprecationManager = new DeprecationManager(this.Monitor, this.ModRegistry);
this.CommandManager = new CommandManager();
-#if !SMAPI_2_0
+#if SMAPI_1_x
// inject compatibility shims
#pragma warning disable 618
Command.Shim(this.CommandManager, this.DeprecationManager, this.ModRegistry);
@@ -357,7 +357,7 @@ namespace StardewModdingAPI
if (this.Settings.DeveloperMode)
{
this.Monitor.ShowTraceInConsole = true;
-#if SMAPI_2_0
+#if !SMAPI_1_x
this.Monitor.ShowFullStampInConsole = true;
#endif
this.Monitor.Log($"You configured SMAPI to run in developer mode. The console may be much more verbose. You can disable developer mode by installing the non-developer version of SMAPI, or by editing {Constants.ApiConfigPath}.", LogLevel.Info);
@@ -375,10 +375,10 @@ namespace StardewModdingAPI
// load mods
{
-#if SMAPI_2_0
- this.Monitor.Log("Loading mod metadata...", LogLevel.Trace);
-#else
+#if SMAPI_1_x
this.Monitor.Log("Loading mod metadata...");
+#else
+ this.Monitor.Log("Loading mod metadata...", LogLevel.Trace);
#endif
ModResolver resolver = new ModResolver();
@@ -387,7 +387,7 @@ namespace StardewModdingAPI
resolver.ValidateManifests(mods, Constants.ApiVersion);
// check for deprecated metadata
-#if !SMAPI_2_0
+#if SMAPI_1_x
IList<Action> deprecationWarnings = new List<Action>();
foreach (IModMetadata mod in mods.Where(m => m.Status != ModMetadataStatus.Failed))
{
@@ -429,12 +429,12 @@ namespace StardewModdingAPI
mods = resolver.ProcessDependencies(mods).ToArray();
// load mods
-#if SMAPI_2_0
- this.LoadMods(mods, new JsonHelper(), this.ContentManager);
-#else
+#if SMAPI_1_x
this.LoadMods(mods, new JsonHelper(), this.ContentManager, deprecationWarnings);
foreach (Action warning in deprecationWarnings)
warning();
+#else
+ this.LoadMods(mods, new JsonHelper(), this.ContentManager);
#endif
}
if (this.Monitor.IsExiting)
@@ -469,7 +469,7 @@ namespace StardewModdingAPI
private void RunConsoleLoop()
{
// prepare console
-#if !SMAPI_2_0
+#if SMAPI_1_x
this.Monitor.Log("Starting console...");
#endif
this.Monitor.Log("Type 'help' for help, or 'help <cmd>' for a command's usage", LogLevel.Info);
@@ -603,17 +603,17 @@ namespace StardewModdingAPI
/// <param name="mods">The mods to load.</param>
/// <param name="jsonHelper">The JSON helper with which to read mods' JSON files.</param>
/// <param name="contentManager">The content manager to use for mod content.</param>
-#if !SMAPI_2_0
+#if SMAPI_1_x
/// <param name="deprecationWarnings">A list to populate with any deprecation warnings.</param>
private void LoadMods(IModMetadata[] mods, JsonHelper jsonHelper, SContentManager contentManager, IList<Action> deprecationWarnings)
#else
private void LoadMods(IModMetadata[] mods, JsonHelper jsonHelper, SContentManager contentManager)
#endif
{
-#if SMAPI_2_0
- this.Monitor.Log("Loading mods...", LogLevel.Trace);
-#else
+#if SMAPI_1_x
this.Monitor.Log("Loading mods...");
+#else
+ this.Monitor.Log("Loading mods...", LogLevel.Trace);
#endif
// load mod assemblies
IDictionary<IModMetadata, string> skippedMods = new Dictionary<IModMetadata, string>();
@@ -691,7 +691,7 @@ namespace StardewModdingAPI
continue;
}
-#if !SMAPI_2_0
+#if SMAPI_1_x
// prevent mods from using SMAPI 2.0 content interception before release
// ReSharper disable SuspiciousTypeConversion.Global
if (mod is IAssetEditor || mod is IAssetLoader)
@@ -712,7 +712,7 @@ namespace StardewModdingAPI
mod.ModManifest = manifest;
mod.Helper = new ModHelper(manifest.UniqueID, metadata.DirectoryPath, jsonHelper, contentHelper, commandHelper, modRegistryHelper, reflectionHelper, translationHelper);
mod.Monitor = this.GetSecondaryMonitor(metadata.DisplayName);
-#if !SMAPI_2_0
+#if SMAPI_1_x
mod.PathOnDisk = metadata.DirectoryPath;
#endif
}
@@ -730,7 +730,7 @@ namespace StardewModdingAPI
IModMetadata[] loadedMods = this.ModRegistry.GetMods().ToArray();
// log skipped mods
-#if SMAPI_2_0
+#if !SMAPI_1_x
this.Monitor.Newline();
#endif
if (skippedMods.Any())
@@ -746,7 +746,7 @@ namespace StardewModdingAPI
else
this.Monitor.Log($" {mod.DisplayName} because {reason}", LogLevel.Error);
}
-#if SMAPI_2_0
+#if !SMAPI_1_x
this.Monitor.Newline();
#endif
}
@@ -763,7 +763,7 @@ namespace StardewModdingAPI
LogLevel.Info
);
}
-#if SMAPI_2_0
+#if !SMAPI_1_x
this.Monitor.Newline();
#endif
@@ -785,7 +785,7 @@ namespace StardewModdingAPI
{
IMod mod = metadata.Mod;
mod.Entry(mod.Helper);
-#if !SMAPI_2_0
+#if SMAPI_1_x
(mod as Mod)?.Entry(); // deprecated since 1.0
// raise deprecation warning for old Entry() methods
@@ -869,7 +869,10 @@ namespace StardewModdingAPI
}
else
{
-#if SMAPI_2_0
+#if SMAPI_1_x
+ this.Monitor.Log("The following commands are registered: " + string.Join(", ", this.CommandManager.GetAll().Select(p => p.Name)) + ".", LogLevel.Info);
+ this.Monitor.Log("For more information about a command, type 'help command_name'.", LogLevel.Info);
+#else
string message = "The following commands are registered:\n";
IGrouping<string, string>[] groups = (from command in this.CommandManager.GetAll() orderby command.ModName, command.Name group command.Name by command.ModName).ToArray();
foreach (var group in groups)
@@ -881,9 +884,6 @@ namespace StardewModdingAPI
message += "For more information about a command, type 'help command_name'.";
this.Monitor.Log(message, LogLevel.Info);
-#else
- this.Monitor.Log("The following commands are registered: " + string.Join(", ", this.CommandManager.GetAll().Select(p => p.Name)) + ".", LogLevel.Info);
- this.Monitor.Log("For more information about a command, type 'help command_name'.", LogLevel.Info);
#endif
}
break;
@@ -933,7 +933,7 @@ namespace StardewModdingAPI
{
WriteToConsole = this.Monitor.WriteToConsole,
ShowTraceInConsole = this.Settings.DeveloperMode,
-#if SMAPI_2_0
+#if !SMAPI_1_x
ShowFullStampInConsole = this.Settings.DeveloperMode
#endif
};
diff --git a/src/StardewModdingAPI/Utilities/SButton.cs b/src/StardewModdingAPI/Utilities/SButton.cs
index f4fccfff..c4833b0b 100644
--- a/src/StardewModdingAPI/Utilities/SButton.cs
+++ b/src/StardewModdingAPI/Utilities/SButton.cs
@@ -1,16 +1,16 @@
-using System;
+using System;
using Microsoft.Xna.Framework.Input;
namespace StardewModdingAPI.Utilities
{
/// <summary>A unified button constant which includes all controller, keyboard, and mouse buttons.</summary>
/// <remarks>Derived from <see cref="Keys"/>, <see cref="Buttons"/>, and <see cref="System.Windows.Forms.MouseButtons"/>.</remarks>
-#if SMAPI_2_0
- public
-#else
+#if SMAPI_1_x
internal
+#else
+ public
#endif
- enum SButton
+ enum SButton
{
/// <summary>No valid key.</summary>
None = 0,
@@ -593,10 +593,10 @@ namespace StardewModdingAPI.Utilities
}
/// <summary>Provides extension methods for <see cref="SButton"/>.</summary>
-#if SMAPI_2_0
- public
-#else
+#if SMAPI_1_x
internal
+#else
+ public
#endif
static class SButtonExtensions
{
@@ -646,7 +646,7 @@ namespace StardewModdingAPI.Utilities
/// <returns>Returns whether the value was converted successfully.</returns>
public static bool TryGetController(this SButton input, out Buttons button)
{
- if (Enum.IsDefined(typeof(Keys), (int)input - SButtonExtensions.ControllerOffset))
+ if (Enum.IsDefined(typeof(Buttons), (int)input - SButtonExtensions.ControllerOffset))
{
button = (Buttons)(input - SButtonExtensions.ControllerOffset);
return true;
diff --git a/src/TrainerMod/TrainerMod.csproj b/src/TrainerMod/TrainerMod.csproj
index 99a15c8f..57c8a907 100644
--- a/src/TrainerMod/TrainerMod.csproj
+++ b/src/TrainerMod/TrainerMod.csproj
@@ -38,7 +38,7 @@
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
- <Private>True</Private>
+ <Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
diff --git a/src/TrainerMod/manifest.json b/src/TrainerMod/manifest.json
index f1665a45..5c634f53 100644
--- a/src/TrainerMod/manifest.json
+++ b/src/TrainerMod/manifest.json
@@ -4,7 +4,7 @@
"Version": {
"MajorVersion": 1,
"MinorVersion": 15,
- "PatchVersion": 0,
+ "PatchVersion": 1,
"Build": null
},
"Description": "Adds SMAPI console commands that let you manipulate the game.",
diff --git a/src/crossplatform.targets b/src/crossplatform.targets
index 929aac6c..66e15abd 100644
--- a/src/crossplatform.targets
+++ b/src/crossplatform.targets
@@ -1,4 +1,4 @@
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Condition="$(OS) != 'Windows_NT' AND Exists('$(HOME)\stardewvalley.targets')" Project="$(HOME)\stardewvalley.targets" />
<Import Condition="$(OS) == 'Windows_NT' AND Exists('$(USERPROFILE)\stardewvalley.targets')" Project="$(USERPROFILE)\stardewvalley.targets" />
<PropertyGroup>
@@ -35,6 +35,7 @@
</Reference>
<Reference Include="Stardew Valley">
<HintPath>$(GamePath)\Stardew Valley.exe</HintPath>
+ <Private Condition="'$(MSBuildProjectName)' != 'StardewModdingAPI.Tests'">False</Private>
</Reference>
<Reference Include="xTile, Version=2.0.4.0, Culture=neutral, processorArchitecture=x86">
<HintPath>$(GamePath)\xTile.dll</HintPath>