mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
refactor done
This commit is contained in:
@@ -49,15 +49,14 @@ internal static partial class EnumerableExtension
|
|||||||
return list.GetRange(start, length);
|
return list.GetRange(start, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsNullOrEmpty<TSource>([NotNullWhen(false)] this List<TSource>? source)
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static bool IsNullOrEmpty<TSource>([NotNullWhen(false)][MaybeNullWhen(true)] this List<TSource>? source)
|
||||||
{
|
{
|
||||||
if (source is { } list)
|
if (source is { Count: > 0 })
|
||||||
{
|
{
|
||||||
// empty
|
return false;
|
||||||
return list.Count <= 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// null
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ internal sealed partial class LaunchGameViewModel : Abstraction.ViewModel
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 已知的服务器方案
|
/// 已知的服务器方案
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[SuppressMessage("", "CA1822")]
|
||||||
public List<LaunchScheme> KnownSchemes { get => LaunchScheme.GetKnownSchemes(); }
|
public List<LaunchScheme> KnownSchemes { get => LaunchScheme.GetKnownSchemes(); }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -417,7 +417,8 @@ internal class MiHoYoJSInterface
|
|||||||
private void OnNavigationStarting(CoreWebView2 coreWebView2, CoreWebView2NavigationStartingEventArgs args)
|
private void OnNavigationStarting(CoreWebView2 coreWebView2, CoreWebView2NavigationStartingEventArgs args)
|
||||||
{
|
{
|
||||||
string uriHost = new Uri(args.Uri).Host;
|
string uriHost = new Uri(args.Uri).Host;
|
||||||
if (uriHost.EndsWith("mihoyo.com") || uriHost.EndsWith("hoyolab.com"))
|
ReadOnlySpan<char> uriHostSpan = uriHost.AsSpan();
|
||||||
|
if (uriHostSpan.EndsWith("mihoyo.com") || uriHostSpan.EndsWith("hoyolab.com"))
|
||||||
{
|
{
|
||||||
// Execute this solve issue: When open same site second time,there might be no bridge init.
|
// Execute this solve issue: When open same site second time,there might be no bridge init.
|
||||||
coreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(InitializeJsInterfaceScript2).AsTask().SafeForget(logger);
|
coreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(InitializeJsInterfaceScript2).AsTask().SafeForget(logger);
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ internal sealed partial class EnkaClient
|
|||||||
/// <returns>Enka API 响应</returns>
|
/// <returns>Enka API 响应</returns>
|
||||||
public ValueTask<EnkaResponse?> GetForwardDataAsync(in PlayerUid playerUid, CancellationToken token = default)
|
public ValueTask<EnkaResponse?> GetForwardDataAsync(in PlayerUid playerUid, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
return TryGetEnkaResponseCoreAsync(string.Format(EnkaAPIHutaoForward, playerUid.Value), token);
|
return TryGetEnkaResponseCoreAsync(EnkaAPIHutaoForward.Format(playerUid.Value), token);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ internal sealed partial class Cookie
|
|||||||
public static Cookie Parse(string cookieString)
|
public static Cookie Parse(string cookieString)
|
||||||
{
|
{
|
||||||
SortedDictionary<string, string> cookieMap = new();
|
SortedDictionary<string, string> cookieMap = new();
|
||||||
cookieString = cookieString.Replace(" ", string.Empty);
|
cookieString = cookieString.Replace(" ", string.Empty, StringComparison.Ordinal);
|
||||||
string[] values = cookieString.Split(';', StringSplitOptions.RemoveEmptyEntries);
|
string[] values = cookieString.Split(';', StringSplitOptions.RemoveEmptyEntries);
|
||||||
foreach (string[] parts in values.Select(c => c.Split('=', 2)))
|
foreach (string[] parts in values.Select(c => c.Split('=', 2)))
|
||||||
{
|
{
|
||||||
@@ -76,7 +76,7 @@ internal sealed partial class Cookie
|
|||||||
/// <returns>Cookie</returns>
|
/// <returns>Cookie</returns>
|
||||||
public static Cookie FromLoginResult(LoginResult? loginResult)
|
public static Cookie FromLoginResult(LoginResult? loginResult)
|
||||||
{
|
{
|
||||||
if (loginResult == null)
|
if (loginResult is null)
|
||||||
{
|
{
|
||||||
return new();
|
return new();
|
||||||
}
|
}
|
||||||
@@ -115,15 +115,12 @@ internal sealed partial class Cookie
|
|||||||
|
|
||||||
public bool TryGetLToken([NotNullWhen(true)] out Cookie? cookie)
|
public bool TryGetLToken([NotNullWhen(true)] out Cookie? cookie)
|
||||||
{
|
{
|
||||||
bool hasLtoken = TryGetValue(LTOKEN, out string? ltoken);
|
if (TryGetValue(LTOKEN, out string? ltoken) && TryGetValue(LTUID, out string? ltuid))
|
||||||
bool hasStuid = TryGetValue(LTUID, out string? ltuid);
|
|
||||||
|
|
||||||
if (hasLtoken && hasStuid)
|
|
||||||
{
|
{
|
||||||
cookie = new Cookie(new()
|
cookie = new Cookie(new()
|
||||||
{
|
{
|
||||||
[LTOKEN] = ltoken!,
|
[LTOKEN] = ltoken,
|
||||||
[LTUID] = ltuid!,
|
[LTUID] = ltuid,
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -135,15 +132,12 @@ internal sealed partial class Cookie
|
|||||||
|
|
||||||
public bool TryGetCookieToken([NotNullWhen(true)] out Cookie? cookie)
|
public bool TryGetCookieToken([NotNullWhen(true)] out Cookie? cookie)
|
||||||
{
|
{
|
||||||
bool hasAccountId = TryGetValue(ACCOUNT_ID, out string? accountId);
|
if (TryGetValue(ACCOUNT_ID, out string? accountId) && TryGetValue(COOKIE_TOKEN, out string? cookieToken))
|
||||||
bool hasCookieToken = TryGetValue(COOKIE_TOKEN, out string? cookieToken);
|
|
||||||
|
|
||||||
if (hasAccountId && hasCookieToken)
|
|
||||||
{
|
{
|
||||||
cookie = new Cookie(new()
|
cookie = new Cookie(new()
|
||||||
{
|
{
|
||||||
[ACCOUNT_ID] = accountId!,
|
[ACCOUNT_ID] = accountId,
|
||||||
[COOKIE_TOKEN] = cookieToken!,
|
[COOKIE_TOKEN] = cookieToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -180,17 +174,13 @@ internal sealed partial class Cookie
|
|||||||
|
|
||||||
private bool TryGetSToken([NotNullWhen(true)] out Cookie? cookie)
|
private bool TryGetSToken([NotNullWhen(true)] out Cookie? cookie)
|
||||||
{
|
{
|
||||||
bool hasMid = TryGetValue(MID, out string? mid);
|
if (TryGetValue(MID, out string? mid) && TryGetValue(STOKEN, out string? stoken) && TryGetValue(STUID, out string? stuid))
|
||||||
bool hasSToken = TryGetValue(STOKEN, out string? stoken);
|
|
||||||
bool hasSTuid = TryGetValue(STUID, out string? stuid);
|
|
||||||
|
|
||||||
if (hasMid && hasSToken && hasSTuid)
|
|
||||||
{
|
{
|
||||||
cookie = new Cookie(new()
|
cookie = new Cookie(new()
|
||||||
{
|
{
|
||||||
[MID] = mid!,
|
[MID] = mid,
|
||||||
[STOKEN] = stoken!,
|
[STOKEN] = stoken,
|
||||||
[STUID] = stuid!,
|
[STUID] = stuid,
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -202,15 +192,12 @@ internal sealed partial class Cookie
|
|||||||
|
|
||||||
private bool TryGetLegacySToken([NotNullWhen(true)] out Cookie? cookie)
|
private bool TryGetLegacySToken([NotNullWhen(true)] out Cookie? cookie)
|
||||||
{
|
{
|
||||||
bool hasSToken = TryGetValue(STOKEN, out string? stoken);
|
if (TryGetValue(STOKEN, out string? stoken) && TryGetValue(STUID, out string? stuid))
|
||||||
bool hasSTuid = TryGetValue(STUID, out string? stuid);
|
|
||||||
|
|
||||||
if (hasSToken && hasSTuid)
|
|
||||||
{
|
{
|
||||||
cookie = new Cookie(new()
|
cookie = new Cookie(new()
|
||||||
{
|
{
|
||||||
[STOKEN] = stoken!,
|
[STOKEN] = stoken,
|
||||||
[STUID] = stuid!,
|
[STUID] = stuid,
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ internal sealed class DynamicSecretHandler : DelegatingHandler
|
|||||||
return await base.SendAsync(request, token).ConfigureAwait(false);
|
return await base.SendAsync(request, token).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task ProcessRequestWithOptionsAsync(HttpRequestMessage request, DynamicSecretCreationOptions options, CancellationToken token)
|
[SuppressMessage("", "CA1308")]
|
||||||
|
private static async ValueTask ProcessRequestWithOptionsAsync(HttpRequestMessage request, DynamicSecretCreationOptions options, CancellationToken token)
|
||||||
{
|
{
|
||||||
string salt = HoyolabOptions.Salts[options.SaltType];
|
string salt = HoyolabOptions.Salts[options.SaltType];
|
||||||
|
|
||||||
@@ -44,11 +45,12 @@ internal sealed class DynamicSecretHandler : DelegatingHandler
|
|||||||
// ds2 b & q process
|
// ds2 b & q process
|
||||||
if (options.Version == DynamicSecretVersion.Gen2)
|
if (options.Version == DynamicSecretVersion.Gen2)
|
||||||
{
|
{
|
||||||
string b = request.Content != null
|
string b = request.Content is not null
|
||||||
? await request.Content.ReadAsStringAsync(token).ConfigureAwait(false)
|
? await request.Content.ReadAsStringAsync(token).ConfigureAwait(false)
|
||||||
: options.DefaultBody; // PROD's default value is {}
|
: options.DefaultBody; // PROD's default value is {}
|
||||||
|
|
||||||
string[] queries = Uri.UnescapeDataString(request.RequestUri!.Query).Split('?', 2);
|
ArgumentNullException.ThrowIfNull(request.RequestUri);
|
||||||
|
string[] queries = Uri.UnescapeDataString(request.RequestUri.Query).Split('?', 2);
|
||||||
string q = queries.Length == 2 ? string.Join('&', queries[1].Split('&').OrderBy(x => x)) : string.Empty;
|
string q = queries.Length == 2 ? string.Join('&', queries[1].Split('&').OrderBy(x => x)) : string.Empty;
|
||||||
|
|
||||||
dsContent = $"{dsContent}&b={b}&q={q}";
|
dsContent = $"{dsContent}&b={b}&q={q}";
|
||||||
|
|||||||
@@ -9,6 +9,6 @@ namespace Snap.Hutao.Web.Hoyolab.DynamicSecret;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[HighQuality]
|
[HighQuality]
|
||||||
[AttributeUsage(AttributeTargets.Class)]
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
internal class UseDynamicSecretAttribute : Attribute
|
internal sealed class UseDynamicSecretAttribute : Attribute
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -32,20 +32,20 @@ internal sealed class Announcement : AnnouncementContent
|
|||||||
TimeSpan span = StartTime - now;
|
TimeSpan span = StartTime - now;
|
||||||
if (span.TotalDays <= 1)
|
if (span.TotalDays <= 1)
|
||||||
{
|
{
|
||||||
return string.Format(SH.WebAnnouncementTimeHoursBeginFormat, (int)span.TotalHours);
|
return SH.WebAnnouncementTimeHoursBeginFormat.Format((int)span.TotalHours);
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Format(SH.WebAnnouncementTimeDaysBeginFormat, (int)span.TotalDays);
|
return SH.WebAnnouncementTimeDaysBeginFormat.Format((int)span.TotalDays);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TimeSpan span = EndTime - now;
|
TimeSpan span = EndTime - now;
|
||||||
if (span.TotalDays <= 1)
|
if (span.TotalDays <= 1)
|
||||||
{
|
{
|
||||||
return string.Format(SH.WebAnnouncementTimeHoursEndFormat, (int)span.TotalHours);
|
return SH.WebAnnouncementTimeHoursEndFormat.Format((int)span.TotalHours);
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Format(SH.WebAnnouncementTimeDaysEndFormat, (int)span.TotalDays);
|
return SH.WebAnnouncementTimeDaysEndFormat.Format((int)span.TotalDays);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ internal sealed partial class AnnouncementClient
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cancellationToken">取消令牌</param>
|
/// <param name="cancellationToken">取消令牌</param>
|
||||||
/// <returns>公告列表</returns>
|
/// <returns>公告列表</returns>
|
||||||
public async Task<Response<AnnouncementWrapper>> GetAnnouncementsAsync(CancellationToken cancellationToken = default)
|
public async ValueTask<Response<AnnouncementWrapper>> GetAnnouncementsAsync(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
Response<AnnouncementWrapper>? resp = await httpClient
|
Response<AnnouncementWrapper>? resp = await httpClient
|
||||||
.TryCatchGetFromJsonAsync<Response<AnnouncementWrapper>>(ApiEndpoints.AnnList, jsonSerializerOptions, logger, cancellationToken)
|
.TryCatchGetFromJsonAsync<Response<AnnouncementWrapper>>(ApiEndpoints.AnnList, jsonSerializerOptions, logger, cancellationToken)
|
||||||
@@ -37,7 +37,7 @@ internal sealed partial class AnnouncementClient
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cancellationToken">取消令牌</param>
|
/// <param name="cancellationToken">取消令牌</param>
|
||||||
/// <returns>公告内容列表</returns>
|
/// <returns>公告内容列表</returns>
|
||||||
public async Task<Response<ListWrapper<AnnouncementContent>>> GetAnnouncementContentsAsync(CancellationToken cancellationToken = default)
|
public async ValueTask<Response<ListWrapper<AnnouncementContent>>> GetAnnouncementContentsAsync(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
Response<ListWrapper<AnnouncementContent>>? resp = await httpClient
|
Response<ListWrapper<AnnouncementContent>>? resp = await httpClient
|
||||||
.TryCatchGetFromJsonAsync<Response<ListWrapper<AnnouncementContent>>>(ApiEndpoints.AnnContent, jsonSerializerOptions, logger, cancellationToken)
|
.TryCatchGetFromJsonAsync<Response<ListWrapper<AnnouncementContent>>>(ApiEndpoints.AnnContent, jsonSerializerOptions, logger, cancellationToken)
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ internal sealed partial class GachaInfoClient
|
|||||||
/// <param name="options">查询</param>
|
/// <param name="options">查询</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>单个祈愿记录页面</returns>
|
/// <returns>单个祈愿记录页面</returns>
|
||||||
public async Task<Response<GachaLogPage>> GetGachaLogPageAsync(GachaLogQueryOptions options, CancellationToken token = default)
|
public async ValueTask<Response<GachaLogPage>> GetGachaLogPageAsync(GachaLogQueryOptions options, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
string query = options.ToQueryString();
|
string query = options.ToQueryString();
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ internal struct GachaLogQueryOptions
|
|||||||
/// 转换到查询字符串
|
/// 转换到查询字符串
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>匹配的查询字符串</returns>
|
/// <returns>匹配的查询字符串</returns>
|
||||||
public string ToQueryString()
|
public readonly string ToQueryString()
|
||||||
{
|
{
|
||||||
// Make the cached end id into query.
|
// Make the cached end id into query.
|
||||||
innerQuery.Set("end_id", EndId);
|
innerQuery.Set("end_id", EndId);
|
||||||
|
|||||||
@@ -27,17 +27,17 @@ internal static class HoyolabHttpClientExtension
|
|||||||
|
|
||||||
if (cookie.HasFlag(CookieType.CookieToken))
|
if (cookie.HasFlag(CookieType.CookieToken))
|
||||||
{
|
{
|
||||||
stringBuilder.Append(user.CookieToken).AppendIf(user.CookieToken != null, ';');
|
stringBuilder.Append(user.CookieToken).AppendIf(user.CookieToken is not null, ';');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cookie.HasFlag(CookieType.LToken))
|
if (cookie.HasFlag(CookieType.LToken))
|
||||||
{
|
{
|
||||||
stringBuilder.Append(user.LToken).AppendIf(user.LToken != null, ';');
|
stringBuilder.Append(user.LToken).AppendIf(user.LToken is not null, ';');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cookie.HasFlag(CookieType.SToken))
|
if (cookie.HasFlag(CookieType.SToken))
|
||||||
{
|
{
|
||||||
stringBuilder.Append(user.SToken).AppendIf(user.SToken != null, ';');
|
stringBuilder.Append(user.SToken).AppendIf(user.SToken is not null, ';');
|
||||||
}
|
}
|
||||||
|
|
||||||
string result = stringBuilder.ToString();
|
string result = stringBuilder.ToString();
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ internal interface IPassportClient
|
|||||||
/// <param name="user">用户</param>
|
/// <param name="user">用户</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>cookie token</returns>
|
/// <returns>cookie token</returns>
|
||||||
Task<Response<UidCookieToken>> GetCookieAccountInfoBySTokenAsync(User user, CancellationToken token = default);
|
ValueTask<Response<UidCookieToken>> GetCookieAccountInfoBySTokenAsync(User user, CancellationToken token = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异步获取 LToken
|
/// 异步获取 LToken
|
||||||
@@ -25,5 +25,5 @@ internal interface IPassportClient
|
|||||||
/// <param name="user">用户</param>
|
/// <param name="user">用户</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>uid 与 cookie token</returns>
|
/// <returns>uid 与 cookie token</returns>
|
||||||
Task<Response<LTokenWrapper>> GetLTokenBySTokenAsync(User user, CancellationToken token = default);
|
ValueTask<Response<LTokenWrapper>> GetLTokenBySTokenAsync(User user, CancellationToken token = default);
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ internal sealed partial class PassportClient : IPassportClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>cookie token</returns>
|
/// <returns>cookie token</returns>
|
||||||
[ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.PROD)]
|
[ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.PROD)]
|
||||||
public async Task<Response<UidCookieToken>> GetCookieAccountInfoBySTokenAsync(User user, CancellationToken token = default)
|
public async ValueTask<Response<UidCookieToken>> GetCookieAccountInfoBySTokenAsync(User user, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Response<UidCookieToken>? resp = await httpClient
|
Response<UidCookieToken>? resp = await httpClient
|
||||||
.SetUser(user, CookieType.SToken)
|
.SetUser(user, CookieType.SToken)
|
||||||
@@ -48,7 +48,7 @@ internal sealed partial class PassportClient : IPassportClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>uid 与 cookie token</returns>
|
/// <returns>uid 与 cookie token</returns>
|
||||||
[ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.PROD)]
|
[ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.PROD)]
|
||||||
public async Task<Response<LTokenWrapper>> GetLTokenBySTokenAsync(User user, CancellationToken token = default)
|
public async ValueTask<Response<LTokenWrapper>> GetLTokenBySTokenAsync(User user, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Response<LTokenWrapper>? resp = await httpClient
|
Response<LTokenWrapper>? resp = await httpClient
|
||||||
.SetUser(user, CookieType.SToken)
|
.SetUser(user, CookieType.SToken)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ internal sealed partial class PassportClient2
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>验证信息</returns>
|
/// <returns>验证信息</returns>
|
||||||
[ApiInformation(Cookie = CookieType.LToken)]
|
[ApiInformation(Cookie = CookieType.LToken)]
|
||||||
public async Task<Response<UserInfoWrapper>> VerifyLtokenAsync(User user, CancellationToken token)
|
public async ValueTask<Response<UserInfoWrapper>> VerifyLtokenAsync(User user, CancellationToken token)
|
||||||
{
|
{
|
||||||
Response<UserInfoWrapper>? response = await httpClient
|
Response<UserInfoWrapper>? response = await httpClient
|
||||||
.SetUser(user, CookieType.LToken)
|
.SetUser(user, CookieType.LToken)
|
||||||
@@ -48,7 +48,7 @@ internal sealed partial class PassportClient2
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>登录数据</returns>
|
/// <returns>登录数据</returns>
|
||||||
[ApiInformation(Salt = SaltType.PROD)]
|
[ApiInformation(Salt = SaltType.PROD)]
|
||||||
public async Task<Response<LoginResult>> LoginBySTokenAsync(Cookie stokenV1, CancellationToken token = default)
|
public async ValueTask<Response<LoginResult>> LoginBySTokenAsync(Cookie stokenV1, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
HttpResponseMessage message = await httpClient
|
HttpResponseMessage message = await httpClient
|
||||||
.SetHeader("Cookie", stokenV1.ToString())
|
.SetHeader("Cookie", stokenV1.ToString())
|
||||||
|
|||||||
@@ -27,9 +27,12 @@ internal sealed partial class PassportClientOversea : IPassportClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>cookie token</returns>
|
/// <returns>cookie token</returns>
|
||||||
[ApiInformation(Cookie = CookieType.SToken)]
|
[ApiInformation(Cookie = CookieType.SToken)]
|
||||||
public async Task<Response<UidCookieToken>> GetCookieAccountInfoBySTokenAsync(User user, CancellationToken token = default)
|
public async ValueTask<Response<UidCookieToken>> GetCookieAccountInfoBySTokenAsync(User user, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
STokenWrapper data = new(user.SToken?.GetValueOrDefault(Cookie.STOKEN)!, user.Aid!);
|
string? stoken = user.SToken?.GetValueOrDefault(Cookie.STOKEN);
|
||||||
|
ArgumentException.ThrowIfNullOrEmpty(stoken);
|
||||||
|
ArgumentException.ThrowIfNullOrEmpty(user.Aid);
|
||||||
|
STokenWrapper data = new(stoken, user.Aid);
|
||||||
|
|
||||||
Response<UidCookieToken>? resp = await httpClient
|
Response<UidCookieToken>? resp = await httpClient
|
||||||
.SetUser(user, CookieType.SToken)
|
.SetUser(user, CookieType.SToken)
|
||||||
@@ -46,9 +49,12 @@ internal sealed partial class PassportClientOversea : IPassportClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>uid 与 cookie token</returns>
|
/// <returns>uid 与 cookie token</returns>
|
||||||
[ApiInformation(Cookie = CookieType.SToken)]
|
[ApiInformation(Cookie = CookieType.SToken)]
|
||||||
public async Task<Response<LTokenWrapper>> GetLTokenBySTokenAsync(User user, CancellationToken token = default)
|
public async ValueTask<Response<LTokenWrapper>> GetLTokenBySTokenAsync(User user, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
STokenWrapper data = new(user.SToken?.GetValueOrDefault(Cookie.STOKEN)!, user.Aid!);
|
string? stoken = user.SToken?.GetValueOrDefault(Cookie.STOKEN);
|
||||||
|
ArgumentException.ThrowIfNullOrEmpty(stoken);
|
||||||
|
ArgumentException.ThrowIfNullOrEmpty(user.Aid);
|
||||||
|
STokenWrapper data = new(stoken, user.Aid);
|
||||||
|
|
||||||
Response<LTokenWrapper>? resp = await httpClient
|
Response<LTokenWrapper>? resp = await httpClient
|
||||||
.SetUser(user, CookieType.SToken)
|
.SetUser(user, CookieType.SToken)
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ internal sealed partial class ResourceClient
|
|||||||
/// <param name="scheme">方案</param>
|
/// <param name="scheme">方案</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>游戏资源</returns>
|
/// <returns>游戏资源</returns>
|
||||||
public async Task<Response<GameResource>> GetResourceAsync(LaunchScheme scheme, CancellationToken token = default)
|
public async ValueTask<Response<GameResource>> GetResourceAsync(LaunchScheme scheme, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
string url = scheme.IsOversea
|
string url = scheme.IsOversea
|
||||||
? ApiOsEndpoints.SdkOsStaticLauncherResource(scheme)
|
? ApiOsEndpoints.SdkOsStaticLauncherResource(scheme)
|
||||||
|
|||||||
@@ -31,9 +31,10 @@ internal sealed partial class AuthClient
|
|||||||
/// <param name="user">用户</param>
|
/// <param name="user">用户</param>
|
||||||
/// <returns>操作凭证</returns>
|
/// <returns>操作凭证</returns>
|
||||||
[ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.K2)]
|
[ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.K2)]
|
||||||
public async Task<Response<ActionTicketWrapper>> GetActionTicketBySTokenAsync(string action, User user)
|
public async ValueTask<Response<ActionTicketWrapper>> GetActionTicketBySTokenAsync(string action, User user)
|
||||||
{
|
{
|
||||||
string url = ApiEndpoints.AuthActionTicket(action, user.SToken?[Cookie.STOKEN] ?? string.Empty, user.Aid!);
|
ArgumentException.ThrowIfNullOrEmpty(user.Aid);
|
||||||
|
string url = ApiEndpoints.AuthActionTicket(action, user.SToken?[Cookie.STOKEN] ?? string.Empty, user.Aid);
|
||||||
|
|
||||||
Response<ActionTicketWrapper>? resp = await httpClient
|
Response<ActionTicketWrapper>? resp = await httpClient
|
||||||
.SetUser(user, CookieType.SToken)
|
.SetUser(user, CookieType.SToken)
|
||||||
@@ -51,7 +52,7 @@ internal sealed partial class AuthClient
|
|||||||
/// <param name="isOversea">是否为国际服</param>
|
/// <param name="isOversea">是否为国际服</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>包含token的字典</returns>
|
/// <returns>包含token的字典</returns>
|
||||||
public async Task<Response<ListWrapper<NameToken>>> GetMultiTokenByLoginTicketAsync(Cookie cookie, bool isOversea, CancellationToken token = default)
|
public async ValueTask<Response<ListWrapper<NameToken>>> GetMultiTokenByLoginTicketAsync(Cookie cookie, bool isOversea, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
string loginTicket = cookie[Cookie.LOGIN_TICKET];
|
string loginTicket = cookie[Cookie.LOGIN_TICKET];
|
||||||
string loginUid = cookie[Cookie.LOGIN_UID];
|
string loginUid = cookie[Cookie.LOGIN_UID];
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ internal sealed partial class BindingClient
|
|||||||
/// <param name="user">用户</param>
|
/// <param name="user">用户</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>用户角色信息</returns>
|
/// <returns>用户角色信息</returns>
|
||||||
public async Task<Response<ListWrapper<UserGameRole>>> GetUserGameRolesOverseaAwareAsync(User user, CancellationToken token = default)
|
public async ValueTask<Response<ListWrapper<UserGameRole>>> GetUserGameRolesOverseaAwareAsync(User user, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (user.IsOversea)
|
if (user.IsOversea)
|
||||||
{
|
{
|
||||||
@@ -63,7 +63,7 @@ internal sealed partial class BindingClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>用户角色信息</returns>
|
/// <returns>用户角色信息</returns>
|
||||||
[ApiInformation(Cookie = CookieType.LToken)]
|
[ApiInformation(Cookie = CookieType.LToken)]
|
||||||
public async Task<Response<ListWrapper<UserGameRole>>> GetUserGameRolesByActionTicketAsync(string actionTicket, User user, CancellationToken token = default)
|
public async ValueTask<Response<ListWrapper<UserGameRole>>> GetUserGameRolesByActionTicketAsync(string actionTicket, User user, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
string url = ApiEndpoints.UserGameRolesByActionTicket(actionTicket);
|
string url = ApiEndpoints.UserGameRolesByActionTicket(actionTicket);
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ internal sealed partial class BindingClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>用户角色信息</returns>
|
/// <returns>用户角色信息</returns>
|
||||||
[ApiInformation(Cookie = CookieType.LToken)]
|
[ApiInformation(Cookie = CookieType.LToken)]
|
||||||
public async Task<Response<ListWrapper<UserGameRole>>> GetOverseaUserGameRolesByCookieAsync(User user, CancellationToken token = default)
|
public async ValueTask<Response<ListWrapper<UserGameRole>>> GetOverseaUserGameRolesByCookieAsync(User user, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Response<ListWrapper<UserGameRole>>? resp = await httpClient
|
Response<ListWrapper<UserGameRole>>? resp = await httpClient
|
||||||
.SetUser(user, CookieType.LToken)
|
.SetUser(user, CookieType.LToken)
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ internal sealed partial class BindingClient2
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>用户角色信息</returns>
|
/// <returns>用户角色信息</returns>
|
||||||
[ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.LK2)]
|
[ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.LK2)]
|
||||||
public async Task<List<UserGameRole>> GetUserGameRolesBySTokenAsync(User user, CancellationToken token = default)
|
public async ValueTask<List<UserGameRole>> GetUserGameRolesBySTokenAsync(User user, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Response<ListWrapper<UserGameRole>>? resp = await httpClient
|
Response<ListWrapper<UserGameRole>>? resp = await httpClient
|
||||||
.SetUser(user, CookieType.SToken)
|
.SetUser(user, CookieType.SToken)
|
||||||
@@ -50,7 +50,7 @@ internal sealed partial class BindingClient2
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>用户角色信息</returns>
|
/// <returns>用户角色信息</returns>
|
||||||
[ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.LK2)]
|
[ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.LK2)]
|
||||||
public async Task<Response<GameAuthKey>> GenerateAuthenticationKeyAsync(User user, GenAuthKeyData data, CancellationToken token = default)
|
public async ValueTask<Response<GameAuthKey>> GenerateAuthenticationKeyAsync(User user, GenAuthKeyData data, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Response<GameAuthKey>? resp = await httpClient
|
Response<GameAuthKey>? resp = await httpClient
|
||||||
.SetUser(user, CookieType.SToken)
|
.SetUser(user, CookieType.SToken)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) DGP Studio. All rights reserved.
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
// Licensed under the MIT license.
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
namespace Snap.Hutao.Web.Hoyolab.Takumi.Binding;
|
namespace Snap.Hutao.Web.Hoyolab.Takumi.Binding;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -22,7 +24,7 @@ internal sealed class GenAuthKeyData
|
|||||||
{
|
{
|
||||||
AuthAppId = authAppId;
|
AuthAppId = authAppId;
|
||||||
GameBiz = gameBiz;
|
GameBiz = gameBiz;
|
||||||
GameUid = int.Parse(uid.Value);
|
GameUid = int.Parse(uid.Value, CultureInfo.InvariantCulture);
|
||||||
Region = uid.Region;
|
Region = uid.Region;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ internal sealed partial class CalculateClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>消耗结果</returns>
|
/// <returns>消耗结果</returns>
|
||||||
[ApiInformation(Cookie = CookieType.Cookie)]
|
[ApiInformation(Cookie = CookieType.Cookie)]
|
||||||
public async Task<Response<Consumption>> ComputeAsync(Model.Entity.User user, AvatarPromotionDelta delta, CancellationToken token = default)
|
public async ValueTask<Response<Consumption>> ComputeAsync(Model.Entity.User user, AvatarPromotionDelta delta, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
string referer = user.IsOversea
|
string referer = user.IsOversea
|
||||||
? ApiOsEndpoints.ActHoyolabReferer
|
? ApiOsEndpoints.ActHoyolabReferer
|
||||||
@@ -54,7 +54,7 @@ internal sealed partial class CalculateClient
|
|||||||
/// <param name="userAndUid">用户与角色</param>
|
/// <param name="userAndUid">用户与角色</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>角色列表</returns>
|
/// <returns>角色列表</returns>
|
||||||
public async Task<List<Avatar>> GetAvatarsAsync(UserAndUid userAndUid, CancellationToken token = default)
|
public async ValueTask<List<Avatar>> GetAvatarsAsync(UserAndUid userAndUid, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
int currentPage = 1;
|
int currentPage = 1;
|
||||||
SyncAvatarFilter filter = new() { Uid = userAndUid.Uid.Value, Region = userAndUid.Uid.Region };
|
SyncAvatarFilter filter = new() { Uid = userAndUid.Uid.Value, Region = userAndUid.Uid.Region };
|
||||||
@@ -81,7 +81,7 @@ internal sealed partial class CalculateClient
|
|||||||
.TryCatchPostAsJsonAsync<SyncAvatarFilter, Response<ListWrapper<Avatar>>>(url, filter, options, logger, token)
|
.TryCatchPostAsJsonAsync<SyncAvatarFilter, Response<ListWrapper<Avatar>>>(url, filter, options, logger, token)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
if (resp != null && resp.IsOk())
|
if (resp is not null && resp.IsOk())
|
||||||
{
|
{
|
||||||
avatars.AddRange(resp.Data.List);
|
avatars.AddRange(resp.Data.List);
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ internal sealed partial class CalculateClient
|
|||||||
|
|
||||||
await Task.Delay(Random.Shared.Next(0, 1000), token).ConfigureAwait(false);
|
await Task.Delay(Random.Shared.Next(0, 1000), token).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
while (resp?.Data?.List?.Count == 20);
|
while (resp.Data is { List.Count: 20 });
|
||||||
|
|
||||||
return avatars;
|
return avatars;
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ internal sealed partial class CalculateClient
|
|||||||
/// <param name="avatar">角色</param>
|
/// <param name="avatar">角色</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>角色详情</returns>
|
/// <returns>角色详情</returns>
|
||||||
public async Task<Response<AvatarDetail>> GetAvatarDetailAsync(UserAndUid userAndUid, Avatar avatar, CancellationToken token = default)
|
public async ValueTask<Response<AvatarDetail>> GetAvatarDetailAsync(UserAndUid userAndUid, Avatar avatar, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
string url = userAndUid.User.IsOversea
|
string url = userAndUid.User.IsOversea
|
||||||
? ApiOsEndpoints.CalculateSyncAvatarDetail(avatar.Id, userAndUid.Uid.Value)
|
? ApiOsEndpoints.CalculateSyncAvatarDetail(avatar.Id, userAndUid.Uid.Value)
|
||||||
@@ -126,7 +126,7 @@ internal sealed partial class CalculateClient
|
|||||||
/// <param name="shareCode">摹本码</param>
|
/// <param name="shareCode">摹本码</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>家具列表</returns>
|
/// <returns>家具列表</returns>
|
||||||
public async Task<Response<FurnitureListWrapper>> FurnitureBlueprintAsync(Model.Entity.User user, string shareCode, CancellationToken token)
|
public async ValueTask<Response<FurnitureListWrapper>> FurnitureBlueprintAsync(Model.Entity.User user, string shareCode, CancellationToken token)
|
||||||
{
|
{
|
||||||
Response<FurnitureListWrapper>? resp = await httpClient
|
Response<FurnitureListWrapper>? resp = await httpClient
|
||||||
.SetUser(user, CookieType.CookieToken)
|
.SetUser(user, CookieType.CookieToken)
|
||||||
@@ -143,7 +143,7 @@ internal sealed partial class CalculateClient
|
|||||||
/// <param name="items">物品</param>
|
/// <param name="items">物品</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>消耗</returns>
|
/// <returns>消耗</returns>
|
||||||
public async Task<Response<ListWrapper<Item>>> FurnitureComputeAsync(Model.Entity.User user, List<Item> items, CancellationToken token)
|
public async ValueTask<Response<ListWrapper<Item>>> FurnitureComputeAsync(Model.Entity.User user, List<Item> items, CancellationToken token)
|
||||||
{
|
{
|
||||||
ListWrapper<IdCount> data = new() { List = items.Select(i => new IdCount { Id = i.Id, Count = i.Num }).ToList() };
|
ListWrapper<IdCount> data = new() { List = items.Select(i => new IdCount { Id = i.Id, Count = i.Num }).ToList() };
|
||||||
|
|
||||||
|
|||||||
@@ -22,16 +22,19 @@ internal static class ItemHelper
|
|||||||
return new(0);
|
return new(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (right.IsNullOrEmpty())
|
if (left.IsNullOrEmpty() && !right.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
return left!;
|
return right;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (left.IsNullOrEmpty())
|
if (right.IsNullOrEmpty() && !left.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
return right!;
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArgumentNullException.ThrowIfNull(left);
|
||||||
|
ArgumentNullException.ThrowIfNull(right);
|
||||||
|
|
||||||
List<Item> result = new(left.Count + right.Count);
|
List<Item> result = new(left.Count + right.Count);
|
||||||
result.AddRange(left);
|
result.AddRange(left);
|
||||||
|
|
||||||
|
|||||||
@@ -15,33 +15,21 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[HighQuality]
|
[HighQuality]
|
||||||
[UseDynamicSecret]
|
[UseDynamicSecret]
|
||||||
|
[ConstructorGenerated(ResolveHttpClient = true)]
|
||||||
[HttpClient(HttpClientConfiguration.XRpc)]
|
[HttpClient(HttpClientConfiguration.XRpc)]
|
||||||
internal sealed class CardClient
|
internal sealed partial class CardClient
|
||||||
{
|
{
|
||||||
private readonly HttpClient httpClient;
|
private readonly HttpClient httpClient;
|
||||||
private readonly JsonSerializerOptions options;
|
private readonly JsonSerializerOptions options;
|
||||||
private readonly ILogger<CardClient> logger;
|
private readonly ILogger<CardClient> logger;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 构造一个新的卡片客户端
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="httpClient">http客户端</param>
|
|
||||||
/// <param name="options">选项</param>
|
|
||||||
/// <param name="logger">日志器</param>
|
|
||||||
public CardClient(HttpClient httpClient, JsonSerializerOptions options, ILogger<CardClient> logger)
|
|
||||||
{
|
|
||||||
this.httpClient = httpClient;
|
|
||||||
this.options = options;
|
|
||||||
this.logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 注册验证码
|
/// 注册验证码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="user">用户</param>
|
/// <param name="user">用户</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>注册结果</returns>
|
/// <returns>注册结果</returns>
|
||||||
public async Task<Response<VerificationRegistration>> CreateVerificationAsync(User user, CancellationToken token)
|
public async ValueTask<Response<VerificationRegistration>> CreateVerificationAsync(User user, CancellationToken token)
|
||||||
{
|
{
|
||||||
Response<VerificationRegistration>? resp = await httpClient
|
Response<VerificationRegistration>? resp = await httpClient
|
||||||
.SetUser(user, CookieType.LToken)
|
.SetUser(user, CookieType.LToken)
|
||||||
@@ -59,7 +47,7 @@ internal sealed class CardClient
|
|||||||
/// <param name="validate">验证</param>
|
/// <param name="validate">验证</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>验证结果</returns>
|
/// <returns>验证结果</returns>
|
||||||
public async Task<Response<VerificationResult>> VerifyVerificationAsync(string challenge, string validate, CancellationToken token)
|
public async ValueTask<Response<VerificationResult>> VerifyVerificationAsync(string challenge, string validate, CancellationToken token)
|
||||||
{
|
{
|
||||||
VerificationData data = new(challenge, validate);
|
VerificationData data = new(challenge, validate);
|
||||||
|
|
||||||
@@ -77,7 +65,7 @@ internal sealed class CardClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>桌面小组件数据</returns>
|
/// <returns>桌面小组件数据</returns>
|
||||||
[ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.X6)]
|
[ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.X6)]
|
||||||
public async Task<Response<DailyNote.WidgetDailyNote>> GetWidgetDataAsync(User user, CancellationToken token)
|
public async ValueTask<Response<DailyNote.WidgetDailyNote>> GetWidgetDataAsync(User user, CancellationToken token)
|
||||||
{
|
{
|
||||||
Response<DailyNote.WidgetDailyNote>? resp = await httpClient
|
Response<DailyNote.WidgetDailyNote>? resp = await httpClient
|
||||||
.SetUser(user, CookieType.SToken)
|
.SetUser(user, CookieType.SToken)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ internal sealed class CardVerifier
|
|||||||
/// <param name="user">用户</param>
|
/// <param name="user">用户</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>流水号</returns>
|
/// <returns>流水号</returns>
|
||||||
public async Task<string?> TryGetXrpcChallengeAsync(User user, CancellationToken token)
|
public async ValueTask<string?> TryGetXrpcChallengeAsync(User user, CancellationToken token)
|
||||||
{
|
{
|
||||||
Response.Response<VerificationRegistration> registrationResponse = await cardClient.CreateVerificationAsync(user, token).ConfigureAwait(false);
|
Response.Response<VerificationRegistration> registrationResponse = await cardClient.CreateVerificationAsync(user, token).ConfigureAwait(false);
|
||||||
if (registrationResponse.IsOk())
|
if (registrationResponse.IsOk())
|
||||||
@@ -43,14 +43,14 @@ internal sealed class CardVerifier
|
|||||||
await geetestClient.GetTypeAsync(registration.Gt).ConfigureAwait(false);
|
await geetestClient.GetTypeAsync(registration.Gt).ConfigureAwait(false);
|
||||||
GeetestResult<GeetestData>? ajax = await geetestClient.GetAjaxAsync(registration).ConfigureAwait(false);
|
GeetestResult<GeetestData>? ajax = await geetestClient.GetAjaxAsync(registration).ConfigureAwait(false);
|
||||||
|
|
||||||
if (ajax?.Data.Validate is string validate)
|
if (ajax?.Data.Validate is { } validate)
|
||||||
{
|
{
|
||||||
Response.Response<VerificationResult> verifyResponse = await cardClient.VerifyVerificationAsync(registration.Challenge, validate, token).ConfigureAwait(false);
|
Response.Response<VerificationResult> verifyResponse = await cardClient.VerifyVerificationAsync(registration.Challenge, validate, token).ConfigureAwait(false);
|
||||||
if (verifyResponse.IsOk())
|
if (verifyResponse.IsOk())
|
||||||
{
|
{
|
||||||
VerificationResult result = verifyResponse.Data;
|
VerificationResult result = verifyResponse.Data;
|
||||||
|
|
||||||
if (result.Challenge != null)
|
if (result.Challenge is not null)
|
||||||
{
|
{
|
||||||
return result.Challenge;
|
return result.Challenge;
|
||||||
}
|
}
|
||||||
@@ -58,6 +58,6 @@ internal sealed class CardVerifier
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,10 +38,10 @@ internal sealed class DailyNote : DailyNoteCommon
|
|||||||
0 => SH.WebDailyNoteRecoveryTimeDay0,
|
0 => SH.WebDailyNoteRecoveryTimeDay0,
|
||||||
1 => SH.WebDailyNoteRecoveryTimeDay1,
|
1 => SH.WebDailyNoteRecoveryTimeDay1,
|
||||||
2 => SH.WebDailyNoteRecoveryTimeDay2,
|
2 => SH.WebDailyNoteRecoveryTimeDay2,
|
||||||
_ => string.Format(SH.WebDailyNoteRecoveryTimeDayFormat, totalDays),
|
_ => SH.WebDailyNoteRecoveryTimeDayFormat.Format(totalDays),
|
||||||
};
|
};
|
||||||
|
|
||||||
return string.Format(SH.WebDailyNoteResinRecoveryFormat, day, reach);
|
return SH.WebDailyNoteResinRecoveryFormat.Format(day, reach);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,9 +129,9 @@ internal sealed class DailyNote : DailyNoteCommon
|
|||||||
0 => SH.WebDailyNoteRecoveryTimeDay0,
|
0 => SH.WebDailyNoteRecoveryTimeDay0,
|
||||||
1 => SH.WebDailyNoteRecoveryTimeDay1,
|
1 => SH.WebDailyNoteRecoveryTimeDay1,
|
||||||
2 => SH.WebDailyNoteRecoveryTimeDay2,
|
2 => SH.WebDailyNoteRecoveryTimeDay2,
|
||||||
_ => string.Format(SH.WebDailyNoteRecoveryTimeDayFormat, totalDays),
|
_ => SH.WebDailyNoteRecoveryTimeDayFormat.Format(totalDays),
|
||||||
};
|
};
|
||||||
return string.Format(SH.WebDailyNoteHomeCoinRecoveryFormat, day, reach);
|
return SH.WebDailyNoteHomeCoinRecoveryFormat.Format(day, reach);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,8 +84,8 @@ internal sealed class Expedition
|
|||||||
|
|
||||||
TimeSpan ts = new(0, 0, RemainedTime);
|
TimeSpan ts = new(0, 0, RemainedTime);
|
||||||
return ts.Hours > 0
|
return ts.Hours > 0
|
||||||
? string.Format(SH.WebDailyNoteExpeditionRemainHoursFormat, ts.Hours)
|
? SH.WebDailyNoteExpeditionRemainHoursFormat.Format(ts.Hours)
|
||||||
: string.Format(SH.WebDailyNoteExpeditionRemainMinutesFormat, ts.Minutes);
|
: SH.WebDailyNoteExpeditionRemainMinutesFormat.Format(ts.Minutes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,10 +67,10 @@ internal sealed class RecoveryTime
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new StringBuilder()
|
return new StringBuilder()
|
||||||
.AppendIf(Day > 0, string.Format(SH.WebDailyNoteTransformerDaysFormat, Day))
|
.AppendIf(Day > 0, SH.WebDailyNoteTransformerDaysFormat.Format(Day))
|
||||||
.AppendIf(Hour > 0, string.Format(SH.WebDailyNoteTransformerHoursFormat, Hour))
|
.AppendIf(Hour > 0, SH.WebDailyNoteTransformerHoursFormat.Format(Hour))
|
||||||
.AppendIf(Minute > 0, string.Format(SH.WebDailyNoteTransformerMinutesFormat, Minute))
|
.AppendIf(Minute > 0, SH.WebDailyNoteTransformerMinutesFormat.Format(Minute))
|
||||||
.AppendIf(Second > 0, string.Format(SH.WebDailyNoteTransformerSecondsFormat, Second))
|
.AppendIf(Second > 0, SH.WebDailyNoteTransformerSecondsFormat.Format(Second))
|
||||||
.Append(SH.WebDailyNoteTransformerAppend)
|
.Append(SH.WebDailyNoteTransformerAppend)
|
||||||
.ToString();
|
.ToString();
|
||||||
}
|
}
|
||||||
@@ -92,10 +92,10 @@ internal sealed class RecoveryTime
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new StringBuilder()
|
return new StringBuilder()
|
||||||
.AppendIf(Day > 0, string.Format(SH.WebDailyNoteTransformerDaysFormat, Day))
|
.AppendIf(Day > 0, SH.WebDailyNoteTransformerDaysFormat.Format(Day))
|
||||||
.AppendIf(Hour > 0, string.Format(SH.WebDailyNoteTransformerHoursFormat, Hour))
|
.AppendIf(Hour > 0, SH.WebDailyNoteTransformerHoursFormat.Format(Hour))
|
||||||
.AppendIf(Minute > 0, string.Format(SH.WebDailyNoteTransformerMinutesFormat, Minute))
|
.AppendIf(Minute > 0, SH.WebDailyNoteTransformerMinutesFormat.Format(Minute))
|
||||||
.AppendIf(Second > 0, string.Format(SH.WebDailyNoteTransformerSecondsFormat, Second))
|
.AppendIf(Second > 0, SH.WebDailyNoteTransformerSecondsFormat.Format(Second))
|
||||||
.ToString();
|
.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>实时便笺</returns>
|
/// <returns>实时便笺</returns>
|
||||||
[ApiInformation(Cookie = CookieType.Cookie, Salt = SaltType.X4)]
|
[ApiInformation(Cookie = CookieType.Cookie, Salt = SaltType.X4)]
|
||||||
public async Task<Response<DailyNote.DailyNote>> GetDailyNoteAsync(UserAndUid userAndUid, CancellationToken token = default)
|
public async ValueTask<Response<DailyNote.DailyNote>> GetDailyNoteAsync(UserAndUid userAndUid, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Response<DailyNote.DailyNote>? resp = await httpClient
|
Response<DailyNote.DailyNote>? resp = await httpClient
|
||||||
.SetUser(userAndUid.User, CookieType.Cookie)
|
.SetUser(userAndUid.User, CookieType.Cookie)
|
||||||
@@ -48,7 +48,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
|||||||
resp.Message = SH.WebDailyNoteVerificationFailed;
|
resp.Message = SH.WebDailyNoteVerificationFailed;
|
||||||
CardVerifier cardVerifier = serviceProvider.GetRequiredService<CardVerifier>();
|
CardVerifier cardVerifier = serviceProvider.GetRequiredService<CardVerifier>();
|
||||||
|
|
||||||
if (await cardVerifier.TryGetXrpcChallengeAsync(userAndUid.User, token).ConfigureAwait(false) is string challenge)
|
if (await cardVerifier.TryGetXrpcChallengeAsync(userAndUid.User, token).ConfigureAwait(false) is { } challenge)
|
||||||
{
|
{
|
||||||
resp = await httpClient
|
resp = await httpClient
|
||||||
.SetUser(userAndUid.User, CookieType.Cookie)
|
.SetUser(userAndUid.User, CookieType.Cookie)
|
||||||
@@ -69,7 +69,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>玩家的基础信息</returns>
|
/// <returns>玩家的基础信息</returns>
|
||||||
[ApiInformation(Cookie = CookieType.LToken, Salt = SaltType.X4)]
|
[ApiInformation(Cookie = CookieType.LToken, Salt = SaltType.X4)]
|
||||||
public async Task<Response<PlayerInfo>> GetPlayerInfoAsync(UserAndUid userAndUid, CancellationToken token = default)
|
public async ValueTask<Response<PlayerInfo>> GetPlayerInfoAsync(UserAndUid userAndUid, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Response<PlayerInfo>? resp = await httpClient
|
Response<PlayerInfo>? resp = await httpClient
|
||||||
.SetUser(userAndUid.User, CookieType.LToken)
|
.SetUser(userAndUid.User, CookieType.LToken)
|
||||||
@@ -88,7 +88,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>深渊信息</returns>
|
/// <returns>深渊信息</returns>
|
||||||
[ApiInformation(Cookie = CookieType.Cookie, Salt = SaltType.X4)]
|
[ApiInformation(Cookie = CookieType.Cookie, Salt = SaltType.X4)]
|
||||||
public async Task<Response<SpiralAbyss.SpiralAbyss>> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default)
|
public async ValueTask<Response<SpiralAbyss.SpiralAbyss>> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Response<SpiralAbyss.SpiralAbyss>? resp = await httpClient
|
Response<SpiralAbyss.SpiralAbyss>? resp = await httpClient
|
||||||
.SetUser(userAndUid.User, CookieType.Cookie)
|
.SetUser(userAndUid.User, CookieType.Cookie)
|
||||||
@@ -106,7 +106,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>角色基本信息</returns>
|
/// <returns>角色基本信息</returns>
|
||||||
[ApiInformation(Cookie = CookieType.LToken, Salt = SaltType.X4)]
|
[ApiInformation(Cookie = CookieType.LToken, Salt = SaltType.X4)]
|
||||||
public async Task<Response<BasicRoleInfo>> GetRoleBasicInfoAsync(UserAndUid userAndUid, CancellationToken token = default)
|
public async ValueTask<Response<BasicRoleInfo>> GetRoleBasicInfoAsync(UserAndUid userAndUid, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Response<BasicRoleInfo>? resp = await httpClient
|
Response<BasicRoleInfo>? resp = await httpClient
|
||||||
.SetUser(userAndUid.User, CookieType.LToken)
|
.SetUser(userAndUid.User, CookieType.LToken)
|
||||||
@@ -125,7 +125,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>角色列表</returns>
|
/// <returns>角色列表</returns>
|
||||||
[ApiInformation(Cookie = CookieType.LToken, Salt = SaltType.X4)]
|
[ApiInformation(Cookie = CookieType.LToken, Salt = SaltType.X4)]
|
||||||
public async Task<Response<CharacterWrapper>> GetCharactersAsync(UserAndUid userAndUid, PlayerInfo playerInfo, CancellationToken token = default)
|
public async ValueTask<Response<CharacterWrapper>> GetCharactersAsync(UserAndUid userAndUid, PlayerInfo playerInfo, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
CharacterData data = new(userAndUid.Uid, playerInfo.Avatars.Select(x => x.Id));
|
CharacterData data = new(userAndUid.Uid, playerInfo.Avatars.Select(x => x.Id));
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ internal sealed partial class GameRecordClientOversea : IGameRecordClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>实时便笺</returns>
|
/// <returns>实时便笺</returns>
|
||||||
[ApiInformation(Cookie = CookieType.Cookie, Salt = SaltType.OSX4)]
|
[ApiInformation(Cookie = CookieType.Cookie, Salt = SaltType.OSX4)]
|
||||||
public async Task<Response<DailyNote.DailyNote>> GetDailyNoteAsync(UserAndUid userAndUid, CancellationToken token = default)
|
public async ValueTask<Response<DailyNote.DailyNote>> GetDailyNoteAsync(UserAndUid userAndUid, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Response<DailyNote.DailyNote>? resp = await httpClient
|
Response<DailyNote.DailyNote>? resp = await httpClient
|
||||||
.SetUser(userAndUid.User, CookieType.Cookie)
|
.SetUser(userAndUid.User, CookieType.Cookie)
|
||||||
@@ -49,7 +49,7 @@ internal sealed partial class GameRecordClientOversea : IGameRecordClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>玩家的基础信息</returns>
|
/// <returns>玩家的基础信息</returns>
|
||||||
[ApiInformation(Cookie = CookieType.LToken, Salt = SaltType.OSX4)]
|
[ApiInformation(Cookie = CookieType.LToken, Salt = SaltType.OSX4)]
|
||||||
public async Task<Response<PlayerInfo>> GetPlayerInfoAsync(UserAndUid userAndUid, CancellationToken token = default)
|
public async ValueTask<Response<PlayerInfo>> GetPlayerInfoAsync(UserAndUid userAndUid, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Response<PlayerInfo>? resp = await httpClient
|
Response<PlayerInfo>? resp = await httpClient
|
||||||
.SetUser(userAndUid.User, CookieType.Cookie)
|
.SetUser(userAndUid.User, CookieType.Cookie)
|
||||||
@@ -68,7 +68,7 @@ internal sealed partial class GameRecordClientOversea : IGameRecordClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>深渊信息</returns>
|
/// <returns>深渊信息</returns>
|
||||||
[ApiInformation(Cookie = CookieType.Cookie, Salt = SaltType.OSX4)]
|
[ApiInformation(Cookie = CookieType.Cookie, Salt = SaltType.OSX4)]
|
||||||
public async Task<Response<SpiralAbyss.SpiralAbyss>> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default)
|
public async ValueTask<Response<SpiralAbyss.SpiralAbyss>> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Response<SpiralAbyss.SpiralAbyss>? resp = await httpClient
|
Response<SpiralAbyss.SpiralAbyss>? resp = await httpClient
|
||||||
.SetUser(userAndUid.User, CookieType.Cookie)
|
.SetUser(userAndUid.User, CookieType.Cookie)
|
||||||
@@ -87,7 +87,7 @@ internal sealed partial class GameRecordClientOversea : IGameRecordClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>角色列表</returns>
|
/// <returns>角色列表</returns>
|
||||||
[ApiInformation(Cookie = CookieType.LToken, Salt = SaltType.OSX4)]
|
[ApiInformation(Cookie = CookieType.LToken, Salt = SaltType.OSX4)]
|
||||||
public async Task<Response<CharacterWrapper>> GetCharactersAsync(UserAndUid userAndUid, PlayerInfo playerInfo, CancellationToken token = default)
|
public async ValueTask<Response<CharacterWrapper>> GetCharactersAsync(UserAndUid userAndUid, PlayerInfo playerInfo, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
CharacterData data = new(userAndUid.Uid, playerInfo.Avatars.Select(x => x.Id));
|
CharacterData data = new(userAndUid.Uid, playerInfo.Avatars.Select(x => x.Id));
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ internal interface IGameRecordClient
|
|||||||
/// <param name="playerInfo">玩家的基础信息</param>
|
/// <param name="playerInfo">玩家的基础信息</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>角色列表</returns>
|
/// <returns>角色列表</returns>
|
||||||
Task<Response<CharacterWrapper>> GetCharactersAsync(UserAndUid userAndUid, PlayerInfo playerInfo, CancellationToken token = default);
|
ValueTask<Response<CharacterWrapper>> GetCharactersAsync(UserAndUid userAndUid, PlayerInfo playerInfo, CancellationToken token = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异步获取实时便笺
|
/// 异步获取实时便笺
|
||||||
@@ -28,7 +28,7 @@ internal interface IGameRecordClient
|
|||||||
/// <param name="userAndUid">用户与角色</param>
|
/// <param name="userAndUid">用户与角色</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>实时便笺</returns>
|
/// <returns>实时便笺</returns>
|
||||||
Task<Response<DailyNote.DailyNote>> GetDailyNoteAsync(UserAndUid userAndUid, CancellationToken token = default);
|
ValueTask<Response<DailyNote.DailyNote>> GetDailyNoteAsync(UserAndUid userAndUid, CancellationToken token = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取玩家基础信息
|
/// 获取玩家基础信息
|
||||||
@@ -36,7 +36,7 @@ internal interface IGameRecordClient
|
|||||||
/// <param name="userAndUid">用户与角色</param>
|
/// <param name="userAndUid">用户与角色</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>玩家的基础信息</returns>
|
/// <returns>玩家的基础信息</returns>
|
||||||
Task<Response<PlayerInfo>> GetPlayerInfoAsync(UserAndUid userAndUid, CancellationToken token = default);
|
ValueTask<Response<PlayerInfo>> GetPlayerInfoAsync(UserAndUid userAndUid, CancellationToken token = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取玩家深渊信息
|
/// 获取玩家深渊信息
|
||||||
@@ -45,5 +45,5 @@ internal interface IGameRecordClient
|
|||||||
/// <param name="schedule">1:当期,2:上期</param>
|
/// <param name="schedule">1:当期,2:上期</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>深渊信息</returns>
|
/// <returns>深渊信息</returns>
|
||||||
Task<Response<SpiralAbyss.SpiralAbyss>> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default);
|
ValueTask<Response<SpiralAbyss.SpiralAbyss>> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default);
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,7 @@ internal static class HttpClientExtension
|
|||||||
private const string RequestErrorMessage = "请求异常已忽略";
|
private const string RequestErrorMessage = "请求异常已忽略";
|
||||||
|
|
||||||
/// <inheritdoc cref="HttpClientJsonExtensions.GetFromJsonAsync{TValue}(HttpClient, string?, JsonSerializerOptions?, CancellationToken)"/>
|
/// <inheritdoc cref="HttpClientJsonExtensions.GetFromJsonAsync{TValue}(HttpClient, string?, JsonSerializerOptions?, CancellationToken)"/>
|
||||||
internal static async Task<T?> TryCatchGetFromJsonAsync<T>(this HttpClient httpClient, string requestUri, JsonSerializerOptions options, ILogger logger, CancellationToken token = default)
|
internal static async ValueTask<T?> TryCatchGetFromJsonAsync<T>(this HttpClient httpClient, string requestUri, JsonSerializerOptions options, ILogger logger, CancellationToken token = default)
|
||||||
where T : class
|
where T : class
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -47,7 +47,7 @@ internal static class HttpClientExtension
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="HttpClientJsonExtensions.PostAsJsonAsync{TValue}(HttpClient, string?, TValue, JsonSerializerOptions?, CancellationToken)"/>
|
/// <inheritdoc cref="HttpClientJsonExtensions.PostAsJsonAsync{TValue}(HttpClient, string?, TValue, JsonSerializerOptions?, CancellationToken)"/>
|
||||||
internal static async Task<TResult?> TryCatchPostAsJsonAsync<TValue, TResult>(this HttpClient httpClient, string requestUri, TValue value, JsonSerializerOptions options, ILogger logger, CancellationToken token = default)
|
internal static async ValueTask<TResult?> TryCatchPostAsJsonAsync<TValue, TResult>(this HttpClient httpClient, string requestUri, TValue value, JsonSerializerOptions options, ILogger logger, CancellationToken token = default)
|
||||||
where TResult : class
|
where TResult : class
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -78,7 +78,7 @@ internal static class HttpClientExtension
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="HttpClientJsonExtensions.PostAsJsonAsync{TValue}(HttpClient, string?, TValue, JsonSerializerOptions?, CancellationToken)"/>
|
/// <inheritdoc cref="HttpClientJsonExtensions.PostAsJsonAsync{TValue}(HttpClient, string?, TValue, JsonSerializerOptions?, CancellationToken)"/>
|
||||||
internal static async Task<TResult?> TryCatchPostAsJsonAsync<TValue, TResult>(this HttpClient httpClient, string requestUri, TValue value, CancellationToken token = default)
|
internal static async ValueTask<TResult?> TryCatchPostAsJsonAsync<TValue, TResult>(this HttpClient httpClient, string requestUri, TValue value, CancellationToken token = default)
|
||||||
where TResult : class
|
where TResult : class
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ internal sealed class HomaGachaLogClient
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>祈愿统计信息</returns>
|
/// <returns>祈愿统计信息</returns>
|
||||||
public async Task<Response<GachaEventStatistics>> GetGachaEventStatisticsAsync(CancellationToken token = default)
|
public async ValueTask<Response<GachaEventStatistics>> GetGachaEventStatisticsAsync(CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Response<GachaEventStatistics>? resp = await httpClient
|
Response<GachaEventStatistics>? resp = await httpClient
|
||||||
.TryCatchGetFromJsonAsync<Response<GachaEventStatistics>>(HutaoEndpoints.GachaLogStatisticsCurrentEvents, options, logger, token)
|
.TryCatchGetFromJsonAsync<Response<GachaEventStatistics>>(HutaoEndpoints.GachaLogStatisticsCurrentEvents, options, logger, token)
|
||||||
@@ -70,7 +70,7 @@ internal sealed class HomaGachaLogClient
|
|||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>Uid 列表</returns>
|
/// <returns>Uid 列表</returns>
|
||||||
[Obsolete("Use GetGachaEntriesAsync instead")]
|
[Obsolete("Use GetGachaEntriesAsync instead")]
|
||||||
public async Task<Response<List<string>>> GetUidsAsync(CancellationToken token = default)
|
public async ValueTask<Response<List<string>>> GetUidsAsync(CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Response<List<string>>? resp = await httpClient
|
Response<List<string>>? resp = await httpClient
|
||||||
.TryCatchGetFromJsonAsync<Response<List<string>>>(HutaoEndpoints.GachaLogUids, options, logger, token)
|
.TryCatchGetFromJsonAsync<Response<List<string>>>(HutaoEndpoints.GachaLogUids, options, logger, token)
|
||||||
@@ -99,7 +99,7 @@ internal sealed class HomaGachaLogClient
|
|||||||
/// <param name="uid">uid</param>
|
/// <param name="uid">uid</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>末尾Id</returns>
|
/// <returns>末尾Id</returns>
|
||||||
public async Task<Response<EndIds>> GetEndIdsAsync(string uid, CancellationToken token = default)
|
public async ValueTask<Response<EndIds>> GetEndIdsAsync(string uid, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Response<EndIds>? resp = await httpClient
|
Response<EndIds>? resp = await httpClient
|
||||||
.TryCatchGetFromJsonAsync<Response<EndIds>>(HutaoEndpoints.GachaLogEndIds(uid), options, logger, token)
|
.TryCatchGetFromJsonAsync<Response<EndIds>>(HutaoEndpoints.GachaLogEndIds(uid), options, logger, token)
|
||||||
@@ -115,7 +115,7 @@ internal sealed class HomaGachaLogClient
|
|||||||
/// <param name="endIds">末尾 Id</param>
|
/// <param name="endIds">末尾 Id</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>云端祈愿记录</returns>
|
/// <returns>云端祈愿记录</returns>
|
||||||
public async Task<Response<List<GachaItem>>> RetrieveGachaItemsAsync(string uid, EndIds endIds, CancellationToken token = default)
|
public async ValueTask<Response<List<GachaItem>>> RetrieveGachaItemsAsync(string uid, EndIds endIds, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
UidAndEndIds uidAndEndIds = new(uid, endIds);
|
UidAndEndIds uidAndEndIds = new(uid, endIds);
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ internal sealed class HomaGachaLogClient
|
|||||||
/// <param name="gachaItems">祈愿记录</param>
|
/// <param name="gachaItems">祈愿记录</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>响应</returns>
|
/// <returns>响应</returns>
|
||||||
public async Task<Response.Response> UploadGachaItemsAsync(string uid, List<GachaItem> gachaItems, CancellationToken token = default)
|
public async ValueTask<Response.Response> UploadGachaItemsAsync(string uid, List<GachaItem> gachaItems, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
UidAndItems uidAndItems = new(uid, gachaItems);
|
UidAndItems uidAndItems = new(uid, gachaItems);
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ internal sealed class HomaGachaLogClient
|
|||||||
/// <param name="uid">uid</param>
|
/// <param name="uid">uid</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>响应</returns>
|
/// <returns>响应</returns>
|
||||||
public async Task<Response.Response> DeleteGachaItemsAsync(string uid, CancellationToken token = default)
|
public async ValueTask<Response.Response> DeleteGachaItemsAsync(string uid, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Response.Response? resp = await httpClient
|
Response.Response? resp = await httpClient
|
||||||
.TryCatchGetFromJsonAsync<Response<List<GachaItem>>>(HutaoEndpoints.GachaLogDelete(uid), options, logger, token)
|
.TryCatchGetFromJsonAsync<Response<List<GachaItem>>>(HutaoEndpoints.GachaLogDelete(uid), options, logger, token)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ internal sealed class HomaLogUploadClient
|
|||||||
/// <param name="serviceProvider">服务提供器</param>
|
/// <param name="serviceProvider">服务提供器</param>
|
||||||
/// <param name="exception">异常</param>
|
/// <param name="exception">异常</param>
|
||||||
/// <returns>任务</returns>
|
/// <returns>任务</returns>
|
||||||
public async Task<string?> UploadLogAsync(IServiceProvider serviceProvider, Exception exception)
|
public async ValueTask<string?> UploadLogAsync(IServiceProvider serviceProvider, Exception exception)
|
||||||
{
|
{
|
||||||
HutaoLog log = BuildFromException(serviceProvider, exception);
|
HutaoLog log = BuildFromException(serviceProvider, exception);
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ internal sealed partial class HomaPassportClient
|
|||||||
/// <param name="isResetPassword">是否重置账号密码</param>
|
/// <param name="isResetPassword">是否重置账号密码</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>响应</returns>
|
/// <returns>响应</returns>
|
||||||
public async Task<Response.Response> VerifyAsync(string email, bool isResetPassword, CancellationToken token = default)
|
public async ValueTask<Response.Response> VerifyAsync(string email, bool isResetPassword, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Dictionary<string, object> data = new()
|
Dictionary<string, object> data = new()
|
||||||
{
|
{
|
||||||
@@ -67,7 +67,7 @@ internal sealed partial class HomaPassportClient
|
|||||||
/// <param name="verifyCode">验证码</param>
|
/// <param name="verifyCode">验证码</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>响应,包含登录令牌</returns>
|
/// <returns>响应,包含登录令牌</returns>
|
||||||
public async Task<Response<string>> RegisterAsync(string email, string password, string verifyCode, CancellationToken token = default)
|
public async ValueTask<Response<string>> RegisterAsync(string email, string password, string verifyCode, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Dictionary<string, string> data = new()
|
Dictionary<string, string> data = new()
|
||||||
{
|
{
|
||||||
@@ -91,7 +91,7 @@ internal sealed partial class HomaPassportClient
|
|||||||
/// <param name="verifyCode">验证码</param>
|
/// <param name="verifyCode">验证码</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>响应,包含登录令牌</returns>
|
/// <returns>响应,包含登录令牌</returns>
|
||||||
public async Task<Response<string>> ResetPasswordAsync(string email, string password, string verifyCode, CancellationToken token = default)
|
public async ValueTask<Response<string>> ResetPasswordAsync(string email, string password, string verifyCode, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Dictionary<string, string> data = new()
|
Dictionary<string, string> data = new()
|
||||||
{
|
{
|
||||||
@@ -114,7 +114,7 @@ internal sealed partial class HomaPassportClient
|
|||||||
/// <param name="password">密码</param>
|
/// <param name="password">密码</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>响应,包含登录令牌</returns>
|
/// <returns>响应,包含登录令牌</returns>
|
||||||
public async Task<Response<string>> LoginAsync(string email, string password, CancellationToken token = default)
|
public async ValueTask<Response<string>> LoginAsync(string email, string password, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
Dictionary<string, string> data = new()
|
Dictionary<string, string> data = new()
|
||||||
{
|
{
|
||||||
@@ -135,7 +135,7 @@ internal sealed partial class HomaPassportClient
|
|||||||
/// <param name="authToken">验证令牌</param>
|
/// <param name="authToken">验证令牌</param>
|
||||||
/// <param name="token">取消令牌</param>
|
/// <param name="token">取消令牌</param>
|
||||||
/// <returns>用户信息</returns>
|
/// <returns>用户信息</returns>
|
||||||
public async Task<Response<UserInfo>> GetUserInfoAsync(string authToken, CancellationToken token = default)
|
public async ValueTask<Response<UserInfo>> GetUserInfoAsync(string authToken, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
httpClient.DefaultRequestHeaders.Authorization = new("Bearer", authToken);
|
httpClient.DefaultRequestHeaders.Authorization = new("Bearer", authToken);
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ internal readonly struct QueryString
|
|||||||
return new QueryString();
|
return new QueryString();
|
||||||
}
|
}
|
||||||
|
|
||||||
int questionMarkIndex = queryString.IndexOf('?');
|
int questionMarkIndex = queryString.AsSpan().IndexOf('?');
|
||||||
queryString = queryString[(questionMarkIndex + 1)..];
|
queryString = queryString[(questionMarkIndex + 1)..];
|
||||||
|
|
||||||
string[] pairs = queryString.Split('&', ';');
|
string[] pairs = queryString.Split('&', ';');
|
||||||
|
|||||||
Reference in New Issue
Block a user