mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
Feat: Daily check-in support for hoyolab user
This commit is contained in:
@@ -47,7 +47,7 @@ internal static class CoreEnvironment
|
||||
/// <summary>
|
||||
/// Hoyolab Rpc 版本
|
||||
/// </summary>
|
||||
public const string HoyolabOsXrpcVersion = "2.28.0";
|
||||
public const string HoyolabOsXrpcVersion = "2.30.0";
|
||||
|
||||
/// <summary>
|
||||
/// 盐
|
||||
|
||||
@@ -11,7 +11,7 @@ using Snap.Hutao.Web.Bridge;
|
||||
namespace Snap.Hutao.View.Dialog;
|
||||
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD><EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ի<EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 养成计算器对话框
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed partial class AdoptCalculatorDialog : ContentDialog
|
||||
@@ -20,9 +20,9 @@ internal sealed partial class AdoptCalculatorDialog : ContentDialog
|
||||
private MiHoYoJSInterface? jsInterface;
|
||||
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ի<EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 构造一个新的养成计算器对话框
|
||||
/// </summary>
|
||||
/// <param name="window"><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||
/// <param name="window">窗体</param>
|
||||
public AdoptCalculatorDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -49,7 +49,7 @@ internal sealed partial class AdoptCalculatorDialog : ContentDialog
|
||||
}
|
||||
|
||||
coreWebView2.SetCookie(user.CookieToken, user.LToken, null).SetMobileUserAgent();
|
||||
jsInterface = new(coreWebView2, scope.ServiceProvider);
|
||||
jsInterface = new(coreWebView2, scope.ServiceProvider, false);
|
||||
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");
|
||||
|
||||
@@ -11,7 +11,7 @@ using Snap.Hutao.Web.Bridge;
|
||||
namespace Snap.Hutao.View.Dialog;
|
||||
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><EFBFBD>¼<EFBFBD>Ի<EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 社区游戏记录对话框
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed partial class CommunityGameRecordDialog : ContentDialog
|
||||
@@ -20,9 +20,9 @@ internal sealed partial class CommunityGameRecordDialog : ContentDialog
|
||||
private MiHoYoJSInterface? jsInterface;
|
||||
|
||||
/// <summary>
|
||||
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><EFBFBD>¼<EFBFBD>Ի<EFBFBD><EFBFBD><EFBFBD>
|
||||
/// 构造一个新的社区游戏记录对话框
|
||||
/// </summary>
|
||||
/// <param name="window"><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||
/// <param name="window">窗体</param>
|
||||
public CommunityGameRecordDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -47,7 +47,7 @@ internal sealed partial class CommunityGameRecordDialog : ContentDialog
|
||||
}
|
||||
|
||||
coreWebView2.SetCookie(user.CookieToken, user.LToken, null).SetMobileUserAgent();
|
||||
jsInterface = new(coreWebView2, scope.ServiceProvider);
|
||||
jsInterface = new(coreWebView2, scope.ServiceProvider, false);
|
||||
jsInterface.ClosePageRequested += OnClosePageRequested;
|
||||
|
||||
coreWebView2.Navigate("https://webstatic.mihoyo.com/app/community-game-records/index.html");
|
||||
|
||||
@@ -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);
|
||||
jsInterface = new(coreWebView2, scope.ServiceProvider, false);
|
||||
jsInterface.ClosePageRequested += OnClosePageRequested;
|
||||
|
||||
string query = $"?role_id={userAndUid.Uid.Value}&server={userAndUid.Uid.Region}";
|
||||
|
||||
@@ -48,14 +48,14 @@ internal sealed partial class SignInWebViewDialog : ContentDialog
|
||||
|
||||
if (user.Entity.IsOversea)
|
||||
{
|
||||
coreWebView2.SetCookie(user.CookieToken, user.LToken, null).SetMobileOverseaUserAgent();
|
||||
signInJsInterface = new(coreWebView2, scope.ServiceProvider);
|
||||
coreWebView2.SetCookie(user.CookieToken, user.LToken, null, true).SetMobileOverseaUserAgent();
|
||||
signInJsInterface = new(coreWebView2, scope.ServiceProvider, true);
|
||||
coreWebView2.Navigate("https://act.hoyolab.com/ys/event/signin-sea-v3/index.html?act_id=e202102251931481");
|
||||
}
|
||||
else
|
||||
{
|
||||
coreWebView2.SetCookie(user.CookieToken, user.LToken, null).SetMobileUserAgent();
|
||||
signInJsInterface = new(coreWebView2, scope.ServiceProvider);
|
||||
coreWebView2.SetCookie(user.CookieToken, user.LToken, null, false).SetMobileUserAgent();
|
||||
signInJsInterface = new(coreWebView2, scope.ServiceProvider, false);
|
||||
coreWebView2.Navigate("https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?act_id=e202009291139501");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,32 +41,33 @@ internal static class CoreWebView2Extension
|
||||
/// <param name="cookieToken">CookieToken</param>
|
||||
/// <param name="lToken">LToken</param>
|
||||
/// <param name="sToken">SToken</param>
|
||||
/// <param name="isOversea">是否为国际服,用于改变 cookie domain</param>
|
||||
/// <returns>链式调用的WebView2</returns>
|
||||
public static CoreWebView2 SetCookie(this CoreWebView2 webView, Cookie? cookieToken = null, Cookie? lToken = null, Cookie? sToken = null)
|
||||
public static CoreWebView2 SetCookie(this CoreWebView2 webView, Cookie? cookieToken = null, Cookie? lToken = null, Cookie? sToken = null, bool isOversea = false)
|
||||
{
|
||||
CoreWebView2CookieManager cookieManager = webView.CookieManager;
|
||||
|
||||
if (cookieToken != null)
|
||||
{
|
||||
cookieManager.AddMihoyoCookie("account_id", cookieToken).AddMihoyoCookie("cookie_token", cookieToken);
|
||||
cookieManager.AddMihoyoCookie("account_id", cookieToken, isOversea).AddMihoyoCookie("cookie_token", cookieToken, isOversea);
|
||||
}
|
||||
|
||||
if (lToken != null)
|
||||
{
|
||||
cookieManager.AddMihoyoCookie("ltuid", lToken).AddMihoyoCookie("ltoken", lToken);
|
||||
cookieManager.AddMihoyoCookie("ltuid", lToken, isOversea).AddMihoyoCookie("ltoken", lToken, isOversea);
|
||||
}
|
||||
|
||||
if (sToken != null)
|
||||
{
|
||||
cookieManager.AddMihoyoCookie("stuid", sToken).AddMihoyoCookie("stoken", sToken);
|
||||
cookieManager.AddMihoyoCookie("stuid", sToken, isOversea).AddMihoyoCookie("stoken", sToken, isOversea);
|
||||
}
|
||||
|
||||
return webView;
|
||||
}
|
||||
|
||||
private static CoreWebView2CookieManager AddMihoyoCookie(this CoreWebView2CookieManager manager, string name, Cookie cookie)
|
||||
private static CoreWebView2CookieManager AddMihoyoCookie(this CoreWebView2CookieManager manager, string name, Cookie cookie, bool isOversea = false)
|
||||
{
|
||||
manager.AddOrUpdateCookie(manager.CreateCookie(name, cookie[name], ".mihoyo.com", "/"));
|
||||
manager.AddOrUpdateCookie(manager.CreateCookie(name, cookie[name], isOversea ? ".hoyolab.com" : ".mihoyo.com", "/"));
|
||||
return manager;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ using Snap.Hutao.Web.Hoyolab;
|
||||
using Snap.Hutao.Web.Hoyolab.Bbs.User;
|
||||
using Snap.Hutao.Web.Hoyolab.DynamicSecret;
|
||||
using Snap.Hutao.Web.Hoyolab.Takumi.Auth;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
@@ -35,6 +36,11 @@ 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<MiHoYoJSInterface> logger;
|
||||
@@ -45,10 +51,12 @@ internal class MiHoYoJSInterface
|
||||
/// </summary>
|
||||
/// <param name="webView">webview2</param>
|
||||
/// <param name="serviceProvider">服务提供器</param>
|
||||
public MiHoYoJSInterface(CoreWebView2 webView, IServiceProvider serviceProvider)
|
||||
/// <param name="isOversea">是否为 HoYoVerse 账号</param>
|
||||
public MiHoYoJSInterface(CoreWebView2 webView, IServiceProvider serviceProvider, bool isOversea)
|
||||
{
|
||||
this.webView = webView;
|
||||
this.serviceProvider = serviceProvider;
|
||||
IsOversea = isOversea;
|
||||
|
||||
logger = serviceProvider.GetRequiredService<ILogger<MiHoYoJSInterface>>();
|
||||
|
||||
@@ -57,8 +65,14 @@ internal class MiHoYoJSInterface
|
||||
webView.NavigationStarting += OnNavigationStarting;
|
||||
}
|
||||
|
||||
|
||||
public event Action? ClosePageRequested;
|
||||
|
||||
/// <summary>
|
||||
/// 是否为 HoYoVerse 账号
|
||||
/// </summary>
|
||||
public bool IsOversea { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取ActionTicket
|
||||
/// </summary>
|
||||
@@ -67,10 +81,20 @@ internal class MiHoYoJSInterface
|
||||
public virtual async Task<IJsResult?> GetActionTicketAsync(JsParam<ActionTypePayload> jsParam)
|
||||
{
|
||||
User user = serviceProvider.GetRequiredService<IUserService>().Current!;
|
||||
return await serviceProvider
|
||||
.GetRequiredService<AuthClient>()
|
||||
.GetActionTicketBySTokenAsync(jsParam.Payload!.ActionType, user.Entity)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (IsOversea)
|
||||
{
|
||||
// TODO: ActionTicket for hoyolab account
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return await serviceProvider
|
||||
.GetRequiredService<AuthClient>()
|
||||
.GetActionTicketBySTokenAsync(jsParam.Payload!.ActionType, user.Entity)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -86,7 +110,7 @@ internal class MiHoYoJSInterface
|
||||
{
|
||||
{ "x-rpc-client_type", "5" },
|
||||
{ "x-rpc-device_id", Core.CoreEnvironment.HoyolabDeviceId },
|
||||
{ "x-rpc-app_version", Core.CoreEnvironment.HoyolabXrpcVersion },
|
||||
{ "x-rpc-app_version", IsOversea ? Core.CoreEnvironment.HoyolabOsXrpcVersion : Core.CoreEnvironment.HoyolabXrpcVersion },
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -148,6 +172,7 @@ internal class MiHoYoJSInterface
|
||||
/// <returns>响应</returns>
|
||||
public virtual JsResult<Dictionary<string, string>> GetDynamicSecrectV2(JsParam<DynamicSecrect2Playload> param)
|
||||
{
|
||||
// TODO: Salt X4 for hoyolab user
|
||||
string salt = Core.CoreEnvironment.DynamicSecretSalts[SaltType.X4];
|
||||
long t = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||
int r = GetRandom();
|
||||
@@ -253,6 +278,23 @@ internal class MiHoYoJSInterface
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前语言和时区
|
||||
/// </summary>
|
||||
/// <param name="param">param</param>
|
||||
/// <returns>语言与时区</returns>
|
||||
public virtual JsResult<Dictionary<string, string>> GetCurrentLocale(JsParam<PushPagePayload> param)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Data = new()
|
||||
{
|
||||
["language"] = CultureInfo.CurrentUICulture.Name,
|
||||
["timeZone"] = "GMT+8",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public virtual Task<IJsResult?> ShowAlertDialogAsync(JsParam param)
|
||||
{
|
||||
return Task.FromException<IJsResult?>(new NotImplementedException());
|
||||
@@ -378,6 +420,7 @@ internal class MiHoYoJSInterface
|
||||
"login" => null,
|
||||
"pushPage" => await PushPageAsync(param).ConfigureAwait(false),
|
||||
"showLoading" => null,
|
||||
"getCurrentLocale" => GetCurrentLocale(param),
|
||||
_ => LogUnhandledMessage("Unhandled Message Type: {method}", param.Method),
|
||||
};
|
||||
}
|
||||
@@ -391,11 +434,17 @@ 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("mihoyo.com"))
|
||||
if (new Uri(args.Uri).Host.EndsWith(IsOversea ? "hoyolab.com" : "mihoyo.com"))
|
||||
{
|
||||
// Execute this solve issue: When open same site second time,there might be no bridge init.
|
||||
coreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(InitializeJsInterfaceScript2).AsTask().SafeForget(logger);
|
||||
|
||||
@@ -13,8 +13,8 @@ namespace Snap.Hutao.Web.Bridge;
|
||||
internal sealed class SignInJsInterface : MiHoYoJSInterface
|
||||
{
|
||||
/// <inheritdoc cref="MiHoYoJSInterface(CoreWebView2, IServiceProvider)"/>
|
||||
public SignInJsInterface(CoreWebView2 webView, IServiceProvider serviceProvider)
|
||||
: base(webView, serviceProvider)
|
||||
public SignInJsInterface(CoreWebView2 webView, IServiceProvider serviceProvider, bool isOversea)
|
||||
: base(webView, serviceProvider, isOversea)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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", Core.CoreEnvironment.HoyolabXrpcVersion },
|
||||
{ "x-rpc-app_version", IsOversea ? Core.CoreEnvironment.HoyolabOsXrpcVersion : Core.CoreEnvironment.HoyolabXrpcVersion },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user