From 4df8f4a656ce68b5bb7dc76eefd6da9c27620928 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 11 Jun 2021 19:14:59 -0400 Subject: [PATCH] fix edge case where save constants aren't set correctly --- docs/release-notes.md | 3 ++- src/SMAPI/Constants.cs | 47 ++++++++++++++++++++++++++---------------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index 7ac1b518..0879a072 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -11,6 +11,7 @@ * For players: * Fixed error when running the Windows installer as administrator (thanks to LostLogic!). * Fixed `player_add` and `list_items` console commands not including some shirts _(in Console Commands)_. + * Fixed installer error on some older Windows systems (thanks to eddyballs!). * For mod authors: * Added `World.FurnitureListChanged` event (thanks to DiscipleOfEris!). @@ -20,7 +21,7 @@ * Fixed JSON schema for `i18n` files requiring the wrong value for the `$schema` field. * Fixed validation for mods with version `0.0.0`. * Fixed _loaded with custom settings_ trace log when using default settings. - * Fixed installer error on some older Windows systems (thanks to eddyballs!). + * Fixed `Constants.SaveFolderName` and `Constants.CurrentSavePath` not set correctly in rare cases. * For the web UI: * Updated the JSON validator/schema for Content Patcher 1.23. diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index 2e476208..38e8c500 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -322,31 +322,42 @@ namespace StardewModdingAPI /// Get the name of the save folder, if any. private static string GetSaveFolderName() { - // save not available - if (Context.LoadStage == LoadStage.None) - return null; - - // get basic info - string saveName = Game1.GetSaveGameName(set_value: false); - ulong saveID = Context.LoadStage == LoadStage.SaveParsed - ? SaveGame.loaded.uniqueIDForThisGame - : Game1.uniqueIDForThisGame; - - // build folder name - return $"{new string(saveName.Where(char.IsLetterOrDigit).ToArray())}_{saveID}"; + return Constants.GetSaveFolder()?.Name; } /// Get the path to the current save folder, if any. private static string GetSaveFolderPathIfExists() { - string folderName = Constants.GetSaveFolderName(); - if (folderName == null) + DirectoryInfo saveFolder = Constants.GetSaveFolder(); + return saveFolder?.Exists == true + ? saveFolder.FullName + : null; + } + + /// Get the current save folder, if any. + private static DirectoryInfo GetSaveFolder() + { + // save not available + if (Context.LoadStage == LoadStage.None) return null; - string path = Path.Combine(Constants.SavesPath, folderName); - return Directory.Exists(path) - ? path - : null; + // get basic info + string rawSaveName = Game1.GetSaveGameName(set_value: false); + ulong saveID = Context.LoadStage == LoadStage.SaveParsed + ? SaveGame.loaded.uniqueIDForThisGame + : Game1.uniqueIDForThisGame; + + // get best match (accounting for rare case where folder name isn't sanitized) + DirectoryInfo folder = null; + foreach (string saveName in new[] { rawSaveName, new string(rawSaveName.Where(char.IsLetterOrDigit).ToArray()) }) + { + folder = new DirectoryInfo(Path.Combine(Constants.SavesPath, $"{saveName}_{saveID}")); + if (folder.Exists) + return folder; + } + + // if save doesn't exist yet, return the default one we expect to be created + return folder; } } }