Add zip backup options to mods.

This commit is contained in:
Ottermandias 2022-05-12 16:49:49 +02:00
parent f3d4ffc40a
commit b8210e094b
2 changed files with 128 additions and 2 deletions

View file

@ -0,0 +1,94 @@
using System;
using System.IO;
using System.IO.Compression;
using System.Threading.Tasks;
using Dalamud.Logging;
namespace Penumbra.Mods;
// Utility to create and apply a zipped backup of a mod.
public class ModBackup
{
public static bool CreatingBackup { get; private set; }
private readonly Mod _mod;
public readonly string Name;
public readonly bool Exists;
public ModBackup( Mod mod )
{
_mod = mod;
Name = mod.ModPath + ".zip";
Exists = File.Exists( Name );
}
// Create a backup zip without blocking the main thread.
public async void CreateAsync()
{
if( CreatingBackup )
{
return;
}
CreatingBackup = true;
await Task.Run( Create );
CreatingBackup = false;
}
// Create a backup. Overwrites pre-existing backups.
private void Create()
{
try
{
Delete();
ZipFile.CreateFromDirectory( _mod.ModPath.FullName, Name, CompressionLevel.Optimal, false );
PluginLog.Debug( "Created backup file {backupName} from {modDirectory}.", Name, _mod.ModPath.FullName );
}
catch( Exception e )
{
PluginLog.Error( $"Could not backup mod {_mod.Name} to \"{Name}\":\n{e}" );
}
}
// Delete a pre-existing backup.
public void Delete()
{
if( !Exists )
{
return;
}
try
{
File.Delete( Name );
PluginLog.Debug( "Deleted backup file {backupName}.", Name );
}
catch( Exception e )
{
PluginLog.Error( $"Could not delete file \"{Name}\":\n{e}" );
}
}
// Restore a mod from a pre-existing backup. Does not check if the mod contained in the backup is even similar.
// Does an automatic reload after extraction.
public void Restore()
{
try
{
if( Directory.Exists( _mod.ModPath.FullName ) )
{
Directory.Delete( _mod.ModPath.FullName, true );
PluginLog.Debug( "Deleted mod folder {modFolder}.", _mod.ModPath.FullName );
}
ZipFile.ExtractToDirectory( Name, _mod.ModPath.FullName );
PluginLog.Debug( "Extracted backup file {backupName} to {modName}.", Name, _mod.ModPath.FullName );
Penumbra.ModManager.ReloadMod( _mod.Index );
}
catch( Exception e )
{
PluginLog.Error( $"Could not restore {_mod.Name} from backup \"{Name}\":\n{e}" );
}
}
}

View file

@ -6,7 +6,6 @@ using System.Numerics;
using Dalamud.Interface;
using Dalamud.Interface.Components;
using Dalamud.Logging;
using Dalamud.Memory;
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
@ -90,11 +89,44 @@ public partial class ConfigWindow
Penumbra.ModManager.ReloadMod( _mod.Index );
}
BackupButtons( buttonSize );
MoveDirectory.Draw( _mod, buttonSize );
ImGui.Dummy( _window._defaultSpace );
}
private void BackupButtons( Vector2 buttonSize )
{
var backup = new ModBackup( _mod );
var tt = ModBackup.CreatingBackup
? "Already creating a backup."
: backup.Exists
? $"Overwrite current backup \"{backup.Name}\" with current mod."
: $"Create backup archive of current mod at \"{backup.Name}\".";
if( ImGuiUtil.DrawDisabledButton( "Create Backup", buttonSize, tt, ModBackup.CreatingBackup ) )
{
backup.CreateAsync();
}
ImGui.SameLine();
tt = backup.Exists
? $"Delete existing backup file \"{backup.Name}\"."
: $"Backup file \"{backup.Name}\" does not exist.";
if( ImGuiUtil.DrawDisabledButton( "Delete Backup", buttonSize, tt, !backup.Exists ) )
{
backup.Delete();
}
tt = backup.Exists
? $"Restore mod from backup file \"{backup.Name}\"."
: $"Backup file \"{backup.Name}\" does not exist.";
ImGui.SameLine();
if( ImGuiUtil.DrawDisabledButton( "Restore From Backup", buttonSize, tt, !backup.Exists ) )
{
backup.Restore();
}
}
// Anything about editing the regular meta information about the mod.
private void EditRegularMeta()
{