mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
fix crashes
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
|
||||
using Microsoft.UI.Xaml;
|
||||
using Snap.Hutao.Core.Logging;
|
||||
using Snap.Hutao.Web.Hutao;
|
||||
|
||||
namespace Snap.Hutao.Core.ExceptionService;
|
||||
|
||||
@@ -30,9 +29,9 @@ internal class ExceptionRecorder
|
||||
private void OnAppUnhandledException(object? sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
|
||||
{
|
||||
#if RELEASE
|
||||
#pragma warning disable VSTHRD002
|
||||
#pragma warning disable VSTHRD002
|
||||
Ioc.Default.GetRequiredService<Web.Hutao.HomaClient2>().UploadLogAsync(e.Exception).GetAwaiter().GetResult();
|
||||
#pragma warning restore VSTHRD002
|
||||
#pragma warning restore VSTHRD002
|
||||
#endif
|
||||
logger.LogError(EventIds.UnhandledException, e.Exception, "未经处理的异常");
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Snap.Hutao.Core.Logging;
|
||||
using Snap.Hutao.Factory.Abstraction;
|
||||
using Snap.Hutao.Web.Hutao;
|
||||
|
||||
namespace Snap.Hutao.Factory;
|
||||
|
||||
|
||||
@@ -55,4 +55,38 @@ public class Material
|
||||
/// 效果描述
|
||||
/// </summary>
|
||||
public string? EffectDescription { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否为物品栏物品
|
||||
/// </summary>
|
||||
/// <returns>是否为物品栏物品</returns>
|
||||
public bool IsInventoryItem()
|
||||
{
|
||||
// 原质
|
||||
if (Id == 112001)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 摩拉
|
||||
if (Id == 202)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (TypeDescription.EndsWith("区域特产"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return TypeDescription switch
|
||||
{
|
||||
"角色经验素材" => true,
|
||||
"角色培养素材" => true,
|
||||
"天赋培养素材" => true,
|
||||
"武器强化素材" => true,
|
||||
"武器突破素材" => true,
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ internal class AvatarInfoService : IAvatarInfoService
|
||||
|
||||
if (resp.IsValid)
|
||||
{
|
||||
IList<EnkaAvatarInfo> list = UpdateDbAvatarInfos(userAndUid.Uid.Value, resp.AvatarInfoList);
|
||||
IList<EnkaAvatarInfo> list = UpdateDbAvatarInfos(userAndUid.Uid.Value, resp.AvatarInfoList, token);
|
||||
Summary summary = await GetSummaryCoreAsync(resp.PlayerInfo, list, token).ConfigureAwait(false);
|
||||
token.ThrowIfCancellationRequested();
|
||||
return new(RefreshResult.Ok, summary);
|
||||
@@ -90,7 +90,7 @@ internal class AvatarInfoService : IAvatarInfoService
|
||||
case RefreshOption.RequestFromHoyolabGameRecord:
|
||||
{
|
||||
EnkaPlayerInfo info = EnkaPlayerInfo.CreateEmpty(userAndUid.Uid.Value);
|
||||
IList<EnkaAvatarInfo> list = await UpdateDbAvatarInfosByGameRecordCharacterAsync(userAndUid).ConfigureAwait(false);
|
||||
IList<EnkaAvatarInfo> list = await UpdateDbAvatarInfosByGameRecordCharacterAsync(userAndUid, token).ConfigureAwait(false);
|
||||
Summary summary = await GetSummaryCoreAsync(info, list, token).ConfigureAwait(false);
|
||||
return new(RefreshResult.Ok, summary);
|
||||
}
|
||||
@@ -98,7 +98,7 @@ internal class AvatarInfoService : IAvatarInfoService
|
||||
case RefreshOption.RequestFromHoyolabCalculate:
|
||||
{
|
||||
EnkaPlayerInfo info = EnkaPlayerInfo.CreateEmpty(userAndUid.Uid.Value);
|
||||
IList<EnkaAvatarInfo> list = await UpdateDbAvatarInfosByCalculateAvatarDetailAsync(userAndUid).ConfigureAwait(false);
|
||||
IList<EnkaAvatarInfo> list = await UpdateDbAvatarInfosByCalculateAvatarDetailAsync(userAndUid, token).ConfigureAwait(false);
|
||||
Summary summary = await GetSummaryCoreAsync(info, list, token).ConfigureAwait(false);
|
||||
return new(RefreshResult.Ok, summary);
|
||||
}
|
||||
@@ -135,8 +135,9 @@ internal class AvatarInfoService : IAvatarInfoService
|
||||
return summary;
|
||||
}
|
||||
|
||||
private List<EnkaAvatarInfo> UpdateDbAvatarInfos(string uid, IEnumerable<EnkaAvatarInfo> webInfos)
|
||||
private List<EnkaAvatarInfo> UpdateDbAvatarInfos(string uid, IEnumerable<EnkaAvatarInfo> webInfos, CancellationToken token)
|
||||
{
|
||||
token.ThrowIfCancellationRequested();
|
||||
List<ModelAvatarInfo> dbInfos = appDbContext.AvatarInfos
|
||||
.Where(i => i.Uid == uid)
|
||||
.ToList();
|
||||
@@ -148,8 +149,10 @@ internal class AvatarInfoService : IAvatarInfoService
|
||||
continue;
|
||||
}
|
||||
|
||||
ModelAvatarInfo? entity = dbInfos.SingleOrDefault(i => i.Info.AvatarId == webInfo.AvatarId);
|
||||
token.ThrowIfCancellationRequested();
|
||||
|
||||
// TODO: ensure the operation executes atomically
|
||||
ModelAvatarInfo? entity = dbInfos.SingleOrDefault(i => i.Info.AvatarId == webInfo.AvatarId);
|
||||
if (entity == null)
|
||||
{
|
||||
entity = ModelAvatarInfo.Create(uid, webInfo);
|
||||
@@ -162,10 +165,11 @@ internal class AvatarInfoService : IAvatarInfoService
|
||||
}
|
||||
}
|
||||
|
||||
token.ThrowIfCancellationRequested();
|
||||
return GetDbAvatarInfos(uid);
|
||||
}
|
||||
|
||||
private async Task<List<EnkaAvatarInfo>> UpdateDbAvatarInfosByGameRecordCharacterAsync(UserAndUid userAndUid)
|
||||
private async Task<List<EnkaAvatarInfo>> UpdateDbAvatarInfosByGameRecordCharacterAsync(UserAndUid userAndUid, CancellationToken token)
|
||||
{
|
||||
string uid = userAndUid.Uid.Value;
|
||||
List<ModelAvatarInfo> dbInfos = appDbContext.AvatarInfos
|
||||
@@ -218,7 +222,7 @@ internal class AvatarInfoService : IAvatarInfoService
|
||||
return GetDbAvatarInfos(uid);
|
||||
}
|
||||
|
||||
private async Task<List<EnkaAvatarInfo>> UpdateDbAvatarInfosByCalculateAvatarDetailAsync(UserAndUid userAndUid)
|
||||
private async Task<List<EnkaAvatarInfo>> UpdateDbAvatarInfosByCalculateAvatarDetailAsync(UserAndUid userAndUid, CancellationToken token)
|
||||
{
|
||||
string uid = userAndUid.Uid.Value;
|
||||
List<ModelAvatarInfo> dbInfos = appDbContext.AvatarInfos
|
||||
|
||||
@@ -118,7 +118,7 @@ internal class CultivationService : ICultivationService
|
||||
.ToList();
|
||||
|
||||
List<BindingInventoryItem> results = new();
|
||||
foreach (Model.Metadata.Material meta in metadata.Where(IsInventoryItem).OrderBy(m => m.Id))
|
||||
foreach (Model.Metadata.Material meta in metadata.Where(m => m.IsInventoryItem()).OrderBy(m => m.Id))
|
||||
{
|
||||
InventoryItem entity = entities.SingleOrDefault(e => e.ItemId == meta.Id) ?? InventoryItem.Create(projectId, meta.Id);
|
||||
results.Add(new(meta, entity));
|
||||
@@ -309,34 +309,4 @@ internal class CultivationService : ICultivationService
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool IsInventoryItem(Model.Metadata.Material material)
|
||||
{
|
||||
// 原质
|
||||
if (material.Id == 112001)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 摩拉
|
||||
if (material.Id == 202)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (material.TypeDescription.EndsWith("区域特产"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return material.TypeDescription switch
|
||||
{
|
||||
"角色经验素材" => true,
|
||||
"角色培养素材" => true,
|
||||
"天赋培养素材" => true,
|
||||
"武器强化素材" => true,
|
||||
"武器突破素材" => true,
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
using Snap.Hutao.Core.IO;
|
||||
using Snap.Hutao.Factory.Abstraction;
|
||||
using Windows.Storage;
|
||||
using Windows.Storage.Pickers;
|
||||
|
||||
namespace Snap.Hutao.Service.Game.Locator;
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<mxi:Interaction.Behaviors>
|
||||
<shcb:InvokeCommandOnLoadedBehavior Command="{Binding OpenUICommand}"/>
|
||||
</mxi:Interaction.Behaviors>
|
||||
<Grid>
|
||||
<Grid Visibility="{Binding IsInitialized, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Grid Visibility="{Binding Projects.Count, Converter={StaticResource Int32ToVisibilityConverter}}">
|
||||
<Rectangle
|
||||
Height="48"
|
||||
|
||||
@@ -267,7 +267,7 @@ internal class AchievementViewModel
|
||||
}
|
||||
|
||||
openUICompletionSource.TrySetResult(metaInitialized);
|
||||
IsInitialized = true;
|
||||
IsInitialized = metaInitialized;
|
||||
}
|
||||
|
||||
#region 存档操作
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Snap.Hutao.ViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// 角色属性视图模型
|
||||
/// TODO: support page unload as cancellation
|
||||
/// </summary>
|
||||
[Injection(InjectAs.Scoped)]
|
||||
internal class AvatarPropertyViewModel : ObservableObject, ISupportCancellation
|
||||
|
||||
@@ -27,6 +27,7 @@ internal class CultivationViewModel : ObservableObject, ISupportCancellation
|
||||
private readonly IMetadataService metadataService;
|
||||
private readonly ILogger<CultivationViewModel> logger;
|
||||
|
||||
private bool isInitialized;
|
||||
private ObservableCollection<CultivateProject>? projects;
|
||||
private CultivateProject? selectedProject;
|
||||
private List<Model.Binding.Inventory.InventoryItem>? inventoryItems;
|
||||
@@ -65,6 +66,11 @@ internal class CultivationViewModel : ObservableObject, ISupportCancellation
|
||||
/// <inheritdoc/>
|
||||
public CancellationToken CancellationToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否初始化完成
|
||||
/// </summary>
|
||||
public bool IsInitialized { get => isInitialized; set => SetProperty(ref isInitialized, value); }
|
||||
|
||||
/// <summary>
|
||||
/// 项目
|
||||
/// </summary>
|
||||
@@ -140,12 +146,15 @@ internal class CultivationViewModel : ObservableObject, ISupportCancellation
|
||||
|
||||
private async Task OpenUIAsync()
|
||||
{
|
||||
if (await metadataService.InitializeAsync().ConfigureAwait(true))
|
||||
bool metaInitialized = await metadataService.InitializeAsync().ConfigureAwait(true);
|
||||
if (metaInitialized)
|
||||
{
|
||||
Projects = cultivationService.GetProjectCollection();
|
||||
SelectedProject = cultivationService.Current;
|
||||
await UpdateCultivateEntriesAndInventoryItemsAsync(SelectedProject).ConfigureAwait(false);
|
||||
await UpdateCultivateEntriesAndInventoryItemsAsync(SelectedProject).ConfigureAwait(true);
|
||||
}
|
||||
|
||||
IsInitialized = metaInitialized;
|
||||
}
|
||||
|
||||
private async Task AddProjectAsync()
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Extension;
|
||||
using Snap.Hutao.Web.Response;
|
||||
using System.Net.Http;
|
||||
|
||||
|
||||
@@ -40,7 +40,12 @@ internal static class HoyolabHttpClientExtensions
|
||||
stringBuilder.Append(user.Stoken).AppendIf(user.Stoken != null, ';');
|
||||
}
|
||||
|
||||
httpClient.DefaultRequestHeaders.Set("Cookie", stringBuilder.ToString());
|
||||
string result = stringBuilder.ToString();
|
||||
if (!string.IsNullOrWhiteSpace(result))
|
||||
{
|
||||
httpClient.DefaultRequestHeaders.Set("Cookie", result);
|
||||
}
|
||||
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Extension;
|
||||
using Snap.Hutao.Model.Entity;
|
||||
using Snap.Hutao.Web.Hoyolab.Annotation;
|
||||
using Snap.Hutao.Web.Response;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Extension;
|
||||
using Snap.Hutao.Model.Binding.User;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
using Snap.Hutao.Service.Abstraction;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Extension;
|
||||
using Snap.Hutao.Model.Binding.User;
|
||||
using Snap.Hutao.Web.Hoyolab;
|
||||
using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Web.Hoyolab;
|
||||
using System.Numerics;
|
||||
using Windows.Graphics;
|
||||
using Windows.Win32.System.Diagnostics.ToolHelp;
|
||||
|
||||
Reference in New Issue
Block a user