From 2367c4759dae6d41ce17eb9fcf8e7f54e1dfd317 Mon Sep 17 00:00:00 2001 From: Lightczx <1686188646@qq.com> Date: Wed, 10 Apr 2024 16:53:21 +0800 Subject: [PATCH] refactor --- src/Snap.Hutao/.editorconfig | 4 +- .../IO/Http/Sharding/HttpShardCopyWorker.cs | 45 ++++---- .../Snap.Hutao/Core/IO/StreamCopyWorker.cs | 36 ++++--- .../Snap.Hutao/Core/Setting/SettingKeys.cs | 8 +- src/Snap.Hutao/Snap.Hutao/GuideWindow.xaml | 2 +- src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj | 3 - .../ViewModel/Guide/DownloadSummary.cs | 102 +++++++++--------- .../Snap.Hutao/ViewModel/Guide/GuideState.cs | 12 ++- .../ViewModel/Guide/GuideViewModel.cs | 24 ++--- .../ViewModel/Guide/StaticResource.cs | 2 +- ...taticResourceHttpHeaderBuilderExtension.cs | 20 ++++ .../ViewModel/Guide/StaticResourceQuality.cs | 10 ++ .../Builder/HttpContentBuilderExtension.cs | 3 +- .../Builder/HttpHeadersBuilderExtension.cs | 12 +-- .../Request/Builder/HttpHeadersExtension.cs | 2 +- 15 files changed, 168 insertions(+), 117 deletions(-) create mode 100644 src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/StaticResourceHttpHeaderBuilderExtension.cs create mode 100644 src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/StaticResourceQuality.cs diff --git a/src/Snap.Hutao/.editorconfig b/src/Snap.Hutao/.editorconfig index d3d7c0b4..5905c66a 100644 --- a/src/Snap.Hutao/.editorconfig +++ b/src/Snap.Hutao/.editorconfig @@ -110,7 +110,6 @@ dotnet_diagnostic.SA1642.severity = none dotnet_diagnostic.IDE0005.severity = warning dotnet_diagnostic.IDE0060.severity = none -dotnet_diagnostic.IDE0290.severity = none # SA1208: System using directives should be placed before other using directives dotnet_diagnostic.SA1208.severity = none @@ -321,7 +320,8 @@ dotnet_diagnostic.CA2227.severity = suggestion # CA2251: 使用 “string.Equals” dotnet_diagnostic.CA2251.severity = suggestion -csharp_style_prefer_primary_constructors = true:suggestion + +csharp_style_prefer_primary_constructors = false:none [*.vb] #### 命名样式 #### diff --git a/src/Snap.Hutao/Snap.Hutao/Core/IO/Http/Sharding/HttpShardCopyWorker.cs b/src/Snap.Hutao/Snap.Hutao/Core/IO/Http/Sharding/HttpShardCopyWorker.cs index 3db6ad1f..3c345662 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/IO/Http/Sharding/HttpShardCopyWorker.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/IO/Http/Sharding/HttpShardCopyWorker.cs @@ -3,6 +3,7 @@ using Microsoft.Win32.SafeHandles; using Snap.Hutao.Core.Diagnostics; +using System.Buffers; using System.IO; using System.Net.Http; @@ -77,34 +78,36 @@ internal sealed class HttpShardCopyWorker : IDisposable using (HttpResponseMessage response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token).ConfigureAwait(false)) { response.EnsureSuccessStatusCode(); - - Memory buffer = new byte[bufferSize]; - using (Stream stream = await response.Content.ReadAsStreamAsync(token).ConfigureAwait(false)) + using (IMemoryOwner memoryOwner = MemoryPool.Shared.Rent()) { - int totalBytesRead = 0; - int bytesReadAfterPreviousReport = 0; - do + Memory buffer = memoryOwner.Memory; + using (Stream stream = await response.Content.ReadAsStreamAsync(token).ConfigureAwait(false)) { - int bytesRead = await stream.ReadAsync(buffer, token).ConfigureAwait(false); - if (bytesRead <= 0) + int totalBytesRead = 0; + int bytesReadAfterPreviousReport = 0; + do { - progress.Report(new(bytesReadAfterPreviousReport)); - bytesReadAfterPreviousReport = 0; - break; - } + int bytesRead = await stream.ReadAsync(buffer, token).ConfigureAwait(false); + if (bytesRead <= 0) + { + progress.Report(new(bytesReadAfterPreviousReport)); + bytesReadAfterPreviousReport = 0; + break; + } - await RandomAccess.WriteAsync(destFileHandle, buffer[..bytesRead], shard.StartOffset + totalBytesRead, token).ConfigureAwait(false); + await RandomAccess.WriteAsync(destFileHandle, buffer[..bytesRead], shard.StartOffset + totalBytesRead, token).ConfigureAwait(false); - totalBytesRead += bytesRead; - bytesReadAfterPreviousReport += bytesRead; - if (stopwatch.GetElapsedTime().TotalMilliseconds > 500) - { - progress.Report(new(bytesReadAfterPreviousReport)); - bytesReadAfterPreviousReport = 0; - stopwatch = ValueStopwatch.StartNew(); + totalBytesRead += bytesRead; + bytesReadAfterPreviousReport += bytesRead; + if (stopwatch.GetElapsedTime().TotalMilliseconds > 500) + { + progress.Report(new(bytesReadAfterPreviousReport)); + bytesReadAfterPreviousReport = 0; + stopwatch = ValueStopwatch.StartNew(); + } } + while (true); } - while (true); } } } diff --git a/src/Snap.Hutao/Snap.Hutao/Core/IO/StreamCopyWorker.cs b/src/Snap.Hutao/Snap.Hutao/Core/IO/StreamCopyWorker.cs index 31455288..90c36f5e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/IO/StreamCopyWorker.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/IO/StreamCopyWorker.cs @@ -1,7 +1,9 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using Snap.Hutao.Core.Buffer; using Snap.Hutao.Core.Diagnostics; +using System.Buffers; using System.IO; namespace Snap.Hutao.Core.IO; @@ -51,26 +53,30 @@ internal class StreamCopyWorker long totalBytesRead = 0; int bytesRead; - Memory buffer = new byte[bufferSize]; - do + using (IMemoryOwner memoryOwner = MemoryPool.Shared.Rent(bufferSize)) { - bytesRead = await source.ReadAsync(buffer).ConfigureAwait(false); - if (bytesRead == 0) - { - progress.Report(statusFactory(totalBytesRead)); - break; - } + Memory buffer = memoryOwner.Memory; - await destination.WriteAsync(buffer[..bytesRead]).ConfigureAwait(false); - - totalBytesRead += bytesRead; - if (stopwatch.GetElapsedTime().TotalMilliseconds > 1000) + do { - progress.Report(statusFactory(totalBytesRead)); - stopwatch = ValueStopwatch.StartNew(); + bytesRead = await source.ReadAsync(buffer).ConfigureAwait(false); + if (bytesRead is 0) + { + progress.Report(statusFactory(totalBytesRead)); + break; + } + + await destination.WriteAsync(buffer[..bytesRead]).ConfigureAwait(false); + + totalBytesRead += bytesRead; + if (stopwatch.GetElapsedTime().TotalMilliseconds > 1000) + { + progress.Report(statusFactory(totalBytesRead)); + stopwatch = ValueStopwatch.StartNew(); + } } + while (bytesRead > 0); } - while (bytesRead > 0); } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Setting/SettingKeys.cs b/src/Snap.Hutao/Snap.Hutao/Core/Setting/SettingKeys.cs index db6749c2..9071073e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Setting/SettingKeys.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Setting/SettingKeys.cs @@ -20,7 +20,9 @@ internal static class SettingKeys #region Application public const string LaunchTimes = "LaunchTimes"; public const string DataFolderPath = "DataFolderPath"; - public const string Major1Minor7Revision0GuideState = "Major1Minor7Revision0GuideState"; + public const string Major1Minor10Revision0GuideState = "Major1Minor10Revision0GuideState"; + public const string StaticResourceImageQuality = "StaticResourceImageQuality"; + public const string StaticResourceUseTrimmedArchive = "StaticResourceUseTrimmedArchive"; public const string HotKeyMouseClickRepeatForever = "HotKeyMouseClickRepeatForever"; public const string IsAllocConsoleDebugModeEnabled = "IsAllocConsoleDebugModeEnabled2"; #endregion @@ -60,6 +62,10 @@ internal static class SettingKeys #endregion #region Obsolete + + [Obsolete("重置新手引导状态")] + public const string Major1Minor7Revision0GuideState = "Major1Minor7Revision0GuideState"; + [Obsolete("重置调试控制台开关")] public const string IsAllocConsoleDebugModeEnabledLegacy1 = "IsAllocConsoleDebugModeEnabled"; #endregion diff --git a/src/Snap.Hutao/Snap.Hutao/GuideWindow.xaml b/src/Snap.Hutao/Snap.Hutao/GuideWindow.xaml index 1c1d719c..03e26d1a 100644 --- a/src/Snap.Hutao/Snap.Hutao/GuideWindow.xaml +++ b/src/Snap.Hutao/Snap.Hutao/GuideWindow.xaml @@ -8,7 +8,7 @@ xmlns:shvg="using:Snap.Hutao.View.Guide" mc:Ignorable="d"> - + diff --git a/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj b/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj index 05c4de84..fff69edf 100644 --- a/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj +++ b/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj @@ -347,9 +347,6 @@ - - - MSBuild:Compile diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/DownloadSummary.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/DownloadSummary.cs index 628c1a7f..a573956f 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/DownloadSummary.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/DownloadSummary.cs @@ -7,105 +7,107 @@ using Snap.Hutao.Core; using Snap.Hutao.Core.Caching; using Snap.Hutao.Core.ExceptionService; using Snap.Hutao.Core.IO; +using Snap.Hutao.Factory.Progress; +using Snap.Hutao.Web.Request.Builder; +using Snap.Hutao.Web.Request.Builder.Abstraction; +using System.Collections.Frozen; using System.IO; using System.IO.Compression; using System.Net.Http; namespace Snap.Hutao.ViewModel.Guide; -/// -/// 下载信息 -/// internal sealed class DownloadSummary : ObservableObject { + private static readonly FrozenSet AllowedMediaTypes = FrozenSet.ToFrozenSet( + [ + "application/octet-stream", + "application/zip", + ]); + private readonly IServiceProvider serviceProvider; private readonly ITaskContext taskContext; private readonly IImageCache imageCache; + private readonly IHttpRequestMessageBuilderFactory httpRequestMessageBuilderFactory; private readonly HttpClient httpClient; + private readonly string fileName; private readonly string fileUrl; - private readonly Progress progress; + private readonly IProgress progress; + private string description = SH.ViewModelWelcomeDownloadSummaryDefault; private double progressValue; - /// - /// 构造一个新的下载信息 - /// - /// 服务提供器 - /// 压缩文件名称 public DownloadSummary(IServiceProvider serviceProvider, string fileName) { taskContext = serviceProvider.GetRequiredService(); + httpRequestMessageBuilderFactory = serviceProvider.GetRequiredService(); httpClient = serviceProvider.GetRequiredService(); + httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(serviceProvider.GetRequiredService().UserAgent); imageCache = serviceProvider.GetRequiredService(); - RuntimeOptions runtimeOptions = serviceProvider.GetRequiredService(); - httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(runtimeOptions.UserAgent); this.serviceProvider = serviceProvider; - DisplayName = fileName; this.fileName = fileName; fileUrl = Web.HutaoEndpoints.StaticZip(fileName); - progress = new(UpdateProgressStatus); + progress = serviceProvider.GetRequiredService().CreateForMainThread(UpdateProgressStatus); } - /// - /// 显示名称 - /// - public string DisplayName { get; init; } + public string DisplayName { get => fileName; } - /// - /// 描述 - /// public string Description { get => description; private set => SetProperty(ref description, value); } - /// - /// 进度值,最大1 - /// public double ProgressValue { get => progressValue; set => SetProperty(ref progressValue, value); } - /// - /// 异步下载并解压 - /// - /// 任务 public async ValueTask DownloadAndExtractAsync() { ILogger logger = serviceProvider.GetRequiredService>(); try { - HttpResponseMessage response = await httpClient.GetAsync(fileUrl, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false); + HttpRequestMessage message = httpRequestMessageBuilderFactory + .Create() + .SetRequestUri(fileUrl) + .SetStaticResourceControlHeaders() + .Get() + .HttpRequestMessage; - if (response.Content.Headers.ContentType?.MediaType is not ("application/octet-stream" or "application/zip")) + using (message) { - logger.LogWarning("Download Static Zip failed, Content-Type is {Type}", response.Content.Headers.ContentType); - await taskContext.SwitchToMainThreadAsync(); - Description = SH.ViewModelWelcomeDownloadSummaryContentTypeNotMatch; - return false; - } - - long contentLength = response.Content.Headers.ContentLength ?? 0; - logger.LogInformation("Begin download, length: {length}", contentLength); - using (Stream content = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) - { - using (TempFileStream temp = new(FileMode.OpenOrCreate, FileAccess.ReadWrite)) + using (HttpResponseMessage response = await httpClient.SendAsync(message, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false)) { - await new StreamCopyWorker(content, temp, contentLength).CopyAsync(progress).ConfigureAwait(false); - ExtractFiles(temp); + if (!AllowedMediaTypes.Contains(response.Content.Headers.ContentType?.MediaType)) + { + logger.LogWarning("Download Static Zip failed, Content-Type is {Type}", response.Content.Headers.ContentType); + await taskContext.SwitchToMainThreadAsync(); + Description = SH.ViewModelWelcomeDownloadSummaryContentTypeNotMatch; + return false; + } - await taskContext.SwitchToMainThreadAsync(); - ProgressValue = 1; - Description = SH.ViewModelWelcomeDownloadSummaryComplete; - return true; + long contentLength = response.Content.Headers.ContentLength ?? 0; + logger.LogInformation("Begin download, size: {length}", Converters.ToFileSizeString(contentLength)); + using (Stream content = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) + { + using (TempFileStream temp = new(FileMode.OpenOrCreate, FileAccess.ReadWrite)) + { + await new StreamCopyWorker(content, temp, contentLength).CopyAsync(progress).ConfigureAwait(false); + ExtractFiles(temp); + await taskContext.SwitchToMainThreadAsync(); + ProgressValue = 1; + Description = SH.ViewModelWelcomeDownloadSummaryComplete; + return true; + } + } } } } catch (Exception ex) { - logger.LogError(ex, "Download Static Zip failed"); + logger.LogError(ex, "Download static zip failed"); + await taskContext.SwitchToMainThreadAsync(); - Description = ex is HttpRequestException httpRequestException - ? $"{SH.ViewModelWelcomeDownloadSummaryException} - [HTTP '{httpRequestException.StatusCode:D}'] [Error '{httpRequestException.HttpRequestError}']" + Description = ex is HttpRequestException httpRequestEx + ? $"{SH.ViewModelWelcomeDownloadSummaryException} - [HTTP '{httpRequestEx.StatusCode:D}'] [Error '{httpRequestEx.HttpRequestError}']" : ex.Message; return false; } @@ -114,7 +116,7 @@ internal sealed class DownloadSummary : ObservableObject private void UpdateProgressStatus(StreamCopyStatus status) { Description = $"{Converters.ToFileSizeString(status.BytesCopied)}/{Converters.ToFileSizeString(status.TotalBytes)}"; - ProgressValue = status.TotalBytes == 0 ? 0 : (double)status.BytesCopied / status.TotalBytes; + ProgressValue = status.TotalBytes is 0 ? 0 : (double)status.BytesCopied / status.TotalBytes; } private void ExtractFiles(Stream stream) diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/GuideState.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/GuideState.cs index f9e7d7aa..2089186d 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/GuideState.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/GuideState.cs @@ -24,7 +24,17 @@ internal enum GuideState : uint Environment, /// - /// 开始下载资源 + /// 正在查看常用设置 + /// + CommonSetting, + + /// + /// 正在查看图像资源设置 + /// + StaticResourceSetting, + + /// + /// 开始下载图像资源 /// StaticResourceBegin, diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/GuideViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/GuideViewModel.cs index d36d9661..1e9f2f22 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/GuideViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/GuideViewModel.cs @@ -36,8 +36,7 @@ internal sealed partial class GuideViewModel : Abstraction.ViewModel { get { - uint value = LocalSetting.Get(SettingKeys.Major1Minor7Revision0GuideState, 0U); - GuideState state = (GuideState)value; + GuideState state = UnsafeLocalSetting.Get(SettingKeys.Major1Minor10Revision0GuideState, GuideState.Language); if (state is GuideState.Document) { @@ -61,12 +60,12 @@ internal sealed partial class GuideViewModel : Abstraction.ViewModel (NextOrCompleteButtonText, IsNextOrCompleteButtonEnabled) = (SH.ViewModelGuideActionNext, true); } - return value; + return (uint)state; } set { - LocalSetting.Set(SettingKeys.Major1Minor7Revision0GuideState, value); + LocalSetting.Set(SettingKeys.Major1Minor10Revision0GuideState, value); OnPropertyChanged(); } } @@ -93,13 +92,14 @@ internal sealed partial class GuideViewModel : Abstraction.ViewModel } } + #region Agreement public bool IsTermOfServiceAgreed { get => isTermOfServiceAgreed; set { if (SetProperty(ref isTermOfServiceAgreed, value)) { - OnAgreeSateChanged(); + OnAgreementStateChanged(); } } } @@ -110,7 +110,7 @@ internal sealed partial class GuideViewModel : Abstraction.ViewModel { if (SetProperty(ref isPrivacyPolicyAgreed, value)) { - OnAgreeSateChanged(); + OnAgreementStateChanged(); } } } @@ -121,7 +121,7 @@ internal sealed partial class GuideViewModel : Abstraction.ViewModel { if (SetProperty(ref isIssueReportAgreed, value)) { - OnAgreeSateChanged(); + OnAgreementStateChanged(); } } } @@ -132,14 +132,12 @@ internal sealed partial class GuideViewModel : Abstraction.ViewModel { if (SetProperty(ref isOpenSourceLicenseAgreed, value)) { - OnAgreeSateChanged(); + OnAgreementStateChanged(); } } } + #endregion - /// - /// 下载信息 - /// public ObservableCollection? DownloadSummaries { get => downloadSummaries; @@ -152,7 +150,7 @@ internal sealed partial class GuideViewModel : Abstraction.ViewModel ++State; } - private void OnAgreeSateChanged() + private void OnAgreementStateChanged() { IsNextOrCompleteButtonEnabled = IsTermOfServiceAgreed && IsPrivacyPolicyAgreed && IsIssueReportAgreed && IsOpenSourceLicenseAgreed; } @@ -173,7 +171,7 @@ internal sealed partial class GuideViewModel : Abstraction.ViewModel }).ConfigureAwait(false); StaticResource.FulfillAll(); - UnsafeLocalSetting.Set(SettingKeys.Major1Minor7Revision0GuideState, GuideState.Completed); + UnsafeLocalSetting.Set(SettingKeys.Major1Minor10Revision0GuideState, GuideState.Completed); AppInstance.Restart(string.Empty); } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/StaticResource.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/StaticResource.cs index 5175aa2d..cddb3425 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/StaticResource.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/StaticResource.cs @@ -16,7 +16,7 @@ internal static class StaticResource private static readonly ApplicationDataCompositeValue DefaultResourceVersionMap = new() { - // DO NOT MIDIFY THIS MAP + // DO NOT MODIFY THIS MAP { "AchievementIcon", 0 }, { "AvatarCard", 0 }, { "AvatarIcon", 0 }, diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/StaticResourceHttpHeaderBuilderExtension.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/StaticResourceHttpHeaderBuilderExtension.cs new file mode 100644 index 00000000..90bc5705 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/StaticResourceHttpHeaderBuilderExtension.cs @@ -0,0 +1,20 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Snap.Hutao.Core.Setting; +using Snap.Hutao.Web.Request.Builder; +using Snap.Hutao.Web.Request.Builder.Abstraction; +using System.Net.Http.Headers; + +namespace Snap.Hutao.ViewModel.Guide; + +internal static class StaticResourceHttpHeaderBuilderExtension +{ + public static TBuilder SetStaticResourceControlHeaders(this TBuilder builder) + where TBuilder : IHttpHeadersBuilder + { + return builder + .SetHeader("x-quality", $"{UnsafeLocalSetting.Get(SettingKeys.StaticResourceImageQuality, StaticResourceQuality.Raw)}") + .SetHeader("x-minimum", $"{LocalSetting.Get(SettingKeys.StaticResourceUseTrimmedArchive, false)}"); + } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/StaticResourceQuality.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/StaticResourceQuality.cs new file mode 100644 index 00000000..dda7c521 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Guide/StaticResourceQuality.cs @@ -0,0 +1,10 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.ViewModel.Guide; + +internal enum StaticResourceQuality +{ + Raw, + High, +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpContentBuilderExtension.cs b/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpContentBuilderExtension.cs index e0fa7755..dbfd72b7 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpContentBuilderExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpContentBuilderExtension.cs @@ -35,8 +35,7 @@ internal static class HttpContentBuilderExtension } [DebuggerStepThrough] - public static T SetFormUrlEncodedContent( - this T builder, IEnumerable> content) + public static T SetFormUrlEncodedContent(this T builder, IEnumerable> content) where T : IHttpContentBuilder { ArgumentNullException.ThrowIfNull(builder); diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpHeadersBuilderExtension.cs b/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpHeadersBuilderExtension.cs index acfc3f73..09ce7b94 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpHeadersBuilderExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpHeadersBuilderExtension.cs @@ -41,12 +41,6 @@ internal static partial class HttpHeadersBuilderExtension return builder.ConfigureHeaders(headers => headers.Add(name, value)); } - public static T SetReferer(this T builder, string referer) - where T : IHttpHeadersBuilder - { - return builder.SetHeader("Referer", referer); - } - [DebuggerStepThrough] public static T SetHeader(this T builder, string name) where T : IHttpHeadersBuilder @@ -80,6 +74,12 @@ internal static partial class HttpHeadersBuilderExtension .AddHeader(name, value); } + public static T SetReferer(this T builder, string referer) + where T : IHttpHeadersBuilder + { + return builder.SetHeader("Referer", referer); + } + [DebuggerStepThrough] public static T RemoveHeader(this T builder, params string?[]? names) where T : IHttpHeadersBuilder diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpHeadersExtension.cs b/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpHeadersExtension.cs index ca49ee01..8c413300 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpHeadersExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpHeadersExtension.cs @@ -12,7 +12,7 @@ internal static class HttpHeadersExtension ArgumentNullException.ThrowIfNull(name); // We have to work around the .NET API a little bit. See the comment below for details. - values ??= Enumerable.Empty(); + values ??= []; values = values.Where(v => v is not null); if (values.Any())