mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-01-03 14:23:43 +01:00
139 lines
4.2 KiB
C#
139 lines
4.2 KiB
C#
using OtterGui.Tasks;
|
|
using Penumbra.Mods.Manager;
|
|
|
|
namespace Penumbra.Mods.Editor;
|
|
|
|
/// <summary> Utility to create and apply a zipped backup of a mod. </summary>
|
|
public class ModBackup
|
|
{
|
|
/// <summary> Set when reading Config and migrating from v4 to v5. </summary>
|
|
public static bool MigrateModBackups = false;
|
|
|
|
public static bool CreatingBackup { get; private set; }
|
|
|
|
private readonly Mod _mod;
|
|
public readonly string Name;
|
|
public readonly bool Exists;
|
|
|
|
public ModBackup(ModExportManager modExportManager, Mod mod)
|
|
{
|
|
_mod = mod;
|
|
Name = Path.Combine(modExportManager.ExportDirectory.FullName, _mod.ModPath.Name) + ".pmp";
|
|
Exists = File.Exists(Name);
|
|
}
|
|
|
|
/// <summary> Migrate file extensions. </summary>
|
|
public static void MigrateZipToPmp(IEnumerable<Mod> modStorage)
|
|
{
|
|
foreach (var mod in modStorage)
|
|
{
|
|
var pmpName = mod.ModPath + ".pmp";
|
|
var zipName = mod.ModPath + ".zip";
|
|
if (!File.Exists(zipName))
|
|
continue;
|
|
|
|
try
|
|
{
|
|
if (!File.Exists(pmpName))
|
|
File.Move(zipName, pmpName);
|
|
else
|
|
File.Delete(zipName);
|
|
|
|
Penumbra.Log.Information($"Migrated mod export from {zipName} to {pmpName}.");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Penumbra.Log.Warning($"Could not migrate mod export of {mod.ModPath} from .pmp to .zip:\n{e}");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Move and/or rename an exported mod.
|
|
/// This object is unusable afterwards.
|
|
/// </summary>
|
|
public void Move(string? newBasePath = null, string? newName = null)
|
|
{
|
|
if (CreatingBackup || !Exists)
|
|
return;
|
|
|
|
try
|
|
{
|
|
newBasePath ??= Path.GetDirectoryName(Name) ?? string.Empty;
|
|
newName = newName == null ? Path.GetFileName(Name) : newName + ".pmp";
|
|
var newPath = Path.Combine(newBasePath, newName);
|
|
File.Move(Name, newPath);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Penumbra.Log.Warning($"Could not move mod export file {Name}:\n{e}");
|
|
}
|
|
}
|
|
|
|
/// <summary> Create a backup zip without blocking the main thread. </summary>
|
|
public async void CreateAsync()
|
|
{
|
|
if (CreatingBackup)
|
|
return;
|
|
|
|
CreatingBackup = true;
|
|
await AsyncTask.Run(Create);
|
|
CreatingBackup = false;
|
|
}
|
|
|
|
/// <summary> Create a backup. Overwrites pre-existing backups. </summary>
|
|
private void Create()
|
|
{
|
|
try
|
|
{
|
|
Delete();
|
|
ZipFile.CreateFromDirectory(_mod.ModPath.FullName, Name, CompressionLevel.Optimal, false);
|
|
Penumbra.Log.Debug($"Created export file {Name} from {_mod.ModPath.FullName}.");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Penumbra.Log.Error($"Could not export mod {_mod.Name} to \"{Name}\":\n{e}");
|
|
}
|
|
}
|
|
|
|
/// <summary> Delete a pre-existing backup. </summary>
|
|
public void Delete()
|
|
{
|
|
if (!Exists)
|
|
return;
|
|
|
|
try
|
|
{
|
|
File.Delete(Name);
|
|
Penumbra.Log.Debug($"Deleted export file {Name}.");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Penumbra.Log.Error($"Could not delete file \"{Name}\":\n{e}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
public void Restore(ModManager modManager)
|
|
{
|
|
try
|
|
{
|
|
if (Directory.Exists(_mod.ModPath.FullName))
|
|
{
|
|
Directory.Delete(_mod.ModPath.FullName, true);
|
|
Penumbra.Log.Debug($"Deleted mod folder {_mod.ModPath.FullName}.");
|
|
}
|
|
|
|
ZipFile.ExtractToDirectory(Name, _mod.ModPath.FullName);
|
|
Penumbra.Log.Debug($"Extracted exported file {Name} to {_mod.ModPath.FullName}.");
|
|
modManager.ReloadMod(_mod);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Penumbra.Log.Error($"Could not restore {_mod.Name} from export \"{Name}\":\n{e}");
|
|
}
|
|
}
|
|
}
|