@@ -127,7 +127,7 @@ public static async Task<GameRes> AddGameFolder(string local, string? name, stri
127127 /// <param name="arg">导入参数</param>
128128 /// <param name="st">输入流</param>
129129 /// <returns>导入结果</returns>
130- private static async Task < GameRes > ModPackAsync ( PackType type , string ? group , Stream st ,
130+ private static async Task < GameRes > ModPackAsync ( PackType type , string ? group , ZipArchive zip , List < ZipArchiveEntry > unselects ,
131131 IOverGameGui ? gui , IAddGui ? packgui , CancellationToken token )
132132 {
133133 packgui ? . SetState ( AddState . ReadInfo ) ;
@@ -136,8 +136,8 @@ private static async Task<GameRes> ModPackAsync(PackType type, string? group, St
136136
137137 using IModPackWork work = type switch
138138 {
139- PackType . CurseForge => new CurseForgeWork ( st , gui , packgui , token ) ,
140- PackType . Modrinth => new ModrinthWork ( st , gui , packgui , token ) ,
139+ PackType . CurseForge => new CurseForgeWork ( zip , gui , packgui , token ) ,
140+ PackType . Modrinth => new ModrinthWork ( zip , gui , packgui , token ) ,
141141 _ => throw new ArgumentOutOfRangeException ( nameof ( type ) )
142142 } ;
143143
@@ -162,7 +162,7 @@ private static async Task<GameRes> ModPackAsync(PackType type, string? group, St
162162 packgui ? . SetNow ( 2 , 5 ) ;
163163 packgui ? . SetNowSub ( 0 , 1 ) ;
164164
165- if ( ! await work . Unzip ( ) || token . IsCancellationRequested )
165+ if ( ! await work . Unzip ( unselects ) || token . IsCancellationRequested )
166166 {
167167 return new GameRes ( ) { Game = game } ;
168168 }
@@ -198,13 +198,13 @@ private static async Task<GameRes> ModPackAsync(PackType type, string? group, St
198198 /// <param name="arg">导入参数</param>
199199 /// <param name="st">输入流</param>
200200 /// <returns>导入结果</returns>
201- private static async Task < GameRes > ColorMCAsync ( Stream st , IOverGameGui ? gui , IAddGui ? packgui )
201+ private static async Task < GameRes > ColorMCAsync ( ZipArchive zip , List < ZipArchiveEntry > unselect , IOverGameGui ? gui ,
202+ IAddGui ? packgui )
202203 {
203204 packgui ? . SetState ( AddState . ReadInfo ) ;
204205 //直接解压
205- using var zFile = ZipArchive . Open ( st ) ;
206206 GameSettingObj ? game = null ;
207- if ( zFile . Entries . FirstOrDefault ( item => item . Key == Names . NameGameFile ) is { } item )
207+ if ( zip . Entries . FirstOrDefault ( item => item . Key == Names . NameGameFile ) is { } item )
208208 {
209209 using var stream = item . OpenEntryStream ( ) ;
210210 game = JsonUtils . ToObj ( stream , JsonType . GameSettingObj ) ;
@@ -224,24 +224,25 @@ private static async Task<GameRes> ColorMCAsync(Stream st, IOverGameGui? gui, IA
224224 }
225225
226226 //复制文件
227- var size = zFile . Entries . Count ;
227+ var size = zip . Entries . Count ;
228228 var index = 0 ;
229229
230230 packgui ? . SetState ( AddState . Unzip ) ;
231231 packgui ? . SetNowSub ( index , size ) ;
232232
233- foreach ( var e in zFile . Entries )
233+ foreach ( var e in zip . Entries )
234234 {
235- if ( ! FunctionUtils . IsFile ( e ) )
235+ if ( unselect . Contains ( e ) || ! FunctionUtils . IsFile ( e ) )
236236 {
237237 index ++ ;
238238 continue ;
239239 }
240+
240241 packgui ? . SetNowSub ( index , size ) ;
241242 packgui ? . SetSubText ( e . Key ! ) ;
242243 index ++ ;
243244 using var stream = e . OpenEntryStream ( ) ;
244- string file = Path . GetFullPath ( game . GetBasePath ( ) + "/" + e . Key ) ;
245+ string file = Path . GetFullPath ( game . GetBasePath ( ) + Path . DirectorySeparatorChar + e . Key ) ;
245246 await PathHelper . WriteBytesAsync ( file , stream ) ;
246247 }
247248
@@ -258,14 +259,13 @@ private static async Task<GameRes> ColorMCAsync(Stream st, IOverGameGui? gui, IA
258259 /// <param name="st">输入流</param>
259260 /// <returns>导入结果</returns>
260261 private static async Task < GameRes > MMCAsync ( string ? name , string ? group , string file ,
261- Stream st , IOverGameGui ? gui , IAddGui ? packgui )
262+ ZipArchive zip , List < ZipArchiveEntry > unselect , IOverGameGui ? gui , IAddGui ? packgui )
262263 {
263264 packgui ? . SetState ( AddState . ReadInfo ) ;
264- using var zFile = ZipArchive . Open ( st ) ;
265265 string path = "" ;
266266 MMCObj ? mmc = null ;
267267 Dictionary < string , string > ? mmc1 = null ;
268- foreach ( var e in zFile . Entries )
268+ foreach ( var e in zip . Entries )
269269 {
270270 if ( ! FunctionUtils . IsFile ( e ) )
271271 {
@@ -321,15 +321,15 @@ private static async Task<GameRes> MMCAsync(string? name, string? group, string
321321 return new GameRes ( ) ;
322322 }
323323
324- var size = zFile . Entries . Count ;
324+ var size = zip . Entries . Count ;
325325 var index = 0 ;
326326
327327 packgui ? . SetState ( AddState . Unzip ) ;
328328 packgui ? . SetNowSub ( index , size ) ;
329329
330- foreach ( var e in zFile . Entries )
330+ foreach ( var e in zip . Entries )
331331 {
332- if ( ! FunctionUtils . IsFile ( e ) )
332+ if ( unselect . Contains ( e ) || ! FunctionUtils . IsFile ( e ) )
333333 {
334334 index ++ ;
335335 continue ;
@@ -365,18 +365,18 @@ private static async Task<GameRes> MMCAsync(string? name, string? group, string
365365 /// <param name="arg">导入参数</param>
366366 /// <param name="st">输入流</param>
367367 /// <returns>导入结果</returns>
368- private static async Task < GameRes > HMCLAsync ( string ? name , string ? group , string file , Stream st , IOverGameGui ? gui , IAddGui ? packgui )
368+ private static async Task < GameRes > HMCLAsync ( string ? name , string ? group , string file , ZipArchive zip ,
369+ List < ZipArchiveEntry > ? unselect , IOverGameGui ? gui , IAddGui ? packgui )
369370 {
370371 packgui ? . SetState ( AddState . ReadInfo ) ;
371- using var zFile = ZipArchive . Open ( st ) ;
372372 HMCLObj ? obj = null ;
373373 CurseForgePackObj ? obj1 = null ;
374- if ( zFile . Entries . FirstOrDefault ( item => item . Key == Names . NameHMCLFile ) is { } item )
374+ if ( zip . Entries . FirstOrDefault ( item => item . Key == Names . NameHMCLFile ) is { } item )
375375 {
376376 using var stream = item . OpenEntryStream ( ) ;
377377 obj = JsonUtils . ToObj ( stream , JsonType . HMCLObj ) ;
378378 }
379- if ( zFile . Entries . FirstOrDefault ( item => item . Key == Names . NameManifestFile ) is { } item1 )
379+ if ( zip . Entries . FirstOrDefault ( item => item . Key == Names . NameManifestFile ) is { } item1 )
380380 {
381381 using var stream = item1 . OpenEntryStream ( ) ;
382382 obj1 = JsonUtils . ToObj ( stream , JsonType . CurseForgePackObj ) ;
@@ -415,15 +415,15 @@ private static async Task<GameRes> HMCLAsync(string? name, string? group, string
415415 overrides = obj1 . Overrides ;
416416 }
417417
418- var size = zFile . Entries . Count ;
418+ var size = zip . Entries . Count ;
419419 var index = 0 ;
420420
421421 packgui ? . SetState ( AddState . Unzip ) ;
422422 packgui ? . SetNowSub ( index , size ) ;
423423
424- foreach ( var e in zFile . Entries )
424+ foreach ( var e in zip . Entries )
425425 {
426- if ( ! FunctionUtils . IsFile ( e ) )
426+ if ( unselect . Contains ( e ) || ! FunctionUtils . IsFile ( e ) )
427427 {
428428 index ++ ;
429429 continue ;
@@ -453,7 +453,8 @@ private static async Task<GameRes> HMCLAsync(string? name, string? group, string
453453 /// </summary>
454454 /// <param name="st">输入流</param>
455455 /// <returns>导入结果</returns>
456- private static async Task < GameRes > UnzipAsync ( string ? name , string ? group , string file , Stream st , IOverGameGui ? gui , IAddGui ? packgui )
456+ private static async Task < GameRes > UnzipAsync ( string ? name , string ? group , string file , ZipArchive zip ,
457+ List < ZipArchiveEntry > unselect , IOverGameGui ? gui , IAddGui ? packgui )
457458 {
458459 packgui ? . SetState ( AddState . ReadInfo ) ;
459460
@@ -473,16 +474,15 @@ private static async Task<GameRes> UnzipAsync(string? name, string? group, strin
473474 return new GameRes ( ) ;
474475 }
475476
476- using var zFile = ZipArchive . Open ( st ) ;
477- var size = zFile . Entries . Count ;
477+ var size = zip . Entries . Count ;
478478 var index = 0 ;
479479
480480 packgui ? . SetState ( AddState . Unzip ) ;
481481 packgui ? . SetNowSub ( index , size ) ;
482482
483- foreach ( var e in zFile . Entries )
483+ foreach ( var e in zip . Entries )
484484 {
485- if ( ! FunctionUtils . IsFile ( e ) )
485+ if ( unselect . Contains ( e ) || ! FunctionUtils . IsFile ( e ) )
486486 {
487487 index ++ ;
488488 continue ;
@@ -542,13 +542,13 @@ private static async Task<GameRes> UnzipAsync(string? name, string? group, strin
542542
543543 return new GameRes { State = true , Game = game } ;
544544 }
545-
545+
546546 /// <summary>
547547 /// 导入整合包
548548 /// </summary>
549549 /// <returns>导入结果</returns>
550550 public static async Task < GameRes > InstallZip ( string ? name , string ? group , string file ,
551- PackType type , IOverGameGui ? gui , IAddGui ? packgui , CancellationToken token = default )
551+ PackType type , List < ZipArchiveEntry > unselects , IOverGameGui ? gui , IAddGui ? packgui , CancellationToken token = default )
552552 {
553553 GameRes ? res1 = null ;
554554 Stream ? st = null ;
@@ -577,19 +577,11 @@ public static async Task<GameRes> InstallZip(string? name, string? group, string
577577 }
578578 if ( st == null )
579579 {
580- return new ( ) ;
580+ return new GameRes ( ) ;
581581 }
582- res1 = type switch
583- {
584- PackType . ColorMC => await ColorMCAsync ( st , gui , packgui ) ,
585- PackType . CurseForge or PackType . Modrinth => await ModPackAsync ( type , group , st , gui , packgui , token ) ,
586- PackType . MMC => await MMCAsync ( name , group , file , st , gui , packgui ) ,
587- PackType . HMCL => await HMCLAsync ( name , group , file , st , gui , packgui ) ,
588- PackType . ZipPack => await UnzipAsync ( name , group , file , st , gui , packgui ) ,
589- _ => null
590- } ;
582+ using var zip = ZipArchive . Open ( st ) ;
591583
592- return res1 ?? new GameRes ( ) ;
584+ return await InstallZip ( name , group , file , zip , type , unselects , gui , packgui , token ) ;
593585 }
594586 catch ( Exception e )
595587 {
@@ -607,6 +599,40 @@ public static async Task<GameRes> InstallZip(string? name, string? group, string
607599
608600 return new GameRes ( ) ;
609601 }
602+
603+ /// <summary>
604+ /// 导入整合包
605+ /// </summary>
606+ /// <returns>导入结果</returns>
607+ public static async Task < GameRes > InstallZip ( string ? name , string ? group , string file , ZipArchive zip ,
608+ PackType type , List < ZipArchiveEntry > unselects , IOverGameGui ? gui , IAddGui ? packgui , CancellationToken token = default )
609+ {
610+ GameRes ? res1 = null ;
611+ try
612+ {
613+ res1 = type switch
614+ {
615+ PackType . ColorMC => await ColorMCAsync ( zip , unselects , gui , packgui ) ,
616+ PackType . CurseForge or PackType . Modrinth => await ModPackAsync ( type , group , zip , unselects , gui , packgui , token ) ,
617+ PackType . MMC => await MMCAsync ( name , group , file , zip , unselects , gui , packgui ) ,
618+ PackType . HMCL => await HMCLAsync ( name , group , file , zip , unselects , gui , packgui ) ,
619+ PackType . ZipPack => await UnzipAsync ( name , group , file , zip , unselects , gui , packgui ) ,
620+ _ => null
621+ } ;
622+
623+ return res1 ?? new GameRes ( ) ;
624+ }
625+ catch ( Exception e )
626+ {
627+ ColorMCCore . OnError ( new InstallModPackErrorEventArgs ( file , e ) ) ;
628+ }
629+ if ( res1 ? . State == false && res1 ? . Game is { } game )
630+ {
631+ await game . RemoveAsync ( ) ;
632+ }
633+
634+ return new GameRes ( ) ;
635+ }
610636
611637 /// <summary>
612638 /// 下载并安装Modrinth整合包
@@ -624,17 +650,19 @@ public static async Task<GameRes> InstallModrinth(string? group,
624650 return new GameRes ( ) ;
625651 }
626652
627- var res2 = await InstallZip ( null , group , item . Local , PackType . Modrinth , gui , packgui ) ;
628- if ( res2 . State )
653+ var res2 = await InstallZip ( null , group , item . Local , PackType . Modrinth , [ ] , gui , packgui ) ;
654+ if ( ! res2 . State )
629655 {
630- res2 . Game ! . PID = data . ProjectId ;
631- res2 . Game . FID = data . Id ;
632- res2 . Game . Save ( ) ;
656+ return res2 ;
657+ }
633658
634- if ( icon != null )
635- {
636- await res2 . Game . SetGameIconFromUrlAsync ( icon ) ;
637- }
659+ res2 . Game ! . PID = data . ProjectId ;
660+ res2 . Game . FID = data . Id ;
661+ res2 . Game . Save ( ) ;
662+
663+ if ( icon != null )
664+ {
665+ await res2 . Game . SetGameIconFromUrlAsync ( icon ) ;
638666 }
639667
640668 return res2 ;
@@ -668,7 +696,7 @@ public static async Task<GameRes> InstallCurseForge(string? group, FileItemObj i
668696 return new GameRes ( ) ;
669697 }
670698
671- var res2 = await InstallZip ( null , group , item . Local , PackType . CurseForge , gui , packgui , token ) ;
699+ var res2 = await InstallZip ( null , group , item . Local , PackType . CurseForge , [ ] , gui , packgui , token ) ;
672700 if ( res2 . State && ! token . IsCancellationRequested )
673701 {
674702 res2 . Game ! . PID = modid ;
0 commit comments