Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preview 1.82.11 Hotfix #648

Merged
merged 50 commits into from
Jan 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
aeae079
[skip ci] Sync translation Translate en_US.json in ja_JP
transifex-integration[bot] Dec 26, 2024
d0cee71
[skip ci] Sync translation Translate en_US.json in zh_CN
transifex-integration[bot] Dec 26, 2024
a00781e
[skip ci] Update README.md
neon-nyan Dec 27, 2024
2d14d0a
Regional Discord RPC "Playing" status toggle #562
bagusnl Dec 28, 2024
6d78242
Fix ArgumentException in StartCarouselAutoScroll
bagusnl Dec 28, 2024
5f30530
[Win32] Fix ExecutionEngineException during Clipboard set
neon-nyan Dec 28, 2024
480b5ba
More using of FileInfo and DirectoryInfo
neon-nyan Dec 29, 2024
ac6a892
[skip ci] Sync translation Translate en_US.json in id_ID
transifex-integration[bot] Dec 30, 2024
5ceab0a
[skip ci] Sync translation Translate en_US.json in zh_CN
transifex-integration[bot] Dec 30, 2024
9aae481
[skip ci] Make submodule init faster in AppVeyor
bagusnl Dec 30, 2024
2ac4381
[Sentry] Filter some network exception
bagusnl Dec 30, 2024
a232009
Use Source-generated Regex on InstallManagerBase.PkgVersion
neon-nyan Dec 30, 2024
bfe8a79
Fix duplicate entry on selected sophon VO manifest
neon-nyan Dec 30, 2024
d50f05a
[Repair] Fix crashing due to value overflow
bagusnl Dec 30, 2024
95b4941
[skip ci] Sync translation Translate en_US.json in zh_CN
transifex-integration[bot] Dec 30, 2024
c919962
[skip ci] Sync translation Translate en_US.json in ja_JP
transifex-integration[bot] Dec 30, 2024
be6c53b
Ignore if VO's LanguageString is not valid on non-debug build
neon-nyan Dec 30, 2024
5256c81
Implement override for GetDeviceId on HoYoPlay API
neon-nyan Dec 30, 2024
6c3815a
Widely use User-agent aware HttpClient on UI images
neon-nyan Dec 30, 2024
81a7614
Remove unused/legacy classes on ``RegionClasses``
neon-nyan Dec 30, 2024
c1b44f6
[QD] Enable scan on release PRs
bagusnl Dec 31, 2024
4a7f04e
[Sentry] Add translated exception message and loaded modules
bagusnl Dec 31, 2024
0b32e85
[Sentry] Use hashset on exception filters
bagusnl Dec 31, 2024
bda4cd1
Remove unused usings
bagusnl Dec 31, 2024
ce8844a
[skip ci] Sync translation Translate en_US.json in vi_VN
transifex-integration[bot] Dec 31, 2024
8142cc9
Fix nulls in FileMigrationProcess.cs
bagusnl Dec 31, 2024
215a2cf
CodeQA: Virtual member calls in constructor
bagusnl Dec 31, 2024
8c614c7
[skip ci] Sync translation Translate en_US.json in vi_VN
transifex-integration[bot] Dec 31, 2024
83c9957
CodeQA: another one
bagusnl Dec 31, 2024
ace6c0f
Avoid crash if image loading is failing on NativeAOT
neon-nyan Dec 31, 2024
47d1be9
Remove unnecessary ConfigureAwait
neon-nyan Dec 31, 2024
709a89d
[Sentry] Remove Exception message localization due to trim issue
bagusnl Dec 31, 2024
1cf1e43
[skip ci] Sync translation Translate en_US.json in es_419
transifex-integration[bot] Dec 31, 2024
e33e9eb
Use fallback poster when background API is not available
bagusnl Dec 31, 2024
ba008a7
New fallback background
shatyuka Dec 31, 2024
c815443
Pop up social media flyout only once
shatyuka Dec 26, 2024
cada880
Disable some tab focus within the PostPanel
shatyuka Dec 26, 2024
16c5ae9
Resize Pivot header in PostPanel
shatyuka Dec 26, 2024
9199705
Make ScrollViewer receive focus as a whole
shatyuka Dec 27, 2024
2a2973b
Sophon improvements
neon-nyan Dec 31, 2024
591851d
Enable navigation via arrow keys in ScrollViewer
shatyuka Dec 31, 2024
8a66e1c
Make EnsureDiskSpaceSufficiencyAsync universal
neon-nyan Jan 1, 2025
df99433
Add disk space check on Sophon initial install
neon-nyan Jan 1, 2025
113e92c
CodeQA
neon-nyan Jan 1, 2025
8e391e9
Show loading state on sophon before the actual download happen
neon-nyan Jan 1, 2025
2d4efba
Update Hi3Helper.Sophon
neon-nyan Jan 1, 2025
4091f81
Fix wrong percentage assignment + check for thread access
neon-nyan Jan 1, 2025
7abdba3
Fix DB sync buttons not disabled when toggle is off
neon-nyan Jan 1, 2025
932622b
Minor Adjustment on Genshin GSP
neon-nyan Jan 1, 2025
16e4707
CodeQA
neon-nyan Jan 1, 2025
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
2 changes: 2 additions & 0 deletions .github/workflows/qodana-scan-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ on:
pull_request:
branches:
- main
- preview
- stable

jobs:
qodana:
Expand Down
177 changes: 150 additions & 27 deletions CollapseLauncher/App.xaml

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
31 changes: 22 additions & 9 deletions CollapseLauncher/Classes/CachesManagement/Honkai/Check.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using CollapseLauncher.Interfaces;
using CollapseLauncher.Helper;
using CollapseLauncher.Interfaces;
using Hi3Helper;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -57,19 +58,31 @@ private async Task<List<CacheAsset>> Check(List<CacheAsset> assetIndex, Cancella

private void CheckUnusedAssets(List<CacheAsset> assetIndex, List<CacheAsset> returnAsset)
{
// Directory info and if the directory doesn't exist, return
DirectoryInfo directoryInfo = new DirectoryInfo(_gamePath);
if (!directoryInfo.Exists)
{
return;
}

// Iterate the file contained in the _gamePath
foreach (string filePath in Directory.EnumerateFiles(_gamePath!, "*", SearchOption.AllDirectories))
foreach (FileInfo fileInfo in directoryInfo.EnumerateFiles("*", SearchOption.AllDirectories)
.EnumerateNoReadOnly())
{
if (!filePath.Contains("output_log") && !filePath.Contains("Crashes")
&& !filePath.Contains("Verify.txt") && !filePath.Contains("APM")
&& !filePath.Contains("FBData") && !filePath.Contains("asb.dat")
&& !assetIndex!.Exists(x => x!.ConcatPath == filePath))
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))
{
// Increment the total found count
_progressAllCountFound++;

// Add asset to the returnAsset
FileInfo fileInfo = new FileInfo(filePath);
CacheAsset asset = new CacheAsset()
{
BasePath = Path.GetDirectoryName(filePath),
Expand Down Expand Up @@ -106,10 +119,10 @@ private async ValueTask CheckAsset(CacheAsset asset, List<CacheAsset> returnAsse
_status.ActivityAll = string.Format(Lang._CachesPage.CachesTotalStatusChecking!, _progressAllCountCurrent, _progressAllCountTotal);

// Assign the file info.
FileInfo fileInfo = new FileInfo(asset.ConcatPath!);
FileInfo fileInfo = new FileInfo(asset.ConcatPath).EnsureNoReadOnly(out bool isExist);

// Check if the file exist. If not, then add it to asset index.
if (!fileInfo.Exists)
if (!isExist)
{
AddGenericCheckAsset(asset, CacheAssetStatus.New, returnAsset, null, asset.CRCArray);
return;
Expand Down
4 changes: 2 additions & 2 deletions CollapseLauncher/Classes/CachesManagement/Honkai/Update.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,12 @@ private async Task UpdateCacheAsset((CacheAsset AssetIndex, IAssetProperty Asset

FileInfo fileInfo = new FileInfo(asset.AssetIndex.ConcatPath!)
.EnsureCreationOfDirectory()
.EnsureNoReadOnly();
.EnsureNoReadOnly(out bool isExist);

// This is a action for Unused asset.
if (asset.AssetIndex.DataType == CacheAssetType.Unused)
{
if (fileInfo.Exists)
if (isExist)
fileInfo.Delete();

LogWriteLine($"Deleted unused file: {fileInfo.FullName}", LogType.Default, true);
Expand Down
13 changes: 7 additions & 6 deletions CollapseLauncher/Classes/CachesManagement/StarRail/Check.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Hi3Helper;
using CollapseLauncher.Helper;
using Hi3Helper;
using Hi3Helper.EncTool.Parser.AssetMetadata.SRMetadataAsset;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -79,16 +80,16 @@
}

// Get persistent and streaming paths
FileInfo fileInfoPersistent = new FileInfo(Path.Combine(basePersistent!, asset.LocalName!));
FileInfo fileInfoStreaming = new FileInfo(Path.Combine(baseStreaming!, asset.LocalName!));
FileInfo fileInfoPersistent = new FileInfo(Path.Combine(basePersistent!, asset.LocalName!)).EnsureNoReadOnly(out bool isPersistentExist);
FileInfo fileInfoStreaming = new FileInfo(Path.Combine(baseStreaming!, asset.LocalName!)).EnsureNoReadOnly(out bool isStreamingExist);

bool UsePersistent = !fileInfoStreaming.Exists;
bool IsPersistentExist = fileInfoPersistent.Exists && fileInfoPersistent.Length == asset.Size;
bool IsStreamingExist = fileInfoStreaming.Exists && fileInfoStreaming.Length == asset.Size;
bool UsePersistent = !isStreamingExist;
bool IsPersistentExist = isPersistentExist && fileInfoPersistent.Length == asset.Size;
bool IsStreamingExist = isStreamingExist && fileInfoStreaming.Length == asset.Size;
asset.LocalName = UsePersistent ? fileInfoPersistent.FullName : fileInfoStreaming.FullName;

// Check if the file exist. If not, then add it to asset index.
if (UsePersistent && !IsPersistentExist && !IsStreamingExist)

Check warning on line 92 in CollapseLauncher/Classes/CachesManagement/StarRail/Check.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Expression is always 'true' or always 'false'

Expression is always true

Check warning on line 92 in CollapseLauncher/Classes/CachesManagement/StarRail/Check.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Expression is always 'true' or always 'false'

Expression is always true
{
AddGenericCheckAsset(asset, CacheAssetStatus.New, returnAsset, null, asset.Hash);
return;
Expand Down
4 changes: 2 additions & 2 deletions CollapseLauncher/Classes/Extension/TaskExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#nullable enable
namespace CollapseLauncher.Extension
{
internal delegate Task<TResult?> ActionTimeoutValueTaskCallback<TResult>(CancellationToken token);
internal delegate void ActionOnTimeOutRetry(int retryAttemptCount, int retryAttemptTotal, int timeOutSecond, int timeOutStep);
public delegate Task<TResult?> ActionTimeoutValueTaskCallback<TResult>(CancellationToken token);
public delegate void ActionOnTimeOutRetry(int retryAttemptCount, int retryAttemptTotal, int timeOutSecond, int timeOutStep);
internal static class TaskExtensions
{
internal const int DefaultTimeoutSec = 10;
Expand Down
2 changes: 1 addition & 1 deletion CollapseLauncher/Classes/FileDialog/FileDialogHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ private static bool IsCollapseProgramPath(ReadOnlySpan<char> path)
/// </summary>
/// <param name="path">Path to check</param>
/// <returns>True if path is root of the drive</returns>
internal static bool IsRootPath(ReadOnlySpan<char> path)
public static bool IsRootPath(ReadOnlySpan<char> path)
{
ReadOnlySpan<char> rootPath = Path.GetPathRoot(path);
return rootPath.SequenceEqual(path);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,25 @@ private async Task<string> StartRoutineInner(FileMigrationProcessUIRef uiRef)

private async Task<string> MoveFile(FileMigrationProcessUIRef uiRef)
{
FileInfo inputPathInfo = new FileInfo(this.inputPath!);
FileInfo outputPathInfo = new FileInfo(this.outputPath!);
FileInfo inputPathInfo = new FileInfo(inputPath);
FileInfo outputPathInfo = new FileInfo(outputPath);

string inputPathDir = Path.GetDirectoryName(inputPathInfo.FullName);
string outputPathDir = Path.GetDirectoryName(outputPathInfo.FullName);
var inputPathDir = FileDialogHelper.IsRootPath(inputPath)
? Path.GetPathRoot(inputPath)
: Path.GetDirectoryName(inputPathInfo.FullName);

if (!Directory.Exists(outputPathDir))
Directory.CreateDirectory(outputPathDir!);
if (string.IsNullOrEmpty(inputPathDir))
throw new InvalidOperationException(string.Format(Locale.Lang._Dialogs.InvalidGameDirNewTitleFormat,
inputPath));

DirectoryInfo outputPathDirInfo = new DirectoryInfo(inputPathDir);
outputPathDirInfo.Create();

// Update path display
string inputFileBasePath = inputPathInfo.FullName.Substring(inputPathDir!.Length + 1);
UpdateCountProcessed(uiRef, inputFileBasePath);

if (this.IsSameOutputDrive)
if (IsSameOutputDrive)
{
Logger.LogWriteLine($"[FileMigrationProcess::MoveFile()] Moving file in the same drive from: {inputPathInfo.FullName} to {outputPathInfo.FullName}", LogType.Default, true);
inputPathInfo.MoveTo(outputPathInfo.FullName, true);
Expand All @@ -112,29 +117,27 @@ private async Task<string> MoveFile(FileMigrationProcessUIRef uiRef)
else
{
Logger.LogWriteLine($"[FileMigrationProcess::MoveFile()] Moving file across different drives from: {inputPathInfo.FullName} to {outputPathInfo.FullName}", LogType.Default, true);
await MoveWriteFile(uiRef, inputPathInfo, outputPathInfo, this.tokenSource == null ? default : this.tokenSource.Token);
await MoveWriteFile(uiRef, inputPathInfo, outputPathInfo, tokenSource == null ? default : tokenSource.Token);
}

return outputPathInfo.FullName;
}

private async Task<string> MoveDirectory(FileMigrationProcessUIRef uiRef)
{
DirectoryInfo inputPathInfo = new DirectoryInfo(this.inputPath!);
if (!Directory.Exists(this.outputPath))
Directory.CreateDirectory(this.outputPath!);

DirectoryInfo outputPathInfo = new DirectoryInfo(this.outputPath);
DirectoryInfo inputPathInfo = new DirectoryInfo(inputPath);
DirectoryInfo outputPathInfo = new DirectoryInfo(outputPath);
outputPathInfo.Create();

int parentInputPathLength = inputPathInfo.Parent!.FullName.Length + 1;
string outputDirBaseNamePath = inputPathInfo.FullName.Substring(parentInputPathLength);
string outputDirPath = Path.Combine(this.outputPath, outputDirBaseNamePath);
string outputDirPath = Path.Combine(outputPath, outputDirBaseNamePath);

await Parallel.ForEachAsync(
inputPathInfo.EnumerateFiles("*", SearchOption.AllDirectories),
new ParallelOptions
{
CancellationToken = this.tokenSource?.Token ?? default,
CancellationToken = tokenSource?.Token ?? default,
MaxDegreeOfParallelism = LauncherConfig.AppCurrentThread
},
async (inputFileInfo, cancellationToken) =>
Expand All @@ -146,10 +149,14 @@ await Parallel.ForEachAsync(
UpdateCountProcessed(uiRef, inputFileBasePath);

string outputTargetPath = Path.Combine(outputPathInfo.FullName, inputFileBasePath);
string outputTargetDirPath = Path.GetDirectoryName(outputTargetPath);

if (!Directory.Exists(outputTargetDirPath))
Directory.CreateDirectory(outputTargetDirPath!);
string outputTargetDirPath = Path.GetDirectoryName(outputTargetPath) ?? Path.GetPathRoot(outputTargetPath);

if (string.IsNullOrEmpty(outputTargetDirPath))
throw new InvalidOperationException(string.Format(Locale.Lang._Dialogs.InvalidGameDirNewTitleFormat,
inputPath));

DirectoryInfo outputTargetDirInfo = new DirectoryInfo(outputTargetDirPath);
Fixed Show fixed Hide fixed
outputTargetDirInfo.Create();

if (this.IsSameOutputDrive)
{
Expand Down
4 changes: 2 additions & 2 deletions CollapseLauncher/Classes/FileMigrationProcess/IO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ private async Task MoveWriteFile(FileMigrationProcessUIRef uiRef, FileInfo input
{
int bufferSize = 1 << 18; // 256 kB Buffer

if (inputFile!.Length < bufferSize)
if (inputFile.Length < bufferSize)
bufferSize = (int)inputFile.Length;

byte[] buffer = new byte[bufferSize];

await using (FileStream inputStream = inputFile.OpenRead())
await using (FileStream outputStream = outputFile!.Exists && outputFile.Length <= inputFile.Length ?
await using (FileStream outputStream = outputFile.Exists && outputFile.Length <= inputFile.Length ?
outputFile.Open(FileMode.Open) : outputFile.Create())
{
// Set the output file size to inputStream's if the length is more than inputStream
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ public bool UseCustomRegionBG
/// Determines if the game playtime should be synced to the database
/// </summary>
public bool IsSyncPlaytimeToDatabase { get; set; } = true;

/// <summary>
/// Set per-region Discord Rich Presence setting for playing status
/// </summary>
public bool IsPlayingRpc { get; set; } = true;

#endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ internal enum MediaType
{
try
{
await action.ConfigureAwait(false);
await action;
}
catch (Exception ex)
{
Expand Down
64 changes: 50 additions & 14 deletions CollapseLauncher/Classes/Helper/HttpClientBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using CollapseLauncher.Helper.Update;
using Hi3Helper.Shared.Region;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Http;
Expand All @@ -17,21 +18,22 @@ public class HttpClientBuilder : HttpClientBuilder<SocketsHttpHandler>;
private const int _maxConnectionsDefault = 32;
private const double _httpTimeoutDefault = 90; // in Seconds

private bool IsUseProxy { get; set; } = true;
private bool IsUseSystemProxy { get; set; } = true;
private bool IsUseProxy { get; set; } = true;
private bool IsUseSystemProxy { get; set; } = true;
private bool IsAllowHttpRedirections { get; set; }
private bool IsAllowHttpCookies { get; set; }
private bool IsAllowUntrustedCert { get; set; }

private int MaxConnections { get; set; } = _maxConnectionsDefault;
private DecompressionMethods DecompressionMethod { get; set; } = DecompressionMethods.All;
private WebProxy? ExternalProxy { get; set; }
private Version HttpProtocolVersion { get; set; } = HttpVersion.Version30;
private string? HttpUserAgent { get; set; } = GetDefaultUserAgent();
private string? HttpAuthHeader { get; set; }
private HttpVersionPolicy HttpProtocolVersionPolicy { get; set; } = HttpVersionPolicy.RequestVersionOrLower;
private TimeSpan HttpTimeout { get; set; } = TimeSpan.FromSeconds(_httpTimeoutDefault);
private Uri? HttpBaseUri { get; set; }
private bool IsAllowHttpCookies { get; set; }
private bool IsAllowUntrustedCert { get; set; }

private int MaxConnections { get; set; } = _maxConnectionsDefault;
private DecompressionMethods DecompressionMethod { get; set; } = DecompressionMethods.All;
private WebProxy? ExternalProxy { get; set; }
private Version HttpProtocolVersion { get; set; } = HttpVersion.Version30;
private string? HttpUserAgent { get; set; } = GetDefaultUserAgent();
private string? HttpAuthHeader { get; set; }
private HttpVersionPolicy HttpProtocolVersionPolicy { get; set; } = HttpVersionPolicy.RequestVersionOrLower;
private TimeSpan HttpTimeout { get; set; } = TimeSpan.FromSeconds(_httpTimeoutDefault);
private Uri? HttpBaseUri { get; set; }
private Dictionary<string, string?> HttpHeaders { get; set; } = new(StringComparer.OrdinalIgnoreCase);

public HttpClientBuilder<THandler> UseProxy(bool isUseSystemProxy = true)
{
Expand Down Expand Up @@ -191,6 +193,34 @@ public HttpClientBuilder<THandler> SetBaseUrl(Uri baseUrl)
return this;
}

public HttpClientBuilder<THandler> AddHeader(string key, string? value)
{
// Throw if the key is null or empty
ArgumentException.ThrowIfNullOrEmpty(key, nameof(key));

// Try check if the key is user-agent. If the user-agent has already
// been set, then override the value from HttpUserAgent property
if (key.Equals("User-Agent", StringComparison.OrdinalIgnoreCase))
{
HttpUserAgent = null;
}

// If the key already exist, then override the previous one.
// Otherwise, add the new key-value pair
// ReSharper disable once RedundantDictionaryContainsKeyBeforeAdding
if (HttpHeaders.ContainsKey(key))
Fixed Show fixed Hide fixed
{
HttpHeaders[key] = value;
}
else
{
HttpHeaders.Add(key, value);
}

// Return the instance of the builder
return this;
}

public HttpClient Create()
{
// Create the instance of the handler
Expand Down Expand Up @@ -273,6 +303,12 @@ public HttpClient Create()
if (!string.IsNullOrEmpty(HttpAuthHeader))
client.DefaultRequestHeaders.Add("Authorization", HttpAuthHeader);

// Add other headers
foreach (KeyValuePair<string, string?> header in HttpHeaders)
{
_ = client.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value);
}

return client;
}
}
Expand Down
Loading
Loading