From b5371a965698d2d5a3a519a0ed39145f1a235a67 Mon Sep 17 00:00:00 2001 From: Xhichn Date: Wed, 19 Apr 2023 18:23:45 +0800 Subject: [PATCH] Use seperated js interface for hoyolab check-in --- .../View/Dialog/AdoptCalculatorDialog.xaml.cs | 2 +- .../Dialog/CommunityGameRecordDialog.xaml.cs | 2 +- .../DailyNoteVerificationDialog.xaml.cs | 2 +- .../View/Dialog/SignInWebViewDialog.xaml.cs | 6 +-- .../Web/Bridge/MiHoYoJSInterface.cs | 47 ++++--------------- .../Web/Bridge/SignInJSInterfaceOversea.cs | 46 ++++++++++++++++++ .../Web/Bridge/SignInJsInterface.cs | 6 +-- 7 files changed, 65 insertions(+), 46 deletions(-) create mode 100644 src/Snap.Hutao/Snap.Hutao/Web/Bridge/SignInJSInterfaceOversea.cs diff --git a/src/Snap.Hutao/Snap.Hutao/View/Dialog/AdoptCalculatorDialog.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Dialog/AdoptCalculatorDialog.xaml.cs index c1fddf64..fc74e5be 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Dialog/AdoptCalculatorDialog.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/View/Dialog/AdoptCalculatorDialog.xaml.cs @@ -49,7 +49,7 @@ internal sealed partial class AdoptCalculatorDialog : ContentDialog } coreWebView2.SetCookie(user.CookieToken, user.LToken, null).SetMobileUserAgent(); - jsInterface = new(coreWebView2, scope.ServiceProvider, false); + jsInterface = new(coreWebView2, scope.ServiceProvider); jsInterface.ClosePageRequested += OnClosePageRequested; coreWebView2.Navigate($"http://webstatic.mihoyo.com/ys/event/e20200923adopt_calculator/index.html?bbs_presentation_style=fullscreen&bbs_auth_required=true&&utm_source=bbs&utm_medium=mys&utm_campaign=GameRecord"); diff --git a/src/Snap.Hutao/Snap.Hutao/View/Dialog/CommunityGameRecordDialog.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Dialog/CommunityGameRecordDialog.xaml.cs index b8981412..4fe97297 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Dialog/CommunityGameRecordDialog.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/View/Dialog/CommunityGameRecordDialog.xaml.cs @@ -47,7 +47,7 @@ internal sealed partial class CommunityGameRecordDialog : ContentDialog } coreWebView2.SetCookie(user.CookieToken, user.LToken, null).SetMobileUserAgent(); - jsInterface = new(coreWebView2, scope.ServiceProvider, false); + jsInterface = new(coreWebView2, scope.ServiceProvider); jsInterface.ClosePageRequested += OnClosePageRequested; coreWebView2.Navigate("https://webstatic.mihoyo.com/app/community-game-records/index.html"); diff --git a/src/Snap.Hutao/Snap.Hutao/View/Dialog/DailyNoteVerificationDialog.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Dialog/DailyNoteVerificationDialog.xaml.cs index 6f9cc1eb..02e2e4c3 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Dialog/DailyNoteVerificationDialog.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/View/Dialog/DailyNoteVerificationDialog.xaml.cs @@ -45,7 +45,7 @@ internal sealed partial class DailyNoteVerificationDialog : ContentDialog Model.Entity.User user = userAndUid.User; coreWebView2.SetCookie(user.CookieToken, user.LToken, null).SetMobileUserAgent(); - jsInterface = new(coreWebView2, scope.ServiceProvider, false); + jsInterface = new(coreWebView2, scope.ServiceProvider); jsInterface.ClosePageRequested += OnClosePageRequested; string query = $"?role_id={userAndUid.Uid.Value}&server={userAndUid.Uid.Region}"; diff --git a/src/Snap.Hutao/Snap.Hutao/View/Dialog/SignInWebViewDialog.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Dialog/SignInWebViewDialog.xaml.cs index db978b6b..74a2c5a7 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Dialog/SignInWebViewDialog.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/View/Dialog/SignInWebViewDialog.xaml.cs @@ -17,7 +17,7 @@ internal sealed partial class SignInWebViewDialog : ContentDialog { private readonly IServiceScope scope; [SuppressMessage("", "IDE0052")] - private SignInJsInterface? signInJsInterface; + private MiHoYoJSInterface? signInJsInterface; /// /// 构造一个新的签到网页视图对话框 @@ -49,13 +49,13 @@ internal sealed partial class SignInWebViewDialog : ContentDialog if (user.Entity.IsOversea) { coreWebView2.SetCookie(user.CookieToken, user.LToken, null, true).SetMobileOverseaUserAgent(); - signInJsInterface = new(coreWebView2, scope.ServiceProvider, true); + signInJsInterface = new SignInJSInterfaceOversea(coreWebView2, scope.ServiceProvider); coreWebView2.Navigate("https://act.hoyolab.com/ys/event/signin-sea-v3/index.html?act_id=e202102251931481"); } else { coreWebView2.SetCookie(user.CookieToken, user.LToken, null, false).SetMobileUserAgent(); - signInJsInterface = new(coreWebView2, scope.ServiceProvider, false); + signInJsInterface = new SignInJsInterface(coreWebView2, scope.ServiceProvider); coreWebView2.Navigate("https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?act_id=e202009291139501"); } } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Bridge/MiHoYoJSInterface.cs b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/MiHoYoJSInterface.cs index 0722bce1..23cc30a1 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Bridge/MiHoYoJSInterface.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/MiHoYoJSInterface.cs @@ -36,11 +36,6 @@ internal class MiHoYoJSInterface document.querySelector('body').appendChild(st); """; - private const string RemoveRotationWarningScript = """ - let landscape = document.getElementById('mihoyo_landscape'); - landscape.remove(); - """; - private readonly CoreWebView2 webView; private readonly IServiceProvider serviceProvider; private readonly ILogger logger; @@ -51,12 +46,10 @@ internal class MiHoYoJSInterface /// /// webview2 /// 服务提供器 - /// 是否为 HoYoVerse 账号 - public MiHoYoJSInterface(CoreWebView2 webView, IServiceProvider serviceProvider, bool isOversea) + public MiHoYoJSInterface(CoreWebView2 webView, IServiceProvider serviceProvider) { this.webView = webView; this.serviceProvider = serviceProvider; - IsOversea = isOversea; logger = serviceProvider.GetRequiredService>(); @@ -65,14 +58,8 @@ internal class MiHoYoJSInterface webView.NavigationStarting += OnNavigationStarting; } - public event Action? ClosePageRequested; - /// - /// 是否为 HoYoVerse 账号 - /// - public bool IsOversea { get; private set; } - /// /// 获取ActionTicket /// @@ -81,20 +68,10 @@ internal class MiHoYoJSInterface public virtual async Task GetActionTicketAsync(JsParam jsParam) { User user = serviceProvider.GetRequiredService().Current!; - - if (IsOversea) - { - // TODO: ActionTicket for hoyolab account - return null; - } - else - { - return await serviceProvider - .GetRequiredService() - .GetActionTicketBySTokenAsync(jsParam.Payload!.ActionType, user.Entity) - .ConfigureAwait(false); - } - + return await serviceProvider + .GetRequiredService() + .GetActionTicketBySTokenAsync(jsParam.Payload!.ActionType, user.Entity) + .ConfigureAwait(false); } /// @@ -110,7 +87,7 @@ internal class MiHoYoJSInterface { { "x-rpc-client_type", "5" }, { "x-rpc-device_id", Core.CoreEnvironment.HoyolabDeviceId }, - { "x-rpc-app_version", IsOversea ? Core.CoreEnvironment.HoyolabOsXrpcVersion : Core.CoreEnvironment.HoyolabXrpcVersion }, + { "x-rpc-app_version", Core.CoreEnvironment.HoyolabXrpcVersion }, }, }; } @@ -285,11 +262,12 @@ internal class MiHoYoJSInterface /// 语言与时区 public virtual JsResult> GetCurrentLocale(JsParam param) { + string cultureName = CultureInfo.CurrentCulture.Name; return new() { Data = new() { - ["language"] = CultureInfo.CurrentUICulture.Name, + ["language"] = cultureName.ToLowerInvariant(), ["timeZone"] = "GMT+8", }, }; @@ -434,17 +412,12 @@ internal class MiHoYoJSInterface private void OnDOMContentLoaded(CoreWebView2 coreWebView2, CoreWebView2DOMContentLoadedEventArgs args) { coreWebView2.ExecuteScriptAsync(HideScrollBarScript).AsTask().SafeForget(logger); - - // 移除“请旋转手机”提示所在的HTML元素 - if (IsOversea) - { - coreWebView2.ExecuteScriptAsync(RemoveRotationWarningScript).AsTask().SafeForget(logger); - } } private void OnNavigationStarting(CoreWebView2 coreWebView2, CoreWebView2NavigationStartingEventArgs args) { - if (new Uri(args.Uri).Host.EndsWith(IsOversea ? "hoyolab.com" : "mihoyo.com")) + string uriHost = new Uri(args.Uri).Host; + if (uriHost.EndsWith("mihoyo.com") || uriHost.EndsWith("hoyolab.com")) { // Execute this solve issue: When open same site second time,there might be no bridge init. coreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(InitializeJsInterfaceScript2).AsTask().SafeForget(logger); diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Bridge/SignInJSInterfaceOversea.cs b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/SignInJSInterfaceOversea.cs new file mode 100644 index 00000000..01c9fbba --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/SignInJSInterfaceOversea.cs @@ -0,0 +1,46 @@ +using Microsoft.Web.WebView2.Core; +using Snap.Hutao.Web.Bridge.Model; + +namespace Snap.Hutao.Web.Bridge; + +/// +/// HoYoLAB 签到页面JS桥 +/// +[HighQuality] +internal sealed class SignInJSInterfaceOversea : MiHoYoJSInterface +{ + private const string RemoveRotationWarningScript = """ + let landscape = document.getElementById('mihoyo_landscape'); + landscape.remove(); + """; + + private readonly ILogger logger; + + /// + public SignInJSInterfaceOversea(CoreWebView2 webView, IServiceProvider serviceProvider) + : base(webView, serviceProvider) + { + logger = serviceProvider.GetRequiredService>(); + webView.DOMContentLoaded += OnDOMContentLoaded; + } + + /// + public override JsResult> GetHttpRequestHeader(JsParam param) + { + return new() + { + Data = new Dictionary() + { + { "x-rpc-client_type", "2" }, + { "x-rpc-device_id", Core.CoreEnvironment.HoyolabDeviceId }, + { "x-rpc-app_version", Core.CoreEnvironment.HoyolabOsXrpcVersion }, + }, + }; + } + + private void OnDOMContentLoaded(CoreWebView2 coreWebView2, CoreWebView2DOMContentLoadedEventArgs args) + { + // 移除“请旋转手机”提示所在的HTML元素 + coreWebView2.ExecuteScriptAsync(RemoveRotationWarningScript).AsTask().SafeForget(logger); + } +} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Bridge/SignInJsInterface.cs b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/SignInJsInterface.cs index b4bb28a2..cd8a9fe4 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Bridge/SignInJsInterface.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Bridge/SignInJsInterface.cs @@ -13,8 +13,8 @@ namespace Snap.Hutao.Web.Bridge; internal sealed class SignInJsInterface : MiHoYoJSInterface { /// - public SignInJsInterface(CoreWebView2 webView, IServiceProvider serviceProvider, bool isOversea) - : base(webView, serviceProvider, isOversea) + public SignInJsInterface(CoreWebView2 webView, IServiceProvider serviceProvider) + : base(webView, serviceProvider) { } @@ -27,7 +27,7 @@ internal sealed class SignInJsInterface : MiHoYoJSInterface { { "x-rpc-client_type", "2" }, { "x-rpc-device_id", Core.CoreEnvironment.HoyolabDeviceId }, - { "x-rpc-app_version", IsOversea ? Core.CoreEnvironment.HoyolabOsXrpcVersion : Core.CoreEnvironment.HoyolabXrpcVersion }, + { "x-rpc-app_version", Core.CoreEnvironment.HoyolabXrpcVersion }, }, }; }