From 7a99c44b298d921d2d0be55978bf831b490674eb Mon Sep 17 00:00:00 2001 From: DismissedLight <1686188646@qq.com> Date: Tue, 25 Oct 2022 15:47:12 +0800 Subject: [PATCH] collocation for wiki avatar --- .../Model/Binding/Hutao/ComplexAvatar.cs | 2 +- .../Binding/Hutao/ComplexAvatarCollocation.cs | 10 +- .../Binding/Hutao/ComplexReliquarySet.cs | 2 +- .../Model/Binding/Hutao/ComplexWeapon.cs | 2 +- .../Model/Metadata/Avatar/Avatar.cs | 6 + .../Converter/GachaAvatarImgConverter.cs | 31 ++++++ .../Snap.Hutao/Service/Hutao/HutaoCache.cs | 5 +- .../Hutao/{IHtaoCache.cs => IHutaoCache.cs} | 2 +- .../Snap.Hutao/View/Page/WikiAvatarPage.xaml | 104 ++++++++++++++++++ .../ViewModel/HutaoDatabaseViewModel.cs | 4 +- .../ViewModel/WikiAvatarViewModel.cs | 32 +++++- .../Snap.Hutao/Web/Hutao/Model/AvatarBuild.cs | 4 +- 12 files changed, 187 insertions(+), 17 deletions(-) create mode 100644 src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/GachaAvatarImgConverter.cs rename src/Snap.Hutao/Snap.Hutao/Service/Hutao/{IHtaoCache.cs => IHutaoCache.cs} (97%) diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/ComplexAvatar.cs b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/ComplexAvatar.cs index 8b286729..ab278210 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/ComplexAvatar.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/ComplexAvatar.cs @@ -10,7 +10,7 @@ namespace Snap.Hutao.Model.Binding.Hutao; /// /// 角色 /// -internal class ComplexAvatar +public class ComplexAvatar { /// /// 构造一个胡桃数据库角色 diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/ComplexAvatarCollocation.cs b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/ComplexAvatarCollocation.cs index f0557f7a..dfed6404 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/ComplexAvatarCollocation.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/ComplexAvatarCollocation.cs @@ -1,16 +1,15 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. -using Snap.Hutao.Model.Intrinsic; using Snap.Hutao.Model.Metadata.Avatar; -using Snap.Hutao.Model.Metadata.Converter; +using Snap.Hutao.Model.Primitive; namespace Snap.Hutao.Model.Binding.Hutao; /// /// 角色搭配 /// -internal class ComplexAvatarCollocation : ComplexAvatar +public class ComplexAvatarCollocation : ComplexAvatar { /// /// 构造一个新的角色搭配 @@ -22,6 +21,11 @@ internal class ComplexAvatarCollocation : ComplexAvatar { } + /// + /// 角色Id + /// + public AvatarId AvatarId { get; set; } + /// /// 角色 /// diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/ComplexReliquarySet.cs b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/ComplexReliquarySet.cs index b6c7d089..a65515f7 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/ComplexReliquarySet.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/ComplexReliquarySet.cs @@ -10,7 +10,7 @@ namespace Snap.Hutao.Model.Binding.Hutao; /// /// 圣遗物套装 /// -internal class ComplexReliquarySet +public class ComplexReliquarySet { /// /// 构造一个新的胡桃数据库圣遗物套装 diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/ComplexWeapon.cs b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/ComplexWeapon.cs index 1a8b6ae0..709e0b66 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/ComplexWeapon.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/ComplexWeapon.cs @@ -10,7 +10,7 @@ namespace Snap.Hutao.Model.Binding.Hutao; /// /// 胡桃数据库武器 /// -internal class ComplexWeapon +public class ComplexWeapon { /// /// 构造一个胡桃数据库武器 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 3727447f..dbd8a435 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.cs @@ -3,6 +3,7 @@ using Snap.Hutao.Model.Binding.Gacha; using Snap.Hutao.Model.Binding.Gacha.Abstraction; +using Snap.Hutao.Model.Binding.Hutao; using Snap.Hutao.Model.Intrinsic; using Snap.Hutao.Model.Metadata.Abstraction; using Snap.Hutao.Model.Metadata.Converter; @@ -84,6 +85,11 @@ public class Avatar : IStatisticsItemSource, ISummaryItemSource, INameQuality /// public IEnumerable Costumes { get; set; } = default!; + /// + /// [非元数据] 搭配数据 + /// + public ComplexAvatarCollocation? Collocation { get; set; } + /// /// 转换为基础物品 /// diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/GachaAvatarImgConverter.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/GachaAvatarImgConverter.cs new file mode 100644 index 00000000..b0b192c5 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/GachaAvatarImgConverter.cs @@ -0,0 +1,31 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Snap.Hutao.Control; + +namespace Snap.Hutao.Model.Metadata.Converter; + +/// +/// 角色头像转换器 +/// +internal class GachaAvatarImgConverter : ValueConverterBase +{ + private const string BaseUrl = "https://static.snapgenshin.com/GachaAvatarImg/UI_Gacha_AvatarImg_{0}.png"; + + /// + /// 名称转Uri + /// + /// 名称 + /// 链接 + public static Uri IconNameToUri(string name) + { + name = name["UI_AvatarIcon_".Length..]; + return new Uri(string.Format(BaseUrl, name)); + } + + /// + public override Uri Convert(string from) + { + return IconNameToUri(from); + } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Hutao/HutaoCache.cs b/src/Snap.Hutao/Snap.Hutao/Service/Hutao/HutaoCache.cs index 5304e4ab..66541172 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Hutao/HutaoCache.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Hutao/HutaoCache.cs @@ -12,8 +12,8 @@ namespace Snap.Hutao.Service.Hutao; /// /// 胡桃 API 缓存 /// -[Injection(InjectAs.Singleton, typeof(IHtaoCache))] -internal class HutaoCache : IHtaoCache +[Injection(InjectAs.Singleton, typeof(IHutaoCache))] +internal class HutaoCache : IHutaoCache { private readonly IHutaoService hutaoService; private readonly IMetadataService metadataService; @@ -91,6 +91,7 @@ internal class HutaoCache : IHtaoCache { return new ComplexAvatarCollocation(idAvatarMap[co.AvatarId]) { + AvatarId = co.AvatarId, Avatars = co.Avatars.Select(a => new ComplexAvatar(idAvatarMap[a.Item], a.Rate)).ToList(), Weapons = co.Weapons.Select(w => new ComplexWeapon(idWeaponMap[w.Item], w.Rate)).ToList(), ReliquarySets = co.Reliquaries.Select(r => new ComplexReliquarySet(r, idReliquarySetMap)).ToList(), diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Hutao/IHtaoCache.cs b/src/Snap.Hutao/Snap.Hutao/Service/Hutao/IHutaoCache.cs similarity index 97% rename from src/Snap.Hutao/Snap.Hutao/Service/Hutao/IHtaoCache.cs rename to src/Snap.Hutao/Snap.Hutao/Service/Hutao/IHutaoCache.cs index d2443b33..e4bf0bd0 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Hutao/IHtaoCache.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Hutao/IHutaoCache.cs @@ -9,7 +9,7 @@ namespace Snap.Hutao.Service.Hutao; /// /// 胡桃 API 缓存 /// -internal interface IHtaoCache +internal interface IHutaoCache { /// /// 角色使用率 diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml index 711bf686..8da416bd 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml @@ -25,6 +25,7 @@ + @@ -69,6 +70,10 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -445,6 +538,17 @@ + + + + diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/HutaoDatabaseViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/HutaoDatabaseViewModel.cs index 8e5e220c..a90c8439 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/HutaoDatabaseViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/HutaoDatabaseViewModel.cs @@ -15,7 +15,7 @@ namespace Snap.Hutao.ViewModel; [Injection(InjectAs.Scoped)] internal class HutaoDatabaseViewModel : ObservableObject, ISupportCancellation { - private readonly IHtaoCache hutaoCache; + private readonly IHutaoCache hutaoCache; private List? avatarUsageRanks; private List? avatarAppearanceRanks; @@ -28,7 +28,7 @@ internal class HutaoDatabaseViewModel : ObservableObject, ISupportCancellation /// 胡桃服务缓存 /// 元数据服务 /// 异步命令工厂 - public HutaoDatabaseViewModel(IHtaoCache hutaoCache, IAsyncRelayCommandFactory asyncRelayCommandFactory) + public HutaoDatabaseViewModel(IHutaoCache hutaoCache, IAsyncRelayCommandFactory asyncRelayCommandFactory) { this.hutaoCache = hutaoCache; diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiAvatarViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiAvatarViewModel.cs index f6728b02..27eb5682 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiAvatarViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiAvatarViewModel.cs @@ -6,8 +6,11 @@ using CommunityToolkit.WinUI.UI; using Snap.Hutao.Core.Threading; using Snap.Hutao.Factory.Abstraction; using Snap.Hutao.Model; +using Snap.Hutao.Model.Binding.Hutao; using Snap.Hutao.Model.Intrinsic; using Snap.Hutao.Model.Metadata.Avatar; +using Snap.Hutao.Model.Primitive; +using Snap.Hutao.Service.Hutao; using Snap.Hutao.Service.Metadata; namespace Snap.Hutao.ViewModel; @@ -19,6 +22,7 @@ namespace Snap.Hutao.ViewModel; internal class WikiAvatarViewModel : ObservableObject { private readonly IMetadataService metadataService; + private readonly IHutaoCache hutaoCache; // filters private readonly List> filterElementInfos; @@ -34,10 +38,12 @@ internal class WikiAvatarViewModel : ObservableObject /// 构造一个新的角色资料视图模型 /// /// 元数据服务 + /// 胡桃缓存 /// 异步命令工厂 - public WikiAvatarViewModel(IMetadataService metadataService, IAsyncRelayCommandFactory asyncRelayCommandFactory) + public WikiAvatarViewModel(IMetadataService metadataService, IHutaoCache hutaoCache, IAsyncRelayCommandFactory asyncRelayCommandFactory) { this.metadataService = metadataService; + this.hutaoCache = hutaoCache; OpenUICommand = asyncRelayCommandFactory.Create(OpenUIAsync); filterElementInfos = new() @@ -146,17 +152,33 @@ internal class WikiAvatarViewModel : ObservableObject { if (await metadataService.InitializeAsync().ConfigureAwait(false)) { - IList avatars = await metadataService.GetAvatarsAsync().ConfigureAwait(false); - IOrderedEnumerable sorted = avatars + List avatars = await metadataService.GetAvatarsAsync().ConfigureAwait(false); + List sorted = avatars .OrderByDescending(avatar => avatar.BeginTime) - .ThenByDescending(avatar => avatar.Sort); + .ThenByDescending(avatar => avatar.Sort) + .ToList(); + + await CombineWithAvatarCollocationsAsync(sorted).ConfigureAwait(false); await ThreadHelper.SwitchToMainThreadAsync(); - Avatars = new AdvancedCollectionView(sorted.ToList(), true); + Avatars = new AdvancedCollectionView(sorted, true); Selected = Avatars.Cast().FirstOrDefault(); } } + private async Task CombineWithAvatarCollocationsAsync(List avatars) + { + if (await hutaoCache.InitializeForWikiAvatarViewModelAsync().ConfigureAwait(false)) + { + Dictionary idCollocations = hutaoCache.AvatarCollocations!.ToDictionary(a => a.AvatarId); + + foreach (Avatar avatar in avatars) + { + avatar.Collocation = idCollocations.GetValueOrDefault(avatar.Id); + } + } + } + private void OnFilterChanged() { if (Avatars is not null) diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/AvatarBuild.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/AvatarBuild.cs index bc296828..f5fb25fe 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/AvatarBuild.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hutao/Model/AvatarBuild.cs @@ -1,6 +1,8 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using Snap.Hutao.Model.Primitive; + namespace Snap.Hutao.Web.Hutao.Model; /// @@ -11,5 +13,5 @@ public abstract class AvatarBuild /// /// 角色Id /// - public int AvatarId { get; set; } + public AvatarId AvatarId { get; set; } }