mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
impl #1720
This commit is contained in:
@@ -3,26 +3,12 @@
|
||||
|
||||
namespace Snap.Hutao.Model.Calculable;
|
||||
|
||||
/// <summary>
|
||||
/// 可计算物品选项
|
||||
/// </summary>
|
||||
internal readonly struct CalculableOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色
|
||||
/// </summary>
|
||||
public readonly ICalculableAvatar? Avatar;
|
||||
|
||||
/// <summary>
|
||||
/// 武器
|
||||
/// </summary>
|
||||
public readonly ICalculableWeapon? Weapon;
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的可计算物品选项
|
||||
/// </summary>
|
||||
/// <param name="avatar">角色</param>
|
||||
/// <param name="weapon">武器</param>
|
||||
public CalculableOptions(ICalculableAvatar? avatar, ICalculableWeapon? weapon)
|
||||
{
|
||||
Avatar = avatar;
|
||||
|
||||
@@ -228,7 +228,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// We have a verification procedure to handle
|
||||
if (resp?.ReturnCode == (int)KnownReturnCode.CODE1034)
|
||||
if (resp?.ReturnCode is (int)KnownReturnCode.CODE1034)
|
||||
{
|
||||
// Replace message
|
||||
resp.Message = SH.WebIndexOrSpiralAbyssVerificationFailed;
|
||||
|
||||
@@ -8,7 +8,7 @@ using System.Net.Http.Headers;
|
||||
|
||||
namespace Snap.Hutao.Web.Request.Builder;
|
||||
|
||||
internal class HttpRequestMessageBuilder :
|
||||
internal sealed class HttpRequestMessageBuilder :
|
||||
IBuilder,
|
||||
IHttpRequestMessageBuilder,
|
||||
IHttpHeadersBuilder<HttpHeaders>,
|
||||
@@ -22,12 +22,14 @@ internal class HttpRequestMessageBuilder :
|
||||
IHttpMethodBuilder
|
||||
{
|
||||
private readonly HttpContentSerializer httpContentSerializer;
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
private HttpRequestMessage httpRequestMessage;
|
||||
|
||||
public HttpRequestMessageBuilder(HttpContentSerializer httpContentSerializer, HttpRequestMessage? httpRequestMessage = default)
|
||||
public HttpRequestMessageBuilder(IServiceProvider serviceProvider, HttpContentSerializer httpContentSerializer, HttpRequestMessage? httpRequestMessage = default)
|
||||
{
|
||||
this.serviceProvider = serviceProvider;
|
||||
this.httpContentSerializer = httpContentSerializer;
|
||||
this.httpRequestMessage = httpRequestMessage ?? new HttpRequestMessage();
|
||||
this.httpRequestMessage = httpRequestMessage ?? new();
|
||||
}
|
||||
|
||||
public HttpRequestMessage HttpRequestMessage
|
||||
@@ -40,6 +42,8 @@ internal class HttpRequestMessageBuilder :
|
||||
}
|
||||
}
|
||||
|
||||
public IServiceProvider ServiceProvider { get => serviceProvider; }
|
||||
|
||||
public HttpContentSerializer HttpContentSerializer { get => httpContentSerializer; }
|
||||
|
||||
HttpContentHeaders IHttpHeadersBuilder<HttpContentHeaders>.Headers
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Web.Hutao.Response;
|
||||
using Snap.Hutao.Web.Response;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
|
||||
namespace Snap.Hutao.Web.Request.Builder;
|
||||
|
||||
@@ -22,6 +25,10 @@ internal static class HttpRequestMessageBuilderExtension
|
||||
internal static async ValueTask<TResult?> SendAsync<TResult>(this HttpRequestMessageBuilder builder, HttpClient httpClient, ILogger logger, CancellationToken token)
|
||||
where TResult : class
|
||||
{
|
||||
StringBuilder messageBuilder = new();
|
||||
messageBuilder.AppendLine(System.Globalization.CultureInfo.CurrentCulture, $"Host: {builder.RequestUri?.Host}");
|
||||
bool showInfo = true;
|
||||
|
||||
try
|
||||
{
|
||||
using (builder.HttpRequestMessage)
|
||||
@@ -29,51 +36,50 @@ internal static class HttpRequestMessageBuilderExtension
|
||||
using (HttpResponseMessage message = await httpClient.SendAsync(builder.HttpRequestMessage, token).ConfigureAwait(false))
|
||||
{
|
||||
message.EnsureSuccessStatusCode();
|
||||
return await builder.HttpContentSerializer.DeserializeAsync<TResult>(message.Content, token).ConfigureAwait(false);
|
||||
showInfo = false;
|
||||
return result = await builder.HttpContentSerializer.DeserializeAsync<TResult>(message.Content, token).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
|
||||
|
||||
if (ex.StatusCode is HttpStatusCode.BadGateway)
|
||||
if (TryHandleHttp502HutaoResponseSpecialCase(ex, out TResult? result))
|
||||
{
|
||||
Type resultType = typeof(TResult);
|
||||
|
||||
if (resultType == typeof(HutaoResponse))
|
||||
{
|
||||
return Activator.CreateInstance(resultType, 502, SH.WebHutaoServiceUnAvailable, default) as TResult;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (resultType.IsConstructedGenericType && resultType.GetGenericTypeDefinition() == typeof(HutaoResponse<>))
|
||||
{
|
||||
return Activator.CreateInstance(resultType, 502, SH.WebHutaoServiceUnAvailable, default, default) as TResult;
|
||||
}
|
||||
}
|
||||
|
||||
return default;
|
||||
ProcessException(messageBuilder, ex);
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
|
||||
return default;
|
||||
ProcessException(messageBuilder, ex);
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
|
||||
}
|
||||
catch (JsonException ex)
|
||||
{
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
|
||||
return default;
|
||||
ProcessException(messageBuilder, ex);
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
|
||||
}
|
||||
catch (HttpContentSerializationException ex)
|
||||
{
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
|
||||
return default;
|
||||
ProcessException(messageBuilder, ex);
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
|
||||
return default;
|
||||
ProcessException(messageBuilder, ex);
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (showInfo)
|
||||
{
|
||||
builder.ServiceProvider.GetRequiredService<IInfoBarService>().Error(messageBuilder.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
internal static void Send(this HttpRequestMessageBuilder builder, HttpClient httpClient, ILogger logger)
|
||||
@@ -86,23 +92,95 @@ internal static class HttpRequestMessageBuilderExtension
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
|
||||
}
|
||||
catch (JsonException ex)
|
||||
{
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
|
||||
}
|
||||
catch (HttpContentSerializationException ex)
|
||||
{
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
|
||||
logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryHandleHttp502HutaoResponseSpecialCase<TResult>(HttpRequestException ex, out TResult? result)
|
||||
where TResult : class
|
||||
{
|
||||
result = default;
|
||||
|
||||
if (ex.StatusCode is HttpStatusCode.BadGateway)
|
||||
{
|
||||
Type resultType = typeof(TResult);
|
||||
|
||||
if (resultType == typeof(HutaoResponse))
|
||||
{
|
||||
// HutaoResponse(int returnCode, string message, string? localizationKey)
|
||||
result = Activator.CreateInstance(resultType, 502, SH.WebHutaoServiceUnAvailable, default) as TResult;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (resultType.IsConstructedGenericType && resultType.GetGenericTypeDefinition() == typeof(HutaoResponse<>))
|
||||
{
|
||||
// HutaoResponse<TData>(int returnCode, string message, TData? data, string? localizationKey)
|
||||
result = Activator.CreateInstance(resultType, 502, SH.WebHutaoServiceUnAvailable, default, default) as TResult;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[SuppressMessage("", "CA1305")]
|
||||
private static void ProcessException(StringBuilder builder, Exception exception)
|
||||
{
|
||||
if (exception is HttpRequestException hre)
|
||||
{
|
||||
builder
|
||||
.AppendLine($"{nameof(HttpRequestException)}: Status Code: {hre.StatusCode} Error: {hre.HttpRequestError}")
|
||||
.AppendLine(hre.Message);
|
||||
}
|
||||
|
||||
if (exception is IOException ioe)
|
||||
{
|
||||
builder
|
||||
.AppendLine($"{nameof(IOException)}: 0x{ioe.HResult:X8}")
|
||||
.AppendLine(ioe.Message);
|
||||
}
|
||||
|
||||
if (exception is JsonException je)
|
||||
{
|
||||
builder
|
||||
.AppendLine($"{nameof(JsonException)}: Path: {je.Path} at Line: {je.LineNumber} Position: {je.BytePositionInLine}")
|
||||
.AppendLine(je.Message);
|
||||
}
|
||||
|
||||
if (exception is HttpContentSerializationException hcse)
|
||||
{
|
||||
builder
|
||||
.AppendLine($"{nameof(HttpContentSerializationException)}:")
|
||||
.AppendLine(hcse.Message);
|
||||
}
|
||||
|
||||
if (exception is SocketException se)
|
||||
{
|
||||
builder
|
||||
.AppendLine($"{nameof(SocketException)}: Error: {se.SocketErrorCode}")
|
||||
.AppendLine(se.Message);
|
||||
}
|
||||
|
||||
if (exception.InnerException is { } inner)
|
||||
{
|
||||
builder.AppendLine(new string('-', 40));
|
||||
ProcessException(builder, inner);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,10 @@ namespace Snap.Hutao.Web.Request.Builder;
|
||||
internal sealed partial class HttpRequestMessageBuilderFactory : IHttpRequestMessageBuilderFactory
|
||||
{
|
||||
private readonly JsonHttpContentSerializer jsonHttpContentSerializer;
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
|
||||
public HttpRequestMessageBuilder Create()
|
||||
{
|
||||
return new(jsonHttpContentSerializer);
|
||||
return new(serviceProvider, jsonHttpContentSerializer);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user