From 4e17716fa26161016e5e59f12b52feef3fd0f8f9 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 9 Dec 2021 19:56:46 -0500 Subject: fix log parser handling when multiple mods have the exact same name --- docs/release-notes.md | 4 +++ src/SMAPI.Web/Framework/LogParsing/LogParser.cs | 35 ++++++++++++++++--------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index 499fa322..421378e4 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -1,6 +1,10 @@ ← [README](README.md) # Release notes +## Upcoming release +* For the web UI: + * Fixed log parser not correctly handling multiple mods having the exact same name. + ## 3.13.2 Released 05 December 2021 for Stardew Valley 1.5.5 or later. diff --git a/src/SMAPI.Web/Framework/LogParsing/LogParser.cs b/src/SMAPI.Web/Framework/LogParsing/LogParser.cs index 84013ccc..887d0105 100644 --- a/src/SMAPI.Web/Framework/LogParsing/LogParser.cs +++ b/src/SMAPI.Web/Framework/LogParsing/LogParser.cs @@ -79,7 +79,7 @@ namespace StardewModdingAPI.Web.Framework.LogParsing // parse log messages LogModInfo smapiMod = new LogModInfo { Name = "SMAPI", Author = "Pathoschild", Description = "", Loaded = true }; LogModInfo gameMod = new LogModInfo { Name = "game", Author = "", Description = "", Loaded = true }; - IDictionary mods = new Dictionary(); + IDictionary> mods = new Dictionary>(); bool inModList = false; bool inContentPackList = false; bool inModUpdateList = false; @@ -99,8 +99,11 @@ namespace StardewModdingAPI.Web.Framework.LogParsing break; default: - if (mods.ContainsKey(message.Mod)) - mods[message.Mod].Errors++; + if (mods.TryGetValue(message.Mod, out var entries)) + { + foreach (var entry in entries) + entry.Errors++; + } break; } } @@ -127,7 +130,10 @@ namespace StardewModdingAPI.Web.Framework.LogParsing string version = match.Groups["version"].Value; string author = match.Groups["author"].Value; string description = match.Groups["description"].Value; - mods[name] = new LogModInfo { Name = name, Author = author, Version = version, Description = description, Loaded = true }; + + if (!mods.TryGetValue(name, out List entries)) + mods[name] = entries = new List(); + entries.Add(new LogModInfo { Name = name, Author = author, Version = version, Description = description, Loaded = true }); message.Section = LogSection.ModsList; } @@ -147,7 +153,10 @@ namespace StardewModdingAPI.Web.Framework.LogParsing string author = match.Groups["author"].Value; string description = match.Groups["description"].Value; string forMod = match.Groups["for"].Value; - mods[name] = new LogModInfo { Name = name, Author = author, Version = version, Description = description, ContentPackFor = forMod, Loaded = true }; + + if (!mods.TryGetValue(name, out List entries)) + mods[name] = entries = new List(); + entries.Add(new LogModInfo { Name = name, Author = author, Version = version, Description = description, ContentPackFor = forMod, Loaded = true }); message.Section = LogSection.ContentPackList; } @@ -165,14 +174,14 @@ namespace StardewModdingAPI.Web.Framework.LogParsing string name = match.Groups["name"].Value; string version = match.Groups["version"].Value; string link = match.Groups["link"].Value; - if (mods.ContainsKey(name)) - { - mods[name].UpdateLink = link; - mods[name].UpdateVersion = version; - } - else + + if (mods.TryGetValue(name, out var entries)) { - mods[name] = new LogModInfo { Name = name, UpdateVersion = version, UpdateLink = link, Loaded = false }; + foreach (var entry in entries) + { + entry.UpdateLink = link; + entry.UpdateVersion = version; + } } message.Section = LogSection.ModUpdateList; @@ -219,7 +228,7 @@ namespace StardewModdingAPI.Web.Framework.LogParsing // finalize log gameMod.Version = log.GameVersion; - log.Mods = new[] { gameMod, smapiMod }.Concat(mods.Values.OrderBy(p => p.Name)).ToArray(); + log.Mods = new[] { gameMod, smapiMod }.Concat(mods.Values.SelectMany(p => p).OrderBy(p => p.Name)).ToArray(); return log; } catch (LogParseException ex) -- cgit From aa5d1d4a20c30c9f8fbd30a4d7e8e38e234f17ca Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 9 Dec 2021 19:57:57 -0500 Subject: update compatibility list --- docs/release-notes.md | 3 +++ src/SMAPI.Web/wwwroot/SMAPI.metadata.json | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/docs/release-notes.md b/docs/release-notes.md index 421378e4..41c22085 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -2,6 +2,9 @@ # Release notes ## Upcoming release +* For players: + * Updated compatibility list. + * For the web UI: * Fixed log parser not correctly handling multiple mods having the exact same name. diff --git a/src/SMAPI.Web/wwwroot/SMAPI.metadata.json b/src/SMAPI.Web/wwwroot/SMAPI.metadata.json index eb76b29a..75a3f8c7 100644 --- a/src/SMAPI.Web/wwwroot/SMAPI.metadata.json +++ b/src/SMAPI.Web/wwwroot/SMAPI.metadata.json @@ -481,6 +481,13 @@ "~1.2.2 | StatusReasonDetails": "references the deleted Content/Mine asset" }, + "Critical Crow": { + "ID": "leonary.CRCROWS", + "Default | UpdateKey": "Nexus:2663", + "~1.2.2 | Status": "AssumeBroken", + "~1.2.2 | StatusReasonDetails": "removes newer content from the TileSheets/Craftables asset" + }, + "Green Pastures Farm": { "ID": "bugbuddy.GreenPasturesFarm", "Default | UpdateKey": "Nexus:2326", -- cgit From e0abac8dfb52fb28d296d6df7483094570f68708 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 18 Dec 2021 00:48:55 -0500 Subject: update compatibility list --- src/SMAPI.Web/wwwroot/SMAPI.metadata.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/SMAPI.Web/wwwroot/SMAPI.metadata.json b/src/SMAPI.Web/wwwroot/SMAPI.metadata.json index 75a3f8c7..53c68636 100644 --- a/src/SMAPI.Web/wwwroot/SMAPI.metadata.json +++ b/src/SMAPI.Web/wwwroot/SMAPI.metadata.json @@ -283,6 +283,11 @@ /********* ** Broke in SDV 1.5 (Content Patcher packs) *********/ + "Empty Spouse Room": { + "ID": "Lerura.EmptySpouseRoom", + "~1.0.0 | Status": "AssumeBroken", + "~1.0.0 | StatusReasonDetails": "prevents loading married saves due to a missing tilesheet in the spouse room map" + }, "mi.Mermaids": { "ID": "mi.Mermaids", "~1.0.0 | Status": "AssumeBroken", -- cgit From beb1acd4f823d64d125f5749b2edad06e5731407 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 18 Dec 2021 22:21:31 -0500 Subject: update Steam error message --- docs/release-notes.md | 1 + src/SMAPI/Framework/Logging/LogManager.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index 41c22085..b54aeb15 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -3,6 +3,7 @@ # Release notes ## Upcoming release * For players: + * Fixed outdated instructions in Steam error message. * Updated compatibility list. * For the web UI: diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index 5a291d0a..ef89c751 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -49,7 +49,7 @@ namespace StardewModdingAPI.Framework.Logging search: new Regex(@"^System\.InvalidOperationException: Steamworks is not initialized\.[\s\S]+$", RegexOptions.Compiled | RegexOptions.CultureInvariant), replacement: #if SMAPI_FOR_WINDOWS - "Oops! Steam achievements won't work because Steam isn't loaded. See 'Launch SMAPI through Steam or GOG Galaxy' in the install guide for more info: https://smapi.io/install.", + "Oops! Steam achievements won't work because Steam isn't loaded. See 'Configure your game client' in the install guide for more info: https://smapi.io/install.", #else "Oops! Steam achievements won't work because Steam isn't loaded. You can launch the game through Steam to fix that.", #endif -- cgit From 95f658014ebd2aadce1bc72d1d7e763efd7782ba Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 18 Dec 2021 23:07:33 -0500 Subject: simplify running SMAPI without a terminal on Linux/macOS --- docs/release-notes.md | 1 + src/SMAPI.Installer/assets/unix-launcher.sh | 122 +++++++++++++++------------- 2 files changed, 67 insertions(+), 56 deletions(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index b54aeb15..e0c6977d 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -4,6 +4,7 @@ ## Upcoming release * For players: * Fixed outdated instructions in Steam error message. + * Simplified [running without a terminal on Linux/macOS](https://stardewvalleywiki.com/Modding:Player_Guide/Troubleshooting#SMAPI_doesn.27t_recognize_controller_.28Steam_only.29) when needed. * Updated compatibility list. * For the web UI: diff --git a/src/SMAPI.Installer/assets/unix-launcher.sh b/src/SMAPI.Installer/assets/unix-launcher.sh index e8b9ae62..713597e2 100644 --- a/src/SMAPI.Installer/assets/unix-launcher.sh +++ b/src/SMAPI.Installer/assets/unix-launcher.sh @@ -6,6 +6,10 @@ # move to script's directory cd "$(dirname "$0")" || exit $? +# change to true to skip opening a terminal +# This isn't recommended since you won't see errors, warnings, and update alerts. +SKIP_TERMINAL=false + ########## ## Open terminal if needed @@ -16,7 +20,6 @@ cd "$(dirname "$0")" || exit $? if [ "$(uname)" == "Darwin" ]; then if [ ! -t 1 ]; then # https://stackoverflow.com/q/911168/262123 # sanity check to make sure we don't have an infinite loop of opening windows - SKIP_TERMINAL=false for argument in "$@"; do if [ "$argument" == "--no-reopen-terminal" ]; then SKIP_TERMINAL=true @@ -63,64 +66,71 @@ else LAUNCH_FILE="./StardewModdingAPI" export LAUNCH_FILE - # select terminal (prefer xterm for best compatibility, then known supported terminals) - for terminal in xterm gnome-terminal kitty terminator xfce4-terminal konsole terminal termite alacritty mate-terminal x-terminal-emulator; do - if command -v "$terminal" 2>/dev/null; then - export TERMINAL_NAME=$terminal - break; + # run in terminal + if [ "$SKIP_TERMINAL" == "false" ]; then + # select terminal (prefer xterm for best compatibility, then known supported terminals) + for terminal in xterm gnome-terminal kitty terminator xfce4-terminal konsole terminal termite alacritty mate-terminal x-terminal-emulator; do + if command -v "$terminal" 2>/dev/null; then + export TERMINAL_NAME=$terminal + break; + fi + done + + # find the true shell behind x-terminal-emulator + if [ "$TERMINAL_NAME" = "x-terminal-emulator" ]; then + export TERMINAL_NAME="$(basename "$(readlink -f $(command -v x-terminal-emulator))")" fi - done - # find the true shell behind x-terminal-emulator - if [ "$TERMINAL_NAME" = "x-terminal-emulator" ]; then - export TERMINAL_NAME="$(basename "$(readlink -f $(command -v x-terminal-emulator))")" - fi + # run in selected terminal and account for quirks + export TERMINAL_PATH="$(command -v $TERMINAL_NAME)" + if [ -x $TERMINAL_PATH ]; then + case $TERMINAL_NAME in + terminal|termite) + # consumes only one argument after -e + # options containing space characters are unsupported + exec $TERMINAL_NAME -e "env TERM=xterm $LAUNCH_FILE $@" + ;; + + xterm|konsole|alacritty) + # consumes all arguments after -e + exec $TERMINAL_NAME -e env TERM=xterm $LAUNCH_FILE "$@" + ;; + + terminator|xfce4-terminal|mate-terminal) + # consumes all arguments after -x + exec $TERMINAL_NAME -x env TERM=xterm $LAUNCH_FILE "$@" + ;; + + gnome-terminal) + # consumes all arguments after -- + exec $TERMINAL_NAME -- env TERM=xterm $LAUNCH_FILE "$@" + ;; + + kitty) + # consumes all trailing arguments + exec $TERMINAL_NAME env TERM=xterm $LAUNCH_FILE "$@" + ;; + + *) + # If we don't know the terminal, just try to run it in the current shell. + # If THAT fails, launch with no output. + env TERM=xterm $LAUNCH_FILE "$@" + if [ $? -eq 127 ]; then + exec $LAUNCH_FILE --no-terminal "$@" + fi + esac + + ## terminal isn't executable; fallback to current shell or no terminal + else + echo "The '$TERMINAL_NAME' terminal isn't executable. SMAPI might be running in a sandbox or the system might be misconfigured? Falling back to current shell." + env TERM=xterm $LAUNCH_FILE "$@" + if [ $? -eq 127 ]; then + exec $LAUNCH_FILE --no-terminal "$@" + fi + fi - # run in selected terminal and account for quirks - export TERMINAL_PATH="$(command -v $TERMINAL_NAME)" - if [ -x $TERMINAL_PATH ]; then - case $TERMINAL_NAME in - terminal|termite) - # consumes only one argument after -e - # options containing space characters are unsupported - exec $TERMINAL_NAME -e "env TERM=xterm $LAUNCH_FILE $@" - ;; - - xterm|konsole|alacritty) - # consumes all arguments after -e - exec $TERMINAL_NAME -e env TERM=xterm $LAUNCH_FILE "$@" - ;; - - terminator|xfce4-terminal|mate-terminal) - # consumes all arguments after -x - exec $TERMINAL_NAME -x env TERM=xterm $LAUNCH_FILE "$@" - ;; - - gnome-terminal) - # consumes all arguments after -- - exec $TERMINAL_NAME -- env TERM=xterm $LAUNCH_FILE "$@" - ;; - - kitty) - # consumes all trailing arguments - exec $TERMINAL_NAME env TERM=xterm $LAUNCH_FILE "$@" - ;; - - *) - # If we don't know the terminal, just try to run it in the current shell. - # If THAT fails, launch with no output. - env TERM=xterm $LAUNCH_FILE "$@" - if [ $? -eq 127 ]; then - exec $LAUNCH_FILE --no-terminal "$@" - fi - esac - - ## terminal isn't executable; fallback to current shell or no terminal + # explicitly run without terminal else - echo "The '$TERMINAL_NAME' terminal isn't executable. SMAPI might be running in a sandbox or the system might be misconfigured? Falling back to current shell." - env TERM=xterm $LAUNCH_FILE "$@" - if [ $? -eq 127 ]; then - exec $LAUNCH_FILE --no-terminal "$@" - fi + exec $LAUNCH_FILE --no-terminal "$@" fi fi -- cgit From 0d7d4476004d33b395d6df81386e4159d8898027 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Mon, 20 Dec 2021 22:18:09 -0500 Subject: auto-fix maps broken due to missing vanilla tilesheet --- docs/release-notes.md | 1 + src/SMAPI.sln.DotSettings | 1 + src/SMAPI/Framework/Content/TilesheetReference.cs | 15 ++++++++- src/SMAPI/Framework/ContentCoordinator.cs | 4 +-- .../ContentManagers/GameContentManager.cs | 39 +++++++++------------- 5 files changed, 33 insertions(+), 27 deletions(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index e0c6977d..caa5cc68 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -3,6 +3,7 @@ # Release notes ## Upcoming release * For players: + * SMAPI now auto-fixes maps loaded without a required tilesheet to prevent errors. * Fixed outdated instructions in Steam error message. * Simplified [running without a terminal on Linux/macOS](https://stardewvalleywiki.com/Modding:Player_Guide/Troubleshooting#SMAPI_doesn.27t_recognize_controller_.28Steam_only.29) when needed. * Updated compatibility list. diff --git a/src/SMAPI.sln.DotSettings b/src/SMAPI.sln.DotSettings index 9a6cad37..71cd7b82 100644 --- a/src/SMAPI.sln.DotSettings +++ b/src/SMAPI.sln.DotSettings @@ -70,6 +70,7 @@ True True True + True True True \ No newline at end of file diff --git a/src/SMAPI/Framework/Content/TilesheetReference.cs b/src/SMAPI/Framework/Content/TilesheetReference.cs index 2ea38430..0919bb44 100644 --- a/src/SMAPI/Framework/Content/TilesheetReference.cs +++ b/src/SMAPI/Framework/Content/TilesheetReference.cs @@ -1,3 +1,6 @@ +using System.Numerics; +using xTile.Dimensions; + namespace StardewModdingAPI.Framework.Content { /// Basic metadata about a vanilla tilesheet. @@ -15,6 +18,12 @@ namespace StardewModdingAPI.Framework.Content /// The asset path for the tilesheet texture. public readonly string ImageSource; + /// The number of tiles in the tilesheet. + public readonly Size SheetSize; + + /// The size of each tile in pixels. + public readonly Size TileSize; + /********* ** Public methods @@ -23,11 +32,15 @@ namespace StardewModdingAPI.Framework.Content /// The tilesheet's index in the list. /// The tilesheet's unique ID in the map. /// The asset path for the tilesheet texture. - public TilesheetReference(int index, string id, string imageSource) + /// The number of tiles in the tilesheet. + /// The size of each tile in pixels. + public TilesheetReference(int index, string id, string imageSource, Size sheetSize, Size tileSize) { this.Index = index; this.Id = id; this.ImageSource = imageSource; + this.SheetSize = sheetSize; + this.TileSize = tileSize; } } } diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs index b6f1669a..99091f3e 100644 --- a/src/SMAPI/Framework/ContentCoordinator.cs +++ b/src/SMAPI/Framework/ContentCoordinator.cs @@ -406,14 +406,14 @@ namespace StardewModdingAPI.Framework if (!this.VanillaTilesheets.TryGetValue(assetName, out TilesheetReference[] tilesheets)) { tilesheets = this.TryLoadVanillaAsset(assetName, out Map map) - ? map.TileSheets.Select((sheet, index) => new TilesheetReference(index, sheet.Id, sheet.ImageSource)).ToArray() + ? map.TileSheets.Select((sheet, index) => new TilesheetReference(index, sheet.Id, sheet.ImageSource, sheet.SheetSize, sheet.TileSize)).ToArray() : null; this.VanillaTilesheets[assetName] = tilesheets; this.VanillaContentManager.Unload(); } - return tilesheets ?? new TilesheetReference[0]; + return tilesheets ?? Array.Empty(); } /// Get the language enum which corresponds to a locale code (e.g. given fr-FR). diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs index 7a49dd36..ab198076 100644 --- a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs @@ -13,6 +13,7 @@ using StardewModdingAPI.Framework.Utilities; using StardewModdingAPI.Internal; using StardewValley; using xTile; +using xTile.Tiles; namespace StardewModdingAPI.Framework.ContentManagers { @@ -308,7 +309,7 @@ namespace StardewModdingAPI.Framework.ContentManagers } // return matched asset - return this.TryValidateLoadedAsset(info, data, mod) + return this.TryFixAndValidateLoadedAsset(info, data, mod) ? new AssetDataForObject(info, data, this.AssertAndNormalizeAssetName) : null; } @@ -381,12 +382,13 @@ namespace StardewModdingAPI.Framework.ContentManagers return asset; } - /// Validate that an asset loaded by a mod is valid and won't cause issues. + /// Validate that an asset loaded by a mod is valid and won't cause issues, and fix issues if possible. /// The asset type. /// The basic asset metadata. /// The loaded asset data. /// The mod which loaded the asset. - private bool TryValidateLoadedAsset(IAssetInfo info, T data, IModMetadata mod) + /// Returns whether the asset passed validation checks (after any fixes were applied). + private bool TryFixAndValidateLoadedAsset(IAssetInfo info, T data, IModMetadata mod) { // can't load a null asset if (data == null) @@ -401,20 +403,23 @@ namespace StardewModdingAPI.Framework.ContentManagers TilesheetReference[] vanillaTilesheetRefs = this.Coordinator.GetVanillaTilesheetIds(info.AssetName); foreach (TilesheetReference vanillaSheet in vanillaTilesheetRefs) { - // skip if match - if (loadedMap.TileSheets.Count > vanillaSheet.Index && loadedMap.TileSheets[vanillaSheet.Index].Id == vanillaSheet.Id) - continue; + // add missing tilesheet + if (loadedMap.GetTileSheet(vanillaSheet.Id) == null) + { + mod.Monitor.LogOnce("SMAPI fixed maps loaded by this mod to prevent errors. See the log file for details.", LogLevel.Warn); + this.Monitor.Log($"Fixed broken map replacement: {mod.DisplayName} loaded '{info.AssetName}' without a required tilesheet (id: {vanillaSheet.Id}, source: {vanillaSheet.ImageSource})."); + + loadedMap.AddTileSheet(new TileSheet(vanillaSheet.Id, loadedMap, vanillaSheet.ImageSource, vanillaSheet.SheetSize, vanillaSheet.TileSize)); + } // handle mismatch + if (loadedMap.TileSheets.Count <= vanillaSheet.Index || loadedMap.TileSheets[vanillaSheet.Index].Id != vanillaSheet.Id) { // only show warning if not farm map // This is temporary: mods shouldn't do this for any vanilla map, but these are the ones we know will crash. Showing a warning for others instead gives modders time to update their mods, while still simplifying troubleshooting. bool isFarmMap = info.AssetNameEquals("Maps/Farm") || info.AssetNameEquals("Maps/Farm_Combat") || info.AssetNameEquals("Maps/Farm_Fishing") || info.AssetNameEquals("Maps/Farm_Foraging") || info.AssetNameEquals("Maps/Farm_FourCorners") || info.AssetNameEquals("Maps/Farm_Island") || info.AssetNameEquals("Maps/Farm_Mining"); - int loadedIndex = this.TryFindTilesheet(loadedMap, vanillaSheet.Id); - string reason = loadedIndex != -1 - ? $"mod reordered the original tilesheets, which {(isFarmMap ? "would cause a crash" : "often causes crashes")}.\nTechnical details for mod author: Expected order: {string.Join(", ", vanillaTilesheetRefs.Select(p => p.Id))}. See https://stardewvalleywiki.com/Modding:Maps#Tilesheet_order for help." - : $"mod has no tilesheet with ID '{vanillaSheet.Id}'. Map replacements must keep the original tilesheets to avoid errors or crashes."; + string reason = $"mod reordered the original tilesheets, which {(isFarmMap ? "would cause a crash" : "often causes crashes")}.\nTechnical details for mod author: Expected order: {string.Join(", ", vanillaTilesheetRefs.Select(p => p.Id))}. See https://stardewvalleywiki.com/Modding:Maps#Tilesheet_order for help."; SCore.DeprecationManager.PlaceholderWarn("3.8.2", DeprecationLevel.PendingRemoval); if (isFarmMap) @@ -429,19 +434,5 @@ namespace StardewModdingAPI.Framework.ContentManagers return true; } - - /// Find a map tilesheet by ID. - /// The map whose tilesheets to search. - /// The tilesheet ID to match. - private int TryFindTilesheet(Map map, string id) - { - for (int i = 0; i < map.TileSheets.Count; i++) - { - if (map.TileSheets[i].Id == id) - return i; - } - - return -1; - } } } -- cgit From 52f4df3f301ecde85a76e10ea9ddd607ab7a1b79 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 21 Dec 2021 20:33:08 -0500 Subject: add new game build number to the SMAPI log --- docs/release-notes.md | 1 + src/SMAPI/Constants.cs | 11 +++++++++++ src/SMAPI/Framework/Logging/LogManager.cs | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index caa5cc68..a98cfd8e 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -4,6 +4,7 @@ ## Upcoming release * For players: * SMAPI now auto-fixes maps loaded without a required tilesheet to prevent errors. + * Added the new game build number to the SMAPI console + log. * Fixed outdated instructions in Steam error message. * Simplified [running without a terminal on Linux/macOS](https://stardewvalleywiki.com/Modding:Player_Guide/Troubleshooting#SMAPI_doesn.27t_recognize_controller_.28Steam_only.29) when needed. * Updated compatibility list. diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index 5de28f84..c86acd0a 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -340,5 +340,16 @@ namespace StardewModdingAPI // if save doesn't exist yet, return the default one we expect to be created return folder; } + + /// Get a display label for the game's build number. + internal static string GetBuildVersionLabel() + { + string version = typeof(Game1).Assembly.GetName().Version?.ToString() ?? "unknown"; + + if (version.StartsWith($"{Game1.version}.")) + version = version.Substring(Game1.version.Length + 1); + + return version; + } } } diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index ef89c751..90433c37 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -262,7 +262,7 @@ namespace StardewModdingAPI.Framework.Logging public void LogIntro(string modsPath, IDictionary customSettings) { // log platform - this.Monitor.Log($"SMAPI {Constants.ApiVersion} with Stardew Valley {Constants.GameVersion} on {EnvironmentUtility.GetFriendlyPlatformName(Constants.Platform)}", LogLevel.Info); + this.Monitor.Log($"SMAPI {Constants.ApiVersion} with Stardew Valley {Constants.GameVersion} (build {Constants.GetBuildVersionLabel()}) on {EnvironmentUtility.GetFriendlyPlatformName(Constants.Platform)}", LogLevel.Info); // log basic info this.Monitor.Log($"Mods go here: {modsPath}", LogLevel.Info); -- cgit From 571211687935ce3a12bf4905f056d9be1d6b147f Mon Sep 17 00:00:00 2001 From: bruce2409 Date: Wed, 22 Dec 2021 17:41:11 +0000 Subject: Added shell shebang to MacOS Launcher code --- src/SMAPI.Installer/assets/unix-launcher.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SMAPI.Installer/assets/unix-launcher.sh b/src/SMAPI.Installer/assets/unix-launcher.sh index 713597e2..7cf39f0e 100644 --- a/src/SMAPI.Installer/assets/unix-launcher.sh +++ b/src/SMAPI.Installer/assets/unix-launcher.sh @@ -31,7 +31,8 @@ if [ "$(uname)" == "Darwin" ]; then # https://stackoverflow.com/a/29511052/262123 if [ "$SKIP_TERMINAL" == "false" ]; then echo "Reopening in the Terminal app..." - echo "\"$0\" $@ --no-reopen-terminal" > /tmp/open-smapi-terminal.sh + echo '#!/bin/sh" > /tmp/open-smapi-terminal.sh + echo "\"$0\" $@ --no-reopen-terminal" >> /tmp/open-smapi-terminal.sh chmod +x /tmp/open-smapi-terminal.sh cat /tmp/open-smapi-terminal.sh open -W -a Terminal /tmp/open-smapi-terminal.sh -- cgit From 02831503ddae7d3cd977c21cdd056fc218594ad1 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 23 Dec 2021 18:59:14 -0500 Subject: remove content pack from compatibility blacklist It's no longer broken with the auto-fixes in the upcoming SMAPI update. --- src/SMAPI.Web/wwwroot/SMAPI.metadata.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/SMAPI.Web/wwwroot/SMAPI.metadata.json b/src/SMAPI.Web/wwwroot/SMAPI.metadata.json index 53c68636..75a3f8c7 100644 --- a/src/SMAPI.Web/wwwroot/SMAPI.metadata.json +++ b/src/SMAPI.Web/wwwroot/SMAPI.metadata.json @@ -283,11 +283,6 @@ /********* ** Broke in SDV 1.5 (Content Patcher packs) *********/ - "Empty Spouse Room": { - "ID": "Lerura.EmptySpouseRoom", - "~1.0.0 | Status": "AssumeBroken", - "~1.0.0 | StatusReasonDetails": "prevents loading married saves due to a missing tilesheet in the spouse room map" - }, "mi.Mermaids": { "ID": "mi.Mermaids", "~1.0.0 | Status": "AssumeBroken", -- cgit From aad77242f02c0a851b5d6ad11c258d9b74d90c5b Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 23 Dec 2021 23:08:49 -0500 Subject: fix uninstaller not removing StardewModdingAPI.deps.json file --- docs/release-notes.md | 1 + src/SMAPI.Installer/InteractiveInstaller.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/release-notes.md b/docs/release-notes.md index a98cfd8e..0be39c13 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -6,6 +6,7 @@ * SMAPI now auto-fixes maps loaded without a required tilesheet to prevent errors. * Added the new game build number to the SMAPI console + log. * Fixed outdated instructions in Steam error message. + * Fixed uninstaller not removing `StardewModdingAPI.deps.json` file. * Simplified [running without a terminal on Linux/macOS](https://stardewvalleywiki.com/Modding:Player_Guide/Troubleshooting#SMAPI_doesn.27t_recognize_controller_.28Steam_only.29) when needed. * Updated compatibility list. diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs index 1257f12b..b3bba883 100644 --- a/src/SMAPI.Installer/InteractiveInstaller.cs +++ b/src/SMAPI.Installer/InteractiveInstaller.cs @@ -41,6 +41,7 @@ namespace StardewModdingApi.Installer // current files yield return GetInstallPath("StardewModdingAPI"); // Linux/macOS only + yield return GetInstallPath("StardewModdingAPI.deps.json"); yield return GetInstallPath("StardewModdingAPI.dll"); yield return GetInstallPath("StardewModdingAPI.exe"); yield return GetInstallPath("StardewModdingAPI.exe.config"); -- cgit From 92f35837ad771090d96a759feb0d5d6d8c273b0e Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 2 Jan 2022 13:48:53 -0500 Subject: fix syntax, update release notes --- docs/release-notes.md | 1 + src/SMAPI.Installer/assets/unix-launcher.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index 0be39c13..3eac227f 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -7,6 +7,7 @@ * Added the new game build number to the SMAPI console + log. * Fixed outdated instructions in Steam error message. * Fixed uninstaller not removing `StardewModdingAPI.deps.json` file. + * Fixed launch issue on macOS when using some terminals (thanks to bruce2409!). * Simplified [running without a terminal on Linux/macOS](https://stardewvalleywiki.com/Modding:Player_Guide/Troubleshooting#SMAPI_doesn.27t_recognize_controller_.28Steam_only.29) when needed. * Updated compatibility list. diff --git a/src/SMAPI.Installer/assets/unix-launcher.sh b/src/SMAPI.Installer/assets/unix-launcher.sh index 7cf39f0e..47937f95 100644 --- a/src/SMAPI.Installer/assets/unix-launcher.sh +++ b/src/SMAPI.Installer/assets/unix-launcher.sh @@ -31,7 +31,7 @@ if [ "$(uname)" == "Darwin" ]; then # https://stackoverflow.com/a/29511052/262123 if [ "$SKIP_TERMINAL" == "false" ]; then echo "Reopening in the Terminal app..." - echo '#!/bin/sh" > /tmp/open-smapi-terminal.sh + echo '#!/bin/sh' > /tmp/open-smapi-terminal.sh echo "\"$0\" $@ --no-reopen-terminal" >> /tmp/open-smapi-terminal.sh chmod +x /tmp/open-smapi-terminal.sh cat /tmp/open-smapi-terminal.sh -- cgit From 1fab386ab1ba6ae92ff934c3869f31a1660cf3b3 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 2 Jan 2022 13:57:14 -0500 Subject: add Ukrainian translations (#823) --- docs/README.md | 38 +++++++++++++++++--------------- docs/release-notes.md | 1 + src/SMAPI.Mods.ErrorHandler/i18n/uk.json | 4 ++++ src/SMAPI/i18n/uk.json | 6 +++++ 4 files changed, 31 insertions(+), 18 deletions(-) create mode 100644 src/SMAPI.Mods.ErrorHandler/i18n/uk.json create mode 100644 src/SMAPI/i18n/uk.json diff --git a/docs/README.md b/docs/README.md index ecfa6f2b..d3aaae64 100644 --- a/docs/README.md +++ b/docs/README.md @@ -56,22 +56,24 @@ SMAPI rarely shows text in-game, so it only has a few translations. Contribution [Modding:Translations](https://stardewvalleywiki.com/Modding:Translations) on the wiki for help contributing translations. -locale | status ----------- | :---------------- -default | ✓ [fully translated](../src/SMAPI/i18n/default.json) -Chinese | ✓ [fully translated](../src/SMAPI/i18n/zh.json) -French | ✓ [fully translated](../src/SMAPI/i18n/fr.json) -German | ✓ [fully translated](../src/SMAPI/i18n/de.json) -Hungarian | ✓ [fully translated](../src/SMAPI/i18n/hu.json) -Italian | ✓ [fully translated](../src/SMAPI/i18n/it.json) -Japanese | ✓ [fully translated](../src/SMAPI/i18n/ja.json) -Korean | ✓ [fully translated](../src/SMAPI/i18n/ko.json) -Polish¹ | ✓ [fully translated](../src/SMAPI/i18n/pl.json) -Portuguese | ✓ [fully translated](../src/SMAPI/i18n/pt.json) -Russian | ✓ [fully translated](../src/SMAPI/i18n/ru.json) -Spanish | ✓ [fully translated](../src/SMAPI/i18n/es.json) -Thai¹ | ✓ [fully translated](../src/SMAPI/i18n/th.json) -Turkish | ✓ [fully translated](../src/SMAPI/i18n/tr.json) +locale | status +----------- | :---------------- +default | ✓ [fully translated](../src/SMAPI/i18n/default.json) +Chinese | ✓ [fully translated](../src/SMAPI/i18n/zh.json) +French | ✓ [fully translated](../src/SMAPI/i18n/fr.json) +German | ✓ [fully translated](../src/SMAPI/i18n/de.json) +Hungarian | ✓ [fully translated](../src/SMAPI/i18n/hu.json) +Italian | ✓ [fully translated](../src/SMAPI/i18n/it.json) +Japanese | ✓ [fully translated](../src/SMAPI/i18n/ja.json) +Korean | ✓ [fully translated](../src/SMAPI/i18n/ko.json) +[Polish] | ✓ [fully translated](../src/SMAPI/i18n/pl.json) +Portuguese | ✓ [fully translated](../src/SMAPI/i18n/pt.json) +Russian | ✓ [fully translated](../src/SMAPI/i18n/ru.json) +Spanish | ✓ [fully translated](../src/SMAPI/i18n/es.json) +[Thai] | ✓ [fully translated](../src/SMAPI/i18n/th.json) +Turkish | ✓ [fully translated](../src/SMAPI/i18n/tr.json) +[Ukrainian] | ✓ [fully translated](../src/SMAPI/i18n/uk.json) -¹ This is a custom language provided by a mod (see [Polish](https://www.nexusmods.com/stardewvalley/mods/3616) -and [Thai](https://www.nexusmods.com/stardewvalley/mods/7052)). +[Polish]: https://www.nexusmods.com/stardewvalley/mods/3616 +[Thai]: https://www.nexusmods.com/stardewvalley/mods/7052 +[Ukrainian]: https://www.nexusmods.com/stardewvalley/mods/8427 diff --git a/docs/release-notes.md b/docs/release-notes.md index 3eac227f..8ca2e884 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -10,6 +10,7 @@ * Fixed launch issue on macOS when using some terminals (thanks to bruce2409!). * Simplified [running without a terminal on Linux/macOS](https://stardewvalleywiki.com/Modding:Player_Guide/Troubleshooting#SMAPI_doesn.27t_recognize_controller_.28Steam_only.29) when needed. * Updated compatibility list. + * Improved translations. Thanks to ChulkyBow (added Ukrainian)! * For the web UI: * Fixed log parser not correctly handling multiple mods having the exact same name. diff --git a/src/SMAPI.Mods.ErrorHandler/i18n/uk.json b/src/SMAPI.Mods.ErrorHandler/i18n/uk.json new file mode 100644 index 00000000..a58102ab --- /dev/null +++ b/src/SMAPI.Mods.ErrorHandler/i18n/uk.json @@ -0,0 +1,4 @@ +{ + // warning messages + "warn.invalid-content-removed": "Недійсний вміст видалено, щоб запобігти аварійному завершенню роботи (Додаткову інформацію див. на консолі SMAPI)." +} diff --git a/src/SMAPI/i18n/uk.json b/src/SMAPI/i18n/uk.json new file mode 100644 index 00000000..d84aabcf --- /dev/null +++ b/src/SMAPI/i18n/uk.json @@ -0,0 +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": "{{season}} День {{day}}, Рік {{year}}" +} -- cgit From e30e42762871af3900c47886b57e8c43287b290a Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 2 Jan 2022 19:59:38 -0500 Subject: add download option to log view --- docs/release-notes.md | 1 + src/SMAPI.Web/Controllers/LogParserController.cs | 33 +++++++++++++++++++----- src/SMAPI.Web/ViewModels/LogViewFormat.cs | 15 +++++++++++ src/SMAPI.Web/Views/LogParser/Index.cshtml | 17 +++++++++--- 4 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 src/SMAPI.Web/ViewModels/LogViewFormat.cs diff --git a/docs/release-notes.md b/docs/release-notes.md index 8ca2e884..1df0af0e 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -13,6 +13,7 @@ * Improved translations. Thanks to ChulkyBow (added Ukrainian)! * For the web UI: + * Added log download option. * Fixed log parser not correctly handling multiple mods having the exact same name. ## 3.13.2 diff --git a/src/SMAPI.Web/Controllers/LogParserController.cs b/src/SMAPI.Web/Controllers/LogParserController.cs index 39de4b5d..db53d942 100644 --- a/src/SMAPI.Web/Controllers/LogParserController.cs +++ b/src/SMAPI.Web/Controllers/LogParserController.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using StardewModdingAPI.Toolkit.Utilities; @@ -39,24 +40,42 @@ namespace StardewModdingAPI.Web.Controllers ***/ /// Render the log parser UI. /// The stored file ID. - /// Whether to display the raw unparsed log. + /// How to render the log view. /// Whether to reset the log expiry. [HttpGet] [Route("log")] [Route("log/{id}")] - public async Task Index(string id = null, bool raw = false, bool renew = false) + public async Task Index(string id = null, LogViewFormat format = LogViewFormat.Default, bool renew = false) { // fresh page if (string.IsNullOrWhiteSpace(id)) return this.View("Index", this.GetModel(id)); - // log page + // fetch log StoredFileInfo file = await this.Storage.GetAsync(id, renew); - ParsedLog log = file.Success - ? new LogParser().Parse(file.Content) - : new ParsedLog { IsValid = false, Error = file.Error }; - return this.View("Index", this.GetModel(id, uploadWarning: file.Warning, expiry: file.Expiry).SetResult(log, raw)); + // render view + switch (format) + { + case LogViewFormat.Default: + case LogViewFormat.RawView: + { + ParsedLog log = file.Success + ? new LogParser().Parse(file.Content) + : new ParsedLog { IsValid = false, Error = file.Error }; + + return this.View("Index", this.GetModel(id, uploadWarning: file.Warning, expiry: file.Expiry).SetResult(log, showRaw: format == LogViewFormat.RawView)); + } + + case LogViewFormat.RawDownload: + { + string content = file.Error ?? file.Content; + return this.File(Encoding.UTF8.GetBytes(content), "plain/text", $"SMAPI log ({id}).txt"); + } + + default: + throw new InvalidOperationException($"Unknown log view format '{format}'."); + } } /*** diff --git a/src/SMAPI.Web/ViewModels/LogViewFormat.cs b/src/SMAPI.Web/ViewModels/LogViewFormat.cs new file mode 100644 index 00000000..7ef79319 --- /dev/null +++ b/src/SMAPI.Web/ViewModels/LogViewFormat.cs @@ -0,0 +1,15 @@ +namespace StardewModdingAPI.Web.ViewModels +{ + /// How a log file should be displayed. + public enum LogViewFormat + { + /// Render a parsed log and metadata. + Default, + + /// Render a raw log with parsed metadata. + RawView, + + /// Render directly as a text file. + RawDownload + } +} diff --git a/src/SMAPI.Web/Views/LogParser/Index.cshtml b/src/SMAPI.Web/Views/LogParser/Index.cshtml index 06d46c9e..eeff776c 100644 --- a/src/SMAPI.Web/Views/LogParser/Index.cshtml +++ b/src/SMAPI.Web/Views/LogParser/Index.cshtml @@ -2,6 +2,7 @@ @using StardewModdingAPI.Toolkit.Utilities @using StardewModdingAPI.Web.Framework @using StardewModdingAPI.Web.Framework.LogParsing.Models +@using StardewModdingAPI.Web.ViewModels @model StardewModdingAPI.Web.ViewModels.LogParserModel @{ @@ -338,14 +339,24 @@ else if (Model.ParsedLog?.IsValid == true) } } - - view raw log } else {
@Model.ParsedLog.RawText
- view parsed log } + + + @if (Model.ShowRaw) + { + view parsed log + } + else + { + view raw log + } + + | download + } else if (Model.ParsedLog?.IsValid == false) -- cgit From a8985e122e9ebd3cb1545971474b95d34058f896 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 15 Jan 2022 12:21:22 -0500 Subject: fix suppressed console output not suppressing newlines --- docs/release-notes.md | 1 + .../Framework/Logging/InterceptingTextWriter.cs | 12 +++++++++++- src/SMAPI/Framework/Logging/LogManager.cs | 20 ++++++++++++++++---- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index 1df0af0e..735c7c12 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -5,6 +5,7 @@ * For players: * SMAPI now auto-fixes maps loaded without a required tilesheet to prevent errors. * Added the new game build number to the SMAPI console + log. + * Fixed extra newlines shown in the console in non-developer mode. * Fixed outdated instructions in Steam error message. * Fixed uninstaller not removing `StardewModdingAPI.deps.json` file. * Fixed launch issue on macOS when using some terminals (thanks to bruce2409!). diff --git a/src/SMAPI/Framework/Logging/InterceptingTextWriter.cs b/src/SMAPI/Framework/Logging/InterceptingTextWriter.cs index d99f1dd2..41a3abcb 100644 --- a/src/SMAPI/Framework/Logging/InterceptingTextWriter.cs +++ b/src/SMAPI/Framework/Logging/InterceptingTextWriter.cs @@ -26,6 +26,10 @@ namespace StardewModdingAPI.Framework.Logging /// The event raised when a message is written to the console directly. public event Action OnMessageIntercepted; + /// Whether the text writer should ignore the next input if it's a newline. + /// This is used when log output is suppressed from the console, since Console.WriteLine writes the trailing newline as a separate call. + public bool IgnoreNextIfNewline { get; set; } + /********* ** Public methods @@ -42,12 +46,18 @@ namespace StardewModdingAPI.Framework.Logging /// public override void Write(char[] buffer, int index, int count) { + bool ignoreIfNewline = this.IgnoreNextIfNewline; + this.IgnoreNextIfNewline = false; + if (buffer.Length == 0) this.Out.Write(buffer, index, count); else if (buffer[0] == this.IgnoreChar) this.Out.Write(buffer, index + 1, count - 1); else if (this.IsEmptyOrNewline(buffer)) - this.Out.Write(buffer, index, count); + { + if (!ignoreIfNewline) + this.Out.Write(buffer, index, count); + } else this.OnMessageIntercepted?.Invoke(new string(buffer, index, count).TrimEnd('\r', '\n')); } diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index 90433c37..acd2c617 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -22,9 +22,15 @@ namespace StardewModdingAPI.Framework.Logging /********* ** Fields *********/ + /// Whether to show trace messages in the console. + private readonly bool ShowTraceInConsole; + /// The log file to which to write messages. private readonly LogFileManager LogFile; + /// The text writer which intercepts console output. + private readonly InterceptingTextWriter ConsoleInterceptor; + /// Prefixing a low-level message with this character indicates that the console interceptor should write the string without intercepting it. (The character itself is not written.) private readonly char IgnoreChar = '\u200B'; @@ -91,10 +97,11 @@ namespace StardewModdingAPI.Framework.Logging public LogManager(string logPath, ColorSchemeConfig colorConfig, bool writeToConsole, bool isVerbose, bool isDeveloperMode, Func getScreenIdForLog) { // init construction logic + this.ShowTraceInConsole = isDeveloperMode; this.GetMonitorImpl = name => new Monitor(name, this.IgnoreChar, this.LogFile, colorConfig, isVerbose, getScreenIdForLog) { WriteToConsole = writeToConsole, - ShowTraceInConsole = isDeveloperMode, + ShowTraceInConsole = this.ShowTraceInConsole, ShowFullStampInConsole = isDeveloperMode }; @@ -104,10 +111,10 @@ namespace StardewModdingAPI.Framework.Logging this.MonitorForGame = this.GetMonitor("game"); // redirect direct console output - var output = new InterceptingTextWriter(Console.Out, this.IgnoreChar); + this.ConsoleInterceptor = new InterceptingTextWriter(Console.Out, this.IgnoreChar); if (writeToConsole) - output.OnMessageIntercepted += message => this.HandleConsoleMessage(this.MonitorForGame, message); - Console.SetOut(output); + this.ConsoleInterceptor.OnMessageIntercepted += message => this.HandleConsoleMessage(this.MonitorForGame, message); + Console.SetOut(this.ConsoleInterceptor); // enable Unicode handling on Windows // (the terminal defaults to UTF-8 on Linux/macOS) @@ -363,7 +370,10 @@ namespace StardewModdingAPI.Framework.Logging // ignore suppressed message if (level != LogLevel.Error && this.SuppressConsolePatterns.Any(p => p.IsMatch(message))) + { + this.ConsoleInterceptor.IgnoreNextIfNewline = true; return; + } // show friendly error if applicable foreach (ReplaceLogPattern entry in this.ReplaceConsolePatterns) @@ -383,6 +393,8 @@ namespace StardewModdingAPI.Framework.Logging // forward to monitor gameMonitor.Log(message, level); + if (level == LogLevel.Trace && !this.ShowTraceInConsole) + this.ConsoleInterceptor.IgnoreNextIfNewline = true; } /// Write a summary of mod warnings to the console and log. -- cgit From 8ebb9ce8d4c554b077e1e6286531c101d64c019d Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 15 Jan 2022 13:27:23 -0500 Subject: fix backspaces ignored on Linux/macOS in SDV 1.5.5+ --- docs/release-notes.md | 5 +++-- src/SMAPI/Framework/Logging/InterceptingTextWriter.cs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index 735c7c12..06d75b15 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -3,12 +3,13 @@ # Release notes ## Upcoming release * For players: - * SMAPI now auto-fixes maps loaded without a required tilesheet to prevent errors. + * Added auto-fix for custom maps which don't have a required tilesheet. * Added the new game build number to the SMAPI console + log. * Fixed extra newlines shown in the console in non-developer mode. + * Fixed macOS launch issue when using some terminals (thanks to bruce2409!). + * Fixed Linux/macOS terminal ignoring backspace in Stardew Valley 1.5.5+. * Fixed outdated instructions in Steam error message. * Fixed uninstaller not removing `StardewModdingAPI.deps.json` file. - * Fixed launch issue on macOS when using some terminals (thanks to bruce2409!). * Simplified [running without a terminal on Linux/macOS](https://stardewvalleywiki.com/Modding:Player_Guide/Troubleshooting#SMAPI_doesn.27t_recognize_controller_.28Steam_only.29) when needed. * Updated compatibility list. * Improved translations. Thanks to ChulkyBow (added Ukrainian)! diff --git a/src/SMAPI/Framework/Logging/InterceptingTextWriter.cs b/src/SMAPI/Framework/Logging/InterceptingTextWriter.cs index 41a3abcb..36f81d22 100644 --- a/src/SMAPI/Framework/Logging/InterceptingTextWriter.cs +++ b/src/SMAPI/Framework/Logging/InterceptingTextWriter.cs @@ -51,7 +51,7 @@ namespace StardewModdingAPI.Framework.Logging if (buffer.Length == 0) this.Out.Write(buffer, index, count); - else if (buffer[0] == this.IgnoreChar) + else if (buffer[0] == this.IgnoreChar || char.IsControl(buffer[0])) // ignore control characters like backspace this.Out.Write(buffer, index + 1, count - 1); else if (this.IsEmptyOrNewline(buffer)) { -- cgit From 4cffd6c2c092b18940f2dd1041e418f60573a87e Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 15 Jan 2022 17:21:11 -0500 Subject: add save recovery for missing custom farm type --- docs/release-notes.md | 3 ++- .../Patches/SaveGamePatcher.cs | 30 ++++++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index 06d75b15..aea4dbab 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -3,7 +3,8 @@ # Release notes ## Upcoming release * For players: - * Added auto-fix for custom maps which don't have a required tilesheet. + * Added automatic fix for custom maps which don't have a required tilesheet. + * Added automatic save recovery when the custom farm type isn't available anymore. * Added the new game build number to the SMAPI console + log. * Fixed extra newlines shown in the console in non-developer mode. * Fixed macOS launch issue when using some terminals (thanks to bruce2409!). diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/SaveGamePatcher.cs b/src/SMAPI.Mods.ErrorHandler/Patches/SaveGamePatcher.cs index 2a43cb10..0a7ed212 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/SaveGamePatcher.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/SaveGamePatcher.cs @@ -4,11 +4,11 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using HarmonyLib; using Microsoft.Xna.Framework.Content; +using StardewModdingAPI.Internal; using StardewModdingAPI.Internal.Patching; using StardewValley; using StardewValley.Buildings; using StardewValley.Locations; -using SObject = StardewValley.Object; namespace StardewModdingAPI.Mods.ErrorHandler.Patches { @@ -47,6 +47,11 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches original: this.RequireMethod(nameof(SaveGame.loadDataToLocations)), prefix: this.GetHarmonyMethod(nameof(SaveGamePatcher.Before_LoadDataToLocations)) ); + + harmony.Patch( + original: this.RequireMethod(nameof(SaveGame.LoadFarmType)), + finalizer: this.GetHarmonyMethod(nameof(SaveGamePatcher.Finalize_LoadFarmType)) + ); } @@ -58,14 +63,35 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches /// Returns whether to execute the original method. private static bool Before_LoadDataToLocations(List gamelocations) { + // missing locations/NPCs IDictionary npcs = Game1.content.Load>("Data\\NPCDispositions"); - if (SaveGamePatcher.RemoveBrokenContent(gamelocations, npcs)) SaveGamePatcher.OnContentRemoved(); return true; } + /// The method to call after throws an exception. + /// The exception thrown by the wrapped method, if any. + /// Returns the exception to throw, if any. + private static Exception Finalize_LoadFarmType(Exception __exception) + { + // missing custom farm type + if (__exception?.Message?.Contains("not a valid farm type") == true && !int.TryParse(SaveGame.loaded.whichFarm, out _)) + { + SaveGamePatcher.Monitor.Log(__exception.GetLogSummary(), LogLevel.Error); + SaveGamePatcher.Monitor.Log($"Removed invalid custom farm type '{SaveGame.loaded.whichFarm}' to avoid a crash when loading save '{Constants.SaveFolderName}'. (Did you remove a custom farm type mod?)", LogLevel.Warn); + + SaveGame.loaded.whichFarm = Farm.default_layout.ToString(); + SaveGame.LoadFarmType(); + SaveGamePatcher.OnContentRemoved(); + + __exception = null; + } + + return __exception; + } + /// Remove content which no longer exists in the game data. /// The current game locations. /// The NPC data. -- cgit From d029dd652fcb7390d756d92803da2dbc91f8b0de Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 15 Jan 2022 18:04:33 -0500 Subject: fix JSON validator not recognizing manifest update subkeys --- docs/release-notes.md | 1 + src/SMAPI.Web/wwwroot/schemas/manifest.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index aea4dbab..3be90208 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -18,6 +18,7 @@ * For the web UI: * Added log download option. * Fixed log parser not correctly handling multiple mods having the exact same name. + * Fixed JSON validator not recognizing manifest [update subkeys](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Update_checks#Update_subkeys). ## 3.13.2 Released 05 December 2021 for Stardew Valley 1.5.5 or later. diff --git a/src/SMAPI.Web/wwwroot/schemas/manifest.json b/src/SMAPI.Web/wwwroot/schemas/manifest.json index 05698ba2..b6722347 100644 --- a/src/SMAPI.Web/wwwroot/schemas/manifest.json +++ b/src/SMAPI.Web/wwwroot/schemas/manifest.json @@ -103,7 +103,7 @@ "type": "array", "items": { "type": "string", - "pattern": "^(?i)(Chucklefish:\\d+|Nexus:\\d+|GitHub:[A-Za-z0-9_\\-]+/[A-Za-z0-9_\\-]+|ModDrop:\\d+)$", + "pattern": "^(?i)(Chucklefish:\\d+|Nexus:\\d+|GitHub:[A-Za-z0-9_\\-]+/[A-Za-z0-9_\\-]+|ModDrop:\\d+)(?: *@ *[a-zA-Z0-9_]+ *)$", "@errorMessages": { "pattern": "Invalid update key; see https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Manifest#Update_checks for more info." } -- cgit From 6f05580191e27bdf876d75a967a3238947d5a091 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 15 Jan 2022 20:39:32 -0500 Subject: add detection for Xbox app game folders --- build/find-game-folder.targets | 22 +++++++++++++++++++--- docs/release-notes.md | 1 + docs/technical/mod-package.md | 3 +++ .../Framework/GameScanning/GameScanner.cs | 11 ++++++++++- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/build/find-game-folder.targets b/build/find-game-folder.targets index 3164b071..ba7cb26c 100644 --- a/build/find-game-folder.targets +++ b/build/find-game-folder.targets @@ -28,15 +28,31 @@ <_SteamLibraryPath>$([MSBuild]::GetRegistryValueFromView('HKEY_CURRENT_USER\SOFTWARE\Valve\Steam', 'SteamPath', null, RegistryView.Registry32)) $(_SteamLibraryPath)\steamapps\common\Stardew Valley - + C:\Program Files\GalaxyClient\Games\Stardew Valley C:\Program Files\GOG Galaxy\Games\Stardew Valley C:\Program Files\GOG Games\Stardew Valley - C:\Program Files\Steam\steamapps\common\Stardew Valley - C:\Program Files (x86)\GalaxyClient\Games\Stardew Valley C:\Program Files (x86)\GOG Galaxy\Games\Stardew Valley C:\Program Files (x86)\GOG Games\Stardew Valley + + +