Skip to content

Commit

Permalink
Merge branch 'develop' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
Pathoschild committed Mar 25, 2024
2 parents d771c60 + 63fdcd3 commit e8a86a0
Show file tree
Hide file tree
Showing 16 changed files with 89 additions and 36 deletions.
2 changes: 1 addition & 1 deletion build/common.targets
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ repo. It imports the other MSBuild files as needed.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!--set general build properties -->
<Version>4.0.1</Version>
<Version>4.0.2</Version>
<Product>SMAPI</Product>
<LangVersion>latest</LangVersion>
<AssemblySearchPaths>$(AssemblySearchPaths);{GAC}</AssemblySearchPaths>
Expand Down
10 changes: 10 additions & 0 deletions docs/release-notes.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
[README](README.md)

# Release notes
## 4.0.2
Released 24 March 2024 for Stardew Valley 1.6.0 or later.

* For players:
* Updated mod compatibility list.
* Improved status for obsolete mods to be clearer that they can be removed.
* Disabled Extra Map Layers mod.
_Extra Map Layers mod caused visual issues like dark shadows in all locations with extra map layers, since the game now handles them automatically. SMAPI now disables Extra Map Layers and ignores dependencies on it._
* When using a custom `Mods` folder path, SMAPI now logs the game folder path to simplify troubleshooting.

# 4.0.1
Released 20 March 2024 for Stardew Valley 1.6.0 or later.

Expand Down
4 changes: 2 additions & 2 deletions src/SMAPI.Mods.ConsoleCommands/manifest.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"Name": "Console Commands",
"Author": "SMAPI",
"Version": "4.0.1",
"Version": "4.0.2",
"Description": "Adds SMAPI console commands that let you manipulate the game.",
"UniqueID": "SMAPI.ConsoleCommands",
"EntryDll": "ConsoleCommands.dll",
"MinimumApiVersion": "4.0.1"
"MinimumApiVersion": "4.0.2"
}
4 changes: 2 additions & 2 deletions src/SMAPI.Mods.SaveBackup/manifest.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"Name": "Save Backup",
"Author": "SMAPI",
"Version": "4.0.1",
"Version": "4.0.2",
"Description": "Automatically backs up all your saves once per day into its folder.",
"UniqueID": "SMAPI.SaveBackup",
"EntryDll": "SaveBackup.dll",
"MinimumApiVersion": "4.0.1"
"MinimumApiVersion": "4.0.2"
}
2 changes: 1 addition & 1 deletion src/SMAPI.Tests/Core/ModResolverTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ private Mock<IModMetadata> GetMetadata(IManifest manifest, bool allowStatusChang
/// <summary>Generate a default mod data record.</summary>
private ModDataRecord GetModDataRecord()
{
return new("Default Display Name", new ModDataModel("Sample ID", null, ModWarning.None));
return new("Default Display Name", new ModDataModel("Sample ID", null, ModWarning.None, false));
}

/// <summary>Generate a default mod data versioned fields instance.</summary>
Expand Down
7 changes: 6 additions & 1 deletion src/SMAPI.Toolkit/Framework/ModData/ModDataModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ internal class ModDataModel
/// <summary>The mod warnings to suppress, even if they'd normally be shown.</summary>
public ModWarning SuppressWarnings { get; }

/// <summary>Whether to ignore dependencies on this mod ID when it's not loaded.</summary>
public bool IgnoreDependencies { get; set; }

/// <summary>This field stores properties that aren't mapped to another field before they're parsed into <see cref="Fields"/>.</summary>
[JsonExtensionData]
public IDictionary<string, JToken> ExtensionData { get; } = new Dictionary<string, JToken>();
Expand All @@ -54,11 +57,13 @@ internal class ModDataModel
/// <param name="id">The mod's current unique ID.</param>
/// <param name="formerIds">The former mod IDs (if any).</param>
/// <param name="suppressWarnings">The mod warnings to suppress, even if they'd normally be shown.</param>
public ModDataModel(string id, string? formerIds, ModWarning suppressWarnings)
/// <param name="ignoreDependencies">Whether to ignore dependencies on this mod ID when it's not loaded.</param>
public ModDataModel(string id, string? formerIds, ModWarning suppressWarnings, bool ignoreDependencies)
{
this.ID = id;
this.FormerIDs = formerIds;
this.SuppressWarnings = suppressWarnings;
this.IgnoreDependencies = ignoreDependencies;
}

/// <summary>Get a parsed representation of the <see cref="Fields"/>.</summary>
Expand Down
4 changes: 4 additions & 0 deletions src/SMAPI.Toolkit/Framework/ModData/ModDataRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ public class ModDataRecord
/// <summary>The mod warnings to suppress, even if they'd normally be shown.</summary>
public ModWarning SuppressWarnings { get; }

/// <summary>Whether to ignore dependencies on this mod ID when it's not loaded.</summary>
public bool IgnoreDependencies { get; set; }

/// <summary>The versioned field data.</summary>
public ModDataField[] Fields { get; }

Expand All @@ -38,6 +41,7 @@ internal ModDataRecord(string displayName, ModDataModel model)
this.ID = model.ID;
this.FormerIDs = model.GetFormerIDs().ToArray();
this.SuppressWarnings = model.SuppressWarnings;
this.IgnoreDependencies = model.IgnoreDependencies;
this.Fields = model.GetFields().ToArray();
}

Expand Down
4 changes: 2 additions & 2 deletions src/SMAPI.Web/Controllers/IndexController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ public async Task<ViewResult> Index()

// render view
IndexVersionModel stableVersionModel = stableVersion != null
? new IndexVersionModel(stableVersion.Version.ToString(), stableVersion.Release.Body, stableVersion.Asset.DownloadUrl, stableVersionForDevs?.Asset.DownloadUrl)
: new IndexVersionModel("unknown", "", "https://github.com/Pathoschild/SMAPI/releases", null); // just in case something goes wrong
? new IndexVersionModel(stableVersion.Version.ToString(), stableVersion.Release.Body, stableVersion.Release.WebUrl, stableVersion.Asset.DownloadUrl, stableVersionForDevs?.Asset.DownloadUrl)
: new IndexVersionModel("unknown", "", "https://github.com/Pathoschild/SMAPI/releases", "https://github.com/Pathoschild/SMAPI/releases", null); // just in case something goes wrong

// render view
var model = new IndexModel(stableVersionModel, this.SiteConfig.OtherBlurb, this.SiteConfig.SupporterList);
Expand Down
8 changes: 7 additions & 1 deletion src/SMAPI.Web/Framework/Clients/GitHub/GitRelease.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ internal class GitRelease
[JsonProperty("tag_name")]
public string Tag { get; }

/// <summary>The URL to the release web page.</summary>
[JsonProperty("html_url")]
public string WebUrl { get; }

/// <summary>The Markdown description for the release.</summary>
public string Body { get; internal set; }

Expand All @@ -38,14 +42,16 @@ internal class GitRelease
/// <summary>Construct an instance.</summary>
/// <param name="name">The display name.</param>
/// <param name="tag">The semantic version string.</param>
/// <param name="webUrl">The URL to the release web page.</param>
/// <param name="body">The Markdown description for the release.</param>
/// <param name="isDraft">Whether this is a draft version.</param>
/// <param name="isPrerelease">Whether this is a prerelease version.</param>
/// <param name="assets">The attached files.</param>
public GitRelease(string name, string tag, string? body, bool isDraft, bool isPrerelease, GitAsset[]? assets)
public GitRelease(string name, string tag, string webUrl, string? body, bool isDraft, bool isPrerelease, GitAsset[]? assets)
{
this.Name = name;
this.Tag = tag;
this.WebUrl = webUrl;
this.Body = body ?? string.Empty;
this.IsDraft = isDraft;
this.IsPrerelease = isPrerelease;
Expand Down
15 changes: 10 additions & 5 deletions src/SMAPI.Web/ViewModels/IndexVersionModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ public class IndexVersionModel
/// <summary>The Markdown description for the release.</summary>
public string Description { get; }

/// <summary>The main download URL.</summary>
/// <summary>The URL to the download page.</summary>
public string WebUrl { get; }

/// <summary>The direct download URL for the main version.</summary>
public string DownloadUrl { get; }

/// <summary>The for-developers download URL (not applicable for prerelease versions).</summary>
/// <summary>The direct download URL for the for-developers version. Not applicable for prerelease versions.</summary>
public string? DevDownloadUrl { get; }


Expand All @@ -25,12 +28,14 @@ public class IndexVersionModel
/// <summary>Construct an instance.</summary>
/// <param name="version">The release number.</param>
/// <param name="description">The Markdown description for the release.</param>
/// <param name="downloadUrl">The main download URL.</param>
/// <param name="devDownloadUrl">The for-developers download URL (not applicable for prerelease versions).</param>
internal IndexVersionModel(string version, string description, string downloadUrl, string? devDownloadUrl)
/// <param name="webUrl">The URL to the download page.</param>
/// <param name="downloadUrl">The direct download URL for the main version.</param>
/// <param name="devDownloadUrl">The direct download URL for the for-developers version. Not applicable for prerelease versions.</param>
internal IndexVersionModel(string version, string description, string webUrl, string downloadUrl, string? devDownloadUrl)
{
this.Version = version;
this.Description = description;
this.WebUrl = webUrl;
this.DownloadUrl = downloadUrl;
this.DevDownloadUrl = devDownloadUrl;
}
Expand Down
2 changes: 1 addition & 1 deletion src/SMAPI.Web/Views/Index/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<div class="dropdown-content">
<a href="https://www.nexusmods.com/stardewvalley/mods/2400"><img src="Content/images/nexus-icon.png" /> Download from Nexus</a>
<a href="https://www.curseforge.com/stardewvalley/utility/smapi"><img src="Content/images/curseforge-icon.png" /> Download from CurseForge</a>
<a href="@Model.StableVersion.DownloadUrl"><img src="Content/images/github-logo.png" /> Download from GitHub</a>
<a href="@Model.StableVersion.WebUrl"><img src="Content/images/github-logo.png" /> Download from GitHub</a>
</div>
</div>
<div><a href="https://stardewvalleywiki.com/Modding:Player_Guide" class="secondary-cta">Player guide</a></div>
Expand Down
34 changes: 25 additions & 9 deletions src/SMAPI.Web/wwwroot/SMAPI.metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,37 +109,43 @@
"Animal Mood Fix": {
"ID": "GPeters-AnimalMoodFix",
"~ | Status": "Obsolete",
"~ | StatusReasonPhrase": "the animal mood bugs were fixed in Stardew Valley 1.2."
"~ | StatusReasonPhrase": "the animal mood bugs were fixed in Stardew Valley 1.2. You can delete this mod."
},
"Bee House Flower Range Fix": {
"ID": "kirbylink.beehousefix",
"~ | Status": "Obsolete",
"~ | StatusReasonPhrase": "the bee house flower range was fixed in Stardew Valley 1.4."
"~ | StatusReasonPhrase": "the bee house flower range was fixed in Stardew Valley 1.4. You can delete this mod."
},
"Colored Chests": {
"ID": "4befde5c-731c-4853-8e4b-c5cdf946805f",
"~ | Status": "Obsolete",
"~ | StatusReasonPhrase": "colored chests were added in Stardew Valley 1.1."
"~ | StatusReasonPhrase": "colored chests were added in Stardew Valley 1.1. You can delete this mod."
},
"Error Handler": {
"ID": "SMAPI.ErrorHandler",
"~ | Status": "Obsolete",
"~ | StatusReasonPhrase": "its error handling was integrated into Stardew Valley 1.6."
"~ | StatusReasonPhrase": "its error handling was integrated into Stardew Valley 1.6. You can delete this mod."
},
"Extra Map Layers": {
"ID": "aedenthorn.ExtraMapLayers",
"~0.3.10 | Status": "Obsolete",
"~0.3.10 | StatusReasonPhrase": "extra map layer support was added in Stardew Valley 1.6. You can delete this mod.",
"IgnoreDependencies": true
},
"Modder Serialization Utility": {
"ID": "SerializerUtils-0-1",
"~ | Status": "Obsolete",
"~ | StatusReasonPhrase": "it's no longer maintained or used."
"~ | StatusReasonPhrase": "it's no longer maintained or used. You can delete this mod."
},
"No Debug Mode": {
"ID": "NoDebugMode",
"~ | Status": "Obsolete",
"~ | StatusReasonPhrase": "debug mode was removed in SMAPI 1.0."
"~ | StatusReasonPhrase": "debug mode was removed in SMAPI 1.0. You can delete this mod."
},
"Split Screen": {
"ID": "Ilyaki.SplitScreen",
"~ | Status": "Obsolete",
"~ | StatusReasonPhrase": "split-screen mode was added in Stardew Valley 1.5"
"~ | StatusReasonPhrase": "split-screen mode was added in Stardew Valley 1.5. You can delete this mod."
},

/*********
Expand All @@ -150,6 +156,11 @@
"~0.3.1 | Status": "AssumeBroken",
"~0.3.1 | StatusReasonDetails": "Harmony patches fail at runtime"
},
"Aimon's Fancy Farmhouse": {
"ID": "Aimon111.RedesignedFarmHouseLayoutAlt",
"~2.0.0 | Status": "AssumeBroken",
"~2.0.0 | StatusReasonDetails": "breaks farmhouse layout and causes runtime crashes"
},
"All Chests Menu": {
"ID": "aedenthorn.AllChestsMenu",
"~0.3.1 | Status": "AssumeBroken",
Expand All @@ -172,8 +183,8 @@
},
"Better Elevator": {
"ID": "aedenthorn.BetterElevator",
"~2.1.0 | Status": "AssumeBroken",
"~2.1.0 | StatusReasonDetails": "Harmony patches fail at runtime"
"~0.2.4 | Status": "AssumeBroken",
"~0.2.4 | StatusReasonDetails": "Harmony patches fail at runtime"
},
"Better Crab Pots": {
"ID": "EpicBellyFlop45.BetterCrabPots",
Expand Down Expand Up @@ -505,6 +516,11 @@
"~1.0.0 | Status": "AssumeBroken",
"~1.0.0 | StatusReasonDetails": "affected by breaking changes in the Json Assets mod API"
},
"TimeSpeed": {
"ID": "cantorsdust.TimeSpeed",
"~2.7.7-alpha.20240220 | Status": "AssumeBroken",
"~2.7.7-alpha.20240220 | StatusReasonDetails": "causes runtime time issues before 2.7.7"
},
"Wealth is Health": {
"ID": "QiTheMysterious.WealthIsHealth",
"~0.1.2 | Status": "AssumeBroken",
Expand Down
2 changes: 1 addition & 1 deletion src/SMAPI/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ internal static class EarlyConstants
internal static int? LogScreenId { get; set; }

/// <summary>SMAPI's current raw semantic version.</summary>
internal static string RawApiVersion = "4.0.1";
internal static string RawApiVersion = "4.0.2";
}

/// <summary>Contains SMAPI's constants and assumptions.</summary>
Expand Down
2 changes: 1 addition & 1 deletion src/SMAPI/Framework/Logging/LogManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ public void LogIntro(string modsPath, IDictionary<string, object?> customSetting
// log basic info
this.Monitor.Log($"Mods go here: {modsPath}", LogLevel.Info);
if (modsPath != Constants.DefaultModsPath)
this.Monitor.Log("(Using custom --mods-path argument.)");
this.Monitor.Log($"(Using custom --mods-path argument. Game folder: {Constants.GamePath}.)");
this.Monitor.Log($"Log started at {DateTime.UtcNow:s} UTC");

// log custom settings
Expand Down
1 change: 1 addition & 0 deletions src/SMAPI/Framework/ModLoading/ModResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ from entry in dependencies
// sorted successfully
case ModDependencyStatus.Sorted:
case ModDependencyStatus.Failed when !dependency.IsRequired: // ignore failed optional dependency
case ModDependencyStatus.Failed when modDatabase.Get(dependency.ID)?.IgnoreDependencies is true: // ignore failed dependency based on SMAPI metadata
break;

// failed, which means this mod can't be loaded either
Expand Down
24 changes: 15 additions & 9 deletions src/SMAPI/Framework/SCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1846,15 +1846,21 @@ private bool TryLoadMod(IModMetadata mod, IModMetadata[] mods, AssemblyLoader as
// Although dependencies are validated before mods are loaded, a dependency may have failed to load.
foreach (IManifestDependency dependency in manifest.Dependencies.Where(p => p.IsRequired))
{
if (this.ModRegistry.Get(dependency.UniqueID) == null)
{
string dependencyName = mods
.FirstOrDefault(otherMod => otherMod.HasID(dependency.UniqueID))
?.DisplayName ?? dependency.UniqueID;
errorReasonPhrase = $"it needs the '{dependencyName}' mod, which couldn't be loaded.";
failReason = ModFailReason.MissingDependencies;
return false;
}
// not missing
if (this.ModRegistry.Get(dependency.UniqueID) != null)
continue;

// ignored in compatibility list (e.g. fully replaced by the game code)
if (modDatabase.Get(dependency.UniqueID)?.IgnoreDependencies is true)
continue;

// mark failed
string dependencyName = mods
.FirstOrDefault(otherMod => otherMod.HasID(dependency.UniqueID))
?.DisplayName ?? dependency.UniqueID;
errorReasonPhrase = $"it needs the '{dependencyName}' mod, which couldn't be loaded.";
failReason = ModFailReason.MissingDependencies;
return false;
}

// load as content pack
Expand Down

0 comments on commit e8a86a0

Please sign in to comment.