Skip to content

Commit

Permalink
Merge branch 'develop' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
Pathoschild committed Nov 29, 2024
2 parents ae4c426 + e8987dc commit 667844d
Show file tree
Hide file tree
Showing 57 changed files with 1,018 additions and 816 deletions.
2 changes: 1 addition & 1 deletion build/common.targets
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ repo. It imports the other MSBuild files as needed.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!--set general build properties -->
<Version>4.1.7</Version>
<Version>4.1.8</Version>
<Product>SMAPI</Product>
<LangVersion>latest</LangVersion>
<AssemblySearchPaths>$(AssemblySearchPaths);{GAC}</AssemblySearchPaths>
Expand Down
1 change: 1 addition & 0 deletions build/deploy-local-smapi.targets
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ This assumes `find-game-folder.targets` has already been imported and validated.
<Copy SourceFiles="$(TargetDir)\$(TargetName).xml" DestinationFolder="$(GamePath)" />
<Copy SourceFiles="$(TargetDir)\SMAPI.config.json" DestinationFiles="$(GamePath)\smapi-internal\config.json" />
<Copy SourceFiles="$(TargetDir)\SMAPI.metadata.json" DestinationFiles="$(GamePath)\smapi-internal\metadata.json" />
<Copy SourceFiles="$(TargetDir)\Markdig.dll" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="$(TargetDir)\Newtonsoft.Json.dll" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="$(TargetDir)\TMXTile.dll" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="$(TargetDir)\Pintail.dll" DestinationFolder="$(GamePath)\smapi-internal" />
Expand Down
2 changes: 1 addition & 1 deletion build/unix/prepare-install-package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ for folder in ${folders[@]}; do
cp -r "$smapiBin/i18n" "$bundlePath/smapi-internal"

# bundle smapi-internal
for name in "0Harmony.dll" "0Harmony.xml" "Mono.Cecil.dll" "Mono.Cecil.Mdb.dll" "Mono.Cecil.Pdb.dll" "MonoMod.Common.dll" "Newtonsoft.Json.dll" "Pathoschild.Http.Client.dll" "Pintail.dll" "TMXTile.dll" "SMAPI.Toolkit.dll" "SMAPI.Toolkit.xml" "SMAPI.Toolkit.CoreInterfaces.dll" "SMAPI.Toolkit.CoreInterfaces.xml" "System.Net.Http.Formatting.dll"; do
for name in "0Harmony.dll" "0Harmony.xml" "Markdig.dll" "Mono.Cecil.dll" "Mono.Cecil.Mdb.dll" "Mono.Cecil.Pdb.dll" "MonoMod.Common.dll" "Newtonsoft.Json.dll" "Pathoschild.Http.Client.dll" "Pintail.dll" "TMXTile.dll" "SMAPI.Toolkit.dll" "SMAPI.Toolkit.xml" "SMAPI.Toolkit.CoreInterfaces.dll" "SMAPI.Toolkit.CoreInterfaces.xml" "System.Net.Http.Formatting.dll"; do
cp "$smapiBin/$name" "$bundlePath/smapi-internal"
done

Expand Down
2 changes: 1 addition & 1 deletion build/windows/prepare-install-package.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ foreach ($folder in $folders) {
cp -Recurse "$smapiBin/i18n" "$bundlePath/smapi-internal"

# bundle smapi-internal
foreach ($name in @("0Harmony.dll", "0Harmony.xml", "Mono.Cecil.dll", "Mono.Cecil.Mdb.dll", "Mono.Cecil.Pdb.dll", "MonoMod.Common.dll", "Newtonsoft.Json.dll", "Pathoschild.Http.Client.dll", "Pintail.dll", "TMXTile.dll", "SMAPI.Toolkit.dll", "SMAPI.Toolkit.xml", "SMAPI.Toolkit.CoreInterfaces.dll", "SMAPI.Toolkit.CoreInterfaces.xml", "System.Net.Http.Formatting.dll")) {
foreach ($name in @("0Harmony.dll", "0Harmony.xml", "Markdig.dll", "Mono.Cecil.dll", "Mono.Cecil.Mdb.dll", "Mono.Cecil.Pdb.dll", "MonoMod.Common.dll", "Newtonsoft.Json.dll", "Pathoschild.Http.Client.dll", "Pintail.dll", "TMXTile.dll", "SMAPI.Toolkit.dll", "SMAPI.Toolkit.xml", "SMAPI.Toolkit.CoreInterfaces.dll", "SMAPI.Toolkit.CoreInterfaces.xml", "System.Net.Http.Formatting.dll")) {
cp "$smapiBin/$name" "$bundlePath/smapi-internal"
}

Expand Down
22 changes: 22 additions & 0 deletions docs/release-notes.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,28 @@
[README](README.md)

# Release notes
## 4.1.8
Released 28 November 2024 for Stardew Valley 1.6.14 or later.

* For players:
* Updated the mod compatibility blacklist.
* Fixed compatibility with newer macOS security restrictions.
* Fixed crash with some rare combinations of mods involving Harmony and mod APIs.

* For mod authors:
* Added `PathUtilities.CreateSlug` to get a safe Unicode string for use in special contexts like URLs and file paths.
_For example, `PathUtilities.CreateSlug("some 例子?!/\\~ text")` becomes `"some-例子-text"`._
* `PathUtilities.IsSlug` now allows more Unicode characters.
* Updated [Pintail](https://github.com/Nanoray-pl/Pintail) 2.6.0 → 2.6.1 (see [changes](https://github.com/Nanoray-pl/Pintail/blob/master/docs/release-notes.md#261)).

* For the web UI:
* Fixed log parser not highlighting update alerts for mods which SMAPI couldn't load.
* Fixed CurseForge links not shown for mods that have a CurseForge page.

* For external tools:
* Revamped the mod compatibility list to simplify maintenance. It's now stored [in a Git repo](https://github.com/Pathoschild/SmapiCompatibilityList), which replaces the former [wiki page](https://stardewvalleywiki.com/Modding:Mod_compatibility).
* Added toolkit method to get the URL from an update key's site and mod ID.

## 4.1.7
Released 12 November 2024 for Stardew Valley 1.6.14 or later.

Expand Down
16 changes: 4 additions & 12 deletions docs/technical/web.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,9 @@ The mod ID you specified in the request.
<td>

The update version recommended by the web API, if any. This is based on some internal rules (e.g.
it won't recommend a prerelease update if the player has a working stable version) and context
(e.g. whether the player is in the game beta channel). Choosing an update version yourself isn't
recommended, but you can set `includeExtendedMetadata: true` and check the `metadata` field if you
really want to do that.
it won't recommend a prerelease update if the player has a working stable version). Choosing an
update version yourself isn't recommended, but you can set `includeExtendedMetadata: true` and
check the `metadata` field if you really want to do that.

</td>
</tr>
Expand Down Expand Up @@ -260,20 +259,16 @@ field | summary
`nexusID` | The mod ID on [Nexus Mods](https://www.nexusmods.com/stardewvalley/), if any.
`chucklefishID` | The mod ID in the [Chucklefish mod repo](https://community.playstarbound.com/resources/categories/stardew-valley.22/), if any.
`curseForgeID` | The mod project ID on [CurseForge](https://www.curseforge.com/stardewvalley), if any.
`curseForgeKey` | The mod key on [CurseForge](https://www.curseforge.com/stardewvalley), if any. This is used in the mod page URL.
`modDropID` | The mod ID on [ModDrop](https://www.moddrop.com/stardew-valley), if any.
`gitHubRepo` | The GitHub repository containing the mod code, if any. Specified in the `Owner/Repo` form.
`customSourceUrl` | The custom URL to the mod code, if any. This is used for mods which aren't stored in a GitHub repo.
`customUrl` | The custom URL to the mod page, if any. This is used for mods which aren't stored on one of the standard mod sites covered by the ID fields.
`main` | The primary mod version, if any. This depends on the mod site, but it's typically either the version of the mod itself or of its latest non-optional download.
`optional` | The latest optional download version, if any.
`unofficial` | The version of the unofficial update defined on the wiki for this mod, if any.
`unofficialForBeta` | Equivalent to `unofficial`, but for beta versions of SMAPI or Stardew Valley.
`hasBetaInfo` | Whether there's an ongoing Stardew Valley or SMAPI beta which may affect update checks.
`compatibilityStatus` | The compatibility status for the mod for the stable version of the game, as defined on the wiki, if any. See [possible values](https://github.com/Pathoschild/SMAPI/blob/develop/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs).
`compatibilitySummary` | The human-readable summary of the mod's compatibility in HTML format, if any.
`brokeIn` | The SMAPI or Stardew Valley version that broke this mod, if any.
`betaCompatibilityStatus`<br />`betaCompatibilitySummary`<br />`betaBrokeIn` | Equivalent to the preceding fields, but for beta versions of SMAPI or Stardew Valley.

</td>
</tr>
Expand Down Expand Up @@ -307,14 +302,12 @@ Example response with `includeExtendedMetadata: true`:
"name": "Content Patcher",
"nexusID": 1915,
"curseForgeID": 309243,
"curseForgeKey": "content-patcher",
"modDropID": 470174,
"gitHubRepo": "Pathoschild/StardewMods",
"main": {
"version": "1.10",
"url": "https://www.nexusmods.com/stardewvalley/mods/1915"
},
"hasBetaInfo": true,
"compatibilityStatus": "Ok",
"compatibilitySummary": "✓ use latest version."
},
Expand Down Expand Up @@ -389,8 +382,7 @@ Initial setup:
property name | description
------------------------------- | -----------------
`BackgroundServices:Enabled` | Set to `true` to enable background processes like fetching data from the wiki, or false to disable them.
`Site:BetaEnabled` | Set to `true` to show a separate download button if there's a beta version of SMAPI in its GitHub releases.
`Site:BetaBlurb` | If `Site:BetaEnabled` is true and there's a beta version of SMAPI in its GitHub releases, this is shown on the beta download button as explanatory subtext.
`Site:OtherBlurb` | A message to show below the download button (e.g. for details on downloading a beta version), in Markdown format.
`Site:SupporterList` | A list of Patreon supports to credit on the download page.

To deploy updates, just [redeploy the web project from Visual Studio](https://docs.microsoft.com/en-us/visualstudio/deployment/quickstart-deploy-to-azure).
10 changes: 5 additions & 5 deletions src/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

<ItemGroup>
<!-- SMAPI + toolkit -->
<PackageVersion Include="FluentAssertions" Version="6.12.1" />
<PackageVersion Include="HtmlAgilityPack" Version="1.11.70" />
<PackageVersion Include="FluentAssertions" Version="6.12.2" />
<PackageVersion Include="HtmlAgilityPack" Version="1.11.71" />
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="17.10.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.9.2" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageVersion Include="Mono.Cecil" Version="0.11.5" />
<PackageVersion Include="MonoMod.Common" Version="22.3.5.1" />
Expand All @@ -18,14 +18,14 @@
<PackageVersion Include="NUnit" Version="4.2.2" />
<PackageVersion Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageVersion Include="Pathoschild.Http.FluentClient" Version="4.4.1" />
<PackageVersion Include="Pintail" Version="2.6.0" />
<PackageVersion Include="Pintail" Version="2.6.1" />
<PackageVersion Include="Platonymous.TMXTile" Version="1.5.9" />
<PackageVersion Include="System.Management" Version="8.0.0" />
<PackageVersion Include="System.Reflection.Emit" Version="4.7.0" />
<PackageVersion Include="VdfConverter" Version="1.0.3" />

<!-- web -->
<PackageVersion Include="Azure.Storage.Blobs" Version="12.22.2" />
<PackageVersion Include="Azure.Storage.Blobs" Version="12.23.0" />
<PackageVersion Include="Hangfire.AspNetCore" Version="1.8.15" />
<PackageVersion Include="Hangfire.Console" Version="1.4.3" />
<PackageVersion Include="Hangfire.MemoryStorage" Version="1.8.1.1" />
Expand Down
15 changes: 15 additions & 0 deletions src/SMAPI.Installer/InteractiveInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,21 @@ public void Run(string[] args)
}
}.Start();
}

// sign SMAPI on macOS
// This avoids 'StardewModdingAPI will damage your computer' errors in newer versions.
if (context.Platform is Platform.Mac)
{
new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "codesign",
Arguments = $"--force --sign - \"{paths.UnixSmapiExecutablePath}\"",
CreateNoWindow = true
}
}.Start();
}
}

// copy the game's deps.json file
Expand Down
4 changes: 2 additions & 2 deletions src/SMAPI.Mods.ConsoleCommands/manifest.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"Name": "Console Commands",
"Author": "SMAPI",
"Version": "4.1.7",
"Version": "4.1.8",
"Description": "Adds SMAPI console commands that let you manipulate the game.",
"UniqueID": "SMAPI.ConsoleCommands",
"EntryDll": "ConsoleCommands.dll",
"MinimumApiVersion": "4.1.7"
"MinimumApiVersion": "4.1.8"
}
4 changes: 2 additions & 2 deletions src/SMAPI.Mods.SaveBackup/manifest.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"Name": "Save Backup",
"Author": "SMAPI",
"Version": "4.1.7",
"Version": "4.1.8",
"Description": "Automatically backs up all your saves once per day into its folder.",
"UniqueID": "SMAPI.SaveBackup",
"EntryDll": "SaveBackup.dll",
"MinimumApiVersion": "4.1.7"
"MinimumApiVersion": "4.1.8"
}
72 changes: 65 additions & 7 deletions src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal class PathUtilitiesTests
** Sample data
*********/
/// <summary>Sample paths used in unit tests.</summary>
public static readonly SamplePath[] SamplePaths = {
public static readonly SamplePath[] SamplePaths = [
// Windows absolute path
new(
OriginalPath: @"C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley",
Expand Down Expand Up @@ -136,7 +136,7 @@ internal class PathUtilitiesTests
NormalizedOnWindows: @"C:\some\mixed\path\separators",
NormalizedOnUnix: @"C:/some/mixed/path/separators"
)
};
];


/*********
Expand All @@ -145,7 +145,7 @@ internal class PathUtilitiesTests
/****
** GetSegments
****/
[Test(Description = "Assert that PathUtilities.GetSegments splits paths correctly.")]
[Test(Description = $"Assert that {nameof(PathUtilities.GetSegments)} splits paths correctly.")]
[TestCaseSource(nameof(PathUtilitiesTests.SamplePaths))]
public void GetSegments(SamplePath path)
{
Expand All @@ -158,7 +158,7 @@ public void GetSegments(SamplePath path)
.And.ContainInOrder(segments);
}

[Test(Description = "Assert that PathUtilities.GetSegments splits paths correctly when given a limit.")]
[Test(Description = $"Assert that {nameof(PathUtilities.GetSegments)} splits paths correctly when given a limit.")]
[TestCaseSource(nameof(PathUtilitiesTests.SamplePaths))]
public void GetSegments_WithLimit(SamplePath path)
{
Expand All @@ -174,7 +174,7 @@ public void GetSegments_WithLimit(SamplePath path)
/****
** NormalizeAssetName
****/
[Test(Description = "Assert that PathUtilities.NormalizeAssetName normalizes paths correctly.")]
[Test(Description = $"Assert that {nameof(PathUtilities.NormalizeAssetName)} normalizes paths correctly.")]
[TestCaseSource(nameof(PathUtilitiesTests.SamplePaths))]
public void NormalizeAssetName(SamplePath path)
{
Expand All @@ -191,7 +191,7 @@ public void NormalizeAssetName(SamplePath path)
/****
** NormalizePath
****/
[Test(Description = "Assert that PathUtilities.NormalizePath normalizes paths correctly.")]
[Test(Description = $"Assert that {nameof(PathUtilities.NormalizePath)} normalizes paths correctly.")]
[TestCaseSource(nameof(PathUtilitiesTests.SamplePaths))]
public void NormalizePath(SamplePath path)
{
Expand All @@ -211,7 +211,7 @@ public void NormalizePath(SamplePath path)
/****
** GetRelativePath
****/
[Test(Description = "Assert that PathUtilities.GetRelativePath returns the expected values.")]
[Test(Description = $"Assert that {nameof(PathUtilities.GetRelativePath)} returns the expected values.")]
#if SMAPI_FOR_WINDOWS
[TestCase(
@"C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley",
Expand Down Expand Up @@ -275,6 +275,64 @@ public string GetRelativePath(string sourceDir, string targetPath)
return PathUtilities.GetRelativePath(sourceDir, targetPath);
}

/****
** IsSlug
****/
[Test(Description = $"Assert that {nameof(PathUtilities.IsSlug)} returns the expected values.")]
[TestCase("example", ExpectedResult = true)]
[TestCase("example2", ExpectedResult = true)]
[TestCase("ex-ample", ExpectedResult = true)]
[TestCase("ex_ample", ExpectedResult = true)]
[TestCase("ex.ample", ExpectedResult = true)]
[TestCase("ex-ample---text", ExpectedResult = true)]
[TestCase("eXAMple", ExpectedResult = true)]
[TestCase("example-例子-text", ExpectedResult = true)]

[TestCase(" example", ExpectedResult = false)]
[TestCase("example ", ExpectedResult = false)]
[TestCase("exa mple", ExpectedResult = false)]
[TestCase("exa - mple", ExpectedResult = false)]
[TestCase("exam!ple", ExpectedResult = false)]
[TestCase("example?", ExpectedResult = false)]
[TestCase("#example", ExpectedResult = false)]
[TestCase("example~", ExpectedResult = false)]
[TestCase("example/", ExpectedResult = false)]
[TestCase("example\\", ExpectedResult = false)]
[TestCase("example|", ExpectedResult = false)]
public bool IsSlug(string input)
{
return PathUtilities.IsSlug(input);
}

/****
** GetSlug
****/
[Test(Description = $"Assert that {nameof(PathUtilities.CreateSlug)} returns the expected values.")]
[TestCase("example", ExpectedResult = "example")]
[TestCase("example2", ExpectedResult = "example2")]
[TestCase("ex-ample", ExpectedResult = "ex-ample")]
[TestCase("ex_ample", ExpectedResult = "ex_ample")]
[TestCase("ex.ample", ExpectedResult = "ex.ample")]
[TestCase("ex-ample---text", ExpectedResult = "ex-ample-text")]
[TestCase("eXAMple", ExpectedResult = "eXAMple")]
[TestCase("example-例子-text", ExpectedResult = "example-例子-text")]

[TestCase(" example", ExpectedResult = "example")]
[TestCase("example ", ExpectedResult = "example-")]
[TestCase("exa mple", ExpectedResult = "exa-mple")]
[TestCase("exa - mple", ExpectedResult = "exa-mple")]
[TestCase("exam!ple", ExpectedResult = "exam-ple")]
[TestCase("example?", ExpectedResult = "example-")]
[TestCase("#example", ExpectedResult = "example")]
[TestCase("example~", ExpectedResult = "example-")]
[TestCase("example/", ExpectedResult = "example-")]
[TestCase("example\\", ExpectedResult = "example-")]
[TestCase("example|", ExpectedResult = "example-")]
public string CreateSlug(string input)
{
return PathUtilities.CreateSlug(input);
}


/*********
** Private classes
Expand Down
2 changes: 1 addition & 1 deletion src/SMAPI.Tests/WikiClient/ChangeDescriptorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using FluentAssertions;
using NUnit.Framework;
using StardewModdingAPI;
using StardewModdingAPI.Toolkit.Framework.Clients.Wiki;
using StardewModdingAPI.Toolkit.Framework.Clients.CompatibilityRepo;

namespace SMAPI.Tests.WikiClient;

Expand Down
Loading

0 comments on commit 667844d

Please sign in to comment.