mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-30 20:33:43 +01:00
Make extracting mods cancelable, some fixes.
This commit is contained in:
parent
cf54bc7f57
commit
5e46f43d7d
9 changed files with 182 additions and 108 deletions
|
|
@ -13,6 +13,8 @@ namespace Penumbra.Import;
|
|||
|
||||
public partial class TexToolsImporter
|
||||
{
|
||||
private DirectoryInfo? _currentModDirectory;
|
||||
|
||||
// Version 1 mod packs are a simple collection of files without much information.
|
||||
private DirectoryInfo ImportV1ModPack( FileInfo modPackFile, ZipFile extractedModPack, string modRaw )
|
||||
{
|
||||
|
|
@ -31,16 +33,16 @@ public partial class TexToolsImporter
|
|||
|
||||
var modList = modListRaw.Select( m => JsonConvert.DeserializeObject< SimpleMod >( m, JsonSettings )! ).ToList();
|
||||
|
||||
// Open the mod data file from the mod pack as a SqPackStream
|
||||
using var modData = GetSqPackStreamStream( extractedModPack, "TTMPD.mpd" );
|
||||
|
||||
var ret = Mod.CreateModFolder( _baseDirectory, Path.GetFileNameWithoutExtension( modPackFile.Name ) );
|
||||
_currentModDirectory = Mod.CreateModFolder( _baseDirectory, Path.GetFileNameWithoutExtension( modPackFile.Name ) );
|
||||
// Create a new ModMeta from the TTMP mod list info
|
||||
Mod.CreateMeta( ret, _currentModName, DefaultTexToolsData.Author, DefaultTexToolsData.Description, null, null );
|
||||
Mod.CreateMeta( _currentModDirectory, _currentModName, DefaultTexToolsData.Author, DefaultTexToolsData.Description, null, null );
|
||||
|
||||
ExtractSimpleModList( ret, modList, modData );
|
||||
Mod.CreateDefaultFiles( ret );
|
||||
return ret;
|
||||
// Open the mod data file from the mod pack as a SqPackStream
|
||||
_streamDisposer = GetSqPackStreamStream( extractedModPack, "TTMPD.mpd" );
|
||||
ExtractSimpleModList( _currentModDirectory, modList );
|
||||
Mod.CreateDefaultFiles( _currentModDirectory );
|
||||
ResetStreamDisposer();
|
||||
return _currentModDirectory;
|
||||
}
|
||||
|
||||
// Version 2 mod packs can either be simple or extended, import accordingly.
|
||||
|
|
@ -87,17 +89,17 @@ public partial class TexToolsImporter
|
|||
_currentOptionName = DefaultTexToolsData.DefaultOption;
|
||||
PluginLog.Log( " -> Importing Simple V2 ModPack" );
|
||||
|
||||
// Open the mod data file from the mod pack as a SqPackStream
|
||||
using var modData = GetSqPackStreamStream( extractedModPack, "TTMPD.mpd" );
|
||||
|
||||
var ret = Mod.CreateModFolder( _baseDirectory, _currentModName );
|
||||
Mod.CreateMeta( ret, _currentModName, modList.Author, string.IsNullOrEmpty( modList.Description )
|
||||
_currentModDirectory = Mod.CreateModFolder( _baseDirectory, _currentModName );
|
||||
Mod.CreateMeta( _currentModDirectory, _currentModName, modList.Author, string.IsNullOrEmpty( modList.Description )
|
||||
? "Mod imported from TexTools mod pack"
|
||||
: modList.Description, null, null );
|
||||
|
||||
ExtractSimpleModList( ret, modList.SimpleModsList, modData );
|
||||
Mod.CreateDefaultFiles( ret );
|
||||
return ret;
|
||||
// Open the mod data file from the mod pack as a SqPackStream
|
||||
_streamDisposer = GetSqPackStreamStream( extractedModPack, "TTMPD.mpd" );
|
||||
ExtractSimpleModList( _currentModDirectory, modList.SimpleModsList );
|
||||
Mod.CreateDefaultFiles( _currentModDirectory );
|
||||
ResetStreamDisposer();
|
||||
return _currentModDirectory;
|
||||
}
|
||||
|
||||
// Obtain the number of relevant options to extract.
|
||||
|
|
@ -118,23 +120,24 @@ public partial class TexToolsImporter
|
|||
var modList = JsonConvert.DeserializeObject< ExtendedModPack >( modRaw, JsonSettings )!;
|
||||
_currentNumOptions = GetOptionCount( modList );
|
||||
_currentModName = modList.Name;
|
||||
// Open the mod data file from the mod pack as a SqPackStream
|
||||
using var modData = GetSqPackStreamStream( extractedModPack, "TTMPD.mpd" );
|
||||
|
||||
var ret = Mod.CreateModFolder( _baseDirectory, _currentModName );
|
||||
Mod.CreateMeta( ret, _currentModName, modList.Author, modList.Description, modList.Version, null );
|
||||
_currentModDirectory = Mod.CreateModFolder( _baseDirectory, _currentModName );
|
||||
Mod.CreateMeta( _currentModDirectory, _currentModName, modList.Author, modList.Description, modList.Version, null );
|
||||
|
||||
if( _currentNumOptions == 0 )
|
||||
{
|
||||
return ret;
|
||||
return _currentModDirectory;
|
||||
}
|
||||
|
||||
// Open the mod data file from the mod pack as a SqPackStream
|
||||
_streamDisposer = GetSqPackStreamStream( extractedModPack, "TTMPD.mpd" );
|
||||
|
||||
// It can contain a simple list, still.
|
||||
if( modList.SimpleModsList.Length > 0 )
|
||||
{
|
||||
_currentGroupName = string.Empty;
|
||||
_currentOptionName = "Default";
|
||||
ExtractSimpleModList( ret, modList.SimpleModsList, modData );
|
||||
ExtractSimpleModList( _currentModDirectory, modList.SimpleModsList );
|
||||
}
|
||||
|
||||
// Iterate through all pages
|
||||
|
|
@ -147,18 +150,19 @@ public partial class TexToolsImporter
|
|||
_currentGroupName = group.GroupName;
|
||||
options.Clear();
|
||||
var description = new StringBuilder();
|
||||
var groupFolder = Mod.NewSubFolderName( ret, group.GroupName )
|
||||
?? new DirectoryInfo( Path.Combine( ret.FullName, $"Group {groupPriority + 1}" ) );
|
||||
var groupFolder = Mod.NewSubFolderName( _currentModDirectory, group.GroupName )
|
||||
?? new DirectoryInfo( Path.Combine( _currentModDirectory.FullName, $"Group {groupPriority + 1}" ) );
|
||||
|
||||
var optionIdx = 1;
|
||||
|
||||
foreach( var option in group.OptionList.Where( option => option.Name.Length > 0 && option.ModsJsons.Length > 0 ) )
|
||||
{
|
||||
_token.ThrowIfCancellationRequested();
|
||||
_currentOptionName = option.Name;
|
||||
var optionFolder = Mod.NewSubFolderName( groupFolder, option.Name )
|
||||
?? new DirectoryInfo( Path.Combine( groupFolder.FullName, $"Option {optionIdx}" ) );
|
||||
ExtractSimpleModList( optionFolder, option.ModsJsons, modData );
|
||||
options.Add( Mod.CreateSubMod( ret, optionFolder, option ) );
|
||||
ExtractSimpleModList( optionFolder, option.ModsJsons );
|
||||
options.Add( Mod.CreateSubMod( _currentModDirectory, optionFolder, option ) );
|
||||
description.Append( option.Description );
|
||||
if( !string.IsNullOrEmpty( option.Description ) )
|
||||
{
|
||||
|
|
@ -169,15 +173,16 @@ public partial class TexToolsImporter
|
|||
++_currentOptionIdx;
|
||||
}
|
||||
|
||||
Mod.CreateOptionGroup( ret, group, groupPriority++, description.ToString(), options );
|
||||
Mod.CreateOptionGroup( _currentModDirectory, group, groupPriority++, description.ToString(), options );
|
||||
}
|
||||
}
|
||||
|
||||
Mod.CreateDefaultFiles( ret );
|
||||
return ret;
|
||||
ResetStreamDisposer();
|
||||
Mod.CreateDefaultFiles( _currentModDirectory );
|
||||
return _currentModDirectory;
|
||||
}
|
||||
|
||||
private void ExtractSimpleModList( DirectoryInfo outDirectory, ICollection< SimpleMod > mods, PenumbraSqPackStream dataStream )
|
||||
private void ExtractSimpleModList( DirectoryInfo outDirectory, ICollection< SimpleMod > mods )
|
||||
{
|
||||
State = ImporterState.ExtractingModFiles;
|
||||
|
||||
|
|
@ -187,35 +192,34 @@ public partial class TexToolsImporter
|
|||
// Extract each SimpleMod into the new mod folder
|
||||
foreach( var simpleMod in mods )
|
||||
{
|
||||
ExtractMod( outDirectory, simpleMod, dataStream );
|
||||
ExtractMod( outDirectory, simpleMod );
|
||||
++_currentFileIdx;
|
||||
}
|
||||
}
|
||||
|
||||
private void ExtractMod( DirectoryInfo outDirectory, SimpleMod mod, PenumbraSqPackStream dataStream )
|
||||
private void ExtractMod( DirectoryInfo outDirectory, SimpleMod mod )
|
||||
{
|
||||
if( _streamDisposer is not PenumbraSqPackStream stream )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PluginLog.Log( " -> Extracting {0} at {1}", mod.FullPath, mod.ModOffset.ToString( "X" ) );
|
||||
|
||||
try
|
||||
_token.ThrowIfCancellationRequested();
|
||||
var data = stream.ReadFile< PenumbraSqPackStream.PenumbraFileResource >( mod.ModOffset );
|
||||
|
||||
_currentFileName = mod.FullPath;
|
||||
var extractedFile = new FileInfo( Path.Combine( outDirectory.FullName, mod.FullPath ) );
|
||||
|
||||
extractedFile.Directory?.Create();
|
||||
|
||||
if( extractedFile.FullName.EndsWith( ".mdl" ) )
|
||||
{
|
||||
var data = dataStream.ReadFile< PenumbraSqPackStream.PenumbraFileResource >( mod.ModOffset );
|
||||
|
||||
_currentFileName = mod.FullPath;
|
||||
var extractedFile = new FileInfo( Path.Combine( outDirectory.FullName, mod.FullPath ) );
|
||||
|
||||
extractedFile.Directory?.Create();
|
||||
|
||||
if( extractedFile.FullName.EndsWith( ".mdl" ) )
|
||||
{
|
||||
ProcessMdl( data.Data );
|
||||
}
|
||||
|
||||
File.WriteAllBytes( extractedFile.FullName, data.Data );
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
PluginLog.LogError( ex, "Could not extract mod." );
|
||||
ProcessMdl( data.Data );
|
||||
}
|
||||
|
||||
File.WriteAllBytes( extractedFile.FullName, data.Data );
|
||||
}
|
||||
|
||||
private static void ProcessMdl( byte[] mdl )
|
||||
|
|
@ -226,11 +230,11 @@ public partial class TexToolsImporter
|
|||
mdl[ 64 ] = 1;
|
||||
|
||||
// Model header LOD num
|
||||
var stackSize = BitConverter.ToUInt32( mdl, 4 );
|
||||
var runtimeBegin = stackSize + 0x44;
|
||||
var stringsLengthOffset = runtimeBegin + 4;
|
||||
var stringsLength = BitConverter.ToUInt32( mdl, ( int )stringsLengthOffset );
|
||||
var modelHeaderStart = stringsLengthOffset + stringsLength + 4;
|
||||
var stackSize = BitConverter.ToUInt32( mdl, 4 );
|
||||
var runtimeBegin = stackSize + 0x44;
|
||||
var stringsLengthOffset = runtimeBegin + 4;
|
||||
var stringsLength = BitConverter.ToUInt32( mdl, ( int )stringsLengthOffset );
|
||||
var modelHeaderStart = stringsLengthOffset + stringsLength + 4;
|
||||
mdl[ modelHeaderStart + modelHeaderLodOffset ] = 1;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue