polish recent changes & update release notes

This commit is contained in:
Jesse Plamondon-Willard 2022-10-09 13:50:24 -04:00
parent fce1b1bd0b
commit a220e14f2d
No known key found for this signature in database
GPG Key ID: CF8B1456B3E29F49
4 changed files with 44 additions and 34 deletions

View File

@ -9,11 +9,16 @@
## Upcoming release
* For players:
* Fixed update alert shown for a prerelease version on GitHub if it's not marked as prerelease.
* The SMAPI installer now also detects game folders listed in Steam's `.vdf` library data on Windows (thanks to pizzaoverhead!).
* Optimized performance and memory usage (thanks to atravita!).
* Added more file extensions to ignore when searching for mod folders: `.7z`, `.tar`, `.tar.gz`, and `.xcf` (thanks to atravita!).
* Fixed update alerts incorrectly shown for prerelease versions on GitHub that aren't marked as prerelease.
* For mod authors:
* When [providing a mod API for a C# mod](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Integrations), you can now get an optional parameter with the mod requesting the API (thanks to KhloeLeclair!). This avoids needing the pattern where each method needs the requesting mod's manifest.
* SMAPI now treats square brackets in the manifest `Name` field as round brackets, to avoid breaking tools which parse log files.
* Updated to [FluentHttpClient](https://github.com/Pathoschild/FluentHttpClient#readme) 4.2.0 (see [changes](https://github.com/Pathoschild/FluentHttpClient/blob/develop/RELEASE-NOTES.md#420)).
* Fixed `LocationListChanged` event not raised & memory leak occurring when a generated mine/volcano is removed (thanks to tylergibbs2!).
## 3.16.2
Released 31 August 2022 for Stardew Valley 1.5.6 or later.

View File

@ -52,7 +52,7 @@ namespace StardewModdingAPI.Toolkit.Framework.ModScanning
".zip",
".7z",
".tar",
".tar.gz"
".tar.gz",
// backup files
".backup",

View File

@ -1686,12 +1686,16 @@ namespace StardewModdingAPI.Framework
this.Monitor.Log("Launching mods...", LogLevel.Debug);
foreach (IModMetadata metadata in loadedMods)
{
IMod mod =
metadata.Mod
?? throw new InvalidOperationException($"The '{metadata.DisplayName}' mod is not initialized correctly."); // should never happen, but avoids nullability warnings
#if SMAPI_DEPRECATED
// add interceptors
if (metadata.Mod?.Helper is ModHelper helper)
if (mod.Helper is ModHelper helper)
{
// ReSharper disable SuspiciousTypeConversion.Global
if (metadata.Mod is IAssetEditor editor)
if (mod is IAssetEditor editor)
{
SCore.DeprecationManager.Warn(
source: metadata,
@ -1704,7 +1708,7 @@ namespace StardewModdingAPI.Framework
this.ContentCore.Editors.Add(new ModLinked<IAssetEditor>(metadata, editor));
}
if (metadata.Mod is IAssetLoader loader)
if (mod is IAssetLoader loader)
{
SCore.DeprecationManager.Warn(
source: metadata,
@ -1749,41 +1753,42 @@ namespace StardewModdingAPI.Framework
}
#endif
// call entry method
// initialize mod
Context.HeuristicModsRunningCode.Push(metadata);
try
{
IMod mod = metadata.Mod!;
mod.Entry(mod.Helper!);
}
catch (Exception ex)
{
metadata.LogAsMod($"Mod crashed on entry and might not work correctly. Technical details:\n{ex.GetLogSummary()}", LogLevel.Error);
}
// get mod API
try
{
object? api = metadata.Mod!.GetApi();
if (api != null && !api.GetType().IsPublic)
// call entry method
try
{
api = null;
this.Monitor.Log($"{metadata.DisplayName} provides an API instance with a non-public type. This isn't currently supported, so the API won't be available to other mods.", LogLevel.Warn);
mod.Entry(mod.Helper!);
}
catch (Exception ex)
{
metadata.LogAsMod($"Mod crashed on entry and might not work correctly. Technical details:\n{ex.GetLogSummary()}", LogLevel.Error);
}
if (api != null)
this.Monitor.Log($" Found mod-provided API ({api.GetType().FullName}).");
metadata.SetApi(api);
}
catch (Exception ex)
{
this.Monitor.Log($"Failed loading mod-provided API for {metadata.DisplayName}. Integrations with other mods may not work. Error: {ex.GetLogSummary()}", LogLevel.Error);
}
// get mod API
try
{
object? api = mod.GetApi();
if (api != null && !api.GetType().IsPublic)
{
api = null;
this.Monitor.Log($"{metadata.DisplayName} provides an API instance with a non-public type. This isn't currently supported, so the API won't be available to other mods.", LogLevel.Warn);
}
// validate mod doesn't implement both GetApi() and GetApi(mod)
if (metadata.Api != null && metadata.Mod!.GetType().GetMethod(nameof(Mod.GetApi), new Type[] { typeof(IManifest) })!.DeclaringType != typeof(Mod))
metadata.LogAsMod($"Mod implements both {nameof(Mod.GetApi)}() and {nameof(Mod.GetApi)}({nameof(IManifest)}), which isn't allowed. The latter will be ignored.", LogLevel.Error);
if (api != null)
this.Monitor.Log($" Found mod-provided API ({api.GetType().FullName}).");
metadata.SetApi(api);
}
catch (Exception ex)
{
this.Monitor.Log($"Failed loading mod-provided API for {metadata.DisplayName}. Integrations with other mods may not work. Error: {ex.GetLogSummary()}", LogLevel.Error);
}
// validate mod doesn't implement both GetApi() and GetApi(mod)
if (metadata.Api != null && mod.GetType().GetMethod(nameof(Mod.GetApi), new Type[] { typeof(IModInfo) })!.DeclaringType != typeof(Mod))
metadata.LogAsMod($"Mod implements both {nameof(Mod.GetApi)}() and {nameof(Mod.GetApi)}({nameof(IModInfo)}), which isn't allowed. The latter will be ignored.", LogLevel.Error);
}
Context.HeuristicModsRunningCode.TryPop(out _);
}

View File

@ -30,7 +30,7 @@ namespace StardewModdingAPI
/// <summary>Get an <a href="https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Integrations">API that other mods can access</a>. This is always called after <see cref="Entry"/>, and is called once per mod that accesses the API (even if they access it multiple times).</summary>
/// <param name="mod">The mod accessing the API.</param>
/// <remarks>Returns the API instance, or <c>null</c> if the mod has no API. Note that the manifest is provided for informational purposes only, and that denying API access to specific mods is strongly discouraged and may be considered abusive.</remarks>
/// <remarks>Returns the API instance, or <c>null</c> if the mod has no API. Note that <paramref name="mod"/> is provided for informational purposes only, and that denying API access to specific mods is strongly discouraged and may be considered abusive.</remarks>
/// <inheritdoc cref="GetApi()" include="/Remarks" />
object? GetApi(IModInfo mod);
}