@@ -336,6 +336,114 @@ public async Task<int> CreateSimpleModPack(SimpleModPackData modPackData, Direct
336
336
return processCount ;
337
337
}
338
338
339
+ public async Task < int > CreateBackupModpack ( BackupModPackData backupModpackData , DirectoryInfo gameDirectory , IProgress < ( int current , int total , string message ) > progress , bool overwriteModpack )
340
+ {
341
+ var processCount = await Task . Run < int > ( ( ) =>
342
+ {
343
+ var dat = new Dat ( gameDirectory ) ;
344
+
345
+ var guid = Guid . NewGuid ( ) ;
346
+
347
+ var dir = Path . Combine ( Path . GetTempPath ( ) , guid . ToString ( ) ) ;
348
+ Directory . CreateDirectory ( dir ) ;
349
+
350
+
351
+ _tempMPD = Path . Combine ( dir , "TTMPD.mpd" ) ;
352
+ _tempMPL = Path . Combine ( dir , "TTMPL.mpl" ) ;
353
+
354
+ var modCount = 0 ;
355
+
356
+ var modPackJson = new ModPackJson
357
+ {
358
+ TTMPVersion = _currentBackupTTMPVersion ,
359
+ Name = backupModpackData . Name ,
360
+ Author = backupModpackData . Author ,
361
+ Version = backupModpackData . Version . ToString ( ) ,
362
+ MinimumFrameworkVersion = _minimumAssembly ,
363
+ Url = backupModpackData . Url ,
364
+ Description = backupModpackData . Description ,
365
+ SimpleModsList = new List < ModsJson > ( )
366
+ } ;
367
+
368
+ try
369
+ {
370
+ using ( var binaryWriter = new BinaryWriter ( File . Open ( _tempMPD , FileMode . Create ) ) )
371
+ {
372
+ foreach ( var backupModData in backupModpackData . ModsToBackup )
373
+ {
374
+ if ( ForbiddenModTypes . Contains ( Path . GetExtension ( backupModData . SimpleModData . FullPath ) ) ) continue ;
375
+
376
+ var modsJson = new ModsJson
377
+ {
378
+ Name = backupModData . SimpleModData . Name ,
379
+ Category = backupModData . SimpleModData . Category . GetEnDisplayName ( ) ,
380
+ FullPath = backupModData . SimpleModData . FullPath ,
381
+ ModSize = backupModData . SimpleModData . ModSize ,
382
+ DatFile = backupModData . SimpleModData . DatFile ,
383
+ IsDefault = backupModData . SimpleModData . IsDefault ,
384
+ ModOffset = binaryWriter . BaseStream . Position ,
385
+ ModPackEntry = backupModData . ModPack ,
386
+ } ;
387
+
388
+ var rawData = dat . GetRawData ( backupModData . SimpleModData . ModOffset ,
389
+ XivDataFiles . GetXivDataFile ( backupModData . SimpleModData . DatFile ) ,
390
+ backupModData . SimpleModData . ModSize ) ;
391
+
392
+ if ( rawData == null )
393
+ {
394
+ throw new Exception ( "Unable to obtain data for the following mod\n \n " +
395
+ $ "Name: { backupModData . SimpleModData . Name } \n Full Path: { backupModData . SimpleModData . FullPath } \n " +
396
+ $ "Mod Offset: { backupModData . SimpleModData . ModOffset } \n Data File: { backupModData . SimpleModData . DatFile } \n \n " +
397
+ $ "Unselect the above mod and try again.") ;
398
+ }
399
+
400
+ binaryWriter . Write ( rawData ) ;
401
+
402
+ modPackJson . SimpleModsList . Add ( modsJson ) ;
403
+
404
+ progress ? . Report ( ( ++ modCount , backupModpackData . ModsToBackup . Count , string . Empty ) ) ;
405
+ }
406
+ }
407
+
408
+ progress ? . Report ( ( 0 , backupModpackData . ModsToBackup . Count , GeneralStrings . TTMP_Creating ) ) ;
409
+
410
+ File . WriteAllText ( _tempMPL , JsonConvert . SerializeObject ( modPackJson ) ) ;
411
+
412
+ var modPackPath = Path . Combine ( _modPackDirectory . FullName , $ "{ backupModpackData . Name } .ttmp2") ;
413
+
414
+ if ( File . Exists ( modPackPath ) && ! overwriteModpack )
415
+ {
416
+ var fileNum = 1 ;
417
+ modPackPath = Path . Combine ( _modPackDirectory . FullName , $ "{ backupModpackData . Name } ({ fileNum } ).ttmp2") ;
418
+ while ( File . Exists ( modPackPath ) )
419
+ {
420
+ fileNum ++ ;
421
+ modPackPath = Path . Combine ( _modPackDirectory . FullName , $ "{ backupModpackData . Name } ({ fileNum } ).ttmp2") ;
422
+ }
423
+ }
424
+ else if ( File . Exists ( modPackPath ) && overwriteModpack )
425
+ {
426
+ File . Delete ( modPackPath ) ;
427
+ }
428
+
429
+ var zf = new ZipFile ( ) ;
430
+ zf . UseZip64WhenSaving = Zip64Option . AsNecessary ;
431
+ zf . CompressionLevel = Ionic . Zlib . CompressionLevel . None ;
432
+ zf . AddFile ( _tempMPL , "" ) ;
433
+ zf . AddFile ( _tempMPD , "" ) ;
434
+ zf . Save ( modPackPath ) ;
435
+ }
436
+ finally
437
+ {
438
+ Directory . Delete ( dir , true ) ;
439
+ }
440
+
441
+ return modCount ;
442
+ } ) ;
443
+
444
+ return processCount ;
445
+ }
446
+
339
447
/// <summary>
340
448
/// Gets the data from a mod pack including images if present
341
449
/// </summary>
@@ -673,6 +781,8 @@ await Task.Run(async () =>
673
781
// Add entries for new modpacks to the mod list
674
782
foreach ( var modsJson in filteredModsJson )
675
783
{
784
+ if ( modsJson . ModPackEntry == null ) continue ;
785
+
676
786
var modPackExists = modList . ModPacks . Any ( modpack => modpack . name == modsJson . ModPackEntry . name ) ;
677
787
678
788
if ( ! modPackExists )
@@ -685,8 +795,8 @@ await Task.Run(async () =>
685
795
if ( GetRootConversionsFunction != null )
686
796
{
687
797
// Get the modpack to list the conversions under, this is the just the modpack entry of the first modsJson since they're all the same unless it's a backup
688
- // However, this code isn 't used for importing backup modpacks since they already had the choice to change the destination item after the initial import
689
- var modPack = modList . ModPacks . First ( x => x . name == filteredModsJson [ 0 ] . ModPackEntry . name ) ;
798
+ // However, this code shouldn 't be used when importing backup modpacks since they already had the choice to change the destination item after the initial import
799
+ var modPack = modList . ModPacks . First ( x => x . name == filteredModsJson [ 0 ] . ModPackEntry ? . name ) ;
690
800
691
801
Dictionary < XivDependencyRoot , ( XivDependencyRoot Root , int Variant ) > rootConversions = null ;
692
802
try
0 commit comments