66using CollapseLauncher . Helper . StreamUtility ;
77using Hi3Helper ;
88using Hi3Helper . Data ;
9- using Hi3Helper . EncTool . Hashes ;
109using Hi3Helper . EncTool . Parser . AssetIndex ;
1110using Hi3Helper . Plugin . Core . Management ;
1211using Hi3Helper . SentryHelper ;
2019using System . Diagnostics . CodeAnalysis ;
2120using System . IO ;
2221using System . Linq ;
23- using System . Security . Cryptography ;
22+ using System . Threading ;
2423using System . Threading . Tasks ;
24+ // ReSharper disable AccessToDisposedClosure
2525// ReSharper disable CommentTypo
2626// ReSharper disable IdentifierTypo
2727// ReSharper disable InconsistentNaming
@@ -132,7 +132,7 @@ public virtual bool IsGameVersionMatch()
132132 // But if the game version matches, then return to true.
133133 => GameVersionInstalled == GameVersionAPI ;
134134
135- public virtual async ValueTask < bool > IsPluginVersionsMatch ( )
135+ public virtual Task < bool > IsPluginVersionsMatch ( )
136136 {
137137#if ! MHYPLUGINSUPPORT
138138 return true ;
@@ -142,17 +142,12 @@ public virtual async ValueTask<bool> IsPluginVersionsMatch()
142142 Dictionary < string , GameVersion > pluginVersionsInstalled = PluginVersionsInstalled ;
143143
144144 // If the plugin version installed is null, return true as it doesn't need to check
145- if ( pluginVersionsInstalled . Count == 0 )
145+ if ( pluginVersions . Count == 0 )
146146 {
147- return true ;
148- }
149-
150- // Compare each entry in the dict
151- if ( pluginVersions . Count != pluginVersionsInstalled . Count )
152- {
153- return false ;
147+ return Task . FromResult ( true ) ;
154148 }
155149
150+ // Check each of the version
156151 MismatchPlugin . Clear ( ) ;
157152 foreach ( KeyValuePair < string , GameVersion > pluginVersion in pluginVersions )
158153 {
@@ -163,21 +158,15 @@ public virtual async ValueTask<bool> IsPluginVersionsMatch()
163158 }
164159
165160 // Uh-oh, we need to calculate the file hash.
166- MismatchPlugin = await CheckPluginUpdate ( pluginVersion . Key ) ;
167- if ( MismatchPlugin . Count != 0 )
168- {
169- return false ;
170- }
161+ MismatchPlugin = CheckPluginUpdate ( pluginVersion . Key ) ;
171162 }
172163
173- // Update cached plugin versions
174- PluginVersionsInstalled = PluginVersionsAPI ;
175-
176- return true ;
164+ // Return based on how many mismatched plugin found
165+ return Task . FromResult ( MismatchPlugin . Count == 0 ) ;
177166#endif
178167 }
179168
180- public virtual async ValueTask < bool > IsSdkVersionsMatch ( )
169+ public virtual async Task < bool > IsSdkVersionsMatch ( )
181170 {
182171#if ! MHYPLUGINSUPPORT
183172 return true ;
@@ -226,7 +215,7 @@ protected virtual bool IsGameInstalledInner([NotNullWhen(true)] string? executab
226215 }
227216
228217 // Check if the executable file exist and has the size at least > 64 KiB. If not, then return as false.
229- FileInfo execFileInfo = new FileInfo ( Path . Combine ( GameDirPath , executableName ) ) ;
218+ FileInfo execFileInfo = new ( Path . Combine ( GameDirPath , executableName ) ) ;
230219
231220 // Check if the vendor type exist. If not, then return false
232221 if ( VendorTypeProp . GameName == null || string . IsNullOrEmpty ( VendorTypeProp . VendorType ) )
@@ -299,7 +288,10 @@ public async ValueTask<GameInstallStateEnum> GetGameState()
299288 }
300289
301290 // If the plugin version is not match, return that it's installed but have plugin updates.
302- if ( ! await IsPluginVersionsMatch ( ) || ! await IsSdkVersionsMatch ( ) )
291+ Task < bool > pluginMatchTask = IsPluginVersionsMatch ( ) ;
292+ Task < bool > sdkMatchTask = IsSdkVersionsMatch ( ) ;
293+ bool [ ] isBothDepTaskMatches = await Task . WhenAll ( pluginMatchTask , sdkMatchTask ) ;
294+ if ( ! isBothDepTaskMatches . All ( x => x ) )
303295 {
304296 return GameInstallStateEnum . InstalledHavePlugin ;
305297 }
@@ -389,45 +381,61 @@ public virtual async ValueTask<bool> EnsureGameConfigIniCorrectiveness(UIElement
389381 return false ;
390382 }
391383
392- public virtual async ValueTask < bool > CheckSdkUpdate ( string validatePath )
384+ public virtual ValueTask < bool > CheckSdkUpdate ( string validatePath )
393385 {
394386 try
395387 {
396- using StreamReader reader = new StreamReader ( validatePath ) ;
397- while ( await reader . ReadLineAsync ( ) is { } line )
388+ if ( ! File . Exists ( validatePath ) )
398389 {
399- if ( string . IsNullOrEmpty ( line ) )
400- continue ;
390+ return ValueTask . FromResult ( false ) ;
391+ }
401392
402- PkgVersionProperties ? pkgVersion = line . Deserialize ( CoreLibraryJsonContext . Default . PkgVersionProperties ) ;
393+ long totalSize = 0 ;
394+ long existingSize = 0 ;
403395
404- if ( pkgVersion == null )
396+ string gamePath = GameDirPath ;
397+ foreach ( PkgVersionProperties pkg in EnumerateList ( ) )
398+ {
399+ Interlocked . Add ( ref totalSize , pkg . fileSize ) ;
400+
401+ string filePath = Path . Combine ( gamePath , pkg . remoteName ?? "" ) ;
402+ FileInfo fileInfo = new ( filePath ) ;
403+ if ( fileInfo . Exists )
405404 {
406- continue ;
405+ Interlocked . Add ( ref existingSize , fileInfo . Length ) ;
407406 }
407+ }
408408
409- string filePath = Path . Combine ( GameDirPath , pkgVersion . remoteName ) ;
410- if ( ! File . Exists ( filePath ) )
411- return false ;
409+ return ValueTask . FromResult ( totalSize == existingSize ) ;
412410
413- await using FileStream fs = new FileStream ( filePath , FileMode . Open , FileAccess . Read ) ;
414- byte [ ] hashArray = await CryptoHashUtility < MD5 > . ThreadSafe . GetHashFromStreamAsync ( fs ) ;
415- string md5 = Convert . ToHexStringLower ( hashArray ) ;
416- if ( ! md5 . Equals ( pkgVersion . md5 , StringComparison . OrdinalIgnoreCase ) )
417- return false ;
418- }
411+ IEnumerable < PkgVersionProperties > EnumerateList ( )
412+ {
413+ using StreamReader reader = File . OpenText ( validatePath ) ;
414+ while ( reader . ReadLine ( ) is { } line )
415+ {
416+ PkgVersionProperties ? pkgVersion = line . Deserialize ( CoreLibraryJsonContext . Default . PkgVersionProperties ) ;
417+ if ( pkgVersion == null )
418+ {
419+ continue ;
420+ }
419421
420- return true ;
422+ yield return pkgVersion ;
423+ }
424+ }
425+ }
426+ catch ( OperationCanceledException )
427+ {
428+ return ValueTask . FromResult ( false ) ;
421429 }
422430 catch ( Exception ex )
423431 {
424432 Logger . LogWriteLine ( $ "Failed while checking the SDK file update\r \n { ex } ", LogType . Error , true ) ;
425- await SentryHelper . ExceptionHandlerAsync ( ex , SentryHelper . ExceptionType . UnhandledOther ) ;
426- return false ;
433+ SentryHelper . ExceptionHandler ( ex , SentryHelper . ExceptionType . UnhandledOther ) ;
434+ return ValueTask . FromResult ( true ) ;
427435 }
428436 }
429437
430- protected virtual async Task < List < HypPluginPackageInfo > > CheckPluginUpdate ( string pluginKey )
438+ protected virtual List < HypPluginPackageInfo > CheckPluginUpdate ( string pluginKey )
431439 {
432440 List < HypPluginPackageInfo > result = [ ] ;
433441 if ( GameDataPlugin ? . Plugins == null ||
@@ -436,7 +444,7 @@ protected virtual async Task<List<HypPluginPackageInfo>> CheckPluginUpdate(strin
436444 return result ;
437445 }
438446
439- var pluginList = GameDataPlugin . Plugins ;
447+ List < HypPluginPackageInfo > pluginList = GameDataPlugin . Plugins ;
440448 if ( pluginList . FirstOrDefault ( x => x . PluginId ? . Equals ( pluginKey , StringComparison . OrdinalIgnoreCase ) ??
441449 false ) is not { PluginPackage : { } packageData } packageInfo ||
442450 packageData . PackageAssetValidationList . Count == 0 )
@@ -458,18 +466,8 @@ protected virtual async Task<List<HypPluginPackageInfo>> CheckPluginUpdate(strin
458466 . EnsureNoReadOnly ( )
459467 . StripAlternateDataStream ( ) ;
460468
461- if ( ! fileInfo . Exists )
462- {
463- result . Add ( packageInfo ) ;
464- break ;
465- }
466-
467- await using FileStream fs = fileInfo . Open ( FileMode . Open , FileAccess . Read , FileShare . ReadWrite ) ;
468-
469- byte [ ] hashBytes = await CryptoHashUtility < MD5 > . ThreadSafe . GetHashFromStreamAsync ( fs ) ;
470- string ? md5 = HexTool . BytesToHexUnsafe ( hashBytes ) ;
471-
472- if ( md5 ? . Equals ( validate . PackageMD5HashString , StringComparison . OrdinalIgnoreCase ) ?? false )
469+ if ( fileInfo . Exists &&
470+ fileInfo . Length == validate . PackageSize )
473471 {
474472 continue ;
475473 }
0 commit comments