mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-20 07:34:25 +01:00
Extended export capabilities
This commit is contained in:
parent
097923f5ff
commit
31ac6187bc
6 changed files with 147 additions and 20 deletions
|
|
@ -26,6 +26,7 @@ public partial class Configuration : IPluginConfiguration
|
||||||
|
|
||||||
public bool EnableMods { get; set; } = true;
|
public bool EnableMods { get; set; } = true;
|
||||||
public string ModDirectory { get; set; } = string.Empty;
|
public string ModDirectory { get; set; } = string.Empty;
|
||||||
|
public string ExportDirectory { get; set; } = string.Empty;
|
||||||
|
|
||||||
public bool HideUiInGPose { get; set; } = false;
|
public bool HideUiInGPose { get; set; } = false;
|
||||||
public bool HideUiInCutscenes { get; set; } = true;
|
public bool HideUiInCutscenes { get; set; } = true;
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,12 @@ public class ModBackup
|
||||||
public ModBackup( Mod mod )
|
public ModBackup( Mod mod )
|
||||||
{
|
{
|
||||||
_mod = mod;
|
_mod = mod;
|
||||||
Name = _mod.ModPath + ".pmp";
|
Name = Path.Combine( Penumbra.ModManager.ExportDirectory.FullName, _mod.ModPath.Name ) + ".pmp";
|
||||||
Exists = File.Exists( Name );
|
Exists = File.Exists( Name );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate file extensions.
|
// Migrate file extensions.
|
||||||
public static void MigrateZipToPmp(Mod.Manager manager)
|
public static void MigrateZipToPmp( Mod.Manager manager )
|
||||||
{
|
{
|
||||||
foreach( var mod in manager )
|
foreach( var mod in manager )
|
||||||
{
|
{
|
||||||
|
|
@ -40,16 +40,39 @@ public class ModBackup
|
||||||
{
|
{
|
||||||
File.Delete( zipName );
|
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 )
|
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.
|
// Create a backup zip without blocking the main thread.
|
||||||
public async void CreateAsync()
|
public async void CreateAsync()
|
||||||
{
|
{
|
||||||
|
|
@ -71,11 +94,11 @@ public class ModBackup
|
||||||
{
|
{
|
||||||
Delete();
|
Delete();
|
||||||
ZipFile.CreateFromDirectory( _mod.ModPath.FullName, Name, CompressionLevel.Optimal, false );
|
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 )
|
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
|
try
|
||||||
{
|
{
|
||||||
File.Delete( Name );
|
File.Delete( Name );
|
||||||
Penumbra.Log.Debug( $"Deleted backup file {Name}." );
|
Penumbra.Log.Debug( $"Deleted export file {Name}." );
|
||||||
}
|
}
|
||||||
catch( Exception e )
|
catch( Exception e )
|
||||||
{
|
{
|
||||||
|
|
@ -111,12 +134,12 @@ public class ModBackup
|
||||||
}
|
}
|
||||||
|
|
||||||
ZipFile.ExtractToDirectory( Name, _mod.ModPath.FullName );
|
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 );
|
Penumbra.ModManager.ReloadMod( _mod.Index );
|
||||||
}
|
}
|
||||||
catch( Exception e )
|
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}" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -58,6 +58,8 @@ public partial class Mod
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new ModBackup( mod ).Move( null, dir.Name );
|
||||||
|
|
||||||
dir.Refresh();
|
dir.Refresh();
|
||||||
mod.ModPath = dir;
|
mod.ModPath = dir;
|
||||||
if( !mod.Reload( false, out var metaChange ) )
|
if( !mod.Reload( false, out var metaChange ) )
|
||||||
|
|
@ -109,7 +111,7 @@ public partial class Mod
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Directory.Delete( mod.ModPath.FullName, true );
|
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 )
|
catch( Exception e )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using ImGuizmoNET;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
|
|
@ -8,6 +9,11 @@ public sealed partial class Mod
|
||||||
public sealed partial class Manager
|
public sealed partial class Manager
|
||||||
{
|
{
|
||||||
public DirectoryInfo BasePath { get; private set; } = null!;
|
public DirectoryInfo BasePath { get; private set; } = null!;
|
||||||
|
private DirectoryInfo? _exportDirectory;
|
||||||
|
|
||||||
|
public DirectoryInfo ExportDirectory
|
||||||
|
=> _exportDirectory ?? BasePath;
|
||||||
|
|
||||||
public bool Valid { get; private set; }
|
public bool Valid { get; private set; }
|
||||||
|
|
||||||
public event Action? ModDiscoveryStarted;
|
public event Action? ModDiscoveryStarted;
|
||||||
|
|
@ -103,5 +109,49 @@ public sealed partial class Mod
|
||||||
ModBackup.MigrateZipToPmp( this );
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -119,29 +119,29 @@ public partial class ConfigWindow
|
||||||
{
|
{
|
||||||
var backup = new ModBackup( _mod );
|
var backup = new ModBackup( _mod );
|
||||||
var tt = ModBackup.CreatingBackup
|
var tt = ModBackup.CreatingBackup
|
||||||
? "Already creating a backup."
|
? "Already exporting a mod."
|
||||||
: backup.Exists
|
: backup.Exists
|
||||||
? $"Overwrite current backup \"{backup.Name}\" with current mod."
|
? $"Overwrite current exported mod \"{backup.Name}\" with current mod."
|
||||||
: $"Create backup archive of current mod at \"{backup.Name}\".";
|
: $"Create exported archive of current mod at \"{backup.Name}\".";
|
||||||
if( ImGuiUtil.DrawDisabledButton( "Create Backup", buttonSize, tt, ModBackup.CreatingBackup ) )
|
if( ImGuiUtil.DrawDisabledButton( "Export Mod", buttonSize, tt, ModBackup.CreatingBackup ) )
|
||||||
{
|
{
|
||||||
backup.CreateAsync();
|
backup.CreateAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
tt = backup.Exists
|
tt = backup.Exists
|
||||||
? $"Delete existing backup file \"{backup.Name}\"."
|
? $"Delete existing mod export \"{backup.Name}\"."
|
||||||
: $"Backup file \"{backup.Name}\" does not exist.";
|
: $"Exported mod \"{backup.Name}\" does not exist.";
|
||||||
if( ImGuiUtil.DrawDisabledButton( "Delete Backup", buttonSize, tt, !backup.Exists ) )
|
if( ImGuiUtil.DrawDisabledButton( "Delete Export", buttonSize, tt, !backup.Exists ) )
|
||||||
{
|
{
|
||||||
backup.Delete();
|
backup.Delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
tt = backup.Exists
|
tt = backup.Exists
|
||||||
? $"Restore mod from backup file \"{backup.Name}\"."
|
? $"Restore mod from exported file \"{backup.Name}\"."
|
||||||
: $"Backup file \"{backup.Name}\" does not exist.";
|
: $"Exported mod \"{backup.Name}\" does not exist.";
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
if( ImGuiUtil.DrawDisabledButton( "Restore From Backup", buttonSize, tt, !backup.Exists ) )
|
if( ImGuiUtil.DrawDisabledButton( "Restore From Export", buttonSize, tt, !backup.Exists ) )
|
||||||
{
|
{
|
||||||
backup.Restore();
|
backup.Restore();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,7 @@ public partial class ConfigWindow
|
||||||
DrawDefaultModImportPath();
|
DrawDefaultModImportPath();
|
||||||
DrawDefaultModAuthor();
|
DrawDefaultModAuthor();
|
||||||
DrawDefaultModImportFolder();
|
DrawDefaultModImportFolder();
|
||||||
|
DrawDefaultModExportPath();
|
||||||
|
|
||||||
ImGui.NewLine();
|
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." );
|
"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()
|
private void DrawDefaultModAuthor()
|
||||||
{
|
{
|
||||||
var tmp = Penumbra.Config.DefaultModAuthor;
|
var tmp = Penumbra.Config.DefaultModAuthor;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue