From c245fe654e451cf8d0b2e105c2a4c9b0e950239c Mon Sep 17 00:00:00 2001 From: DismissedLight <1686188646@qq.com> Date: Tue, 7 Feb 2023 16:57:53 +0800 Subject: [PATCH] add gacha import validation --- src/Snap.Hutao/Snap.Hutao/App.xaml | 3 +- src/Snap.Hutao/Snap.Hutao/App.xaml.cs | 4 +- .../Snap.Hutao/Core/IO/Bits/BitsJob.cs | 2 +- .../Model/InterChange/GachaLog/UIGF.cs | 17 ++++++++ .../Resource/Localization/SH.Designer.cs | 18 +++++++++ .../Snap.Hutao/Resource/Localization/SH.resx | 6 +++ .../Factory/GachaStatisticsFactory.cs | 3 +- .../Service/GachaLog/GachaLogService.cs | 2 + .../Snap.Hutao/ViewModel/GachaLogViewModel.cs | 40 +++++++++++++------ 9 files changed, 77 insertions(+), 18 deletions(-) diff --git a/src/Snap.Hutao/Snap.Hutao/App.xaml b/src/Snap.Hutao/Snap.Hutao/App.xaml index ae61c20a..abfbb9ab 100644 --- a/src/Snap.Hutao/Snap.Hutao/App.xaml +++ b/src/Snap.Hutao/Snap.Hutao/App.xaml @@ -427,7 +427,6 @@ - @@ -443,4 +442,4 @@ - + \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/App.xaml.cs b/src/Snap.Hutao/Snap.Hutao/App.xaml.cs index a1a88d06..4f7fbe6e 100644 --- a/src/Snap.Hutao/Snap.Hutao/App.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/App.xaml.cs @@ -49,8 +49,8 @@ public partial class App : Application firstInstance.Activated += Activation.Activate; ToastNotificationManagerCompat.OnActivated += Activation.NotificationActivate; - logger.LogInformation(EventIds.CommonLog, "Snap Hutao | {name} : {version}", CoreEnvironment.FamilyName, CoreEnvironment.Version); - logger.LogInformation(EventIds.CommonLog, "Cache folder : {folder}", ApplicationData.Current.LocalCacheFolder.Path); + logger.LogInformation("Snap Hutao | {name} : {version}", CoreEnvironment.FamilyName, CoreEnvironment.Version); + logger.LogInformation("Cache folder : {folder}", ApplicationData.Current.LocalCacheFolder.Path); JumpListHelper.ConfigureAsync().SafeForget(logger); } diff --git a/src/Snap.Hutao/Snap.Hutao/Core/IO/Bits/BitsJob.cs b/src/Snap.Hutao/Snap.Hutao/Core/IO/Bits/BitsJob.cs index df436b5d..6c12019b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/IO/Bits/BitsJob.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/IO/Bits/BitsJob.cs @@ -22,7 +22,7 @@ internal class BitsJob : DisposableObject, IBackgroundCopyCallback /// public const string JobNamePrefix = "SnapHutaoBitsJob"; - private const uint BitsEngineNoProgressTimeout = 120; + private const uint BitsEngineNoProgressTimeout = 30; private const int MaxResumeAttempts = 10; private readonly string displayName; 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 25b19967..9c58a3ec 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGF.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/InterChange/GachaLog/UIGF.cs @@ -41,4 +41,21 @@ public class UIGF { return SupportedVersion.Contains(Info?.UIGFVersion ?? string.Empty); } + + /// + /// 列表物品是否正常 + /// + /// 是否正常 + public bool IsValidList() + { + foreach (UIGFItem item in List) + { + if (item.ItemType != "角色" || item.ItemType != "武器") + { + return false; + } + } + + return true; + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.Designer.cs b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.Designer.cs index 1512b802..3c6b5c0d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.Designer.cs +++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.Designer.cs @@ -600,6 +600,15 @@ namespace Snap.Hutao.Resource.Localization { } } + /// + /// 查找类似 不支持的 Item Id: {0} 的本地化字符串。 + /// + internal static string ServiceGachaStatisticsFactoryItemIdInvalid { + get { + return ResourceManager.GetString("ServiceGachaStatisticsFactoryItemIdInvalid", resourceCulture); + } + } + /// /// 查找类似 存在多个匹配账号,请删除重复的账号 的本地化字符串。 /// @@ -1617,6 +1626,15 @@ namespace Snap.Hutao.Resource.Localization { } } + /// + /// 查找类似 导入数据中包含了不支持的物品 的本地化字符串。 + /// + internal static string ViewModelGachaLogImportWarningMessage2 { + get { + return ResourceManager.GetString("ViewModelGachaLogImportWarningMessage2", resourceCulture); + } + } + /// /// 查找类似 导入失败 的本地化字符串。 /// diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx index 01c97771..4446d5fc 100644 --- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx +++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx @@ -297,6 +297,9 @@ 提供的 Url 无效 + + 不支持的 Item Id: {0} + 存在多个匹配账号,请删除重复的账号 @@ -636,6 +639,9 @@ 数据的 UIGF 版本过低,无法导入 + + 导入数据中包含了不支持的物品 + 导入失败 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 71d60414..e14728aa 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. using Snap.Hutao.Core.Database; +using Snap.Hutao.Core.ExceptionService; using Snap.Hutao.Extension; using Snap.Hutao.Model.Binding.Gacha; using Snap.Hutao.Model.Entity; @@ -137,7 +138,7 @@ internal class GachaStatisticsFactory : IGachaStatisticsFactory { // ItemId place not correct. // TODO: check items id when importing - Must.NeverHappen(); + ThrowHelper.UserdataCorrupted(string.Format(SH.ServiceGachaStatisticsFactoryItemIdInvalid, item.ItemId), null!); } } diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs index 6d566111..7d3f62d4 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs @@ -16,6 +16,7 @@ using Snap.Hutao.Model.Entity.Database; using Snap.Hutao.Model.InterChange.GachaLog; using Snap.Hutao.Model.Metadata.Abstraction; using Snap.Hutao.Model.Primitive; +using Snap.Hutao.Service.Abstraction; using Snap.Hutao.Service.GachaLog.Factory; using Snap.Hutao.Service.GachaLog.QueryProvider; using Snap.Hutao.Service.Metadata; @@ -163,6 +164,7 @@ internal class GachaLogService : IGachaLogService .Where(i => i.ArchiveId == archive.InnerId); GachaStatistics statistics = await gachaStatisticsFactory.CreateAsync(items).ConfigureAwait(false); + logger.LogInformation(EventIds.GachaStatisticGeneration, "GachaStatistic Generation toke {time} ms.", stopwatch.GetElapsedTime().TotalMilliseconds); return statistics; } diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLogViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLogViewModel.cs index bb3a3e85..34e0f867 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLogViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLogViewModel.cs @@ -4,6 +4,7 @@ using CommunityToolkit.Mvvm.Input; using Microsoft.UI.Xaml.Controls; using Snap.Hutao.Control.Extension; +using Snap.Hutao.Core.ExceptionService; using Snap.Hutao.Core.IO; using Snap.Hutao.Extension; using Snap.Hutao.Factory.Abstraction; @@ -343,10 +344,18 @@ internal class GachaLogViewModel : Abstraction.ViewModel private async Task UpdateStatisticsAsync(GachaArchive? archive) { - GachaStatistics temp = await gachaLogService.GetStatisticsAsync(archive).ConfigureAwait(false); - await ThreadHelper.SwitchToMainThreadAsync(); - Statistics = temp; - IsInitialized = true; + try + { + GachaStatistics? temp = await gachaLogService.GetStatisticsAsync(archive).ConfigureAwait(false); + + await ThreadHelper.SwitchToMainThreadAsync(); + Statistics = temp; + IsInitialized = true; + } + catch (UserdataCorruptedException ex) + { + Ioc.Default.GetRequiredService().Error(ex); + } } private async Task TryImportUIGFInternalAsync(UIGF uigf) @@ -357,16 +366,23 @@ internal class GachaLogViewModel : Abstraction.ViewModel await ThreadHelper.SwitchToMainThreadAsync(); if (await new GachaLogImportDialog(uigf).GetShouldImportAsync().ConfigureAwait(true)) { - ContentDialog dialog = await contentDialogFactory.CreateForIndeterminateProgressAsync(SH.ViewModelGachaLogImportProgress).ConfigureAwait(true); - await using (await dialog.BlockAsync().ConfigureAwait(false)) + if (uigf.IsValidList()) { - await gachaLogService.ImportFromUIGFAsync(uigf.List, uigf.Info.Uid).ConfigureAwait(false); - } + ContentDialog dialog = await contentDialogFactory.CreateForIndeterminateProgressAsync(SH.ViewModelGachaLogImportProgress).ConfigureAwait(true); + await using (await dialog.BlockAsync().ConfigureAwait(false)) + { + await gachaLogService.ImportFromUIGFAsync(uigf.List, uigf.Info.Uid).ConfigureAwait(false); + } - infoBarService.Success(SH.ViewModelGachaLogImportComplete); - await ThreadHelper.SwitchToMainThreadAsync(); - SetSelectedArchiveAndUpdateStatistics(gachaLogService.CurrentArchive, true); - return true; + infoBarService.Success(SH.ViewModelGachaLogImportComplete); + await ThreadHelper.SwitchToMainThreadAsync(); + SetSelectedArchiveAndUpdateStatistics(gachaLogService.CurrentArchive, true); + return true; + } + else + { + infoBarService.Warning(SH.ViewModelGachaLogImportWarningTitle, SH.ViewModelGachaLogImportWarningMessage2); + } } } else