diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/Achievement.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/Achievement.cs index c87f76d0..ce387466 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/Achievement.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/Achievement.cs @@ -10,60 +10,29 @@ using System.ComponentModel.DataAnnotations.Schema; namespace Snap.Hutao.Model.Entity; -/// -/// 成就 -/// -[HighQuality] [Table("achievements")] internal sealed class Achievement : IAppDbEntityHasArchive, IEquatable, IDbMappingForeignKeyFrom, IDbMappingForeignKeyFrom { - /// - /// 内部Id - /// [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid InnerId { get; set; } - /// - /// 存档 Id - /// public Guid ArchiveId { get; set; } - /// - /// 存档 - /// [ForeignKey(nameof(ArchiveId))] public AchievementArchive Archive { get; set; } = default!; - /// - /// Id - /// public uint Id { get; set; } - /// - /// 当前进度 - /// public uint Current { get; set; } - /// - /// 完成时间 - /// public DateTimeOffset Time { get; set; } - /// - /// 状态 - /// public AchievementStatus Status { get; set; } - /// - /// 创建一个新的成就 - /// - /// 对应的用户id - /// 成就Id - /// 新创建的成就 public static Achievement From(in Guid archiveId, in AchievementId id) { return new() @@ -75,12 +44,6 @@ internal sealed class Achievement : IAppDbEntityHasArchive, }; } - /// - /// 创建一个新的成就 - /// - /// 对应的用户id - /// uiaf项 - /// 新创建的成就 public static Achievement From(in Guid userId, in UIAFItem uiaf) { return new() @@ -93,32 +56,27 @@ internal sealed class Achievement : IAppDbEntityHasArchive, }; } - /// public bool Equals(Achievement? other) { if (other is null) { return false; } - else - { - return ArchiveId == other.ArchiveId - && Id == other.Id - && Current == other.Current - && Status == other.Status - && Time == other.Time; - } + + return ArchiveId == other.ArchiveId + && Id == other.Id + && Current == other.Current + && Status == other.Status + && Time == other.Time; } #region Object - /// public override bool Equals(object? obj) { return Equals(obj as Achievement); } - /// public override int GetHashCode() { return HashCode.Combine(ArchiveId, Id, Current, Status, Time); diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/AvatarInfo.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/AvatarInfo.cs index aff34126..fda356f5 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/AvatarInfo.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/AvatarInfo.cs @@ -7,28 +7,15 @@ using System.ComponentModel.DataAnnotations.Schema; namespace Snap.Hutao.Model.Entity; -/// -/// 角色信息表 -/// -[HighQuality] [Table("avatar_infos")] internal sealed class AvatarInfo : IMappingFrom { - /// - /// 内部 Id - /// [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid InnerId { get; set; } - /// - /// Uid - /// public string Uid { get; set; } = default!; - /// - /// 角色的信息 - /// public Web.Enka.Model.AvatarInfo Info { get; set; } = default!; public DateTimeOffset ShowcaseRefreshTime { get; set; } @@ -37,12 +24,6 @@ internal sealed class AvatarInfo : IMappingFrom - /// 创建一个新的实体角色信息 - /// - /// uid - /// 角色信息 - /// 实体角色信息 public static AvatarInfo From(string uid, Web.Enka.Model.AvatarInfo info) { return new() { Uid = uid, Info = info }; diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/Configuration/JsonTextValueConverter.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/Configuration/JsonTextValueConverter.cs index fee9d0e0..4dfcaff5 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/Configuration/JsonTextValueConverter.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/Configuration/JsonTextValueConverter.cs @@ -6,18 +6,13 @@ using Snap.Hutao.Core.Json; namespace Snap.Hutao.Model.Entity.Configuration; -/// -/// Json文本转换器 -/// -/// 实体类型 -[HighQuality] -internal sealed class JsonTextValueConverter : ValueConverter +internal sealed class JsonTextValueConverter : ValueConverter { [SuppressMessage("", "SH007")] public JsonTextValueConverter() : base( obj => JsonSerializer.Serialize(obj, JsonOptions.Default), - str => JsonSerializer.Deserialize(str, JsonOptions.Default)!) + str => JsonSerializer.Deserialize(str, JsonOptions.Default)!) { } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateEntry.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateEntry.cs index d39c1dc3..87db775a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateEntry.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateEntry.cs @@ -8,51 +8,25 @@ using System.ComponentModel.DataAnnotations.Schema; namespace Snap.Hutao.Model.Entity; -/// -/// 养成入口 -/// -[HighQuality] [Table("cultivate_entries")] internal sealed class CultivateEntry : IAppDbEntity, IDbMappingForeignKeyFrom { - /// - /// 内部Id - /// [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid InnerId { get; set; } - /// - /// 项目Id - /// public Guid ProjectId { get; set; } - /// - /// 项目 - /// [ForeignKey(nameof(ProjectId))] public CultivateProject Project { get; set; } = default!; public CultivateEntryLevelInformation? LevelInformation { get; set; } - /// - /// 养成类型 - /// public CultivateType Type { get; set; } - /// - /// 角色/武器/家具 Id - /// public uint Id { get; set; } - /// - /// 创建一个新的养成入口点 - /// - /// 项目Id - /// 类型 - /// 主Id - /// 养成入口点 public static CultivateEntry From(in Guid projectId, in CultivateType type, in uint id) { return new() @@ -62,10 +36,4 @@ internal sealed class CultivateEntry : IAppDbEntity, Id = id, }; } - - public static CultivateEntry Join(CultivateEntry entry, CultivateEntryLevelInformation levelInformation) - { - entry.LevelInformation = levelInformation; - return entry; - } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateItem.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateItem.cs index eef1e917..702ed58c 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateItem.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateItem.cs @@ -7,52 +7,24 @@ using System.ComponentModel.DataAnnotations.Schema; namespace Snap.Hutao.Model.Entity; -/// -/// 消耗物品 -/// -[HighQuality] [Table("cultivate_items")] internal sealed class CultivateItem : IDbMappingForeignKeyFrom { - /// - /// 内部Id - /// [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid InnerId { get; set; } - /// - /// 外键 - /// public Guid EntryId { get; set; } - /// - /// 入口名称 - /// [ForeignKey(nameof(EntryId))] public CultivateEntry Entry { get; set; } = default!; - /// - /// 物品 Id - /// public uint ItemId { get; set; } - /// - /// 物品个数 - /// public uint Count { get; set; } - /// - /// 是否完成此项 - /// public bool IsFinished { get; set; } - /// - /// 创建一个新的养成物品 - /// - /// 入口点 Id - /// 物品 - /// 养成物品 public static CultivateItem From(in Guid entryId, in Web.Hoyolab.Takumi.Event.Calculate.Item item) { return new() diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateProject.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateProject.cs index 3bb4b78d..adb04ac4 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateProject.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateProject.cs @@ -9,45 +9,21 @@ using System.ComponentModel.DataAnnotations.Schema; namespace Snap.Hutao.Model.Entity; -/// -/// 培养计划 -/// -[HighQuality] [Table("cultivate_projects")] internal sealed partial class CultivateProject : ISelectable, IAdvancedCollectionViewItem, - IMappingFrom + IMappingFrom { - /// - /// 内部Id - /// [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid InnerId { get; set; } - /// - /// 是否选中 - /// public bool IsSelected { get; set; } - /// - /// 名称 - /// public string Name { get; set; } = default!; - /// - /// 所属的Uid - /// - public string? AttachedUid { get; set; } - - /// - /// 创建新的养成计划 - /// - /// 名称 - /// 绑定的Uid - /// 新的养成计划 - public static CultivateProject From(string name, string? attachedUid = null) + public static CultivateProject From(string name) { - return new() { Name = name, AttachedUid = attachedUid }; + return new() { Name = name }; } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReserved.cs b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReserved.cs index b0707f9e..e6b7d086 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReserved.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReserved.cs @@ -6,4 +6,12 @@ namespace Snap.Hutao.Model.InterChange; internal sealed class HutaoReserved { public required uint Version { get; set; } + + public List>? Achievement { get; set; } + + public List>? AvatarInfo { get; set; } + + public List>? Cultivation { get; set; } + + public List>? SpiralAbyss { get; set; } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReservedAchievement.cs b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReservedAchievement.cs new file mode 100644 index 00000000..65a9b953 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReservedAchievement.cs @@ -0,0 +1,29 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Snap.Hutao.Core.Abstraction; +using Snap.Hutao.Model.Intrinsic; + +namespace Snap.Hutao.Model.InterChange; + +internal sealed class HutaoReservedAchievement : IMappingFrom +{ + public required uint Id { get; set; } + + public required uint Current { get; set; } + + public required DateTimeOffset Time { get; set; } + + public required AchievementStatus Status { get; set; } + + public static HutaoReservedAchievement From(Entity.Achievement source) + { + return new() + { + Id = source.Id, + Current = source.Current, + Time = source.Time, + Status = source.Status, + }; + } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReservedCultivationEntry.cs b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReservedCultivationEntry.cs new file mode 100644 index 00000000..54c49085 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReservedCultivationEntry.cs @@ -0,0 +1,45 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Snap.Hutao.Model.Entity.Primitive; + +namespace Snap.Hutao.Model.InterChange; + +internal sealed class HutaoReservedCultivationEntry +{ + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public uint AvatarLevelFrom { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public uint AvatarLevelTo { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public uint SkillALevelFrom { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public uint SkillALevelTo { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public uint SkillELevelFrom { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public uint SkillELevelTo { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public uint SkillQLevelFrom { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public uint SkillQLevelTo { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public uint WeaponLevelFrom { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public uint WeaponLevelTo { get; set; } + + public required CultivateType Type { get; set; } + + public required uint Id { get; set; } + + public required List Items { get; set; } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReservedCultivationItem.cs b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReservedCultivationItem.cs new file mode 100644 index 00000000..0b6a992b --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReservedCultivationItem.cs @@ -0,0 +1,26 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Snap.Hutao.Core.Abstraction; +using Snap.Hutao.Model.Entity; + +namespace Snap.Hutao.Model.InterChange; + +internal sealed class HutaoReservedCultivationItem : IMappingFrom +{ + public required uint ItemId { get; set; } + + public required uint Count { get; set; } + + public required bool IsFinished { get; set; } + + public static HutaoReservedCultivationItem From(CultivateItem item) + { + return new() + { + ItemId = item.ItemId, + Count = item.Count, + IsFinished = item.IsFinished, + }; + } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReservedEntry.cs b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReservedEntry.cs new file mode 100644 index 00000000..e7746593 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReservedEntry.cs @@ -0,0 +1,11 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Model.InterChange; + +internal sealed class HutaoReservedEntry +{ + public required string Identity { get; set; } + + public required List List { get; set; } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReservedSpiralAbyssEntry.cs b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReservedSpiralAbyssEntry.cs new file mode 100644 index 00000000..3ffa9446 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/HutaoReservedSpiralAbyssEntry.cs @@ -0,0 +1,11 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Model.InterChange; + +internal sealed class HutaoReservedSpiralAbyssEntry +{ + public required uint ScheduleId { get; set; } + + public required Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.SpiralAbyss SpiralAbyss { get; set; } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementDbService.cs index 19b2f2be..c6450b16 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementDbService.cs @@ -78,4 +78,9 @@ internal sealed partial class AchievementDbService : IAchievementDbService { return this.List(); } + + public AchievementArchive? GetAchievementArchiveById(Guid archiveId) + { + return this.SingleOrDefault(a => a.InnerId == archiveId); + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/IAchievementDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/IAchievementDbService.cs index 5f172bae..cd0b57f0 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/IAchievementDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/IAchievementDbService.cs @@ -5,14 +5,19 @@ using Snap.Hutao.Model.Primitive; using Snap.Hutao.Service.Abstraction; using System.Collections.ObjectModel; using EntityAchievement = Snap.Hutao.Model.Entity.Achievement; +using EntityArchive = Snap.Hutao.Model.Entity.AchievementArchive; namespace Snap.Hutao.Service.Achievement; -internal interface IAchievementDbService : IAppDbService, IAppDbService +internal interface IAchievementDbService : IAppDbService, IAppDbService { - ObservableCollection GetAchievementArchiveCollection(); + ObservableCollection GetAchievementArchiveCollection(); - List GetAchievementArchiveList(); + List GetAchievementArchiveList(); + + EntityArchive? GetAchievementArchiveById(Guid archiveId); + + void RemoveAchievementArchive(EntityArchive archive); List GetAchievementListByArchiveId(Guid archiveId); @@ -23,6 +28,4 @@ internal interface IAchievementDbService : IAppDbService GetLatestFinishedAchievementListByArchiveId(Guid archiveId, int take); void OverwriteAchievement(EntityAchievement achievement); - - void RemoveAchievementArchive(Model.Entity.AchievementArchive archive); } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationDbService.cs index 389de62e..9f413c2d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationDbService.cs @@ -85,4 +85,9 @@ internal sealed partial class CultivationDbService : ICultivationDbService { this.Add(levelInformation); } + + public CultivateProject? GetCultivateProjectById(Guid projectId) + { + return this.SingleOrDefault(p => p.InnerId == projectId); + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationDbService.cs index 3a8e84a4..84f80573 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationDbService.cs @@ -28,6 +28,8 @@ internal interface ICultivationDbService : IAppDbService GetCultivateProjectCollection(); + CultivateProject? GetCultivateProjectById(Guid projectId); + void AddCultivateEntry(CultivateEntry entry); void AddCultivateItemRange(IEnumerable toAdd); diff --git a/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/ISpiralAbyssRecordDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/ISpiralAbyssRecordDbService.cs index 411b7178..a53e91d1 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/ISpiralAbyssRecordDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/ISpiralAbyssRecordDbService.cs @@ -10,7 +10,7 @@ internal interface ISpiralAbyssRecordDbService : IAppDbService { void AddSpiralAbyssEntry(SpiralAbyssEntry entry); - Dictionary GetSpiralAbyssEntryListByUid(string uid); + Dictionary GetSpiralAbyssEntryMapByUid(string uid); void UpdateSpiralAbyssEntry(SpiralAbyssEntry entry); } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/SpiralAbyssRecordDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/SpiralAbyssRecordDbService.cs index 6079a19d..1ad80d04 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/SpiralAbyssRecordDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/SpiralAbyssRecordDbService.cs @@ -14,7 +14,7 @@ internal sealed partial class SpiralAbyssRecordDbService : ISpiralAbyssRecordDbS public IServiceProvider ServiceProvider { get => serviceProvider; } - public Dictionary GetSpiralAbyssEntryListByUid(string uid) + public Dictionary GetSpiralAbyssEntryMapByUid(string uid) { return this.Query(query => query .Where(s => s.Uid == uid) diff --git a/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/SpiralAbyssRecordService.cs b/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/SpiralAbyssRecordService.cs index fc2a3e11..403f0459 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/SpiralAbyssRecordService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/SpiralAbyssRecordService.cs @@ -34,6 +34,7 @@ internal sealed partial class SpiralAbyssRecordService : ISpiralAbyssRecordServi { if (await metadataService.InitializeAsync().ConfigureAwait(false)) { + // TODO replace to IMetadataContext metadataContext = new() { IdScheduleMap = await metadataService.GetIdToTowerScheduleMapAsync().ConfigureAwait(false), @@ -60,7 +61,7 @@ internal sealed partial class SpiralAbyssRecordService : ISpiralAbyssRecordServi if (spiralAbysses is null) { await taskContext.SwitchToBackgroundAsync(); - Dictionary entryMap = spiralAbyssRecordDbService.GetSpiralAbyssEntryListByUid(userAndUid.Uid.Value); + Dictionary entryMap = spiralAbyssRecordDbService.GetSpiralAbyssEntryMapByUid(userAndUid.Uid.Value); ArgumentNullException.ThrowIfNull(metadataContext); spiralAbysses = metadataContext.IdScheduleMap.Values diff --git a/src/Snap.Hutao/Snap.Hutao/Service/UIGF/UIGF40ExportService.cs b/src/Snap.Hutao/Snap.Hutao/Service/UIGF/UIGF40ExportService.cs index 5f763ade..32590c84 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/UIGF/UIGF40ExportService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/UIGF/UIGF40ExportService.cs @@ -4,8 +4,13 @@ using Snap.Hutao.Core; using Snap.Hutao.Model.Entity; using Snap.Hutao.Model.InterChange; +using Snap.Hutao.Service.Achievement; +using Snap.Hutao.Service.AvatarInfo; +using Snap.Hutao.Service.Cultivation; using Snap.Hutao.Service.GachaLog; +using Snap.Hutao.Service.SpiralAbyss; using System.IO; +using System.Runtime.InteropServices; namespace Snap.Hutao.Service.UIGF; @@ -13,8 +18,8 @@ namespace Snap.Hutao.Service.UIGF; [Injection(InjectAs.Transient, typeof(IUIGFExportService), Key = UIGFVersion.UIGF40)] internal sealed partial class UIGF40ExportService : IUIGFExportService { - private readonly IGachaLogDbService gachaLogDbService; private readonly JsonSerializerOptions jsonOptions; + private readonly IServiceProvider serviceProvider; private readonly RuntimeOptions runtimeOptions; private readonly ITaskContext taskContext; @@ -38,6 +43,10 @@ internal sealed partial class UIGF40ExportService : IUIGFExportService }; ExportGachaArchives(uigf, exportOptions.GachaArchiveIds); + ExportAchievementArchives(uigf.HutaoReserved, exportOptions.ReservedAchievementArchiveIds); + ExportAvatarInfoUids(uigf.HutaoReserved, exportOptions.ReservedAvatarInfoUids); + ExportCultivationProjects(uigf.HutaoReserved, exportOptions.ReservedCultivationProjectIds); + ExportSpialAbysses(uigf.HutaoReserved, exportOptions.ReservedSpiralAbyssUids); using (FileStream stream = File.Create(exportOptions.FilePath)) { @@ -49,7 +58,14 @@ internal sealed partial class UIGF40ExportService : IUIGFExportService private void ExportGachaArchives(Model.InterChange.UIGF uigf, List archiveIds) { - List> hk4eEntries = []; + if (archiveIds.Count <= 0) + { + return; + } + + IGachaLogDbService gachaLogDbService = serviceProvider.GetRequiredService(); + + List> results = []; foreach (Guid archiveId in archiveIds) { GachaArchive? archive = gachaLogDbService.GetGachaArchiveById(archiveId); @@ -59,12 +75,163 @@ internal sealed partial class UIGF40ExportService : IUIGFExportService { Uid = archive.Uid, TimeZone = 0, - List = [.. dbItems.Select(Hk4eItem.From)], + List = dbItems.SelectList(Hk4eItem.From), }; - hk4eEntries.Add(entry); + results.Add(entry); } - uigf.Hk4e = hk4eEntries; + uigf.Hk4e = results; } + + private void ExportAchievementArchives(HutaoReserved hutaoReserved, List archiveIds) + { + if (archiveIds.Count <= 0) + { + return; + } + + IAchievementDbService achievementDbService = serviceProvider.GetRequiredService(); + + List> results = []; + foreach (Guid archiveId in archiveIds) + { + AchievementArchive? archive = achievementDbService.GetAchievementArchiveById(archiveId); + ArgumentNullException.ThrowIfNull(archive); + List dbItems = achievementDbService.GetAchievementListByArchiveId(archiveId); + HutaoReservedEntry entry = new() + { + Identity = archive.Name, + List = dbItems.SelectList(HutaoReservedAchievement.From), + }; + + results.Add(entry); + } + + hutaoReserved.Achievement = results; + } + + private void ExportAvatarInfoUids(HutaoReserved hutaoReserved, List uids) + { + if (uids.Count <= 0) + { + return; + } + + IAvatarInfoDbService avatarInfoDbService = serviceProvider.GetRequiredService(); + + List> results = []; + foreach (string uid in uids) + { + List? dbItems = avatarInfoDbService.GetAvatarInfoListByUid(uid); + HutaoReservedEntry entry = new() + { + Identity = uid, + List = dbItems.SelectList(item => item.Info), + }; + + results.Add(entry); + } + + hutaoReserved.AvatarInfo = results; + } + + private void ExportCultivationProjects(HutaoReserved hutaoReserved, List projectIds) + { + if (projectIds.Count <= 0) + { + return; + } + + ICultivationDbService cultivationDbService = serviceProvider.GetRequiredService(); + + List> results = []; + foreach (Guid projectId in projectIds) + { + CultivateProject? project = cultivationDbService.GetCultivateProjectById(projectId); + ArgumentNullException.ThrowIfNull(project); + List entries = cultivationDbService.GetCultivateEntryListIncludingLevelInformationByProjectId(projectId); + + List innerResults = []; + foreach (ref readonly CultivateEntry innerEntry in CollectionsMarshal.AsSpan(entries)) + { + List items = cultivationDbService.GetCultivateItemListByEntryId(innerEntry.InnerId); + + HutaoReservedCultivationEntry innerResultEntry = new() + { + AvatarLevelFrom = innerEntry.LevelInformation?.AvatarLevelFrom ?? 0, + AvatarLevelTo = innerEntry.LevelInformation?.AvatarLevelTo ?? 0, + SkillALevelFrom = innerEntry.LevelInformation?.SkillALevelFrom ?? 0, + SkillALevelTo = innerEntry.LevelInformation?.SkillALevelTo ?? 0, + SkillELevelFrom = innerEntry.LevelInformation?.SkillELevelFrom ?? 0, + SkillELevelTo = innerEntry.LevelInformation?.SkillELevelTo ?? 0, + SkillQLevelFrom = innerEntry.LevelInformation?.SkillQLevelFrom ?? 0, + SkillQLevelTo = innerEntry.LevelInformation?.SkillQLevelTo ?? 0, + WeaponLevelFrom = innerEntry.LevelInformation?.WeaponLevelFrom ?? 0, + WeaponLevelTo = innerEntry.LevelInformation?.WeaponLevelTo ?? 0, + Type = innerEntry.Type, + Id = innerEntry.Id, + Items = items.SelectList(HutaoReservedCultivationItem.From), + }; + + innerResults.Add(innerResultEntry); + } + + HutaoReservedEntry outerEntry = new() + { + Identity = project.Name, + List = innerResults, + }; + + results.Add(outerEntry); + } + + hutaoReserved.Cultivation = results; + } + + private void ExportSpialAbysses(HutaoReserved hutaoReserved, List uids) + { + if (uids.Count <= 0) + { + return; + } + + ISpiralAbyssRecordDbService spiralAbyssRecordDbService = serviceProvider.GetRequiredService(); + + List> results = []; + foreach (string uid in uids) + { + Dictionary dbMap = spiralAbyssRecordDbService.GetSpiralAbyssEntryMapByUid(uid); + HutaoReservedEntry entry = new() + { + Identity = uid, + List = dbMap.Select(item => new HutaoReservedSpiralAbyssEntry + { + ScheduleId = item.Key, + SpiralAbyss = item.Value.SpiralAbyss, + }).ToList(), + }; + + results.Add(entry); + } + + hutaoReserved.SpiralAbyss = results; + } +} + +[ConstructorGenerated] +[Injection(InjectAs.Transient, typeof(IUIGFImportService), Key = UIGFVersion.UIGF40)] +internal sealed partial class UIGF40ImportService : IUIGFImportService +{ + public async ValueTask ImportAsync(UIGFImportOptions importOptions, CancellationToken token) + { + await Task.CompletedTask; + + return true; + } +} + +internal interface IUIGFImportService +{ + } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/UIGF/UIGFExportOptions.cs b/src/Snap.Hutao/Snap.Hutao/Service/UIGF/UIGFExportOptions.cs index 9429b0be..bfa5c19b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/UIGF/UIGFExportOptions.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/UIGF/UIGFExportOptions.cs @@ -5,17 +5,24 @@ namespace Snap.Hutao.Service.UIGF; internal sealed class UIGFExportOptions { - public string FilePath { get; set; } = default!; + public required string FilePath { get; set; } - public List GachaArchiveIds { get; set; } = []; + public required List GachaArchiveIds { get; set; } - public List ReservedAchievementArchiveIds { get; set; } = []; + public required List ReservedAchievementArchiveIds { get; set; } - public List ReservedAvatarInfoUids { get; set; } = []; + public required List ReservedAvatarInfoUids { get; set; } - public List ReservedCultivationProjectIds { get; set; } = []; + public required List ReservedCultivationProjectIds { get; set; } - public List ReservedSpiralAbyssUids { get; set; } = []; + public required List ReservedSpiralAbyssUids { get; set; } +} - public List ReservedUserIds { get; set; } = []; +internal sealed class UIGFImportOptions +{ + public Model.InterChange.UIGF UIGF { get; set; } = default!; + + public HashSet GachaArchiveUids { get; set; } = default!; + + public HashSet ReservedAchievementArchiveIdentities { get; set; } = default!; } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivateProjectDialog.xaml b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivateProjectDialog.xaml index c8dd1d74..fc25ce0d 100644 --- a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivateProjectDialog.xaml +++ b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivateProjectDialog.xaml @@ -17,10 +17,5 @@ VerticalAlignment="Top" PlaceholderText="{shuxm:ResourceString Name=ViewDialogCultivateProjectInputPlaceholder}" Text="{x:Bind Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> - diff --git a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivateProjectDialog.xaml.cs b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivateProjectDialog.xaml.cs index 5c35ad0f..ada860cb 100644 --- a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivateProjectDialog.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/CultivateProjectDialog.xaml.cs @@ -7,44 +7,25 @@ using Snap.Hutao.Service.User; namespace Snap.Hutao.UI.Xaml.View.Dialog; -/// -/// 养成计划对话框 -/// -[HighQuality] [DependencyProperty("Text", typeof(string))] [DependencyProperty("IsUidAttached", typeof(bool))] internal sealed partial class CultivateProjectDialog : ContentDialog { - private readonly IServiceProvider serviceProvider; private readonly ITaskContext taskContext; - /// - /// 构造一个新的养成计划对话框 - /// - /// 服务提供器 public CultivateProjectDialog(IServiceProvider serviceProvider) { InitializeComponent(); - this.serviceProvider = serviceProvider; taskContext = serviceProvider.GetRequiredService(); } - /// - /// 创建一个新的,用户指定的计划 - /// - /// 计划 public async ValueTask> CreateProjectAsync() { await taskContext.SwitchToMainThreadAsync(); - ContentDialogResult result = await ShowAsync(); - if (result == ContentDialogResult.Primary) + if (await ShowAsync() is ContentDialogResult.Primary) { - string? uid = IsUidAttached - ? await serviceProvider.GetRequiredService().GetCurrentUidAsync().ConfigureAwait(false) - : null; - - return new(true, CultivateProject.From(Text, uid)); + return new(true, CultivateProject.From(Text)); } return new(false, default!);