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 89de9538..69696e8f 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Control/AnnouncementContentViewer.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/View/Control/AnnouncementContentViewer.xaml.cs @@ -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() diff --git a/src/Snap.Hutao/Snap.Hutao/View/Control/WebViewer.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Control/WebViewer.xaml.cs index 8974cdc2..a180ea3e 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Control/WebViewer.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/View/Control/WebViewer.xaml.cs @@ -18,15 +18,12 @@ namespace Snap.Hutao.View.Control; [DependencyProperty("SourceProvider", typeof(IWebViewerSource))] internal partial class WebViewer : UserControl, IRecipient { - [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 serviceProvider.GetRequiredService().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 taskContext.InvokeOnMainThread(RefreshWebview2Content); } - private static bool IsCoreWebView2ProfileAvailable(CoreWebView2 coreWebView2) - { - int hr = ((IWinRTObject)coreWebView2).NativeObject.TryAs(ICoreWebView2_13iid, out ObjectReference 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 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); diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml index 23a69bd9..1472301e 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml @@ -22,10 +22,13 @@ - + + + + @@ -74,29 +77,31 @@ Margin="0,4" Text="Copyright © 2022 - 2023 DGP Studio. All Rights Reserved." TextWrapping="Wrap"/> + - + HeaderIcon="{shcm:FontIcon Glyph=}" + IsExpanded="True"> + + + + + - - + + HeaderIcon="{shcm:FontIcon Glyph=}" + IsExpanded="True"> , { private readonly SpiralAbyssEntry? entity; - /// - /// 构造一个新的深渊视图 - /// - /// 实体 - /// Id角色映射 private SpiralAbyssView(SpiralAbyssEntry entity, SpiralAbyssMetadataContext context) : this(context.IdScheduleMap[entity.ScheduleId], context) { @@ -32,12 +27,12 @@ internal sealed class SpiralAbyssView : IEntityOnly, 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, return new(meta, context); } } + + private static List ToRankAvatars(List 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 ranks, SpiralAbyssMetadataContext context) + { + return ranks.Where(r => r.AvatarId != 0U).Select(r => new RankAvatar(r.Value, context.IdAvatarMap[r.AvatarId])).SingleOrDefault(); + } + } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Bridge/CoreWebView2Extension.cs b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/CoreWebView2Extension.cs index d09b5013..123e611f 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Bridge/CoreWebView2Extension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/CoreWebView2Extension.cs @@ -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); } } - - /// - /// 设置 移动端UA - /// - /// webView2 - /// 链式调用的WebView2 - public static CoreWebView2 SetMobileUserAgent(this CoreWebView2 webView) - { - webView.Settings.UserAgent = HoyolabOptions.MobileUserAgent; - return webView; - } - - /// - /// 设置 移动端OsUA - /// - /// webView2 - /// 链式调用的WebView2 - public static CoreWebView2 SetMobileOverseaUserAgent(this CoreWebView2 webView) - { - webView.Settings.UserAgent = HoyolabOptions.MobileUserAgentOversea; - return webView; - } - - /// - /// 设置WebView2的Cookie - /// - /// webView2 - /// CookieToken - /// LToken - /// 是否为国际服,用于改变 cookie domain - /// 链式调用的WebView2 - 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; - } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Bridge/HoyolabCoreWebView2Extension.cs b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/HoyolabCoreWebView2Extension.cs new file mode 100644 index 00000000..7131fdcc --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/HoyolabCoreWebView2Extension.cs @@ -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(); + } + + /// + /// 设置 移动端UA + /// + /// webView2 + /// 链式调用的WebView2 + public static CoreWebView2 SetMobileUserAgentChinese(this CoreWebView2 webView) + { + webView.Settings.UserAgent = HoyolabOptions.MobileUserAgent; + return webView; + } + + /// + /// 设置 移动端OsUA + /// + /// webView2 + /// 链式调用的WebView2 + public static CoreWebView2 SetMobileUserAgentOversea(this CoreWebView2 webView) + { + webView.Settings.UserAgent = HoyolabOptions.MobileUserAgentOversea; + return webView; + } + + /// + /// 设置WebView2的Cookie + /// + /// webView2 + /// CookieToken + /// LToken + /// 是否为国际服,用于改变 cookie domain + /// 链式调用的WebView2 + 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; + } +} \ No newline at end of file