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 Aug 29, 2022
2 parents a1bc96d + 8b6c732 commit e0838a2
Show file tree
Hide file tree
Showing 13 changed files with 55 additions and 21 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>3.16.0</Version>
<Version>3.16.1</Version>
<Product>SMAPI</Product>
<LangVersion>latest</LangVersion>
<AssemblySearchPaths>$(AssemblySearchPaths);{GAC}</AssemblySearchPaths>
Expand Down
7 changes: 7 additions & 0 deletions docs/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
_If needed, you can update to SMAPI 3.16.0 first and then install the latest version._
-->

## 3.16.1
Released 29 August 2022 for Stardew Valley 1.5.6 or later.

* For players:
* Updated PyTK compatibility mode for the latest PyTK version.
* Fixed broken mods sometimes incorrectly listed as duplicate.

## 3.16.0
Released 22 August 2022 for Stardew Valley 1.5.6 or later. See [release highlights](https://www.patreon.com/posts/70797008).

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": "3.16.0",
"Version": "3.16.1",
"Description": "Adds SMAPI console commands that let you manipulate the game.",
"UniqueID": "SMAPI.ConsoleCommands",
"EntryDll": "ConsoleCommands.dll",
"MinimumApiVersion": "3.16.0"
"MinimumApiVersion": "3.16.1"
}
8 changes: 6 additions & 2 deletions src/SMAPI.Mods.ErrorHandler/ModEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
using System.Reflection;
using StardewModdingAPI.Events;
using StardewModdingAPI.Internal.Patching;
#if SMAPI_DEPRECATED
using StardewModdingAPI.Mods.ErrorHandler.ModPatches;
#endif
using StardewModdingAPI.Mods.ErrorHandler.Patches;
using StardewValley;

Expand Down Expand Up @@ -39,10 +41,12 @@ public override void Entry(IModHelper helper)
new ObjectPatcher(),
new SaveGamePatcher(this.Monitor, this.OnSaveContentRemoved),
new SpriteBatchPatcher(),
new UtilityPatcher(),
new UtilityPatcher()

#if SMAPI_DEPRECATED
// mod patches
new PyTkPatcher(helper.ModRegistry)
, new PyTkPatcher(helper.ModRegistry)
#endif
);

// hook events
Expand Down
6 changes: 4 additions & 2 deletions src/SMAPI.Mods.ErrorHandler/ModPatches/PyTkPatcher.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#if SMAPI_DEPRECATED
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
Expand All @@ -10,7 +11,7 @@
using StardewModdingAPI.Internal.Patching;

//
// This is part of a three-part fix for PyTK 1.23.0 and earlier. When removing this, search
// This is part of a three-part fix for PyTK 1.23.* and earlier. When removing this, search
// 'Platonymous.Toolkit' to find the other part in SMAPI and Content Patcher.
//

Expand Down Expand Up @@ -38,7 +39,7 @@ internal class PyTkPatcher : BasePatcher
public PyTkPatcher(IModRegistry modRegistry)
{
IModMetadata? pyTk = (IModMetadata?)modRegistry.Get(@"Platonymous.Toolkit");
if (pyTk is not null && !pyTk.Manifest.Version.IsNewerThan("1.23.0"))
if (pyTk is not null && pyTk.Manifest.Version.IsOlderThan("1.24.0"))
PyTkPatcher.PyTk = pyTk;
}

Expand Down Expand Up @@ -77,3 +78,4 @@ public override void Apply(Harmony harmony, IMonitor monitor)
}
}
}
#endif
4 changes: 2 additions & 2 deletions src/SMAPI.Mods.ErrorHandler/manifest.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"Name": "Error Handler",
"Author": "SMAPI",
"Version": "3.16.0",
"Version": "3.16.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.16.0"
"MinimumApiVersion": "3.16.1"
}
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": "3.16.0",
"Version": "3.16.1",
"Description": "Automatically backs up all your saves once per day into its folder.",
"UniqueID": "SMAPI.SaveBackup",
"EntryDll": "SaveBackup.dll",
"MinimumApiVersion": "3.16.0"
"MinimumApiVersion": "3.16.1"
}
4 changes: 2 additions & 2 deletions src/SMAPI.Web/Views/LogParser/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
LogModInfo[] outdatedMods = log?.Mods.Where(mod => mod.HasUpdate).ToArray() ?? Array.Empty<LogModInfo>();
LogModInfo? errorHandler = log?.Mods.FirstOrDefault(p => p.IsCodeMod && p.Name == "Error Handler");
bool hasOlderErrorHandler = errorHandler?.GetParsedVersion() is not null && log?.ApiVersionParsed is not null && log.ApiVersionParsed.IsNewerThan(errorHandler.GetParsedVersion());
bool isPyTkCompatibilityMode = log?.ApiVersionParsed?.IsOlderThan("3.15.0") is false && log.Mods.Any(p => p.IsCodeMod && p.Name == "PyTK" && p.GetParsedVersion()?.IsOlderThan("1.23.1") is true);
bool isPyTkCompatibilityMode = log?.ApiVersionParsed?.IsOlderThan("3.15.0") is false && log.Mods.Any(p => p.IsCodeMod && p.Name == "PyTK" && p.GetParsedVersion()?.IsOlderThan("1.24.0") is true);

// get filters
IDictionary<string, bool> defaultFilters = Enum
Expand Down Expand Up @@ -257,7 +257,7 @@ else if (log?.IsValid == true)
}
@if (isPyTkCompatibilityMode)
{
<li>PyTK 1.23.0 or earlier isn't compatible with newer SMAPI performance optimizations. This may increase loading times or in-game lag.</li>
<li>PyTK 1.23.* or earlier isn't compatible with newer SMAPI performance optimizations. This may increase loading times or in-game lag.</li>
}
@if (outdatedMods.Any())
{
Expand Down
2 changes: 1 addition & 1 deletion src/SMAPI/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ internal static class EarlyConstants
internal static int? LogScreenId { get; set; }

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

/// <summary>Contains SMAPI's constants and assumptions.</summary>
Expand Down
6 changes: 5 additions & 1 deletion src/SMAPI/Framework/ContentManagers/ModContentManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ internal sealed class ModContentManager : BaseContentManager
/*********
** Accessors
*********/
#if SMAPI_DEPRECATED
/// <summary>Whether to enable legacy compatibility mode for PyTK scale-up textures.</summary>
internal static bool EnablePyTkLegacyMode;
#endif


/*********
Expand Down Expand Up @@ -202,6 +204,7 @@ private T LoadImageFile<T>(IAssetName assetName, FileInfo file)
bool expectsRawData = typeof(T).IsAssignableTo(typeof(IRawTextureData));
bool asRawData = expectsRawData || this.UseRawImageLoading;

#if SMAPI_DEPRECATED
// disable raw data if PyTK will rescale the image (until it supports raw data)
if (asRawData && !expectsRawData)
{
Expand All @@ -212,9 +215,10 @@ private T LoadImageFile<T>(IAssetName assetName, FileInfo file)
// current file has a '.pytk.json' rescale file though, since PyTK may still
// rescale it if the original asset or another edit gets rescaled.
asRawData = false;
this.Monitor.LogOnce("Enabled compatibility mode for PyTK 1.23.0 or earlier. This won't cause any issues, but may impact performance.", LogLevel.Warn);
this.Monitor.LogOnce("Enabled compatibility mode for PyTK 1.23.* or earlier. This won't cause any issues, but may impact performance. This will no longer be supported in the upcoming SMAPI 4.0.0.", LogLevel.Warn);
}
}
#endif

// load
if (asRawData)
Expand Down
8 changes: 7 additions & 1 deletion src/SMAPI/Framework/ModLoading/ModFailReason.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ internal enum ModFailReason
/// <summary>Multiple copies of the mod are installed.</summary>
Duplicate,

/// <summary>The folder is empty or contains only ignored files.</summary>
EmptyFolder,

/// <summary>The mod has incompatible code instructions, needs a newer SMAPI version, or is marked 'assume broken' in the SMAPI metadata list.</summary>
Incompatible,

Expand All @@ -22,6 +25,9 @@ internal enum ModFailReason
MissingDependencies,

/// <summary>The mod is marked obsolete in the SMAPI metadata list.</summary>
Obsolete
Obsolete,

/// <summary>The folder is an XNB mod, which can't be loaded through SMAPI.</summary>
XnbMod
}
}
15 changes: 12 additions & 3 deletions src/SMAPI/Framework/ModLoading/ModResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,16 @@ public IEnumerable<IModMetadata> ReadManifests(ModToolkit toolkit, string rootPa
if (shouldIgnore)
metadata.SetStatus(status, ModFailReason.DisabledByDotConvention, "disabled by dot convention");
else if (status == ModMetadataStatus.Failed)
metadata.SetStatus(status, ModFailReason.InvalidManifest, folder.ManifestParseErrorText);
{
ModFailReason reason = folder.ManifestParseError switch
{
ModParseError.EmptyFolder or ModParseError.EmptyVortexFolder => ModFailReason.EmptyFolder,
ModParseError.XnbMod => ModFailReason.XnbMod,
_ => ModFailReason.InvalidManifest
};

metadata.SetStatus(status, reason, folder.ManifestParseErrorText);
}

yield return metadata;
}
Expand Down Expand Up @@ -218,12 +227,12 @@ public void ValidateManifests(IEnumerable<IModMetadata> mods, ISemanticVersion a
{
var duplicatesByID = mods
.GroupBy(mod => mod.Manifest?.UniqueID?.Trim(), mod => mod, StringComparer.OrdinalIgnoreCase)
.Where(p => p.Count() > 1);
.Where(p => !string.IsNullOrEmpty(p.Key) && p.Count() > 1);
foreach (var group in duplicatesByID)
{
foreach (IModMetadata mod in group)
{
if (mod.Status == ModMetadataStatus.Failed && mod.FailReason != ModFailReason.InvalidManifest)
if (mod.Status == ModMetadataStatus.Failed && mod.FailReason is not (ModFailReason.InvalidManifest or ModFailReason.LoadFailed or ModFailReason.MissingDependencies))
continue;

string folderList = string.Join(", ", group.Select(p => p.GetRelativePathWithRoot()).OrderBy(p => p));
Expand Down
6 changes: 4 additions & 2 deletions src/SMAPI/Framework/SCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1672,13 +1672,15 @@ private void LoadMods(IModMetadata[] mods, JsonHelper jsonHelper, ContentCoordin
// initialize translations
this.ReloadTranslations(loaded);

#if SMAPI_DEPRECATED
// set temporary PyTK compatibility mode
// This is part of a three-part fix for PyTK 1.23.0 and earlier. When removing this,
// This is part of a three-part fix for PyTK 1.23.* and earlier. When removing this,
// search 'Platonymous.Toolkit' to find the other part in SMAPI and Content Patcher.
{
IModInfo? pyTk = this.ModRegistry.Get("Platonymous.Toolkit");
ModContentManager.EnablePyTkLegacyMode = pyTk is not null && pyTk.Manifest.Version.IsOlderThan("1.23.1");
ModContentManager.EnablePyTkLegacyMode = pyTk is not null && pyTk.Manifest.Version.IsOlderThan("1.24.0");
}
#endif

// initialize loaded non-content-pack mods
this.Monitor.Log("Launching mods...", LogLevel.Debug);
Expand Down

0 comments on commit e0838a2

Please sign in to comment.