From da22446964f4dba0047a29dee3efec7c00835048 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 23 May 2018 19:09:19 -0400 Subject: [PATCH] fix SaveBackup failing on Mac (#522) --- src/SMAPI.Mods.SaveBackup/ModEntry.cs | 82 +++++++++++++++---- .../StardewModdingAPI.Mods.SaveBackup.csproj | 2 - 2 files changed, 65 insertions(+), 19 deletions(-) diff --git a/src/SMAPI.Mods.SaveBackup/ModEntry.cs b/src/SMAPI.Mods.SaveBackup/ModEntry.cs index 37793ced..78578c3c 100644 --- a/src/SMAPI.Mods.SaveBackup/ModEntry.cs +++ b/src/SMAPI.Mods.SaveBackup/ModEntry.cs @@ -1,7 +1,9 @@ using System; +using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; +using System.Reflection; using StardewModdingAPI.Mods.SaveBackup.Framework; using StardewValley; @@ -50,11 +52,49 @@ namespace StardewModdingAPI.Mods.SaveBackup /// The folder containing save backups. private void CreateBackup(DirectoryInfo backupFolder) { - FileInfo file = new FileInfo(Path.Combine(backupFolder.FullName, this.FileName)); - if (!file.Exists) + try { - this.Monitor.Log($"Adding {file.Name}...", LogLevel.Trace); - ZipFile.CreateFromDirectory(Constants.SavesPath, file.FullName, CompressionLevel.Fastest, includeBaseDirectory: false); + // get target path + FileInfo targetFile = new FileInfo(Path.Combine(backupFolder.FullName, this.FileName)); + if (targetFile.Exists) + targetFile.Delete(); //return; + + // create zip + // due to limitations with the bundled Mono on Mac, we can't reference System.IO.Compression. + this.Monitor.Log($"Adding {targetFile.Name}...", LogLevel.Trace); + switch (Constants.TargetPlatform) + { + case GamePlatform.Linux: + case GamePlatform.Windows: + { + Assembly coreAssembly = Assembly.Load("System.IO.Compression, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") ?? throw new InvalidOperationException("Can't load System.IO.Compression assembly."); + Assembly fsAssembly = Assembly.Load("System.IO.Compression.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") ?? throw new InvalidOperationException("Can't load System.IO.Compression assembly."); + Type compressionLevelType = coreAssembly.GetType("System.IO.Compression.CompressionLevel") ?? throw new InvalidOperationException("Can't load CompressionLevel type."); + Type zipFileType = fsAssembly.GetType("System.IO.Compression.ZipFile") ?? throw new InvalidOperationException("Can't load ZipFile type."); + MethodInfo createMethod = zipFileType.GetMethod("CreateFromDirectory", new[] { typeof(string), typeof(string), compressionLevelType, typeof(bool) }) ?? throw new InvalidOperationException("Can't load ZipFile.CreateFromDirectory method."); + createMethod.Invoke(null, new object[] { Constants.SavesPath, targetFile.FullName, CompressionLevel.Fastest, false }); + } + break; + + case GamePlatform.Mac: + { + DirectoryInfo saveFolder = new DirectoryInfo(Constants.SavesPath); + ProcessStartInfo startInfo = new ProcessStartInfo + { + FileName = "zip", + Arguments = $"-rq \"{targetFile.FullName}\" \"{saveFolder.Name}\" -x \"*.DS_Store\" -x \"__MACOSX\"", + WorkingDirectory = $"{Constants.SavesPath}/../", + CreateNoWindow = true + }; + new Process { StartInfo = startInfo }.Start(); + } + break; + } + } + 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); } } @@ -63,23 +103,31 @@ namespace StardewModdingAPI.Mods.SaveBackup /// The number of backups to keep. private void PruneBackups(DirectoryInfo backupFolder, int backupsToKeep) { - var oldBackups = backupFolder - .GetFiles() - .OrderByDescending(p => p.CreationTimeUtc) - .Skip(backupsToKeep); - - foreach (FileInfo file in oldBackups) + try { - try + var oldBackups = backupFolder + .GetFiles() + .OrderByDescending(p => p.CreationTimeUtc) + .Skip(backupsToKeep); + + foreach (FileInfo file in oldBackups) { - this.Monitor.Log($"Deleting {file.Name}...", LogLevel.Trace); - file.Delete(); - } - catch (Exception ex) - { - this.Monitor.Log($"Error deleting old save backup '{file.Name}': {ex}"); + try + { + this.Monitor.Log($"Deleting {file.Name}...", LogLevel.Trace); + file.Delete(); + } + catch (Exception ex) + { + this.Monitor.Log($"Error deleting old save backup '{file.Name}': {ex}"); + } } } + 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); + } } } } diff --git a/src/SMAPI.Mods.SaveBackup/StardewModdingAPI.Mods.SaveBackup.csproj b/src/SMAPI.Mods.SaveBackup/StardewModdingAPI.Mods.SaveBackup.csproj index 89e92a8a..44fff536 100644 --- a/src/SMAPI.Mods.SaveBackup/StardewModdingAPI.Mods.SaveBackup.csproj +++ b/src/SMAPI.Mods.SaveBackup/StardewModdingAPI.Mods.SaveBackup.csproj @@ -31,8 +31,6 @@ - -