fix spiralabyss damage rank empty crash

This commit is contained in:
DismissedLight
2023-10-14 17:26:06 +08:00
parent 830556a043
commit 9ed53e8c34
6 changed files with 139 additions and 124 deletions

View File

@@ -3,6 +3,7 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Markup;
using Microsoft.Web.WebView2.Core;
using Snap.Hutao.Control.Theme;
using Snap.Hutao.Web.Bridge;
@@ -132,8 +133,6 @@ internal sealed partial class AnnouncementContentViewer : UserControl
private void OnUnloaded(object sender, RoutedEventArgs e)
{
WebView.CoreWebView2.WebMessageReceived -= webMessageReceivedHandler;
Loaded -= loadEventHandler;
Unloaded -= unloadEventHandler;
}
private async ValueTask LoadAnnouncementAsync()

View File

@@ -18,15 +18,12 @@ namespace Snap.Hutao.View.Control;
[DependencyProperty("SourceProvider", typeof(IWebViewerSource))]
internal partial class WebViewer : UserControl, IRecipient<UserChangedMessage>
{
[SuppressMessage("", "SA1310")]
private static readonly Guid ICoreWebView2_13iid = Guid.Parse("314B5846-DBC7-5DE4-A792-647EA0F3296A");
private readonly IServiceProvider serviceProvider;
private readonly IInfoBarService infoBarService;
private readonly RoutedEventHandler loadEventHandler;
private readonly RoutedEventHandler unloadEventHandler;
private MiHoYoJSInterface? jsInterface;
private bool isInitializingOrInitialized;
public WebViewer()
{
@@ -36,10 +33,8 @@ internal partial class WebViewer : UserControl, IRecipient<UserChangedMessage>
serviceProvider.GetRequiredService<IMessenger>().Register(this);
loadEventHandler = OnLoaded;
unloadEventHandler = OnUnloaded;
Loaded += loadEventHandler;
Unloaded += unloadEventHandler;
}
public void Receive(UserChangedMessage message)
@@ -48,34 +43,20 @@ internal partial class WebViewer : UserControl, IRecipient<UserChangedMessage>
taskContext.InvokeOnMainThread(RefreshWebview2Content);
}
private static bool IsCoreWebView2ProfileAvailable(CoreWebView2 coreWebView2)
{
int hr = ((IWinRTObject)coreWebView2).NativeObject.TryAs(ICoreWebView2_13iid, out ObjectReference<IUnknownVftbl> objRef);
using (objRef)
{
if (hr >= 0)
{
// ICoreWebView2_13.Profile is available
return true;
}
}
return false;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
InitializeAsync().SafeForget();
}
private void OnUnloaded(object sender, RoutedEventArgs e)
{
Loaded -= loadEventHandler;
Unloaded -= unloadEventHandler;
}
private async ValueTask InitializeAsync()
{
if (isInitializingOrInitialized)
{
return;
}
isInitializingOrInitialized = true;
await WebView.EnsureCoreWebView2Async();
WebView.CoreWebView2.DisableDevToolsOnReleaseBuild();
RefreshWebview2Content();
@@ -106,20 +87,22 @@ internal partial class WebViewer : UserControl, IRecipient<UserChangedMessage>
string source = SourceProvider.GetSource(userAndUid);
if (!string.IsNullOrEmpty(source))
{
if (IsCoreWebView2ProfileAvailable(coreWebView2))
try
{
await coreWebView2.Profile.ClearBrowsingDataAsync();
}
else
catch (InvalidCastException)
{
infoBarService.Warning(SH.ViewControlWebViewerCoreWebView2ProfileQueryInterfaceFailed);
await coreWebView2.DeleteCookiesAsync(userAndUid.IsOversea).ConfigureAwait(true);
}
CoreWebView2Navigator navigator = new(coreWebView2);
await navigator.NavigateAsync("about:blank").ConfigureAwait(true);
coreWebView2.SetCookie(user.CookieToken, user.LToken);
_ = userAndUid.User.IsOversea ? coreWebView2.SetMobileOverseaUserAgent() : coreWebView2.SetMobileUserAgent();
coreWebView2
.SetCookie(user.CookieToken, user.LToken, userAndUid.IsOversea)
.SetMobileUserAgent(userAndUid.IsOversea);
jsInterface?.Detach();
jsInterface = SourceProvider.CreateJsInterface(serviceProvider, coreWebView2, userAndUid);

View File

@@ -22,10 +22,13 @@
<StackPanel Margin="16,16,16,16" Spacing="{StaticResource SettingsCardSpacing}">
<Border cw:Effects.Shadow="{ThemeResource CompatCardShadow}">
<Grid Height="280" Style="{ThemeResource GridCardStyle}">
<Image
VerticalAlignment="Center"
Source="ms-appx:///Resource/BlurBackground.png"
Stretch="Fill"/>
<Border CornerRadius="{ThemeResource ControlCornerRadius}">
<Image
VerticalAlignment="Center"
Source="ms-appx:///Resource/BlurBackground.png"
Stretch="Fill"/>
</Border>
<Grid Background="{ThemeResource SystemControlBackgroundAltMediumBrush}">
<Grid.RowDefinitions>
<RowDefinition/>
@@ -74,29 +77,31 @@
Margin="0,4"
Text="Copyright © 2022 - 2023 DGP Studio. All Rights Reserved."
TextWrapping="Wrap"/>
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageSettingAboutHeader}"/>
<cwc:SettingsCard
<cwc:SettingsExpander
Description="{Binding HutaoOptions.Version}"
Header="{shcm:ResourceString Name=AppName}"
HeaderIcon="{shcm:FontIcon Glyph=&#xECAA;}"/>
HeaderIcon="{shcm:FontIcon Glyph=&#xECAA;}"
IsExpanded="True">
<cwc:SettingsExpander.Items>
<cwc:SettingsCard
ActionIcon="{shcm:FontIcon Glyph=&#xE8C8;}"
ActionIconToolTip="{shcm:ResourceString Name=ViewPageSettingCopyDeviceIdAction}"
Command="{Binding CopyDeviceIdCommand}"
Description="{Binding HutaoOptions.DeviceId}"
Header="{shcm:ResourceString Name=ViewPageSettingDeviceIdHeader}"
IsClickEnabled="True"/>
<cwc:SettingsCard Description="{Binding HutaoOptions.WebView2Version}" Header="{shcm:ResourceString Name=ViewPageSettingWebview2Header}"/>
</cwc:SettingsExpander.Items>
</cwc:SettingsExpander>
<cwc:SettingsCard
Command="{Binding NavigateToHutaoPassportCommand}"
Description="{Binding UserOptions.UserName}"
Header="{shcm:ResourceString Name=ViewPageSettingHutaoPassportHeader}"
HeaderIcon="{shcm:FontIcon Glyph=&#xE716;}"
IsClickEnabled="True"/>
<cwc:SettingsCard
ActionIcon="{shcm:FontIcon Glyph=&#xE8C8;}"
ActionIconToolTip="{shcm:ResourceString Name=ViewPageSettingCopyDeviceIdAction}"
Command="{Binding CopyDeviceIdCommand}"
Description="{Binding HutaoOptions.DeviceId}"
Header="{shcm:ResourceString Name=ViewPageSettingDeviceIdHeader}"
HeaderIcon="{shcm:FontIcon Glyph=&#xE975;}"
IsClickEnabled="True"/>
<cwc:SettingsCard
Description="{Binding HutaoOptions.WebView2Version}"
Header="{shcm:ResourceString Name=ViewPageSettingWebview2Header}"
HeaderIcon="{shcm:FontIcon Glyph=&#xECAA;}"/>
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageSettingGeetestVerificationHeader}"/>
<cwc:SettingsCard
@@ -141,7 +146,8 @@
<cwc:SettingsExpander
Description="{shcm:ResourceString Name=ViewpageSettingHomeCardDescription}"
Header="{shcm:ResourceString Name=ViewpageSettingHomeCardHeader}"
HeaderIcon="{shcm:FontIcon Glyph=&#xEE40;}">
HeaderIcon="{shcm:FontIcon Glyph=&#xEE40;}"
IsExpanded="True">
<cwc:SettingsExpander.Items>
<cwc:SettingsCard Header="{shcm:ResourceString Name=ViewpageSettingHomeCardItemLaunchGameHeader}">
<ToggleSwitch
@@ -238,7 +244,7 @@
IsClickEnabled="True"/>
<cwc:SettingsCard
Margin="0,4,0,0"
Margin="0,3,0,0"
ActionIcon="{shcm:FontIcon Glyph=&#xE76C;}"
ActionIconToolTip="{shcm:ResourceString Name=ViewPageSettingStorageOpenAction}"
Command="{Binding OpenCacheFolderCommand}"
@@ -276,7 +282,7 @@
</StackPanel>
</cwc:SettingsCard>
<InfoBar
Margin="0,4,0,0"
Margin="0,3,0,0"
IsClosable="False"
IsOpen="True"
Message="{shcm:ResourceString Name=ViewPageSettingDangerousHint}"

View File

@@ -18,11 +18,6 @@ internal sealed class SpiralAbyssView : IEntityOnly<SpiralAbyssEntry?>,
{
private readonly SpiralAbyssEntry? entity;
/// <summary>
/// 构造一个新的深渊视图
/// </summary>
/// <param name="entity">实体</param>
/// <param name="idAvatarMap">Id角色映射</param>
private SpiralAbyssView(SpiralAbyssEntry entity, SpiralAbyssMetadataContext context)
: this(context.IdScheduleMap[entity.ScheduleId], context)
{
@@ -32,12 +27,12 @@ internal sealed class SpiralAbyssView : IEntityOnly<SpiralAbyssEntry?>,
TotalBattleTimes = spiralAbyss.TotalBattleTimes;
TotalStar = spiralAbyss.TotalStar;
MaxFloor = spiralAbyss.MaxFloor;
Reveals = spiralAbyss.RevealRank.SelectList(r => new RankAvatar(r.Value, context.IdAvatarMap[r.AvatarId]));
Defeat = spiralAbyss.DefeatRank.Select(r => new RankAvatar(r.Value, context.IdAvatarMap[r.AvatarId])).SingleOrDefault();
Damage = spiralAbyss.DamageRank.Select(r => new RankAvatar(r.Value, context.IdAvatarMap[r.AvatarId])).SingleOrDefault();
TakeDamage = spiralAbyss.TakeDamageRank.Select(r => new RankAvatar(r.Value, context.IdAvatarMap[r.AvatarId])).SingleOrDefault();
NormalSkill = spiralAbyss.NormalSkillRank.Select(r => new RankAvatar(r.Value, context.IdAvatarMap[r.AvatarId])).SingleOrDefault();
EnergySkill = spiralAbyss.EnergySkillRank.Select(r => new RankAvatar(r.Value, context.IdAvatarMap[r.AvatarId])).SingleOrDefault();
Reveals = ToRankAvatars(spiralAbyss.RevealRank, context);
Defeat = ToRankAvatar(spiralAbyss.DefeatRank, context);
Damage = ToRankAvatar(spiralAbyss.DamageRank, context);
TakeDamage = ToRankAvatar(spiralAbyss.TakeDamageRank, context);
NormalSkill = ToRankAvatar(spiralAbyss.NormalSkillRank, context);
EnergySkill = ToRankAvatar(spiralAbyss.EnergySkillRank, context);
Engaged = true;
foreach (Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.Floor webFloor in spiralAbyss.Floors)
@@ -143,4 +138,15 @@ internal sealed class SpiralAbyssView : IEntityOnly<SpiralAbyssEntry?>,
return new(meta, context);
}
}
private static List<RankAvatar> ToRankAvatars(List<Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.Rank> ranks, SpiralAbyssMetadataContext context)
{
return ranks.Where(r => r.AvatarId != 0U).Select(r => new RankAvatar(r.Value, context.IdAvatarMap[r.AvatarId])).ToList();
}
private static RankAvatar? ToRankAvatar(List<Web.Hoyolab.Takumi.GameRecord.SpiralAbyss.Rank> ranks, SpiralAbyssMetadataContext context)
{
return ranks.Where(r => r.AvatarId != 0U).Select(r => new RankAvatar(r.Value, context.IdAvatarMap[r.AvatarId])).SingleOrDefault();
}
}

View File

@@ -2,7 +2,6 @@
// Licensed under the MIT license.
using Microsoft.Web.WebView2.Core;
using Snap.Hutao.Web.Hoyolab;
using System.Diagnostics;
namespace Snap.Hutao.Web.Bridge;
@@ -38,62 +37,4 @@ internal static class CoreWebView2Extension
manager.DeleteCookie(item);
}
}
/// <summary>
/// 设置 移动端UA
/// </summary>
/// <param name="webView">webView2</param>
/// <returns>链式调用的WebView2</returns>
public static CoreWebView2 SetMobileUserAgent(this CoreWebView2 webView)
{
webView.Settings.UserAgent = HoyolabOptions.MobileUserAgent;
return webView;
}
/// <summary>
/// 设置 移动端OsUA
/// </summary>
/// <param name="webView">webView2</param>
/// <returns>链式调用的WebView2</returns>
public static CoreWebView2 SetMobileOverseaUserAgent(this CoreWebView2 webView)
{
webView.Settings.UserAgent = HoyolabOptions.MobileUserAgentOversea;
return webView;
}
/// <summary>
/// 设置WebView2的Cookie
/// </summary>
/// <param name="webView">webView2</param>
/// <param name="cookieToken">CookieToken</param>
/// <param name="lToken">LToken</param>
/// <param name="isOversea">是否为国际服,用于改变 cookie domain</param>
/// <returns>链式调用的WebView2</returns>
public static CoreWebView2 SetCookie(this CoreWebView2 webView, Cookie? cookieToken = null, Cookie? lToken = null, bool isOversea = false)
{
CoreWebView2CookieManager cookieManager = webView.CookieManager;
if (cookieToken is not null)
{
cookieManager
.AddMihoyoCookie(Cookie.ACCOUNT_ID, cookieToken, isOversea)
.AddMihoyoCookie(Cookie.COOKIE_TOKEN, cookieToken, isOversea);
}
if (lToken is not null)
{
cookieManager
.AddMihoyoCookie(Cookie.LTUID, lToken, isOversea)
.AddMihoyoCookie(Cookie.LTOKEN, lToken, isOversea);
}
return webView;
}
private static CoreWebView2CookieManager AddMihoyoCookie(this CoreWebView2CookieManager manager, string name, Cookie cookie, bool isOversea = false)
{
string domain = isOversea ? ".hoyolab.com" : ".mihoyo.com";
manager.AddOrUpdateCookie(manager.CreateCookie(name, cookie[name], domain, "/"));
return manager;
}
}

View File

@@ -0,0 +1,80 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Microsoft.Web.WebView2.Core;
using Snap.Hutao.Web.Hoyolab;
namespace Snap.Hutao.Web.Bridge;
internal static class HoyolabCoreWebView2Extension
{
public static ValueTask DeleteCookiesAsync(this CoreWebView2 webView, bool isOversea)
{
return webView.DeleteCookiesAsync(isOversea ? ".hoyolab.com" : ".mihoyo.com");
}
public static CoreWebView2 SetMobileUserAgent(this CoreWebView2 webView, bool isOversea)
{
return isOversea
? webView.SetMobileUserAgentOversea()
: webView.SetMobileUserAgentChinese();
}
/// <summary>
/// 设置 移动端UA
/// </summary>
/// <param name="webView">webView2</param>
/// <returns>链式调用的WebView2</returns>
public static CoreWebView2 SetMobileUserAgentChinese(this CoreWebView2 webView)
{
webView.Settings.UserAgent = HoyolabOptions.MobileUserAgent;
return webView;
}
/// <summary>
/// 设置 移动端OsUA
/// </summary>
/// <param name="webView">webView2</param>
/// <returns>链式调用的WebView2</returns>
public static CoreWebView2 SetMobileUserAgentOversea(this CoreWebView2 webView)
{
webView.Settings.UserAgent = HoyolabOptions.MobileUserAgentOversea;
return webView;
}
/// <summary>
/// 设置WebView2的Cookie
/// </summary>
/// <param name="webView">webView2</param>
/// <param name="cookieToken">CookieToken</param>
/// <param name="lToken">LToken</param>
/// <param name="isOversea">是否为国际服,用于改变 cookie domain</param>
/// <returns>链式调用的WebView2</returns>
public static CoreWebView2 SetCookie(this CoreWebView2 webView, Cookie? cookieToken = null, Cookie? lToken = null, bool isOversea = false)
{
CoreWebView2CookieManager cookieManager = webView.CookieManager;
if (cookieToken is not null)
{
cookieManager
.AddMihoyoCookie(Cookie.ACCOUNT_ID, cookieToken, isOversea)
.AddMihoyoCookie(Cookie.COOKIE_TOKEN, cookieToken, isOversea);
}
if (lToken is not null)
{
cookieManager
.AddMihoyoCookie(Cookie.LTUID, lToken, isOversea)
.AddMihoyoCookie(Cookie.LTOKEN, lToken, isOversea);
}
return webView;
}
private static CoreWebView2CookieManager AddMihoyoCookie(this CoreWebView2CookieManager manager, string name, Cookie cookie, bool isOversea = false)
{
string domain = isOversea ? ".hoyolab.com" : ".mihoyo.com";
manager.AddOrUpdateCookie(manager.CreateCookie(name, cookie[name], domain, "/"));
return manager;
}
}