From 801eaa70871a9ca86dab8022abfd87d558fa1db3 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Mon, 10 Feb 2020 19:14:06 -0500 Subject: improve save backup logic --- src/SMAPI.Mods.SaveBackup/ModEntry.cs | 46 ++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 17 deletions(-) (limited to 'src/SMAPI.Mods.SaveBackup') diff --git a/src/SMAPI.Mods.SaveBackup/ModEntry.cs b/src/SMAPI.Mods.SaveBackup/ModEntry.cs index 8b139d8f..b8d3be1c 100644 --- a/src/SMAPI.Mods.SaveBackup/ModEntry.cs +++ b/src/SMAPI.Mods.SaveBackup/ModEntry.cs @@ -66,29 +66,37 @@ namespace StardewModdingAPI.Mods.SaveBackup FileInfo targetFile = new FileInfo(Path.Combine(backupFolder.FullName, this.FileName)); DirectoryInfo fallbackDir = new DirectoryInfo(Path.Combine(backupFolder.FullName, this.BackupLabel)); if (targetFile.Exists || fallbackDir.Exists) + { + this.Monitor.Log("Already backed up today."); return; + } // copy saves to fallback directory (ignore non-save files/folders) - this.Monitor.Log($"Backing up saves to {fallbackDir.FullName}...", LogLevel.Trace); DirectoryInfo savesDir = new DirectoryInfo(Constants.SavesPath); - this.RecursiveCopy(savesDir, fallbackDir, entry => this.MatchSaveFolders(savesDir, entry), copyRoot: false); + if (!this.RecursiveCopy(savesDir, fallbackDir, entry => this.MatchSaveFolders(savesDir, entry), copyRoot: false)) + { + this.Monitor.Log("No saves found."); + return; + } // compress backup if possible - this.Monitor.Log("Compressing backup if possible...", LogLevel.Trace); if (!this.TryCompress(fallbackDir.FullName, targetFile, out Exception compressError)) { - if (Constants.TargetPlatform != GamePlatform.Android) // expected to fail on Android - this.Monitor.Log($"Couldn't compress backup, leaving it uncompressed.\n{compressError}", LogLevel.Trace); + this.Monitor.Log(Constants.TargetPlatform != GamePlatform.Android + ? $"Backed up to {fallbackDir.FullName}." // expected to fail on Android + : $"Backed up to {fallbackDir.FullName}. Couldn't compress backup:\n{compressError}" + ); } else + { + this.Monitor.Log($"Backed up to {targetFile.FullName}."); fallbackDir.Delete(recursive: true); - - this.Monitor.Log("Backup done!", LogLevel.Trace); + } } catch (Exception ex) { - this.Monitor.Log("Couldn't back up save files (see log file for details).", LogLevel.Warn); - this.Monitor.Log(ex.ToString(), LogLevel.Trace); + this.Monitor.Log("Couldn't back up saves (see log file for details).", LogLevel.Warn); + this.Monitor.Log(ex.ToString()); } } @@ -108,7 +116,7 @@ namespace StardewModdingAPI.Mods.SaveBackup { try { - this.Monitor.Log($"Deleting {entry.Name}...", LogLevel.Trace); + this.Monitor.Log($"Deleting {entry.Name}..."); if (entry is DirectoryInfo folder) folder.Delete(recursive: true); else @@ -123,7 +131,7 @@ namespace StardewModdingAPI.Mods.SaveBackup catch (Exception ex) { this.Monitor.Log("Couldn't remove old backups (see log file for details).", LogLevel.Warn); - this.Monitor.Log(ex.ToString(), LogLevel.Trace); + this.Monitor.Log(ex.ToString()); } } @@ -199,29 +207,33 @@ namespace StardewModdingAPI.Mods.SaveBackup /// Whether to copy the root folder itself, or false to only copy its contents. /// A filter which matches the files or directories to copy, or null to copy everything. /// Derived from the SMAPI installer code. - private void RecursiveCopy(FileSystemInfo source, DirectoryInfo targetFolder, Func filter, bool copyRoot = true) + /// Returns whether any files were copied. + private bool RecursiveCopy(FileSystemInfo source, DirectoryInfo targetFolder, Func filter, bool copyRoot = true) { - if (!targetFolder.Exists) - targetFolder.Create(); + if (!source.Exists || filter?.Invoke(source) == false) + return false; - if (filter?.Invoke(source) == false) - return; + bool anyCopied = false; switch (source) { case FileInfo sourceFile: + targetFolder.Create(); sourceFile.CopyTo(Path.Combine(targetFolder.FullName, sourceFile.Name)); + anyCopied = true; break; case DirectoryInfo sourceDir: DirectoryInfo targetSubfolder = copyRoot ? new DirectoryInfo(Path.Combine(targetFolder.FullName, sourceDir.Name)) : targetFolder; foreach (var entry in sourceDir.EnumerateFileSystemInfos()) - this.RecursiveCopy(entry, targetSubfolder, filter); + anyCopied = this.RecursiveCopy(entry, targetSubfolder, filter) || anyCopied; break; default: throw new NotSupportedException($"Unknown filesystem info type '{source.GetType().FullName}'."); } + + return anyCopied; } /// A copy filter which matches save folders. -- cgit From 585b23797e262073e0738069eff61e90819216b7 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 22 Feb 2020 12:03:09 -0500 Subject: prepare for release --- build/common.targets | 2 +- docs/release-notes.md | 11 +++++++---- src/SMAPI.Mods.ConsoleCommands/manifest.json | 4 ++-- src/SMAPI.Mods.SaveBackup/manifest.json | 4 ++-- src/SMAPI/Constants.cs | 2 +- 5 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src/SMAPI.Mods.SaveBackup') diff --git a/build/common.targets b/build/common.targets index 8b0d1301..626eeef6 100644 --- a/build/common.targets +++ b/build/common.targets @@ -4,7 +4,7 @@ - 3.2.0 + 3.3.0 SMAPI $(AssemblySearchPaths);{GAC} diff --git a/docs/release-notes.md b/docs/release-notes.md index 05bb2c60..26515b61 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -1,9 +1,11 @@ ← [README](README.md) # Release notes -## Upcoming release +## 3.3 +Released 22 February 2020 for Stardew Valley 1.4.1 or later. + * For players: - * Improved performance for mods which load a large number of images. + * Improved performance for mods which load many images. * Reduced network traffic for mod broadcasts to players who can't process them. * Fixed update-check errors for recent versions of SMAPI on Android. * Updated draw logic to match recent game updates. @@ -19,17 +21,18 @@ * Added support for [message sending](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Integrations#Message_sending) to mods on the current computer (in addition to remote computers). * Added `ExtendImage` method to content API when editing files to resize textures. * Added `helper.Input.GetState` to get the low-level state of a button. - * **[Breaking change]** Map tilesheets are no loaded from `Content` if they can't be found in `Content/Maps`. This reflects an upcoming change in the game to delete map tilesheets under `Content`. + * **[Breaking change]** Map tilesheets are no loaded from `Content` if they can't be found in `Content/Maps`. This reflects an upcoming change in the game to delete duplicate map tilesheets under `Content`. Most mods should be unaffected. * Improved map tilesheet errors so they provide more info. + * When mods load an asset using a more general type like `content.Load`, SMAPI now calls `IAssetEditor` instances with the actual asset type instead of the specified one. * Updated dependencies (including Mono.Cecil 0.11.1 → 0.11.2). * Fixed dialogue propagation clearing marriage dialogue. - * Fixed issue where SMAPI didn't call `IAssetEditor` with the actual type if a mod loaded an asset using `content.Load`. * For the web UI: * Updated the JSON validator and Content Patcher schema for `.tmx` support. * The mod compatibility page now has a sticky table header. * For SMAPI/tool developers: + * Improved support for four-part versions to support SMAPI on Android. * The SMAPI log now prefixes the OS name with `Android` on Android. ## 3.2 diff --git a/src/SMAPI.Mods.ConsoleCommands/manifest.json b/src/SMAPI.Mods.ConsoleCommands/manifest.json index 0d0e4901..971c591a 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.2.0", + "Version": "3.3.0", "Description": "Adds SMAPI console commands that let you manipulate the game.", "UniqueID": "SMAPI.ConsoleCommands", "EntryDll": "ConsoleCommands.dll", - "MinimumApiVersion": "3.2.0" + "MinimumApiVersion": "3.3.0" } diff --git a/src/SMAPI.Mods.SaveBackup/manifest.json b/src/SMAPI.Mods.SaveBackup/manifest.json index 74256013..4559d1b0 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.2.0", + "Version": "3.3.0", "Description": "Automatically backs up all your saves once per day into its folder.", "UniqueID": "SMAPI.SaveBackup", "EntryDll": "SaveBackup.dll", - "MinimumApiVersion": "3.2.0" + "MinimumApiVersion": "3.3.0" } diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index 443ca7a6..670dc494 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -20,7 +20,7 @@ namespace StardewModdingAPI ** Public ****/ /// SMAPI's current semantic version. - public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("3.2.0"); + public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("3.3.0"); /// The minimum supported version of Stardew Valley. public static ISemanticVersion MinimumGameVersion { get; } = new GameVersion("1.4.1"); -- cgit