diff --git a/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/SpiralAbyssRecordService.cs b/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/SpiralAbyssRecordService.cs index 6b36d762..fc2a3e11 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/SpiralAbyssRecordService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/SpiralAbyssRecordService.cs @@ -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 response; using (IServiceScope scope = serviceScopeFactory.CreateScope()) diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/BattleView.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/BattleView.cs index cff22872..ceee006b 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/BattleView.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/BattleView.cs @@ -52,7 +52,7 @@ internal sealed class BattleView : IMappingFrom AvatarView.From(context.IdAvatarMap[a.Id])); diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/FloorView.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/FloorView.cs index 9a5e6e3d..9105fe06 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/FloorView.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyss/FloorView.cs @@ -52,7 +52,7 @@ internal sealed class FloorView : IMappingFrom, 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, } } - private static List ToRankAvatars(List ranks, SpiralAbyssMetadataContext context) + private static List ToRankAvatars(List 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 ranks, SpiralAbyssMetadataContext context) + private static RankAvatar? ToRankAvatar(List ranks, SpiralAbyssMetadataContext context) { return ranks.Where(r => r.AvatarId != 0U).Select(r => new RankAvatar(r.Value, context.IdAvatarMap[r.AvatarId])).SingleOrDefault(); } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/ApiEndpoints.cs b/src/Snap.Hutao/Snap.Hutao/Web/ApiEndpoints.cs index 0ad572e9..4b16269a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/ApiEndpoints.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/ApiEndpoints.cs @@ -142,12 +142,19 @@ internal static class ApiEndpoints /// 深渊类型 /// Uid /// 深渊信息字符串 - 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 diff --git a/src/Snap.Hutao/Snap.Hutao/Web/ApiOsEndpoints.cs b/src/Snap.Hutao/Snap.Hutao/Web/ApiOsEndpoints.cs index 94d2025d..f8c43ccd 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/ApiOsEndpoints.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/ApiOsEndpoints.cs @@ -168,7 +168,7 @@ internal static class ApiOsEndpoints /// 深渊类型 /// Uid /// 深渊信息字符串 - 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}"; } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/CardVerifiationHeaders.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/CardVerifiationHeaders.cs index 0511cd00..5c5d2df0 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/CardVerifiationHeaders.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/CardVerifiationHeaders.cs @@ -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() diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNote.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNote.cs index 74a00f8b..80733099 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNote.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DailyNote/DailyNote.cs @@ -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, diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SettleDateTime.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DateTime.cs similarity index 83% rename from src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SettleDateTime.cs rename to src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DateTime.cs index 20defc10..ca811f8d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SettleDateTime.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/DateTime.cs @@ -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; } 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 1546e96e..8659d6e1 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 @@ -110,7 +110,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient return Response.Response.DefaultIfNull(resp); } - public async ValueTask> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default) + public async ValueTask> 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> 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? resp = await builder + .SendAsync>(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(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>(httpClient, logger, token) + .ConfigureAwait(false); + } + } + + return Response.Response.DefaultIfNull(resp); + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/GameRecordClientOversea.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/GameRecordClientOversea.cs index 65fae74e..50bdc430 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/GameRecordClientOversea.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/GameRecordClientOversea.cs @@ -53,7 +53,7 @@ internal sealed partial class GameRecordClientOversea : IGameRecordClient return Response.Response.DefaultIfNull(resp); } - public async ValueTask> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default) + public async ValueTask> 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> GetRoleCombatAsync(UserAndUid userAndUid, CancellationToken token = default(CancellationToken)) + { + return ValueTask.FromException>(new NotSupportedException()); + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/IGameRecordClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/IGameRecordClient.cs index d7dba61c..dbe7f00b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/IGameRecordClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/IGameRecordClient.cs @@ -12,37 +12,13 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord; /// internal interface IGameRecordClient { - /// - /// 获取玩家角色详细信息 - /// - /// 用户与角色 - /// 玩家的基础信息 - /// 取消令牌 - /// 角色列表 ValueTask> GetCharactersAsync(UserAndUid userAndUid, PlayerInfo playerInfo, CancellationToken token = default); - /// - /// 异步获取实时便笺 - /// - /// 用户与角色 - /// 取消令牌 - /// 实时便笺 ValueTask> GetDailyNoteAsync(UserAndUid userAndUid, CancellationToken token = default); - /// - /// 获取玩家基础信息 - /// - /// 用户与角色 - /// 取消令牌 - /// 玩家的基础信息 ValueTask> GetPlayerInfoAsync(UserAndUid userAndUid, CancellationToken token = default); - /// - /// 获取玩家深渊信息 - /// - /// 用户 - /// 1:当期,2:上期 - /// 取消令牌 - /// 深渊信息 - ValueTask> GetSpiralAbyssAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule, CancellationToken token = default); + ValueTask> GetSpiralAbyssAsync(UserAndUid userAndUid, ScheduleType schedule, CancellationToken token = default); + + ValueTask> GetRoleCombatAsync(UserAndUid userAndUid, CancellationToken token = default); } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombat.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombat.cs new file mode 100644 index 00000000..ae04bfcf --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombat.cs @@ -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 Data { get; set; } = default!; + + [JsonPropertyName("is_unlock")] + public bool IsUnlock { get; set; } + + [JsonPropertyName("links")] + public RoleCombatLinks Links { get; set; } = default!; +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatAvatar.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatAvatar.cs new file mode 100644 index 00000000..f7ca95d1 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatAvatar.cs @@ -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; } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatAvatarType.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatAvatarType.cs new file mode 100644 index 00000000..11190012 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatAvatarType.cs @@ -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 +{ + /// + /// 已有 + /// + Default = 1, + + /// + /// 试用 + /// + Trial = 2, + + /// + /// 借用 + /// + Support = 3, +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatBuff.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatBuff.cs new file mode 100644 index 00000000..aa5d329e --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatBuff.cs @@ -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; } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatData.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatData.cs new file mode 100644 index 00000000..7705fd4d --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatData.cs @@ -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; } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatDetail.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatDetail.cs new file mode 100644 index 00000000..80659a29 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatDetail.cs @@ -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 RoundsData { get; set; } = default!; + + [JsonPropertyName("detail_stat")] + public RoleCombatStat? DetailStat { get; set; } + + [JsonPropertyName("backup_avatars")] + public List BackupAvatars { get; set; } = default!; +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatLinks.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatLinks.cs new file mode 100644 index 00000000..7005476a --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatLinks.cs @@ -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!; +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatRoundData.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatRoundData.cs new file mode 100644 index 00000000..cd6c9287 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatRoundData.cs @@ -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 Avatars { get; set; } = default!; + + [JsonPropertyName("choice_cards")] + public List ChoiceCards { get; set; } = default!; + + [JsonPropertyName("buffs")] + public List 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!; +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatSchedule.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatSchedule.cs new file mode 100644 index 00000000..2457ea54 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatSchedule.cs @@ -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!; +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatStat.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatStat.cs new file mode 100644 index 00000000..7b3e7d65 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/RoleCombat/RoleCombatStat.cs @@ -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 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; } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyssSchedule.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/ScheduleType.cs similarity index 73% rename from src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyssSchedule.cs rename to src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/ScheduleType.cs index d8938af0..9a74509e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyssSchedule.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/ScheduleType.cs @@ -3,11 +3,7 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord; -/// -/// 深渊期数类型 -/// -[HighQuality] -internal enum SpiralAbyssSchedule +internal enum ScheduleType { /// /// 当期 diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyss.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyss.cs index 3d3a9244..bbe27aeb 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyss.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyss.cs @@ -49,43 +49,43 @@ internal sealed class SpiralAbyss /// 出战次数 /// [JsonPropertyName("reveal_rank")] - public List RevealRank { get; set; } = default!; + public List RevealRank { get; set; } = default!; /// /// 击破次数 /// [JsonPropertyName("defeat_rank")] - public List DefeatRank { get; set; } = default!; + public List DefeatRank { get; set; } = default!; /// /// 最强一击 /// [JsonPropertyName("damage_rank")] - public List DamageRank { get; set; } = default!; + public List DamageRank { get; set; } = default!; /// /// 承受伤害 /// [JsonPropertyName("take_damage_rank")] - public List TakeDamageRank { get; set; } = default!; + public List TakeDamageRank { get; set; } = default!; /// /// 元素战技 /// [JsonPropertyName("normal_skill_rank")] - public List NormalSkillRank { get; set; } = default!; + public List NormalSkillRank { get; set; } = default!; /// /// 元素爆发 /// [JsonPropertyName("energy_skill_rank")] - public List EnergySkillRank { get; set; } = default!; + public List EnergySkillRank { get; set; } = default!; /// /// 层信息 /// [JsonPropertyName("floors")] - public List Floors { get; set; } = default!; + public List Floors { get; set; } = default!; /// /// 共获得渊星 diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Avatar.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssAvatar.cs similarity index 95% rename from src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Avatar.cs rename to src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssAvatar.cs index 4961e810..7399dbe4 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Avatar.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssAvatar.cs @@ -9,7 +9,7 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss; /// 仅包含头像的角色信息 /// [HighQuality] -internal sealed class Avatar +internal sealed class SpiralAbyssAvatar { /// /// Id diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Battle.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssBattle.cs similarity index 78% rename from src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Battle.cs rename to src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssBattle.cs index 116f7428..0dc95dc3 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Battle.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssBattle.cs @@ -7,7 +7,7 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss; /// 表示一次战斗 /// [HighQuality] -internal sealed class Battle +internal sealed class SpiralAbyssBattle { /// /// 索引 @@ -25,8 +25,8 @@ internal sealed class Battle /// 参战角色 /// [JsonPropertyName("avatars")] - public List Avatars { get; set; } = default!; + public List Avatars { get; set; } = default!; [JsonPropertyName("settle_date_time")] - public SettleDateTime SettleDateTime { get; set; } = default!; + public DateTime SettleDateTime { get; set; } = default!; } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Floor.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssFloor.cs similarity index 89% rename from src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Floor.cs rename to src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssFloor.cs index a53bfc3e..f12f3686 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Floor.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssFloor.cs @@ -7,7 +7,7 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss; /// 层 /// [HighQuality] -internal sealed class Floor +internal sealed class SpiralAbyssFloor { /// /// 层号 @@ -50,10 +50,10 @@ internal sealed class Floor /// 层信息 /// [JsonPropertyName("levels")] - public List Levels { get; set; } = default!; + public List Levels { get; set; } = default!; [JsonPropertyName("settle_date_time")] - public SettleDateTime? SettleDateTime { get; set; } + public DateTime? SettleDateTime { get; set; } [JsonPropertyName("ley_line_disorder")] public List LeyLineDisorder { get; set; } = default!; diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Level.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssLevel.cs similarity index 73% rename from src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Level.cs rename to src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssLevel.cs index c3b637bc..61ac0d53 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Level.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssLevel.cs @@ -7,7 +7,7 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss; /// 间 /// [HighQuality] -internal sealed class Level +internal sealed class SpiralAbyssLevel { /// /// 索引 @@ -31,11 +31,11 @@ internal sealed class Level /// 上下半 /// [JsonPropertyName("battles")] - public List Battles { get; set; } = default!; + public List Battles { get; set; } = default!; [JsonPropertyName("top_half_floor_monster")] - public List TopHalfFloorMonster { get; set; } = default!; + public List TopHalfFloorMonster { get; set; } = default!; [JsonPropertyName("bottom_half_floor_monster")] - public List BottomHalfFloorMonster { get; set; } = default!; + public List BottomHalfFloorMonster { get; set; } = default!; } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Monster.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssMonster.cs similarity index 90% rename from src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Monster.cs rename to src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssMonster.cs index 7bb96cd8..2b709764 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Monster.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssMonster.cs @@ -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!; diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Rank.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssRank.cs similarity index 95% rename from src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Rank.cs rename to src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssRank.cs index 8964640a..41cb5597 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/Rank.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/SpiralAbyss/SpiralAbyssRank.cs @@ -9,7 +9,7 @@ namespace Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss; /// 角色数值排行信息 /// [HighQuality] -internal sealed class Rank +internal sealed class SpiralAbyssRank { /// /// 角色Id diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/HutaoSpiralAbyssClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/HutaoSpiralAbyssClient.cs index 4e09d763..f9c9399d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/HutaoSpiralAbyssClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/HutaoSpiralAbyssClient.cs @@ -214,7 +214,7 @@ internal sealed partial class HutaoSpiralAbyssClient if (charactersResponse.IsOk()) { Response spiralAbyssResponse = await gameRecordClient - .GetSpiralAbyssAsync(userAndUid, SpiralAbyssSchedule.Current, token) + .GetSpiralAbyssAsync(userAndUid, ScheduleType.Current, token) .ConfigureAwait(false); if (spiralAbyssResponse.IsOk()) diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/Post/SimpleBattle.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/Post/SimpleBattle.cs index 2766682f..2ebadf93 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/Post/SimpleBattle.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/Post/SimpleBattle.cs @@ -16,7 +16,7 @@ internal sealed class SimpleBattle /// 构造一个新的战斗 /// /// 战斗 - public SimpleBattle(Battle battle) + public SimpleBattle(SpiralAbyssBattle battle) { Index = battle.Index; Avatars = battle.Avatars.Select(a => a.Id); diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/Post/SimpleFloor.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/Post/SimpleFloor.cs index 030ebbd2..4c67bf06 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/Post/SimpleFloor.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/Post/SimpleFloor.cs @@ -15,7 +15,7 @@ internal sealed class SimpleFloor /// 构造一个新的层信息 /// /// 层信息 - public SimpleFloor(Floor floor) + public SimpleFloor(SpiralAbyssFloor floor) { Index = floor.Index; Star = floor.Star; diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/Post/SimpleLevel.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/Post/SimpleLevel.cs index 3a4793b0..32a12e03 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/Post/SimpleLevel.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/Post/SimpleLevel.cs @@ -15,7 +15,7 @@ internal sealed class SimpleLevel /// 构造一个新的间信息 /// /// 间信息 - public SimpleLevel(Level level) + public SimpleLevel(SpiralAbyssLevel level) { Index = level.Index; Star = level.Star; diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/Post/SimpleRank.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/Post/SimpleRank.cs index 07b94b24..7701905c 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/Post/SimpleRank.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/SpiralAbyss/Post/SimpleRank.cs @@ -15,7 +15,7 @@ internal sealed class SimpleRank /// 构造一个新的数值 /// /// 排行 - private SimpleRank(Rank rank) + private SimpleRank(SpiralAbyssRank rank) { AvatarId = rank.AvatarId; Value = rank.Value; @@ -36,7 +36,7 @@ internal sealed class SimpleRank /// /// 排行 /// 新的简单数值 - public static SimpleRank? FromRank(Rank? rank) + public static SimpleRank? FromRank(SpiralAbyssRank? rank) { if (rank is null) { diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpRequestMessageBuilderExtension.cs b/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpRequestMessageBuilderExtension.cs index 45875414..b834f07e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpRequestMessageBuilderExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpRequestMessageBuilderExtension.cs @@ -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 SendAsync(this HttpRequestMessageBuilder builder, HttpClient httpClient, ILogger logger, CancellationToken token)