From 68c58a477783fc2ab3e0d3558ce3b6345a21236e Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Mon, 18 Oct 2021 17:17:54 -0400 Subject: move release note --- docs/release-notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/release-notes.md b/docs/release-notes.md index 25b0d740..fa2ec91b 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -6,12 +6,12 @@ Released 18 October 2021 for Stardew Valley 1.5.4. * For players: * Fixed mod edits to the farmhouse shifting the player down one tile in some cases. + * Fixed map tile rotations/flips not working for farmhands in split-screen mode. * Improved translations. Thanks to ellipszist (added Thai) and Zangorr (added Polish)! _These are custom languages which require Stardew Valley 1.5.5 and the [Polish](https://www.nexusmods.com/stardewvalley/mods/3616) or [Thai](https://www.nexusmods.com/stardewvalley/mods/7052) mod._ * For mod authors: * SMAPI now intercepts dictionary duplicate-key errors and adds the key to the error message to simplify troubleshooting. (Due to Harmony limitations, this only works for the dictionary types used by the game.) - * Fixed map tile rotations/flips not working for farmhands in split-screen mode. * Fixed barn/coop exit warps being reset when you edit their interior map. * For the web UI: -- cgit From e89de6316d8a8b2e0169790b2a14427892828be5 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 30 Oct 2021 19:53:28 -0400 Subject: add set_farm_type console command --- docs/release-notes.md | 4 + .../Commands/Player/SetFarmTypeCommand.cs | 91 ++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetFarmTypeCommand.cs (limited to 'docs') diff --git a/docs/release-notes.md b/docs/release-notes.md index fa2ec91b..42519b1f 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -1,6 +1,10 @@ ← [README](README.md) # Release notes +## Upcoming release +* For players: + * Added `set_farm_type` [console command](https://stardewvalleywiki.com/Modding:Console_commands#Console_commands) to change the current farm type. + ## 3.12.8 Released 18 October 2021 for Stardew Valley 1.5.4. diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetFarmTypeCommand.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetFarmTypeCommand.cs new file mode 100644 index 00000000..0bebd2b7 --- /dev/null +++ b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetFarmTypeCommand.cs @@ -0,0 +1,91 @@ +using System.Collections.Generic; +using System.Linq; +using StardewValley; + +namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Player +{ + /// A command which changes the player's farm type. + internal class SetFarmTypeCommand : ConsoleCommand + { + /********* + ** Fields + *********/ + /// The vanilla farm type IDs. + private static readonly ISet VanillaFarmTypes = new HashSet( + Enumerable.Range(0, Farm.layout_max + 1) + ); + + + /********* + ** Public methods + *********/ + /// Construct an instance. + public SetFarmTypeCommand() + : base("set_farm_type", $"Sets the current player's farm type.\n\nUsage: set_farm_type \n- farm type: one of {string.Join(", ", SetFarmTypeCommand.VanillaFarmTypes.Select(id => $"{id} ({SetFarmTypeCommand.GetFarmLabel(id)})"))}.") { } + + /// Handle the command. + /// Writes messages to the console and log file. + /// The command name. + /// The command arguments. + public override void Handle(IMonitor monitor, string command, ArgumentParser args) + { + // validation checks + if (!Context.IsWorldReady) + { + monitor.Log("You must load a save to use this command.", LogLevel.Error); + return; + } + + // parse argument + if (!args.TryGetInt(0, "farm type", out int farmType, min: 0, max: Farm.layout_max)) + return; + + // handle + if (Game1.whichFarm == farmType) + { + monitor.Log($"Your current farm is already set to {farmType} ({SetFarmTypeCommand.GetFarmLabel(farmType)}).", LogLevel.Info); + return; + } + + this.SetFarmType(farmType); + monitor.Log($"Your current farm has been converted to {farmType} ({SetFarmTypeCommand.GetFarmLabel(farmType)}).", LogLevel.Warn); + monitor.Log("Saving and reloading is recommended to make sure everything is updated for the change.", LogLevel.Warn); + } + + + /********* + ** Private methods + *********/ + /// Change the farm type to the given value. + /// The farm type ID. + private void SetFarmType(int type) + { + Game1.whichFarm = type; + + Farm farm = Game1.getFarm(); + farm.mapPath.Value = $@"Maps\{Farm.getMapNameFromTypeInt(Game1.whichFarm)}"; + farm.reloadMap(); + } + + /// Get the display name for a vanilla farm type. + /// The farm type. + private static string GetFarmLabel(int type) + { + string translationKey = type switch + { + Farm.default_layout => "Character_FarmStandard", + Farm.riverlands_layout => "Character_FarmFishing", + Farm.forest_layout => "Character_FarmForaging", + Farm.mountains_layout => "Character_FarmMining", + Farm.combat_layout => "Character_FarmCombat", + Farm.fourCorners_layout => "Character_FarmFourCorners", + Farm.beach_layout => "Character_FarmBeach", + _ => null + }; + + return translationKey != null + ? Game1.content.LoadString(@$"Strings\UI:{translationKey}").Split('_')[0] + : type.ToString(); + } + } +} -- cgit From 96db1d931552ef8973cdf07e3f1d4a4618992276 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 31 Oct 2021 14:14:21 -0400 Subject: update Content Patcher schema for 1.24.0 --- docs/release-notes.md | 3 +++ src/SMAPI.Web/wwwroot/schemas/content-patcher.json | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/release-notes.md b/docs/release-notes.md index 42519b1f..efda7267 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -5,6 +5,9 @@ * For players: * Added `set_farm_type` [console command](https://stardewvalleywiki.com/Modding:Console_commands#Console_commands) to change the current farm type. +* For the web UI: + * Updated the JSON validator/schema for Content Patcher 1.24.0. + ## 3.12.8 Released 18 October 2021 for Stardew Valley 1.5.4. diff --git a/src/SMAPI.Web/wwwroot/schemas/content-patcher.json b/src/SMAPI.Web/wwwroot/schemas/content-patcher.json index aac4ff0f..d39574ef 100644 --- a/src/SMAPI.Web/wwwroot/schemas/content-patcher.json +++ b/src/SMAPI.Web/wwwroot/schemas/content-patcher.json @@ -12,11 +12,11 @@ "properties": { "Format": { "title": "Format version", - "description": "The format version. You should always use the latest version to enable the latest features and avoid obsolete behavior.", + "description": "The format version. You should always use the latest version to enable the latest features, avoid obsolete behavior, and reduce load times.", "type": "string", - "const": "1.23.0", + "const": "1.24.0", "@errorMessages": { - "const": "Incorrect value '@value'. This should be set to the latest format version, currently '1.23.0'." + "const": "Incorrect value '@value'. You should always use the latest format version (currently 1.24.0) to enable the latest features, avoid obsolete behavior, and reduce load times." } }, "ConfigSchema": { -- cgit From 6efaa651cb2b026b7bace55ffeba9d7c5a3d0567 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 12 Aug 2021 21:26:01 -0400 Subject: drop support for XNA Framework Stardew Valley 1.5.5 migrates to MonoGame on all platforms. --- docs/technical/smapi.md | 1 - src/SMAPI.ModBuildConfig/build/smapi.targets | 32 +++------ .../SMAPI.Mods.ConsoleCommands.csproj | 18 +---- .../Patches/SpriteBatchPatcher.cs | 9 +-- .../SMAPI.Mods.ErrorHandler.csproj | 18 +---- src/SMAPI/Constants.cs | 82 +++++++--------------- src/SMAPI/Framework/Content/ContentCache.cs | 9 +-- src/SMAPI/Framework/Input/GamePadStateBuilder.cs | 19 ++--- src/SMAPI/Framework/InternalExtensions.cs | 7 +- src/SMAPI/Framework/Logging/LogManager.cs | 8 +-- .../ModLoading/RewriteFacades/SpriteBatchFacade.cs | 10 +-- src/SMAPI/Framework/SCore.cs | 8 +-- src/SMAPI/GameFramework.cs | 7 +- src/SMAPI/Metadata/InstructionMetadata.cs | 8 +-- src/SMAPI/SMAPI.csproj | 19 +---- 15 files changed, 60 insertions(+), 195 deletions(-) (limited to 'docs') diff --git a/docs/technical/smapi.md b/docs/technical/smapi.md index f454e99c..29fa43a8 100644 --- a/docs/technical/smapi.md +++ b/docs/technical/smapi.md @@ -57,7 +57,6 @@ SMAPI uses a small number of conditional compilation constants, which you can se flag | purpose ---- | ------- `SMAPI_FOR_WINDOWS` | Whether SMAPI is being compiled for Windows; if not set, the code assumes Linux/macOS. Set automatically in `common.targets`. -`SMAPI_FOR_XNA` | Whether SMAPI is being compiled for XNA Framework; if not set, the code assumes MonoGame. Set automatically in `common.targets` with the same value as `SMAPI_FOR_WINDOWS`. ## For SMAPI developers ### Compiling from source diff --git a/src/SMAPI.ModBuildConfig/build/smapi.targets b/src/SMAPI.ModBuildConfig/build/smapi.targets index 698765ad..664ba7df 100644 --- a/src/SMAPI.ModBuildConfig/build/smapi.targets +++ b/src/SMAPI.ModBuildConfig/build/smapi.targets @@ -43,38 +43,24 @@ - + + + + + - + + - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchPatcher.cs b/src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchPatcher.cs index 6860a4ec..f243c6d1 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchPatcher.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchPatcher.cs @@ -19,9 +19,7 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches public override void Apply(Harmony harmony, IMonitor monitor) { harmony.Patch( - original: Constants.GameFramework == GameFramework.Xna - ? this.RequireMethod("InternalDraw") - : this.RequireMethod("CheckValid", new[] { typeof(Texture2D) }), + original: this.RequireMethod("CheckValid", new[] { typeof(Texture2D) }), postfix: this.GetHarmonyMethod(nameof(SpriteBatchPatcher.After_CheckValid)) ); } @@ -30,13 +28,8 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches /********* ** Private methods *********/ -#if SMAPI_FOR_XNA - /// The method to call after . - /// The texture to validate. -#else /// The method to call after . /// The texture to validate. -#endif private static void After_CheckValid(Texture2D texture) { if (texture?.IsDisposed == true) diff --git a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj index 182a978e..27b9144f 100644 --- a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj +++ b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj @@ -15,6 +15,7 @@ + @@ -24,23 +25,6 @@ - - - - - - - - - - - - - - - - - diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index 4d6a2a0b..72456ae4 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -40,12 +40,7 @@ namespace StardewModdingAPI internal static GamePlatform Platform { get; } = (GamePlatform)Enum.Parse(typeof(GamePlatform), LowLevelEnvironmentUtility.DetectPlatform()); /// The game framework running the game. - internal static GameFramework GameFramework { get; } = -#if SMAPI_FOR_XNA - GameFramework.Xna; -#else - GameFramework.MonoGame; -#endif + internal static GameFramework GameFramework { get; } = GameFramework.MonoGame; /// The game's assembly name. internal static string GameAssemblyName => EarlyConstants.Platform == GamePlatform.Windows ? "Stardew Valley" : "StardewValley"; @@ -260,61 +255,32 @@ namespace StardewModdingAPI removeAssemblyReferences.Add("StardewModdingAPI.Toolkit.CoreInterfaces"); targetAssemblies.Add(typeof(StardewModdingAPI.IManifest).Assembly); - // get changes for platform - if (Constants.Platform != Platform.Windows) + // XNA Framework before Stardew Valley 1.5.5 + removeAssemblyReferences.AddRange(new[] { - removeAssemblyReferences.AddRange(new[] - { - "Netcode", - "Stardew Valley" - }); - targetAssemblies.Add( - typeof(StardewValley.Game1).Assembly // note: includes Netcode types on Linux/macOS - ); - } - else - { - removeAssemblyReferences.Add( - "StardewValley" - ); - targetAssemblies.AddRange(new[] - { - typeof(Netcode.NetBool).Assembly, - typeof(StardewValley.Game1).Assembly - }); - } + "Microsoft.Xna.Framework", + "Microsoft.Xna.Framework.Game", + "Microsoft.Xna.Framework.Graphics", + "Microsoft.Xna.Framework.Xact" + }); + targetAssemblies.Add( + typeof(Microsoft.Xna.Framework.Vector2).Assembly + ); - // get changes for game framework - switch (framework) - { - case GameFramework.MonoGame: - removeAssemblyReferences.AddRange(new[] - { - "Microsoft.Xna.Framework", - "Microsoft.Xna.Framework.Game", - "Microsoft.Xna.Framework.Graphics", - "Microsoft.Xna.Framework.Xact" - }); - targetAssemblies.Add( - typeof(Microsoft.Xna.Framework.Vector2).Assembly - ); - break; - - case GameFramework.Xna: - removeAssemblyReferences.Add( - "MonoGame.Framework" - ); - targetAssemblies.AddRange(new[] - { - typeof(Microsoft.Xna.Framework.Vector2).Assembly, - typeof(Microsoft.Xna.Framework.Game).Assembly, - typeof(Microsoft.Xna.Framework.Graphics.SpriteBatch).Assembly - }); - break; + // `Netcode.dll` merged into the game assembly in Stardew Valley 1.5.5 + removeAssemblyReferences.Add( + "Netcode" + ); - default: - throw new InvalidOperationException($"Unknown game framework '{framework}'."); - } + // Stardew Valley reference + removeAssemblyReferences.Add( + Constants.Platform == Platform.Windows + ? "StardewValley" + : "Stardew Valley" + ); + targetAssemblies.Add( + typeof(StardewValley.Game1).Assembly + ); return new PlatformAssemblyMap(targetPlatform, removeAssemblyReferences.ToArray(), targetAssemblies.ToArray()); } diff --git a/src/SMAPI/Framework/Content/ContentCache.cs b/src/SMAPI/Framework/Content/ContentCache.cs index 7edc9ab9..87d15e32 100644 --- a/src/SMAPI/Framework/Content/ContentCache.cs +++ b/src/SMAPI/Framework/Content/ContentCache.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; -using Microsoft.Xna.Framework; using StardewModdingAPI.Framework.Reflection; using StardewModdingAPI.Toolkit.Utilities; using StardewValley; @@ -52,13 +51,7 @@ namespace StardewModdingAPI.Framework.Content this.Cache = reflection.GetField>(contentManager, "loadedAssets").GetValue(); // get key normalization logic - if (Constants.GameFramework == GameFramework.Xna) - { - IReflectedMethod method = reflection.GetMethod(typeof(TitleContainer), "GetCleanPath"); - this.NormalizeAssetNameForPlatform = path => method.Invoke(path); - } - else - this.NormalizeAssetNameForPlatform = key => key.Replace('\\', '/'); // based on MonoGame's ContentManager.Load logic + this.NormalizeAssetNameForPlatform = PathUtilities.NormalizePath; //this.NormalizeAssetNameForPlatform = key => key.Replace('\\', '/'); // based on MonoGame's ContentManager.Load logic } /**** diff --git a/src/SMAPI/Framework/Input/GamePadStateBuilder.cs b/src/SMAPI/Framework/Input/GamePadStateBuilder.cs index f5f2d916..b0bb7f80 100644 --- a/src/SMAPI/Framework/Input/GamePadStateBuilder.cs +++ b/src/SMAPI/Framework/Input/GamePadStateBuilder.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; @@ -157,11 +158,8 @@ namespace StardewModdingAPI.Framework.Input yield break; // buttons - foreach (var pair in this.ButtonStates) - { - if (pair.Value == ButtonState.Pressed && pair.Key.TryGetController(out Buttons button)) - yield return button.ToSButton(); - } + foreach (Buttons button in this.GetPressedGamePadButtons()) + yield return button.ToSButton(); // triggers if (this.LeftTrigger > 0.2f) @@ -201,7 +199,7 @@ namespace StardewModdingAPI.Framework.Input rightThumbStick: this.RightStickPos, leftTrigger: this.LeftTrigger, rightTrigger: this.RightTrigger, - buttons: this.GetButtonBitmask() // MonoGame requires one bitmask here; don't specify multiple values + buttons: this.GetPressedGamePadButtons().ToArray() ); return this.State.Value; @@ -211,17 +209,14 @@ namespace StardewModdingAPI.Framework.Input /********* ** Private methods *********/ - /// Get a bitmask representing the pressed buttons. - private Buttons GetButtonBitmask() + /// Get the pressed gamepad buttons. + private IEnumerable GetPressedGamePadButtons() { - Buttons flag = 0; foreach (var pair in this.ButtonStates) { if (pair.Value == ButtonState.Pressed && pair.Key.TryGetController(out Buttons button)) - flag |= button; + yield return button; } - - return flag; } } } diff --git a/src/SMAPI/Framework/InternalExtensions.cs b/src/SMAPI/Framework/InternalExtensions.cs index 6c9a5f3b..4cb77a45 100644 --- a/src/SMAPI/Framework/InternalExtensions.cs +++ b/src/SMAPI/Framework/InternalExtensions.cs @@ -6,7 +6,6 @@ using System.Threading; using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI.Framework.Events; using StardewModdingAPI.Framework.Reflection; -using StardewValley; using StardewValley.Menus; namespace StardewModdingAPI.Framework @@ -150,11 +149,7 @@ namespace StardewModdingAPI.Framework /// The reflection helper with which to access private fields. public static bool IsOpen(this SpriteBatch spriteBatch, Reflector reflection) { - string fieldName = Constants.GameFramework == GameFramework.Xna - ? "inBeginEndPair" - : "_beginCalled"; - - return reflection.GetField(Game1.spriteBatch, fieldName).GetValue(); + return reflection.GetField(spriteBatch, "_beginCalled").GetValue(); } } } diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index f2876146..2e25a94a 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -253,10 +253,10 @@ namespace StardewModdingAPI.Framework.Logging switch (exception) { // audio crash - case InvalidOperationException ex when ex.Source == "Microsoft.Xna.Framework.Xact" && ex.StackTrace.Contains("Microsoft.Xna.Framework.Audio.AudioEngine..ctor"): - this.Monitor.Log("The game couldn't load audio. Do you have speakers or headphones plugged in?", LogLevel.Error); - this.Monitor.Log($"Technical details: {ex.GetLogSummary()}"); - break; + //case InvalidOperationException ex when ex.Source == "Microsoft.Xna.Framework.Xact" && ex.StackTrace.Contains("Microsoft.Xna.Framework.Audio.AudioEngine..ctor"): + // this.Monitor.Log("The game couldn't load audio. Do you have speakers or headphones plugged in?", LogLevel.Error); + // this.Monitor.Log($"Technical details: {ex.GetLogSummary()}"); + // break; // missing content folder exception case FileNotFoundException ex when ex.Message == "Couldn't find file 'C:\\Program Files (x86)\\Steam\\SteamApps\\common\\Stardew Valley\\Content\\XACT\\FarmerSounds.xgs'.": // path in error is hardcoded regardless of install path diff --git a/src/SMAPI/Framework/ModLoading/RewriteFacades/SpriteBatchFacade.cs b/src/SMAPI/Framework/ModLoading/RewriteFacades/SpriteBatchFacade.cs index aefd1c20..a064f503 100644 --- a/src/SMAPI/Framework/ModLoading/RewriteFacades/SpriteBatchFacade.cs +++ b/src/SMAPI/Framework/ModLoading/RewriteFacades/SpriteBatchFacade.cs @@ -4,7 +4,7 @@ using Microsoft.Xna.Framework.Graphics; namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades { - /// Provides method signatures that can be injected into mod code for compatibility between Linux/macOS or Windows. + /// Provides method signatures that can be injected into mod code for compatibility with mods written for XNA Framework before Stardew Valley 1.5.5. /// This is public to support SMAPI rewriting and should not be referenced directly by mods. [SuppressMessage("ReSharper", "UnusedMember.Global", Justification = "Used via assembly rewriting")] [SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Linux/macOS.")] @@ -18,14 +18,6 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades public SpriteBatchFacade(GraphicsDevice graphicsDevice) : base(graphicsDevice) { } - /**** - ** MonoGame signatures - ****/ - public new void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState, Effect effect, Matrix? matrix) - { - base.Begin(sortMode, blendState, samplerState, depthStencilState, rasterizerState, effect, matrix ?? Matrix.Identity); - } - /**** ** XNA signatures ****/ diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index 6dffb1de..b049e868 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -16,9 +16,7 @@ using Microsoft.Xna.Framework; #if SMAPI_FOR_WINDOWS using Microsoft.Win32; #endif -#if SMAPI_FOR_XNA -using System.Windows.Forms; -#endif +using Microsoft.Xna.Framework; using Newtonsoft.Json; using StardewModdingAPI.Enums; using StardewModdingAPI.Events; @@ -224,10 +222,6 @@ namespace StardewModdingAPI.Framework this.Toolkit.JsonHelper.JsonSettings.Converters.Add(converter); // add error handlers -#if SMAPI_FOR_XNA - Application.ThreadException += (sender, e) => this.Monitor.Log($"Critical thread exception: {e.Exception.GetLogSummary()}", LogLevel.Error); - Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); -#endif AppDomain.CurrentDomain.UnhandledException += (sender, e) => this.Monitor.Log($"Critical app domain exception: {e.ExceptionObject}", LogLevel.Error); // add more lenient assembly resolver diff --git a/src/SMAPI/GameFramework.cs b/src/SMAPI/GameFramework.cs index 7670ce8f..a0154329 100644 --- a/src/SMAPI/GameFramework.cs +++ b/src/SMAPI/GameFramework.cs @@ -1,12 +1,15 @@ +using System; + namespace StardewModdingAPI { /// The game framework running the game. public enum GameFramework { - /// The XNA Framework on Windows. + /// The XNA Framework, previously used on Windows. + [Obsolete("Stardew Valley no longer uses XNA Framework on any supported platform.")] Xna, - /// The MonoGame framework, usually on non-Windows platforms. + /// The MonoGame framework. MonoGame } } diff --git a/src/SMAPI/Metadata/InstructionMetadata.cs b/src/SMAPI/Metadata/InstructionMetadata.cs index 76371e50..368306a1 100644 --- a/src/SMAPI/Metadata/InstructionMetadata.cs +++ b/src/SMAPI/Metadata/InstructionMetadata.cs @@ -36,9 +36,6 @@ namespace StardewModdingAPI.Metadata // rewrite for crossplatform compatibility if (rewriteMods) { - if (platformChanged) - yield return new MethodParentRewriter(typeof(SpriteBatch), typeof(SpriteBatchFacade)); - // rewrite for Stardew Valley 1.5 yield return new FieldReplaceRewriter(typeof(DecoratableLocation), "furniture", typeof(GameLocation), nameof(GameLocation.furniture)); yield return new FieldReplaceRewriter(typeof(Farm), "resourceClumps", typeof(GameLocation), nameof(GameLocation.resourceClumps)); @@ -48,8 +45,9 @@ namespace StardewModdingAPI.Metadata yield return new HeuristicFieldRewriter(this.ValidateReferencesToAssemblies); yield return new HeuristicMethodRewriter(this.ValidateReferencesToAssemblies); - // rewrite for 64-bit mode - // re-enable in Stardew Valley 1.5.5 + // rewrite for Stardew Valley 1.5.5 + if (platformChanged) + yield return new MethodParentRewriter(typeof(SpriteBatch), typeof(SpriteBatchFacade)); //yield return new ArchitectureAssemblyRewriter(); // detect Harmony & rewrite for SMAPI 3.12 (Harmony 1.x => 2.0 update) diff --git a/src/SMAPI/SMAPI.csproj b/src/SMAPI/SMAPI.csproj index c147e7dc..7fb40722 100644 --- a/src/SMAPI/SMAPI.csproj +++ b/src/SMAPI/SMAPI.csproj @@ -30,32 +30,15 @@ + - - - - - - - - - - - - - - - - - - -- cgit From 727d75ae728ba6cc8fc070524264c454aac8404f Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 12 Aug 2021 21:26:10 -0400 Subject: update to .NET 5 and official 64-bit --- build/common.targets | 25 ++++-- build/prepare-install-package.targets | 66 +++++--------- docs/release-notes.md | 14 +++ docs/technical/mod-package.md | 1 + docs/technical/web.md | 2 +- src/SMAPI.Installer/Framework/InstallerContext.cs | 45 ---------- src/SMAPI.Installer/Framework/InstallerPaths.cs | 44 +++++----- src/SMAPI.Installer/InteractiveInstaller.cs | 81 ++++++----------- src/SMAPI.Installer/SMAPI.Installer.csproj | 2 +- src/SMAPI.Installer/assets/System.Numerics.dll | Bin 54272 -> 0 bytes .../assets/System.Runtime.Caching.dll | Bin 71168 -> 0 bytes src/SMAPI.Installer/assets/unix-install.sh | 18 +--- src/SMAPI.Installer/assets/unix-launcher.sh | 96 +++++---------------- .../SMAPI.ModBuildConfig.Analyzer.Tests.csproj | 13 +-- .../SMAPI.ModBuildConfig.Analyzer.csproj | 3 +- .../SMAPI.ModBuildConfig.csproj | 16 ++-- src/SMAPI.ModBuildConfig/build/smapi.targets | 8 +- .../SMAPI.Mods.ConsoleCommands.csproj | 4 +- .../SMAPI.Mods.ErrorHandler.csproj | 4 +- .../SMAPI.Mods.SaveBackup.csproj | 4 +- src/SMAPI.Tests/SMAPI.Tests.csproj | 5 +- .../SMAPI.Toolkit.CoreInterfaces.csproj | 2 +- src/SMAPI.Toolkit/Framework/Constants.cs | 9 ++ .../Framework/GameScanning/GameScanner.cs | 5 +- .../Framework/LowLevelEnvironmentUtility.cs | 9 -- src/SMAPI.Toolkit/SMAPI.Toolkit.csproj | 6 +- src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs | 7 -- src/SMAPI.Toolkit/Utilities/PathUtilities.cs | 15 ++-- src/SMAPI/Framework/Logging/LogManager.cs | 2 +- .../Framework/Reflection/InterfaceProxyFactory.cs | 2 +- src/SMAPI/Framework/SCore.cs | 9 +- src/SMAPI/Metadata/InstructionMetadata.cs | 2 +- src/SMAPI/SMAPI.csproj | 14 +-- 33 files changed, 192 insertions(+), 341 deletions(-) delete mode 100644 src/SMAPI.Installer/assets/System.Numerics.dll delete mode 100644 src/SMAPI.Installer/assets/System.Runtime.Caching.dll create mode 100644 src/SMAPI.Toolkit/Framework/Constants.cs (limited to 'docs') diff --git a/build/common.targets b/build/common.targets index 02142351..a74002a6 100644 --- a/build/common.targets +++ b/build/common.targets @@ -7,7 +7,7 @@ $(AssemblySearchPaths);{GAC} - $(DefineConstants);SMAPI_FOR_WINDOWS;SMAPI_FOR_XNA + $(DefineConstants);SMAPI_FOR_WINDOWS @@ -27,20 +27,31 @@ - + + + + + + + + + - - - + + + + + + @@ -54,13 +65,13 @@ - + - + diff --git a/build/prepare-install-package.targets b/build/prepare-install-package.targets index 601f6496..bc1716a3 100644 --- a/build/prepare-install-package.targets +++ b/build/prepare-install-package.targets @@ -14,7 +14,7 @@ $(SolutionDir)\..\bin $(BuildRootPath)\SMAPI\bin\$(Configuration) - $(BuildRootPath)\SMAPI.Toolkit\bin\$(Configuration)\net452 + $(BuildRootPath)\SMAPI.Toolkit\bin\$(Configuration)\net5.0 $(BuildRootPath)\SMAPI.Mods.ConsoleCommands\bin\$(Configuration) $(BuildRootPath)\SMAPI.Mods.ErrorHandler\bin\$(Configuration) $(BuildRootPath)\SMAPI.Mods.SaveBackup\bin\$(Configuration) @@ -35,12 +35,17 @@ - - - + + + + + + - + + + @@ -61,11 +66,16 @@ - - + + + + + + + @@ -78,63 +88,33 @@ - - - - - - + + + - + - + - - - - - - - - - - - - - - - - + - diff --git a/docs/release-notes.md b/docs/release-notes.md index efda7267..43370409 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -3,8 +3,22 @@ # Release notes ## Upcoming release * For players: + * Updated for Stardew Valley 1.5.5. * Added `set_farm_type` [console command](https://stardewvalleywiki.com/Modding:Console_commands#Console_commands) to change the current farm type. +* For mod authors: + * Migrated to 64-bit MonoGame and .NET 5 on all platforms (see [migration guide for mod authors](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5)). + +**Update note for players with older systems:** +The game now has two branches: the _main branch_ which you'll get by default, and an optional +_compatibility branch_ for [older systems](https://www.stardewvalley.net/compatibility/). The two +branches have identical content, but use [different technologies](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5#Stardew_Valley_compatibility_branch). + +Unfortunately **SMAPI only supports the main branch of the game**. There are formidable difficulties +across all mods in supporting all three variations, the [Steam hardware stats](https://store.steampowered.com/hwsurvey) +show that 99.69% of players have 64-bit, and 32-bit imposes significant restrictions on what mods +can do. + * For the web UI: * Updated the JSON validator/schema for Content Patcher 1.24.0. diff --git a/docs/technical/mod-package.md b/docs/technical/mod-package.md index 7eefc7a4..a3ce8761 100644 --- a/docs/technical/mod-package.md +++ b/docs/technical/mod-package.md @@ -366,6 +366,7 @@ when you compile it. ## Release notes ## Upcoming release +* Updated for Stardew Valley 1.5.5 and SMAPI 3.13.0. **The older versions are no longer supported.** * Improved analyzer performance by enabling parallel execution. ## 3.3.0 diff --git a/docs/technical/web.md b/docs/technical/web.md index 50237bfe..f0d43fb1 100644 --- a/docs/technical/web.md +++ b/docs/technical/web.md @@ -367,7 +367,7 @@ accordingly. Initial setup: 1. Create an Azure Blob storage account for uploaded files. -2. Create an Azure App Services environment running the latest .NET Core on Linux or Windows. +2. Create an Azure App Services environment running the latest .NET on Linux or Windows. 3. Add these application settings in the new App Services environment: property name | description diff --git a/src/SMAPI.Installer/Framework/InstallerContext.cs b/src/SMAPI.Installer/Framework/InstallerContext.cs index 88e57760..95df32ca 100644 --- a/src/SMAPI.Installer/Framework/InstallerContext.cs +++ b/src/SMAPI.Installer/Framework/InstallerContext.cs @@ -1,6 +1,4 @@ -using System; using System.IO; -using Microsoft.Win32; using StardewModdingAPI.Toolkit; using StardewModdingAPI.Toolkit.Framework.GameScanning; using StardewModdingAPI.Toolkit.Utilities; @@ -13,9 +11,6 @@ namespace StardewModdingAPI.Installer.Framework /********* ** Fields *********/ - /// The value that represents Windows 7. - private readonly Version Windows7Version = new Version(6, 1); - /// The underlying toolkit game scanner. private readonly GameScanner GameScanner = new GameScanner(); @@ -29,9 +24,6 @@ namespace StardewModdingAPI.Installer.Framework /// The human-readable OS name and version. public string PlatformName { get; } - /// The name of the Stardew Valley executable. - public string ExecutableName { get; } - /// Whether the installer is running on Windows. public bool IsWindows => this.Platform == Platform.Windows; @@ -47,7 +39,6 @@ namespace StardewModdingAPI.Installer.Framework { this.Platform = EnvironmentUtility.DetectPlatform(); this.PlatformName = EnvironmentUtility.GetFriendlyPlatformName(this.Platform); - this.ExecutableName = EnvironmentUtility.GetExecutableName(this.Platform); } /// Get the installer's version number. @@ -57,42 +48,6 @@ namespace StardewModdingAPI.Installer.Framework return new SemanticVersion(raw); } - /// Get whether the current system has .NET Framework 4.5 or later installed. This only applies on Windows. - /// The current platform is not Windows. - public bool HasNetFramework45() - { - switch (this.Platform) - { - case Platform.Windows: - using (RegistryKey versionKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full")) - return versionKey?.GetValue("Release") != null; // .NET Framework 4.5+ - - default: - throw new NotSupportedException("The installed .NET Framework version can only be checked on Windows."); - } - } - - /// Get whether the current system has XNA Framework installed. This only applies on Windows. - /// The current platform is not Windows. - public bool HasXna() - { - switch (this.Platform) - { - case Platform.Windows: - using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\XNA\Framework")) - return key != null; // XNA Framework 4.0+ - - default: - throw new NotSupportedException("The installed XNA Framework version can only be checked on Windows."); - } - } - - /// Whether the current OS supports newer versions of .NET Framework. - public bool CanInstallLatestNetFramework() - { - return Environment.OSVersion.Version >= this.Windows7Version; // Windows 7+ - } - /// Get whether a folder seems to contain the game files. /// The folder to check. public bool LooksLikeGameFolder(DirectoryInfo dir) diff --git a/src/SMAPI.Installer/Framework/InstallerPaths.cs b/src/SMAPI.Installer/Framework/InstallerPaths.cs index 6ba5fa5f..0976eceb 100644 --- a/src/SMAPI.Installer/Framework/InstallerPaths.cs +++ b/src/SMAPI.Installer/Framework/InstallerPaths.cs @@ -1,4 +1,5 @@ using System.IO; +using StardewModdingAPI.Toolkit.Framework; namespace StardewModdingAPI.Installer.Framework { @@ -44,17 +45,20 @@ namespace StardewModdingAPI.Installer.Framework /// The full path to the user's config overrides file. public string ApiUserConfigPath { get; } - /// The full path to the installed game executable file. - public string ExecutablePath { get; private set; } + /// The full path to the installed game DLL. + public string GameDllPath { get; } - /// The full path to the vanilla game launcher on Linux/macOS. - public string UnixLauncherPath { get; } + /// The full path to the installed SMAPI executable file. + public string UnixSmapiExecutablePath { get; } - /// The full path to the installed SMAPI launcher on Linux/macOS before it's renamed. - public string UnixSmapiLauncherPath { get; } + /// The full path to the vanilla game launch script on Linux/macOS. + public string VanillaLaunchScriptPath { get; } - /// The full path to the vanilla game launcher on Linux/macOS after SMAPI is installed. - public string UnixBackupLauncherPath { get; } + /// The full path to the installed SMAPI launch script on Linux/macOS before it's renamed. + public string NewLaunchScriptPath { get; } + + /// The full path to the backed up game launch script on Linux/macOS after SMAPI is installed. + public string BackupLaunchScriptPath { get; } /********* @@ -63,28 +67,24 @@ namespace StardewModdingAPI.Installer.Framework /// Construct an instance. /// The directory path containing the files to copy into the game folder. /// The directory path for the installed game. - /// The name of the game's executable file for the current platform. - public InstallerPaths(DirectoryInfo bundleDir, DirectoryInfo gameDir, string gameExecutableName) + public InstallerPaths(DirectoryInfo bundleDir, DirectoryInfo gameDir) { + // base paths this.BundleDir = bundleDir; this.GameDir = gameDir; this.ModsDir = new DirectoryInfo(Path.Combine(gameDir.FullName, "Mods")); + this.GameDllPath = Path.Combine(gameDir.FullName, Constants.GameDllName); - this.BundleApiUserConfigPath = Path.Combine(bundleDir.FullName, "smapi-internal", "config.user.json"); + // launch scripts + this.VanillaLaunchScriptPath = Path.Combine(gameDir.FullName, "StardewValley"); + this.NewLaunchScriptPath = Path.Combine(gameDir.FullName, "unix-launcher.sh"); + this.BackupLaunchScriptPath = Path.Combine(gameDir.FullName, "StardewValley-original"); + this.UnixSmapiExecutablePath = Path.Combine(gameDir.FullName, "StardewModdingAPI"); - this.ExecutablePath = Path.Combine(gameDir.FullName, gameExecutableName); - this.UnixLauncherPath = Path.Combine(gameDir.FullName, "StardewValley"); - this.UnixSmapiLauncherPath = Path.Combine(gameDir.FullName, "StardewModdingAPI"); - this.UnixBackupLauncherPath = Path.Combine(gameDir.FullName, "StardewValley-original"); + // internal files + this.BundleApiUserConfigPath = Path.Combine(bundleDir.FullName, "smapi-internal", "config.user.json"); this.ApiConfigPath = Path.Combine(gameDir.FullName, "smapi-internal", "config.json"); this.ApiUserConfigPath = Path.Combine(gameDir.FullName, "smapi-internal", "config.user.json"); } - - /// Override the filename for the . - /// the file name. - public void SetExecutableFileName(string filename) - { - this.ExecutablePath = Path.Combine(this.GamePath, filename); - } } } diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs index 79c3b891..34285cf7 100644 --- a/src/SMAPI.Installer/InteractiveInstaller.cs +++ b/src/SMAPI.Installer/InteractiveInstaller.cs @@ -41,12 +41,13 @@ namespace StardewModdingApi.Installer // current files yield return GetInstallPath("libgdiplus.dylib"); // Linux/macOS only yield return GetInstallPath("StardewModdingAPI"); // Linux/macOS only + yield return GetInstallPath("StardewModdingAPI.dll"); yield return GetInstallPath("StardewModdingAPI.exe"); yield return GetInstallPath("StardewModdingAPI.exe.config"); yield return GetInstallPath("StardewModdingAPI.exe.mdb"); // Linux/macOS only yield return GetInstallPath("StardewModdingAPI.pdb"); // Windows only + yield return GetInstallPath("StardewModdingAPI.runtimeconfig.json"); yield return GetInstallPath("StardewModdingAPI.xml"); - yield return GetInstallPath("StardewModdingAPI-x64.exe"); // not normally added to game folder, but may be mistakenly added by a manual install yield return GetInstallPath("smapi-internal"); yield return GetInstallPath("steam_appid.txt"); @@ -70,9 +71,7 @@ namespace StardewModdingApi.Installer yield return GetInstallPath("StardewModdingAPI.Toolkit.CoreInterfaces.dll"); // moved in 2.8 yield return GetInstallPath("StardewModdingAPI.Toolkit.CoreInterfaces.pdb"); // moved in 2.8 yield return GetInstallPath("StardewModdingAPI.Toolkit.CoreInterfaces.xml"); // moved in 2.8 - yield return GetInstallPath("System.Numerics.dll"); // moved in 2.8 - yield return GetInstallPath("System.Runtime.Caching.dll"); // moved in 2.8 - yield return GetInstallPath("System.ValueTuple.dll"); // moved in 2.8 + yield return GetInstallPath("StardewModdingAPI-x64.exe"); // 3.13 if (modsDir.Exists) { @@ -149,30 +148,6 @@ namespace StardewModdingApi.Installer } #endif - /**** - ** Check Windows dependencies - ****/ - if (context.IsWindows) - { - // .NET Framework 4.5+ - if (!context.HasNetFramework45()) - { - this.PrintError(context.CanInstallLatestNetFramework() - ? "Please install the latest version of .NET Framework before installing SMAPI." - : "Please install .NET Framework 4.5 before installing SMAPI." - ); - this.PrintError("See the download page at https://www.microsoft.com/net/download/framework for details."); - Console.ReadLine(); - return; - } - if (!context.HasXna()) - { - this.PrintError("You don't seem to have XNA Framework installed. Please run the game at least once before installing SMAPI, so it can perform its first-time setup."); - Console.ReadLine(); - return; - } - } - /**** ** read command-line arguments ****/ @@ -270,7 +245,7 @@ namespace StardewModdingApi.Installer // get folders DirectoryInfo bundleDir = new DirectoryInfo(this.BundlePath); - paths = new InstallerPaths(bundleDir, installDir, context.ExecutableName); + paths = new InstallerPaths(bundleDir, installDir); } @@ -278,7 +253,7 @@ namespace StardewModdingApi.Installer ** Step 4: validate assumptions *********/ // executable exists - if (!File.Exists(paths.ExecutablePath)) + if (!File.Exists(paths.GameDllPath)) { this.PrintError("The detected game install path doesn't contain a Stardew Valley executable."); Console.ReadLine(); @@ -367,11 +342,11 @@ namespace StardewModdingApi.Installer ** Always uninstall old files ****/ // restore game launcher - if (context.IsUnix && File.Exists(paths.UnixBackupLauncherPath)) + if (context.IsUnix && File.Exists(paths.BackupLaunchScriptPath)) { this.PrintDebug("Removing SMAPI launcher..."); - this.InteractivelyDelete(paths.UnixLauncherPath); - File.Move(paths.UnixBackupLauncherPath, paths.UnixLauncherPath); + this.InteractivelyDelete(paths.VanillaLaunchScriptPath); + File.Move(paths.BackupLaunchScriptPath, paths.VanillaLaunchScriptPath); } // remove old files @@ -419,28 +394,31 @@ namespace StardewModdingApi.Installer this.PrintDebug("Safely replacing game launcher..."); // back up & remove current launcher - if (File.Exists(paths.UnixLauncherPath)) + if (File.Exists(paths.VanillaLaunchScriptPath)) { - if (!File.Exists(paths.UnixBackupLauncherPath)) - File.Move(paths.UnixLauncherPath, paths.UnixBackupLauncherPath); + if (!File.Exists(paths.BackupLaunchScriptPath)) + File.Move(paths.VanillaLaunchScriptPath, paths.BackupLaunchScriptPath); else - this.InteractivelyDelete(paths.UnixLauncherPath); + this.InteractivelyDelete(paths.VanillaLaunchScriptPath); } // add new launcher - File.Move(paths.UnixSmapiLauncherPath, paths.UnixLauncherPath); + File.Move(paths.NewLaunchScriptPath, paths.VanillaLaunchScriptPath); - // mark file executable + // mark files executable // (MSBuild doesn't keep permission flags for files zipped in a build task.) - new Process + foreach (string path in new[] { paths.VanillaLaunchScriptPath, paths.UnixSmapiExecutablePath }) { - StartInfo = new ProcessStartInfo + new Process { - FileName = "chmod", - Arguments = $"755 \"{paths.UnixLauncherPath}\"", - CreateNoWindow = true - } - }.Start(); + StartInfo = new ProcessStartInfo + { + FileName = "chmod", + Arguments = $"755 \"{path}\"", + CreateNoWindow = true + } + }.Start(); + } } // create mods directory (if needed) @@ -507,7 +485,7 @@ namespace StardewModdingApi.Installer /********* - ** Step 6: final instructions + ** Step 7: final instructions *********/ if (context.IsWindows) { @@ -536,13 +514,6 @@ namespace StardewModdingApi.Installer /********* ** Private methods *********/ - /// Get whether an executable is 64-bit. - /// The absolute path to the executable file. - private bool Is64Bit(string executablePath) - { - return LowLevelEnvironmentUtility.Is64BitAssembly(executablePath); - } - /// Get the display text for a color scheme. /// The color scheme. private string GetDisplayText(MonitorColorScheme scheme) @@ -705,7 +676,7 @@ namespace StardewModdingApi.Installer { // get path from user Console.WriteLine(); - this.PrintInfo($"Type the file path to the game directory (the one containing '{context.ExecutableName}'), then press enter."); + this.PrintInfo($"Type the file path to the game directory (the one containing '{Constants.GameDllName}'), then press enter."); string path = Console.ReadLine()?.Trim(); if (string.IsNullOrWhiteSpace(path)) { diff --git a/src/SMAPI.Installer/SMAPI.Installer.csproj b/src/SMAPI.Installer/SMAPI.Installer.csproj index c47f3e6e..e3e01467 100644 --- a/src/SMAPI.Installer/SMAPI.Installer.csproj +++ b/src/SMAPI.Installer/SMAPI.Installer.csproj @@ -2,7 +2,7 @@ StardewModdingAPI.Installer The SMAPI installer for players. - net452 + net5.0 Exe false diff --git a/src/SMAPI.Installer/assets/System.Numerics.dll b/src/SMAPI.Installer/assets/System.Numerics.dll deleted file mode 100644 index fed0f92c..00000000 Binary files a/src/SMAPI.Installer/assets/System.Numerics.dll and /dev/null differ diff --git a/src/SMAPI.Installer/assets/System.Runtime.Caching.dll b/src/SMAPI.Installer/assets/System.Runtime.Caching.dll deleted file mode 100644 index a062391d..00000000 Binary files a/src/SMAPI.Installer/assets/System.Runtime.Caching.dll and /dev/null differ diff --git a/src/SMAPI.Installer/assets/unix-install.sh b/src/SMAPI.Installer/assets/unix-install.sh index 311c5469..a830a22d 100644 --- a/src/SMAPI.Installer/assets/unix-install.sh +++ b/src/SMAPI.Installer/assets/unix-install.sh @@ -1,24 +1,10 @@ #!/bin/bash -# Run the SMAPI installer through Mono on Linux or macOS. # Move to script's directory cd "`dirname "$0"`" -# get cross-distro version of POSIX command -COMMAND="" -if command -v command >/dev/null 2>&1; then - COMMAND="command -v" -elif type type >/dev/null 2>&1; then - COMMAND="type" -fi - # if $TERM is not set to xterm, mono will bail out when attempting to write to the console. export TERM=xterm -# validate Mono & run installer -if $COMMAND mono >/dev/null 2>&1; then - mono internal/unix-install.exe -else - echo "Oops! Looks like Mono isn't installed. Please install Mono from https://mono-project.com, reboot, and run this installer again." - read -fi +# run installer +./internal/unix-install diff --git a/src/SMAPI.Installer/assets/unix-launcher.sh b/src/SMAPI.Installer/assets/unix-launcher.sh index d309f750..21bed803 100644 --- a/src/SMAPI.Installer/assets/unix-launcher.sh +++ b/src/SMAPI.Installer/assets/unix-launcher.sh @@ -1,34 +1,17 @@ #!/usr/bin/env bash -# MonoKickstart Shell Script -# Written by Ethan "flibitijibibo" Lee -# Modified for SMAPI by various contributors # Move to script's directory cd "$(dirname "$0")" || exit $? -# Get the system architecture -UNAME=$(uname) -ARCH=$(uname -m) +# validate script is being run from the game folder +if [ ! -f "Stardew Valley.dll" ]; then + echo "Oops! SMAPI must be placed in the Stardew Valley game folder.\nSee instructions: https://stardewvalleywiki.com/Modding:Player_Guide"; + read + exit 1 +fi -# MonoKickstart picks the right libfolder, so just execute the right binary. +# macOS if [ "$UNAME" == "Darwin" ]; then - # ... Except on OSX. - export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:./osx/ - - # El Capitan is a total idiot and wipes this variable out, making the - # Steam overlay disappear. This sidesteps "System Integrity Protection" - # and resets the variable with Valve's own variable (they provided this - # fix by the way, thanks Valve!). Note that you will need to update your - # launch configuration to the script location, NOT just the app location - # (i.e. Kick.app/Contents/MacOS/Kick, not just Kick.app). - # -flibit - if [ "$STEAM_DYLD_INSERT_LIBRARIES" != "" ] && [ "$DYLD_INSERT_LIBRARIES" == "" ]; then - export DYLD_INSERT_LIBRARIES="$STEAM_DYLD_INSERT_LIBRARIES" - fi - - # this was here before - ln -sf mcs.bin.osx mcs - # fix "DllNotFoundException: libgdiplus.dylib" errors when loading images in SMAPI if [ -f libgdiplus.dylib ]; then rm libgdiplus.dylib @@ -37,52 +20,13 @@ if [ "$UNAME" == "Darwin" ]; then ln -s /Library/Frameworks/Mono.framework/Versions/Current/lib/libgdiplus.dylib libgdiplus.dylib fi - # create bin file - # Note: don't overwrite if it's identical, to avoid resetting permission flags - if [ ! -x StardewModdingAPI.bin.osx ] || ! cmp StardewValley.bin.osx StardewModdingAPI.bin.osx >/dev/null 2>&1; then - cp -p StardewValley.bin.osx StardewModdingAPI.bin.osx - fi - - # Make sure we're running in Terminal (so the user can see errors/warnings/update alerts). - # Previously we would just use `open -a Terminal` to launch the .bin.osx file, but that - # doesn't let us set environment variables. - if [ ! -t 1 ]; then # https://stackoverflow.com/q/911168/262123 - # sanity check to make sure we don't have an infinite loop of opening windows - SKIP_TERMINAL=false - for argument in "$@"; do - if [ "$argument" == "--no-reopen-terminal" ]; then - SKIP_TERMINAL=true - break - fi - done - - # reopen in Terminal if needed - # https://stackoverflow.com/a/29511052/262123 - if [ "$SKIP_TERMINAL" == "false" ]; then - echo "Reopening in the Terminal app..." - echo "\"$0\" $@ --no-reopen-terminal" > /tmp/open-smapi-terminal.sh - chmod +x /tmp/open-smapi-terminal.sh - cat /tmp/open-smapi-terminal.sh - open -W -a Terminal /tmp/open-smapi-terminal.sh - rm /tmp/open-smapi-terminal.sh - exit 0 - fi - fi + # launch smapi + open -a Terminal ./StardewModdingAPI "$@" - # launch SMAPI - LC_ALL="C" ./StardewModdingAPI.bin.osx "$@" +# Linux else # choose binary file to launch - LAUNCH_FILE="" - if [ "$ARCH" == "x86_64" ]; then - ln -sf mcs.bin.x86_64 mcs - cp StardewValley.bin.x86_64 StardewModdingAPI.bin.x86_64 - LAUNCH_FILE="./StardewModdingAPI.bin.x86_64" - else - ln -sf mcs.bin.x86 mcs - cp StardewValley.bin.x86 StardewModdingAPI.bin.x86 - LAUNCH_FILE="./StardewModdingAPI.bin.x86" - fi + LAUNCH_FILE="./StardewModdingAPI" export LAUNCH_FILE # select terminal (prefer xterm for best compatibility, then known supported terminals) @@ -105,44 +49,44 @@ else terminal|termite) # consumes only one argument after -e # options containing space characters are unsupported - exec $TERMINAL_NAME -e "env TERM=xterm LC_ALL=\"C\" $LAUNCH_FILE $@" + exec $TERMINAL_NAME -e "env TERM=xterm $LAUNCH_FILE $@" ;; xterm|konsole|alacritty) # consumes all arguments after -e - exec $TERMINAL_NAME -e env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@" + exec $TERMINAL_NAME -e env TERM=xterm $LAUNCH_FILE "$@" ;; terminator|xfce4-terminal|mate-terminal) # consumes all arguments after -x - exec $TERMINAL_NAME -x env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@" + exec $TERMINAL_NAME -x env TERM=xterm $LAUNCH_FILE "$@" ;; gnome-terminal) # consumes all arguments after -- - exec $TERMINAL_NAME -- env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@" + exec $TERMINAL_NAME -- env TERM=xterm $LAUNCH_FILE "$@" ;; kitty) # consumes all trailing arguments - exec $TERMINAL_NAME env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@" + exec $TERMINAL_NAME env TERM=xterm $LAUNCH_FILE "$@" ;; *) # If we don't know the terminal, just try to run it in the current shell. # If THAT fails, launch with no output. - env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@" + env TERM=xterm $LAUNCH_FILE "$@" if [ $? -eq 127 ]; then - exec LC_ALL="C" $LAUNCH_FILE --no-terminal "$@" + exec $LAUNCH_FILE --no-terminal "$@" fi esac ## terminal isn't executable; fallback to current shell or no terminal else echo "The '$TERMINAL_NAME' terminal isn't executable. SMAPI might be running in a sandbox or the system might be misconfigured? Falling back to current shell." - env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@" + env TERM=xterm $LAUNCH_FILE "$@" if [ $? -eq 127 ]; then - exec LC_ALL="C" $LAUNCH_FILE --no-terminal "$@" + exec $LAUNCH_FILE --no-terminal "$@" fi fi fi diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj b/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj index dc3d8320..264932e4 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj @@ -1,18 +1,14 @@  - - netcoreapp2.0 + net5.0 latest - - + + - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + @@ -20,5 +16,4 @@ - diff --git a/src/SMAPI.ModBuildConfig.Analyzer/SMAPI.ModBuildConfig.Analyzer.csproj b/src/SMAPI.ModBuildConfig.Analyzer/SMAPI.ModBuildConfig.Analyzer.csproj index 0d109b83..3fadc37a 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer/SMAPI.ModBuildConfig.Analyzer.csproj +++ b/src/SMAPI.ModBuildConfig.Analyzer/SMAPI.ModBuildConfig.Analyzer.csproj @@ -9,8 +9,7 @@ - - + diff --git a/src/SMAPI.ModBuildConfig/SMAPI.ModBuildConfig.csproj b/src/SMAPI.ModBuildConfig/SMAPI.ModBuildConfig.csproj index 93769650..33356413 100644 --- a/src/SMAPI.ModBuildConfig/SMAPI.ModBuildConfig.csproj +++ b/src/SMAPI.ModBuildConfig/SMAPI.ModBuildConfig.csproj @@ -2,28 +2,28 @@ StardewModdingAPI.ModBuildConfig - net452 + netstandard2.0 latest true Pathoschild.Stardew.ModBuildConfig Build package for SMAPI mods - 3.3.0 + 3.4.0 Pathoschild - Automates the build configuration for crossplatform Stardew Valley SMAPI mods. For SMAPI 3.0 or later. + Automates the build configuration for crossplatform Stardew Valley SMAPI mods. For SMAPI 3.13.0 or later. MIT images/icon.png https://smapi.io/package/readme false + + + true - - - - - + + diff --git a/src/SMAPI.ModBuildConfig/build/smapi.targets b/src/SMAPI.ModBuildConfig/build/smapi.targets index be10481b..a3cd6c45 100644 --- a/src/SMAPI.ModBuildConfig/build/smapi.targets +++ b/src/SMAPI.ModBuildConfig/build/smapi.targets @@ -45,13 +45,13 @@ **********************************************--> - + - + @@ -68,8 +68,8 @@ - - + + diff --git a/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj b/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj index fa192073..65d54599 100644 --- a/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj +++ b/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj @@ -2,7 +2,7 @@ ConsoleCommands StardewModdingAPI.Mods.ConsoleCommands - net452 + net5.0 false @@ -13,7 +13,7 @@ - + diff --git a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj index 7ba6025b..2ad19df7 100644 --- a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj +++ b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj @@ -2,7 +2,7 @@ ErrorHandler StardewModdingAPI.Mods.ErrorHandler - net452 + net5.0 false @@ -14,7 +14,7 @@ - + diff --git a/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj b/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj index 079beb08..f8908c7d 100644 --- a/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj +++ b/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj @@ -2,7 +2,7 @@ SaveBackup StardewModdingAPI.Mods.SaveBackup - net452 + net5.0 false @@ -13,7 +13,7 @@ - + diff --git a/src/SMAPI.Tests/SMAPI.Tests.csproj b/src/SMAPI.Tests/SMAPI.Tests.csproj index 8f7bfab4..e19105ff 100644 --- a/src/SMAPI.Tests/SMAPI.Tests.csproj +++ b/src/SMAPI.Tests/SMAPI.Tests.csproj @@ -2,7 +2,7 @@ SMAPI.Tests SMAPI.Tests - net452 + net5.0 false latest @@ -16,6 +16,7 @@ + @@ -23,7 +24,7 @@ - $(GamePath)\$(GameExecutableName).exe + $(GamePath)\$(GameExecutableName).dll True diff --git a/src/SMAPI.Toolkit.CoreInterfaces/SMAPI.Toolkit.CoreInterfaces.csproj b/src/SMAPI.Toolkit.CoreInterfaces/SMAPI.Toolkit.CoreInterfaces.csproj index 0e1e40b2..4c92b4db 100644 --- a/src/SMAPI.Toolkit.CoreInterfaces/SMAPI.Toolkit.CoreInterfaces.csproj +++ b/src/SMAPI.Toolkit.CoreInterfaces/SMAPI.Toolkit.CoreInterfaces.csproj @@ -2,7 +2,7 @@ StardewModdingAPI Provides toolkit interfaces which are available to SMAPI mods. - net452;netstandard2.0 + net5.0; netstandard2.0 true diff --git a/src/SMAPI.Toolkit/Framework/Constants.cs b/src/SMAPI.Toolkit/Framework/Constants.cs new file mode 100644 index 00000000..55f26582 --- /dev/null +++ b/src/SMAPI.Toolkit/Framework/Constants.cs @@ -0,0 +1,9 @@ +namespace StardewModdingAPI.Toolkit.Framework +{ + /// Contains the SMAPI installer's constants and assumptions. + internal static class Constants + { + /// The name of the game's main DLL, used to detect game folders. + public const string GameDllName = "Stardew Valley.dll"; + } +} diff --git a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs index c90fc1d3..7553c07f 100644 --- a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs +++ b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs @@ -56,10 +56,7 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning { return dir.Exists - && ( - dir.EnumerateFiles("StardewValley.exe").Any() - || dir.EnumerateFiles("Stardew Valley.exe").Any() - ); + && dir.EnumerateFiles("Stardew Valley.dll").Any(); } diff --git a/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs b/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs index 2636aae0..8b6eb5fb 100644 --- a/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs +++ b/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs @@ -80,15 +80,6 @@ namespace StardewModdingAPI.Toolkit.Framework return name; } - /// Get the name of the Stardew Valley executable. - /// The current platform. - public static string GetExecutableName(string platform) - { - return platform == nameof(Platform.Windows) - ? "Stardew Valley.exe" - : "StardewValley.exe"; - } - /// Get whether an executable is 64-bit. /// The absolute path to the assembly file. public static bool Is64BitAssembly(string path) diff --git a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj index 3d87c169..ec27bf79 100644 --- a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj +++ b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj @@ -2,7 +2,7 @@ StardewModdingAPI.Toolkit A library which encapsulates mod-handling logic for mod managers and tools. Not intended for use by mods. - net452;netstandard2.0 + net5.0; netstandard2.0 true @@ -12,8 +12,8 @@ - - + + diff --git a/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs b/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs index 6de79a85..7536337a 100644 --- a/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs +++ b/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs @@ -40,13 +40,6 @@ namespace StardewModdingAPI.Toolkit.Utilities return LowLevelEnvironmentUtility.GetFriendlyPlatformName(platform.ToString()); } - /// Get the name of the Stardew Valley executable. - /// The current platform. - public static string GetExecutableName(Platform platform) - { - return LowLevelEnvironmentUtility.GetExecutableName(platform.ToString()); - } - /// Get whether an executable is 64-bit. /// The absolute path to the assembly file. public static bool Is64BitAssembly(string path) diff --git a/src/SMAPI.Toolkit/Utilities/PathUtilities.cs b/src/SMAPI.Toolkit/Utilities/PathUtilities.cs index 020ebc6d..c17bb354 100644 --- a/src/SMAPI.Toolkit/Utilities/PathUtilities.cs +++ b/src/SMAPI.Toolkit/Utilities/PathUtilities.cs @@ -88,14 +88,18 @@ namespace StardewModdingAPI.Toolkit.Utilities /// Get a directory or file path relative to a given source path. If no relative path is possible (e.g. the paths are on different drives), an absolute path is returned. /// The source folder path. /// The target folder or file path. - /// - /// - /// NOTE: this is a heuristic implementation that works in the cases SMAPI needs it for, but it doesn't handle all edge cases (e.g. case-sensitivity on Linux, or traversing between UNC paths on Windows). This should be replaced with the more comprehensive Path.GetRelativePath if the game ever migrates to .NET Core. - /// - /// [Pure] public static string GetRelativePath(string sourceDir, string targetPath) { +#if NET5_0 + return Path.GetRelativePath(sourceDir, targetPath); +#else + // NOTE: + // this is a heuristic implementation that works in the cases SMAPI needs it for, but it + // doesn't handle all edge cases (e.g. case-sensitivity on Linux, or traversing between + // UNC paths on Windows). SMAPI and mods will use the more robust .NET 5 version anyway + // though, this is only for compatibility with the mod build package. + // convert to URIs Uri from = new Uri(sourceDir.TrimEnd(PathUtilities.PossiblePathSeparators) + "/"); Uri to = new Uri(targetPath.TrimEnd(PathUtilities.PossiblePathSeparators) + "/"); @@ -123,6 +127,7 @@ namespace StardewModdingAPI.Toolkit.Utilities } return relative; +#endif } /// Get whether a path is relative and doesn't try to climb out of its containing folder (e.g. doesn't contain ../). diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index 2e25a94a..abcb2f64 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -290,7 +290,7 @@ namespace StardewModdingAPI.Framework.Logging /// The custom SMAPI settings. public void LogIntro(string modsPath, IDictionary customSettings) { - // log platform & patches + // log platform this.Monitor.Log($"SMAPI {Constants.ApiVersion} with Stardew Valley {Constants.GameVersion} on {EnvironmentUtility.GetFriendlyPlatformName(Constants.Platform)}", LogLevel.Info); // log basic info diff --git a/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs b/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs index 8d1b6034..5acba569 100644 --- a/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs +++ b/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs @@ -24,7 +24,7 @@ namespace StardewModdingAPI.Framework.Reflection /// Construct an instance. public InterfaceProxyFactory() { - AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName($"StardewModdingAPI.Proxies, Version={this.GetType().Assembly.GetName().Version}, Culture=neutral"), AssemblyBuilderAccess.Run); + AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName($"StardewModdingAPI.Proxies, Version={this.GetType().Assembly.GetName().Version}, Culture=neutral"), AssemblyBuilderAccess.Run); this.ModuleBuilder = assemblyBuilder.DefineDynamicModule("StardewModdingAPI.Proxies"); } diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index b049e868..95a7ace6 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -16,7 +16,6 @@ using Microsoft.Xna.Framework; #if SMAPI_FOR_WINDOWS using Microsoft.Win32; #endif -using Microsoft.Xna.Framework; using Newtonsoft.Json; using StardewModdingAPI.Enums; using StardewModdingAPI.Events; @@ -1298,9 +1297,6 @@ namespace StardewModdingAPI.Framework { // create client string url = this.Settings.WebApiBaseUrl; -#if !SMAPI_FOR_WINDOWS - url = url.Replace("https://", "http://"); // workaround for OpenSSL issues with the game's bundled Mono on Linux/macOS -#endif WebApiClient client = new WebApiClient(url, Constants.ApiVersion); this.Monitor.Log("Checking for updates..."); @@ -1695,9 +1691,8 @@ namespace StardewModdingAPI.Framework catch (Exception ex) { errorReasonPhrase = "its DLL couldn't be loaded."; - // re-enable in Stardew Valley 1.5.5 - //if (ex is BadImageFormatException && !EnvironmentUtility.Is64BitAssembly(assemblyPath)) - // errorReasonPhrase = "it needs to be updated for 64-bit mode."; + if (ex is BadImageFormatException && !EnvironmentUtility.Is64BitAssembly(assemblyPath)) + errorReasonPhrase = "it needs to be updated for 64-bit mode."; errorDetails = $"Error: {ex.GetLogSummary()}"; failReason = ModFailReason.LoadFailed; diff --git a/src/SMAPI/Metadata/InstructionMetadata.cs b/src/SMAPI/Metadata/InstructionMetadata.cs index 368306a1..232e54ce 100644 --- a/src/SMAPI/Metadata/InstructionMetadata.cs +++ b/src/SMAPI/Metadata/InstructionMetadata.cs @@ -48,7 +48,7 @@ namespace StardewModdingAPI.Metadata // rewrite for Stardew Valley 1.5.5 if (platformChanged) yield return new MethodParentRewriter(typeof(SpriteBatch), typeof(SpriteBatchFacade)); - //yield return new ArchitectureAssemblyRewriter(); + yield return new ArchitectureAssemblyRewriter(); // detect Harmony & rewrite for SMAPI 3.12 (Harmony 1.x => 2.0 update) yield return new HarmonyRewriter(); diff --git a/src/SMAPI/SMAPI.csproj b/src/SMAPI/SMAPI.csproj index e5cc8da6..a04dd1b6 100644 --- a/src/SMAPI/SMAPI.csproj +++ b/src/SMAPI/SMAPI.csproj @@ -3,13 +3,16 @@ StardewModdingAPI StardewModdingAPI The modding API for Stardew Valley. - net452 - x86 + net5.0 + x64 Exe true false true icon.ico + + + true @@ -19,15 +22,16 @@ - + + + - + - -- cgit From 1ab0420b6d2371095756e5049fd28d419bfe31f0 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Mon, 30 Aug 2021 23:42:59 -0400 Subject: update compatibility list --- docs/release-notes.md | 1 + src/SMAPI.Web/wwwroot/SMAPI.metadata.json | 65 +++++++++++++++++++++++++------ 2 files changed, 55 insertions(+), 11 deletions(-) (limited to 'docs') diff --git a/docs/release-notes.md b/docs/release-notes.md index 43370409..d6e22af4 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -4,6 +4,7 @@ ## Upcoming release * For players: * Updated for Stardew Valley 1.5.5. + * Updated compatibility list. * Added `set_farm_type` [console command](https://stardewvalleywiki.com/Modding:Console_commands#Console_commands) to change the current farm type. * For mod authors: diff --git a/src/SMAPI.Web/wwwroot/SMAPI.metadata.json b/src/SMAPI.Web/wwwroot/SMAPI.metadata.json index dcdd6298..bb166017 100644 --- a/src/SMAPI.Web/wwwroot/SMAPI.metadata.json +++ b/src/SMAPI.Web/wwwroot/SMAPI.metadata.json @@ -167,6 +167,60 @@ "~ | StatusReasonPhrase": "split-screen mode was added in Stardew Valley 1.5" }, + /********* + ** Broke in SDV 1.5.5 + *********/ + "Animated Portrait Framework": { + "ID": "akai.AnimatedPortrait", + "~1.0.0 | Status": "AssumeBroken", + "~1.0.0 | StatusReasonDetails": "requires the 'System.Windows.Forms' API, which isn't available in .NET 5" + }, + "Audio Devices": { + "ID": "maxvollmer.audiodevices", + "~3.0.1 | Status": "AssumeBroken", + "~3.0.1 | StatusReasonDetails": "fails to load due to an outdated implementation of the game's 'IAudioEngine' interface" + }, + "Battery Warning": { + "ID": "Husky110.BatteryWarningMod", + "~1.0.4 | Status": "AssumeBroken", + "~1.0.4 | StatusReasonDetails": "requires the 'System.Management' API, which is a different DLL in .NET 5" + }, + "Junimo Studio": { + "ID": "Becks723.JunimoStudio", + "~2.0.1 | Status": "AssumeBroken", + "~2.0.1 | StatusReasonDetails": "requires 'Microsoft.Xna.Framework.Audio.AudioCategory' which doesn't exist in MonoGame" + }, + "Skip Intro": { + "ID": "Pathoschild.SkipIntro", + "~1.9.1 | Status": "AssumeBroken", + "~1.9.1 | StatusReasonDetails": "causes freeze during game launch" + }, + "Stardew Hack": { + "ID": "bcmpinc.StardewHack", + "~5.1.0 | Status": "AssumeBroken", + "~5.1.0 | StatusReasonDetails": "runtime error when initializing due to an API change between .NET Framework and .NET 5" + }, + "Stardew Valley Expanded": { + "ID": "FlashShifter.SVECode", + "~1.13.11 | Status": "AssumeBroken", + "~1.13.11 | StatusReasonDetails": "fails to load due to an outdated implementation of the game's 'ICue' interface" + }, + "Stardew Web": { + "ID": "prism99.stardewweb", + "~0.7.2 | Status": "AssumeBroken", + "~0.7.2 | StatusReasonDetails": "requires the 'System.Drawing' API, which isn't available in .NET 5" + }, + "Sundrop City": { + "ID": "SundropTeam.SundropCity", + "~0.4.1 | Status": "AssumeBroken", + "~0.4.1 | StatusReasonDetails": "causes freeze during game launch" + }, + "Video Player": { + "ID": "aedenthorn.VideoPlayer", + "~0.2.5 | Status": "AssumeBroken", + "~0.2.5 | StatusReasonDetails": "requires an XNA Framework API that's not available in MonoGame and causes a crash to desktop" + }, + /********* ** Broke in SMAPI 3.12.0 *********/ @@ -205,11 +259,6 @@ "~1.9.3 | Status": "AssumeBroken", "~1.9.3 | StatusReasonDetails": "fails to load with 'ReflectionTypeLoadException' error" }, - "Stardew Hack": { - "ID": "bcmpinc.StardewHack", - "~5.0.0 | Status": "AssumeBroken", - "~5.0.0 | StatusReasonDetails": "causes Harmony patching errors for other mods" - }, "Tilled Soil Decay": { "ID": "bcmpinc.TilledSoilDecay", "~4.1.0 | Status": "AssumeBroken", @@ -238,12 +287,6 @@ /********* ** Broke in SDV 1.5 (SMAPI mods) *********/ - "Audio Devices": { - "ID": "maxvollmer.audiodevices", - "~2.0.0 | Status": "AssumeBroken", - "~2.0.0 | StatusReasonDetails": "causes crash to desktop when starting the game" - }, - "ChestEx": { "ID": "berkayylmao.ChestEx", "~1.3.4 | Status": "AssumeBroken", -- cgit From 217cc7af21a501daabea16dc7331401a19706bf4 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 16 Sep 2021 17:34:31 -0400 Subject: add IgnoreModFilePaths option to package --- docs/technical/mod-package.md | 17 +++++++++++- src/SMAPI.ModBuildConfig/DeployModTask.cs | 32 ++++++++++++++++++++-- .../Framework/ModFileManager.cs | 9 ++++-- src/SMAPI.ModBuildConfig/build/smapi.targets | 1 + 4 files changed, 53 insertions(+), 6 deletions(-) (limited to 'docs') diff --git a/docs/technical/mod-package.md b/docs/technical/mod-package.md index a3ce8761..0fdd4c4a 100644 --- a/docs/technical/mod-package.md +++ b/docs/technical/mod-package.md @@ -222,6 +222,20 @@ Whether to configure the project so you can launch or debug the game through the Visual Studio (default `true`). There's usually no reason to change this, unless it's a unit test project. + + + +IgnoreModFilePaths + + +A comma-delimited list of literal file paths to ignore, relative to the mod's `bin` folder. Paths +are case-sensitive, but path delimiters are normalized automatically. For example, this ignores a +set of tilesheets: + +```xml +assets/paths.png, assets/springobjects.png +``` + @@ -366,7 +380,8 @@ when you compile it. ## Release notes ## Upcoming release -* Updated for Stardew Valley 1.5.5 and SMAPI 3.13.0. **The older versions are no longer supported.** +* Updated for Stardew Valley 1.5.5 and SMAPI 3.13.0. **Older versions are no longer supported.** +* Added `IgnoreModFilePaths` option to ignore literal paths. * Improved analyzer performance by enabling parallel execution. ## 3.3.0 diff --git a/src/SMAPI.ModBuildConfig/DeployModTask.cs b/src/SMAPI.ModBuildConfig/DeployModTask.cs index 9ee6be12..0c64aed3 100644 --- a/src/SMAPI.ModBuildConfig/DeployModTask.cs +++ b/src/SMAPI.ModBuildConfig/DeployModTask.cs @@ -8,6 +8,7 @@ using System.Text.RegularExpressions; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; using StardewModdingAPI.ModBuildConfig.Framework; +using StardewModdingAPI.Toolkit.Utilities; namespace StardewModdingAPI.ModBuildConfig { @@ -45,9 +46,12 @@ namespace StardewModdingAPI.ModBuildConfig [Required] public bool EnableModZip { get; set; } - /// Custom comma-separated regex patterns matching files to ignore when deploying or zipping the mod. + /// A comma-separated list of regex patterns matching files to ignore when deploying or zipping the mod. public string IgnoreModFilePatterns { get; set; } + /// A comma-separated list of relative file paths to ignore when deploying or zipping the mod. + public string IgnoreModFilePaths { get; set; } + /********* ** Public methods @@ -70,10 +74,11 @@ namespace StardewModdingAPI.ModBuildConfig try { // parse ignore patterns + string[] ignoreFilePaths = this.GetCustomIgnoreFilePaths().ToArray(); Regex[] ignoreFilePatterns = this.GetCustomIgnorePatterns().ToArray(); // get mod info - ModFileManager package = new ModFileManager(this.ProjectDir, this.TargetDir, ignoreFilePatterns, validateRequiredModFiles: this.EnableModDeploy || this.EnableModZip); + ModFileManager package = new ModFileManager(this.ProjectDir, this.TargetDir, ignoreFilePaths, ignoreFilePatterns, validateRequiredModFiles: this.EnableModDeploy || this.EnableModZip); // deploy mod files if (this.EnableModDeploy) @@ -157,6 +162,29 @@ namespace StardewModdingAPI.ModBuildConfig } } + /// Get the custom relative file paths provided by the user to ignore. + private IEnumerable GetCustomIgnoreFilePaths() + { + if (string.IsNullOrWhiteSpace(this.IgnoreModFilePaths)) + yield break; + + foreach (string raw in this.IgnoreModFilePaths.Split(',')) + { + string path; + try + { + path = PathUtilities.NormalizePath(raw); + } + catch (Exception ex) + { + this.Log.LogWarning($"[mod build package] Ignored invalid <{nameof(this.IgnoreModFilePaths)}> path {raw}:\n{ex}"); + continue; + } + + yield return path; + } + } + /// Copy the mod files into the game's mod folder. /// The files to include. /// The folder path to create with the mod files. diff --git a/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs b/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs index 3d9b206b..fbb91193 100644 --- a/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs +++ b/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs @@ -28,10 +28,11 @@ namespace StardewModdingAPI.ModBuildConfig.Framework /// Construct an instance. /// The folder containing the project files. /// The folder containing the build output. + /// The custom relative file paths provided by the user to ignore. /// Custom regex patterns matching files to ignore when deploying or zipping the mod. /// Whether to validate that required mod files like the manifest are present. /// The mod package isn't valid. - public ModFileManager(string projectDir, string targetDir, Regex[] ignoreFilePatterns, bool validateRequiredModFiles) + public ModFileManager(string projectDir, string targetDir, string[] ignoreFilePaths, Regex[] ignoreFilePatterns, bool validateRequiredModFiles) { this.Files = new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -47,7 +48,7 @@ namespace StardewModdingAPI.ModBuildConfig.Framework string relativePath = entry.Item1; FileInfo file = entry.Item2; - if (!this.ShouldIgnore(file, relativePath, ignoreFilePatterns)) + if (!this.ShouldIgnore(file, relativePath, ignoreFilePaths, ignoreFilePatterns)) this.Files[relativePath] = file; } @@ -149,8 +150,9 @@ namespace StardewModdingAPI.ModBuildConfig.Framework /// Get whether a build output file should be ignored. /// The file to check. /// The file's relative path in the package. + /// The custom relative file paths provided by the user to ignore. /// Custom regex patterns matching files to ignore when deploying or zipping the mod. - private bool ShouldIgnore(FileInfo file, string relativePath, Regex[] ignoreFilePatterns) + private bool ShouldIgnore(FileInfo file, string relativePath, string[] ignoreFilePaths, Regex[] ignoreFilePatterns) { bool IsAssemblyFile(string baseName) { @@ -181,6 +183,7 @@ namespace StardewModdingAPI.ModBuildConfig.Framework || this.EqualsInvariant(file.Name, "Thumbs.db") // custom ignore patterns + || ignoreFilePaths.Any(p => p == relativePath) || ignoreFilePatterns.Any(p => p.IsMatch(relativePath)); } diff --git a/src/SMAPI.ModBuildConfig/build/smapi.targets b/src/SMAPI.ModBuildConfig/build/smapi.targets index 74ac56e6..b254dd7c 100644 --- a/src/SMAPI.ModBuildConfig/build/smapi.targets +++ b/src/SMAPI.ModBuildConfig/build/smapi.targets @@ -94,6 +94,7 @@ TargetDir="$(TargetDir)" GameModsDir="$(GameModsPath)" IgnoreModFilePatterns="$(IgnoreModFilePatterns)" + IgnoreModFilePaths="$(IgnoreModFilePaths)" /> -- cgit From 4a26c96fbe600a4a229a1e63abb716a62dc7f450 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 16 Sep 2021 18:48:59 -0400 Subject: remove GameExecutableName build property from package --- build/find-game-folder.targets | 5 ----- docs/technical/mod-package.md | 24 +++++++++++----------- src/SMAPI.ModBuildConfig/build/smapi.targets | 4 ++-- .../SMAPI.Mods.ConsoleCommands.csproj | 2 +- .../SMAPI.Mods.ErrorHandler.csproj | 2 +- .../SMAPI.Mods.SaveBackup.csproj | 2 +- src/SMAPI.Tests/SMAPI.Tests.csproj | 5 +---- src/SMAPI/SMAPI.csproj | 2 +- 8 files changed, 19 insertions(+), 27 deletions(-) (limited to 'docs') diff --git a/build/find-game-folder.targets b/build/find-game-folder.targets index 3341226d..3164b071 100644 --- a/build/find-game-folder.targets +++ b/build/find-game-folder.targets @@ -41,9 +41,4 @@ - - - - Stardew Valley - diff --git a/docs/technical/mod-package.md b/docs/technical/mod-package.md index 0fdd4c4a..5eff3d2e 100644 --- a/docs/technical/mod-package.md +++ b/docs/technical/mod-package.md @@ -29,7 +29,7 @@ change how these work): * **Detect game path:** The package automatically finds your game folder by scanning the default install paths and Windows registry. It adds two MSBuild properties for use in your `.csproj` file if needed: - `$(GamePath)` and `$(GameExecutableName)`. + `$(GamePath)` and `$(GameModsPath)`. * **Add assembly references:** The package adds assembly references to SMAPI, Stardew Valley, xTile, and the game framework @@ -126,15 +126,6 @@ change it. The absolute path to the folder containing the game's installed mods (defaults to `$(GamePath)/Mods`), used when deploying the mod files. - - - -GameExecutableName - - -The filename for the game's executable (i.e. `StardewValley.exe` on Linux/macOS or -`Stardew Valley.exe` on Windows). This is auto-detected, and you should almost never change this. - @@ -382,13 +373,21 @@ when you compile it. ## Upcoming release * Updated for Stardew Valley 1.5.5 and SMAPI 3.13.0. **Older versions are no longer supported.** * Added `IgnoreModFilePaths` option to ignore literal paths. +* Removed the `GameExecutableName` build property (since it now has the same value on all platforms). * Improved analyzer performance by enabling parallel execution. +**Migration guide for mod authors:** +1. See [_migrate to 64-bit_](https://stardewvalleywiki.com/Modding:Migrate_to_64-bit_on_Windows) and + [_migrate to Stardew Valley 1.5.5_](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5). +2. Possible changes in your `.csproj` or `.targets` files: + * If you use `$(GameExecutableName)`, replace it with `Stardew Valley`. + ## 3.3.0 Released 30 March 2021. * Added a build warning when the mod isn't compiled for `Any CPU`. -* Added a `GameFramework` build property set to `MonoGame` or `Xna` based on the platform. This can be overridden to change which framework it references. +* Added a `GameFramework` build property set to `MonoGame` or `Xna` based on the platform. This can + be overridden to change which framework it references. * Added support for building mods against the 64-bit Linux version of the game on Windows. * The package now suppresses the misleading 'processor architecture mismatch' warnings. @@ -396,7 +395,8 @@ Released 30 March 2021. Released 23 September 2020. * Reworked and streamlined how the package is compiled. -* Added [SMAPI-ModTranslationClassBuilder](https://github.com/Pathoschild/SMAPI-ModTranslationClassBuilder) files to the ignore list. +* Added [SMAPI-ModTranslationClassBuilder](https://github.com/Pathoschild/SMAPI-ModTranslationClassBuilder) + files to the ignore list. ### 3.2.1 Released 11 September 2020. diff --git a/src/SMAPI.ModBuildConfig/build/smapi.targets b/src/SMAPI.ModBuildConfig/build/smapi.targets index b254dd7c..6fc62046 100644 --- a/src/SMAPI.ModBuildConfig/build/smapi.targets +++ b/src/SMAPI.ModBuildConfig/build/smapi.targets @@ -48,7 +48,7 @@ **********************************************--> - + @@ -71,7 +71,7 @@ - + diff --git a/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj b/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj index 65d54599..52439c41 100644 --- a/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj +++ b/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj @@ -13,8 +13,8 @@ - + diff --git a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj index 2ad19df7..78cdb315 100644 --- a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj +++ b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj @@ -14,8 +14,8 @@ - + diff --git a/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj b/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj index f8908c7d..a8b0dfdb 100644 --- a/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj +++ b/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/SMAPI.Tests/SMAPI.Tests.csproj b/src/SMAPI.Tests/SMAPI.Tests.csproj index e19105ff..8329b2e1 100644 --- a/src/SMAPI.Tests/SMAPI.Tests.csproj +++ b/src/SMAPI.Tests/SMAPI.Tests.csproj @@ -23,10 +23,7 @@ - - $(GamePath)\$(GameExecutableName).dll - True - + diff --git a/src/SMAPI/SMAPI.csproj b/src/SMAPI/SMAPI.csproj index 16ddb92a..4f9aa9b1 100644 --- a/src/SMAPI/SMAPI.csproj +++ b/src/SMAPI/SMAPI.csproj @@ -29,7 +29,7 @@ - + -- cgit From bf10aeef0afae20e1d79f0772ba41a38fcb572ae Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 16 Sep 2021 18:59:25 -0400 Subject: remove GameFramework build property from package --- docs/technical/mod-package.md | 20 +++++++------------- src/SMAPI.ModBuildConfig/build/smapi.targets | 3 --- src/SMAPI/Constants.cs | 3 +-- src/SMAPI/Framework/ModLoading/AssemblyLoader.cs | 5 ++--- src/SMAPI/Framework/SCore.cs | 2 +- 5 files changed, 11 insertions(+), 22 deletions(-) (limited to 'docs') diff --git a/docs/technical/mod-package.md b/docs/technical/mod-package.md index 5eff3d2e..2e26275b 100644 --- a/docs/technical/mod-package.md +++ b/docs/technical/mod-package.md @@ -32,10 +32,10 @@ change how these work): `$(GamePath)` and `$(GameModsPath)`. * **Add assembly references:** - The package adds assembly references to SMAPI, Stardew Valley, xTile, and the game framework - (MonoGame on Linux/macOS, XNA Framework on Windows). It automatically adjusts depending on which OS - you're compiling it on. If you use [Harmony](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Harmony), - it can optionally add a reference to that too. + The package adds assembly references to MonoGame, SMAPI, Stardew Valley, and xTile. It + automatically adjusts depending on which OS you're compiling it on. If you use + [Harmony](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Harmony), it can optionally add + a reference to that too. * **Copy files into the `Mods` folder:** The package automatically copies your mod's DLL and PDB files, `manifest.json`, [`i18n` @@ -129,14 +129,6 @@ The absolute path to the folder containing the game's installed mods (defaults t -GameFramework - - -The game framework for which the mod is being compiled (one of `Xna` or `MonoGame`). This is -auto-detected based on the platform, and you should almost never change this. - - - @@ -373,7 +365,8 @@ when you compile it. ## Upcoming release * Updated for Stardew Valley 1.5.5 and SMAPI 3.13.0. **Older versions are no longer supported.** * Added `IgnoreModFilePaths` option to ignore literal paths. -* Removed the `GameExecutableName` build property (since it now has the same value on all platforms). +* Removed the `GameExecutableName` and `GameFramework` build properties (since they now have the + same value on all platforms). * Improved analyzer performance by enabling parallel execution. **Migration guide for mod authors:** @@ -381,6 +374,7 @@ when you compile it. [_migrate to Stardew Valley 1.5.5_](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5). 2. Possible changes in your `.csproj` or `.targets` files: * If you use `$(GameExecutableName)`, replace it with `Stardew Valley`. + * If you use `$(GameFramework)`, replace it with `MonoGame` and remove any XNA-specific logic. ## 3.3.0 Released 30 March 2021. diff --git a/src/SMAPI.ModBuildConfig/build/smapi.targets b/src/SMAPI.ModBuildConfig/build/smapi.targets index 6fc62046..8ad298d0 100644 --- a/src/SMAPI.ModBuildConfig/build/smapi.targets +++ b/src/SMAPI.ModBuildConfig/build/smapi.targets @@ -30,9 +30,6 @@ false true false - - Xna - MonoGame diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index 2c16052b..3ae8661a 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -241,8 +241,7 @@ namespace StardewModdingAPI /// Get metadata for mapping assemblies to the current platform. /// The target game platform. - /// The game framework running the game. - internal static PlatformAssemblyMap GetAssemblyMap(Platform targetPlatform, GameFramework framework) + internal static PlatformAssemblyMap GetAssemblyMap(Platform targetPlatform) { var removeAssemblyReferences = new List(); var targetAssemblies = new List(); diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs index 57a76a35..cb5fa2ae 100644 --- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs +++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs @@ -53,16 +53,15 @@ namespace StardewModdingAPI.Framework.ModLoading *********/ /// Construct an instance. /// The current game platform. - /// The game framework running the game. /// Encapsulates monitoring and logging. /// Whether to detect paranoid mode issues. /// Whether to rewrite mods for compatibility. - public AssemblyLoader(Platform targetPlatform, GameFramework framework, IMonitor monitor, bool paranoidMode, bool rewriteMods) + public AssemblyLoader(Platform targetPlatform, IMonitor monitor, bool paranoidMode, bool rewriteMods) { this.Monitor = monitor; this.ParanoidMode = paranoidMode; this.RewriteMods = rewriteMods; - this.AssemblyMap = this.TrackForDisposal(Constants.GetAssemblyMap(targetPlatform, framework)); + this.AssemblyMap = this.TrackForDisposal(Constants.GetAssemblyMap(targetPlatform)); // init resolver this.AssemblyDefinitionResolver = this.TrackForDisposal(new AssemblyDefinitionResolver()); diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index a0467daa..55a7f083 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -1473,7 +1473,7 @@ namespace StardewModdingAPI.Framework // load mods IList skippedMods = new List(); - using (AssemblyLoader modAssemblyLoader = new AssemblyLoader(Constants.Platform, Constants.GameFramework, this.Monitor, this.Settings.ParanoidWarnings, this.Settings.RewriteMods)) + using (AssemblyLoader modAssemblyLoader = new AssemblyLoader(Constants.Platform, this.Monitor, this.Settings.ParanoidWarnings, this.Settings.RewriteMods)) { // init HashSet suppressUpdateChecks = new HashSet(this.Settings.SuppressUpdateChecks, StringComparer.OrdinalIgnoreCase); -- cgit From f5807e22be157d908e3b8c65f19acaa16c3588e7 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 16 Sep 2021 22:47:05 -0400 Subject: add BundleExtraAssemblies package option for new .NET 5 reference model --- docs/technical/mod-package.md | 100 +++++++++++++---- src/SMAPI.ModBuildConfig/DeployModTask.cs | 34 +++++- .../Framework/ExtraAssemblyType.cs | 21 ++++ .../Framework/ModFileManager.cs | 124 ++++++++++++++++----- src/SMAPI.ModBuildConfig/build/smapi.targets | 22 ++-- 5 files changed, 244 insertions(+), 57 deletions(-) create mode 100644 src/SMAPI.ModBuildConfig/Framework/ExtraAssemblyType.cs (limited to 'docs') diff --git a/docs/technical/mod-package.md b/docs/technical/mod-package.md index 2e26275b..93e0009d 100644 --- a/docs/technical/mod-package.md +++ b/docs/technical/mod-package.md @@ -39,10 +39,9 @@ change how these work): * **Copy files into the `Mods` folder:** The package automatically copies your mod's DLL and PDB files, `manifest.json`, [`i18n` - files](https://stardewvalleywiki.com/Modding:Translations) (if any), the `assets` folder (if - any), and [build output](https://stackoverflow.com/a/10828462/262123) into your game's `Mods` - folder when you rebuild the code, with a subfolder matching the mod's project name. That lets you - try the mod in-game right after building it. + files](https://stardewvalleywiki.com/Modding:Translations) (if any), and the `assets` folder (if + any) into the `Mods` folder when you rebuild the code, with a subfolder matching the mod's project + name. That lets you try the mod in-game right after building it. * **Create release zip:** The package adds a zip file in your project's `bin` folder when you rebuild the code, in the @@ -189,11 +188,63 @@ The folder path where the release zip is created (defaults to the project's `bin effect -CopyModReferencesToBuildOutput +BundleExtraAssemblies -Whether to copy game and framework DLLs into the mod folder (default `false`). This is useful for -unit test projects, but not needed for mods that'll be run through SMAPI. +**Most mods should not change this option.** + +By default (when this is _not_ enabled), only the mod files [normally considered part of the +mod](#Features) will be added to the release `.zip` and copied into the `Mods` folder (i.e. +"deployed"). That includes the assembly files (`*.dll`, `*.pdb`, and `*.xml`) for your mod project, +but any other DLLs won't be deployed. + +Enabling this option will add _all_ dependencies to the build output, then deploy _some_ of them +depending on the comma-separated value(s) you set: + + + + + + + + + + + + + + + + + + + + + + +
optionresult
ThirdParty + +Assembly files which don't match any other category. + +
System + +Assembly files whose names start with `Microsoft.*` or `System.*`. + +
Game + +Assembly files which are part of MonoGame, SMAPI, or Stardew Valley. + +
All + +Equivalent to `System, Game, ThirdParty`. + +
+ +Most mods should omit the option. Some mods may need `ThirdParty` if they bundle third-party DLLs +with their mod. The other options are mainly useful for unit tests. + +When enabling this option, you should **manually review which files get deployed** and use the +`IgnoreModFilePaths` or `IgnoreModFilePatterns` options to exclude files as needed. @@ -327,16 +378,15 @@ The configuration will check your custom path first, then fall back to the defau still compile on a different computer). ### How do I change which files are included in the mod deploy/zip? -For custom files, you can [add/remove them in the build output](https://stackoverflow.com/a/10828462/262123). -(If your project references another mod, make sure the reference is [_not_ marked 'copy -local'](https://msdn.microsoft.com/en-us/library/t1zz5y8c(v=vs.100).aspx).) - -To exclude a file the package copies by default, see `IgnoreModFilePatterns` under -[_configure_](#configure). +* For normal files, you can [add/remove them in the build output](https://stackoverflow.com/a/10828462/262123). +* For assembly files (`*.dll`, `*.exe`, `*.pdb`, or `*.xml`), see the + [`BundleExtraAssemblies` option](#configure). +* To exclude a file which the package copies by default, see the [`IgnoreModFilePaths` or + `IgnoreModFilePatterns` options](#configure). ### Can I use the package for non-mod projects? -You can use the package in non-mod projects too (e.g. unit tests or framework DLLs). Just disable -the mod-related package features (see [_configure_](#configure)): +Yep, this works in unit tests and framework projects too. Just disable the mod-related package +features (see [_configure_](#configure)): ```xml false @@ -344,9 +394,9 @@ the mod-related package features (see [_configure_](#configure)): false ``` -If you need to copy the referenced DLLs into your build output, add this too: +To copy referenced DLLs into your build output for unit tests, add this too: ```xml -true +All ``` ## For SMAPI developers @@ -363,18 +413,24 @@ when you compile it. ## Release notes ## Upcoming release -* Updated for Stardew Valley 1.5.5 and SMAPI 3.13.0. **Older versions are no longer supported.** +* Updated for Stardew Valley 1.5.5 and SMAPI 3.13.0. (Older versions are no longer supported.) * Added `IgnoreModFilePaths` option to ignore literal paths. -* Removed the `GameExecutableName` and `GameFramework` build properties (since they now have the - same value on all platforms). +* Added `BundleExtraAssemblies` option to copy bundled DLLs into the mod zip/folder. +* Removed the `GameExecutableName` and `GameFramework` options (since they now have the same value + on all platforms). +* Removed the `CopyModReferencesToBuildOutput` option (superseded by `BundleExtraAssemblies`). * Improved analyzer performance by enabling parallel execution. **Migration guide for mod authors:** 1. See [_migrate to 64-bit_](https://stardewvalleywiki.com/Modding:Migrate_to_64-bit_on_Windows) and [_migrate to Stardew Valley 1.5.5_](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5). 2. Possible changes in your `.csproj` or `.targets` files: - * If you use `$(GameExecutableName)`, replace it with `Stardew Valley`. - * If you use `$(GameFramework)`, replace it with `MonoGame` and remove any XNA-specific logic. + * Replace `$(GameExecutableName)` with `Stardew Valley`. + * Replace `$(GameFramework)` with `MonoGame` and remove any XNA Framework-specific logic. + * Replace `true` with + `Game`. + * If you need to bundle extra DLLs besides your mod DLL, see the [`BundleExtraAssemblies` + documentation](#configure). ## 3.3.0 Released 30 March 2021. diff --git a/src/SMAPI.ModBuildConfig/DeployModTask.cs b/src/SMAPI.ModBuildConfig/DeployModTask.cs index 0c64aed3..140933bd 100644 --- a/src/SMAPI.ModBuildConfig/DeployModTask.cs +++ b/src/SMAPI.ModBuildConfig/DeployModTask.cs @@ -18,6 +18,10 @@ namespace StardewModdingAPI.ModBuildConfig /********* ** Accessors *********/ + /// The name (without extension or path) of the current mod's DLL. + [Required] + public string ModDllName { get; set; } + /// The name of the mod folder. [Required] public string ModFolderName { get; set; } @@ -52,6 +56,9 @@ namespace StardewModdingAPI.ModBuildConfig /// A comma-separated list of relative file paths to ignore when deploying or zipping the mod. public string IgnoreModFilePaths { get; set; } + /// A comma-separated list of values which indicate which extra DLLs to bundle. + public string BundleExtraAssemblies { get; set; } + /********* ** Public methods @@ -73,12 +80,15 @@ namespace StardewModdingAPI.ModBuildConfig try { + // parse extra DLLs to bundle + ExtraAssemblyTypes bundleAssemblyTypes = this.GetExtraAssembliesToBundleOption(); + // parse ignore patterns string[] ignoreFilePaths = this.GetCustomIgnoreFilePaths().ToArray(); Regex[] ignoreFilePatterns = this.GetCustomIgnorePatterns().ToArray(); // get mod info - ModFileManager package = new ModFileManager(this.ProjectDir, this.TargetDir, ignoreFilePaths, ignoreFilePatterns, validateRequiredModFiles: this.EnableModDeploy || this.EnableModZip); + ModFileManager package = new ModFileManager(this.ProjectDir, this.TargetDir, ignoreFilePaths, ignoreFilePatterns, bundleAssemblyTypes, this.ModDllName, validateRequiredModFiles: this.EnableModDeploy || this.EnableModZip); // deploy mod files if (this.EnableModDeploy) @@ -139,6 +149,28 @@ namespace StardewModdingAPI.ModBuildConfig } } + /// Parse the extra assembly types which should be bundled with the mod. + private ExtraAssemblyTypes GetExtraAssembliesToBundleOption() + { + ExtraAssemblyTypes flags = ExtraAssemblyTypes.None; + + if (!string.IsNullOrWhiteSpace(this.BundleExtraAssemblies)) + { + foreach (string raw in this.BundleExtraAssemblies.Split(',')) + { + if (!Enum.TryParse(raw, out ExtraAssemblyTypes type)) + { + this.Log.LogWarning($"[mod build package] Ignored invalid <{nameof(this.BundleExtraAssemblies)}> value '{raw}', expected one of '{string.Join("', '", Enum.GetNames(typeof(ExtraAssemblyTypes)))}'."); + continue; + } + + flags |= type; + } + } + + return flags; + } + /// Get the custom ignore patterns provided by the user. private IEnumerable GetCustomIgnorePatterns() { diff --git a/src/SMAPI.ModBuildConfig/Framework/ExtraAssemblyType.cs b/src/SMAPI.ModBuildConfig/Framework/ExtraAssemblyType.cs new file mode 100644 index 00000000..571bf7c7 --- /dev/null +++ b/src/SMAPI.ModBuildConfig/Framework/ExtraAssemblyType.cs @@ -0,0 +1,21 @@ +using System; + +namespace StardewModdingAPI.ModBuildConfig.Framework +{ + /// An extra assembly type for the field. + [Flags] + internal enum ExtraAssemblyTypes + { + /// Don't include extra assemblies. + None = 0, + + /// Assembly files which are part of MonoGame, SMAPI, or Stardew Valley. + Game = 1, + + /// Assembly files whose names start with Microsoft.* or System.*. + System = 2, + + /// Assembly files which don't match any other category. + ThirdParty = 4 + } +} diff --git a/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs b/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs index fbb91193..ad4ffdf9 100644 --- a/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs +++ b/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs @@ -21,6 +21,45 @@ namespace StardewModdingAPI.ModBuildConfig.Framework /// The files that are part of the package. private readonly IDictionary Files; + /// The file extensions used by assembly files. + private readonly ISet AssemblyFileExtensions = new HashSet(StringComparer.OrdinalIgnoreCase) + { + ".dll", + ".exe", + ".pdb", + ".xml" + }; + + /// The DLLs which match the type. + private readonly ISet GameDllNames = new HashSet + { + // SMAPI + "0Harmony", + "Mono.Cecil", + "Mono.Cecil.Mdb", + "Mono.Cecil.Pdb", + "MonoMod.Common", + "Newtonsoft.Json", + "StardewModdingAPI", + "SMAPI.Toolkit", + "SMAPI.Toolkit.CoreInterfaces", + "TMXTile", + + // game + framework + "BmFont", + "FAudio-CS", + "GalaxyCSharp", + "GalaxyCSharpGlue", + "Lidgren.Network", + "MonoGame.Framework", + "SkiaSharp", + "Stardew Valley", + "StardewValley.GameData", + "Steamworks.NET", + "TextCopy", + "xTile" + }; + /********* ** Public methods @@ -30,9 +69,11 @@ namespace StardewModdingAPI.ModBuildConfig.Framework /// The folder containing the build output. /// The custom relative file paths provided by the user to ignore. /// Custom regex patterns matching files to ignore when deploying or zipping the mod. + /// The extra assembly types which should be bundled with the mod. + /// The name (without extension or path) for the current mod's DLL. /// Whether to validate that required mod files like the manifest are present. /// The mod package isn't valid. - public ModFileManager(string projectDir, string targetDir, string[] ignoreFilePaths, Regex[] ignoreFilePatterns, bool validateRequiredModFiles) + public ModFileManager(string projectDir, string targetDir, string[] ignoreFilePaths, Regex[] ignoreFilePatterns, ExtraAssemblyTypes bundleAssemblyTypes, string modDllName, bool validateRequiredModFiles) { this.Files = new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -48,7 +89,7 @@ namespace StardewModdingAPI.ModBuildConfig.Framework string relativePath = entry.Item1; FileInfo file = entry.Item2; - if (!this.ShouldIgnore(file, relativePath, ignoreFilePaths, ignoreFilePatterns)) + if (!this.ShouldIgnore(file, relativePath, ignoreFilePaths, ignoreFilePatterns, bundleAssemblyTypes, modDllName)) this.Files[relativePath] = file; } @@ -152,39 +193,70 @@ namespace StardewModdingAPI.ModBuildConfig.Framework /// The file's relative path in the package. /// The custom relative file paths provided by the user to ignore. /// Custom regex patterns matching files to ignore when deploying or zipping the mod. - private bool ShouldIgnore(FileInfo file, string relativePath, string[] ignoreFilePaths, Regex[] ignoreFilePatterns) + /// The extra assembly types which should be bundled with the mod. + /// The name (without extension or path) for the current mod's DLL. + private bool ShouldIgnore(FileInfo file, string relativePath, string[] ignoreFilePaths, Regex[] ignoreFilePatterns, ExtraAssemblyTypes bundleAssemblyTypes, string modDllName) { - bool IsAssemblyFile(string baseName) + // apply custom patterns + if (ignoreFilePaths.Any(p => p == relativePath) || ignoreFilePatterns.Any(p => p.IsMatch(relativePath))) + return true; + + // ignore unneeded files + { + bool shouldIgnore = + // release zips + this.EqualsInvariant(file.Extension, ".zip") + + // *.deps.json (only SMAPI's top-level one is used) + || file.Name.EndsWith(".deps.json") + + // code analysis files + || file.Name.EndsWith(".CodeAnalysisLog.xml", StringComparison.OrdinalIgnoreCase) + || file.Name.EndsWith(".lastcodeanalysissucceeded", StringComparison.OrdinalIgnoreCase) + + // translation class builder (not used at runtime) + || ( + file.Name.StartsWith("Pathoschild.Stardew.ModTranslationClassBuilder") + && this.AssemblyFileExtensions.Contains(file.Extension) + ) + + // OS metadata files + || this.EqualsInvariant(file.Name, ".DS_Store") + || this.EqualsInvariant(file.Name, "Thumbs.db"); + if (shouldIgnore) + return true; + } + + // check for bundled assembly types + // When bundleAssemblyTypes is set, *all* dependencies are copied into the build output but only those which match the given assembly types should be bundled. + if (bundleAssemblyTypes != ExtraAssemblyTypes.None) { - return - this.EqualsInvariant(file.Name, $"{baseName}.dll") - || this.EqualsInvariant(file.Name, $"{baseName}.pdb") - || this.EqualsInvariant(file.Name, $"{baseName}.xnb"); + var type = this.GetExtraAssemblyType(file, modDllName); + if (type != ExtraAssemblyTypes.None && !bundleAssemblyTypes.HasFlag(type)) + return true; } - return - // release zips - this.EqualsInvariant(file.Extension, ".zip") + return false; + } - // unneeded *.deps.json (only SMAPI's top-level one is used) - || file.Name.EndsWith(".deps.json") + /// Get the extra assembly type for a file, assuming that the user specified one or more extra types to bundle. + /// The file to check. + /// The name (without extension or path) for the current mod's DLL. + private ExtraAssemblyTypes GetExtraAssemblyType(FileInfo file, string modDllName) + { + string baseName = Path.GetFileNameWithoutExtension(file.Name); + string extension = file.Extension; - // dependencies bundled with SMAPI - || IsAssemblyFile("0Harmony") - || IsAssemblyFile("Newtonsoft.Json") - || IsAssemblyFile("Pathoschild.Stardew.ModTranslationClassBuilder") // not used at runtime + if (baseName == modDllName || !this.AssemblyFileExtensions.Contains(extension)) + return ExtraAssemblyTypes.None; - // code analysis files - || file.Name.EndsWith(".CodeAnalysisLog.xml", StringComparison.OrdinalIgnoreCase) - || file.Name.EndsWith(".lastcodeanalysissucceeded", StringComparison.OrdinalIgnoreCase) + if (this.GameDllNames.Contains(baseName)) + return ExtraAssemblyTypes.Game; - // OS metadata files - || this.EqualsInvariant(file.Name, ".DS_Store") - || this.EqualsInvariant(file.Name, "Thumbs.db") + if (baseName.StartsWith("System.", StringComparison.OrdinalIgnoreCase) || baseName.StartsWith("Microsoft.", StringComparison.OrdinalIgnoreCase)) + return ExtraAssemblyTypes.System; - // custom ignore patterns - || ignoreFilePaths.Any(p => p == relativePath) - || ignoreFilePatterns.Any(p => p.IsMatch(relativePath)); + return ExtraAssemblyTypes.ThirdParty; } /// Get whether a string is equal to another case-insensitively. diff --git a/src/SMAPI.ModBuildConfig/build/smapi.targets b/src/SMAPI.ModBuildConfig/build/smapi.targets index 8ad298d0..de00cbe8 100644 --- a/src/SMAPI.ModBuildConfig/build/smapi.targets +++ b/src/SMAPI.ModBuildConfig/build/smapi.targets @@ -29,7 +29,10 @@ true false true - false + + + + true
@@ -45,17 +48,17 @@ **********************************************--> - - - - + + + + - - + + - + @@ -81,6 +84,7 @@ **********************************************--> -- cgit From cb378a1c558dc2c5de9f2ab1ae9ba38b17d2ac7c Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 23 Sep 2021 23:25:51 -0400 Subject: keep installer window open if it crashes --- docs/release-notes.md | 1 + src/SMAPI.Installer/assets/windows-install.bat | 9 +++++++++ 2 files changed, 10 insertions(+) (limited to 'docs') diff --git a/docs/release-notes.md b/docs/release-notes.md index d6e22af4..f8c1b495 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -6,6 +6,7 @@ * Updated for Stardew Valley 1.5.5. * Updated compatibility list. * Added `set_farm_type` [console command](https://stardewvalleywiki.com/Modding:Console_commands#Console_commands) to change the current farm type. + * Fixed installer window closing immediately if the installer crashed. * For mod authors: * Migrated to 64-bit MonoGame and .NET 5 on all platforms (see [migration guide for mod authors](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5)). diff --git a/src/SMAPI.Installer/assets/windows-install.bat b/src/SMAPI.Installer/assets/windows-install.bat index cb96fc19..2e0be906 100644 --- a/src/SMAPI.Installer/assets/windows-install.bat +++ b/src/SMAPI.Installer/assets/windows-install.bat @@ -38,3 +38,12 @@ if not exist "%installerDir%internal\windows\SMAPI.Installer.dll" ( REM start installer dotnet internal\windows\SMAPI.Installer.dll + +REM keep window open if it failed +if %ERRORLEVEL% NEQ 0 ( + echo. + echo Oops! The SMAPI installer seems to have failed. The error details may be shown above. + echo. + pause + exit +) -- cgit From fe675540b5c3a48764e70c596132a3ed65a790fb Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 25 Sep 2021 01:28:15 -0400 Subject: add map overlay patches --- docs/release-notes.md | 1 + src/SMAPI/Framework/Content/AssetDataForMap.cs | 90 ++++++++++++++++---------- src/SMAPI/IAssetDataForMap.cs | 3 +- src/SMAPI/PatchMapMode.cs | 15 +++++ 4 files changed, 73 insertions(+), 36 deletions(-) create mode 100644 src/SMAPI/PatchMapMode.cs (limited to 'docs') diff --git a/docs/release-notes.md b/docs/release-notes.md index f8c1b495..69eab3ec 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -10,6 +10,7 @@ * For mod authors: * Migrated to 64-bit MonoGame and .NET 5 on all platforms (see [migration guide for mod authors](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5)). + * Added support for [map overlays via `asset.AsMap().PatchMap`](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Content#Edit_a_map). **Update note for players with older systems:** The game now has two branches: the _main branch_ which you'll get by default, and an optional diff --git a/src/SMAPI/Framework/Content/AssetDataForMap.cs b/src/SMAPI/Framework/Content/AssetDataForMap.cs index 4f810948..0a5fa7e7 100644 --- a/src/SMAPI/Framework/Content/AssetDataForMap.cs +++ b/src/SMAPI/Framework/Content/AssetDataForMap.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using StardewModdingAPI.Toolkit.Utilities; +using StardewValley; using xTile; using xTile.Layers; using xTile.Tiles; @@ -25,18 +26,17 @@ namespace StardewModdingAPI.Framework.Content : base(locale, assetName, data, getNormalizedPath, onDataReplaced) { } /// - /// Derived from with a few changes: + /// Derived from with a few changes: /// - can be applied directly to the maps when loading, before the location is created; - /// - added support for source/target areas; + /// - added support for patch modes (overlay, replace by layer, or fully replace); /// - added disambiguation if source has a modified version of the same tilesheet, instead of copying tiles into the target tilesheet; - /// - changed to always overwrite tiles within the target area (to avoid edge cases where some tiles are only partly applied); /// - fixed copying tilesheets (avoid "The specified TileSheet was not created for use with this map" error); /// - fixed tilesheets not added at the end (via z_ prefix), which can cause crashes in game code which depends on hardcoded tilesheet indexes; /// - fixed issue where different tilesheets are linked by ID. /// - public void PatchMap(Map source, Rectangle? sourceArea = null, Rectangle? targetArea = null) + public void PatchMap(Map source, Rectangle? sourceArea = null, Rectangle? targetArea = null, PatchMapMode patchMode = PatchMapMode.Overlay) { - var target = this.Data; + Map target = this.Data; // get areas { @@ -84,10 +84,13 @@ namespace StardewModdingAPI.Framework.Content tilesheetMap[sourceSheet] = targetSheet; } - // get layer map - IDictionary layerMap = source.Layers.ToDictionary(p => p, p => target.GetLayer(p.Id)); + // get target layers + IDictionary sourceToTargetLayers = source.Layers.ToDictionary(p => p, p => target.GetLayer(p.Id)); + HashSet orphanedTargetLayers = new HashSet(target.Layers.Except(sourceToTargetLayers.Values)); // apply tiles + bool replaceAll = patchMode == PatchMapMode.Replace; + bool replaceByLayer = patchMode == PatchMapMode.ReplaceByLayer; for (int x = 0; x < sourceArea.Value.Width; x++) { for (int y = 0; y < sourceArea.Value.Height; y++) @@ -96,47 +99,37 @@ namespace StardewModdingAPI.Framework.Content Point sourcePos = new Point(sourceArea.Value.X + x, sourceArea.Value.Y + y); Point targetPos = new Point(targetArea.Value.X + x, targetArea.Value.Y + y); + // replace tiles on target-only layers + if (replaceAll) + { + foreach (Layer targetLayer in orphanedTargetLayers) + targetLayer.Tiles[targetPos.X, targetPos.Y] = null; + } + // merge layers foreach (Layer sourceLayer in source.Layers) { // get layer - Layer targetLayer = layerMap[sourceLayer]; + Layer targetLayer = sourceToTargetLayers[sourceLayer]; if (targetLayer == null) { target.AddLayer(targetLayer = new Layer(sourceLayer.Id, target, target.Layers[0].LayerSize, Layer.m_tileSize)); - layerMap[sourceLayer] = target.GetLayer(sourceLayer.Id); + sourceToTargetLayers[sourceLayer] = target.GetLayer(sourceLayer.Id); } // copy layer properties targetLayer.Properties.CopyFrom(sourceLayer.Properties); - // copy tiles + // create new tile Tile sourceTile = sourceLayer.Tiles[sourcePos.X, sourcePos.Y]; - Tile targetTile; - switch (sourceTile) - { - case StaticTile _: - targetTile = new StaticTile(targetLayer, tilesheetMap[sourceTile.TileSheet], sourceTile.BlendMode, sourceTile.TileIndex); - break; - - case AnimatedTile animatedTile: - { - StaticTile[] tileFrames = new StaticTile[animatedTile.TileFrames.Length]; - for (int frame = 0; frame < animatedTile.TileFrames.Length; ++frame) - { - StaticTile frameTile = animatedTile.TileFrames[frame]; - tileFrames[frame] = new StaticTile(targetLayer, tilesheetMap[frameTile.TileSheet], frameTile.BlendMode, frameTile.TileIndex); - } - targetTile = new AnimatedTile(targetLayer, tileFrames, animatedTile.FrameInterval); - } - break; - - default: // null or unhandled type - targetTile = null; - break; - } - targetTile?.Properties.CopyFrom(sourceTile.Properties); - targetLayer.Tiles[targetPos.X, targetPos.Y] = targetTile; + Tile newTile = sourceTile != null + ? this.CreateTile(sourceTile, targetLayer, tilesheetMap[sourceTile.TileSheet]) + : null; + newTile?.Properties.CopyFrom(sourceTile.Properties); + + // replace tile + if (newTile != null || replaceByLayer || replaceAll) + targetLayer.Tiles[targetPos.X, targetPos.Y] = newTile; } } } @@ -146,6 +139,33 @@ namespace StardewModdingAPI.Framework.Content /********* ** Private methods *********/ + /// Create a new tile for the target map. + /// The source tile to copy. + /// The target layer. + /// The target tilesheet. + private Tile CreateTile(Tile sourceTile, Layer targetLayer, TileSheet targetSheet) + { + switch (sourceTile) + { + case StaticTile _: + return new StaticTile(targetLayer, targetSheet, sourceTile.BlendMode, sourceTile.TileIndex); + + case AnimatedTile animatedTile: + { + StaticTile[] tileFrames = new StaticTile[animatedTile.TileFrames.Length]; + for (int frame = 0; frame < animatedTile.TileFrames.Length; ++frame) + { + StaticTile frameTile = animatedTile.TileFrames[frame]; + tileFrames[frame] = new StaticTile(targetLayer, targetSheet, frameTile.BlendMode, frameTile.TileIndex); + } + + return new AnimatedTile(targetLayer, tileFrames, animatedTile.FrameInterval); + } + + default: // null or unhandled type + return null; + } + } /// Normalize a map tilesheet path for comparison. This value should *not* be used as the actual tilesheet path. /// The path to normalize. private string NormalizeTilesheetPathForComparison(string path) diff --git a/src/SMAPI/IAssetDataForMap.cs b/src/SMAPI/IAssetDataForMap.cs index bfaba9ba..47a33de8 100644 --- a/src/SMAPI/IAssetDataForMap.cs +++ b/src/SMAPI/IAssetDataForMap.cs @@ -13,6 +13,7 @@ namespace StardewModdingAPI /// The map from which to copy. /// The tile area within the source map to copy, or null for the entire source map size. This must be within the bounds of the map. /// The tile area within the target map to overwrite, or null to patch the whole map. The original content within this area will be erased. This must be within the bounds of the existing map. - void PatchMap(Map source, Rectangle? sourceArea = null, Rectangle? targetArea = null); + /// Indicates how the map should be patched. + void PatchMap(Map source, Rectangle? sourceArea = null, Rectangle? targetArea = null, PatchMapMode patchMode = PatchMapMode.Overlay); } } diff --git a/src/SMAPI/PatchMapMode.cs b/src/SMAPI/PatchMapMode.cs new file mode 100644 index 00000000..1f1ac6a9 --- /dev/null +++ b/src/SMAPI/PatchMapMode.cs @@ -0,0 +1,15 @@ +namespace StardewModdingAPI +{ + /// Indicates how a map should be patched. + public enum PatchMapMode + { + /// Replace matching tiles. Target tiles missing in the source area are kept as-is. + Overlay, + + /// Replace all tiles on layers that exist in the source map. + ReplaceByLayer, + + /// Replace all tiles with the source map. + Replace + } +} -- cgit From d1d09ae1df63826dd453aa0347d668f420754ed7 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 25 Nov 2021 23:01:14 -0500 Subject: add support for loading BmFont files for custom languages --- docs/release-notes.md | 1 + src/SMAPI/Framework/ContentManagers/ModContentManager.cs | 11 ++++++++++- src/SMAPI/SMAPI.csproj | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/release-notes.md b/docs/release-notes.md index 69eab3ec..d60156d5 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -5,6 +5,7 @@ * For players: * Updated for Stardew Valley 1.5.5. * Updated compatibility list. + * Added support for loading BmFont `.fnt` files for [custom languages](https://stardewvalleywiki.com/Modding:Custom_languages) through the [content API](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Content). * Added `set_farm_type` [console command](https://stardewvalleywiki.com/Modding:Console_commands#Console_commands) to change the current farm type. * Fixed installer window closing immediately if the installer crashed. diff --git a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs index bf0b54b9..beb90a5d 100644 --- a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs @@ -2,6 +2,7 @@ using System; using System.Globalization; using System.IO; using System.Linq; +using BmFont; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; @@ -129,6 +130,14 @@ namespace StardewModdingAPI.Framework.ContentManagers } break; + // unpacked Bitmap font + case ".fnt": + { + string source = File.ReadAllText(file.FullName); + asset = (T)(object)new XmlSource(source); + } + break; + // unpacked data case ".json": { @@ -171,7 +180,7 @@ namespace StardewModdingAPI.Framework.ContentManagers break; default: - throw GetContentError($"unknown file extension '{file.Extension}'; must be one of '.json', '.png', '.tbin', or '.xnb'."); + throw GetContentError($"unknown file extension '{file.Extension}'; must be one of '.fnt', '.json', '.png', '.tbin', or '.xnb'."); } } catch (Exception ex) when (!(ex is SContentLoadException)) diff --git a/src/SMAPI/SMAPI.csproj b/src/SMAPI/SMAPI.csproj index 4f9aa9b1..b99028da 100644 --- a/src/SMAPI/SMAPI.csproj +++ b/src/SMAPI/SMAPI.csproj @@ -31,6 +31,7 @@ + -- cgit From b294ac1203aa78575f8c72f0be1ee9d3edff15ab Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 30 Nov 2021 17:13:53 -0500 Subject: prepare for release --- build/common.targets | 2 +- docs/release-notes.md | 24 +++++++++++++----------- src/SMAPI.Mods.ConsoleCommands/manifest.json | 4 ++-- src/SMAPI.Mods.ErrorHandler/manifest.json | 4 ++-- src/SMAPI.Mods.SaveBackup/manifest.json | 4 ++-- src/SMAPI/Constants.cs | 2 +- 6 files changed, 21 insertions(+), 19 deletions(-) (limited to 'docs') diff --git a/build/common.targets b/build/common.targets index a74002a6..9dd6f7a2 100644 --- a/build/common.targets +++ b/build/common.targets @@ -1,7 +1,7 @@ - 3.12.8 + 3.13.0 SMAPI latest $(AssemblySearchPaths);{GAC} diff --git a/docs/release-notes.md b/docs/release-notes.md index d60156d5..08cc832c 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -1,30 +1,32 @@ ← [README](README.md) # Release notes -## Upcoming release +## 3.13.0 +Released 30 November 2021 for Stardew Valley 1.5.5 or later. + * For players: * Updated for Stardew Valley 1.5.5. - * Updated compatibility list. - * Added support for loading BmFont `.fnt` files for [custom languages](https://stardewvalleywiki.com/Modding:Custom_languages) through the [content API](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Content). * Added `set_farm_type` [console command](https://stardewvalleywiki.com/Modding:Console_commands#Console_commands) to change the current farm type. * Fixed installer window closing immediately if the installer crashed. + * Updated compatibility list. * For mod authors: * Migrated to 64-bit MonoGame and .NET 5 on all platforms (see [migration guide for mod authors](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5)). * Added support for [map overlays via `asset.AsMap().PatchMap`](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Content#Edit_a_map). + * Added support for loading BmFont `.fnt` files for [custom languages](https://stardewvalleywiki.com/Modding:Custom_languages) through the [content API](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Content). + +* For the web UI: + * Updated the JSON validator/schema for Content Patcher 1.24.0. **Update note for players with older systems:** The game now has two branches: the _main branch_ which you'll get by default, and an optional -_compatibility branch_ for [older systems](https://www.stardewvalley.net/compatibility/). The two -branches have identical content, but use [different technologies](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5#Stardew_Valley_compatibility_branch). +[_compatibility branch_ for older systems](https://www.stardewvalley.net/compatibility/). The two +branches have identical content, but use [different technologies](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5#Game_compatibility_branch). Unfortunately **SMAPI only supports the main branch of the game**. There are formidable difficulties -across all mods in supporting all three variations, the [Steam hardware stats](https://store.steampowered.com/hwsurvey) -show that 99.69% of players have 64-bit, and 32-bit imposes significant restrictions on what mods -can do. - -* For the web UI: - * Updated the JSON validator/schema for Content Patcher 1.24.0. +across all mods in supporting all three variations, 32-bit imposes significant restrictions on what +mods can do, and the [Steam hardware stats](https://store.steampowered.com/hwsurvey) show that 99.69% +of players now have 64-bit. ## 3.12.8 Released 18 October 2021 for Stardew Valley 1.5.4. diff --git a/src/SMAPI.Mods.ConsoleCommands/manifest.json b/src/SMAPI.Mods.ConsoleCommands/manifest.json index 9af3ce5d..85653a7d 100644 --- a/src/SMAPI.Mods.ConsoleCommands/manifest.json +++ b/src/SMAPI.Mods.ConsoleCommands/manifest.json @@ -1,9 +1,9 @@ { "Name": "Console Commands", "Author": "SMAPI", - "Version": "3.12.8", + "Version": "3.13.0", "Description": "Adds SMAPI console commands that let you manipulate the game.", "UniqueID": "SMAPI.ConsoleCommands", "EntryDll": "ConsoleCommands.dll", - "MinimumApiVersion": "3.12.8" + "MinimumApiVersion": "3.13.0" } diff --git a/src/SMAPI.Mods.ErrorHandler/manifest.json b/src/SMAPI.Mods.ErrorHandler/manifest.json index cfbaa661..da8306d1 100644 --- a/src/SMAPI.Mods.ErrorHandler/manifest.json +++ b/src/SMAPI.Mods.ErrorHandler/manifest.json @@ -1,9 +1,9 @@ { "Name": "Error Handler", "Author": "SMAPI", - "Version": "3.12.8", + "Version": "3.13.0", "Description": "Handles some common vanilla errors to log more useful info or avoid breaking the game.", "UniqueID": "SMAPI.ErrorHandler", "EntryDll": "ErrorHandler.dll", - "MinimumApiVersion": "3.12.8" + "MinimumApiVersion": "3.13.0" } diff --git a/src/SMAPI.Mods.SaveBackup/manifest.json b/src/SMAPI.Mods.SaveBackup/manifest.json index 1efd1d89..4c57bd49 100644 --- a/src/SMAPI.Mods.SaveBackup/manifest.json +++ b/src/SMAPI.Mods.SaveBackup/manifest.json @@ -1,9 +1,9 @@ { "Name": "Save Backup", "Author": "SMAPI", - "Version": "3.12.8", + "Version": "3.13.0", "Description": "Automatically backs up all your saves once per day into its folder.", "UniqueID": "SMAPI.SaveBackup", "EntryDll": "SaveBackup.dll", - "MinimumApiVersion": "3.12.8" + "MinimumApiVersion": "3.13.0" } diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index 3ae8661a..cf4bb677 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -49,7 +49,7 @@ namespace StardewModdingAPI internal static int? LogScreenId { get; set; } /// SMAPI's current raw semantic version. - internal static string RawApiVersion = "3.12.8"; + internal static string RawApiVersion = "3.13.0"; } /// Contains SMAPI's constants and assumptions. -- cgit