This commit is contained in:
Lightczx
2023-07-30 12:47:22 +08:00
parent c5ab707b66
commit 93ee1a3386
29 changed files with 112 additions and 57 deletions

View File

@@ -138,6 +138,12 @@ internal sealed class DependencyPropertyGenerator : IIncrementalGenerator
return boolValue ? "true" : "false"; return boolValue ? "true" : "false";
} }
return typedConstant.Value!.ToString(); string result = typedConstant.Value!.ToString();
if (string.IsNullOrEmpty(result))
{
return default;
}
return result;
} }
} }

View File

@@ -40,7 +40,7 @@ internal sealed class UniversalAnalyzer : DiagnosticAnalyzer
context.RegisterCompilationStartAction(CompilationStart); context.RegisterCompilationStartAction(CompilationStart);
} }
private void CompilationStart(CompilationStartAnalysisContext context) private static void CompilationStart(CompilationStartAnalysisContext context)
{ {
SyntaxKind[] types = new SyntaxKind[] SyntaxKind[] types = new SyntaxKind[]
{ {
@@ -50,13 +50,14 @@ internal sealed class UniversalAnalyzer : DiagnosticAnalyzer
SyntaxKind.EnumDeclaration SyntaxKind.EnumDeclaration
}; };
context.RegisterSyntaxNodeAction(HandleTypeDeclaration, types); context.RegisterSyntaxNodeAction(HandleTypeShouldBeInternal, types);
context.RegisterSyntaxNodeAction(HandleMethodDeclaration, SyntaxKind.MethodDeclaration); context.RegisterSyntaxNodeAction(HandleMethodParameterShouldUseRefLikeKeyword, SyntaxKind.MethodDeclaration);
context.RegisterSyntaxNodeAction(HandleConstructorDeclaration, SyntaxKind.ConstructorDeclaration); context.RegisterSyntaxNodeAction(HandleMethodReturnTypeShouldUseValueTaskInsteadOfTask, SyntaxKind.MethodDeclaration);
context.RegisterSyntaxNodeAction(HandleConstructorParameterShouldUseRefLikeKeyword, SyntaxKind.ConstructorDeclaration);
} }
private void HandleTypeDeclaration(SyntaxNodeAnalysisContext context) private static void HandleTypeShouldBeInternal(SyntaxNodeAnalysisContext context)
{ {
BaseTypeDeclarationSyntax syntax = (BaseTypeDeclarationSyntax)context.Node; BaseTypeDeclarationSyntax syntax = (BaseTypeDeclarationSyntax)context.Node;
@@ -90,15 +91,31 @@ internal sealed class UniversalAnalyzer : DiagnosticAnalyzer
} }
} }
private void HandleMethodDeclaration(SyntaxNodeAnalysisContext context) private static void HandleMethodReturnTypeShouldUseValueTaskInsteadOfTask(SyntaxNodeAnalysisContext context)
{ {
MethodDeclarationSyntax methodSyntax = (MethodDeclarationSyntax)context.Node; MethodDeclarationSyntax methodSyntax = (MethodDeclarationSyntax)context.Node;
IMethodSymbol methodSymbol = context.SemanticModel.GetDeclaredSymbol(methodSyntax)!; IMethodSymbol methodSymbol = context.SemanticModel.GetDeclaredSymbol(methodSyntax)!;
// 跳过重载方法
if (methodSyntax.Modifiers.Any(token => token.IsKind(SyntaxKind.OverrideKeyword)))
{
return;
}
if (methodSymbol.ReturnType.IsOrInheritsFrom("System.Threading.Tasks.Task")) if (methodSymbol.ReturnType.IsOrInheritsFrom("System.Threading.Tasks.Task"))
{ {
Location location = methodSyntax.ReturnType.GetLocation(); Location location = methodSyntax.ReturnType.GetLocation();
Diagnostic diagnostic = Diagnostic.Create(useValueTaskIfPossibleDescriptor, location); Diagnostic diagnostic = Diagnostic.Create(useValueTaskIfPossibleDescriptor, location);
context.ReportDiagnostic(diagnostic); context.ReportDiagnostic(diagnostic);
}
}
private static void HandleMethodParameterShouldUseRefLikeKeyword(SyntaxNodeAnalysisContext context)
{
MethodDeclarationSyntax methodSyntax = (MethodDeclarationSyntax)context.Node;
IMethodSymbol methodSymbol = context.SemanticModel.GetDeclaredSymbol(methodSyntax)!;
if (methodSymbol.ReturnType.IsOrInheritsFrom("System.Threading.Tasks.Task"))
{
return; return;
} }
@@ -150,7 +167,7 @@ internal sealed class UniversalAnalyzer : DiagnosticAnalyzer
} }
} }
private void HandleConstructorDeclaration(SyntaxNodeAnalysisContext context) private static void HandleConstructorParameterShouldUseRefLikeKeyword(SyntaxNodeAnalysisContext context)
{ {
ConstructorDeclarationSyntax constructorSyntax = (ConstructorDeclarationSyntax)context.Node; ConstructorDeclarationSyntax constructorSyntax = (ConstructorDeclarationSyntax)context.Node;

View File

@@ -143,7 +143,7 @@ internal struct Rgba32
/// 转换到 HSL 颜色 /// 转换到 HSL 颜色
/// </summary> /// </summary>
/// <returns>HSL 颜色</returns> /// <returns>HSL 颜色</returns>
public HslColor ToHsl() public readonly HslColor ToHsl()
{ {
const double toDouble = 1.0 / 255; const double toDouble = 1.0 / 255;
double r = toDouble * R; double r = toDouble * R;

View File

@@ -54,7 +54,7 @@ internal class ScopedPage : Page
/// </summary> /// </summary>
/// <param name="extra">额外内容</param> /// <param name="extra">额外内容</param>
/// <returns>任务</returns> /// <returns>任务</returns>
public async Task NotifyRecipientAsync(INavigationData extra) public async ValueTask NotifyRecipientAsync(INavigationData extra)
{ {
if (extra.Data != null && DataContext is INavigationRecipient recipient) if (extra.Data != null && DataContext is INavigationRecipient recipient)
{ {

View File

@@ -17,7 +17,7 @@ internal interface IImageCache : ICastService
/// </summary> /// </summary>
/// <param name="uri">Uri of the item.</param> /// <param name="uri">Uri of the item.</param>
/// <returns>a string path</returns> /// <returns>a string path</returns>
Task<ValueFile> GetFileFromCacheAsync(Uri uri); ValueTask<ValueFile> GetFileFromCacheAsync(Uri uri);
/// <summary> /// <summary>
/// Removed items based on uri list passed /// Removed items based on uri list passed

View File

@@ -93,7 +93,7 @@ internal sealed class ImageCache : IImageCache, IImageCacheFilePathOperation
} }
/// <inheritdoc/> /// <inheritdoc/>
public async Task<ValueFile> GetFileFromCacheAsync(Uri uri) public async ValueTask<ValueFile> GetFileFromCacheAsync(Uri uri)
{ {
string fileName = GetCacheFileName(uri); string fileName = GetCacheFileName(uri);
string filePath = Path.Combine(GetCacheFolder(), fileName); string filePath = Path.Combine(GetCacheFolder(), fileName);
@@ -166,6 +166,7 @@ internal sealed class ImageCache : IImageCache, IImageCacheFilePathOperation
} }
} }
[SuppressMessage("", "SH003")]
private async Task DownloadFileAsync(Uri uri, string baseFile) private async Task DownloadFileAsync(Uri uri, string baseFile)
{ {
logger.LogInformation("Begin downloading for {Uri}", uri); logger.LogInformation("Begin downloading for {Uri}", uri);

View File

@@ -35,8 +35,8 @@ internal static class QueryableExtension
/// <param name="token">取消令牌</param> /// <param name="token">取消令牌</param>
/// <returns>SQL返回个数</returns> /// <returns>SQL返回个数</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Task<int> ExecuteDeleteWhereAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate, CancellationToken token = default) public static ValueTask<int> ExecuteDeleteWhereAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate, CancellationToken token = default)
{ {
return source.Where(predicate).ExecuteDeleteAsync(token); return source.Where(predicate).ExecuteDeleteAsync(token).AsValueTask();
} }
} }

View File

@@ -17,7 +17,7 @@ internal sealed partial class ClipboardInterop : IClipboardInterop
private readonly ITaskContext taskContext; private readonly ITaskContext taskContext;
/// <inheritdoc/> /// <inheritdoc/>
public async Task<T?> DeserializeFromJsonAsync<T>() public async ValueTask<T?> DeserializeFromJsonAsync<T>()
where T : class where T : class
{ {
await taskContext.SwitchToMainThreadAsync(); await taskContext.SwitchToMainThreadAsync();

View File

@@ -15,7 +15,7 @@ internal interface IClipboardInterop
/// </summary> /// </summary>
/// <typeparam name="T">目标类型</typeparam> /// <typeparam name="T">目标类型</typeparam>
/// <returns>实例</returns> /// <returns>实例</returns>
Task<T?> DeserializeFromJsonAsync<T>() ValueTask<T?> DeserializeFromJsonAsync<T>()
where T : class; where T : class;
/// <summary> /// <summary>

View File

@@ -17,7 +17,7 @@ internal static class MD5
/// <param name="filePath">文件路径</param> /// <param name="filePath">文件路径</param>
/// <param name="token">取消令牌</param> /// <param name="token">取消令牌</param>
/// <returns>文件 Md5 摘要</returns> /// <returns>文件 Md5 摘要</returns>
public static async Task<string> HashFileAsync(string filePath, CancellationToken token = default) public static async ValueTask<string> HashFileAsync(string filePath, CancellationToken token = default)
{ {
await using (FileStream stream = File.OpenRead(filePath)) await using (FileStream stream = File.OpenRead(filePath))
{ {
@@ -31,7 +31,7 @@ internal static class MD5
/// <param name="stream">流</param> /// <param name="stream">流</param>
/// <param name="token">取消令牌</param> /// <param name="token">取消令牌</param>
/// <returns>流 Md5 摘要</returns> /// <returns>流 Md5 摘要</returns>
public static async Task<string> HashAsync(Stream stream, CancellationToken token = default) public static async ValueTask<string> HashAsync(Stream stream, CancellationToken token = default)
{ {
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create()) using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{ {

View File

@@ -17,7 +17,7 @@ internal static class XXH64
/// <param name="stream">流</param> /// <param name="stream">流</param>
/// <param name="token">取消令牌</param> /// <param name="token">取消令牌</param>
/// <returns>摘要</returns> /// <returns>摘要</returns>
public static async Task<string> HashAsync(Stream stream, CancellationToken token = default) public static async ValueTask<string> HashAsync(Stream stream, CancellationToken token = default)
{ {
XxHash64 xxHash64 = new(); XxHash64 xxHash64 = new();
await xxHash64.AppendAsync(stream, token).ConfigureAwait(false); await xxHash64.AppendAsync(stream, token).ConfigureAwait(false);
@@ -31,7 +31,7 @@ internal static class XXH64
/// <param name="path">路径</param> /// <param name="path">路径</param>
/// <param name="token">取消令牌</param> /// <param name="token">取消令牌</param>
/// <returns>摘要</returns> /// <returns>摘要</returns>
public static async Task<string> HashFileAsync(string path, CancellationToken token = default) public static async ValueTask<string> HashFileAsync(string path, CancellationToken token = default)
{ {
await using (FileStream stream = File.OpenRead(path)) await using (FileStream stream = File.OpenRead(path))
{ {

View File

@@ -13,7 +13,7 @@ namespace Snap.Hutao.Core.IO;
internal static class PickerExtension internal static class PickerExtension
{ {
/// <inheritdoc cref="FileOpenPicker.PickSingleFileAsync"/> /// <inheritdoc cref="FileOpenPicker.PickSingleFileAsync"/>
public static async Task<ValueResult<bool, ValueFile>> TryPickSingleFileAsync(this FileOpenPicker picker) public static async ValueTask<ValueResult<bool, ValueFile>> TryPickSingleFileAsync(this FileOpenPicker picker)
{ {
StorageFile? file; StorageFile? file;
Exception? exception = null; Exception? exception = null;
@@ -39,7 +39,7 @@ internal static class PickerExtension
} }
/// <inheritdoc cref="FileSavePicker.PickSaveFileAsync"/> /// <inheritdoc cref="FileSavePicker.PickSaveFileAsync"/>
public static async Task<ValueResult<bool, ValueFile>> TryPickSaveFileAsync(this FileSavePicker picker) public static async ValueTask<ValueResult<bool, ValueFile>> TryPickSaveFileAsync(this FileSavePicker picker)
{ {
StorageFile? file; StorageFile? file;
Exception? exception = null; Exception? exception = null;
@@ -65,7 +65,7 @@ internal static class PickerExtension
} }
/// <inheritdoc cref="FolderPicker.PickSingleFolderAsync"/> /// <inheritdoc cref="FolderPicker.PickSingleFolderAsync"/>
public static async Task<ValueResult<bool, string>> TryPickSingleFolderAsync(this FolderPicker picker) public static async ValueTask<ValueResult<bool, string>> TryPickSingleFolderAsync(this FolderPicker picker)
{ {
StorageFolder? folder; StorageFolder? folder;
Exception? exception = null; Exception? exception = null;

View File

@@ -38,7 +38,7 @@ internal sealed class StreamCopyWorker
/// </summary> /// </summary>
/// <param name="progress">进度</param> /// <param name="progress">进度</param>
/// <returns>任务</returns> /// <returns>任务</returns>
public async Task CopyAsync(IProgress<StreamCopyStatus> progress) public async ValueTask CopyAsync(IProgress<StreamCopyStatus> progress)
{ {
long totalBytesRead = 0; long totalBytesRead = 0;
int bytesRead; int bytesRead;
@@ -91,7 +91,7 @@ internal sealed class StreamCopyWorker<TStatus>
/// </summary> /// </summary>
/// <param name="progress">进度</param> /// <param name="progress">进度</param>
/// <returns>任务</returns> /// <returns>任务</returns>
public async Task CopyAsync(IProgress<TStatus> progress) public async ValueTask CopyAsync(IProgress<TStatus> progress)
{ {
long totalBytesRead = 0; long totalBytesRead = 0;
int bytesRead; int bytesRead;

View File

@@ -37,7 +37,7 @@ internal readonly struct ValueFile
/// <typeparam name="T">内容的类型</typeparam> /// <typeparam name="T">内容的类型</typeparam>
/// <param name="options">序列化选项</param> /// <param name="options">序列化选项</param>
/// <returns>操作是否成功,反序列化后的内容</returns> /// <returns>操作是否成功,反序列化后的内容</returns>
public async Task<ValueResult<bool, T?>> DeserializeFromJsonAsync<T>(JsonSerializerOptions options) public async ValueTask<ValueResult<bool, T?>> DeserializeFromJsonAsync<T>(JsonSerializerOptions options)
where T : class where T : class
{ {
try try
@@ -62,7 +62,7 @@ internal readonly struct ValueFile
/// <param name="obj">对象</param> /// <param name="obj">对象</param>
/// <param name="options">序列化选项</param> /// <param name="options">序列化选项</param>
/// <returns>操作是否成功</returns> /// <returns>操作是否成功</returns>
public async Task<bool> SerializeToJsonAsync<T>(T obj, JsonSerializerOptions options) public async ValueTask<bool> SerializeToJsonAsync<T>(T obj, JsonSerializerOptions options)
{ {
try try
{ {

View File

@@ -103,7 +103,7 @@ internal sealed class Activation : IActivation
} }
} }
private async Task HandleActivationAsync(AppActivationArguments args, bool isRedirected) private async ValueTask HandleActivationAsync(AppActivationArguments args, bool isRedirected)
{ {
if (activateSemaphore.CurrentCount > 0) if (activateSemaphore.CurrentCount > 0)
{ {
@@ -114,7 +114,7 @@ internal sealed class Activation : IActivation
} }
} }
private async Task HandleActivationCoreAsync(AppActivationArguments args, bool isRedirected) private async ValueTask HandleActivationCoreAsync(AppActivationArguments args, bool isRedirected)
{ {
if (args.Kind == ExtendedActivationKind.Protocol) if (args.Kind == ExtendedActivationKind.Protocol)
{ {
@@ -145,7 +145,7 @@ internal sealed class Activation : IActivation
} }
} }
private async Task HandleNormalLaunchActionAsync() private async ValueTask HandleNormalLaunchActionAsync()
{ {
// Increase launch times // Increase launch times
LocalSetting.Set(SettingKeys.LaunchTimes, LocalSetting.Get(SettingKeys.LaunchTimes, 0) + 1); LocalSetting.Set(SettingKeys.LaunchTimes, LocalSetting.Get(SettingKeys.LaunchTimes, 0) + 1);
@@ -161,7 +161,7 @@ internal sealed class Activation : IActivation
} }
} }
private async Task WaitMainWindowAsync() private async ValueTask WaitMainWindowAsync()
{ {
if (!mainWindowReference.TryGetTarget(out _)) if (!mainWindowReference.TryGetTarget(out _))
{ {
@@ -183,7 +183,7 @@ internal sealed class Activation : IActivation
} }
} }
private async Task HandleUrlActivationAsync(Uri uri, bool isRedirected) private async ValueTask HandleUrlActivationAsync(Uri uri, bool isRedirected)
{ {
UriBuilder builder = new(uri); UriBuilder builder = new(uri);
@@ -214,7 +214,7 @@ internal sealed class Activation : IActivation
} }
} }
private async Task HandleAchievementActionAsync(string action, string parameter, bool isRedirected) private async ValueTask HandleAchievementActionAsync(string action, string parameter, bool isRedirected)
{ {
_ = parameter; _ = parameter;
_ = isRedirected; _ = isRedirected;
@@ -234,7 +234,7 @@ internal sealed class Activation : IActivation
} }
} }
private async Task HandleDailyNoteActionAsync(string action, string parameter, bool isRedirected) private async ValueTask HandleDailyNoteActionAsync(string action, string parameter, bool isRedirected)
{ {
_ = parameter; _ = parameter;
switch (action) switch (action)
@@ -258,7 +258,7 @@ internal sealed class Activation : IActivation
} }
} }
private async Task HandleLaunchGameActionAsync(string? uid = null) private async ValueTask HandleLaunchGameActionAsync(string? uid = null)
{ {
serviceProvider serviceProvider
.GetRequiredService<IMemoryCache>() .GetRequiredService<IMemoryCache>()

View File

@@ -36,6 +36,7 @@ internal sealed class DebugLogger : ILogger
} }
/// <inheritdoc /> /// <inheritdoc />
[SuppressMessage("", "SH002")]
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter) public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{ {
if (!IsEnabled(logLevel)) if (!IsEnabled(logLevel))

View File

@@ -7,7 +7,6 @@ namespace Snap.Hutao.Core.Setting;
/// 设置键 /// 设置键
/// </summary> /// </summary>
[HighQuality] [HighQuality]
[SuppressMessage("", "SA1124")]
internal static class SettingKeys internal static class SettingKeys
{ {
/// <summary> /// <summary>

View File

@@ -12,5 +12,5 @@ internal interface IJumpListInterop
/// 异步配置跳转列表 /// 异步配置跳转列表
/// </summary> /// </summary>
/// <returns>任务</returns> /// <returns>任务</returns>
Task ConfigureAsync(); ValueTask ConfigureAsync();
} }

View File

@@ -17,7 +17,7 @@ internal sealed class JumpListInterop : IJumpListInterop
/// 异步配置跳转列表 /// 异步配置跳转列表
/// </summary> /// </summary>
/// <returns>任务</returns> /// <returns>任务</returns>
public async Task ConfigureAsync() public async ValueTask ConfigureAsync()
{ {
if (JumpList.IsSupported()) if (JumpList.IsSupported())
{ {

View File

@@ -38,7 +38,7 @@ internal class AsyncBarrier
/// that completes when all other participants have also signaled ready. /// that completes when all other participants have also signaled ready.
/// </summary> /// </summary>
/// <returns>A Task, which will complete (or may already be completed) when the last participant calls this method.</returns> /// <returns>A Task, which will complete (or may already be completed) when the last participant calls this method.</returns>
public Task SignalAndWaitAsync() public ValueTask SignalAndWaitAsync()
{ {
lock (waiters) lock (waiters)
{ {
@@ -52,14 +52,14 @@ internal class AsyncBarrier
} }
// And allow this one to continue immediately. // And allow this one to continue immediately.
return Task.CompletedTask; return ValueTask.CompletedTask;
} }
else else
{ {
// We need more folks. So suspend this caller. // We need more folks. So suspend this caller.
TaskCompletionSource tcs = new(); TaskCompletionSource tcs = new();
waiters.Enqueue(tcs); waiters.Enqueue(tcs);
return tcs.Task; return tcs.Task.AsValueTask();
} }
} }
} }

View File

@@ -11,8 +11,8 @@ internal readonly struct Delay
/// <param name="minMilliSeconds">最小,闭</param> /// <param name="minMilliSeconds">最小,闭</param>
/// <param name="maxMilliSeconds">最小,开</param> /// <param name="maxMilliSeconds">最小,开</param>
/// <returns>任务</returns> /// <returns>任务</returns>
public static Task RandomAsync(int minMilliSeconds, int maxMilliSeconds) public static ValueTask RandomAsync(int minMilliSeconds, int maxMilliSeconds)
{ {
return Task.Delay((int)(System.Random.Shared.NextDouble() * (maxMilliSeconds - minMilliSeconds)) + minMilliSeconds); return Task.Delay((int)(Random.Shared.NextDouble() * (maxMilliSeconds - minMilliSeconds)) + minMilliSeconds).AsValueTask();
} }
} }

View File

@@ -2,6 +2,7 @@
// Licensed under the MIT license. // Licensed under the MIT license.
using Snap.Hutao.Core.ExceptionService; using Snap.Hutao.Core.ExceptionService;
using System.Runtime.CompilerServices;
namespace Snap.Hutao.Core.Threading; namespace Snap.Hutao.Core.Threading;
@@ -13,6 +14,20 @@ namespace Snap.Hutao.Core.Threading;
[SuppressMessage("", "VSTHRD100")] [SuppressMessage("", "VSTHRD100")]
internal static class TaskExtension internal static class TaskExtension
{ {
[SuppressMessage("", "VSTHRD200")]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ValueTask AsValueTask(this Task task)
{
return new(task);
}
[SuppressMessage("", "VSTHRD200")]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ValueTask<T> AsValueTask<T>(this Task<T> task)
{
return new(task);
}
/// <summary> /// <summary>
/// 安全的触发任务 /// 安全的触发任务
/// </summary> /// </summary>

View File

@@ -31,7 +31,9 @@ internal static partial class EnumerableExtension
/// <typeparam name="TSource">源的类型</typeparam> /// <typeparam name="TSource">源的类型</typeparam>
/// <param name="source">源</param> /// <param name="source">源</param>
/// <returns>集合</returns> /// <returns>集合</returns>
#if NET8_0
[Obsolete("Use C# 12 Collection Literal instead")] [Obsolete("Use C# 12 Collection Literal instead")]
#endif
public static IEnumerable<TSource> Enumerate<TSource>(this TSource source) public static IEnumerable<TSource> Enumerate<TSource>(this TSource source)
{ {
yield return source; yield return source;

View File

@@ -16,7 +16,9 @@ internal static class ObjectExtension
/// <typeparam name="T">数据类型</typeparam> /// <typeparam name="T">数据类型</typeparam>
/// <param name="source">源</param> /// <param name="source">源</param>
/// <returns>数组</returns> /// <returns>数组</returns>
[Obsolete("Use C# 12 Collection Literals when we migrate")] #if NET8_0
[Obsolete("Use C# 12 Collection Literals")]
#endif
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T[] ToArray<T>(this T source) public static T[] ToArray<T>(this T source)
{ {

View File

@@ -32,4 +32,13 @@ internal sealed class UIIF
/// </summary> /// </summary>
[JsonPropertyName("list")] [JsonPropertyName("list")]
public List<UIIFItem> List { get; set; } = default!; public List<UIIFItem> List { get; set; } = default!;
/// <summary>
/// 确认当前UIIF对象的版本是否受支持
/// </summary>
/// <returns>当前UIIF对象是否受支持</returns>
public bool IsCurrentVersionSupported()
{
return SupportedVersion.Contains(Info?.UIIFVersion ?? string.Empty);
}
} }

View File

@@ -35,7 +35,7 @@ internal sealed partial class PackageConverter
/// <param name="gameFolder">游戏目录</param> /// <param name="gameFolder">游戏目录</param>
/// <param name="progress">进度</param> /// <param name="progress">进度</param>
/// <returns>替换结果与资源</returns> /// <returns>替换结果与资源</returns>
public async Task<bool> EnsureGameResourceAsync(LaunchScheme targetScheme, GameResource gameResource, string gameFolder, IProgress<PackageReplaceStatus> progress) public async ValueTask<bool> EnsureGameResourceAsync(LaunchScheme targetScheme, GameResource gameResource, string gameFolder, IProgress<PackageReplaceStatus> progress)
{ {
string scatteredFilesUrl = gameResource.Game.Latest.DecompressedPath; string scatteredFilesUrl = gameResource.Game.Latest.DecompressedPath;
Uri pkgVersionUri = $"{scatteredFilesUrl}/pkg_version".ToUri(); Uri pkgVersionUri = $"{scatteredFilesUrl}/pkg_version".ToUri();
@@ -56,7 +56,7 @@ internal sealed partial class PackageConverter
/// <param name="resource">游戏资源</param> /// <param name="resource">游戏资源</param>
/// <param name="gameFolder">游戏文件夹</param> /// <param name="gameFolder">游戏文件夹</param>
/// <returns>任务</returns> /// <returns>任务</returns>
public async Task EnsureDeprecatedFilesAndSdkAsync(GameResource resource, string gameFolder) public async ValueTask EnsureDeprecatedFilesAndSdkAsync(GameResource resource, string gameFolder)
{ {
string sdkDllBackup = Path.Combine(gameFolder, YuanShenData, "Plugins\\PCGameSDK.dll.backup"); string sdkDllBackup = Path.Combine(gameFolder, YuanShenData, "Plugins\\PCGameSDK.dll.backup");
string sdkDll = Path.Combine(gameFolder, YuanShenData, "Plugins\\PCGameSDK.dll"); string sdkDll = Path.Combine(gameFolder, YuanShenData, "Plugins\\PCGameSDK.dll");
@@ -164,7 +164,7 @@ internal sealed partial class PackageConverter
File.Move(targetFullPath, cacheFilePath, true); File.Move(targetFullPath, cacheFilePath, true);
} }
private async Task<Dictionary<string, VersionItem>> TryGetLocalItemsAsync(string gameFolder, ConvertDirection direction) private async ValueTask<Dictionary<string, VersionItem>> TryGetLocalItemsAsync(string gameFolder, ConvertDirection direction)
{ {
using (FileStream localSteam = File.OpenRead(Path.Combine(gameFolder, "pkg_version"))) using (FileStream localSteam = File.OpenRead(Path.Combine(gameFolder, "pkg_version")))
{ {
@@ -172,7 +172,7 @@ internal sealed partial class PackageConverter
} }
} }
private async Task<Dictionary<string, VersionItem>> TryGetRemoteItemsAsync(Uri pkgVersionUri) private async ValueTask<Dictionary<string, VersionItem>> TryGetRemoteItemsAsync(Uri pkgVersionUri)
{ {
try try
{ {
@@ -187,7 +187,7 @@ internal sealed partial class PackageConverter
} }
} }
private async Task<bool> ReplaceGameResourceAsync(IEnumerable<ItemOperationInfo> operations, string gameFolder, string scatteredFilesUrl, ConvertDirection direction, IProgress<PackageReplaceStatus> progress) private async ValueTask<bool> ReplaceGameResourceAsync(IEnumerable<ItemOperationInfo> operations, string gameFolder, string scatteredFilesUrl, ConvertDirection direction, IProgress<PackageReplaceStatus> progress)
{ {
// 重命名 _Data 目录 // 重命名 _Data 目录
try try
@@ -236,7 +236,7 @@ internal sealed partial class PackageConverter
return true; return true;
} }
private async Task ReplaceFromCacheOrWebAsync(string cacheFilePath, string targetFilePath, string scatteredFilesUrl, ItemOperationInfo info, IProgress<PackageReplaceStatus> progress) private async ValueTask ReplaceFromCacheOrWebAsync(string cacheFilePath, string targetFilePath, string scatteredFilesUrl, ItemOperationInfo info, IProgress<PackageReplaceStatus> progress)
{ {
if (File.Exists(cacheFilePath)) if (File.Exists(cacheFilePath))
{ {
@@ -291,7 +291,7 @@ internal sealed partial class PackageConverter
} }
} }
private async Task ReplacePackageVersionsAsync(string scatteredFilesUrl, string gameFolder) private async ValueTask ReplacePackageVersionsAsync(string scatteredFilesUrl, string gameFolder)
{ {
foreach (string versionFilePath in Directory.EnumerateFiles(gameFolder, "*pkg_version")) foreach (string versionFilePath in Directory.EnumerateFiles(gameFolder, "*pkg_version"))
{ {
@@ -314,7 +314,7 @@ internal sealed partial class PackageConverter
} }
} }
private async Task<Dictionary<string, VersionItem>> GetRemoteVersionItemsAsync(Stream stream) private async ValueTask<Dictionary<string, VersionItem>> GetRemoteVersionItemsAsync(Stream stream)
{ {
Dictionary<string, VersionItem> results = new(); Dictionary<string, VersionItem> results = new();
using (StreamReader reader = new(stream)) using (StreamReader reader = new(stream))
@@ -334,7 +334,7 @@ internal sealed partial class PackageConverter
return results; return results;
} }
private async Task<Dictionary<string, VersionItem>> GetLocalVersionItemsAsync(Stream stream, ConvertDirection direction) private async ValueTask<Dictionary<string, VersionItem>> GetLocalVersionItemsAsync(Stream stream, ConvertDirection direction)
{ {
Dictionary<string, VersionItem> results = new(); Dictionary<string, VersionItem> results = new();

View File

@@ -109,8 +109,6 @@ internal static class ApiOsEndpoints
/// Game Authkey /// Game Authkey
/// </summary> /// </summary>
public const string BindingGenAuthKey = $"{ApiAccountOsBindingApi}/genAuthKey"; public const string BindingGenAuthKey = $"{ApiAccountOsBindingApi}/genAuthKey";
#endregion #endregion
#region BbsApiOsApi #region BbsApiOsApi

View File

@@ -32,9 +32,11 @@ internal sealed partial class UserClient : IUserClient
public async Task<Response<UserFullInfoWrapper>> GetUserFullInfoAsync(Model.Entity.User user, CancellationToken token = default) public async Task<Response<UserFullInfoWrapper>> GetUserFullInfoAsync(Model.Entity.User user, CancellationToken token = default)
{ {
Response<UserFullInfoWrapper>? resp = await httpClient Response<UserFullInfoWrapper>? resp = await httpClient
//.SetUser(user, CookieType.SToken)
// .SetUser(user, CookieType.SToken)
.SetReferer(ApiEndpoints.BbsReferer) .SetReferer(ApiEndpoints.BbsReferer)
//.UseDynamicSecret(DynamicSecretVersion.Gen1, SaltType.K2, true)
// .UseDynamicSecret(DynamicSecretVersion.Gen1, SaltType.K2, true)
.TryCatchGetFromJsonAsync<Response<UserFullInfoWrapper>>(ApiEndpoints.UserFullInfoQuery(user.Aid!), options, logger, token) .TryCatchGetFromJsonAsync<Response<UserFullInfoWrapper>>(ApiEndpoints.UserFullInfoQuery(user.Aid!), options, logger, token)
.ConfigureAwait(false); .ConfigureAwait(false);

View File

@@ -38,11 +38,14 @@ internal readonly struct QueryString
} }
} }
#if NET8_0
private static QueryString Parse(ReadOnlySpan<char> value) private static QueryString Parse(ReadOnlySpan<char> value)
{ {
// TODO: .NET 8 ReadOnlySpan Split // TODO: .NET 8 ReadOnlySpan Split
return default; return default;
} }
#endif
/// <summary> /// <summary>
/// Parses a query string into a <see cref="QueryString"/> object. Keys/values are automatically URL decoded. /// Parses a query string into a <see cref="QueryString"/> object. Keys/values are automatically URL decoded.