mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-14 04:34:19 +01:00
Move TexTools around.
This commit is contained in:
parent
f38a252295
commit
174e640c45
19 changed files with 212 additions and 228 deletions
|
|
@ -9,7 +9,7 @@ using OtterGui.Classes;
|
||||||
using OtterGui.Filesystem;
|
using OtterGui.Filesystem;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.Import;
|
using Penumbra.Import.Structs;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
using Penumbra.Services;
|
using Penumbra.Services;
|
||||||
using Penumbra.UI;
|
using Penumbra.UI;
|
||||||
|
|
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
using Penumbra.GameData.Enums;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using Penumbra.GameData;
|
|
||||||
|
|
||||||
namespace Penumbra.Import;
|
|
||||||
|
|
||||||
// Obtain information what type of object is manipulated
|
|
||||||
// by the given .meta file from TexTools, using its name.
|
|
||||||
public class MetaFileInfo
|
|
||||||
{
|
|
||||||
private const string Pt = @"(?'PrimaryType'[a-z]*)"; // language=regex
|
|
||||||
private const string Pp = @"(?'PrimaryPrefix'[a-z])"; // language=regex
|
|
||||||
private const string Pi = @"(?'PrimaryId'\d{4})"; // language=regex
|
|
||||||
private const string Pir = @"\k'PrimaryId'"; // language=regex
|
|
||||||
private const string St = @"(?'SecondaryType'[a-z]*)"; // language=regex
|
|
||||||
private const string Sp = @"(?'SecondaryPrefix'[a-z])"; // language=regex
|
|
||||||
private const string Si = @"(?'SecondaryId'\d{4})"; // language=regex
|
|
||||||
private const string File = @"\k'PrimaryPrefix'\k'PrimaryId'(\k'SecondaryPrefix'\k'SecondaryId')?"; // language=regex
|
|
||||||
private const string Slot = @"(_(?'Slot'[a-z]{3}))?"; // language=regex
|
|
||||||
private const string Ext = @"\.meta";
|
|
||||||
|
|
||||||
// These are the valid regexes for .meta files that we are able to support at the moment.
|
|
||||||
private static readonly Regex HousingMeta = new($"bgcommon/hou/{Pt}/general/{Pi}/{Pir}{Ext}", RegexOptions.Compiled);
|
|
||||||
private static readonly Regex CharaMeta = new($"chara/{Pt}/{Pp}{Pi}(/obj/{St}/{Sp}{Si})?/{File}{Slot}{Ext}", RegexOptions.Compiled);
|
|
||||||
|
|
||||||
public readonly ObjectType PrimaryType;
|
|
||||||
public readonly BodySlot SecondaryType;
|
|
||||||
public readonly ushort PrimaryId;
|
|
||||||
public readonly ushort SecondaryId;
|
|
||||||
public readonly EquipSlot EquipSlot = EquipSlot.Unknown;
|
|
||||||
public readonly CustomizationType CustomizationType = CustomizationType.Unknown;
|
|
||||||
|
|
||||||
private static bool ValidType( ObjectType type )
|
|
||||||
{
|
|
||||||
return type switch
|
|
||||||
{
|
|
||||||
ObjectType.Accessory => true,
|
|
||||||
ObjectType.Character => true,
|
|
||||||
ObjectType.Equipment => true,
|
|
||||||
ObjectType.DemiHuman => true,
|
|
||||||
ObjectType.Housing => true,
|
|
||||||
ObjectType.Monster => true,
|
|
||||||
ObjectType.Weapon => true,
|
|
||||||
ObjectType.Icon => false,
|
|
||||||
ObjectType.Font => false,
|
|
||||||
ObjectType.Interface => false,
|
|
||||||
ObjectType.LoadingScreen => false,
|
|
||||||
ObjectType.Map => false,
|
|
||||||
ObjectType.Vfx => false,
|
|
||||||
ObjectType.Unknown => false,
|
|
||||||
ObjectType.World => false,
|
|
||||||
_ => false,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public MetaFileInfo( IGamePathParser parser, string fileName )
|
|
||||||
{
|
|
||||||
// Set the primary type from the gamePath start.
|
|
||||||
PrimaryType = parser.PathToObjectType( fileName );
|
|
||||||
PrimaryId = 0;
|
|
||||||
SecondaryType = BodySlot.Unknown;
|
|
||||||
SecondaryId = 0;
|
|
||||||
// Not all types of objects can have valid meta data manipulation.
|
|
||||||
if( !ValidType( PrimaryType ) )
|
|
||||||
{
|
|
||||||
PrimaryType = ObjectType.Unknown;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Housing files have a separate regex that just contains the primary id.
|
|
||||||
if( PrimaryType == ObjectType.Housing )
|
|
||||||
{
|
|
||||||
var housingMatch = HousingMeta.Match( fileName );
|
|
||||||
if( housingMatch.Success )
|
|
||||||
{
|
|
||||||
PrimaryId = ushort.Parse( housingMatch.Groups[ "PrimaryId" ].Value );
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Non-housing is in chara/.
|
|
||||||
var match = CharaMeta.Match( fileName );
|
|
||||||
if( !match.Success )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The primary ID has to be available for every object.
|
|
||||||
PrimaryId = ushort.Parse( match.Groups[ "PrimaryId" ].Value );
|
|
||||||
|
|
||||||
// Depending on slot, we can set equip slot or customization type.
|
|
||||||
if( match.Groups[ "Slot" ].Success )
|
|
||||||
{
|
|
||||||
switch( PrimaryType )
|
|
||||||
{
|
|
||||||
case ObjectType.Equipment:
|
|
||||||
case ObjectType.Accessory:
|
|
||||||
if( Names.SuffixToEquipSlot.TryGetValue( match.Groups[ "Slot" ].Value, out var tmpSlot ) )
|
|
||||||
{
|
|
||||||
EquipSlot = tmpSlot;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case ObjectType.Character:
|
|
||||||
if( Names.SuffixToCustomizationType.TryGetValue( match.Groups[ "Slot" ].Value, out var tmpCustom ) )
|
|
||||||
{
|
|
||||||
CustomizationType = tmpCustom;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Secondary type and secondary id are for weapons and demihumans.
|
|
||||||
if( match.Groups[ "SecondaryType" ].Success
|
|
||||||
&& Names.StringToBodySlot.TryGetValue( match.Groups[ "SecondaryType" ].Value, out SecondaryType ) )
|
|
||||||
{
|
|
||||||
SecondaryId = ushort.Parse( match.Groups[ "SecondaryId" ].Value );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Penumbra.Import;
|
namespace Penumbra.Import.Structs;
|
||||||
|
|
||||||
public enum ImporterState
|
public enum ImporterState
|
||||||
{
|
{
|
||||||
104
Penumbra/Import/Structs/MetaFileInfo.cs
Normal file
104
Penumbra/Import/Structs/MetaFileInfo.cs
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
using Penumbra.GameData.Enums;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Penumbra.GameData;
|
||||||
|
|
||||||
|
namespace Penumbra.Import.Structs;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Obtain information what type of object is manipulated
|
||||||
|
/// by the given .meta file from TexTools, using its name.
|
||||||
|
/// </summary>
|
||||||
|
public partial struct MetaFileInfo
|
||||||
|
{
|
||||||
|
// These are the valid regexes for .meta files that we are able to support at the moment.
|
||||||
|
[GeneratedRegex(@"bgcommon/hou/(?'Type1'[a-z]*)/general/(?'Id1'\d{4})/\k'Id1'\.meta",
|
||||||
|
RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.NonBacktracking)]
|
||||||
|
private static partial Regex HousingMeta();
|
||||||
|
|
||||||
|
[GeneratedRegex(
|
||||||
|
@"chara/(?'Type1'[a-z]*)/(?'Pre1'[a-z])(?'Id1'\d{4})(/obj/(?'Type2'[a-z]*)/(?'Pre2'[a-z])(?'Id2'\d{4}))?/\k'Pre1'\k'Id1'(\k'Pre2'\k'Id2')?(_(?'Slot'[a-z]{3}))?\\.meta",
|
||||||
|
RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.NonBacktracking)]
|
||||||
|
private static partial Regex CharaMeta();
|
||||||
|
|
||||||
|
public readonly ObjectType PrimaryType;
|
||||||
|
public readonly BodySlot SecondaryType;
|
||||||
|
public readonly ushort PrimaryId;
|
||||||
|
public readonly ushort SecondaryId;
|
||||||
|
public readonly EquipSlot EquipSlot = EquipSlot.Unknown;
|
||||||
|
public readonly CustomizationType CustomizationType = CustomizationType.Unknown;
|
||||||
|
|
||||||
|
private static bool ValidType(ObjectType type)
|
||||||
|
=> type switch
|
||||||
|
{
|
||||||
|
ObjectType.Accessory => true,
|
||||||
|
ObjectType.Character => true,
|
||||||
|
ObjectType.Equipment => true,
|
||||||
|
ObjectType.DemiHuman => true,
|
||||||
|
ObjectType.Housing => true,
|
||||||
|
ObjectType.Monster => true,
|
||||||
|
ObjectType.Weapon => true,
|
||||||
|
ObjectType.Icon => false,
|
||||||
|
ObjectType.Font => false,
|
||||||
|
ObjectType.Interface => false,
|
||||||
|
ObjectType.LoadingScreen => false,
|
||||||
|
ObjectType.Map => false,
|
||||||
|
ObjectType.Vfx => false,
|
||||||
|
ObjectType.Unknown => false,
|
||||||
|
ObjectType.World => false,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
public MetaFileInfo(IGamePathParser parser, string fileName)
|
||||||
|
{
|
||||||
|
// Set the primary type from the gamePath start.
|
||||||
|
PrimaryType = parser.PathToObjectType(fileName);
|
||||||
|
PrimaryId = 0;
|
||||||
|
SecondaryType = BodySlot.Unknown;
|
||||||
|
SecondaryId = 0;
|
||||||
|
// Not all types of objects can have valid meta data manipulation.
|
||||||
|
if (!ValidType(PrimaryType))
|
||||||
|
{
|
||||||
|
PrimaryType = ObjectType.Unknown;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Housing files have a separate regex that just contains the primary id.
|
||||||
|
if (PrimaryType == ObjectType.Housing)
|
||||||
|
{
|
||||||
|
var housingMatch = HousingMeta().Match(fileName);
|
||||||
|
if (housingMatch.Success)
|
||||||
|
PrimaryId = ushort.Parse(housingMatch.Groups["Id1"].Value);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-housing is in chara/.
|
||||||
|
var match = CharaMeta().Match(fileName);
|
||||||
|
if (!match.Success)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// The primary ID has to be available for every object.
|
||||||
|
PrimaryId = ushort.Parse(match.Groups["Id1"].Value);
|
||||||
|
|
||||||
|
// Depending on slot, we can set equip slot or customization type.
|
||||||
|
if (match.Groups["Slot"].Success)
|
||||||
|
switch (PrimaryType)
|
||||||
|
{
|
||||||
|
case ObjectType.Equipment:
|
||||||
|
case ObjectType.Accessory:
|
||||||
|
if (Names.SuffixToEquipSlot.TryGetValue(match.Groups["Slot"].Value, out var tmpSlot))
|
||||||
|
EquipSlot = tmpSlot;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case ObjectType.Character:
|
||||||
|
if (Names.SuffixToCustomizationType.TryGetValue(match.Groups["Slot"].Value, out var tmpCustom))
|
||||||
|
CustomizationType = tmpCustom;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Secondary type and secondary id are for weapons and demihumans.
|
||||||
|
if (match.Groups["Type2"].Success && Names.StringToBodySlot.TryGetValue(match.Groups["Type2"].Value, out SecondaryType))
|
||||||
|
SecondaryId = ushort.Parse(match.Groups["Id2"].Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@ using Penumbra.Util;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace Penumbra.Import;
|
namespace Penumbra.Import.Structs;
|
||||||
|
|
||||||
// Create an automatically disposing SqPack stream.
|
// Create an automatically disposing SqPack stream.
|
||||||
public class StreamDisposer : PenumbraSqPackStream, IDisposable
|
public class StreamDisposer : PenumbraSqPackStream, IDisposable
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
|
|
||||||
namespace Penumbra.Import;
|
namespace Penumbra.Import.Structs;
|
||||||
|
|
||||||
internal static class DefaultTexToolsData
|
internal static class DefaultTexToolsData
|
||||||
{
|
{
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
@ -6,6 +7,7 @@ using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Penumbra.Import.Structs;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
using FileMode = System.IO.FileMode;
|
using FileMode = System.IO.FileMode;
|
||||||
using ZipArchive = SharpCompress.Archives.Zip.ZipArchive;
|
using ZipArchive = SharpCompress.Archives.Zip.ZipArchive;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ using Dalamud.Utility;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui.Filesystem;
|
using OtterGui.Filesystem;
|
||||||
|
using Penumbra.Import.Structs;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
using SharpCompress.Archives;
|
using SharpCompress.Archives;
|
||||||
using SharpCompress.Archives.Rar;
|
using SharpCompress.Archives.Rar;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using System.Numerics;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
|
using Penumbra.Import.Structs;
|
||||||
using Penumbra.UI.Classes;
|
using Penumbra.UI.Classes;
|
||||||
|
|
||||||
namespace Penumbra.Import;
|
namespace Penumbra.Import;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
|
using Penumbra.Import.Structs;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
using Penumbra.Util;
|
using Penumbra.Util;
|
||||||
using SharpCompress.Archives.Zip;
|
using SharpCompress.Archives.Zip;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using System.IO;
|
||||||
using Lumina.Extensions;
|
using Lumina.Extensions;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
using Penumbra.Import.Structs;
|
||||||
using Penumbra.Meta.Files;
|
using Penumbra.Meta.Files;
|
||||||
using Penumbra.Meta.Manipulations;
|
using Penumbra.Meta.Manipulations;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Penumbra.GameData;
|
using Penumbra.GameData;
|
||||||
|
using Penumbra.Import.Structs;
|
||||||
using Penumbra.Meta.Manipulations;
|
using Penumbra.Meta.Manipulations;
|
||||||
|
|
||||||
namespace Penumbra.Import;
|
namespace Penumbra.Import;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Interface.ImGuiFileDialog;
|
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using ImGuiScene;
|
using ImGuiScene;
|
||||||
using Lumina.Data.Files;
|
using Lumina.Data.Files;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
using Lumina.Data.Files;
|
using Lumina.Data.Files;
|
||||||
using SixLabors.ImageSharp;
|
using SixLabors.ImageSharp;
|
||||||
using SixLabors.ImageSharp.PixelFormats;
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Penumbra.Import.Dds;
|
namespace Penumbra.Import.Textures;
|
||||||
|
|
||||||
public static class TextureImporter
|
public static class TextureImporter
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ public unsafe partial class CharacterUtility
|
||||||
ResetResourceInternal();
|
ResetResourceInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the currently stored data of this resource to new values.
|
/// <summary> Set the currently stored data of this resource to new values. </summary>
|
||||||
private void SetResourceInternal(nint data, int length)
|
private void SetResourceInternal(nint data, int length)
|
||||||
{
|
{
|
||||||
if (!Ready)
|
if (!Ready)
|
||||||
|
|
@ -92,7 +92,7 @@ public unsafe partial class CharacterUtility
|
||||||
resource->SetData(data, length);
|
resource->SetData(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the currently stored data of this resource to its default values.
|
/// <summary> Reset the currently stored data of this resource to its default values. </summary>
|
||||||
private void ResetResourceInternal()
|
private void ResetResourceInternal()
|
||||||
=> SetResourceInternal(_defaultResourceData, _defaultResourceSize);
|
=> SetResourceInternal(_defaultResourceData, _defaultResourceSize);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,41 +5,40 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Penumbra.Mods;
|
namespace Penumbra.Mods;
|
||||||
|
|
||||||
// Utility to create and apply a zipped backup of a mod.
|
/// <summary> Utility to create and apply a zipped backup of a mod. </summary>
|
||||||
public class ModBackup
|
public class ModBackup
|
||||||
{
|
{
|
||||||
public static bool CreatingBackup { get; private set; }
|
public static bool CreatingBackup { get; private set; }
|
||||||
|
|
||||||
|
private readonly Mod.Manager _modManager;
|
||||||
private readonly Mod _mod;
|
private readonly Mod _mod;
|
||||||
public readonly string Name;
|
public readonly string Name;
|
||||||
public readonly bool Exists;
|
public readonly bool Exists;
|
||||||
|
|
||||||
public ModBackup(Mod.Manager modManager, Mod mod)
|
public ModBackup(Mod.Manager modManager, Mod mod)
|
||||||
{
|
{
|
||||||
|
_modManager = modManager;
|
||||||
_mod = mod;
|
_mod = mod;
|
||||||
Name = Path.Combine( modManager.ExportDirectory.FullName, _mod.ModPath.Name ) + ".pmp";
|
Name = Path.Combine(_modManager.ExportDirectory.FullName, _mod.ModPath.Name) + ".pmp";
|
||||||
Exists = File.Exists(Name);
|
Exists = File.Exists(Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate file extensions.
|
/// <summary> Migrate file extensions. </summary>
|
||||||
public static void MigrateZipToPmp(Mod.Manager manager)
|
public static void MigrateZipToPmp(Mod.Manager manager)
|
||||||
{
|
{
|
||||||
foreach (var mod in manager)
|
foreach (var mod in manager)
|
||||||
{
|
{
|
||||||
var pmpName = mod.ModPath + ".pmp";
|
var pmpName = mod.ModPath + ".pmp";
|
||||||
var zipName = mod.ModPath + ".zip";
|
var zipName = mod.ModPath + ".zip";
|
||||||
if( File.Exists( zipName ) )
|
if (!File.Exists(zipName))
|
||||||
{
|
continue;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!File.Exists(pmpName))
|
if (!File.Exists(pmpName))
|
||||||
{
|
|
||||||
File.Move(zipName, pmpName);
|
File.Move(zipName, pmpName);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
File.Delete(zipName);
|
File.Delete(zipName);
|
||||||
}
|
|
||||||
|
|
||||||
Penumbra.Log.Information($"Migrated mod export from {zipName} to {pmpName}.");
|
Penumbra.Log.Information($"Migrated mod export from {zipName} to {pmpName}.");
|
||||||
}
|
}
|
||||||
|
|
@ -49,16 +48,15 @@ public class ModBackup
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Move and/or rename an exported mod.
|
/// <summary>
|
||||||
// This object is unusable afterwards.
|
/// Move and/or rename an exported mod.
|
||||||
|
/// This object is unusable afterwards.
|
||||||
|
/// </summary>
|
||||||
public void Move(string? newBasePath = null, string? newName = null)
|
public void Move(string? newBasePath = null, string? newName = null)
|
||||||
{
|
{
|
||||||
if (CreatingBackup || !Exists)
|
if (CreatingBackup || !Exists)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -73,21 +71,18 @@ public class ModBackup
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a backup zip without blocking the main thread.
|
/// <summary> Create a backup zip without blocking the main thread. </summary>
|
||||||
public async void CreateAsync()
|
public async void CreateAsync()
|
||||||
{
|
{
|
||||||
if (CreatingBackup)
|
if (CreatingBackup)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
CreatingBackup = true;
|
CreatingBackup = true;
|
||||||
await Task.Run(Create);
|
await Task.Run(Create);
|
||||||
CreatingBackup = false;
|
CreatingBackup = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Create a backup. Overwrites pre-existing backups. </summary>
|
||||||
// Create a backup. Overwrites pre-existing backups.
|
|
||||||
private void Create()
|
private void Create()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -102,13 +97,11 @@ public class ModBackup
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete a pre-existing backup.
|
/// <summary> Delete a pre-existing backup. </summary>
|
||||||
public void Delete()
|
public void Delete()
|
||||||
{
|
{
|
||||||
if (!Exists)
|
if (!Exists)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -121,8 +114,10 @@ public class ModBackup
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore a mod from a pre-existing backup. Does not check if the mod contained in the backup is even similar.
|
/// <summary>
|
||||||
// Does an automatic reload after extraction.
|
/// 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()
|
public void Restore()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -135,7 +130,7 @@ public class ModBackup
|
||||||
|
|
||||||
ZipFile.ExtractToDirectory(Name, _mod.ModPath.FullName);
|
ZipFile.ExtractToDirectory(Name, _mod.ModPath.FullName);
|
||||||
Penumbra.Log.Debug($"Extracted exported file {Name} to {_mod.ModPath.FullName}.");
|
Penumbra.Log.Debug($"Extracted exported file {Name} to {_mod.ModPath.FullName}.");
|
||||||
Penumbra.ModManager.ReloadMod( _mod.Index );
|
_modManager.ReloadMod(_mod.Index);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ public class ModEditor : IDisposable
|
||||||
GroupIdx = -1;
|
GroupIdx = -1;
|
||||||
OptionIdx = 0;
|
OptionIdx = 0;
|
||||||
if (message)
|
if (message)
|
||||||
global::Penumbra.Penumbra.Log.Error($"Loading invalid option {groupIdx} {optionIdx} for Mod {Mod?.Name ?? "Unknown"}.");
|
Penumbra.Log.Error($"Loading invalid option {groupIdx} {optionIdx} for Mod {Mod?.Name ?? "Unknown"}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ using Newtonsoft.Json.Linq;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Filesystem;
|
using OtterGui.Filesystem;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
using Penumbra.Import;
|
using Penumbra.Import.Structs;
|
||||||
using Penumbra.String.Classes;
|
using Penumbra.String.Classes;
|
||||||
|
|
||||||
namespace Penumbra.Mods;
|
namespace Penumbra.Mods;
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ using OtterGui.Raii;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
using Penumbra.Collections;
|
using Penumbra.Collections;
|
||||||
using Penumbra.Import;
|
using Penumbra.Import;
|
||||||
|
using Penumbra.Import.Structs;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
using Penumbra.Services;
|
using Penumbra.Services;
|
||||||
using Penumbra.UI.Classes;
|
using Penumbra.UI.Classes;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue