From ca10afa25a057837b8565e037950ddc11f4557dd Mon Sep 17 00:00:00 2001 From: Lightczx <1686188646@qq.com> Date: Mon, 15 May 2023 12:37:46 +0800 Subject: [PATCH] fully support UIGF v2.3 --- .../Snap.Hutao.Test/JsonSerializeTest.cs | 21 +++++++++++++ .../Snap.Hutao/Model/Entity/GachaItem.cs | 22 +++++++++++++- .../Model/InterChange/GachaLog/UIGF.cs | 26 ++++++++-------- .../Model/InterChange/GachaLog/UIGFVersion.cs | 25 ++++++++++++++++ .../Service/GachaLog/GachaLogService.cs | 10 +++---- .../Service/GachaLog/IGachaLogService.cs | 5 ++-- ...ExportService.cs => IUIGFExportService.cs} | 4 +-- ...ImportService.cs => IUIGFImportService.cs} | 7 ++--- ...gExportService.cs => UIGFExportService.cs} | 6 ++-- ...gImportService.cs => UIGFImportService.cs} | 30 ++++++++++++------- .../Snap.Hutao/Service/Game/ProcessInterop.cs | 2 +- .../ViewModel/GachaLog/GachaLogViewModel.cs | 20 +++++++++++-- .../Hk4e/Event/GachaInfo/GachaLogItem.cs | 4 +-- 13 files changed, 136 insertions(+), 46 deletions(-) create mode 100644 src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGFVersion.cs rename src/Snap.Hutao/Snap.Hutao/Service/GachaLog/{IGachaLogExportService.cs => IUIGFExportService.cs} (78%) rename src/Snap.Hutao/Snap.Hutao/Service/GachaLog/{IGachaLogImportService.cs => IUIGFImportService.cs} (65%) rename src/Snap.Hutao/Snap.Hutao/Service/GachaLog/{GachaLogExportService.cs => UIGFExportService.cs} (82%) rename src/Snap.Hutao/Snap.Hutao/Service/GachaLog/{GachaLogImportService.cs => UIGFImportService.cs} (53%) diff --git a/src/Snap.Hutao/Snap.Hutao.Test/JsonSerializeTest.cs b/src/Snap.Hutao/Snap.Hutao.Test/JsonSerializeTest.cs index d537f34e..40724e6b 100644 --- a/src/Snap.Hutao/Snap.Hutao.Test/JsonSerializeTest.cs +++ b/src/Snap.Hutao/Snap.Hutao.Test/JsonSerializeTest.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using System.Text.Json.Serialization; namespace Snap.Hutao.Test; @@ -11,6 +12,12 @@ public class JsonSerializeTest } """; + private const string SmapleNumberObjectJson = """ + { + "A" : "" + } + """; + [TestMethod] public void DelegatePropertyCanSerialize() { @@ -18,9 +25,23 @@ public class JsonSerializeTest Assert.AreEqual(sample.B, 1); } + [TestMethod] + public void EmptyStringCanSerializeAsNumber() + { + // Throw + StringNumberSample sample = JsonSerializer.Deserialize(SmapleNumberObjectJson)!; + Assert.AreEqual(sample.A, 0); + } + private class Sample { public int A { get => B; set => B = value; } public int B { get; set; } } + + private class StringNumberSample + { + [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] + public int A { get; set; } + } } \ 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 f2bf6eda..4661d460 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/GachaItem.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/GachaItem.cs @@ -103,7 +103,7 @@ internal sealed class GachaItem /// 祈愿物品 /// 物品Id /// 新的祈愿物品 - public static GachaItem Create(in Guid archiveId, UIGFItem item, int itemId) + public static GachaItem CreateForMajor2Minor2OrLower(in Guid archiveId, UIGFItem item, int itemId) { return new() { @@ -116,6 +116,25 @@ internal sealed class GachaItem }; } + /// + /// 构造一个新的数据库祈愿物品 + /// + /// 存档Id + /// 祈愿物品 + /// 新的祈愿物品 + public static GachaItem CreateForMajor2Minor3OrHigher(in Guid archiveId, UIGFItem item) + { + return new() + { + ArchiveId = archiveId, + GachaType = item.GachaType, + QueryType = item.UIGFGachaType, + ItemId = int.Parse(item.ItemId), + Time = item.Time, + Id = item.Id, + }; + } + /// /// 构造一个新的数据库祈愿物品 /// @@ -159,6 +178,7 @@ internal sealed class GachaItem return new() { GachaType = GachaType, + ItemId = $"{ItemId}", Count = 1, Time = Time, Name = nameQuality.Name, diff --git a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGF.cs b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGF.cs index 466309d6..88379526 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGF.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGF.cs @@ -1,8 +1,6 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. -using System.Collections.Immutable; - namespace Snap.Hutao.Model.InterChange.GachaLog; /// @@ -13,14 +11,9 @@ namespace Snap.Hutao.Model.InterChange.GachaLog; internal sealed class UIGF { /// - /// 当前发行的版本 + /// 当前版本 /// - public const string CurrentVersion = "v2.2"; - - private static readonly ImmutableList SupportedVersion = new List() - { - "v2.1", CurrentVersion, - }.ToImmutableList(); + public const string CurrentVersion = "v2.3"; /// /// 信息 @@ -37,17 +30,26 @@ internal sealed class UIGF /// /// 确认当前UIGF对象的版本是否受支持 /// + /// 版本 /// 当前UIAF对象是否受支持 - public bool IsCurrentVersionSupported() + public bool IsCurrentVersionSupported(out UIGFVersion version) { - return SupportedVersion.Contains(Info?.UIGFVersion ?? string.Empty); + version = Info.UIGFVersion switch + { + "v2.1" => UIGFVersion.Major2Minor2OrLower, + "v2.2" => UIGFVersion.Major2Minor2OrLower, + "v2.3" => UIGFVersion.Major2Minor3OrHigher, + _ => UIGFVersion.NotSupported, + }; + + return version != UIGFVersion.NotSupported; } /// /// 列表物品是否正常 /// /// 是否正常 - public bool IsValidList() + public bool IsMajor2Minor2OrLowerListValid() { foreach (UIGFItem item in List) { diff --git a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGFVersion.cs b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGFVersion.cs new file mode 100644 index 00000000..c229ab8f --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGFVersion.cs @@ -0,0 +1,25 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Model.InterChange.GachaLog; + +/// +/// UIGF版本 +/// +internal enum UIGFVersion +{ + /// + /// 不支持的版本 + /// + NotSupported, + + /// + /// v2.2以及之前的版本 + /// + Major2Minor2OrLower, + + /// + /// v2.3以及之后的版本 + /// + Major2Minor3OrHigher, +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs index c56ffcf1..e79abc52 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs @@ -28,8 +28,8 @@ internal sealed partial class GachaLogService : IGachaLogService private readonly ScopedDbCurrent dbCurrent; private readonly IGachaStatisticsSlimFactory gachaStatisticsSlimFactory; private readonly IGachaStatisticsFactory gachaStatisticsFactory; - private readonly IGachaLogExportService gachaLogExportService; - private readonly IGachaLogImportService gachaLogImportService; + private readonly IUIGFExportService gachaLogExportService; + private readonly IUIGFImportService gachaLogImportService; private readonly IServiceProvider serviceProvider; private readonly IMetadataService metadataService; private readonly ILogger logger; @@ -134,13 +134,13 @@ internal sealed partial class GachaLogService : IGachaLogService /// public Task ExportToUIGFAsync(GachaArchive archive) { - return gachaLogExportService.ExportToUIGFAsync(context, archive); + return gachaLogExportService.ExportAsync(context, archive); } /// - public async Task ImportFromUIGFAsync(List list, string uid) + public async Task ImportFromUIGFAsync(UIGF uigf) { - CurrentArchive = await gachaLogImportService.ImportFromUIGFAsync(context, list, uid).ConfigureAwait(false); + CurrentArchive = await gachaLogImportService.ImportAsync(context, uigf).ConfigureAwait(false); } /// diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogService.cs index 8fd2ec20..23b6961d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogService.cs @@ -48,10 +48,9 @@ internal interface IGachaLogService /// /// 异步从UIGF导入数据 /// - /// 列表 - /// Uid + /// 信息 /// 任务 - Task ImportFromUIGFAsync(List list, string uid); + Task ImportFromUIGFAsync(UIGF uigf); /// /// 异步初始化 diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogExportService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IUIGFExportService.cs similarity index 78% rename from src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogExportService.cs rename to src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IUIGFExportService.cs index 6d22f7f0..702a17fa 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogExportService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IUIGFExportService.cs @@ -9,7 +9,7 @@ namespace Snap.Hutao.Service.GachaLog; /// /// 祈愿记录导出服务 /// -internal interface IGachaLogExportService +internal interface IUIGFExportService { /// /// 异步导出存档到 UIGF @@ -17,5 +17,5 @@ internal interface IGachaLogExportService /// 元数据上下文 /// 存档 /// UIGF - Task ExportToUIGFAsync(GachaLogServiceContext context, GachaArchive archive); + Task ExportAsync(GachaLogServiceContext context, GachaArchive archive); } diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogImportService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IUIGFImportService.cs similarity index 65% rename from src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogImportService.cs rename to src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IUIGFImportService.cs index a97f65da..feab2181 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IGachaLogImportService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/IUIGFImportService.cs @@ -9,14 +9,13 @@ namespace Snap.Hutao.Service.GachaLog; /// /// 祈愿记录导入服务 /// -internal interface IGachaLogImportService +internal interface IUIGFImportService { /// /// 异步从 UIGF 导入 /// /// 祈愿记录服务上下文 - /// 列表 - /// uid + /// 数据 /// 存档 - Task ImportFromUIGFAsync(GachaLogServiceContext context, List list, string uid); + Task ImportAsync(GachaLogServiceContext context, UIGF uigf); } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogExportService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UIGFExportService.cs similarity index 82% rename from src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogExportService.cs rename to src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UIGFExportService.cs index a7260186..0f026b3e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogExportService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UIGFExportService.cs @@ -11,14 +11,14 @@ namespace Snap.Hutao.Service.GachaLog; /// 祈愿记录导出服务 /// [ConstructorGenerated] -[Injection(InjectAs.Scoped, typeof(IGachaLogExportService))] -internal sealed partial class GachaLogExportService : IGachaLogExportService +[Injection(InjectAs.Scoped, typeof(IUIGFExportService))] +internal sealed partial class UIGFExportService : IUIGFExportService { private readonly IServiceProvider serviceProvider; private readonly ITaskContext taskContext; /// - public async Task ExportToUIGFAsync(GachaLogServiceContext context, GachaArchive archive) + public async Task ExportAsync(GachaLogServiceContext context, GachaArchive archive) { await taskContext.SwitchToBackgroundAsync(); using (IServiceScope scope = serviceProvider.CreateScope()) diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogImportService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UIGFImportService.cs similarity index 53% rename from src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogImportService.cs rename to src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UIGFImportService.cs index a126570b..d607892f 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogImportService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UIGFImportService.cs @@ -9,25 +9,25 @@ using Snap.Hutao.Model.InterChange.GachaLog; namespace Snap.Hutao.Service.GachaLog; /// -/// 祈愿记录导入服务 +/// v2.1 v2.2 祈愿记录导入服务 /// [ConstructorGenerated] -[Injection(InjectAs.Scoped, typeof(IGachaLogImportService))] -internal sealed partial class GachaLogImportService : IGachaLogImportService +[Injection(InjectAs.Scoped, typeof(IUIGFImportService))] +internal sealed partial class UIGFImportService : IUIGFImportService { - private readonly ILogger logger; + private readonly ILogger logger; private readonly IServiceProvider serviceProvider; private readonly ITaskContext taskContext; /// - public async Task ImportFromUIGFAsync(GachaLogServiceContext context, List list, string uid) + public async Task ImportAsync(GachaLogServiceContext context, UIGF uigf) { await taskContext.SwitchToBackgroundAsync(); using (IServiceScope scope = serviceProvider.CreateScope()) { AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService(); - GachaArchiveInitializationContext initContext = new(taskContext, uid, appDbContext.GachaArchives, context.ArchiveCollection); + GachaArchiveInitializationContext initContext = new(taskContext, uigf.Info.Uid, appDbContext.GachaArchives, context.ArchiveCollection); GachaArchive.Init(initContext, out GachaArchive? archive); Guid archiveId = archive.InnerId; @@ -38,10 +38,20 @@ internal sealed partial class GachaLogImportService : IGachaLogImportService logger.LogInformation("Last Id to trim with: [{id}]", trimId); - IEnumerable toAdd = list - .OrderByDescending(i => i.Id) - .Where(i => i.Id < trimId) - .Select(i => GachaItem.Create(archiveId, i, context.GetItemId(i))); + _ = uigf.IsCurrentVersionSupported(out UIGFVersion version); + + IEnumerable toAdd = version switch + { + UIGFVersion.Major2Minor3OrHigher => uigf.List + .OrderByDescending(i => i.Id) + .Where(i => i.Id < trimId) + .Select(i => GachaItem.CreateForMajor2Minor3OrHigher(archiveId, i)), + UIGFVersion.Major2Minor2OrLower => uigf.List + .OrderByDescending(i => i.Id) + .Where(i => i.Id < trimId) + .Select(i => GachaItem.CreateForMajor2Minor2OrLower(archiveId, i, context.GetItemId(i))), + _ => Enumerable.Empty(), + }; await appDbContext.GachaItems.AddRangeAndSaveAsync(toAdd).ConfigureAwait(false); return archive; diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/ProcessInterop.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/ProcessInterop.cs index e5c3838d..9c4ba836 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Game/ProcessInterop.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/ProcessInterop.cs @@ -100,7 +100,7 @@ internal static class ProcessInterop HINSTANCE hKernelDll = GetModuleHandle("kernel32.dll"); Marshal.ThrowExceptionForHR(Marshal.GetLastPInvokeError()); - FARPROC pLoadLibraryA = GetProcAddress(hKernelDll, libraryPathu8); + FARPROC pLoadLibraryA = GetProcAddress(hKernelDll, "LoadLibraryA"u8); Marshal.ThrowExceptionForHR(Marshal.GetLastPInvokeError()); void* pNativeLibraryPath = default; diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaLogViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaLogViewModel.cs index 14d23e1c..8860c25c 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaLogViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLog/GachaLogViewModel.cs @@ -104,6 +104,20 @@ internal sealed partial class GachaLogViewModel : Abstraction.ViewModel } } + private static bool CanImport(UIGFVersion version, UIGF uigf) + { + if (version == UIGFVersion.Major2Minor3OrHigher) + { + return true; + } + else if (version == UIGFVersion.Major2Minor2OrLower && uigf.IsMajor2Minor2OrLowerListValid()) + { + return true; + } + + return false; + } + [Command("RefreshByWebCacheCommand")] private Task RefreshByWebCacheAsync() { @@ -331,19 +345,19 @@ internal sealed partial class GachaLogViewModel : Abstraction.ViewModel private async Task TryImportUIGFInternalAsync(UIGF uigf) { - if (uigf.IsCurrentVersionSupported()) + if (uigf.IsCurrentVersionSupported(out UIGFVersion version)) { // ContentDialog must be created by main thread. await taskContext.SwitchToMainThreadAsync(); GachaLogImportDialog importDialog = serviceProvider.CreateInstance(uigf); if (await importDialog.GetShouldImportAsync().ConfigureAwait(true)) { - if (uigf.IsValidList()) + if (CanImport(version, uigf)) { ContentDialog dialog = await contentDialogFactory.CreateForIndeterminateProgressAsync(SH.ViewModelGachaLogImportProgress).ConfigureAwait(true); using (await dialog.BlockAsync(taskContext).ConfigureAwait(false)) { - await gachaLogService.ImportFromUIGFAsync(uigf.List, uigf.Info.Uid).ConfigureAwait(false); + await gachaLogService.ImportFromUIGFAsync(uigf).ConfigureAwait(false); } infoBarService.Success(SH.ViewModelGachaLogImportComplete); 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 028cd8d7..85145295 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 @@ -27,10 +27,10 @@ internal class GachaLogItem /// /// 总为 + /// v2.3 使用了此值 /// - [Obsolete("API set this property empty")] [JsonPropertyName("item_id")] - public string ItemId { get; set; } = string.Empty; + public string ItemId { get; set; } = default!; /// /// 个数 一般为 1