diff --git a/src/Snap.Hutao/Snap.Hutao/Core/CoreEnvironment.cs b/src/Snap.Hutao/Snap.Hutao/Core/CoreEnvironment.cs index 738242ee..d7068aae 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/CoreEnvironment.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/CoreEnvironment.cs @@ -17,14 +17,24 @@ internal static class CoreEnvironment // 计算过程:https://github.com/UIGF-org/Hoyolab.Salt /// - /// 动态密钥1的盐 + /// 动态密钥1的K2盐 /// - public const string DynamicSecret1Salt = "jEpJb9rRARU2rXDA9qYbZ3selxkuct9a"; + public const string DynamicSecretK2Salt = "fdv0fY9My9eA7MR0NpjGP9RjueFvjUSQ"; /// - /// 动态密钥2的盐 + /// 动态密钥1的LK2盐 /// - public const string DynamicSecret2Salt = "xV8v4Qu54lUKrEYFZkJhB8cuOh9Asafs"; + public const string DynamicSecretLK2Salt = "jEpJb9rRARU2rXDA9qYbZ3selxkuct9a"; + + /// + /// 动态密钥2的X4盐 + /// + public const string DynamicSecretX4Salt = "xV8v4Qu54lUKrEYFZkJhB8cuOh9Asafs"; + + /// + /// 动态密钥2的X6盐 + /// + public const string DynamicSecretX6Salt = "t0qEgfub6cvueAPgR5m9aQWWVciEer7v"; /// /// 米游社请求UA 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 e531a250..2f0f58f5 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Annotation/ApiInformationAttribute.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Annotation/ApiInformationAttribute.cs @@ -1,6 +1,7 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using Snap.Hutao.Web.Hoyolab.DynamicSecret; using System; using System.Collections.Generic; using System.Linq; @@ -20,4 +21,9 @@ internal class ApiInformationAttribute : Attribute /// Cookie类型 /// public CookieType Cookie { get; set; } + + /// + /// SALT + /// + public SaltType Salt { get; set; } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/ApiEndpoints.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/ApiEndpoints.cs index 41286916..8595699c 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/ApiEndpoints.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/ApiEndpoints.cs @@ -145,6 +145,14 @@ internal static class ApiEndpoints // https://sdk-static.mihoyo.com/hk4e_cn/mdk/launcher/api/content?key=eYd89JmJ&language=zh-cn&launcher_id=18 #endregion + #region ma-cn-session + + /// + /// 验证 Ltoken 有效性 + /// + public const string AccountVerifyLtoken = $"{PassportApiV4}/account/ma-cn-session/web/verifyLtoken"; + #endregion + #region App /// @@ -171,6 +179,8 @@ internal static class ApiEndpoints private const string Hk4eApiAnnouncementApi = $"{Hk4eApi}/common/hk4e_cn/announcement/api"; private const string Hk4eApiGachaInfoApi = $"{Hk4eApi}/event/gacha_info/api"; + private const string PassportApiV4 = "passport-api-v4.mihoyo.com"; + private const string SdkStatic = "https://sdk-static.mihoyo.com"; private const string SdkStaticLauncherApi = $"{SdkStatic}/hk4e_cn/mdk/launcher/api"; diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/App/GameRecord/CardClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/App/GameRecord/CardClient.cs index 200fafd3..dced6c50 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/App/GameRecord/CardClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/App/GameRecord/CardClient.cs @@ -4,6 +4,7 @@ using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient; using Snap.Hutao.Model.Entity; using Snap.Hutao.Web.Hoyolab.Annotation; +using Snap.Hutao.Web.Hoyolab.DynamicSecret; using Snap.Hutao.Web.Response; using System.Net.Http; @@ -23,7 +24,7 @@ internal class CardClient /// 构造一个新的桌面卡片客户端 /// /// http客户端 - /// 选项 + /// json序列化选项 /// 日志器 public CardClient(HttpClient httpClient, JsonSerializerOptions options, ILogger logger) { @@ -38,12 +39,13 @@ internal class CardClient /// 用户 /// 取消令牌 /// 桌面小组件数据 - [ApiInformation(Cookie = CookieType.Stoken)] + [ApiInformation(Cookie = CookieType.Stoken, Salt = SaltType.X6)] public async Task GetWidgetDataAsync(User user, CancellationToken token) { Response>? resp = await httpClient .SetUser(user, CookieType.Stoken) - .TryCatchGetFromJsonAsync>>(ApiEndpoints.UserFullInfo, options, logger, token) + .UsingDynamicSecret2(SaltType.X6, options, ApiEndpoints.AppWidgetData) + .TryCatchGetFromJsonAsync>>(logger, token) .ConfigureAwait(false); return resp?.Data?.Data; diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Cookie.Constant.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Cookie.Constant.cs index bdbae465..29438b66 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Cookie.Constant.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Cookie.Constant.cs @@ -10,8 +10,10 @@ namespace Snap.Hutao.Web.Hoyolab; [SuppressMessage("", "SA1600")] public partial class Cookie { - public const string COOKIE_TOKEN = "cookie_token"; public const string ACCOUNT_ID = "account_id"; + public const string COOKIE_TOKEN = "cookie_token"; + + public const string E_HK4E_TOKEN = "e_hk4e_token"; public const string LOGIN_TICKET = "login_ticket"; public const string LOGIN_UID = "login_uid"; @@ -19,8 +21,8 @@ public partial class Cookie public const string LTOKEN = "ltoken"; public const string LTUID = "ltuid"; + public const string MID = "mid"; + public const string STOKEN = "stoken"; public const string STUID = "stuid"; - - public const string MID = "mid"; } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretProvider.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretProvider.cs index aad9294f..2d0bc6a6 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretProvider.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretProvider.cs @@ -16,15 +16,19 @@ internal abstract class DynamicSecretProvider : Md5Convert /// /// 创建动态密钥 /// + /// SALT 类型 /// 密钥 - public static string Create() + public static string Create(SaltType saltType) { + Verify.Operation(saltType is SaltType.K2 or SaltType.LK2, "SALT 值无效"); + // unix timestamp long t = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); string r = GetRandomString(); - string check = ToHexString($"salt={Core.CoreEnvironment.DynamicSecret1Salt}&t={t}&r={r}").ToLowerInvariant(); + string salt = saltType == SaltType.K2 ? Core.CoreEnvironment.DynamicSecretK2Salt : Core.CoreEnvironment.DynamicSecretLK2Salt; + string check = ToHexString($"salt={salt}&t={t}&r={r}").ToLowerInvariant(); return $"{t},{r},{check}"; } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretProvider2.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretProvider2.cs index b71e760b..0a1d3ed2 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretProvider2.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretProvider2.cs @@ -13,12 +13,15 @@ internal abstract class DynamicSecretProvider2 : Md5Convert /// /// 创建动态密钥 /// + /// SALT 类型 /// json格式化器 /// 查询url /// 请求体 /// 密钥 - public static string Create(JsonSerializerOptions options, string queryUrl, object? postBody = null) + public static string Create(SaltType saltType, JsonSerializerOptions options, string queryUrl, object? postBody = null) { + Verify.Operation(saltType is SaltType.X6 or SaltType.X4, "SALT 值无效"); + // unix timestamp long t = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); @@ -33,7 +36,8 @@ internal abstract class DynamicSecretProvider2 : Md5Convert string q = queries.Length == 2 ? string.Join('&', queries[1].Split('&').OrderBy(x => x)) : string.Empty; // check - string check = ToHexString($"salt={Core.CoreEnvironment.DynamicSecret2Salt}&t={t}&r={r}&b={b}&q={q}").ToLowerInvariant(); + string salt = saltType == SaltType.X6 ? Core.CoreEnvironment.DynamicSecretX6Salt : Core.CoreEnvironment.DynamicSecretX4Salt; + string check = ToHexString($"salt={salt}&t={t}&r={r}&b={b}&q={q}").ToLowerInvariant(); return $"{t},{r},{check}"; } 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 badbe5c1..31fe098b 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 @@ -1,6 +1,7 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using Snap.Hutao.Core.Logging; using Snap.Hutao.Web.Request; using System.Net.Http; using System.Net.Http.Json; @@ -14,6 +15,7 @@ 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; @@ -21,12 +23,13 @@ internal class DynamicSecretHttpClient : IDynamicSecretHttpClient /// 构造一个新的使用动态密钥2的Http客户端默认实现的实例 /// /// 请求使用的客户端 + /// SALT 类型 /// Json序列化选项 /// url - /// 请求的数据 - public DynamicSecretHttpClient(HttpClient httpClient, JsonSerializerOptions options, string url) + public DynamicSecretHttpClient(HttpClient httpClient, SaltType saltType, JsonSerializerOptions options, string url) { this.httpClient = httpClient; + this.saltType = saltType; this.options = options; this.url = url; @@ -38,6 +41,35 @@ internal class DynamicSecretHttpClient : IDynamicSecretHttpClient { return httpClient.GetFromJsonAsync(url, options, token); } + + /// + public async Task TryCatchGetFromJsonAsync(CancellationToken token = default) + where T : class + { + try + { + return await httpClient.GetFromJsonAsync(url, options, token).ConfigureAwait(false); + } + catch + { + return null; + } + } + + /// + public async Task TryCatchGetFromJsonAsync(ILogger logger, CancellationToken token = default) + where T : class + { + try + { + return await httpClient.GetFromJsonAsync(url, options, token).ConfigureAwait(false); + } + catch (HttpRequestException ex) + { + logger.LogWarning(EventIds.HttpException, ex, "请求异常已忽略"); + return null; + } + } } /// @@ -49,6 +81,7 @@ internal class DynamicSecretHttpClient : IDynamicSecretHttpClient : IDynamicSecretHttpClient /// 请求使用的客户端 + /// SALT 类型 /// Json序列化选项 /// url /// 请求的数据 - public DynamicSecretHttpClient(HttpClient httpClient, JsonSerializerOptions options, string url, TValue data) + public DynamicSecretHttpClient(HttpClient httpClient, SaltType saltType, JsonSerializerOptions options, string url, TValue data) { this.httpClient = httpClient; + this.saltType = saltType; this.options = options; this.url = url; this.data = data; diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/Http/IDynamicSecretHttpClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/Http/IDynamicSecretHttpClient.cs index ed42a578..9d67ede1 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/Http/IDynamicSecretHttpClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/Http/IDynamicSecretHttpClient.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. using System.Net.Http; +using System.Net.Http.Json; namespace Snap.Hutao.Web.Hoyolab.DynamicSecret.Http; @@ -17,6 +18,14 @@ internal interface IDynamicSecretHttpClient /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. /// The task object representing the asynchronous operation. Task GetFromJsonAsync(CancellationToken token); + + /// + Task TryCatchGetFromJsonAsync(CancellationToken token = default) + where T : class; + + /// + Task TryCatchGetFromJsonAsync(ILogger logger, CancellationToken token = default(CancellationToken)) + where T : class; } /// diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/HttpClientDynamicSecretExtensions.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/HttpClientDynamicSecretExtensions.cs index a255b28b..e1c2bd02 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/HttpClientDynamicSecretExtensions.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/HttpClientDynamicSecretExtensions.cs @@ -13,40 +13,43 @@ namespace Snap.Hutao.Web.Hoyolab.DynamicSecret; internal static class HttpClientDynamicSecretExtensions { /// - /// 使用一代动态密钥执行 GET 操作 + /// 使用一代动态密钥执行 GET/POST 操作 /// /// 请求器 + /// SALT 类型 /// 响应 - public static HttpClient UsingDynamicSecret(this HttpClient httpClient) + public static HttpClient UsingDynamicSecret1(this HttpClient httpClient, SaltType type) { - httpClient.DefaultRequestHeaders.Set("DS", DynamicSecretProvider.Create()); + httpClient.DefaultRequestHeaders.Set("DS", DynamicSecretProvider.Create(type)); return httpClient; } /// - /// 使用二代动态密钥执行 GET 操作 + /// 使用二代动态密钥执行 GET/POST 操作 /// /// 请求器 + /// SALT 类型 /// 选项 /// 地址 /// 响应 - public static IDynamicSecretHttpClient UsingDynamicSecret(this HttpClient httpClient, JsonSerializerOptions options, string url) + public static IDynamicSecretHttpClient UsingDynamicSecret2(this HttpClient httpClient, SaltType type, JsonSerializerOptions options, string url) { - return new DynamicSecretHttpClient(httpClient, options, url); + return new DynamicSecretHttpClient(httpClient, type, options, url); } /// - /// 使用二代动态密钥执行 GET 操作 + /// 使用二代动态密钥执行 GET/POST 操作 /// /// 请求数据的类型 /// 请求器 + /// SALT 类型 /// 选项 /// 地址 /// post数据 /// 响应 - public static IDynamicSecretHttpClient UsingDynamicSecret(this HttpClient httpClient, JsonSerializerOptions options, string url, TValue data) + public static IDynamicSecretHttpClient UsingDynamicSecret2(this HttpClient httpClient, SaltType type, JsonSerializerOptions options, string url, TValue data) where TValue : class { - return new DynamicSecretHttpClient(httpClient, options, url, data); + return new DynamicSecretHttpClient(httpClient, type, options, url, data); } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/SaltType.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/SaltType.cs new file mode 100644 index 00000000..a8582f31 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/SaltType.cs @@ -0,0 +1,35 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Web.Hoyolab.DynamicSecret; + +/// +/// Salt's type +/// +public enum SaltType +{ + /// + /// 不需要 SALT + /// + None, + + /// + /// X4 + /// + X4, + + /// + /// X6 + /// + X6, + + /// + /// K2 + /// + K2, + + /// + /// LK2 + /// + LK2, +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HttpClientExtensions.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HttpClientExtensions.cs index 4bf2b8c0..795977a3 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HttpClientExtensions.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HttpClientExtensions.cs @@ -3,6 +3,7 @@ using Snap.Hutao.Core.Logging; using Snap.Hutao.Model.Binding.User; +using Snap.Hutao.Web.Hoyolab.DynamicSecret; using Snap.Hutao.Web.Request; using System.Net.Http; using System.Net.Http.Json; @@ -66,7 +67,7 @@ internal static class HttpClientExtensions /// http客户端 /// 绑定用户 /// 客户端 - [Obsolete("请使用带有 type 的重载")] + [Obsolete("请使用带有 cookie 的重载")] internal static HttpClient SetUser(this HttpClient httpClient, User user) { httpClient.DefaultRequestHeaders.Set("Cookie", user.Cookie!.ToString()); @@ -78,11 +79,11 @@ internal static class HttpClientExtensions /// /// http客户端 /// 实体用户 - /// Cookie类型 + /// Cookie类型 /// 客户端 - internal static HttpClient SetUser(this HttpClient httpClient, Model.Entity.User user, CookieType type = CookieType.All) + internal static HttpClient SetUser(this HttpClient httpClient, Model.Entity.User user, CookieType cookie = CookieType.All) { - httpClient.DefaultRequestHeaders.Set("Cookie", user.Cookie!.ToString(type)); + httpClient.DefaultRequestHeaders.Set("Cookie", user.Cookie!.ToString(cookie)); return httpClient; } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/Link.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/Link.cs new file mode 100644 index 00000000..bf321f30 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/Link.cs @@ -0,0 +1,32 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient; +using Snap.Hutao.Web.Response; +using System.Net.Http; + +namespace Snap.Hutao.Web.Hoyolab.Passport; + +/// +/// 链接 +/// +public class Link +{ + /// + /// 第三方 sn + /// + [JsonPropertyName("thirdparty")] + public string Thirdparty { get; set; } = default!; + + /// + /// Union Id + /// + [JsonPropertyName("union_id")] + public string UnionId { get; set; } = default!; + + /// + /// 昵称 + /// + [JsonPropertyName("nickname")] + public string Nickname { get; set; } = default!; +} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/PassportClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/PassportClient.cs new file mode 100644 index 00000000..95d01174 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/PassportClient.cs @@ -0,0 +1,62 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient; +using Snap.Hutao.Model.Entity; +using Snap.Hutao.Web.Hoyolab.Annotation; +using Snap.Hutao.Web.Response; +using System.Net.Http; + +namespace Snap.Hutao.Web.Hoyolab.Passport; + +/// +/// 通行证客户端 +/// +[HttpClient(HttpClientConfigration.Default)] +internal class PassportClient +{ + private readonly HttpClient httpClient; + private readonly JsonSerializerOptions options; + private readonly ILogger logger; + + /// + /// 构造一个新的通行证客户端 + /// + /// http客户端 + /// json序列化选项 + /// 日志器 + public PassportClient(HttpClient httpClient, JsonSerializerOptions options, ILogger logger) + { + this.httpClient = httpClient; + this.options = options; + this.logger = logger; + } + + /// + /// 异步验证Ltoken + /// + /// 用户 + /// 取消令牌 + /// 验证信息 + [ApiInformation(Cookie = CookieType.All)] + public async Task VerifyLtokenAsync(User user, CancellationToken token) + { + Response? response = await httpClient + .SetUser(user, CookieType.All) + .TryCatchPostAsJsonAsync>(ApiEndpoints.AccountVerifyLtoken, new(), options, logger, token) + .ConfigureAwait(false); + + return response?.Data; + } + + private class Timestamp + { + public Timestamp() + { + T = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + } + + [JsonPropertyName("t")] + public long T { get; set; } + } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/VerifyInformation.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/VerifyInformation.cs new file mode 100644 index 00000000..46a170b1 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Passport/VerifyInformation.cs @@ -0,0 +1,104 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient; +using Snap.Hutao.Web.Response; +using System.Net.Http; + +namespace Snap.Hutao.Web.Hoyolab.Passport; + +/// +/// 验证返回信息 +/// +public class VerifyInformation +{ + /// + /// 账户Id + /// + [JsonPropertyName("aid")] + public string Aid { get; set; } = default!; + + /// + /// 米哈游Id + /// + [JsonPropertyName("mid")] + public string Mid { get; set; } = default!; + + /// + /// 空 + /// + [JsonPropertyName("account_name")] + public string AccountName { get; set; } = default!; + + /// + /// 空 + /// + [JsonPropertyName("email")] + public string Email { get; set; } = default!; + + /// + /// 是否为邮箱验证 + /// + [JsonPropertyName("is_email_verify")] + public int IsEmailVerify { get; set; } = default!; + + /// + /// 区域码 +86 + /// + [JsonPropertyName("area_code")] + public string AreaCode { get; set; } = default!; + + /// + /// 手机号 111****1111 + /// + [JsonPropertyName("mobile")] + public string Mobile { get; set; } = default!; + + /// + /// 安全手机区域码 +86 + /// + [JsonPropertyName("safe_area_code")] + public string SafeAreaCode { get; set; } = default!; + + /// + /// 安全手机号 111****1111 + /// + [JsonPropertyName("safe_mobile")] + public string SafeMobile { get; set; } = default!; + + /// + /// 真名 **某 + /// + [JsonPropertyName("realname")] + public string Realname { get; set; } = default!; + + /// + /// 身份证号 111************111 + /// + [JsonPropertyName("identity_code")] + public string IdentityCode { get; set; } = default!; + + /// + /// 重新绑定区域码 + /// + [JsonPropertyName("rebind_area_code")] + public string RebindAreaCode { get; set; } = default!; + + /// + /// 重新绑定的手机号 + /// + [JsonPropertyName("rebind_mobile")] + public string RebindMobile { get; set; } = default!; + + /// + /// 重新绑定时间 "0" + /// + [JsonPropertyName("rebind_mobile_time")] + public string RebindMobileTime { get; set; } = default!; + + /// + /// 链接 + /// + [JsonPropertyName("links")] + public List Links { get; set; } = default!; +} \ No newline at end of file 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 22d73332..85f7b96a 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 @@ -45,7 +45,7 @@ internal class BindingClient2 Response? resp = await httpClient .SetUser(user) .SetReferer("https://app.mihoyo.com") - .UsingDynamicSecret() + .UsingDynamicSecret1() .TryCatchPostAsJsonAsync>(ApiEndpoints.GenAuthKey, data, options, logger, token) .ConfigureAwait(false); 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 90bdcd29..8f074bf6 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 @@ -45,7 +45,7 @@ internal class GameRecordClient { Response? resp = await httpClient .SetUser(user) - .UsingDynamicSecret(options, ApiEndpoints.GameRecordDailyNote(uid.Value, uid.Region)) + .UsingDynamicSecret2(options, ApiEndpoints.GameRecordDailyNote(uid.Value, uid.Region)) .GetFromJsonAsync>(token) .ConfigureAwait(false); @@ -63,7 +63,7 @@ internal class GameRecordClient { Response? resp = await httpClient .SetUser(user) - .UsingDynamicSecret(options, ApiEndpoints.GameRecordDailyNote(uid.Value, uid.Region)) + .UsingDynamicSecret2(options, ApiEndpoints.GameRecordDailyNote(uid.Value, uid.Region)) .GetFromJsonAsync>(token) .ConfigureAwait(false); @@ -93,7 +93,7 @@ internal class GameRecordClient { Response? resp = await httpClient .SetUser(user) - .UsingDynamicSecret(options, ApiEndpoints.GameRecordIndex(uid.Value, uid.Region)) + .UsingDynamicSecret2(options, ApiEndpoints.GameRecordIndex(uid.Value, uid.Region)) .GetFromJsonAsync>(token) .ConfigureAwait(false); @@ -125,7 +125,7 @@ internal class GameRecordClient { Response? resp = await httpClient .SetUser(user) - .UsingDynamicSecret(options, ApiEndpoints.GameRecordSpiralAbyss(schedule, uid)) + .UsingDynamicSecret2(options, ApiEndpoints.GameRecordSpiralAbyss(schedule, uid)) .GetFromJsonAsync>(token) .ConfigureAwait(false); @@ -159,7 +159,7 @@ internal class GameRecordClient Response? resp = await httpClient .SetUser(user) - .UsingDynamicSecret(options, ApiEndpoints.GameRecordCharacter, data) + .UsingDynamicSecret2(options, ApiEndpoints.GameRecordCharacter, data) .TryCatchPostAsJsonAsync>(logger, token) .ConfigureAwait(false);