mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
unify response behavior
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
@@ -65,6 +66,20 @@ public sealed class JsonSerializeTest
|
||||
Assert.AreEqual(result, """{"Array":"AQIDBAU="}""");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InterfaceDefaultMethodCanSerializeActualInstanceMember()
|
||||
{
|
||||
ISampleInterface sample = new SampleClassImplementedInterface()
|
||||
{
|
||||
A = 1,
|
||||
B = 2,
|
||||
};
|
||||
|
||||
string result = sample.ToJson();
|
||||
Console.WriteLine(result);
|
||||
Assert.AreEqual(result, """{"A":1,"B":2}""");
|
||||
}
|
||||
|
||||
private sealed class SampleDelegatePropertyClass
|
||||
{
|
||||
public int A { get => B; set => B = value; }
|
||||
@@ -81,4 +96,22 @@ public sealed class JsonSerializeTest
|
||||
{
|
||||
public byte[]? Array { get; set; }
|
||||
}
|
||||
|
||||
private sealed class SampleClassImplementedInterface : ISampleInterface
|
||||
{
|
||||
public int A { get; set; }
|
||||
|
||||
public int B { get; set; }
|
||||
}
|
||||
|
||||
[JsonDerivedType(typeof(SampleClassImplementedInterface))]
|
||||
private interface ISampleInterface
|
||||
{
|
||||
int A { get; set; }
|
||||
|
||||
string ToJson()
|
||||
{
|
||||
return JsonSerializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ K32EnumProcessModules
|
||||
K32GetModuleBaseNameW
|
||||
K32GetModuleInformation
|
||||
ReadProcessMemory
|
||||
SetConsoleTitle
|
||||
SetEvent
|
||||
VirtualAlloc
|
||||
VirtualAllocEx
|
||||
|
||||
@@ -15,6 +15,7 @@ internal sealed class ConsoleWindowLifeTime : IDisposable
|
||||
if (LocalSetting.Get(SettingKeys.IsAllocConsoleDebugModeEnabled, false))
|
||||
{
|
||||
consoleWindowAllocated = AllocConsole();
|
||||
SetConsoleTitle("Snap Hutao Debug Console");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ internal class MiHoYoJSBridge
|
||||
/// </summary>
|
||||
/// <param name="param">参数</param>
|
||||
/// <returns>响应</returns>
|
||||
protected virtual async ValueTask<IJsResult?> ClosePageAsync(JsParam param)
|
||||
protected virtual async ValueTask<IJsBridgeResult?> ClosePageAsync(JsParam param)
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
if (coreWebView2.CanGoBack)
|
||||
@@ -106,7 +106,7 @@ internal class MiHoYoJSBridge
|
||||
/// </summary>
|
||||
/// <param name="param">参数</param>
|
||||
/// <returns>响应</returns>
|
||||
protected virtual IJsResult? ConfigureShare(JsParam param)
|
||||
protected virtual IJsBridgeResult? ConfigureShare(JsParam param)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -116,7 +116,7 @@ internal class MiHoYoJSBridge
|
||||
/// </summary>
|
||||
/// <param name="jsParam">参数</param>
|
||||
/// <returns>响应</returns>
|
||||
protected virtual async ValueTask<IJsResult?> GetActionTicketAsync(JsParam<ActionTypePayload> jsParam)
|
||||
protected virtual async ValueTask<IJsBridgeResult?> GetActionTicketAsync(JsParam<ActionTypePayload> jsParam)
|
||||
{
|
||||
return await serviceProvider
|
||||
.GetRequiredService<AuthClient>()
|
||||
@@ -299,7 +299,7 @@ internal class MiHoYoJSBridge
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual async ValueTask<IJsResult?> PushPageAsync(JsParam<PushPagePayload> param)
|
||||
protected virtual async ValueTask<IJsBridgeResult?> PushPageAsync(JsParam<PushPagePayload> param)
|
||||
{
|
||||
const string bbsSchema = "mihoyobbs://";
|
||||
string pageUrl = param.Payload.Page;
|
||||
@@ -323,7 +323,7 @@ internal class MiHoYoJSBridge
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual IJsResult? Share(JsParam<SharePayload> param)
|
||||
protected virtual IJsBridgeResult? Share(JsParam<SharePayload> param)
|
||||
{
|
||||
return new JsResult<Dictionary<string, string>>()
|
||||
{
|
||||
@@ -334,47 +334,47 @@ internal class MiHoYoJSBridge
|
||||
};
|
||||
}
|
||||
|
||||
protected virtual ValueTask<IJsResult?> ShowAlertDialogAsync(JsParam param)
|
||||
protected virtual ValueTask<IJsBridgeResult?> ShowAlertDialogAsync(JsParam param)
|
||||
{
|
||||
return ValueTask.FromException<IJsResult?>(new NotSupportedException());
|
||||
return ValueTask.FromException<IJsBridgeResult?>(new NotSupportedException());
|
||||
}
|
||||
|
||||
protected virtual IJsResult? StartRealPersonValidation(JsParam param)
|
||||
protected virtual IJsBridgeResult? StartRealPersonValidation(JsParam param)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected virtual IJsResult? StartRealnameAuth(JsParam param)
|
||||
protected virtual IJsBridgeResult? StartRealnameAuth(JsParam param)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected virtual IJsResult? GenAuthKey(JsParam param)
|
||||
protected virtual IJsBridgeResult? GenAuthKey(JsParam param)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected virtual IJsResult? GenAppAuthKey(JsParam param)
|
||||
protected virtual IJsBridgeResult? GenAppAuthKey(JsParam param)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected virtual IJsResult? OpenSystemBrowser(JsParam param)
|
||||
protected virtual IJsBridgeResult? OpenSystemBrowser(JsParam param)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected virtual IJsResult? SaveLoginTicket(JsParam param)
|
||||
protected virtual IJsBridgeResult? SaveLoginTicket(JsParam param)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected virtual ValueTask<IJsResult?> GetNotificationSettingsAsync(JsParam param)
|
||||
protected virtual ValueTask<IJsBridgeResult?> GetNotificationSettingsAsync(JsParam param)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected virtual IJsResult? ShowToast(JsParam param)
|
||||
protected virtual IJsBridgeResult? ShowToast(JsParam param)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
@@ -430,7 +430,7 @@ internal class MiHoYoJSBridge
|
||||
logger.LogInformation("[OnMessage]\nMethod : {method}\nPayload : {payload}\nCallback: {callback}", param.Method, param.Payload, param.Callback);
|
||||
using (await webMessageSemaphore.EnterAsync().ConfigureAwait(false))
|
||||
{
|
||||
IJsResult? result = await TryGetJsResultFromJsParamAsync(param).ConfigureAwait(false);
|
||||
IJsBridgeResult? result = await TryGetJsResultFromJsParamAsync(param).ConfigureAwait(false);
|
||||
|
||||
if (result is not null && param.Callback is not null)
|
||||
{
|
||||
@@ -440,13 +440,13 @@ internal class MiHoYoJSBridge
|
||||
}
|
||||
|
||||
[SuppressMessage("", "CA2254")]
|
||||
private IJsResult? LogUnhandledMessage(string message, params object?[] param)
|
||||
private IJsBridgeResult? LogUnhandledMessage(string message, params object?[] param)
|
||||
{
|
||||
logger.LogWarning(message, param);
|
||||
return default;
|
||||
}
|
||||
|
||||
private async ValueTask<IJsResult?> TryGetJsResultFromJsParamAsync(JsParam param)
|
||||
private async ValueTask<IJsBridgeResult?> TryGetJsResultFromJsParamAsync(JsParam param)
|
||||
{
|
||||
if (coreWebView2.IsDisposed())
|
||||
{
|
||||
|
||||
@@ -7,11 +7,10 @@ namespace Snap.Hutao.Web.Bridge.Model;
|
||||
/// 指示此为Js结果
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal interface IJsResult
|
||||
internal interface IJsBridgeResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 转换到Json字符串表示
|
||||
/// </summary>
|
||||
/// <returns>JSON字符串</returns>
|
||||
string ToJson();
|
||||
}
|
||||
string ToJson()
|
||||
{
|
||||
return JsonSerializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ namespace Snap.Hutao.Web.Bridge.Model;
|
||||
/// </summary>
|
||||
/// <typeparam name="TData">内部数据类型</typeparam>
|
||||
[HighQuality]
|
||||
internal sealed class JsResult<TData> : IJsResult
|
||||
internal sealed class JsResult<TData> : IJsBridgeResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 代码
|
||||
@@ -28,10 +28,4 @@ internal sealed class JsResult<TData> : IJsResult
|
||||
/// </summary>
|
||||
[JsonPropertyName("data")]
|
||||
public TData Data { get; set; } = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
string IJsResult.ToJson()
|
||||
{
|
||||
return JsonSerializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
@@ -50,10 +50,8 @@ internal sealed partial class BindingClient
|
||||
string actionTicket = actionTicketResponse.Data.Ticket;
|
||||
return await GetUserGameRolesByActionTicketAsync(actionTicket, user, token).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Response.Response.DefaultIfNull<ListWrapper<UserGameRole>, ActionTicketWrapper>(actionTicketResponse);
|
||||
}
|
||||
|
||||
return Response.Response.CloneReturnCodeAndMessage<ListWrapper<UserGameRole>, ActionTicketWrapper>(actionTicketResponse);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ internal sealed partial class HomaGachaLogClient
|
||||
.TryCatchSendAsync<HutaoResponse<GachaEventStatistics>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -60,7 +60,7 @@ internal sealed partial class HomaGachaLogClient
|
||||
.TryCatchSendAsync<HutaoResponse<GachaDistribution>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -80,7 +80,7 @@ internal sealed partial class HomaGachaLogClient
|
||||
.TryCatchSendAsync<HutaoResponse<List<GachaEntry>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -101,7 +101,7 @@ internal sealed partial class HomaGachaLogClient
|
||||
.TryCatchSendAsync<HutaoResponse<EndIds>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -125,7 +125,7 @@ internal sealed partial class HomaGachaLogClient
|
||||
.TryCatchSendAsync<HutaoResponse<List<GachaItem>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -149,7 +149,7 @@ internal sealed partial class HomaGachaLogClient
|
||||
.TryCatchSendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -170,7 +170,7 @@ internal sealed partial class HomaGachaLogClient
|
||||
.TryCatchSendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
private sealed class UidAndEndIds
|
||||
|
||||
@@ -34,7 +34,7 @@ internal sealed partial class HutaoAsAServiceClient
|
||||
.TryCatchSendAsync<HutaoResponse<List<Announcement>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
public async ValueTask<HutaoResponse> UploadAnnouncementAsync(UploadAnnouncement uploadAnnouncement, CancellationToken token = default)
|
||||
@@ -49,7 +49,7 @@ internal sealed partial class HutaoAsAServiceClient
|
||||
.TryCatchSendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
public async ValueTask<HutaoResponse> GachaLogCompensationAsync(int days, CancellationToken token = default)
|
||||
@@ -64,7 +64,7 @@ internal sealed partial class HutaoAsAServiceClient
|
||||
.TryCatchSendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
public async ValueTask<HutaoResponse> GachaLogDesignationAsync(string userName, int days, CancellationToken token = default)
|
||||
@@ -79,6 +79,6 @@ internal sealed partial class HutaoAsAServiceClient
|
||||
.TryCatchSendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Web.Hutao.Response;
|
||||
using Snap.Hutao.Web.Request.Builder;
|
||||
using Snap.Hutao.Web.Request.Builder.Abstraction;
|
||||
using Snap.Hutao.Web.Response;
|
||||
@@ -17,7 +18,7 @@ internal sealed partial class HutaoInfrastructureClient
|
||||
private readonly ILogger<HutaoInfrastructureClient> logger;
|
||||
private readonly HttpClient httpClient;
|
||||
|
||||
public async ValueTask<Response<IPInformation>> GetIPInformationAsync(CancellationToken token = default)
|
||||
public async ValueTask<HutaoResponse<IPInformation>> GetIPInformationAsync(CancellationToken token = default)
|
||||
{
|
||||
HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create()
|
||||
.SetRequestUri(HutaoEndpoints.Ip)
|
||||
@@ -26,4 +27,24 @@ internal sealed partial class HutaoInfrastructureClient
|
||||
Response<IPInformation>? resp = await builder.TryCatchSendAsync<Response<IPInformation>>(httpClient, logger, token).ConfigureAwait(false);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
public async ValueTask<HutaoResponse<HutaoVersionInformation>> GetHutaoVersionInfomationAsync(CancellationToken token = default)
|
||||
{
|
||||
HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create()
|
||||
.SetRequestUri(HutaoEndpoints.PatchSnapHutao)
|
||||
.Get();
|
||||
|
||||
Response<HutaoVersionInformation>? resp = await builder.TryCatchSendAsync<Response<HutaoVersionInformation>>(httpClient, logger, token).ConfigureAwait(false);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
public async ValueTask<HutaoResponse<YaeVersionInformation>> GetYaeVersionInformationAsync(CancellationToken token = default)
|
||||
{
|
||||
HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create()
|
||||
.SetRequestUri(HutaoEndpoints.PatchYaeAchievement)
|
||||
.Get();
|
||||
|
||||
Response<YaeVersionInformation>? resp = await builder.TryCatchSendAsync<Response<YaeVersionInformation>>(httpClient, logger, token).ConfigureAwait(false);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,7 @@ internal sealed partial class HutaoPassportClient
|
||||
.TryCatchSendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -95,7 +95,7 @@ internal sealed partial class HutaoPassportClient
|
||||
.TryCatchSendAsync<HutaoResponse<string>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
public async ValueTask<HutaoResponse> UnregisterAsync(string email, string password, string verifyCode, CancellationToken token = default)
|
||||
@@ -117,7 +117,7 @@ internal sealed partial class HutaoPassportClient
|
||||
.TryCatchSendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -145,7 +145,7 @@ internal sealed partial class HutaoPassportClient
|
||||
.TryCatchSendAsync<HutaoResponse<string>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -171,7 +171,7 @@ internal sealed partial class HutaoPassportClient
|
||||
.TryCatchSendAsync<HutaoResponse<string>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -191,7 +191,7 @@ internal sealed partial class HutaoPassportClient
|
||||
.TryCatchSendAsync<HutaoResponse<UserInfo>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
private static string Encrypt(string text)
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Web.Hutao;
|
||||
|
||||
internal sealed class HutaoVersionInformation
|
||||
{
|
||||
[JsonPropertyName("version")]
|
||||
public Version Version { get; set; } = default!;
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
using Snap.Hutao.Web.Response;
|
||||
|
||||
namespace Snap.Hutao.Web.Hutao.Response;
|
||||
|
||||
internal sealed class HutaoResponse : Web.Response.Response, ILocalizableResponse
|
||||
internal sealed class HutaoResponse : Web.Response.Response, ILocalizableResponse, ICommonResponse<HutaoResponse>
|
||||
{
|
||||
[JsonConstructor]
|
||||
public HutaoResponse(int returnCode, string message, string? localizationKey)
|
||||
@@ -17,18 +17,9 @@ internal sealed class HutaoResponse : Web.Response.Response, ILocalizableRespons
|
||||
[JsonPropertyName("l10nKey")]
|
||||
public string? LocalizationKey { get; set; }
|
||||
|
||||
public static HutaoResponse DefaultIfNull(HutaoResponse? response, [CallerMemberName] string callerName = default!)
|
||||
static HutaoResponse ICommonResponse<HutaoResponse>.CreateDefault(int returnCode, string message)
|
||||
{
|
||||
// 0x26F19335 is a magic number that hashed from "Snap.Hutao"
|
||||
response ??= new(InternalFailure, SH.FormatWebResponseRequestExceptionFormat(callerName, null), default);
|
||||
return response;
|
||||
}
|
||||
|
||||
public static HutaoResponse<TData> DefaultIfNull<TData>(HutaoResponse<TData>? response, [CallerMemberName] string callerName = default!)
|
||||
{
|
||||
// 0x26F19335 is a magic number that hashed from "Snap.Hutao"
|
||||
response ??= new(InternalFailure, SH.FormatWebResponseRequestExceptionFormat(callerName, typeof(TData).Name), default, default);
|
||||
return response ?? new(InternalFailure, SH.FormatWebResponseRequestExceptionFormat(callerName, typeof(TData).Name), default, default);
|
||||
return new(returnCode, message, default);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@@ -38,7 +29,7 @@ internal sealed class HutaoResponse : Web.Response.Response, ILocalizableRespons
|
||||
}
|
||||
|
||||
[SuppressMessage("", "SA1402")]
|
||||
internal sealed class HutaoResponse<TData> : Web.Response.Response<TData>, ILocalizableResponse
|
||||
internal sealed class HutaoResponse<TData> : Response<TData>, ILocalizableResponse, ICommonResponse<HutaoResponse<TData>>
|
||||
{
|
||||
[JsonConstructor]
|
||||
public HutaoResponse(int returnCode, string message, TData? data, string? localizationKey)
|
||||
@@ -50,6 +41,11 @@ internal sealed class HutaoResponse<TData> : Web.Response.Response<TData>, ILoca
|
||||
[JsonPropertyName("l10nKey")]
|
||||
public string? LocalizationKey { get; set; }
|
||||
|
||||
static HutaoResponse<TData> ICommonResponse<HutaoResponse<TData>>.CreateDefault(int returnCode, string message)
|
||||
{
|
||||
return new(returnCode, message, default, default);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return SH.FormatWebResponseFormat(ReturnCode, this.GetLocalizationMessageOrDefault());
|
||||
|
||||
@@ -47,7 +47,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.TryCatchSendAsync<HutaoResponse<bool>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -67,7 +67,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.TryCatchSendAsync<HutaoResponse<RankInfo>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -86,7 +86,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.TryCatchSendAsync<HutaoResponse<Overview>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -105,7 +105,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.TryCatchSendAsync<HutaoResponse<List<AvatarAppearanceRank>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -124,7 +124,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.TryCatchSendAsync<HutaoResponse<List<AvatarUsageRank>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -143,7 +143,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.TryCatchSendAsync<HutaoResponse<List<AvatarCollocation>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -162,7 +162,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.TryCatchSendAsync<HutaoResponse<List<WeaponCollocation>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -181,7 +181,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.TryCatchSendAsync<HutaoResponse<List<AvatarConstellationInfo>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -200,7 +200,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.TryCatchSendAsync<HutaoResponse<List<TeamAppearance>>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -259,6 +259,6 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
.TryCatchSendAsync<HutaoResponse>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return HutaoResponse.DefaultIfNull(resp);
|
||||
return Web.Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
}
|
||||
19
src/Snap.Hutao/Snap.Hutao/Web/Hutao/YaeVersionInformation.cs
Normal file
19
src/Snap.Hutao/Snap.Hutao/Web/Hutao/YaeVersionInformation.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Web.Hutao;
|
||||
|
||||
internal sealed class YaeVersionInformation
|
||||
{
|
||||
[JsonPropertyName("tagName")]
|
||||
public Version Version { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("url")]
|
||||
public string Url { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("source")]
|
||||
public string Source { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("frameworkUrl")]
|
||||
public string FrameworkUrl { get; set; } = default!;
|
||||
}
|
||||
@@ -15,24 +15,7 @@ namespace Snap.Hutao.Web;
|
||||
[SuppressMessage("", "SA1124")]
|
||||
internal static class HutaoEndpoints
|
||||
{
|
||||
#region Hutao as a Service
|
||||
public static string Announcement(string locale)
|
||||
{
|
||||
return $"{HomaSnapGenshinApi}/Announcement/List?locale={locale}";
|
||||
}
|
||||
|
||||
public const string AnnouncementUpload = $"{HomaSnapGenshinApi}/Service/Announcement/Upload";
|
||||
|
||||
public static string GachaLogCompensation(int days)
|
||||
{
|
||||
return $"{HomaSnapGenshinApi}/Service/GachaLog/Compensation?days={days}";
|
||||
}
|
||||
|
||||
public static string GachaLogDesignation(string userName, int days)
|
||||
{
|
||||
return $"{HomaSnapGenshinApi}/Service/GachaLog/Designation?userName={userName}&days={days}";
|
||||
}
|
||||
#endregion
|
||||
#region HomaAPI
|
||||
|
||||
#region GachaLog
|
||||
|
||||
@@ -43,28 +26,28 @@ internal static class HutaoEndpoints
|
||||
/// <returns>获取末尾Id Url</returns>
|
||||
public static string GachaLogEndIds(string uid)
|
||||
{
|
||||
return $"{HomaSnapGenshinApi}/GachaLog/EndIds?Uid={uid}";
|
||||
return $"{HomaSnapGenshin}/GachaLog/EndIds?Uid={uid}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取祈愿记录
|
||||
/// </summary>
|
||||
public const string GachaLogRetrieve = $"{HomaSnapGenshinApi}/GachaLog/Retrieve";
|
||||
public const string GachaLogRetrieve = $"{HomaSnapGenshin}/GachaLog/Retrieve";
|
||||
|
||||
/// <summary>
|
||||
/// 上传祈愿记录
|
||||
/// </summary>
|
||||
public const string GachaLogUpload = $"{HomaSnapGenshinApi}/GachaLog/Upload";
|
||||
public const string GachaLogUpload = $"{HomaSnapGenshin}/GachaLog/Upload";
|
||||
|
||||
/// <summary>
|
||||
/// 获取Uid列表
|
||||
/// </summary>
|
||||
public const string GachaLogUids = $"{HomaSnapGenshinApi}/GachaLog/Uids";
|
||||
public const string GachaLogUids = $"{HomaSnapGenshin}/GachaLog/Uids";
|
||||
|
||||
/// <summary>
|
||||
/// 获取Uid列表
|
||||
/// </summary>
|
||||
public const string GachaLogEntries = $"{HomaSnapGenshinApi}/GachaLog/Entries";
|
||||
public const string GachaLogEntries = $"{HomaSnapGenshin}/GachaLog/Entries";
|
||||
|
||||
/// <summary>
|
||||
/// 删除祈愿记录
|
||||
@@ -73,13 +56,13 @@ internal static class HutaoEndpoints
|
||||
/// <returns>删除祈愿记录 Url</returns>
|
||||
public static string GachaLogDelete(string uid)
|
||||
{
|
||||
return $"{HomaSnapGenshinApi}/GachaLog/Delete?Uid={uid}";
|
||||
return $"{HomaSnapGenshin}/GachaLog/Delete?Uid={uid}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取祈愿统计信息
|
||||
/// </summary>
|
||||
public const string GachaLogStatisticsCurrentEvents = $"{HomaSnapGenshinApi}/GachaLog/Statistics/CurrentEventStatistics";
|
||||
public const string GachaLogStatisticsCurrentEvents = $"{HomaSnapGenshin}/GachaLog/Statistics/CurrentEventStatistics";
|
||||
|
||||
/// <summary>
|
||||
/// 获取祈愿统计信息
|
||||
@@ -88,41 +71,27 @@ internal static class HutaoEndpoints
|
||||
/// <returns>祈愿统计信息Url</returns>
|
||||
public static string GachaLogStatisticsDistribution(GachaDistributionType distributionType)
|
||||
{
|
||||
return $"{HomaSnapGenshinApi}/GachaLog/Statistics/Distribution/{distributionType}";
|
||||
return $"{HomaSnapGenshin}/GachaLog/Statistics/Distribution/{distributionType}";
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Passport
|
||||
#region Hutao as a Service
|
||||
public static string Announcement(string locale)
|
||||
{
|
||||
return $"{HomaSnapGenshin}/Announcement/List?locale={locale}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取注册验证码
|
||||
/// </summary>
|
||||
public const string PassportVerify = $"{HomaSnapGenshinApi}/Passport/Verify";
|
||||
public const string AnnouncementUpload = $"{HomaSnapGenshin}/Service/Announcement/Upload";
|
||||
|
||||
/// <summary>
|
||||
/// 注册账号
|
||||
/// </summary>
|
||||
public const string PassportRegister = $"{HomaSnapGenshinApi}/Passport/Register";
|
||||
public static string GachaLogCompensation(int days)
|
||||
{
|
||||
return $"{HomaSnapGenshin}/Service/GachaLog/Compensation?days={days}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注销账号
|
||||
/// </summary>
|
||||
public const string PassportCancel = $"{HomaSnapGenshinApi}/Passport/Cancel";
|
||||
|
||||
/// <summary>
|
||||
/// 重设密码
|
||||
/// </summary>
|
||||
public const string PassportResetPassword = $"{HomaSnapGenshinApi}/Passport/ResetPassword";
|
||||
|
||||
/// <summary>
|
||||
/// 登录
|
||||
/// </summary>
|
||||
public const string PassportLogin = $"{HomaSnapGenshinApi}/Passport/Login";
|
||||
|
||||
/// <summary>
|
||||
/// 用户信息
|
||||
/// </summary>
|
||||
public const string PassportUserInfo = $"{HomaSnapGenshinApi}/Passport/UserInfo";
|
||||
public static string GachaLogDesignation(string userName, int days)
|
||||
{
|
||||
return $"{HomaSnapGenshin}/Service/GachaLog/Designation?userName={userName}&days={days}";
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region LogUpload
|
||||
@@ -130,7 +99,40 @@ internal static class HutaoEndpoints
|
||||
/// <summary>
|
||||
/// 上传日志
|
||||
/// </summary>
|
||||
public const string HutaoLogUpload = $"{HomaSnapGenshinApi}/HutaoLog/Upload";
|
||||
public const string HutaoLogUpload = $"{HomaSnapGenshin}/HutaoLog/Upload";
|
||||
#endregion
|
||||
|
||||
#region Passport
|
||||
|
||||
/// <summary>
|
||||
/// 获取注册验证码
|
||||
/// </summary>
|
||||
public const string PassportVerify = $"{HomaSnapGenshin}/Passport/Verify";
|
||||
|
||||
/// <summary>
|
||||
/// 注册账号
|
||||
/// </summary>
|
||||
public const string PassportRegister = $"{HomaSnapGenshin}/Passport/Register";
|
||||
|
||||
/// <summary>
|
||||
/// 注销账号
|
||||
/// </summary>
|
||||
public const string PassportCancel = $"{HomaSnapGenshin}/Passport/Cancel";
|
||||
|
||||
/// <summary>
|
||||
/// 重设密码
|
||||
/// </summary>
|
||||
public const string PassportResetPassword = $"{HomaSnapGenshin}/Passport/ResetPassword";
|
||||
|
||||
/// <summary>
|
||||
/// 登录
|
||||
/// </summary>
|
||||
public const string PassportLogin = $"{HomaSnapGenshin}/Passport/Login";
|
||||
|
||||
/// <summary>
|
||||
/// 用户信息
|
||||
/// </summary>
|
||||
public const string PassportUserInfo = $"{HomaSnapGenshin}/Passport/UserInfo";
|
||||
#endregion
|
||||
|
||||
#region SpiralAbyss
|
||||
@@ -142,7 +144,7 @@ internal static class HutaoEndpoints
|
||||
/// <returns>路径</returns>
|
||||
public static string RecordCheck(string uid)
|
||||
{
|
||||
return $"{HomaSnapGenshinApi}/Record/Check?uid={uid}";
|
||||
return $"{HomaSnapGenshin}/Record/Check?uid={uid}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -152,50 +154,66 @@ internal static class HutaoEndpoints
|
||||
/// <returns>路径</returns>
|
||||
public static string RecordRank(string uid)
|
||||
{
|
||||
return $"{HomaSnapGenshinApi}/Record/Rank?uid={uid}";
|
||||
return $"{HomaSnapGenshin}/Record/Rank?uid={uid}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上传记录
|
||||
/// </summary>
|
||||
public const string RecordUpload = $"{HomaSnapGenshinApi}/Record/Upload";
|
||||
public const string RecordUpload = $"{HomaSnapGenshin}/Record/Upload";
|
||||
|
||||
/// <summary>
|
||||
/// 统计信息
|
||||
/// </summary>
|
||||
public const string StatisticsOverview = $"{HomaSnapGenshinApi}/Statistics/Overview";
|
||||
public const string StatisticsOverview = $"{HomaSnapGenshin}/Statistics/Overview";
|
||||
|
||||
/// <summary>
|
||||
/// 出场率
|
||||
/// </summary>
|
||||
public const string StatisticsAvatarAttendanceRate = $"{HomaSnapGenshinApi}/Statistics/Avatar/AttendanceRate";
|
||||
public const string StatisticsAvatarAttendanceRate = $"{HomaSnapGenshin}/Statistics/Avatar/AttendanceRate";
|
||||
|
||||
/// <summary>
|
||||
/// 使用率
|
||||
/// </summary>
|
||||
public const string StatisticsAvatarUtilizationRate = $"{HomaSnapGenshinApi}/Statistics/Avatar/UtilizationRate";
|
||||
public const string StatisticsAvatarUtilizationRate = $"{HomaSnapGenshin}/Statistics/Avatar/UtilizationRate";
|
||||
|
||||
/// <summary>
|
||||
/// 角色搭配
|
||||
/// </summary>
|
||||
public const string StatisticsAvatarAvatarCollocation = $"{HomaSnapGenshinApi}/Statistics/Avatar/AvatarCollocation";
|
||||
public const string StatisticsAvatarAvatarCollocation = $"{HomaSnapGenshin}/Statistics/Avatar/AvatarCollocation";
|
||||
|
||||
/// <summary>
|
||||
/// 角色持有率
|
||||
/// </summary>
|
||||
public const string StatisticsAvatarHoldingRate = $"{HomaSnapGenshinApi}/Statistics/Avatar/HoldingRate";
|
||||
public const string StatisticsAvatarHoldingRate = $"{HomaSnapGenshin}/Statistics/Avatar/HoldingRate";
|
||||
|
||||
/// <summary>
|
||||
/// 武器搭配
|
||||
/// </summary>
|
||||
public const string StatisticsWeaponWeaponCollocation = $"{HomaSnapGenshinApi}/Statistics/Weapon/WeaponCollocation";
|
||||
public const string StatisticsWeaponWeaponCollocation = $"{HomaSnapGenshin}/Statistics/Weapon/WeaponCollocation";
|
||||
|
||||
/// <summary>
|
||||
/// 持有率
|
||||
/// </summary>
|
||||
public const string StatisticsTeamCombination = $"{HomaSnapGenshinApi}/Statistics/Team/Combination";
|
||||
public const string StatisticsTeamCombination = $"{HomaSnapGenshin}/Statistics/Team/Combination";
|
||||
#endregion
|
||||
|
||||
public static string Website(string path)
|
||||
{
|
||||
return $"{HomaSnapGenshin}/{path}";
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Infrasturcture
|
||||
|
||||
public static string Enka(in PlayerUid uid)
|
||||
{
|
||||
return $"{ApiSnapGenshinEnka}/{uid}";
|
||||
}
|
||||
|
||||
public const string Ip = $"{ApiSnapGenshin}/ip";
|
||||
|
||||
#region Metadata
|
||||
|
||||
/// <summary>
|
||||
@@ -210,7 +228,12 @@ internal static class HutaoEndpoints
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Static & Zip
|
||||
#region Patch
|
||||
public const string PatchYaeAchievement = $"{ApiSnapGenshinPatch}/yae";
|
||||
public const string PatchSnapHutao = $"{ApiSnapGenshinPatch}/hutao";
|
||||
#endregion
|
||||
|
||||
#region StaticResources
|
||||
|
||||
/// <summary>
|
||||
/// UI_Icon_None
|
||||
@@ -249,21 +272,13 @@ internal static class HutaoEndpoints
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static string Website(string path)
|
||||
{
|
||||
return $"{HomaSnapGenshinApi}/{path}";
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static string Enka(in PlayerUid uid)
|
||||
{
|
||||
return $"{ApiSnapGenshinEnka}/{uid}";
|
||||
}
|
||||
|
||||
public const string Ip = $"{ApiSnapGenshin}/ip";
|
||||
private const string ApiSnapGenshin = "https://api.snapgenshin.com";
|
||||
private const string ApiSnapGenshinMetadata = $"{ApiSnapGenshin}/metadata";
|
||||
private const string ApiSnapGenshinPatch = $"{ApiSnapGenshin}/patch";
|
||||
private const string ApiSnapGenshinStaticRaw = $"{ApiSnapGenshin}/static/raw";
|
||||
private const string ApiSnapGenshinStaticZip = $"{ApiSnapGenshin}/static/zip";
|
||||
private const string ApiSnapGenshinEnka = $"{ApiSnapGenshin}/enka";
|
||||
private const string HomaSnapGenshinApi = "https://homa.snapgenshin.com";
|
||||
private const string HomaSnapGenshin = "https://homa.snapgenshin.com";
|
||||
}
|
||||
14
src/Snap.Hutao/Snap.Hutao/Web/Response/ICommonResponse.cs
Normal file
14
src/Snap.Hutao/Snap.Hutao/Web/Response/ICommonResponse.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Web.Response;
|
||||
|
||||
internal interface ICommonResponse<TResponse>
|
||||
where TResponse : ICommonResponse<TResponse>
|
||||
{
|
||||
int ReturnCode { get; }
|
||||
|
||||
string Message { get; set; }
|
||||
|
||||
static abstract TResponse CreateDefault(int returnCode, string message);
|
||||
}
|
||||
@@ -1,25 +1,17 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core;
|
||||
using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Web.Bridge.Model;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Snap.Hutao.Web.Response;
|
||||
|
||||
/// <summary>
|
||||
/// 提供 <see cref="Response{T}"/> 的非泛型基类
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal class Response
|
||||
internal class Response : ICommonResponse<Response>
|
||||
{
|
||||
public const int InternalFailure = 0x26F19335;
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的响应
|
||||
/// </summary>
|
||||
/// <param name="returnCode">返回代码</param>
|
||||
/// <param name="message">消息</param>
|
||||
[JsonConstructor]
|
||||
public Response(int returnCode, string message)
|
||||
{
|
||||
@@ -30,15 +22,9 @@ internal class Response
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回代码
|
||||
/// </summary>
|
||||
[JsonPropertyName("retcode")]
|
||||
public int ReturnCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息
|
||||
/// </summary>
|
||||
[JsonPropertyName("message")]
|
||||
public string Message { get; set; } = default!;
|
||||
|
||||
@@ -47,16 +33,16 @@ internal class Response
|
||||
return new(response.ReturnCode == 0, response.Message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回本体或带有消息提示的默认值
|
||||
/// </summary>
|
||||
/// <param name="response">本体</param>
|
||||
/// <param name="callerName">调用方法名称</param>
|
||||
/// <returns>本体或默认值,当本体为 null 时 返回默认值</returns>
|
||||
public static Response DefaultIfNull(Response? response, [CallerMemberName] string callerName = default!)
|
||||
static Response ICommonResponse<Response>.CreateDefault(int returnCode, string message)
|
||||
{
|
||||
// 0x26F19335 is a magic number that hashed from "Snap.Hutao"
|
||||
response ??= new(InternalFailure, SH.FormatWebResponseRequestExceptionFormat(callerName, null));
|
||||
return new(returnCode, message);
|
||||
}
|
||||
|
||||
public static TResponse DefaultIfNull<TResponse>(TResponse? response, [CallerMemberName] string callerName = default!)
|
||||
where TResponse : ICommonResponse<TResponse>
|
||||
{
|
||||
string message = SH.FormatWebResponseRequestExceptionFormat(callerName, TypeNameHelper.GetTypeDisplayName(typeof(TResponse)));
|
||||
response ??= TResponse.CreateDefault(InternalFailure, message);
|
||||
|
||||
if (((KnownReturnCode)response.ReturnCode) is KnownReturnCode.PleaseLogin or KnownReturnCode.RET_TOKEN_INVALID)
|
||||
{
|
||||
@@ -66,46 +52,9 @@ internal class Response
|
||||
return response;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回本体或带有消息提示的默认值
|
||||
/// </summary>
|
||||
/// <typeparam name="TData">类型</typeparam>
|
||||
/// <param name="response">本体</param>
|
||||
/// <param name="callerName">调用方法名称</param>
|
||||
/// <returns>本体或默认值,当本体为 null 时 返回默认值</returns>
|
||||
public static Response<TData> DefaultIfNull<TData>(Response<TData>? response, [CallerMemberName] string callerName = default!)
|
||||
public static Response<TData> CloneReturnCodeAndMessage<TData, TOther>(Response<TOther> response, [CallerMemberName] string callerName = default!)
|
||||
{
|
||||
// 0x26F19335 is a magic number that hashed from "Snap.Hutao"
|
||||
response ??= new(InternalFailure, SH.FormatWebResponseRequestExceptionFormat(callerName, typeof(TData).Name), default);
|
||||
|
||||
if (((KnownReturnCode)response.ReturnCode) is KnownReturnCode.PleaseLogin or KnownReturnCode.RET_TOKEN_INVALID)
|
||||
{
|
||||
response.Message = SH.FormatWebResponseRefreshCookieHintFormat(response.Message);
|
||||
}
|
||||
|
||||
return response ?? new(InternalFailure, SH.FormatWebResponseRequestExceptionFormat(callerName, typeof(TData).Name), default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回本体或带有消息提示的默认值
|
||||
/// </summary>
|
||||
/// <typeparam name="TData">类型</typeparam>
|
||||
/// <typeparam name="TOther">其他类型</typeparam>
|
||||
/// <param name="response">本体</param>
|
||||
/// <param name="callerName">调用方法名称</param>
|
||||
/// <returns>本体或默认值,当本体为 null 时 返回默认值</returns>
|
||||
public static Response<TData> DefaultIfNull<TData, TOther>(Response<TOther>? response, [CallerMemberName] string callerName = default!)
|
||||
{
|
||||
if (response is not null)
|
||||
{
|
||||
Must.Argument(response.ReturnCode != 0, "RetCode has to be 0");
|
||||
return new(response.ReturnCode, response.Message, default);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Magic number that hashed from "Snap.Hutao"
|
||||
return new(InternalFailure, SH.FormatWebResponseRequestExceptionFormat(callerName, typeof(TData).Name), default);
|
||||
}
|
||||
return new(response.ReturnCode, response.Message, default);
|
||||
}
|
||||
|
||||
public virtual bool IsOk(bool showInfoBar = true, IServiceProvider? serviceProvider = null)
|
||||
@@ -126,27 +75,15 @@ internal class Response
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return SH.FormatWebResponseFormat(ReturnCode, Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mihoyo 标准API响应
|
||||
/// </summary>
|
||||
/// <typeparam name="TData">数据类型</typeparam>
|
||||
[SuppressMessage("", "SA1402")]
|
||||
[HighQuality]
|
||||
internal class Response<TData> : Response, IJsResult
|
||||
internal class Response<TData> : Response, ICommonResponse<Response<TData>>, IJsBridgeResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造一个新的 Mihoyo 标准API响应
|
||||
/// </summary>
|
||||
/// <param name="returnCode">返回代码</param>
|
||||
/// <param name="message">消息</param>
|
||||
/// <param name="data">数据</param>
|
||||
[JsonConstructor]
|
||||
public Response(int returnCode, string message, TData? data)
|
||||
: base(returnCode, message)
|
||||
@@ -154,18 +91,14 @@ internal class Response<TData> : Response, IJsResult
|
||||
Data = data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据
|
||||
/// </summary>
|
||||
[JsonPropertyName("data")]
|
||||
public TData? Data { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 响应是否正常
|
||||
/// </summary>
|
||||
/// <param name="showInfoBar">是否显示错误信息</param>
|
||||
/// <param name="serviceProvider">服务提供器</param>
|
||||
/// <returns>是否Ok</returns>
|
||||
static Response<TData> ICommonResponse<Response<TData>>.CreateDefault(int returnCode, string message)
|
||||
{
|
||||
return new(returnCode, message, default);
|
||||
}
|
||||
|
||||
[MemberNotNullWhen(true, nameof(Data))]
|
||||
public override bool IsOk(bool showInfoBar = true, IServiceProvider? serviceProvider = null)
|
||||
{
|
||||
@@ -185,28 +118,4 @@ internal class Response<TData> : Response, IJsResult
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetData([NotNullWhen(true)] out TData? data, IInfoBarService? infoBarService = null, IServiceProvider? serviceProvider = null)
|
||||
{
|
||||
if (ReturnCode == 0)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(Data);
|
||||
data = Data;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
serviceProvider ??= Ioc.Default;
|
||||
infoBarService ??= serviceProvider.GetRequiredService<IInfoBarService>();
|
||||
infoBarService.Error(ToString());
|
||||
data = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string ToJson()
|
||||
{
|
||||
return JsonSerializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
27
src/Snap.Hutao/Snap.Hutao/Web/Response/ResponseExtension.cs
Normal file
27
src/Snap.Hutao/Snap.Hutao/Web/Response/ResponseExtension.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Service.Notification;
|
||||
|
||||
namespace Snap.Hutao.Web.Response;
|
||||
|
||||
internal static class ResponseExtension
|
||||
{
|
||||
public static bool TryGetData<TData>(this Response<TData> response, [NotNullWhen(true)] out TData? data, IInfoBarService? infoBarService = null, IServiceProvider? serviceProvider = null)
|
||||
{
|
||||
if (response.ReturnCode == 0)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(response.Data);
|
||||
data = response.Data;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
serviceProvider ??= Ioc.Default;
|
||||
infoBarService ??= serviceProvider.GetRequiredService<IInfoBarService>();
|
||||
infoBarService.Error(response.ToString());
|
||||
data = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user