diff options
42 files changed, 524 insertions, 331 deletions
diff --git a/build/common.targets b/build/common.targets index 70f0a741..5eb69901 100644 --- a/build/common.targets +++ b/build/common.targets @@ -1,18 +1,13 @@ <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <!--set general build properties --> - <Version>3.12.5</Version> + <Version>3.12.6</Version> <Product>SMAPI</Product> <LangVersion>latest</LangVersion> <AssemblySearchPaths>$(AssemblySearchPaths);{GAC}</AssemblySearchPaths> - <!--uncomment for 64-bit Stardew Valley on Windows--> - <!--<GamePath>D:\dev\SDV 64-bit\6125897</GamePath> - <DefineConstants>$(DefineConstants);SMAPI_FOR_WINDOWS_64BIT_HACK</DefineConstants>--> - <!--set platform--> - <DefineConstants Condition="$(OS) == 'Windows_NT'">$(DefineConstants);SMAPI_FOR_WINDOWS</DefineConstants> - <DefineConstants Condition="$(OS) == 'Windows_NT' AND !$(DefineConstants.Contains(SMAPI_FOR_WINDOWS_64BIT_HACK))">$(DefineConstants);SMAPI_FOR_XNA</DefineConstants> + <DefineConstants Condition="$(OS) == 'Windows_NT'">$(DefineConstants);SMAPI_FOR_WINDOWS;SMAPI_FOR_XNA</DefineConstants> </PropertyGroup> <!--find game folder--> diff --git a/docs/release-notes.md b/docs/release-notes.md index db0c3a2a..4e0a9df6 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -1,6 +1,30 @@ ← [README](README.md) # Release notes +## 3.12.6 +Released 03 September 2021 for Stardew Valley 1.5.4 or later. + +* For players: + * Added friendly error when using SMAPI 3.2._x_ with Stardew Valley 1.5.5 or later. + * Improved mod compatibility in 64-bit mode (thanks to spacechase0!). + * Reduced load time when scanning/rewriting many mods for compatibility. + * **Dropped support for unofficial 64-bit mode**. You can now use the [official 64-bit Stardew Valley 1.5.5 beta](https://stardewvalleywiki.com/Modding:Migrate_to_64-bit_on_Windows) instead. + * Updated compatibility list. + +* For mod authors: + * Added `PathUtilities.NormalizeAssetName` and `PathUtilities.PreferredAssetSeparator` to prepare for the upcoming Stardew Valley 1.5.5. + * **SMAPI no longer propagates changes to `Data/Bundles`.** + _You can still load/edit the asset like usual, but if bundles have already been loaded for a save, SMAPI will no longer dynamically update the in-game bundles to reflect the changes. Unfortunately this caused bundle corruption when playing in non-English._ + * Fixed content packs created via `helper.ContentPacks.CreateFake` or `CreateTemporary` not initializing translations correctly. + +* For console commands: + * Added `hurry_all` command which immediately warps all NPCs to their scheduled positions. + +**Update note for mod authors:** +Stardew Valley 1.5.5 will change how asset names are formatted. If you use `PathUtilities.NormalizePath` +to format asset names, you should switch to `PathUtilities.NormalizeAssetName` now so your code will +continue working in the next game update. + ## 3.12.5 Released 26 August 2021 for Stardew Valley 1.5.4 or later. diff --git a/docs/technical/smapi.md b/docs/technical/smapi.md index 586b17aa..4be062e2 100644 --- a/docs/technical/smapi.md +++ b/docs/technical/smapi.md @@ -57,8 +57,7 @@ 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_WINDOWS_64BIT_HACK` | Whether SMAPI is being [compiled for Windows with a 64-bit Linux version of the game](https://github.com/Pathoschild/SMAPI/issues/767). This is highly specialized and shouldn't be used in most cases. False by default. -`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` (unless `SMAPI_FOR_WINDOWS_64BIT_HACK` is set). +`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 @@ -81,9 +80,7 @@ To prepare a crossplatform SMAPI release, you'll need to compile it on two platf [crossplatforming info](https://stardewvalleywiki.com/Modding:Modder_Guide/Test_and_Troubleshoot#Testing_on_all_platforms) on the wiki for the first-time setup. -1. [Install a separate 64-bit version of Stardew Valley](https://github.com/Steviegt6/Stardew64Installer#readme) - on Windows. -2. Update the version numbers in `build/common.targets`, `Constants`, and the `manifest.json` for +1. Update the version numbers in `build/common.targets`, `Constants`, and the `manifest.json` for bundled mods. Make sure you use a [semantic version](https://semver.org). Recommended format: build type | format | example @@ -91,14 +88,9 @@ on the wiki for the first-time setup. dev build | `<version>-alpha.<date>` | `3.0.0-alpha.20171230` prerelease | `<version>-beta.<date>` | `3.0.0-beta.20171230` release | `<version>` | `3.0.0` -3. In Windows: +2. In Windows: 1. Rebuild the solution with the _release_ solution configuration. - 2. Back up the `bin/SMAPI installer` and `bin/SMAPI installer for developers` folders. - 3. Edit `common.targets` and uncomment the Stardew Valley 64-bit section at the top. - 4. Rebuild the solution again. - 5. Rename the compiled `StardewModdingAPI.exe` file to `StardewModdingAPI-x64.exe`, and copy it - into the `windows-install.dat` files from step ii. - 6. Copy the folders from step ii to Linux/MacOS. + 2. Copy the `bin/SMAPI installer` and `bin/SMAPI installer for developers` folders to Linux/macOS. 4. In Linux/macOS: 1. Rebuild the solution with the _release_ solution configuration. 2. Add the `windows-install.*` files from Windows to the `bin/SMAPI installer` and diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs index b91d0dd3..9f49137f 100644 --- a/src/SMAPI.Installer/InteractiveInstaller.cs +++ b/src/SMAPI.Installer/InteractiveInstaller.cs @@ -275,21 +275,20 @@ namespace StardewModdingApi.Installer /********* - ** Step 4: detect 64-bit Stardew Valley + ** Step 4: validate assumptions *********/ - // detect 64-bit mode - bool isWindows64Bit = false; + // not 64-bit on Windows if (context.Platform == Platform.Windows) { FileInfo linuxExecutable = new FileInfo(Path.Combine(paths.GamePath, "StardewValley.exe")); - isWindows64Bit = linuxExecutable.Exists && this.Is64Bit(linuxExecutable.FullName); - if (isWindows64Bit) - paths.SetExecutableFileName(linuxExecutable.Name); + if (linuxExecutable.Exists && this.Is64Bit(linuxExecutable.FullName)) + { + this.PrintError("Oops! The detected game install path seems to be unofficial 64-bit mode, which is no longer supported. You can update to Stardew Valley 1.5.5 or later instead. See https://stardewvalleywiki.com/Modding:Migrate_to_64-bit_on_Windows for more info."); + Console.ReadLine(); + return; + } } - /********* - ** Step 5: validate assumptions - *********/ // executable exists if (!File.Exists(paths.ExecutablePath)) { @@ -298,6 +297,14 @@ namespace StardewModdingApi.Installer return; } + // not Stardew Valley 1.5.5+ + if (File.Exists(Path.Combine(paths.GamePath, "Stardew Valley.dll"))) + { + this.PrintError("Oops! The detected game install path seems to be Stardew Valley 1.5.5 or later, but this version of SMAPI is only compatible up to Stardew Valley 1.5.4. Please check for a newer version of SMAPI: https://smapi.io."); + Console.ReadLine(); + return; + } + // game folder doesn't contain paths beyond the max limit { string[] tooLongPaths = PathUtilities.GetTooLongPaths(Path.Combine(paths.GamePath, "Mods")).ToArray(); @@ -312,7 +319,7 @@ namespace StardewModdingApi.Installer /********* - ** Step 6: ask what to do + ** Step 5: ask what to do *********/ ScriptAction action; { @@ -320,7 +327,7 @@ namespace StardewModdingApi.Installer ** print header ****/ this.PrintInfo("Hi there! I'll help you install or remove SMAPI. Just one question first."); - this.PrintDebug($"Game path: {paths.GamePath}{(context.IsWindows ? $" [{(isWindows64Bit ? "64-bit" : "32-bit")}]" : "")}"); + this.PrintDebug($"Game path: {paths.GamePath}"); this.PrintDebug($"Color scheme: {this.GetDisplayText(scheme)}"); this.PrintDebug("----------------------------------------------------------------------------"); Console.WriteLine(); @@ -358,14 +365,14 @@ namespace StardewModdingApi.Installer /********* - ** Step 7: apply + ** Step 6: apply *********/ { /**** ** print header ****/ this.PrintInfo($"That's all I need! I'll {action.ToString().ToLower()} SMAPI now."); - this.PrintDebug($"Game path: {paths.GamePath}{(context.IsWindows ? $" [{(isWindows64Bit ? "64-bit" : "32-bit")}]" : "")}"); + this.PrintDebug($"Game path: {paths.GamePath}"); this.PrintDebug($"Color scheme: {this.GetDisplayText(scheme)}"); this.PrintDebug("----------------------------------------------------------------------------"); Console.WriteLine(); @@ -426,25 +433,6 @@ namespace StardewModdingApi.Installer this.RecursiveCopy(sourceEntry, paths.GameDir); } - // handle 64-bit file - { - FileInfo x64Executable = new FileInfo(Path.Combine(paths.GameDir.FullName, "StardewModdingAPI-x64.exe")); - if (isWindows64Bit) - { - this.PrintDebug("Making SMAPI 64-bit..."); - if (x64Executable.Exists) - { - string targetPath = Path.Combine(paths.GameDir.FullName, "StardewModdingAPI.exe"); - this.InteractivelyDelete(targetPath); - x64Executable.MoveTo(targetPath); - } - else - this.PrintError($"Oops! Could not find the required '{x64Executable.Name}' installer file. SMAPI may not work correctly."); - } - else if (x64Executable.Exists) - x64Executable.Delete(); - } - // replace mod launcher (if possible) if (context.IsUnix) { @@ -539,7 +527,7 @@ namespace StardewModdingApi.Installer /********* - ** Step 7: final instructions + ** Step 6: final instructions *********/ if (context.IsWindows) { diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/HurryAllCommand.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/HurryAllCommand.cs new file mode 100644 index 00000000..2deac5f8 --- /dev/null +++ b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/HurryAllCommand.cs @@ -0,0 +1,54 @@ +using System; +using StardewValley; + +namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.World +{ + /// <summary>A command which immediately warps all NPCs to their scheduled positions. To hurry a single NPC, see <c>debug hurry npc-name</c> instead.</summary> + internal class HurryAllCommand : ConsoleCommand + { + /********* + ** Public methods + *********/ + /// <summary>Construct an instance.</summary> + public HurryAllCommand() + : base( + name: "hurry_all", + description: "Immediately warps all NPCs to their scheduled positions. (To hurry a single NPC, use `debug hurry npc-name` instead.)\n\n" + + "Usage: hurry_all" + ) + { } + + /// <summary>Handle the command.</summary> + /// <param name="monitor">Writes messages to the console and log file.</param> + /// <param name="command">The command name.</param> + /// <param name="args">The command arguments.</param> + public override void Handle(IMonitor monitor, string command, ArgumentParser args) + { + // check context + if (!Context.IsWorldReady) + { + monitor.Log("You need to load a save to use this command.", LogLevel.Error); + return; + } + + // hurry all NPCs + foreach (NPC npc in Utility.getAllCharacters()) + { + if (!npc.isVillager()) + continue; + + monitor.Log($"Hurrying {npc.Name}..."); + try + { + npc.warpToPathControllerDestination(); + } + catch (Exception ex) + { + monitor.Log($"Failed hurrying {npc.Name}. Technical details:\n{ex}", LogLevel.Error); + } + } + + monitor.Log("Done!", LogLevel.Info); + } + } +} diff --git a/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj b/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj index 432fdc35..a187c1ff 100644 --- a/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj +++ b/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj @@ -19,7 +19,7 @@ <!-- Windows only --> <ItemGroup Condition="'$(OS)' == 'Windows_NT'"> - <Reference Include="Netcode" HintPath="$(GamePath)\Netcode.dll" Private="False" Condition="!$(DefineConstants.Contains(SMAPI_FOR_WINDOWS_64BIT_HACK))" /> + <Reference Include="Netcode" HintPath="$(GamePath)\Netcode.dll" Private="False" /> </ItemGroup> <!-- Game framework --> diff --git a/src/SMAPI.Mods.ConsoleCommands/manifest.json b/src/SMAPI.Mods.ConsoleCommands/manifest.json index 540d0488..de223c01 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.5", + "Version": "3.12.6", "Description": "Adds SMAPI console commands that let you manipulate the game.", "UniqueID": "SMAPI.ConsoleCommands", "EntryDll": "ConsoleCommands.dll", - "MinimumApiVersion": "3.12.5" + "MinimumApiVersion": "3.12.6" } diff --git a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj index ffda5f89..eb878bc5 100644 --- a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj +++ b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj @@ -21,7 +21,7 @@ <!-- Windows only --> <ItemGroup Condition="'$(OS)' == 'Windows_NT'"> - <Reference Include="Netcode" HintPath="$(GamePath)\Netcode.dll" Private="False" Condition="!$(DefineConstants.Contains(SMAPI_FOR_WINDOWS_64BIT_HACK))" /> + <Reference Include="Netcode" HintPath="$(GamePath)\Netcode.dll" Private="False" /> </ItemGroup> <!-- Game framework --> diff --git a/src/SMAPI.Mods.ErrorHandler/manifest.json b/src/SMAPI.Mods.ErrorHandler/manifest.json index 645a7514..fcb6d7eb 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.5", + "Version": "3.12.6", "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.5" + "MinimumApiVersion": "3.12.6" } diff --git a/src/SMAPI.Mods.SaveBackup/manifest.json b/src/SMAPI.Mods.SaveBackup/manifest.json index d8b77339..1c84b5c2 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.5", + "Version": "3.12.6", "Description": "Automatically backs up all your saves once per day into its folder.", "UniqueID": "SMAPI.SaveBackup", "EntryDll": "SaveBackup.dll", - "MinimumApiVersion": "3.12.5" + "MinimumApiVersion": "3.12.6" } diff --git a/src/SMAPI.Tests/Core/ModResolverTests.cs b/src/SMAPI.Tests/Core/ModResolverTests.cs index 28262111..da3446bb 100644 --- a/src/SMAPI.Tests/Core/ModResolverTests.cs +++ b/src/SMAPI.Tests/Core/ModResolverTests.cs @@ -10,6 +10,7 @@ using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.ModLoading; using StardewModdingAPI.Toolkit; using StardewModdingAPI.Toolkit.Framework.ModData; +using StardewModdingAPI.Toolkit.Framework.UpdateData; using StardewModdingAPI.Toolkit.Serialization.Models; using SemanticVersion = StardewModdingAPI.SemanticVersion; @@ -489,7 +490,8 @@ namespace SMAPI.Tests.Core EntryDll = entryDll ?? $"{Sample.String()}.dll", ContentPackFor = contentPackForID != null ? new ManifestContentPackFor { UniqueID = contentPackForID } : null, MinimumApiVersion = minimumApiVersion != null ? new SemanticVersion(minimumApiVersion) : null, - Dependencies = dependencies + Dependencies = dependencies ?? new IManifestDependency[0], + UpdateKeys = new string[0] }; } @@ -541,6 +543,7 @@ namespace SMAPI.Tests.Core mod.Setup(p => p.Manifest).Returns(this.GetManifest()); mod.Setup(p => p.DirectoryPath).Returns(Path.GetTempPath()); mod.Setup(p => p.DataRecord).Returns(modRecord); + mod.Setup(p => p.GetUpdateKeys(It.IsAny<bool>())).Returns(Enumerable.Empty<UpdateKey>()); } } } diff --git a/src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs b/src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs index 5a342974..c18f47a5 100644 --- a/src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs +++ b/src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs @@ -1,3 +1,4 @@ +using System.IO; using NUnit.Framework; using StardewModdingAPI.Toolkit.Utilities; @@ -175,9 +176,30 @@ namespace SMAPI.Tests.Utilities } /**** - ** NormalizePathSeparators + ** NormalizeAssetName ****/ - [Test(Description = "Assert that PathUtilities.NormalizePathSeparators normalizes paths correctly.")] + [Test(Description = "Assert that PathUtilities.NormalizeAssetName normalizes paths correctly.")] + [TestCaseSource(nameof(PathUtilitiesTests.SamplePaths))] + public void NormalizeAssetName(SamplePath path) + { + if (Path.IsPathRooted(path.OriginalPath) || path.OriginalPath.StartsWith("/") || path.OriginalPath.StartsWith("\\")) + Assert.Ignore("Absolute paths can't be used as asset names."); + + // act + string normalized = PathUtilities.NormalizeAssetName(path.OriginalPath); + + // assert +#if SMAPI_FOR_WINDOWS + Assert.AreEqual(path.NormalizedOnWindows, normalized); +#else + Assert.AreEqual(path.NormalizedOnUnix, normalized); +#endif + } + + /**** + ** NormalizePath + ****/ + [Test(Description = "Assert that PathUtilities.NormalizePath normalizes paths correctly.")] [TestCaseSource(nameof(PathUtilitiesTests.SamplePaths))] public void NormalizePath(SamplePath path) { diff --git a/src/SMAPI.Toolkit/ModToolkit.cs b/src/SMAPI.Toolkit/ModToolkit.cs index 695a2c52..38a67ae5 100644 --- a/src/SMAPI.Toolkit/ModToolkit.cs +++ b/src/SMAPI.Toolkit/ModToolkit.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -8,6 +7,7 @@ using StardewModdingAPI.Toolkit.Framework.Clients.Wiki; using StardewModdingAPI.Toolkit.Framework.GameScanning; using StardewModdingAPI.Toolkit.Framework.ModData; using StardewModdingAPI.Toolkit.Framework.ModScanning; +using StardewModdingAPI.Toolkit.Framework.UpdateData; using StardewModdingAPI.Toolkit.Serialization; namespace StardewModdingAPI.Toolkit @@ -22,11 +22,11 @@ namespace StardewModdingAPI.Toolkit private readonly string UserAgent; /// <summary>Maps vendor keys (like <c>Nexus</c>) to their mod URL template (where <c>{0}</c> is the mod ID). This doesn't affect update checks, which defer to the remote web API.</summary> - private readonly IDictionary<string, string> VendorModUrls = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) + private readonly IDictionary<ModSiteKey, string> VendorModUrls = new Dictionary<ModSiteKey, string>() { - ["Chucklefish"] = "https://community.playstarbound.com/resources/{0}", - ["GitHub"] = "https://github.com/{0}/releases", - ["Nexus"] = "https://www.nexusmods.com/stardewvalley/mods/{0}" + [ModSiteKey.Chucklefish] = "https://community.playstarbound.com/resources/{0}", + [ModSiteKey.GitHub] = "https://github.com/{0}/releases", + [ModSiteKey.Nexus] = "https://www.nexusmods.com/stardewvalley/mods/{0}" }; @@ -89,15 +89,12 @@ namespace StardewModdingAPI.Toolkit /// <param name="updateKey">The update key.</param> public string GetUpdateUrl(string updateKey) { - string[] parts = updateKey.Split(new[] { ':' }, 2); - if (parts.Length != 2) + UpdateKey parsed = UpdateKey.Parse(updateKey); + if (!parsed.LooksValid) return null; - string vendorKey = parts[0].Trim(); - string modID = parts[1].Trim(); - - if (this.VendorModUrls.TryGetValue(vendorKey, out string urlTemplate)) - return string.Format(urlTemplate, modID); + if (this.VendorModUrls.TryGetValue(parsed.Site, out string urlTemplate)) + return string.Format(urlTemplate, parsed.ID); return null; } diff --git a/src/SMAPI.Toolkit/Utilities/PathUtilities.cs b/src/SMAPI.Toolkit/Utilities/PathUtilities.cs index babc0981..020ebc6d 100644 --- a/src/SMAPI.Toolkit/Utilities/PathUtilities.cs +++ b/src/SMAPI.Toolkit/Utilities/PathUtilities.cs @@ -23,9 +23,12 @@ namespace StardewModdingAPI.Toolkit.Utilities /// <summary>The possible directory separator characters in a file path.</summary> public static readonly char[] PossiblePathSeparators = new[] { '/', '\\', Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }.Distinct().ToArray(); - /// <summary>The preferred directory separator character in an asset key.</summary> + /// <summary>The preferred directory separator character in a file path.</summary> public static readonly char PreferredPathSeparator = Path.DirectorySeparatorChar; + /// <summary>The preferred directory separator character in an asset key.</summary> + public static readonly char PreferredAssetSeparator = PathUtilities.PreferredPathSeparator; + /********* ** Public methods @@ -41,8 +44,16 @@ namespace StardewModdingAPI.Toolkit.Utilities : path.Split(PathUtilities.PossiblePathSeparators, StringSplitOptions.RemoveEmptyEntries); } - /// <summary>Normalize separators in a file path.</summary> + /// <summary>Normalize an asset name to match how MonoGame's content APIs would normalize and cache it.</summary> + /// <param name="assetName">The asset name to normalize.</param> + public static string NormalizeAssetName(string assetName) + { + return string.Join(PathUtilities.PreferredAssetSeparator.ToString(), PathUtilities.GetSegments(assetName)); // based on MonoGame's ContentManager.Load<T> logic + } + + /// <summary>Normalize separators in a file path for the current platform.</summary> /// <param name="path">The file path to normalize.</param> + /// <remarks>This should only be used for file paths. For asset names, use <see cref="NormalizeAssetName"/> instead.</remarks> [Pure] public static string NormalizePath(string path) { diff --git a/src/SMAPI.Web/wwwroot/SMAPI.metadata.json b/src/SMAPI.Web/wwwroot/SMAPI.metadata.json index 7dff16c4..dcdd6298 100644 --- a/src/SMAPI.Web/wwwroot/SMAPI.metadata.json +++ b/src/SMAPI.Web/wwwroot/SMAPI.metadata.json @@ -170,38 +170,28 @@ /********* ** Broke in SMAPI 3.12.0 *********/ - "PlatoTK": { - "ID": "Platonymous.PlatoTK", - "~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" - }, "Always Scroll Map": { "ID": "bcmpinc.AlwaysScrollMap", "~4.1.0 | Status": "AssumeBroken", "~4.1.0 | StatusReasonDetails": "causes Harmony patching errors for other mods" // requested by the mod author }, + "Big Silo": { + "ID": "lperkins2.BigSilo", + "~0.0.3 | Status": "AssumeBroken", + "~0.0.3 | StatusReasonDetails": "not compatible with Harmony 2.x" + }, "Fix Animal Tools": { "ID": "bcmpinc.FixAnimalTools", "~4.1.0 | Status": "AssumeBroken", "~4.1.0 | StatusReasonDetails": "causes Harmony |
