From 009a387526ee10b18d0ed3030d6e8868edf17203 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 1 May 2018 18:44:39 -0400 Subject: unify SMAPI.AssemblyRewriters and SMAPI.Common projects --- src/SMAPI.Web/StardewModdingAPI.Web.csproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/SMAPI.Web/StardewModdingAPI.Web.csproj') diff --git a/src/SMAPI.Web/StardewModdingAPI.Web.csproj b/src/SMAPI.Web/StardewModdingAPI.Web.csproj index e2eee8a8..bc337e7e 100644 --- a/src/SMAPI.Web/StardewModdingAPI.Web.csproj +++ b/src/SMAPI.Web/StardewModdingAPI.Web.csproj @@ -22,6 +22,8 @@ - + + + -- cgit From 60040854a3b95ab220a42c087bda7f9011dda8ca Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 3 May 2018 01:38:08 -0400 Subject: switch back to shared project due to installer issues --- build/build.targets | 92 --------------- build/common.targets | 125 +++++++++++++++++++++ build/constants.targets | 25 ----- .../StardewModdingAPI.Installer.csproj | 10 +- src/SMAPI.Internal/Properties/AssemblyInfo.cs | 9 -- src/SMAPI.Internal/SMAPI.Internal.projitems | 18 +++ .../StardewModdingAPI.Internal.csproj | 50 --------- .../StardewModdingAPI.Internal.shproj | 13 +++ .../StardewModdingAPI.ModBuildConfig.csproj | 9 +- .../StardewModdingAPI.Mods.ConsoleCommands.csproj | 3 +- src/SMAPI.Web/StardewModdingAPI.Web.csproj | 4 +- src/SMAPI.sln | 23 ++-- src/SMAPI/StardewModdingAPI.csproj | 10 +- 13 files changed, 173 insertions(+), 218 deletions(-) delete mode 100644 build/build.targets create mode 100644 build/common.targets delete mode 100644 build/constants.targets delete mode 100644 src/SMAPI.Internal/Properties/AssemblyInfo.cs create mode 100644 src/SMAPI.Internal/SMAPI.Internal.projitems delete mode 100644 src/SMAPI.Internal/StardewModdingAPI.Internal.csproj create mode 100644 src/SMAPI.Internal/StardewModdingAPI.Internal.shproj (limited to 'src/SMAPI.Web/StardewModdingAPI.Web.csproj') diff --git a/build/build.targets b/build/build.targets deleted file mode 100644 index 270fd95d..00000000 --- a/build/build.targets +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - False - - - False - - - False - - - False - - - - - $(GamePath)\Netcode.dll - False - - - $(GamePath)\Stardew Valley.exe - False - - - $(GamePath)\xTile.dll - False - False - - - - - - - - $(GamePath)\MonoGame.Framework.dll - False - False - - - - - $(GamePath)\StardewValley.exe - False - - - $(GamePath)\xTile.dll - False - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Program - $(GamePath)\StardewModdingAPI.exe - $(GamePath) - - - - - diff --git a/build/common.targets b/build/common.targets new file mode 100644 index 00000000..44c2c071 --- /dev/null +++ b/build/common.targets @@ -0,0 +1,125 @@ + + + + + + + + + $(HOME)/GOG Games/Stardew Valley/game + $(HOME)/.local/share/Steam/steamapps/common/Stardew Valley + $(HOME)/.steam/steam/steamapps/common/Stardew Valley + + /Applications/Stardew Valley.app/Contents/MacOS + $(HOME)/Library/Application Support/Steam/steamapps/common/Stardew Valley/Contents/MacOS + + C:\Program Files (x86)\GalaxyClient\Games\Stardew Valley + C:\Program Files (x86)\GOG Galaxy\Games\Stardew Valley + C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley + $([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\GOG.com\Games\1453375253', 'PATH', null, RegistryView.Registry32)) + $([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 413150', 'InstallLocation', null, RegistryView.Registry64, RegistryView.Registry32)) + + + $(DefineConstants);SMAPI_FOR_WINDOWS + + + + + + + + + + + + + + + + False + + + False + + + False + + + False + + + + + $(GamePath)\Netcode.dll + False + + + $(GamePath)\Stardew Valley.exe + False + + + $(GamePath)\xTile.dll + False + False + + + + + + + + $(GamePath)\MonoGame.Framework.dll + False + False + + + + + $(GamePath)\StardewValley.exe + False + + + $(GamePath)\xTile.dll + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Program + $(GamePath)\StardewModdingAPI.exe + $(GamePath) + + + + + diff --git a/build/constants.targets b/build/constants.targets deleted file mode 100644 index 3e10462a..00000000 --- a/build/constants.targets +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - $(HOME)/GOG Games/Stardew Valley/game - $(HOME)/.local/share/Steam/steamapps/common/Stardew Valley - $(HOME)/.steam/steam/steamapps/common/Stardew Valley - - /Applications/Stardew Valley.app/Contents/MacOS - $(HOME)/Library/Application Support/Steam/steamapps/common/Stardew Valley/Contents/MacOS - - C:\Program Files (x86)\GalaxyClient\Games\Stardew Valley - C:\Program Files (x86)\GOG Galaxy\Games\Stardew Valley - C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley - $([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\GOG.com\Games\1453375253', 'PATH', null, RegistryView.Registry32)) - $([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 413150', 'InstallLocation', null, RegistryView.Registry64, RegistryView.Registry32)) - - - $(DefineConstants);SMAPI_FOR_WINDOWS - - diff --git a/src/SMAPI.Installer/StardewModdingAPI.Installer.csproj b/src/SMAPI.Installer/StardewModdingAPI.Installer.csproj index dd349e09..2ad7e82a 100644 --- a/src/SMAPI.Installer/StardewModdingAPI.Installer.csproj +++ b/src/SMAPI.Installer/StardewModdingAPI.Installer.csproj @@ -57,14 +57,8 @@ PreserveNewest - - - {10db0676-9fc1-4771-a2c8-e2519f091e49} - StardewModdingAPI.Internal - - + - - + \ No newline at end of file diff --git a/src/SMAPI.Internal/Properties/AssemblyInfo.cs b/src/SMAPI.Internal/Properties/AssemblyInfo.cs deleted file mode 100644 index b314b353..00000000 --- a/src/SMAPI.Internal/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -[assembly: AssemblyTitle("SMAPI.Internal")] -[assembly: AssemblyDescription("Contains internal SMAPI code that's shared between its projects.")] -[assembly: InternalsVisibleTo("StardewModdingAPI")] -[assembly: InternalsVisibleTo("StardewModdingAPI.ModBuildConfig")] -[assembly: InternalsVisibleTo("StardewModdingAPI.Installer")] -[assembly: InternalsVisibleTo("StardewModdingAPI.Web")] diff --git a/src/SMAPI.Internal/SMAPI.Internal.projitems b/src/SMAPI.Internal/SMAPI.Internal.projitems new file mode 100644 index 00000000..764cb12e --- /dev/null +++ b/src/SMAPI.Internal/SMAPI.Internal.projitems @@ -0,0 +1,18 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + 85208f8d-6fd1-4531-be05-7142490f59fe + + + SMAPI.Internal + + + + + + + + + \ No newline at end of file diff --git a/src/SMAPI.Internal/StardewModdingAPI.Internal.csproj b/src/SMAPI.Internal/StardewModdingAPI.Internal.csproj deleted file mode 100644 index a87dcb0a..00000000 --- a/src/SMAPI.Internal/StardewModdingAPI.Internal.csproj +++ /dev/null @@ -1,50 +0,0 @@ - - - - - Debug - x86 - {10DB0676-9FC1-4771-A2C8-E2519F091E49} - Library - Properties - StardewModdingAPI.Internal - StardewModdingAPI.Internal - v4.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - Properties\GlobalAssemblyInfo.cs - - - - - - - - - - - \ No newline at end of file diff --git a/src/SMAPI.Internal/StardewModdingAPI.Internal.shproj b/src/SMAPI.Internal/StardewModdingAPI.Internal.shproj new file mode 100644 index 00000000..a098828a --- /dev/null +++ b/src/SMAPI.Internal/StardewModdingAPI.Internal.shproj @@ -0,0 +1,13 @@ + + + + 85208f8d-6fd1-4531-be05-7142490f59fe + 14.0 + + + + + + + + diff --git a/src/SMAPI.ModBuildConfig/StardewModdingAPI.ModBuildConfig.csproj b/src/SMAPI.ModBuildConfig/StardewModdingAPI.ModBuildConfig.csproj index c6d25c19..e0ea876f 100644 --- a/src/SMAPI.ModBuildConfig/StardewModdingAPI.ModBuildConfig.csproj +++ b/src/SMAPI.ModBuildConfig/StardewModdingAPI.ModBuildConfig.csproj @@ -55,13 +55,8 @@ - - - {10db0676-9fc1-4771-a2c8-e2519f091e49} - StardewModdingAPI.Internal - - + - + \ No newline at end of file diff --git a/src/SMAPI.Mods.ConsoleCommands/StardewModdingAPI.Mods.ConsoleCommands.csproj b/src/SMAPI.Mods.ConsoleCommands/StardewModdingAPI.Mods.ConsoleCommands.csproj index 15c1c9a8..d1f72c6c 100644 --- a/src/SMAPI.Mods.ConsoleCommands/StardewModdingAPI.Mods.ConsoleCommands.csproj +++ b/src/SMAPI.Mods.ConsoleCommands/StardewModdingAPI.Mods.ConsoleCommands.csproj @@ -94,6 +94,5 @@ - - + \ No newline at end of file diff --git a/src/SMAPI.Web/StardewModdingAPI.Web.csproj b/src/SMAPI.Web/StardewModdingAPI.Web.csproj index bc337e7e..e4678269 100644 --- a/src/SMAPI.Web/StardewModdingAPI.Web.csproj +++ b/src/SMAPI.Web/StardewModdingAPI.Web.csproj @@ -22,8 +22,6 @@ - - - + diff --git a/src/SMAPI.sln b/src/SMAPI.sln index 282d8397..c8760dcb 100644 --- a/src/SMAPI.sln +++ b/src/SMAPI.sln @@ -24,8 +24,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StardewModdingAPI.Installer {F1A573B0-F436-472C-AE29-0B91EA6B9F8F} = {F1A573B0-F436-472C-AE29-0B91EA6B9F8F} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StardewModdingAPI.Internal", "SMAPI.Internal\StardewModdingAPI.Internal.csproj", "{10DB0676-9FC1-4771-A2C8-E2519F091E49}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StardewModdingAPI.Tests", "SMAPI.Tests\StardewModdingAPI.Tests.csproj", "{36CCB19E-92EB-48C7-9615-98EEFD45109B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StardewModdingAPI.Web", "SMAPI.Web\StardewModdingAPI.Web.csproj", "{A308F679-51A3-4006-92D5-BAEC7EBD01A1}" @@ -43,8 +41,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{EB35A917-6 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{09CF91E5-5BAB-4650-A200-E5EA9A633046}" ProjectSection(SolutionItems) = preProject - ..\build\build.targets = ..\build\build.targets - ..\build\constants.targets = ..\build\constants.targets + ..\build\common.targets = ..\build\common.targets ..\build\GlobalAssemblyInfo.cs = ..\build\GlobalAssemblyInfo.cs ..\build\prepare-install-package.targets = ..\build\prepare-install-package.targets ..\build\prepare-nuget-package.targets = ..\build\prepare-nuget-package.targets @@ -59,7 +56,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StardewModdingAPI.ModBuildC EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SMAPI.ModBuildConfig.Analyzer.Tests", "SMAPI.ModBuildConfig.Analyzer.Tests\SMAPI.ModBuildConfig.Analyzer.Tests.csproj", "{0CF97929-B0D0-4D73-B7BF-4FF7191035F9}" EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "StardewModdingAPI.Internal", "SMAPI.Internal\StardewModdingAPI.Internal.shproj", "{85208F8D-6FD1-4531-BE05-7142490F59FE}" +EndProject Global + GlobalSection(SharedMSBuildProjectFiles) = preSolution + SMAPI.Internal\SMAPI.Internal.projitems*{443ddf81-6aaf-420a-a610-3459f37e5575}*SharedItemsImports = 4 + SMAPI.Internal\SMAPI.Internal.projitems*{85208f8d-6fd1-4531-be05-7142490f59fe}*SharedItemsImports = 13 + SMAPI.Internal\SMAPI.Internal.projitems*{ea4f1e80-743f-4a1d-9757-ae66904a196a}*SharedItemsImports = 4 + SMAPI.Internal\SMAPI.Internal.projitems*{f1a573b0-f436-472c-ae29-0b91ea6b9f8f}*SharedItemsImports = 4 + EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|Mixed Platforms = Debug|Mixed Platforms @@ -99,16 +104,6 @@ Global {443DDF81-6AAF-420A-A610-3459F37E5575}.Release|Mixed Platforms.Build.0 = Release|x86 {443DDF81-6AAF-420A-A610-3459F37E5575}.Release|x86.ActiveCfg = Release|x86 {443DDF81-6AAF-420A-A610-3459F37E5575}.Release|x86.Build.0 = Release|x86 - {10DB0676-9FC1-4771-A2C8-E2519F091E49}.Debug|Any CPU.ActiveCfg = Debug|x86 - {10DB0676-9FC1-4771-A2C8-E2519F091E49}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {10DB0676-9FC1-4771-A2C8-E2519F091E49}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {10DB0676-9FC1-4771-A2C8-E2519F091E49}.Debug|x86.ActiveCfg = Debug|x86 - {10DB0676-9FC1-4771-A2C8-E2519F091E49}.Debug|x86.Build.0 = Debug|x86 - {10DB0676-9FC1-4771-A2C8-E2519F091E49}.Release|Any CPU.ActiveCfg = Release|x86 - {10DB0676-9FC1-4771-A2C8-E2519F091E49}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {10DB0676-9FC1-4771-A2C8-E2519F091E49}.Release|Mixed Platforms.Build.0 = Release|x86 - {10DB0676-9FC1-4771-A2C8-E2519F091E49}.Release|x86.ActiveCfg = Release|x86 - {10DB0676-9FC1-4771-A2C8-E2519F091E49}.Release|x86.Build.0 = Release|x86 {36CCB19E-92EB-48C7-9615-98EEFD45109B}.Debug|Any CPU.ActiveCfg = Debug|x86 {36CCB19E-92EB-48C7-9615-98EEFD45109B}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 {36CCB19E-92EB-48C7-9615-98EEFD45109B}.Debug|Mixed Platforms.Build.0 = Debug|x86 diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj index ca6459fe..1822b134 100644 --- a/src/SMAPI/StardewModdingAPI.csproj +++ b/src/SMAPI/StardewModdingAPI.csproj @@ -304,16 +304,10 @@ false - - - {10db0676-9fc1-4771-a2c8-e2519f091e49} - StardewModdingAPI.Internal - - + - - + \ No newline at end of file -- cgit From 3129f67eb1f162e06d96854f319b10ccf583f0aa Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 25 May 2018 01:14:40 -0400 Subject: add semantic version to toolkit (#532) --- src/SMAPI.Installer/InteractiveInstaller.cs | 12 +- src/SMAPI.Internal/SMAPI.Internal.projitems | 1 - src/SMAPI.Internal/SemanticVersionImpl.cs | 199 ----------------- .../Framework/ModFileManager.cs | 6 +- .../StardewModdingAPI.ModBuildConfig.csproj | 6 + src/SMAPI.Web/Controllers/IndexController.cs | 8 +- src/SMAPI.Web/Framework/LogParsing/LogParser.cs | 4 +- src/SMAPI.Web/Framework/VersionConstraint.cs | 4 +- src/SMAPI.Web/StardewModdingAPI.Web.csproj | 3 + src/SMAPI/SemanticVersion.cs | 16 +- src/StardewModdingAPI.Toolkit/ISemanticVersion.cs | 46 ++++ .../Properties/AssemblyInfo.cs | 1 + src/StardewModdingAPI.Toolkit/SemanticVersion.cs | 239 +++++++++++++++++++++ 13 files changed, 325 insertions(+), 220 deletions(-) delete mode 100644 src/SMAPI.Internal/SemanticVersionImpl.cs create mode 100644 src/StardewModdingAPI.Toolkit/ISemanticVersion.cs create mode 100644 src/StardewModdingAPI.Toolkit/SemanticVersion.cs (limited to 'src/SMAPI.Web/StardewModdingAPI.Web.csproj') diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs index ace560e5..6e4cb95d 100644 --- a/src/SMAPI.Installer/InteractiveInstaller.cs +++ b/src/SMAPI.Installer/InteractiveInstaller.cs @@ -152,7 +152,7 @@ namespace StardewModdingApi.Installer ** Get platform & set window title ****/ Platform platform = EnvironmentUtility.DetectPlatform(); - Console.Title = $"SMAPI {new SemanticVersionImpl(this.GetType().Assembly.GetName().Version)} installer on {platform} {EnvironmentUtility.GetFriendlyPlatformName(platform)}"; + Console.Title = $"SMAPI {this.GetDisplayVersion(this.GetType().Assembly.GetName().Version)} installer on {platform} {EnvironmentUtility.GetFriendlyPlatformName(platform)}"; Console.WriteLine(); #if SMAPI_FOR_WINDOWS @@ -421,6 +421,16 @@ namespace StardewModdingApi.Installer /********* ** Private methods *********/ + /// Get the display text for an assembly version. + /// The assembly version. + private string GetDisplayVersion(Version version) + { + string str = $"{version.Major}.{version.Minor}"; + if (version.Build != 0) + str += $".{version.Build}"; + return str; + } + /// Get the value of a key in the Windows registry. /// The full path of the registry key relative to HKLM. /// The name of the value. diff --git a/src/SMAPI.Internal/SMAPI.Internal.projitems b/src/SMAPI.Internal/SMAPI.Internal.projitems index dadae4b0..33b8cbfa 100644 --- a/src/SMAPI.Internal/SMAPI.Internal.projitems +++ b/src/SMAPI.Internal/SMAPI.Internal.projitems @@ -16,6 +16,5 @@ - \ No newline at end of file diff --git a/src/SMAPI.Internal/SemanticVersionImpl.cs b/src/SMAPI.Internal/SemanticVersionImpl.cs deleted file mode 100644 index 7ae34f07..00000000 --- a/src/SMAPI.Internal/SemanticVersionImpl.cs +++ /dev/null @@ -1,199 +0,0 @@ -using System; -using System.Text.RegularExpressions; - -namespace StardewModdingAPI.Internal -{ - /// A low-level implementation of a semantic version with an optional release tag. - /// The implementation is defined by Semantic Version 2.0 (http://semver.org/). - internal class SemanticVersionImpl : IComparable - { - /********* - ** Accessors - *********/ - /// The major version incremented for major API changes. - public int Major { get; } - - /// The minor version incremented for backwards-compatible changes. - public int Minor { get; } - - /// The patch version for backwards-compatible bug fixes. - public int Patch { get; } - - /// An optional prerelease tag. - public string Tag { get; } - - /// A regex pattern matching a version within a larger string. - internal const string UnboundedVersionPattern = @"(?>(?0|[1-9]\d*))\.(?>(?0|[1-9]\d*))(?>(?:\.(?0|[1-9]\d*))?)(?:-(?(?>[a-z0-9]+[\-\.]?)+))?"; - - /// A regular expression matching a semantic version string. - /// - /// This pattern is derived from the BNF documentation in the semver repo, - /// with three important deviations intended to support Stardew Valley mod conventions: - /// - allows short-form "x.y" versions; - /// - allows hyphens in prerelease tags as synonyms for dots (like "-unofficial-update.3"); - /// - doesn't allow '+build' suffixes. - /// - internal static readonly Regex Regex = new Regex($@"^{SemanticVersionImpl.UnboundedVersionPattern}$", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ExplicitCapture); - - /********* - ** Public methods - *********/ - /// Construct an instance. - /// The major version incremented for major API changes. - /// The minor version incremented for backwards-compatible changes. - /// The patch version for backwards-compatible bug fixes. - /// An optional prerelease tag. - public SemanticVersionImpl(int major, int minor, int patch, string tag = null) - { - this.Major = major; - this.Minor = minor; - this.Patch = patch; - this.Tag = this.GetNormalisedTag(tag); - } - - /// Construct an instance. - /// The assembly version. - /// The is null. - public SemanticVersionImpl(Version version) - { - if (version == null) - throw new ArgumentNullException(nameof(version), "The input version can't be null."); - - this.Major = version.Major; - this.Minor = version.Minor; - this.Patch = version.Build; - } - - /// Construct an instance. - /// The semantic version string. - /// The is null. - /// The is not a valid semantic version. - public SemanticVersionImpl(string version) - { - // parse - if (version == null) - throw new ArgumentNullException(nameof(version), "The input version string can't be null."); - var match = SemanticVersionImpl.Regex.Match(version.Trim()); - if (!match.Success) - throw new FormatException($"The input '{version}' isn't a valid semantic version."); - - // initialise - this.Major = int.Parse(match.Groups["major"].Value); - this.Minor = match.Groups["minor"].Success ? int.Parse(match.Groups["minor"].Value) : 0; - this.Patch = match.Groups["patch"].Success ? int.Parse(match.Groups["patch"].Value) : 0; - this.Tag = match.Groups["prerelease"].Success ? this.GetNormalisedTag(match.Groups["prerelease"].Value) : null; - } - - /// Get an integer indicating whether this version precedes (less than 0), supercedes (more than 0), or is equivalent to (0) the specified version. - /// The version to compare with this instance. - /// The value is null. - public int CompareTo(SemanticVersionImpl other) - { - if (other == null) - throw new ArgumentNullException(nameof(other)); - return this.CompareTo(other.Major, other.Minor, other.Patch, other.Tag); - } - - - /// Get an integer indicating whether this version precedes (less than 0), supercedes (more than 0), or is equivalent to (0) the specified version. - /// The major version to compare with this instance. - /// The minor version to compare with this instance. - /// The patch version to compare with this instance. - /// The prerelease tag to compare with this instance. - public int CompareTo(int otherMajor, int otherMinor, int otherPatch, string otherTag) - { - const int same = 0; - const int curNewer = 1; - const int curOlder = -1; - - // compare stable versions - if (this.Major != otherMajor) - return this.Major.CompareTo(otherMajor); - if (this.Minor != otherMinor) - return this.Minor.CompareTo(otherMinor); - if (this.Patch != otherPatch) - return this.Patch.CompareTo(otherPatch); - if (this.Tag == otherTag) - return same; - - // stable supercedes pre-release - bool curIsStable = string.IsNullOrWhiteSpace(this.Tag); - bool otherIsStable = string.IsNullOrWhiteSpace(otherTag); - if (curIsStable) - return curNewer; - if (otherIsStable) - return curOlder; - - // compare two pre-release tag values - string[] curParts = this.Tag.Split('.', '-'); - string[] otherParts = otherTag.Split('.', '-'); - for (int i = 0; i < curParts.Length; i++) - { - // longer prerelease tag supercedes if otherwise equal - if (otherParts.Length <= i) - return curNewer; - - // compare if different - if (curParts[i] != otherParts[i]) - { - // compare numerically if possible - { - if (int.TryParse(curParts[i], out int curNum) && int.TryParse(otherParts[i], out int otherNum)) - return curNum.CompareTo(otherNum); - } - - // else compare lexically - return string.Compare(curParts[i], otherParts[i], StringComparison.OrdinalIgnoreCase); - } - } - - // fallback (this should never happen) - return string.Compare(this.ToString(), new SemanticVersionImpl(otherMajor, otherMinor, otherPatch, otherTag).ToString(), StringComparison.InvariantCultureIgnoreCase); - } - - /// Get a string representation of the version. - public override string ToString() - { - // version - string result = this.Patch != 0 - ? $"{this.Major}.{this.Minor}.{this.Patch}" - : $"{this.Major}.{this.Minor}"; - - // tag - string tag = this.Tag; - if (tag != null) - result += $"-{tag}"; - return result; - } - - /// Parse a version string without throwing an exception if it fails. - /// The version string. - /// The parsed representation. - /// Returns whether parsing the version succeeded. - internal static bool TryParse(string version, out SemanticVersionImpl parsed) - { - try - { - parsed = new SemanticVersionImpl(version); - return true; - } - catch - { - parsed = null; - return false; - } - } - - - /********* - ** Private methods - *********/ - /// Get a normalised build tag. - /// The tag to normalise. - private string GetNormalisedTag(string tag) - { - tag = tag?.Trim(); - return !string.IsNullOrWhiteSpace(tag) ? tag : null; - } - } -} diff --git a/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs b/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs index 3fec8215..41e0201d 100644 --- a/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs +++ b/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Web.Script.Serialization; -using StardewModdingAPI.Internal; +using StardewModdingAPI.Toolkit; namespace StardewModdingAPI.ModBuildConfig.Framework { @@ -132,9 +132,9 @@ namespace StardewModdingAPI.ModBuildConfig.Framework int minor = versionFields.ContainsKey("MinorVersion") ? (int)versionFields["MinorVersion"] : 0; int patch = versionFields.ContainsKey("PatchVersion") ? (int)versionFields["PatchVersion"] : 0; string tag = versionFields.ContainsKey("Build") ? (string)versionFields["Build"] : null; - return new SemanticVersionImpl(major, minor, patch, tag).ToString(); + return new SemanticVersion(major, minor, patch, tag).ToString(); } - return new SemanticVersionImpl(versionObj.ToString()).ToString(); // SMAPI 2.0+ + return new SemanticVersion(versionObj.ToString()).ToString(); // SMAPI 2.0+ } diff --git a/src/SMAPI.ModBuildConfig/StardewModdingAPI.ModBuildConfig.csproj b/src/SMAPI.ModBuildConfig/StardewModdingAPI.ModBuildConfig.csproj index e0ea876f..6a52daac 100644 --- a/src/SMAPI.ModBuildConfig/StardewModdingAPI.ModBuildConfig.csproj +++ b/src/SMAPI.ModBuildConfig/StardewModdingAPI.ModBuildConfig.csproj @@ -55,6 +55,12 @@ + + + {ea5cfd2e-9453-4d29-b80f-8e0ea23f4ac6} + StardewModdingAPI.Toolkit + + diff --git a/src/SMAPI.Web/Controllers/IndexController.cs b/src/SMAPI.Web/Controllers/IndexController.cs index 08b7363a..0cc3c37a 100644 --- a/src/SMAPI.Web/Controllers/IndexController.cs +++ b/src/SMAPI.Web/Controllers/IndexController.cs @@ -5,7 +5,7 @@ using System.Text.RegularExpressions; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; -using StardewModdingAPI.Internal; +using StardewModdingAPI.Toolkit; using StardewModdingAPI.Web.Framework.Clients.GitHub; using StardewModdingAPI.Web.ViewModels; @@ -105,7 +105,7 @@ namespace StardewModdingAPI.Web.Controllers foreach (GitAsset asset in release.Assets) { Match match = Regex.Match(asset.FileName, @"SMAPI-(?[\d\.]+(?:-.+)?)-installer(?-for-developers)?.zip"); - if (!match.Success || !SemanticVersionImpl.TryParse(match.Groups["version"].Value, out SemanticVersionImpl version)) + if (!match.Success || !SemanticVersion.TryParse(match.Groups["version"].Value, out ISemanticVersion version)) continue; bool isBeta = version.Tag != null; bool isForDevs = match.Groups["forDevs"].Success; @@ -127,7 +127,7 @@ namespace StardewModdingAPI.Web.Controllers public GitAsset Asset { get; } /// The SMAPI version. - public SemanticVersionImpl Version { get; } + public ISemanticVersion Version { get; } /// Whether this is a beta download. public bool IsBeta { get; } @@ -145,7 +145,7 @@ namespace StardewModdingAPI.Web.Controllers /// The SMAPI version. /// Whether this is a beta download. /// Whether this is a 'for developers' download. - public ReleaseVersion(GitRelease release, GitAsset asset, SemanticVersionImpl version, bool isBeta, bool isForDevs) + public ReleaseVersion(GitRelease release, GitAsset asset, ISemanticVersion version, bool isBeta, bool isForDevs) { this.Release = release; this.Asset = asset; diff --git a/src/SMAPI.Web/Framework/LogParsing/LogParser.cs b/src/SMAPI.Web/Framework/LogParsing/LogParser.cs index 163176fd..c50e643a 100644 --- a/src/SMAPI.Web/Framework/LogParsing/LogParser.cs +++ b/src/SMAPI.Web/Framework/LogParsing/LogParser.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; -using StardewModdingAPI.Internal; +using StardewModdingAPI.Toolkit; using StardewModdingAPI.Web.Framework.LogParsing.Models; namespace StardewModdingAPI.Web.Framework.LogParsing @@ -31,7 +31,7 @@ namespace StardewModdingAPI.Web.Framework.LogParsing /// A regex pattern matching an entry in SMAPI's mod list. /// The author name and description are optional. - private readonly Regex ModListEntryPattern = new Regex(@"^ (?.+?) (?" + SemanticVersionImpl.UnboundedVersionPattern + @")(?: by (?[^\|]+))?(?: \| (?.+))?$", RegexOptions.Compiled | RegexOptions.IgnoreCase); + private readonly Regex ModListEntryPattern = new Regex(@"^ (?.+?) (?" + SemanticVersion.UnboundedVersionPattern + @")(?: by (?[^\|]+))?(?: \| (?.+))?$", RegexOptions.Compiled | RegexOptions.IgnoreCase); /// A regex pattern matching the start of SMAPI's content pack list. private readonly Regex ContentPackListStartPattern = new Regex(@"^Loaded \d+ content packs:$", RegexOptions.Compiled | RegexOptions.IgnoreCase); diff --git a/src/SMAPI.Web/Framework/VersionConstraint.cs b/src/SMAPI.Web/Framework/VersionConstraint.cs index 1502f5d8..2d6ec603 100644 --- a/src/SMAPI.Web/Framework/VersionConstraint.cs +++ b/src/SMAPI.Web/Framework/VersionConstraint.cs @@ -1,5 +1,5 @@ using Microsoft.AspNetCore.Routing.Constraints; -using StardewModdingAPI.Internal; +using StardewModdingAPI.Toolkit; namespace StardewModdingAPI.Web.Framework { @@ -11,6 +11,6 @@ namespace StardewModdingAPI.Web.Framework *********/ /// Construct an instance. public VersionConstraint() - : base(SemanticVersionImpl.Regex) { } + : base(SemanticVersion.Regex) { } } } diff --git a/src/SMAPI.Web/StardewModdingAPI.Web.csproj b/src/SMAPI.Web/StardewModdingAPI.Web.csproj index e4678269..202a8376 100644 --- a/src/SMAPI.Web/StardewModdingAPI.Web.csproj +++ b/src/SMAPI.Web/StardewModdingAPI.Web.csproj @@ -23,5 +23,8 @@ + + + diff --git a/src/SMAPI/SemanticVersion.cs b/src/SMAPI/SemanticVersion.cs index 9db1cf14..3ee3ccf3 100644 --- a/src/SMAPI/SemanticVersion.cs +++ b/src/SMAPI/SemanticVersion.cs @@ -1,6 +1,5 @@ using System; using Newtonsoft.Json; -using StardewModdingAPI.Internal; namespace StardewModdingAPI { @@ -11,7 +10,7 @@ namespace StardewModdingAPI ** Properties *********/ /// The underlying semantic version implementation. - private readonly SemanticVersionImpl Version; + private readonly Toolkit.ISemanticVersion Version; /********* @@ -40,20 +39,20 @@ namespace StardewModdingAPI /// An optional build tag. [JsonConstructor] public SemanticVersion(int majorVersion, int minorVersion, int patchVersion, string build = null) - : this(new SemanticVersionImpl(majorVersion, minorVersion, patchVersion, build)) { } + : this(new Toolkit.SemanticVersion(majorVersion, minorVersion, patchVersion, build)) { } /// Construct an instance. /// The semantic version string. /// The is null. /// The is not a valid semantic version. public SemanticVersion(string version) - : this(new SemanticVersionImpl(version)) { } + : this(new Toolkit.SemanticVersion(version)) { } /// Construct an instance. /// The assembly version. /// The is null. public SemanticVersion(Version version) - : this(new SemanticVersionImpl(version)) { } + : this(new Toolkit.SemanticVersion(version)) { } /// Whether this is a pre-release version. public bool IsPrerelease() @@ -67,7 +66,8 @@ namespace StardewModdingAPI /// The implementation is defined by Semantic Version 2.0 (http://semver.org/). public int CompareTo(ISemanticVersion other) { - return this.Version.CompareTo(other.MajorVersion, other.MinorVersion, other.PatchVersion, other.Build); + Toolkit.ISemanticVersion toolkitOther = new Toolkit.SemanticVersion(other.MajorVersion, other.MinorVersion, other.PatchVersion, other.Build); + return this.Version.CompareTo(toolkitOther); } /// Get whether this version is older than the specified version. @@ -137,7 +137,7 @@ namespace StardewModdingAPI /// Returns whether parsing the version succeeded. internal static bool TryParse(string version, out ISemanticVersion parsed) { - if (SemanticVersionImpl.TryParse(version, out SemanticVersionImpl versionImpl)) + if (Toolkit.SemanticVersion.TryParse(version, out Toolkit.ISemanticVersion versionImpl)) { parsed = new SemanticVersion(versionImpl); return true; @@ -153,7 +153,7 @@ namespace StardewModdingAPI *********/ /// Construct an instance. /// The underlying semantic version implementation. - private SemanticVersion(SemanticVersionImpl version) + private SemanticVersion(Toolkit.ISemanticVersion version) { this.Version = version; } diff --git a/src/StardewModdingAPI.Toolkit/ISemanticVersion.cs b/src/StardewModdingAPI.Toolkit/ISemanticVersion.cs new file mode 100644 index 00000000..ca62d393 --- /dev/null +++ b/src/StardewModdingAPI.Toolkit/ISemanticVersion.cs @@ -0,0 +1,46 @@ +using System; + +namespace StardewModdingAPI.Toolkit +{ + /// A semantic version with an optional release tag. + public interface ISemanticVersion : IComparable, IEquatable + { + /********* + ** Accessors + *********/ + /// The major version incremented for major API changes. + int Major { get; } + + /// The minor version incremented for backwards-compatible changes. + int Minor { get; } + + /// The patch version for backwards-compatible bug fixes. + int Patch { get; } + + /// An optional prerelease tag. + string Tag { get; } + + + /********* + ** Accessors + *********/ + /// Whether this is a pre-release version. + bool IsPrerelease(); + + /// Get whether this version is older than the specified version. + /// The version to compare with this instance. + bool IsOlderThan(ISemanticVersion other); + + /// Get whether this version is newer than the specified version. + /// The version to compare with this instance. + bool IsNewerThan(ISemanticVersion other); + + /// Get whether this version is between two specified versions (inclusively). + /// The minimum version. + /// The maximum version. + bool IsBetween(ISemanticVersion min, ISemanticVersion max); + + /// Get a string representation of the version. + string ToString(); + } +} diff --git a/src/StardewModdingAPI.Toolkit/Properties/AssemblyInfo.cs b/src/StardewModdingAPI.Toolkit/Properties/AssemblyInfo.cs index 20118fce..9b55dac6 100644 --- a/src/StardewModdingAPI.Toolkit/Properties/AssemblyInfo.cs +++ b/src/StardewModdingAPI.Toolkit/Properties/AssemblyInfo.cs @@ -4,3 +4,4 @@ using System.Runtime.CompilerServices; [assembly: AssemblyTitle("SMAPI.Toolkit")] [assembly: AssemblyDescription("")] [assembly: InternalsVisibleTo("StardewModdingAPI")] +[assembly: InternalsVisibleTo("StardewModdingAPI.Web")] diff --git a/src/StardewModdingAPI.Toolkit/SemanticVersion.cs b/src/StardewModdingAPI.Toolkit/SemanticVersion.cs new file mode 100644 index 00000000..bd85f990 --- /dev/null +++ b/src/StardewModdingAPI.Toolkit/SemanticVersion.cs @@ -0,0 +1,239 @@ +using System; +using System.Text.RegularExpressions; + +namespace StardewModdingAPI.Toolkit +{ + /// A semantic version with an optional release tag. + /// The implementation is defined by Semantic Version 2.0 (http://semver.org/). + public class SemanticVersion : ISemanticVersion + { + /********* + ** Properties + *********/ + /// A regex pattern matching a version within a larger string. + internal const string UnboundedVersionPattern = @"(?>(?0|[1-9]\d*))\.(?>(?0|[1-9]\d*))(?>(?:\.(?0|[1-9]\d*))?)(?:-(?(?>[a-z0-9]+[\-\.]?)+))?"; + + /// A regular expression matching a semantic version string. + /// + /// This pattern is derived from the BNF documentation in the semver repo, + /// with three important deviations intended to support Stardew Valley mod conventions: + /// - allows short-form "x.y" versions; + /// - allows hyphens in prerelease tags as synonyms for dots (like "-unofficial-update.3"); + /// - doesn't allow '+build' suffixes. + /// + internal static readonly Regex Regex = new Regex($@"^{SemanticVersion.UnboundedVersionPattern}$", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ExplicitCapture); + + + /********* + ** Accessors + *********/ + /// The major version incremented for major API changes. + public int Major { get; } + + /// The minor version incremented for backwards-compatible changes. + public int Minor { get; } + + /// The patch version for backwards-compatible bug fixes. + public int Patch { get; } + + /// An optional prerelease tag. + public string Tag { get; } + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// The major version incremented for major API changes. + /// The minor version incremented for backwards-compatible changes. + /// The patch version for backwards-compatible fixes. + /// An optional prerelease tag. + public SemanticVersion(int major, int minor, int patch, string tag = null) + { + this.Major = major; + this.Minor = minor; + this.Patch = patch; + this.Tag = this.GetNormalisedTag(tag); + } + + /// Construct an instance. + /// The assembly version. + /// The is null. + public SemanticVersion(Version version) + { + if (version == null) + throw new ArgumentNullException(nameof(version), "The input version can't be null."); + + this.Major = version.Major; + this.Minor = version.Minor; + this.Patch = version.Build; + } + + /// Construct an instance. + /// The semantic version string. + /// The is null. + /// The is not a valid semantic version. + public SemanticVersion(string version) + { + // parse + if (version == null) + throw new ArgumentNullException(nameof(version), "The input version string can't be null."); + var match = SemanticVersion.Regex.Match(version.Trim()); + if (!match.Success) + throw new FormatException($"The input '{version}' isn't a valid semantic version."); + + // initialise + this.Major = int.Parse(match.Groups["major"].Value); + this.Minor = match.Groups["minor"].Success ? int.Parse(match.Groups["minor"].Value) : 0; + this.Patch = match.Groups["patch"].Success ? int.Parse(match.Groups["patch"].Value) : 0; + this.Tag = match.Groups["prerelease"].Success ? this.GetNormalisedTag(match.Groups["prerelease"].Value) : null; + } + + /// Get an integer indicating whether this version precedes (less than 0), supercedes (more than 0), or is equivalent to (0) the specified version. + /// The version to compare with this instance. + /// The value is null. + public int CompareTo(ISemanticVersion other) + { + if (other == null) + throw new ArgumentNullException(nameof(other)); + return this.CompareTo(other.Major, other.Minor, other.Patch, other.Tag); + } + + /// Indicates whether the current object is equal to another object of the same type. + /// true if the current object is equal to the parameter; otherwise, false. + /// An object to compare with this object. + public bool Equals(ISemanticVersion other) + { + return other != null && this.CompareTo(other) == 0; + } + + /// Whether this is a pre-release version. + public bool IsPrerelease() + { + return !string.IsNullOrWhiteSpace(this.Tag); + } + + /// Get whether this version is older than the specified version. + /// The version to compare with this instance. + public bool IsOlderThan(ISemanticVersion other) + { + return this.CompareTo(other) < 0; + } + + /// Get whether this version is newer than the specified version. + /// The version to compare with this instance. + public bool IsNewerThan(ISemanticVersion other) + { + return this.CompareTo(other) > 0; + } + + /// Get whether this version is between two specified versions (inclusively). + /// The minimum version. + /// The maximum version. + public bool IsBetween(ISemanticVersion min, ISemanticVersion max) + { + return this.CompareTo(min) >= 0 && this.CompareTo(max) <= 0; + } + + /// Get a string representation of the version. + public override string ToString() + { + // version + string result = this.Patch != 0 + ? $"{this.Major}.{this.Minor}.{this.Patch}" + : $"{this.Major}.{this.Minor}"; + + // tag + string tag = this.Tag; + if (tag != null) + result += $"-{tag}"; + return result; + } + + /// Parse a version string without throwing an exception if it fails. + /// The version string. + /// The parsed representation. + /// Returns whether parsing the version succeeded. + public static bool TryParse(string version, out ISemanticVersion parsed) + { + try + { + parsed = new SemanticVersion(version); + return true; + } + catch + { + parsed = null; + return false; + } + } + + + /********* + ** Private methods + *********/ + /// Get a normalised build tag. + /// The tag to normalise. + private string GetNormalisedTag(string tag) + { + tag = tag?.Trim(); + return !string.IsNullOrWhiteSpace(tag) ? tag : null; + } + + /// Get an integer indicating whether this version precedes (less than 0), supercedes (more than 0), or is equivalent to (0) the specified version. + /// The major version to compare with this instance. + /// The minor version to compare with this instance. + /// The patch version to compare with this instance. + /// The prerelease tag to compare with this instance. + private int CompareTo(int otherMajor, int otherMinor, int otherPatch, string otherTag) + { + const int same = 0; + const int curNewer = 1; + const int curOlder = -1; + + // compare stable versions + if (this.Major != otherMajor) + return this.Major.CompareTo(otherMajor); + if (this.Minor != otherMinor) + return this.Minor.CompareTo(otherMinor); + if (this.Patch != otherPatch) + return this.Patch.CompareTo(otherPatch); + if (this.Tag == otherTag) + return same; + + // stable supercedes pre-release + bool curIsStable = string.IsNullOrWhiteSpace(this.Tag); + bool otherIsStable = string.IsNullOrWhiteSpace(otherTag); + if (curIsStable) + return curNewer; + if (otherIsStable) + return curOlder; + + // compare two pre-release tag values + string[] curParts = this.Tag.Split('.', '-'); + string[] otherParts = otherTag.Split('.', '-'); + for (int i = 0; i < curParts.Length; i++) + { + // longer prerelease tag supercedes if otherwise equal + if (otherParts.Length <= i) + return curNewer; + + // compare if different + if (curParts[i] != otherParts[i]) + { + // compare numerically if possible + { + if (int.TryParse(curParts[i], out int curNum) && int.TryParse(otherParts[i], out int otherNum)) + return curNum.CompareTo(otherNum); + } + + // else compare lexically + return string.Compare(curParts[i], otherParts[i], StringComparison.OrdinalIgnoreCase); + } + } + + // fallback (this should never happen) + return string.Compare(this.ToString(), new SemanticVersion(otherMajor, otherMinor, otherPatch, otherTag).ToString(), StringComparison.InvariantCultureIgnoreCase); + } + } +} -- cgit From 03860cca868aceb6af67d9a6ad171c8ceb9be7eb Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 25 May 2018 19:26:09 -0400 Subject: add wiki compatibility list parsing to toolkit (#532) --- src/SMAPI.Web/StardewModdingAPI.Web.csproj | 2 +- .../Clients/Wiki/WikiCompatibilityClient.cs | 142 +++++++++++++++++++++ .../Clients/Wiki/WikiCompatibilityEntry.cs | 24 ++++ .../Clients/Wiki/WikiCompatibilityStatus.cs | 24 ++++ src/StardewModdingAPI.Toolkit/ModToolkit.cs | 33 +++++ .../StardewModdingAPI.Toolkit.csproj | 2 + 6 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs create mode 100644 src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityEntry.cs create mode 100644 src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs create mode 100644 src/StardewModdingAPI.Toolkit/ModToolkit.cs (limited to 'src/SMAPI.Web/StardewModdingAPI.Web.csproj') diff --git a/src/SMAPI.Web/StardewModdingAPI.Web.csproj b/src/SMAPI.Web/StardewModdingAPI.Web.csproj index 202a8376..9210565a 100644 --- a/src/SMAPI.Web/StardewModdingAPI.Web.csproj +++ b/src/SMAPI.Web/StardewModdingAPI.Web.csproj @@ -17,7 +17,7 @@ - + diff --git a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs new file mode 100644 index 00000000..be03a120 --- /dev/null +++ b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading.Tasks; +using HtmlAgilityPack; +using Pathoschild.Http.Client; + +namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki +{ + /// An HTTP client for fetching mod metadata from the wiki compatibility list. + public class WikiCompatibilityClient : IDisposable + { + /********* + ** Properties + *********/ + /// The underlying HTTP client. + private readonly IClient Client; + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// The user agent for the wiki API. + /// The base URL for the wiki API. + public WikiCompatibilityClient(string userAgent, string baseUrl = "https://stardewvalleywiki.com/mediawiki/api.php") + { + this.Client = new FluentClient(baseUrl).SetUserAgent(userAgent); + } + + /// Fetch mod compatibility entries. + public async Task FetchAsync() + { + // fetch HTML + ResponseModel response = await this.Client + .GetAsync("") + .WithArguments(new + { + action = "parse", + page = "Modding:SMAPI_compatibility", + format = "json" + }) + .As(); + string html = response.Parse.Text["*"]; + + // parse HTML + var doc = new HtmlDocument(); + doc.LoadHtml(html); + + // find mod entries + HtmlNodeCollection modNodes = doc.DocumentNode.SelectNodes("table[@id='mod-list']//tr[@class='mod']"); + if (modNodes == null) + throw new InvalidOperationException("Can't parse wiki compatibility list, no mods found."); + + // parse + return this.ParseEntries(modNodes).ToArray(); + } + + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + public void Dispose() + { + this.Client?.Dispose(); + } + + + /********* + ** Private methods + *********/ + /// Parse valid mod compatibility entries. + /// The HTML compatibility entries. + private IEnumerable ParseEntries(IEnumerable nodes) + { + foreach (HtmlNode node in nodes) + { + // parse status + WikiCompatibilityStatus status; + { + string rawStatus = node.GetAttributeValue("data-status", null); + if (rawStatus == null) + continue; // not a mod node? + if (!Enum.TryParse(rawStatus, true, out status)) + throw new InvalidOperationException($"Unknown status '{rawStatus}' when parsing compatibility list."); + } + + // parse unofficial version + ISemanticVersion unofficialVersion = null; + { + string rawUnofficialVersion = node.GetAttributeValue("data-unofficial-version", null); + SemanticVersion.TryParse(rawUnofficialVersion, out unofficialVersion); + } + + // parse other fields + int? nexusID = this.GetNullableIntAttribute(node, "data-nexus-id"); + int? chucklefishID = this.GetNullableIntAttribute(node, "data-chucklefish-id"); + string githubRepo = node.GetAttributeValue("data-github", null); + string customSourceUrl = node.GetAttributeValue("data-custom-source", null); + + // yield model + yield return new WikiCompatibilityEntry + { + Status = status, + NexusID = nexusID, + ChucklefishID = chucklefishID, + GitHubRepo = githubRepo, + CustomSourceUrl = customSourceUrl, + UnofficialVersion = unofficialVersion + }; + } + } + + /// Get a nullable integer attribute value. + /// The HTML node. + /// The attribute name. + private int? GetNullableIntAttribute(HtmlNode node, string attributeName) + { + string raw = node.GetAttributeValue(attributeName, null); + if (raw != null && int.TryParse(raw, out int value)) + return value; + return null; + } + + /// The response model for the MediaWiki parse API. + [SuppressMessage("ReSharper", "ClassNeverInstantiated.Local")] + [SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local")] + private class ResponseModel + { + /// The parse API results. + public ResponseParseModel Parse { get; set; } + } + + /// The inner response model for the MediaWiki parse API. + [SuppressMessage("ReSharper", "ClassNeverInstantiated.Local")] + [SuppressMessage("ReSharper", "CollectionNeverUpdated.Local")] + [SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local")] + private class ResponseParseModel + { + /// The parsed text. + public IDictionary Text { get; set; } + } + } +} diff --git a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityEntry.cs b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityEntry.cs new file mode 100644 index 00000000..ceeb2de5 --- /dev/null +++ b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityEntry.cs @@ -0,0 +1,24 @@ +namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki +{ + /// An entry in the mod compatibility list. + public class WikiCompatibilityEntry + { + /// The mod ID on Nexus. + public int? NexusID { get; set; } + + /// The mod ID in the Chucklefish mod repo. + public int? ChucklefishID { get; set; } + + /// The GitHub repository in the form 'owner/repo'. + public string GitHubRepo { get; set; } + + /// The URL to a non-GitHub source repo. + public string CustomSourceUrl { get; set; } + + /// The version of the latest unofficial update, if applicable. + public ISemanticVersion UnofficialVersion { get; set; } + + /// The compatibility status. + public WikiCompatibilityStatus Status { get; set; } + } +} diff --git a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs new file mode 100644 index 00000000..06252b2f --- /dev/null +++ b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs @@ -0,0 +1,24 @@ +namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki +{ + /// The compatibility status for a mod. + public enum WikiCompatibilityStatus + { + /// The mod is compatible. + Ok = 0, + + /// The mod is compatible if you use an optional official download. + Optional = 1, + + /// The mod isn't compatible, but the player can fix it or there's a good alternative. + Workaround = 2, + + /// The mod isn't compatible. + Broken = 3, + + /// The mod is no longer maintained by the author, and an unofficial update or continuation is unlikely. + Abandoned = 4, + + /// The mod is no longer needed and should be removed. + Obsolete = 5 + } +} diff --git a/src/StardewModdingAPI.Toolkit/ModToolkit.cs b/src/StardewModdingAPI.Toolkit/ModToolkit.cs new file mode 100644 index 00000000..6136186e --- /dev/null +++ b/src/StardewModdingAPI.Toolkit/ModToolkit.cs @@ -0,0 +1,33 @@ +using System.Threading.Tasks; +using StardewModdingAPI.Toolkit.Framework.Clients.Wiki; + +namespace StardewModdingAPI.Toolkit +{ + /// A convenience wrapper for the various tools. + public class ModToolkit + { + /********* + ** Properties + *********/ + /// The default HTTP user agent for the toolkit. + private readonly string UserAgent; + + + /********* + ** Public methods + *********/ + /// Construct an instance. + public ModToolkit() + { + ISemanticVersion version = new SemanticVersion(this.GetType().Assembly.GetName().Version); + this.UserAgent = $"SMAPI Mod Handler Toolkit/{version}"; + } + + /// Extract mod metadata from the wiki compatibility list. + public async Task GetWikiCompatibilityListAsync() + { + var client = new WikiCompatibilityClient(this.UserAgent); + return await client.FetchAsync(); + } + } +} diff --git a/src/StardewModdingAPI.Toolkit/StardewModdingAPI.Toolkit.csproj b/src/StardewModdingAPI.Toolkit/StardewModdingAPI.Toolkit.csproj index 6859d825..6688a2a1 100644 --- a/src/StardewModdingAPI.Toolkit/StardewModdingAPI.Toolkit.csproj +++ b/src/StardewModdingAPI.Toolkit/StardewModdingAPI.Toolkit.csproj @@ -10,7 +10,9 @@ + + -- cgit From 9d33aaf832652a2183af863db6103bf6f8e5a682 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 24 Jun 2018 18:53:33 -0400 Subject: update web/toolkit packages --- src/SMAPI.Web/StardewModdingAPI.Web.csproj | 14 +++++++------- .../StardewModdingAPI.Toolkit.csproj | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/SMAPI.Web/StardewModdingAPI.Web.csproj') diff --git a/src/SMAPI.Web/StardewModdingAPI.Web.csproj b/src/SMAPI.Web/StardewModdingAPI.Web.csproj index 9210565a..a409e6eb 100644 --- a/src/SMAPI.Web/StardewModdingAPI.Web.csproj +++ b/src/SMAPI.Web/StardewModdingAPI.Web.csproj @@ -10,13 +10,13 @@ - - - - - - - + + + + + + + diff --git a/src/StardewModdingAPI.Toolkit/StardewModdingAPI.Toolkit.csproj b/src/StardewModdingAPI.Toolkit/StardewModdingAPI.Toolkit.csproj index 6688a2a1..dda7c17c 100644 --- a/src/StardewModdingAPI.Toolkit/StardewModdingAPI.Toolkit.csproj +++ b/src/StardewModdingAPI.Toolkit/StardewModdingAPI.Toolkit.csproj @@ -10,7 +10,7 @@ - + -- cgit From 583cb91f4a3429549b8e56081737e6a410ebd1a4 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 28 Jun 2018 20:59:39 -0400 Subject: use mod DB in web API to get default update keys for mod IDs (#532) --- docs/release-notes.md | 15 +- src/SMAPI.Web/Controllers/ModsApiController.cs | 22 +- src/SMAPI.Web/StardewModdingAPI.Web.csproj | 5 + .../wwwroot/StardewModdingAPI.metadata.json | 1668 ++++++++++++++++++++ src/SMAPI/StardewModdingAPI.csproj | 7 +- src/SMAPI/StardewModdingAPI.metadata.json | 1668 -------------------- 6 files changed, 1707 insertions(+), 1678 deletions(-) create mode 100644 src/SMAPI.Web/wwwroot/StardewModdingAPI.metadata.json delete mode 100644 src/SMAPI/StardewModdingAPI.metadata.json (limited to 'src/SMAPI.Web/StardewModdingAPI.Web.csproj') diff --git a/docs/release-notes.md b/docs/release-notes.md index 329ea3ad..062f902e 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -3,13 +3,16 @@ * For players: * Updated for Stardew Valley 1.3 (no longer compatible with earlier versions). * Added a bundled Save Backup mod. - * Added beta update channel. * Added prompt when in beta channel and a new version is found. * Added friendly error when game can't start audio. - * Added console warning for mods which don't have update checks configured. - * Added update checks for optional mod files on Nexus. * Added `player_add name` command, which lets you add items to your inventory by name instead of ID. * Improved how mod warnings are shown in the console. + * Improved update checks: + * added beta update channel; + * added support for optional files on Nexus; + * added console warning for mods which don't have update checks configured; + * fixed mod update checks failing if a mod only has prerelease versions on GitHub; + * fixed Nexus mod update alerts not showing HTTPS links. * Fixed `SEHException` errors and performance issues in some cases. * Fixed console color scheme on Mac or in PowerShell, configurable via `StardewModdingAPI.config.json`. * Fixed installer error on Linux/Mac in some cases. @@ -20,9 +23,7 @@ * Fixed `world_setseason` command not running season-change logic. * Fixed `world_setseason` command not normalising the season value. * Fixed `world_settime` sometimes breaking NPC schedules (e.g. so they stay in bed). - * Fixed mod update checks failing if a mod only has prerelease versions on GitHub. * Fixed launch issue for Linux players with some terminals. (Thanks to HanFox and kurumushi!) - * Fixed Nexus mod update alerts not showing HTTPS links. * Fixed issue where a mod crashing in `CanEdit` or `CanLoad` could cause an abort-retry loop. * Renamed `install.exe` to `install on Windows.exe` to avoid confusion. * Updated compatibility list. @@ -79,6 +80,10 @@ * Added Harmony for SMAPI's internal use to patch game functions for events. * Added metadata dump option in `StardewModdingAPI.config.json` for troubleshooting some cases. * Rewrote input suppression using new SDV 1.3 APIs. + * Rewrote update checks: + * Moved most logic into the web API. + * Changed web API to require mod ID. + * Changed web API to also fetch update keys from SMAPI's internal mod DB. * Rewrote world/player state tracking: * much more efficient than previous method; * uses net field events where available; diff --git a/src/SMAPI.Web/Controllers/ModsApiController.cs b/src/SMAPI.Web/Controllers/ModsApiController.cs index c5a1705d..960602f4 100644 --- a/src/SMAPI.Web/Controllers/ModsApiController.cs +++ b/src/SMAPI.Web/Controllers/ModsApiController.cs @@ -1,13 +1,16 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Options; using StardewModdingAPI.Toolkit; using StardewModdingAPI.Toolkit.Framework.Clients.WebApi; +using StardewModdingAPI.Toolkit.Framework.ModData; using StardewModdingAPI.Web.Framework.Clients.Chucklefish; using StardewModdingAPI.Web.Framework.Clients.GitHub; using StardewModdingAPI.Web.Framework.Clients.Nexus; @@ -39,18 +42,23 @@ namespace StardewModdingAPI.Web.Controllers /// A regex which matches SMAPI-style semantic version. private readonly string VersionRegex; + /// The internal mod metadata list. + private readonly ModDatabase ModDatabase; + /********* ** Public methods *********/ /// Construct an instance. + /// The web hosting environment. /// The cache in which to store mod metadata. /// The config settings for mod update checks. /// The Chucklefish API client. /// The GitHub API client. /// The Nexus API client. - public ModsApiController(IMemoryCache cache, IOptions configProvider, IChucklefishClient chucklefish, IGitHubClient github, INexusClient nexus) + public ModsApiController(IHostingEnvironment environment, IMemoryCache cache, IOptions configProvider, IChucklefishClient chucklefish, IGitHubClient github, INexusClient nexus) { + this.ModDatabase = new ModToolkit().GetModDatabase(Path.Combine(environment.WebRootPath, "StardewModdingAPI.metadata.json")); ModUpdateCheckConfig config = configProvider.Value; this.Cache = cache; @@ -79,10 +87,20 @@ namespace StardewModdingAPI.Web.Controllers if (string.IsNullOrWhiteSpace(mod.ID)) continue; + // resolve update keys + var updateKeys = new HashSet(mod.UpdateKeys ?? new string[0], StringComparer.InvariantCultureIgnoreCase); + ModDataRecord record = this.ModDatabase.Get(mod.ID); + if (record?.Fields != null) + { + string defaultUpdateKey = record.Fields.FirstOrDefault(p => p.Key == ModDataFieldKey.UpdateKey && p.IsDefault)?.Value; + if (!string.IsNullOrWhiteSpace(defaultUpdateKey)) + updateKeys.Add(defaultUpdateKey); + } + // get latest versions ModEntryModel result = new ModEntryModel { ID = mod.ID }; IList errors = new List(); - foreach (string updateKey in mod.UpdateKeys ?? new string[0]) + foreach (string updateKey in updateKeys) { // fetch data ModInfoModel data = await this.GetInfoForUpdateKeyAsync(updateKey); diff --git a/src/SMAPI.Web/StardewModdingAPI.Web.csproj b/src/SMAPI.Web/StardewModdingAPI.Web.csproj index a409e6eb..6761c7ad 100644 --- a/src/SMAPI.Web/StardewModdingAPI.Web.csproj +++ b/src/SMAPI.Web/StardewModdingAPI.Web.csproj @@ -26,5 +26,10 @@ + + + PreserveNewest + + diff --git a/src/SMAPI.Web/wwwroot/StardewModdingAPI.metadata.json b/src/SMAPI.Web/wwwroot/StardewModdingAPI.metadata.json new file mode 100644 index 00000000..343257f1 --- /dev/null +++ b/src/SMAPI.Web/wwwroot/StardewModdingAPI.metadata.json @@ -0,0 +1,1668 @@ +{ + /** + * 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 + * default display name for the mod if one isn't available (e.g. in dependency checks). + * + * - ID: the mod's latest unique ID (if any). + * + * - FormerIDs: uniquely identifies the mod across multiple versions, and supports matching + * other fields if no ID was specified. This doesn't include the latest ID, if any. Multiple + * variants can be separated with '|'. + * + * - MapLocalVersions and MapRemoteVersions correct local manifest versions and remote versions + * during update checks. For example, if the API returns version '1.1-1078' where '1078' is + * intended to be a build number, MapRemoteVersions can map it to '1.1' when comparing to the + * mod's current version. This is only meant to support legacy mods with injected update keys. + * + * Versioned metadata + * ================== + * Each record can also specify extra metadata using the field keys below. + * + * Each key consists of a field name prefixed with any combination of version range and 'Default', + * separated by pipes (whitespace trimmed). For example, 'UpdateKey' will always override, + * 'Default | UpdateKey' will only override if the mod has no update keys, and + * '~1.1 | Default | Name' will do the same up to version 1.1. + * + * The version format is 'min~max' (where either side can be blank for unbounded), or a single + * version number. + * + * These are the valid field names: + * + * - UpdateKey: the update key to set in the mod's manifest. This is used to enable update + * checks for older mods that haven't been updated to use it yet. + * + * - Status: overrides compatibility checks. The possible values are Obsolete (SMAPI won't load + * it because the mod should no longer be used), AssumeBroken (SMAPI won't load it because + * the specified version isn't compatible), or AssumeCompatible (SMAPI will try to load it + * even if it detects incompatible code). + * + * Note that this shouldn't be set to 'AssumeBroken' if SMAPI can detect the incompatibility + * automatically, since that hides the details from trace logs. + * + * - StatusReasonPhrase: a message to show to the player explaining why the mod can't be loaded + * (if applicable). If blank, will default to a generic not-compatible message. + * + * - AlternativeUrl: a URL where the player can find an unofficial update or alternative if the + * mod is no longer compatible. + */ + "ModData": { + "AccessChestAnywhere": { + "ID": "AccessChestAnywhere", + "MapLocalVersions": { "1.1-1078": "1.1" }, + "Default | UpdateKey": "Nexus:257", + "~1.1 | Status": "AssumeBroken" + }, + + "Adjust Artisan Prices": { + "ID": "ThatNorthernMonkey.AdjustArtisanPrices", + "FormerIDs": "1e36d4ca-c7ef-4dfb-9927-d27a6c3c8bdc", // changed in 0.0.2-pathoschild-update + "MapRemoteVersions": { "0.01": "0.0.1" }, + "Default | UpdateKey": "Chucklefish:3532" + }, + + "Adjust Monster": { + "ID": "mmanlapat.AdjustMonster", + "Default | UpdateKey": "Nexus:1161" + }, + + "Advanced Location Loader": { + "ID": "Entoarox.AdvancedLocationLoader", + "~1.3.7 | UpdateKey": "Chucklefish:3619" // only enable update checks up to 1.3.7 by request (has its own update-check feature) + }, + + "Adventure Shop Inventory": { + "ID": "HammurabiAdventureShopInventory", + "Default | UpdateKey": "Chucklefish:4608" + }, + + "AgingMod": { + "ID": "skn.AgingMod", + "Default | UpdateKey": "Nexus:1129", + "~1.0 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "All Crops All Seasons": { + "ID": "cantorsdust.AllCropsAllSeasons", + "FormerIDs": "29ee8246-d67b-4242-a340-35a9ae0d5dd7 | community.AllCropsAllSeasons", // changed in 1.3 and 1.5 + "Default | UpdateKey": "Nexus:170" + }, + + "All Professions": { + "ID": "cantorsdust.AllProfessions", + "FormerIDs": "8c37b1a7-4bfb-4916-9d8a-9533e6363ea3 | community.AllProfessions", // changed in 1.2 and 1.3.1 + "Default | UpdateKey": "Nexus:174" + }, + + "Almighty Farming Tool": { + "ID": "439", + "MapRemoteVersions": { "1.21": "1.2.1" }, + "Default | UpdateKey": "Nexus:439" + }, + + "Animal Husbandry": { + "ID": "DIGUS.ANIMALHUSBANDRYMOD", + "FormerIDs": "DIGUS.BUTCHER", // changed in 2.0.1 + "Default | UpdateKey": "Nexus:1538" + }, + + "Animal Mood Fix": { + "ID": "GPeters-AnimalMoodFix", + "~ | Status": "Obsolete", + "~ | StatusReasonPhrase": "the animal mood bugs were fixed in Stardew Valley 1.2." + }, + + "Animal Sitter": { + "ID": "jwdred.AnimalSitter", + "Default | UpdateKey": "Nexus:581", + "~1.0.8 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Arcade Pong": { + "ID": "Platonymous.ArcadePong", + "~1.0.2 | Status": "AssumeBroken" // broke in SMAPI 2.6-beta.16 due to reflection into SMAPI internals + }, + + "A Tapper's Dream": { + "ID": "ddde5195-8f85-4061-90cc-0d4fd5459358", + "Default | UpdateKey": "Nexus:260" + }, + + "Auto Animal Doors": { + "ID": "AaronTaggart.AutoAnimalDoors", + "Default | UpdateKey": "Nexus:1019" + }, + + "Auto-Eat": { + "ID": "Permamiss.AutoEat", + "FormerIDs": "BALANCEMOD_AutoEat", // changed in 1.1.1 + "Default | UpdateKey": "Nexus:643" + }, + + "AutoFish": { + "ID": "WhiteMind.AF", + "Default | UpdateKey": "Nexus:1895" + }, + + "AutoGate": { + "ID": "AutoGate", + "Default | UpdateKey": "Nexus:820" + }, + + "Automate": { + "ID": "Pathoschild.Automate", + "Default | UpdateKey": "Nexus:1063", + "~1.10-beta.7 | Status": "AssumeBroken" // broke in SDV 1.3.20 + }, + + "Automated Doors": { + "ID": "azah.automated-doors", + "FormerIDs": "1abcfa07-2cf4-4dc3-a6e9-6068b642112b", // changed in 1.4.1 + "Default | UpdateKey": "GitHub:azah/AutomatedDoors" // added in 1.4.2 + }, + + "AutoSpeed": { + "ID": "Omegasis.AutoSpeed", + "Default | UpdateKey": "Nexus:443" // added in 1.4.1 + }, + + "Basic Sprinklers Improved": { + "ID": "lrsk_sdvm_bsi.0117171308", + "MapRemoteVersions": { "1.0.2": "1.0.1-release" }, // manifest not updated + "Default | UpdateKey": "Nexus:833" + }, + + "Better Hay": { + "ID": "cat.betterhay", + "Default | UpdateKey": "Nexus:1430" + }, + + "Better Quality More Seasons": { + "ID": "SB_BQMS", + "Default | UpdateKey": "Nexus:935" + }, + + "Better Quarry": { + "ID": "BetterQuarry", + "Default | UpdateKey": "Nexus:771" + }, + + "Better Ranching": { + "ID": "BetterRanching", + "Default | UpdateKey": "Nexus:859" + }, + + "Better Shipping Box": { + "ID": "Kithio:BetterShippingBox", + "MapLocalVersions": { "1.0.1": "1.0.2" }, + "Default | UpdateKey": "Chucklefish:4302" + }, + + "Better Sprinklers": { + "ID": "Speeder.BetterSprinklers", + "FormerIDs": "SPDSprinklersMod", // changed in 2.3 + "Default | UpdateKey": "Nexus:41" + }, + + "Billboard Anywhere": { + "ID": "Omegasis.BillboardAnywhere", + "Default | UpdateKey": "Nexus:492" // added in 1.4.1 + }, + + "Birthday Mail": { + "ID": "KathrynHazuka.BirthdayMail", + "FormerIDs": "005e02dc-d900-425c-9c68-1ff55c5a295d", // changed in 1.2.3-pathoschild-update + "Default | UpdateKey": "Nexus:276", + "MapRemoteVersions": { "1.3.1": "1.3" } // manifest not updated + }, + + "Breed Like Rabbits": { + "ID": "dycedarger.breedlikerabbits", + "Default | UpdateKey": "Nexus:948" + }, + + "Build Endurance": { + "ID": "Omegasis.BuildEndurance", + "Default | UpdateKey": "Nexus:445" // added in 1.4.1 + }, + + "Build Health": { + "ID": "Omegasis.BuildHealth", + "Default | UpdateKey": "Nexus:446" // added in 1.4.1 + }, + + "Buy Cooking Recipes": { + "ID": "Denifia.BuyRecipes", + "Default | UpdateKey": "Nexus:1126" // added in 1.0.1 (2017-10-04) + }, + + "Buy Back Collectables": { + "ID": "Omegasis.BuyBackCollectables", + "FormerIDs": "BuyBackCollectables", // changed in 1.4 + "Default | UpdateKey": "Nexus:507" // added in 1.4.1 + }, + + "Carry Chest": { + "ID": "spacechase0.CarryChest", + "Default | UpdateKey": "Nexus:1333" + }, + + "Casks Anywhere": { + "ID": "CasksAnywhere", + "MapLocalVersions": { "1.1-alpha": "1.1" }, + "Default | UpdateKey": "Nexus:878" + }, + + "Categorize Chests": { + "ID": "CategorizeChests", + "Default | UpdateKey": "Nexus:1300", + "~1.4.3-unofficial.2.mizzion | Status": "AssumeBroken" // broke in SMAPI 2.6-beta.18 (in-game errors) + }, + + "Chefs Closet": { + "ID": "Duder.ChefsCloset", + "MapLocalVersions": { "1.3-1": "1.3" }, + "Default | UpdateKey": "Nexus:1030" + }, + + "Chest Label System": { + "ID": "Speeder.ChestLabel", + "FormerIDs": "SPDChestLabel", // changed in 1.5.1-pathoschild-update + "Default | UpdateKey": "Nexus:242" + }, + + "Chest Pooling": { + "ID": "mralbobo.ChestPooling", + "Default | UpdateKey": "GitHub:mralbobo/stardew-chest-pooling" + }, + + "Chests Anywhere": { + "ID": "Pathoschild.ChestsAnywhere", + "FormerIDs": "ChestsAnywhere", // changed in 1.9 + "Default | UpdateKey": "Nexus:518", + "~1.12.4 | Status": "AssumeBroken" // broke in SDV 1.3 + }, + + "CJB Automation": { + "ID": "CJBAutomation", + "Default | UpdateKey": "Nexus:211", + "~1.4 | Status": "AssumeBroken", // broke in SDV 1.2 + "~1.4 | AlternativeUrl": "http://www.nexusmods.com/stardewvalley/mods/1063" + }, + + "CJB Cheats Menu": { + "ID": "CJBok.CheatsMenu", + "FormerIDs": "CJBCheatsMenu", // changed in 1.14 + "Default | UpdateKey": "Nexus:4", + "~1.18-beta | Status": "AssumeBroken" // broke in SDV 1.3, first beta causes significant friendship bugs + }, + + "CJB Item Spawner": { + "ID": "CJBok.ItemSpawner", + "FormerIDs": "CJBItemSpawner", // changed in 1.7 + "Default | UpdateKey": "Nexus:93", + "~1.10 | Status": "AssumeBroken" // broke in SDV 1.3 + }, + + "CJB Show Item Sell Price": { + "ID": "CJBok.ShowItemSellPrice", + "FormerIDs": "CJBShowItemSellPrice", // changed in 1.7 + "Default | UpdateKey": "Nexus:5", + "~1.8 | Status": "AssumeBroken" // broke in SDV 1.3 + }, + + "Clean Farm": { + "ID": "tstaples.CleanFarm", + "Default | UpdateKey": "Nexus:794" + }, + + "Climates of Ferngill": { + "ID": "KoihimeNakamura.ClimatesOfFerngill", + "Default | UpdateKey": "Nexus:604" + }, + + "Coal Regen": { + "ID": "Blucifer.CoalRegen", + "Default | UpdateKey": "Nexus:1664" + }, + + "Cobalt": { + "ID": "spacechase0.Cobalt", + "MapRemoteVersions": { "1.1.3": "1.1.2" } // not updated in manifest + }, + + "Cold Weather Haley": { + "ID": "LordXamon.ColdWeatherHaleyPRO", + "Default | UpdateKey": "Nexus:1169", + "~1.0 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Colored Chests": { + "ID": "4befde5c-731c-4853-8e4b-c5cdf946805f", + "~ | Status": "Obsolete", + "~ | StatusReasonPhrase": "colored chests were added in Stardew Valley 1.1." + }, + + "Combat with Farm Implements": { + "ID": "SPDFarmingImplementsInCombat", + "Default | UpdateKey": "Nexus:313" + }, + + "Community Bundle Item Tooltip": { + "ID": "musbah.bundleTooltip", + "Default | UpdateKey": "Nexus:1329" + }, + + "Concentration on Farming": { + "ID": "punyo.ConcentrationOnFarming", + "Default | UpdateKey": "Nexus:1445" + }, + + "Configurable Machines": { + "ID": "21da6619-dc03-4660-9794-8e5b498f5b97", + "MapLocalVersions": { "1.2-beta": "1.2" }, + "Default | UpdateKey": "Nexus:280" + }, + + "Configurable Shipping Dates": { + "ID": "ConfigurableShippingDates", + "Default | UpdateKey": "Nexus:675", + "~1.1.1 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Content Patcher": { + "ID": "Pathoschild.ContentPatcher", + "Default | UpdateKey": "Nexus:1915", + "~1.4-beta.5 | Status": "AssumeBroken" // broke in SMAPI 2.6-beta.18 (in-game errors) + }, + + "Cooking Skill": { + "ID": "spacechase0.CookingSkill", + "FormerIDs": "CookingSkill", // changed in 1.0.4–6 + "Default | UpdateKey": "Nexus:522" + }, + + "CrabNet": { + "ID": "jwdred.CrabNet", + "Default | UpdateKey": "Nexus:584" + }, + + "Crafting Counter": { + "ID": "lolpcgaming.CraftingCounter", + "Default | UpdateKey": "Nexus:1585", + "MapRemoteVersions": { "1.1": "1.0" } // not updated in manifest + }, + + "Current Location": { + "ID": "CurrentLocation102120161203", + "Default | UpdateKey": "Nexus:638" + }, + + "Custom Asset Modifier": { + "ID": "Omegasis.CustomAssetModifier", + "Default | UpdateKey": "1836" + }, + + "Custom Critters": { + "ID": "spacechase0.CustomCritters", + "Default | UpdateKey": "Nexus:1255" + }, + + "Custom Crops": { + "ID": "spacechase0.CustomCrops", + "Default | UpdateKey": "Nexus:1592" + }, + + "Custom Element Handler": { + "ID": "Platonymous.CustomElementHandler", + "Default | UpdateKey": "Nexus:1068" // added in 1.3.1 + }, + + "Custom Farming Redux": { + "ID": "Platonymous.CustomFarming", + "Default | UpdateKey": "Nexus:991" // added in 0.6.1 + }, + + "Custom Farming Automate Bridge": { + "ID": "Platonymous.CFAutomate", + "~1.0.1 | Status": "AssumeBroken", // no longer compatible with Automate + "~1.0.1 | AlternativeUrl": "https://www.nexusmods.com/stardewvalley/mods/991" + }, + + "Custom Farm Types": { + "ID": "spacechase0.CustomFarmTypes", + "Default | UpdateKey": "Nexus:1140" + }, + + "Custom Furniture": { + "ID": "Platonymous.CustomFurniture", + "Default | UpdateKey": "Nexus:1254" // added in 0.4.1 + }, + + "Customize Exterior": { + "ID": "spacechase0.CustomizeExterior", + "FormerIDs": "CustomizeExterior", // changed in 1.0.3 + "Default | UpdateKey": "Nexus:1099", + "~1.0.2 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Customizable Cart Redux": { + "ID": "KoihimeNakamura.CCR", + "MapLocalVersions": { "1.1-20170917": "1.1" }, + "Default | UpdateKey": "Nexus:1402" + }, + + "Customizable Traveling Cart Days": { + "ID": "TravelingCartYyeahdude", + "Default | UpdateKey": "Nexus:567" + }, + + "Custom Linens": { + "ID": "Mevima.CustomLinens", + "MapRemoteVersions": { "1.1": "1.0" }, // manifest not updated + "Default | UpdateKey": "Nexus:1027" + }, + + "Custom NPC": { + "ID": "Platonymous.CustomNPC", + "Default | UpdateKey": "Nexus:1607" + }, + + "Custom Shops Redux": { + "ID": "Omegasis.CustomShopReduxGui", + "Default | UpdateKey": "Nexus:1378" // added in 1.4.1 + }, + + "Custom TV": { + "ID": "Platonymous.CustomTV", + "Default | UpdateKey": "Nexus:1139" // added in 1.0.6 + }, + + "Daily Luck Message": { + "ID": "Schematix.DailyLuckMessage", + "Default | UpdateKey": "Nexus:1327" + }, + + "Daily News": { + "ID": "bashNinja.DailyNews", + "Default | UpdateKey": "Nexus:1141", + "~1.2 | Status": "AssumeBroken" // broke in Stardew Valley 1.3 (or depends on CustomTV which broke) + }, + + "Daily Quest Anywhere": { + "ID": "Omegasis.DailyQuestAnywhere", + "FormerIDs": "DailyQuest", // changed in 1.4 + "Default | UpdateKey": "Nexus:513" // added in 1.4.1 + }, + + "Data Maps": { + "ID": "Pathoschild.DataMaps", + "Default | UpdateKey": "Nexus:1691", + "~1.3 | Status": "AssumeBroken" // broke in SDV 1.3 + }, + + "Debug Mode": { + "ID": "Pathoschild.DebugMode", + "FormerIDs": "Pathoschild.Stardew.DebugMode", // changed in 1.4 + "Default | UpdateKey": "Nexus:679", + "~1.8 | Status": "AssumeBroken" // broke in SDV 1.3 + }, + + "Did You Water Your Crops?": { + "ID": "Nishtra.DidYouWaterYourCrops", + "Default | UpdateKey": "Nexus:1583" + }, + + "Dynamic Checklist": { + "ID": "gunnargolf.DynamicChecklist", + "Default | UpdateKey": "Nexus:1145" // added in 1.0.1-pathoschild-update + }, + + "Dynamic Horses": { + "ID": "Bpendragon-DynamicHorses", + "MapRemoteVersions": { "1.2": "1.1-release" }, // manifest not updated + "Default | UpdateKey": "Nexus:874" + }, + + "Dynamic Machines": { + "ID": "DynamicMachines", + "MapLocalVersions": { "1.1": "1.1.1" }, + "Default | UpdateKey": "Nexus:374", + "~1.1.1 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Dynamic NPC Sprites": { + "ID": "BashNinja.DynamicNPCSprites", + "Default | UpdateKey": "Nexus:1183" + }, + + "Easier Farming": { + "ID": "cautiouswafffle.EasierFarming", + "Default | UpdateKey": "Nexus:1426" + }, + + "Empty Hands": { + "ID": "QuicksilverFox.EmptyHands", + "Default | UpdateKey": "Nexus:1176" // added in 1.0.1-pathoschild-update + }, + + "Enemy Health Bars": { + "ID": "Speeder.HealthBars", + "FormerIDs": "SPDHealthBar", // changed in 1.7.1-pathoschild-update + "Default | UpdateKey": "Nexus:193" + }, + + "Entoarox Framework": { + "ID": "Entoarox.EntoaroxFramework", + "FormerIDs": "eacdb74b-4080-4452-b16b-93773cda5cf9", // changed in ??? + "~2.0.6 | UpdateKey": "Chucklefish:4228", // only enable update checks up to 2.0.6 by request (has its own update-check feature) + "~2.0.6 | Status": "AssumeBroken" // broke in SMAPI 2.5 (error reflecting into SMAPI internals) + }, + + "Expanded Fridge": { + "ID": "Uwazouri.ExpandedFridge", + "Default | UpdateKey": "Nexus:1191" + }, + + "Experience Bars": { + "ID": "spacechase0.ExperienceBars", + "FormerIDs": "ExperienceBars", // changed in 1.0.2 + "Default | UpdateKey": "Nexus:509" + }, + + "Extended Bus System": { + "ID": "ExtendedBusSystem", + "Default | UpdateKey": "Chucklefish:4373" + }, + + "Extended Fridge": { + "ID": "Crystalmir.ExtendedFridge", + "FormerIDs": "Mystra007ExtendedFridge", // changed in 1.0.1 + "Default | UpdateKey": "Nexus:485" + }, + + "Extended Greenhouse": { + "ID": "ExtendedGreenhouse", + "Default | UpdateKey": "Chucklefish:4303", + "~1.0.2 | Status": "AssumeBroken" // broke in SDV 1.2 + }, + + "Extended Minecart": { + "ID": "Entoarox.ExtendedMinecart", + "~1.7.1 | UpdateKey": "Chucklefish:4359" // only enable update checks up to 1.7.1 by request (has its own update-check feature) + }, + + "Extended Reach": { + "ID": "spacechase0.ExtendedReach", + "Default | UpdateKey": "Nexus:1493" + }, + + "Fall 28 Snow Day": { + "ID": "Omegasis.Fall28SnowDay", + "Default | UpdateKey": "Nexus:486", // added in 1.4.1 + "~1.4.1 | Status": "AssumeBroken" // broke in SMAPI 2.0, and update for SMAPI 2.0 doesn't do anything + }, + + "Farm Automation Unofficial: Item Collector": { + "ID": "Maddy99.FarmAutomation.ItemCollector", + "~0.5 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Farm Expansion": { + "ID": "Advize.FarmExpansion", + "FormerIDs": "3888bdfd-73f6-4776-8bb7-8ad45aea1915 | AdvizeFarmExpansionMod-2-0 | AdvizeFarmExpansionMod-2-0-5", // changed in 2.0, 2.0.5, and 3.0 + "Default | UpdateKey": "Nexus:130" + }, + + "Fast Animations": { + "ID": "Pathoschild.FastAnimations", + "Default | UpdateKey": "Nexus:1089", + "~1.5 | Status": "AssumeBroken" // broke in SDV 1.3 + }, + + "Faster Grass": { + "ID": "IceGladiador.FasterGrass", + "Default | UpdateKey": "Nexus:1772" + }, + + "Faster Paths": { + "ID": "Entoarox.FasterPaths", + "FormerIDs": "615f85f8-5c89-44ee-aecc-c328f172e413", // changed in 1.3 + "~1.3.3 | UpdateKey": "Chucklefish:3641" // only enable update checks up to 1.3.3 by request (has its own update-check feature) + }, + + "Fishing Adjust": { + "ID": "shuaiz.FishingAdjustMod", + "Default | UpdateKey": "Nexus:1350", + "~2.0.1 | Status": "AssumeBroken" // Method not found: 'Void Harmony.HarmonyInstance.Patch(System.Reflection.MethodBase, Harmony.HarmonyMethod, Harmony.HarmonyMethod, Harmony.HarmonyMethod)' + }, + + "Fishing Tuner Redux": { + "ID": "HammurabiFishingTunerRedux", + "Default | UpdateKey": "Chucklefish:4578" + }, + + "Fixed Secret Woods Debris": { + "ID": "f4iTh.WoodsDebrisFix", + "Default | UpdateKey": "Nexus:1941" + }, + + "Flower Color Picker": { + "ID": "spacechase0.FlowerColorPicker", + "Default | UpdateKey": "Nexus:1229" + }, + + "Forage at the Farm": { + "ID": "Nishtra.ForageAtTheFarm", + "FormerIDs": "ForageAtTheFarm", // changed in <=1.6 + "Default | UpdateKey": "Nexus:673" + }, + + "Furniture Anywhere": { + "ID": "Entoarox.FurnitureAnywhere", + "~1.1.5 | UpdateKey": "Chucklefish:4324" // only enable update checks up to 1.1.5 by request (has its own update-check feature) + }, + + "Game Reminder": { + "ID": "mmanlapat.GameReminder", + "Default | UpdateKey": "Nexus:1153" + }, + + "Gate Opener": { + "ID": "mralbobo.GateOpener", + "Default | UpdateKey": "GitHub:mralbobo/stardew-gate-opener" + }, + + "GenericShopExtender": { + "ID": "GenericShopExtender", + "Default | UpdateKey": "Nexus:814" // added in 0.1.3 + }, + + "Geode Info Menu": { + "ID": "cat.geodeinfomenu", + "Default | UpdateKey": "Nexus:1448" + }, + + "Get Dressed": { + "ID": "Advize.GetDressed", + "Default | UpdateKey": "Nexus:331" + }, + + "Giant Crop Ring": { + "ID": "cat.giantcropring", + "Default | UpdateKey": "Nexus:1182" + }, + + "Gift Taste Helper": { + "ID": "tstaples.GiftTasteHelper", + "FormerIDs": "8008db57-fa67-4730-978e-34b37ef191d6", // changed in 2.5 + "Default | UpdateKey": "Nexus:229" + }, + + "Grandfather's Gift": { + "ID": "ShadowDragon.GrandfathersGift", + "Default | UpdateKey": "Nexus:985" + }, + + "Happy Animals": { + "ID": "HappyAnimals", + "~1.0.3 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Happy Birthday (Omegasis)": { + "ID": "Omegasis.HappyBirthday", + "Default | UpdateKey": "Nexus:520" // added in 1.4.1 + }, + + "Hardcore Mines": { + "ID": "kibbe.hardcore_mines", + "Default | UpdateKey": "Nexus:1674" + }, + + "Harp of Yoba Redux": { + "ID": "Platonymous.HarpOfYobaRedux", + "Default | UpdateKey": "Nexus:914" // added in 2.0.3 + }, + + "Harvest Moon Witch Princess": { + "ID": "Sasara.WitchPrincess", + "Default | UpdateKey": "Nexus:1157" + }, + + "Harvest With Scythe": { + "ID": "965169fd-e1ed-47d0-9f12-b104535fb4bc", + "Default | UpdateKey": "Nexus:236" + }, + + "Horse Whistle (icepuente)": { + "ID": "icepuente.HorseWhistle", + "Default | UpdateKey": "Nexus:1131", + "~1.1.2-unofficial.1-pathoschild | Status": "AssumeBroken" // causes significant lag, fixed in unofficial.2 + }, + + "Hunger (Yyeadude)": { + "ID": "HungerYyeadude", + "Default | UpdateKey": "Nexus:613" + }, + + "Hunger for Food (Tigerle)": { + "ID": "HungerForFoodByTigerle", + "Default | UpdateKey": "Nexus:810", + "~0.1.2 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Hunger Mod (skn)": { + "ID": "skn.HungerMod", + "MapRemoteVersions": { "1.2.1": "1.0" }, // manifest not updated + "Default | UpdateKey": "Nexus:1127" + }, + + "Idle Pause": { + "ID": "Veleek.IdlePause", + "MapRemoteVersions": { "1.2": "1.1" }, // manifest not updated + "Default | UpdateKey": "Nexus:1092" + }, + + "Improved Quality of Life": { + "ID": "Demiacle.ImprovedQualityOfLife", + "Default | UpdateKey": "Nexus:1025", + "~1.1 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Instant Geode": { + "ID": "InstantGeode", + "~1.12 | Status": "AssumeBroken" // broke in SDV 1.2 + }, + + "Instant Grow Trees": { + "ID": "cantorsdust.InstantGrowTrees", + "FormerIDs": "dc50c58b-c7d8-4e60-86cc-e27b5d95ee59 | community.InstantGrowTrees", // changed in 1.2 and 1.3.1 + "Default | UpdateKey": "Nexus:173" + }, + + "Interaction Helper": { + "ID": "HammurabiInteractionHelper", + "Default | UpdateKey": "Chucklefish:4640" // added in 1.0.4-pathoschild-update + }, + + "Item Auto Stacker": { + "ID": "cat.autostacker", + "MapRemoteVersions": { "1.0.1": "1.0" }, // manifest not updated + "Default | UpdateKey": "Nexus:1184" + }, + + "Json Assets": { + "ID": "spacechase0.JsonAssets", + "Default | UpdateKey": "Nexus:1720" + }, + + "Junimo Farm": { + "ID": "Platonymous.JunimoFarm", + "MapRemoteVersions": { "1.1.2": "1.1.1" }, // manifest not updated + "Default | UpdateKey": "Nexus:984" // added in 1.1.3 + }, + + "Less Strict Over-Exertion (AntiExhaustion)": { + "ID": "BALANCEMOD_AntiExhaustion", + "MapLocalVersions": { "0.0": "1.1" }, + "Default | UpdateKey": "Nexus:637", + "~1.1 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Level Extender": { + "ID": "DevinLematty.LevelExtender", + "FormerIDs": "Devin Lematty.Level Extender", // changed in 1.3 + "Default | UpdateKey": "Nexus:1471" + }, + + "Level Up Notifications": { + "ID": "Level Up Notifications", + "MapRemoteVersions": { "0.0.1a": "0.0.1" }, + "Default | UpdateKey": "Nexus:855" + }, + + "Location and Music Logging": { + "ID": "Brandy Lover.LMlog", + "Default | UpdateKey": "Nexus:1366" + }, + + "Longevity": { + "ID": "RTGOAT.Longevity", + "MapRemoteVersions": { "1.6.8h": "1.6.8" }, + "Default | UpdateKey": "Nexus:649" + }, + + "Lookup Anything": { + "ID": "Pathoschild.LookupAnything", + "FormerIDs": "LookupAnything", // changed in 1.10.1 + "Default | UpdateKey": "Nexus:541", + "~1.18.1 | Status": "AssumeBroken" // broke in SDV 1.3 + }, + + "Love Bubbles": { + "ID": "LoveBubbles", + "Default | UpdateKey": "Nexus:1318" + }, + + "Loved Labels": { + "ID": "Advize.LovedLabels", + "Default | UpdateKey": "Nexus:279" + }, + + "Luck Skill": { + "ID": "spacechase0.LuckSkill", + "FormerIDs": "LuckSkill", // changed in 0.1.4 + "Default | UpdateKey": "Nexus:521" + }, + + "Magic": { + "ID": "spacechase0.Magic", + "MapRemoteVersions": { "0.1.2": "0.1.1" } // not updated in manifest + }, + + "Mail Framework": { + "ID": "DIGUS.MailFrameworkMod", + "Default | UpdateKey": "Nexus:1536" + }, + + "MailOrderPigs": { + "ID": "jwdred.MailOrderPigs", + "Default | UpdateKey": "Nexus:632" + }, + + "Makeshift Multiplayer": { + "ID": "spacechase0.StardewValleyMP", + "FormerIDs": "StardewValleyMP", // changed in 0.3 + "Default | UpdateKey": "Nexus:501" + }, + + "Map Image Exporter": { + "ID": "spacechase0.MapImageExporter", + "FormerIDs": "MapImageExporter", // changed in 1.0.2 + "Default | UpdateKey": "Nexus:1073" + }, + + "Message Box [API]? (ChatMod)": { + "ID": "Kithio:ChatMod", + "Default | UpdateKey": "Chucklefish:4296", + "~1.0 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Mining at the Farm": { + "ID": "Nishtra.MiningAtTheFarm", + "FormerIDs": "MiningAtTheFarm", // changed in <=1.7 + "Default | UpdateKey": "Nexus:674" + }, + + "Mining With Explosives": { + "ID": "Nishtra.MiningWithExplosives", + "FormerIDs": "MiningWithExplosives", // changed in 1.1 + "Default | UpdateKey": "Nexus:770" + }, + + "Modder Serialization Utility": { + "ID": "SerializerUtils-0-1", + "~ | Status": "Obsolete", + "~ | StatusReasonPhrase": "it's no longer maintained or used." + }, + + "Monster Level Tip": { + "ID": "WhiteMind.MonsterLT", + "Default | UpdateKey": "Nexus:1896" + }, + + "More Animals": { + "ID": "Entoarox.MoreAnimals", + "FormerIDs": "821ce8f6-e629-41ad-9fde-03b54f68b0b6MOREPETS | Entoarox.MorePets", // changed in 1.3 and 2.0 + "~2.0.2 | UpdateKey": "Chucklefish:4288" // only enable update checks up to 2.0.2 by request (has its own update-check feature) + }, + + "More Artifact Spots": { + "ID": "451", + "Default | UpdateKey": "Nexus:451" + }, + + "More Map Layers": { + "ID": "Platonymous.MoreMapLayers", + "Default | UpdateKey": "Nexus:1134" // added in 1.1.1 + }, + + "More Rain": { + "ID": "Omegasis.MoreRain", + "Default | UpdateKey": "Nexus:441", // added in 1.5.1 + "~1.4 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "More Weapons": { + "ID": "Joco80.MoreWeapons", + "Default | UpdateKey": "Nexus:1168" + }, + + "Move Faster": { + "ID": "shuaiz.MoveFasterMod", + "Default | UpdateKey": "Nexus:1351", + "1.0.1 | Status": "AssumeBroken" // doesn't do anything as of SDV 1.2.33 (bad Harmony patch?) + }, + + "Multiple Sprites and Portraits On Rotation (File Loading)": { + "ID": "FileLoading", + "MapLocalVersions": { "1.1": "1.12" }, + "Default | UpdateKey": "Nexus:1094", + "~1.12 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Museum Rearranger": { + "ID": "Omegasis.MuseumRearranger", + "Default | UpdateKey": "Nexus:428" // added in 1.4.1 + }, + + "Mushroom Level Tip": { + "ID": "WhiteMind.MLT", + "Default | UpdateKey": "Nexus:1894" + }, + + "New Machines": { + "ID": "F70D4FAB-0AB2-4B78-9F1B-AF2CA2236A59", + "Default | UpdateKey": "Chucklefish:3683", + "~4.2.1343 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Night Owl": { + "ID": "Omegasis.NightOwl", + "MapLocalVersions": { "2.1": "1.3" }, // 1.3 had wrong version in manifest + "Default | UpdateKey": "Nexus:433" // added in 1.4.1 + }, + + "No Crows": { + "ID": "cat.nocrows", + "Default | UpdateKey": "Nexus:1682" + }, + + "No Kids Ever": { + "ID": "Hangy.NoKidsEver", + "Default | UpdateKey": "Nexus:1464" + }, + + "No Debug Mode": { + "ID": "NoDebugMode", + "~ | Status": "Obsolete", + "~ | StatusReasonPhrase": "debug mode was removed in SMAPI 1.0." + }, + + "No Fence Decay": { + "ID": "cat.nofencedecay", + "Default | UpdateKey": "Nexus:1180" + }, + + "No More Pets": { + "ID": "Omegasis.NoMorePets", + "FormerIDs": "NoMorePets", // changed in 1.4 + "Default | UpdateKey": "Nexus:506" // added in 1.4.1 + }, + + "No Rumble Horse": { + "ID": "Xangria.NoRumbleHorse", + "Default | UpdateKey": "Nexus:1779" + }, + + "No Soil Decay": { + "ID": "289dee03-5f38-4d8e-8ffc-e440198e8610", + "Default | UpdateKey": "Nexus:237", + "~0.5 | Status": "AssumeBroken" // broke in SDV 1.2 and uses Assembly.GetExecutingAssembly().Location + }, + + "No Soil Decay Redux": { + "ID": "Platonymous.NoSoilDecayRedux", + "Default | UpdateKey": "Nexus:1084" // added in 1.1.9 + }, + + "NPC Map Locations": { + "ID": "Bouhm.NPCMapLocations", + "FormerIDs": "NPCMapLocationsMod", // changed in 2.0 + "Default | UpdateKey": "Nexus:239" + }, + + "Object Time Left": { + "ID": "spacechase0.ObjectTimeLeft", + "Default | UpdateKey": "Nexus:1315" + }, + + "OmniFarm": { + "ID": "PhthaloBlue.OmniFarm", + "FormerIDs": "BlueMod_OmniFarm", // changed in 2.0.2-pathoschild-update + "Default | UpdateKey": "GitHub:lambui/StardewValleyMod_OmniFarm" + }, + + "One Click Shed": { + "ID": "BitwiseJonMods.OneClickShedReloader", + "Default | UpdateKey": "Nexus:2052" + }, + + "Out of Season Bonuses (Seasonal Items)": { + "ID": "midoriarmstrong.seasonalitems", + "Default | UpdateKey": "Nexus:1452" + }, + + "Part of the Community": { + "ID": "SB_PotC", + "Default | UpdateKey": "Nexus:923" + }, + + "PelicanFiber": { + "ID": "jwdred.PelicanFiber", + "Default | UpdateKey": "Nexus:631" + }, + + "PelicanTTS": { + "ID": "Platonymous.PelicanTTS", + "Default | UpdateKey": "Nexus:1079" // added in 1.6.1 + }, + + "Persia the Mermaid - Standalone Custom NPC": { + "ID": "63b9f419-7449-42db-ab2e-440b4d05c073", + "Default | UpdateKey": "Nexus:1419" + }, + + "Persistent Game Options": { + "ID": "Xangria.PersistentGameOptions", + "Default | UpdateKey": "Nexus:1778" + }, + + "Plant on Grass": { + "ID": "Demiacle.PlantOnGrass", + "Default | UpdateKey": "Nexus:1026" + }, + + "PyTK - Platonymous Toolkit": { + "ID": "Platonymous.Toolkit", + "Default | UpdateKey": "Nexus:1726" + }, + + "Point-and-Plant": { + "ID": "jwdred.PointAndPlant", + "Default | UpdateKey": "Nexus:572", + "MapRemoteVersions": { "1.0.3": "1.0.2" } // manifest not updated + }, + + "Pony Weight Loss Program": { + "ID": "BadNetCode.PonyWeightLossProgram", + "Default | UpdateKey": "Nexus:1232" + }, + + "Portraiture": { + "ID": "Platonymous.Portraiture", + "Default | UpdateKey": "Nexus:999" // added in 1.3.1 + }, + + "Prairie King Made Easy": { + "ID": "Mucchan.PrairieKingMadeEasy", + "Default | UpdateKey": "Chucklefish:3594", + "~1.0 | Status": "AssumeBroken" // broke in SDV 1.2 + }, + + "Purchasable Recipes": { + "ID": "Paracosm.PurchasableRecipes", + "Default | UpdateKey": "Nexus:1722" + }, + + "Quest Delay": { + "ID": "BadNetCode.QuestDelay", + "Default | UpdateKey": "Nexus:1239" + }, + + "Recatch Legendary Fish": { + "ID": "cantorsdust.RecatchLegendaryFish", + "FormerIDs": "b3af8c31-48f0-43cf-8343-3eb08bcfa1f9 | community.RecatchLegendaryFish", // changed in 1.3 and 1.5.1 + "Default | UpdateKey": "Nexus:172" + }, + + "Regeneration": { + "ID": "HammurabiRegeneration", + "Default | UpdateKey": "Chucklefish:4584" + }, + + "Relationship Bar UI": { + "ID": "RelationshipBar", + "Default | UpdateKey": "Nexus:1009" + }, + + "RelationshipsEnhanced": { + "ID": "relationshipsenhanced", + "Default | UpdateKey": "Chucklefish:4435", + "~1.0 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Relationship Status": { + "ID": "relationshipstatus", + "MapRemoteVersions": { "1.0.5": "1.0.4" }, // not updated in manifest + "Default | UpdateKey": "Nexus:751", + "~1.0.5 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Rented Tools": { + "ID": "JarvieK.RentedTools", + "Default | UpdateKey": "Nexus:1307" + }, + + "Replanter": { + "ID": "jwdred.Replanter", + "Default | UpdateKey": "Nexus:589" + }, + + "ReRegeneration": { + "ID": "lrsk_sdvm_rerg.0925160827", + "MapLocalVersions": { "1.1.2-release": "1.1.2" }, + "Default | UpdateKey": "Chucklefish:4465" + }, + + "Reseed": { + "ID": "Roc.Reseed", + "Default | UpdateKey": "Nexus:887" + }, + + "Reusable Wallpapers and Floors (Wallpaper Retain)": { + "ID": "dae1b553-2e39-43e7-8400-c7c5c836134b", + "Default | UpdateKey": "Nexus:356", + "~1.5 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Ring of Fire": { + "ID": "Platonymous.RingOfFire", + "Default | UpdateKey": "Nexus:1166" // added in 1.0.1 + }, + + "Rope Bridge": { + "ID": "RopeBridge", + "Default | UpdateKey": "Nexus:824" + }, + + "Rotate Toolbar": { + "ID": "Pathoschild.RotateToolbar", + "Default | UpdateKey": "Nexus:1100", + "~1.2.1 | Status": "AssumeBroken" // broke in SDV 1.3 + }, + + "Rush Orders": { + "ID": "spacechase0.RushOrders", + "FormerIDs": "RushOrders", // changed in 1.1 + "Default | UpdateKey": "Nexus:605" + }, + + "Save Anywhere": { + "ID": "Omegasis.SaveAnywhere", + "Default | UpdateKey": "Nexus:444", // added in 2.6.1 + "MapRemoteVersions": { "2.6.2": "2.6.1" } // not updated in manifest + }, + + "Save Backup": { + "ID": "Omegasis.SaveBackup", + "Default | UpdateKey": "Nexus:435", // added in 1.3.1 + "~1.2 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Scroll to Blank": { + "ID": "caraxian.scroll.to.blank", + "Default | UpdateKey": "Chucklefish:4405" + }, + + "Scythe Harvesting": { + "ID": "mmanlapat.ScytheHarvesting", + "FormerIDs": "ScytheHarvesting", // changed in 1.6 + "Default | UpdateKey": "Nexus:1106" + }, + + "SDV Twitch": { + "ID": "MTD.SDVTwitch", + "Default | UpdateKey": "Nexus:1760" + }, + + "Seasonal Immersion": { + "ID": "Entoarox.SeasonalImmersion", + "FormerIDs": "EntoaroxSeasonalHouse | EntoaroxSeasonalBuildings | EntoaroxSeasonalImmersion", // changed in 1.1, 1.6 or earlier, and 1.7 + "~1.11 | UpdateKey": "Chucklefish:4262" // only enable update checks up to 1.11 by request (has its own update-check feature) + }, + + "Seed Bag": { + "ID": "Platonymous.SeedBag", + "Default | UpdateKey": "Nexus:1133" // added in 1.1.2 + }, + + "Seed Catalogue": { + "ID": "spacechase0.SeedCatalogue", + "Default | UpdateKey": "Nexus:1640" + }, + + "Self Service": { + "ID": "JarvieK.SelfService", + "MapRemoteVersions": { "0.2.1": "0.2" }, // manifest not updated + "Default | UpdateKey": "Nexus:1304" + }, + + "Send Items": { + "ID": "Denifia.SendItems", + "Default | UpdateKey": "Nexus:1087" // added in 1.0.3 (2017-10-04) + }, + + "Shed Notifications (BuildingsNotifications)": { + "ID": "TheCroak.BuildingsNotifications", + "Default | UpdateKey": "Nexus:620", + "~0.4.1 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Shenandoah Project": { + "ID": "Nishtra.ShenandoahProject", + "FormerIDs": "Shenandoah Project", // changed in 1.2 + "MapRemoteVersions": { "1.1.1": "1.1" }, // not updated in manifest + "Default | UpdateKey": "Nexus:756" + }, + + "Ship Anywhere": { + "ID": "spacechase0.ShipAnywhere", + "Default | UpdateKey": "Nexus:1379" + }, + + "Shipment Tracker": { + "ID": "7e474181-e1a0-40f9-9c11-d08a3dcefaf3", + "Default | UpdateKey": "Nexus:321" + }, + + "Shop Expander": { + "ID": "Entoarox.ShopExpander", + "FormerIDs": "EntoaroxShopExpander", // changed in 1.5 and 1.5.2; disambiguate from Faster Paths + "MapRemoteVersions": { "1.6.0b": "1.6.0" }, + "~1.6 | UpdateKey": "Chucklefish:4381" // only enable update checks up to 1.6 by request (has its own update-check feature) + }, + + "Showcase Mod": { + "ID": "Igorious.Showcase", + "MapLocalVersions": { "0.9-500": "0.9" }, + "Default | UpdateKey": "Chucklefish:4487", + "~0.9 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Shroom Spotter": { + "ID": "TehPers.ShroomSpotter", + "Default | UpdateKey": "Nexus:908" + }, + + "Simple Crop Label": { + "ID": "SimpleCropLabel", + "Default | UpdateKey": "Nexus:314" + }, + + "Simple Sound Manager": { + "ID": "Omegasis.SimpleSoundManager", + "Default | UpdateKey": "Nexus:1410" // added in 1.0.1 + }, + + "Simple Sprinklers": { + "ID": "tZed.SimpleSprinkler", + "Default | UpdateKey": "Nexus:76" + }, + + "Siv's Marriage Mod": { + "ID": "6266959802", // official version + "FormerIDs": "Siv.MarriageMod | medoli900.Siv's Marriage Mod", // 1.2.3-unofficial versions + "MapLocalVersions": { "0.0": "1.4" }, + "Default | UpdateKey": "Nexus:366" + }, + + "Skill Prestige": { + "ID": "alphablackwolf.skillPrestige", + "FormerIDs": "6b843e60-c8fc-4a25-a67b-4a38ac8dcf9b", // changed circa 1.2.3 + "Default | UpdateKey": "Nexus:569" + }, + + "Skill Prestige: Cooking Adapter": { + "ID": "Alphablackwolf.CookingSkillPrestigeAdapter", + "FormerIDs": "20d6b8a3-b6e7-460b-a6e4-07c2b0cb6c63", // changed circa 1.1 + "MapRemoteVersions": { "1.2.3": "1.1" }, // manifest not updated + "Default | UpdateKey": "Nexus:569" + }, + + "Skip Intro": { + "ID": "Pathoschild.SkipIntro", + "FormerIDs": "SkipIntro", // changed in 1.4 + "Default | UpdateKey": "Nexus:533", + "~1.7.2 | Status": "AssumeBroken" // broke in SDV 1.3 + }, + + "Skull Cavern Elevator": { + "ID": "SkullCavernElevator", + "Default | UpdateKey": "Nexus:963" + }, + + "Skull Cave Saver": { + "ID": "cantorsdust.SkullCaveSaver", + "FormerIDs": "8ac06349-26f7-4394-806c-95d48fd35774 | community.SkullCaveSaver", // changed in 1.1 and 1.2.2 + "Default | UpdateKey": "Nexus:175", + "1.3-beta | Status": "AssumeBroken" // doesn't work in multiplayer, no longer maintained + }, + + "Sleepy Eye": { + "ID": "spacechase0.SleepyEye", + "Default | UpdateKey": "Nexus:1152" + }, + + "Slower Fence Decay": { + "ID": "Speeder.SlowerFenceDecay", + "FormerIDs": "SPDSlowFenceDecay", // changed in 0.5.2-pathoschild-update + "Default | UpdateKey": "Nexus:252", + "~0.5.1 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Smart Mod": { + "ID": "KuroBear.SmartMod", + "~2.2 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Solar Eclipse Event": { + "ID": "KoihimeNakamura.SolarEclipseEvent", + "Default | UpdateKey": "Nexus:897", + "MapLocalVersions": { "1.3.1-20180131": "1.3.1" } + }, + + "SpaceCore": { + "ID": "spacechase0.SpaceCore", + "Default | UpdateKey": "Nexus:1348" + }, + + "Speedster": { + "ID": "Platonymous.Speedster", + "Default | UpdateKey": "Nexus:1102" // added in 1.3.1 + }, + + "Split Screen": { + "ID": "Ilyaki.SplitScreen", + "~3.0.1 | Status": "AssumeBroken" // broke in SMAPI 2.6-beta.16 due to reflection into SMAPI internals + }, + + "Sprinkler Range": { + "ID": "cat.sprinklerrange", + "Default | UpdateKey": "Nexus:1179" + }, + + "Sprinkles": { + "ID": "Platonymous.Sprinkles", + "Default | UpdateKey": "Chucklefish:4592" + }, + + "Sprint and Dash": { + "ID": "SPDSprintAndDash", + "Default | UpdateKey": "Nexus:235", + "~1.0 | Status": "AssumeBroken" // broke in SDV 1.2 + }, + + "Sprint and Dash Redux": { + "ID": "littleraskol.SprintAndDashRedux", + "FormerIDs": "lrsk_sdvm_sndr.0921161059", // changed in 1.3 + "Default | UpdateKey": "Chucklefish:4201" + }, + + "StackSplitX": { + "ID": "tstaples.StackSplitX", + "Default | UpdateKey": "Nexus:798" + }, + + "Stardew Config Menu": { + "ID": "Juice805.StardewConfigMenu", + "Default | UpdateKey": "Nexus:1312" + }, + + "Stardew Content Compatibility Layer (SCCL)": { + "ID": "SCCL", + "Default | UpdateKey": "Nexus:889", + "~0.1 | Status": "AssumeBroken" // broke in SDV 1.2 + }, + + "Stardew Editor Game Integration": { + "ID": "spacechase0.StardewEditor.GameIntegration", + "Default | UpdateKey": "Nexus:1298" + }, + + "Stardew Notification": { + "ID": "stardewnotification", + "Default | UpdateKey": "GitHub:monopandora/StardewNotification" + }, + + "Stardew Symphony": { + "ID": "Omegasis.StardewSymphony", + "Default | UpdateKey": "Nexus:425" // added in 1.4.1 + }, + + "StarDustCore": { + "ID": "StarDustCore", + "~ | Status": "Obsolete", + "~ | StatusReasonPhrase": "it was only used by earlier versions of Save Anywhere, and is no longer used or maintained." + }, + + "Starting Money": { + "ID": "mmanlapat.StartingMoney", + "FormerIDs": "StartingMoney", // changed in 1.1 + "Default | UpdateKey": "Nexus:1138" + }, + + "StashItemsToChest": { + "ID": "BlueMod_StashItemsToChest", + "Default | UpdateKey": "GitHub:lambui/StardewValleyMod_StashItemsToChest", + "~1.0.1 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Stephan's Lots of Crops": { + "ID": "stephansstardewcrops", + "MapRemoteVersions": { "1.41": "1.1" }, // manifest not updated + "Default | UpdateKey": "Chucklefish:4314" + }, + + "Stumps to Hardwood Stumps": { + "ID": "StumpsToHardwoodStumps", + "Default | UpdateKey": "Nexus:691" + }, + + "Summit Reborn": { + "ID": "KoihimeNakamura.summitreborn", + "FormerIDs": "emissaryofinfinity.summitreborn", // changed in 1.0.2 + "~1.0.2 | Status": "AssumeBroken" // broke in SDV 1.3 (runtime errors) + }, + + "Super Greenhouse Warp Modifier": { + "ID": "SuperGreenhouse", + "Default | UpdateKey": "Chucklefish:4334", + "~1.0 | Status": "AssumeBroken" // broke in SMAPI 2.0 + }, + + "Swim Almost Anywhere / Swim Suit": { + "ID": "Platonymous.SwimSuit", + "Default | UpdateKey": "Nexus:1215" // added in 0.5.1 + }, + + "Tapper Ready": { + "ID": "skunkkk.TapperReady", + "Default | UpdateKey": "Nexus:1219" + }, + + "Teh's Fishing Overhaul": { + "ID": "TehPers.FishingOverhaul", + "Default | UpdateKey": "Nexus:866" + }, + + "Teleporter": { + "ID": "Teleporter", + "Default | UpdateKey": "Chucklefish:4374", + "~1.0.2 | Status": "AssumeBroken" // broke in SDV 1.2 + }, + + "The Long Night": { + "ID": "Pathoschild.TheLongNight", + "Default | UpdateKey": "Nexus:1369", + "~1.1.1 | Status": "AssumeBroken" // broke in SDV 1.3 + }, + + "Three-heart Dance Partner": { + "ID": "ThreeHeartDancePartner", + "Default | UpdateKey": "Nexus:500" + }, + + "TimeFreeze": { + "ID": "Omegasis.TimeFreeze", + "FormerIDs": "4108e859-333c-4fec-a1a7-d2e18c1019fe", // changed in 1.2 + "Default | UpdateKey": "Nexus:973" // added in 1.2.1 + }, + + "Time Reminder": { + "ID": "KoihimeNakamura.TimeReminder", + "MapLocalVersions": { "1.0-20170314": "1.0.2" }, + "Default | UpdateKey": "Nexus:1000" + }, + + "TimeSpeed": { + "ID": "cantorsdust.TimeSpeed", + "FormerIDs": "community.TimeSpeed", // changed in 2.3.3 + "Default | UpdateKey": "Nexus:169" + }, + + "To Do List": { + "ID": "eleanor.todolist", + "Default | UpdateKey": "Nexus:1630" + }, + + "Tool Charging": { + "ID": "mralbobo.ToolCharging", + "Default | UpdateKey": "GitHub:mralbobo/stardew-tool-charging" + }, + + "TractorMod": { + "ID": "Pathoschild.TractorMod", + "FormerIDs": "BlueMod_TractorMod | PhthaloBlue.TractorMod | community.TractorMod", // changed in 3.2, 4.0 beta, and 4.0 + "Default | UpdateKey": "Nexus:1401", + "~4.5-beta | Status": "AssumeBroken" // broke in SDV 1.3 + }, + + "TrainerMod": { + "ID": "SMAPI.TrainerMod", + "~ | Status": "Obsolete", + "~ | StatusReasonPhrase": "replaced by ConsoleCommands, which is added by the SMAPI installer." + }, + + "Tree Transplant": { + "ID": "TreeTransplant", + "Default | UpdateKey": "Nexus:1342" + }, + + "UI Info Suite": { + "ID": "Cdaragorn.UiInfoSuite", + "Default | UpdateKey": "Nexus:1150" + }, + + "UiModSuite": { + "ID": "Demiacle.UiModSuite", + "MapLocalVersions": { "0.5": "1.0" }, // not updated in manifest + "Default | UpdateKey": "Nexus:1023", + "~1.0 | Status": "AssumeBroken" // broke in SDV 1.2 + }, + + "Variable Grass": { + "ID": "dantheman999.VariableGrass", + "Default | UpdateKey": "GitHub:dantheman999301/StardewMods" + }, + + "Vertical Toolbar": { + "ID": "SB_VerticalToolMenu", + "Default | UpdateKey": "Nexus:943" + }, + + "WarpAnimals": { + "ID": "Symen.WarpAnimals", + "Default | UpdateKey": "Nexus:1400" + }, + + "What Farm Cave / WhatAMush": { + "ID": "WhatAMush", + "Default | UpdateKey": "Nexus:1097" + }, + + "WHats Up": { + "ID": "wHatsUp", + "Default | UpdateKey": "Nexus:1082" + }, + + "Winter Grass": { + "ID": "cat.wintergrass", + "Default | UpdateKey": "Nexus:1601" + }, + + "Xnb Loader": { + "ID": "Entoarox.XnbLoader", + "~1.1.10 | UpdateKey": "Chucklefish:4506" // only enable update checks up to 1.1.10 by request (has its own update-check feature) + }, + + "zDailyIncrease": { + "ID": "zdailyincrease", + "MapRemoteVersions": { "1.3.5": "1.3.4" }, // not updated in manifest + "Default | UpdateKey": "Chucklefish:4247" + }, + + "Zoom Out Extreme": { + "ID": "RockinMods.ZoomMod", + "FormerIDs": "ZoomMod", // changed circa 1.2.1 + "Default | UpdateKey": "Nexus:1326", + "~0.1 | Status": "AssumeBroken" // broke in SDV 1.2 + }, + + "Zoryn's Better RNG": { + "ID": "Zoryn.BetterRNG", + "FormerIDs": "76b6d1e1-f7ba-4d72-8c32-5a1e6d2716f6", // changed in 1.6 + "Default | UpdateKey": "GitHub:Zoryn4163/SMAPI-Mods", + "~1.6 | Status": "AssumeBroken" // broke in SDV 1.2 + }, + + "Zoryn's Calendar Anywhere": { + "ID": "Zoryn.CalendarAnywhere", + "FormerIDs": "a41c01cd-0437-43eb-944f-78cb5a53002a", // changed in 1.6 + "Default | UpdateKey": "GitHub:Zoryn4163/SMAPI-Mods", + "~1.6 | Status": "AssumeBroken" // broke in SDV 1.2 + }, + + "Zoryn's Durable Fences": { + "ID": "Zoryn.DurableFences", + "FormerIDs": "56d3439c-7b9b-497e-9496-0c4890e8a00e", // changed in 1.6 + "Default | UpdateKey": "GitHub:Zoryn4163/SMAPI-Mods" + }, + + "Zoryn's Health Bars": { + "ID": "Zoryn.HealthBars", + "Default | UpdateKey": "GitHub:Zoryn4163/SMAPI-Mods", + "~1.6 | Status": "AssumeBroken" // broke in SDV 1.2 + }, + + "Zoryn's Fishing Mod": { + "ID": "Zoryn.FishingMod", + "FormerIDs": "fa277b1f-265e-47c3-a84f-cd320cc74949", // changed in 1.6 + "Default | UpdateKey": "GitHub:Zoryn4163/SMAPI-Mods" + }, + + "Zoryn's Junimo Deposit Anywhere": { + "ID": "Zoryn.JunimoDepositAnywhere", + "FormerIDs": "f93a4fe8-cade-4146-9335-b5f82fbbf7bc", // changed in 1.6 + "Default | UpdateKey": "GitHub:Zoryn4163/SMAPI-Mods", + "~1.7 | Status": "AssumeBroken" // broke in SDV 1.2 + }, + + "Zoryn's Movement Mod": { + "ID": "Zoryn.MovementModifier", + "FormerIDs": "8a632929-8335-484f-87dd-c29d2ba3215d", // changed in 1.6 + "Default | UpdateKey": "GitHub:Zoryn4163/SMAPI-Mods" + }, + + "Zoryn's Regen Mod": { + "ID": "Zoryn.RegenMod", + "FormerIDs": "dfac4383-1b6b-4f33-ae4e-37fc23e5252e", // changed in 1.6 + "Default | UpdateKey": "GitHub:Zoryn4163/SMAPI-Mods", + "~1.6 | Status": "AssumeBroken" // broke in SDV 1.2 + } + } +} diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj index f849ee53..c13f5e30 100644 --- a/src/SMAPI/StardewModdingAPI.csproj +++ b/src/SMAPI/StardewModdingAPI.csproj @@ -293,16 +293,17 @@ Designer - Always + PreserveNewest - + + StardewModdingAPI.metadata.json PreserveNewest - Always + PreserveNewest diff --git a/src/SMAPI/StardewModdingAPI.metadata.json b/src/SMAPI/StardewModdingAPI.metadata.json deleted file mode 100644 index 343257f1..00000000 --- a/src/SMAPI/StardewModdingAPI.metadata.json +++ /dev/null @@ -1,1668 +0,0 @@ -{ - /** - * 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 - * default display name for the mod if one isn't available (e.g. in dependency checks). - * - * - ID: the mod's latest unique ID (if any). - * - * - FormerIDs: uniquely identifies the mod across multiple versions, and supports matching - * other fields if no ID was specified. This doesn't include the latest ID, if any. Multiple - * variants can be separated with '|'. - * - * - MapLocalVersions and MapRemoteVersions correct local manifest versions and remote versions - * during update checks. For example, if the API returns version '1.1-1078' where '1078' is - * intended to be a build number, MapRemoteVersions can map it to '1.1' when comparing to the - * mod's current version. This is only meant to support legacy mods with injected update keys. - * - * Versioned metadata - * ================== - * Each record can also specify extra metadata using the field keys below. - * - * Each key consists of a field name prefixed with any combination of version range and 'Default', - * separated by pipes (whitespace trimmed). For example, 'UpdateKey' will always override, - * 'Default | UpdateKey' will only override if the mod has no update keys, and - * '~1.1 | Default | Name' will do the same up to version 1.1. - * - * The version format is 'min~max' (where either side can be blank for unbounded), or a single - * version number. - * - * These are the valid field names: - * - * - UpdateKey: the update key to set in the mod's manifest. This is used to enable update - * checks for older mods that haven't been updated to use it yet. - * - * - Status: overrides compatibility checks. The possible values are Obsolete (SMAPI won't load - * it because the mod should no longer be used), AssumeBroken (SMAPI won't load it because - * the specified version isn't compatible), or AssumeCompatible (SMAPI will try to load it - * even if it detects incompatible code). - * - * Note that this shouldn't be set to 'AssumeBroken' if SMAPI can detect the incompatibility - * automatically, since that hides the details from trace logs. - * - * - StatusReasonPhrase: a message to show to the player explaining why the mod can't be loaded - * (if applicable). If blank, will default to a generic not-compatible message. - * - * - AlternativeUrl: a URL where the player can find an unofficial update or alternative if the - * mod is no longer compatible. - */ - "ModData": { - "AccessChestAnywhere": { - "ID": "AccessChestAnywhere", - "MapLocalVersions": { "1.1-1078": "1.1" }, - "Default | UpdateKey": "Nexus:257", - "~1.1 | Status": "AssumeBroken" - }, - - "Adjust Artisan Prices": { - "ID": "ThatNorthernMonkey.AdjustArtisanPrices", - "FormerIDs": "1e36d4ca-c7ef-4dfb-9927-d27a6c3c8bdc", // changed in 0.0.2-pathoschild-update - "MapRemoteVersions": { "0.01": "0.0.1" }, - "Default | UpdateKey": "Chucklefish:3532" - }, - - "Adjust Monster": { - "ID": "mmanlapat.AdjustMonster", - "Default | UpdateKey": "Nexus:1161" - }, - - "Advanced Location Loader": { - "ID": "Entoarox.AdvancedLocationLoader", - "~1.3.7 | UpdateKey": "Chucklefish:3619" // only enable update checks up to 1.3.7 by request (has its own update-check feature) - }, - - "Adventure Shop Inventory": { - "ID": "HammurabiAdventureShopInventory", - "Default | UpdateKey": "Chucklefish:4608" - }, - - "AgingMod": { - "ID": "skn.AgingMod", - "Default | UpdateKey": "Nexus:1129", - "~1.0 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "All Crops All Seasons": { - "ID": "cantorsdust.AllCropsAllSeasons", - "FormerIDs": "29ee8246-d67b-4242-a340-35a9ae0d5dd7 | community.AllCropsAllSeasons", // changed in 1.3 and 1.5 - "Default | UpdateKey": "Nexus:170" - }, - - "All Professions": { - "ID": "cantorsdust.AllProfessions", - "FormerIDs": "8c37b1a7-4bfb-4916-9d8a-9533e6363ea3 | community.AllProfessions", // changed in 1.2 and 1.3.1 - "Default | UpdateKey": "Nexus:174" - }, - - "Almighty Farming Tool": { - "ID": "439", - "MapRemoteVersions": { "1.21": "1.2.1" }, - "Default | UpdateKey": "Nexus:439" - }, - - "Animal Husbandry": { - "ID": "DIGUS.ANIMALHUSBANDRYMOD", - "FormerIDs": "DIGUS.BUTCHER", // changed in 2.0.1 - "Default | UpdateKey": "Nexus:1538" - }, - - "Animal Mood Fix": { - "ID": "GPeters-AnimalMoodFix", - "~ | Status": "Obsolete", - "~ | StatusReasonPhrase": "the animal mood bugs were fixed in Stardew Valley 1.2." - }, - - "Animal Sitter": { - "ID": "jwdred.AnimalSitter", - "Default | UpdateKey": "Nexus:581", - "~1.0.8 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Arcade Pong": { - "ID": "Platonymous.ArcadePong", - "~1.0.2 | Status": "AssumeBroken" // broke in SMAPI 2.6-beta.16 due to reflection into SMAPI internals - }, - - "A Tapper's Dream": { - "ID": "ddde5195-8f85-4061-90cc-0d4fd5459358", - "Default | UpdateKey": "Nexus:260" - }, - - "Auto Animal Doors": { - "ID": "AaronTaggart.AutoAnimalDoors", - "Default | UpdateKey": "Nexus:1019" - }, - - "Auto-Eat": { - "ID": "Permamiss.AutoEat", - "FormerIDs": "BALANCEMOD_AutoEat", // changed in 1.1.1 - "Default | UpdateKey": "Nexus:643" - }, - - "AutoFish": { - "ID": "WhiteMind.AF", - "Default | UpdateKey": "Nexus:1895" - }, - - "AutoGate": { - "ID": "AutoGate", - "Default | UpdateKey": "Nexus:820" - }, - - "Automate": { - "ID": "Pathoschild.Automate", - "Default | UpdateKey": "Nexus:1063", - "~1.10-beta.7 | Status": "AssumeBroken" // broke in SDV 1.3.20 - }, - - "Automated Doors": { - "ID": "azah.automated-doors", - "FormerIDs": "1abcfa07-2cf4-4dc3-a6e9-6068b642112b", // changed in 1.4.1 - "Default | UpdateKey": "GitHub:azah/AutomatedDoors" // added in 1.4.2 - }, - - "AutoSpeed": { - "ID": "Omegasis.AutoSpeed", - "Default | UpdateKey": "Nexus:443" // added in 1.4.1 - }, - - "Basic Sprinklers Improved": { - "ID": "lrsk_sdvm_bsi.0117171308", - "MapRemoteVersions": { "1.0.2": "1.0.1-release" }, // manifest not updated - "Default | UpdateKey": "Nexus:833" - }, - - "Better Hay": { - "ID": "cat.betterhay", - "Default | UpdateKey": "Nexus:1430" - }, - - "Better Quality More Seasons": { - "ID": "SB_BQMS", - "Default | UpdateKey": "Nexus:935" - }, - - "Better Quarry": { - "ID": "BetterQuarry", - "Default | UpdateKey": "Nexus:771" - }, - - "Better Ranching": { - "ID": "BetterRanching", - "Default | UpdateKey": "Nexus:859" - }, - - "Better Shipping Box": { - "ID": "Kithio:BetterShippingBox", - "MapLocalVersions": { "1.0.1": "1.0.2" }, - "Default | UpdateKey": "Chucklefish:4302" - }, - - "Better Sprinklers": { - "ID": "Speeder.BetterSprinklers", - "FormerIDs": "SPDSprinklersMod", // changed in 2.3 - "Default | UpdateKey": "Nexus:41" - }, - - "Billboard Anywhere": { - "ID": "Omegasis.BillboardAnywhere", - "Default | UpdateKey": "Nexus:492" // added in 1.4.1 - }, - - "Birthday Mail": { - "ID": "KathrynHazuka.BirthdayMail", - "FormerIDs": "005e02dc-d900-425c-9c68-1ff55c5a295d", // changed in 1.2.3-pathoschild-update - "Default | UpdateKey": "Nexus:276", - "MapRemoteVersions": { "1.3.1": "1.3" } // manifest not updated - }, - - "Breed Like Rabbits": { - "ID": "dycedarger.breedlikerabbits", - "Default | UpdateKey": "Nexus:948" - }, - - "Build Endurance": { - "ID": "Omegasis.BuildEndurance", - "Default | UpdateKey": "Nexus:445" // added in 1.4.1 - }, - - "Build Health": { - "ID": "Omegasis.BuildHealth", - "Default | UpdateKey": "Nexus:446" // added in 1.4.1 - }, - - "Buy Cooking Recipes": { - "ID": "Denifia.BuyRecipes", - "Default | UpdateKey": "Nexus:1126" // added in 1.0.1 (2017-10-04) - }, - - "Buy Back Collectables": { - "ID": "Omegasis.BuyBackCollectables", - "FormerIDs": "BuyBackCollectables", // changed in 1.4 - "Default | UpdateKey": "Nexus:507" // added in 1.4.1 - }, - - "Carry Chest": { - "ID": "spacechase0.CarryChest", - "Default | UpdateKey": "Nexus:1333" - }, - - "Casks Anywhere": { - "ID": "CasksAnywhere", - "MapLocalVersions": { "1.1-alpha": "1.1" }, - "Default | UpdateKey": "Nexus:878" - }, - - "Categorize Chests": { - "ID": "CategorizeChests", - "Default | UpdateKey": "Nexus:1300", - "~1.4.3-unofficial.2.mizzion | Status": "AssumeBroken" // broke in SMAPI 2.6-beta.18 (in-game errors) - }, - - "Chefs Closet": { - "ID": "Duder.ChefsCloset", - "MapLocalVersions": { "1.3-1": "1.3" }, - "Default | UpdateKey": "Nexus:1030" - }, - - "Chest Label System": { - "ID": "Speeder.ChestLabel", - "FormerIDs": "SPDChestLabel", // changed in 1.5.1-pathoschild-update - "Default | UpdateKey": "Nexus:242" - }, - - "Chest Pooling": { - "ID": "mralbobo.ChestPooling", - "Default | UpdateKey": "GitHub:mralbobo/stardew-chest-pooling" - }, - - "Chests Anywhere": { - "ID": "Pathoschild.ChestsAnywhere", - "FormerIDs": "ChestsAnywhere", // changed in 1.9 - "Default | UpdateKey": "Nexus:518", - "~1.12.4 | Status": "AssumeBroken" // broke in SDV 1.3 - }, - - "CJB Automation": { - "ID": "CJBAutomation", - "Default | UpdateKey": "Nexus:211", - "~1.4 | Status": "AssumeBroken", // broke in SDV 1.2 - "~1.4 | AlternativeUrl": "http://www.nexusmods.com/stardewvalley/mods/1063" - }, - - "CJB Cheats Menu": { - "ID": "CJBok.CheatsMenu", - "FormerIDs": "CJBCheatsMenu", // changed in 1.14 - "Default | UpdateKey": "Nexus:4", - "~1.18-beta | Status": "AssumeBroken" // broke in SDV 1.3, first beta causes significant friendship bugs - }, - - "CJB Item Spawner": { - "ID": "CJBok.ItemSpawner", - "FormerIDs": "CJBItemSpawner", // changed in 1.7 - "Default | UpdateKey": "Nexus:93", - "~1.10 | Status": "AssumeBroken" // broke in SDV 1.3 - }, - - "CJB Show Item Sell Price": { - "ID": "CJBok.ShowItemSellPrice", - "FormerIDs": "CJBShowItemSellPrice", // changed in 1.7 - "Default | UpdateKey": "Nexus:5", - "~1.8 | Status": "AssumeBroken" // broke in SDV 1.3 - }, - - "Clean Farm": { - "ID": "tstaples.CleanFarm", - "Default | UpdateKey": "Nexus:794" - }, - - "Climates of Ferngill": { - "ID": "KoihimeNakamura.ClimatesOfFerngill", - "Default | UpdateKey": "Nexus:604" - }, - - "Coal Regen": { - "ID": "Blucifer.CoalRegen", - "Default | UpdateKey": "Nexus:1664" - }, - - "Cobalt": { - "ID": "spacechase0.Cobalt", - "MapRemoteVersions": { "1.1.3": "1.1.2" } // not updated in manifest - }, - - "Cold Weather Haley": { - "ID": "LordXamon.ColdWeatherHaleyPRO", - "Default | UpdateKey": "Nexus:1169", - "~1.0 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Colored Chests": { - "ID": "4befde5c-731c-4853-8e4b-c5cdf946805f", - "~ | Status": "Obsolete", - "~ | StatusReasonPhrase": "colored chests were added in Stardew Valley 1.1." - }, - - "Combat with Farm Implements": { - "ID": "SPDFarmingImplementsInCombat", - "Default | UpdateKey": "Nexus:313" - }, - - "Community Bundle Item Tooltip": { - "ID": "musbah.bundleTooltip", - "Default | UpdateKey": "Nexus:1329" - }, - - "Concentration on Farming": { - "ID": "punyo.ConcentrationOnFarming", - "Default | UpdateKey": "Nexus:1445" - }, - - "Configurable Machines": { - "ID": "21da6619-dc03-4660-9794-8e5b498f5b97", - "MapLocalVersions": { "1.2-beta": "1.2" }, - "Default | UpdateKey": "Nexus:280" - }, - - "Configurable Shipping Dates": { - "ID": "ConfigurableShippingDates", - "Default | UpdateKey": "Nexus:675", - "~1.1.1 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Content Patcher": { - "ID": "Pathoschild.ContentPatcher", - "Default | UpdateKey": "Nexus:1915", - "~1.4-beta.5 | Status": "AssumeBroken" // broke in SMAPI 2.6-beta.18 (in-game errors) - }, - - "Cooking Skill": { - "ID": "spacechase0.CookingSkill", - "FormerIDs": "CookingSkill", // changed in 1.0.4–6 - "Default | UpdateKey": "Nexus:522" - }, - - "CrabNet": { - "ID": "jwdred.CrabNet", - "Default | UpdateKey": "Nexus:584" - }, - - "Crafting Counter": { - "ID": "lolpcgaming.CraftingCounter", - "Default | UpdateKey": "Nexus:1585", - "MapRemoteVersions": { "1.1": "1.0" } // not updated in manifest - }, - - "Current Location": { - "ID": "CurrentLocation102120161203", - "Default | UpdateKey": "Nexus:638" - }, - - "Custom Asset Modifier": { - "ID": "Omegasis.CustomAssetModifier", - "Default | UpdateKey": "1836" - }, - - "Custom Critters": { - "ID": "spacechase0.CustomCritters", - "Default | UpdateKey": "Nexus:1255" - }, - - "Custom Crops": { - "ID": "spacechase0.CustomCrops", - "Default | UpdateKey": "Nexus:1592" - }, - - "Custom Element Handler": { - "ID": "Platonymous.CustomElementHandler", - "Default | UpdateKey": "Nexus:1068" // added in 1.3.1 - }, - - "Custom Farming Redux": { - "ID": "Platonymous.CustomFarming", - "Default | UpdateKey": "Nexus:991" // added in 0.6.1 - }, - - "Custom Farming Automate Bridge": { - "ID": "Platonymous.CFAutomate", - "~1.0.1 | Status": "AssumeBroken", // no longer compatible with Automate - "~1.0.1 | AlternativeUrl": "https://www.nexusmods.com/stardewvalley/mods/991" - }, - - "Custom Farm Types": { - "ID": "spacechase0.CustomFarmTypes", - "Default | UpdateKey": "Nexus:1140" - }, - - "Custom Furniture": { - "ID": "Platonymous.CustomFurniture", - "Default | UpdateKey": "Nexus:1254" // added in 0.4.1 - }, - - "Customize Exterior": { - "ID": "spacechase0.CustomizeExterior", - "FormerIDs": "CustomizeExterior", // changed in 1.0.3 - "Default | UpdateKey": "Nexus:1099", - "~1.0.2 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Customizable Cart Redux": { - "ID": "KoihimeNakamura.CCR", - "MapLocalVersions": { "1.1-20170917": "1.1" }, - "Default | UpdateKey": "Nexus:1402" - }, - - "Customizable Traveling Cart Days": { - "ID": "TravelingCartYyeahdude", - "Default | UpdateKey": "Nexus:567" - }, - - "Custom Linens": { - "ID": "Mevima.CustomLinens", - "MapRemoteVersions": { "1.1": "1.0" }, // manifest not updated - "Default | UpdateKey": "Nexus:1027" - }, - - "Custom NPC": { - "ID": "Platonymous.CustomNPC", - "Default | UpdateKey": "Nexus:1607" - }, - - "Custom Shops Redux": { - "ID": "Omegasis.CustomShopReduxGui", - "Default | UpdateKey": "Nexus:1378" // added in 1.4.1 - }, - - "Custom TV": { - "ID": "Platonymous.CustomTV", - "Default | UpdateKey": "Nexus:1139" // added in 1.0.6 - }, - - "Daily Luck Message": { - "ID": "Schematix.DailyLuckMessage", - "Default | UpdateKey": "Nexus:1327" - }, - - "Daily News": { - "ID": "bashNinja.DailyNews", - "Default | UpdateKey": "Nexus:1141", - "~1.2 | Status": "AssumeBroken" // broke in Stardew Valley 1.3 (or depends on CustomTV which broke) - }, - - "Daily Quest Anywhere": { - "ID": "Omegasis.DailyQuestAnywhere", - "FormerIDs": "DailyQuest", // changed in 1.4 - "Default | UpdateKey": "Nexus:513" // added in 1.4.1 - }, - - "Data Maps": { - "ID": "Pathoschild.DataMaps", - "Default | UpdateKey": "Nexus:1691", - "~1.3 | Status": "AssumeBroken" // broke in SDV 1.3 - }, - - "Debug Mode": { - "ID": "Pathoschild.DebugMode", - "FormerIDs": "Pathoschild.Stardew.DebugMode", // changed in 1.4 - "Default | UpdateKey": "Nexus:679", - "~1.8 | Status": "AssumeBroken" // broke in SDV 1.3 - }, - - "Did You Water Your Crops?": { - "ID": "Nishtra.DidYouWaterYourCrops", - "Default | UpdateKey": "Nexus:1583" - }, - - "Dynamic Checklist": { - "ID": "gunnargolf.DynamicChecklist", - "Default | UpdateKey": "Nexus:1145" // added in 1.0.1-pathoschild-update - }, - - "Dynamic Horses": { - "ID": "Bpendragon-DynamicHorses", - "MapRemoteVersions": { "1.2": "1.1-release" }, // manifest not updated - "Default | UpdateKey": "Nexus:874" - }, - - "Dynamic Machines": { - "ID": "DynamicMachines", - "MapLocalVersions": { "1.1": "1.1.1" }, - "Default | UpdateKey": "Nexus:374", - "~1.1.1 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Dynamic NPC Sprites": { - "ID": "BashNinja.DynamicNPCSprites", - "Default | UpdateKey": "Nexus:1183" - }, - - "Easier Farming": { - "ID": "cautiouswafffle.EasierFarming", - "Default | UpdateKey": "Nexus:1426" - }, - - "Empty Hands": { - "ID": "QuicksilverFox.EmptyHands", - "Default | UpdateKey": "Nexus:1176" // added in 1.0.1-pathoschild-update - }, - - "Enemy Health Bars": { - "ID": "Speeder.HealthBars", - "FormerIDs": "SPDHealthBar", // changed in 1.7.1-pathoschild-update - "Default | UpdateKey": "Nexus:193" - }, - - "Entoarox Framework": { - "ID": "Entoarox.EntoaroxFramework", - "FormerIDs": "eacdb74b-4080-4452-b16b-93773cda5cf9", // changed in ??? - "~2.0.6 | UpdateKey": "Chucklefish:4228", // only enable update checks up to 2.0.6 by request (has its own update-check feature) - "~2.0.6 | Status": "AssumeBroken" // broke in SMAPI 2.5 (error reflecting into SMAPI internals) - }, - - "Expanded Fridge": { - "ID": "Uwazouri.ExpandedFridge", - "Default | UpdateKey": "Nexus:1191" - }, - - "Experience Bars": { - "ID": "spacechase0.ExperienceBars", - "FormerIDs": "ExperienceBars", // changed in 1.0.2 - "Default | UpdateKey": "Nexus:509" - }, - - "Extended Bus System": { - "ID": "ExtendedBusSystem", - "Default | UpdateKey": "Chucklefish:4373" - }, - - "Extended Fridge": { - "ID": "Crystalmir.ExtendedFridge", - "FormerIDs": "Mystra007ExtendedFridge", // changed in 1.0.1 - "Default | UpdateKey": "Nexus:485" - }, - - "Extended Greenhouse": { - "ID": "ExtendedGreenhouse", - "Default | UpdateKey": "Chucklefish:4303", - "~1.0.2 | Status": "AssumeBroken" // broke in SDV 1.2 - }, - - "Extended Minecart": { - "ID": "Entoarox.ExtendedMinecart", - "~1.7.1 | UpdateKey": "Chucklefish:4359" // only enable update checks up to 1.7.1 by request (has its own update-check feature) - }, - - "Extended Reach": { - "ID": "spacechase0.ExtendedReach", - "Default | UpdateKey": "Nexus:1493" - }, - - "Fall 28 Snow Day": { - "ID": "Omegasis.Fall28SnowDay", - "Default | UpdateKey": "Nexus:486", // added in 1.4.1 - "~1.4.1 | Status": "AssumeBroken" // broke in SMAPI 2.0, and update for SMAPI 2.0 doesn't do anything - }, - - "Farm Automation Unofficial: Item Collector": { - "ID": "Maddy99.FarmAutomation.ItemCollector", - "~0.5 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Farm Expansion": { - "ID": "Advize.FarmExpansion", - "FormerIDs": "3888bdfd-73f6-4776-8bb7-8ad45aea1915 | AdvizeFarmExpansionMod-2-0 | AdvizeFarmExpansionMod-2-0-5", // changed in 2.0, 2.0.5, and 3.0 - "Default | UpdateKey": "Nexus:130" - }, - - "Fast Animations": { - "ID": "Pathoschild.FastAnimations", - "Default | UpdateKey": "Nexus:1089", - "~1.5 | Status": "AssumeBroken" // broke in SDV 1.3 - }, - - "Faster Grass": { - "ID": "IceGladiador.FasterGrass", - "Default | UpdateKey": "Nexus:1772" - }, - - "Faster Paths": { - "ID": "Entoarox.FasterPaths", - "FormerIDs": "615f85f8-5c89-44ee-aecc-c328f172e413", // changed in 1.3 - "~1.3.3 | UpdateKey": "Chucklefish:3641" // only enable update checks up to 1.3.3 by request (has its own update-check feature) - }, - - "Fishing Adjust": { - "ID": "shuaiz.FishingAdjustMod", - "Default | UpdateKey": "Nexus:1350", - "~2.0.1 | Status": "AssumeBroken" // Method not found: 'Void Harmony.HarmonyInstance.Patch(System.Reflection.MethodBase, Harmony.HarmonyMethod, Harmony.HarmonyMethod, Harmony.HarmonyMethod)' - }, - - "Fishing Tuner Redux": { - "ID": "HammurabiFishingTunerRedux", - "Default | UpdateKey": "Chucklefish:4578" - }, - - "Fixed Secret Woods Debris": { - "ID": "f4iTh.WoodsDebrisFix", - "Default | UpdateKey": "Nexus:1941" - }, - - "Flower Color Picker": { - "ID": "spacechase0.FlowerColorPicker", - "Default | UpdateKey": "Nexus:1229" - }, - - "Forage at the Farm": { - "ID": "Nishtra.ForageAtTheFarm", - "FormerIDs": "ForageAtTheFarm", // changed in <=1.6 - "Default | UpdateKey": "Nexus:673" - }, - - "Furniture Anywhere": { - "ID": "Entoarox.FurnitureAnywhere", - "~1.1.5 | UpdateKey": "Chucklefish:4324" // only enable update checks up to 1.1.5 by request (has its own update-check feature) - }, - - "Game Reminder": { - "ID": "mmanlapat.GameReminder", - "Default | UpdateKey": "Nexus:1153" - }, - - "Gate Opener": { - "ID": "mralbobo.GateOpener", - "Default | UpdateKey": "GitHub:mralbobo/stardew-gate-opener" - }, - - "GenericShopExtender": { - "ID": "GenericShopExtender", - "Default | UpdateKey": "Nexus:814" // added in 0.1.3 - }, - - "Geode Info Menu": { - "ID": "cat.geodeinfomenu", - "Default | UpdateKey": "Nexus:1448" - }, - - "Get Dressed": { - "ID": "Advize.GetDressed", - "Default | UpdateKey": "Nexus:331" - }, - - "Giant Crop Ring": { - "ID": "cat.giantcropring", - "Default | UpdateKey": "Nexus:1182" - }, - - "Gift Taste Helper": { - "ID": "tstaples.GiftTasteHelper", - "FormerIDs": "8008db57-fa67-4730-978e-34b37ef191d6", // changed in 2.5 - "Default | UpdateKey": "Nexus:229" - }, - - "Grandfather's Gift": { - "ID": "ShadowDragon.GrandfathersGift", - "Default | UpdateKey": "Nexus:985" - }, - - "Happy Animals": { - "ID": "HappyAnimals", - "~1.0.3 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Happy Birthday (Omegasis)": { - "ID": "Omegasis.HappyBirthday", - "Default | UpdateKey": "Nexus:520" // added in 1.4.1 - }, - - "Hardcore Mines": { - "ID": "kibbe.hardcore_mines", - "Default | UpdateKey": "Nexus:1674" - }, - - "Harp of Yoba Redux": { - "ID": "Platonymous.HarpOfYobaRedux", - "Default | UpdateKey": "Nexus:914" // added in 2.0.3 - }, - - "Harvest Moon Witch Princess": { - "ID": "Sasara.WitchPrincess", - "Default | UpdateKey": "Nexus:1157" - }, - - "Harvest With Scythe": { - "ID": "965169fd-e1ed-47d0-9f12-b104535fb4bc", - "Default | UpdateKey": "Nexus:236" - }, - - "Horse Whistle (icepuente)": { - "ID": "icepuente.HorseWhistle", - "Default | UpdateKey": "Nexus:1131", - "~1.1.2-unofficial.1-pathoschild | Status": "AssumeBroken" // causes significant lag, fixed in unofficial.2 - }, - - "Hunger (Yyeadude)": { - "ID": "HungerYyeadude", - "Default | UpdateKey": "Nexus:613" - }, - - "Hunger for Food (Tigerle)": { - "ID": "HungerForFoodByTigerle", - "Default | UpdateKey": "Nexus:810", - "~0.1.2 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Hunger Mod (skn)": { - "ID": "skn.HungerMod", - "MapRemoteVersions": { "1.2.1": "1.0" }, // manifest not updated - "Default | UpdateKey": "Nexus:1127" - }, - - "Idle Pause": { - "ID": "Veleek.IdlePause", - "MapRemoteVersions": { "1.2": "1.1" }, // manifest not updated - "Default | UpdateKey": "Nexus:1092" - }, - - "Improved Quality of Life": { - "ID": "Demiacle.ImprovedQualityOfLife", - "Default | UpdateKey": "Nexus:1025", - "~1.1 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Instant Geode": { - "ID": "InstantGeode", - "~1.12 | Status": "AssumeBroken" // broke in SDV 1.2 - }, - - "Instant Grow Trees": { - "ID": "cantorsdust.InstantGrowTrees", - "FormerIDs": "dc50c58b-c7d8-4e60-86cc-e27b5d95ee59 | community.InstantGrowTrees", // changed in 1.2 and 1.3.1 - "Default | UpdateKey": "Nexus:173" - }, - - "Interaction Helper": { - "ID": "HammurabiInteractionHelper", - "Default | UpdateKey": "Chucklefish:4640" // added in 1.0.4-pathoschild-update - }, - - "Item Auto Stacker": { - "ID": "cat.autostacker", - "MapRemoteVersions": { "1.0.1": "1.0" }, // manifest not updated - "Default | UpdateKey": "Nexus:1184" - }, - - "Json Assets": { - "ID": "spacechase0.JsonAssets", - "Default | UpdateKey": "Nexus:1720" - }, - - "Junimo Farm": { - "ID": "Platonymous.JunimoFarm", - "MapRemoteVersions": { "1.1.2": "1.1.1" }, // manifest not updated - "Default | UpdateKey": "Nexus:984" // added in 1.1.3 - }, - - "Less Strict Over-Exertion (AntiExhaustion)": { - "ID": "BALANCEMOD_AntiExhaustion", - "MapLocalVersions": { "0.0": "1.1" }, - "Default | UpdateKey": "Nexus:637", - "~1.1 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Level Extender": { - "ID": "DevinLematty.LevelExtender", - "FormerIDs": "Devin Lematty.Level Extender", // changed in 1.3 - "Default | UpdateKey": "Nexus:1471" - }, - - "Level Up Notifications": { - "ID": "Level Up Notifications", - "MapRemoteVersions": { "0.0.1a": "0.0.1" }, - "Default | UpdateKey": "Nexus:855" - }, - - "Location and Music Logging": { - "ID": "Brandy Lover.LMlog", - "Default | UpdateKey": "Nexus:1366" - }, - - "Longevity": { - "ID": "RTGOAT.Longevity", - "MapRemoteVersions": { "1.6.8h": "1.6.8" }, - "Default | UpdateKey": "Nexus:649" - }, - - "Lookup Anything": { - "ID": "Pathoschild.LookupAnything", - "FormerIDs": "LookupAnything", // changed in 1.10.1 - "Default | UpdateKey": "Nexus:541", - "~1.18.1 | Status": "AssumeBroken" // broke in SDV 1.3 - }, - - "Love Bubbles": { - "ID": "LoveBubbles", - "Default | UpdateKey": "Nexus:1318" - }, - - "Loved Labels": { - "ID": "Advize.LovedLabels", - "Default | UpdateKey": "Nexus:279" - }, - - "Luck Skill": { - "ID": "spacechase0.LuckSkill", - "FormerIDs": "LuckSkill", // changed in 0.1.4 - "Default | UpdateKey": "Nexus:521" - }, - - "Magic": { - "ID": "spacechase0.Magic", - "MapRemoteVersions": { "0.1.2": "0.1.1" } // not updated in manifest - }, - - "Mail Framework": { - "ID": "DIGUS.MailFrameworkMod", - "Default | UpdateKey": "Nexus:1536" - }, - - "MailOrderPigs": { - "ID": "jwdred.MailOrderPigs", - "Default | UpdateKey": "Nexus:632" - }, - - "Makeshift Multiplayer": { - "ID": "spacechase0.StardewValleyMP", - "FormerIDs": "StardewValleyMP", // changed in 0.3 - "Default | UpdateKey": "Nexus:501" - }, - - "Map Image Exporter": { - "ID": "spacechase0.MapImageExporter", - "FormerIDs": "MapImageExporter", // changed in 1.0.2 - "Default | UpdateKey": "Nexus:1073" - }, - - "Message Box [API]? (ChatMod)": { - "ID": "Kithio:ChatMod", - "Default | UpdateKey": "Chucklefish:4296", - "~1.0 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Mining at the Farm": { - "ID": "Nishtra.MiningAtTheFarm", - "FormerIDs": "MiningAtTheFarm", // changed in <=1.7 - "Default | UpdateKey": "Nexus:674" - }, - - "Mining With Explosives": { - "ID": "Nishtra.MiningWithExplosives", - "FormerIDs": "MiningWithExplosives", // changed in 1.1 - "Default | UpdateKey": "Nexus:770" - }, - - "Modder Serialization Utility": { - "ID": "SerializerUtils-0-1", - "~ | Status": "Obsolete", - "~ | StatusReasonPhrase": "it's no longer maintained or used." - }, - - "Monster Level Tip": { - "ID": "WhiteMind.MonsterLT", - "Default | UpdateKey": "Nexus:1896" - }, - - "More Animals": { - "ID": "Entoarox.MoreAnimals", - "FormerIDs": "821ce8f6-e629-41ad-9fde-03b54f68b0b6MOREPETS | Entoarox.MorePets", // changed in 1.3 and 2.0 - "~2.0.2 | UpdateKey": "Chucklefish:4288" // only enable update checks up to 2.0.2 by request (has its own update-check feature) - }, - - "More Artifact Spots": { - "ID": "451", - "Default | UpdateKey": "Nexus:451" - }, - - "More Map Layers": { - "ID": "Platonymous.MoreMapLayers", - "Default | UpdateKey": "Nexus:1134" // added in 1.1.1 - }, - - "More Rain": { - "ID": "Omegasis.MoreRain", - "Default | UpdateKey": "Nexus:441", // added in 1.5.1 - "~1.4 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "More Weapons": { - "ID": "Joco80.MoreWeapons", - "Default | UpdateKey": "Nexus:1168" - }, - - "Move Faster": { - "ID": "shuaiz.MoveFasterMod", - "Default | UpdateKey": "Nexus:1351", - "1.0.1 | Status": "AssumeBroken" // doesn't do anything as of SDV 1.2.33 (bad Harmony patch?) - }, - - "Multiple Sprites and Portraits On Rotation (File Loading)": { - "ID": "FileLoading", - "MapLocalVersions": { "1.1": "1.12" }, - "Default | UpdateKey": "Nexus:1094", - "~1.12 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Museum Rearranger": { - "ID": "Omegasis.MuseumRearranger", - "Default | UpdateKey": "Nexus:428" // added in 1.4.1 - }, - - "Mushroom Level Tip": { - "ID": "WhiteMind.MLT", - "Default | UpdateKey": "Nexus:1894" - }, - - "New Machines": { - "ID": "F70D4FAB-0AB2-4B78-9F1B-AF2CA2236A59", - "Default | UpdateKey": "Chucklefish:3683", - "~4.2.1343 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Night Owl": { - "ID": "Omegasis.NightOwl", - "MapLocalVersions": { "2.1": "1.3" }, // 1.3 had wrong version in manifest - "Default | UpdateKey": "Nexus:433" // added in 1.4.1 - }, - - "No Crows": { - "ID": "cat.nocrows", - "Default | UpdateKey": "Nexus:1682" - }, - - "No Kids Ever": { - "ID": "Hangy.NoKidsEver", - "Default | UpdateKey": "Nexus:1464" - }, - - "No Debug Mode": { - "ID": "NoDebugMode", - "~ | Status": "Obsolete", - "~ | StatusReasonPhrase": "debug mode was removed in SMAPI 1.0." - }, - - "No Fence Decay": { - "ID": "cat.nofencedecay", - "Default | UpdateKey": "Nexus:1180" - }, - - "No More Pets": { - "ID": "Omegasis.NoMorePets", - "FormerIDs": "NoMorePets", // changed in 1.4 - "Default | UpdateKey": "Nexus:506" // added in 1.4.1 - }, - - "No Rumble Horse": { - "ID": "Xangria.NoRumbleHorse", - "Default | UpdateKey": "Nexus:1779" - }, - - "No Soil Decay": { - "ID": "289dee03-5f38-4d8e-8ffc-e440198e8610", - "Default | UpdateKey": "Nexus:237", - "~0.5 | Status": "AssumeBroken" // broke in SDV 1.2 and uses Assembly.GetExecutingAssembly().Location - }, - - "No Soil Decay Redux": { - "ID": "Platonymous.NoSoilDecayRedux", - "Default | UpdateKey": "Nexus:1084" // added in 1.1.9 - }, - - "NPC Map Locations": { - "ID": "Bouhm.NPCMapLocations", - "FormerIDs": "NPCMapLocationsMod", // changed in 2.0 - "Default | UpdateKey": "Nexus:239" - }, - - "Object Time Left": { - "ID": "spacechase0.ObjectTimeLeft", - "Default | UpdateKey": "Nexus:1315" - }, - - "OmniFarm": { - "ID": "PhthaloBlue.OmniFarm", - "FormerIDs": "BlueMod_OmniFarm", // changed in 2.0.2-pathoschild-update - "Default | UpdateKey": "GitHub:lambui/StardewValleyMod_OmniFarm" - }, - - "One Click Shed": { - "ID": "BitwiseJonMods.OneClickShedReloader", - "Default | UpdateKey": "Nexus:2052" - }, - - "Out of Season Bonuses (Seasonal Items)": { - "ID": "midoriarmstrong.seasonalitems", - "Default | UpdateKey": "Nexus:1452" - }, - - "Part of the Community": { - "ID": "SB_PotC", - "Default | UpdateKey": "Nexus:923" - }, - - "PelicanFiber": { - "ID": "jwdred.PelicanFiber", - "Default | UpdateKey": "Nexus:631" - }, - - "PelicanTTS": { - "ID": "Platonymous.PelicanTTS", - "Default | UpdateKey": "Nexus:1079" // added in 1.6.1 - }, - - "Persia the Mermaid - Standalone Custom NPC": { - "ID": "63b9f419-7449-42db-ab2e-440b4d05c073", - "Default | UpdateKey": "Nexus:1419" - }, - - "Persistent Game Options": { - "ID": "Xangria.PersistentGameOptions", - "Default | UpdateKey": "Nexus:1778" - }, - - "Plant on Grass": { - "ID": "Demiacle.PlantOnGrass", - "Default | UpdateKey": "Nexus:1026" - }, - - "PyTK - Platonymous Toolkit": { - "ID": "Platonymous.Toolkit", - "Default | UpdateKey": "Nexus:1726" - }, - - "Point-and-Plant": { - "ID": "jwdred.PointAndPlant", - "Default | UpdateKey": "Nexus:572", - "MapRemoteVersions": { "1.0.3": "1.0.2" } // manifest not updated - }, - - "Pony Weight Loss Program": { - "ID": "BadNetCode.PonyWeightLossProgram", - "Default | UpdateKey": "Nexus:1232" - }, - - "Portraiture": { - "ID": "Platonymous.Portraiture", - "Default | UpdateKey": "Nexus:999" // added in 1.3.1 - }, - - "Prairie King Made Easy": { - "ID": "Mucchan.PrairieKingMadeEasy", - "Default | UpdateKey": "Chucklefish:3594", - "~1.0 | Status": "AssumeBroken" // broke in SDV 1.2 - }, - - "Purchasable Recipes": { - "ID": "Paracosm.PurchasableRecipes", - "Default | UpdateKey": "Nexus:1722" - }, - - "Quest Delay": { - "ID": "BadNetCode.QuestDelay", - "Default | UpdateKey": "Nexus:1239" - }, - - "Recatch Legendary Fish": { - "ID": "cantorsdust.RecatchLegendaryFish", - "FormerIDs": "b3af8c31-48f0-43cf-8343-3eb08bcfa1f9 | community.RecatchLegendaryFish", // changed in 1.3 and 1.5.1 - "Default | UpdateKey": "Nexus:172" - }, - - "Regeneration": { - "ID": "HammurabiRegeneration", - "Default | UpdateKey": "Chucklefish:4584" - }, - - "Relationship Bar UI": { - "ID": "RelationshipBar", - "Default | UpdateKey": "Nexus:1009" - }, - - "RelationshipsEnhanced": { - "ID": "relationshipsenhanced", - "Default | UpdateKey": "Chucklefish:4435", - "~1.0 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Relationship Status": { - "ID": "relationshipstatus", - "MapRemoteVersions": { "1.0.5": "1.0.4" }, // not updated in manifest - "Default | UpdateKey": "Nexus:751", - "~1.0.5 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Rented Tools": { - "ID": "JarvieK.RentedTools", - "Default | UpdateKey": "Nexus:1307" - }, - - "Replanter": { - "ID": "jwdred.Replanter", - "Default | UpdateKey": "Nexus:589" - }, - - "ReRegeneration": { - "ID": "lrsk_sdvm_rerg.0925160827", - "MapLocalVersions": { "1.1.2-release": "1.1.2" }, - "Default | UpdateKey": "Chucklefish:4465" - }, - - "Reseed": { - "ID": "Roc.Reseed", - "Default | UpdateKey": "Nexus:887" - }, - - "Reusable Wallpapers and Floors (Wallpaper Retain)": { - "ID": "dae1b553-2e39-43e7-8400-c7c5c836134b", - "Default | UpdateKey": "Nexus:356", - "~1.5 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Ring of Fire": { - "ID": "Platonymous.RingOfFire", - "Default | UpdateKey": "Nexus:1166" // added in 1.0.1 - }, - - "Rope Bridge": { - "ID": "RopeBridge", - "Default | UpdateKey": "Nexus:824" - }, - - "Rotate Toolbar": { - "ID": "Pathoschild.RotateToolbar", - "Default | UpdateKey": "Nexus:1100", - "~1.2.1 | Status": "AssumeBroken" // broke in SDV 1.3 - }, - - "Rush Orders": { - "ID": "spacechase0.RushOrders", - "FormerIDs": "RushOrders", // changed in 1.1 - "Default | UpdateKey": "Nexus:605" - }, - - "Save Anywhere": { - "ID": "Omegasis.SaveAnywhere", - "Default | UpdateKey": "Nexus:444", // added in 2.6.1 - "MapRemoteVersions": { "2.6.2": "2.6.1" } // not updated in manifest - }, - - "Save Backup": { - "ID": "Omegasis.SaveBackup", - "Default | UpdateKey": "Nexus:435", // added in 1.3.1 - "~1.2 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Scroll to Blank": { - "ID": "caraxian.scroll.to.blank", - "Default | UpdateKey": "Chucklefish:4405" - }, - - "Scythe Harvesting": { - "ID": "mmanlapat.ScytheHarvesting", - "FormerIDs": "ScytheHarvesting", // changed in 1.6 - "Default | UpdateKey": "Nexus:1106" - }, - - "SDV Twitch": { - "ID": "MTD.SDVTwitch", - "Default | UpdateKey": "Nexus:1760" - }, - - "Seasonal Immersion": { - "ID": "Entoarox.SeasonalImmersion", - "FormerIDs": "EntoaroxSeasonalHouse | EntoaroxSeasonalBuildings | EntoaroxSeasonalImmersion", // changed in 1.1, 1.6 or earlier, and 1.7 - "~1.11 | UpdateKey": "Chucklefish:4262" // only enable update checks up to 1.11 by request (has its own update-check feature) - }, - - "Seed Bag": { - "ID": "Platonymous.SeedBag", - "Default | UpdateKey": "Nexus:1133" // added in 1.1.2 - }, - - "Seed Catalogue": { - "ID": "spacechase0.SeedCatalogue", - "Default | UpdateKey": "Nexus:1640" - }, - - "Self Service": { - "ID": "JarvieK.SelfService", - "MapRemoteVersions": { "0.2.1": "0.2" }, // manifest not updated - "Default | UpdateKey": "Nexus:1304" - }, - - "Send Items": { - "ID": "Denifia.SendItems", - "Default | UpdateKey": "Nexus:1087" // added in 1.0.3 (2017-10-04) - }, - - "Shed Notifications (BuildingsNotifications)": { - "ID": "TheCroak.BuildingsNotifications", - "Default | UpdateKey": "Nexus:620", - "~0.4.1 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Shenandoah Project": { - "ID": "Nishtra.ShenandoahProject", - "FormerIDs": "Shenandoah Project", // changed in 1.2 - "MapRemoteVersions": { "1.1.1": "1.1" }, // not updated in manifest - "Default | UpdateKey": "Nexus:756" - }, - - "Ship Anywhere": { - "ID": "spacechase0.ShipAnywhere", - "Default | UpdateKey": "Nexus:1379" - }, - - "Shipment Tracker": { - "ID": "7e474181-e1a0-40f9-9c11-d08a3dcefaf3", - "Default | UpdateKey": "Nexus:321" - }, - - "Shop Expander": { - "ID": "Entoarox.ShopExpander", - "FormerIDs": "EntoaroxShopExpander", // changed in 1.5 and 1.5.2; disambiguate from Faster Paths - "MapRemoteVersions": { "1.6.0b": "1.6.0" }, - "~1.6 | UpdateKey": "Chucklefish:4381" // only enable update checks up to 1.6 by request (has its own update-check feature) - }, - - "Showcase Mod": { - "ID": "Igorious.Showcase", - "MapLocalVersions": { "0.9-500": "0.9" }, - "Default | UpdateKey": "Chucklefish:4487", - "~0.9 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Shroom Spotter": { - "ID": "TehPers.ShroomSpotter", - "Default | UpdateKey": "Nexus:908" - }, - - "Simple Crop Label": { - "ID": "SimpleCropLabel", - "Default | UpdateKey": "Nexus:314" - }, - - "Simple Sound Manager": { - "ID": "Omegasis.SimpleSoundManager", - "Default | UpdateKey": "Nexus:1410" // added in 1.0.1 - }, - - "Simple Sprinklers": { - "ID": "tZed.SimpleSprinkler", - "Default | UpdateKey": "Nexus:76" - }, - - "Siv's Marriage Mod": { - "ID": "6266959802", // official version - "FormerIDs": "Siv.MarriageMod | medoli900.Siv's Marriage Mod", // 1.2.3-unofficial versions - "MapLocalVersions": { "0.0": "1.4" }, - "Default | UpdateKey": "Nexus:366" - }, - - "Skill Prestige": { - "ID": "alphablackwolf.skillPrestige", - "FormerIDs": "6b843e60-c8fc-4a25-a67b-4a38ac8dcf9b", // changed circa 1.2.3 - "Default | UpdateKey": "Nexus:569" - }, - - "Skill Prestige: Cooking Adapter": { - "ID": "Alphablackwolf.CookingSkillPrestigeAdapter", - "FormerIDs": "20d6b8a3-b6e7-460b-a6e4-07c2b0cb6c63", // changed circa 1.1 - "MapRemoteVersions": { "1.2.3": "1.1" }, // manifest not updated - "Default | UpdateKey": "Nexus:569" - }, - - "Skip Intro": { - "ID": "Pathoschild.SkipIntro", - "FormerIDs": "SkipIntro", // changed in 1.4 - "Default | UpdateKey": "Nexus:533", - "~1.7.2 | Status": "AssumeBroken" // broke in SDV 1.3 - }, - - "Skull Cavern Elevator": { - "ID": "SkullCavernElevator", - "Default | UpdateKey": "Nexus:963" - }, - - "Skull Cave Saver": { - "ID": "cantorsdust.SkullCaveSaver", - "FormerIDs": "8ac06349-26f7-4394-806c-95d48fd35774 | community.SkullCaveSaver", // changed in 1.1 and 1.2.2 - "Default | UpdateKey": "Nexus:175", - "1.3-beta | Status": "AssumeBroken" // doesn't work in multiplayer, no longer maintained - }, - - "Sleepy Eye": { - "ID": "spacechase0.SleepyEye", - "Default | UpdateKey": "Nexus:1152" - }, - - "Slower Fence Decay": { - "ID": "Speeder.SlowerFenceDecay", - "FormerIDs": "SPDSlowFenceDecay", // changed in 0.5.2-pathoschild-update - "Default | UpdateKey": "Nexus:252", - "~0.5.1 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Smart Mod": { - "ID": "KuroBear.SmartMod", - "~2.2 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Solar Eclipse Event": { - "ID": "KoihimeNakamura.SolarEclipseEvent", - "Default | UpdateKey": "Nexus:897", - "MapLocalVersions": { "1.3.1-20180131": "1.3.1" } - }, - - "SpaceCore": { - "ID": "spacechase0.SpaceCore", - "Default | UpdateKey": "Nexus:1348" - }, - - "Speedster": { - "ID": "Platonymous.Speedster", - "Default | UpdateKey": "Nexus:1102" // added in 1.3.1 - }, - - "Split Screen": { - "ID": "Ilyaki.SplitScreen", - "~3.0.1 | Status": "AssumeBroken" // broke in SMAPI 2.6-beta.16 due to reflection into SMAPI internals - }, - - "Sprinkler Range": { - "ID": "cat.sprinklerrange", - "Default | UpdateKey": "Nexus:1179" - }, - - "Sprinkles": { - "ID": "Platonymous.Sprinkles", - "Default | UpdateKey": "Chucklefish:4592" - }, - - "Sprint and Dash": { - "ID": "SPDSprintAndDash", - "Default | UpdateKey": "Nexus:235", - "~1.0 | Status": "AssumeBroken" // broke in SDV 1.2 - }, - - "Sprint and Dash Redux": { - "ID": "littleraskol.SprintAndDashRedux", - "FormerIDs": "lrsk_sdvm_sndr.0921161059", // changed in 1.3 - "Default | UpdateKey": "Chucklefish:4201" - }, - - "StackSplitX": { - "ID": "tstaples.StackSplitX", - "Default | UpdateKey": "Nexus:798" - }, - - "Stardew Config Menu": { - "ID": "Juice805.StardewConfigMenu", - "Default | UpdateKey": "Nexus:1312" - }, - - "Stardew Content Compatibility Layer (SCCL)": { - "ID": "SCCL", - "Default | UpdateKey": "Nexus:889", - "~0.1 | Status": "AssumeBroken" // broke in SDV 1.2 - }, - - "Stardew Editor Game Integration": { - "ID": "spacechase0.StardewEditor.GameIntegration", - "Default | UpdateKey": "Nexus:1298" - }, - - "Stardew Notification": { - "ID": "stardewnotification", - "Default | UpdateKey": "GitHub:monopandora/StardewNotification" - }, - - "Stardew Symphony": { - "ID": "Omegasis.StardewSymphony", - "Default | UpdateKey": "Nexus:425" // added in 1.4.1 - }, - - "StarDustCore": { - "ID": "StarDustCore", - "~ | Status": "Obsolete", - "~ | StatusReasonPhrase": "it was only used by earlier versions of Save Anywhere, and is no longer used or maintained." - }, - - "Starting Money": { - "ID": "mmanlapat.StartingMoney", - "FormerIDs": "StartingMoney", // changed in 1.1 - "Default | UpdateKey": "Nexus:1138" - }, - - "StashItemsToChest": { - "ID": "BlueMod_StashItemsToChest", - "Default | UpdateKey": "GitHub:lambui/StardewValleyMod_StashItemsToChest", - "~1.0.1 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Stephan's Lots of Crops": { - "ID": "stephansstardewcrops", - "MapRemoteVersions": { "1.41": "1.1" }, // manifest not updated - "Default | UpdateKey": "Chucklefish:4314" - }, - - "Stumps to Hardwood Stumps": { - "ID": "StumpsToHardwoodStumps", - "Default | UpdateKey": "Nexus:691" - }, - - "Summit Reborn": { - "ID": "KoihimeNakamura.summitreborn", - "FormerIDs": "emissaryofinfinity.summitreborn", // changed in 1.0.2 - "~1.0.2 | Status": "AssumeBroken" // broke in SDV 1.3 (runtime errors) - }, - - "Super Greenhouse Warp Modifier": { - "ID": "SuperGreenhouse", - "Default | UpdateKey": "Chucklefish:4334", - "~1.0 | Status": "AssumeBroken" // broke in SMAPI 2.0 - }, - - "Swim Almost Anywhere / Swim Suit": { - "ID": "Platonymous.SwimSuit", - "Default | UpdateKey": "Nexus:1215" // added in 0.5.1 - }, - - "Tapper Ready": { - "ID": "skunkkk.TapperReady", - "Default | UpdateKey": "Nexus:1219" - }, - - "Teh's Fishing Overhaul": { - "ID": "TehPers.FishingOverhaul", - "Default | UpdateKey": "Nexus:866" - }, - - "Teleporter": { - "ID": "Teleporter", - "Default | UpdateKey": "Chucklefish:4374", - "~1.0.2 | Status": "AssumeBroken" // broke in SDV 1.2 - }, - - "The Long Night": { - "ID": "Pathoschild.TheLongNight", - "Default | UpdateKey": "Nexus:1369", - "~1.1.1 | Status": "AssumeBroken" // broke in SDV 1.3 - }, - - "Three-heart Dance Partner": { - "ID": "ThreeHeartDancePartner", - "Default | UpdateKey": "Nexus:500" - }, - - "TimeFreeze": { - "ID": "Omegasis.TimeFreeze", - "FormerIDs": "4108e859-333c-4fec-a1a7-d2e18c1019fe", // changed in 1.2 - "Default | UpdateKey": "Nexus:973" // added in 1.2.1 - }, - - "Time Reminder": { - "ID": "KoihimeNakamura.TimeReminder", - "MapLocalVersions": { "1.0-20170314": "1.0.2" }, - "Default | UpdateKey": "Nexus:1000" - }, - - "TimeSpeed": { - "ID": "cantorsdust.TimeSpeed", - "FormerIDs": "community.TimeSpeed", // changed in 2.3.3 - "Default | UpdateKey": "Nexus:169" - }, - - "To Do List": { - "ID": "eleanor.todolist", - "Default | UpdateKey": "Nexus:1630" - }, - - "Tool Charging": { - "ID": "mralbobo.ToolCharging", - "Default | UpdateKey": "GitHub:mralbobo/stardew-tool-charging" - }, - - "TractorMod": { - "ID": "Pathoschild.TractorMod", - "FormerIDs": "BlueMod_TractorMod | PhthaloBlue.TractorMod | community.TractorMod", // changed in 3.2, 4.0 beta, and 4.0 - "Default | UpdateKey": "Nexus:1401", - "~4.5-beta | Status": "AssumeBroken" // broke in SDV 1.3 - }, - - "TrainerMod": { - "ID": "SMAPI.TrainerMod", - "~ | Status": "Obsolete", - "~ | StatusReasonPhrase": "replaced by ConsoleCommands, which is added by the SMAPI installer." - }, - - "Tree Transplant": { - "ID": "TreeTransplant", - "Default | UpdateKey": "Nexus:1342" - }, - - "UI Info Suite": { - "ID": "Cdaragorn.UiInfoSuite", - "Default | UpdateKey": "Nexus:1150" - }, - - "UiModSuite": { - "ID": "Demiacle.UiModSuite", - "MapLocalVersions": { "0.5": "1.0" }, // not updated in manifest - "Default | UpdateKey": "Nexus:1023", - "~1.0 | Status": "AssumeBroken" // broke in SDV 1.2 - }, - - "Variable Grass": { - "ID": "dantheman999.VariableGrass", - "Default | UpdateKey": "GitHub:dantheman999301/StardewMods" - }, - - "Vertical Toolbar": { - "ID": "SB_VerticalToolMenu", - "Default | UpdateKey": "Nexus:943" - }, - - "WarpAnimals": { - "ID": "Symen.WarpAnimals", - "Default | UpdateKey": "Nexus:1400" - }, - - "What Farm Cave / WhatAMush": { - "ID": "WhatAMush", - "Default | UpdateKey": "Nexus:1097" - }, - - "WHats Up": { - "ID": "wHatsUp", - "Default | UpdateKey": "Nexus:1082" - }, - - "Winter Grass": { - "ID": "cat.wintergrass", - "Default | UpdateKey": "Nexus:1601" - }, - - "Xnb Loader": { - "ID": "Entoarox.XnbLoader", - "~1.1.10 | UpdateKey": "Chucklefish:4506" // only enable update checks up to 1.1.10 by request (has its own update-check feature) - }, - - "zDailyIncrease": { - "ID": "zdailyincrease", - "MapRemoteVersions": { "1.3.5": "1.3.4" }, // not updated in manifest - "Default | UpdateKey": "Chucklefish:4247" - }, - - "Zoom Out Extreme": { - "ID": "RockinMods.ZoomMod", - "FormerIDs": "ZoomMod", // changed circa 1.2.1 - "Default | UpdateKey": "Nexus:1326", - "~0.1 | Status": "AssumeBroken" // broke in SDV 1.2 - }, - - "Zoryn's Better RNG": { - "ID": "Zoryn.BetterRNG", - "FormerIDs": "76b6d1e1-f7ba-4d72-8c32-5a1e6d2716f6", // changed in 1.6 - "Default | UpdateKey": "GitHub:Zoryn4163/SMAPI-Mods", - "~1.6 | Status": "AssumeBroken" // broke in SDV 1.2 - }, - - "Zoryn's Calendar Anywhere": { - "ID": "Zoryn.CalendarAnywhere", - "FormerIDs": "a41c01cd-0437-43eb-944f-78cb5a53002a", // changed in 1.6 - "Default | UpdateKey": "GitHub:Zoryn4163/SMAPI-Mods", - "~1.6 | Status": "AssumeBroken" // broke in SDV 1.2 - }, - - "Zoryn's Durable Fences": { - "ID": "Zoryn.DurableFences", - "FormerIDs": "56d3439c-7b9b-497e-9496-0c4890e8a00e", // changed in 1.6 - "Default | UpdateKey": "GitHub:Zoryn4163/SMAPI-Mods" - }, - - "Zoryn's Health Bars": { - "ID": "Zoryn.HealthBars", - "Default | UpdateKey": "GitHub:Zoryn4163/SMAPI-Mods", - "~1.6 | Status": "AssumeBroken" // broke in SDV 1.2 - }, - - "Zoryn's Fishing Mod": { - "ID": "Zoryn.FishingMod", - "FormerIDs": "fa277b1f-265e-47c3-a84f-cd320cc74949", // changed in 1.6 - "Default | UpdateKey": "GitHub:Zoryn4163/SMAPI-Mods" - }, - - "Zoryn's Junimo Deposit Anywhere": { - "ID": "Zoryn.JunimoDepositAnywhere", - "FormerIDs": "f93a4fe8-cade-4146-9335-b5f82fbbf7bc", // changed in 1.6 - "Default | UpdateKey": "GitHub:Zoryn4163/SMAPI-Mods", - "~1.7 | Status": "AssumeBroken" // broke in SDV 1.2 - }, - - "Zoryn's Movement Mod": { - "ID": "Zoryn.MovementModifier", - "FormerIDs": "8a632929-8335-484f-87dd-c29d2ba3215d", // changed in 1.6 - "Default | UpdateKey": "GitHub:Zoryn4163/SMAPI-Mods" - }, - - "Zoryn's Regen Mod": { - "ID": "Zoryn.RegenMod", - "FormerIDs": "dfac4383-1b6b-4f33-ae4e-37fc23e5252e", // changed in 1.6 - "Default | UpdateKey": "GitHub:Zoryn4163/SMAPI-Mods", - "~1.6 | Status": "AssumeBroken" // broke in SDV 1.2 - } - } -} -- cgit