Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/dd-static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ jobs:

- name: Check code meets quality and security standards
id: datadog-static-analysis
uses: DataDog/datadog-static-analyzer-github-action@v1
uses: DataDog/datadog-static-analyzer-github-action@v3
with:
dd_api_key: ${{ secrets.DD_API_KEY }}
dd_app_key: ${{ secrets.DD_APP_KEY }}
dd_site: ap1.datadoghq.com
secrets_enabled: false
static_analysis_enabled: true
cpu_count: 2
cpu_count: 2
23 changes: 13 additions & 10 deletions CollapseLauncher/Classes/CachesManagement/Honkai/Check.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,6 @@ private async Task<List<CacheAsset>> Check(List<CacheAsset> assetIndex, Cancella
return returnAsset;
}

private readonly SearchValues<string> _unusedSearchValues = SearchValues.Create([
"output_log",
"Crashes",
"Verify.txt",
"APM",
"FBData",
"asb.dat"
], StringComparison.OrdinalIgnoreCase);

private void CheckUnusedAssets(List<CacheAsset> assetIndex, List<CacheAsset> returnAsset)
{
// Directory info and if the directory doesn't exist, return
Expand All @@ -76,13 +67,25 @@ private void CheckUnusedAssets(List<CacheAsset> assetIndex, List<CacheAsset> ret
return;
}

SearchValues<string> unusedSearchValues = SearchValues
.Create(GameVersionManager.GamePreset.GameInstallFileInfo?.CacheUpdateUnusedFilesIgnoreList
?? [
"output_log",
"Crashes",
"Verify.txt",
"APM",
"FBData",
"asb.dat",
"MiHoYoSDK.log"
], StringComparison.OrdinalIgnoreCase);

// Iterate the file contained in the _gamePath
foreach (FileInfo fileInfo in directoryInfo.EnumerateFiles("*", SearchOption.AllDirectories)
.EnumerateNoReadOnly())
{
ReadOnlySpan<char> filePath = fileInfo.FullName;

if (filePath.ContainsAny(_unusedSearchValues)
if (filePath.ContainsAny(unusedSearchValues)
|| assetIndex.Exists(x => x.ConcatPath == fileInfo.FullName))
{
continue;
Expand Down
11 changes: 6 additions & 5 deletions CollapseLauncher/Classes/Helper/Metadata/PresetConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,12 @@ public enum LauncherType

public class GameInstallFileInfo
{
public string GameDataFolderName { get; init; } = string.Empty;
public string[] FilesToDelete { get; init; } = [];
public string[] FoldersToDelete { get; init; } = [];
public string[] FoldersToKeepInData { get; init; } = [];
public string[] FilesCleanupIgnoreList { get; init; } = [];
public string GameDataFolderName { get; init; } = string.Empty;
public string[] FilesToDelete { get; init; } = [];
public string[] FoldersToDelete { get; init; } = [];
public string[] FoldersToKeepInData { get; init; } = [];
public string[] FilesCleanupIgnoreList { get; init; } = [];
public string[] CacheUpdateUnusedFilesIgnoreList { get; init; } = [];
}

public class SophonChunkUrls
Expand Down
32 changes: 23 additions & 9 deletions CollapseLauncher/Classes/Helper/StreamUtility/StreamExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -309,28 +309,42 @@ public static FileInfo ResolveSymlink(this FileInfo fileInfo)
/// </summary>
/// <param name="dir">The directory to remove.</param>
/// <param name="recursive">Whether to remove all possibly empty directories recursively.</param>
public static void DeleteEmptyDirectory(this string dir, bool recursive = false)
public static bool DeleteEmptyDirectory(this string dir, bool recursive = false)
=> new DirectoryInfo(dir).DeleteEmptyDirectory(recursive);

/// <summary>
/// Deletes the directory if it is empty.
/// </summary>
/// <param name="dir">The directory to remove.</param>
/// <param name="recursive">Whether to remove all possibly empty directories recursively.</param>
public static void DeleteEmptyDirectory(this DirectoryInfo dir, bool recursive = false)
public static bool DeleteEmptyDirectory(this DirectoryInfo dir, bool recursive = false)
{
if (recursive)
try
{
foreach (DirectoryInfo childDir in dir.EnumerateDirectories("*", SearchOption.TopDirectoryOnly))
if (!dir.Exists)
{
childDir.DeleteEmptyDirectory();
return true;
}

if (recursive)
{
foreach (DirectoryInfo childDir in dir.EnumerateDirectories("*", SearchOption.TopDirectoryOnly))
{
childDir.DeleteEmptyDirectory();
}
}
}

FindFiles.TryIsDirectoryEmpty(dir.FullName, out bool isEmpty);
if (isEmpty)
FindFiles.TryIsDirectoryEmpty(dir.FullName, out bool isEmpty);
if (isEmpty)
{
dir.Delete(true);
}

return true;
}
catch
{
dir.Delete(true);
return false;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,7 @@ await TryGetAdditionalPackageForSophonDiff(httpClient,
}

// Filter asset list
await FilterSophonPatchAssetList(sophonUpdateAssetList, Token!.Token);
await FilterAssetList(sophonUpdateAssetList, x => x.AssetName, Token!.Token);

// Get the remote chunk size
ProgressPerFileSizeTotal = sophonUpdateAssetList.GetCalculatedDiffSize(!isPreloadMode);
Expand Down Expand Up @@ -925,12 +925,6 @@ await Parallel.ForEachAsync(sophonUpdateAssetList
}
}

protected virtual Task FilterSophonPatchAssetList(List<SophonAsset> itemList, CancellationToken token)
{
// NOP
return Task.CompletedTask;
}

private ValueTask RunSophonAssetDownloadThread(HttpClient client,
SophonAsset asset,
ParallelOptions parallelOptions)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Hi3Helper.Data;
using Hi3Helper;
using Hi3Helper.Data;
using System;
using System.Buffers;
using System.Collections.Generic;
Expand Down Expand Up @@ -56,15 +57,19 @@ public override async Task FilterAssetList<T>(
List<T> listFiltered = [];
foreach (T patchAsset in itemList)
{
if (itemPathSelector(patchAsset) is not {} filePath)
if (itemPathSelector(patchAsset) is not { } filePath)
{
listFiltered.Add(patchAsset);
continue;
}

ConverterTool.NormalizePathInplaceNoTrim(filePath);

int indexOfAny = filePath.IndexOfAny(searchValues);
if (indexOfAny >= 0)
{
Logger.LogWriteLine($"[StarRailInstall::FilterAssetList] Asset: {patchAsset} is ignored due to marked as deleted asset.",
writeToLog: true);
continue;
}

Expand All @@ -90,12 +95,9 @@ static ReadOnlySpan<char> GetFilePathFromJson(ReadOnlySpan<char> line)
line = line[(firstIndexOf + first.Length)..];
int endIndexOf = line.IndexOf(end);

if (endIndexOf <= 0)
{
return ReadOnlySpan<char>.Empty;
}

return line[..endIndexOf];
return endIndexOf <= 0
? ReadOnlySpan<char>.Empty
: line[..endIndexOf];
}
}

Expand Down Expand Up @@ -127,4 +129,4 @@ private static void AddBothPersistentOrStreamingAssets(
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
using Hi3Helper.Sophon;
using Hi3Helper.Sophon.Infos;
using Hi3Helper;
using Hi3Helper.Sophon.Structs;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
// ReSharper disable CheckNamespace
Expand All @@ -17,17 +15,9 @@ internal partial class ZenlessInstall
{
private const StringSplitOptions SplitOptions = StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries;

// ReSharper disable once StringLiteralTypo
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "<SophonChunksInfo>k__BackingField")]
private static extern ref SophonChunksInfo GetChunkAssetChunksInfo(SophonAsset element);

// ReSharper disable once StringLiteralTypo
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "<SophonChunksInfoAlt>k__BackingField")]
private static extern ref SophonChunksInfo GetChunkAssetChunksInfoAlt(SophonAsset element);

public override async Task FilterAssetList<T>(
List<T> itemList,
Func<T, string?> itemPathSelector,
List<T> itemList,
Func<T, string?> itemPathSelector,
CancellationToken token)
{
HashSet<string> exceptMatchFieldHashSet = await GetExceptMatchFieldHashSet(token);
Expand Down Expand Up @@ -67,6 +57,8 @@ private static void FilterSophonAsset<T>(List<T> itemList, HashSet<string> excep
if (asset is SophonIdentifiableProperty { MatchingField: { } assetMatchingField } &&
exceptMatchFieldHashSet.Contains(assetMatchingField))
{
Logger.LogWriteLine($"[ZenlessInstall::FilterSophonAsset] Asset: {asset} is ignored due to marked as deleted asset.",
writeToLog: true);
continue;
}

Expand Down Expand Up @@ -114,4 +106,4 @@ internal static HashSet<string> CreateExceptMatchFieldHashSet(string exceptMatch
return hashSetReturn;
}
}
}
}
18 changes: 15 additions & 3 deletions CollapseLauncher/Classes/RepairManagement/Genshin/Repair.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
// ReSharper disable StringLiteralTypo
// ReSharper disable CommentTypo

#nullable enable
namespace CollapseLauncher
{
internal partial class GenshinRepair
Expand All @@ -46,7 +47,15 @@ private async Task<bool> Repair(List<PkgVersionProperties> repairAssetIndex, Can
DownloadClient downloadClient = DownloadClient.CreateInstance(client);

// Get the Dispatcher Query
QueryProperty queryProperty = await GetCachedDispatcherQuery(downloadClient.GetHttpClient(), token);
QueryProperty? queryProperty = null;
try
{
queryProperty = await GetCachedDispatcherQuery(downloadClient.GetHttpClient(), token);
}
catch (Exception ex)
{
LogWriteLine($"An error has occurred while parsing Persistent Manifests! {ex}", LogType.Warning, true);
}

// Iterate repair asset
ObservableCollection<IAssetProperty> assetProperty = [.. AssetEntry];
Expand Down Expand Up @@ -97,7 +106,10 @@ await Parallel.ForEachAsync(
}
}

await SavePersistentRevision(queryProperty, token);
if (queryProperty != null)
{
await SavePersistentRevision(queryProperty, token);
}

// Duplicate ctable.dat to ctable_streaming.dat
string streamingAssetsPath = Path.Combine(GamePath, $"{ExecPrefix}_Data", "StreamingAssets");
Expand Down Expand Up @@ -157,7 +169,7 @@ private async Task RepairAssetTypeGeneric((PkgVersionProperties AssetIndex, IAss
if (isUseSophonDownload)
{
ReadOnlySpan<char> splittedPath = asset.AssetIndex.remoteName.TrimStart('\\');
if (!SophonAssetDictRefLookup.TryGetValue(splittedPath, out SophonAsset downloadAsSophon))
if (!SophonAssetDictRefLookup.TryGetValue(splittedPath, out SophonAsset? downloadAsSophon))
{
throw new InvalidOperationException($"Asset {splittedPath} is marked as \"SophonGeneric\" but it wasn't included in the manifest");
}
Expand Down
Loading
Loading