mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
code style
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
using System.Drawing;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Snap.Hutao.Test.RuntimeBehavior;
|
||||
|
||||
[TestClass]
|
||||
public sealed class HttpClientBehaviorTest
|
||||
{
|
||||
private const int MessageNotYetSent = 0;
|
||||
|
||||
[TestMethod]
|
||||
public async Task RetrySendHttpRequestMessage()
|
||||
{
|
||||
using (HttpClient httpClient = new())
|
||||
{
|
||||
HttpRequestMessage requestMessage = new(HttpMethod.Post, "https://jsonplaceholder.typicode.com/posts");
|
||||
JsonContent content = JsonContent.Create(new Point(12, 34));
|
||||
requestMessage.Content = content;
|
||||
using (requestMessage)
|
||||
{
|
||||
await httpClient.SendAsync(requestMessage).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
Interlocked.Exchange(ref GetPrivateSendStatus(requestMessage), MessageNotYetSent);
|
||||
Volatile.Write(ref GetPrivateDisposed(content), false);
|
||||
await httpClient.SendAsync(requestMessage).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
// private int _sendStatus
|
||||
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_sendStatus")]
|
||||
private static extern ref int GetPrivateSendStatus(HttpRequestMessage message);
|
||||
|
||||
// private bool _disposed
|
||||
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_disposed")]
|
||||
private static extern ref bool GetPrivateDisposed(HttpRequestMessage message);
|
||||
|
||||
// private bool _disposed
|
||||
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_disposed")]
|
||||
private static extern ref bool GetPrivateDisposed(HttpContent content);
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Markup;
|
||||
|
||||
namespace Snap.Hutao.Control;
|
||||
|
||||
@@ -36,9 +37,18 @@ internal class Loading : Microsoft.UI.Xaml.Controls.ContentControl
|
||||
private static void IsLoadingPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
Loading control = (Loading)d;
|
||||
control.presenter ??= control.GetTemplateChild("ContentGrid") as FrameworkElement;
|
||||
|
||||
control?.Update();
|
||||
if ((bool)e.NewValue)
|
||||
{
|
||||
control.presenter ??= control.GetTemplateChild("ContentGrid") as FrameworkElement;
|
||||
}
|
||||
else if (control.presenter is not null)
|
||||
{
|
||||
XamlMarkupHelper.UnloadObject(control.presenter);
|
||||
control.presenter = null;
|
||||
}
|
||||
|
||||
control.Update();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
<ContentPresenter
|
||||
x:Name="ContentGrid"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
x:Load="False">
|
||||
<ContentPresenter.RenderTransform>
|
||||
<CompositeTransform/>
|
||||
</ContentPresenter.RenderTransform>
|
||||
@@ -84,4 +85,4 @@
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary>
|
||||
@@ -11,16 +11,13 @@ using Snap.Hutao.Web.Request.Builder;
|
||||
using Snap.Hutao.Web.Request.Builder.Abstraction;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Frozen;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace Snap.Hutao.Core.Caching;
|
||||
|
||||
/// <summary>
|
||||
/// Provides methods and tools to cache files in a folder
|
||||
/// The class's name will become the cache folder's name
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
[ConstructorGenerated]
|
||||
[Injection(InjectAs.Singleton, typeof(IImageCache))]
|
||||
@@ -28,10 +25,9 @@ namespace Snap.Hutao.Core.Caching;
|
||||
[PrimaryHttpMessageHandler(MaxConnectionsPerServer = 8)]
|
||||
internal sealed partial class ImageCache : IImageCache, IImageCacheFilePathOperation
|
||||
{
|
||||
private const string CacheFolderName = nameof(ImageCache);
|
||||
private const string CacheFailedDownloadTasksName = $"{nameof(ImageCache)}.FailedDownloadTasks";
|
||||
|
||||
private readonly FrozenDictionary<int, TimeSpan> retryCountToDelay = FrozenDictionary.ToFrozenDictionary(
|
||||
private static readonly FrozenDictionary<int, TimeSpan> DelayFromRetryCount = FrozenDictionary.ToFrozenDictionary(
|
||||
[
|
||||
KeyValuePair.Create(0, TimeSpan.FromSeconds(4)),
|
||||
KeyValuePair.Create(1, TimeSpan.FromSeconds(16)),
|
||||
@@ -46,16 +42,13 @@ internal sealed partial class ImageCache : IImageCache, IImageCacheFilePathOpera
|
||||
private readonly ILogger<ImageCache> logger;
|
||||
private readonly IMemoryCache memoryCache;
|
||||
|
||||
private string? baseFolder;
|
||||
private string? cacheFolder;
|
||||
|
||||
private string CacheFolder
|
||||
{
|
||||
get => LazyInitializer.EnsureInitialized(ref cacheFolder, () =>
|
||||
{
|
||||
baseFolder ??= serviceProvider.GetRequiredService<RuntimeOptions>().LocalCache;
|
||||
DirectoryInfo info = Directory.CreateDirectory(Path.Combine(baseFolder, CacheFolderName));
|
||||
return info.FullName;
|
||||
return serviceProvider.GetRequiredService<RuntimeOptions>().GetLocalCacheImageCacheFolder();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -149,8 +142,7 @@ internal sealed partial class ImageCache : IImageCache, IImageCacheFilePathOpera
|
||||
return treatNullFileAsInvalid;
|
||||
}
|
||||
|
||||
FileInfo fileInfo = new(file);
|
||||
return fileInfo.Length == 0;
|
||||
return new FileInfo(file).Length == 0;
|
||||
}
|
||||
|
||||
private void RemoveCore(IEnumerable<string> filePaths)
|
||||
@@ -172,80 +164,76 @@ internal sealed partial class ImageCache : IImageCache, IImageCacheFilePathOpera
|
||||
[SuppressMessage("", "SH003")]
|
||||
private async Task DownloadFileAsync(Uri uri, string baseFile)
|
||||
{
|
||||
int retryCount = 0;
|
||||
HttpClient httpClient = httpClientFactory.CreateClient(nameof(ImageCache));
|
||||
while (retryCount < 3)
|
||||
using (HttpClient httpClient = httpClientFactory.CreateClient(nameof(ImageCache)))
|
||||
{
|
||||
int retryCount = 0;
|
||||
|
||||
HttpRequestMessageBuilder requestMessageBuilder = httpRequestMessageBuilderFactory
|
||||
.Create()
|
||||
.SetRequestUri(uri)
|
||||
|
||||
// These headers are only available for our own api
|
||||
.SetStaticResourceControlHeadersIf(uri.Host.Contains("api.snapgenshin.com", StringComparison.OrdinalIgnoreCase))
|
||||
.SetStaticResourceControlHeadersIf(uri.Host.Contains("api.snapgenshin.com", StringComparison.OrdinalIgnoreCase)) // These headers are only available for our own api
|
||||
.Get();
|
||||
|
||||
using (HttpRequestMessage requestMessage = requestMessageBuilder.HttpRequestMessage)
|
||||
while (retryCount < 3)
|
||||
{
|
||||
using (HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false))
|
||||
{
|
||||
if (responseMessage.RequestMessage is { RequestUri: { } target } && target != uri)
|
||||
{
|
||||
logger.LogDebug("The Request '{Source}' has been redirected to '{Target}'", uri, target);
|
||||
}
|
||||
requestMessageBuilder.Resurrect();
|
||||
|
||||
if (responseMessage.IsSuccessStatusCode)
|
||||
using (HttpRequestMessage requestMessage = requestMessageBuilder.HttpRequestMessage)
|
||||
{
|
||||
using (HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false))
|
||||
{
|
||||
if (responseMessage.Content.Headers.ContentType?.MediaType is "application/json")
|
||||
// Redirect detection
|
||||
if (responseMessage.RequestMessage is { RequestUri: { } target } && target != uri)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugTrack(uri);
|
||||
#endif
|
||||
string raw = await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
logger.LogColorizedCritical("Failed to download '{Uri}' with unexpected body '{Raw}'", (uri, ConsoleColor.Red), (raw, ConsoleColor.DarkYellow));
|
||||
return;
|
||||
logger.LogDebug("The Request '{Source}' has been redirected to '{Target}'", uri, target);
|
||||
}
|
||||
|
||||
using (Stream httpStream = await responseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false))
|
||||
if (responseMessage.IsSuccessStatusCode)
|
||||
{
|
||||
using (FileStream fileStream = File.Create(baseFile))
|
||||
if (responseMessage.Content.Headers.ContentType?.MediaType is "application/json")
|
||||
{
|
||||
await httpStream.CopyToAsync(fileStream).ConfigureAwait(false);
|
||||
DebugTrackFailedUri(uri);
|
||||
string raw = await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
logger.LogColorizedCritical("Failed to download '{Uri}' with unexpected body '{Raw}'", (uri, ConsoleColor.Red), (raw, ConsoleColor.DarkYellow));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (responseMessage.StatusCode)
|
||||
{
|
||||
case HttpStatusCode.TooManyRequests:
|
||||
using (Stream httpStream = await responseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false))
|
||||
{
|
||||
retryCount++;
|
||||
TimeSpan delay = responseMessage.Headers.RetryAfter?.Delta ?? retryCountToDelay[retryCount];
|
||||
logger.LogInformation("Retry download '{Uri}' after {Delay}.", uri, delay);
|
||||
await Task.Delay(delay).ConfigureAwait(false);
|
||||
break;
|
||||
using (FileStream fileStream = File.Create(baseFile))
|
||||
{
|
||||
await httpStream.CopyToAsync(fileStream).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
#if DEBUG
|
||||
DebugTrack(uri);
|
||||
#endif
|
||||
logger.LogColorizedCritical("Failed to download '{Uri}' with status code '{StatusCode}'", (uri, ConsoleColor.Red), (responseMessage.StatusCode, ConsoleColor.DarkYellow));
|
||||
return;
|
||||
switch (responseMessage.StatusCode)
|
||||
{
|
||||
case HttpStatusCode.TooManyRequests:
|
||||
{
|
||||
retryCount++;
|
||||
TimeSpan delay = responseMessage.Headers.RetryAfter?.Delta ?? DelayFromRetryCount[retryCount];
|
||||
logger.LogInformation("Retry download '{Uri}' after {Delay}.", uri, delay);
|
||||
await Task.Delay(delay).ConfigureAwait(false);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
DebugTrackFailedUri(uri);
|
||||
logger.LogColorizedCritical("Failed to download '{Uri}' with status code '{StatusCode}'", (uri, ConsoleColor.Red), (responseMessage.StatusCode, ConsoleColor.DarkYellow));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
internal partial class ImageCache
|
||||
{
|
||||
private void DebugTrack(Uri uri)
|
||||
[Conditional("DEBUG")]
|
||||
private void DebugTrackFailedUri(Uri uri)
|
||||
{
|
||||
HashSet<string>? set = memoryCache.GetOrCreate(CacheFailedDownloadTasksName, entry => entry.Value ??= new HashSet<string>()) as HashSet<string>;
|
||||
HashSet<string>? set = memoryCache.GetOrCreate(CacheFailedDownloadTasksName, entry => new HashSet<string>());
|
||||
set?.Add(uri.ToString());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -70,7 +70,7 @@ internal sealed class ObservableReorderableDbCollection<TEntity> : ObservableCol
|
||||
|
||||
[SuppressMessage("", "SA1402")]
|
||||
internal sealed class ObservableReorderableDbCollection<TEntityOnly, TEntity> : ObservableCollection<TEntityOnly>
|
||||
where TEntityOnly : class, IEntityOnly<TEntity>
|
||||
where TEntityOnly : class, IEntityAccess<TEntity>
|
||||
where TEntity : class, IReorderable
|
||||
{
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
|
||||
@@ -73,7 +73,7 @@ internal sealed partial class ScopedDbCurrent<TEntity, TMessage>
|
||||
|
||||
[ConstructorGenerated]
|
||||
internal sealed partial class ScopedDbCurrent<TEntityOnly, TEntity, TMessage>
|
||||
where TEntityOnly : class, IEntityOnly<TEntity>
|
||||
where TEntityOnly : class, IEntityAccess<TEntity>
|
||||
where TEntity : class, ISelectable
|
||||
where TMessage : Message.ValueChangedMessage<TEntityOnly>, new()
|
||||
{
|
||||
|
||||
@@ -41,7 +41,7 @@ internal static class DependencyInjection
|
||||
.AddJsonOptions()
|
||||
.AddDatabase()
|
||||
.AddInjections()
|
||||
.AddAllHttpClients()
|
||||
.AddConfiguredHttpClients()
|
||||
|
||||
// Discrete services
|
||||
.AddSingleton<IMessenger, WeakReferenceMessenger>()
|
||||
|
||||
@@ -34,27 +34,27 @@ internal static class IocConfiguration
|
||||
.AddTransient(typeof(Database.ScopedDbCurrent<,>))
|
||||
.AddTransient(typeof(Database.ScopedDbCurrent<,,>))
|
||||
.AddDbContextPool<AppDbContext>(AddDbContextCore);
|
||||
}
|
||||
|
||||
private static void AddDbContextCore(IServiceProvider serviceProvider, DbContextOptionsBuilder builder)
|
||||
{
|
||||
RuntimeOptions runtimeOptions = serviceProvider.GetRequiredService<RuntimeOptions>();
|
||||
string dbFile = System.IO.Path.Combine(runtimeOptions.DataFolder, "Userdata.db");
|
||||
string sqlConnectionString = $"Data Source={dbFile}";
|
||||
|
||||
// Temporarily create a context
|
||||
using (AppDbContext context = AppDbContext.Create(serviceProvider, sqlConnectionString))
|
||||
static void AddDbContextCore(IServiceProvider serviceProvider, DbContextOptionsBuilder builder)
|
||||
{
|
||||
if (context.Database.GetPendingMigrations().Any())
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("[Database] Performing AppDbContext Migrations");
|
||||
context.Database.Migrate();
|
||||
}
|
||||
}
|
||||
RuntimeOptions runtimeOptions = serviceProvider.GetRequiredService<RuntimeOptions>();
|
||||
string dbFile = System.IO.Path.Combine(runtimeOptions.DataFolder, "Userdata.db");
|
||||
string sqlConnectionString = $"Data Source={dbFile}";
|
||||
|
||||
builder
|
||||
.EnableSensitiveDataLogging()
|
||||
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
|
||||
.UseSqlite(sqlConnectionString);
|
||||
// Temporarily create a context
|
||||
using (AppDbContext context = AppDbContext.Create(serviceProvider, sqlConnectionString))
|
||||
{
|
||||
if (context.Database.GetPendingMigrations().Any())
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("[Database] Performing AppDbContext Migrations");
|
||||
context.Database.Migrate();
|
||||
}
|
||||
}
|
||||
|
||||
builder
|
||||
.EnableSensitiveDataLogging()
|
||||
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
|
||||
.UseSqlite(sqlConnectionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ internal static partial class IocHttpClientConfiguration
|
||||
{
|
||||
private const string ApplicationJson = "application/json";
|
||||
|
||||
public static IServiceCollection AddAllHttpClients(this IServiceCollection services)
|
||||
public static IServiceCollection AddConfiguredHttpClients(this IServiceCollection services)
|
||||
{
|
||||
services
|
||||
.ConfigureHttpClientDefaults(clientBuilder =>
|
||||
@@ -27,7 +27,7 @@ internal static partial class IocHttpClientConfiguration
|
||||
HttpClientHandler clientHandler = (HttpClientHandler)handler;
|
||||
clientHandler.AllowAutoRedirect = true;
|
||||
clientHandler.UseProxy = true;
|
||||
clientHandler.Proxy = provider.GetRequiredService<DynamicHttpProxy>();
|
||||
clientHandler.Proxy = provider.GetRequiredService<HttpProxyUsingSystemProxy>();
|
||||
});
|
||||
})
|
||||
.AddHttpClients();
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Snap.Hutao.Core.ExceptionService;
|
||||
|
||||
/// <summary>
|
||||
/// 帮助更好的抛出异常
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
[System.Diagnostics.StackTraceHidden]
|
||||
[Obsolete("Use HutaoException instead")]
|
||||
internal static class ThrowHelper
|
||||
{
|
||||
[DoesNotReturn]
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static ArgumentException Argument(string message, string? paramName)
|
||||
{
|
||||
throw new ArgumentException(message, paramName);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,12 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.VisualBasic.FileIO;
|
||||
using Snap.Hutao.Win32.System.Com;
|
||||
using Snap.Hutao.Win32.UI.Shell;
|
||||
using System.IO;
|
||||
using static Snap.Hutao.Win32.Macros;
|
||||
using static Snap.Hutao.Win32.Ole32;
|
||||
using static Snap.Hutao.Win32.Shell32;
|
||||
|
||||
namespace Snap.Hutao.Core.IO;
|
||||
|
||||
@@ -18,4 +23,29 @@ internal static class DirectoryOperation
|
||||
FileSystem.MoveDirectory(sourceDirName, destDirName, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static unsafe bool UnsafeRename(string path, string name, FILEOPERATION_FLAGS flags = FILEOPERATION_FLAGS.FOF_ALLOWUNDO | FILEOPERATION_FLAGS.FOF_NOCONFIRMMKDIR)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (SUCCEEDED(CoCreateInstance(in Win32.UI.Shell.FileOperation.CLSID, default, CLSCTX.CLSCTX_INPROC_SERVER, in IFileOperation.IID, out IFileOperation* pFileOperation)))
|
||||
{
|
||||
if (SUCCEEDED(SHCreateItemFromParsingName(path, default, in IShellItem.IID, out IShellItem* pShellItem)))
|
||||
{
|
||||
pFileOperation->SetOperationFlags(flags);
|
||||
pFileOperation->RenameItem(pShellItem, name, default);
|
||||
|
||||
if (SUCCEEDED(pFileOperation->PerformOperations()))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
IUnknownMarshal.Release(pShellItem);
|
||||
}
|
||||
|
||||
IUnknownMarshal.Release(pFileOperation);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,30 @@ internal static class FileOperation
|
||||
return true;
|
||||
}
|
||||
|
||||
public static unsafe bool UnsafeDelete(string path)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (SUCCEEDED(CoCreateInstance(in Win32.UI.Shell.FileOperation.CLSID, default, CLSCTX.CLSCTX_INPROC_SERVER, in IFileOperation.IID, out IFileOperation* pFileOperation)))
|
||||
{
|
||||
if (SUCCEEDED(SHCreateItemFromParsingName(path, default, in IShellItem.IID, out IShellItem* pShellItem)))
|
||||
{
|
||||
pFileOperation->DeleteItem(pShellItem, default);
|
||||
|
||||
if (SUCCEEDED(pFileOperation->PerformOperations()))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
IUnknownMarshal.Release(pShellItem);
|
||||
}
|
||||
|
||||
IUnknownMarshal.Release(pFileOperation);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static unsafe bool UnsafeMove(string sourceFileName, string destFileName)
|
||||
{
|
||||
bool result = false;
|
||||
@@ -73,28 +97,4 @@ internal static class FileOperation
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static unsafe bool UnsafeDelete(string path)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (SUCCEEDED(CoCreateInstance(in Win32.UI.Shell.FileOperation.CLSID, default, CLSCTX.CLSCTX_INPROC_SERVER, in IFileOperation.IID, out IFileOperation* pFileOperation)))
|
||||
{
|
||||
if (SUCCEEDED(SHCreateItemFromParsingName(path, default, in IShellItem.IID, out IShellItem* pShellItem)))
|
||||
{
|
||||
pFileOperation->DeleteItem(pShellItem, default);
|
||||
|
||||
if (SUCCEEDED(pFileOperation->PerformOperations()))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
IUnknownMarshal.Release(pShellItem);
|
||||
}
|
||||
|
||||
IUnknownMarshal.Release(pFileOperation);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,9 @@ using System.Text;
|
||||
|
||||
namespace Snap.Hutao.Core.IO.Hashing;
|
||||
|
||||
#if NET9_0_OR_GREATER
|
||||
[Obsolete]
|
||||
#endif
|
||||
internal static class Hash
|
||||
{
|
||||
public static unsafe string SHA1HexString(string input)
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Snap.Hutao.Win32.Registry;
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Snap.Hutao.Core.IO.Http.Proxy;
|
||||
|
||||
[Injection(InjectAs.Singleton)]
|
||||
internal sealed partial class DynamicHttpProxy : ObservableObject, IWebProxy, IDisposable
|
||||
internal sealed partial class HttpProxyUsingSystemProxy : ObservableObject, IWebProxy, IDisposable
|
||||
{
|
||||
private const string ProxySettingPath = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections";
|
||||
|
||||
@@ -20,7 +21,7 @@ internal sealed partial class DynamicHttpProxy : ObservableObject, IWebProxy, ID
|
||||
|
||||
private IWebProxy innerProxy = default!;
|
||||
|
||||
public DynamicHttpProxy(IServiceProvider serviceProvider)
|
||||
public HttpProxyUsingSystemProxy(IServiceProvider serviceProvider)
|
||||
{
|
||||
this.serviceProvider = serviceProvider;
|
||||
UpdateInnerProxy();
|
||||
@@ -27,4 +27,11 @@ internal static class RuntimeOptionsExtension
|
||||
Directory.CreateDirectory(directory);
|
||||
return directory;
|
||||
}
|
||||
|
||||
public static string GetLocalCacheImageCacheFolder(this RuntimeOptions options)
|
||||
{
|
||||
string directory = Path.Combine(options.LocalCache, "ImageCache");
|
||||
Directory.CreateDirectory(directory);
|
||||
return directory;
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,7 @@ internal sealed partial class ShellLinkInterop : IShellLinkInterop
|
||||
IUnknownMarshal.Release(pPersistFile);
|
||||
}
|
||||
|
||||
uint value = IUnknownMarshal.Release(pShellLink);
|
||||
IUnknownMarshal.Release(pShellLink);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
using Windows.Graphics;
|
||||
|
||||
namespace Snap.Hutao.Core.Windowing;
|
||||
|
||||
internal readonly struct CompactRect
|
||||
internal readonly struct RectInt16
|
||||
{
|
||||
private readonly short x;
|
||||
private readonly short y;
|
||||
private readonly short width;
|
||||
private readonly short height;
|
||||
|
||||
private CompactRect(int x, int y, int width, int height)
|
||||
private RectInt16(int x, int y, int width, int height)
|
||||
{
|
||||
this.x = (short)x;
|
||||
this.y = (short)y;
|
||||
@@ -21,24 +20,22 @@ internal readonly struct CompactRect
|
||||
this.height = (short)height;
|
||||
}
|
||||
|
||||
public static implicit operator RectInt32(CompactRect rect)
|
||||
public static implicit operator RectInt32(RectInt16 rect)
|
||||
{
|
||||
return new(rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
|
||||
public static explicit operator CompactRect(RectInt32 rect)
|
||||
public static explicit operator RectInt16(RectInt32 rect)
|
||||
{
|
||||
return new(rect.X, rect.Y, rect.Width, rect.Height);
|
||||
}
|
||||
|
||||
public static unsafe explicit operator CompactRect(ulong value)
|
||||
public static unsafe explicit operator RectInt16(ulong value)
|
||||
{
|
||||
Unsafe.SkipInit(out CompactRect rect);
|
||||
*(ulong*)&rect = value;
|
||||
return rect;
|
||||
return *(RectInt16*)&value;
|
||||
}
|
||||
|
||||
public static unsafe implicit operator ulong(CompactRect rect)
|
||||
public static unsafe implicit operator ulong(RectInt16 rect)
|
||||
{
|
||||
return *(ulong*)▭
|
||||
}
|
||||
@@ -241,7 +241,7 @@ internal sealed class XamlWindowController
|
||||
|
||||
if (window is IXamlWindowRectPersisted rectPersisted)
|
||||
{
|
||||
RectInt32 nonDpiPersistedRect = (CompactRect)LocalSetting.Get(rectPersisted.PersistRectKey, (CompactRect)rect);
|
||||
RectInt32 nonDpiPersistedRect = (RectInt16)LocalSetting.Get(rectPersisted.PersistRectKey, (RectInt16)rect);
|
||||
RectInt32 persistedRect = nonDpiPersistedRect.Scale(scale);
|
||||
|
||||
// If the persisted size is less than min size, we want to reset to the init size.
|
||||
@@ -266,7 +266,7 @@ internal sealed class XamlWindowController
|
||||
{
|
||||
// We save the non-dpi rect here
|
||||
double scale = 1.0 / window.GetRasterizationScale();
|
||||
LocalSetting.Set(rectPersisted.PersistRectKey, (CompactRect)window.AppWindow.GetRect().Scale(scale));
|
||||
LocalSetting.Set(rectPersisted.PersistRectKey, (RectInt16)window.AppWindow.GetRect().Scale(scale));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -104,7 +104,7 @@ internal static partial class EnumerableExtension
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ObservableReorderableDbCollection<TEntityOnly, TEntity> ToObservableReorderableDbCollection<TEntityOnly, TEntity>(this IEnumerable<TEntityOnly> source, IServiceProvider serviceProvider)
|
||||
where TEntityOnly : class, IEntityOnly<TEntity>
|
||||
where TEntityOnly : class, IEntityAccess<TEntity>
|
||||
where TEntity : class, IReorderable
|
||||
{
|
||||
return source is List<TEntityOnly> list
|
||||
|
||||
14
src/Snap.Hutao/Snap.Hutao/Model/IEntityAccessWithMetadata.cs
Normal file
14
src/Snap.Hutao/Snap.Hutao/Model/IEntityAccessWithMetadata.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Model;
|
||||
|
||||
internal interface IEntityAccessWithMetadata<out TEntity, out TMetadata> : IEntityAccess<TEntity>
|
||||
{
|
||||
TMetadata Inner { get; }
|
||||
}
|
||||
|
||||
internal interface IEntityAccess<out TEntity>
|
||||
{
|
||||
TEntity Entity { get; }
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Model;
|
||||
|
||||
/// <summary>
|
||||
/// 实体与元数据
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">实体</typeparam>
|
||||
/// <typeparam name="TMetadata">元数据</typeparam>
|
||||
[HighQuality]
|
||||
internal interface IEntityWithMetadata<out TEntity, out TMetadata> : IEntityOnly<TEntity>
|
||||
{
|
||||
/// <summary>
|
||||
/// 元数据
|
||||
/// </summary>
|
||||
TMetadata Inner { get; }
|
||||
}
|
||||
|
||||
internal interface IEntityOnly<out TEntity>
|
||||
{
|
||||
/// <summary>
|
||||
/// 实体
|
||||
/// </summary>
|
||||
TEntity Entity { get; }
|
||||
}
|
||||
@@ -82,31 +82,10 @@ internal abstract partial class DbStoreOptions : ObservableObject
|
||||
return storage.Value;
|
||||
}
|
||||
|
||||
[return: NotNull]
|
||||
protected T GetOption<T>(ref T? storage, string key, Func<string, T> deserializer, [DisallowNull] T defaultValue)
|
||||
[return: NotNullIfNotNull(nameof(defaultValue))]
|
||||
protected T GetOption<T>(ref T? storage, string key, Func<string, T> deserializer, T defaultValue)
|
||||
{
|
||||
if (storage is not null)
|
||||
{
|
||||
return storage;
|
||||
}
|
||||
|
||||
using (IServiceScope scope = serviceProvider.CreateScope())
|
||||
{
|
||||
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||
string? value = appDbContext.Settings.SingleOrDefault(e => e.Key == key)?.Value;
|
||||
if (value is null)
|
||||
{
|
||||
storage = defaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
T targetValue = deserializer(value);
|
||||
ArgumentNullException.ThrowIfNull(targetValue);
|
||||
storage = targetValue;
|
||||
}
|
||||
}
|
||||
|
||||
return storage;
|
||||
return GetOption(ref storage, key, deserializer, () => defaultValue);
|
||||
}
|
||||
|
||||
protected T GetOption<T>(ref T? storage, string key, Func<string, T> deserializer, Func<T> defaultValueFactory)
|
||||
|
||||
@@ -32,6 +32,6 @@ internal sealed partial class DailyNoteWebhookOperation
|
||||
.SetHeader("x-uid", $"{playerUid}")
|
||||
.PostJson(dailyNote);
|
||||
|
||||
await builder.TryCatchSendAsync(httpClient, logger, token).ConfigureAwait(false);
|
||||
await builder.SendAsync(httpClient, logger, token).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,6 @@ internal static class DirectX
|
||||
return false;
|
||||
}
|
||||
|
||||
//IUnknownMarshal.Release(swapChain);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -122,7 +122,8 @@ internal sealed class GameScreenCaptureSession : IDisposable
|
||||
try
|
||||
{
|
||||
captureContext.UpdatePreview(previewWindow, frame.Surface);
|
||||
//UnsafeProcessFrameSurface(frame.Surface);
|
||||
|
||||
// UnsafeProcessFrameSurface(frame.Surface);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -49,7 +49,7 @@ internal sealed partial class LoginHoyoverseUserPage : Microsoft.UI.Xaml.Control
|
||||
HttpClient httpClient = serviceProvider.GetRequiredService<HttpClient>();
|
||||
|
||||
WebApiResponse<AccountInfoWrapper>? resp = await builder
|
||||
.TryCatchSendAsync<WebApiResponse<AccountInfoWrapper>>(httpClient, logger, token)
|
||||
.SendAsync<WebApiResponse<AccountInfoWrapper>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return $"{resp?.Data?.AccountInfo?.AccountId}";
|
||||
|
||||
@@ -124,6 +124,11 @@
|
||||
Header="Screen Capture Test"
|
||||
IsClickEnabled="True"/>
|
||||
|
||||
<cwc:SettingsCard
|
||||
Command="{Binding FileOperationRenameCommand}"
|
||||
Header="Rename Desktop TestFolder"
|
||||
IsClickEnabled="True"/>
|
||||
|
||||
<cwc:SettingsCard Header="Crash">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Command="{Binding ExceptionCommand}" Content="Activate"/>
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Snap.Hutao.ViewModel.Achievement;
|
||||
/// 用于视图绑定的成就
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed class AchievementView : ObservableObject, IEntityWithMetadata<Model.Entity.Achievement, Model.Metadata.Achievement.Achievement>
|
||||
internal sealed class AchievementView : ObservableObject, IEntityAccessWithMetadata<Model.Entity.Achievement, Model.Metadata.Achievement.Achievement>
|
||||
{
|
||||
/// <summary>
|
||||
/// 满进度占位符
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Snap.Hutao.ViewModel.Cultivation;
|
||||
/// 养成物品
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed class CultivateItemView : ObservableObject, IEntityWithMetadata<Model.Entity.CultivateItem, Material>
|
||||
internal sealed class CultivateItemView : ObservableObject, IEntityAccessWithMetadata<Model.Entity.CultivateItem, Material>
|
||||
{
|
||||
/// <summary>
|
||||
/// 养成物品
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Snap.Hutao.ViewModel.Cultivation;
|
||||
/// 背包物品
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed class InventoryItemView : ObservableObject, IEntityWithMetadata<Model.Entity.InventoryItem, Material>
|
||||
internal sealed class InventoryItemView : ObservableObject, IEntityAccessWithMetadata<Model.Entity.InventoryItem, Material>
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建一个新的背包物品
|
||||
|
||||
@@ -25,7 +25,7 @@ internal sealed partial class FeedbackViewModel : Abstraction.ViewModel
|
||||
private readonly HutaoDocumentationClient hutaoDocumentationClient;
|
||||
private readonly IContentDialogFactory contentDialogFactory;
|
||||
private readonly IClipboardProvider clipboardProvider;
|
||||
private readonly DynamicHttpProxy dynamicHttpProxy;
|
||||
private readonly HttpProxyUsingSystemProxy dynamicHttpProxy;
|
||||
private readonly LoopbackManager loopbackManager;
|
||||
private readonly IInfoBarService infoBarService;
|
||||
private readonly CultureOptions cultureOptions;
|
||||
@@ -38,7 +38,7 @@ internal sealed partial class FeedbackViewModel : Abstraction.ViewModel
|
||||
|
||||
public RuntimeOptions RuntimeOptions { get => runtimeOptions; }
|
||||
|
||||
public DynamicHttpProxy DynamicHttpProxy { get => dynamicHttpProxy; }
|
||||
public HttpProxyUsingSystemProxy DynamicHttpProxy { get => dynamicHttpProxy; }
|
||||
|
||||
public LoopbackManager LoopbackManager { get => loopbackManager; }
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Snap.Hutao.ViewModel.SpiralAbyss;
|
||||
/// 深渊视图
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed class SpiralAbyssView : IEntityOnly<SpiralAbyssEntry?>,
|
||||
internal sealed class SpiralAbyssView : IEntityAccess<SpiralAbyssEntry?>,
|
||||
IMappingFrom<SpiralAbyssView, SpiralAbyssEntry, SpiralAbyssMetadataContext>,
|
||||
IMappingFrom<SpiralAbyssView, SpiralAbyssEntry?, TowerSchedule, SpiralAbyssMetadataContext>
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Snap.Hutao.Core.Caching;
|
||||
using Snap.Hutao.Core.ExceptionService;
|
||||
using Snap.Hutao.Core.IO;
|
||||
using Snap.Hutao.Core.LifeCycle;
|
||||
using Snap.Hutao.Core.Setting;
|
||||
using Snap.Hutao.Core.Windowing;
|
||||
@@ -13,6 +14,7 @@ using Snap.Hutao.View.Converter;
|
||||
using Snap.Hutao.ViewModel.Guide;
|
||||
using Snap.Hutao.Web.Hutao.HutaoAsAService;
|
||||
using Snap.Hutao.Win32.Foundation;
|
||||
using System.IO;
|
||||
|
||||
namespace Snap.Hutao.ViewModel;
|
||||
|
||||
@@ -163,4 +165,12 @@ internal sealed partial class TestViewModel : Abstraction.ViewModel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Command("FileOperationRenameCommand")]
|
||||
private void FileOperationRename()
|
||||
{
|
||||
string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
|
||||
string source = Path.Combine(desktop, "TestFolder");
|
||||
DirectoryOperation.UnsafeRename(source, "TestFolder1");
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ namespace Snap.Hutao.ViewModel.User;
|
||||
/// 用于视图绑定的用户
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed class User : ObservableObject, IEntityOnly<EntityUser>, IMappingFrom<User, EntityUser, IServiceProvider>, ISelectable
|
||||
internal sealed class User : ObservableObject, IEntityAccess<EntityUser>, IMappingFrom<User, EntityUser, IServiceProvider>, ISelectable
|
||||
{
|
||||
private readonly EntityUser inner;
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
|
||||
@@ -32,7 +32,7 @@ internal sealed partial class AccountClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen1, SaltType.K2, false).ConfigureAwait(false);
|
||||
|
||||
Response<GameAuthKey>? resp = await builder
|
||||
.TryCatchSendAsync<Response<GameAuthKey>>(httpClient, logger, token)
|
||||
.SendAsync<Response<GameAuthKey>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -28,7 +28,7 @@ internal sealed partial class UserClient : IUserClient
|
||||
.Get();
|
||||
|
||||
Response<UserFullInfoWrapper>? resp = await builder
|
||||
.TryCatchSendAsync<Response<UserFullInfoWrapper>>(httpClient, logger, token)
|
||||
.SendAsync<Response<UserFullInfoWrapper>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -27,7 +27,7 @@ internal sealed partial class UserClientOversea : IUserClient
|
||||
.Get();
|
||||
|
||||
Response<UserFullInfoWrapper>? resp = await builder
|
||||
.TryCatchSendAsync<Response<UserFullInfoWrapper>>(httpClient, logger, token)
|
||||
.SendAsync<Response<UserFullInfoWrapper>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -38,7 +38,7 @@ internal sealed partial class AnnouncementClient
|
||||
.Get();
|
||||
|
||||
Response<AnnouncementWrapper>? resp = await builder
|
||||
.TryCatchSendAsync<Response<AnnouncementWrapper>>(httpClient, logger, token)
|
||||
.SendAsync<Response<AnnouncementWrapper>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -62,7 +62,7 @@ internal sealed partial class AnnouncementClient
|
||||
.Get();
|
||||
|
||||
Response<ListWrapper<AnnouncementContent>>? resp = await builder
|
||||
.TryCatchSendAsync<Response<ListWrapper<AnnouncementContent>>>(httpClient, logger, token)
|
||||
.SendAsync<Response<ListWrapper<AnnouncementContent>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -40,7 +40,7 @@ internal sealed partial class GachaInfoClient
|
||||
.Get();
|
||||
|
||||
Response<GachaLogPage>? resp = await builder
|
||||
.TryCatchSendAsync<Response<GachaLogPage>>(httpClient, logger, token)
|
||||
.SendAsync<Response<GachaLogPage>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -26,7 +26,7 @@ internal sealed partial class PandaClient
|
||||
.PostJson(options);
|
||||
|
||||
Response<UrlWrapper>? resp = await builder
|
||||
.TryCatchSendAsync<Response<UrlWrapper>>(httpClient, logger, token)
|
||||
.SendAsync<Response<UrlWrapper>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -41,7 +41,7 @@ internal sealed partial class PandaClient
|
||||
.PostJson(options);
|
||||
|
||||
Response<GameLoginResult>? resp = await builder
|
||||
.TryCatchSendAsync<Response<GameLoginResult>>(httpClient, logger, token)
|
||||
.SendAsync<Response<GameLoginResult>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -30,7 +30,7 @@ internal sealed partial class PassportClient : IPassportClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.PROD, true).ConfigureAwait(false);
|
||||
|
||||
Response<UidCookieToken>? resp = await builder
|
||||
.TryCatchSendAsync<Response<UidCookieToken>>(httpClient, logger, token)
|
||||
.SendAsync<Response<UidCookieToken>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -46,7 +46,7 @@ internal sealed partial class PassportClient : IPassportClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.PROD, true).ConfigureAwait(false);
|
||||
|
||||
Response<LTokenWrapper>? resp = await builder
|
||||
.TryCatchSendAsync<Response<LTokenWrapper>>(httpClient, logger, token)
|
||||
.SendAsync<Response<LTokenWrapper>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -29,7 +29,7 @@ internal sealed partial class PassportClient2
|
||||
.PostJson(new Timestamp());
|
||||
|
||||
Response<UserInfoWrapper>? resp = await builder
|
||||
.TryCatchSendAsync<Response<UserInfoWrapper>>(httpClient, logger, token)
|
||||
.SendAsync<Response<UserInfoWrapper>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -45,7 +45,7 @@ internal sealed partial class PassportClient2
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.PROD, true).ConfigureAwait(false);
|
||||
|
||||
Response<LoginResult>? resp = await builder
|
||||
.TryCatchSendAsync<Response<LoginResult>>(httpClient, logger, token)
|
||||
.SendAsync<Response<LoginResult>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -64,7 +64,7 @@ internal sealed partial class PassportClient2
|
||||
.PostJson(data);
|
||||
|
||||
Response<LoginResult>? resp = await builder
|
||||
.TryCatchSendAsync<Response<LoginResult>>(httpClient, logger, token)
|
||||
.SendAsync<Response<LoginResult>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -31,7 +31,7 @@ internal sealed partial class PassportClientOversea : IPassportClient
|
||||
.PostJson(data);
|
||||
|
||||
Response<UidCookieToken>? resp = await builder
|
||||
.TryCatchSendAsync<Response<UidCookieToken>>(httpClient, logger, token)
|
||||
.SendAsync<Response<UidCookieToken>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -50,7 +50,7 @@ internal sealed partial class PassportClientOversea : IPassportClient
|
||||
.PostJson(data);
|
||||
|
||||
Response<LTokenWrapper>? resp = await builder
|
||||
.TryCatchSendAsync<Response<LTokenWrapper>>(httpClient, logger, token)
|
||||
.SendAsync<Response<LTokenWrapper>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -24,7 +24,7 @@ internal sealed partial class DeviceFpClient
|
||||
.PostJson(data);
|
||||
|
||||
Response<DeviceFpWrapper>? resp = await builder
|
||||
.TryCatchSendAsync<Response<DeviceFpWrapper>>(httpClient, logger, token)
|
||||
.SendAsync<Response<DeviceFpWrapper>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -41,7 +41,7 @@ internal sealed partial class ResourceClient
|
||||
.Get();
|
||||
|
||||
Response<GameResource>? resp = await builder
|
||||
.TryCatchSendAsync<Response<GameResource>>(httpClient, logger, token)
|
||||
.SendAsync<Response<GameResource>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// 最新版完整包
|
||||
@@ -70,7 +70,7 @@ internal sealed partial class ResourceClient
|
||||
.Get();
|
||||
|
||||
Response<GameContent>? resp = await builder
|
||||
.TryCatchSendAsync<Response<GameContent>>(httpClient, logger, token)
|
||||
.SendAsync<Response<GameContent>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -34,7 +34,7 @@ internal sealed partial class AuthClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen1, SaltType.K2, true).ConfigureAwait(false);
|
||||
|
||||
Response<ActionTicketWrapper>? resp = await builder
|
||||
.TryCatchSendAsync<Response<ActionTicketWrapper>>(httpClient, logger, token)
|
||||
.SendAsync<Response<ActionTicketWrapper>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -57,7 +57,7 @@ internal sealed partial class AuthClient
|
||||
.Get();
|
||||
|
||||
resp = await builder
|
||||
.TryCatchSendAsync<Response<ListWrapper<NameToken>>>(httpClient, logger, token)
|
||||
.SendAsync<Response<ListWrapper<NameToken>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ internal sealed partial class BindingClient
|
||||
.Get();
|
||||
|
||||
Response<ListWrapper<UserGameRole>>? resp = await builder
|
||||
.TryCatchSendAsync<Response<ListWrapper<UserGameRole>>>(httpClient, logger, token)
|
||||
.SendAsync<Response<ListWrapper<UserGameRole>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -66,7 +66,7 @@ internal sealed partial class BindingClient
|
||||
.Get();
|
||||
|
||||
Response<ListWrapper<UserGameRole>>? resp = await builder
|
||||
.TryCatchSendAsync<Response<ListWrapper<UserGameRole>>>(httpClient, logger, token)
|
||||
.SendAsync<Response<ListWrapper<UserGameRole>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -32,7 +32,7 @@ internal sealed partial class BindingClient2
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen1, SaltType.LK2, true).ConfigureAwait(false);
|
||||
|
||||
Response<ListWrapper<UserGameRole>>? resp = await builder
|
||||
.TryCatchSendAsync<Response<ListWrapper<UserGameRole>>>(httpClient, logger, token)
|
||||
.SendAsync<Response<ListWrapper<UserGameRole>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -49,7 +49,7 @@ internal sealed partial class BindingClient2
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen1, SaltType.LK2, true).ConfigureAwait(false);
|
||||
|
||||
Response<GameAuthKey>? resp = await builder
|
||||
.TryCatchSendAsync<Response<GameAuthKey>>(httpClient, logger, token)
|
||||
.SendAsync<Response<GameAuthKey>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -38,7 +38,7 @@ internal sealed partial class SignInClient : ISignInClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen1, SaltType.LK2, true).ConfigureAwait(false);
|
||||
|
||||
Response<ExtraAwardInfo>? resp = await builder
|
||||
.TryCatchSendAsync<Response<ExtraAwardInfo>>(httpClient, logger, token)
|
||||
.SendAsync<Response<ExtraAwardInfo>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -55,7 +55,7 @@ internal sealed partial class SignInClient : ISignInClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen1, SaltType.LK2, true).ConfigureAwait(false);
|
||||
|
||||
Response<SignInRewardInfo>? resp = await builder
|
||||
.TryCatchSendAsync<Response<SignInRewardInfo>>(httpClient, logger, token)
|
||||
.SendAsync<Response<SignInRewardInfo>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -72,7 +72,7 @@ internal sealed partial class SignInClient : ISignInClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen1, SaltType.LK2, true).ConfigureAwait(false);
|
||||
|
||||
Response<SignInRewardReSignInfo>? resp = await builder
|
||||
.TryCatchSendAsync<Response<SignInRewardReSignInfo>>(httpClient, logger, token)
|
||||
.SendAsync<Response<SignInRewardReSignInfo>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -87,7 +87,7 @@ internal sealed partial class SignInClient : ISignInClient
|
||||
.Get();
|
||||
|
||||
Response<Reward>? resp = await builder
|
||||
.TryCatchSendAsync<Response<Reward>>(httpClient, logger, token)
|
||||
.SendAsync<Response<Reward>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -104,7 +104,7 @@ internal sealed partial class SignInClient : ISignInClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen1, SaltType.LK2, true).ConfigureAwait(false);
|
||||
|
||||
Response<SignInResult>? resp = await builder
|
||||
.TryCatchSendAsync<Response<SignInResult>>(httpClient, logger, token)
|
||||
.SendAsync<Response<SignInResult>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -121,7 +121,7 @@ internal sealed partial class SignInClient : ISignInClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen1, SaltType.LK2, true).ConfigureAwait(false);
|
||||
|
||||
Response<SignInResult>? resp = await builder
|
||||
.TryCatchSendAsync<Response<SignInResult>>(httpClient, logger, token)
|
||||
.SendAsync<Response<SignInResult>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (resp is { Data: { Success: 1, Gt: string gt, Challenge: string originChallenge } })
|
||||
@@ -140,7 +140,7 @@ internal sealed partial class SignInClient : ISignInClient
|
||||
await verifiedBuilder.SignDataAsync(DataSignAlgorithmVersion.Gen1, SaltType.LK2, true).ConfigureAwait(false);
|
||||
|
||||
resp = await verifiedBuilder
|
||||
.TryCatchSendAsync<Response<SignInResult>>(httpClient, logger, token)
|
||||
.SendAsync<Response<SignInResult>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -32,7 +32,7 @@ internal sealed partial class SignInClientOversea : ISignInClient
|
||||
.Get();
|
||||
|
||||
Response<SignInRewardInfo>? resp = await builder
|
||||
.TryCatchSendAsync<Response<SignInRewardInfo>>(httpClient, logger, token)
|
||||
.SendAsync<Response<SignInRewardInfo>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -46,7 +46,7 @@ internal sealed partial class SignInClientOversea : ISignInClient
|
||||
.Get();
|
||||
|
||||
Response<Reward>? resp = await builder
|
||||
.TryCatchSendAsync<Response<Reward>>(httpClient, logger, token)
|
||||
.SendAsync<Response<Reward>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -60,7 +60,7 @@ internal sealed partial class SignInClientOversea : ISignInClient
|
||||
.PostJson(new SignInData(userAndUid.Uid, true));
|
||||
|
||||
Response<SignInResult>? resp = await builder
|
||||
.TryCatchSendAsync<Response<SignInResult>>(httpClient, logger, token)
|
||||
.SendAsync<Response<SignInResult>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (resp is { Data: { Success: 1, Gt: string gt, Challenge: string originChallenge } })
|
||||
@@ -76,7 +76,7 @@ internal sealed partial class SignInClientOversea : ISignInClient
|
||||
.PostJson(new SignInData(userAndUid.Uid, true));
|
||||
|
||||
resp = await verifiedBuilder
|
||||
.TryCatchSendAsync<Response<SignInResult>>(httpClient, logger, token)
|
||||
.SendAsync<Response<SignInResult>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -28,7 +28,7 @@ internal sealed partial class CalculateClient
|
||||
.PostJson(delta);
|
||||
|
||||
Response<Consumption>? resp = await builder
|
||||
.TryCatchSendAsync<Response<Consumption>>(httpClient, logger, token)
|
||||
.SendAsync<Response<Consumption>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -52,7 +52,7 @@ internal sealed partial class CalculateClient
|
||||
.PostJson(data);
|
||||
|
||||
Response<BatchConsumption>? resp = await builder
|
||||
.TryCatchSendAsync<Response<BatchConsumption>>(httpClient, logger, token)
|
||||
.SendAsync<Response<BatchConsumption>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -77,7 +77,7 @@ internal sealed partial class CalculateClient
|
||||
.PostJson(filter);
|
||||
|
||||
resp = await builder
|
||||
.TryCatchSendAsync<Response<ListWrapper<Avatar>>>(httpClient, logger, token)
|
||||
.SendAsync<Response<ListWrapper<Avatar>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (resp is not null && resp.IsOk())
|
||||
@@ -110,7 +110,7 @@ internal sealed partial class CalculateClient
|
||||
.Get();
|
||||
|
||||
Response<AvatarDetail>? resp = await builder
|
||||
.TryCatchSendAsync<Response<AvatarDetail>>(httpClient, logger, token)
|
||||
.SendAsync<Response<AvatarDetail>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -125,7 +125,7 @@ internal sealed partial class CalculateClient
|
||||
.Get();
|
||||
|
||||
Response<FurnitureListWrapper>? resp = await builder
|
||||
.TryCatchSendAsync<Response<FurnitureListWrapper>>(httpClient, logger, token)
|
||||
.SendAsync<Response<FurnitureListWrapper>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -142,7 +142,7 @@ internal sealed partial class CalculateClient
|
||||
.PostJson(data);
|
||||
|
||||
Response<ListWrapper<Item>>? resp = await builder
|
||||
.TryCatchSendAsync<Response<ListWrapper<Item>>>(httpClient, logger, token)
|
||||
.SendAsync<Response<ListWrapper<Item>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -33,7 +33,7 @@ internal sealed partial class CardClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.X4, false).ConfigureAwait(false);
|
||||
|
||||
Response<VerificationRegistration>? resp = await builder
|
||||
.TryCatchSendAsync<Response<VerificationRegistration>>(httpClient, logger, token)
|
||||
.SendAsync<Response<VerificationRegistration>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -51,7 +51,7 @@ internal sealed partial class CardClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.X4, false).ConfigureAwait(false);
|
||||
|
||||
Response<VerificationResult>? resp = await builder
|
||||
.TryCatchSendAsync<Response<VerificationResult>>(httpClient, logger, token)
|
||||
.SendAsync<Response<VerificationResult>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -67,7 +67,7 @@ internal sealed partial class CardClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.X6, false).ConfigureAwait(false);
|
||||
|
||||
Response<DailyNote.WidgetDailyNote>? resp = await builder
|
||||
.TryCatchSendAsync<Response<DailyNote.WidgetDailyNote>>(httpClient, logger, token)
|
||||
.SendAsync<Response<DailyNote.WidgetDailyNote>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -35,7 +35,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.X4, false).ConfigureAwait(false);
|
||||
|
||||
Response<DailyNote.DailyNote>? resp = await builder
|
||||
.TryCatchSendAsync<Response<DailyNote.DailyNote>>(httpClient, logger, token)
|
||||
.SendAsync<Response<DailyNote.DailyNote>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// We have a verification procedure to handle
|
||||
@@ -59,7 +59,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
||||
await verifiedbuilder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.X4, false).ConfigureAwait(false);
|
||||
|
||||
resp = await verifiedbuilder
|
||||
.TryCatchSendAsync<Response<DailyNote.DailyNote>>(httpClient, logger, token)
|
||||
.SendAsync<Response<DailyNote.DailyNote>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -78,7 +78,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.X4, false).ConfigureAwait(false);
|
||||
|
||||
Response<PlayerInfo>? resp = await builder
|
||||
.TryCatchSendAsync<Response<PlayerInfo>>(httpClient, logger, token)
|
||||
.SendAsync<Response<PlayerInfo>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// We have a verification procedure to handle
|
||||
@@ -102,7 +102,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
||||
await verifiedbuilder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.X4, false).ConfigureAwait(false);
|
||||
|
||||
resp = await verifiedbuilder
|
||||
.TryCatchSendAsync<Response<PlayerInfo>>(httpClient, logger, token)
|
||||
.SendAsync<Response<PlayerInfo>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -121,7 +121,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.X4, false).ConfigureAwait(false);
|
||||
|
||||
Response<SpiralAbyss.SpiralAbyss>? resp = await builder
|
||||
.TryCatchSendAsync<Response<SpiralAbyss.SpiralAbyss>>(httpClient, logger, token)
|
||||
.SendAsync<Response<SpiralAbyss.SpiralAbyss>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// We have a verification procedure to handle
|
||||
@@ -145,7 +145,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
||||
await verifiedbuilder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.X4, false).ConfigureAwait(false);
|
||||
|
||||
resp = await verifiedbuilder
|
||||
.TryCatchSendAsync<Response<SpiralAbyss.SpiralAbyss>>(httpClient, logger, token)
|
||||
.SendAsync<Response<SpiralAbyss.SpiralAbyss>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -164,7 +164,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.X4, false).ConfigureAwait(false);
|
||||
|
||||
Response<BasicRoleInfo>? resp = await builder
|
||||
.TryCatchSendAsync<Response<BasicRoleInfo>>(httpClient, logger, token)
|
||||
.SendAsync<Response<BasicRoleInfo>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -181,7 +181,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.X4, false).ConfigureAwait(false);
|
||||
|
||||
Response<CharacterWrapper>? resp = await builder
|
||||
.TryCatchSendAsync<Response<CharacterWrapper>>(httpClient, logger, token)
|
||||
.SendAsync<Response<CharacterWrapper>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// We have a verification procedure to handle
|
||||
@@ -205,7 +205,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
||||
await verifiedBuilder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.X4, false).ConfigureAwait(false);
|
||||
|
||||
resp = await verifiedBuilder
|
||||
.TryCatchSendAsync<Response<CharacterWrapper>>(httpClient, logger, token)
|
||||
.SendAsync<Response<CharacterWrapper>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ internal sealed partial class GameRecordClientOversea : IGameRecordClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.OSX4, false).ConfigureAwait(false);
|
||||
|
||||
Response<DailyNote.DailyNote>? resp = await builder
|
||||
.TryCatchSendAsync<Response<DailyNote.DailyNote>>(httpClient, logger, token)
|
||||
.SendAsync<Response<DailyNote.DailyNote>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -47,7 +47,7 @@ internal sealed partial class GameRecordClientOversea : IGameRecordClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.OSX4, false).ConfigureAwait(false);
|
||||
|
||||
Response<PlayerInfo>? resp = await builder
|
||||
.TryCatchSendAsync<Response<PlayerInfo>>(httpClient, logger, token)
|
||||
.SendAsync<Response<PlayerInfo>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -63,7 +63,7 @@ internal sealed partial class GameRecordClientOversea : IGameRecordClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.OSX4, false).ConfigureAwait(false);
|
||||
|
||||
Response<SpiralAbyss.SpiralAbyss>? resp = await builder
|
||||
.TryCatchSendAsync<Response<SpiralAbyss.SpiralAbyss>>(httpClient, logger, token)
|
||||
.SendAsync<Response<SpiralAbyss.SpiralAbyss>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
@@ -79,7 +79,7 @@ internal sealed partial class GameRecordClientOversea : IGameRecordClient
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.OSX4, false).ConfigureAwait(false);
|
||||
|
||||
Response<CharacterWrapper>? resp = await builder
|
||||
.TryCatchSendAsync<Response<CharacterWrapper>>(httpClient, logger, token)
|
||||
.SendAsync<Response<CharacterWrapper>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -41,6 +41,6 @@ internal sealed partial class HutaoDocumentationClient
|
||||
.SetHeader("x-algolia-application-id", AlgoliaApplicationId)
|
||||
.PostJson(data);
|
||||
|
||||
return await builder.TryCatchSendAsync<AlgoliaResponse>(httpClient, logger, token).ConfigureAwait(false);
|
||||
return await builder.SendAsync<AlgoliaResponse>(httpClient, logger, token).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ internal sealed partial class HomaGachaLogClient
|
||||
await builder.TrySetTokenAsync(hutaoUserOptions).ConfigureAwait(false);
|
||||
|
||||
HutaoResponse<GachaEventStatistics>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<GachaEventStatistics>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<GachaEventStatistics>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -57,7 +57,7 @@ internal sealed partial class HomaGachaLogClient
|
||||
await builder.TrySetTokenAsync(hutaoUserOptions).ConfigureAwait(false);
|
||||
|
||||
HutaoResponse<GachaDistribution>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<GachaDistribution>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<GachaDistribution>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -77,7 +77,7 @@ internal sealed partial class HomaGachaLogClient
|
||||
await builder.TrySetTokenAsync(hutaoUserOptions).ConfigureAwait(false);
|
||||
|
||||
HutaoResponse<List<GachaEntry>>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<List<GachaEntry>>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<List<GachaEntry>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -98,7 +98,7 @@ internal sealed partial class HomaGachaLogClient
|
||||
await builder.TrySetTokenAsync(hutaoUserOptions).ConfigureAwait(false);
|
||||
|
||||
HutaoResponse<EndIds>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<EndIds>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<EndIds>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -122,7 +122,7 @@ internal sealed partial class HomaGachaLogClient
|
||||
await builder.TrySetTokenAsync(hutaoUserOptions).ConfigureAwait(false);
|
||||
|
||||
HutaoResponse<List<GachaItem>>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<List<GachaItem>>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<List<GachaItem>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -146,7 +146,7 @@ internal sealed partial class HomaGachaLogClient
|
||||
await builder.TrySetTokenAsync(hutaoUserOptions).ConfigureAwait(false);
|
||||
|
||||
HutaoResponse? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -167,7 +167,7 @@ internal sealed partial class HomaGachaLogClient
|
||||
await builder.TrySetTokenAsync(hutaoUserOptions).ConfigureAwait(false);
|
||||
|
||||
HutaoResponse? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -43,7 +43,7 @@ internal sealed partial class HomaGeetestClient
|
||||
.Get();
|
||||
|
||||
GeetestResponse? resp = await builder
|
||||
.TryCatchSendAsync<GeetestResponse>(httpClient, logger, token)
|
||||
.SendAsync<GeetestResponse>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (resp is null)
|
||||
|
||||
@@ -31,7 +31,7 @@ internal sealed partial class HutaoAsAServiceClient
|
||||
.PostJson(excluedeIds);
|
||||
|
||||
HutaoResponse<List<Announcement>>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<List<Announcement>>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<List<Announcement>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -46,7 +46,7 @@ internal sealed partial class HutaoAsAServiceClient
|
||||
await builder.TrySetTokenAsync(hutaoUserOptions).ConfigureAwait(false);
|
||||
|
||||
HutaoResponse? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -61,7 +61,7 @@ internal sealed partial class HutaoAsAServiceClient
|
||||
await builder.TrySetTokenAsync(hutaoUserOptions).ConfigureAwait(false);
|
||||
|
||||
HutaoResponse? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -76,7 +76,7 @@ internal sealed partial class HutaoAsAServiceClient
|
||||
await builder.TrySetTokenAsync(hutaoUserOptions).ConfigureAwait(false);
|
||||
|
||||
HutaoResponse? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -25,7 +25,7 @@ internal sealed partial class HutaoInfrastructureClient
|
||||
.SetRequestUri(HutaoEndpoints.StaticSize)
|
||||
.Get();
|
||||
|
||||
HutaoResponse<StaticResourceSizeInformation>? resp = await builder.TryCatchSendAsync<HutaoResponse<StaticResourceSizeInformation>>(httpClient, logger, token).ConfigureAwait(false);
|
||||
HutaoResponse<StaticResourceSizeInformation>? resp = await builder.SendAsync<HutaoResponse<StaticResourceSizeInformation>>(httpClient, logger, token).ConfigureAwait(false);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ internal sealed partial class HutaoInfrastructureClient
|
||||
.SetRequestUri(HutaoEndpoints.Ip)
|
||||
.Get();
|
||||
|
||||
HutaoResponse<IPInformation>? resp = await builder.TryCatchSendAsync<HutaoResponse<IPInformation>>(httpClient, logger, token).ConfigureAwait(false);
|
||||
HutaoResponse<IPInformation>? resp = await builder.SendAsync<HutaoResponse<IPInformation>>(httpClient, logger, token).ConfigureAwait(false);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ internal sealed partial class HutaoInfrastructureClient
|
||||
.SetHeader("x-hutao-device-id", runtimeOptions.DeviceId)
|
||||
.Get();
|
||||
|
||||
HutaoResponse<HutaoVersionInformation>? resp = await builder.TryCatchSendAsync<HutaoResponse<HutaoVersionInformation>>(httpClient, logger, token).ConfigureAwait(false);
|
||||
HutaoResponse<HutaoVersionInformation>? resp = await builder.SendAsync<HutaoResponse<HutaoVersionInformation>>(httpClient, logger, token).ConfigureAwait(false);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ internal sealed partial class HutaoInfrastructureClient
|
||||
.SetRequestUri(HutaoEndpoints.PatchYaeAchievement)
|
||||
.Get();
|
||||
|
||||
HutaoResponse<YaeVersionInformation>? resp = await builder.TryCatchSendAsync<HutaoResponse<YaeVersionInformation>>(httpClient, logger, token).ConfigureAwait(false);
|
||||
HutaoResponse<YaeVersionInformation>? resp = await builder.SendAsync<HutaoResponse<YaeVersionInformation>>(httpClient, logger, token).ConfigureAwait(false);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
}
|
||||
@@ -64,7 +64,7 @@ internal sealed partial class HutaoPassportClient
|
||||
await builder.TrySetTokenAsync(hutaoUserOptions).ConfigureAwait(false);
|
||||
|
||||
HutaoResponse? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -92,7 +92,7 @@ internal sealed partial class HutaoPassportClient
|
||||
.PostJson(data);
|
||||
|
||||
HutaoResponse<string>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<string>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<string>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -114,7 +114,7 @@ internal sealed partial class HutaoPassportClient
|
||||
await builder.TrySetTokenAsync(hutaoUserOptions).ConfigureAwait(false);
|
||||
|
||||
HutaoResponse? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -142,7 +142,7 @@ internal sealed partial class HutaoPassportClient
|
||||
.PostJson(data);
|
||||
|
||||
HutaoResponse<string>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<string>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<string>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -168,7 +168,7 @@ internal sealed partial class HutaoPassportClient
|
||||
.PostJson(data);
|
||||
|
||||
HutaoResponse<string>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<string>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<string>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -188,7 +188,7 @@ internal sealed partial class HutaoPassportClient
|
||||
await builder.TrySetTokenAsync(hutaoUserOptions).ConfigureAwait(false);
|
||||
|
||||
HutaoResponse<UserInfo>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<UserInfo>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<UserInfo>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -35,7 +35,7 @@ internal sealed partial class HutaoLogUploadClient
|
||||
.PostJson(BuildFromException(exception));
|
||||
|
||||
Response<string>? resp = await builder
|
||||
.TryCatchSendAsync<Response<string>>(httpClient, logger, default)
|
||||
.SendAsync<Response<string>>(httpClient, logger, default)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return resp?.Data;
|
||||
|
||||
@@ -44,7 +44,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.Get();
|
||||
|
||||
HutaoResponse<bool>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<bool>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<bool>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -64,7 +64,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.Get();
|
||||
|
||||
HutaoResponse<RankInfo>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<RankInfo>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<RankInfo>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -83,7 +83,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.Get();
|
||||
|
||||
HutaoResponse<Overview>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<Overview>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<Overview>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -102,7 +102,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.Get();
|
||||
|
||||
HutaoResponse<List<AvatarAppearanceRank>>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<List<AvatarAppearanceRank>>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<List<AvatarAppearanceRank>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -121,7 +121,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.Get();
|
||||
|
||||
HutaoResponse<List<AvatarUsageRank>>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<List<AvatarUsageRank>>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<List<AvatarUsageRank>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -140,7 +140,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.Get();
|
||||
|
||||
HutaoResponse<List<AvatarCollocation>>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<List<AvatarCollocation>>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<List<AvatarCollocation>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -159,7 +159,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.Get();
|
||||
|
||||
HutaoResponse<List<WeaponCollocation>>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<List<WeaponCollocation>>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<List<WeaponCollocation>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -178,7 +178,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.Get();
|
||||
|
||||
HutaoResponse<List<AvatarConstellationInfo>>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<List<AvatarConstellationInfo>>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<List<AvatarConstellationInfo>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -197,7 +197,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.Get();
|
||||
|
||||
HutaoResponse<List<TeamAppearance>>? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse<List<TeamAppearance>>>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse<List<TeamAppearance>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
@@ -256,7 +256,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.PostJson(playerRecord);
|
||||
|
||||
HutaoResponse? resp = await builder
|
||||
.TryCatchSendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.SendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -38,7 +38,7 @@ internal sealed partial class HutaoWallpaperClient
|
||||
.SetRequestUri(url)
|
||||
.Get();
|
||||
|
||||
Response<Wallpaper>? resp = await builder.TryCatchSendAsync<Response<Wallpaper>>(httpClient, logger, token).ConfigureAwait(false);
|
||||
Response<Wallpaper>? resp = await builder.SendAsync<Response<Wallpaper>>(httpClient, logger, token).ConfigureAwait(false);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,12 @@ internal static class HttpRequestMessageBuilderExtension
|
||||
{
|
||||
private const string RequestErrorMessage = "请求异常已忽略: {Uri}";
|
||||
|
||||
internal static async ValueTask<TResult?> TryCatchSendAsync<TResult>(this HttpRequestMessageBuilder builder, HttpClient httpClient, ILogger logger, CancellationToken token)
|
||||
internal static void Resurrect(this HttpRequestMessageBuilder builder)
|
||||
{
|
||||
builder.HttpRequestMessage.Resurrect();
|
||||
}
|
||||
|
||||
internal static async ValueTask<TResult?> SendAsync<TResult>(this HttpRequestMessageBuilder builder, HttpClient httpClient, ILogger logger, CancellationToken token)
|
||||
where TResult : class
|
||||
{
|
||||
try
|
||||
@@ -70,7 +75,7 @@ internal static class HttpRequestMessageBuilderExtension
|
||||
}
|
||||
}
|
||||
|
||||
internal static async ValueTask TryCatchSendAsync(this HttpRequestMessageBuilder builder, HttpClient httpClient, ILogger logger, CancellationToken token)
|
||||
internal static async ValueTask SendAsync(this HttpRequestMessageBuilder builder, HttpClient httpClient, ILogger logger, CancellationToken token)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System.Net.Http;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Snap.Hutao.Web.Request.Builder;
|
||||
|
||||
internal static class HttpRequestMessageExtension
|
||||
{
|
||||
private const int MessageNotYetSent = 0;
|
||||
|
||||
public static void Resurrect(this HttpRequestMessage httpRequestMessage)
|
||||
{
|
||||
Interlocked.Exchange(ref GetPrivateSendStatus(httpRequestMessage), MessageNotYetSent);
|
||||
|
||||
if (httpRequestMessage.Content is { } content)
|
||||
{
|
||||
Volatile.Write(ref GetPrivatedDisposed(content), false);
|
||||
}
|
||||
}
|
||||
|
||||
// private int _sendStatus
|
||||
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_sendStatus")]
|
||||
private static extern ref int GetPrivateSendStatus(HttpRequestMessage message);
|
||||
|
||||
// private bool _disposed
|
||||
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_disposed")]
|
||||
private static extern ref bool GetPrivatedDisposed(HttpContent content);
|
||||
}
|
||||
@@ -22,7 +22,8 @@ internal unsafe struct IPersistFile
|
||||
}
|
||||
}
|
||||
|
||||
public HRESULT Save(string szFileName, bool fRemember)
|
||||
[SuppressMessage("", "SH002")]
|
||||
public HRESULT Save(ReadOnlySpan<char> szFileName, bool fRemember)
|
||||
{
|
||||
fixed (char* pszFileName = szFileName)
|
||||
{
|
||||
|
||||
@@ -24,7 +24,22 @@ internal unsafe struct IFileOperation
|
||||
}
|
||||
}
|
||||
|
||||
public HRESULT MoveItem(IShellItem* psiItem, IShellItem* psiDestinationFolder, [AllowNull] string szNewName, IFileOperationProgressSink* pfopsItem)
|
||||
public HRESULT SetOperationFlags(FILEOPERATION_FLAGS dwOperationFlags)
|
||||
{
|
||||
return ThisPtr->SetOperationFlags((IFileOperation*)Unsafe.AsPointer(ref this), dwOperationFlags);
|
||||
}
|
||||
|
||||
[SuppressMessage("", "SH002")]
|
||||
public HRESULT RenameItem(IShellItem* psiItem, ReadOnlySpan<char> szNewName, IFileOperationProgressSink* pfopsItem)
|
||||
{
|
||||
fixed (char* pszNewName = szNewName)
|
||||
{
|
||||
return ThisPtr->RenameItem((IFileOperation*)Unsafe.AsPointer(ref this), psiItem, pszNewName, pfopsItem);
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("", "SH002")]
|
||||
public HRESULT MoveItem(IShellItem* psiItem, IShellItem* psiDestinationFolder, [AllowNull] ReadOnlySpan<char> szNewName, IFileOperationProgressSink* pfopsItem)
|
||||
{
|
||||
fixed (char* pszNewName = szNewName)
|
||||
{
|
||||
|
||||
@@ -26,7 +26,8 @@ internal unsafe struct IShellLinkW
|
||||
}
|
||||
}
|
||||
|
||||
public HRESULT SetArguments(string szArgs)
|
||||
[SuppressMessage("", "SH002")]
|
||||
public HRESULT SetArguments(ReadOnlySpan<char> szArgs)
|
||||
{
|
||||
fixed (char* pszArgs = szArgs)
|
||||
{
|
||||
@@ -39,7 +40,8 @@ internal unsafe struct IShellLinkW
|
||||
return ThisPtr->SetShowCmd((IShellLinkW*)Unsafe.AsPointer(ref this), iShowCmd);
|
||||
}
|
||||
|
||||
public HRESULT SetIconLocation(string szIconPath, int iIcon)
|
||||
[SuppressMessage("", "SH002")]
|
||||
public HRESULT SetIconLocation(ReadOnlySpan<char> szIconPath, int iIcon)
|
||||
{
|
||||
fixed (char* pszIconPath = szIconPath)
|
||||
{
|
||||
@@ -47,7 +49,8 @@ internal unsafe struct IShellLinkW
|
||||
}
|
||||
}
|
||||
|
||||
public HRESULT SetPath(string szFile)
|
||||
[SuppressMessage("", "SH002")]
|
||||
public HRESULT SetPath(ReadOnlySpan<char> szFile)
|
||||
{
|
||||
fixed (char* pszFile = szFile)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user