Skip to content

Commit 8018144

Browse files
committed
Use simple size check for SDK and Plugin
1 parent 934774c commit 8018144

File tree

3 files changed

+59
-61
lines changed

3 files changed

+59
-61
lines changed

CollapseLauncher/Classes/GameManagement/Versioning/GameVersionBase.GameState.cs

Lines changed: 55 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using CollapseLauncher.Helper.StreamUtility;
77
using Hi3Helper;
88
using Hi3Helper.Data;
9-
using Hi3Helper.EncTool.Hashes;
109
using Hi3Helper.EncTool.Parser.AssetIndex;
1110
using Hi3Helper.Plugin.Core.Management;
1211
using Hi3Helper.SentryHelper;
@@ -20,8 +19,9 @@
2019
using System.Diagnostics.CodeAnalysis;
2120
using System.IO;
2221
using System.Linq;
23-
using System.Security.Cryptography;
22+
using System.Threading;
2423
using 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
}

CollapseLauncher/Classes/Interfaces/IGameVersionCheck.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,13 @@ internal interface IGameVersion
122122
/// <summary>
123123
/// Checks if the plugin version is installed or matches the version provided from miHoYo's API.
124124
/// </summary>
125-
ValueTask<bool> IsPluginVersionsMatch();
125+
Task<bool> IsPluginVersionsMatch();
126126

127127
/// <summary>
128128
/// Checks if the sdk version is installed or matches the version provided from miHoYo's API.
129129
/// This is used to obtain the status of the SDK .dlls for certain builds (for example: Bilibili version)
130130
/// </summary>
131-
ValueTask<bool> IsSdkVersionsMatch();
131+
Task<bool> IsSdkVersionsMatch();
132132

133133
/// <summary>
134134
/// Check if the game version is installed.

CollapseLauncher/Classes/Plugins/PluginGameVersionWrapper.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,8 @@ public override bool IsGameInstalled()
201201
}
202202
public override bool IsGameVersionMatch() => GetGameExistingVersion() == GetGameVersionApi();
203203

204-
public override ValueTask<bool> IsPluginVersionsMatch() => ValueTask.FromResult(true);
205-
public override ValueTask<bool> IsSdkVersionsMatch() => ValueTask.FromResult(true);
204+
public override Task<bool> IsPluginVersionsMatch() => Task.FromResult(true);
205+
public override Task<bool> IsSdkVersionsMatch() => Task.FromResult(true);
206206

207207
/*
208208
public override void Reinitialize()

0 commit comments

Comments
 (0)