From 8a2fa3c7017a621ef0a4aac78bc272f87e1059e2 Mon Sep 17 00:00:00 2001 From: Lightczx <1686188646@qq.com> Date: Sun, 3 Mar 2024 17:25:51 +0800 Subject: [PATCH 1/6] factory completed --- .../Core/ExceptionService/HutaoException.cs | 8 ++++++ .../ExceptionService/HutaoExceptionKind.cs | 1 + .../Snap.Hutao/Model/Entity/GachaItem.cs | 4 +-- .../Model/InterChange/GachaLog/UIGFItem.cs | 2 +- .../Snap.Hutao/Model/Metadata/GachaEvent.cs | 2 +- .../Snap.Hutao/Resource/Localization/SH.resx | 6 ++++ .../Factory/GachaConfigTypeComparer.cs | 6 ++-- .../Factory/GachaStatisticsExtension.cs | 2 +- .../Factory/GachaStatisticsFactory.cs | 12 ++++++-- .../Factory/GachaStatisticsSlimFactory.cs | 20 ++++++++++--- .../GachaLog/Factory/HistoryWishBuilder.cs | 12 ++++++-- .../Factory/HutaoStatisticsFactory.cs | 15 ++++++---- .../HutaoStatisticsFactoryMetadataContext.cs | 19 ++++++------- .../Factory/TypedWishSummaryBuilder.cs | 6 ++-- .../Factory/TypedWishSummaryBuilderContext.cs | 16 +++++++---- .../Service/GachaLog/GachaItemSaveContext.cs | 4 +-- .../Snap.Hutao/Service/GachaLog/GachaLog.cs | 10 +++---- .../Service/GachaLog/GachaLogDbService.cs | 18 ++++++------ .../Service/GachaLog/GachaLogFetchContext.cs | 4 +-- .../Service/GachaLog/GachaLogFetchStatus.cs | 4 +-- .../GachaLog/GachaLogHutaoCloudService.cs | 12 ++++---- .../Service/GachaLog/GachaLogService.cs | 2 +- .../Service/GachaLog/IGachaLogDbService.cs | 18 ++++++------ .../Service/GachaLog/UIGFImportService.cs | 2 +- .../IMetadataListGachaEventSource.cs | 11 ++++++++ .../MetadataServiceContextExtension.cs | 5 ++++ .../Snap.Hutao/View/Page/GachaLogPage.xaml | 2 +- .../ViewModel/GachaLog/GachaStatistics.cs | 5 ++++ .../ViewModel/GachaLog/HutaoStatistics.cs | 7 ++++- .../GachaInfo/GachaConfigTypeExtension.cs | 4 +-- .../Hk4e/Event/GachaInfo/GachaLogItem.cs | 2 +- .../Event/GachaInfo/GachaLogQueryOptions.cs | 4 +-- .../{GachaConfigType.cs => GachaType.cs} | 25 +++++++++-------- .../Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs | 28 +++++++++---------- .../Hutao/GachaLog/GachaDistributionType.cs | 5 ++++ .../Hutao/GachaLog/GachaEventStatistics.cs | 5 ++++ .../Web/Hutao/GachaLog/GachaItem.cs | 4 +-- 37 files changed, 198 insertions(+), 114 deletions(-) create mode 100644 src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/IMetadataListGachaEventSource.cs rename src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/{GachaConfigType.cs => GachaType.cs} (68%) diff --git a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoException.cs b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoException.cs index 33194edd..85aadfae 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoException.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoException.cs @@ -1,6 +1,8 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using System.Numerics; + namespace Snap.Hutao.Core.ExceptionService; internal sealed class HutaoException : Exception @@ -37,4 +39,10 @@ internal sealed class HutaoException : Exception string message = $"This instance of '{typeof(TFrom).FullName}' '{name}' doesn't implement '{typeof(TTo).FullName}'"; throw new HutaoException(HutaoExceptionKind.ServiceTypeCastFailed, message, innerException); } + + public static HutaoException GachaStatisticsInvalidItemId(uint id, Exception? innerException = default) + { + string message = SH.FormatServiceGachaStatisticsFactoryItemIdInvalid(id); + throw new HutaoException(HutaoExceptionKind.GachaStatisticsInvalidItemId, message, innerException); + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoExceptionKind.cs b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoExceptionKind.cs index 1848aae4..382c2ed0 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoExceptionKind.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoExceptionKind.cs @@ -9,4 +9,5 @@ internal enum HutaoExceptionKind ServiceTypeCastFailed, FileSystemCreateFileInsufficientPermissions, PrivateNamedPipeContentHashIncorrect, + GachaStatisticsInvalidItemId, } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/GachaItem.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/GachaItem.cs index cf7407b5..158bd4a6 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/GachaItem.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/GachaItem.cs @@ -42,14 +42,14 @@ internal sealed partial class GachaItem /// /// 祈愿记录分类 /// - public GachaConfigType GachaType { get; set; } + public GachaType GachaType { get; set; } /// /// 祈愿记录查询分类 /// 合并保底的卡池使用此属性 /// 仅4种(不含400) /// - public GachaConfigType QueryType { get; set; } + public GachaType QueryType { get; set; } /// /// 物品Id diff --git a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGFItem.cs b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGFItem.cs index 1f7df4fd..a0b6fe2f 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGFItem.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGFItem.cs @@ -20,7 +20,7 @@ internal sealed class UIGFItem : GachaLogItem, IMappingFrom [JsonPropertyName("uigf_gacha_type")] [JsonEnum(JsonSerializeType.NumberString)] - public GachaConfigType UIGFGachaType { get; set; } = default!; + public GachaType UIGFGachaType { get; set; } = default!; public static UIGFItem From(GachaItem item, INameQuality nameQuality) { diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/GachaEvent.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/GachaEvent.cs index dac8a7a7..6360b379 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/GachaEvent.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/GachaEvent.cs @@ -49,7 +49,7 @@ internal sealed class GachaEvent /// /// 卡池类型 /// - public GachaConfigType Type { get; set; } + public GachaType Type { get; set; } /// /// 五星列表 diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx index 13e56bf4..eb7bdfde 100644 --- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx +++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx @@ -860,6 +860,9 @@ 角色活动 + + 集录祈愿 + 奔行世间 @@ -3047,6 +3050,9 @@ 角色活动祈愿-2 + + 集录祈愿 + 新手祈愿 diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaConfigTypeComparer.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaConfigTypeComparer.cs index 533ff220..9771397f 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaConfigTypeComparer.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaConfigTypeComparer.cs @@ -10,7 +10,7 @@ namespace Snap.Hutao.Service.GachaLog.Factory; /// /// 祈愿配置类型比较器 /// -internal sealed class GachaConfigTypeComparer : IComparer +internal sealed class GachaConfigTypeComparer : IComparer { private static readonly Lazy LazyShared = new(() => new()); private static readonly FrozenDictionary OrderMap = FrozenDictionary.ToFrozenDictionary( @@ -28,13 +28,13 @@ internal sealed class GachaConfigTypeComparer : IComparer public static GachaConfigTypeComparer Shared { get => LazyShared.Value; } /// - public int Compare(GachaConfigType x, GachaConfigType y) + public int Compare(GachaType x, GachaType y) { return OrderOf(x) - OrderOf(y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int OrderOf(GachaConfigType type) + private static int OrderOf(GachaType type) { return OrderMap.GetValueOrDefault(type, 0); } diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsExtension.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsExtension.cs index 7259e33f..9663e3b1 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsExtension.cs @@ -62,4 +62,4 @@ internal static class GachaStatisticsExtension ReadOnlySpan codes = MD5.HashData(Encoding.UTF8.GetBytes(name)); return Color.FromArgb(255, codes.Slice(0, 5).Average(), codes.Slice(5, 5).Average(), codes.Slice(10, 5).Average()); } -} +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs index 56506999..d484cd32 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs @@ -54,6 +54,9 @@ internal sealed partial class GachaStatisticsFactory : IGachaStatisticsFactory TypedWishSummaryBuilderContext weaponContext = TypedWishSummaryBuilderContext.WeaponEventWish(taskContext, gachaLogClient); TypedWishSummaryBuilder weaponWishBuilder = new(weaponContext); + TypedWishSummaryBuilderContext chronicledContext = TypedWishSummaryBuilderContext.ChronicledWish(taskContext, gachaLogClient); + TypedWishSummaryBuilder chronicledWishBuilder = new(chronicledContext); + Dictionary orangeAvatarCounter = []; Dictionary purpleAvatarCounter = []; Dictionary orangeWeaponCounter = []; @@ -61,7 +64,7 @@ internal sealed partial class GachaStatisticsFactory : IGachaStatisticsFactory Dictionary blueWeaponCounter = []; // Pre group builders - Dictionary> historyWishBuilderMap = historyWishBuilders + Dictionary> historyWishBuilderMap = historyWishBuilders .GroupBy(b => b.ConfigType) .ToDictionary(g => g.Key, g => g.ToList().SortBy(b => b.From)); @@ -70,7 +73,7 @@ internal sealed partial class GachaStatisticsFactory : IGachaStatisticsFactory foreach (Model.Entity.GachaItem item in CollectionsMarshal.AsSpan(items)) { // Find target history wish to operate. // w.From <= item.Time <= w.To - HistoryWishBuilder? targetHistoryWishBuilder = item.GachaType is not (GachaConfigType.StandardWish or GachaConfigType.NoviceWish) + HistoryWishBuilder? targetHistoryWishBuilder = item.GachaType is not (GachaType.Standard or GachaType.NewBie) ? historyWishBuilderMap[item.GachaType].BinarySearch(w => item.Time < w.From ? -1 : item.Time > w.To ? 1 : 0) : default; @@ -98,6 +101,7 @@ internal sealed partial class GachaStatisticsFactory : IGachaStatisticsFactory standardWishBuilder.Track(item, avatar, isUp); avatarWishBuilder.Track(item, avatar, isUp); weaponWishBuilder.Track(item, avatar, isUp); + chronicledWishBuilder.Track(item, avatar, isUp); break; } @@ -127,12 +131,13 @@ internal sealed partial class GachaStatisticsFactory : IGachaStatisticsFactory standardWishBuilder.Track(item, weapon, isUp); avatarWishBuilder.Track(item, weapon, isUp); weaponWishBuilder.Track(item, weapon, isUp); + chronicledWishBuilder.Track(item, weapon, isUp); break; } default: // ItemId string length not correct. - ThrowHelper.UserdataCorrupted(SH.FormatServiceGachaStatisticsFactoryItemIdInvalid(item.ItemId), default!); + HutaoException.GachaStatisticsInvalidItemId(item.ItemId); break; } } @@ -162,6 +167,7 @@ internal sealed partial class GachaStatisticsFactory : IGachaStatisticsFactory StandardWish = standardWishBuilder.ToTypedWishSummary(barrier), AvatarWish = avatarWishBuilder.ToTypedWishSummary(barrier), WeaponWish = weaponWishBuilder.ToTypedWishSummary(barrier), + ChronicledWish = chronicledWishBuilder.ToTypedWishSummary(barrier), }; } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsSlimFactory.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsSlimFactory.cs index daa3e0b6..22b02de4 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsSlimFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsSlimFactory.cs @@ -62,22 +62,29 @@ internal sealed partial class GachaStatisticsSlimFactory : IGachaStatisticsSlimF int weaponPurpleTracker = 0; TypedWishSummarySlim weaponWish = new(SH.ServiceGachaLogFactoryWeaponWishName, 80, 10); + int chronicledOrangeTracker = 0; + int chronicledPurpleTracker = 0; + TypedWishSummarySlim chronicledWish = new(SH.ServiceGachaLogFactoryChronicledWishName, 90, 10); + // O(n) operation foreach (ref readonly GachaItem item in CollectionsMarshal.AsSpan(items)) { INameQuality nameQuality = context.GetNameQualityByItemId(item.ItemId); switch (item.QueryType) { - case GachaConfigType.StandardWish: + case GachaType.Standard: Track(nameQuality, ref standardOrangeTracker, ref standardPurpleTracker); break; - case GachaConfigType.AvatarEventWish: - case GachaConfigType.AvatarEventWish2: + case GachaType.ActivityAvatar: + case GachaType.SpecialActivityAvatar: Track(nameQuality, ref avatarOrangeTracker, ref avatarPurpleTracker); break; - case GachaConfigType.WeaponEventWish: + case GachaType.ActivityWeapon: Track(nameQuality, ref weaponOrangeTracker, ref weaponPurpleTracker); break; + case GachaType.ActivityCity: + Track(nameQuality, ref chronicledOrangeTracker, ref chronicledPurpleTracker); + break; default: break; } @@ -85,11 +92,16 @@ internal sealed partial class GachaStatisticsSlimFactory : IGachaStatisticsSlimF standardWish.LastOrangePull = standardOrangeTracker; standardWish.LastPurplePull = standardPurpleTracker; + avatarWish.LastOrangePull = avatarOrangeTracker; avatarWish.LastPurplePull = avatarPurpleTracker; + weaponWish.LastOrangePull = weaponOrangeTracker; weaponWish.LastPurplePull = weaponPurpleTracker; + chronicledWish.LastOrangePull = chronicledOrangeTracker; + chronicledWish.LastPurplePull = chronicledPurpleTracker; + return new() { Uid = uid, diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HistoryWishBuilder.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HistoryWishBuilder.cs index 043a43bb..55166473 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HistoryWishBuilder.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HistoryWishBuilder.cs @@ -37,21 +37,27 @@ internal sealed class HistoryWishBuilder switch (ConfigType) { - case GachaConfigType.AvatarEventWish or GachaConfigType.AvatarEventWish2: + case GachaType.ActivityAvatar or GachaType.SpecialActivityAvatar: orangeUpCounter = gachaEvent.UpOrangeList.Select(id => context.IdAvatarMap[id]).ToDictionary(a => (IStatisticsItemSource)a, a => 0); purpleUpCounter = gachaEvent.UpPurpleList.Select(id => context.IdAvatarMap[id]).ToDictionary(a => (IStatisticsItemSource)a, a => 0); break; - case GachaConfigType.WeaponEventWish: + case GachaType.ActivityWeapon: orangeUpCounter = gachaEvent.UpOrangeList.Select(id => context.IdWeaponMap[id]).ToDictionary(w => (IStatisticsItemSource)w, w => 0); purpleUpCounter = gachaEvent.UpPurpleList.Select(id => context.IdWeaponMap[id]).ToDictionary(w => (IStatisticsItemSource)w, w => 0); break; + case GachaType.ActivityCity: + + // Avatars are less than weapons, so we try to get the value from avatar map first + orangeUpCounter = gachaEvent.UpOrangeList.Select(id => (IStatisticsItemSource?)context.IdAvatarMap.GetValueOrDefault(id) ?? context.IdWeaponMap[id]).ToDictionary(c => c, c => 0); + purpleUpCounter = gachaEvent.UpPurpleList.Select(id => (IStatisticsItemSource?)context.IdAvatarMap.GetValueOrDefault(id) ?? context.IdWeaponMap[id]).ToDictionary(c => c, c => 0); + break; } } /// /// 祈愿配置类型 /// - public GachaConfigType ConfigType { get; } + public GachaType ConfigType { get; } /// public DateTimeOffset From { get => gachaEvent.From; } diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactory.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactory.cs index feae8b55..1e4657a1 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactory.cs @@ -18,18 +18,20 @@ internal sealed class HutaoStatisticsFactory private readonly GachaEvent avatarEvent; private readonly GachaEvent avatarEvent2; private readonly GachaEvent weaponEvent; + private readonly GachaEvent chronicledEvent; public HutaoStatisticsFactory(in HutaoStatisticsFactoryMetadataContext context) { this.context = context; - // TODO: when in new verion + // when in new verion // due to lack of newer metadata // this can crash DateTimeOffset now = DateTimeOffset.UtcNow; - avatarEvent = context.GachaEvents.Single(g => g.From < now && g.To > now && g.Type == GachaConfigType.AvatarEventWish); - avatarEvent2 = context.GachaEvents.Single(g => g.From < now && g.To > now && g.Type == GachaConfigType.AvatarEventWish2); - weaponEvent = context.GachaEvents.Single(g => g.From < now && g.To > now && g.Type == GachaConfigType.WeaponEventWish); + avatarEvent = context.GachaEvents.Single(g => g.From < now && g.To > now && g.Type == GachaType.ActivityAvatar); + avatarEvent2 = context.GachaEvents.Single(g => g.From < now && g.To > now && g.Type == GachaType.SpecialActivityAvatar); + weaponEvent = context.GachaEvents.Single(g => g.From < now && g.To > now && g.Type == GachaType.ActivityWeapon); + chronicledEvent = context.GachaEvents.Single(g => g.From < now && g.To > now && g.Type == GachaType.ActivityCity); } public HutaoStatistics Create(GachaEventStatistics raw) @@ -38,7 +40,8 @@ internal sealed class HutaoStatisticsFactory { AvatarEvent = CreateWishSummary(avatarEvent, raw.AvatarEvent), AvatarEvent2 = CreateWishSummary(avatarEvent2, raw.AvatarEvent2), - WeaponWish = CreateWishSummary(weaponEvent, raw.WeaponEvent), + WeaponEvent = CreateWishSummary(weaponEvent, raw.WeaponEvent), + ChronicledWish = CreateWishSummary(chronicledEvent, raw.Chronicled), }; } @@ -55,7 +58,7 @@ internal sealed class HutaoStatisticsFactory { 8U => context.IdAvatarMap[item.Item], 5U => context.IdWeaponMap[item.Item], - _ => throw ThrowHelper.UserdataCorrupted(SH.FormatServiceGachaStatisticsFactoryItemIdInvalid(item.Item), default!), + _ => throw HutaoException.GachaStatisticsInvalidItemId(item.Item), }; StatisticsItem statisticsItem = source.ToStatisticsItem(unchecked((int)item.Count)); diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactoryMetadataContext.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactoryMetadataContext.cs index 9076274d..6ef7af42 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactoryMetadataContext.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactoryMetadataContext.cs @@ -5,19 +5,18 @@ using Snap.Hutao.Model.Metadata; using Snap.Hutao.Model.Metadata.Avatar; using Snap.Hutao.Model.Metadata.Weapon; using Snap.Hutao.Model.Primitive; +using Snap.Hutao.Service.Metadata.ContextAbstraction; namespace Snap.Hutao.Service.GachaLog.Factory; -internal readonly struct HutaoStatisticsFactoryMetadataContext +internal sealed class HutaoStatisticsFactoryMetadataContext : IMetadataContext, + IMetadataDictionaryIdAvatarSource, + IMetadataDictionaryIdWeaponSource, + IMetadataListGachaEventSource { - public readonly Dictionary IdAvatarMap; - public readonly Dictionary IdWeaponMap; - public readonly List GachaEvents; + public Dictionary IdAvatarMap { get; set; } = default!; - public HutaoStatisticsFactoryMetadataContext(Dictionary idAvatarMap, Dictionary idWeaponMap, List gachaEvents) - { - IdAvatarMap = idAvatarMap; - IdWeaponMap = idWeaponMap; - GachaEvents = gachaEvents; - } + public Dictionary IdWeaponMap { get; set; } = default!; + + public List GachaEvents { get; set; } = default!; } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilder.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilder.cs index db25c690..72e13b23 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilder.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilder.cs @@ -18,17 +18,17 @@ internal sealed class TypedWishSummaryBuilder /// /// 常驻祈愿 /// - public static readonly Func IsStandardWish = type => type is GachaConfigType.StandardWish; + public static readonly Func IsStandardWish = type => type is GachaType.Standard; /// /// 角色活动 /// - public static readonly Func IsAvatarEventWish = type => type is GachaConfigType.AvatarEventWish or GachaConfigType.AvatarEventWish2; + public static readonly Func IsAvatarEventWish = type => type is GachaType.ActivityAvatar or GachaType.SpecialActivityAvatar; /// /// 武器活动 /// - public static readonly Func IsWeaponEventWish = type => type is GachaConfigType.WeaponEventWish; + public static readonly Func IsWeaponEventWish = type => type is GachaType.ActivityWeapon; private readonly TypedWishSummaryBuilderContext context; diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilderContext.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilderContext.cs index 5c964feb..f75fb481 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilderContext.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilderContext.cs @@ -14,12 +14,13 @@ internal readonly struct TypedWishSummaryBuilderContext public readonly string Name; public readonly int GuaranteeOrangeThreshold; public readonly int GuaranteePurpleThreshold; - public readonly Func TypeEvaluator; + public readonly Func TypeEvaluator; public readonly GachaDistributionType DistributionType; - private static readonly Func IsStandardWish = type => type is GachaConfigType.StandardWish; - private static readonly Func IsAvatarEventWish = type => type is GachaConfigType.AvatarEventWish or GachaConfigType.AvatarEventWish2; - private static readonly Func IsWeaponEventWish = type => type is GachaConfigType.WeaponEventWish; + private static readonly Func IsStandardWish = type => type is GachaType.Standard; + private static readonly Func IsAvatarEventWish = type => type is GachaType.ActivityAvatar or GachaType.SpecialActivityAvatar; + private static readonly Func IsWeaponEventWish = type => type is GachaType.ActivityWeapon; + private static readonly Func IsChronicledWish = type => type is GachaType.ActivityCity; public TypedWishSummaryBuilderContext( ITaskContext taskContext, @@ -27,7 +28,7 @@ internal readonly struct TypedWishSummaryBuilderContext string name, int guaranteeOrangeThreshold, int guaranteePurpleThreshold, - Func typeEvaluator, + Func typeEvaluator, GachaDistributionType distributionType) { TaskContext = taskContext; @@ -54,6 +55,11 @@ internal readonly struct TypedWishSummaryBuilderContext return new(taskContext, gachaLogClient, SH.ServiceGachaLogFactoryWeaponWishName, 80, 10, IsWeaponEventWish, GachaDistributionType.WeaponEvent); } + public static TypedWishSummaryBuilderContext ChronicledWish(ITaskContext taskContext, HomaGachaLogClient gachaLogClient) + { + return new(taskContext, gachaLogClient, SH.ServiceGachaLogFactoryChronicledWishName, 90, 10, IsChronicledWish, GachaDistributionType.Chronicled); + } + public ValueTask> GetGachaDistributionAsync() { return GachaLogClient.GetGachaDistributionAsync(DistributionType); diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaItemSaveContext.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaItemSaveContext.cs index b225eb64..4895bf5a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaItemSaveContext.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaItemSaveContext.cs @@ -21,7 +21,7 @@ internal readonly struct GachaItemSaveContext /// public readonly bool IsLazy; - public readonly GachaConfigType QueryType; + public readonly GachaType QueryType; /// /// 结尾 Id @@ -33,7 +33,7 @@ internal readonly struct GachaItemSaveContext /// public readonly IGachaLogDbService GachaLogDbService; - public GachaItemSaveContext(List itemsToAdd, bool isLazy, GachaConfigType queryType, long endId, IGachaLogDbService gachaLogDbService) + public GachaItemSaveContext(List itemsToAdd, bool isLazy, GachaType queryType, long endId, IGachaLogDbService gachaLogDbService) { ItemsToAdd = itemsToAdd; IsLazy = isLazy; diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLog.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLog.cs index 81de38be..bc85b90a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLog.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLog.cs @@ -14,11 +14,11 @@ internal static class GachaLog /// /// 查询类型 /// - public static readonly FrozenSet QueryTypes = FrozenSet.ToFrozenSet( + public static readonly FrozenSet QueryTypes = FrozenSet.ToFrozenSet( [ - GachaConfigType.NoviceWish, - GachaConfigType.StandardWish, - GachaConfigType.AvatarEventWish, - GachaConfigType.WeaponEventWish, + GachaType.NewBie, + GachaType.Standard, + GachaType.ActivityAvatar, + GachaType.ActivityWeapon, ]); } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogDbService.cs index 4d6b8abb..421f8951 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogDbService.cs @@ -73,7 +73,7 @@ internal sealed partial class GachaLogDbService : IGachaLogDbService } } - public async ValueTask GetNewestGachaItemIdByArchiveIdAndQueryTypeAsync(Guid archiveId, GachaConfigType queryType, CancellationToken token) + public async ValueTask GetNewestGachaItemIdByArchiveIdAndQueryTypeAsync(Guid archiveId, GachaType queryType, CancellationToken token) { GachaItem? item = null; @@ -103,7 +103,7 @@ internal sealed partial class GachaLogDbService : IGachaLogDbService return item?.Id ?? 0L; } - public long GetNewestGachaItemIdByArchiveIdAndQueryType(Guid archiveId, GachaConfigType queryType) + public long GetNewestGachaItemIdByArchiveIdAndQueryType(Guid archiveId, GachaType queryType) { GachaItem? item = null; @@ -132,7 +132,7 @@ internal sealed partial class GachaLogDbService : IGachaLogDbService return item?.Id ?? 0L; } - public async ValueTask GetNewestGachaItemIdByArchiveIdAndQueryTypeAsync(Guid archiveId, GachaConfigType queryType) + public async ValueTask GetNewestGachaItemIdByArchiveIdAndQueryTypeAsync(Guid archiveId, GachaType queryType) { GachaItem? item = null; @@ -205,7 +205,7 @@ internal sealed partial class GachaLogDbService : IGachaLogDbService return item?.Id ?? long.MaxValue; } - public long GetOldestGachaItemIdByArchiveIdAndQueryType(Guid archiveId, GachaConfigType queryType) + public long GetOldestGachaItemIdByArchiveIdAndQueryType(Guid archiveId, GachaType queryType) { GachaItem? item = null; @@ -226,7 +226,7 @@ internal sealed partial class GachaLogDbService : IGachaLogDbService return item?.Id ?? long.MaxValue; } - public async ValueTask GetOldestGachaItemIdByArchiveIdAndQueryTypeAsync(Guid archiveId, GachaConfigType queryType, CancellationToken token) + public async ValueTask GetOldestGachaItemIdByArchiveIdAndQueryTypeAsync(Guid archiveId, GachaType queryType, CancellationToken token) { GachaItem? item = null; @@ -266,7 +266,7 @@ internal sealed partial class GachaLogDbService : IGachaLogDbService } } - public List GetHutaoGachaItemList(Guid archiveId, GachaConfigType queryType, long endId) + public List GetHutaoGachaItemList(Guid archiveId, GachaType queryType, long endId) { using (IServiceScope scope = serviceProvider.CreateScope()) { @@ -291,7 +291,7 @@ internal sealed partial class GachaLogDbService : IGachaLogDbService } } - public async ValueTask> GetHutaoGachaItemListAsync(Guid archiveId, GachaConfigType queryType, long endId) + public async ValueTask> GetHutaoGachaItemListAsync(Guid archiveId, GachaType queryType, long endId) { using (IServiceScope scope = serviceProvider.CreateScope()) { @@ -368,7 +368,7 @@ internal sealed partial class GachaLogDbService : IGachaLogDbService } } - public void RemoveNewerGachaItemRangeByArchiveIdQueryTypeAndEndId(Guid archiveId, GachaConfigType queryType, long endId) + public void RemoveNewerGachaItemRangeByArchiveIdQueryTypeAndEndId(Guid archiveId, GachaType queryType, long endId) { using (IServiceScope scope = serviceProvider.CreateScope()) { @@ -381,7 +381,7 @@ internal sealed partial class GachaLogDbService : IGachaLogDbService } } - public async ValueTask RemoveNewerGachaItemRangeByArchiveIdQueryTypeAndEndIdAsync(Guid archiveId, GachaConfigType queryType, long endId) + public async ValueTask RemoveNewerGachaItemRangeByArchiveIdQueryTypeAndEndIdAsync(Guid archiveId, GachaType queryType, long endId) { using (IServiceScope scope = serviceProvider.CreateScope()) { diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogFetchContext.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogFetchContext.cs index 5d7448eb..871ee384 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogFetchContext.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogFetchContext.cs @@ -46,7 +46,7 @@ internal struct GachaLogFetchContext /// /// 当前类型 /// - public GachaConfigType CurrentType; + public GachaType CurrentType; private readonly GachaLogServiceMetadataContext serviceContext; private readonly IGachaLogDbService gachaLogDbService; @@ -66,7 +66,7 @@ internal struct GachaLogFetchContext /// /// 卡池类型 /// 查询 - public void ResetForProcessingType(GachaConfigType configType, in GachaLogQuery query) + public void ResetForProcessingType(GachaType configType, in GachaLogQuery query) { DbEndId = null; CurrentType = configType; diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogFetchStatus.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogFetchStatus.cs index a01c15c4..55fa83d0 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogFetchStatus.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogFetchStatus.cs @@ -15,7 +15,7 @@ internal sealed class GachaLogFetchStatus /// 构造一个新的祈愿记录获取状态 /// /// 卡池类型 - public GachaLogFetchStatus(GachaConfigType configType) + public GachaLogFetchStatus(GachaType configType) { ConfigType = configType; } @@ -28,7 +28,7 @@ internal sealed class GachaLogFetchStatus /// /// 卡池类型 /// - public GachaConfigType ConfigType { get; set; } + public GachaType ConfigType { get; set; } /// /// 当前获取的物品 diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogHutaoCloudService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogHutaoCloudService.cs index 9998565e..232eb10b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogHutaoCloudService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogHutaoCloudService.cs @@ -8,6 +8,7 @@ using Snap.Hutao.Model.Metadata.Weapon; using Snap.Hutao.Model.Primitive; using Snap.Hutao.Service.GachaLog.Factory; using Snap.Hutao.Service.Metadata; +using Snap.Hutao.Service.Metadata.ContextAbstraction; using Snap.Hutao.ViewModel.GachaLog; using Snap.Hutao.Web.Hoyolab.Hk4e.Event.GachaInfo; using Snap.Hutao.Web.Hutao.GachaLog; @@ -40,7 +41,7 @@ internal sealed partial class GachaLogHutaoCloudService : IGachaLogHutaoCloudSer if (await GetEndIdsFromCloudAsync(uid, token).ConfigureAwait(false) is { } endIds) { List items = []; - foreach ((GachaConfigType type, long endId) in endIds) + foreach ((GachaType type, long endId) in endIds) { List part = await gachaLogDbService .GetHutaoGachaItemListAsync(gachaArchive.InnerId, type, endId) @@ -94,10 +95,9 @@ internal sealed partial class GachaLogHutaoCloudService : IGachaLogHutaoCloudSer { if (await metadataService.InitializeAsync().ConfigureAwait(false)) { - Dictionary idAvatarMap = await metadataService.GetIdToAvatarMapAsync(token).ConfigureAwait(false); - Dictionary idWeaponMap = await metadataService.GetIdToWeaponMapAsync(token).ConfigureAwait(false); - List gachaEvents = await metadataService.GetGachaEventListAsync(token).ConfigureAwait(false); - HutaoStatisticsFactoryMetadataContext context = new(idAvatarMap, idWeaponMap, gachaEvents); + HutaoStatisticsFactoryMetadataContext context = await metadataService + .GetContextAsync(token) + .ConfigureAwait(false); GachaEventStatistics raw = response.Data; try @@ -126,7 +126,7 @@ internal sealed partial class GachaLogHutaoCloudService : IGachaLogHutaoCloudSer private async ValueTask CreateEndIdsAsync(GachaArchive? archive, CancellationToken token) { EndIds endIds = new(); - foreach (GachaConfigType type in GachaLog.QueryTypes) + foreach (GachaType type in GachaLog.QueryTypes) { if (archive is not null) { diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs index 0f2416e8..d6a86465 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs @@ -182,7 +182,7 @@ internal sealed partial class GachaLogService : IGachaLogService ArgumentNullException.ThrowIfNull(ArchiveCollection); GachaLogFetchContext fetchContext = new(gachaLogDbService, taskContext, context, isLazy); - foreach (GachaConfigType configType in GachaLog.QueryTypes) + foreach (GachaType configType in GachaLog.QueryTypes) { fetchContext.ResetForProcessingType(configType, query); diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogDbService.cs index 43fba695..14d38197 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogDbService.cs @@ -19,7 +19,7 @@ internal interface IGachaLogDbService ValueTask RemoveGachaArchiveByIdAsync(Guid archiveId); - void RemoveNewerGachaItemRangeByArchiveIdQueryTypeAndEndId(Guid archiveId, GachaConfigType queryType, long endId); + void RemoveNewerGachaItemRangeByArchiveIdQueryTypeAndEndId(Guid archiveId, GachaType queryType, long endId); ValueTask GetGachaArchiveByIdAsync(Guid archiveId, CancellationToken token); @@ -31,25 +31,25 @@ internal interface IGachaLogDbService ValueTask> GetGachaItemListByArchiveIdAsync(Guid archiveId); - List GetHutaoGachaItemList(Guid archiveId, GachaConfigType queryType, long endId); + List GetHutaoGachaItemList(Guid archiveId, GachaType queryType, long endId); - long GetNewestGachaItemIdByArchiveIdAndQueryType(Guid archiveId, GachaConfigType queryType); + long GetNewestGachaItemIdByArchiveIdAndQueryType(Guid archiveId, GachaType queryType); - ValueTask GetNewestGachaItemIdByArchiveIdAndQueryTypeAsync(Guid archiveId, GachaConfigType queryType, CancellationToken token); + ValueTask GetNewestGachaItemIdByArchiveIdAndQueryTypeAsync(Guid archiveId, GachaType queryType, CancellationToken token); long GetOldestGachaItemIdByArchiveId(Guid archiveId); - long GetOldestGachaItemIdByArchiveIdAndQueryType(Guid archiveId, GachaConfigType queryType); + long GetOldestGachaItemIdByArchiveIdAndQueryType(Guid archiveId, GachaType queryType); - ValueTask GetOldestGachaItemIdByArchiveIdAndQueryTypeAsync(Guid archiveId, GachaConfigType queryType, CancellationToken token); + ValueTask GetOldestGachaItemIdByArchiveIdAndQueryTypeAsync(Guid archiveId, GachaType queryType, CancellationToken token); - ValueTask GetNewestGachaItemIdByArchiveIdAndQueryTypeAsync(Guid archiveId, GachaConfigType queryType); + ValueTask GetNewestGachaItemIdByArchiveIdAndQueryTypeAsync(Guid archiveId, GachaType queryType); ValueTask GetOldestGachaItemIdByArchiveIdAsync(Guid archiveId); - ValueTask> GetHutaoGachaItemListAsync(Guid archiveId, GachaConfigType queryType, long endId); + ValueTask> GetHutaoGachaItemListAsync(Guid archiveId, GachaType queryType, long endId); ValueTask AddGachaItemRangeAsync(List items); - ValueTask RemoveNewerGachaItemRangeByArchiveIdQueryTypeAndEndIdAsync(Guid archiveId, GachaConfigType queryType, long endId); + ValueTask RemoveNewerGachaItemRangeByArchiveIdQueryTypeAndEndIdAsync(Guid archiveId, GachaType queryType, long endId); } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UIGFImportService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UIGFImportService.cs index 696d65cc..f4efebb5 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UIGFImportService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UIGFImportService.cs @@ -62,7 +62,7 @@ internal sealed partial class UIGFImportService : IUIGFImportService Guid archiveId = archive.InnerId; List fullItems = []; - foreach (GachaConfigType queryType in GachaLog.QueryTypes) + foreach (GachaType queryType in GachaLog.QueryTypes) { long trimId = gachaLogDbService.GetOldestGachaItemIdByArchiveIdAndQueryType(archiveId, queryType); logger.LogInformation("Last Id to trim with: [{Id}]", trimId); diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/IMetadataListGachaEventSource.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/IMetadataListGachaEventSource.cs new file mode 100644 index 00000000..165cdcef --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/IMetadataListGachaEventSource.cs @@ -0,0 +1,11 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Snap.Hutao.Model.Metadata; + +namespace Snap.Hutao.Service.Metadata.ContextAbstraction; + +internal interface IMetadataListGachaEventSource +{ + public List GachaEvents { get; set; } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/MetadataServiceContextExtension.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/MetadataServiceContextExtension.cs index 114b56f5..e0db64dd 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/MetadataServiceContextExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/MetadataServiceContextExtension.cs @@ -21,6 +21,11 @@ internal static class MetadataServiceContextExtension { listMaterialSource.Materials = await metadataService.GetMaterialListAsync(token).ConfigureAwait(false); } + + if (context is IMetadataListGachaEventSource listGachaEventSource) + { + listGachaEventSource.GachaEvents = await metadataService.GetGachaEventListAsync(token).ConfigureAwait(false); + } } // Dictionary diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/GachaLogPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/GachaLogPage.xaml index 6116d098..67a608f3 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/GachaLogPage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/GachaLogPage.xaml @@ -484,7 +484,7 @@ - + diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaStatistics.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaStatistics.cs index 3b1b2b51..d0512416 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaStatistics.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaStatistics.cs @@ -19,6 +19,11 @@ internal sealed class GachaStatistics /// public TypedWishSummary WeaponWish { get; set; } = default!; + /// + /// 集录祈愿 + /// + public TypedWishSummary ChronicledWish { get; set; } = default!; + /// /// 奔行世间 /// diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/HutaoStatistics.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/HutaoStatistics.cs index 7abf372a..c3b68061 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/HutaoStatistics.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/HutaoStatistics.cs @@ -21,5 +21,10 @@ internal sealed class HutaoStatistics /// /// 神铸赋形 /// - public HutaoWishSummary WeaponWish { get; set; } = default!; + public HutaoWishSummary WeaponEvent { get; set; } = default!; + + /// + /// 集录祈愿 + /// + public HutaoWishSummary ChronicledWish { get; set; } = default!; } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaConfigTypeExtension.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaConfigTypeExtension.cs index ddda41be..3850e975 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaConfigTypeExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaConfigTypeExtension.cs @@ -10,11 +10,11 @@ internal static class GachaConfigTypeExtension /// /// 配置类型 /// 祈愿查询类型 - public static GachaConfigType ToQueryType(this GachaConfigType configType) + public static GachaType ToQueryType(this GachaType configType) { return configType switch { - GachaConfigType.AvatarEventWish2 => GachaConfigType.AvatarEventWish, + GachaType.SpecialActivityAvatar => GachaType.ActivityAvatar, _ => configType, }; } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaLogItem.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaLogItem.cs index ee0a60bf..7b5a682f 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaLogItem.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaLogItem.cs @@ -23,7 +23,7 @@ internal class GachaLogItem /// [JsonPropertyName("gacha_type")] [JsonEnum(JsonSerializeType.NumberString)] - public GachaConfigType GachaType { get; set; } = default!; + public GachaType GachaType { get; set; } = default!; /// /// 总为 diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaLogQueryOptions.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaLogQueryOptions.cs index 11d31ea4..e8c33611 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaLogQueryOptions.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaLogQueryOptions.cs @@ -31,7 +31,7 @@ internal struct GachaLogQueryOptions /// public long EndId; - public GachaConfigType Type; + public GachaType Type; /// /// Keys required: @@ -53,7 +53,7 @@ internal struct GachaLogQueryOptions /// 原始查询字符串 /// 祈愿类型 /// 终止Id - public GachaLogQueryOptions(in GachaLogQuery query, GachaConfigType queryType) + public GachaLogQueryOptions(in GachaLogQuery query, GachaType queryType) { IsOversea = query.IsOversea; diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaConfigType.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaType.cs similarity index 68% rename from src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaConfigType.cs rename to src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaType.cs index fa41947e..c23571a3 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaConfigType.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Event/GachaInfo/GachaType.cs @@ -4,44 +4,45 @@ namespace Snap.Hutao.Web.Hoyolab.Hk4e.Event.GachaInfo; /// -/// 祈愿配置类型 +/// 祈愿类型 /// [HighQuality] [Localization] -internal enum GachaConfigType +internal enum GachaType { /// /// 新手池 /// - [Description("新手祈愿")] [LocalizationKey(nameof(SH.WebGachaConfigTypeNoviceWish))] - NoviceWish = 100, + NewBie = 100, /// /// 常驻池 /// - [Description("常驻祈愿")] [LocalizationKey(nameof(SH.WebGachaConfigTypePermanentWish))] - StandardWish = 200, + Standard = 200, /// /// 角色1池 /// - [Description("角色活动祈愿")] [LocalizationKey(nameof(SH.WebGachaConfigTypeAvatarEventWish))] - AvatarEventWish = 301, + ActivityAvatar = 301, /// /// 武器池 /// - [Description("武器活动祈愿")] [LocalizationKey(nameof(SH.WebGachaConfigTypeWeaponEventWish))] - WeaponEventWish = 302, + ActivityWeapon = 302, /// /// 角色2池 /// - [Description("角色活动祈愿-2")] [LocalizationKey(nameof(SH.WebGachaConfigTypeAvatarEventWish2))] - AvatarEventWish2 = 400, + SpecialActivityAvatar = 400, + + /// + /// 集录池 + /// + [LocalizationKey(nameof(SH.WebGachaConfigTypeChronicledWish))] + ActivityCity = 500, } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs index bfdb4578..07baf4a5 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs @@ -39,16 +39,16 @@ internal sealed class EndIds /// /// 类型 /// Last Id - public long this[GachaConfigType type] + public long this[GachaType type] { get { return type switch { - GachaConfigType.NoviceWish => NoviceWish, - GachaConfigType.StandardWish => StandardWish, - GachaConfigType.AvatarEventWish => AvatarEventWish, - GachaConfigType.WeaponEventWish => WeaponEventWish, + GachaType.NewBie => NoviceWish, + GachaType.Standard => StandardWish, + GachaType.ActivityAvatar => AvatarEventWish, + GachaType.ActivityWeapon => WeaponEventWish, _ => 0, }; } @@ -57,16 +57,16 @@ internal sealed class EndIds { switch (type) { - case GachaConfigType.NoviceWish: + case GachaType.NewBie: NoviceWish = value; break; - case GachaConfigType.StandardWish: + case GachaType.Standard: StandardWish = value; break; - case GachaConfigType.AvatarEventWish: + case GachaType.ActivityAvatar: AvatarEventWish = value; break; - case GachaConfigType.WeaponEventWish: + case GachaType.ActivityWeapon: WeaponEventWish = value; break; } @@ -77,11 +77,11 @@ internal sealed class EndIds /// 获取枚举器 /// /// 枚举器 - public IEnumerator> GetEnumerator() + public IEnumerator> GetEnumerator() { - yield return new(GachaConfigType.NoviceWish, NoviceWish); - yield return new(GachaConfigType.StandardWish, StandardWish); - yield return new(GachaConfigType.AvatarEventWish, AvatarEventWish); - yield return new(GachaConfigType.WeaponEventWish, WeaponEventWish); + yield return new(GachaType.NewBie, NoviceWish); + yield return new(GachaType.Standard, StandardWish); + yield return new(GachaType.ActivityAvatar, AvatarEventWish); + yield return new(GachaType.ActivityWeapon, WeaponEventWish); } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaDistributionType.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaDistributionType.cs index 17a19c2f..ba924565 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaDistributionType.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaDistributionType.cs @@ -18,6 +18,11 @@ internal enum GachaDistributionType /// WeaponEvent, + /// + /// 集录 + /// + Chronicled, + /// /// 常驻 /// diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaEventStatistics.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaEventStatistics.cs index 845c231d..e99fb580 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaEventStatistics.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaEventStatistics.cs @@ -22,4 +22,9 @@ internal sealed class GachaEventStatistics /// 武器活动 /// public List WeaponEvent { get; set; } = default!; + + /// + /// 集录祈愿 + /// + public List Chronicled { get; set; } = default!; } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaItem.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaItem.cs index 058a3081..e696819d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaItem.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaItem.cs @@ -13,14 +13,14 @@ internal sealed class GachaItem /// /// 祈愿记录分类 /// - public GachaConfigType GachaType { get; set; } + public GachaType GachaType { get; set; } /// /// 祈愿记录查询分类 /// 合并保底的卡池使用此属性 /// 仅4种(不含400) /// - public GachaConfigType QueryType { get; set; } + public GachaType QueryType { get; set; } /// /// 物品Id From 44e7f7482c5d610f72c92357cc6aadd1e7197f32 Mon Sep 17 00:00:00 2001 From: Lightczx <1686188646@qq.com> Date: Mon, 4 Mar 2024 15:38:17 +0800 Subject: [PATCH 2/6] minor adjustment --- .../Service/GachaLog/GachaItemSaveContext.cs | 18 ++++++++++-------- .../Snap.Hutao/Service/GachaLog/GachaLog.cs | 1 + 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaItemSaveContext.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaItemSaveContext.cs index 4895bf5a..e12e644b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaItemSaveContext.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaItemSaveContext.cs @@ -44,15 +44,17 @@ internal readonly struct GachaItemSaveContext public void SaveItems(GachaArchive archive) { - if (ItemsToAdd.Count > 0) + if (ItemsToAdd.Count <= 0) { - // 全量刷新 - if (!IsLazy) - { - GachaLogDbService.RemoveNewerGachaItemRangeByArchiveIdQueryTypeAndEndId(archive.InnerId, QueryType, EndId); - } - - GachaLogDbService.AddGachaItemRange(ItemsToAdd); + return; } + + // 全量刷新 + if (!IsLazy) + { + GachaLogDbService.RemoveNewerGachaItemRangeByArchiveIdQueryTypeAndEndId(archive.InnerId, QueryType, EndId); + } + + GachaLogDbService.AddGachaItemRange(ItemsToAdd); } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLog.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLog.cs index bc85b90a..9d7532c3 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLog.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLog.cs @@ -20,5 +20,6 @@ internal static class GachaLog GachaType.Standard, GachaType.ActivityAvatar, GachaType.ActivityWeapon, + GachaType.ActivityCity, ]); } \ No newline at end of file From 4c38bb528f3a885e397b1a1a2e5eebec826a2a6f Mon Sep 17 00:00:00 2001 From: Lightczx <1686188646@qq.com> Date: Wed, 6 Mar 2024 11:50:55 +0800 Subject: [PATCH 3/6] basic support --- .../Service/Cultivation/CultivationService.cs | 2 +- .../Factory/GachaStatisticsExtension.cs | 3 +- .../Factory/GachaStatisticsFactory.cs | 17 ++-- ...igTypeComparer.cs => GachaTypeComparer.cs} | 19 ++-- .../GachaLog/Factory/HistoryWishBuilder.cs | 5 +- .../Factory/HutaoStatisticsFactory.cs | 6 +- .../Factory/TypedWishSummaryBuilder.cs | 93 ++++++++----------- .../Service/GachaLog/GachaArchiveOperation.cs | 12 ++- .../Service/GachaLog/GachaItemSaveContext.cs | 60 ------------ .../Service/GachaLog/GachaLogFetchContext.cs | 16 +++- .../Service/GachaLog/GachaLogFetchStatus.cs | 16 ---- .../GachaLog/GachaLogHutaoCloudService.cs | 9 +- .../Service/GachaLog/GachaLogService.cs | 9 +- .../GachaLogServiceMetadataContext.cs | 78 ++++------------ .../GachaLog/IGachaLogHutaoCloudService.cs | 2 +- .../IMetadataDictionaryNameAvatarSource.cs | 9 ++ .../IMetadataDictionaryNameWeaponSource.cs | 9 ++ .../IMetadataSupportInitialization.cs | 9 ++ .../MetadataServiceContextExtension.cs | 39 ++++++-- .../ViewModel/GachaLog/HutaoCloudViewModel.cs | 2 +- .../Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs | 7 ++ .../Web/Hutao/GachaLog/GachaEntry.cs | 5 + 22 files changed, 185 insertions(+), 242 deletions(-) rename src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/{GachaConfigTypeComparer.cs => GachaTypeComparer.cs} (51%) delete mode 100644 src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaItemSaveContext.cs create mode 100644 src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/IMetadataDictionaryNameAvatarSource.cs create mode 100644 src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/IMetadataDictionaryNameWeaponSource.cs create mode 100644 src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/IMetadataSupportInitialization.cs diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs index b8d72295..d3a93bfc 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs @@ -39,7 +39,7 @@ internal sealed partial class CultivationService : ICultivationService List entities = cultivationDbService.GetInventoryItemListByProjectId(projectId); List results = []; - foreach (Material meta in context.EnumerateInventroyMaterial()) + foreach (Material meta in context.EnumerateInventoryMaterial()) { InventoryItem entity = entities.SingleOrDefault(e => e.ItemId == meta.Id) ?? InventoryItem.From(projectId, meta.Id); results.Add(new(entity, meta, saveCommand)); diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsExtension.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsExtension.cs index 9663e3b1..420fa93e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsExtension.cs @@ -3,6 +3,7 @@ using Snap.Hutao.Model.Metadata.Abstraction; using Snap.Hutao.ViewModel.GachaLog; +using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Text; using Windows.UI; @@ -25,7 +26,7 @@ internal static class GachaStatisticsExtension bool isPreviousUp = true; // mark the IsGuarantee - foreach (SummaryItem item in summaryItems) + foreach (ref readonly SummaryItem item in CollectionsMarshal.AsSpan(summaryItems)) { if (item.IsUp && (!isPreviousUp)) { diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs index d484cd32..998edb50 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs @@ -7,6 +7,7 @@ using Snap.Hutao.Model.Metadata; using Snap.Hutao.Model.Metadata.Avatar; using Snap.Hutao.Model.Metadata.Weapon; using Snap.Hutao.Service.Metadata; +using Snap.Hutao.Service.Metadata.ContextAbstraction; using Snap.Hutao.ViewModel.GachaLog; using Snap.Hutao.Web.Hoyolab.Hk4e.Event.GachaInfo; using Snap.Hutao.Web.Hutao.GachaLog; @@ -31,9 +32,8 @@ internal sealed partial class GachaStatisticsFactory : IGachaStatisticsFactory public async ValueTask CreateAsync(List items, GachaLogServiceMetadataContext context) { await taskContext.SwitchToBackgroundAsync(); - List gachaEvents = await metadataService.GetGachaEventListAsync().ConfigureAwait(false); - List historyWishBuilders = gachaEvents.SelectList(gachaEvent => new HistoryWishBuilder(gachaEvent, context)); + List historyWishBuilders = context.GachaEvents.SelectList(gachaEvent => new HistoryWishBuilder(gachaEvent, context)); return CreateCore(taskContext, homaGachaLogClient, items, historyWishBuilders, context, options.IsEmptyHistoryWishVisible); } @@ -70,18 +70,19 @@ internal sealed partial class GachaStatisticsFactory : IGachaStatisticsFactory // Items are ordered by precise time, first is oldest // 'ref' is not allowed here because we have lambda below - foreach (Model.Entity.GachaItem item in CollectionsMarshal.AsSpan(items)) + foreach (ref readonly Model.Entity.GachaItem item in CollectionsMarshal.AsSpan(items)) { - // Find target history wish to operate. // w.From <= item.Time <= w.To + // Find target history wish to operate. // banner.From <= item.Time <= banner.To + Model.Entity.GachaItem pinned = item; HistoryWishBuilder? targetHistoryWishBuilder = item.GachaType is not (GachaType.Standard or GachaType.NewBie) - ? historyWishBuilderMap[item.GachaType].BinarySearch(w => item.Time < w.From ? -1 : item.Time > w.To ? 1 : 0) + ? historyWishBuilderMap[item.GachaType].BinarySearch(banner => pinned.Time < banner.From ? -1 : pinned.Time > banner.To ? 1 : 0) : default; switch (item.ItemId.StringLength()) { case 8U: { - Avatar avatar = context.IdAvatarMap[item.ItemId]; + Avatar avatar = context.GetAvatar(item.ItemId); bool isUp = false; switch (avatar.Quality) @@ -142,7 +143,7 @@ internal sealed partial class GachaStatisticsFactory : IGachaStatisticsFactory } } - AsyncBarrier barrier = new(3); + AsyncBarrier barrier = new(4); return new() { @@ -150,7 +151,7 @@ internal sealed partial class GachaStatisticsFactory : IGachaStatisticsFactory HistoryWishes = historyWishBuilders .Where(b => isEmptyHistoryWishVisible || (!b.IsEmpty)) .OrderByDescending(builder => builder.From) - .ThenBy(builder => builder.ConfigType, GachaConfigTypeComparer.Shared) + .ThenBy(builder => builder.ConfigType, GachaTypeComparer.Shared) .Select(builder => builder.ToHistoryWish()) .ToList(), diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaConfigTypeComparer.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaTypeComparer.cs similarity index 51% rename from src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaConfigTypeComparer.cs rename to src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaTypeComparer.cs index 9771397f..25f2e0d4 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaConfigTypeComparer.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaTypeComparer.cs @@ -10,22 +10,23 @@ namespace Snap.Hutao.Service.GachaLog.Factory; /// /// 祈愿配置类型比较器 /// -internal sealed class GachaConfigTypeComparer : IComparer +internal sealed class GachaTypeComparer : IComparer { - private static readonly Lazy LazyShared = new(() => new()); - private static readonly FrozenDictionary OrderMap = FrozenDictionary.ToFrozenDictionary( + private static readonly Lazy LazyShared = new(() => new()); + private static readonly FrozenDictionary OrderMap = FrozenDictionary.ToFrozenDictionary( [ - KeyValuePair.Create(GachaConfigType.AvatarEventWish, 0), - KeyValuePair.Create(GachaConfigType.AvatarEventWish2, 1), - KeyValuePair.Create(GachaConfigType.WeaponEventWish, 2), - KeyValuePair.Create(GachaConfigType.StandardWish, 3), - KeyValuePair.Create(GachaConfigType.NoviceWish, 4), + KeyValuePair.Create(GachaType.ActivityAvatar, 0), + KeyValuePair.Create(GachaType.SpecialActivityAvatar, 1), + KeyValuePair.Create(GachaType.ActivityWeapon, 2), + KeyValuePair.Create(GachaType.Standard, 3), + KeyValuePair.Create(GachaType.NewBie, 4), + KeyValuePair.Create(GachaType.ActivityCity, 5), ]); /// /// 共享的比较器 /// - public static GachaConfigTypeComparer Shared { get => LazyShared.Value; } + public static GachaTypeComparer Shared { get => LazyShared.Value; } /// public int Compare(GachaType x, GachaType y) diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HistoryWishBuilder.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HistoryWishBuilder.cs index 55166473..34ce5071 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HistoryWishBuilder.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HistoryWishBuilder.cs @@ -29,7 +29,6 @@ internal sealed class HistoryWishBuilder /// /// 卡池配置 /// 祈愿记录上下文 - [SuppressMessage("", "SH002")] public HistoryWishBuilder(GachaEvent gachaEvent, GachaLogServiceMetadataContext context) { this.gachaEvent = gachaEvent; @@ -112,13 +111,13 @@ internal sealed class HistoryWishBuilder { HistoryWish historyWish = new() { - // base + // Base Name = gachaEvent.Name, From = gachaEvent.From, To = gachaEvent.To, TotalCount = totalCountTracker, - // fill + // Fill Version = gachaEvent.Version, BannerImage = gachaEvent.Banner, OrangeUpList = orangeUpCounter.ToStatisticsList(), diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactory.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactory.cs index 1e4657a1..45fbbd70 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactory.cs @@ -5,6 +5,7 @@ using Snap.Hutao.Core.ExceptionService; using Snap.Hutao.Model.Intrinsic; using Snap.Hutao.Model.Metadata; using Snap.Hutao.Model.Metadata.Abstraction; +using Snap.Hutao.Service.Metadata.ContextAbstraction; using Snap.Hutao.ViewModel.GachaLog; using Snap.Hutao.Web.Hoyolab.Hk4e.Event.GachaInfo; using Snap.Hutao.Web.Hutao.GachaLog; @@ -56,12 +57,13 @@ internal sealed class HutaoStatisticsFactory { IStatisticsItemSource source = item.Item.StringLength() switch { - 8U => context.IdAvatarMap[item.Item], - 5U => context.IdWeaponMap[item.Item], + 8U => context.GetAvatar(item.Item), + 5U => context.GetWeapon(item.Item), _ => throw HutaoException.GachaStatisticsInvalidItemId(item.Item), }; StatisticsItem statisticsItem = source.ToStatisticsItem(unchecked((int)item.Count)); + // Put UP items to a separate list if (gachaEvent.UpOrangeList.Contains(item.Item) || gachaEvent.UpPurpleList.Contains(item.Item)) { upItems.Add(statisticsItem); diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilder.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilder.cs index 72e13b23..08064ae6 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilder.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilder.cs @@ -15,21 +15,6 @@ namespace Snap.Hutao.Service.GachaLog.Factory; [HighQuality] internal sealed class TypedWishSummaryBuilder { - /// - /// 常驻祈愿 - /// - public static readonly Func IsStandardWish = type => type is GachaType.Standard; - - /// - /// 角色活动 - /// - public static readonly Func IsAvatarEventWish = type => type is GachaType.ActivityAvatar or GachaType.SpecialActivityAvatar; - - /// - /// 武器活动 - /// - public static readonly Func IsWeaponEventWish = type => type is GachaType.ActivityWeapon; - private readonly TypedWishSummaryBuilderContext context; private readonly List averageOrangePullTracker = []; @@ -62,52 +47,54 @@ internal sealed class TypedWishSummaryBuilder /// 是否为Up物品 public void Track(GachaItem item, ISummaryItemSource source, bool isUp) { - if (context.TypeEvaluator(item.GachaType)) + if (!context.TypeEvaluator(item.GachaType)) { - ++lastOrangePullTracker; - ++lastPurplePullTracker; - ++lastUpOrangePullTracker; + return; + } - // track total pulls - ++totalCountTracker; - TrackFromToTime(item.Time); + ++lastOrangePullTracker; + ++lastPurplePullTracker; + ++lastUpOrangePullTracker; - switch (source.Quality) - { - case QualityType.QUALITY_ORANGE: + // track total pulls + ++totalCountTracker; + TrackFromToTime(item.Time); + + switch (source.Quality) + { + case QualityType.QUALITY_ORANGE: + { + TrackMinMaxOrangePull(lastOrangePullTracker); + averageOrangePullTracker.Add(lastOrangePullTracker); + + if (isUp) { - TrackMinMaxOrangePull(lastOrangePullTracker); - averageOrangePullTracker.Add(lastOrangePullTracker); - - if (isUp) - { - averageUpOrangePullTracker.Add(lastUpOrangePullTracker); - lastUpOrangePullTracker = 0; - } - - summaryItems.Add(source.ToSummaryItem(lastOrangePullTracker, item.Time, isUp)); - - lastOrangePullTracker = 0; - ++totalOrangePullTracker; - break; + averageUpOrangePullTracker.Add(lastUpOrangePullTracker); + lastUpOrangePullTracker = 0; } - case QualityType.QUALITY_PURPLE: - { - lastPurplePullTracker = 0; - ++totalPurplePullTracker; - break; - } + summaryItems.Add(source.ToSummaryItem(lastOrangePullTracker, item.Time, isUp)); - case QualityType.QUALITY_BLUE: - { - ++totalBluePullTracker; - break; - } - - default: + lastOrangePullTracker = 0; + ++totalOrangePullTracker; break; - } + } + + case QualityType.QUALITY_PURPLE: + { + lastPurplePullTracker = 0; + ++totalPurplePullTracker; + break; + } + + case QualityType.QUALITY_BLUE: + { + ++totalBluePullTracker; + break; + } + + default: + break; } } diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaArchiveOperation.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaArchiveOperation.cs index 6bf5dc77..70b9f085 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaArchiveOperation.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaArchiveOperation.cs @@ -15,12 +15,14 @@ internal static class GachaArchiveOperation { archive = archives.SingleOrDefault(a => a.Uid == uid); - if (archive is null) + if (archive is not null) { - GachaArchive created = GachaArchive.From(uid); - gachaLogDbService.AddGachaArchive(created); - taskContext.InvokeOnMainThread(() => archives.Add(created)); - archive = created; + return; } + + GachaArchive created = GachaArchive.From(uid); + gachaLogDbService.AddGachaArchive(created); + taskContext.InvokeOnMainThread(() => archives.Add(created)); + archive = created; } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaItemSaveContext.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaItemSaveContext.cs deleted file mode 100644 index e12e644b..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaItemSaveContext.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -using Snap.Hutao.Model.Entity; -using Snap.Hutao.Web.Hoyolab.Hk4e.Event.GachaInfo; - -namespace Snap.Hutao.Service.GachaLog; - -/// -/// 祈愿物品保存上下文 -/// -internal readonly struct GachaItemSaveContext -{ - /// - /// 待添加物品 - /// - public readonly List ItemsToAdd; - - /// - /// 是否懒惰 - /// - public readonly bool IsLazy; - - public readonly GachaType QueryType; - - /// - /// 结尾 Id - /// - public readonly long EndId; - - /// - /// 数据集 - /// - public readonly IGachaLogDbService GachaLogDbService; - - public GachaItemSaveContext(List itemsToAdd, bool isLazy, GachaType queryType, long endId, IGachaLogDbService gachaLogDbService) - { - ItemsToAdd = itemsToAdd; - IsLazy = isLazy; - QueryType = queryType; - EndId = endId; - GachaLogDbService = gachaLogDbService; - } - - public void SaveItems(GachaArchive archive) - { - if (ItemsToAdd.Count <= 0) - { - return; - } - - // 全量刷新 - if (!IsLazy) - { - GachaLogDbService.RemoveNewerGachaItemRangeByArchiveIdQueryTypeAndEndId(archive.InnerId, QueryType, EndId); - } - - GachaLogDbService.AddGachaItemRange(ItemsToAdd); - } -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogFetchContext.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogFetchContext.cs index 871ee384..76c9137d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogFetchContext.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogFetchContext.cs @@ -53,7 +53,7 @@ internal struct GachaLogFetchContext private readonly ITaskContext taskContext; private readonly bool isLazy; - public GachaLogFetchContext(IGachaLogDbService gachaLogDbService, ITaskContext taskContext, in GachaLogServiceMetadataContext serviceContext, bool isLazy) + public GachaLogFetchContext(IGachaLogDbService gachaLogDbService, ITaskContext taskContext, GachaLogServiceMetadataContext serviceContext, bool isLazy) { this.gachaLogDbService = gachaLogDbService; this.taskContext = taskContext; @@ -140,8 +140,18 @@ internal struct GachaLogFetchContext // While no item is fetched, archive can be null. if (TargetArchive is not null) { - GachaItemSaveContext saveContext = new(ItemsToAdd, isLazy, QueryOptions.Type, QueryOptions.EndId, gachaLogDbService); - saveContext.SaveItems(TargetArchive); + if (ItemsToAdd.Count <= 0) + { + return; + } + + // 全量刷新 + if (!isLazy) + { + gachaLogDbService.RemoveNewerGachaItemRangeByArchiveIdQueryTypeAndEndId(TargetArchive.InnerId, QueryOptions.Type, QueryOptions.EndId); + } + + gachaLogDbService.AddGachaItemRange(ItemsToAdd); } } diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogFetchStatus.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogFetchStatus.cs index 55fa83d0..6b51193a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogFetchStatus.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogFetchStatus.cs @@ -6,33 +6,17 @@ using Snap.Hutao.Web.Hoyolab.Hk4e.Event.GachaInfo; namespace Snap.Hutao.Service.GachaLog; -/// -/// 祈愿记录获取状态 -/// internal sealed class GachaLogFetchStatus { - /// - /// 构造一个新的祈愿记录获取状态 - /// - /// 卡池类型 public GachaLogFetchStatus(GachaType configType) { ConfigType = configType; } - /// - /// 验证密钥是否过期 - /// public bool AuthKeyTimeout { get; set; } - /// - /// 卡池类型 - /// public GachaType ConfigType { get; set; } - /// - /// 当前获取的物品 - /// public List Items { get; set; } = new(20); public string Header diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogHutaoCloudService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogHutaoCloudService.cs index 232eb10b..dfeffede 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogHutaoCloudService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogHutaoCloudService.cs @@ -56,14 +56,16 @@ internal sealed partial class GachaLogHutaoCloudService : IGachaLogHutaoCloudSer } /// - public async ValueTask> RetrieveGachaItemsAsync(string uid, CancellationToken token = default) + public async ValueTask> RetrieveGachaArchiveIdAsync(string uid, CancellationToken token = default) { GachaArchive? archive = await gachaLogDbService .GetGachaArchiveByUidAsync(uid, token) .ConfigureAwait(false); EndIds endIds = await CreateEndIdsAsync(archive, token).ConfigureAwait(false); - Response> resp = await homaGachaLogClient.RetrieveGachaItemsAsync(uid, endIds, token).ConfigureAwait(false); + Response> resp = await homaGachaLogClient + .RetrieveGachaItemsAsync(uid, endIds, token) + .ConfigureAwait(false); if (!resp.IsOk()) { @@ -76,7 +78,8 @@ internal sealed partial class GachaLogHutaoCloudService : IGachaLogHutaoCloudSer await gachaLogDbService.AddGachaArchiveAsync(archive).ConfigureAwait(false); } - List gachaItems = resp.Data.SelectList(i => Model.Entity.GachaItem.From(archive.InnerId, i)); + Guid archiveId = archive.InnerId; + List gachaItems = resp.Data.SelectList(i => Model.Entity.GachaItem.From(archiveId, i)); await gachaLogDbService.AddGachaItemsAsync(gachaItems).ConfigureAwait(false); return new(true, archive.InnerId); } diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs index d6a86465..9e1cd8e4 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs @@ -9,6 +9,7 @@ using Snap.Hutao.Model.Primitive; using Snap.Hutao.Service.GachaLog.Factory; using Snap.Hutao.Service.GachaLog.QueryProvider; using Snap.Hutao.Service.Metadata; +using Snap.Hutao.Service.Metadata.ContextAbstraction; using Snap.Hutao.ViewModel.GachaLog; using Snap.Hutao.Web.Hoyolab.Hk4e.Event.GachaInfo; using Snap.Hutao.Web.Response; @@ -62,13 +63,7 @@ internal sealed partial class GachaLogService : IGachaLogService if (await metadataService.InitializeAsync().ConfigureAwait(false)) { - Dictionary idAvatarMap = await metadataService.GetIdToAvatarMapAsync(token).ConfigureAwait(false); - Dictionary idWeaponMap = await metadataService.GetIdToWeaponMapAsync(token).ConfigureAwait(false); - - Dictionary nameAvatarMap = await metadataService.GetNameToAvatarMapAsync(token).ConfigureAwait(false); - Dictionary nameWeaponMap = await metadataService.GetNameToWeaponMapAsync(token).ConfigureAwait(false); - context = new(idAvatarMap, idWeaponMap, nameAvatarMap, nameWeaponMap); - + context = await metadataService.GetContextAsync(token).ConfigureAwait(false); ArchiveCollection = gachaLogDbService.GetGachaArchiveCollection(); return true; } diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogServiceMetadataContext.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogServiceMetadataContext.cs index 749903fc..26a2665a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogServiceMetadataContext.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogServiceMetadataContext.cs @@ -2,10 +2,12 @@ // Licensed under the MIT license. using Snap.Hutao.Model; +using Snap.Hutao.Model.Metadata; using Snap.Hutao.Model.Metadata.Abstraction; using Snap.Hutao.Model.Metadata.Avatar; using Snap.Hutao.Model.Metadata.Weapon; using Snap.Hutao.Model.Primitive; +using Snap.Hutao.Service.Metadata.ContextAbstraction; using Snap.Hutao.Web.Hoyolab.Hk4e.Event.GachaInfo; namespace Snap.Hutao.Service.GachaLog; @@ -13,65 +15,28 @@ namespace Snap.Hutao.Service.GachaLog; /// /// 祈愿记录服务上下文 /// -internal readonly struct GachaLogServiceMetadataContext +internal sealed class GachaLogServiceMetadataContext : IMetadataContext, + IMetadataSupportInitialization, + IMetadataListGachaEventSource, + IMetadataDictionaryIdAvatarSource, + IMetadataDictionaryIdWeaponSource, + IMetadataDictionaryNameAvatarSource, + IMetadataDictionaryNameWeaponSource { - /// - /// 物品缓存 - /// - public readonly Dictionary ItemCache = []; + public Dictionary ItemCache { get; set; } = []; - /// - /// Id 角色 映射 - /// - public readonly Dictionary IdAvatarMap; + public List GachaEvents { get; set; } = default!; - /// - /// Id 武器 映射 - /// - public readonly Dictionary IdWeaponMap; + public Dictionary IdAvatarMap { get; set; } = default!; - /// - /// 名称 角色 映射 - /// - public readonly Dictionary NameAvatarMap; + public Dictionary IdWeaponMap { get; set; } = default!; - /// - /// 名称 武器 映射 - /// - public readonly Dictionary NameWeaponMap; + public Dictionary NameAvatarMap { get; set; } = default!; - /// - /// 是否初始化完成 - /// - public readonly bool IsInitialized; + public Dictionary NameWeaponMap { get; set; } = default!; - /// - /// 构造一个新的祈愿记录服务上下文 - /// - /// Id 角色 映射 - /// Id 武器 映射 - /// 名称 角色 映射 - /// 名称 武器 映射 - public GachaLogServiceMetadataContext( - Dictionary idAvatarMap, - Dictionary idWeaponMap, - Dictionary nameAvatarMap, - Dictionary nameWeaponMap) - { - IdAvatarMap = idAvatarMap; - IdWeaponMap = idWeaponMap; - NameAvatarMap = nameAvatarMap; - NameWeaponMap = nameWeaponMap; + public bool IsInitialized { get; set; } - IsInitialized = true; - } - - /// - /// 按名称获取物品 - /// - /// 名称 - /// 类型 - /// 物品 public Item GetItemByNameAndType(string name, string type) { if (!ItemCache.TryGetValue(name, out Item? result)) @@ -93,11 +58,6 @@ internal readonly struct GachaLogServiceMetadataContext return result; } - /// - /// 按物品 Id 获取名称星级 - /// - /// Id - /// 名称星级 public INameQuality GetNameQualityByItemId(uint id) { uint place = id.StringLength(); @@ -109,12 +69,6 @@ internal readonly struct GachaLogServiceMetadataContext }; } - /// - /// 获取物品 Id - /// O(1) - /// - /// 祈愿物品 - /// 物品 Id public uint GetItemId(GachaLogItem item) { if (item.ItemType == SH.ModelInterchangeUIGFItemTypeAvatar) diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogHutaoCloudService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogHutaoCloudService.cs index 18fc51ce..c000e23a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogHutaoCloudService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogHutaoCloudService.cs @@ -36,7 +36,7 @@ internal interface IGachaLogHutaoCloudService /// uid /// 取消令牌 /// 是否获取成功 - ValueTask> RetrieveGachaItemsAsync(string uid, CancellationToken token = default); + ValueTask> RetrieveGachaArchiveIdAsync(string uid, CancellationToken token = default); /// /// 异步上传祈愿记录 diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/IMetadataDictionaryNameAvatarSource.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/IMetadataDictionaryNameAvatarSource.cs new file mode 100644 index 00000000..88ecf91d --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/IMetadataDictionaryNameAvatarSource.cs @@ -0,0 +1,9 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Service.Metadata.ContextAbstraction; + +internal interface IMetadataDictionaryNameAvatarSource +{ + public Dictionary NameAvatarMap { get; set; } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/IMetadataDictionaryNameWeaponSource.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/IMetadataDictionaryNameWeaponSource.cs new file mode 100644 index 00000000..34b69054 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/IMetadataDictionaryNameWeaponSource.cs @@ -0,0 +1,9 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Service.Metadata.ContextAbstraction; + +internal interface IMetadataDictionaryNameWeaponSource +{ + public Dictionary NameWeaponMap { get; set; } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/IMetadataSupportInitialization.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/IMetadataSupportInitialization.cs new file mode 100644 index 00000000..27ee8318 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/IMetadataSupportInitialization.cs @@ -0,0 +1,9 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Service.Metadata.ContextAbstraction; + +internal interface IMetadataSupportInitialization +{ + bool IsInitialized { get; set; } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/MetadataServiceContextExtension.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/MetadataServiceContextExtension.cs index e0db64dd..f511bc7a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/MetadataServiceContextExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/ContextAbstraction/MetadataServiceContextExtension.cs @@ -30,27 +30,42 @@ internal static class MetadataServiceContextExtension // Dictionary { - if (context is IMetadataDictionaryIdAvatarSource dictionaryAvatarSource) + if (context is IMetadataDictionaryIdAvatarSource dictionaryIdAvatarSource) { - dictionaryAvatarSource.IdAvatarMap = await metadataService.GetIdToAvatarMapAsync(token).ConfigureAwait(false); + dictionaryIdAvatarSource.IdAvatarMap = await metadataService.GetIdToAvatarMapAsync(token).ConfigureAwait(false); } - if (context is IMetadataDictionaryIdMaterialSource dictionaryMaterialSource) + if (context is IMetadataDictionaryIdMaterialSource dictionaryIdMaterialSource) { - dictionaryMaterialSource.IdMaterialMap = await metadataService.GetIdToMaterialMapAsync(token).ConfigureAwait(false); + dictionaryIdMaterialSource.IdMaterialMap = await metadataService.GetIdToMaterialMapAsync(token).ConfigureAwait(false); } - if (context is IMetadataDictionaryIdWeaponSource dictionaryWeaponSource) + if (context is IMetadataDictionaryIdWeaponSource dictionaryIdWeaponSource) { - dictionaryWeaponSource.IdWeaponMap = await metadataService.GetIdToWeaponMapAsync(token).ConfigureAwait(false); + dictionaryIdWeaponSource.IdWeaponMap = await metadataService.GetIdToWeaponMapAsync(token).ConfigureAwait(false); } + + if (context is IMetadataDictionaryNameAvatarSource dictionaryNameAvatarSource) + { + dictionaryNameAvatarSource.NameAvatarMap = await metadataService.GetNameToAvatarMapAsync(token).ConfigureAwait(false); + } + + if (context is IMetadataDictionaryNameWeaponSource dictionaryNameWeaponSource) + { + dictionaryNameWeaponSource.NameWeaponMap = await metadataService.GetNameToWeaponMapAsync(token).ConfigureAwait(false); + } + } + + if (context is IMetadataSupportInitialization supportInitialization) + { + supportInitialization.IsInitialized = true; } return context; } #pragma warning disable SH002 - public static IEnumerable EnumerateInventroyMaterial(this IMetadataListMaterialSource context) + public static IEnumerable EnumerateInventoryMaterial(this IMetadataListMaterialSource context) { return context.Materials.Where(m => m.IsInventoryItem()).OrderBy(m => m.Id.Value); } @@ -60,6 +75,11 @@ internal static class MetadataServiceContextExtension return context.IdAvatarMap[id]; } + public static Avatar GetAvatar(this IMetadataDictionaryNameAvatarSource context, string name) + { + return context.NameAvatarMap[name]; + } + public static Material GetMaterial(this IMetadataDictionaryIdMaterialSource context, MaterialId id) { return context.IdMaterialMap[id]; @@ -69,5 +89,10 @@ internal static class MetadataServiceContextExtension { return context.IdWeaponMap[id]; } + + public static Weapon GetWeapon(this IMetadataDictionaryNameWeaponSource context, string name) + { + return context.NameWeaponMap[name]; + } #pragma warning restore SH002 } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/HutaoCloudViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/HutaoCloudViewModel.cs index 890282ab..6829162d 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/HutaoCloudViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/HutaoCloudViewModel.cs @@ -60,7 +60,7 @@ internal sealed partial class HutaoCloudViewModel : Abstraction.ViewModel using (await dialog.BlockAsync(taskContext).ConfigureAwait(false)) { - return await hutaoCloudService.RetrieveGachaItemsAsync(uid).ConfigureAwait(false); + return await hutaoCloudService.RetrieveGachaArchiveIdAsync(uid).ConfigureAwait(false); } } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs index 07baf4a5..e5274ce8 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs @@ -34,6 +34,12 @@ internal sealed class EndIds [JsonPropertyName("302")] public long WeaponEventWish { get; set; } + /// + /// 集录祈愿 + /// + [JsonPropertyName("500")] + public long ChronicledWish { get; set; } + /// /// 获取 Last Id /// @@ -83,5 +89,6 @@ internal sealed class EndIds yield return new(GachaType.Standard, StandardWish); yield return new(GachaType.ActivityAvatar, AvatarEventWish); yield return new(GachaType.ActivityWeapon, WeaponEventWish); + yield return new(GachaType.ActivityCity, ChronicledWish); } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaEntry.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaEntry.cs index ab18eb88..30187115 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaEntry.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/GachaEntry.cs @@ -10,6 +10,11 @@ internal sealed class GachaEntry /// public string Uid { get; set; } = default!; + /// + /// 是否被排除出了全球统计 + /// + public bool Excluded { get; set; } + /// /// 物品个数 /// From 4f1bbd2e89b29c7fc9fe688c36c70551ce0681b7 Mon Sep 17 00:00:00 2001 From: Lightczx <1686188646@qq.com> Date: Wed, 6 Mar 2024 13:58:34 +0800 Subject: [PATCH 4/6] typo fix --- .../Service/GachaLog/Factory/HutaoStatisticsFactory.cs | 2 +- src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/HutaoStatistics.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactory.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactory.cs index 45fbbd70..f7c0ddaa 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactory.cs @@ -42,7 +42,7 @@ internal sealed class HutaoStatisticsFactory AvatarEvent = CreateWishSummary(avatarEvent, raw.AvatarEvent), AvatarEvent2 = CreateWishSummary(avatarEvent2, raw.AvatarEvent2), WeaponEvent = CreateWishSummary(weaponEvent, raw.WeaponEvent), - ChronicledWish = CreateWishSummary(chronicledEvent, raw.Chronicled), + Chronicled = CreateWishSummary(chronicledEvent, raw.Chronicled), }; } diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/HutaoStatistics.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/HutaoStatistics.cs index c3b68061..1602ff3f 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/HutaoStatistics.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/HutaoStatistics.cs @@ -26,5 +26,5 @@ internal sealed class HutaoStatistics /// /// 集录祈愿 /// - public HutaoWishSummary ChronicledWish { get; set; } = default!; + public HutaoWishSummary Chronicled { get; set; } = default!; } \ No newline at end of file From 2e685182e636431e1ba2e6dc5d493fadba8464d8 Mon Sep 17 00:00:00 2001 From: Lightczx <1686188646@qq.com> Date: Wed, 6 Mar 2024 14:01:53 +0800 Subject: [PATCH 5/6] fixup endid indexer getter --- src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs index e5274ce8..c8b6bb93 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs @@ -55,6 +55,7 @@ internal sealed class EndIds GachaType.Standard => StandardWish, GachaType.ActivityAvatar => AvatarEventWish, GachaType.ActivityWeapon => WeaponEventWish, + GachaType.ActivityCity => ChronicledWish, _ => 0, }; } From 46dd4db25cb00d0ea6d67ea0debbac6da84edf73 Mon Sep 17 00:00:00 2001 From: Lightczx <1686188646@qq.com> Date: Wed, 6 Mar 2024 14:04:04 +0800 Subject: [PATCH 6/6] fixup endid indexer setter --- src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs index c8b6bb93..a82bad90 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/GachaLog/EndIds.cs @@ -76,6 +76,9 @@ internal sealed class EndIds case GachaType.ActivityWeapon: WeaponEventWish = value; break; + case GachaType.ActivityCity: + ChronicledWish = value; + break; } } }