mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
support Action Ticket for #207
This commit is contained in:
@@ -137,7 +137,7 @@ public class User : ObservableObject
|
||||
.ConfigureAwait(false);
|
||||
|
||||
UserGameRoles = await userGameRoleClient
|
||||
.GetUserGameRolesAsync(this, token)
|
||||
.GetUserGameRolesAsync(Entity, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
SelectedUserGameRole = UserGameRoles.FirstOrFirstOrDefault(role => role.IsChosen);
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Web.Hoyolab.DynamicSecret;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.Annotation;
|
||||
|
||||
@@ -15,7 +10,7 @@ namespace Snap.Hutao.Web.Hoyolab.Annotation;
|
||||
/// </summary>
|
||||
/// <typeparam name="TReturnType">API 的返回类型</typeparam>
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
internal class ApiInformationAttribute<TReturnType> : Attribute
|
||||
internal class ApiInformationAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Cookie类型
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab;
|
||||
|
||||
/// <summary>
|
||||
@@ -105,7 +107,17 @@ internal static class ApiEndpoints
|
||||
/// <summary>
|
||||
/// 用户游戏角色
|
||||
/// </summary>
|
||||
public const string UserGameRoles = $"{ApiTaKumiBindingApi}/getUserGameRolesByCookie?game_biz=hk4e_cn";
|
||||
/// <param name="actionTicket">操作凭证</param>
|
||||
/// <returns>用户游戏角色字符串</returns>
|
||||
public static string UserGameRolesByActionTicket(string actionTicket)
|
||||
{
|
||||
return $"{ApiTaKumiBindingApi}/getUserGameRolesByCookie?action_ticket={actionTicket}&game_biz=hk4e_cn";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用户游戏角色
|
||||
/// </summary>
|
||||
public const string UserGameRolesByCookie = $"{ApiTaKumiBindingApi}/getUserGameRolesByCookie?game_biz=hk4e_cn";
|
||||
|
||||
/// <summary>
|
||||
/// AuthKey
|
||||
@@ -115,6 +127,18 @@ internal static class ApiEndpoints
|
||||
|
||||
#region Auth
|
||||
|
||||
/// <summary>
|
||||
/// 获取 stoken 与 ltoken
|
||||
/// </summary>
|
||||
/// <param name="actionType">操作类型 game_role</param>
|
||||
/// <param name="stoken">Stoken</param>
|
||||
/// <param name="uid">uid</param>
|
||||
/// <returns>Url</returns>
|
||||
public static string AuthActionTicket(string actionType, string stoken, string uid)
|
||||
{
|
||||
return $"{ApiTakumiAuthApi}/getMultiTokenByLoginTicket?action_type={actionType}&stoken={Uri.EscapeDataString(stoken)}&uid={uid}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 stoken 与 ltoken
|
||||
/// </summary>
|
||||
|
||||
@@ -39,7 +39,7 @@ internal class CardClient
|
||||
/// <param name="user">用户</param>
|
||||
/// <param name="token">取消令牌</param>
|
||||
/// <returns>桌面小组件数据</returns>
|
||||
[ApiInformation<WidgetData>(Cookie = CookieType.Stoken, Salt = SaltType.X6)]
|
||||
[ApiInformation(Cookie = CookieType.Stoken, Salt = SaltType.X6)]
|
||||
public async Task<WidgetData?> GetWidgetDataAsync(User user, CancellationToken token)
|
||||
{
|
||||
Response<DataWrapper<WidgetData>>? resp = await httpClient
|
||||
|
||||
@@ -13,6 +13,11 @@ public enum CookieType
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// 需要 Ltoken 与 e_hk4e_token
|
||||
/// </summary>
|
||||
Ltoken,
|
||||
|
||||
/// <summary>
|
||||
/// 需要 Stoken
|
||||
/// </summary>
|
||||
|
||||
@@ -38,7 +38,7 @@ internal class PassportClient
|
||||
/// <param name="user">用户</param>
|
||||
/// <param name="token">取消令牌</param>
|
||||
/// <returns>验证信息</returns>
|
||||
[ApiInformation<VerifyInformation>(Cookie = CookieType.All)]
|
||||
[ApiInformation(Cookie = CookieType.All)]
|
||||
public async Task<VerifyInformation?> VerifyLtokenAsync(User user, CancellationToken token)
|
||||
{
|
||||
Response<VerifyInformation>? response = await httpClient
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Web.Hoyolab.Takumi.Binding;
|
||||
using Snap.Hutao.Web.Response;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.Takumi.Auth;
|
||||
|
||||
/// <summary>
|
||||
/// 账户信息
|
||||
/// </summary>
|
||||
[SuppressMessage("", "SA1600")]
|
||||
public class AccountInfo
|
||||
{
|
||||
|
||||
[JsonPropertyName("is_realname")]
|
||||
public bool IsRealname { get; set; }
|
||||
|
||||
[JsonPropertyName("mobile")]
|
||||
public string Mobile { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("safe_mobile")]
|
||||
public string SafeMobile { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("account_id")]
|
||||
public string AccountId { 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 bool IsEmailVerify { get; set; }
|
||||
|
||||
[JsonPropertyName("area_code")]
|
||||
public string AreaCode { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("safe_area_code")]
|
||||
public string SafeAreaCode { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("real_name")]
|
||||
public string RealName { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("identity_code")]
|
||||
public string IdentityCode { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("create_time")]
|
||||
public string CreateTime { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("create_ip")]
|
||||
public string CreateIp { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("change_pwd_time")]
|
||||
public string ChangePwdTime { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("nickname")]
|
||||
public string Nickname { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("user_icon_id")]
|
||||
public int UserIconId { get; set; }
|
||||
|
||||
[JsonPropertyName("safe_level")]
|
||||
public int SafeLevel { get; set; }
|
||||
|
||||
[JsonPropertyName("black_endtime")]
|
||||
public string BlackEndtime { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("black_note")]
|
||||
public string BlackNote { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("gender")]
|
||||
public int Gender { get; set; }
|
||||
|
||||
[JsonPropertyName("real_stat")]
|
||||
public int RealStat { get; set; }
|
||||
|
||||
[JsonPropertyName("apple_name")]
|
||||
public string AppleName { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("sony_name")]
|
||||
public string SonyName { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("tap_name")]
|
||||
public string TapName { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("reactivate_ticket")]
|
||||
public string ReactivateTicket { get; set; } = default!;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Web.Hoyolab.Takumi.Binding;
|
||||
using Snap.Hutao.Web.Response;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.Takumi.Auth;
|
||||
|
||||
/// <summary>
|
||||
/// 操作凭证包装器
|
||||
/// </summary>
|
||||
public class ActionTicketWrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// 凭证
|
||||
/// </summary>
|
||||
[JsonPropertyName("ticket")]
|
||||
public string Ticket { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否验证
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_verified")]
|
||||
public bool IsVerified { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 账户信息
|
||||
/// </summary>
|
||||
[JsonPropertyName("account_info")]
|
||||
public AccountInfo AccountInfo { get; set; }
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
// 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.Hoyolab.Takumi.Binding;
|
||||
using Snap.Hutao.Web.Response;
|
||||
using System.Net.Http;
|
||||
@@ -31,6 +33,30 @@ internal class AuthClient
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步获取操作凭证
|
||||
/// </summary>
|
||||
/// <param name="action">操作</param>
|
||||
/// <param name="user">用户</param>
|
||||
/// <returns>操作凭证</returns>
|
||||
[ApiInformation(Cookie = CookieType.Stoken, Salt = DynamicSecret.SaltType.K2)]
|
||||
public async Task<string?> GetActionTicketByStokenAsync(string action, User user)
|
||||
{
|
||||
if (user.Cookie!.TryGetValue(Cookie.STOKEN, out string? stoken))
|
||||
{
|
||||
if (user.Cookie.TryGetUid(out string? uid))
|
||||
{
|
||||
Response<ActionTicketWrapper>? resp = await httpClient
|
||||
.TryCatchGetFromJsonAsync<Response<ActionTicketWrapper>>(ApiEndpoints.AuthActionTicket(action, stoken, uid), options, logger)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return resp.Data?.Ticket;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 MultiToken
|
||||
/// </summary>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Extension;
|
||||
using Snap.Hutao.Model.Binding.User;
|
||||
using Snap.Hutao.Web.Hoyolab.Annotation;
|
||||
using Snap.Hutao.Web.Response;
|
||||
using System.Net.Http;
|
||||
|
||||
@@ -35,12 +36,21 @@ internal class BindingClient
|
||||
/// <summary>
|
||||
/// 获取用户角色信息
|
||||
/// </summary>
|
||||
/// <param name="actionTicket">操作凭证</param>
|
||||
/// <param name="user">用户</param>
|
||||
/// <param name="token">取消令牌</param>
|
||||
/// <returns>用户角色信息</returns>
|
||||
public Task<List<UserGameRole>> GetUserGameRolesAsync(User user, CancellationToken token = default)
|
||||
[ApiInformation(Cookie = CookieType.Ltoken)]
|
||||
public async Task<List<UserGameRole>> GetUserGameRolesAsync(string actionTicket, Model.Entity.User user, CancellationToken token = default)
|
||||
{
|
||||
return GetUserGameRolesAsync(user.Entity, token);
|
||||
string url = ApiEndpoints.UserGameRolesByActionTicket(actionTicket);
|
||||
|
||||
Response<ListWrapper<UserGameRole>>? resp = await httpClient
|
||||
.SetUser(user)
|
||||
.TryCatchGetFromJsonAsync<Response<ListWrapper<UserGameRole>>>(url, options, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return EnumerableExtension.EmptyIfNull(resp?.Data?.List);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -53,7 +63,7 @@ internal class BindingClient
|
||||
{
|
||||
Response<ListWrapper<UserGameRole>>? resp = await httpClient
|
||||
.SetUser(user)
|
||||
.TryCatchGetFromJsonAsync<Response<ListWrapper<UserGameRole>>>(ApiEndpoints.UserGameRoles, options, logger, token)
|
||||
.TryCatchGetFromJsonAsync<Response<ListWrapper<UserGameRole>>>(ApiEndpoints.UserGameRolesByCookie, options, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return EnumerableExtension.EmptyIfNull(resp?.Data?.List);
|
||||
|
||||
Reference in New Issue
Block a user