mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
role combat spec
This commit is contained in:
@@ -85,12 +85,12 @@ internal sealed partial class SpiralAbyssRecordService : ISpiralAbyssRecordServi
|
||||
.GetPlayerInfoAsync(userAndUid)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await RefreshSpiralAbyssCoreAsync(userAndUid, SpiralAbyssSchedule.Last).ConfigureAwait(false);
|
||||
await RefreshSpiralAbyssCoreAsync(userAndUid, SpiralAbyssSchedule.Current).ConfigureAwait(false);
|
||||
await RefreshSpiralAbyssCoreAsync(userAndUid, ScheduleType.Last).ConfigureAwait(false);
|
||||
await RefreshSpiralAbyssCoreAsync(userAndUid, ScheduleType.Current).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private async ValueTask RefreshSpiralAbyssCoreAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule)
|
||||
private async ValueTask RefreshSpiralAbyssCoreAsync(UserAndUid userAndUid, ScheduleType schedule)
|
||||
{
|
||||
Response<Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.SpiralAbyss> response;
|
||||
using (IServiceScope scope = serviceScopeFactory.CreateScope())
|
||||
|
||||
@@ -52,7 +52,7 @@ internal sealed class BattleView : IMappingFrom<BattleView, TowerLevel, uint, Sp
|
||||
return new(level, index, context);
|
||||
}
|
||||
|
||||
public void WithSpiralAbyssBattle(Battle battle, SpiralAbyssMetadataContext context)
|
||||
public void WithSpiralAbyssBattle(SpiralAbyssBattle battle, SpiralAbyssMetadataContext context)
|
||||
{
|
||||
Time = $"{DateTimeOffset.FromUnixTimeSeconds(battle.Timestamp).ToLocalTime():yyyy.MM.dd HH:mm:ss}";
|
||||
Avatars = battle.Avatars.SelectList(a => AvatarView.From(context.IdAvatarMap[a.Id]));
|
||||
|
||||
@@ -52,7 +52,7 @@ internal sealed class FloorView : IMappingFrom<FloorView, TowerFloor, SpiralAbys
|
||||
return new(floor, context);
|
||||
}
|
||||
|
||||
public void WithSpiralAbyssFloor(Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.Floor floor, SpiralAbyssMetadataContext context)
|
||||
public void WithSpiralAbyssFloor(Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.SpiralAbyssFloor floor, SpiralAbyssMetadataContext context)
|
||||
{
|
||||
SettleTime = $"{DateTimeOffset.FromUnixTimeSeconds(floor.SettleTime).ToLocalTime():yyyy.MM.dd HH:mm:ss}";
|
||||
Star = floor.Star;
|
||||
|
||||
@@ -41,7 +41,7 @@ internal sealed class LevelView : IMappingFrom<LevelView, TowerLevel, SpiralAbys
|
||||
return new(towerLevel, context);
|
||||
}
|
||||
|
||||
public void WithSpiralAbyssLevel(Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.Level level, SpiralAbyssMetadataContext context)
|
||||
public void WithSpiralAbyssLevel(Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.SpiralAbyssLevel level, SpiralAbyssMetadataContext context)
|
||||
{
|
||||
Star = level.Star;
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ internal sealed class SpiralAbyssView : IEntityAccess<SpiralAbyssEntry?>,
|
||||
EnergySkill = ToRankAvatar(spiralAbyss.EnergySkillRank, context);
|
||||
Engaged = true;
|
||||
|
||||
foreach (Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.Floor webFloor in spiralAbyss.Floors)
|
||||
foreach (Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.SpiralAbyssFloor webFloor in spiralAbyss.Floors)
|
||||
{
|
||||
// Ignoring floor 1 - 8 here
|
||||
if (Floors.SingleOrDefault(f => f.IndexValue == webFloor.Index) is { } floor)
|
||||
@@ -139,12 +139,12 @@ internal sealed class SpiralAbyssView : IEntityAccess<SpiralAbyssEntry?>,
|
||||
}
|
||||
}
|
||||
|
||||
private static List<RankAvatar> ToRankAvatars(List<Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.Rank> ranks, SpiralAbyssMetadataContext context)
|
||||
private static List<RankAvatar> ToRankAvatars(List<Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.SpiralAbyssRank> ranks, SpiralAbyssMetadataContext context)
|
||||
{
|
||||
return ranks.Where(r => r.AvatarId != 0U).Select(r => new RankAvatar(r.Value, context.IdAvatarMap[r.AvatarId])).ToList();
|
||||
}
|
||||
|
||||
private static RankAvatar? ToRankAvatar(List<Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.Rank> ranks, SpiralAbyssMetadataContext context)
|
||||
private static RankAvatar? ToRankAvatar(List<Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.SpiralAbyssRank> ranks, SpiralAbyssMetadataContext context)
|
||||
{
|
||||
return ranks.Where(r => r.AvatarId != 0U).Select(r => new RankAvatar(r.Value, context.IdAvatarMap[r.AvatarId])).SingleOrDefault();
|
||||
}
|
||||
|
||||
@@ -142,12 +142,19 @@ internal static class ApiEndpoints
|
||||
/// <param name="scheduleType">深渊类型</param>
|
||||
/// <param name="uid">Uid</param>
|
||||
/// <returns>深渊信息字符串</returns>
|
||||
public static string GameRecordSpiralAbyss(Hoyolab.Takumi.GameRecord.SpiralAbyssSchedule scheduleType, in PlayerUid uid)
|
||||
public static string GameRecordSpiralAbyss(Hoyolab.Takumi.GameRecord.ScheduleType scheduleType, in PlayerUid uid)
|
||||
{
|
||||
return $"{GameRecordSpiralAbyssPath}?schedule_type={(int)scheduleType}&role_id={uid.Value}&server={uid.Region}";
|
||||
}
|
||||
|
||||
public const string GameRecordSpiralAbyssPath = $"{ApiTakumiRecordApi}/spiralAbyss";
|
||||
|
||||
public static string GameRecordRoleCombat(in PlayerUid uid)
|
||||
{
|
||||
return $"{GameRecordRoleCombatPath}?server={uid.Region}&role_id={uid.Value}&need_detail=true";
|
||||
}
|
||||
|
||||
public const string GameRecordRoleCombatPath = $"{ApiTakumiRecordApi}/role_combat";
|
||||
#endregion
|
||||
|
||||
#region ApiTakumiEventCalculate
|
||||
|
||||
@@ -168,7 +168,7 @@ internal static class ApiOsEndpoints
|
||||
/// <param name="scheduleType">深渊类型</param>
|
||||
/// <param name="uid">Uid</param>
|
||||
/// <returns>深渊信息字符串</returns>
|
||||
public static string GameRecordSpiralAbyss(Hoyolab.Takumi.GameRecord.SpiralAbyssSchedule scheduleType, in PlayerUid uid)
|
||||
public static string GameRecordSpiralAbyss(Hoyolab.Takumi.GameRecord.ScheduleType scheduleType, in PlayerUid uid)
|
||||
{
|
||||
return $"{BbsApiOsGameRecordAppApi}/spiralAbyss?server={uid.Region}&role_id={uid.Value}&schedule_type={(int)scheduleType}";
|
||||
}
|
||||
|
||||
@@ -31,6 +31,11 @@ internal sealed class CardVerifiationHeaders
|
||||
return Create(ApiEndpoints.GameRecordCharacter, $"{HoyolabOptions.ToolVersion}_#/ys/role/all");
|
||||
}
|
||||
|
||||
public static CardVerifiationHeaders CreateForRoleCombat()
|
||||
{
|
||||
return Create(ApiEndpoints.GameRecordRoleCombatPath);
|
||||
}
|
||||
|
||||
private static CardVerifiationHeaders Create(string path, string page = $"{HoyolabOptions.ToolVersion}_#/ys")
|
||||
{
|
||||
return new()
|
||||
|
||||
@@ -26,8 +26,8 @@ internal sealed class DailyNote : DailyNoteCommon
|
||||
return SH.WebDailyNoteResinRecoveryCompleted;
|
||||
}
|
||||
|
||||
DateTime reach = DateTime.Now.AddSeconds(ResinRecoveryTime);
|
||||
int totalDays = (reach - DateTime.Today).Days;
|
||||
System.DateTime reach = System.DateTime.Now.AddSeconds(ResinRecoveryTime);
|
||||
int totalDays = (reach - System.DateTime.Today).Days;
|
||||
string day = totalDays switch
|
||||
{
|
||||
0 => SH.WebDailyNoteRecoveryTimeDay0,
|
||||
@@ -82,8 +82,8 @@ internal sealed class DailyNote : DailyNoteCommon
|
||||
{
|
||||
get
|
||||
{
|
||||
DateTime reach = DateTime.Now.AddSeconds(HomeCoinRecoveryTime);
|
||||
int totalDays = (reach - DateTime.Today).Days;
|
||||
System.DateTime reach = System.DateTime.Now.AddSeconds(HomeCoinRecoveryTime);
|
||||
int totalDays = (reach - System.DateTime.Today).Days;
|
||||
string day = totalDays switch
|
||||
{
|
||||
0 => SH.WebDailyNoteRecoveryTimeDay0,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss;
|
||||
namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord;
|
||||
|
||||
internal sealed class SettleDateTime
|
||||
internal sealed class DateTime
|
||||
{
|
||||
[JsonPropertyName("year")]
|
||||
public int Year { get; set; }
|
||||
@@ -110,7 +110,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
public async ValueTask<Response<SpiralAbyss.SpiralAbyss>> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default)
|
||||
public async ValueTask<Response<SpiralAbyss.SpiralAbyss>> GetSpiralAbyssAsync(UserAndUid userAndUid, ScheduleType schedule, CancellationToken token = default)
|
||||
{
|
||||
HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create()
|
||||
.SetRequestUri(ApiEndpoints.GameRecordSpiralAbyss(schedule, userAndUid.Uid))
|
||||
@@ -212,4 +212,41 @@ internal sealed partial class GameRecordClient : IGameRecordClient
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
public async ValueTask<Response<RoleCombat.RoleCombat>> GetRoleCombatAsync(UserAndUid userAndUid, CancellationToken token = default(CancellationToken))
|
||||
{
|
||||
HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create()
|
||||
.SetRequestUri(ApiEndpoints.GameRecordRoleCombat(userAndUid.Uid))
|
||||
.SetUserCookieAndFpHeader(userAndUid, CookieType.Cookie)
|
||||
.SetReferer(ApiEndpoints.WebStaticMihoyoReferer)
|
||||
.Get();
|
||||
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.X4, false).ConfigureAwait(false);
|
||||
|
||||
Response<RoleCombat.RoleCombat>? resp = await builder
|
||||
.SendAsync<Response<RoleCombat.RoleCombat>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// We have a verification procedure to handle
|
||||
if (resp?.ReturnCode == (int)KnownReturnCode.CODE1034)
|
||||
{
|
||||
// Replace message
|
||||
resp.Message = SH.WebIndexOrSpiralAbyssVerificationFailed;
|
||||
|
||||
IGeetestCardVerifier verifier = serviceProvider.GetRequiredKeyedService<IGeetestCardVerifier>(GeetestCardVerifierType.Custom);
|
||||
CardVerifiationHeaders headers = CardVerifiationHeaders.CreateForRoleCombat();
|
||||
|
||||
if (await verifier.TryValidateXrpcChallengeAsync(userAndUid.User, headers, token).ConfigureAwait(false) is { } challenge)
|
||||
{
|
||||
builder.Resurrect().SetXrpcChallenge(challenge);
|
||||
await builder.SignDataAsync(DataSignAlgorithmVersion.Gen2, SaltType.X4, false).ConfigureAwait(false);
|
||||
|
||||
resp = await builder
|
||||
.SendAsync<Response<RoleCombat.RoleCombat>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,7 @@ internal sealed partial class GameRecordClientOversea : IGameRecordClient
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
public async ValueTask<Response<SpiralAbyss.SpiralAbyss>> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default)
|
||||
public async ValueTask<Response<SpiralAbyss.SpiralAbyss>> GetSpiralAbyssAsync(UserAndUid userAndUid, ScheduleType schedule, CancellationToken token = default)
|
||||
{
|
||||
HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create()
|
||||
.SetRequestUri(ApiOsEndpoints.GameRecordSpiralAbyss(schedule, userAndUid.Uid))
|
||||
@@ -84,4 +84,9 @@ internal sealed partial class GameRecordClientOversea : IGameRecordClient
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
}
|
||||
|
||||
public ValueTask<Response<RoleCombat.RoleCombat>> GetRoleCombatAsync(UserAndUid userAndUid, CancellationToken token = default(CancellationToken))
|
||||
{
|
||||
return ValueTask.FromException<Response<RoleCombat.RoleCombat>>(new NotSupportedException());
|
||||
}
|
||||
}
|
||||
@@ -12,37 +12,13 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord;
|
||||
/// </summary>
|
||||
internal interface IGameRecordClient
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取玩家角色详细信息
|
||||
/// </summary>
|
||||
/// <param name="userAndUid">用户与角色</param>
|
||||
/// <param name="playerInfo">玩家的基础信息</param>
|
||||
/// <param name="token">取消令牌</param>
|
||||
/// <returns>角色列表</returns>
|
||||
ValueTask<Response<CharacterWrapper>> GetCharactersAsync(UserAndUid userAndUid, PlayerInfo playerInfo, CancellationToken token = default);
|
||||
|
||||
/// <summary>
|
||||
/// 异步获取实时便笺
|
||||
/// </summary>
|
||||
/// <param name="userAndUid">用户与角色</param>
|
||||
/// <param name="token">取消令牌</param>
|
||||
/// <returns>实时便笺</returns>
|
||||
ValueTask<Response<DailyNote.DailyNote>> GetDailyNoteAsync(UserAndUid userAndUid, CancellationToken token = default);
|
||||
|
||||
/// <summary>
|
||||
/// 获取玩家基础信息
|
||||
/// </summary>
|
||||
/// <param name="userAndUid">用户与角色</param>
|
||||
/// <param name="token">取消令牌</param>
|
||||
/// <returns>玩家的基础信息</returns>
|
||||
ValueTask<Response<PlayerInfo>> GetPlayerInfoAsync(UserAndUid userAndUid, CancellationToken token = default);
|
||||
|
||||
/// <summary>
|
||||
/// 获取玩家深渊信息
|
||||
/// </summary>
|
||||
/// <param name="userAndUid">用户</param>
|
||||
/// <param name="schedule">1:当期,2:上期</param>
|
||||
/// <param name="token">取消令牌</param>
|
||||
/// <returns>深渊信息</returns>
|
||||
ValueTask<Response<SpiralAbyss.SpiralAbyss>> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default);
|
||||
ValueTask<Response<SpiralAbyss.SpiralAbyss>> GetSpiralAbyssAsync(UserAndUid userAndUid, ScheduleType schedule, CancellationToken token = default);
|
||||
|
||||
ValueTask<Response<RoleCombat.RoleCombat>> GetRoleCombatAsync(UserAndUid userAndUid, CancellationToken token = default);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.RoleCombat;
|
||||
|
||||
internal sealed class RoleCombat
|
||||
{
|
||||
[JsonPropertyName("data")]
|
||||
public List<RoleCombatData> Data { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("is_unlock")]
|
||||
public bool IsUnlock { get; set; }
|
||||
|
||||
[JsonPropertyName("links")]
|
||||
public RoleCombatLinks Links { get; set; } = default!;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.RoleCombat;
|
||||
|
||||
internal sealed class RoleCombatAvatar
|
||||
{
|
||||
[JsonPropertyName("avatar_id")]
|
||||
public AvatarId AvatarId { get; set; }
|
||||
|
||||
[JsonPropertyName("avatar_type")]
|
||||
public RoleCombatAvatarType AvatarType { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("element")]
|
||||
public string Element { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("image")]
|
||||
public string Image { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("level")]
|
||||
public Level Level { get; set; }
|
||||
|
||||
[JsonPropertyName("rarity")]
|
||||
public QualityType Rarity { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.RoleCombat;
|
||||
|
||||
internal enum RoleCombatAvatarType
|
||||
{
|
||||
/// <summary>
|
||||
/// 已有
|
||||
/// </summary>
|
||||
Default = 1,
|
||||
|
||||
/// <summary>
|
||||
/// 试用
|
||||
/// </summary>
|
||||
Trial = 2,
|
||||
|
||||
/// <summary>
|
||||
/// 借用
|
||||
/// </summary>
|
||||
Support = 3,
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.RoleCombat;
|
||||
|
||||
internal sealed class RoleCombatBuff
|
||||
{
|
||||
[JsonPropertyName("icon")]
|
||||
public string Icon { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("desc")]
|
||||
public string Description { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("is_enhanced")]
|
||||
public bool IsEnhanced { get; set; }
|
||||
|
||||
[JsonPropertyName("id")]
|
||||
public uint Id { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.RoleCombat;
|
||||
|
||||
internal sealed class RoleCombatData
|
||||
{
|
||||
[JsonPropertyName("detail")]
|
||||
public RoleCombatDetail Detail { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("stat")]
|
||||
public RoleCombatStat Stat { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("schedule")]
|
||||
public RoleCombatSchedule Schedule { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("has_data")]
|
||||
public bool HasData { get; set; }
|
||||
|
||||
[JsonPropertyName("has_detail_data")]
|
||||
[MemberNotNullWhen(true, nameof(Detail))]
|
||||
public bool HasDetailData { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.RoleCombat;
|
||||
|
||||
internal sealed class RoleCombatDetail
|
||||
{
|
||||
[JsonPropertyName("rounds_data")]
|
||||
public List<RoleCombatRoundData> RoundsData { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("detail_stat")]
|
||||
public RoleCombatStat? DetailStat { get; set; }
|
||||
|
||||
[JsonPropertyName("backup_avatars")]
|
||||
public List<RoleCombatAvatar> BackupAvatars { get; set; } = default!;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.RoleCombat;
|
||||
|
||||
internal sealed class RoleCombatLinks
|
||||
{
|
||||
[JsonPropertyName("lineup_link")]
|
||||
public string LineupLink { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("lineup_link_pc")]
|
||||
public string LineupLinkPC { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("strategy_link")]
|
||||
public string StrategyLink { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("lineup_publish_link")]
|
||||
public string LineupPublishLink { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("lineup_publish_link_pc")]
|
||||
public string LineupPublishLinkPC { get; set; } = default!;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.RoleCombat;
|
||||
|
||||
internal sealed class RoleCombatRoundData
|
||||
{
|
||||
[JsonPropertyName("avatars")]
|
||||
public List<RoleCombatAvatar> Avatars { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("choice_cards")]
|
||||
public List<RoleCombatBuff> ChoiceCards { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("buffs")]
|
||||
public List<RoleCombatBuff> Buffs { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("is_get_medal")]
|
||||
public bool IsGetMedal { get; set; }
|
||||
|
||||
[JsonPropertyName("round_id")]
|
||||
public uint RoundId { get; set; }
|
||||
|
||||
[JsonPropertyName("finish_time")]
|
||||
public long FinishTime { get; set; }
|
||||
|
||||
[JsonPropertyName("finish_date_time")]
|
||||
public DateTime FinishDateTime { get; set; } = default!;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.RoleCombat;
|
||||
|
||||
internal sealed class RoleCombatSchedule
|
||||
{
|
||||
[JsonPropertyName("start_time")]
|
||||
public long StartTime { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("end_time")]
|
||||
public long EndTime { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("schedule_type")]
|
||||
public ScheduleType ScheduleType { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("schedule_id")]
|
||||
public int ScheduleId { get; set; }
|
||||
|
||||
[JsonPropertyName("start_date_time")]
|
||||
public DateTime StartDateTime { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("end_date_time")]
|
||||
public DateTime EndDateTime { get; set; } = default!;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.RoleCombat;
|
||||
|
||||
internal sealed class RoleCombatStat
|
||||
{
|
||||
[JsonPropertyName("difficulty_id")]
|
||||
public uint DifficultyId { get; set; }
|
||||
|
||||
[JsonPropertyName("max_round_id")]
|
||||
public uint MaxRoundId { get; set; }
|
||||
|
||||
[JsonPropertyName("heraldry")]
|
||||
public int Heraldry { get; set; }
|
||||
|
||||
[JsonPropertyName("get_medal_round_list")]
|
||||
public List<int> GetMedalRoundList { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("medal_num")]
|
||||
public int MedalNumber { get; set; }
|
||||
|
||||
[JsonPropertyName("coin_num")]
|
||||
public int CoinNumber { get; set; }
|
||||
|
||||
[JsonPropertyName("avatar_bonus_num")]
|
||||
public int AvatarBonusNumber { get; set; }
|
||||
|
||||
[JsonPropertyName("rent_cnt")]
|
||||
public int RentCount { get; set; }
|
||||
}
|
||||
@@ -3,11 +3,7 @@
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord;
|
||||
|
||||
/// <summary>
|
||||
/// 深渊期数类型
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal enum SpiralAbyssSchedule
|
||||
internal enum ScheduleType
|
||||
{
|
||||
/// <summary>
|
||||
/// 当期
|
||||
@@ -49,43 +49,43 @@ internal sealed class SpiralAbyss
|
||||
/// 出战次数
|
||||
/// </summary>
|
||||
[JsonPropertyName("reveal_rank")]
|
||||
public List<Rank> RevealRank { get; set; } = default!;
|
||||
public List<SpiralAbyssRank> RevealRank { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 击破次数
|
||||
/// </summary>
|
||||
[JsonPropertyName("defeat_rank")]
|
||||
public List<Rank> DefeatRank { get; set; } = default!;
|
||||
public List<SpiralAbyssRank> DefeatRank { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 最强一击
|
||||
/// </summary>
|
||||
[JsonPropertyName("damage_rank")]
|
||||
public List<Rank> DamageRank { get; set; } = default!;
|
||||
public List<SpiralAbyssRank> DamageRank { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 承受伤害
|
||||
/// </summary>
|
||||
[JsonPropertyName("take_damage_rank")]
|
||||
public List<Rank> TakeDamageRank { get; set; } = default!;
|
||||
public List<SpiralAbyssRank> TakeDamageRank { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 元素战技
|
||||
/// </summary>
|
||||
[JsonPropertyName("normal_skill_rank")]
|
||||
public List<Rank> NormalSkillRank { get; set; } = default!;
|
||||
public List<SpiralAbyssRank> NormalSkillRank { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 元素爆发
|
||||
/// </summary>
|
||||
[JsonPropertyName("energy_skill_rank")]
|
||||
public List<Rank> EnergySkillRank { get; set; } = default!;
|
||||
public List<SpiralAbyssRank> EnergySkillRank { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 层信息
|
||||
/// </summary>
|
||||
[JsonPropertyName("floors")]
|
||||
public List<Floor> Floors { get; set; } = default!;
|
||||
public List<SpiralAbyssFloor> Floors { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 共获得渊星
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss;
|
||||
/// 仅包含头像的角色信息
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed class Avatar
|
||||
internal sealed class SpiralAbyssAvatar
|
||||
{
|
||||
/// <summary>
|
||||
/// Id
|
||||
@@ -7,7 +7,7 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss;
|
||||
/// 表示一次战斗
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed class Battle
|
||||
internal sealed class SpiralAbyssBattle
|
||||
{
|
||||
/// <summary>
|
||||
/// 索引
|
||||
@@ -25,8 +25,8 @@ internal sealed class Battle
|
||||
/// 参战角色
|
||||
/// </summary>
|
||||
[JsonPropertyName("avatars")]
|
||||
public List<Avatar> Avatars { get; set; } = default!;
|
||||
public List<SpiralAbyssAvatar> Avatars { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("settle_date_time")]
|
||||
public SettleDateTime SettleDateTime { get; set; } = default!;
|
||||
public DateTime SettleDateTime { get; set; } = default!;
|
||||
}
|
||||
@@ -7,7 +7,7 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss;
|
||||
/// 层
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed class Floor
|
||||
internal sealed class SpiralAbyssFloor
|
||||
{
|
||||
/// <summary>
|
||||
/// 层号
|
||||
@@ -50,10 +50,10 @@ internal sealed class Floor
|
||||
/// 层信息
|
||||
/// </summary>
|
||||
[JsonPropertyName("levels")]
|
||||
public List<Level> Levels { get; set; } = default!;
|
||||
public List<SpiralAbyssLevel> Levels { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("settle_date_time")]
|
||||
public SettleDateTime? SettleDateTime { get; set; }
|
||||
public DateTime? SettleDateTime { get; set; }
|
||||
|
||||
[JsonPropertyName("ley_line_disorder")]
|
||||
public List<string> LeyLineDisorder { get; set; } = default!;
|
||||
@@ -7,7 +7,7 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss;
|
||||
/// 间
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed class Level
|
||||
internal sealed class SpiralAbyssLevel
|
||||
{
|
||||
/// <summary>
|
||||
/// 索引
|
||||
@@ -31,11 +31,11 @@ internal sealed class Level
|
||||
/// 上下半
|
||||
/// </summary>
|
||||
[JsonPropertyName("battles")]
|
||||
public List<Battle> Battles { get; set; } = default!;
|
||||
public List<SpiralAbyssBattle> Battles { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("top_half_floor_monster")]
|
||||
public List<Monster> TopHalfFloorMonster { get; set; } = default!;
|
||||
public List<SpiralAbyssMonster> TopHalfFloorMonster { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("bottom_half_floor_monster")]
|
||||
public List<Monster> BottomHalfFloorMonster { get; set; } = default!;
|
||||
public List<SpiralAbyssMonster> BottomHalfFloorMonster { get; set; } = default!;
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss;
|
||||
|
||||
internal sealed class Monster
|
||||
internal sealed class SpiralAbyssMonster
|
||||
{
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; } = default!;
|
||||
@@ -9,7 +9,7 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss;
|
||||
/// 角色数值排行信息
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed class Rank
|
||||
internal sealed class SpiralAbyssRank
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色Id
|
||||
@@ -214,7 +214,7 @@ internal sealed partial class HutaoSpiralAbyssClient
|
||||
if (charactersResponse.IsOk())
|
||||
{
|
||||
Response<Hoyolab.Takumi.GameRecord.SpiralAbyss.SpiralAbyss> spiralAbyssResponse = await gameRecordClient
|
||||
.GetSpiralAbyssAsync(userAndUid, SpiralAbyssSchedule.Current, token)
|
||||
.GetSpiralAbyssAsync(userAndUid, ScheduleType.Current, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (spiralAbyssResponse.IsOk())
|
||||
|
||||
@@ -16,7 +16,7 @@ internal sealed class SimpleBattle
|
||||
/// 构造一个新的战斗
|
||||
/// </summary>
|
||||
/// <param name="battle">战斗</param>
|
||||
public SimpleBattle(Battle battle)
|
||||
public SimpleBattle(SpiralAbyssBattle battle)
|
||||
{
|
||||
Index = battle.Index;
|
||||
Avatars = battle.Avatars.Select(a => a.Id);
|
||||
|
||||
@@ -15,7 +15,7 @@ internal sealed class SimpleFloor
|
||||
/// 构造一个新的层信息
|
||||
/// </summary>
|
||||
/// <param name="floor">层信息</param>
|
||||
public SimpleFloor(Floor floor)
|
||||
public SimpleFloor(SpiralAbyssFloor floor)
|
||||
{
|
||||
Index = floor.Index;
|
||||
Star = floor.Star;
|
||||
|
||||
@@ -15,7 +15,7 @@ internal sealed class SimpleLevel
|
||||
/// 构造一个新的间信息
|
||||
/// </summary>
|
||||
/// <param name="level">间信息</param>
|
||||
public SimpleLevel(Level level)
|
||||
public SimpleLevel(SpiralAbyssLevel level)
|
||||
{
|
||||
Index = level.Index;
|
||||
Star = level.Star;
|
||||
|
||||
@@ -15,7 +15,7 @@ internal sealed class SimpleRank
|
||||
/// 构造一个新的数值
|
||||
/// </summary>
|
||||
/// <param name="rank">排行</param>
|
||||
private SimpleRank(Rank rank)
|
||||
private SimpleRank(SpiralAbyssRank rank)
|
||||
{
|
||||
AvatarId = rank.AvatarId;
|
||||
Value = rank.Value;
|
||||
@@ -36,7 +36,7 @@ internal sealed class SimpleRank
|
||||
/// </summary>
|
||||
/// <param name="rank">排行</param>
|
||||
/// <returns>新的简单数值</returns>
|
||||
public static SimpleRank? FromRank(Rank? rank)
|
||||
public static SimpleRank? FromRank(SpiralAbyssRank? rank)
|
||||
{
|
||||
if (rank is null)
|
||||
{
|
||||
|
||||
@@ -13,9 +13,10 @@ internal static class HttpRequestMessageBuilderExtension
|
||||
{
|
||||
private const string RequestErrorMessage = "请求异常已忽略: {Uri}";
|
||||
|
||||
internal static void Resurrect(this HttpRequestMessageBuilder builder)
|
||||
internal static HttpRequestMessageBuilder Resurrect(this HttpRequestMessageBuilder builder)
|
||||
{
|
||||
builder.HttpRequestMessage.Resurrect();
|
||||
return builder;
|
||||
}
|
||||
|
||||
internal static async ValueTask<TResult?> SendAsync<TResult>(this HttpRequestMessageBuilder builder, HttpClient httpClient, ILogger logger, CancellationToken token)
|
||||
|
||||
Reference in New Issue
Block a user