Merge branch 'develop' into stable

This commit is contained in:
Jesse Plamondon-Willard 2021-01-25 21:53:11 -05:00
commit f1505b0ebe
No known key found for this signature in database
GPG Key ID: CF8B1456B3E29F49
15 changed files with 60 additions and 36 deletions

View File

@ -4,7 +4,7 @@
<!--set properties -->
<PropertyGroup>
<Version>3.9.0</Version>
<Version>3.9.1</Version>
<Product>SMAPI</Product>
<LangVersion>latest</LangVersion>

View File

@ -7,8 +7,15 @@
* Migrated to Harmony 2.0 (see [_migrate to Harmony 2.0_](https://stardewvalleywiki.com/Modding:Migrate_to_Harmony_2.0) for more info).
-->
## 3.9.1
Released 25 January 2021 for Stardew Valley 1.5.4 or later.
* For players:
* Fixed _tile contains an invalid TileSheet reference_ crash after mods change certain maps.
* Fixed _patched game code_ issue shown for the bundled Error Handler mod.
## 3.9
Released 22 January 2021 for Stardew Valley 1.5.4 or later.
Released 22 January 2021 for Stardew Valley 1.5.4 or later. See [release highlights](https://www.patreon.com/posts/46553874).
* For players:
* Updated for Stardew Valley 1.5.4.

View File

@ -1,9 +1,9 @@
{
"Name": "Console Commands",
"Author": "SMAPI",
"Version": "3.9.0",
"Version": "3.9.1",
"Description": "Adds SMAPI console commands that let you manipulate the game.",
"UniqueID": "SMAPI.ConsoleCommands",
"EntryDll": "ConsoleCommands.dll",
"MinimumApiVersion": "3.9.0"
"MinimumApiVersion": "3.9.1"
}

View File

@ -1,9 +1,9 @@
{
"Name": "Error Handler",
"Author": "SMAPI",
"Version": "3.9.0",
"Version": "3.9.1",
"Description": "Handles some common vanilla errors to log more useful info or avoid breaking the game.",
"UniqueID": "SMAPI.ErrorHandler",
"EntryDll": "ErrorHandler.dll",
"MinimumApiVersion": "3.9.0"
"MinimumApiVersion": "3.9.1"
}

View File

@ -1,9 +1,9 @@
{
"Name": "Save Backup",
"Author": "SMAPI",
"Version": "3.9.0",
"Version": "3.9.1",
"Description": "Automatically backs up all your saves once per day into its folder.",
"UniqueID": "SMAPI.SaveBackup",
"EntryDll": "SaveBackup.dll",
"MinimumApiVersion": "3.9.0"
"MinimumApiVersion": "3.9.1"
}

View File

@ -146,8 +146,7 @@ namespace SMAPI.Tests.Core
Mock<IModMetadata> mock = this.GetMetadata("Mod A", new string[0], allowStatusChange: true);
this.SetupMetadataForValidation(mock, new ModDataRecordVersionedFields
{
Status = ModStatus.AssumeBroken,
AlternativeUrl = "https://example.org"
Status = ModStatus.AssumeBroken
});
// act

View File

@ -69,7 +69,6 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData
return manifest.UpdateKeys != null && manifest.UpdateKeys.Any(p => !string.IsNullOrWhiteSpace(p));
// non-manifest fields
case ModDataFieldKey.AlternativeUrl:
case ModDataFieldKey.StatusReasonPhrase:
case ModDataFieldKey.StatusReasonDetails:
case ModDataFieldKey.Status:

View File

@ -6,9 +6,6 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData
/// <summary>A manifest update key.</summary>
UpdateKey,
/// <summary>An alternative URL the player can check for an updated version.</summary>
AlternativeUrl,
/// <summary>The mod's predefined compatibility status.</summary>
Status,

View File

@ -92,11 +92,6 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData
parsed.UpdateKey = field.Value;
break;
// alternative URL
case ModDataFieldKey.AlternativeUrl:
parsed.AlternativeUrl = field.Value;
break;
// status
case ModDataFieldKey.Status:
parsed.Status = (ModStatus)Enum.Parse(typeof(ModStatus), field.Value, ignoreCase: true);

View File

@ -15,9 +15,6 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData
/// <summary>The update key to apply.</summary>
public string UpdateKey { get; set; }
/// <summary>The alternative URL the player can check for an updated version.</summary>
public string AlternativeUrl { get; set; }
/// <summary>The predefined compatibility status.</summary>
public ModStatus Status { get; set; } = ModStatus.None;

View File

@ -3,6 +3,7 @@
* Metadata about some SMAPI mods used in compatibility, update, and dependency checks. This
* field shouldn't be edited by players in most cases.
*
*
* Standard fields
* ===============
* The predefined fields are documented below (only 'ID' is required). Each entry's key is the
@ -14,6 +15,10 @@
* other fields if no ID was specified. This doesn't include the latest ID, if any. Multiple
* variants can be separated with '|'.
*
* - SuppressWarnings: the mod warnings to suppress, even if they'd normally be shown. This
* should match the ModWarning enum.
*
*
* Versioned metadata
* ==================
* Each record can also specify extra metadata using the field keys below.
@ -44,11 +49,16 @@
*
* - StatusReasonDetails: a technical reason shown in TRACE logs, indicating why the status
* was overridden. If not provided, it defaults to the StatusReasonPhrase or 'no reason given'.
*
* - AlternativeUrl: a URL where the player can find an unofficial update or alternative if the
* mod is no longer compatible.
*/
"ModData": {
/*********
** Mods bundles with SMAPI
*********/
"Error Handler": {
"ID": "SMAPI.ErrorHandler",
"SuppressWarnings": "PatchesGame"
},
/*********
** Common dependencies for friendly errors
*********/

View File

@ -54,7 +54,7 @@ namespace StardewModdingAPI
** Public
****/
/// <summary>SMAPI's current semantic version.</summary>
public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("3.9.0");
public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("3.9.1");
/// <summary>The minimum supported version of Stardew Valley.</summary>
public static ISemanticVersion MinimumGameVersion { get; } = new GameVersion("1.5.4");

View File

@ -99,7 +99,17 @@ namespace StardewModdingAPI.Framework
this.OnLoadingFirstAsset = onLoadingFirstAsset;
this.FullRootDirectory = Path.Combine(Constants.ExecutionPath, rootDirectory);
this.ContentManagers.Add(
this.MainContentManager = new GameContentManager("Game1.content", serviceProvider, rootDirectory, currentCulture, this, monitor, reflection, this.OnDisposing, onLoadingFirstAsset)
this.MainContentManager = new GameContentManager(
name: "Game1.content",
serviceProvider: serviceProvider,
rootDirectory: rootDirectory,
currentCulture: currentCulture,
coordinator: this,
monitor: monitor,
reflection: reflection,
onDisposing: this.OnDisposing,
onLoadingFirstAsset: onLoadingFirstAsset
)
);
this.VanillaContentManager = new LocalizedContentManager(serviceProvider, rootDirectory);
this.CoreAssets = new CoreAssetPropagator(this.MainContentManager.AssertAndNormalizeAssetName, reflection);
@ -111,7 +121,17 @@ namespace StardewModdingAPI.Framework
{
return this.ContentManagerLock.InWriteLock(() =>
{
GameContentManager manager = new GameContentManager(name, this.MainContentManager.ServiceProvider, this.MainContentManager.RootDirectory, this.MainContentManager.CurrentCulture, this, this.Monitor, this.Reflection, this.OnDisposing, this.OnLoadingFirstAsset);
GameContentManager manager = new GameContentManager(
name: name,
serviceProvider: this.MainContentManager.ServiceProvider,
rootDirectory: this.MainContentManager.RootDirectory,
currentCulture: this.MainContentManager.CurrentCulture,
coordinator: this,
monitor: this.Monitor,
reflection: this.Reflection,
onDisposing: this.OnDisposing,
onLoadingFirstAsset: this.OnLoadingFirstAsset
);
this.ContentManagers.Add(manager);
return manager;
});

View File

@ -88,8 +88,6 @@ namespace StardewModdingAPI.Framework.ModLoading
if (url != null)
updateUrls.Add(url);
}
if (mod.DataRecord.AlternativeUrl != null)
updateUrls.Add(mod.DataRecord.AlternativeUrl);
// default update URL
updateUrls.Add("https://smapi.io/mods");

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using Microsoft.Xna.Framework.Graphics;
@ -79,7 +80,7 @@ namespace StardewModdingAPI.Metadata
});
// reload assets
IDictionary<string, bool> propagated = assets.ToDictionary(p => p.Key, p => false, StringComparer.OrdinalIgnoreCase);
IDictionary<string, bool> propagated = assets.ToDictionary(p => p.Key, _ => false, StringComparer.OrdinalIgnoreCase);
foreach (var bucket in buckets)
{
switch (bucket.Key)
@ -110,6 +111,7 @@ namespace StardewModdingAPI.Metadata
/// <param name="key">The asset key to reload.</param>
/// <param name="type">The asset type to reload.</param>
/// <returns>Returns whether an asset was loaded. The return value may be true or false, or a non-null value for true.</returns>
[SuppressMessage("ReSharper", "StringLiteralTypo", Justification = "These deliberately match the asset names.")]
private bool PropagateOther(LocalizedContentManager content, string key, Type type)
{
key = this.AssertAndNormalizeAssetName(key);
@ -492,8 +494,7 @@ namespace StardewModdingAPI.Metadata
return true;
case "terrainfeatures\\grass": // from Grass
this.ReloadGrassTextures(content, key);
return true;
return this.ReloadGrassTextures(content, key);
case "terrainfeatures\\hoedirt": // from HoeDirt
HoeDirt.lightTexture = content.Load<Texture2D>(key);
@ -785,6 +786,7 @@ namespace StardewModdingAPI.Metadata
private void ReloadMap(GameLocation location)
{
// reload map
location.interiorDoors.Clear(); // prevent errors when doors try to update tiles which no longer exist
location.reloadMap();
location.updateWarps();
location.MakeMapModifications(force: true);