diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index c51d164bb..000000000 --- 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 000000000..63d7bb67f --- /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 000000000..11306e7f5 --- /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 8d935dc84..000000000 --- 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 f02d3c9a4..000000000 --- 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 590e04155..1ead15089 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 1d805e009..304579b95 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 0c0cbeb09..02b5e615a 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 0996e3ed5..117e33e57 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 9eb55b367..e99218bdb 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 23f0b221d..ab8a2c95e 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 3b7eae9c3..70b215215 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 b0d9ae815..c61a801e1 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 abd21dc8f..e85230ed1 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 6ababef00..2447c5c39 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 826304798..306c92fc9 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 e29a3ed32..c5075c572 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 9529241f3..2a9a8294b 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 1c0e4e420..1e5685720 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 a00403c05..bd9e74272 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 8bf86487c..99b9dc834 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 482ec8169..77a199649 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -52,7 +52,7 @@ internal static class EarlyConstants 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 c822908e9..978459e8f 100644 --- a/src/SMAPI/Context.cs +++ b/src/SMAPI/Context.cs @@ -60,7 +60,7 @@ internal static LoadStage LoadStage 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 badbd7669..2c0687842 100644 --- a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs @@ -130,7 +130,7 @@ public override T LoadExact(IAssetName assetName, bool useCache) ".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 @@ private T LoadXnbFile(IAssetName assetName) } /// 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 cb62e16f1..607bb70dc 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -180,13 +180,16 @@ public IModMetadata[] ApplyLoadOrderOverrides(IModMetadata[] mods, HashSet { - 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 1d146d5f5..abba7f3b9 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -433,7 +433,7 @@ private void InitializeBeforeFirstAssetLoaded() // 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 59ad47f00..530b75aa7 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 87bf20272..674ec760e 100644 --- a/src/SMAPI/Utilities/PerScreen.cs +++ b/src/SMAPI/Utilities/PerScreen.cs @@ -101,6 +101,12 @@ public void ResetAllScreens() 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 8d267e5ef..8122a9e21 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}}일" }