Merge branch 'develop' into stable

This commit is contained in:
Jesse Plamondon-Willard 2023-04-09 13:09:47 -04:00
commit 53e0e8cd24
No known key found for this signature in database
GPG Key ID: CF8B1456B3E29F49
29 changed files with 115 additions and 91 deletions

View File

@ -1,30 +0,0 @@
---
name: Bug report
about: Report a problem with SMAPI.
---
<!--
Only report a bug here if you're sure it's a SMAPI bug!
To request support instead, see https://smapi.io/community.
Replace the instructions below with the bug details.
-->
**Describe the bug**
A clear and concise description of what the bug is. Provide any other details you think might be relevant here.
**To Reproduce**
Exact steps which reproduce the bug, if possible. For example:
1. Load save '...'.
2. Walk to '....'.
3. Click '....'.
4. Error occurs.
**Log file**
Upload your SMAPI log to https://smapi.io/log and post a link here.
**Screenshots**
If applicable, add screenshots to help explain your problem.

8
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Troubleshooting guide for players
url: https://smapi.io/troubleshoot
about: See if your question is already answered first!
- name: Get help or discuss
url: https://smapi.io/help
about: Ask for help from the community, or join the Stardew Valley Discord to ask questions, report issues, or discuss with the SMAPI developer, players, and mod authors. The SMAPI developer is @Pathoschild#0001 on Discord.

37
.github/ISSUE_TEMPLATE/custom.md vendored Normal file
View File

@ -0,0 +1,37 @@
---
name: Create a development task
about: DON'T DO THIS BEFORE READING. This is for specific changes to the code or technical bug reports. See below if something isn't working, you have questions or ideas, or you want to discuss something.
---
<!--
STOP!
Is this a specific development task? Don't create an issue if not!
See https://smapi.io/community if something isn't working, you have questions or ideas, or you want
to discuss something.
If you're absolutely sure it's a specific development task (e.g. a specific bug, not just
'something went wrong on my computer'), edit the template below.
-->
**Describe the bug**
A clear and concise description of what the bug is. Provide any other details you think might be relevant here.
**To Reproduce**
Exact steps which reproduce the bug, if possible. For example:
1. Load save '...'.
2. Walk to '....'.
3. Click '....'.
4. Error occurs.
**Log file**
Upload your SMAPI log to https://smapi.io/log and post a link here.
**Screenshots**
If applicable, add screenshots to help explain your problem.

View File

@ -1,12 +0,0 @@
---
name: Feature request
about: Suggest an idea for SMAPI.
---
<!--
GitHub issues are only used for development tasks. Please don't submit feature requests here!
Instead, see https://smapi.io/community to discuss SMAPI.
-->

View File

@ -1,12 +0,0 @@
---
name: General
about: Create a ticket about something else.
---
<!--
GitHub issues are only used for development tasks.
For support and questions, see https://smapi.io/community instead.
-->

View File

@ -7,7 +7,7 @@ repo. It imports the other MSBuild files as needed.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<!--set general build properties --> <!--set general build properties -->
<Version>3.18.2</Version> <Version>3.18.3</Version>
<Product>SMAPI</Product> <Product>SMAPI</Product>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<AssemblySearchPaths>$(AssemblySearchPaths);{GAC}</AssemblySearchPaths> <AssemblySearchPaths>$(AssemblySearchPaths);{GAC}</AssemblySearchPaths>

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
# #
# #

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
# #
# #

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
########## ##########
## Read config ## Read config

View File

@ -7,6 +7,25 @@
_If needed, you can update to SMAPI 3.16.0 first and then install the latest version._ _If needed, you can update to SMAPI 3.16.0 first and then install the latest version._
--> -->
## 3.18.3
Released 09 April 2023 for Stardew Valley 1.5.6 or later.
* For players:
* Fixed `findstr` installer error for some players.
* Fixed installer error for some Linux players due to a non-portable shebang (thanks to freyacoded!).
* Fixed error using load order overrides when there are broken mods installed (thanks to atravita!).
* Removed `LargeAddressAware` flag on SMAPI (no longer needed since it's 64-bit now).
* Improved translations. Thganks to stylemate (updated Korean)!
* For mod authors:
* Added `IsActiveForScreen()` method to `PerScreen<T>`.
* Updated to [FluentHttpClient](https://github.com/Pathoschild/FluentHttpClient#readme) 4.3.0 (see [changes](https://github.com/Pathoschild/FluentHttpClient/blob/develop/RELEASE-NOTES.md#430)).
* Adjusted `ModContentManager.HandleUnknownFileType` to let mods patch it.
* Fixed `Context.IsWorldReady` being editable by mods.
* For the web UI:
* Updated the JSON validator/schema for Content Patcher 1.29.0.
## 3.18.2 ## 3.18.2
Released 09 January 2023 for Stardew Valley 1.5.6 or later. Released 09 January 2023 for Stardew Valley 1.5.6 or later.

View File

@ -99,6 +99,10 @@ There are two places you can put them:
2. Open the `.csproj` file in a text editor (Notepad is fine). 2. Open the `.csproj` file in a text editor (Notepad is fine).
3. Add the properties between the first `<PropertyGroup>` and `</PropertyGroup>` tags you find. 3. Add the properties between the first `<PropertyGroup>` and `</PropertyGroup>` tags you find.
**Note:** you can't use a property before it's defined. That mainly means that when setting
`GameModsPath`, you'll need to either specify `GamePath` manually or put the full path in
`GameModsPath`.
### Available properties ### Available properties
These are the options you can set: These are the options you can set:

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
cd "`dirname "$0"`" cd "`dirname "$0"`"
internal/linux/SMAPI.Installer internal/linux/SMAPI.Installer

View File

@ -4,7 +4,9 @@ setlocal enabledelayedexpansion
SET installerDir="%~dp0" SET installerDir="%~dp0"
REM make sure we're not running within a zip folder REM make sure we're not running within a zip folder
echo %installerDir% | findstr /C:"%TEMP%" 1>nul REM The error level is usually 0 (install dir contains temp path), 1 (it doesn't), or 9009 (findstr doesn't exist due to a Windows issue).
REM If the command doesn't exist, just skip this check.
echo %installerDir% | findstr /C:"%TEMP%" 1>nul 2>null
if %ERRORLEVEL% EQU 0 ( if %ERRORLEVEL% EQU 0 (
echo Oops! It looks like you're running the installer from inside a zip file. Make sure you unzip the download first. echo Oops! It looks like you're running the installer from inside a zip file. Make sure you unzip the download first.
echo. echo.

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
cd "`dirname "$0"`" cd "`dirname "$0"`"

View File

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

View File

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

View File

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

View File

@ -11,7 +11,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="HtmlAgilityPack" Version="1.11.46" /> <PackageReference Include="HtmlAgilityPack" Version="1.11.46" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Pathoschild.Http.FluentClient" Version="4.2.0" /> <PackageReference Include="Pathoschild.Http.FluentClient" Version="4.3.0" />
<PackageReference Include="System.Management" Version="5.0.0" Condition="'$(OS)' == 'Windows_NT'" /> <PackageReference Include="System.Management" Version="5.0.0" Condition="'$(OS)' == 'Windows_NT'" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" Condition="'$(OS)' == 'Windows_NT'" /> <PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" Condition="'$(OS)' == 'Windows_NT'" />
<PackageReference Include="VdfConverter" Version="1.0.3" Condition="'$(OS)' == 'Windows_NT'" Private="False" /> <PackageReference Include="VdfConverter" Version="1.0.3" Condition="'$(OS)' == 'Windows_NT'" Private="False" />

View File

@ -25,7 +25,7 @@
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.1" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.1" />
<PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.14" /> <PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.14" />
<PackageReference Include="Pathoschild.FluentNexus" Version="1.0.5" /> <PackageReference Include="Pathoschild.FluentNexus" Version="1.0.5" />
<PackageReference Include="Pathoschild.Http.FluentClient" Version="4.2.0" /> <PackageReference Include="Pathoschild.Http.FluentClient" Version="4.3.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.1" /> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.1" />

View File

@ -14,9 +14,9 @@
"title": "Format version", "title": "Format version",
"description": "The format version. You should always use the latest version to enable the latest features, avoid obsolete behavior, and reduce load times.", "description": "The format version. You should always use the latest version to enable the latest features, avoid obsolete behavior, and reduce load times.",
"type": "string", "type": "string",
"pattern": "^1\\.28\\.[0-9]+$", "pattern": "^1\\.29\\.[0-9]+$",
"@errorMessages": { "@errorMessages": {
"pattern": "Incorrect value '@value'. You should always use the latest format version (currently 1.28.0) to enable the latest features, avoid obsolete behavior, and reduce load times." "pattern": "Incorrect value '@value'. You should always use the latest format version (currently 1.29.0) to enable the latest features, avoid obsolete behavior, and reduce load times."
} }
}, },
"ConfigSchema": { "ConfigSchema": {

View File

@ -19,9 +19,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{4B1C
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ISSUE_TEMPLATE", "ISSUE_TEMPLATE", "{F4453AB6-D7D6-447F-A973-956CC777968F}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ISSUE_TEMPLATE", "ISSUE_TEMPLATE", "{F4453AB6-D7D6-447F-A973-956CC777968F}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
..\.github\ISSUE_TEMPLATE\bug_report.md = ..\.github\ISSUE_TEMPLATE\bug_report.md ..\.github\ISSUE_TEMPLATE\config.yml = ..\.github\ISSUE_TEMPLATE\config.yml
..\.github\ISSUE_TEMPLATE\feature_request.md = ..\.github\ISSUE_TEMPLATE\feature_request.md ..\.github\ISSUE_TEMPLATE\custom.md = ..\.github\ISSUE_TEMPLATE\custom.md
..\.github\ISSUE_TEMPLATE\general.md = ..\.github\ISSUE_TEMPLATE\general.md
EndProjectSection EndProjectSection
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{09CF91E5-5BAB-4650-A200-E5EA9A633046}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{09CF91E5-5BAB-4650-A200-E5EA9A633046}"

View File

@ -52,7 +52,7 @@ namespace StardewModdingAPI
internal static int? LogScreenId { get; set; } internal static int? LogScreenId { get; set; }
/// <summary>SMAPI's current raw semantic version.</summary> /// <summary>SMAPI's current raw semantic version.</summary>
internal static string RawApiVersion = "3.18.2"; internal static string RawApiVersion = "3.18.3";
} }
/// <summary>Contains SMAPI's constants and assumptions.</summary> /// <summary>Contains SMAPI's constants and assumptions.</summary>

View File

@ -60,7 +60,7 @@ namespace StardewModdingAPI
public static bool IsWorldReady public static bool IsWorldReady
{ {
get => Context.IsWorldReadyForScreen.Value; get => Context.IsWorldReadyForScreen.Value;
set => Context.IsWorldReadyForScreen.Value = value; internal set => Context.IsWorldReadyForScreen.Value = value;
} }
/// <summary>Whether <see cref="IsWorldReady"/> is true and the player is free to act in the world (no menu is displayed, no cutscene is in progress, etc).</summary> /// <summary>Whether <see cref="IsWorldReady"/> is true and the player is free to act in the world (no menu is displayed, no cutscene is in progress, etc).</summary>

View File

@ -130,7 +130,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
".png" => this.LoadImageFile<T>(assetName, file), ".png" => this.LoadImageFile<T>(assetName, file),
".tbin" or ".tmx" => this.LoadMapFile<T>(assetName, file), ".tbin" or ".tmx" => this.LoadMapFile<T>(assetName, file),
".xnb" => this.LoadXnbFile<T>(assetName), ".xnb" => this.LoadXnbFile<T>(assetName),
_ => this.HandleUnknownFileType<T>(assetName, file) _ => (T)this.HandleUnknownFileType(assetName, file, typeof(T))
}; };
} }
catch (Exception ex) catch (Exception ex)
@ -323,13 +323,15 @@ namespace StardewModdingAPI.Framework.ContentManagers
} }
/// <summary>Handle a request to load a file type that isn't supported by SMAPI.</summary> /// <summary>Handle a request to load a file type that isn't supported by SMAPI.</summary>
/// <typeparam name="T">The expected file type.</typeparam>
/// <param name="assetName">The asset name relative to the loader root directory.</param> /// <param name="assetName">The asset name relative to the loader root directory.</param>
/// <param name="file">The file to load.</param> /// <param name="file">The file to load.</param>
private T HandleUnknownFileType<T>(IAssetName assetName, FileInfo file) /// <param name="assetType">The expected file type.</param>
private object HandleUnknownFileType(IAssetName assetName, FileInfo file, Type assetType)
{ {
this.ThrowLoadError(assetName, ContentLoadErrorType.InvalidName, $"unknown file extension '{file.Extension}'; must be one of '.fnt', '.json', '.png', '.tbin', '.tmx', or '.xnb'."); this.ThrowLoadError(assetName, ContentLoadErrorType.InvalidName, $"unknown file extension '{file.Extension}'; must be one of '.fnt', '.json', '.png', '.tbin', '.tmx', or '.xnb'.");
return default; return assetType.IsValueType
? Activator.CreateInstance(assetType)
: null;
} }
/// <summary>Assert that the asset type is compatible with one of the allowed types.</summary> /// <summary>Assert that the asset type is compatible with one of the allowed types.</summary>

View File

@ -180,13 +180,16 @@ namespace StardewModdingAPI.Framework.ModLoading
return mods return mods
.OrderBy(mod => .OrderBy(mod =>
{ {
string id = mod.Manifest.UniqueID; string? id = mod.Manifest?.UniqueID;
if (id is not null)
{
if (modIdsToLoadEarly.TryGetValue(id, out string? actualId)) if (modIdsToLoadEarly.TryGetValue(id, out string? actualId))
return -int.MaxValue + Array.IndexOf(earlyArray, actualId); return -int.MaxValue + Array.IndexOf(earlyArray, actualId);
if (modIdsToLoadLate.TryGetValue(id, out actualId)) if (modIdsToLoadLate.TryGetValue(id, out actualId))
return int.MaxValue - Array.IndexOf(lateArray, actualId); return int.MaxValue - Array.IndexOf(lateArray, actualId);
}
return 0; return 0;
}) })

View File

@ -433,7 +433,7 @@ namespace StardewModdingAPI.Framework
// apply load order customizations // apply load order customizations
if (this.Settings.ModsToLoadEarly.Any() || this.Settings.ModsToLoadLate.Any()) if (this.Settings.ModsToLoadEarly.Any() || this.Settings.ModsToLoadLate.Any())
{ {
HashSet<string> installedIds = new HashSet<string>(mods.Select(p => p.Manifest.UniqueID), StringComparer.OrdinalIgnoreCase); HashSet<string> installedIds = new HashSet<string>(mods.Select(p => p.Manifest?.UniqueID).Where(p => p is not null), StringComparer.OrdinalIgnoreCase);
string[] missingEarlyMods = this.Settings.ModsToLoadEarly.Where(id => !installedIds.Contains(id)).OrderBy(p => p, StringComparer.OrdinalIgnoreCase).ToArray(); string[] missingEarlyMods = this.Settings.ModsToLoadEarly.Where(id => !installedIds.Contains(id)).OrderBy(p => p, StringComparer.OrdinalIgnoreCase).ToArray();
string[] missingLateMods = this.Settings.ModsToLoadLate.Where(id => !installedIds.Contains(id)).OrderBy(p => p, StringComparer.OrdinalIgnoreCase).ToArray(); string[] missingLateMods = this.Settings.ModsToLoadLate.Where(id => !installedIds.Contains(id)).OrderBy(p => p, StringComparer.OrdinalIgnoreCase).ToArray();

View File

@ -8,7 +8,6 @@
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<LargeAddressAware Condition="'$(OS)' == 'Windows_NT'">true</LargeAddressAware>
<ApplicationIcon>icon.ico</ApplicationIcon> <ApplicationIcon>icon.ico</ApplicationIcon>
<!--copy dependency DLLs to bin folder so we can include them in installer bundle --> <!--copy dependency DLLs to bin folder so we can include them in installer bundle -->
@ -22,11 +21,10 @@
<Import Project="..\..\build\common.targets" /> <Import Project="..\..\build\common.targets" />
<ItemGroup> <ItemGroup>
<PackageReference Include="LargeAddressAware" Version="1.0.6" />
<PackageReference Include="Mono.Cecil" Version="0.11.4" /> <PackageReference Include="Mono.Cecil" Version="0.11.4" />
<PackageReference Include="MonoMod.Common" Version="22.3.5.1" /> <PackageReference Include="MonoMod.Common" Version="22.3.5.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Pathoschild.Http.FluentClient" Version="4.2.0" /> <PackageReference Include="Pathoschild.Http.FluentClient" Version="4.3.0" />
<PackageReference Include="Pintail" Version="2.2.2" /> <PackageReference Include="Pintail" Version="2.2.2" />
<PackageReference Include="Platonymous.TMXTile" Version="1.5.9" /> <PackageReference Include="Platonymous.TMXTile" Version="1.5.9" />
<PackageReference Include="System.Reflection.Emit" Version="4.7.0" /> <PackageReference Include="System.Reflection.Emit" Version="4.7.0" />

View File

@ -101,6 +101,12 @@ namespace StardewModdingAPI.Utilities
this.RemoveScreens(_ => true); this.RemoveScreens(_ => true);
} }
/// <summary>Get whether the current screen has a value created yet.</summary>
public bool IsActiveForScreen()
{
return this.States.ContainsKey(Context.ScreenId);
}
/********* /*********
** Private methods ** Private methods

View File

@ -1,6 +1,6 @@
{ {
// short date format for SDate // short date format for SDate
// tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2)
"generic.date": "{{season}} {{day}}", "generic.date": "{{season}} {{day}}",
"generic.date-with-year": "{{year}}년 {{season}} {{day}}" "generic.date-with-year": "{{year}} {{season}} {{day}}"
} }