Extended export capabilities

This commit is contained in:
Ottermandias 2022-10-05 12:31:08 +02:00
parent 097923f5ff
commit 31ac6187bc
6 changed files with 147 additions and 20 deletions

View file

@ -26,6 +26,7 @@ public partial class Configuration : IPluginConfiguration
public bool EnableMods { get; set; } = true;
public string ModDirectory { get; set; } = string.Empty;
public string ExportDirectory { get; set; } = string.Empty;
public bool HideUiInGPose { get; set; } = false;
public bool HideUiInCutscenes { get; set; } = true;

View file

@ -17,12 +17,12 @@ public class ModBackup
public ModBackup( Mod mod )
{
_mod = mod;
Name = _mod.ModPath + ".pmp";
Name = Path.Combine( Penumbra.ModManager.ExportDirectory.FullName, _mod.ModPath.Name ) + ".pmp";
Exists = File.Exists( Name );
}
// Migrate file extensions.
public static void MigrateZipToPmp(Mod.Manager manager)
public static void MigrateZipToPmp( Mod.Manager manager )
{
foreach( var mod in manager )
{
@ -40,16 +40,39 @@ public class ModBackup
{
File.Delete( zipName );
}
Penumbra.Log.Information( $"Migrated mod backup from {zipName} to {pmpName}." );
Penumbra.Log.Information( $"Migrated mod export from {zipName} to {pmpName}." );
}
catch( Exception e )
{
Penumbra.Log.Warning( $"Could not migrate mod backup of {mod.ModPath} from .pmp to .zip:\n{e}" );
Penumbra.Log.Warning( $"Could not migrate mod export of {mod.ModPath} from .pmp to .zip:\n{e}" );
}
}
}
}
// Move and/or rename an exported mod.
// This object is unusable afterwards.
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}" );
}
}
// Create a backup zip without blocking the main thread.
public async void CreateAsync()
{
@ -71,11 +94,11 @@ public class ModBackup
{
Delete();
ZipFile.CreateFromDirectory( _mod.ModPath.FullName, Name, CompressionLevel.Optimal, false );
Penumbra.Log.Debug( $"Created backup file {Name} from {_mod.ModPath.FullName}.");
Penumbra.Log.Debug( $"Created export file {Name} from {_mod.ModPath.FullName}." );
}
catch( Exception e )
{
Penumbra.Log.Error( $"Could not backup mod {_mod.Name} to \"{Name}\":\n{e}" );
Penumbra.Log.Error( $"Could not export mod {_mod.Name} to \"{Name}\":\n{e}" );
}
}
@ -90,7 +113,7 @@ public class ModBackup
try
{
File.Delete( Name );
Penumbra.Log.Debug( $"Deleted backup file {Name}." );
Penumbra.Log.Debug( $"Deleted export file {Name}." );
}
catch( Exception e )
{
@ -111,12 +134,12 @@ public class ModBackup
}
ZipFile.ExtractToDirectory( Name, _mod.ModPath.FullName );
Penumbra.Log.Debug( $"Extracted backup file {Name} to {_mod.ModPath.FullName}.");
Penumbra.Log.Debug( $"Extracted exported file {Name} to {_mod.ModPath.FullName}." );
Penumbra.ModManager.ReloadMod( _mod.Index );
}
catch( Exception e )
{
Penumbra.Log.Error( $"Could not restore {_mod.Name} from backup \"{Name}\":\n{e}" );
Penumbra.Log.Error( $"Could not restore {_mod.Name} from export \"{Name}\":\n{e}" );
}
}
}

View file

@ -58,6 +58,8 @@ public partial class Mod
return;
}
new ModBackup( mod ).Move( null, dir.Name );
dir.Refresh();
mod.ModPath = dir;
if( !mod.Reload( false, out var metaChange ) )
@ -109,7 +111,7 @@ public partial class Mod
try
{
Directory.Delete( mod.ModPath.FullName, true );
Penumbra.Log.Debug( $"Deleted directory {mod.ModPath.FullName} for {mod.Name}.");
Penumbra.Log.Debug( $"Deleted directory {mod.ModPath.FullName} for {mod.Name}." );
}
catch( Exception e )
{

View file

@ -1,3 +1,4 @@
using ImGuizmoNET;
using System;
using System.IO;
@ -8,6 +9,11 @@ public sealed partial class Mod
public sealed partial class Manager
{
public DirectoryInfo BasePath { get; private set; } = null!;
private DirectoryInfo? _exportDirectory;
public DirectoryInfo ExportDirectory
=> _exportDirectory ?? BasePath;
public bool Valid { get; private set; }
public event Action? ModDiscoveryStarted;
@ -103,5 +109,49 @@ public sealed partial class Mod
ModBackup.MigrateZipToPmp( this );
}
}
public void UpdateExportDirectory( string newDirectory )
{
if( newDirectory.Length == 0 )
{
if( _exportDirectory == null )
{
return;
}
_exportDirectory = null;
Penumbra.Config.ExportDirectory = string.Empty;
Penumbra.Config.Save();
return;
}
var dir = new DirectoryInfo( newDirectory );
if( dir.FullName.Equals( _exportDirectory?.FullName, StringComparison.OrdinalIgnoreCase ) )
{
return;
}
if( !dir.Exists )
{
try
{
Directory.CreateDirectory( dir.FullName );
}
catch( Exception e )
{
Penumbra.Log.Error( $"Could not create Export Directory:\n{e}" );
return;
}
}
foreach( var mod in _mods )
{
new ModBackup( mod ).Move( dir.FullName );
}
_exportDirectory = dir;
Penumbra.Config.ExportDirectory = dir.FullName;
Penumbra.Config.Save();
}
}
}

View file

@ -119,29 +119,29 @@ public partial class ConfigWindow
{
var backup = new ModBackup( _mod );
var tt = ModBackup.CreatingBackup
? "Already creating a backup."
? "Already exporting a mod."
: 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 ) )
? $"Overwrite current exported mod \"{backup.Name}\" with current mod."
: $"Create exported archive of current mod at \"{backup.Name}\".";
if( ImGuiUtil.DrawDisabledButton( "Export Mod", 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 ) )
? $"Delete existing mod export \"{backup.Name}\"."
: $"Exported mod \"{backup.Name}\" does not exist.";
if( ImGuiUtil.DrawDisabledButton( "Delete Export", buttonSize, tt, !backup.Exists ) )
{
backup.Delete();
}
tt = backup.Exists
? $"Restore mod from backup file \"{backup.Name}\"."
: $"Backup file \"{backup.Name}\" does not exist.";
? $"Restore mod from exported file \"{backup.Name}\"."
: $"Exported mod \"{backup.Name}\" does not exist.";
ImGui.SameLine();
if( ImGuiUtil.DrawDisabledButton( "Restore From Backup", buttonSize, tt, !backup.Exists ) )
if( ImGuiUtil.DrawDisabledButton( "Restore From Export", buttonSize, tt, !backup.Exists ) )
{
backup.Restore();
}

View file

@ -111,6 +111,7 @@ public partial class ConfigWindow
DrawDefaultModImportPath();
DrawDefaultModAuthor();
DrawDefaultModImportFolder();
DrawDefaultModExportPath();
ImGui.NewLine();
}
@ -228,6 +229,56 @@ public partial class ConfigWindow
"Set the directory that gets opened when using the file picker to import mods for the first time." );
}
private string _tempExportDirectory = string.Empty;
private void DrawDefaultModExportPath()
{
var tmp = Penumbra.Config.ExportDirectory;
var spacing = new Vector2( 3 * ImGuiHelpers.GlobalScale );
using var style = ImRaii.PushStyle( ImGuiStyleVar.ItemSpacing, spacing );
ImGui.SetNextItemWidth( _window._inputTextWidth.X - _window._iconButtonSize.X - spacing.X );
if( ImGui.InputText( "##defaultModExport", ref tmp, 256 ) )
{
_tempExportDirectory = tmp;
}
if( ImGui.IsItemDeactivatedAfterEdit() )
{
Penumbra.ModManager.UpdateExportDirectory( _tempExportDirectory );
}
ImGui.SameLine();
if( ImGuiUtil.DrawDisabledButton( $"{FontAwesomeIcon.Folder.ToIconString()}##export", _window._iconButtonSize,
"Select a directory via dialog.", false, true ) )
{
if( _dialogOpen )
{
_dialogManager.Reset();
_dialogOpen = false;
}
else
{
var startDir = Penumbra.Config.ExportDirectory.Length > 0 && Directory.Exists( Penumbra.Config.ExportDirectory )
? Penumbra.Config.ExportDirectory
: Directory.Exists( Penumbra.Config.ModDirectory )
? Penumbra.Config.ModDirectory
: ".";
_dialogManager.OpenFolderDialog( "Choose Default Export Directory", ( b, s ) =>
{
Penumbra.ModManager.UpdateExportDirectory( b ? s : Penumbra.Config.ExportDirectory );
_dialogOpen = false;
}, startDir );
_dialogOpen = true;
}
}
style.Pop();
ImGuiUtil.LabeledHelpMarker( "Default Mod Export Directory",
"Set the directory mods get saved to when using the export function or loaded from when reimporting backups.\n"
+ "Keep this empty to use the root directory." );
}
private void DrawDefaultModAuthor()
{
var tmp = Penumbra.Config.DefaultModAuthor;