diff --git a/.github/workflows/qodana-scan-pr.yml b/.github/workflows/qodana-scan-pr.yml
index 5c247122f..481297118 100644
--- a/.github/workflows/qodana-scan-pr.yml
+++ b/.github/workflows/qodana-scan-pr.yml
@@ -3,8 +3,6 @@ on:
pull_request:
branches:
- main
- - preview
- - stable
paths-ignore:
- '**.md'
- 'Hi3Helper.Core/Lang/**.json'
@@ -21,13 +19,11 @@ jobs:
pull-requests: write
checks: write
security-events: write
-
strategy:
matrix:
configuration: [Release] # No need to distribute Debug builds
platform: [x64]
framework: [net9.0-windows10.0.22621.0]
-
env:
Configuration: ${{ matrix.configuration }}
Platform: ${{ matrix.platform }}
@@ -45,7 +41,6 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit
fetch-depth: 0 # a full history is required for pull request analysis
submodules: recursive # many many submodules
-
- name: Install .NET
uses: actions/setup-dotnet@v4
with:
@@ -62,7 +57,6 @@ jobs:
pr-mode: true
env:
QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} # read the steps about it below
-
- uses: github/codeql-action/upload-sarif@v3
if: ${{ github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name }}
with:
diff --git a/.github/workflows/qodana-scan.yml b/.github/workflows/qodana-scan.yml
index 6910a91fc..2037d01f5 100644
--- a/.github/workflows/qodana-scan.yml
+++ b/.github/workflows/qodana-scan.yml
@@ -3,9 +3,10 @@ on:
workflow_dispatch:
schedule:
- cron: '0 0 * * 0,3,5' # At 00:00 on Sunday, Wednesday, and Friday.
-# pull_request:
-# branches:
-# - main
+ pull_request:
+ branches:
+ - preview
+ - stable
jobs:
qodana:
@@ -15,7 +16,6 @@ jobs:
configuration: [Release] # No need to distribute Debug builds
platform: [x64]
framework: [net9.0-windows10.0.22621.0]
-
env:
Configuration: ${{ matrix.configuration }}
Platform: ${{ matrix.platform }}
@@ -23,23 +23,19 @@ jobs:
DOTNET_VERSION: '9.x'
DOTNET_QUALITY: 'ga'
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
-
permissions:
actions: read
contents: write
pull-requests: write
checks: write
security-events: write
-
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit
submodules: recursive # many many submodules
-
# - name: Install winget
# uses: Cyberboss/install-winget@v1
-
# - name: Install Qodana CLI
# uses: crazy-max/ghaction-chocolatey@v3
# with:
@@ -50,7 +46,6 @@ jobs:
# Import-Module "$env:ChocolateyInstall/helpers/chocolateyInstaller.psm1"
# refreshenv
# qodana --version
-
- name: Install .NET
uses: actions/setup-dotnet@v4
with:
@@ -58,13 +53,11 @@ jobs:
dotnet-quality: ${{ env.DOTNET_QUALITY }}
cache: true
cache-dependency-path: CollapseLauncher/packages.lock.json
-
# - name: Qodana Scan
# run: |
# Import-Module "$env:ChocolateyInstall/helpers/chocolateyInstaller.psm1"
# refreshenv
# qodana scan --ide QDNET-EAP -o ${{ runner.temp }}\qodana\results --cache-dir ${{ runner.temp }}\qodana\cache
-
- name: Qodana Scan
uses: JetBrains/qodana-action@v2024.3.3
continue-on-error: true
@@ -73,9 +66,8 @@ jobs:
pr-mode: false
env:
QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
-
- uses: github/codeql-action/upload-sarif@v3
if: always()
continue-on-error: true
with:
- sarif_file: ${{ runner.temp }}/qodana/results/qodana.sarif.json
\ No newline at end of file
+ sarif_file: ${{ runner.temp }}/qodana/results/qodana.sarif.json
diff --git a/.gitignore b/.gitignore
index b2fcd1f69..cef97bf38 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,8 @@
packages/*
CollapseLauncher/Deps/*
+CollapseLauncher/StaticLib/*.lib
+CollapseLauncher/StaticLib/**/*.lib
CollapseLauncher/Invoker/*
**/Generated Files/**
*.psd
diff --git a/CollapseLauncher/App.xaml b/CollapseLauncher/App.xaml
index ec4f953ec..6072c813d 100644
--- a/CollapseLauncher/App.xaml
+++ b/CollapseLauncher/App.xaml
@@ -2,10 +2,9 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:animatedvisuals="using:Microsoft.UI.Xaml.Controls.AnimatedVisuals"
+ xmlns:controls="using:Microsoft.UI.Xaml.Controls"
xmlns:conv="using:CollapseLauncher.Pages"
- xmlns:interactions="using:Microsoft.Xaml.Interactions.Core"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
- xmlns:controls="using:Microsoft.UI.Xaml.Controls"
xmlns:primitives="using:Microsoft.UI.Xaml.Controls.Primitives"
xmlns:ui="using:Windows.UI">
@@ -2190,13 +2189,13 @@
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
-
-
+
0,-6,0,0
diff --git a/CollapseLauncher/App.xaml.cs b/CollapseLauncher/App.xaml.cs
index 4960e5312..679200abf 100644
--- a/CollapseLauncher/App.xaml.cs
+++ b/CollapseLauncher/App.xaml.cs
@@ -14,20 +14,26 @@
using Windows.UI;
using static CollapseLauncher.InnerLauncherConfig;
using static Hi3Helper.Logger;
+// ReSharper disable SwitchStatementMissingSomeEnumCasesNoDefault
+// ReSharper disable CommentTypo
+// ReSharper disable StringLiteralTypo
namespace CollapseLauncher
{
public partial class App
{
- public static bool IsAppKilled = false;
+ // TODO: #671 This App.IsAppKilled will be replaced with cancellable-awaitable event
+ // to ensure no hot-exit being called before all background tasks
+ // hasn't being cancelled.
+ // public static bool IsAppKilled { get; set; } = false;
public App()
{
if (DebugSettings != null)
{
-#if ENABLEFRAMECOUNTER
+ #if ENABLEFRAMECOUNTER
DebugSettings.EnableFrameRateCounter = true;
-#endif
+ #endif
#if DEBUG
DebugSettings.LayoutCycleDebugBreakLevel = LayoutCycleDebugBreakLevel.High;
DebugSettings.LayoutCycleTracingLevel = LayoutCycleTracingLevel.High;
@@ -68,7 +74,7 @@ public App()
RequestedTheme = IsAppThemeLight ? ApplicationTheme.Light : ApplicationTheme.Dark;
PInvoke.SetPreferredAppMode(PInvoke.ShouldAppsUseDarkMode() ? PreferredAppMode.AllowDark : PreferredAppMode.Default);
- this.InitializeComponent();
+ InitializeComponent();
}
protected override void OnLaunched(LaunchActivatedEventArgs args)
diff --git a/CollapseLauncher/Classes/CachesManagement/Honkai/Check.cs b/CollapseLauncher/Classes/CachesManagement/Honkai/Check.cs
index ff657f4ca..fd2238611 100644
--- a/CollapseLauncher/Classes/CachesManagement/Honkai/Check.cs
+++ b/CollapseLauncher/Classes/CachesManagement/Honkai/Check.cs
@@ -2,6 +2,7 @@
using CollapseLauncher.Interfaces;
using Hi3Helper;
using System;
+using System.Buffers;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -10,6 +11,7 @@
using System.Threading.Tasks;
using static Hi3Helper.Locale;
using static Hi3Helper.Logger;
+// ReSharper disable CommentTypo
namespace CollapseLauncher
{
@@ -18,20 +20,20 @@ internal partial class HonkaiCache
private async Task> Check(List assetIndex, CancellationToken token)
{
// Initialize asset index for the return
- List returnAsset = new List();
+ List returnAsset = [];
// Set Indetermined status as false
- _status.IsProgressAllIndetermined = false;
+ Status.IsProgressAllIndetermined = false;
// Show the asset entry panel
- _status.IsAssetEntryPanelShow = true;
+ Status.IsAssetEntryPanelShow = true;
try
{
// Create the cache directory if it doesn't exist
- if (!Directory.Exists(_gamePath))
+ if (!Directory.Exists(GamePath))
{
- Directory.CreateDirectory(_gamePath!);
+ Directory.CreateDirectory(GamePath!);
}
// Check for unused files
@@ -40,7 +42,7 @@ private async Task> Check(List assetIndex, Cancella
// Do check in parallelization.
await Parallel.ForEachAsync(assetIndex!, new ParallelOptions
{
- MaxDegreeOfParallelism = _threadCount,
+ MaxDegreeOfParallelism = ThreadCount,
CancellationToken = token
}, async (asset, localToken) =>
{
@@ -56,10 +58,19 @@ private async Task> Check(List assetIndex, Cancella
return returnAsset;
}
+ private readonly SearchValues _unusedSearchValues = SearchValues.Create([
+ "output_log",
+ "Crashes",
+ "Verify.txt",
+ "APM",
+ "FBData",
+ "asb.dat"
+ ], StringComparison.OrdinalIgnoreCase);
+
private void CheckUnusedAssets(List assetIndex, List returnAsset)
{
// Directory info and if the directory doesn't exist, return
- DirectoryInfo directoryInfo = new DirectoryInfo(_gamePath);
+ DirectoryInfo directoryInfo = new DirectoryInfo(GamePath);
if (!directoryInfo.Exists)
{
return;
@@ -69,54 +80,51 @@ private void CheckUnusedAssets(List assetIndex, List ret
foreach (FileInfo fileInfo in directoryInfo.EnumerateFiles("*", SearchOption.AllDirectories)
.EnumerateNoReadOnly())
{
- string filePath = fileInfo.FullName;
-
- if (!filePath.Contains("output_log", StringComparison.OrdinalIgnoreCase)
- && !filePath.Contains("Crashes", StringComparison.OrdinalIgnoreCase)
- && !filePath.Contains("Verify.txt", StringComparison.OrdinalIgnoreCase)
- && !filePath.Contains("APM", StringComparison.OrdinalIgnoreCase)
- && !filePath.Contains("FBData", StringComparison.OrdinalIgnoreCase)
- && !filePath.Contains("asb.dat", StringComparison.OrdinalIgnoreCase)
- && !assetIndex.Exists(x => x.ConcatPath == fileInfo.FullName))
+ ReadOnlySpan filePath = fileInfo.FullName;
+
+ if (filePath.ContainsAny(_unusedSearchValues)
+ || assetIndex.Exists(x => x.ConcatPath == fileInfo.FullName))
{
- // Increment the total found count
- _progressAllCountFound++;
-
- // Add asset to the returnAsset
- CacheAsset asset = new CacheAsset()
- {
- BasePath = Path.GetDirectoryName(filePath),
- N = Path.GetFileName(filePath),
- DataType = CacheAssetType.Unused,
- CS = fileInfo.Length,
- CRC = null,
- Status = CacheAssetStatus.Unused,
- IsUseLocalPath = true
- };
- returnAsset!.Add(asset);
-
- // Add to asset entry display
- Dispatch(() => AssetEntry!.Add(new AssetProperty(
- asset.N,
- asset.DataType,
- asset.BasePath,
- asset.CS,
- null,
- null
- ))
- );
-
- LogWriteLine($"File: {asset.ConcatPath} is unused!", LogType.Warning, true);
+ continue;
}
+
+ // Increment the total found count
+ ProgressAllCountFound++;
+
+ // Add asset to the returnAsset
+ CacheAsset asset = new CacheAsset
+ {
+ BasePath = Path.GetDirectoryName(fileInfo.FullName),
+ N = Path.GetFileName(fileInfo.FullName),
+ DataType = CacheAssetType.Unused,
+ CS = fileInfo.Length,
+ CRC = null,
+ Status = CacheAssetStatus.Unused,
+ IsUseLocalPath = true
+ };
+ returnAsset!.Add(asset);
+
+ // Add to asset entry display
+ Dispatch(() => AssetEntry!.Add(new AssetProperty(
+ asset.N,
+ asset.DataType,
+ asset.BasePath,
+ asset.CS,
+ null,
+ null
+ ))
+ );
+
+ LogWriteLine($"File: {asset.ConcatPath} is unused!", LogType.Warning, true);
}
}
private async ValueTask CheckAsset(CacheAsset asset, List returnAsset, CancellationToken token)
{
// Increment the count and update the status
- Interlocked.Add(ref _progressAllCountCurrent, 1);
- _status.ActivityStatus = string.Format(Lang!._CachesPage!.CachesStatusChecking!, asset!.DataType, asset.N);
- _status.ActivityAll = string.Format(Lang._CachesPage.CachesTotalStatusChecking!, _progressAllCountCurrent, _progressAllCountTotal);
+ Interlocked.Add(ref ProgressAllCountCurrent, 1);
+ Status.ActivityStatus = string.Format(Lang!._CachesPage!.CachesStatusChecking!, asset!.DataType, asset.N);
+ Status.ActivityAll = string.Format(Lang._CachesPage.CachesTotalStatusChecking!, ProgressAllCountCurrent, ProgressAllCountTotal);
// Assign the file info.
FileInfo fileInfo = new FileInfo(asset.ConcatPath).EnsureNoReadOnly(out bool isExist);
@@ -136,7 +144,7 @@ private async ValueTask CheckAsset(CacheAsset asset, List returnAsse
}
// Skip CRC check if fast method is used
- if (_useFastMethod)
+ if (UseFastMethod)
{
return;
}
@@ -144,7 +152,7 @@ private async ValueTask CheckAsset(CacheAsset asset, List returnAsse
// If above passes, then run the CRC check
await using FileStream fs = await NaivelyOpenFileStreamAsync(fileInfo, FileMode.Open, FileAccess.Read, FileShare.Read);
// Calculate the asset CRC (SHA1)
- byte[] hashArray = await CheckHashAsync(fs, new HMACSHA1(_gameSalt!), token);
+ byte[] hashArray = await GetCryptoHashAsync(fs, GameSalt, true, true, token);
// If the asset CRC doesn't match, then add the file to asset index.
if (!IsArrayMatch(asset.CRCArray, hashArray))
@@ -159,9 +167,9 @@ private void AddGenericCheckAsset(CacheAsset asset, CacheAssetStatus assetStatus
lock (this)
{
// Set Indetermined status as false
- _status.IsProgressAllIndetermined = false;
- _progressAllCountFound++;
- _progressAllSizeFound += asset!.CS;
+ Status.IsProgressAllIndetermined = false;
+ ProgressAllCountFound++;
+ ProgressAllSizeFound += asset!.CS;
}
// Add file into asset index
diff --git a/CollapseLauncher/Classes/CachesManagement/Honkai/Fetch.cs b/CollapseLauncher/Classes/CachesManagement/Honkai/Fetch.cs
index efa9ff8b3..cd609a033 100644
--- a/CollapseLauncher/Classes/CachesManagement/Honkai/Fetch.cs
+++ b/CollapseLauncher/Classes/CachesManagement/Honkai/Fetch.cs
@@ -19,6 +19,8 @@
using static Hi3Helper.Locale;
using static Hi3Helper.Logger;
// ReSharper disable SwitchStatementHandlesSomeKnownEnumValuesWithDefault
+// ReSharper disable CommentTypo
+// ReSharper disable StringLiteralTypo
namespace CollapseLauncher
{
@@ -31,8 +33,8 @@ private async Task> Fetch(CancellationToken token)
// Initialize new proxy-aware HttpClient
using HttpClient httpClientNew = new HttpClientBuilder()
- .UseLauncherConfig(_downloadThreadCount + _downloadThreadCountReserved)
- .SetUserAgent(_userAgent)
+ .UseLauncherConfig(DownloadThreadWithReservedCount)
+ .SetUserAgent(UserAgent)
.SetAllowedDecompression(DecompressionMethods.None)
.Create();
@@ -47,7 +49,7 @@ await Parallel.ForEachAsync(
Enum.GetValues(),
new ParallelOptions
{
- MaxDegreeOfParallelism = _threadCount,
+ MaxDegreeOfParallelism = ThreadCount,
CancellationToken = token
},
async (type, ctx) =>
@@ -68,8 +70,8 @@ await Parallel.ForEachAsync(
LogWriteLine($" Cache Size = {SummarizeSizeSimple(count.Item2)}", LogType.NoTag, true);
// Increment the Total Size and Count
- Interlocked.Add(ref _progressAllCountTotal, count.Item1);
- Interlocked.Add(ref _progressAllSizeTotal, count.Item2);
+ Interlocked.Add(ref ProgressAllCountTotal, count.Item1);
+ Interlocked.Add(ref ProgressAllSizeTotal, count.Item2);
}
break;
default:
@@ -86,23 +88,23 @@ private async Task BuildGameRepoURL(DownloadClient downloadClient, CancellationT
KianaDispatch dispatch = null;
Exception lastException = null;
- foreach (string baseURL in _gameVersionManager!.GamePreset!.GameDispatchArrayURL!)
+ foreach (string baseURL in GameVersionManager!.GamePreset!.GameDispatchArrayURL!)
{
try
{
// Init the key and decrypt it if existed.
- if (string.IsNullOrEmpty(_gameVersionManager.GamePreset.DispatcherKey))
+ if (string.IsNullOrEmpty(GameVersionManager.GamePreset.DispatcherKey))
{
throw new NullReferenceException("Dispatcher key is null or empty!");
}
- string key = _gameVersionManager.GamePreset.DispatcherKey;
+ string key = GameVersionManager.GamePreset.DispatcherKey;
// Try assign dispatcher
dispatch = await KianaDispatch.GetDispatch(downloadClient, baseURL,
- _gameVersionManager.GamePreset.GameDispatchURLTemplate,
- _gameVersionManager.GamePreset.GameDispatchChannelName,
- key, _gameVersion.VersionArray, token);
+ GameVersionManager.GamePreset.GameDispatchURLTemplate,
+ GameVersionManager.GamePreset.GameDispatchChannelName,
+ key, GameVersion.VersionArray, token);
lastException = null;
break;
}
@@ -116,9 +118,9 @@ private async Task BuildGameRepoURL(DownloadClient downloadClient, CancellationT
if (lastException != null) throw lastException;
// Get gatewayURl and fetch the gateway
- _gameGateway =
- await KianaDispatch.GetGameserver(downloadClient, dispatch!, _gameVersionManager.GamePreset.GameGatewayDefault!, token);
- _gameRepoURL = BuildAssetBundleURL(_gameGateway);
+ GameGateway =
+ await KianaDispatch.GetGameserver(downloadClient, dispatch!, GameVersionManager.GamePreset.GameGatewayDefault!, token);
+ GameRepoURL = BuildAssetBundleURL(GameGateway);
}
private static string BuildAssetBundleURL(KianaDispatch gateway) => CombineURLFromString(gateway!.AssetBundleUrls![0], "/{0}/editor_compressed/");
@@ -126,13 +128,13 @@ private async Task BuildGameRepoURL(DownloadClient downloadClient, CancellationT
private async Task<(int, long)> FetchByType(CacheAssetType type, DownloadClient downloadClient, List assetIndex, CancellationToken token)
{
// Set total activity string as "Fetching Caches Type: "
- _status.ActivityStatus = string.Format(Lang!._CachesPage!.CachesStatusFetchingType!, type);
- _status.IsProgressAllIndetermined = true;
- _status.IsIncludePerFileIndicator = false;
+ Status.ActivityStatus = string.Format(Lang!._CachesPage!.CachesStatusFetchingType!, type);
+ Status.IsProgressAllIndetermined = true;
+ Status.IsIncludePerFileIndicator = false;
UpdateStatus();
// Get the asset index properties
- string baseURL = string.Format(_gameRepoURL!, type.ToString().ToLowerInvariant());
+ string baseURL = string.Format(GameRepoURL!, type.ToString().ToLowerInvariant());
string assetIndexURL = string.Format(CombineURLFromString(baseURL, "{0}Version.unity3d")!,
type == CacheAssetType.Data ? "Data" : "Resource");
@@ -186,7 +188,7 @@ private IEnumerable EnumerateCacheTextAsset(CacheAssetType type, IEn
// If isFirst flag set to true, then get the _gameSalt.
if (isFirst)
{
- _gameSalt = GetAssetIndexSalt(line);
+ GameSalt = GetAssetIndexSalt(line);
isFirst = false;
continue;
}
@@ -194,7 +196,7 @@ private IEnumerable EnumerateCacheTextAsset(CacheAssetType type, IEn
// Get the lucky number if it does so 👀
if (isNeedReadLuckyNumber && int.TryParse(line, null, out int luckyNumber))
{
- _luckyNumber = luckyNumber;
+ LuckyNumber = luckyNumber;
isNeedReadLuckyNumber = false;
continue;
}
@@ -211,7 +213,7 @@ private IEnumerable EnumerateCacheTextAsset(CacheAssetType type, IEn
try
{
// Deserialize the line and set the type
- content = line.Deserialize(InternalAppJSONContext.Default.CacheAsset);
+ content = line.Deserialize(CacheAssetJsonContext.Default.CacheAsset);
}
catch (Exception ex)
{
@@ -225,15 +227,17 @@ private IEnumerable EnumerateCacheTextAsset(CacheAssetType type, IEn
if (content == null) continue;
// Check if the asset is regional and contains only selected language.
- if (IsValidRegionFile(content.N, _gameLang))
+ if (!IsValidRegionFile(content.N, GameLang))
{
- // Set base URL and Path and add it to asset index
- content.BaseURL = baseUrl;
- content.DataType = type;
- content.BasePath = GetAssetBasePathByType(type);
-
- yield return content;
+ continue;
}
+
+ // Set base URL and Path and add it to asset index
+ content.BaseURL = baseUrl;
+ content.DataType = type;
+ content.BasePath = GetAssetBasePathByType(type);
+
+ yield return content;
}
}
@@ -260,8 +264,8 @@ private async ValueTask> BuildAssetIndex(CacheAssetType ty
// Initialize local HTTP client
using HttpClient client = new HttpClientBuilder()
- .UseLauncherConfig(_downloadThreadCount + _downloadThreadCountReserved)
- .SetUserAgent(_userAgent)
+ .UseLauncherConfig(DownloadThreadWithReservedCount)
+ .SetUserAgent(UserAgent)
.SetAllowedDecompression(DecompressionMethods.None)
.Create();
@@ -273,7 +277,7 @@ await Parallel.ForEachAsync(EnumerateCacheTextAsset(type, dataTextAsset.GetStrin
new ParallelOptions
{
CancellationToken = token,
- MaxDegreeOfParallelism = _threadCount
+ MaxDegreeOfParallelism = ThreadCount
},
async (content, cancellationToken) =>
{
@@ -281,9 +285,9 @@ await Parallel.ForEachAsync(EnumerateCacheTextAsset(type, dataTextAsset.GetStrin
if (content.DLM == 2)
{
// Update the status
- _status.ActivityStatus = string.Format(Lang._CachesPage.Status2, type, content.N);
- _status.IsProgressAllIndetermined = true;
- _status.IsProgressPerFileIndetermined = true;
+ Status.ActivityStatus = string.Format(Lang._CachesPage.Status2, type, content.N);
+ Status.IsProgressAllIndetermined = true;
+ Status.IsProgressPerFileIndetermined = true;
UpdateStatus();
// Check for the URL availability and is not available, then skip.
@@ -316,10 +320,10 @@ private byte[] GetAssetIndexSalt(string data)
if (DataCooker.IsServeV3Data(LauncherMetadataHelper.CurrentMasterKey?.Key))
{
DataCooker.GetServeV3DataSize(LauncherMetadataHelper.CurrentMasterKey?.Key, out long keyCompSize,
- out long keyDecompSize);
+ out long keyDecompressedSize);
key = new byte[keyCompSize];
DataCooker.ServeV3Data(LauncherMetadataHelper.CurrentMasterKey?.Key, key, (int)keyCompSize,
- (int)keyDecompSize, out _);
+ (int)keyDecompressedSize, out _);
}
else
{
@@ -330,28 +334,24 @@ private byte[] GetAssetIndexSalt(string data)
return saltTool.GetSalt();
}
- private string GetAssetBasePathByType(CacheAssetType type) => Path.Combine(_gamePath!, type == CacheAssetType.Data ? "Data" : "Resources");
+ private string GetAssetBasePathByType(CacheAssetType type) => Path.Combine(GamePath!, type == CacheAssetType.Data ? "Data" : "Resources");
- private bool IsValidRegionFile(string input, string lang)
+ private static bool IsValidRegionFile(string input, string lang)
{
// If the path contains regional string, then move to the next check
- if (input!.Contains(_cacheRegionalCheckName!))
- {
- // Check if the regional string has specified language string
- return input.Contains($"{_cacheRegionalCheckName}_{lang}");
- }
-
+ return !input.Contains(CacheRegionalCheckName!) ||
+ // Check if the regional string has specified language string
+ input.Contains($"{CacheRegionalCheckName}_{lang}");
// If none, then pass it as true (non-regional string)
- return true;
}
- public KianaDispatch GetCurrentGateway() => _gameGateway;
+ public KianaDispatch GetCurrentGateway() => GameGateway;
public async Task<(List, string, string, int)> GetCacheAssetList(
DownloadClient downloadClient, CacheAssetType type, CancellationToken token)
{
// Initialize asset index for the return
- List returnAsset = new();
+ List returnAsset = [];
// Build _gameRepoURL from loading Dispatcher and Gateway
await BuildGameRepoURL(downloadClient, token);
@@ -360,8 +360,8 @@ private bool IsValidRegionFile(string input, string lang)
_ = await FetchByType(type, downloadClient, returnAsset, token);
// Return the list and base asset bundle repo URL
- return (returnAsset, _gameGateway!.ExternalAssetUrls!.FirstOrDefault(), BuildAssetBundleURL(_gameGateway),
- _luckyNumber);
+ return (returnAsset, GameGateway!.ExternalAssetUrls!.FirstOrDefault(), BuildAssetBundleURL(GameGateway),
+ LuckyNumber);
}
}
}
\ No newline at end of file
diff --git a/CollapseLauncher/Classes/CachesManagement/Honkai/HonkaiCache.cs b/CollapseLauncher/Classes/CachesManagement/Honkai/HonkaiCache.cs
index 4a58339d1..91ccb50b1 100644
--- a/CollapseLauncher/Classes/CachesManagement/Honkai/HonkaiCache.cs
+++ b/CollapseLauncher/Classes/CachesManagement/Honkai/HonkaiCache.cs
@@ -13,30 +13,31 @@ namespace CollapseLauncher
internal partial class HonkaiCache : ProgressBase, ICache, ICacheBase
{
#region Properties
- private string _cacheRegionalCheckName = "sprite";
- private string _gameLang { get; set; }
- private byte[] _gameSalt { get; set; }
- private KianaDispatch _gameGateway { get; set; }
- private List _updateAssetIndex { get; set; }
- private int _luckyNumber { get; set; }
+
+ private const string CacheRegionalCheckName = "sprite";
+ private string GameLang { get; }
+ private byte[] GameSalt { get; set; }
+ private KianaDispatch GameGateway { get; set; }
+ private List UpdateAssetIndex { get; set; }
+ private int LuckyNumber { get; set; }
#endregion
- public HonkaiCache(UIElement parentUI, IGameVersionCheck GameVersionManager)
+ public HonkaiCache(UIElement parentUI, IGameVersion gameVersionManager)
: base(
parentUI,
- GameVersionManager!,
- GameVersionManager!.GameDirAppDataPath,
+ gameVersionManager!,
+ gameVersionManager!.GameDirAppDataPath,
null,
- GameVersionManager.GetGameVersionAPI()?.VersionString)
+ gameVersionManager.GetGameVersionApi()?.VersionString)
{
- _gameLang = _gameVersionManager!.GamePreset!.GetGameLanguage() ?? "en";
+ GameLang = GameVersionManager!.GamePreset!.GetGameLanguage() ?? "en";
}
~HonkaiCache() => Dispose();
public async Task StartCheckRoutine(bool useFastCheck)
{
- _useFastMethod = useFastCheck;
+ UseFastMethod = useFastCheck;
return await TryRunExamineThrow(CheckRoutine());
}
@@ -46,29 +47,29 @@ private async Task CheckRoutine()
ResetStatusAndProgress();
// Initialize _updateAssetIndex
- _updateAssetIndex = new List();
+ UpdateAssetIndex = [];
// Reset status and progress
// ResetStatusAndProgress();
- _token = new CancellationTokenSourceWrapper();
+ Token = new CancellationTokenSourceWrapper();
// Step 1: Fetch asset indexes
- _assetIndex = await Fetch(_token!.Token);
+ AssetIndex = await Fetch(Token!.Token);
// Step 2: Start assets checking
- _updateAssetIndex = await Check(_assetIndex, _token!.Token);
+ UpdateAssetIndex = await Check(AssetIndex, Token!.Token);
// Step 3: Summarize and returns true if the assetIndex count != 0 indicates caches needs to be update.
// either way, returns false.
return SummarizeStatusAndProgress(
- _updateAssetIndex,
- string.Format(Lang!._CachesPage!.CachesStatusNeedUpdate!, _progressAllCountFound, ConverterTool.SummarizeSizeSimple(_progressAllSizeFound)),
+ UpdateAssetIndex,
+ string.Format(Lang!._CachesPage!.CachesStatusNeedUpdate!, ProgressAllCountFound, ConverterTool.SummarizeSizeSimple(ProgressAllSizeFound)),
Lang._CachesPage.CachesStatusUpToDate);
}
public async Task StartUpdateRoutine(bool showInteractivePrompt = false)
{
- if (_updateAssetIndex!.Count == 0) throw new InvalidOperationException("There's no cache file need to be update! You can't do the update process!");
+ if (UpdateAssetIndex!.Count == 0) throw new InvalidOperationException("There's no cache file need to be update! You can't do the update process!");
_ = await TryRunExamineThrow(UpdateRoutine());
}
@@ -76,7 +77,7 @@ public async Task StartUpdateRoutine(bool showInteractivePrompt = false)
private async Task UpdateRoutine()
{
// Assign update task
- Task updateTask = Update(_updateAssetIndex, _assetIndex, _token!.Token);
+ Task updateTask = Update(UpdateAssetIndex, AssetIndex, Token!.Token);
// Run update process
bool updateTaskSuccess = await TryRunExamineThrow(updateTask);
@@ -85,15 +86,15 @@ private async Task UpdateRoutine()
ResetStatusAndProgress();
// Set as completed
- _status.IsCompleted = true;
- _status.IsCanceled = false;
- _status.ActivityStatus = Lang!._CachesPage!.CachesStatusUpToDate;
+ Status.IsCompleted = true;
+ Status.IsCanceled = false;
+ Status.ActivityStatus = Lang!._CachesPage!.CachesStatusUpToDate;
// Update status and progress
UpdateAll();
// Clean up _updateAssetIndex
- _updateAssetIndex!.Clear();
+ UpdateAssetIndex!.Clear();
return updateTaskSuccess;
}
@@ -102,12 +103,13 @@ private async Task UpdateRoutine()
public void CancelRoutine()
{
- _token!.Cancel();
+ Token!.Cancel();
}
public void Dispose()
{
CancelRoutine();
+ GC.SuppressFinalize(this);
}
}
}
diff --git a/CollapseLauncher/Classes/CachesManagement/Honkai/Update.cs b/CollapseLauncher/Classes/CachesManagement/Honkai/Update.cs
index ab1feb6eb..57b13ff2a 100644
--- a/CollapseLauncher/Classes/CachesManagement/Honkai/Update.cs
+++ b/CollapseLauncher/Classes/CachesManagement/Honkai/Update.cs
@@ -14,6 +14,8 @@
using System.Threading.Tasks;
using static Hi3Helper.Locale;
using static Hi3Helper.Logger;
+// ReSharper disable CommentTypo
+// ReSharper disable GrammarMistakeInComment
namespace CollapseLauncher
{
@@ -23,8 +25,8 @@ private async Task Update(List updateAssetIndex, List()
- .UseLauncherConfig(_downloadThreadCount + _downloadThreadCountReserved)
- .SetUserAgent(_userAgent)
+ .UseLauncherConfig(DownloadThreadWithReservedCount)
+ .SetUserAgent(UserAgent)
.SetAllowedDecompression(DecompressionMethods.None)
.Create();
@@ -33,24 +35,24 @@ private async Task Update(List updateAssetIndex, List assetProperty = new ObservableCollection(AssetEntry);
+ ObservableCollection assetProperty = [.. AssetEntry];
- var runningTask = new ConcurrentDictionary<(CacheAsset, IAssetProperty), byte>();
- if (_isBurstDownloadEnabled)
+ ConcurrentDictionary<(CacheAsset, IAssetProperty), byte> runningTask = new();
+ if (IsBurstDownloadEnabled)
{
await Parallel.ForEachAsync(
PairEnumeratePropertyAndAssetIndexPackage(
#if ENABLEHTTPREPAIR
- EnforceHTTPSchemeToAssetIndex(updateAssetIndex)
+ EnforceHttpSchemeToAssetIndex(updateAssetIndex)
#else
updateAssetIndex
#endif
, assetProperty),
- new ParallelOptions { CancellationToken = token, MaxDegreeOfParallelism = _downloadThreadCount },
+ new ParallelOptions { CancellationToken = token, MaxDegreeOfParallelism = DownloadThreadCount },
async (asset, innerToken) =>
{
if (!runningTask.TryAdd(asset, 0))
@@ -67,7 +69,7 @@ await Parallel.ForEachAsync(
foreach ((CacheAsset, IAssetProperty) asset in
PairEnumeratePropertyAndAssetIndexPackage(
#if ENABLEHTTPREPAIR
- EnforceHTTPSchemeToAssetIndex(updateAssetIndex)
+ EnforceHttpSchemeToAssetIndex(updateAssetIndex)
#else
updateAssetIndex
#endif
@@ -100,29 +102,28 @@ await Parallel.ForEachAsync(
private void UpdateCacheVerifyList(List assetIndex)
{
// Get listFile path
- string listFile = Path.Combine(_gamePath!, "Data", "Verify.txt");
+ string listFile = Path.Combine(GamePath!, "Data", "Verify.txt");
// Initialize listFile File Stream
- using (FileStream fs = new FileStream(listFile, FileMode.Create, FileAccess.Write))
- using (StreamWriter sw = new StreamWriter(fs))
- {
- // Iterate asset index and generate the path for the cache path
- foreach (CacheAsset asset in assetIndex!)
- {
- // Yes, the path is written in this way. Idk why miHoYo did this...
- // Update 6.8: They finally notices that they use "//" instead of "/"
- string basePath = GetAssetBasePathByType(asset!.DataType)!.Replace('\\', '/');
- string path = basePath + "/" + asset.ConcatN;
- sw.WriteLine(path);
- }
- }
+ using FileStream fs = new FileStream(listFile, FileMode.Create, FileAccess.Write);
+ using StreamWriter sw = new StreamWriter(fs);
+ // Iterate asset index and generate the path for the cache path
+ for (var index = 0; index < assetIndex!.Count; index++)
+ {
+ var asset = assetIndex![index];
+ // Yes, the path is written in this way. Idk why miHoYo did this...
+ // Update 6.8: They finally notices that they use "//" instead of "/"
+ string basePath = GetAssetBasePathByType(asset!.DataType)!.Replace('\\', '/');
+ string path = basePath + "/" + asset.ConcatN;
+ sw.WriteLine(path);
+ }
}
private async Task UpdateCacheAsset((CacheAsset AssetIndex, IAssetProperty AssetProperty) asset, DownloadClient downloadClient, DownloadProgressDelegate downloadProgress, CancellationToken token)
{
// Increment total count and update the status
- _progressAllCountCurrent++;
- _status.ActivityStatus = string.Format(Lang!._Misc!.Downloading + " {0}: {1}", asset!.AssetIndex.DataType, asset.AssetIndex.N);
+ ProgressAllCountCurrent++;
+ Status.ActivityStatus = string.Format(Lang!._Misc!.Downloading + " {0}: {1}", asset!.AssetIndex.DataType, asset.AssetIndex.N);
UpdateAll();
FileInfo fileInfo = new FileInfo(asset.AssetIndex.ConcatPath!)
@@ -140,15 +141,15 @@ private async Task UpdateCacheAsset((CacheAsset AssetIndex, IAssetProperty Asset
// Other than unused file, do this action
else
{
-#if DEBUG
+ #if DEBUG
LogWriteLine($"Downloading cache [T: {asset.AssetIndex.DataType}]: {asset.AssetIndex.N} at URL: {asset.AssetIndex.ConcatURL}", LogType.Debug, true);
-#endif
+ #endif
await RunDownloadTask(asset.AssetIndex.CS, fileInfo, asset.AssetIndex.ConcatURL, downloadClient, downloadProgress, token);
-#if !DEBUG
+ #if !DEBUG
LogWriteLine($"Downloaded cache [T: {asset.AssetIndex.DataType}]: {asset.AssetIndex.N}", LogType.Default, true);
-#endif
+ #endif
}
// Remove Asset Entry display
diff --git a/CollapseLauncher/Classes/CachesManagement/StarRail/Check.cs b/CollapseLauncher/Classes/CachesManagement/StarRail/Check.cs
index a945b5014..5004e635c 100644
--- a/CollapseLauncher/Classes/CachesManagement/StarRail/Check.cs
+++ b/CollapseLauncher/Classes/CachesManagement/StarRail/Check.cs
@@ -23,28 +23,28 @@ private async Task> Check(List assetIndex, CancellationTo
List returnAsset = [];
// Set Indetermined status as false
- _status.IsProgressAllIndetermined = false;
+ Status.IsProgressAllIndetermined = false;
// Show the asset entry panel
- _status.IsAssetEntryPanelShow = true;
+ Status.IsAssetEntryPanelShow = true;
// Get persistent and streaming paths
- string execName = Path.GetFileNameWithoutExtension(_innerGameVersionManager!.GamePreset!.GameExecutableName);
- string baseDesignDataPathPersistent = Path.Combine(_gamePath!, @$"{execName}_Data\Persistent\DesignData\Windows");
- string baseDesignDataPathStreaming = Path.Combine(_gamePath!, @$"{execName}_Data\StreamingAssets\DesignData\Windows");
+ string execName = Path.GetFileNameWithoutExtension(InnerGameVersionManager!.GamePreset!.GameExecutableName);
+ string baseDesignDataPathPersistent = Path.Combine(GamePath!, @$"{execName}_Data\Persistent\DesignData\Windows");
+ string baseDesignDataPathStreaming = Path.Combine(GamePath!, @$"{execName}_Data\StreamingAssets\DesignData\Windows");
- string baseLuaPathPersistent = Path.Combine(_gamePath!, @$"{execName}_Data\Persistent\Lua\Windows");
- string baseLuaPathStreaming = Path.Combine(_gamePath!, @$"{execName}_Data\StreamingAssets\Lua\Windows");
+ string baseLuaPathPersistent = Path.Combine(GamePath!, @$"{execName}_Data\Persistent\Lua\Windows");
+ string baseLuaPathStreaming = Path.Combine(GamePath!, @$"{execName}_Data\StreamingAssets\Lua\Windows");
- string baseIFixPathPersistent = Path.Combine(_gamePath!, @$"{execName}_Data\Persistent\IFix\Windows");
- string baseIFixPathStreaming = Path.Combine(_gamePath!, @$"{execName}_Data\StreamingAssets\IFix\Windows");
+ string baseIFixPathPersistent = Path.Combine(GamePath!, @$"{execName}_Data\Persistent\IFix\Windows");
+ string baseIFixPathStreaming = Path.Combine(GamePath!, @$"{execName}_Data\StreamingAssets\IFix\Windows");
try
{
// Do check in parallelization.
await Parallel.ForEachAsync(assetIndex!, new ParallelOptions
{
- MaxDegreeOfParallelism = _threadCount,
+ MaxDegreeOfParallelism = ThreadCount,
CancellationToken = token
}, async (asset, threadToken) =>
{
@@ -76,9 +76,9 @@ private async ValueTask CheckAsset(SRAsset asset, List returnAsset, str
// Increment the count and update the status
lock (this)
{
- _progressAllCountCurrent++;
- _status.ActivityStatus = string.Format(Lang!._CachesPage!.CachesStatusChecking!, asset!.AssetType, asset.LocalName);
- _status.ActivityAll = string.Format(Lang!._CachesPage!.CachesTotalStatusChecking!, _progressAllCountCurrent, _progressAllCountTotal);
+ ProgressAllCountCurrent++;
+ Status.ActivityStatus = string.Format(Lang!._CachesPage!.CachesStatusChecking!, asset!.AssetType, asset.LocalName);
+ Status.ActivityAll = string.Format(Lang!._CachesPage!.CachesTotalStatusChecking!, ProgressAllCountCurrent, ProgressAllCountTotal);
}
// Get persistent and streaming paths
@@ -97,7 +97,7 @@ private async ValueTask CheckAsset(SRAsset asset, List returnAsset, str
}
// Skip CRC check if fast method is used
- if (_useFastMethod)
+ if (UseFastMethod)
{
return;
}
@@ -106,7 +106,7 @@ private async ValueTask CheckAsset(SRAsset asset, List returnAsset, str
await using FileStream fs = await NaivelyOpenFileStreamAsync(usePersistent ? fileInfoPersistent : fileInfoStreaming,
FileMode.Open, FileAccess.Read, FileShare.Read);
// Calculate the asset CRC (MD5)
- byte[] hashArray = await CheckHashAsync(fs, MD5.Create(), token);
+ byte[] hashArray = await GetCryptoHashAsync(fs, null, true, true, token);
// If the asset CRC doesn't match, then add the file to asset index.
if (!IsArrayMatch(asset.Hash, hashArray))
@@ -121,9 +121,9 @@ private void AddGenericCheckAsset(SRAsset asset, CacheAssetStatus assetStatus, L
lock (this)
{
// Set Indetermined status as false
- _status.IsProgressAllIndetermined = false;
- _progressAllCountFound++;
- _progressAllSizeFound += asset!.Size;
+ Status.IsProgressAllIndetermined = false;
+ ProgressAllCountFound++;
+ ProgressAllSizeFound += asset!.Size;
}
// Add file into asset index
diff --git a/CollapseLauncher/Classes/CachesManagement/StarRail/Fetch.cs b/CollapseLauncher/Classes/CachesManagement/StarRail/Fetch.cs
index 839aea8d2..2d3b81cba 100644
--- a/CollapseLauncher/Classes/CachesManagement/StarRail/Fetch.cs
+++ b/CollapseLauncher/Classes/CachesManagement/StarRail/Fetch.cs
@@ -14,6 +14,7 @@
using static Hi3Helper.Data.ConverterTool;
using static Hi3Helper.Locale;
using static Hi3Helper.Logger;
+// ReSharper disable SwitchStatementMissingSomeEnumCasesNoDefault
namespace CollapseLauncher
{
@@ -22,12 +23,12 @@ internal partial class StarRailCache
private async Task> Fetch(CancellationToken token)
{
// Initialize asset index for the return
- List returnAsset = new List();
+ List returnAsset = [];
// Initialize new proxy-aware HttpClient
using HttpClient client = new HttpClientBuilder()
- .UseLauncherConfig(_downloadThreadCount + _downloadThreadCountReserved)
- .SetUserAgent(_userAgent)
+ .UseLauncherConfig(DownloadThreadWithReservedCount)
+ .SetUserAgent(UserAgent)
.SetAllowedDecompression(DecompressionMethods.None)
.Create();
@@ -36,12 +37,12 @@ private async Task> Fetch(CancellationToken token)
// Initialize metadata
// Set total activity string as "Fetching Caches Type: Dispatcher"
- _status.ActivityStatus = string.Format(Lang!._CachesPage!.CachesStatusFetchingType!, CacheAssetType.Dispatcher);
- _status.IsProgressAllIndetermined = true;
- _status.IsIncludePerFileIndicator = false;
+ Status.ActivityStatus = string.Format(Lang!._CachesPage!.CachesStatusFetchingType!, CacheAssetType.Dispatcher);
+ Status.IsProgressAllIndetermined = true;
+ Status.IsIncludePerFileIndicator = false;
UpdateStatus();
- if (!await _innerGameVersionManager!.StarRailMetadataTool.Initialize(token, downloadClient, _httpClient_FetchAssetProgress, GetExistingGameRegionID(), Path.Combine(_gamePath!, $"{Path.GetFileNameWithoutExtension(_gameVersionManager!.GamePreset!.GameExecutableName)}_Data\\Persistent")))
+ if (!await InnerGameVersionManager!.StarRailMetadataTool.Initialize(token, downloadClient, _httpClient_FetchAssetProgress, GetExistingGameRegionID(), Path.Combine(GamePath!, $"{Path.GetFileNameWithoutExtension(GameVersionManager!.GamePreset!.GameExecutableName)}_Data\\Persistent")))
throw new InvalidDataException("The dispatcher response is invalid! Please open an issue to our GitHub page to report this issue.");
// Iterate type and do fetch
@@ -67,8 +68,8 @@ await Parallel.ForEachAsync(Enum.GetValues(), token, async (type, i
LogWriteLine($" Cache Size = {SummarizeSizeSimple(count.Item2)}", LogType.NoTag, true);
// Increment the Total Size and Count
- Interlocked.Add(ref _progressAllCountTotal, count.Item1);
- Interlocked.Add(ref _progressAllSizeTotal, count.Item2);
+ Interlocked.Add(ref ProgressAllCountTotal, count.Item1);
+ Interlocked.Add(ref ProgressAllSizeTotal, count.Item2);
}).ConfigureAwait(false);
// Return asset index
@@ -78,9 +79,9 @@ await Parallel.ForEachAsync(Enum.GetValues(), token, async (type, i
private async Task<(int, long)> FetchByType(DownloadClient downloadClient, DownloadProgressDelegate downloadProgress, SRAssetType type, List assetIndex, CancellationToken token)
{
// Set total activity string as "Fetching Caches Type: "
- _status.ActivityStatus = string.Format(Lang!._CachesPage!.CachesStatusFetchingType!, type);
- _status.IsProgressAllIndetermined = true;
- _status.IsIncludePerFileIndicator = false;
+ Status.ActivityStatus = string.Format(Lang!._CachesPage!.CachesStatusFetchingType!, type);
+ Status.IsProgressAllIndetermined = true;
+ Status.IsIncludePerFileIndicator = false;
UpdateStatus();
// Start reading the metadata and build the asset index of each type
@@ -88,18 +89,18 @@ await Parallel.ForEachAsync(Enum.GetValues(), token, async (type, i
switch (type)
{
case SRAssetType.IFix:
- await _innerGameVersionManager!.StarRailMetadataTool!.ReadIFixMetadataInformation(downloadClient, downloadProgress, token);
- assetProperty = _innerGameVersionManager!.StarRailMetadataTool!.MetadataIFix!.GetAssets();
+ await InnerGameVersionManager!.StarRailMetadataTool!.ReadIFixMetadataInformation(downloadClient, downloadProgress, token);
+ assetProperty = InnerGameVersionManager!.StarRailMetadataTool!.MetadataIFix!.GetAssets();
assetIndex!.AddRange(assetProperty!.AssetList!);
return (assetProperty.AssetList.Count, assetProperty.AssetTotalSize);
case SRAssetType.DesignData:
- await _innerGameVersionManager!.StarRailMetadataTool!.ReadDesignMetadataInformation(downloadClient, downloadProgress, token);
- assetProperty = _innerGameVersionManager.StarRailMetadataTool.MetadataDesign!.GetAssets();
+ await InnerGameVersionManager!.StarRailMetadataTool!.ReadDesignMetadataInformation(downloadClient, downloadProgress, token);
+ assetProperty = InnerGameVersionManager.StarRailMetadataTool.MetadataDesign!.GetAssets();
assetIndex!.AddRange(assetProperty!.AssetList!);
return (assetProperty.AssetList.Count, assetProperty.AssetTotalSize);
case SRAssetType.Lua:
- await _innerGameVersionManager!.StarRailMetadataTool!.ReadLuaMetadataInformation(downloadClient, downloadProgress, token);
- assetProperty = _innerGameVersionManager.StarRailMetadataTool.MetadataLua!.GetAssets();
+ await InnerGameVersionManager!.StarRailMetadataTool!.ReadLuaMetadataInformation(downloadClient, downloadProgress, token);
+ assetProperty = InnerGameVersionManager.StarRailMetadataTool.MetadataLua!.GetAssets();
assetIndex!.AddRange(assetProperty!.AssetList!);
return (assetProperty.AssetList.Count, assetProperty.AssetTotalSize);
}
@@ -114,7 +115,7 @@ private unsafe string GetExistingGameRegionID()
object? value = RegistryRoot?.GetValue("App_LastServerName_h2577443795", null);
if (value == null)
{
- return _gameVersionManager!.GamePreset!.GameDispatchDefaultName ?? throw new KeyNotFoundException("Default dispatcher name in metadata is not exist!");
+ return GameVersionManager!.GamePreset.GameDispatchDefaultName ?? throw new KeyNotFoundException("Default dispatcher name in metadata is not exist!");
}
#nullable disable
@@ -126,13 +127,13 @@ private unsafe string GetExistingGameRegionID()
}
}
- private CacheAssetType ConvertCacheAssetTypeEnum(SRAssetType assetType) => assetType switch
- {
- SRAssetType.IFix => CacheAssetType.IFix,
- SRAssetType.DesignData => CacheAssetType.DesignData,
- SRAssetType.Lua => CacheAssetType.Lua,
- _ => CacheAssetType.General
- };
+ private static CacheAssetType ConvertCacheAssetTypeEnum(SRAssetType assetType) => assetType switch
+ {
+ SRAssetType.IFix => CacheAssetType.IFix,
+ SRAssetType.DesignData => CacheAssetType.DesignData,
+ SRAssetType.Lua => CacheAssetType.Lua,
+ _ => CacheAssetType.General
+ };
#endregion
}
}
diff --git a/CollapseLauncher/Classes/CachesManagement/StarRail/StarRailCache.cs b/CollapseLauncher/Classes/CachesManagement/StarRail/StarRailCache.cs
index bf488e171..0097ed2c0 100644
--- a/CollapseLauncher/Classes/CachesManagement/StarRail/StarRailCache.cs
+++ b/CollapseLauncher/Classes/CachesManagement/StarRail/StarRailCache.cs
@@ -7,61 +7,56 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using static Hi3Helper.Locale;
+// ReSharper disable UnusedMember.Global
namespace CollapseLauncher
{
- internal partial class StarRailCache : ProgressBase, ICache
+ internal partial class StarRailCache(UIElement parentUI, IGameVersion gameVersionManager)
+ : ProgressBase(parentUI,
+ gameVersionManager,
+ gameVersionManager.GameDirPath,
+ null,
+ gameVersionManager.GetGameVersionApi()?.VersionString), ICache
{
#region Properties
- private GameTypeStarRailVersion _innerGameVersionManager { get; set; }
- private List _updateAssetIndex { get; set; }
- protected override string _userAgent { get; set; } = "UnityPlayer/2019.4.34f1 (UnityWebRequest/1.0, libcurl/7.75.0-DEV)";
+ private GameTypeStarRailVersion InnerGameVersionManager { get; } = gameVersionManager as GameTypeStarRailVersion;
+ private List UpdateAssetIndex { get; set; }
+ protected override string UserAgent { get; set; } = "UnityPlayer/2019.4.34f1 (UnityWebRequest/1.0, libcurl/7.75.0-DEV)";
#endregion
- public StarRailCache(UIElement parentUI, IGameVersionCheck GameVersionManager)
- : base(
- parentUI,
- GameVersionManager,
- GameVersionManager.GameDirPath,
- null,
- GameVersionManager.GetGameVersionAPI()?.VersionString)
- {
- _innerGameVersionManager = GameVersionManager as GameTypeStarRailVersion;
- }
-
~StarRailCache() => Dispose();
public async Task StartCheckRoutine(bool useFastCheck)
{
- _useFastMethod = useFastCheck;
+ UseFastMethod = useFastCheck;
return await TryRunExamineThrow(CheckRoutine());
}
private async Task CheckRoutine()
{
// Initialize _updateAssetIndex
- _updateAssetIndex = new List();
+ UpdateAssetIndex = [];
// Reset status and progress
ResetStatusAndProgress();
// Step 1: Fetch asset indexes
- _assetIndex = await Fetch(_token.Token);
+ AssetIndex = await Fetch(Token.Token);
// Step 2: Start assets checking
- _updateAssetIndex = await Check(_assetIndex, _token.Token);
+ UpdateAssetIndex = await Check(AssetIndex, Token.Token);
// Step 3: Summarize and returns true if the assetIndex count != 0 indicates caches needs to be update.
// either way, returns false.
return SummarizeStatusAndProgress(
- _updateAssetIndex,
- string.Format(Lang._CachesPage.CachesStatusNeedUpdate, _progressAllCountFound, ConverterTool.SummarizeSizeSimple(_progressAllSizeFound)),
+ UpdateAssetIndex,
+ string.Format(Lang._CachesPage.CachesStatusNeedUpdate, ProgressAllCountFound, ConverterTool.SummarizeSizeSimple(ProgressAllSizeFound)),
Lang._CachesPage.CachesStatusUpToDate);
}
public async Task StartUpdateRoutine(bool showInteractivePrompt = false)
{
- if (_updateAssetIndex.Count == 0) throw new InvalidOperationException("There's no cache file need to be update! You can't do the update process!");
+ if (UpdateAssetIndex.Count == 0) throw new InvalidOperationException("There's no cache file need to be update! You can't do the update process!");
_ = await TryRunExamineThrow(UpdateRoutine());
}
@@ -69,7 +64,7 @@ public async Task StartUpdateRoutine(bool showInteractivePrompt = false)
private async Task UpdateRoutine()
{
// Assign update task
- Task updateTask = Update(_updateAssetIndex, _assetIndex, _token.Token);
+ Task updateTask = Update(UpdateAssetIndex, AssetIndex, Token.Token);
// Run update process
bool updateTaskSuccess = await TryRunExamineThrow(updateTask);
@@ -78,15 +73,15 @@ private async Task UpdateRoutine()
ResetStatusAndProgress();
// Set as completed
- _status.IsCompleted = true;
- _status.IsCanceled = false;
- _status.ActivityStatus = Lang._CachesPage.CachesStatusUpToDate;
+ Status.IsCompleted = true;
+ Status.IsCanceled = false;
+ Status.ActivityStatus = Lang._CachesPage.CachesStatusUpToDate;
// Update status and progress
UpdateAll();
// Clean up _updateAssetIndex
- _updateAssetIndex.Clear();
+ UpdateAssetIndex.Clear();
return updateTaskSuccess;
}
@@ -95,12 +90,13 @@ private async Task UpdateRoutine()
public void CancelRoutine()
{
- _token.Cancel();
+ Token.Cancel();
}
public void Dispose()
{
CancelRoutine();
+ GC.SuppressFinalize(this);
}
}
}
diff --git a/CollapseLauncher/Classes/CachesManagement/StarRail/Update.cs b/CollapseLauncher/Classes/CachesManagement/StarRail/Update.cs
index ae22d92bd..3db2de795 100644
--- a/CollapseLauncher/Classes/CachesManagement/StarRail/Update.cs
+++ b/CollapseLauncher/Classes/CachesManagement/StarRail/Update.cs
@@ -15,6 +15,7 @@
using System.Threading.Tasks;
using static Hi3Helper.Locale;
using static Hi3Helper.Logger;
+// ReSharper disable CommentTypo
namespace CollapseLauncher
{
@@ -26,8 +27,8 @@ private async Task Update(List updateAssetIndex, List as
{
// Initialize new proxy-aware HttpClient
using HttpClient client = new HttpClientBuilder()
- .UseLauncherConfig(_downloadThreadCount + _downloadThreadCountReserved)
- .SetUserAgent(_userAgent)
+ .UseLauncherConfig(DownloadThreadWithReservedCount)
+ .SetUserAgent(UserAgent)
.SetAllowedDecompression(DecompressionMethods.None)
.Create();
@@ -36,24 +37,24 @@ private async Task Update(List updateAssetIndex, List as
try
{
// Set IsProgressAllIndetermined as false and update the status
- _status.IsProgressAllIndetermined = true;
+ Status.IsProgressAllIndetermined = true;
UpdateStatus();
// Iterate the asset index and do update operation
- ObservableCollection assetProperty = new ObservableCollection(AssetEntry);
+ ObservableCollection assetProperty = [.. AssetEntry];
- var runningTask = new ConcurrentDictionary<(SRAsset, IAssetProperty), byte>();
- if (_isBurstDownloadEnabled)
+ ConcurrentDictionary<(SRAsset, IAssetProperty), byte> runningTask = new();
+ if (IsBurstDownloadEnabled)
{
await Parallel.ForEachAsync(
PairEnumeratePropertyAndAssetIndexPackage(
#if ENABLEHTTPREPAIR
- EnforceHTTPSchemeToAssetIndex(updateAssetIndex)
+ EnforceHttpSchemeToAssetIndex(updateAssetIndex)
#else
updateAssetIndex
#endif
, assetProperty),
- new ParallelOptions { CancellationToken = token, MaxDegreeOfParallelism = _downloadThreadCount },
+ new ParallelOptions { CancellationToken = token, MaxDegreeOfParallelism = DownloadThreadCount },
async (asset, innerToken) =>
{
if (!runningTask.TryAdd(asset, 0))
@@ -70,7 +71,7 @@ await Parallel.ForEachAsync(
foreach ((SRAsset, IAssetProperty) asset in
PairEnumeratePropertyAndAssetIndexPackage(
#if ENABLEHTTPREPAIR
- EnforceHTTPSchemeToAssetIndex(updateAssetIndex)
+ EnforceHttpSchemeToAssetIndex(updateAssetIndex)
#else
updateAssetIndex
#endif
@@ -100,9 +101,9 @@ await Parallel.ForEachAsync(
private async Task UpdateCacheAsset((SRAsset AssetIndex, IAssetProperty AssetProperty) asset, DownloadClient downloadClient, DownloadProgressDelegate downloadProgress, CancellationToken token)
{
// Increment total count and update the status
- _progressAllCountCurrent++;
+ ProgressAllCountCurrent++;
FileInfo fileInfo = new FileInfo(asset.AssetIndex.LocalName!).EnsureCreationOfDirectory().EnsureNoReadOnly();
- _status.ActivityStatus = string.Format(Lang._Misc.Downloading + " {0}: {1}", asset.AssetIndex.AssetType, Path.GetFileName(fileInfo.Name));
+ Status.ActivityStatus = string.Format(Lang._Misc.Downloading + " {0}: {1}", asset.AssetIndex.AssetType, Path.GetFileName(fileInfo.Name));
UpdateAll();
// Run download task
diff --git a/CollapseLauncher/Classes/CachesManagement/Zenless/ZenlessCache.cs b/CollapseLauncher/Classes/CachesManagement/Zenless/ZenlessCache.cs
index 8ba3ff936..45ddf28a9 100644
--- a/CollapseLauncher/Classes/CachesManagement/Zenless/ZenlessCache.cs
+++ b/CollapseLauncher/Classes/CachesManagement/Zenless/ZenlessCache.cs
@@ -6,7 +6,7 @@
namespace CollapseLauncher
{
- internal partial class ZenlessCache(UIElement parentUI, IGameVersionCheck gameVersionManager, ZenlessSettings gameSettings)
+ internal partial class ZenlessCache(UIElement parentUI, IGameVersion gameVersionManager, ZenlessSettings gameSettings)
: ZenlessRepair(parentUI, gameVersionManager, gameSettings, false, null, true), ICache, ICacheBase
{
public ZenlessCache AsBaseType() => this;
diff --git a/CollapseLauncher/Classes/ClassesContext.cs b/CollapseLauncher/Classes/ClassesContext.cs
deleted file mode 100644
index cbee07bae..000000000
--- a/CollapseLauncher/Classes/ClassesContext.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using CollapseLauncher.Helper.LauncherApiLoader.HoYoPlay;
-using CollapseLauncher.Helper.LauncherApiLoader.Sophon;
-using CollapseLauncher.Helper.Metadata;
-using CollapseLauncher.InstallManager.Base;
-using CollapseLauncher.Interfaces;
-using Hi3Helper.EncTool.Parser.AssetMetadata;
-using Hi3Helper.Shared.ClassStruct;
-using System.Collections.Generic;
-using System.Text.Json.Serialization;
-// ReSharper disable PartialTypeWithSinglePart
-
-namespace CollapseLauncher
-{
- [JsonSourceGenerationOptions(
- IncludeFields = false,
- GenerationMode = JsonSourceGenerationMode.Metadata,
- IgnoreReadOnlyFields = true,
- // ReSharper disable once BitwiseOperatorOnEnumWithoutFlags
- DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault | JsonIgnoreCondition.WhenWritingNull,
- WriteIndented = true)]
- [JsonSerializable(typeof(Dictionary>))]
- [JsonSerializable(typeof(RegionResourcePluginValidate))]
- [JsonSerializable(typeof(HoYoPlayLauncherResources))]
- [JsonSerializable(typeof(HoYoPlayLauncherGameInfo))]
- [JsonSerializable(typeof(CommunityToolsProperty))]
- [JsonSerializable(typeof(HoYoPlayLauncherNews))]
- [JsonSerializable(typeof(AppUpdateVersionProp))]
- [JsonSerializable(typeof(RegionResourceProp))]
- [JsonSerializable(typeof(NotificationPush))]
- [JsonSerializable(typeof(LauncherGameNews))]
- [JsonSerializable(typeof(GeneralDataProp))]
- [JsonSerializable(typeof(MasterKeyConfig))]
- [JsonSerializable(typeof(AudioPCKType[]))]
- [JsonSerializable(typeof(LocalFileInfo))]
- [JsonSerializable(typeof(PresetConfig))]
- [JsonSerializable(typeof(List))]
- [JsonSerializable(typeof(CacheAsset))]
- [JsonSerializable(typeof(BHI3LInfo))]
- [JsonSerializable(typeof(int[]))]
- internal sealed partial class InternalAppJSONContext : JsonSerializerContext;
-}
diff --git a/CollapseLauncher/Classes/DiscordPresence/DiscordPresenceManager.cs b/CollapseLauncher/Classes/DiscordPresence/DiscordPresenceManager.cs
index c92700c83..07c9962ae 100644
--- a/CollapseLauncher/Classes/DiscordPresence/DiscordPresenceManager.cs
+++ b/CollapseLauncher/Classes/DiscordPresence/DiscordPresenceManager.cs
@@ -8,6 +8,8 @@
using static Hi3Helper.Locale;
using static Hi3Helper.Shared.Region.LauncherConfig;
// ReSharper disable PartialTypeWithSinglePart
+// ReSharper disable StringLiteralTypo
+// ReSharper disable SwitchStatementHandlesSomeKnownEnumValuesWithDefault
namespace CollapseLauncher.DiscordPresence
{
@@ -61,14 +63,16 @@ public bool IdleEnabled
public DiscordPresenceManager(bool initialStart = true)
{
- if (initialStart)
+ if (!initialStart)
{
- // Prepare idle cached setting
- Logger.LogWriteLine($"Doing initial start for Discord RPC!\r\n\tIdle status : {IdleEnabled}",
- LogType.Scheme);
-
- SetupPresence();
+ return;
}
+
+ // Prepare idle cached setting
+ Logger.LogWriteLine($"Doing initial start for Discord RPC!\r\n\tIdle status : {IdleEnabled}",
+ LogType.Scheme);
+
+ SetupPresence();
}
// Deconstruct and dispose unmanaged resources
@@ -189,66 +193,68 @@ public void SetupPresence()
public void SetActivity(ActivityType activity, DateTime? activityOffset = null)
{
- if (GetAppConfigValue("EnableDiscordRPC").ToBool())
+ if (!GetAppConfigValue("EnableDiscordRPC").ToBool())
{
- //_lastAttemptedActivityType = activity;
- _activityType = activity;
+ return;
+ }
- switch (activity)
+ //_lastAttemptedActivityType = activity;
+ _activityType = activity;
+
+ switch (activity)
+ {
+ case ActivityType.Play:
{
- case ActivityType.Play:
+ bool isGameStatusEnabled = GetAppConfigValue("EnableDiscordGameStatus").ToBool();
+ BuildActivityGameStatus(isGameStatusEnabled ? Lang._Misc.DiscordRP_InGame : Lang._Misc.DiscordRP_Play,
+ isGameStatusEnabled, activityOffset);
+ break;
+ }
+ case ActivityType.Update:
+ {
+ bool isGameStatusEnabled = GetAppConfigValue("EnableDiscordGameStatus").ToBool();
+ BuildActivityGameStatus(Lang._Misc.DiscordRP_Update, isGameStatusEnabled);
+ break;
+ }
+ case ActivityType.Repair:
+ BuildActivityAppStatus(Lang._Misc.DiscordRP_Repair);
+ break;
+ case ActivityType.Cache:
+ BuildActivityAppStatus(Lang._Misc.DiscordRP_Cache);
+ break;
+ case ActivityType.GameSettings:
+ BuildActivityAppStatus(Lang._Misc.DiscordRP_GameSettings);
+ break;
+ case ActivityType.AppSettings:
+ BuildActivityAppStatus(Lang._Misc.DiscordRP_AppSettings);
+ break;
+ case ActivityType.Idle:
+ _lastPlayTime = null;
+ if (_cachedIsIdleEnabled)
{
- bool isGameStatusEnabled = GetAppConfigValue("EnableDiscordGameStatus").ToBool();
- BuildActivityGameStatus(isGameStatusEnabled ? Lang._Misc.DiscordRP_InGame : Lang._Misc.DiscordRP_Play,
- isGameStatusEnabled, activityOffset);
- break;
+ BuildActivityAppStatus(Lang._Misc.DiscordRP_Idle);
}
- case ActivityType.Update:
+ else
{
- bool isGameStatusEnabled = GetAppConfigValue("EnableDiscordGameStatus").ToBool();
- BuildActivityGameStatus(Lang._Misc.DiscordRP_Update, isGameStatusEnabled);
- break;
+ _presence = null; // Clear presence
}
- case ActivityType.Repair:
- BuildActivityAppStatus(Lang._Misc.DiscordRP_Repair);
- break;
- case ActivityType.Cache:
- BuildActivityAppStatus(Lang._Misc.DiscordRP_Cache);
- break;
- case ActivityType.GameSettings:
- BuildActivityAppStatus(Lang._Misc.DiscordRP_GameSettings);
- break;
- case ActivityType.AppSettings:
- BuildActivityAppStatus(Lang._Misc.DiscordRP_AppSettings);
- break;
- case ActivityType.Idle:
- _lastPlayTime = null;
- if (_cachedIsIdleEnabled)
- {
- BuildActivityAppStatus(Lang._Misc.DiscordRP_Idle);
- }
- else
- {
- _presence = null; // Clear presence
- }
- break;
- default:
- _presence = new RichPresence
+ break;
+ default:
+ _presence = new RichPresence
+ {
+ Details = Lang._Misc.DiscordRP_Default,
+ Assets = new Assets
{
- Details = Lang._Misc.DiscordRP_Default,
- Assets = new Assets
- {
- LargeImageKey = "launcher-logo-new",
- LargeImageText =
- $"Collapse Launcher v{LauncherUpdateHelper.LauncherCurrentVersionString} {(IsPreview ? "Preview" : "Stable")}"
- }
- };
- break;
- }
-
- UpdateActivity();
+ LargeImageKey = "launcher-logo-new",
+ LargeImageText =
+ $"Collapse Launcher v{LauncherUpdateHelper.LauncherCurrentVersionString} {(IsPreview ? "Preview" : "Stable")}"
+ }
+ };
+ break;
}
+
+ UpdateActivity();
}
private void BuildActivityGameStatus(string activityName, bool isGameStatusEnabled, DateTime? activityOffset = null)
diff --git a/CollapseLauncher/Classes/EventsManagement/BackgroundActivityManager.cs b/CollapseLauncher/Classes/EventsManagement/BackgroundActivityManager.cs
index 2b5fa1141..7065c63cd 100644
--- a/CollapseLauncher/Classes/EventsManagement/BackgroundActivityManager.cs
+++ b/CollapseLauncher/Classes/EventsManagement/BackgroundActivityManager.cs
@@ -13,41 +13,43 @@
using System;
using System.Collections.Generic;
using static Hi3Helper.Locale;
+// ReSharper disable StringLiteralTypo
namespace CollapseLauncher
{
internal class BackgroundActivityManager
{
- private static ThemeShadow _infoBarShadow = new ThemeShadow();
- public static Dictionary BackgroundActivities = new Dictionary();
+ private static readonly ThemeShadow InfoBarShadow = new();
+ public static Dictionary BackgroundActivities = new();
public static void Attach(int hashID, IBackgroundActivity activity, string activityTitle, string activitySubtitle)
{
- if (!BackgroundActivities!.ContainsKey(hashID))
+ if (BackgroundActivities.ContainsKey(hashID))
{
- AttachEventToNotification(hashID, activity, activityTitle, activitySubtitle);
- BackgroundActivities.Add(hashID, activity);
-#if DEBUG
- Logger.LogWriteLine($"Background activity with ID: {hashID} has been attached", LogType.Debug, true);
-#endif
+ return;
}
+
+ AttachEventToNotification(hashID, activity, activityTitle, activitySubtitle);
+ BackgroundActivities.Add(hashID, activity);
+ #if DEBUG
+ Logger.LogWriteLine($"Background activity with ID: {hashID} has been attached", LogType.Debug, true);
+ #endif
}
public static void Detach(int hashID)
{
- if (BackgroundActivities!.ContainsKey(hashID))
+ if (BackgroundActivities.Remove(hashID))
{
- BackgroundActivities.Remove(hashID);
DetachEventFromNotification(hashID);
-#if DEBUG
+ #if DEBUG
Logger.LogWriteLine($"Background activity with ID: {hashID} has been detached", LogType.Debug, true);
-#endif
return;
+ #endif
}
-#if DEBUG
+ #if DEBUG
Logger.LogWriteLine($"Cannot detach background activity with ID: {hashID} because it doesn't attached", LogType.Debug, true);
-#endif
+ #endif
}
private static void AttachEventToNotification(int hashID, IBackgroundActivity activity, string activityTitle, string activitySubtitle)
@@ -55,31 +57,31 @@ private static void AttachEventToNotification(int hashID, IBackgroundActivity ac
Thickness containerNotClosableMargin = new Thickness(-28, -8, 24, 20);
Thickness containerClosableMargin = new Thickness(-28, -8, -28, 20);
- InfoBar _parentNotifUI = new InfoBar
+ InfoBar parentNotificationUI = new InfoBar
{
Tag = hashID,
Severity = InfoBarSeverity.Informational,
Background = (Brush)Application.Current!.Resources!["InfoBarAnnouncementBrush"],
IsOpen = true,
IsClosable = false,
- Shadow = _infoBarShadow,
+ Shadow = InfoBarShadow,
Title = activityTitle,
Message = activitySubtitle
}
.WithMargin(4d, 4d, 4d, 0)
.WithCornerRadius(8);
- _parentNotifUI.Translation = LauncherConfig.Shadow32;
+ parentNotificationUI.Translation = LauncherConfig.Shadow32;
- StackPanel _parentContainer = UIElementExtensions.CreateStackPanel()
- .WithMargin(_parentNotifUI.IsClosable ? containerClosableMargin : containerNotClosableMargin);
+ StackPanel parentContainer = UIElementExtensions.CreateStackPanel()
+ .WithMargin(parentNotificationUI.IsClosable ? containerClosableMargin : containerNotClosableMargin);
- _parentNotifUI.Content = _parentContainer;
- Grid _parentGrid = _parentContainer.AddElementToStackPanel(
+ parentNotificationUI.Content = parentContainer;
+ Grid parentGrid = parentContainer.AddElementToStackPanel(
UIElementExtensions.CreateGrid()
- .WithColumns(new(72), new(1, GridUnitType.Star))
+ .WithColumns(new GridLength(72), new GridLength(1, GridUnitType.Star))
);
- StackPanel progressLogoContainer = _parentGrid.AddElementToGridColumn(
+ StackPanel progressLogoContainer = parentGrid.AddElementToGridColumn(
UIElementExtensions.CreateStackPanel()
.WithWidthAndHeight(64d)
.WithMargin(0d, 4d, 8d, 4d)
@@ -87,11 +89,11 @@ private static void AttachEventToNotification(int hashID, IBackgroundActivity ac
0
);
- GamePresetProperty CurrentGameProperty = GamePropertyVault.GetCurrentGameProperty();
+ GamePresetProperty currentGameProperty = GamePropertyVault.GetCurrentGameProperty();
_ = progressLogoContainer.AddElementToStackPanel(
new Image
{
- Source = new BitmapImage(new Uri(CurrentGameProperty!._GameVersion!.GameType switch
+ Source = new BitmapImage(new Uri(currentGameProperty!.GameVersion!.GameType switch
{
GameNameType.Honkai => "ms-appx:///Assets/Images/GameLogo/honkai-logo.png",
GameNameType.Genshin => "ms-appx:///Assets/Images/GameLogo/genshin-logo.png",
@@ -101,7 +103,7 @@ private static void AttachEventToNotification(int hashID, IBackgroundActivity ac
}))
}.WithWidthAndHeight(64));
- StackPanel progressStatusContainer = _parentGrid.AddElementToGridColumn(
+ StackPanel progressStatusContainer = parentGrid.AddElementToGridColumn(
UIElementExtensions.CreateStackPanel()
.WithVerticalAlignment(VerticalAlignment.Center)
.WithMargin(8d, -4d, 0, 0),
@@ -110,20 +112,20 @@ private static void AttachEventToNotification(int hashID, IBackgroundActivity ac
Grid progressStatusGrid = progressStatusContainer.AddElementToStackPanel(
UIElementExtensions.CreateGrid()
- .WithColumns(new(1, GridUnitType.Star), new(1, GridUnitType.Star))
- .WithRows(new(1, GridUnitType.Star), new(1, GridUnitType.Star))
+ .WithColumns(new GridLength(1, GridUnitType.Star), new GridLength(1, GridUnitType.Star))
+ .WithRows(new GridLength(1, GridUnitType.Star), new GridLength(1, GridUnitType.Star))
.WithMargin(0d, 0d, 0d, 16d)
);
TextBlock progressLeftTitle = progressStatusGrid.AddElementToGridRowColumn(new TextBlock
{
Style = UIElementExtensions.GetApplicationResource