From d7dd8c6f0dbe43cfb800ab06981e18a01061bc52 Mon Sep 17 00:00:00 2001
From: DismissedLight <1686188646@qq.com>
Date: Fri, 10 Feb 2023 16:07:01 +0800
Subject: [PATCH] code style
---
src/Snap.Hutao/Snap.Hutao/App.xaml.cs | 1 -
.../Extension/ContentDialogExtension.cs | 1 +
.../Control/Image/CompositionImage.cs | 1 -
.../Annotation/LocalizationKeyAttribute.cs | 8 +--
src/Snap.Hutao/Snap.Hutao/Core/IO/TempFile.cs | 10 ++-
.../Snap.Hutao/Core/LifeCycle/Activation.cs | 2 +-
.../Core/Windowing/ExtendedWindow.cs | 1 -
.../Model/Entity/SpiralAbyssEntry.cs | 2 +-
.../Resource/Localization/SH.Designer.cs | 45 +++++++++++++
.../Snap.Hutao/Resource/Localization/SH.resx | 15 +++++
.../Service/Achievement/AchievementService.cs | 1 -
.../Service/Cultivation/CultivationService.cs | 26 +++++++-
.../Cultivation/ICultivationService.cs | 1 -
.../Service/DailyNote/DailyNoteNotifier.cs | 1 -
.../Service/GachaLog/GachaLogService.cs | 5 +-
.../GachaLogQueryWebCacheProvider.cs | 2 +-
.../Snap.Hutao/Service/Game/GameService.cs | 5 +-
.../Game/Package/PackageConvertException.cs | 9 ---
.../Service/Metadata/MetadataService.cs | 16 +++--
.../Service/Navigation/NavigationService.cs | 1 -
.../SpiralAbyss/SpiralAbyssRecordService.cs | 57 +++++-----------
.../Snap.Hutao/Service/User/UserService.cs | 2 +-
.../Control/AnnouncementContentViewer.xaml.cs | 6 +-
.../View/Control/StatisticsCard.xaml.cs | 4 +-
.../GachaLogRefreshProgressDialog.xaml.cs | 1 -
.../LaunchGamePackageConvertDialog.xaml.cs | 4 +-
.../View/Page/LoginMihoyoUserPage.xaml.cs | 23 ++++---
.../Snap.Hutao/View/Page/SettingPage.xaml.cs | 2 -
.../View/Page/SpiralAbyssRecordPage.xaml | 2 +-
.../View/Page/WikiAvatarPage.xaml.cs | 2 -
.../ViewModel/Abstraction/ViewModel.cs | 2 +-
.../Achievement/AchievementViewModel.cs | 2 -
.../ViewModel/AvatarPropertyViewModel.cs | 65 +++++++++----------
.../ViewModel/DailyNoteViewModel.cs | 28 ++++----
.../ExperimentalFeaturesViewModel.cs | 11 +++-
.../Snap.Hutao/ViewModel/GachaLogViewModel.cs | 22 +++----
.../ViewModel/HutaoDatabaseViewModel.cs | 6 --
.../ViewModel/LaunchGameViewModel.cs | 39 +++++------
.../Snap.Hutao/ViewModel/SettingViewModel.cs | 37 +++++------
.../ViewModel/SpiralAbyssRecordViewModel.cs | 38 +++++------
.../Snap.Hutao/ViewModel/TestViewModel.cs | 16 +++--
.../Snap.Hutao/ViewModel/UserViewModel.cs | 12 ++--
.../Snap.Hutao/ViewModel/WelcomeViewModel.cs | 17 +++--
.../ViewModel/WikiAvatarViewModel.cs | 44 ++++++++-----
.../ViewModel/WikiWeaponViewModel.cs | 43 +++++++-----
.../DynamicSecret/DynamicSecretHandler.cs | 1 -
.../Snap.Hutao/Web/HttpClientExtensions.cs | 1 -
47 files changed, 353 insertions(+), 287 deletions(-)
diff --git a/src/Snap.Hutao/Snap.Hutao/App.xaml.cs b/src/Snap.Hutao/Snap.Hutao/App.xaml.cs
index 4f7fbe6e..e5a020ae 100644
--- a/src/Snap.Hutao/Snap.Hutao/App.xaml.cs
+++ b/src/Snap.Hutao/Snap.Hutao/App.xaml.cs
@@ -7,7 +7,6 @@ using Microsoft.Windows.AppLifecycle;
using Snap.Hutao.Core;
using Snap.Hutao.Core.ExceptionService;
using Snap.Hutao.Core.LifeCycle;
-using Snap.Hutao.Core.Logging;
using System.Diagnostics;
using Windows.Storage;
diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Extension/ContentDialogExtension.cs b/src/Snap.Hutao/Snap.Hutao/Control/Extension/ContentDialogExtension.cs
index 5eaab145..3bac06ef 100644
--- a/src/Snap.Hutao/Snap.Hutao/Control/Extension/ContentDialogExtension.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Control/Extension/ContentDialogExtension.cs
@@ -21,6 +21,7 @@ internal static class ContentDialogExtension
contentDialog.ShowAsync().AsTask().SafeForget();
// E_ASYNC_OPERATION_NOT_STARTED 0x80000019
+ // Only a single ContentDialog can be open at any time.
return new ContentDialogHider(contentDialog);
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Image/CompositionImage.cs b/src/Snap.Hutao/Snap.Hutao/Control/Image/CompositionImage.cs
index 1e5cf33f..813be0f3 100644
--- a/src/Snap.Hutao/Snap.Hutao/Control/Image/CompositionImage.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Control/Image/CompositionImage.cs
@@ -12,7 +12,6 @@ using Snap.Hutao.Extension;
using Snap.Hutao.Service.Abstraction;
using System.IO;
using System.Net.Http;
-using System.Reflection;
using System.Runtime.InteropServices;
namespace Snap.Hutao.Control.Image;
diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Annotation/LocalizationKeyAttribute.cs b/src/Snap.Hutao/Snap.Hutao/Core/Annotation/LocalizationKeyAttribute.cs
index d43b7f82..1fb583f7 100644
--- a/src/Snap.Hutao/Snap.Hutao/Core/Annotation/LocalizationKeyAttribute.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Core/Annotation/LocalizationKeyAttribute.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Snap.Hutao.Core.Annotation;
+namespace Snap.Hutao.Core.Annotation;
///
/// 本地化键
diff --git a/src/Snap.Hutao/Snap.Hutao/Core/IO/TempFile.cs b/src/Snap.Hutao/Snap.Hutao/Core/IO/TempFile.cs
index 0d32b5e3..cd3774a2 100644
--- a/src/Snap.Hutao/Snap.Hutao/Core/IO/TempFile.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Core/IO/TempFile.cs
@@ -1,6 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Core.ExceptionService;
using System.IO;
namespace Snap.Hutao.Core.IO;
@@ -16,7 +17,14 @@ internal sealed class TempFile : IDisposable
/// 是否在创建时删除文件
public TempFile(bool delete = false)
{
- Path = System.IO.Path.GetTempFileName();
+ try
+ {
+ Path = System.IO.Path.GetTempFileName();
+ }
+ catch (UnauthorizedAccessException ex)
+ {
+ throw ThrowHelper.RuntimeEnvironment(SH.CoreIOTempFileCreateFail, ex);
+ }
if (delete)
{
diff --git a/src/Snap.Hutao/Snap.Hutao/Core/LifeCycle/Activation.cs b/src/Snap.Hutao/Snap.Hutao/Core/LifeCycle/Activation.cs
index 7245cfb2..172de3c2 100644
--- a/src/Snap.Hutao/Snap.Hutao/Core/LifeCycle/Activation.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Core/LifeCycle/Activation.cs
@@ -109,7 +109,7 @@ internal static class Activation
private static async Task HandleActivationCoreAsync(AppActivationArguments args, bool isRedirected)
{
- if (args.Kind == ExtendedActivationKind.Protocol)
+ if (args.Kind == ExtendedActivationKind.Protocol)
{
if (args.TryGetProtocolActivatedUri(out Uri? uri))
{
diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Windowing/ExtendedWindow.cs b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/ExtendedWindow.cs
index 92cfb10f..957ae450 100644
--- a/src/Snap.Hutao/Snap.Hutao/Core/Windowing/ExtendedWindow.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Core/Windowing/ExtendedWindow.cs
@@ -10,7 +10,6 @@ using Snap.Hutao.Extension;
using Snap.Hutao.Message;
using Snap.Hutao.Win32;
using System.IO;
-using Windows.ApplicationModel;
using Windows.Graphics;
using Windows.UI;
using Windows.Win32.Foundation;
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/SpiralAbyssEntry.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/SpiralAbyssEntry.cs
index 7d02971d..fb850071 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/SpiralAbyssEntry.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/SpiralAbyssEntry.cs
@@ -29,7 +29,7 @@ public class SpiralAbyssEntry : ObservableObject
/// 计划名称
///
[NotMapped]
- public string Schedule { get => $"第 {ScheduleId} 期"; }
+ public string Schedule { get => string.Format(SH.ModelEntitySpiralAbyssScheduleFormat, ScheduleId); }
///
/// Uid
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 d5f169ac..ce4382f5 100644
--- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.Designer.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.Designer.cs
@@ -195,6 +195,15 @@ namespace Snap.Hutao.Resource.Localization {
}
}
+ ///
+ /// 查找类似 权限不足,创建临时文件失败 的本地化字符串。
+ ///
+ internal static string CoreIOTempFileCreateFail {
+ get {
+ return ResourceManager.GetString("CoreIOTempFileCreateFail", resourceCulture);
+ }
+ }
+
///
/// 查找类似 启动游戏 的本地化字符串。
///
@@ -339,6 +348,15 @@ namespace Snap.Hutao.Resource.Localization {
}
}
+ ///
+ /// 查找类似 第 {0} 期 的本地化字符串。
+ ///
+ internal static string ModelEntitySpiralAbyssScheduleFormat {
+ get {
+ return ResourceManager.GetString("ModelEntitySpiralAbyssScheduleFormat", resourceCulture);
+ }
+ }
+
///
/// 查找类似 必须先选择一个用户与角色 的本地化字符串。
///
@@ -357,6 +375,24 @@ namespace Snap.Hutao.Resource.Localization {
}
}
+ ///
+ /// 查找类似 保存养成计划状态失败 的本地化字符串。
+ ///
+ internal static string ServiceCultivationProjectCurrentUserdataCourrpted {
+ get {
+ return ResourceManager.GetString("ServiceCultivationProjectCurrentUserdataCourrpted", resourceCulture);
+ }
+ }
+
+ ///
+ /// 查找类似 存在多个选中的养成计划 的本地化字符串。
+ ///
+ internal static string ServiceCultivationProjectCurrentUserdataCourrpted2 {
+ get {
+ return ResourceManager.GetString("ServiceCultivationProjectCurrentUserdataCourrpted2", resourceCulture);
+ }
+ }
+
///
/// 查找类似 开始游戏 的本地化字符串。
///
@@ -1437,6 +1473,15 @@ namespace Snap.Hutao.Resource.Localization {
}
}
+ ///
+ /// 查找类似 养成计划添加失败 的本地化字符串。
+ ///
+ internal static string ViewModelCultivationAddWarning {
+ get {
+ return ResourceManager.GetString("ViewModelCultivationAddWarning", resourceCulture);
+ }
+ }
+
///
/// 查找类似 已成功添加至当前养成计划 的本地化字符串。
///
diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx
index 958603bd..c7e329b2 100644
--- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx
+++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx
@@ -162,6 +162,9 @@
无法打开文件选择器
+
+ 权限不足,创建临时文件失败
+
启动游戏
@@ -210,12 +213,21 @@
{0} 抽
+
+ 第 {0} 期
+
必须先选择一个用户与角色
单个成就存档内发现多个相同的成就 Id
+
+ 保存养成计划状态失败
+
+
+ 存在多个选中的养成计划
+
开始游戏
@@ -576,6 +588,9 @@
角色展柜尚未开启,请前往游戏操作后重试
+
+ 养成计划添加失败
+
已成功添加至当前养成计划
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementService.cs
index 95b359bd..2e59358b 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementService.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementService.cs
@@ -6,7 +6,6 @@ using Microsoft.EntityFrameworkCore;
using Snap.Hutao.Core.Database;
using Snap.Hutao.Core.Diagnostics;
using Snap.Hutao.Core.ExceptionService;
-using Snap.Hutao.Core.Logging;
using Snap.Hutao.Extension;
using Snap.Hutao.Model.Entity.Database;
using Snap.Hutao.Model.InterChange.Achievement;
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs
index 0601f9e8..fd1e78f4 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs
@@ -5,6 +5,7 @@ using CommunityToolkit.Mvvm.Messaging;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Snap.Hutao.Core.Database;
+using Snap.Hutao.Core.ExceptionService;
using Snap.Hutao.Extension;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.Entity.Database;
@@ -55,10 +56,21 @@ internal class CultivationService : ICultivationService
using (IServiceScope scope = scopeFactory.CreateScope())
{
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService();
- projects = new(appDbContext.CultivateProjects.AsNoTracking().ToList());
+ projects = appDbContext.CultivateProjects.AsNoTracking().ToObservableCollection();
}
- Current ??= projects.SingleOrDefault(proj => proj.IsSelected);
+ try
+ {
+ Current ??= projects.SingleOrDefault(proj => proj.IsSelected);
+ }
+ catch (DbUpdateConcurrencyException ex)
+ {
+ ThrowHelper.UserdataCorrupted(SH.ServiceCultivationProjectCurrentUserdataCourrpted, ex);
+ }
+ catch (InvalidOperationException ex)
+ {
+ ThrowHelper.UserdataCorrupted(SH.ServiceCultivationProjectCurrentUserdataCourrpted2, ex);
+ }
}
return projects;
@@ -277,7 +289,15 @@ internal class CultivationService : ICultivationService
{
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService();
- Current ??= appDbContext.CultivateProjects.AsNoTracking().SingleOrDefault(proj => proj.IsSelected);
+ try
+ {
+ Current ??= appDbContext.CultivateProjects.AsNoTracking().SingleOrDefault(proj => proj.IsSelected);
+ }
+ catch (InvalidOperationException ex)
+ {
+ ThrowHelper.UserdataCorrupted(SH.ServiceCultivationProjectCurrentUserdataCourrpted2, ex);
+ }
+
if (Current == null)
{
return false;
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationService.cs
index 5fb5fc86..429f80b7 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationService.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationService.cs
@@ -4,7 +4,6 @@
using Snap.Hutao.Model.Binding.Cultivation;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.Metadata;
-using Snap.Hutao.Model.Primitive;
using Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate;
using System.Collections.ObjectModel;
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/DailyNote/DailyNoteNotifier.cs b/src/Snap.Hutao/Snap.Hutao/Service/DailyNote/DailyNoteNotifier.cs
index a62c991e..ec667d64 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/DailyNote/DailyNoteNotifier.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/DailyNote/DailyNoteNotifier.cs
@@ -6,7 +6,6 @@ using Microsoft.Extensions.DependencyInjection;
using Snap.Hutao.Core.Database;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.Entity.Database;
-using Snap.Hutao.Model.Metadata.Converter;
using Snap.Hutao.Web.Hoyolab.Takumi.Auth;
using Snap.Hutao.Web.Hoyolab.Takumi.Binding;
using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.DailyNote;
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs
index 1ca8a677..38acef09 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/GachaLogService.cs
@@ -16,7 +16,6 @@ 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;
@@ -122,7 +121,7 @@ internal class GachaLogService : IGachaLogService
await ThreadHelper.SwitchToMainThreadAsync();
try
{
- archiveCollection ??= appDbContext.GachaArchives.AsNoTracking().ToObservableCollection();
+ archiveCollection ??= appDbContext.GachaArchives.AsNoTracking().ToObservableCollection();
}
catch (SqliteException ex)
{
@@ -329,6 +328,8 @@ internal class GachaLogService : IGachaLogService
GachaArchive created = GachaArchive.Create(uid);
appDbContext.GachaArchives.AddAndSave(created);
+ // System.InvalidOperationException: Sequence contains no elements
+ // ? how this happen here?
archive = appDbContext.GachaArchives.Single(a => a.Uid == uid);
GachaArchive temp = archive;
ThreadHelper.InvokeOnMainThread(() => archiveCollection!.Add(temp));
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/QueryProvider/GachaLogQueryWebCacheProvider.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/QueryProvider/GachaLogQueryWebCacheProvider.cs
index b167691f..5c285a2c 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/QueryProvider/GachaLogQueryWebCacheProvider.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/QueryProvider/GachaLogQueryWebCacheProvider.cs
@@ -48,7 +48,7 @@ internal class GachaLogQueryWebCacheProvider : IGachaLogQueryProvider
{
(bool isOk, string path) = await gameService.GetGamePathAsync().ConfigureAwait(false);
- if (isOk)
+ if (isOk && (!string.IsNullOrEmpty(path)))
{
string cacheFile = GetCacheFile(path);
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/GameService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/GameService.cs
index 28f8a715..41d9b1c4 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Game/GameService.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/GameService.cs
@@ -59,14 +59,13 @@ internal class GameService : IGameService
{
if (memoryCache.TryGetValue(GamePathKey, out object? value))
{
- return new(true, Must.NotNull((value as string)!));
+ return new(true, (value as string)!);
}
else
{
using (IServiceScope scope = scopeFactory.CreateScope())
{
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService();
-
SettingEntry entry = await appDbContext.Settings.SingleOrAddAsync(SettingEntry.GamePath, string.Empty).ConfigureAwait(false);
// Cannot find in setting
@@ -89,7 +88,7 @@ internal class GameService : IGameService
{
// Save result.
entry.Value = result.Value;
- appDbContext.Settings.UpdateAndSave(entry);
+ await appDbContext.Settings.UpdateAndSaveAsync(entry).ConfigureAwait(false);
}
else
{
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/Package/PackageConvertException.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/Package/PackageConvertException.cs
index 747c7937..c4329da7 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Game/Package/PackageConvertException.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/Package/PackageConvertException.cs
@@ -1,15 +1,6 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
-using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
-using Snap.Hutao.Core.IO;
-using Snap.Hutao.Model.Binding.LaunchGame;
-using Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher;
-using System.IO;
-using System.IO.Compression;
-using System.Net.Http;
-using static Snap.Hutao.Service.Game.GameConstants;
-
namespace Snap.Hutao.Service.Game.Package;
///
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.cs
index 990d7fd2..9974c5f3 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.cs
@@ -4,6 +4,7 @@
using Microsoft.Extensions.Caching.Memory;
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
using Snap.Hutao.Core.Diagnostics;
+using Snap.Hutao.Core.ExceptionService;
using Snap.Hutao.Core.IO;
using Snap.Hutao.Core.Logging;
using Snap.Hutao.Extension;
@@ -11,7 +12,6 @@ using Snap.Hutao.Service.Abstraction;
using System.IO;
using System.Net.Http;
using System.Net.Http.Json;
-using System.Security.Cryptography;
namespace Snap.Hutao.Service.Metadata;
@@ -180,10 +180,18 @@ internal partial class MetadataService : IMetadataService, IMetadataServiceIniti
return Must.NotNull((T)value!);
}
- using (Stream fileStream = File.OpenRead(Path.Combine(metadataFolderPath, $"{fileName}.json")))
+ string path = Path.Combine(metadataFolderPath, $"{fileName}.json");
+ if (File.Exists(path))
{
- T? result = await JsonSerializer.DeserializeAsync(fileStream, options, token).ConfigureAwait(false);
- return memoryCache.Set(cacheKey, Must.NotNull(result!));
+ using (Stream fileStream = File.OpenRead(path))
+ {
+ T? result = await JsonSerializer.DeserializeAsync(fileStream, options, token).ConfigureAwait(false);
+ return memoryCache.Set(cacheKey, Must.NotNull(result!));
+ }
+ }
+ else
+ {
+ throw ThrowHelper.UserdataCorrupted(SH.ServiceMetadataNotInitialized, null!);
}
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Navigation/NavigationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Navigation/NavigationService.cs
index 28abd4d6..b2196e2e 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/Navigation/NavigationService.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/Navigation/NavigationService.cs
@@ -3,7 +3,6 @@
using Microsoft.UI.Xaml.Controls;
using Snap.Hutao.Control;
-using Snap.Hutao.Core.Logging;
using Snap.Hutao.Core.Setting;
using Snap.Hutao.Service.Abstraction;
using Snap.Hutao.View.Helper;
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/SpiralAbyssRecordService.cs b/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/SpiralAbyssRecordService.cs
index d7106c7a..2a0803c8 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/SpiralAbyssRecordService.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/SpiralAbyss/SpiralAbyssRecordService.cs
@@ -63,61 +63,38 @@ internal class SpiralAbyssRecordService : ISpiralAbyssRecordService
///
public async Task RefreshSpiralAbyssAsync(UserAndUid userAndUid)
{
- Response lastResponse = await gameRecordClient
- .GetSpiralAbyssAsync(userAndUid, SpiralAbyssSchedule.Last)
+ await RefreshSpiralAbyssCoreAsync(userAndUid, SpiralAbyssSchedule.Last).ConfigureAwait(false);
+ await RefreshSpiralAbyssCoreAsync(userAndUid, SpiralAbyssSchedule.Current).ConfigureAwait(false);
+ }
+
+ private async Task RefreshSpiralAbyssCoreAsync(UserAndUid userAndUid, SpiralAbyssSchedule schedule)
+ {
+ Response response = await gameRecordClient
+ .GetSpiralAbyssAsync(userAndUid, schedule)
.ConfigureAwait(false);
- if (lastResponse.IsOk())
+ if (response.IsOk())
{
- Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.SpiralAbyss last = lastResponse.Data;
+ Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.SpiralAbyss webSpiralAbyss = response.Data;
- SpiralAbyssEntry? lastEntry = spiralAbysses!.SingleOrDefault(s => s.ScheduleId == last.ScheduleId);
- if (lastEntry != null)
+ SpiralAbyssEntry? existEntry = spiralAbysses!.SingleOrDefault(s => s.ScheduleId == webSpiralAbyss.ScheduleId);
+ if (existEntry != null)
{
await ThreadHelper.SwitchToMainThreadAsync();
- lastEntry.UpdateSpiralAbyss(last);
+ existEntry.UpdateSpiralAbyss(webSpiralAbyss);
await ThreadHelper.SwitchToBackgroundAsync();
- await appDbContext.SpiralAbysses.UpdateAndSaveAsync(lastEntry).ConfigureAwait(false);
+ await appDbContext.SpiralAbysses.UpdateAndSaveAsync(existEntry).ConfigureAwait(false);
}
else
{
- SpiralAbyssEntry entry = SpiralAbyssEntry.Create(userAndUid.Uid.Value, last);
+ SpiralAbyssEntry newEntry = SpiralAbyssEntry.Create(userAndUid.Uid.Value, webSpiralAbyss);
await ThreadHelper.SwitchToMainThreadAsync();
- spiralAbysses!.Insert(0, entry);
+ spiralAbysses!.Insert(0, newEntry);
await ThreadHelper.SwitchToBackgroundAsync();
- await appDbContext.SpiralAbysses.AddAndSaveAsync(entry).ConfigureAwait(false);
- }
- }
-
- Response currentResponse = await gameRecordClient
- .GetSpiralAbyssAsync(userAndUid, SpiralAbyssSchedule.Current)
- .ConfigureAwait(false);
-
- if (currentResponse.IsOk())
- {
- Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.SpiralAbyss current = currentResponse.Data;
-
- SpiralAbyssEntry? currentEntry = spiralAbysses!.SingleOrDefault(s => s.ScheduleId == current.ScheduleId);
- if (currentEntry != null)
- {
- await ThreadHelper.SwitchToMainThreadAsync();
- currentEntry.UpdateSpiralAbyss(current);
-
- await ThreadHelper.SwitchToBackgroundAsync();
- await appDbContext.SpiralAbysses.UpdateAndSaveAsync(currentEntry).ConfigureAwait(false);
- }
- else
- {
- SpiralAbyssEntry entry = SpiralAbyssEntry.Create(userAndUid.Uid.Value, current);
-
- await ThreadHelper.SwitchToMainThreadAsync();
- spiralAbysses!.Insert(0, entry);
-
- await ThreadHelper.SwitchToBackgroundAsync();
- await appDbContext.SpiralAbysses.AddAndSaveAsync(entry).ConfigureAwait(false);
+ await appDbContext.SpiralAbysses.AddAndSaveAsync(newEntry).ConfigureAwait(false);
}
}
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Service/User/UserService.cs b/src/Snap.Hutao/Snap.Hutao/Service/User/UserService.cs
index 95c62397..ca8d60b5 100644
--- a/src/Snap.Hutao/Snap.Hutao/Service/User/UserService.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Service/User/UserService.cs
@@ -99,7 +99,7 @@ internal class UserService : IUserService
// Sync cache
await ThreadHelper.SwitchToMainThreadAsync();
userCollection!.Remove(user);
- roleCollection?.RemoveWhere(r => r.User.InnerId == user.Entity.InnerId);
+ roleCollection?.RemoveWhere(r => r.User.Mid == user.Entity.Mid);
// Sync database
await ThreadHelper.SwitchToBackgroundAsync();
diff --git a/src/Snap.Hutao/Snap.Hutao/View/Control/AnnouncementContentViewer.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Control/AnnouncementContentViewer.xaml.cs
index 3813892d..e1826709 100644
--- a/src/Snap.Hutao/Snap.Hutao/View/Control/AnnouncementContentViewer.xaml.cs
+++ b/src/Snap.Hutao/Snap.Hutao/View/Control/AnnouncementContentViewer.xaml.cs
@@ -2,11 +2,9 @@
// Licensed under the MIT license.
using Microsoft.UI.Xaml;
-using Microsoft.UI.Xaml.Navigation;
using Microsoft.Web.WebView2.Core;
using Snap.Hutao.Control;
using Snap.Hutao.Control.Theme;
-using Snap.Hutao.Service.Navigation;
using Snap.Hutao.Web.Hoyolab.Hk4e.Common.Announcement;
using Windows.System;
@@ -58,8 +56,8 @@ public sealed partial class AnnouncementContentViewer : Microsoft.UI.Xaml.Contro
///
public Announcement Announcement
{
- get { return (Announcement)GetValue(AnnouncementProperty); }
- set { SetValue(AnnouncementProperty, value); }
+ get => (Announcement)GetValue(AnnouncementProperty);
+ set => SetValue(AnnouncementProperty, value);
}
private static string? GenerateHtml(Announcement? announcement, ElementTheme theme)
diff --git a/src/Snap.Hutao/Snap.Hutao/View/Control/StatisticsCard.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Control/StatisticsCard.xaml.cs
index a89bc82f..00343889 100644
--- a/src/Snap.Hutao/Snap.Hutao/View/Control/StatisticsCard.xaml.cs
+++ b/src/Snap.Hutao/Snap.Hutao/View/Control/StatisticsCard.xaml.cs
@@ -27,7 +27,7 @@ public sealed partial class StatisticsCard : UserControl
///
public bool ShowUpPull
{
- get { return (bool)GetValue(ShowUpPullProperty); }
- set { SetValue(ShowUpPullProperty, value); }
+ get => (bool)GetValue(ShowUpPullProperty);
+ set => SetValue(ShowUpPullProperty, value);
}
}
diff --git a/src/Snap.Hutao/Snap.Hutao/View/Dialog/GachaLogRefreshProgressDialog.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Dialog/GachaLogRefreshProgressDialog.xaml.cs
index 8cc8d18e..8700e962 100644
--- a/src/Snap.Hutao/Snap.Hutao/View/Dialog/GachaLogRefreshProgressDialog.xaml.cs
+++ b/src/Snap.Hutao/Snap.Hutao/View/Dialog/GachaLogRefreshProgressDialog.xaml.cs
@@ -8,7 +8,6 @@ using Snap.Hutao.Extension;
using Snap.Hutao.Model.Binding.Gacha.Abstraction;
using Snap.Hutao.Service.GachaLog;
using Snap.Hutao.View.Control;
-using Snap.Hutao.Web.Hoyolab.Hk4e.Event.GachaInfo;
namespace Snap.Hutao.View.Dialog;
diff --git a/src/Snap.Hutao/Snap.Hutao/View/Dialog/LaunchGamePackageConvertDialog.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Dialog/LaunchGamePackageConvertDialog.xaml.cs
index 7948711c..9339907a 100644
--- a/src/Snap.Hutao/Snap.Hutao/View/Dialog/LaunchGamePackageConvertDialog.xaml.cs
+++ b/src/Snap.Hutao/Snap.Hutao/View/Dialog/LaunchGamePackageConvertDialog.xaml.cs
@@ -30,7 +30,7 @@ public sealed partial class LaunchGamePackageConvertDialog : ContentDialog
///
public PackageReplaceStatus State
{
- get { return (PackageReplaceStatus)GetValue(StateProperty); }
- set { SetValue(StateProperty, value); }
+ get => (PackageReplaceStatus)GetValue(StateProperty);
+ set => SetValue(StateProperty, value);
}
}
diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/LoginMihoyoUserPage.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Page/LoginMihoyoUserPage.xaml.cs
index 75338194..ea65fa0e 100644
--- a/src/Snap.Hutao/Snap.Hutao/View/Page/LoginMihoyoUserPage.xaml.cs
+++ b/src/Snap.Hutao/Snap.Hutao/View/Page/LoginMihoyoUserPage.xaml.cs
@@ -29,16 +29,23 @@ public sealed partial class LoginMihoyoUserPage : Microsoft.UI.Xaml.Controls.Pag
[SuppressMessage("", "VSTHRD100")]
private async void OnRootLoaded(object sender, RoutedEventArgs e)
{
- await WebView.EnsureCoreWebView2Async();
-
- CoreWebView2CookieManager manager = WebView.CoreWebView2.CookieManager;
- IReadOnlyList cookies = await manager.GetCookiesAsync("https://user.mihoyo.com");
- foreach (CoreWebView2Cookie item in cookies)
+ try
{
- manager.DeleteCookie(item);
- }
+ await WebView.EnsureCoreWebView2Async();
- WebView.CoreWebView2.Navigate("https://user.mihoyo.com/#/login/password");
+ CoreWebView2CookieManager manager = WebView.CoreWebView2.CookieManager;
+ IReadOnlyList cookies = await manager.GetCookiesAsync("https://user.mihoyo.com");
+ foreach (CoreWebView2Cookie item in cookies)
+ {
+ manager.DeleteCookie(item);
+ }
+
+ WebView.CoreWebView2.Navigate("https://user.mihoyo.com/#/login/password");
+ }
+ catch (Exception ex)
+ {
+ Ioc.Default.GetRequiredService().Error(ex);
+ }
}
private async Task HandleCurrentCookieAsync(CancellationToken token)
diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml.cs
index aa1d0702..5444cf72 100644
--- a/src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml.cs
+++ b/src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml.cs
@@ -1,9 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
-using Microsoft.UI.Xaml.Navigation;
using Snap.Hutao.Control;
-using Snap.Hutao.Service.Navigation;
using Snap.Hutao.ViewModel;
namespace Snap.Hutao.View.Page;
diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/SpiralAbyssRecordPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/SpiralAbyssRecordPage.xaml
index c73866b4..6cf0e29e 100644
--- a/src/Snap.Hutao/Snap.Hutao/View/Page/SpiralAbyssRecordPage.xaml
+++ b/src/Snap.Hutao/Snap.Hutao/View/Page/SpiralAbyssRecordPage.xaml
@@ -21,7 +21,7 @@
-
+
/// 操作被用户取消
- protected void ThrowIfViewDisposed()
+ private void ThrowIfViewDisposed()
{
if (IsViewDisposed)
{
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Achievement/AchievementViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Achievement/AchievementViewModel.cs
index f5e9ba3a..64361e53 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Achievement/AchievementViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Achievement/AchievementViewModel.cs
@@ -5,10 +5,8 @@ using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.WinUI.UI;
using Microsoft.UI.Xaml.Controls;
-using Snap.Hutao.Control.Extension;
using Snap.Hutao.Core.Database;
using Snap.Hutao.Core.IO;
-using Snap.Hutao.Core.IO.DataTransfer;
using Snap.Hutao.Core.LifeCycle;
using Snap.Hutao.Extension;
using Snap.Hutao.Factory.Abstraction;
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarPropertyViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarPropertyViewModel.cs
index 3322781d..f4ef7cfc 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarPropertyViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/AvatarPropertyViewModel.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license.
using CommunityToolkit.Mvvm.Input;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Imaging;
@@ -18,7 +19,6 @@ using Snap.Hutao.Service.AvatarInfo;
using Snap.Hutao.Service.Cultivation;
using Snap.Hutao.Service.User;
using Snap.Hutao.View.Dialog;
-using Snap.Hutao.Web.Hoyolab.Takumi.Binding;
using Snap.Hutao.Web.Response;
using System.Runtime.InteropServices;
using Windows.Graphics.Imaging;
@@ -39,30 +39,21 @@ namespace Snap.Hutao.ViewModel;
[Injection(InjectAs.Scoped)]
internal class AvatarPropertyViewModel : Abstraction.ViewModel
{
+ private readonly IServiceProvider serviceProvider;
private readonly IUserService userService;
- private readonly IAvatarInfoService avatarInfoService;
private readonly IInfoBarService infoBarService;
- private readonly IContentDialogFactory contentDialogFactory;
private Summary? summary;
private Avatar? selectedAvatar;
///
/// 构造一个新的角色属性视图模型
///
- /// 用户服务
- /// 角色信息服务
- /// 对话框工厂
- /// 信息条服务
- public AvatarPropertyViewModel(
- IUserService userService,
- IAvatarInfoService avatarInfoService,
- IContentDialogFactory contentDialogFactory,
- IInfoBarService infoBarService)
+ /// 服务提供器
+ public AvatarPropertyViewModel(IServiceProvider serviceProvider)
{
- this.userService = userService;
- this.avatarInfoService = avatarInfoService;
- this.infoBarService = infoBarService;
- this.contentDialogFactory = contentDialogFactory;
+ userService = serviceProvider.GetRequiredService();
+ infoBarService = serviceProvider.GetRequiredService();
+ this.serviceProvider = serviceProvider;
OpenUICommand = new AsyncRelayCommand(OpenUIAsync);
RefreshFromEnkaApiCommand = new AsyncRelayCommand(RefreshByEnkaApiAsync);
@@ -159,14 +150,18 @@ internal class AvatarPropertyViewModel : Abstraction.ViewModel
ValueResult summaryResult;
using (await EnterCriticalExecutionAsync().ConfigureAwait(false))
{
- ContentDialog dialog = await contentDialogFactory
+ ContentDialog dialog = await serviceProvider
+ .GetRequiredService()
.CreateForIndeterminateProgressAsync(SH.ViewModelAvatarPropertyFetch)
.ConfigureAwait(false);
await ThreadHelper.SwitchToMainThreadAsync();
await using (await dialog.BlockAsync().ConfigureAwait(false))
{
- summaryResult = await avatarInfoService.GetSummaryAsync(userAndUid, option, token).ConfigureAwait(false);
+ summaryResult = await serviceProvider
+ .GetRequiredService()
+ .GetSummaryAsync(userAndUid, option, token)
+ .ConfigureAwait(false);
}
}
@@ -199,9 +194,6 @@ internal class AvatarPropertyViewModel : Abstraction.ViewModel
{
if (avatar != null)
{
- IInfoBarService infoBarService = Ioc.Default.GetRequiredService();
- IUserService userService = Ioc.Default.GetRequiredService();
-
if (userService.Current != null)
{
if (avatar.Weapon == null)
@@ -218,14 +210,14 @@ internal class AvatarPropertyViewModel : Abstraction.ViewModel
if (isOk)
{
- Response consumptionResponse = await Ioc.Default
+ Response consumptionResponse = await serviceProvider
.GetRequiredService()
.ComputeAsync(userService.Current.Entity, delta)
.ConfigureAwait(false);
if (consumptionResponse.IsOk())
{
- ICultivationService cultivationService = Ioc.Default.GetRequiredService();
+ ICultivationService cultivationService = serviceProvider.GetRequiredService();
CalcConsumption consumption = consumptionResponse.Data;
List items = CalcItemHelper.Merge(consumption.AvatarConsume, consumption.AvatarSkillConsume);
@@ -233,18 +225,25 @@ internal class AvatarPropertyViewModel : Abstraction.ViewModel
.SaveConsumptionAsync(CultivateType.AvatarAndSkill, avatar.Id, items)
.ConfigureAwait(false);
- // take a hot path if avatar is not saved.
- bool avatarAndWeaponSaved = avatarSaved && await cultivationService
- .SaveConsumptionAsync(CultivateType.Weapon, avatar.Weapon.Id, consumption.WeaponConsume.EmptyIfNull())
- .ConfigureAwait(false);
+ try
+ {
+ // take a hot path if avatar is not saved.
+ bool avatarAndWeaponSaved = avatarSaved && await cultivationService
+ .SaveConsumptionAsync(CultivateType.Weapon, avatar.Weapon.Id, consumption.WeaponConsume.EmptyIfNull())
+ .ConfigureAwait(false);
- if (avatarAndWeaponSaved)
- {
- infoBarService.Success(SH.ViewModelCultivationEntryAddSuccess);
+ if (avatarAndWeaponSaved)
+ {
+ infoBarService.Success(SH.ViewModelCultivationEntryAddSuccess);
+ }
+ else
+ {
+ infoBarService.Warning(SH.ViewModelCultivationEntryAddWarning);
+ }
}
- else
+ catch (Core.ExceptionService.UserdataCorruptedException ex)
{
- infoBarService.Warning(SH.ViewModelCultivationEntryAddWarning);
+ infoBarService.Error(ex, SH.ViewModelCultivationAddWarning);
}
}
}
@@ -267,7 +266,7 @@ internal class AvatarPropertyViewModel : Abstraction.ViewModel
bool clipboardOpened = false;
using (SoftwareBitmap softwareBitmap = SoftwareBitmap.CreateCopyFromBuffer(buffer, BitmapPixelFormat.Bgra8, bitmap.PixelWidth, bitmap.PixelHeight))
{
- Color tintColor = (Color)Ioc.Default.GetRequiredService().Resources["CompatBackgroundColor"];
+ Color tintColor = (Color)serviceProvider.GetRequiredService().Resources["CompatBackgroundColor"];
Bgra8 tint = Bgra8.FromColor(tintColor);
softwareBitmap.NormalBlend(tint);
using (InMemoryRandomAccessStream memory = new())
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/DailyNoteViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/DailyNoteViewModel.cs
index 7e38f42e..917d1284 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/DailyNoteViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/DailyNoteViewModel.cs
@@ -51,18 +51,11 @@ internal class DailyNoteViewModel : Abstraction.ViewModel
/// 构造一个新的实时便笺视图模型
///
/// 服务提供器
- /// 用户服务
- /// 实时便笺服务
- /// 数据库上下文
- public DailyNoteViewModel(
- IServiceProvider serviceProvider,
- IUserService userService,
- IDailyNoteService dailyNoteService,
- AppDbContext appDbContext)
+ public DailyNoteViewModel(IServiceProvider serviceProvider)
{
- this.userService = userService;
- this.dailyNoteService = dailyNoteService;
- this.appDbContext = appDbContext;
+ userService = serviceProvider.GetRequiredService();
+ dailyNoteService = serviceProvider.GetRequiredService();
+ appDbContext = serviceProvider.GetRequiredService();
this.serviceProvider = serviceProvider;
OpenUICommand = new AsyncRelayCommand(OpenUIAsync);
@@ -92,7 +85,7 @@ internal class DailyNoteViewModel : Abstraction.ViewModel
{
if (!ScheduleTaskHelper.RegisterForDailyNoteRefresh(value.Value))
{
- Ioc.Default.GetRequiredService().Warning(SH.ViewModelDailyNoteRegisterTaskFail);
+ serviceProvider.GetRequiredService().Warning(SH.ViewModelDailyNoteRegisterTaskFail);
}
else
{
@@ -244,10 +237,13 @@ internal class DailyNoteViewModel : Abstraction.ViewModel
{
if (entry != null)
{
- // ContentDialog must be created by main thread.
- await ThreadHelper.SwitchToMainThreadAsync();
- await new DailyNoteNotificationDialog(entry).ShowAsync();
- appDbContext.DailyNotes.UpdateAndSave(entry);
+ using (await EnterCriticalExecutionAsync().ConfigureAwait(false))
+ {
+ // ContentDialog must be created by main thread.
+ await ThreadHelper.SwitchToMainThreadAsync();
+ await new DailyNoteNotificationDialog(entry).ShowAsync();
+ appDbContext.DailyNotes.UpdateAndSave(entry);
+ }
}
}
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/ExperimentalFeaturesViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/ExperimentalFeaturesViewModel.cs
index 66ef9772..b95352a7 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/ExperimentalFeaturesViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/ExperimentalFeaturesViewModel.cs
@@ -18,11 +18,16 @@ namespace Snap.Hutao.ViewModel;
[Injection(InjectAs.Scoped)]
internal class ExperimentalFeaturesViewModel : ObservableObject
{
+ private readonly IServiceProvider serviceProvider;
+
///
/// 构造一个新的实验性功能视图模型
///
- public ExperimentalFeaturesViewModel()
+ /// 服务提供器
+ public ExperimentalFeaturesViewModel(IServiceProvider serviceProvider)
{
+ this.serviceProvider = serviceProvider;
+
OpenCacheFolderCommand = new AsyncRelayCommand(OpenCacheFolderAsync);
OpenDataFolderCommand = new AsyncRelayCommand(OpenDataFolderAsync);
DeleteUsersCommand = new AsyncRelayCommand(DangerousDeleteUsersAsync);
@@ -61,7 +66,7 @@ internal class ExperimentalFeaturesViewModel : ObservableObject
private async Task DangerousDeleteUsersAsync()
{
- using (IServiceScope scope = Ioc.Default.CreateScope())
+ using (IServiceScope scope = serviceProvider.CreateScope())
{
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService();
await appDbContext.Users.ExecuteDeleteAsync().ConfigureAwait(false);
@@ -73,7 +78,7 @@ internal class ExperimentalFeaturesViewModel : ObservableObject
private void DangerousDeleteAllScheduleTasks()
{
- IInfoBarService infoBarService = Ioc.Default.GetRequiredService();
+ IInfoBarService infoBarService = serviceProvider.GetRequiredService();
if (Core.ScheduleTaskHelper.UnregisterAllTasks())
{
infoBarService.Success(SH.ViewModelExperimentalDeleteTaskSuccess);
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLogViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLogViewModel.cs
index 34e0f867..a55b7919 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLogViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/GachaLogViewModel.cs
@@ -150,11 +150,8 @@ internal class GachaLogViewModel : Abstraction.ViewModel
if (await gachaLogService.InitializeAsync(CancellationToken).ConfigureAwait(true))
{
ObservableCollection archives;
-
- ThrowIfViewDisposed();
- using (await DisposeLock.EnterAsync().ConfigureAwait(false))
+ using (await EnterCriticalExecutionAsync().ConfigureAwait(false))
{
- ThrowIfViewDisposed();
archives = await gachaLogService.GetArchiveCollectionAsync().ConfigureAwait(false);
}
@@ -204,13 +201,13 @@ internal class GachaLogViewModel : Abstraction.ViewModel
try
{
- using (await DisposeLock.EnterAsync().ConfigureAwait(false))
+ using (await EnterCriticalExecutionAsync().ConfigureAwait(false))
{
try
{
authkeyValid = await gachaLogService.RefreshGachaLogAsync(query, strategy, progress, CancellationToken).ConfigureAwait(false);
}
- catch (Core.ExceptionService.UserdataCorruptedException ex)
+ catch (UserdataCorruptedException ex)
{
authkeyValid = false;
infoBarService.Error(ex);
@@ -304,11 +301,14 @@ internal class GachaLogViewModel : Abstraction.ViewModel
if (result == ContentDialogResult.Primary)
{
- await gachaLogService.RemoveArchiveAsync(SelectedArchive).ConfigureAwait(false);
+ using (await EnterCriticalExecutionAsync().ConfigureAwait(false))
+ {
+ await gachaLogService.RemoveArchiveAsync(SelectedArchive).ConfigureAwait(false);
- // reselect first archive
- await ThreadHelper.SwitchToMainThreadAsync();
- SelectedArchive = Archives.FirstOrDefault();
+ // reselect first archive
+ await ThreadHelper.SwitchToMainThreadAsync();
+ SelectedArchive = Archives.FirstOrDefault();
+ }
}
}
}
@@ -354,7 +354,7 @@ internal class GachaLogViewModel : Abstraction.ViewModel
}
catch (UserdataCorruptedException ex)
{
- Ioc.Default.GetRequiredService().Error(ex);
+ infoBarService.Error(ex);
}
}
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/HutaoDatabaseViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/HutaoDatabaseViewModel.cs
index e78a0e90..8212a8a9 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/HutaoDatabaseViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/HutaoDatabaseViewModel.cs
@@ -2,15 +2,9 @@
// Licensed under the MIT license.
using CommunityToolkit.Mvvm.Input;
-using Microsoft.UI.Xaml;
-using Microsoft.UI.Xaml.Media.Imaging;
using Snap.Hutao.Model.Binding.Hutao;
using Snap.Hutao.Service.Hutao;
using Snap.Hutao.Web.Hutao.Model;
-using System.IO;
-using System.Runtime.InteropServices.WindowsRuntime;
-using Windows.Graphics.Imaging;
-using Windows.Storage.Streams;
namespace Snap.Hutao.ViewModel;
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/LaunchGameViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/LaunchGameViewModel.cs
index 874a6359..4a48519b 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/LaunchGameViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/LaunchGameViewModel.cs
@@ -4,6 +4,7 @@
using CommunityToolkit.Mvvm.Input;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
+using Microsoft.Extensions.DependencyInjection;
using Snap.Hutao.Control.Extension;
using Snap.Hutao.Core.Database;
using Snap.Hutao.Core.LifeCycle;
@@ -12,7 +13,6 @@ using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.Entity.Database;
using Snap.Hutao.Service.Abstraction;
using Snap.Hutao.Service.Game;
-using Snap.Hutao.Service.Game.Unlocker;
using Snap.Hutao.Service.Navigation;
using Snap.Hutao.Service.User;
using Snap.Hutao.View.Dialog;
@@ -36,6 +36,7 @@ internal class LaunchGameViewModel : Abstraction.ViewModel
private static readonly string TrueString = true.ToString();
private static readonly string FalseString = false.ToString();
+ private readonly IServiceProvider serviceProvider;
private readonly IGameService gameService;
private readonly AppDbContext appDbContext;
private readonly IMemoryCache memoryCache;
@@ -56,17 +57,13 @@ internal class LaunchGameViewModel : Abstraction.ViewModel
///
/// 构造一个新的启动游戏视图模型
///
- /// 游戏服务
- /// 内存缓存
- /// 数据库上下文
- public LaunchGameViewModel(
- IGameService gameService,
- IMemoryCache memoryCache,
- AppDbContext appDbContext)
+ /// 服务提供器
+ public LaunchGameViewModel(IServiceProvider serviceProvider)
{
- this.gameService = gameService;
- this.appDbContext = appDbContext;
- this.memoryCache = memoryCache;
+ gameService = serviceProvider.GetRequiredService();
+ appDbContext = serviceProvider.GetRequiredService();
+ memoryCache = serviceProvider.GetRequiredService();
+ this.serviceProvider = serviceProvider;
OpenUICommand = new AsyncRelayCommand(OpenUIAsync);
LaunchCommand = new AsyncRelayCommand(LaunchAsync);
@@ -210,11 +207,8 @@ internal class LaunchGameViewModel : Abstraction.ViewModel
{
try
{
- ThrowIfViewDisposed();
- using (await DisposeLock.EnterAsync(CancellationToken).ConfigureAwait(true))
+ using (await EnterCriticalExecutionAsync().ConfigureAwait(false))
{
- ThrowIfViewDisposed();
-
MultiChannel multi = gameService.GetMultiChannel();
if (string.IsNullOrEmpty(multi.ConfigFilePath))
{
@@ -222,7 +216,7 @@ internal class LaunchGameViewModel : Abstraction.ViewModel
}
else
{
- Ioc.Default.GetRequiredService().Warning(SH.ViewModelLaunchGameMultiChannelReadFail);
+ serviceProvider.GetRequiredService().Warning(SH.ViewModelLaunchGameMultiChannelReadFail);
}
GameAccounts = await gameService.GetGameAccountCollectionAsync().ConfigureAwait(true);
@@ -231,6 +225,7 @@ internal class LaunchGameViewModel : Abstraction.ViewModel
if (memoryCache.TryGetValue(DesiredUid, out object? value) && value is string uid)
{
SelectedGameAccount = GameAccounts.FirstOrDefault(g => g.AttachUid == uid);
+ memoryCache.Remove(DesiredUid);
}
// Sync from Settings
@@ -243,8 +238,8 @@ internal class LaunchGameViewModel : Abstraction.ViewModel
}
else
{
- Ioc.Default.GetRequiredService().Warning(SH.ViewModelLaunchGamePathInvalid);
- await Ioc.Default.GetRequiredService()
+ serviceProvider.GetRequiredService().Warning(SH.ViewModelLaunchGamePathInvalid);
+ await serviceProvider.GetRequiredService()
.NavigateAsync(INavigationAwaiter.Default, true)
.ConfigureAwait(false);
}
@@ -288,7 +283,7 @@ internal class LaunchGameViewModel : Abstraction.ViewModel
private async Task LaunchAsync()
{
- IInfoBarService infoBarService = Ioc.Default.GetRequiredService();
+ IInfoBarService infoBarService = serviceProvider.GetRequiredService();
if (gameService.IsGameRunning())
{
@@ -344,7 +339,7 @@ internal class LaunchGameViewModel : Abstraction.ViewModel
}
catch (Core.ExceptionService.UserdataCorruptedException ex)
{
- Ioc.Default.GetRequiredService().Error(ex);
+ serviceProvider.GetRequiredService().Error(ex);
}
}
@@ -352,8 +347,8 @@ internal class LaunchGameViewModel : Abstraction.ViewModel
{
if (gameAccount != null)
{
- IUserService userService = Ioc.Default.GetRequiredService();
- IInfoBarService infoBarService = Ioc.Default.GetRequiredService();
+ IUserService userService = serviceProvider.GetRequiredService();
+ IInfoBarService infoBarService = serviceProvider.GetRequiredService();
if (userService.Current?.SelectedUserGameRole is UserGameRole role)
{
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/SettingViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/SettingViewModel.cs
index 13f66030..64ba4295 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/SettingViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/SettingViewModel.cs
@@ -3,6 +3,7 @@
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
+using Microsoft.Extensions.DependencyInjection;
using Snap.Hutao.Core.Database;
using Snap.Hutao.Core.IO;
using Snap.Hutao.Core.Setting;
@@ -27,6 +28,7 @@ namespace Snap.Hutao.ViewModel;
[Injection(InjectAs.Scoped)]
internal class SettingViewModel : Abstraction.ViewModel
{
+ private readonly IServiceProvider serviceProvider;
private readonly AppDbContext appDbContext;
private readonly IGameService gameService;
private readonly ILogger logger;
@@ -46,21 +48,14 @@ internal class SettingViewModel : Abstraction.ViewModel
///
/// 构造一个新的设置视图模型
///
- /// 数据库上下文
- /// 游戏服务
- /// 实验性功能
- /// 日志器
- public SettingViewModel(
- AppDbContext appDbContext,
- IGameService gameService,
- ExperimentalFeaturesViewModel experimental,
- ILogger logger)
+ /// 服务提供器
+ public SettingViewModel(IServiceProvider serviceProvider)
{
- this.appDbContext = appDbContext;
- this.gameService = gameService;
- this.logger = logger;
-
- Experimental = experimental;
+ appDbContext = serviceProvider.GetRequiredService();
+ gameService = serviceProvider.GetRequiredService();
+ logger = serviceProvider.GetRequiredService>();
+ Experimental = serviceProvider.GetRequiredService();
+ this.serviceProvider = serviceProvider;
isEmptyHistoryWishVisibleEntry = appDbContext.Settings.SingleOrAdd(SettingEntry.IsEmptyHistoryWishVisible, SettingEntryHelper.TrueString);
IsEmptyHistoryWishVisible = bool.Parse(isEmptyHistoryWishVisibleEntry.Value!);
@@ -152,7 +147,7 @@ internal class SettingViewModel : Abstraction.ViewModel
{
selectedBackdropTypeEntry.Value = value.Value.ToString();
appDbContext.Settings.UpdateAndSave(selectedBackdropTypeEntry);
- Ioc.Default.GetRequiredService().Send(new Message.BackdropTypeChangedMessage(value.Value));
+ serviceProvider.GetRequiredService().Send(new Message.BackdropTypeChangedMessage(value.Value));
}
}
}
@@ -189,7 +184,7 @@ internal class SettingViewModel : Abstraction.ViewModel
private async Task SetGamePathAsync()
{
- IGameLocator locator = Ioc.Default.GetRequiredService>()
+ IGameLocator locator = serviceProvider.GetRequiredService>()
.Single(l => l.Name == nameof(ManualGameLocator));
(bool isOk, string path) = await locator.LocateGamePathAsync().ConfigureAwait(false);
@@ -203,7 +198,7 @@ internal class SettingViewModel : Abstraction.ViewModel
private void DeleteGameWebCache()
{
- IGameService gameService = Ioc.Default.GetRequiredService();
+ IGameService gameService = serviceProvider.GetRequiredService();
string gamePath = gameService.GetGamePathSkipLocator();
if (!string.IsNullOrEmpty(gamePath))
@@ -211,7 +206,7 @@ internal class SettingViewModel : Abstraction.ViewModel
string cacheFilePath = GachaLogQueryWebCacheProvider.GetCacheFile(gamePath);
string cacheFolder = Path.GetDirectoryName(cacheFilePath)!;
- IInfoBarService infoBarService = Ioc.Default.GetRequiredService();
+ IInfoBarService infoBarService = serviceProvider.GetRequiredService();
if (Directory.Exists(cacheFolder))
{
try
@@ -243,7 +238,7 @@ internal class SettingViewModel : Abstraction.ViewModel
private async Task CheckUpdateAsync()
{
#if DEBUG
- await Ioc.Default
+ await serviceProvider
.GetRequiredService()
.NavigateAsync(Service.Navigation.INavigationAwaiter.Default)
.ConfigureAwait(false);
@@ -254,11 +249,11 @@ internal class SettingViewModel : Abstraction.ViewModel
private async Task SetDataFolderAsync()
{
- IPickerFactory pickerFactory = Ioc.Default.GetRequiredService();
+ IPickerFactory pickerFactory = serviceProvider.GetRequiredService();
FolderPicker picker = pickerFactory.GetFolderPicker();
(bool isOk, string folder) = await picker.TryPickSingleFolderAsync().ConfigureAwait(false);
- IInfoBarService infoBarService = Ioc.Default.GetRequiredService();
+ IInfoBarService infoBarService = serviceProvider.GetRequiredService();
if (isOk)
{
LocalSetting.Set(SettingKeys.DataFolderPath, folder);
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyssRecordViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyssRecordViewModel.cs
index 68d59bea..9299eb30 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyssRecordViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/SpiralAbyssRecordViewModel.cs
@@ -3,6 +3,7 @@
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
+using Microsoft.Extensions.DependencyInjection;
using Snap.Hutao.Message;
using Snap.Hutao.Model.Binding.SpiralAbyss;
using Snap.Hutao.Model.Binding.User;
@@ -25,6 +26,7 @@ namespace Snap.Hutao.ViewModel;
[Injection(InjectAs.Scoped)]
internal class SpiralAbyssRecordViewModel : Abstraction.ViewModel, IRecipient
{
+ private readonly IServiceProvider serviceProvider;
private readonly ISpiralAbyssRecordService spiralAbyssRecordService;
private readonly IMetadataService metadataService;
private readonly IUserService userService;
@@ -37,25 +39,23 @@ internal class SpiralAbyssRecordViewModel : Abstraction.ViewModel, IRecipient
/// 构造一个新的深渊记录视图模型
///
+ /// 服务提供器
/// 深渊记录服务
/// 元数据服务
/// 用户服务
/// 消息器
- public SpiralAbyssRecordViewModel(
- ISpiralAbyssRecordService spiralAbyssRecordService,
- IMetadataService metadataService,
- IUserService userService,
- IMessenger messenger)
+ public SpiralAbyssRecordViewModel(IServiceProvider serviceProvider)
{
- this.spiralAbyssRecordService = spiralAbyssRecordService;
- this.metadataService = metadataService;
- this.userService = userService;
+ spiralAbyssRecordService = serviceProvider.GetRequiredService();
+ metadataService = serviceProvider.GetRequiredService();
+ userService = serviceProvider.GetRequiredService();
+ this.serviceProvider = serviceProvider;
OpenUICommand = new AsyncRelayCommand(OpenUIAsync);
RefreshCommand = new AsyncRelayCommand(RefreshAsync);
UploadSpiralAbyssRecordCommand = new AsyncRelayCommand(UploadSpiralAbyssRecordAsync);
- messenger.Register(this);
+ serviceProvider.GetRequiredService().Register(this);
}
///
@@ -123,10 +123,12 @@ internal class SpiralAbyssRecordViewModel : Abstraction.ViewModel, IRecipient().Warning(SH.MustSelectUserAndUid);
+ serviceProvider.GetRequiredService().Warning(SH.MustSelectUserAndUid);
}
}
}
@@ -136,10 +138,8 @@ internal class SpiralAbyssRecordViewModel : Abstraction.ViewModel, IRecipient? temp = null;
try
{
- ThrowIfViewDisposed();
- using (await DisposeLock.EnterAsync().ConfigureAwait(false))
+ using (await EnterCriticalExecutionAsync().ConfigureAwait(false))
{
- ThrowIfViewDisposed();
temp = await spiralAbyssRecordService
.GetSpiralAbyssCollectionAsync(userAndUid)
.ConfigureAwait(false);
@@ -156,16 +156,14 @@ internal class SpiralAbyssRecordViewModel : Abstraction.ViewModel, IRecipient();
- IInfoBarService infoBarService = Ioc.Default.GetRequiredService();
+ HomaClient homaClient = serviceProvider.GetRequiredService();
+ IInfoBarService infoBarService = serviceProvider.GetRequiredService();
if (UserAndUid.TryFromUser(userService.Current, out UserAndUid? userAndUid))
{
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/TestViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/TestViewModel.cs
index c19b1385..9e83d848 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/TestViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/TestViewModel.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license.
using CommunityToolkit.Mvvm.Input;
+using Microsoft.Extensions.DependencyInjection;
using Snap.Hutao.Core.IO;
using Snap.Hutao.Core.IO.Bits;
using Snap.Hutao.Service.User;
@@ -18,11 +19,16 @@ namespace Snap.Hutao.ViewModel;
[Injection(InjectAs.Scoped)]
internal class TestViewModel : Abstraction.ViewModel
{
+ private readonly IServiceProvider serviceProvider;
+
///
/// 构造一个新的测试视图模型
///
- public TestViewModel()
+ /// 服务提供器
+ public TestViewModel(IServiceProvider serviceProvider)
{
+ this.serviceProvider = serviceProvider;
+
ShowCommunityGameRecordDialogCommand = new AsyncRelayCommand(ShowCommunityGameRecordDialogAsync);
ShowAdoptCalculatorDialogCommand = new AsyncRelayCommand(ShowAdoptCalculatorDialogAsync);
DangerousLoginMihoyoBbsCommand = new AsyncRelayCommand(DangerousLoginMihoyoBbsAsync);
@@ -71,7 +77,7 @@ internal class TestViewModel : Abstraction.ViewModel
if (isOk)
{
- (Response? resp, Aigis? aigis) = await Ioc.Default
+ (Response? resp, Aigis? aigis) = await serviceProvider
.GetRequiredService()
.LoginByPasswordAsync(data, CancellationToken.None)
.ConfigureAwait(false);
@@ -82,7 +88,7 @@ internal class TestViewModel : Abstraction.ViewModel
{
Cookie cookie = Cookie.FromLoginResult(resp.Data);
- await Ioc.Default
+ await serviceProvider
.GetRequiredService()
.ProcessInputCookieAsync(cookie)
.ConfigureAwait(false);
@@ -97,9 +103,9 @@ internal class TestViewModel : Abstraction.ViewModel
private async Task DownloadStaticFileAsync()
{
- BitsManager bitsManager = Ioc.Default.GetRequiredService();
+ BitsManager bitsManager = serviceProvider.GetRequiredService();
Uri testUri = new(Web.HutaoEndpoints.StaticZip("AvatarIcon"));
- ILogger logger = Ioc.Default.GetRequiredService>();
+ ILogger logger = serviceProvider.GetRequiredService>();
Progress progress = new(status => logger.LogInformation("{info}", status));
(bool isOk, TempFile file) = await bitsManager.DownloadAsync(testUri, progress).ConfigureAwait(false);
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/UserViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/UserViewModel.cs
index 2cea4ea9..32334aad 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/UserViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/UserViewModel.cs
@@ -3,6 +3,7 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
+using Microsoft.Extensions.DependencyInjection;
using Snap.Hutao.Core.ExceptionService;
using Snap.Hutao.Core.IO.DataTransfer;
using Snap.Hutao.Extension;
@@ -24,6 +25,7 @@ namespace Snap.Hutao.ViewModel;
[Injection(InjectAs.Singleton)]
internal class UserViewModel : ObservableObject
{
+ private readonly IServiceProvider serviceProvider;
private readonly IUserService userService;
private readonly IInfoBarService infoBarService;
@@ -33,12 +35,14 @@ internal class UserViewModel : ObservableObject
///
/// 构造一个新的用户视图模型
///
+ /// 服务提供器
/// 用户服务
/// 信息条服务
- public UserViewModel(IUserService userService, IInfoBarService infoBarService)
+ public UserViewModel(IServiceProvider serviceProvider)
{
- this.userService = userService;
- this.infoBarService = infoBarService;
+ userService = serviceProvider.GetRequiredService();
+ infoBarService = serviceProvider.GetRequiredService();
+ this.serviceProvider = serviceProvider;
OpenUICommand = new AsyncRelayCommand(OpenUIAsync);
AddUserCommand = new AsyncRelayCommand(AddUserAsync);
@@ -155,7 +159,7 @@ internal class UserViewModel : ObservableObject
{
if (Core.WebView2Helper.IsSupported)
{
- Ioc.Default.GetRequiredService().Navigate(INavigationAwaiter.Default);
+ serviceProvider.GetRequiredService().Navigate(INavigationAwaiter.Default);
}
else
{
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/WelcomeViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/WelcomeViewModel.cs
index 4ad59de3..c8bd97e8 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/WelcomeViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/WelcomeViewModel.cs
@@ -207,15 +207,22 @@ internal class WelcomeViewModel : ObservableObject
private void ExtractFiles(string file)
{
IImageCacheFilePathOperation imageCache = serviceProvider.GetRequiredService().ImplictAs()!;
-
- using (ZipArchive archive = ZipFile.OpenRead(file))
+ try
{
- foreach (ZipArchiveEntry entry in archive.Entries)
+ using (ZipArchive archive = ZipFile.OpenRead(file))
{
- string destPath = imageCache.GetFilePathFromCategoryAndFileName(fileName, entry.FullName);
- entry.ExtractToFile(destPath, true);
+ foreach (ZipArchiveEntry entry in archive.Entries)
+ {
+ string destPath = imageCache.GetFilePathFromCategoryAndFileName(fileName, entry.FullName);
+ entry.ExtractToFile(destPath, true);
+ }
}
}
+ catch (InvalidDataException)
+ {
+ // System.IO.InvalidDataException: End of Central Directory record could not be found.
+ // Basically the file downloaded is corrupted, skip anyway.
+ }
}
}
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiAvatarViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiAvatarViewModel.cs
index 1f84f485..2d47748c 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiAvatarViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiAvatarViewModel.cs
@@ -3,6 +3,7 @@
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.WinUI.UI;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Primitives;
using Snap.Hutao.Extension;
using Snap.Hutao.Model.Binding.Cultivation;
@@ -34,6 +35,7 @@ namespace Snap.Hutao.ViewModel;
[Injection(InjectAs.Scoped)]
internal class WikiAvatarViewModel : Abstraction.ViewModel
{
+ private readonly IServiceProvider serviceProvider;
private readonly IMetadataService metadataService;
private readonly IHutaoCache hutaoCache;
@@ -44,12 +46,13 @@ internal class WikiAvatarViewModel : Abstraction.ViewModel
///
/// 构造一个新的角色资料视图模型
///
- /// 元数据服务
- /// 胡桃缓存
- public WikiAvatarViewModel(IMetadataService metadataService, IHutaoCache hutaoCache)
+ /// 服务提供器
+ public WikiAvatarViewModel(IServiceProvider serviceProvider)
{
- this.metadataService = metadataService;
- this.hutaoCache = hutaoCache;
+ metadataService = serviceProvider.GetRequiredService();
+ hutaoCache = serviceProvider.GetRequiredService();
+ this.serviceProvider = serviceProvider;
+
OpenUICommand = new AsyncRelayCommand(OpenUIAsync);
CultivateCommand = new AsyncRelayCommand(CultivateAsync);
FilterCommand = new RelayCommand(ApplyFilter);
@@ -123,8 +126,8 @@ internal class WikiAvatarViewModel : Abstraction.ViewModel
{
if (avatar != null)
{
- IInfoBarService infoBarService = Ioc.Default.GetRequiredService();
- IUserService userService = Ioc.Default.GetRequiredService();
+ IInfoBarService infoBarService = serviceProvider.GetRequiredService();
+ IUserService userService = serviceProvider.GetRequiredService();
if (userService.Current != null)
{
@@ -136,7 +139,7 @@ internal class WikiAvatarViewModel : Abstraction.ViewModel
if (isOk)
{
- Response consumptionResponse = await Ioc.Default
+ Response consumptionResponse = await serviceProvider
.GetRequiredService()
.ComputeAsync(userService.Current.Entity, delta)
.ConfigureAwait(false);
@@ -146,18 +149,25 @@ internal class WikiAvatarViewModel : Abstraction.ViewModel
CalcConsumption consumption = consumptionResponse.Data;
List items = CalcItemHelper.Merge(consumption.AvatarConsume, consumption.AvatarSkillConsume);
- bool saved = await Ioc.Default
- .GetRequiredService()
- .SaveConsumptionAsync(CultivateType.AvatarAndSkill, avatar.Id, items)
- .ConfigureAwait(false);
+ try
+ {
+ bool saved = await serviceProvider
+ .GetRequiredService()
+ .SaveConsumptionAsync(CultivateType.AvatarAndSkill, avatar.Id, items)
+ .ConfigureAwait(false);
- if (saved)
- {
- infoBarService.Success(SH.ViewModelCultivationEntryAddSuccess);
+ if (saved)
+ {
+ infoBarService.Success(SH.ViewModelCultivationEntryAddSuccess);
+ }
+ else
+ {
+ infoBarService.Warning(SH.ViewModelCultivationEntryAddWarning);
+ }
}
- else
+ catch (Core.ExceptionService.UserdataCorruptedException ex)
{
- infoBarService.Warning(SH.ViewModelCultivationEntryAddWarning);
+ infoBarService.Error(ex, SH.ViewModelCultivationAddWarning);
}
}
}
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiWeaponViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiWeaponViewModel.cs
index a6fa4f2c..982c66f0 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiWeaponViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiWeaponViewModel.cs
@@ -3,6 +3,7 @@
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.WinUI.UI;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Primitives;
using Snap.Hutao.Extension;
using Snap.Hutao.Model.Binding.Cultivation;
@@ -37,6 +38,7 @@ internal class WikiWeaponViewModel : Abstraction.ViewModel
11419, 11420, 11421, // 「一心传」名刀
};
+ private readonly IServiceProvider serviceProvider;
private readonly IMetadataService metadataService;
private readonly IHutaoCache hutaoCache;
@@ -47,12 +49,12 @@ internal class WikiWeaponViewModel : Abstraction.ViewModel
///
/// 构造一个新的武器资料视图模型
///
- /// 元数据服务
- /// 胡桃缓存
- public WikiWeaponViewModel(IMetadataService metadataService, IHutaoCache hutaoCache)
+ /// 服务提供器
+ public WikiWeaponViewModel(IServiceProvider serviceProvider)
{
- this.metadataService = metadataService;
- this.hutaoCache = hutaoCache;
+ metadataService = serviceProvider.GetRequiredService();
+ hutaoCache = serviceProvider.GetRequiredService();
+ this.serviceProvider = serviceProvider;
OpenUICommand = new AsyncRelayCommand(OpenUIAsync);
CultivateCommand = new AsyncRelayCommand(CultivateAsync);
@@ -122,8 +124,8 @@ internal class WikiWeaponViewModel : Abstraction.ViewModel
{
if (weapon != null)
{
- IInfoBarService infoBarService = Ioc.Default.GetRequiredService();
- IUserService userService = Ioc.Default.GetRequiredService();
+ IInfoBarService infoBarService = serviceProvider.GetRequiredService();
+ IUserService userService = serviceProvider.GetRequiredService();
if (userService.Current != null)
{
@@ -135,7 +137,7 @@ internal class WikiWeaponViewModel : Abstraction.ViewModel
if (isOk)
{
- Response consumptionResponse = await Ioc.Default
+ Response consumptionResponse = await serviceProvider
.GetRequiredService()
.ComputeAsync(userService.Current.Entity, delta)
.ConfigureAwait(false);
@@ -144,18 +146,25 @@ internal class WikiWeaponViewModel : Abstraction.ViewModel
{
CalcConsumption consumption = consumptionResponse.Data;
- bool saved = await Ioc.Default
- .GetRequiredService()
- .SaveConsumptionAsync(CultivateType.Weapon, weapon.Id, consumption.WeaponConsume.EmptyIfNull())
- .ConfigureAwait(false);
+ try
+ {
+ bool saved = await serviceProvider
+ .GetRequiredService()
+ .SaveConsumptionAsync(CultivateType.Weapon, weapon.Id, consumption.WeaponConsume.EmptyIfNull())
+ .ConfigureAwait(false);
- if (saved)
- {
- infoBarService.Success(SH.ViewModelCultivationEntryAddSuccess);
+ if (saved)
+ {
+ infoBarService.Success(SH.ViewModelCultivationEntryAddSuccess);
+ }
+ else
+ {
+ infoBarService.Warning(SH.ViewModelCultivationEntryAddWarning);
+ }
}
- else
+ catch (Core.ExceptionService.UserdataCorruptedException ex)
{
- infoBarService.Warning(SH.ViewModelCultivationEntryAddWarning);
+ infoBarService.Error(ex, SH.ViewModelCultivationAddWarning);
}
}
}
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretHandler.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretHandler.cs
index 5351d6a1..9fd7a1cc 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretHandler.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretHandler.cs
@@ -3,7 +3,6 @@
using Snap.Hutao.Web.Request;
using System.Net.Http;
-using System.Text;
namespace Snap.Hutao.Web.Hoyolab.DynamicSecret;
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/HttpClientExtensions.cs b/src/Snap.Hutao/Snap.Hutao/Web/HttpClientExtensions.cs
index 8c9e1031..61aecb37 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/HttpClientExtensions.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/HttpClientExtensions.cs
@@ -2,7 +2,6 @@
// Licensed under the MIT license.
using Snap.Hutao.Core.Logging;
-using Snap.Hutao.Extension;
using System.IO;
using System.Net.Http;
using System.Net.Http.Json;