fix crashes

This commit is contained in:
DismissedLight
2023-01-11 16:02:14 +08:00
parent eec010870a
commit 9ef48ab05c
16 changed files with 69 additions and 54 deletions

View File

@@ -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, "未经处理的异常");

View File

@@ -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;

View File

@@ -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,
};
}
}

View File

@@ -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

View File

@@ -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,
};
}
}
}

View File

@@ -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;

View File

@@ -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"

View File

@@ -267,7 +267,7 @@ internal class AchievementViewModel
}
openUICompletionSource.TrySetResult(metaInitialized);
IsInitialized = true;
IsInitialized = metaInitialized;
}
#region

View File

@@ -32,6 +32,7 @@ namespace Snap.Hutao.ViewModel;
/// <summary>
/// 角色属性视图模型
/// TODO: support page unload as cancellation
/// </summary>
[Injection(InjectAs.Scoped)]
internal class AvatarPropertyViewModel : ObservableObject, ISupportCancellation

View File

@@ -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()

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;