Merge pull request #965 from Xhichn/DailyReward

This commit is contained in:
DismissedLight
2023-10-05 09:37:54 +08:00
committed by GitHub
7 changed files with 163 additions and 7 deletions

View File

@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Microsoft.Extensions.DependencyInjection;
using Snap.Hutao.Core.DependencyInjection.Abstraction;
using Snap.Hutao.ViewModel.User;
using Snap.Hutao.Web.Hoyolab.Takumi.Event.BbsSignReward;
using Snap.Hutao.Web.Response;
@@ -15,7 +17,9 @@ internal sealed partial class SignInService : ISignInService
public async ValueTask<ValueResult<bool, string>> ClaimRewardAsync(UserAndUid userAndUid, CancellationToken token = default)
{
SignInClient signInClient = serviceProvider.GetRequiredService<SignInClient>();
ISignInClient signInClient = serviceProvider
.GetRequiredService<IOverseaSupportFactory<ISignInClient>>()
.Create(userAndUid.User.IsOversea);
Response<Reward> rewardResponse = await signInClient.GetRewardAsync(userAndUid.User, token).ConfigureAwait(false);

View File

@@ -229,6 +229,49 @@ internal static class ApiOsEndpoints
#endregion
#region SgHk4eApi
/// <summary>
/// 签到活动Id
/// </summary>
public const string SignInRewardActivityId = "e202102251931481";
/// <summary>
/// 签到
/// </summary>
public const string SignInRewardSign = $"{SgHk4eApi}/event/sol/sign?lang=zh-cn";
/// <summary>
/// 签到
/// </summary>
public const string SignInRewardHome = $"{SgHk4eApi}/event/sol/home?lang=zh-cn&act_id={SignInRewardActivityId}";
/// <summary>
/// 补签
/// </summary>
public const string SignInRewardReSign = $"{SgHk4eApi}/event/sol/resign?lang=zh-cn";
/// <summary>
/// 补签信息
/// </summary>
/// <param name="uid">uid</param>
/// <returns>补签信息字符串</returns>
public static string SignInRewardResignInfo(in PlayerUid uid)
{
return $"{SgHk4eApi}/event/sol/resign_info?lang=zh-cn&act_id={SignInRewardActivityId}&region={uid.Region}&uid={uid.Value}";
}
/// <summary>
/// 签到信息
/// </summary>
/// <param name="uid">uid</param>
/// <returns>签到信息字符串</returns>
public static string SignInRewardInfo(in PlayerUid uid)
{
return $"{SgHk4eApi}/event/sol/info?lang=zh-cn&act_id={SignInRewardActivityId}&region={uid.Region}&uid={uid.Value}";
}
#endregion
#region SdkStaticLauncherApi
/// <summary>
@@ -270,6 +313,7 @@ internal static class ApiOsEndpoints
private const string SdkOsStaticLauncherApi = $"{SdkOsStatic}/hk4e_global/mdk/launcher/api";
private const string SgPublicApi = "https://sg-public-api.hoyoverse.com";
private const string SgHk4eApi = "https://sg-hk4e-api.hoyoverse.com";
private const string WebApiOs = "https://webapi-os.account.hoyoverse.com";
private const string WebApiOsAccountApi = $"{WebApiOs}/Api";

View File

@@ -0,0 +1,29 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.ViewModel.User;
using Snap.Hutao.Web.Response;
namespace Snap.Hutao.Web.Hoyolab.Takumi.Event.BbsSignReward;
/// <summary>
/// 每日签到客户端接口
/// </summary>
internal interface ISignInClient
{
/// <summary>
/// 获取
/// </summary>
/// <param name="user">用户信息</param>
/// <param name="token">token</param>
/// <returns>结果</returns>
ValueTask<Response<Reward>> GetRewardAsync(Model.Entity.User user, CancellationToken token = default);
/// <summary>
/// 签到
/// </summary>
/// <param name="userAndUid">用户信息</param>
/// <param name="token">token</param>
/// <returns>签到结果</returns>
ValueTask<Response<SignInResult>> SignAsync(UserAndUid userAndUid, CancellationToken token = default);
}

View File

@@ -17,7 +17,7 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.Event.BbsSignReward;
[UseDynamicSecret]
[HttpClient(HttpClientConfiguration.XRpc)]
[PrimaryHttpMessageHandler(UseCookies = false)]
internal sealed partial class SignInClient
internal sealed partial class SignInClient : ISignInClient
{
private readonly HttpClient httpClient;
private readonly HomaGeetestClient homaGeetestClient;
@@ -58,7 +58,7 @@ internal sealed partial class SignInClient
public async ValueTask<Response<SignInResult>> ReSignAsync(UserAndUid userAndUid, CancellationToken token = default)
{
SignInData data = new(userAndUid.Uid);
SignInData data = new(userAndUid.Uid, false);
Response<SignInResult>? resp = await httpClient
.SetUser(userAndUid.User, CookieType.CookieToken)
@@ -74,7 +74,7 @@ internal sealed partial class SignInClient
Response<SignInResult>? resp = await httpClient
.SetUser(userAndUid.User, CookieType.CookieToken)
.UseDynamicSecret(DynamicSecretVersion.Gen1, SaltType.LK2, false)
.TryCatchPostAsJsonAsync<SignInData, Response<SignInResult>>(ApiEndpoints.SignInRewardSign, new(userAndUid.Uid), options, logger, token)
.TryCatchPostAsJsonAsync<SignInData, Response<SignInResult>>(ApiEndpoints.SignInRewardSign, new(userAndUid.Uid, false), options, logger, token)
.ConfigureAwait(false);
if (resp is { Data: { Success: 1, Gt: string gt, Challenge: string originChallenge } })
@@ -87,7 +87,7 @@ internal sealed partial class SignInClient
.SetUser(userAndUid.User, CookieType.CookieToken)
.SetXrpcChallenge(challenge, validate)
.UseDynamicSecret(DynamicSecretVersion.Gen1, SaltType.LK2, false)
.TryCatchPostAsJsonAsync<SignInData, Response<SignInResult>>(ApiEndpoints.SignInRewardSign, new(userAndUid.Uid), options, logger, token)
.TryCatchPostAsJsonAsync<SignInData, Response<SignInResult>>(ApiEndpoints.SignInRewardSign, new(userAndUid.Uid, false), options, logger, token)
.ConfigureAwait(false);
}
else

View File

@@ -0,0 +1,12 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Core.DependencyInjection.Abstraction;
namespace Snap.Hutao.Web.Hoyolab.Takumi.Event.BbsSignReward;
[ConstructorGenerated(CallBaseConstructor = true)]
[Injection(InjectAs.Transient, typeof(IOverseaSupportFactory<ISignInClient>))]
internal sealed partial class SignInClientFactory : OverseaSupportFactory<ISignInClient, SignInClient, SignInClientOversea>
{
}

View File

@@ -0,0 +1,65 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
using Snap.Hutao.ViewModel.User;
using Snap.Hutao.Web.Hoyolab.DynamicSecret;
using Snap.Hutao.Web.Hutao.Geetest;
using Snap.Hutao.Web.Response;
using System.Net.Http;
namespace Snap.Hutao.Web.Hoyolab.Takumi.Event.BbsSignReward;
/// <summary>
/// Global签到客户端
/// </summary>
[ConstructorGenerated(ResolveHttpClient = true)]
[UseDynamicSecret]
[HttpClient(HttpClientConfiguration.Default)]
[PrimaryHttpMessageHandler(UseCookies = false)]
internal sealed partial class SignInClientOversea : ISignInClient
{
private readonly HttpClient httpClient;
private readonly HomaGeetestClient homaGeetestClient;
private readonly JsonSerializerOptions options;
private readonly ILogger<SignInClient> logger;
public async ValueTask<Response<Reward>> GetRewardAsync(Model.Entity.User user, CancellationToken token = default)
{
Response<Reward>? resp = await httpClient
.SetUser(user, CookieType.CookieToken)
.TryCatchGetFromJsonAsync<Response<Reward>>(ApiOsEndpoints.SignInRewardHome, options, logger, token)
.ConfigureAwait(false);
return Response.Response.DefaultIfNull(resp);
}
public async ValueTask<Response<SignInResult>> SignAsync(UserAndUid userAndUid, CancellationToken token = default)
{
Response<SignInResult>? resp = await httpClient
.SetUser(userAndUid.User, CookieType.CookieToken)
.TryCatchPostAsJsonAsync<SignInData, Response<SignInResult>>(ApiOsEndpoints.SignInRewardSign, new(userAndUid.Uid, true), options, logger, token)
.ConfigureAwait(false);
if (resp is { Data: { Success: 1, Gt: string gt, Challenge: string originChallenge } })
{
GeetestResponse verifyResponse = await homaGeetestClient.VerifyAsync(gt, originChallenge, token).ConfigureAwait(false);
if (verifyResponse is { Code: 0, Data: { Validate: string validate, Challenge: string challenge } })
{
resp = await httpClient
.SetUser(userAndUid.User, CookieType.CookieToken)
.SetXrpcChallenge(challenge, validate)
.TryCatchPostAsJsonAsync<SignInData, Response<SignInResult>>(ApiOsEndpoints.SignInRewardSign, new(userAndUid.Uid, true), options, logger, token)
.ConfigureAwait(false);
}
else
{
resp.ReturnCode = resp.Data.RiskCode;
resp.Message = SH.ServiceSignInRiskVerificationFailed;
}
}
return Response.Response.DefaultIfNull(resp);
}
}

View File

@@ -12,9 +12,11 @@ internal sealed class SignInData
/// 构造一个新的签到提交数据
/// </summary>
/// <param name="uid">uid</param>
/// <param name="isOversea">是否为国际服用于选择ActivityId</param>
[SuppressMessage("", "SH002")]
public SignInData(PlayerUid uid)
public SignInData(PlayerUid uid, bool isOversea)
{
ActivityId = isOversea ? ApiOsEndpoints.SignInRewardActivityId : ApiEndpoints.SignInRewardActivityId;
Region = uid.Region;
Uid = uid.Value;
}
@@ -23,7 +25,7 @@ internal sealed class SignInData
/// 活动Id
/// </summary>
[JsonPropertyName("act_id")]
public string ActivityId { get; } = ApiEndpoints.SignInRewardActivityId;
public string ActivityId { get; }
/// <summary>
/// 地区代码