diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index c51d164b..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -name: Bug report -about: Report a problem with SMAPI. - ---- - - - -**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. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..63d7bb67 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -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. diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md new file mode 100644 index 00000000..11306e7f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -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. + +--- + + + +**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. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 8d935dc8..00000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for SMAPI. - ---- - - diff --git a/.github/ISSUE_TEMPLATE/general.md b/.github/ISSUE_TEMPLATE/general.md deleted file mode 100644 index f02d3c9a..00000000 --- a/.github/ISSUE_TEMPLATE/general.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -name: General -about: Create a ticket about something else. - ---- - - diff --git a/build/common.targets b/build/common.targets index 590e0415..1ead1508 100644 --- a/build/common.targets +++ b/build/common.targets @@ -7,7 +7,7 @@ repo. It imports the other MSBuild files as needed. - 3.18.2 + 3.18.3 SMAPI latest $(AssemblySearchPaths);{GAC} diff --git a/build/unix/prepare-install-package.sh b/build/unix/prepare-install-package.sh index 1d805e00..304579b9 100755 --- a/build/unix/prepare-install-package.sh +++ b/build/unix/prepare-install-package.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # diff --git a/build/unix/set-smapi-version.sh b/build/unix/set-smapi-version.sh index 0c0cbeb0..02b5e615 100755 --- a/build/unix/set-smapi-version.sh +++ b/build/unix/set-smapi-version.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # diff --git a/build/windows/finalize-install-package.sh b/build/windows/finalize-install-package.sh index 0996e3ed..117e33e5 100755 --- a/build/windows/finalize-install-package.sh +++ b/build/windows/finalize-install-package.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash ########## ## Read config diff --git a/docs/release-notes.md b/docs/release-notes.md index 9eb55b36..e99218bd 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -7,6 +7,25 @@ _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`. + * 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 Released 09 January 2023 for Stardew Valley 1.5.6 or later. diff --git a/docs/technical/mod-package.md b/docs/technical/mod-package.md index 23f0b221..ab8a2c95 100644 --- a/docs/technical/mod-package.md +++ b/docs/technical/mod-package.md @@ -99,6 +99,10 @@ There are two places you can put them: 2. Open the `.csproj` file in a text editor (Notepad is fine). 3. Add the properties between the first `` and `` 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 These are the options you can set: diff --git a/src/SMAPI.Installer/assets/install on Linux.sh b/src/SMAPI.Installer/assets/install on Linux.sh index 3b7eae9c..70b21521 100644 --- a/src/SMAPI.Installer/assets/install on Linux.sh +++ b/src/SMAPI.Installer/assets/install on Linux.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash cd "`dirname "$0"`" internal/linux/SMAPI.Installer diff --git a/src/SMAPI.Installer/assets/install on Windows.bat b/src/SMAPI.Installer/assets/install on Windows.bat index b0d9ae81..c61a801e 100644 --- a/src/SMAPI.Installer/assets/install on Windows.bat +++ b/src/SMAPI.Installer/assets/install on Windows.bat @@ -4,7 +4,9 @@ setlocal enabledelayedexpansion SET installerDir="%~dp0" 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 ( echo Oops! It looks like you're running the installer from inside a zip file. Make sure you unzip the download first. echo. diff --git a/src/SMAPI.Installer/assets/install on macOS.command b/src/SMAPI.Installer/assets/install on macOS.command index abd21dc8..e85230ed 100644 --- a/src/SMAPI.Installer/assets/install on macOS.command +++ b/src/SMAPI.Installer/assets/install on macOS.command @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash cd "`dirname "$0"`" diff --git a/src/SMAPI.Mods.ConsoleCommands/manifest.json b/src/SMAPI.Mods.ConsoleCommands/manifest.json index 6ababef0..2447c5c3 100644 --- a/src/SMAPI.Mods.ConsoleCommands/manifest.json +++ b/src/SMAPI.Mods.ConsoleCommands/manifest.json @@ -1,9 +1,9 @@ { "Name": "Console Commands", "Author": "SMAPI", - "Version": "3.18.2", + "Version": "3.18.3", "Description": "Adds SMAPI console commands that let you manipulate the game.", "UniqueID": "SMAPI.ConsoleCommands", "EntryDll": "ConsoleCommands.dll", - "MinimumApiVersion": "3.18.2" + "MinimumApiVersion": "3.18.3" } diff --git a/src/SMAPI.Mods.ErrorHandler/manifest.json b/src/SMAPI.Mods.ErrorHandler/manifest.json index 82630479..306c92fc 100644 --- a/src/SMAPI.Mods.ErrorHandler/manifest.json +++ b/src/SMAPI.Mods.ErrorHandler/manifest.json @@ -1,9 +1,9 @@ { "Name": "Error Handler", "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.", "UniqueID": "SMAPI.ErrorHandler", "EntryDll": "ErrorHandler.dll", - "MinimumApiVersion": "3.18.2" + "MinimumApiVersion": "3.18.3" } diff --git a/src/SMAPI.Mods.SaveBackup/manifest.json b/src/SMAPI.Mods.SaveBackup/manifest.json index e29a3ed3..c5075c57 100644 --- a/src/SMAPI.Mods.SaveBackup/manifest.json +++ b/src/SMAPI.Mods.SaveBackup/manifest.json @@ -1,9 +1,9 @@ { "Name": "Save Backup", "Author": "SMAPI", - "Version": "3.18.2", + "Version": "3.18.3", "Description": "Automatically backs up all your saves once per day into its folder.", "UniqueID": "SMAPI.SaveBackup", "EntryDll": "SaveBackup.dll", - "MinimumApiVersion": "3.18.2" + "MinimumApiVersion": "3.18.3" } diff --git a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj index 9529241f..2a9a8294 100644 --- a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj +++ b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj @@ -11,7 +11,7 @@ - + diff --git a/src/SMAPI.Web/SMAPI.Web.csproj b/src/SMAPI.Web/SMAPI.Web.csproj index 1c0e4e42..1e568572 100644 --- a/src/SMAPI.Web/SMAPI.Web.csproj +++ b/src/SMAPI.Web/SMAPI.Web.csproj @@ -25,7 +25,7 @@ - + diff --git a/src/SMAPI.Web/wwwroot/schemas/content-patcher.json b/src/SMAPI.Web/wwwroot/schemas/content-patcher.json index a00403c0..bd9e7427 100644 --- a/src/SMAPI.Web/wwwroot/schemas/content-patcher.json +++ b/src/SMAPI.Web/wwwroot/schemas/content-patcher.json @@ -14,9 +14,9 @@ "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.", "type": "string", - "pattern": "^1\\.28\\.[0-9]+$", + "pattern": "^1\\.29\\.[0-9]+$", "@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": { diff --git a/src/SMAPI.sln b/src/SMAPI.sln index 8bf86487..99b9dc83 100644 --- a/src/SMAPI.sln +++ b/src/SMAPI.sln @@ -19,9 +19,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{4B1C EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ISSUE_TEMPLATE", "ISSUE_TEMPLATE", "{F4453AB6-D7D6-447F-A973-956CC777968F}" ProjectSection(SolutionItems) = preProject - ..\.github\ISSUE_TEMPLATE\bug_report.md = ..\.github\ISSUE_TEMPLATE\bug_report.md - ..\.github\ISSUE_TEMPLATE\feature_request.md = ..\.github\ISSUE_TEMPLATE\feature_request.md - ..\.github\ISSUE_TEMPLATE\general.md = ..\.github\ISSUE_TEMPLATE\general.md + ..\.github\ISSUE_TEMPLATE\config.yml = ..\.github\ISSUE_TEMPLATE\config.yml + ..\.github\ISSUE_TEMPLATE\custom.md = ..\.github\ISSUE_TEMPLATE\custom.md EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{09CF91E5-5BAB-4650-A200-E5EA9A633046}" diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index 482ec816..77a19964 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -52,7 +52,7 @@ namespace StardewModdingAPI internal static int? LogScreenId { get; set; } /// SMAPI's current raw semantic version. - internal static string RawApiVersion = "3.18.2"; + internal static string RawApiVersion = "3.18.3"; } /// Contains SMAPI's constants and assumptions. diff --git a/src/SMAPI/Context.cs b/src/SMAPI/Context.cs index c822908e..978459e8 100644 --- a/src/SMAPI/Context.cs +++ b/src/SMAPI/Context.cs @@ -60,7 +60,7 @@ namespace StardewModdingAPI public static bool IsWorldReady { get => Context.IsWorldReadyForScreen.Value; - set => Context.IsWorldReadyForScreen.Value = value; + internal set => Context.IsWorldReadyForScreen.Value = value; } /// Whether is true and the player is free to act in the world (no menu is displayed, no cutscene is in progress, etc). diff --git a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs index badbd766..2c068784 100644 --- a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs @@ -130,7 +130,7 @@ namespace StardewModdingAPI.Framework.ContentManagers ".png" => this.LoadImageFile(assetName, file), ".tbin" or ".tmx" => this.LoadMapFile(assetName, file), ".xnb" => this.LoadXnbFile(assetName), - _ => this.HandleUnknownFileType(assetName, file) + _ => (T)this.HandleUnknownFileType(assetName, file, typeof(T)) }; } catch (Exception ex) @@ -323,13 +323,15 @@ namespace StardewModdingAPI.Framework.ContentManagers } /// Handle a request to load a file type that isn't supported by SMAPI. - /// The expected file type. /// The asset name relative to the loader root directory. /// The file to load. - private T HandleUnknownFileType(IAssetName assetName, FileInfo file) + /// The expected file type. + 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'."); - return default; + return assetType.IsValueType + ? Activator.CreateInstance(assetType) + : null; } /// Assert that the asset type is compatible with one of the allowed types. diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs index cb62e16f..607bb70d 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -180,13 +180,16 @@ namespace StardewModdingAPI.Framework.ModLoading return mods .OrderBy(mod => { - string id = mod.Manifest.UniqueID; + string? id = mod.Manifest?.UniqueID; - if (modIdsToLoadEarly.TryGetValue(id, out string? actualId)) - return -int.MaxValue + Array.IndexOf(earlyArray, actualId); + if (id is not null) + { + if (modIdsToLoadEarly.TryGetValue(id, out string? actualId)) + return -int.MaxValue + Array.IndexOf(earlyArray, actualId); - if (modIdsToLoadLate.TryGetValue(id, out actualId)) - return int.MaxValue - Array.IndexOf(lateArray, actualId); + if (modIdsToLoadLate.TryGetValue(id, out actualId)) + return int.MaxValue - Array.IndexOf(lateArray, actualId); + } return 0; }) diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index 1d146d5f..abba7f3b 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -433,7 +433,7 @@ namespace StardewModdingAPI.Framework // apply load order customizations if (this.Settings.ModsToLoadEarly.Any() || this.Settings.ModsToLoadLate.Any()) { - HashSet installedIds = new HashSet(mods.Select(p => p.Manifest.UniqueID), StringComparer.OrdinalIgnoreCase); + HashSet installedIds = new HashSet(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[] missingLateMods = this.Settings.ModsToLoadLate.Where(id => !installedIds.Contains(id)).OrderBy(p => p, StringComparer.OrdinalIgnoreCase).ToArray(); diff --git a/src/SMAPI/SMAPI.csproj b/src/SMAPI/SMAPI.csproj index 59ad47f0..530b75aa 100644 --- a/src/SMAPI/SMAPI.csproj +++ b/src/SMAPI/SMAPI.csproj @@ -8,7 +8,6 @@ Exe true false - true icon.ico @@ -22,11 +21,10 @@ - - + diff --git a/src/SMAPI/Utilities/PerScreen.cs b/src/SMAPI/Utilities/PerScreen.cs index 87bf2027..674ec760 100644 --- a/src/SMAPI/Utilities/PerScreen.cs +++ b/src/SMAPI/Utilities/PerScreen.cs @@ -101,6 +101,12 @@ namespace StardewModdingAPI.Utilities this.RemoveScreens(_ => true); } + /// Get whether the current screen has a value created yet. + public bool IsActiveForScreen() + { + return this.States.ContainsKey(Context.ScreenId); + } + /********* ** Private methods diff --git a/src/SMAPI/i18n/ko.json b/src/SMAPI/i18n/ko.json index 8d267e5e..8122a9e2 100644 --- a/src/SMAPI/i18n/ko.json +++ b/src/SMAPI/i18n/ko.json @@ -1,6 +1,6 @@ { // short date format for SDate // tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2) - "generic.date": "{{season}} {{day}}", - "generic.date-with-year": "{{year}} 학년 {{season}} {{day}}" + "generic.date": "{{season}} {{day}}일", + "generic.date-with-year": "{{year}}년차 {{season}} {{day}}일" }