@@ -361,7 +361,7 @@ private List<string> InstallModule(CkanModule
361361 var filters = config . GetGlobalInstallFilters ( instance . Game )
362362 . Concat ( instance . InstallFilters )
363363 . ToHashSet ( ) ;
364- var groups = FindInstallableFiles ( module , zipfile , instance , instance . Game )
364+ var groups = FindInstallableFiles ( module , zipfile , instance . Game )
365365 // Skip the file if it's a ckan file, these should never be copied to GameData
366366 . Where ( instF => ! IsInternalCkan ( instF . source ) )
367367 // Check whether each file matches any installation filter
@@ -377,7 +377,7 @@ private List<string> InstallModule(CkanModule
377377 // Find where we're installing identifier.optionalversion.dll
378378 // (file name might not be an exact match with manually installed)
379379 var dllFolders = files
380- . Select ( f => instance . ToRelativeGameDir ( f . destination ) )
380+ . Select ( f => f . destination )
381381 . Where ( relPath => instance . DllPathToIdentifier ( relPath ) == module . identifier )
382382 . Select ( Path . GetDirectoryName )
383383 . ToHashSet ( ) ;
@@ -409,7 +409,7 @@ private List<string> InstallModule(CkanModule
409409 {
410410 var fileMsg = string . Join ( Environment . NewLine ,
411411 conflicting . OrderBy ( tuple => tuple . same )
412- . Select ( tuple => $ "- { instance . ToRelativeGameDir ( tuple . file . destination ) } ({ ( tuple . same ? Properties . Resources . ModuleInstallerFileSame : Properties . Resources . ModuleInstallerFileDifferent ) } )") ) ;
412+ . Select ( tuple => $ "- { tuple . file . destination } ({ ( tuple . same ? Properties . Resources . ModuleInstallerFileSame : Properties . Resources . ModuleInstallerFileDifferent ) } )") ) ;
413413 if ( User . RaiseYesNoDialog ( string . Format ( Properties . Resources . ModuleInstallerOverwrite ,
414414 module . name , fileMsg ) ) )
415415 {
@@ -431,8 +431,8 @@ private List<string> InstallModule(CkanModule
431431 throw new CancelledActionKraken ( ) ;
432432 }
433433 log . DebugFormat ( "Copying {0}" , file . source . Name ) ;
434- var path = InstallFile( zipfile , file . source , file . destination , file . makedir ,
435- candidateDuplicates ? . GetValueOrDefault ( ( relPath : instance . ToRelativeGameDir ( file . destination ) ,
434+ var path = InstallFile( zipfile , file . source , instance . ToAbsoluteGameDir ( file . destination ) , file . makedir ,
435+ candidateDuplicates ? . GetValueOrDefault ( ( relPath : file . destination ,
436436 size : file . source . Size ) )
437437 ?? Array . Empty < string > ( ) ,
438438 fileProgress ) ;
@@ -479,21 +479,20 @@ public static bool IsInternalCkan(ZipEntry ze)
479479 IEnumerable < InstallableFile > files ,
480480 Registry registry )
481481 => files . Where ( file => ! file . source . IsDirectory
482- && File . Exists ( file . destination )
483- && registry . FileOwner ( instance . ToRelativeGameDir ( file . destination ) ) == null )
484- . Select ( file =>
485- {
486- log . DebugFormat ( "Comparing {0}" , file . destination ) ;
487- using ( Stream zipStream = zip . GetInputStream ( file . source ) )
488- using ( FileStream curFile = new FileStream ( file . destination ,
489- FileMode . Open ,
490- FileAccess . Read ) )
491- {
492- return ( file ,
493- same : file . source . Size == curFile . Length
494- && StreamsEqual ( zipStream , curFile ) ) ;
495- }
496- } ) ;
482+ && registry . FileOwner ( file . destination ) == null )
483+ . Select( file => ( file , absPath : instance . ToAbsoluteGameDir ( file . destination ) ) )
484+ . Where( tuple => File. Exists( tuple . absPath ) )
485+ . Select( tuple =>
486+ {
487+ log . DebugFormat ( "Comparing { 0 } ", tuple . absPath ) ;
488+ using ( Stream zipStream = zip. GetInputStream( tuple . file . source ) )
489+ using ( FileStream curFile = File. OpenRead( tuple . absPath ) )
490+ {
491+ return ( tuple . file ,
492+ same : tuple . file . source . Size == curFile . Length
493+ && StreamsEqual ( zipStream , curFile ) ) ;
494+ }
495+ } ) ;
497496
498497 /// <summary>
499498 /// Compare the contents of two streams
@@ -547,10 +546,10 @@ private static bool StreamsEqual(Stream s1, Stream s2)
547546 private void DeleteConflictingFiles ( IEnumerable < InstallableFile > files )
548547 {
549548 var txFileMgr = new TxFileManager( instance. CkanDir) ;
550- foreach ( InstallableFile file in files)
549+ foreach ( var absPath in files. Select ( f => instance . ToAbsoluteGameDir ( f . destination ) ) )
551550 {
552- log. DebugFormat ( "Trying to delete {0}" , file . destination ) ;
553- txFileMgr. Delete ( file . destination ) ;
551+ log. DebugFormat( "Trying to delete { 0 } ", absPath ) ;
552+ txFileMgr . Delete ( absPath ) ;
554553 }
555554 }
556555
@@ -566,74 +565,31 @@ private void DeleteConflictingFiles(IEnumerable<InstallableFile> files)
566565 ///
567566 /// Throws a BadMetadataKraken if the stanza resulted in no files being returned.
568567 /// </summary>
569-
570- public static List< InstallableFile > FindInstallableFiles ( CkanModule module ,
571- ZipFile zipfile ,
572- GameInstance inst )
573- => FindInstallableFiles ( module , zipfile , inst , inst . Game ) ;
574-
575- public static List< InstallableFile > FindInstallableFiles ( CkanModule module ,
576- ZipFile zipfile ,
577- IGame game )
578- => FindInstallableFiles ( module , zipfile , null , game ) ;
579-
580- private static List< InstallableFile > FindInstallableFiles ( CkanModule module ,
581- ZipFile zipfile ,
582- GameInstance ? inst ,
583- IGame game )
584- {
585- try
586- {
587- // Use the provided stanzas, or use the default install stanza if they're absent.
588- return module. install is { Length: > 0 }
589- ? module . install
590- . SelectMany ( stanza => stanza . FindInstallableFiles ( zipfile , inst ) )
591- . ToList ( )
592- : ModuleInstallDescriptor . DefaultInstallStanza ( game ,
593- module . identifier )
594- . FindInstallableFiles ( zipfile , inst ) ;
595- }
596- catch ( BadMetadataKraken kraken )
597- {
598- // Decorate our kraken with the current module, as the lower-level
599- // methods won't know it.
600- kraken . module ??= module ;
601- throw ;
602- }
603- }
568+ public static IEnumerable< InstallableFile> FindInstallableFiles( CkanModule module,
569+ ZipFile zipfile ,
570+ IGame game )
571+ // Use the provided stanzas, or use the default install stanza if they're absent.
572+ => module. GetInstallStanzas ( game )
573+ . SelectMany( stanza => stanza. FindInstallableFiles( module, zipfile , game ) )
574+ . ToArray( ) ;
604575
605576 /// <summary>
606577 /// Given a module and a path to a zipfile, returns all the files that would be installed
607578 /// from that zip for this module.
608579 ///
609- /// This *will* throw an exception if the file does not exist.
610- ///
611580 /// Throws a BadMetadataKraken if the stanza resulted in no files being returned.
612581 ///
613582 /// If a KSP instance is provided, it will be used to generate output paths, otherwise these will be null.
614583 /// </summary>
615- // TODO: Document which exception!
616- public static List< InstallableFile> FindInstallableFiles( CkanModule module ,
617- string zip_filename ,
618- IGame game )
584+ public static IEnumerable< InstallableFile> FindInstallableFiles( CkanModule module,
585+ string zip_filename ,
586+ IGame game )
619587 {
620588 // `using` makes sure our zipfile gets closed when we exit this block.
621589 using ( ZipFile zipfile = new ZipFile ( zip_filename ) )
622590 {
623591 log. DebugFormat( "Searching { 0 } using { 1 } as module", zip_filename , module ) ;
624- return FindInstallableFiles( module , zipfile , null , game ) ;
625- }
626- }
627-
628- public static List< InstallableFile > FindInstallableFiles ( CkanModule module ,
629- string zip_filename ,
630- GameInstance inst )
631- {
632- // `using` makes sure our zipfile gets closed when we exit this block.
633- using ( ZipFile zipfile = new ZipFile ( zip_filename ) )
634- {
635- log . DebugFormat ( "Searching {0} using {1} as module" , zip_filename , module ) ;
636- return FindInstallableFiles( module , zipfile , inst ) ;
592+ return FindInstallableFiles ( module, zipfile , game ) ;
637593 }
638594 }
639595
@@ -653,10 +609,10 @@ public static List<InstallableFile> FindInstallableFiles(CkanModule module,
653609 filters ) ;
654610
655611 private static IEnumerable < ( string path , bool dir , bool exists ) > GetModuleContents (
656- GameInstance instance ,
657- IReadOnlyCollection < string > installed ,
658- HashSet < string > parents ,
659- HashSet < string > filters )
612+ GameInstance instance ,
613+ IEnumerable < string > installed ,
614+ HashSet < string > parents ,
615+ HashSet < string > filters )
660616 => installed . Where ( f => ! filters . Any ( filt => f . Contains ( filt ) ) )
661617 . GroupBy( parents . Contains )
662618 . SelectMany( grp =>
@@ -677,20 +633,18 @@ public static List<InstallableFile> FindInstallableFiles(CkanModule module,
677633 CkanModule module ,
678634 HashSet < string > filters )
679635 => ( Cache . GetCachedFilename ( module ) is string filename
680- ? GetModuleContents ( instance ,
681- Utilities . DefaultIfThrows (
682- ( ) => FindInstallableFiles ( module , filename , instance ) ) ,
636+ ? GetModuleContents( Utilities . DefaultIfThrows (
637+ ( ) => FindInstallableFiles ( module , filename , instance . Game ) ) ,
683638 filters )
684639 : null )
685640 ?? Enumerable . Empty < ( string path , bool dir , bool exists ) > ( ) ;
686641
687642 private static IEnumerable < ( string path , bool dir , bool exists ) > ? GetModuleContents (
688- GameInstance instance ,
689643 IEnumerable < InstallableFile > ? installable ,
690644 HashSet < string > filters )
691645 => installable ? . Where ( instF => ! filters . Any ( filt => instF . destination != null
692646 && instF . destination . Contains ( filt ) ) )
693- . Select ( f => ( path : instance . ToRelativeGameDir ( f . destination ) ,
647+ . Select( f => ( path : f . destination ,
694648 dir : f . source . IsDirectory ,
695649 exists : true) ) ;
696650
0 commit comments