From 3e26e247cd34bb30ee67851d6a276f7c2b42ac4e Mon Sep 17 00:00:00 2001 From: DismissedLight <1686188646@qq.com> Date: Mon, 10 Jun 2024 22:43:50 +0800 Subject: [PATCH] refactor metadata abstraction --- .../Snap.Hutao/Model/Entity/InventoryItem.cs | 3 +- .../Model/InterChange/GachaLog/UIGFItem.cs | 4 +- ...ivatable.cs => ICultivationItemsAccess.cs} | 2 +- .../{IItemSource.cs => IItemConvertible.cs} | 2 +- ...{INameQuality.cs => INameQualityAccess.cs} | 2 +- ...ource.cs => IStatisticsItemConvertible.cs} | 2 +- ...emSource.cs => ISummaryItemConvertible.cs} | 12 +- .../Metadata/Avatar/Avatar.Implementation.cs | 99 -------------- .../Model/Metadata/Avatar/Avatar.cs | 129 ++++++++++-------- .../Metadata/Weapon/Weapon.Implementation.cs | 107 --------------- .../Model/Metadata/Weapon/Weapon.cs | 110 ++++++++++----- .../Service/Cultivation/CultivationService.cs | 8 +- .../Factory/GachaStatisticsExtension.cs | 2 +- .../Factory/GachaStatisticsSlimFactory.cs | 4 +- .../GachaLog/Factory/HistoryWishBuilder.cs | 28 ++-- .../Factory/HutaoStatisticsFactory.cs | 2 +- .../Factory/TypedWishSummaryBuilder.cs | 2 +- .../GachaLogServiceMetadataContext.cs | 2 +- .../Snap.Hutao/View/Page/WikiAvatarPage.xaml | 6 +- .../Snap.Hutao/View/Page/WikiWeaponPage.xaml | 2 +- .../ViewModel/Wiki/WikiAvatarViewModel.cs | 2 +- .../ViewModel/Wiki/WikiWeaponViewModel.cs | 2 +- 22 files changed, 186 insertions(+), 346 deletions(-) rename src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/{ICultivatable.cs => ICultivationItemsAccess.cs} (83%) rename src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/{IItemSource.cs => IItemConvertible.cs} (82%) rename src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/{INameQuality.cs => INameQualityAccess.cs} (91%) rename src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/{IStatisticsItemSource.cs => IStatisticsItemConvertible.cs} (90%) rename src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/{ISummaryItemSource.cs => ISummaryItemConvertible.cs} (53%) delete mode 100644 src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.Implementation.cs delete mode 100644 src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/Weapon.Implementation.cs diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/InventoryItem.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/InventoryItem.cs index 8aba7d71..73136219 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/InventoryItem.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/InventoryItem.cs @@ -12,7 +12,8 @@ namespace Snap.Hutao.Model.Entity; /// [HighQuality] [Table("inventory_items")] -internal sealed class InventoryItem : IDbMappingForeignKeyFrom, IDbMappingForeignKeyFrom +internal sealed class InventoryItem : IDbMappingForeignKeyFrom, + IDbMappingForeignKeyFrom { /// /// 内部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 a0b6fe2f..e6f51939 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGFItem.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGFItem.cs @@ -13,7 +13,7 @@ namespace Snap.Hutao.Model.InterChange.GachaLog; /// UIGF物品 /// [HighQuality] -internal sealed class UIGFItem : GachaLogItem, IMappingFrom +internal sealed class UIGFItem : GachaLogItem, IMappingFrom { /// /// 额外祈愿映射 @@ -22,7 +22,7 @@ internal sealed class UIGFItem : GachaLogItem, IMappingFrom CultivationItems { get; } } diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/IItemSource.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/IItemConvertible.cs similarity index 82% rename from src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/IItemSource.cs rename to src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/IItemConvertible.cs index cca32549..535d7b7e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/IItemSource.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/IItemConvertible.cs @@ -3,7 +3,7 @@ namespace Snap.Hutao.Model.Metadata.Abstraction; -internal interface IItemSource +internal interface IItemConvertible { Model.Item ToItem(); } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/INameQuality.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/INameQualityAccess.cs similarity index 91% rename from src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/INameQuality.cs rename to src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/INameQualityAccess.cs index b29640d9..a6d83c8a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/INameQuality.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/INameQualityAccess.cs @@ -9,7 +9,7 @@ namespace Snap.Hutao.Model.Metadata.Abstraction; /// 物品与星级 /// [HighQuality] -internal interface INameQuality +internal interface INameQualityAccess { /// /// 名称 diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/IStatisticsItemSource.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/IStatisticsItemConvertible.cs similarity index 90% rename from src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/IStatisticsItemSource.cs rename to src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/IStatisticsItemConvertible.cs index b1e71200..fb51bec9 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/IStatisticsItemSource.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/IStatisticsItemConvertible.cs @@ -9,7 +9,7 @@ namespace Snap.Hutao.Model.Metadata.Abstraction; /// 指示该类为统计物品的源 /// [HighQuality] -internal interface IStatisticsItemSource +internal interface IStatisticsItemConvertible { /// /// 转换到统计物品 diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/ISummaryItemSource.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/ISummaryItemConvertible.cs similarity index 53% rename from src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/ISummaryItemSource.cs rename to src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/ISummaryItemConvertible.cs index 2be603a4..97647310 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/ISummaryItemSource.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Abstraction/ISummaryItemConvertible.cs @@ -10,19 +10,9 @@ namespace Snap.Hutao.Model.Metadata.Abstraction; /// 指示该类为简述统计物品的源 /// [HighQuality] -internal interface ISummaryItemSource +internal interface ISummaryItemConvertible { - /// - /// 星级 - /// QualityType Quality { get; } - /// - /// 转换到简述统计物品 - /// - /// 距上个五星 - /// 时间 - /// 是否为Up物品 - /// 简述统计物品 SummaryItem ToSummaryItem(int lastPull, in DateTimeOffset time, bool isUp); } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.Implementation.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.Implementation.cs deleted file mode 100644 index 19ca1bd8..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.Implementation.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -using Snap.Hutao.Model.Calculable; -using Snap.Hutao.Model.Metadata.Abstraction; -using Snap.Hutao.Model.Metadata.Converter; -using Snap.Hutao.Model.Metadata.Item; -using Snap.Hutao.ViewModel.Complex; -using Snap.Hutao.ViewModel.GachaLog; -using Snap.Hutao.ViewModel.Wiki; - -namespace Snap.Hutao.Model.Metadata.Avatar; - -/// -/// 角色的接口实现部分 -/// -internal partial class Avatar : IStatisticsItemSource, ISummaryItemSource, IItemSource, INameQuality, ICalculableSource, ICultivatable -{ - /// - /// [非元数据] 搭配数据 - /// TODO:Add View suffix. - /// - [JsonIgnore] - public AvatarCollocationView? Collocation { get; set; } - - /// - /// [非元数据] 烹饪奖励 - /// - [JsonIgnore] - public CookBonusView? CookBonusView { get; set; } - - /// - /// [非元数据] 养成物品视图 - /// - [JsonIgnore] - public List? CultivationItemsView { get; set; } - - /// - /// 最大等级 - /// - [SuppressMessage("", "CA1822")] - public uint MaxLevel { get => GetMaxLevel(); } - - public static uint GetMaxLevel() - { - return 90U; - } - - /// - public ICalculableAvatar ToCalculable() - { - return CalculableAvatar.From(this); - } - - /// - /// 转换为基础物品 - /// - /// 基础物品 - public Model.Item ToItem() - { - return new() - { - Name = Name, - Icon = AvatarIconConverter.IconNameToUri(Icon), - Badge = ElementNameIconConverter.ElementNameToIconUri(FetterInfo.VisionBefore), - Quality = Quality, - }; - } - - /// - public StatisticsItem ToStatisticsItem(int count) - { - return new() - { - Name = Name, - Icon = AvatarIconConverter.IconNameToUri(Icon), - Badge = ElementNameIconConverter.ElementNameToIconUri(FetterInfo.VisionBefore), - Quality = Quality, - - Count = count, - }; - } - - /// - public SummaryItem ToSummaryItem(int lastPull, in DateTimeOffset time, bool isUp) - { - return new() - { - Name = Name, - Icon = AvatarIconConverter.IconNameToUri(Icon), - Badge = ElementNameIconConverter.ElementNameToIconUri(FetterInfo.VisionBefore), - Quality = Quality, - - Time = time, - LastPull = lastPull, - IsUp = isUp, - }; - } -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.cs index 79a81f4a..e88b0a80 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.cs @@ -1,99 +1,118 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using Snap.Hutao.Model.Calculable; using Snap.Hutao.Model.Intrinsic; +using Snap.Hutao.Model.Metadata.Abstraction; +using Snap.Hutao.Model.Metadata.Converter; +using Snap.Hutao.Model.Metadata.Item; using Snap.Hutao.Model.Primitive; +using Snap.Hutao.ViewModel.Complex; +using Snap.Hutao.ViewModel.GachaLog; +using Snap.Hutao.ViewModel.Wiki; namespace Snap.Hutao.Model.Metadata.Avatar; -/// -/// 角色 -/// [HighQuality] -internal partial class Avatar +internal partial class Avatar : INameQualityAccess, + IStatisticsItemConvertible, + ISummaryItemConvertible, + IItemConvertible, + ICalculableSource, + ICultivationItemsAccess { - /// - /// Id - /// public AvatarId Id { get; set; } - /// - /// 突破提升 Id 外键 - /// public PromoteId PromoteId { get; set; } - /// - /// 排序号 - /// public uint Sort { get; set; } - /// - /// 体型 - /// public BodyType Body { get; set; } = default!; - /// - /// 正面图标 - /// public string Icon { get; set; } = default!; - /// - /// 侧面图标 - /// public string SideIcon { get; set; } = default!; - /// - /// 名称 - /// public string Name { get; set; } = default!; - /// - /// 描述 - /// public string Description { get; set; } = default!; - /// - /// 角色加入游戏时间 - /// public DateTimeOffset BeginTime { get; set; } - /// - /// 星级 - /// public QualityType Quality { get; set; } - /// - /// 武器类型 - /// public WeaponType Weapon { get; set; } - /// - /// 基础数值 - /// public AvatarBaseValue BaseValue { get; set; } = default!; - /// - /// 生长曲线 - /// public List> GrowCurves { get; set; } = default!; - /// - /// 技能 - /// public SkillDepot SkillDepot { get; set; } = default!; - /// - /// 好感信息/基本信息 - /// public FetterInfo FetterInfo { get; set; } = default!; - /// - /// 皮肤 - /// public List Costumes { get; set; } = default!; - /// - /// 养成物品 - /// public List CultivationItems { get; set; } = default!; + + [JsonIgnore] + public AvatarCollocationView? CollocationView { get; set; } + + [JsonIgnore] + public CookBonusView? CookBonusView { get; set; } + + [JsonIgnore] + public List? CultivationItemsView { get; set; } + + [SuppressMessage("", "CA1822")] + public uint MaxLevel { get => GetMaxLevel(); } + + public static uint GetMaxLevel() + { + return 90U; + } + + public ICalculableAvatar ToCalculable() + { + return CalculableAvatar.From(this); + } + + public Model.Item ToItem() + { + return new() + { + Name = Name, + Icon = AvatarIconConverter.IconNameToUri(Icon), + Badge = ElementNameIconConverter.ElementNameToIconUri(FetterInfo.VisionBefore), + Quality = Quality, + }; + } + + public StatisticsItem ToStatisticsItem(int count) + { + return new() + { + Name = Name, + Icon = AvatarIconConverter.IconNameToUri(Icon), + Badge = ElementNameIconConverter.ElementNameToIconUri(FetterInfo.VisionBefore), + Quality = Quality, + + Count = count, + }; + } + + public SummaryItem ToSummaryItem(int lastPull, in DateTimeOffset time, bool isUp) + { + return new() + { + Name = Name, + Icon = AvatarIconConverter.IconNameToUri(Icon), + Badge = ElementNameIconConverter.ElementNameToIconUri(FetterInfo.VisionBefore), + Quality = Quality, + + Time = time, + LastPull = lastPull, + IsUp = isUp, + }; + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/Weapon.Implementation.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/Weapon.Implementation.cs deleted file mode 100644 index 060a0d6d..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/Weapon.Implementation.cs +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -using Snap.Hutao.Model.Calculable; -using Snap.Hutao.Model.Intrinsic; -using Snap.Hutao.Model.Metadata.Abstraction; -using Snap.Hutao.Model.Metadata.Converter; -using Snap.Hutao.Model.Metadata.Item; -using Snap.Hutao.ViewModel.Complex; -using Snap.Hutao.ViewModel.GachaLog; - -namespace Snap.Hutao.Model.Metadata.Weapon; - -/// -/// 武器的接口实现 -/// -internal sealed partial class Weapon : IStatisticsItemSource, ISummaryItemSource, IItemSource, INameQuality, ICalculableSource, ICultivatable -{ - /// - /// [非元数据] 搭配数据 - /// TODO:Add View suffix. - /// - [JsonIgnore] - public WeaponCollocationView? Collocation { get; set; } - - /// - /// [非元数据] 养成物品视图 - /// - [JsonIgnore] - public List? CultivationItemsView { get; set; } - - /// - [JsonIgnore] - public QualityType Quality - { - get => RankLevel; - } - - /// - /// 最大等级 - /// - internal uint MaxLevel { get => GetMaxLevelByQuality(Quality); } - - public static uint GetMaxLevelByQuality(QualityType quality) - { - return quality >= QualityType.QUALITY_BLUE ? 90U : 70U; - } - - /// - public ICalculableWeapon ToCalculable() - { - return CalculableWeapon.From(this); - } - - /// - /// 转换为基础物品 - /// - /// 基础物品 - public Model.Item ToItem() - { - return new() - { - Name = Name, - Icon = EquipIconConverter.IconNameToUri(Icon), - Badge = WeaponTypeIconConverter.WeaponTypeToIconUri(WeaponType), - Quality = RankLevel, - }; - } - - /// - /// 转换到统计物品 - /// - /// 个数 - /// 统计物品 - public StatisticsItem ToStatisticsItem(int count) - { - return new() - { - Name = Name, - Icon = EquipIconConverter.IconNameToUri(Icon), - Badge = WeaponTypeIconConverter.WeaponTypeToIconUri(WeaponType), - Quality = RankLevel, - Count = count, - }; - } - - /// - /// 转换到简述统计物品 - /// - /// 距上个五星 - /// 时间 - /// 是否为Up物品 - /// 简述统计物品 - public SummaryItem ToSummaryItem(int lastPull, in DateTimeOffset time, bool isUp) - { - return new() - { - Name = Name, - Icon = EquipIconConverter.IconNameToUri(Icon), - Badge = WeaponTypeIconConverter.WeaponTypeToIconUri(WeaponType), - Time = time, - Quality = RankLevel, - LastPull = lastPull, - IsUp = isUp, - }; - } -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/Weapon.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/Weapon.cs index 19136d47..46233381 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/Weapon.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Weapon/Weapon.cs @@ -1,69 +1,105 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using Snap.Hutao.Model.Calculable; using Snap.Hutao.Model.Intrinsic; +using Snap.Hutao.Model.Metadata.Abstraction; +using Snap.Hutao.Model.Metadata.Converter; +using Snap.Hutao.Model.Metadata.Item; using Snap.Hutao.Model.Primitive; +using Snap.Hutao.ViewModel.Complex; +using Snap.Hutao.ViewModel.GachaLog; namespace Snap.Hutao.Model.Metadata.Weapon; -/// -/// 武器 -/// [HighQuality] -internal sealed partial class Weapon +internal sealed partial class Weapon : INameQualityAccess, + IStatisticsItemConvertible, + ISummaryItemConvertible, + IItemConvertible, + ICalculableSource, + ICultivationItemsAccess { - /// - /// Id - /// public WeaponId Id { get; set; } - /// - /// 突破 Id - /// public PromoteId PromoteId { get; set; } - /// - /// 武器类型 - /// public WeaponType WeaponType { get; set; } - /// - /// 等级 - /// public QualityType RankLevel { get; set; } - /// - /// 名称 - /// public string Name { get; set; } = default!; - /// - /// 描述 - /// public string Description { get; set; } = default!; - /// - /// 图标 - /// public string Icon { get; set; } = default!; - /// - /// 觉醒图标 - /// public string AwakenIcon { get; set; } = default!; - /// - /// 生长曲线 - /// public List GrowCurves { get; set; } = default!; - /// - /// 被动信息, 无被动的武器为 - /// public NameDescriptions? Affix { get; set; } = default!; - /// - /// 养成物品 - /// public List CultivationItems { get; set; } = default!; + + [JsonIgnore] + public WeaponCollocationView? CollocationView { get; set; } + + [JsonIgnore] + public List? CultivationItemsView { get; set; } + + [JsonIgnore] + public QualityType Quality + { + get => RankLevel; + } + + internal uint MaxLevel { get => GetMaxLevelByQuality(Quality); } + + public static uint GetMaxLevelByQuality(QualityType quality) + { + return quality >= QualityType.QUALITY_BLUE ? 90U : 70U; + } + + public ICalculableWeapon ToCalculable() + { + return CalculableWeapon.From(this); + } + + public Model.Item ToItem() + { + return new() + { + Name = Name, + Icon = EquipIconConverter.IconNameToUri(Icon), + Badge = WeaponTypeIconConverter.WeaponTypeToIconUri(WeaponType), + Quality = RankLevel, + }; + } + + public StatisticsItem ToStatisticsItem(int count) + { + return new() + { + Name = Name, + Icon = EquipIconConverter.IconNameToUri(Icon), + Badge = WeaponTypeIconConverter.WeaponTypeToIconUri(WeaponType), + Quality = RankLevel, + Count = count, + }; + } + + public SummaryItem ToSummaryItem(int lastPull, in DateTimeOffset time, bool isUp) + { + return new() + { + Name = Name, + Icon = EquipIconConverter.IconNameToUri(Icon), + Badge = WeaponTypeIconConverter.WeaponTypeToIconUri(WeaponType), + Time = time, + Quality = RankLevel, + LastPull = lastPull, + IsUp = isUp, + }; + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs index f7d8b514..509a26db 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs @@ -262,7 +262,7 @@ internal sealed partial class CultivationService : ICultivationService /// public async ValueTask RefreshInventoryAsync(CultivateProject project) { - List cultivatables = + List cultivationItemsEntryList = [ .. await metadataService.GetAvatarListAsync().ConfigureAwait(false), .. (await metadataService.GetWeaponListAsync().ConfigureAwait(false)).Where(weapon => weapon.Quality >= Model.Intrinsic.QualityType.QUALITY_BLUE), @@ -280,7 +280,7 @@ internal sealed partial class CultivationService : ICultivationService CalculateClient calculateClient = scope.ServiceProvider.GetRequiredService(); Response? resp = await calculateClient - .BatchComputeAsync(userAndUid, GeneratePromotionDeltas(cultivatables), true) + .BatchComputeAsync(userAndUid, GeneratePromotionDeltas(cultivationItemsEntryList), true) .ConfigureAwait(false); if (!resp.IsOk()) @@ -298,7 +298,7 @@ internal sealed partial class CultivationService : ICultivationService } } - private static List GeneratePromotionDeltas(List cultivatables) + private static List GeneratePromotionDeltas(List cultivatables) { List avatars = []; List weapons = []; @@ -306,7 +306,7 @@ internal sealed partial class CultivationService : ICultivationService while (cultivatables.Count > 0) { - ICultivatable bestItem = cultivatables.OrderByDescending(item => item.CultivationItems.Count(material => !materialIds.Contains(material))).First(); + ICultivationItemsAccess bestItem = cultivatables.OrderByDescending(item => item.CultivationItems.Count(material => !materialIds.Contains(material))).First(); if (bestItem.CultivationItems.All(materialIds.Contains)) { 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 420fa93e..497ad2dd 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsExtension.cs @@ -49,7 +49,7 @@ internal static class GachaStatisticsExtension /// 计数器 /// 统计物品列表 public static List ToStatisticsList(this Dictionary dict) - where TItem : IStatisticsItemSource + where TItem : IStatisticsItemConvertible { IOrderedEnumerable result = dict .Select(kvp => kvp.Key.ToStatisticsItem(kvp.Value)) 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 22b02de4..1ef41991 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsSlimFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsSlimFactory.cs @@ -27,7 +27,7 @@ internal sealed partial class GachaStatisticsSlimFactory : IGachaStatisticsSlimF return CreateCore(context, items, uid); } - private static void Track(INameQuality nameQuality, ref int orangeTracker, ref int purpleTracker) + private static void Track(INameQualityAccess nameQuality, ref int orangeTracker, ref int purpleTracker) { switch (nameQuality.Quality) { @@ -69,7 +69,7 @@ internal sealed partial class GachaStatisticsSlimFactory : IGachaStatisticsSlimF // O(n) operation foreach (ref readonly GachaItem item in CollectionsMarshal.AsSpan(items)) { - INameQuality nameQuality = context.GetNameQualityByItemId(item.ItemId); + INameQualityAccess nameQuality = context.GetNameQualityByItemId(item.ItemId); switch (item.QueryType) { case GachaType.Standard: 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 34ce5071..2541b719 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HistoryWishBuilder.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HistoryWishBuilder.cs @@ -16,11 +16,11 @@ internal sealed class HistoryWishBuilder { private readonly GachaEvent gachaEvent; - private readonly Dictionary orangeUpCounter = []; - private readonly Dictionary purpleUpCounter = []; - private readonly Dictionary orangeCounter = []; - private readonly Dictionary purpleCounter = []; - private readonly Dictionary blueCounter = []; + private readonly Dictionary orangeUpCounter = []; + private readonly Dictionary purpleUpCounter = []; + private readonly Dictionary orangeCounter = []; + private readonly Dictionary purpleCounter = []; + private readonly Dictionary blueCounter = []; private int totalCountTracker; @@ -37,18 +37,18 @@ internal sealed class HistoryWishBuilder switch (ConfigType) { 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); + orangeUpCounter = gachaEvent.UpOrangeList.Select(id => context.IdAvatarMap[id]).ToDictionary(a => (IStatisticsItemConvertible)a, a => 0); + purpleUpCounter = gachaEvent.UpPurpleList.Select(id => context.IdAvatarMap[id]).ToDictionary(a => (IStatisticsItemConvertible)a, a => 0); break; 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); + orangeUpCounter = gachaEvent.UpOrangeList.Select(id => context.IdWeaponMap[id]).ToDictionary(w => (IStatisticsItemConvertible)w, w => 0); + purpleUpCounter = gachaEvent.UpPurpleList.Select(id => context.IdWeaponMap[id]).ToDictionary(w => (IStatisticsItemConvertible)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); + orangeUpCounter = gachaEvent.UpOrangeList.Select(id => (IStatisticsItemConvertible?)context.IdAvatarMap.GetValueOrDefault(id) ?? context.IdWeaponMap[id]).ToDictionary(c => c, c => 0); + purpleUpCounter = gachaEvent.UpPurpleList.Select(id => (IStatisticsItemConvertible?)context.IdAvatarMap.GetValueOrDefault(id) ?? context.IdWeaponMap[id]).ToDictionary(c => c, c => 0); break; } } @@ -74,7 +74,7 @@ internal sealed class HistoryWishBuilder /// /// 物品 /// 是否为Up物品 - public bool IncreaseOrange(IStatisticsItemSource item) + public bool IncreaseOrange(IStatisticsItemConvertible item) { orangeCounter.IncreaseOne(item); ++totalCountTracker; @@ -86,7 +86,7 @@ internal sealed class HistoryWishBuilder /// 计数四星物品 /// /// 物品 - public void IncreasePurple(IStatisticsItemSource item) + public void IncreasePurple(IStatisticsItemConvertible item) { purpleUpCounter.TryIncreaseOne(item); purpleCounter.IncreaseOne(item); @@ -97,7 +97,7 @@ internal sealed class HistoryWishBuilder /// 计数三星武器 /// /// 武器 - public void IncreaseBlue(IStatisticsItemSource item) + public void IncreaseBlue(IStatisticsItemConvertible item) { blueCounter.IncreaseOne(item); ++totalCountTracker; 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 e98ed1d1..39387960 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/HutaoStatisticsFactory.cs @@ -55,7 +55,7 @@ internal sealed class HutaoStatisticsFactory foreach (ref readonly ItemCount item in CollectionsMarshal.AsSpan(items)) { - IStatisticsItemSource source = item.Item.StringLength() switch + IStatisticsItemConvertible source = item.Item.StringLength() switch { 8U => context.GetAvatar(item.Item), 5U => context.GetWeapon(item.Item), 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 067c739a..1bed7e2e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilder.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/TypedWishSummaryBuilder.cs @@ -44,7 +44,7 @@ internal sealed class TypedWishSummaryBuilder /// 祈愿物品 /// 对应武器 /// 是否为Up物品 - public void Track(GachaItem item, ISummaryItemSource source, bool isUp) + public void Track(GachaItem item, ISummaryItemConvertible source, bool isUp) { if (!context.TypeEvaluator(item.GachaType)) { diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogServiceMetadataContext.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogServiceMetadataContext.cs index e7dd7207..08c6bd73 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogServiceMetadataContext.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogServiceMetadataContext.cs @@ -59,7 +59,7 @@ internal sealed class GachaLogServiceMetadataContext : IMetadataContext, return result; } - public INameQuality GetNameQualityByItemId(uint id) + public INameQualityAccess GetNameQualityByItemId(uint id) { uint place = id.StringLength(); return place switch diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml index 843d4cbf..548ea944 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml @@ -571,7 +571,7 @@ Grid.Column="0" ItemTemplate="{StaticResource CollocationTemplate}" ItemsPanel="{StaticResource StackPanelSpacing4Template}" - ItemsSource="{Binding Selected.Collocation.Avatars}"/> + ItemsSource="{Binding Selected.CollocationView.Avatars}"/> + ItemsSource="{Binding Selected.CollocationView.Weapons}"/> + ItemsSource="{Binding Selected.CollocationView.ReliquarySets}"/> diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiWeaponPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiWeaponPage.xaml index 0e9d5d43..51d7054c 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiWeaponPage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiWeaponPage.xaml @@ -336,7 +336,7 @@ - + idMaterialMap.GetValueOrDefault(i, Material.Default)); } diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiWeaponViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiWeaponViewModel.cs index 78673e7c..b6ed7362 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiWeaponViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiWeaponViewModel.cs @@ -141,7 +141,7 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel foreach (Weapon weapon in weapons) { - weapon.Collocation = hutaoCache.WeaponCollocations.GetValueOrDefault(weapon.Id); + weapon.CollocationView = hutaoCache.WeaponCollocations.GetValueOrDefault(weapon.Id); weapon.CultivationItemsView ??= weapon.CultivationItems.SelectList(i => idMaterialMap.GetValueOrDefault(i, Material.Default)); } }