Skip to content

Commit cddd41b

Browse files
authored
Preview 1.82.18 Hotfix (#690)
# What's changed? - 1.82.18 - **[Fix]** Launcher crashing when the main game thread unexpectedly closes, by @neon-nyan - **[Fix]** Taskbar progress not reset after game install/update, by @shatyuka - **[Fix]** Ensures temporary files availability, by @neon-nyan - **[Fix]** 7z COMException errors, by @neon-nyan - **[Fix]** Genshin's repair missing a few files, by @neon-nyan
2 parents 3260e8e + dd37df8 commit cddd41b

File tree

16 files changed

+523
-317
lines changed

16 files changed

+523
-317
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ on:
2727

2828
env:
2929
DOTNET_INSTALL_DIR: '.\.dotnet'
30-
DOTNET_VERSION: '9.x'
30+
DOTNET_VERSION: '9.0.1xx'
3131
DOTNET_QUALITY: 'ga'
3232
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
3333

.github/workflows/qodana-scan-pr.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
Configuration: ${{ matrix.configuration }}
2929
Platform: ${{ matrix.platform }}
3030
DOTNET_INSTALL_DIR: '.\.dotnet'
31-
DOTNET_VERSION: '9.x'
31+
DOTNET_VERSION: '9.0.1xx'
3232
DOTNET_QUALITY: 'ga'
3333
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
3434

.github/workflows/qodana-scan.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
Configuration: ${{ matrix.configuration }}
2121
Platform: ${{ matrix.platform }}
2222
DOTNET_INSTALL_DIR: '.\.dotnet'
23-
DOTNET_VERSION: '9.x'
23+
DOTNET_VERSION: '9.0.1xx'
2424
DOTNET_QUALITY: 'ga'
2525
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
2626
permissions:

.github/workflows/vt-scan-releases.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ on:
77
jobs:
88
virustotal:
99
runs-on: ubuntu-latest
10+
permissions:
11+
actions: read
12+
contents: write
13+
pull-requests: write
14+
checks: write
15+
security-events: write
16+
deployments: write
17+
packages: write
18+
statuses: write
19+
1020
steps:
1121
- name: VirusTotal Scan Executables
1222
uses: crazy-max/ghaction-virustotal@v4

CollapseLauncher/Classes/GameManagement/GamePlaytime/Playtime.cs

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -81,63 +81,70 @@ public void Reset()
8181

8282
public async void StartSession(Process proc, DateTime? begin = null)
8383
{
84-
int hashId = _gameVersionManager.GamePreset.HashID;
84+
try
85+
{
86+
int hashId = _gameVersionManager.GamePreset.HashID;
8587

86-
// If a playtime HashSet has already tracked, then return (do not track the playtime more than once)
87-
// Otherwise, add it to track list
88-
if (!ActiveSessions.Add(hashId)) return;
88+
// If a playtime HashSet has already tracked, then return (do not track the playtime more than once)
89+
// Otherwise, add it to track list
90+
if (!ActiveSessions.Add(hashId)) return;
8991

90-
begin ??= DateTime.Now;
92+
begin ??= DateTime.Now;
9193

92-
TimeSpan initialTimeSpan = CollapsePlaytime.TotalPlaytime;
94+
TimeSpan initialTimeSpan = CollapsePlaytime.TotalPlaytime;
9395

94-
CollapsePlaytime.LastPlayed = begin;
95-
CollapsePlaytime.LastSession = TimeSpan.Zero;
96-
CollapsePlaytime.Save();
97-
PlaytimeUpdated?.Invoke(this, CollapsePlaytime);
96+
CollapsePlaytime.LastPlayed = begin;
97+
CollapsePlaytime.LastSession = TimeSpan.Zero;
98+
CollapsePlaytime.Save();
99+
PlaytimeUpdated?.Invoke(this, CollapsePlaytime);
98100

99101
#if DEBUG
100-
LogWriteLine($"{_gameVersionManager.GamePreset.ProfileName} - Started session at {begin.Value.ToLongTimeString()}.");
102+
LogWriteLine($"{_gameVersionManager.GamePreset.ProfileName} - Started session at {begin.Value.ToLongTimeString()}.");
101103
#endif
102-
int elapsedSeconds = 0;
104+
int elapsedSeconds = 0;
103105

104-
using (var inGameTimer = new Timer())
105-
{
106-
inGameTimer.Interval = 60000;
107-
inGameTimer.Elapsed += (_, _) =>
106+
using (var inGameTimer = new Timer())
108107
{
109-
elapsedSeconds += 60;
110-
DateTime now = DateTime.Now;
111-
112-
CollapsePlaytime.AddMinute();
113-
PlaytimeUpdated?.Invoke(this, CollapsePlaytime);
108+
inGameTimer.Interval = 60000;
109+
inGameTimer.Elapsed += (_, _) =>
110+
{
111+
elapsedSeconds += 60;
112+
DateTime now = DateTime.Now;
113+
114+
CollapsePlaytime.AddMinute();
115+
PlaytimeUpdated?.Invoke(this, CollapsePlaytime);
114116
#if DEBUG
115-
LogWriteLine($"{_gameVersionManager.GamePreset.ProfileName} - {elapsedSeconds}s elapsed. ({now.ToLongTimeString()})");
117+
LogWriteLine($"{_gameVersionManager.GamePreset.ProfileName} - {elapsedSeconds}s elapsed. ({now.ToLongTimeString()})");
116118
#endif
117-
};
119+
};
118120

119-
inGameTimer.Start();
120-
await proc.WaitForExitAsync(_token.Token);
121-
inGameTimer.Stop();
122-
}
121+
inGameTimer.Start();
122+
await proc.WaitForExitAsync(_token.Token);
123+
inGameTimer.Stop();
124+
}
123125

124-
DateTime end = DateTime.Now;
125-
double totalElapsedSeconds = (end - begin.Value).TotalSeconds;
126-
if (totalElapsedSeconds < 0)
127-
{
128-
LogWriteLine($"[HomePage::StartPlaytimeCounter] Date difference cannot be lower than 0. ({totalElapsedSeconds}s)", LogType.Error);
129-
Dialog_InvalidPlaytime(elapsedSeconds);
130-
totalElapsedSeconds = elapsedSeconds;
131-
}
126+
DateTime end = DateTime.Now;
127+
double totalElapsedSeconds = (end - begin.Value).TotalSeconds;
128+
if (totalElapsedSeconds < 0)
129+
{
130+
LogWriteLine($"[HomePage::StartPlaytimeCounter] Date difference cannot be lower than 0. ({totalElapsedSeconds}s)", LogType.Error);
131+
Dialog_InvalidPlaytime(elapsedSeconds);
132+
totalElapsedSeconds = elapsedSeconds;
133+
}
132134

133-
TimeSpan totalTimeSpan = TimeSpan.FromSeconds(totalElapsedSeconds);
134-
LogWriteLine($"Added {totalElapsedSeconds}s [{totalTimeSpan.Hours}h {totalTimeSpan.Minutes}m {totalTimeSpan.Seconds}s] " +
135-
$"to {_gameVersionManager.GamePreset.ProfileName} playtime.", LogType.Default, true);
136-
137-
CollapsePlaytime.Update(initialTimeSpan.Add(totalTimeSpan), false, true);
138-
PlaytimeUpdated?.Invoke(this, CollapsePlaytime);
135+
TimeSpan totalTimeSpan = TimeSpan.FromSeconds(totalElapsedSeconds);
136+
LogWriteLine($"Added {totalElapsedSeconds}s [{totalTimeSpan.Hours}h {totalTimeSpan.Minutes}m {totalTimeSpan.Seconds}s] " +
137+
$"to {_gameVersionManager.GamePreset.ProfileName} playtime.", LogType.Default, true);
138+
139+
CollapsePlaytime.Update(initialTimeSpan.Add(totalTimeSpan), false, true);
140+
PlaytimeUpdated?.Invoke(this, CollapsePlaytime);
139141

140-
ActiveSessions.Remove(hashId);
142+
ActiveSessions.Remove(hashId);
143+
}
144+
catch
145+
{
146+
// ignored
147+
}
141148
}
142149

143150
private static string TimeSpanToString(TimeSpan timeSpan) => $"{timeSpan.Days * 24 + timeSpan.Hours}h {timeSpan.Minutes}m";

CollapseLauncher/Classes/InstallManagement/Base/InstallManagerBase.cs

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -771,9 +771,43 @@ private long GetAssetIndexTotalUncompressSize(List<GameInstallPackage> assetInde
771771

772772
private long GetSingleOrSegmentedUncompressedSize(GameInstallPackage asset)
773773
{
774-
using Stream stream = GetSingleOrSegmentedDownloadStream(asset);
775-
using ArchiveFile archiveFile = ArchiveFile.Create(stream, true);
776-
return archiveFile.Entries.Sum(x => (long)x!.Size);
774+
using Stream stream = GetSingleOrSegmentedDownloadStream(asset);
775+
776+
#if USENEWZIPDECOMPRESS
777+
Func<Stream, long> summaryDelegate;
778+
if (LauncherConfig.IsEnforceToUse7zipOnExtract)
779+
{
780+
summaryDelegate = GetArchiveUncompressedSizeNative7zip;
781+
}
782+
else if ((asset.PathOutput.EndsWith(".zip", StringComparison.OrdinalIgnoreCase) ||
783+
asset.PathOutput.EndsWith(".zip.001", StringComparison.OrdinalIgnoreCase)) &&
784+
!_isAllowExtractCorruptZip)
785+
{
786+
summaryDelegate = GetArchiveUncompressedSizeManaged;
787+
}
788+
else
789+
{
790+
summaryDelegate = GetArchiveUncompressedSizeNative7zip;
791+
}
792+
#else
793+
Func<Stream, long> summaryDelegate = GetArchiveUncompressedSizeNative7zip;
794+
#endif
795+
796+
return summaryDelegate(stream);
797+
}
798+
799+
#if USENEWZIPDECOMPRESS
800+
private long GetArchiveUncompressedSizeManaged(Stream archiveStream)
801+
{
802+
using ZipArchive archive = ZipArchive.Open(archiveStream);
803+
return archive.Entries.Select(x => x.Size).ToArray().Sum();
804+
}
805+
#endif
806+
807+
private long GetArchiveUncompressedSizeNative7zip(Stream archiveStream)
808+
{
809+
using ArchiveFile archiveFile = ArchiveFile.Create(archiveStream, true);
810+
return archiveFile.Entries.Select(x => (long)x.Size).ToArray().Sum();
777811
}
778812

779813
private Stream GetSingleOrSegmentedDownloadStream(GameInstallPackage asset)
@@ -869,20 +903,20 @@ protected virtual async Task StartPackageInstallationInner(List<GameInstallPacka
869903
InstallPackageExtractorDelegate installTaskDelegate;
870904
if (LauncherConfig.IsEnforceToUse7zipOnExtract)
871905
{
872-
installTaskDelegate = ExtractUsing7zip;
906+
installTaskDelegate = ExtractUsingNative7zip;
873907
}
874908
else if ((asset!.PathOutput.EndsWith(".zip", StringComparison.OrdinalIgnoreCase)
875909
|| asset!.PathOutput.EndsWith(".zip.001", StringComparison.OrdinalIgnoreCase))
876910
&& !_isAllowExtractCorruptZip)
877911
{
878-
installTaskDelegate = ExtractUsingNativeZip;
912+
installTaskDelegate = ExtractUsingManagedZip;
879913
}
880914
else
881915
{
882-
installTaskDelegate = ExtractUsing7zip;
916+
installTaskDelegate = ExtractUsingNative7zip;
883917
}
884918
#else
885-
InstallPackageExtractorDelegate installTaskDelegate = ExtractUsing7zip;
919+
InstallPackageExtractorDelegate installTaskDelegate = ExtractUsingNative7zip;
886920
#endif
887921

888922
// Execute method delegate for the extractor
@@ -1018,7 +1052,7 @@ protected virtual async Task StartPackageInstallationInner(List<GameInstallPacka
10181052
}
10191053

10201054
#if USENEWZIPDECOMPRESS
1021-
private async Task ExtractUsingNativeZip(GameInstallPackage asset)
1055+
private async Task ExtractUsingManagedZip(GameInstallPackage asset)
10221056
{
10231057
int threadCounts = ThreadCount;
10241058

@@ -1037,8 +1071,7 @@ private async Task ExtractUsingNativeZip(GameInstallPackage asset)
10371071
IEnumerable<IEnumerable<int>> zipEntriesChunks = zipEntries.Chunk(entriesChunk);
10381072

10391073
// Run the workers
1040-
await Parallel.ForEachAsync(
1041-
zipEntriesChunks, new ParallelOptions
1074+
await Parallel.ForEachAsync(zipEntriesChunks, new ParallelOptions
10421075
{
10431076
CancellationToken = Token.Token
10441077
},
@@ -1047,12 +1080,12 @@ await Parallel.ForEachAsync(
10471080
await using Stream fs = GetSingleOrSegmentedDownloadStream(asset);
10481081
using var zipArchive = ZipArchive.Open(fs);
10491082
List<ZipArchiveEntry> entries = zipArchive.Entries.ToList();
1050-
await ExtractUsingNativeZipWorker(entry, entries, token);
1083+
await ExtractUsingManagedZipWorker(entry, entries, token);
10511084
});
10521085
}
10531086

1054-
private async Task ExtractUsingNativeZipWorker(IEnumerable<int> entriesIndex, List<ZipArchiveEntry> entries,
1055-
CancellationToken cancellationToken)
1087+
private async Task ExtractUsingManagedZipWorker(IEnumerable<int> entriesIndex, List<ZipArchiveEntry> entries,
1088+
CancellationToken cancellationToken)
10561089
{
10571090
byte[] buffer = GC.AllocateUninitializedArray<byte>(BufferBigLength);
10581091

@@ -1139,7 +1172,7 @@ void StartWriteInner(byte[] bufferInner, FileStream outputStream, Stream entrySt
11391172
}
11401173
#endif
11411174

1142-
private async Task ExtractUsing7zip(GameInstallPackage asset)
1175+
private async Task ExtractUsingNative7zip(GameInstallPackage asset)
11431176
{
11441177
// Start Async Thread
11451178
// Since the ArchiveFile (especially with the callbacks) can't run under

CollapseLauncher/Classes/Interfaces/Class/ProgressBase.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ protected void UpdateSophonFileTotalProgress(long read)
461461
ProgressChanged?.Invoke(this, SophonProgress);
462462

463463
// Update taskbar progress
464-
if (Status.IsCanceled)
464+
if (Status.IsCanceled || Status.IsCompleted)
465465
{
466466
WindowUtility.SetTaskBarState(TaskbarState.NoProgress);
467467
}
@@ -1041,7 +1041,7 @@ protected virtual ConfiguredTaskAwaitable<byte[]> GetCryptoHashAsync<T>(
10411041
Hash.GetCryptoHashAsync<T>(fileInfo,
10421042
hmacKey,
10431043
read => UpdateHashReadProgress(read, updateProgress, updateTotalProgress),
1044-
fileInfo is { Exists: true, Length: > 100 << 20 },
1044+
fileInfo is { Exists: true, Length: > 1024 << 20 },
10451045
token);
10461046

10471047
protected virtual ConfiguredTaskAwaitable<byte[]> GetCryptoHashAsync<T>(
@@ -1054,7 +1054,7 @@ protected virtual ConfiguredTaskAwaitable<byte[]> GetCryptoHashAsync<T>(
10541054
Hash.GetCryptoHashAsync<T>(stream,
10551055
hmacKey,
10561056
read => UpdateHashReadProgress(read, updateProgress, updateTotalProgress),
1057-
stream is { Length: > 100 << 20 },
1057+
stream is { Length: > 1024 << 20 },
10581058
token);
10591059

10601060
protected virtual byte[] GetCryptoHash<T>(
@@ -1112,7 +1112,7 @@ protected virtual ConfiguredTaskAwaitable<byte[]> GetHashAsync<T>(
11121112
where T : NonCryptographicHashAlgorithm, new() =>
11131113
Hash.GetHashAsync<T>(fileInfo,
11141114
read => UpdateHashReadProgress(read, updateProgress, updateTotalProgress),
1115-
fileInfo is { Exists: true, Length: > 100 << 20 },
1115+
fileInfo is { Exists: true, Length: > 1024 << 20 },
11161116
token);
11171117

11181118
protected virtual ConfiguredTaskAwaitable<byte[]> GetHashAsync<T>(
@@ -1123,7 +1123,7 @@ protected virtual ConfiguredTaskAwaitable<byte[]> GetHashAsync<T>(
11231123
where T : NonCryptographicHashAlgorithm, new() =>
11241124
Hash.GetHashAsync<T>(stream,
11251125
read => UpdateHashReadProgress(read, updateProgress, updateTotalProgress),
1126-
stream is { Length: > 100 << 20 },
1126+
stream is { Length: > 1024 << 20 },
11271127
token);
11281128

11291129
protected virtual byte[] GetHash<T>(
@@ -1414,7 +1414,7 @@ protected virtual void UpdateStatus()
14141414
{
14151415
StatusChanged?.Invoke(this, Status);
14161416

1417-
if (Status.IsCanceled)
1417+
if (Status.IsCanceled || Status.IsCompleted)
14181418
{
14191419
WindowUtility.SetTaskBarState(TaskbarState.NoProgress);
14201420
}

0 commit comments

Comments
 (0)