@@ -13,28 +13,31 @@ public class ModImportManager(
1313 DuplicateManager duplicates ,
1414 ModNormalizer modNormalizer ,
1515 MigrationManager migrationManager ,
16- FileCompactor compactor ) : IDisposable , Luna . IService
16+ FileCompactor compactor ) : IDisposable , IService
1717{
18- private readonly ConcurrentQueue < string [ ] > _modsToUnpack = new ( ) ;
18+ private readonly Dictionary < string , DateTime > _uniqueModsToUnpack = new ( StringComparer . OrdinalIgnoreCase ) ;
19+ internal readonly Queue < List < string > > ModsToUnpack = new ( ) ;
1920
2021 /// <summary> Mods need to be added thread-safely outside of iteration. </summary>
2122 private readonly ConcurrentQueue < DirectoryInfo > _modsToAdd = new ( ) ;
2223
2324 private TexToolsImporter ? _import ;
2425
25-
26- internal IEnumerable < string [ ] > ModBatches
27- => _modsToUnpack ;
28-
2926 internal IEnumerable < DirectoryInfo > AddableMods
3027 => _modsToAdd ;
3128
32-
3329 public void TryUnpacking ( )
3430 {
35- if ( Importing && _import ! . State is not ImporterState . Done || ! _modsToUnpack . TryDequeue ( out var newMods ) )
31+ if ( Importing && _import ! . State is not ImporterState . Done )
3632 return ;
3733
34+ List < string > newMods ;
35+ lock ( ModsToUnpack )
36+ {
37+ if ( ! ModsToUnpack . TryDequeue ( out newMods ! ) )
38+ return ;
39+ }
40+
3841 var files = newMods . Where ( s =>
3942 {
4043 if ( File . Exists ( s ) )
@@ -63,12 +66,38 @@ public bool IsImporting([NotNullWhen(true)] out TexToolsImporter? importer)
6366 }
6467
6568 public void AddUnpack ( IEnumerable < string > paths )
66- => AddUnpack ( paths . ToArray ( ) ) ;
69+ => AddUnpack ( paths . ToList ( ) ) ;
6770
68- public void AddUnpack ( params string [ ] paths )
71+ public void AddUnpack ( params List < string > paths )
6972 {
70- Penumbra . Log . Debug ( $ "Adding mods to install: { string . Join ( "\n \t " , paths ) } ") ;
71- _modsToUnpack . Enqueue ( paths ) ;
73+ lock ( ModsToUnpack )
74+ {
75+ var now = DateTime . UtcNow ;
76+ var nowOffset = now . AddSeconds ( - 2 ) ;
77+ for ( var i = 0 ; i < paths . Count ; ++ i )
78+ {
79+ var path = paths [ i ] ;
80+ if ( _uniqueModsToUnpack . TryGetValue ( path , out var lastInstallTime ) )
81+ {
82+ _uniqueModsToUnpack [ path ] = now ;
83+ if ( lastInstallTime >= nowOffset )
84+ {
85+ paths . RemoveAt ( i -- ) ;
86+ Penumbra . Log . Debug ( $ "Skipped installing mod { path } since it was last installed { ( lastInstallTime - now ) . TotalSeconds } seconds ago.") ;
87+ }
88+ }
89+ else
90+ {
91+ _uniqueModsToUnpack . Add ( path , now ) ;
92+ }
93+ }
94+
95+ if ( paths . Count > 0 )
96+ {
97+ Penumbra . Log . Debug ( $ "Adding mods to install: { string . Join ( "\n \t " , paths ) } ") ;
98+ ModsToUnpack . Enqueue ( paths ) ;
99+ }
100+ }
72101 }
73102
74103 public void ClearImport ( )
@@ -93,7 +122,11 @@ public void Dispose()
93122 {
94123 ClearImport ( ) ;
95124 _modsToAdd . Clear ( ) ;
96- _modsToUnpack . Clear ( ) ;
125+ lock ( ModsToUnpack )
126+ {
127+ ModsToUnpack . Clear ( ) ;
128+ _uniqueModsToUnpack . Clear ( ) ;
129+ }
97130 }
98131
99132 /// <summary>
0 commit comments