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