diff --git a/src/Snap.Hutao/.editorconfig b/src/Snap.Hutao/.editorconfig index c7c29c71..fe0e366b 100644 --- a/src/Snap.Hutao/.editorconfig +++ b/src/Snap.Hutao/.editorconfig @@ -105,6 +105,8 @@ dotnet_naming_style.pascal_case.capitalization = pascal_case dotnet_diagnostic.SA1629.severity = silent dotnet_diagnostic.SA1642.severity = silent +dotnet_diagnostic.IDE0060.severity = none + # SA1208: System using directives should be placed before other using directives dotnet_diagnostic.SA1208.severity = none @@ -160,6 +162,7 @@ dotnet_diagnostic.CA1805.severity = suggestion # VSTHRD111: Use ConfigureAwait(bool) dotnet_diagnostic.VSTHRD111.severity = suggestion csharp_style_prefer_top_level_statements = true:silent +csharp_style_prefer_readonly_struct = true:suggestion [*.vb] #### 命名样式 #### diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Threading/CancellationTokenTaskCompletionSource.cs b/src/Snap.Hutao/Snap.Hutao/Core/Threading/CancellationTokenTaskCompletionSource.cs index f689af71..f4e0b5cf 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Threading/CancellationTokenTaskCompletionSource.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Threading/CancellationTokenTaskCompletionSource.cs @@ -26,7 +26,7 @@ public sealed class CancellationTokenTaskCompletionSource : IDisposable return; } - TaskCompletionSource tcs = new TaskCompletionSource(); + TaskCompletionSource tcs = new(); registration = cancellationToken.Register(() => tcs.TrySetResult(), useSynchronizationContext: false); Task = tcs.Task; } diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Threading/CodeAnalysis/ThreadAccessAttribute.cs b/src/Snap.Hutao/Snap.Hutao/Core/Threading/CodeAnalysis/ThreadAccessAttribute.cs index 9a4585f1..3c3da0cf 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Threading/CodeAnalysis/ThreadAccessAttribute.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Threading/CodeAnalysis/ThreadAccessAttribute.cs @@ -14,7 +14,6 @@ internal class ThreadAccessAttribute : Attribute /// 指示方法的进入线程访问状态 /// /// 进入状态 - [SuppressMessage("", "IDE0060")] public ThreadAccessAttribute(ThreadAccessState enter) { } diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Binding/User/User.cs b/src/Snap.Hutao/Snap.Hutao/Model/Binding/User/User.cs index de4e7f66..b43c6d7b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Binding/User/User.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Binding/User/User.cs @@ -133,7 +133,7 @@ public class User : ObservableObject } UserInfo = await userClient - .GetUserFullInfoAsync(this, token) + .GetUserFullInfoAsync(Entity, token) .ConfigureAwait(false); UserGameRoles = await userGameRoleClient diff --git a/src/Snap.Hutao/Snap.Hutao/Service/DailyNote/DailyNoteService.cs b/src/Snap.Hutao/Snap.Hutao/Service/DailyNote/DailyNoteService.cs index e35d36eb..9cd945ed 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/DailyNote/DailyNoteService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/DailyNote/DailyNoteService.cs @@ -62,7 +62,7 @@ internal class DailyNoteService : IDailyNoteService, IRecipient n.Uid == roleUid)) { DailyNoteEntry newEntry = DailyNoteEntry.Create(role); - newEntry.DailyNote = await gameRecordClient.GetDialyNoteAsync(role.User, newEntry.Uid).ConfigureAwait(false); + newEntry.DailyNote = await gameRecordClient.GetDailyNoteAsync(role.User, newEntry.Uid).ConfigureAwait(false); appDbContext.DailyNotes.AddAndSave(newEntry); newEntry.UserGameRole = userService.GetUserGameRoleByUid(roleUid); @@ -102,7 +102,7 @@ internal class DailyNoteService : IDailyNoteService, IRecipient n.User)) { - WebDailyNote? dailyNote = await gameRecordClient.GetDialyNoteAsync(entry.User, entry.Uid).ConfigureAwait(false); + WebDailyNote? dailyNote = await gameRecordClient.GetDailyNoteAsync(entry.User, entry.Uid).ConfigureAwait(false); // database entry.DailyNote = dailyNote; diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UrlProvider/GachaLogUrlStokenProvider.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UrlProvider/GachaLogUrlStokenProvider.cs index 4e75ee38..152e5294 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UrlProvider/GachaLogUrlStokenProvider.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UrlProvider/GachaLogUrlStokenProvider.cs @@ -42,7 +42,7 @@ internal class GachaLogUrlStokenProvider : IGachaLogUrlProvider PlayerUid uid = (PlayerUid)user.SelectedUserGameRole; GenAuthKeyData data = GenAuthKeyData.CreateForWebViewGacha(uid); - GameAuthKey? authkey = await bindingClient2.GenerateAuthenticationKeyAsync(user, data).ConfigureAwait(false); + GameAuthKey? authkey = await bindingClient2.GenerateAuthenticationKeyAsync(user.Entity, data).ConfigureAwait(false); if (authkey != null) { return new(true, GachaLogConfigration.AsQuery(data, authkey)); diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Annotation/ApiInformationAttribute.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Annotation/ApiInformationAttribute.cs index 7be30889..69d0198d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Annotation/ApiInformationAttribute.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Annotation/ApiInformationAttribute.cs @@ -7,6 +7,7 @@ namespace Snap.Hutao.Web.Hoyolab.Annotation; /// /// API 信息 +/// 指示此API 已经经过验证,且明确其调用 /// /// API 的返回类型 [AttributeUsage(AttributeTargets.Method)] diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/ApiEndpoints.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/ApiEndpoints.cs index e3338c56..8ade2c73 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/ApiEndpoints.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/ApiEndpoints.cs @@ -40,6 +40,16 @@ internal static class ApiEndpoints #region GameRecord + /// + /// 角色基本信息 + /// + /// uid + /// 角色基本信息字符串 + public static string GameRecordRoleBasicInfo(PlayerUid uid) + { + return $"{ApiTakumiRecordApi}/roleBasicInfo?role_id={uid.Value}&server={uid.Region}"; + } + /// /// 角色信息 /// diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Bbs/User/UserClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Bbs/User/UserClient.cs index b2335ec9..67357025 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Bbs/User/UserClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Bbs/User/UserClient.cs @@ -2,6 +2,8 @@ // Licensed under the MIT license. using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient; +using Snap.Hutao.Web.Hoyolab.Annotation; +using Snap.Hutao.Web.Hoyolab.DynamicSecret; using Snap.Hutao.Web.Response; using System.Net.Http; @@ -33,13 +35,34 @@ internal class UserClient /// /// 获取当前用户详细信息 /// + /// 用户id /// 用户 /// 取消令牌 /// 详细信息 - public async Task GetUserFullInfoAsync(Model.Binding.User.User user, CancellationToken token = default) + [ApiInformation(Cookie = CookieType.Stoken, Salt = SaltType.K2)] + public async Task GetUserFullInfoAsync(string uid, Model.Entity.User user, CancellationToken token = default) { Response? resp = await httpClient - .SetUser(user) + .SetUser(user, CookieType.Stoken) + .SetReferer(ApiEndpoints.BbsReferer) + .UsingDynamicSecret1(SaltType.K2) + .TryCatchGetFromJsonAsync>(ApiEndpoints.UserFullInfoQuery(uid), options, logger, token) + .ConfigureAwait(false); + + return resp?.Data?.UserInfo; + } + + /// + /// 获取当前用户详细信息 + /// + /// 用户 + /// 取消令牌 + /// 详细信息 + [ApiInformation(Cookie = CookieType.Ltoken)] + public async Task GetUserFullInfoAsync(Model.Entity.User user, CancellationToken token = default) + { + Response? resp = await httpClient + .SetUser(user, CookieType.Ltoken) .SetReferer(ApiEndpoints.BbsReferer) .TryCatchGetFromJsonAsync>(ApiEndpoints.UserFullInfo, options, logger, token) .ConfigureAwait(false); diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Cookie.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Cookie.cs index b944bd44..2ec6e7f1 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Cookie.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Cookie.cs @@ -204,6 +204,7 @@ public partial class Cookie results = type switch { CookieType.None => Enumerable.Empty>(), + CookieType.Ltoken => inner.Where(kvp => kvp.Key is E_HK4E_TOKEN or LTUID or LTOKEN or ACCOUNT_ID or COOKIE_TOKEN), CookieType.Stoken => inner.Where(kvp => kvp.Key is STUID or STOKEN or MID), CookieType.All => inner, _ => throw Must.NeverHappen(type.ToString()), diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/CookieType.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/CookieType.cs index fd0332df..ee4f3281 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/CookieType.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/CookieType.cs @@ -14,7 +14,7 @@ public enum CookieType None, /// - /// 需要 Ltoken 与 e_hk4e_token + /// 需要 Ltoken & CookieToken & e_hk4e_token /// Ltoken, diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/Http/DynamicSecretHttpClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/Http/DynamicSecretHttpClient.cs index 31fe098b..18ea70bc 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/Http/DynamicSecretHttpClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/Http/DynamicSecretHttpClient.cs @@ -15,7 +15,6 @@ namespace Snap.Hutao.Web.Hoyolab.DynamicSecret.Http; internal class DynamicSecretHttpClient : IDynamicSecretHttpClient { private readonly HttpClient httpClient; - private readonly SaltType saltType; private readonly JsonSerializerOptions options; private readonly string url; @@ -29,11 +28,10 @@ internal class DynamicSecretHttpClient : IDynamicSecretHttpClient public DynamicSecretHttpClient(HttpClient httpClient, SaltType saltType, JsonSerializerOptions options, string url) { this.httpClient = httpClient; - this.saltType = saltType; this.options = options; this.url = url; - httpClient.DefaultRequestHeaders.Set("DS", DynamicSecretProvider2.Create(options, url, null)); + httpClient.DefaultRequestHeaders.Set("DS", DynamicSecretProvider2.Create(saltType, options, url, null)); } /// @@ -81,7 +79,6 @@ internal class DynamicSecretHttpClient : IDynamicSecretHttpClient : IDynamicSecretHttpClient diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HttpClientExtensions.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HttpClientExtensions.cs index 795977a3..b3eea862 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HttpClientExtensions.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HttpClientExtensions.cs @@ -81,7 +81,7 @@ internal static class HttpClientExtensions /// 实体用户 /// Cookie类型 /// 客户端 - internal static HttpClient SetUser(this HttpClient httpClient, Model.Entity.User user, CookieType cookie = CookieType.All) + internal static HttpClient SetUser(this HttpClient httpClient, Model.Entity.User user, CookieType cookie) { httpClient.DefaultRequestHeaders.Set("Cookie", user.Cookie!.ToString(cookie)); return httpClient; 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 dc398b87..781bd814 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/PassportClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/PassportClient.cs @@ -38,7 +38,7 @@ internal class PassportClient /// 用户 /// 取消令牌 /// 验证信息 - [ApiInformation(Cookie = CookieType.All)] + [ApiInformation(Cookie = CookieType.Ltoken)] public async Task VerifyLtokenAsync(User user, CancellationToken token) { Response? response = await httpClient diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Auth/AccountInfo.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Auth/AccountInfo.cs index 3b8bf8be..44757483 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Auth/AccountInfo.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Auth/AccountInfo.cs @@ -14,7 +14,6 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.Auth; [SuppressMessage("", "SA1600")] public class AccountInfo { - [JsonPropertyName("is_realname")] public bool IsRealname { get; set; } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Auth/ActionTicketWrapper.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Auth/ActionTicketWrapper.cs index 6147751a..5492510e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Auth/ActionTicketWrapper.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/Auth/ActionTicketWrapper.cs @@ -17,7 +17,7 @@ public class ActionTicketWrapper /// 凭证 /// [JsonPropertyName("ticket")] - public string Ticket { get; set; } + public string Ticket { get; set; } = default!; /// /// 是否验证 @@ -29,5 +29,5 @@ public class ActionTicketWrapper /// 账户信息 /// [JsonPropertyName("account_info")] - public AccountInfo AccountInfo { get; set; } + public AccountInfo AccountInfo { get; set; } = default!; } 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 e756c7c8..51e89940 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 @@ -50,7 +50,7 @@ internal class AuthClient .TryCatchGetFromJsonAsync>(ApiEndpoints.AuthActionTicket(action, stoken, uid), options, logger) .ConfigureAwait(false); - return resp.Data?.Ticket; + return resp?.Data?.Ticket; } } 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 2b2c202e..10fb4a13 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 @@ -3,7 +3,7 @@ using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient; using Snap.Hutao.Extension; -using Snap.Hutao.Model.Binding.User; +using Snap.Hutao.Model.Entity; using Snap.Hutao.Web.Hoyolab.Annotation; using Snap.Hutao.Web.Response; using System.Net.Http; @@ -41,12 +41,12 @@ internal class BindingClient /// 取消令牌 /// 用户角色信息 [ApiInformation(Cookie = CookieType.Ltoken)] - public async Task> GetUserGameRolesAsync(string actionTicket, Model.Entity.User user, CancellationToken token = default) + public async Task> GetUserGameRolesAsync(string actionTicket, User user, CancellationToken token = default) { string url = ApiEndpoints.UserGameRolesByActionTicket(actionTicket); Response>? resp = await httpClient - .SetUser(user) + .SetUser(user, CookieType.Ltoken) .TryCatchGetFromJsonAsync>>(url, options, logger, token) .ConfigureAwait(false); @@ -59,10 +59,11 @@ internal class BindingClient /// 用户 /// 取消令牌 /// 用户角色信息 - public async Task> GetUserGameRolesAsync(Model.Entity.User user, CancellationToken token = default) + [ApiInformation(Cookie = CookieType.Ltoken)] + public async Task> GetUserGameRolesAsync(User user, CancellationToken token = default) { Response>? resp = await httpClient - .SetUser(user) + .SetUser(user, CookieType.Ltoken) .TryCatchGetFromJsonAsync>>(ApiEndpoints.UserGameRolesByCookie, options, logger, token) .ConfigureAwait(false); 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 85f7b96a..3d81b1a5 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 @@ -2,7 +2,7 @@ // Licensed under the MIT license. using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient; -using Snap.Hutao.Model.Binding.User; +using Snap.Hutao.Model.Entity; using Snap.Hutao.Web.Hoyolab.DynamicSecret; using Snap.Hutao.Web.Response; using System.Net.Http; @@ -43,9 +43,9 @@ internal class BindingClient2 public async Task GenerateAuthenticationKeyAsync(User user, GenAuthKeyData data, CancellationToken token = default) { Response? resp = await httpClient - .SetUser(user) + .SetUser(user, CookieType.Stoken) .SetReferer("https://app.mihoyo.com") - .UsingDynamicSecret1() + .UsingDynamicSecret1(SaltType.LK2) .TryCatchPostAsJsonAsync>(ApiEndpoints.GenAuthKey, data, options, logger, token) .ConfigureAwait(false); diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/PlayerRole.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/BasicRoleInfo.cs similarity index 96% rename from src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/PlayerRole.cs rename to src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/BasicRoleInfo.cs index c944e0d0..9abfa07c 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/PlayerRole.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/BasicRoleInfo.cs @@ -6,7 +6,7 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord; /// /// 玩家的主角信息 /// -public class PlayerRole +public class BasicRoleInfo { /// /// 角色图标Url 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 8f074bf6..d83740bd 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 @@ -3,7 +3,8 @@ using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient; using Snap.Hutao.Extension; -using Snap.Hutao.Model.Binding.User; +using Snap.Hutao.Model.Entity; +using Snap.Hutao.Web.Hoyolab.Annotation; using Snap.Hutao.Web.Hoyolab.DynamicSecret; using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.Avatar; using Snap.Hutao.Web.Response; @@ -41,47 +42,18 @@ internal class GameRecordClient /// 查询uid /// 取消令牌 /// 实时便笺 - public async Task GetDialyNoteAsync(User user, PlayerUid uid, CancellationToken token = default) + [ApiInformation(Cookie = CookieType.Ltoken, Salt = SaltType.X4)] + public async Task GetDailyNoteAsync(User user, PlayerUid uid, CancellationToken token = default) { Response? resp = await httpClient - .SetUser(user) - .UsingDynamicSecret2(options, ApiEndpoints.GameRecordDailyNote(uid.Value, uid.Region)) + .SetUser(user, CookieType.Ltoken) + .UsingDynamicSecret2(SaltType.X4, options, ApiEndpoints.GameRecordDailyNote(uid.Value, uid.Region)) .GetFromJsonAsync>(token) .ConfigureAwait(false); return resp?.Data; } - /// - /// 异步获取实时便笺 - /// - /// 用户 - /// 查询uid - /// 取消令牌 - /// 实时便笺 - public async Task GetDialyNoteAsync(Model.Entity.User user, PlayerUid uid, CancellationToken token = default) - { - Response? resp = await httpClient - .SetUser(user) - .UsingDynamicSecret2(options, ApiEndpoints.GameRecordDailyNote(uid.Value, uid.Region)) - .GetFromJsonAsync>(token) - .ConfigureAwait(false); - - return resp?.Data; - } - - /// - /// 获取玩家基础信息 - /// - /// 用户 - /// 取消令牌 - /// 玩家的基础信息 - public Task GetPlayerInfoAsync(User user, CancellationToken token = default) - { - PlayerUid uid = (PlayerUid)Must.NotNull(user.SelectedUserGameRole!); - return GetPlayerInfoAsync(user, uid, token); - } - /// /// 获取玩家基础信息 /// @@ -89,30 +61,18 @@ internal class GameRecordClient /// uid /// 取消令牌 /// 玩家的基础信息 + [ApiInformation(Cookie = CookieType.Ltoken, Salt = SaltType.X4)] public async Task GetPlayerInfoAsync(User user, PlayerUid uid, CancellationToken token = default) { Response? resp = await httpClient - .SetUser(user) - .UsingDynamicSecret2(options, ApiEndpoints.GameRecordIndex(uid.Value, uid.Region)) + .SetUser(user, CookieType.Ltoken) + .UsingDynamicSecret2(SaltType.X4, options, ApiEndpoints.GameRecordIndex(uid.Value, uid.Region)) .GetFromJsonAsync>(token) .ConfigureAwait(false); return resp?.Data; } - /// - /// 获取玩家深渊信息 - /// - /// 用户 - /// 期 - /// 取消令牌 - /// 深渊信息 - public Task GetSpiralAbyssAsync(User user, SpiralAbyssSchedule schedule, CancellationToken token = default) - { - PlayerUid uid = (PlayerUid)Must.NotNull(user.SelectedUserGameRole!); - return GetSpiralAbyssAsync(user, uid, schedule, token); - } - /// /// 获取玩家深渊信息 /// @@ -121,30 +81,37 @@ internal class GameRecordClient /// 1:当期,2:上期 /// 取消令牌 /// 深渊信息 + [ApiInformation(Cookie = CookieType.Ltoken, Salt = SaltType.X4)] public async Task GetSpiralAbyssAsync(User user, PlayerUid uid, SpiralAbyssSchedule schedule, CancellationToken token = default) { Response? resp = await httpClient - .SetUser(user) - .UsingDynamicSecret2(options, ApiEndpoints.GameRecordSpiralAbyss(schedule, uid)) + .SetUser(user, CookieType.Ltoken) + .UsingDynamicSecret2(SaltType.X4, options, ApiEndpoints.GameRecordSpiralAbyss(schedule, uid)) .GetFromJsonAsync>(token) .ConfigureAwait(false); return resp?.Data; } - /// - /// 获取玩家角色详细信息 - /// - /// 用户 - /// 玩家的基础信息 - /// 取消令牌 - /// 角色列表 - public Task> GetCharactersAsync(User user, PlayerInfo playerInfo, CancellationToken token = default) - { - PlayerUid uid = (PlayerUid)Must.NotNull(user.SelectedUserGameRole!); - return GetCharactersAsync(user, uid, playerInfo, token); - } - + /// + /// 异步获取角色基本信息 + /// + /// 用户 + /// uid + /// 取消令牌 + /// 角色基本信息 + [ApiInformation(Cookie = CookieType.Ltoken, Salt = SaltType.X4)] + public async Task GetRoleBasicInfoAsync(User user, PlayerUid uid, CancellationToken token = default) + { + Response? resp = await httpClient + .SetUser(user, CookieType.Ltoken) + .UsingDynamicSecret2(SaltType.X4, options, ApiEndpoints.GameRecordRoleBasicInfo(uid)) + .TryCatchGetFromJsonAsync>(logger, token) + .ConfigureAwait(false); + + return resp?.Data; + } + /// /// 获取玩家角色详细信息 /// @@ -153,13 +120,14 @@ internal class GameRecordClient /// 玩家的基础信息 /// 取消令牌 /// 角色列表 + [ApiInformation(Cookie = CookieType.Ltoken, Salt = SaltType.X4)] public async Task> GetCharactersAsync(User user, PlayerUid uid, PlayerInfo playerInfo, CancellationToken token = default) { CharacterData data = new(uid, playerInfo.Avatars.Select(x => x.Id)); Response? resp = await httpClient - .SetUser(user) - .UsingDynamicSecret2(options, ApiEndpoints.GameRecordCharacter, data) + .SetUser(user, CookieType.Ltoken) + .UsingDynamicSecret2(SaltType.X4, options, ApiEndpoints.GameRecordCharacter, data) .TryCatchPostAsJsonAsync>(logger, token) .ConfigureAwait(false); diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/PlayerInfo.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/PlayerInfo.cs index 7d05d01c..45f3f73b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/PlayerInfo.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/PlayerInfo.cs @@ -12,7 +12,7 @@ public class PlayerInfo /// 玩家的角色信息 /// [JsonPropertyName("role")] - public PlayerRole Role { get; set; } = default!; + public BasicRoleInfo Role { get; set; } = default!; /// /// 持有的角色的信息 diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaClient.cs index b4a9169d..faf9349a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/HomaClient.cs @@ -175,21 +175,23 @@ internal class HomaClient /// 玩家记录 public async Task GetPlayerRecordAsync(User user, CancellationToken token = default) { + Must.NotNull(user.SelectedUserGameRole!); + PlayerInfo? playerInfo = await gameRecordClient - .GetPlayerInfoAsync(user, token) + .GetPlayerInfoAsync(user.Entity, user.SelectedUserGameRole, token) .ConfigureAwait(false); Must.NotNull(playerInfo!); List characters = await gameRecordClient - .GetCharactersAsync(user, playerInfo, token) + .GetCharactersAsync(user.Entity, user.SelectedUserGameRole, playerInfo, token) .ConfigureAwait(false); SpiralAbyss? spiralAbyssInfo = await gameRecordClient - .GetSpiralAbyssAsync(user, SpiralAbyssSchedule.Current, token) + .GetSpiralAbyssAsync(user.Entity, user.SelectedUserGameRole, SpiralAbyssSchedule.Current, token) .ConfigureAwait(false); Must.NotNull(spiralAbyssInfo!); - return new(Must.NotNull(user.SelectedUserGameRole!).GameUid, characters, spiralAbyssInfo); + return new(user.SelectedUserGameRole.GameUid, characters, spiralAbyssInfo); } ///