This commit is contained in:
DismissedLight
2023-10-02 13:23:45 +08:00
parent 41ab80511e
commit 1e711172af
9 changed files with 149 additions and 26 deletions

View File

@@ -4,6 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cwcont="using:CommunityToolkit.WinUI.Controls"
xmlns:cwconv="using:CommunityToolkit.WinUI.Converters"
xmlns:cwm="using:CommunityToolkit.WinUI.Media"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
xmlns:shci="using:Snap.Hutao.Control.Image"
xmlns:shmmc="using:Snap.Hutao.Model.Metadata.Converter"
@@ -28,6 +29,7 @@
<SolidColorBrush x:Key="DarkOnlyOverlayMaskBrush" Color="#60000000"/>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
<!-- Modify Window title bar color -->
<StaticResource x:Key="WindowCaptionBackground" ResourceKey="ControlFillColorTransparentBrush"/>
<StaticResource x:Key="WindowCaptionBackgroundDisabled" ResourceKey="ControlFillColorTransparentBrush"/>
@@ -301,6 +303,11 @@
<ReorderThemeTransition/>
<EntranceThemeTransition IsStaggeringEnabled="False"/>
</TransitionCollection>
<cwm:AttachedCardShadow
x:Key="CompatCardShadow"
Opacity="0.1"
Offset="0,4,0"/>
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@@ -7080,6 +7080,15 @@ namespace Snap.Hutao.Resource.Localization {
}
}
/// <summary>
/// 查找类似 验证失败,请手动验证或前往「米游社-我的角色」页面查看 的本地化字符串。
/// </summary>
internal static string WebIndexOrSpiralAbyssVerificationFailed {
get {
return ResourceManager.GetString("WebIndexOrSpiralAbyssVerificationFailed", resourceCulture);
}
}
/// <summary>
/// 查找类似 状态:{0} | 信息:{1} 的本地化字符串。
/// </summary>

View File

@@ -2513,6 +2513,9 @@
<data name="WebGachaConfigTypeWeaponEventWish" xml:space="preserve">
<value>武器活动祈愿</value>
</data>
<data name="WebIndexOrSpiralAbyssVerificationFailed" xml:space="preserve">
<value>验证失败,请手动验证或前往「米游社-我的角色」页面查看</value>
</data>
<data name="WebResponseFormat" xml:space="preserve">
<value>状态:{0} | 信息:{1}</value>
</data>

View File

@@ -77,7 +77,12 @@ internal partial class WebViewer : UserControl, IRecipient<UserChangedMessage>
// TODO: replace with .NET 8 UnsafeAccessor
try
{
CoreWebView2 coreWebView2 = WebView.CoreWebView2;
CoreWebView2? coreWebView2 = WebView?.CoreWebView2;
if (coreWebView2 is null)
{
return;
}
if (SourceProvider is not null)
{

View File

@@ -178,7 +178,7 @@
</DataTemplate>
<DataTemplate x:Key="CardTemplate" x:DataType="shvcp:CardReference">
<ItemContainer Child="{Binding Card}">
<ItemContainer cw:Effects.Shadow="{StaticResource CompatCardShadow}" Child="{Binding Card}">
<ItemContainer.Resources>
<SolidColorBrush x:Key="ItemContainerPointerOverBackground" Color="Transparent"/>
</ItemContainer.Resources>
@@ -188,7 +188,7 @@
</shc:ScopedPage.Resources>
<Grid>
<ScrollViewer Padding="0,0,0,0">
<ScrollViewer Padding="0">
<StackPanel>
<StackPanel>
<TextBlock

View File

@@ -10,6 +10,7 @@
xmlns:shc="using:Snap.Hutao.Control"
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
xmlns:shcm="using:Snap.Hutao.Control.Markup"
xmlns:shvc="using:Snap.Hutao.View.Control"
xmlns:shvu="using:Snap.Hutao.ViewModel.User"
d:DataContext="{d:DesignInstance shvu:UserViewModel}"
mc:Ignorable="d">
@@ -21,22 +22,43 @@
Padding="0,0,0,0"
Spacing="4">
<StackPanel.Resources>
<shc:BindingProxy x:Key="ViewModelBindingProxy" DataContext="{Binding}"/>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<StaticResource x:Key="ButtonBackground" ResourceKey="NavigationViewItemBackground"/>
<StaticResource x:Key="ButtonBackgroundDisabled" ResourceKey="NavigationViewItemBackgroundDisabled"/>
<StaticResource x:Key="ButtonBackgroundPointerOver" ResourceKey="NavigationViewItemBackgroundPointerOver"/>
<StaticResource x:Key="ButtonBackgroundPressed" ResourceKey="NavigationViewItemBackgroundPressed"/>
<StaticResource x:Key="ButtonBackground" ResourceKey="NavigationViewItemBackground"/>
<StaticResource x:Key="ButtonBackgroundDisabled" ResourceKey="NavigationViewItemBackgroundDisabled"/>
<StaticResource x:Key="ButtonBackgroundPointerOver" ResourceKey="NavigationViewItemBackgroundPointerOver"/>
<StaticResource x:Key="ButtonBackgroundPressed" ResourceKey="NavigationViewItemBackgroundPressed"/>
<StaticResource x:Key="ButtonBorderBrush" ResourceKey="NavigationViewItemBorderBrush"/>
<StaticResource x:Key="ButtonBorderBrushDisabled" ResourceKey="NavigationViewItemBorderBrushDisabled"/>
<StaticResource x:Key="ButtonBorderBrushPointerOver" ResourceKey="NavigationViewItemBorderBrushPointerOver"/>
<StaticResource x:Key="ButtonBorderBrushPressed" ResourceKey="NavigationViewItemBorderBrushPressed"/>
<StaticResource x:Key="ButtonBorderBrush" ResourceKey="NavigationViewItemBorderBrush"/>
<StaticResource x:Key="ButtonBorderBrushDisabled" ResourceKey="NavigationViewItemBorderBrushDisabled"/>
<StaticResource x:Key="ButtonBorderBrushPointerOver" ResourceKey="NavigationViewItemBorderBrushPointerOver"/>
<StaticResource x:Key="ButtonBorderBrushPressed" ResourceKey="NavigationViewItemBorderBrushPressed"/>
<StaticResource x:Key="ButtonForeground" ResourceKey="NavigationViewItemForeground"/>
<StaticResource x:Key="ButtonForegroundDisabled" ResourceKey="NavigationViewItemForegroundDisabled"/>
<StaticResource x:Key="ButtonForegroundPointerOver" ResourceKey="NavigationViewItemForegroundPointerOver"/>
<StaticResource x:Key="ButtonForegroundPressed" ResourceKey="NavigationViewItemForegroundPressed"/>
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<StaticResource x:Key="ButtonBackground" ResourceKey="NavigationViewItemBackground"/>
<StaticResource x:Key="ButtonBackgroundDisabled" ResourceKey="NavigationViewItemBackgroundDisabled"/>
<StaticResource x:Key="ButtonBackgroundPointerOver" ResourceKey="NavigationViewItemBackgroundPointerOver"/>
<StaticResource x:Key="ButtonBackgroundPressed" ResourceKey="NavigationViewItemBackgroundPressed"/>
<StaticResource x:Key="ButtonForeground" ResourceKey="NavigationViewItemForeground"/>
<StaticResource x:Key="ButtonForegroundDisabled" ResourceKey="NavigationViewItemForegroundDisabled"/>
<StaticResource x:Key="ButtonForegroundPointerOver" ResourceKey="NavigationViewItemForegroundPointerOver"/>
<StaticResource x:Key="ButtonForegroundPressed" ResourceKey="NavigationViewItemForegroundPressed"/>
<StaticResource x:Key="ButtonBorderBrush" ResourceKey="NavigationViewItemBorderBrush"/>
<StaticResource x:Key="ButtonBorderBrushDisabled" ResourceKey="NavigationViewItemBorderBrushDisabled"/>
<StaticResource x:Key="ButtonBorderBrushPointerOver" ResourceKey="NavigationViewItemBorderBrushPointerOver"/>
<StaticResource x:Key="ButtonBorderBrushPressed" ResourceKey="NavigationViewItemBorderBrushPressed"/>
<StaticResource x:Key="ButtonForeground" ResourceKey="NavigationViewItemForeground"/>
<StaticResource x:Key="ButtonForegroundDisabled" ResourceKey="NavigationViewItemForegroundDisabled"/>
<StaticResource x:Key="ButtonForegroundPointerOver" ResourceKey="NavigationViewItemForegroundPointerOver"/>
<StaticResource x:Key="ButtonForegroundPressed" ResourceKey="NavigationViewItemForegroundPressed"/>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
<shc:BindingProxy x:Key="ViewModelBindingProxy" DataContext="{Binding}"/>
</ResourceDictionary>
</StackPanel.Resources>
<Button
@@ -165,6 +187,36 @@
Icon="{shcm:FontIcon Glyph=&#xF133;}"
Label="{shcm:ResourceString Name=ViewUserCookieOperationSignInRewardAction}"
Style="{StaticResource DefaultAppBarButtonStyle}"/>
<AppBarButton
Width="{StaticResource LargeAppBarButtonWidth}"
MaxWidth="{StaticResource LargeAppBarButtonWidth}"
Margin="2,-4"
Icon="{shcm:FontIcon Glyph=&#xEC26;}"
Label="我的角色"
Style="{StaticResource DefaultAppBarButtonStyle}">
<mxi:Interaction.Behaviors>
<mxic:EventTriggerBehavior EventName="Click">
<shcb:OpenAttachedFlyoutAction/>
</mxic:EventTriggerBehavior>
</mxi:Interaction.Behaviors>
<FlyoutBase.AttachedFlyout>
<Flyout LightDismissOverlayMode="On" Placement="Full">
<Flyout.FlyoutPresenterStyle>
<Style TargetType="FlyoutPresenter">
<Setter Property="Padding" Value="0"/>
<Setter Property="BorderBrush" Value="{ThemeResource CardStrokeColorDefaultBrush}"/>
</Style>
</Flyout.FlyoutPresenterStyle>
<Grid>
<shvc:WebViewer>
<shvc:WebViewer.SourceProvider>
<shvc:StaticWebview2ViewerSource Source="https://webstatic.mihoyo.com/app/community-game-records/index.html"/>
</shvc:WebViewer.SourceProvider>
</shvc:WebViewer>
</Grid>
</Flyout>
</FlyoutBase.AttachedFlyout>
</AppBarButton>
<AppBarButton
Width="{StaticResource LargeAppBarButtonWidth}"
MaxWidth="{StaticResource LargeAppBarButtonWidth}"

View File

@@ -33,11 +33,7 @@ internal sealed partial class UserClient : IUserClient
{
ArgumentException.ThrowIfNullOrEmpty(user.Aid);
Response<UserFullInfoWrapper>? resp = await httpClient
// .SetUser(user, CookieType.SToken)
.SetReferer(ApiEndpoints.BbsReferer)
// .UseDynamicSecret(DynamicSecretVersion.Gen1, SaltType.K2, true)
.TryCatchGetFromJsonAsync<Response<UserFullInfoWrapper>>(ApiEndpoints.UserFullInfoQuery(user.Aid), options, logger, token)
.ConfigureAwait(false);

View File

@@ -78,6 +78,24 @@ internal sealed partial class GameRecordClient : IGameRecordClient
.TryCatchGetFromJsonAsync<Response<PlayerInfo>>(ApiEndpoints.GameRecordIndex(userAndUid.Uid), options, logger, token)
.ConfigureAwait(false);
// We have a verification procedure to handle
if (resp?.ReturnCode == (int)KnownReturnCode.CODE1034)
{
// Replace message
resp.Message = SH.WebIndexOrSpiralAbyssVerificationFailed;
IGeetestCardVerifier verifier = serviceProvider.GetRequiredService<HomaGeetestCardVerifier>();
if (await verifier.TryValidateXrpcChallengeAsync(userAndUid.User, token).ConfigureAwait(false) is { } challenge)
{
resp = await httpClient
.SetUser(userAndUid.User, CookieType.Cookie)
.SetXrpcChallenge(challenge)
.UseDynamicSecret(DynamicSecretVersion.Gen2, SaltType.X4, false)
.TryCatchGetFromJsonAsync<Response<PlayerInfo>>(ApiEndpoints.GameRecordIndex(userAndUid.Uid), options, logger, token)
.ConfigureAwait(false);
}
}
return Response.Response.DefaultIfNull(resp);
}
@@ -97,6 +115,24 @@ internal sealed partial class GameRecordClient : IGameRecordClient
.TryCatchGetFromJsonAsync<Response<SpiralAbyss.SpiralAbyss>>(ApiEndpoints.GameRecordSpiralAbyss(schedule, userAndUid.Uid), options, logger, token)
.ConfigureAwait(false);
// We have a verification procedure to handle
if (resp?.ReturnCode == (int)KnownReturnCode.CODE1034)
{
// Replace message
resp.Message = SH.WebIndexOrSpiralAbyssVerificationFailed;
IGeetestCardVerifier verifier = serviceProvider.GetRequiredService<HomaGeetestCardVerifier>();
if (await verifier.TryValidateXrpcChallengeAsync(userAndUid.User, token).ConfigureAwait(false) is { } challenge)
{
resp = await httpClient
.SetUser(userAndUid.User, CookieType.Cookie)
.SetXrpcChallenge(challenge)
.UseDynamicSecret(DynamicSecretVersion.Gen2, SaltType.X4, false)
.TryCatchGetFromJsonAsync<Response<SpiralAbyss.SpiralAbyss>>(ApiEndpoints.GameRecordSpiralAbyss(schedule, userAndUid.Uid), options, logger, token)
.ConfigureAwait(false);
}
}
return Response.Response.DefaultIfNull(resp);
}
@@ -136,6 +172,24 @@ internal sealed partial class GameRecordClient : IGameRecordClient
.TryCatchPostAsJsonAsync<CharacterData, Response<CharacterWrapper>>(ApiEndpoints.GameRecordCharacter, data, options, logger, token)
.ConfigureAwait(false);
// We have a verification procedure to handle
if (resp?.ReturnCode == (int)KnownReturnCode.CODE1034)
{
// Replace message
resp.Message = SH.WebIndexOrSpiralAbyssVerificationFailed;
IGeetestCardVerifier verifier = serviceProvider.GetRequiredService<HomaGeetestCardVerifier>();
if (await verifier.TryValidateXrpcChallengeAsync(userAndUid.User, token).ConfigureAwait(false) is { } challenge)
{
resp = await httpClient
.SetUser(userAndUid.User, CookieType.Cookie)
.SetXrpcChallenge(challenge)
.UseDynamicSecret(DynamicSecretVersion.Gen2, SaltType.X4, false)
.TryCatchPostAsJsonAsync<CharacterData, Response<CharacterWrapper>>(ApiEndpoints.GameRecordCharacter, data, options, logger, token)
.ConfigureAwait(false);
}
}
return Response.Response.DefaultIfNull(resp);
}
}

View File

@@ -16,13 +16,12 @@ internal static class HttpClientExtension
{
private const string RequestErrorMessage = "请求异常已忽略";
/// <inheritdoc cref="HttpClientJsonExtensions.GetFromJsonAsync{TValue}(HttpClient, string?, JsonSerializerOptions?, CancellationToken)"/>
internal static async ValueTask<T?> TryCatchGetFromJsonAsync<T>(this HttpClient httpClient, string requestUri, JsonSerializerOptions options, ILogger logger, CancellationToken token = default)
where T : class
internal static async ValueTask<TResult?> TryCatchGetFromJsonAsync<TResult>(this HttpClient httpClient, string requestUri, JsonSerializerOptions options, ILogger logger, CancellationToken token = default)
where TResult : class
{
try
{
return await httpClient.GetFromJsonAsync<T>(requestUri, options, token).ConfigureAwait(false);
return await httpClient.GetFromJsonAsync<TResult>(requestUri, options, token).ConfigureAwait(false);
}
catch (HttpRequestException ex)
{
@@ -46,7 +45,6 @@ internal static class HttpClientExtension
}
}
/// <inheritdoc cref="HttpClientJsonExtensions.PostAsJsonAsync{TValue}(HttpClient, string?, TValue, JsonSerializerOptions?, CancellationToken)"/>
internal static async ValueTask<TResult?> TryCatchPostAsJsonAsync<TValue, TResult>(this HttpClient httpClient, string requestUri, TValue value, JsonSerializerOptions options, ILogger logger, CancellationToken token = default)
where TResult : class
{
@@ -77,7 +75,6 @@ internal static class HttpClientExtension
}
}
/// <inheritdoc cref="HttpClientJsonExtensions.PostAsJsonAsync{TValue}(HttpClient, string?, TValue, JsonSerializerOptions?, CancellationToken)"/>
internal static async ValueTask<TResult?> TryCatchPostAsJsonAsync<TValue, TResult>(this HttpClient httpClient, string requestUri, TValue value, CancellationToken token = default)
where TResult : class
{