mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
phase 3
This commit is contained in:
@@ -4723,7 +4723,7 @@ namespace Snap.Hutao.Resource.Localization {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Cookie 操作 的本地化字符串。
|
||||
/// 查找类似 米游社 的本地化字符串。
|
||||
/// </summary>
|
||||
internal static string ViewUserCookieOperation {
|
||||
get {
|
||||
|
||||
@@ -1639,7 +1639,7 @@
|
||||
<value>工具</value>
|
||||
</data>
|
||||
<data name="ViewUserCookieOperation" xml:space="preserve">
|
||||
<value>Cookie 操作</value>
|
||||
<value>米游社</value>
|
||||
</data>
|
||||
<data name="ViewUserCookieOperationLoginMihoyoUserAction" xml:space="preserve">
|
||||
<value>网页登录</value>
|
||||
|
||||
@@ -109,9 +109,8 @@ internal sealed class DailyNoteService : IDailyNoteService, IRecipient<UserRemov
|
||||
using (IServiceScope scope = scopeFactory.CreateScope())
|
||||
{
|
||||
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||
GameRecordClient gameRecordClient = scope.ServiceProvider.GetRequiredService<GameRecordClient>();
|
||||
GameRecordClientOversea gameRecordClientOs = scope.ServiceProvider.GetRequiredService<GameRecordClientOversea>();
|
||||
|
||||
// TODO: Add this option to AppOptions
|
||||
bool isSilentMode = appDbContext.Settings
|
||||
.SingleOrAdd(SettingEntry.DailyNoteSilentWhenPlayingGame, Core.StringLiterals.False)
|
||||
.GetBoolean();
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
HorizontalAlignment="Right"
|
||||
InputScope="Number"
|
||||
MaxLength="9"
|
||||
PlaceholderText="Please fill in your User ID here"/>
|
||||
PlaceholderText="{shcm:ResourceString Name=ViewPageLoginHoyoverseUserHint}"/>
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
Click="CookieButtonClick"
|
||||
|
||||
@@ -61,7 +61,7 @@ internal sealed partial class LoginHoyoverseUserPage : Microsoft.UI.Xaml.Control
|
||||
if (uid.Length != 9)
|
||||
{
|
||||
await ThreadHelper.SwitchToMainThreadAsync();
|
||||
infoBarService.Information($"请在页面右上方的输入框处填写你的通行证 ID!");
|
||||
infoBarService.Information(SH.ViewPageLoginHoyoverseUserHint);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ internal sealed partial class LoginHoyoverseUserPage : Microsoft.UI.Xaml.Control
|
||||
}
|
||||
|
||||
Dictionary<string, string> multiTokenMap = multiTokenResponse.Data.List.ToDictionary(n => n.Name, n => n.Token);
|
||||
Cookie hoyoLabCookie = Cookie.Parse($"stoken={multiTokenMap["stoken"]}; stuid={uid}");
|
||||
Cookie hoyoLabCookie = Cookie.Parse($"{Cookie.STUID}={uid};{Cookie.STOKEN}={multiTokenMap[Cookie.STOKEN]}");
|
||||
|
||||
// 处理 cookie 并添加用户
|
||||
(UserOptionResult result, string nickname) = await Ioc.Default
|
||||
@@ -100,16 +100,16 @@ internal sealed partial class LoginHoyoverseUserPage : Microsoft.UI.Xaml.Control
|
||||
vm.SelectedUser = vm.Users.Single();
|
||||
}
|
||||
|
||||
infoBarService.Success($"用户 [{nickname}] 添加成功");
|
||||
infoBarService.Success(string.Format(SH.ViewModelUserAdded, nickname));
|
||||
break;
|
||||
case UserOptionResult.Incomplete:
|
||||
infoBarService.Information($"此 Cookie 不完整,操作失败");
|
||||
infoBarService.Information(SH.ViewModelUserIncomplete);
|
||||
break;
|
||||
case UserOptionResult.Invalid:
|
||||
infoBarService.Information($"此 Cookie 无效,操作失败");
|
||||
infoBarService.Information(SH.ViewModelUserInvalid);
|
||||
break;
|
||||
case UserOptionResult.Updated:
|
||||
infoBarService.Success($"用户 [{nickname}] 更新成功");
|
||||
infoBarService.Success(string.Format(SH.ViewModelUserUpdated, nickname));
|
||||
break;
|
||||
default:
|
||||
throw Must.NeverHappen();
|
||||
|
||||
@@ -67,9 +67,10 @@ internal sealed partial class LoginMihoyoUserPage : Microsoft.UI.Xaml.Controls.P
|
||||
|
||||
Dictionary<string, string> multiTokenMap = multiTokenResponse.Data.List.ToDictionary(n => n.Name, n => n.Token);
|
||||
|
||||
Cookie stokenV1 = Cookie.Parse($"stuid={loginTicketCookie["login_uid"]};stoken={multiTokenMap["stoken"]}");
|
||||
Cookie stokenV1 = Cookie.Parse($"{Cookie.STUID}={loginTicketCookie[Cookie.LOGIN_UID]};{Cookie.STOKEN}={multiTokenMap[Cookie.STOKEN]}");
|
||||
|
||||
Response<LoginResult> loginResultResponse = await Ioc.Default
|
||||
.GetRequiredService<PassportClient2>()
|
||||
.GetRequiredService<PassportClient>()
|
||||
.LoginBySTokenAsync(stokenV1, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
@@ -87,6 +88,7 @@ internal sealed partial class LoginMihoyoUserPage : Microsoft.UI.Xaml.Controls.P
|
||||
Ioc.Default.GetRequiredService<INavigationService>().GoBack();
|
||||
IInfoBarService infoBarService = Ioc.Default.GetRequiredService<IInfoBarService>();
|
||||
|
||||
// TODO: Move these code somewhere else.
|
||||
switch (result)
|
||||
{
|
||||
case UserOptionResult.Added:
|
||||
@@ -97,16 +99,16 @@ internal sealed partial class LoginMihoyoUserPage : Microsoft.UI.Xaml.Controls.P
|
||||
vm.SelectedUser = vm.Users.Single();
|
||||
}
|
||||
|
||||
infoBarService.Success($"用户 [{nickname}] 添加成功");
|
||||
infoBarService.Success(string.Format(SH.ViewModelUserAdded, nickname));
|
||||
break;
|
||||
case UserOptionResult.Incomplete:
|
||||
infoBarService.Information($"此 Cookie 不完整,操作失败");
|
||||
infoBarService.Information(SH.ViewModelUserIncomplete);
|
||||
break;
|
||||
case UserOptionResult.Invalid:
|
||||
infoBarService.Information($"此 Cookie 无效,操作失败");
|
||||
infoBarService.Information(SH.ViewModelUserInvalid);
|
||||
break;
|
||||
case UserOptionResult.Updated:
|
||||
infoBarService.Success($"用户 [{nickname}] 更新成功");
|
||||
infoBarService.Success(string.Format(SH.ViewModelUserUpdated, nickname));
|
||||
break;
|
||||
default:
|
||||
throw Must.NeverHappen();
|
||||
|
||||
@@ -238,7 +238,7 @@
|
||||
Icon="{shcm:FontIcon Glyph=}"
|
||||
Label="{shcm:ResourceString Name=ViewUserCookieOperationLoginMihoyoUserAction}"/>
|
||||
<AppBarButton
|
||||
Command="{Binding AddOsUserCommand}"
|
||||
Command="{Binding AddOverseaUserCommand}"
|
||||
Icon="{shcm:FontIcon Glyph=}"
|
||||
Label="{shcm:ResourceString Name=ViewUserCookieOperationManualInputAction}"/>
|
||||
</StackPanel>
|
||||
|
||||
@@ -46,7 +46,7 @@ internal sealed class UserViewModel : ObservableObject
|
||||
|
||||
OpenUICommand = new AsyncRelayCommand(OpenUIAsync);
|
||||
AddUserCommand = new AsyncRelayCommand(AddUserAsync);
|
||||
AddOsUserCommand = new AsyncRelayCommand(AddOsUserAsync);
|
||||
AddOverseaUserCommand = new AsyncRelayCommand(AddOverseaUserAsync);
|
||||
LoginMihoyoUserCommand = new RelayCommand(LoginMihoyoUser);
|
||||
LoginHoyoverseUserCommand = new RelayCommand(LoginHoyoverseUser);
|
||||
RemoveUserCommand = new AsyncRelayCommand<User>(RemoveUserAsync);
|
||||
@@ -92,7 +92,7 @@ internal sealed class UserViewModel : ObservableObject
|
||||
/// <summary>
|
||||
/// 添加国际服用户命令
|
||||
/// </summary>
|
||||
public ICommand AddOsUserCommand { get; }
|
||||
public ICommand AddOverseaUserCommand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 登录米游社命令
|
||||
@@ -132,48 +132,17 @@ internal sealed class UserViewModel : ObservableObject
|
||||
}
|
||||
}
|
||||
|
||||
private async Task AddUserAsync()
|
||||
private Task AddUserAsync()
|
||||
{
|
||||
// ContentDialog must be created by main thread.
|
||||
await ThreadHelper.SwitchToMainThreadAsync();
|
||||
|
||||
// Get cookie from user input
|
||||
ValueResult<bool, string> result = await new UserDialog().GetInputCookieAsync().ConfigureAwait(false);
|
||||
|
||||
// User confirms the input
|
||||
if (result.IsOk)
|
||||
{
|
||||
Cookie cookie = Cookie.Parse(result.Value);
|
||||
|
||||
(UserOptionResult optionResult, string uid) = await userService.ProcessInputCookieAsync(cookie).ConfigureAwait(false);
|
||||
|
||||
switch (optionResult)
|
||||
{
|
||||
case UserOptionResult.Added:
|
||||
if (Users!.Count == 1)
|
||||
{
|
||||
await ThreadHelper.SwitchToMainThreadAsync();
|
||||
SelectedUser = Users.Single();
|
||||
}
|
||||
|
||||
infoBarService.Success(string.Format(SH.ViewModelUserAdded, uid));
|
||||
break;
|
||||
case UserOptionResult.Incomplete:
|
||||
infoBarService.Information(SH.ViewModelUserIncomplete);
|
||||
break;
|
||||
case UserOptionResult.Invalid:
|
||||
infoBarService.Information(SH.ViewModelUserInvalid);
|
||||
break;
|
||||
case UserOptionResult.Updated:
|
||||
infoBarService.Success(string.Format(SH.ViewModelUserUpdated, uid));
|
||||
break;
|
||||
default:
|
||||
throw Must.NeverHappen();
|
||||
}
|
||||
}
|
||||
return AddUserCoreAsync(false);
|
||||
}
|
||||
|
||||
private async Task AddOsUserAsync()
|
||||
private Task AddOverseaUserAsync()
|
||||
{
|
||||
return AddUserCoreAsync(true);
|
||||
}
|
||||
|
||||
private async Task AddUserCoreAsync(bool isOversea)
|
||||
{
|
||||
// ContentDialog must be created by main thread.
|
||||
await ThreadHelper.SwitchToMainThreadAsync();
|
||||
@@ -186,7 +155,7 @@ internal sealed class UserViewModel : ObservableObject
|
||||
{
|
||||
Cookie cookie = Cookie.Parse(result.Value);
|
||||
|
||||
(UserOptionResult optionResult, string uid) = await userService.ProcessInputOsCookieAsync(cookie).ConfigureAwait(false);
|
||||
(UserOptionResult optionResult, string uid) = await userService.ProcessInputCookieAsync(cookie, isOversea).ConfigureAwait(false);
|
||||
|
||||
switch (optionResult)
|
||||
{
|
||||
|
||||
@@ -200,7 +200,7 @@ internal static class ApiOsEndpoints
|
||||
/// <summary>
|
||||
/// 计算器结果
|
||||
/// </summary>
|
||||
public const string CalculateOsCompute = $"{SgPublicApi}/event/calculateos/compute";
|
||||
public const string CalculateCompute = $"{SgPublicApi}/event/calculateos/compute";
|
||||
|
||||
/// <summary>
|
||||
/// 计算器同步角色详情 size 20
|
||||
@@ -208,7 +208,7 @@ internal static class ApiOsEndpoints
|
||||
/// <param name="avatarId">角色Id</param>
|
||||
/// <param name="uid">uid</param>
|
||||
/// <returns>角色详情</returns>
|
||||
public static string CalculateOsSyncAvatarDetail(AvatarId avatarId, PlayerUid uid)
|
||||
public static string CalculateSyncAvatarDetail(AvatarId avatarId, PlayerUid uid)
|
||||
{
|
||||
return $"{SgPublicApi}/event/calculateos/sync/avatar/detail?avatar_id={avatarId.Value}&uid={uid.Value}®ion={uid.Region}";
|
||||
}
|
||||
@@ -216,7 +216,7 @@ internal static class ApiOsEndpoints
|
||||
/// <summary>
|
||||
/// 计算器同步角色列表 size 20
|
||||
/// </summary>
|
||||
public const string CalculateOsSyncAvatarList = $"{SgPublicApi}/event/calculateos/sync/avatar/list";
|
||||
public const string CalculateSyncAvatarList = $"{SgPublicApi}/event/calculateos/sync/avatar/list";
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
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;
|
||||
using System.Net.Http.Json;
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.Passport;
|
||||
|
||||
@@ -13,6 +15,7 @@ namespace Snap.Hutao.Web.Hoyolab.Passport;
|
||||
/// 通行证客户端
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
[UseDynamicSecret]
|
||||
[HttpClient(HttpClientConfiguration.Default)]
|
||||
internal sealed class PassportClient
|
||||
{
|
||||
@@ -34,7 +37,7 @@ internal sealed class PassportClient
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步验证Ltoken
|
||||
/// 异步验证 LToken
|
||||
/// </summary>
|
||||
/// <param name="user">用户</param>
|
||||
/// <param name="token">取消令牌</param>
|
||||
@@ -50,6 +53,28 @@ internal sealed class PassportClient
|
||||
return Response.Response.DefaultIfNull(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// V1 SToken 登录
|
||||
/// </summary>
|
||||
/// <param name="stokenV1">v1 SToken</param>
|
||||
/// <param name="token">取消令牌</param>
|
||||
/// <returns>登录数据</returns>
|
||||
[ApiInformation(Salt = SaltType.PROD)]
|
||||
public async Task<Response<LoginResult>> LoginBySTokenAsync(Cookie stokenV1, CancellationToken token)
|
||||
{
|
||||
HttpResponseMessage message = await httpClient
|
||||
.SetHeader("Cookie", stokenV1.ToString())
|
||||
.UseDynamicSecret(DynamicSecretVersion.Gen2, SaltType.PROD, true)
|
||||
.PostAsync(ApiEndpoints.AccountGetSTokenByOldToken, null, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Response<LoginResult>? resp = await message.Content
|
||||
.ReadFromJsonAsync<Response<LoginResult>>(options, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
private class Timestamp
|
||||
{
|
||||
[JsonPropertyName("t")]
|
||||
|
||||
@@ -39,28 +39,6 @@ internal sealed class PassportClient2 : IPassportClient
|
||||
/// <inheritdoc/>
|
||||
public bool IsOversea => false;
|
||||
|
||||
/// <summary>
|
||||
/// V1 SToken 登录
|
||||
/// </summary>
|
||||
/// <param name="stokenV1">v1 SToken</param>
|
||||
/// <param name="token">取消令牌</param>
|
||||
/// <returns>登录数据</returns>
|
||||
[ApiInformation(Salt = SaltType.PROD)]
|
||||
public async Task<Response<LoginResult>> LoginBySTokenAsync(Cookie stokenV1, CancellationToken token)
|
||||
{
|
||||
HttpResponseMessage message = await httpClient
|
||||
.SetHeader("Cookie", stokenV1.ToString())
|
||||
.UseDynamicSecret(DynamicSecretVersion.Gen2, SaltType.PROD, true)
|
||||
.PostAsync(ApiEndpoints.AccountGetSTokenByOldToken, null, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Response<LoginResult>? resp = await message.Content
|
||||
.ReadFromJsonAsync<Response<LoginResult>>(options, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步获取 CookieToken
|
||||
/// </summary>
|
||||
|
||||
@@ -20,7 +20,7 @@ internal sealed class PassportClientOversea : IPassportClient
|
||||
{
|
||||
private readonly HttpClient httpClient;
|
||||
private readonly JsonSerializerOptions options;
|
||||
private readonly ILogger<PassportClient> logger;
|
||||
private readonly ILogger<PassportClientOversea> logger;
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的国际服通行证客户端
|
||||
@@ -28,7 +28,7 @@ internal sealed class PassportClientOversea : IPassportClient
|
||||
/// <param name="httpClient">http客户端</param>
|
||||
/// <param name="options">Json序列化选项</param>
|
||||
/// <param name="logger">日志器</param>
|
||||
public PassportClientOversea(HttpClient httpClient, JsonSerializerOptions options, ILogger<PassportClient> logger)
|
||||
public PassportClientOversea(HttpClient httpClient, JsonSerializerOptions options, ILogger<PassportClientOversea> logger)
|
||||
{
|
||||
this.httpClient = httpClient;
|
||||
this.options = options;
|
||||
|
||||
@@ -40,7 +40,7 @@ internal sealed class ResourceClient
|
||||
/// <returns>游戏资源</returns>
|
||||
public async Task<Response<GameResource>> GetResourceAsync(LaunchScheme scheme, CancellationToken token = default)
|
||||
{
|
||||
string url = scheme.LauncherId == "10"
|
||||
string url = scheme.IsOversea
|
||||
? ApiOsEndpoints.SdkOsStaticLauncherResource(scheme)
|
||||
: ApiEndpoints.SdkStaticLauncherResource(scheme);
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ internal sealed class BindingClient2
|
||||
|
||||
/// <summary>
|
||||
/// 异步生成祈愿验证密钥
|
||||
/// 需要stoken
|
||||
/// 需要 SToken
|
||||
/// </summary>
|
||||
/// <param name="user">用户</param>
|
||||
/// <param name="data">提交数据</param>
|
||||
|
||||
@@ -43,24 +43,19 @@ internal sealed class CalculateClient
|
||||
[ApiInformation(Cookie = CookieType.Cookie)]
|
||||
public async Task<Response<Consumption>> ComputeAsync(Model.Entity.User user, AvatarPromotionDelta delta, CancellationToken token = default)
|
||||
{
|
||||
Response<Consumption>? resp;
|
||||
string referer = user.IsOversea
|
||||
? ApiOsEndpoints.ActHoyolabReferer
|
||||
: ApiEndpoints.WebStaticMihoyoReferer;
|
||||
|
||||
if (user.IsOversea)
|
||||
{
|
||||
resp = await httpClient
|
||||
string url = user.IsOversea
|
||||
? ApiOsEndpoints.CalculateCompute
|
||||
: ApiEndpoints.CalculateCompute;
|
||||
|
||||
Response<Consumption>? resp = await httpClient
|
||||
.SetUser(user, CookieType.Cookie)
|
||||
.SetReferer(ApiOsEndpoints.ActHoyolabReferer)
|
||||
.TryCatchPostAsJsonAsync<AvatarPromotionDelta, Response<Consumption>>(ApiOsEndpoints.CalculateOsCompute, delta, options, logger, token)
|
||||
.SetReferer(referer)
|
||||
.TryCatchPostAsJsonAsync<AvatarPromotionDelta, Response<Consumption>>(url, delta, options, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
resp = await httpClient
|
||||
.SetUser(user, CookieType.Cookie)
|
||||
.SetReferer(ApiEndpoints.WebStaticMihoyoReferer)
|
||||
.TryCatchPostAsJsonAsync<AvatarPromotionDelta, Response<Consumption>>(ApiEndpoints.CalculateCompute, delta, options, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
@@ -80,28 +75,22 @@ internal sealed class CalculateClient
|
||||
Response<ListWrapper<Avatar>>? resp;
|
||||
|
||||
// 根据 uid 所属服务器选择 referer 与 api
|
||||
string referer;
|
||||
string endpoint;
|
||||
string referer = userAndUid.User.IsOversea
|
||||
? ApiOsEndpoints.ActHoyolabReferer
|
||||
: ApiEndpoints.WebStaticMihoyoReferer;
|
||||
string url = userAndUid.User.IsOversea
|
||||
? ApiOsEndpoints.CalculateSyncAvatarList
|
||||
: ApiEndpoints.CalculateSyncAvatarList;
|
||||
|
||||
if (userAndUid.User.IsOversea)
|
||||
{
|
||||
referer = ApiOsEndpoints.ActHoyolabReferer;
|
||||
endpoint = ApiOsEndpoints.CalculateOsSyncAvatarList;
|
||||
httpClient.SetUser(userAndUid.User, CookieType.CookieToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
referer = ApiEndpoints.WebStaticMihoyoReferer;
|
||||
endpoint = ApiEndpoints.CalculateSyncAvatarList;
|
||||
httpClient.SetUser(userAndUid.User, CookieType.CookieToken);
|
||||
}
|
||||
httpClient
|
||||
.SetReferer(referer)
|
||||
.SetUser(userAndUid.User, CookieType.CookieToken);
|
||||
|
||||
do
|
||||
{
|
||||
filter.Page = currentPage++;
|
||||
resp = await httpClient
|
||||
.SetReferer(referer)
|
||||
.TryCatchPostAsJsonAsync<SyncAvatarFilter, Response<ListWrapper<Avatar>>>(endpoint, filter, options, logger, token)
|
||||
.TryCatchPostAsJsonAsync<SyncAvatarFilter, Response<ListWrapper<Avatar>>>(url, filter, options, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (resp != null && resp.IsOk())
|
||||
@@ -130,21 +119,14 @@ internal sealed class CalculateClient
|
||||
/// <returns>角色详情</returns>
|
||||
public async Task<Response<AvatarDetail>> GetAvatarDetailAsync(UserAndUid userAndUid, Avatar avatar, CancellationToken token = default)
|
||||
{
|
||||
Response<AvatarDetail>? resp;
|
||||
if (!userAndUid.User.IsOversea)
|
||||
{
|
||||
resp = await httpClient
|
||||
string url = userAndUid.User.IsOversea
|
||||
? ApiOsEndpoints.CalculateSyncAvatarDetail(avatar.Id, userAndUid.Uid.Value)
|
||||
: ApiEndpoints.CalculateSyncAvatarDetail(avatar.Id, userAndUid.Uid.Value);
|
||||
|
||||
Response<AvatarDetail>? resp = await httpClient
|
||||
.SetUser(userAndUid.User, CookieType.CookieToken)
|
||||
.TryCatchGetFromJsonAsync<Response<AvatarDetail>>(ApiEndpoints.CalculateSyncAvatarDetail(avatar.Id, userAndUid.Uid.Value), options, logger, token)
|
||||
.TryCatchGetFromJsonAsync<Response<AvatarDetail>>(url, options, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
resp = await httpClient
|
||||
.SetUser(userAndUid.User, CookieType.CookieToken)
|
||||
.TryCatchGetFromJsonAsync<Response<AvatarDetail>>(ApiOsEndpoints.CalculateOsSyncAvatarDetail(avatar.Id, userAndUid.Uid.Value), options, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
@@ -21,9 +21,8 @@ namespace Snap.Hutao.Web.Hutao;
|
||||
[HttpClient(HttpClientConfiguration.Default)]
|
||||
internal sealed class HomaSpiralAbyssClient
|
||||
{
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
private readonly HttpClient httpClient;
|
||||
private readonly GameRecordClient gameRecordClient;
|
||||
private readonly GameRecordClientOversea gameRecordClientOs;
|
||||
private readonly JsonSerializerOptions options;
|
||||
private readonly ILogger<HomaSpiralAbyssClient> logger;
|
||||
|
||||
@@ -31,16 +30,14 @@ internal sealed class HomaSpiralAbyssClient
|
||||
/// 构造一个新的胡桃API客户端
|
||||
/// </summary>
|
||||
/// <param name="httpClient">http客户端</param>
|
||||
/// <param name="gameRecordClient">游戏记录客户端</param>
|
||||
/// <param name="options">json序列化选项</param>
|
||||
/// <param name="logger">日志器</param>
|
||||
public HomaSpiralAbyssClient(HttpClient httpClient, GameRecordClient gameRecordClient, GameRecordClientOversea gameRecordClientOs, JsonSerializerOptions options, ILogger<HomaSpiralAbyssClient> logger)
|
||||
/// <param name="serviceProvider">服务提供器</param>
|
||||
public HomaSpiralAbyssClient(HttpClient httpClient, IServiceProvider serviceProvider)
|
||||
{
|
||||
options = serviceProvider.GetRequiredService<JsonSerializerOptions>();
|
||||
logger = serviceProvider.GetRequiredService<ILogger<HomaSpiralAbyssClient>>();
|
||||
|
||||
this.serviceProvider = serviceProvider;
|
||||
this.httpClient = httpClient;
|
||||
this.gameRecordClient = gameRecordClient;
|
||||
this.gameRecordClientOs = gameRecordClientOs;
|
||||
this.options = options;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -188,55 +185,27 @@ internal sealed class HomaSpiralAbyssClient
|
||||
/// <returns>玩家记录</returns>
|
||||
public async Task<SimpleRecord?> GetPlayerRecordAsync(UserAndUid userAndUid, CancellationToken token = default)
|
||||
{
|
||||
if (userAndUid.User.IsOversea)
|
||||
{
|
||||
// for oversea server
|
||||
Response<PlayerInfo> playerInfoResponse = await gameRecordClientOs
|
||||
IGameRecordClient gameRecordClient = serviceProvider.PickRequiredService<IGameRecordClient>(userAndUid.User.IsOversea);
|
||||
|
||||
Response<PlayerInfo> playerInfoResponse = await gameRecordClient
|
||||
.GetPlayerInfoAsync(userAndUid, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (playerInfoResponse.IsOk())
|
||||
{
|
||||
Response<CharacterWrapper> charactersResponse = await gameRecordClientOs
|
||||
.GetCharactersAsync(userAndUid, playerInfoResponse.Data, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (charactersResponse.IsOk())
|
||||
{
|
||||
Response<SpiralAbyss> spiralAbyssResponse = await gameRecordClientOs
|
||||
.GetSpiralAbyssAsync(userAndUid, SpiralAbyssSchedule.Current, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (spiralAbyssResponse.IsOk())
|
||||
{
|
||||
return new(userAndUid.Uid.Value, charactersResponse.Data.Avatars, spiralAbyssResponse.Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (playerInfoResponse.IsOk())
|
||||
{
|
||||
// for cn server
|
||||
Response<PlayerInfo> playerInfoResponse = await gameRecordClient
|
||||
.GetPlayerInfoAsync(userAndUid, token)
|
||||
.ConfigureAwait(false);
|
||||
Response<CharacterWrapper> charactersResponse = await gameRecordClient
|
||||
.GetCharactersAsync(userAndUid, playerInfoResponse.Data, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (playerInfoResponse.IsOk())
|
||||
if (charactersResponse.IsOk())
|
||||
{
|
||||
Response<CharacterWrapper> charactersResponse = await gameRecordClient
|
||||
.GetCharactersAsync(userAndUid, playerInfoResponse.Data, token)
|
||||
.ConfigureAwait(false);
|
||||
Response<SpiralAbyss> spiralAbyssResponse = await gameRecordClient
|
||||
.GetSpiralAbyssAsync(userAndUid, SpiralAbyssSchedule.Current, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (charactersResponse.IsOk())
|
||||
if (spiralAbyssResponse.IsOk())
|
||||
{
|
||||
Response<SpiralAbyss> spiralAbyssResponse = await gameRecordClient
|
||||
.GetSpiralAbyssAsync(userAndUid, SpiralAbyssSchedule.Current, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (spiralAbyssResponse.IsOk())
|
||||
{
|
||||
return new(userAndUid.Uid.Value, charactersResponse.Data.Avatars, spiralAbyssResponse.Data);
|
||||
}
|
||||
return new(userAndUid.Uid.Value, charactersResponse.Data.Avatars, spiralAbyssResponse.Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user