diff --git a/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtension.List.cs b/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtension.List.cs index 9dd786b3..41535305 100644 --- a/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtension.List.cs +++ b/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtension.List.cs @@ -49,15 +49,14 @@ internal static partial class EnumerableExtension return list.GetRange(start, length); } - public static bool IsNullOrEmpty([NotNullWhen(false)] this List? source) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsNullOrEmpty([NotNullWhen(false)][MaybeNullWhen(true)] this List? source) { - if (source is { } list) + if (source is { Count: > 0 }) { - // empty - return list.Count <= 0; + return false; } - // null return true; } diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameViewModel.cs index 1c8c3792..6e6fb91d 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameViewModel.cs @@ -54,6 +54,7 @@ internal sealed partial class LaunchGameViewModel : Abstraction.ViewModel /// /// 已知的服务器方案 /// + [SuppressMessage("", "CA1822")] public List KnownSchemes { get => LaunchScheme.GetKnownSchemes(); } /// diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Bridge/MiHoYoJSInterface.cs b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/MiHoYoJSInterface.cs index 78c6e9c7..713abe6c 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Bridge/MiHoYoJSInterface.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/MiHoYoJSInterface.cs @@ -417,7 +417,8 @@ internal class MiHoYoJSInterface private void OnNavigationStarting(CoreWebView2 coreWebView2, CoreWebView2NavigationStartingEventArgs args) { string uriHost = new Uri(args.Uri).Host; - if (uriHost.EndsWith("mihoyo.com") || uriHost.EndsWith("hoyolab.com")) + ReadOnlySpan 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. coreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(InitializeJsInterfaceScript2).AsTask().SafeForget(logger); diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Enka/EnkaClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Enka/EnkaClient.cs index b442b5f0..94403541 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Enka/EnkaClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Enka/EnkaClient.cs @@ -34,7 +34,7 @@ internal sealed partial class EnkaClient /// Enka API 响应 public ValueTask GetForwardDataAsync(in PlayerUid playerUid, CancellationToken token = default) { - return TryGetEnkaResponseCoreAsync(string.Format(EnkaAPIHutaoForward, playerUid.Value), token); + return TryGetEnkaResponseCoreAsync(EnkaAPIHutaoForward.Format(playerUid.Value), token); } /// diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Cookie.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Cookie.cs index a32f487f..ebf0ca92 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Cookie.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Cookie.cs @@ -45,7 +45,7 @@ internal sealed partial class Cookie public static Cookie Parse(string cookieString) { SortedDictionary cookieMap = new(); - cookieString = cookieString.Replace(" ", string.Empty); + cookieString = cookieString.Replace(" ", string.Empty, StringComparison.Ordinal); string[] values = cookieString.Split(';', StringSplitOptions.RemoveEmptyEntries); foreach (string[] parts in values.Select(c => c.Split('=', 2))) { @@ -76,7 +76,7 @@ internal sealed partial class Cookie /// Cookie public static Cookie FromLoginResult(LoginResult? loginResult) { - if (loginResult == null) + if (loginResult is null) { return new(); } @@ -115,15 +115,12 @@ internal sealed partial class Cookie public bool TryGetLToken([NotNullWhen(true)] out Cookie? cookie) { - bool hasLtoken = TryGetValue(LTOKEN, out string? ltoken); - bool hasStuid = TryGetValue(LTUID, out string? ltuid); - - if (hasLtoken && hasStuid) + if (TryGetValue(LTOKEN, out string? ltoken) && TryGetValue(LTUID, out string? ltuid)) { cookie = new Cookie(new() { - [LTOKEN] = ltoken!, - [LTUID] = ltuid!, + [LTOKEN] = ltoken, + [LTUID] = ltuid, }); return true; @@ -135,15 +132,12 @@ internal sealed partial class Cookie public bool TryGetCookieToken([NotNullWhen(true)] out Cookie? cookie) { - bool hasAccountId = TryGetValue(ACCOUNT_ID, out string? accountId); - bool hasCookieToken = TryGetValue(COOKIE_TOKEN, out string? cookieToken); - - if (hasAccountId && hasCookieToken) + if (TryGetValue(ACCOUNT_ID, out string? accountId) && TryGetValue(COOKIE_TOKEN, out string? cookieToken)) { cookie = new Cookie(new() { - [ACCOUNT_ID] = accountId!, - [COOKIE_TOKEN] = cookieToken!, + [ACCOUNT_ID] = accountId, + [COOKIE_TOKEN] = cookieToken, }); return true; @@ -180,17 +174,13 @@ internal sealed partial class Cookie private bool TryGetSToken([NotNullWhen(true)] out Cookie? cookie) { - bool hasMid = TryGetValue(MID, out string? mid); - bool hasSToken = TryGetValue(STOKEN, out string? stoken); - bool hasSTuid = TryGetValue(STUID, out string? stuid); - - if (hasMid && hasSToken && hasSTuid) + if (TryGetValue(MID, out string? mid) && TryGetValue(STOKEN, out string? stoken) && TryGetValue(STUID, out string? stuid)) { cookie = new Cookie(new() { - [MID] = mid!, - [STOKEN] = stoken!, - [STUID] = stuid!, + [MID] = mid, + [STOKEN] = stoken, + [STUID] = stuid, }); return true; @@ -202,15 +192,12 @@ internal sealed partial class Cookie private bool TryGetLegacySToken([NotNullWhen(true)] out Cookie? cookie) { - bool hasSToken = TryGetValue(STOKEN, out string? stoken); - bool hasSTuid = TryGetValue(STUID, out string? stuid); - - if (hasSToken && hasSTuid) + if (TryGetValue(STOKEN, out string? stoken) && TryGetValue(STUID, out string? stuid)) { cookie = new Cookie(new() { - [STOKEN] = stoken!, - [STUID] = stuid!, + [STOKEN] = stoken, + [STUID] = stuid, }); return true; diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretHandler.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretHandler.cs index 40c57f90..276ee3c5 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretHandler.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretHandler.cs @@ -31,7 +31,8 @@ internal sealed class DynamicSecretHandler : DelegatingHandler 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]; @@ -44,11 +45,12 @@ internal sealed class DynamicSecretHandler : DelegatingHandler // ds2 b & q process if (options.Version == DynamicSecretVersion.Gen2) { - string b = request.Content != null + string b = request.Content is not null ? await request.Content.ReadAsStringAsync(token).ConfigureAwait(false) : 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; dsContent = $"{dsContent}&b={b}&q={q}"; diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/UseDynamicSecretAttribute.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/UseDynamicSecretAttribute.cs index 0fd3bb06..d57b736b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/UseDynamicSecretAttribute.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/UseDynamicSecretAttribute.cs @@ -9,6 +9,6 @@ namespace Snap.Hutao.Web.Hoyolab.DynamicSecret; /// [HighQuality] [AttributeUsage(AttributeTargets.Class)] -internal class UseDynamicSecretAttribute : Attribute +internal sealed class UseDynamicSecretAttribute : Attribute { } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Common/Announcement/Announcement.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Common/Announcement/Announcement.cs index 9f8ec0c6..68b20263 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Common/Announcement/Announcement.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Common/Announcement/Announcement.cs @@ -32,20 +32,20 @@ internal sealed class Announcement : AnnouncementContent TimeSpan span = StartTime - now; 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 { TimeSpan span = EndTime - now; 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); } } } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Common/Announcement/AnnouncementClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Common/Announcement/AnnouncementClient.cs index 3d295f80..5eadbcc5 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Common/Announcement/AnnouncementClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Common/Announcement/AnnouncementClient.cs @@ -23,7 +23,7 @@ internal sealed partial class AnnouncementClient /// /// 取消令牌 /// 公告列表 - public async Task> GetAnnouncementsAsync(CancellationToken cancellationToken = default) + public async ValueTask> GetAnnouncementsAsync(CancellationToken cancellationToken = default) { Response? resp = await httpClient .TryCatchGetFromJsonAsync>(ApiEndpoints.AnnList, jsonSerializerOptions, logger, cancellationToken) @@ -37,7 +37,7 @@ internal sealed partial class AnnouncementClient /// /// 取消令牌 /// 公告内容列表 - public async Task>> GetAnnouncementContentsAsync(CancellationToken cancellationToken = default) + public async ValueTask>> GetAnnouncementContentsAsync(CancellationToken cancellationToken = default) { Response>? resp = await httpClient .TryCatchGetFromJsonAsync>>(ApiEndpoints.AnnContent, jsonSerializerOptions, logger, cancellationToken) diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaInfoClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaInfoClient.cs index 1c8b2941..a436d5d0 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaInfoClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaInfoClient.cs @@ -25,7 +25,7 @@ internal sealed partial class GachaInfoClient /// 查询 /// 取消令牌 /// 单个祈愿记录页面 - public async Task> GetGachaLogPageAsync(GachaLogQueryOptions options, CancellationToken token = default) + public async ValueTask> GetGachaLogPageAsync(GachaLogQueryOptions options, CancellationToken token = default) { string query = options.ToQueryString(); diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaLogQueryOptions.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaLogQueryOptions.cs index de296831..8019cfa0 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaLogQueryOptions.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaLogQueryOptions.cs @@ -86,7 +86,7 @@ internal struct GachaLogQueryOptions /// 转换到查询字符串 /// /// 匹配的查询字符串 - public string ToQueryString() + public readonly string ToQueryString() { // Make the cached end id into query. innerQuery.Set("end_id", EndId); diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyolabHttpClientExtension.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyolabHttpClientExtension.cs index 43373f75..a477c338 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyolabHttpClientExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyolabHttpClientExtension.cs @@ -27,17 +27,17 @@ internal static class HoyolabHttpClientExtension 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)) { - stringBuilder.Append(user.LToken).AppendIf(user.LToken != null, ';'); + stringBuilder.Append(user.LToken).AppendIf(user.LToken is not null, ';'); } 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(); diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/IPassportClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/IPassportClient.cs index 84b673c3..ff0e92b3 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/IPassportClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/IPassportClient.cs @@ -17,7 +17,7 @@ internal interface IPassportClient /// 用户 /// 取消令牌 /// cookie token - Task> GetCookieAccountInfoBySTokenAsync(User user, CancellationToken token = default); + ValueTask> GetCookieAccountInfoBySTokenAsync(User user, CancellationToken token = default); /// /// 异步获取 LToken @@ -25,5 +25,5 @@ internal interface IPassportClient /// 用户 /// 取消令牌 /// uid 与 cookie token - Task> GetLTokenBySTokenAsync(User user, CancellationToken token = default); + ValueTask> GetLTokenBySTokenAsync(User user, CancellationToken token = default); } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/PassportClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/PassportClient.cs index 8a753dbf..41ad846a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/PassportClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/PassportClient.cs @@ -30,7 +30,7 @@ internal sealed partial class PassportClient : IPassportClient /// 取消令牌 /// cookie token [ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.PROD)] - public async Task> GetCookieAccountInfoBySTokenAsync(User user, CancellationToken token = default) + public async ValueTask> GetCookieAccountInfoBySTokenAsync(User user, CancellationToken token = default) { Response? resp = await httpClient .SetUser(user, CookieType.SToken) @@ -48,7 +48,7 @@ internal sealed partial class PassportClient : IPassportClient /// 取消令牌 /// uid 与 cookie token [ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.PROD)] - public async Task> GetLTokenBySTokenAsync(User user, CancellationToken token = default) + public async ValueTask> GetLTokenBySTokenAsync(User user, CancellationToken token = default) { Response? resp = await httpClient .SetUser(user, CookieType.SToken) diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/PassportClient2.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/PassportClient2.cs index 5858151c..8e4f1430 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/PassportClient2.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/PassportClient2.cs @@ -31,7 +31,7 @@ internal sealed partial class PassportClient2 /// 取消令牌 /// 验证信息 [ApiInformation(Cookie = CookieType.LToken)] - public async Task> VerifyLtokenAsync(User user, CancellationToken token) + public async ValueTask> VerifyLtokenAsync(User user, CancellationToken token) { Response? response = await httpClient .SetUser(user, CookieType.LToken) @@ -48,7 +48,7 @@ internal sealed partial class PassportClient2 /// 取消令牌 /// 登录数据 [ApiInformation(Salt = SaltType.PROD)] - public async Task> LoginBySTokenAsync(Cookie stokenV1, CancellationToken token = default) + public async ValueTask> LoginBySTokenAsync(Cookie stokenV1, CancellationToken token = default) { HttpResponseMessage message = await httpClient .SetHeader("Cookie", stokenV1.ToString()) diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/PassportClientOversea.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/PassportClientOversea.cs index a3576826..21d6fad4 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/PassportClientOversea.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/PassportClientOversea.cs @@ -27,9 +27,12 @@ internal sealed partial class PassportClientOversea : IPassportClient /// 取消令牌 /// cookie token [ApiInformation(Cookie = CookieType.SToken)] - public async Task> GetCookieAccountInfoBySTokenAsync(User user, CancellationToken token = default) + public async ValueTask> 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? resp = await httpClient .SetUser(user, CookieType.SToken) @@ -46,9 +49,12 @@ internal sealed partial class PassportClientOversea : IPassportClient /// 取消令牌 /// uid 与 cookie token [ApiInformation(Cookie = CookieType.SToken)] - public async Task> GetLTokenBySTokenAsync(User user, CancellationToken token = default) + public async ValueTask> 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? resp = await httpClient .SetUser(user, CookieType.SToken) diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/ResourceClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/ResourceClient.cs index c4a851fe..9fe44584 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/ResourceClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/ResourceClient.cs @@ -26,7 +26,7 @@ internal sealed partial class ResourceClient /// 方案 /// 取消令牌 /// 游戏资源 - public async Task> GetResourceAsync(LaunchScheme scheme, CancellationToken token = default) + public async ValueTask> GetResourceAsync(LaunchScheme scheme, CancellationToken token = default) { string url = scheme.IsOversea ? ApiOsEndpoints.SdkOsStaticLauncherResource(scheme) diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Auth/AuthClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Auth/AuthClient.cs index 4088973a..7c3a0046 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Auth/AuthClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Auth/AuthClient.cs @@ -31,9 +31,10 @@ internal sealed partial class AuthClient /// 用户 /// 操作凭证 [ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.K2)] - public async Task> GetActionTicketBySTokenAsync(string action, User user) + public async ValueTask> 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? resp = await httpClient .SetUser(user, CookieType.SToken) @@ -51,7 +52,7 @@ internal sealed partial class AuthClient /// 是否为国际服 /// 取消令牌 /// 包含token的字典 - public async Task>> GetMultiTokenByLoginTicketAsync(Cookie cookie, bool isOversea, CancellationToken token = default) + public async ValueTask>> GetMultiTokenByLoginTicketAsync(Cookie cookie, bool isOversea, CancellationToken token = default) { string loginTicket = cookie[Cookie.LOGIN_TICKET]; string loginUid = cookie[Cookie.LOGIN_UID]; diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Binding/BindingClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Binding/BindingClient.cs index d1d1fdf8..01a639f4 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Binding/BindingClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Binding/BindingClient.cs @@ -30,7 +30,7 @@ internal sealed partial class BindingClient /// 用户 /// 取消令牌 /// 用户角色信息 - public async Task>> GetUserGameRolesOverseaAwareAsync(User user, CancellationToken token = default) + public async ValueTask>> GetUserGameRolesOverseaAwareAsync(User user, CancellationToken token = default) { if (user.IsOversea) { @@ -63,7 +63,7 @@ internal sealed partial class BindingClient /// 取消令牌 /// 用户角色信息 [ApiInformation(Cookie = CookieType.LToken)] - public async Task>> GetUserGameRolesByActionTicketAsync(string actionTicket, User user, CancellationToken token = default) + public async ValueTask>> GetUserGameRolesByActionTicketAsync(string actionTicket, User user, CancellationToken token = default) { string url = ApiEndpoints.UserGameRolesByActionTicket(actionTicket); @@ -82,7 +82,7 @@ internal sealed partial class BindingClient /// 取消令牌 /// 用户角色信息 [ApiInformation(Cookie = CookieType.LToken)] - public async Task>> GetOverseaUserGameRolesByCookieAsync(User user, CancellationToken token = default) + public async ValueTask>> GetOverseaUserGameRolesByCookieAsync(User user, CancellationToken token = default) { Response>? resp = await httpClient .SetUser(user, CookieType.LToken) diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Binding/BindingClient2.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Binding/BindingClient2.cs index df7cf4b1..50a01161 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Binding/BindingClient2.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Binding/BindingClient2.cs @@ -30,7 +30,7 @@ internal sealed partial class BindingClient2 /// 取消令牌 /// 用户角色信息 [ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.LK2)] - public async Task> GetUserGameRolesBySTokenAsync(User user, CancellationToken token = default) + public async ValueTask> GetUserGameRolesBySTokenAsync(User user, CancellationToken token = default) { Response>? resp = await httpClient .SetUser(user, CookieType.SToken) @@ -50,7 +50,7 @@ internal sealed partial class BindingClient2 /// 取消令牌 /// 用户角色信息 [ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.LK2)] - public async Task> GenerateAuthenticationKeyAsync(User user, GenAuthKeyData data, CancellationToken token = default) + public async ValueTask> GenerateAuthenticationKeyAsync(User user, GenAuthKeyData data, CancellationToken token = default) { Response? resp = await httpClient .SetUser(user, CookieType.SToken) diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Binding/GenAuthKeyData.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Binding/GenAuthKeyData.cs index d767a139..429049a6 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Binding/GenAuthKeyData.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Binding/GenAuthKeyData.cs @@ -1,6 +1,8 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using System.Globalization; + namespace Snap.Hutao.Web.Hoyolab.Takumi.Binding; /// @@ -22,7 +24,7 @@ internal sealed class GenAuthKeyData { AuthAppId = authAppId; GameBiz = gameBiz; - GameUid = int.Parse(uid.Value); + GameUid = int.Parse(uid.Value, CultureInfo.InvariantCulture); Region = uid.Region; } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/CalculateClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/CalculateClient.cs index 03997147..6cdc5c9f 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/CalculateClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/CalculateClient.cs @@ -29,7 +29,7 @@ internal sealed partial class CalculateClient /// 取消令牌 /// 消耗结果 [ApiInformation(Cookie = CookieType.Cookie)] - public async Task> ComputeAsync(Model.Entity.User user, AvatarPromotionDelta delta, CancellationToken token = default) + public async ValueTask> ComputeAsync(Model.Entity.User user, AvatarPromotionDelta delta, CancellationToken token = default) { string referer = user.IsOversea ? ApiOsEndpoints.ActHoyolabReferer @@ -54,7 +54,7 @@ internal sealed partial class CalculateClient /// 用户与角色 /// 取消令牌 /// 角色列表 - public async Task> GetAvatarsAsync(UserAndUid userAndUid, CancellationToken token = default) + public async ValueTask> GetAvatarsAsync(UserAndUid userAndUid, CancellationToken token = default) { int currentPage = 1; SyncAvatarFilter filter = new() { Uid = userAndUid.Uid.Value, Region = userAndUid.Uid.Region }; @@ -81,7 +81,7 @@ internal sealed partial class CalculateClient .TryCatchPostAsJsonAsync>>(url, filter, options, logger, token) .ConfigureAwait(false); - if (resp != null && resp.IsOk()) + if (resp is not null && resp.IsOk()) { 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); } - while (resp?.Data?.List?.Count == 20); + while (resp.Data is { List.Count: 20 }); return avatars; } @@ -105,7 +105,7 @@ internal sealed partial class CalculateClient /// 角色 /// 取消令牌 /// 角色详情 - public async Task> GetAvatarDetailAsync(UserAndUid userAndUid, Avatar avatar, CancellationToken token = default) + public async ValueTask> GetAvatarDetailAsync(UserAndUid userAndUid, Avatar avatar, CancellationToken token = default) { string url = userAndUid.User.IsOversea ? ApiOsEndpoints.CalculateSyncAvatarDetail(avatar.Id, userAndUid.Uid.Value) @@ -126,7 +126,7 @@ internal sealed partial class CalculateClient /// 摹本码 /// 取消令牌 /// 家具列表 - public async Task> FurnitureBlueprintAsync(Model.Entity.User user, string shareCode, CancellationToken token) + public async ValueTask> FurnitureBlueprintAsync(Model.Entity.User user, string shareCode, CancellationToken token) { Response? resp = await httpClient .SetUser(user, CookieType.CookieToken) @@ -143,7 +143,7 @@ internal sealed partial class CalculateClient /// 物品 /// 取消令牌 /// 消耗 - public async Task>> FurnitureComputeAsync(Model.Entity.User user, List items, CancellationToken token) + public async ValueTask>> FurnitureComputeAsync(Model.Entity.User user, List items, CancellationToken token) { ListWrapper data = new() { List = items.Select(i => new IdCount { Id = i.Id, Count = i.Num }).ToList() }; diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/ItemHelper.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/ItemHelper.cs index e0e4cd48..cb79da8c 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/ItemHelper.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Event/Calculate/ItemHelper.cs @@ -22,16 +22,19 @@ internal static class ItemHelper 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 result = new(left.Count + right.Count); result.AddRange(left); diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/CardClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/CardClient.cs index 865682f3..af7d1417 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/CardClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/CardClient.cs @@ -15,33 +15,21 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord; /// [HighQuality] [UseDynamicSecret] +[ConstructorGenerated(ResolveHttpClient = true)] [HttpClient(HttpClientConfiguration.XRpc)] -internal sealed class CardClient +internal sealed partial class CardClient { private readonly HttpClient httpClient; private readonly JsonSerializerOptions options; private readonly ILogger logger; - /// - /// 构造一个新的卡片客户端 - /// - /// http客户端 - /// 选项 - /// 日志器 - public CardClient(HttpClient httpClient, JsonSerializerOptions options, ILogger logger) - { - this.httpClient = httpClient; - this.options = options; - this.logger = logger; - } - /// /// 注册验证码 /// /// 用户 /// 取消令牌 /// 注册结果 - public async Task> CreateVerificationAsync(User user, CancellationToken token) + public async ValueTask> CreateVerificationAsync(User user, CancellationToken token) { Response? resp = await httpClient .SetUser(user, CookieType.LToken) @@ -59,7 +47,7 @@ internal sealed class CardClient /// 验证 /// 取消令牌 /// 验证结果 - public async Task> VerifyVerificationAsync(string challenge, string validate, CancellationToken token) + public async ValueTask> VerifyVerificationAsync(string challenge, string validate, CancellationToken token) { VerificationData data = new(challenge, validate); @@ -77,7 +65,7 @@ internal sealed class CardClient /// 取消令牌 /// 桌面小组件数据 [ApiInformation(Cookie = CookieType.SToken, Salt = SaltType.X6)] - public async Task> GetWidgetDataAsync(User user, CancellationToken token) + public async ValueTask> GetWidgetDataAsync(User user, CancellationToken token) { Response? resp = await httpClient .SetUser(user, CookieType.SToken) diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/CardVerifier.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/CardVerifier.cs index 78f89dd7..9db52add 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/CardVerifier.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/CardVerifier.cs @@ -33,7 +33,7 @@ internal sealed class CardVerifier /// 用户 /// 取消令牌 /// 流水号 - public async Task TryGetXrpcChallengeAsync(User user, CancellationToken token) + public async ValueTask TryGetXrpcChallengeAsync(User user, CancellationToken token) { Response.Response registrationResponse = await cardClient.CreateVerificationAsync(user, token).ConfigureAwait(false); if (registrationResponse.IsOk()) @@ -43,14 +43,14 @@ internal sealed class CardVerifier await geetestClient.GetTypeAsync(registration.Gt).ConfigureAwait(false); GeetestResult? ajax = await geetestClient.GetAjaxAsync(registration).ConfigureAwait(false); - if (ajax?.Data.Validate is string validate) + if (ajax?.Data.Validate is { } validate) { Response.Response verifyResponse = await cardClient.VerifyVerificationAsync(registration.Challenge, validate, token).ConfigureAwait(false); if (verifyResponse.IsOk()) { VerificationResult result = verifyResponse.Data; - if (result.Challenge != null) + if (result.Challenge is not null) { return result.Challenge; } @@ -58,6 +58,6 @@ internal sealed class CardVerifier } } - return null; + return default; } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNote.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNote.cs index 4cd07d3e..9e2aed5f 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNote.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNote.cs @@ -38,10 +38,10 @@ internal sealed class DailyNote : DailyNoteCommon 0 => SH.WebDailyNoteRecoveryTimeDay0, 1 => SH.WebDailyNoteRecoveryTimeDay1, 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, 1 => SH.WebDailyNoteRecoveryTimeDay1, 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); } } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/Expedition.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/Expedition.cs index ceef0ebf..beb9c7bf 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/Expedition.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/Expedition.cs @@ -84,8 +84,8 @@ internal sealed class Expedition TimeSpan ts = new(0, 0, RemainedTime); return ts.Hours > 0 - ? string.Format(SH.WebDailyNoteExpeditionRemainHoursFormat, ts.Hours) - : string.Format(SH.WebDailyNoteExpeditionRemainMinutesFormat, ts.Minutes); + ? SH.WebDailyNoteExpeditionRemainHoursFormat.Format(ts.Hours) + : SH.WebDailyNoteExpeditionRemainMinutesFormat.Format(ts.Minutes); } } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/RecoveryTime.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/RecoveryTime.cs index c2d3f192..eb526cad 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/RecoveryTime.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/RecoveryTime.cs @@ -67,10 +67,10 @@ internal sealed class RecoveryTime else { return new StringBuilder() - .AppendIf(Day > 0, string.Format(SH.WebDailyNoteTransformerDaysFormat, Day)) - .AppendIf(Hour > 0, string.Format(SH.WebDailyNoteTransformerHoursFormat, Hour)) - .AppendIf(Minute > 0, string.Format(SH.WebDailyNoteTransformerMinutesFormat, Minute)) - .AppendIf(Second > 0, string.Format(SH.WebDailyNoteTransformerSecondsFormat, Second)) + .AppendIf(Day > 0, SH.WebDailyNoteTransformerDaysFormat.Format(Day)) + .AppendIf(Hour > 0, SH.WebDailyNoteTransformerHoursFormat.Format(Hour)) + .AppendIf(Minute > 0, SH.WebDailyNoteTransformerMinutesFormat.Format(Minute)) + .AppendIf(Second > 0, SH.WebDailyNoteTransformerSecondsFormat.Format(Second)) .Append(SH.WebDailyNoteTransformerAppend) .ToString(); } @@ -92,10 +92,10 @@ internal sealed class RecoveryTime else { return new StringBuilder() - .AppendIf(Day > 0, string.Format(SH.WebDailyNoteTransformerDaysFormat, Day)) - .AppendIf(Hour > 0, string.Format(SH.WebDailyNoteTransformerHoursFormat, Hour)) - .AppendIf(Minute > 0, string.Format(SH.WebDailyNoteTransformerMinutesFormat, Minute)) - .AppendIf(Second > 0, string.Format(SH.WebDailyNoteTransformerSecondsFormat, Second)) + .AppendIf(Day > 0, SH.WebDailyNoteTransformerDaysFormat.Format(Day)) + .AppendIf(Hour > 0, SH.WebDailyNoteTransformerHoursFormat.Format(Hour)) + .AppendIf(Minute > 0, SH.WebDailyNoteTransformerMinutesFormat.Format(Minute)) + .AppendIf(Second > 0, SH.WebDailyNoteTransformerSecondsFormat.Format(Second)) .ToString(); } } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/GameRecordClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/GameRecordClient.cs index 377d870d..78da7a3d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/GameRecordClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/GameRecordClient.cs @@ -33,7 +33,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient /// 取消令牌 /// 实时便笺 [ApiInformation(Cookie = CookieType.Cookie, Salt = SaltType.X4)] - public async Task> GetDailyNoteAsync(UserAndUid userAndUid, CancellationToken token = default) + public async ValueTask> GetDailyNoteAsync(UserAndUid userAndUid, CancellationToken token = default) { Response? resp = await httpClient .SetUser(userAndUid.User, CookieType.Cookie) @@ -48,7 +48,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient resp.Message = SH.WebDailyNoteVerificationFailed; CardVerifier cardVerifier = serviceProvider.GetRequiredService(); - 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 .SetUser(userAndUid.User, CookieType.Cookie) @@ -69,7 +69,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient /// 取消令牌 /// 玩家的基础信息 [ApiInformation(Cookie = CookieType.LToken, Salt = SaltType.X4)] - public async Task> GetPlayerInfoAsync(UserAndUid userAndUid, CancellationToken token = default) + public async ValueTask> GetPlayerInfoAsync(UserAndUid userAndUid, CancellationToken token = default) { Response? resp = await httpClient .SetUser(userAndUid.User, CookieType.LToken) @@ -88,7 +88,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient /// 取消令牌 /// 深渊信息 [ApiInformation(Cookie = CookieType.Cookie, Salt = SaltType.X4)] - public async Task> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default) + public async ValueTask> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default) { Response? resp = await httpClient .SetUser(userAndUid.User, CookieType.Cookie) @@ -106,7 +106,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient /// 取消令牌 /// 角色基本信息 [ApiInformation(Cookie = CookieType.LToken, Salt = SaltType.X4)] - public async Task> GetRoleBasicInfoAsync(UserAndUid userAndUid, CancellationToken token = default) + public async ValueTask> GetRoleBasicInfoAsync(UserAndUid userAndUid, CancellationToken token = default) { Response? resp = await httpClient .SetUser(userAndUid.User, CookieType.LToken) @@ -125,7 +125,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient /// 取消令牌 /// 角色列表 [ApiInformation(Cookie = CookieType.LToken, Salt = SaltType.X4)] - public async Task> GetCharactersAsync(UserAndUid userAndUid, PlayerInfo playerInfo, CancellationToken token = default) + public async ValueTask> GetCharactersAsync(UserAndUid userAndUid, PlayerInfo playerInfo, CancellationToken token = default) { CharacterData data = new(userAndUid.Uid, playerInfo.Avatars.Select(x => x.Id)); diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/GameRecordClientOversea.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/GameRecordClientOversea.cs index e656dd87..4396e168 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/GameRecordClientOversea.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/GameRecordClientOversea.cs @@ -31,7 +31,7 @@ internal sealed partial class GameRecordClientOversea : IGameRecordClient /// 取消令牌 /// 实时便笺 [ApiInformation(Cookie = CookieType.Cookie, Salt = SaltType.OSX4)] - public async Task> GetDailyNoteAsync(UserAndUid userAndUid, CancellationToken token = default) + public async ValueTask> GetDailyNoteAsync(UserAndUid userAndUid, CancellationToken token = default) { Response? resp = await httpClient .SetUser(userAndUid.User, CookieType.Cookie) @@ -49,7 +49,7 @@ internal sealed partial class GameRecordClientOversea : IGameRecordClient /// 取消令牌 /// 玩家的基础信息 [ApiInformation(Cookie = CookieType.LToken, Salt = SaltType.OSX4)] - public async Task> GetPlayerInfoAsync(UserAndUid userAndUid, CancellationToken token = default) + public async ValueTask> GetPlayerInfoAsync(UserAndUid userAndUid, CancellationToken token = default) { Response? resp = await httpClient .SetUser(userAndUid.User, CookieType.Cookie) @@ -68,7 +68,7 @@ internal sealed partial class GameRecordClientOversea : IGameRecordClient /// 取消令牌 /// 深渊信息 [ApiInformation(Cookie = CookieType.Cookie, Salt = SaltType.OSX4)] - public async Task> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default) + public async ValueTask> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default) { Response? resp = await httpClient .SetUser(userAndUid.User, CookieType.Cookie) @@ -87,7 +87,7 @@ internal sealed partial class GameRecordClientOversea : IGameRecordClient /// 取消令牌 /// 角色列表 [ApiInformation(Cookie = CookieType.LToken, Salt = SaltType.OSX4)] - public async Task> GetCharactersAsync(UserAndUid userAndUid, PlayerInfo playerInfo, CancellationToken token = default) + public async ValueTask> GetCharactersAsync(UserAndUid userAndUid, PlayerInfo playerInfo, CancellationToken token = default) { CharacterData data = new(userAndUid.Uid, playerInfo.Avatars.Select(x => x.Id)); diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/IGameRecordClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/IGameRecordClient.cs index d67b42e3..ef7cf1d3 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/IGameRecordClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/IGameRecordClient.cs @@ -20,7 +20,7 @@ internal interface IGameRecordClient /// 玩家的基础信息 /// 取消令牌 /// 角色列表 - Task> GetCharactersAsync(UserAndUid userAndUid, PlayerInfo playerInfo, CancellationToken token = default); + ValueTask> GetCharactersAsync(UserAndUid userAndUid, PlayerInfo playerInfo, CancellationToken token = default); /// /// 异步获取实时便笺 @@ -28,7 +28,7 @@ internal interface IGameRecordClient /// 用户与角色 /// 取消令牌 /// 实时便笺 - Task> GetDailyNoteAsync(UserAndUid userAndUid, CancellationToken token = default); + ValueTask> GetDailyNoteAsync(UserAndUid userAndUid, CancellationToken token = default); /// /// 获取玩家基础信息 @@ -36,7 +36,7 @@ internal interface IGameRecordClient /// 用户与角色 /// 取消令牌 /// 玩家的基础信息 - Task> GetPlayerInfoAsync(UserAndUid userAndUid, CancellationToken token = default); + ValueTask> GetPlayerInfoAsync(UserAndUid userAndUid, CancellationToken token = default); /// /// 获取玩家深渊信息 @@ -45,5 +45,5 @@ internal interface IGameRecordClient /// 1:当期,2:上期 /// 取消令牌 /// 深渊信息 - Task> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default); + ValueTask> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default); } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/HttpClientExtension.cs b/src/Snap.Hutao/Snap.Hutao/Web/HttpClientExtension.cs index aa427700..bb29921a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/HttpClientExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/HttpClientExtension.cs @@ -17,7 +17,7 @@ internal static class HttpClientExtension private const string RequestErrorMessage = "请求异常已忽略"; /// - internal static async Task TryCatchGetFromJsonAsync(this HttpClient httpClient, string requestUri, JsonSerializerOptions options, ILogger logger, CancellationToken token = default) + internal static async ValueTask TryCatchGetFromJsonAsync(this HttpClient httpClient, string requestUri, JsonSerializerOptions options, ILogger logger, CancellationToken token = default) where T : class { try @@ -47,7 +47,7 @@ internal static class HttpClientExtension } /// - internal static async Task TryCatchPostAsJsonAsync(this HttpClient httpClient, string requestUri, TValue value, JsonSerializerOptions options, ILogger logger, CancellationToken token = default) + internal static async ValueTask TryCatchPostAsJsonAsync(this HttpClient httpClient, string requestUri, TValue value, JsonSerializerOptions options, ILogger logger, CancellationToken token = default) where TResult : class { try @@ -78,7 +78,7 @@ internal static class HttpClientExtension } /// - internal static async Task TryCatchPostAsJsonAsync(this HttpClient httpClient, string requestUri, TValue value, CancellationToken token = default) + internal static async ValueTask TryCatchPostAsJsonAsync(this HttpClient httpClient, string requestUri, TValue value, CancellationToken token = default) where TResult : class { try @@ -103,4 +103,4 @@ internal static class HttpClientExtension return null; } } -} +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaGachaLogClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaGachaLogClient.cs index 4c8a860c..12021574 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaGachaLogClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaGachaLogClient.cs @@ -40,7 +40,7 @@ internal sealed class HomaGachaLogClient /// /// 取消令牌 /// 祈愿统计信息 - public async Task> GetGachaEventStatisticsAsync(CancellationToken token = default) + public async ValueTask> GetGachaEventStatisticsAsync(CancellationToken token = default) { Response? resp = await httpClient .TryCatchGetFromJsonAsync>(HutaoEndpoints.GachaLogStatisticsCurrentEvents, options, logger, token) @@ -70,7 +70,7 @@ internal sealed class HomaGachaLogClient /// 取消令牌 /// Uid 列表 [Obsolete("Use GetGachaEntriesAsync instead")] - public async Task>> GetUidsAsync(CancellationToken token = default) + public async ValueTask>> GetUidsAsync(CancellationToken token = default) { Response>? resp = await httpClient .TryCatchGetFromJsonAsync>>(HutaoEndpoints.GachaLogUids, options, logger, token) @@ -99,7 +99,7 @@ internal sealed class HomaGachaLogClient /// uid /// 取消令牌 /// 末尾Id - public async Task> GetEndIdsAsync(string uid, CancellationToken token = default) + public async ValueTask> GetEndIdsAsync(string uid, CancellationToken token = default) { Response? resp = await httpClient .TryCatchGetFromJsonAsync>(HutaoEndpoints.GachaLogEndIds(uid), options, logger, token) @@ -115,7 +115,7 @@ internal sealed class HomaGachaLogClient /// 末尾 Id /// 取消令牌 /// 云端祈愿记录 - public async Task>> RetrieveGachaItemsAsync(string uid, EndIds endIds, CancellationToken token = default) + public async ValueTask>> RetrieveGachaItemsAsync(string uid, EndIds endIds, CancellationToken token = default) { UidAndEndIds uidAndEndIds = new(uid, endIds); @@ -133,7 +133,7 @@ internal sealed class HomaGachaLogClient /// 祈愿记录 /// 取消令牌 /// 响应 - public async Task UploadGachaItemsAsync(string uid, List gachaItems, CancellationToken token = default) + public async ValueTask UploadGachaItemsAsync(string uid, List gachaItems, CancellationToken token = default) { UidAndItems uidAndItems = new(uid, gachaItems); @@ -150,7 +150,7 @@ internal sealed class HomaGachaLogClient /// uid /// 取消令牌 /// 响应 - public async Task DeleteGachaItemsAsync(string uid, CancellationToken token = default) + public async ValueTask DeleteGachaItemsAsync(string uid, CancellationToken token = default) { Response.Response? resp = await httpClient .TryCatchGetFromJsonAsync>>(HutaoEndpoints.GachaLogDelete(uid), options, logger, token) diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaLogUploadClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaLogUploadClient.cs index dccd6e6c..50d79f6c 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaLogUploadClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaLogUploadClient.cs @@ -33,7 +33,7 @@ internal sealed class HomaLogUploadClient /// 服务提供器 /// 异常 /// 任务 - public async Task UploadLogAsync(IServiceProvider serviceProvider, Exception exception) + public async ValueTask UploadLogAsync(IServiceProvider serviceProvider, Exception exception) { HutaoLog log = BuildFromException(serviceProvider, exception); diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaPassportClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaPassportClient.cs index ccd40cc1..d572bc6c 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaPassportClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaPassportClient.cs @@ -44,7 +44,7 @@ internal sealed partial class HomaPassportClient /// 是否重置账号密码 /// 取消令牌 /// 响应 - public async Task VerifyAsync(string email, bool isResetPassword, CancellationToken token = default) + public async ValueTask VerifyAsync(string email, bool isResetPassword, CancellationToken token = default) { Dictionary data = new() { @@ -67,7 +67,7 @@ internal sealed partial class HomaPassportClient /// 验证码 /// 取消令牌 /// 响应,包含登录令牌 - public async Task> RegisterAsync(string email, string password, string verifyCode, CancellationToken token = default) + public async ValueTask> RegisterAsync(string email, string password, string verifyCode, CancellationToken token = default) { Dictionary data = new() { @@ -91,7 +91,7 @@ internal sealed partial class HomaPassportClient /// 验证码 /// 取消令牌 /// 响应,包含登录令牌 - public async Task> ResetPasswordAsync(string email, string password, string verifyCode, CancellationToken token = default) + public async ValueTask> ResetPasswordAsync(string email, string password, string verifyCode, CancellationToken token = default) { Dictionary data = new() { @@ -114,7 +114,7 @@ internal sealed partial class HomaPassportClient /// 密码 /// 取消令牌 /// 响应,包含登录令牌 - public async Task> LoginAsync(string email, string password, CancellationToken token = default) + public async ValueTask> LoginAsync(string email, string password, CancellationToken token = default) { Dictionary data = new() { @@ -135,7 +135,7 @@ internal sealed partial class HomaPassportClient /// 验证令牌 /// 取消令牌 /// 用户信息 - public async Task> GetUserInfoAsync(string authToken, CancellationToken token = default) + public async ValueTask> GetUserInfoAsync(string authToken, CancellationToken token = default) { httpClient.DefaultRequestHeaders.Authorization = new("Bearer", authToken); diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Request/QueryString/QueryString.cs b/src/Snap.Hutao/Snap.Hutao/Web/Request/QueryString/QueryString.cs index fba40683..dd22f7d0 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Request/QueryString/QueryString.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Request/QueryString/QueryString.cs @@ -63,7 +63,7 @@ internal readonly struct QueryString return new QueryString(); } - int questionMarkIndex = queryString.IndexOf('?'); + int questionMarkIndex = queryString.AsSpan().IndexOf('?'); queryString = queryString[(questionMarkIndex + 1)..]; string[] pairs = queryString.Split('&', ';');