1
-
2
- // ***********************************************************************
1
+ // ***********************************************************************
3
2
// Assembly : IronyModManager.IO
4
3
// Author : Mario
5
4
// Created : 03-31-2020
6
5
//
7
6
// Last Modified By : Mario
8
- // Last Modified On : 01 -23-2024
7
+ // Last Modified On : 12 -23-2024
9
8
// ***********************************************************************
10
9
// <copyright file="ModWriter.cs" company="Mario">
11
10
// Mario
31
30
32
31
namespace IronyModManager . IO . Mods
33
32
{
34
-
35
33
/// <summary>
36
34
/// Class ModWriter.
37
35
/// Implements the <see cref="IronyModManager.IO.Common.Mods.IModWriter" />
@@ -113,16 +111,17 @@ public async Task<bool> ApplyModsAsync(ModWriterParameters parameters)
113
111
{
114
112
throw new ArgumentException ( "Invalid descriptor type." ) ;
115
113
}
114
+
116
115
Task < bool > [ ] tasks ;
117
116
118
- using ( var mutex = await writeLock . LockAsync ( ) )
117
+ using ( await writeLock . LockAsync ( ) )
119
118
{
120
- tasks = new Task < bool > [ ]
121
- {
122
- Task . Run ( async ( ) => await sqliteExporter . ExportAsync ( parameters ) ) ,
123
- Task . Run ( async ( ) => await sqliteExporterBeta . ExportAsync ( parameters ) ) ,
124
- Task . Run ( async ( ) => await jsonExporter . ExportModsAsync ( parameters ) )
125
- } ;
119
+ tasks =
120
+ [
121
+ Task . Run ( async ( ) => await sqliteExporter . ExportAsync ( parameters ) ) ,
122
+ Task . Run ( async ( ) => await sqliteExporterBeta . ExportAsync ( parameters ) ) ,
123
+ Task . Run ( async ( ) => await jsonExporter . ExportModsAsync ( parameters ) )
124
+ ] ;
126
125
await Task . WhenAll ( tasks ) ;
127
126
}
128
127
@@ -158,6 +157,7 @@ public Task<bool> CanWriteToModDirectoryAsync(ModWriterParameters parameters)
158
157
// Real genious you picked C, D or whatever drive
159
158
return Task . FromResult ( false ) ;
160
159
}
160
+
161
161
var root = Path . Combine ( el [ 0 ] , el [ 1 ] ) ;
162
162
if ( ! Directory . Exists ( root ) && ! IsAdmin ( ) )
163
163
{
@@ -177,12 +177,15 @@ public Task<bool> CanWriteToModDirectoryAsync(ModWriterParameters parameters)
177
177
{
178
178
return Task . FromResult ( false ) ;
179
179
}
180
+
180
181
return Task . FromResult ( true ) ;
181
182
}
182
183
}
183
184
}
185
+
184
186
return Task . FromResult ( true ) ;
185
187
}
188
+
186
189
return Task . FromResult ( false ) ;
187
190
}
188
191
@@ -199,6 +202,7 @@ public Task<bool> CreateModDirectoryAsync(ModWriterParameters parameters)
199
202
Directory . CreateDirectory ( fullPath ) ;
200
203
return Task . FromResult ( true ) ;
201
204
}
205
+
202
206
return Task . FromResult ( false ) ;
203
207
}
204
208
@@ -217,8 +221,10 @@ Task<bool> delete()
217
221
DiskOperations . DeleteFile ( fullPath ) ;
218
222
return Task . FromResult ( true ) ;
219
223
}
224
+
220
225
return Task . FromResult ( false ) ;
221
226
}
227
+
222
228
var retry = new RetryStrategy ( ) ;
223
229
return retry . RetryActionAsync ( ( ) => delete ( ) ) ;
224
230
}
@@ -235,6 +241,7 @@ public Task<bool> DescriptorExistsAsync(ModWriterParameters parameters)
235
241
{
236
242
return Task . FromResult ( true ) ;
237
243
}
244
+
238
245
return Task . FromResult ( false ) ;
239
246
}
240
247
@@ -250,6 +257,7 @@ public string FormatPrefixModName(string prefix, string name)
250
257
{
251
258
return $ "{ prefix } { name } ";
252
259
}
260
+
253
261
return name ;
254
262
}
255
263
@@ -265,6 +273,7 @@ public virtual bool ModDirectoryExists(ModWriterParameters parameters)
265
273
{
266
274
return false ;
267
275
}
276
+
268
277
return Directory . EnumerateFiles ( fullPath , "*" , SearchOption . AllDirectories ) . Any ( ) ;
269
278
}
270
279
@@ -303,21 +312,25 @@ Task<bool> purge()
303
312
{
304
313
DiskOperations . DeleteDirectory ( fullPath , true ) ;
305
314
}
315
+
306
316
return Task . FromResult ( true ) ;
307
317
}
308
318
else if ( File . Exists ( fullPath ) )
309
319
{
310
320
DiskOperations . DeleteFile ( fullPath ) ;
311
321
var directory = Path . GetDirectoryName ( fullPath ) ;
312
- var files = Directory . EnumerateFiles ( directory , "*" , SearchOption . AllDirectories ) ;
322
+ var files = Directory . EnumerateFiles ( directory ! , "*" , SearchOption . AllDirectories ) ;
313
323
if ( ! files . Any ( ) )
314
324
{
315
325
DiskOperations . DeleteDirectory ( directory , true ) ;
316
326
}
327
+
317
328
return Task . FromResult ( true ) ;
318
329
}
330
+
319
331
return Task . FromResult ( false ) ;
320
332
}
333
+
321
334
var retry = new RetryStrategy ( ) ;
322
335
return retry . RetryActionAsync ( ( ) => purge ( ) ) ;
323
336
}
@@ -333,12 +346,10 @@ public Task<bool> SetDescriptorLockAsync(ModWriterParameters parameters, bool is
333
346
var fullPath = Path . Combine ( parameters . RootDirectory ?? string . Empty , parameters . Mod . DescriptorFile ?? string . Empty ) ;
334
347
if ( File . Exists ( fullPath ) )
335
348
{
336
- _ = new System . IO . FileInfo ( fullPath )
337
- {
338
- IsReadOnly = isLocked
339
- } ;
349
+ _ = new System . IO . FileInfo ( fullPath ) { IsReadOnly = isLocked } ;
340
350
return Task . FromResult ( true ) ;
341
351
}
352
+
342
353
return Task . FromResult ( false ) ;
343
354
}
344
355
@@ -356,6 +367,7 @@ public async Task<bool> WriteDescriptorAsync(ModWriterParameters parameters, boo
356
367
{
357
368
throw new ArgumentException ( "Invalid descriptor type." ) ;
358
369
}
370
+
359
371
async Task < bool > writeDescriptors ( )
360
372
{
361
373
// If needed I've got a much more complex serializer, it is written for Kerbal Space Program but the structure seems to be the same though this is much more simpler
@@ -367,12 +379,10 @@ async Task<bool> writeDescriptors()
367
379
{
368
380
if ( File . Exists ( fullPath ) )
369
381
{
370
- _ = new System . IO . FileInfo ( fullPath )
371
- {
372
- IsReadOnly = true
373
- } ;
382
+ _ = new System . IO . FileInfo ( fullPath ) { IsReadOnly = true } ;
374
383
}
375
384
}
385
+
376
386
if ( writeDescriptorInModDirectory )
377
387
{
378
388
var modPath = Path . Combine ( parameters . Mod . FileName ?? string . Empty , parameters . DescriptorType == DescriptorType . DescriptorMod ? Shared . Constants . DescriptorFile : Shared . Constants . DescriptorJsonMetadata ) ;
@@ -381,13 +391,17 @@ async Task<bool> writeDescriptors()
381
391
var dir = Path . GetDirectoryName ( modPath ) ;
382
392
if ( ! Directory . Exists ( dir ) )
383
393
{
384
- Directory . CreateDirectory ( dir ) ;
394
+ Directory . CreateDirectory ( dir ! ) ;
385
395
}
386
396
}
397
+
387
398
await writeDescriptor ( modPath , true ) ;
388
399
}
400
+
389
401
return true ;
390
402
}
403
+
404
+ // ReSharper disable once UnusedLocalFunctionReturnValue
391
405
async Task < bool > writeDescriptor ( string fullPath , bool truncatePath )
392
406
{
393
407
bool ? state = null ;
@@ -397,15 +411,14 @@ async Task<bool> writeDescriptor(string fullPath, bool truncatePath)
397
411
state = fileInfo . IsReadOnly ;
398
412
fileInfo . IsReadOnly = false ;
399
413
}
400
- using var fs = new FileStream ( fullPath , FileMode . Create , FileAccess . Write , FileShare . Read ) ;
414
+
415
+ await using var fs = new FileStream ( fullPath ! , FileMode . Create , FileAccess . Write , FileShare . Read ) ;
401
416
var result = await WriteDescriptorToStreamAsync ( parameters , fs , truncatePath ) ;
402
417
if ( state . HasValue )
403
418
{
404
- var fileInfo = new System . IO . FileInfo ( fullPath )
405
- {
406
- IsReadOnly = state . GetValueOrDefault ( )
407
- } ;
419
+ _ = new System . IO . FileInfo ( fullPath ) { IsReadOnly = state . GetValueOrDefault ( ) } ;
408
420
}
421
+
409
422
return result ;
410
423
}
411
424
@@ -428,6 +441,7 @@ public Task<bool> WriteDescriptorToStreamAsync(ModWriterParameters parameters, S
428
441
{
429
442
throw new ArgumentException ( "Invalid descriptor type." ) ;
430
443
}
444
+
431
445
return WriteDescriptorToStreamInternalAsync ( parameters . Mod , stream , parameters . DescriptorType , truncatePath ) ;
432
446
}
433
447
@@ -452,7 +466,7 @@ static async Task serializeDescriptorMod(IMod content, StreamWriter sw)
452
466
{
453
467
if ( col . Any ( ) )
454
468
{
455
- if ( attr . KeyedArray )
469
+ if ( attr ! . KeyedArray )
456
470
{
457
471
foreach ( var item in col )
458
472
{
@@ -466,6 +480,7 @@ static async Task serializeDescriptorMod(IMod content, StreamWriter sw)
466
480
{
467
481
await sw . WriteLineAsync ( $ "\t \" { item . Replace ( "\" " , "\\ \" " ) } \" ") ;
468
482
}
483
+
469
484
await sw . WriteLineAsync ( "}" ) ;
470
485
}
471
486
}
@@ -474,36 +489,44 @@ static async Task serializeDescriptorMod(IMod content, StreamWriter sw)
474
489
{
475
490
if ( ! string . IsNullOrWhiteSpace ( val != null ? val . ToString ( ) : string . Empty ) )
476
491
{
477
- if ( attr . AlternateNameEndsWithCondition ? . Count ( ) > 0 && attr . AlternateNameEndsWithCondition . Any ( p => val . ToString ( ) . EndsWith ( p , StringComparison . OrdinalIgnoreCase ) ) )
492
+ if ( attr ! . AlternateNameEndsWithCondition ? . Count ( ) > 0 && attr . AlternateNameEndsWithCondition . Any ( p => val ! . ToString ( ) ! . EndsWith ( p , StringComparison . OrdinalIgnoreCase ) ) )
478
493
{
479
- await sw . WriteLineAsync ( $ "{ attr . AlternatePropertyName } =\" { val . ToString ( ) . Replace ( "\" " , "\\ \" " ) } \" ") ;
494
+ await sw . WriteLineAsync ( $ "{ attr . AlternatePropertyName } =\" { val ? . ToString ( ) ? . Replace ( "\" " , "\\ \" " ) } \" ") ;
480
495
}
481
496
else
482
497
{
483
- await sw . WriteLineAsync ( $ "{ attr . PropertyName } =\" { val . ToString ( ) . Replace ( "\" " , "\\ \" " ) } \" ") ;
498
+ await sw . WriteLineAsync ( $ "{ attr . PropertyName } =\" { val ? . ToString ( ) ? . Replace ( "\" " , "\\ \" " ) } \" ") ;
484
499
}
485
500
}
486
501
}
487
502
}
488
503
}
504
+
489
505
static async Task serializeJsonDescriptorMod ( IMod content , StreamWriter sw )
490
506
{
491
507
var customData = content . AdditionalData != null ? new Dictionary < string , object > ( content . AdditionalData ) : new Dictionary < string , object > ( ) ;
492
508
if ( content . ReplacePath != null && content . ReplacePath . Any ( ) )
493
509
{
494
510
customData [ Shared . Constants . JsonMetadataReplacePaths ] = content . ReplacePath ;
495
511
}
512
+
496
513
if ( content . UserDir != null && content . UserDir . Any ( ) )
497
514
{
498
515
customData [ Shared . Constants . DescriptorUserDir ] = content . UserDir ;
499
516
}
500
517
501
- var metaData = new JsonMetadata ( )
518
+ var relationshipData = new List < Dictionary < string , object > > ( ) ;
519
+ if ( content . RelationshipData != null )
520
+ {
521
+ relationshipData . AddRange ( content . RelationshipData . Select ( relData => new Dictionary < string , object > ( relData ) ) ) ;
522
+ }
523
+
524
+ var metaData = new JsonMetadata
502
525
{
503
- Id = content . RemoteId . HasValue ? content . RemoteId . ToString ( ) : string . Empty ,
526
+ Id = ! string . IsNullOrWhiteSpace ( content . JsonId ) ? content . JsonId : content . RemoteId . HasValue ? content . RemoteId . ToString ( ) : string . Empty ,
504
527
Name = content . Name ,
505
528
Path = content . FileName ,
506
- Relationships = content . Dependencies != null ? content . Dependencies . ToList ( ) : new List < string > ( ) ,
529
+ Relationships = relationshipData ,
507
530
SupportedGameVersion = content . Version ,
508
531
Tags = content . Tags != null ? content . Tags . ToList ( ) : new List < string > ( ) ,
509
532
ShortDescription = string . Empty ,
@@ -519,7 +542,8 @@ static async Task serializeJsonDescriptorMod(IMod content, StreamWriter sw)
519
542
mod = mapper . Map < IMod > ( mod ) ;
520
543
mod . FileName = descriptorType == DescriptorType . JsonMetadata ? null : string . Empty ;
521
544
}
522
- using var sw = new StreamWriter ( stream , leaveOpen : true ) ;
545
+
546
+ await using var sw = new StreamWriter ( stream , leaveOpen : true ) ;
523
547
if ( descriptorType == DescriptorType . DescriptorMod )
524
548
{
525
549
await serializeDescriptorMod ( mod , sw ) ;
@@ -528,6 +552,7 @@ static async Task serializeJsonDescriptorMod(IMod content, StreamWriter sw)
528
552
{
529
553
await serializeJsonDescriptorMod ( mod , sw ) ;
530
554
}
555
+
531
556
await sw . FlushAsync ( ) ;
532
557
return true ;
533
558
}
@@ -545,6 +570,7 @@ private bool IsAdmin()
545
570
using var identity = WindowsIdentity . GetCurrent ( ) ;
546
571
return new WindowsPrincipal ( identity ) . IsInRole ( WindowsBuiltInRole . Administrator ) ;
547
572
}
573
+
548
574
return false ;
549
575
}
550
576
catch
@@ -597,7 +623,7 @@ private class JsonMetadata
597
623
/// </summary>
598
624
/// <value>The relationships.</value>
599
625
[ JsonProperty ( "relationships" , NullValueHandling = NullValueHandling . Include ) ]
600
- public List < string > Relationships { get ; set ; }
626
+ public List < Dictionary < string , object > > Relationships { get ; set ; }
601
627
602
628
/// <summary>
603
629
/// Gets or sets the short description.
0 commit comments