diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2017-07-10 22:10:27 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2017-07-10 22:10:27 -0400 |
commit | 674ad0d90f8780130a5fcefb3869acfe2315df2a (patch) | |
tree | eb79fa170a0b74a34061ea1d6838ae5589131c85 | |
parent | 1edd98aef027faa768f56cf0b3591e64e20ba096 (diff) | |
parent | 834aee92f222fa739d7daa6c71f48b7e0df47ffe (diff) | |
download | SMAPI-674ad0d90f8780130a5fcefb3869acfe2315df2a.tar.gz SMAPI-674ad0d90f8780130a5fcefb3869acfe2315df2a.tar.bz2 SMAPI-674ad0d90f8780130a5fcefb3869acfe2315df2a.zip |
Merge branch 'develop' into stable
35 files changed, 207 insertions, 131 deletions
@@ -167,4 +167,4 @@ SMAPI uses a small number of conditional compilation constants, which you can se flag | purpose ---- | ------- `SMAPI_FOR_WINDOWS` | Indicates that SMAPI is being compiled on Windows for players on Windows. Set automatically in `crossplatform.targets`. -`SMAPI_2_0` | Sets SMAPI 2.0 mode, which enables features planned for SMAPI 2.0 and removes all deprecated code. This helps test how mods will work when SMAPI 2.0 is released. +`SMAPI_1_x` | Sets legacy SMAPI 1._x_ mode, disables SMAPI 2.0 features, and enables deprecated code. This will be removed when SMAPI 2.0 is released. diff --git a/release-notes.md b/release-notes.md index 6b860f4f..924ecb90 100644 --- a/release-notes.md +++ b/release-notes.md @@ -14,11 +14,19 @@ For mod developers: * In `manifest.json`: * Dependencies can now be optional. * The version can now be a string like `"1.0-alpha"` instead of a structure. + * The `Name`, `Version,` and `UniqueID` fields are no longer optional. + * The `UniqueID` field must now be unique (case-insensitive). If two installed mods have the same ID, SMAPI will show an error and load neither. * Removed all deprecated code. -## 1.15 -See [log](https://github.com/Pathoschild/SMAPI/compare/1.14...1.15). +## 1.15.1 +For players: +* Fixed controller mod input broken in 1.15. +* Fixed TrainerMod packaging unneeded files. +For modders: +* Fixed mod registry lookups by unique ID not being case-insensitive. + +## 1.15 For players: * Cleaned up SMAPI console a bit. * Revamped TrainerMod's item commands: 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> |