use hoyoverse instead of hoyolab to login

This commit is contained in:
Lightczx
2023-04-17 12:00:48 +08:00
parent b8895d8250
commit 97c7671595
14 changed files with 772 additions and 287 deletions

View File

@@ -2,6 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Text;
@@ -46,7 +47,7 @@ public static class JsonParser
stringBuilder ??= new StringBuilder();
splitArrayPool ??= new Stack<List<string>>();
//Remove all whitespace not within strings to make parsing simpler
// Remove all whitespace not within strings to make parsing simpler
stringBuilder.Length = 0;
for (int i = 0; i < json.Length; i++)
{
@@ -64,7 +65,7 @@ public static class JsonParser
stringBuilder.Append(c);
}
//Parse the thing!
// Parse the thing!
return (T?)ParseValue(typeof(T), stringBuilder.ToString());
}
@@ -96,7 +97,7 @@ public static class JsonParser
return json.Length - 1;
}
//Splits { <value>:<value>, <value>:<value> } and [ <value>, <value> ] into a list of <value> strings
// Splits { <value>:<value>, <value>:<value> } and [ <value>, <value> ] into a list of <value> strings
private static List<string> Split(string json)
{
List<string> splitArray = splitArrayPool!.Count > 0 ? splitArrayPool.Pop() : new List<string>();
@@ -315,7 +316,7 @@ public static class JsonParser
return null;
}
Dictionary<string, object?> dict = new Dictionary<string, object?>(elems.Count / 2);
Dictionary<string, object?> dict = new(elems.Count / 2);
for (int i = 0; i < elems.Count; i += 2)
{
dict[elems[i].Substring(1, elems[i].Length - 2)] = ParseAnonymousValue(elems[i + 1]);
@@ -396,7 +397,7 @@ public static class JsonParser
{
object instance = FormatterServices.GetUninitializedObject(type);
//The list is split into key/value pairs only, this means the split must be divisible by 2 to be valid JSON
// The list is split into key/value pairs only, this means the split must be divisible by 2 to be valid JSON
List<string> elems = Split(json);
if (elems.Count % 2 != 0)
{

View File

@@ -1,4 +1,6 @@
namespace Snap.Hutao.Test;
using System;
namespace Snap.Hutao.Test;
[TestClass]
public class CSharpLanguageFeatureTest
@@ -22,4 +24,41 @@ public class CSharpLanguageFeatureTest
Assert.IsTrue(*pStr == '\0');
}
}
[TestMethod]
public void EnumParseCanNotHandleEmptyString()
{
bool caught = false;
try
{
Enum.Parse<EnumA>(string.Empty);
}
catch (ArgumentException)
{
caught = true;
}
Assert.IsTrue(caught);
}
[TestMethod]
public void EnumParseCanHandleNumberString()
{
EnumA a = Enum.Parse<EnumA>("2");
Assert.AreEqual(a, EnumA.ValueB);
}
[TestMethod]
public void EnumToStringDecimal()
{
Assert.AreEqual("2", EnumA.ValueB.ToString("D"));
}
private enum EnumA
{
None = 0,
ValueA = 1,
ValueB = 2,
ValueC = 3,
}
}

View File

@@ -0,0 +1,105 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
namespace Snap.Hutao.Model.Intrinsic;
/// <summary>
/// 渠道类型
/// </summary>
internal enum ChannelType
{
/// <summary>
/// 错误值
/// </summary>
Default = 0,
/// <summary>
/// 官方渠道
/// </summary>
Official = 1,
/// <summary>
/// 索尼
/// </summary>
MiHoYoSONY = 2,
/// <summary>
/// 小米
/// </summary>
XiaoMi = 11,
/// <summary>
/// 酷派
/// </summary>
KuPai = 12,
/// <summary>
/// 应用宝
/// </summary>
YYB = 13,
/// <summary>
/// 哔哩哔哩
/// </summary>
Bili = 14,
/// <summary>
/// 华为
/// </summary>
HW = 15,
/// <summary>
/// 魅族
/// </summary>
MZ = 16,
/// <summary>
/// 奇虎
/// </summary>
QiHu = 17,
/// <summary>
/// 欧泊
/// </summary>
OPPO = 18,
/// <summary>
/// 维沃
/// </summary>
VIVO = 19,
/// <summary>
/// 阿里
/// </summary>
Ali = 20,
/// <summary>
/// 豌豆荚
/// </summary>
WDJ = 21,
/// <summary>
/// 联想
/// </summary>
Lenove = 22,
/// <summary>
/// 金立
/// </summary>
JinLi = 23,
/// <summary>
/// 百度
/// </summary>
BaiDu = 25,
/// <summary>
/// 当乐
/// </summary>
DL = 26,
/// <summary>
/// WeGame
/// </summary>
WeGame = 27,
}

View File

@@ -0,0 +1,50 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
namespace Snap.Hutao.Model.Intrinsic;
/// <summary>
/// 子渠道类型
/// </summary>
internal enum SubChannelType
{
/// <summary>
/// 默认
/// </summary>
Default = 0,
/// <summary>
/// 官方
/// </summary>
Official = 1,
/// <summary>
/// 非 TapTap
/// </summary>
NoTapTap = 2,
/// <summary>
/// Epic
/// </summary>
Epic = 3,
/// <summary>
/// 三星
/// </summary>
Samsung = 4,
/// <summary>
/// Steam
/// </summary>
Steam = 5,
/// <summary>
/// 谷歌
/// </summary>
Google = 6,
/// <summary>
/// 最大值
/// </summary>
MAX = 7,
}

View File

@@ -2545,7 +2545,7 @@ namespace Snap.Hutao.Resource.Localization {
}
/// <summary>
/// 查找类似 无法读取游戏配置文件 的本地化字符串。
/// 查找类似 无法读取游戏配置文件: {0} 的本地化字符串。
/// </summary>
internal static string ViewModelLaunchGameMultiChannelReadFail {
get {
@@ -4722,6 +4722,204 @@ namespace Snap.Hutao.Resource.Localization {
}
}
/// <summary>
/// 查找类似 搭配圣遗物 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarArtifactSetCombinationHeader {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarArtifactSetCombinationHeader", resourceCulture);
}
}
/// <summary>
/// 查找类似 养成材料 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarAscensionMaterialsHeader {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarAscensionMaterialsHeader", resourceCulture);
}
}
/// <summary>
/// 查找类似 筛选角色 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarAutoSuggestBoxPlaceHolder {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarAutoSuggestBoxPlaceHolder", resourceCulture);
}
}
/// <summary>
/// 查找类似 汉语 CV 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarChineseCVNameTitle {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarChineseCVNameTitle", resourceCulture);
}
}
/// <summary>
/// 查找类似 命之座 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarConstellationNameTitle {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarConstellationNameTitle", resourceCulture);
}
}
/// <summary>
/// 查找类似 衣装 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarCostumeHeader {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarCostumeHeader", resourceCulture);
}
}
/// <summary>
/// 查找类似 生日 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarDateofBirthTitle {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarDateofBirthTitle", resourceCulture);
}
}
/// <summary>
/// 查找类似 英语 CV 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarEnglishCVNameTitle {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarEnglishCVNameTitle", resourceCulture);
}
}
/// <summary>
/// 查找类似 料理 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarFoodHeader {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarFoodHeader", resourceCulture);
}
}
/// <summary>
/// 查找类似 日语 CV 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarJapaneseCVNameTitle {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarJapaneseCVNameTitle", resourceCulture);
}
}
/// <summary>
/// 查找类似 韩语 CV 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarKoreanCVNameTitle {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarKoreanCVNameTitle", resourceCulture);
}
}
/// <summary>
/// 查找类似 其它 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarMiscHeader {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarMiscHeader", resourceCulture);
}
}
/// <summary>
/// 查找类似 所属 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarOccupationNameTitle {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarOccupationNameTitle", resourceCulture);
}
}
/// <summary>
/// 查找类似 原料理 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarOriginalFoodTitle {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarOriginalFoodTitle", resourceCulture);
}
}
/// <summary>
/// 查找类似 资料 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarQuotesHeader {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarQuotesHeader", resourceCulture);
}
}
/// <summary>
/// 查找类似 特殊料理 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarSpecialFoodTitle {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarSpecialFoodTitle", resourceCulture);
}
}
/// <summary>
/// 查找类似 故事 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarStoriesHeader {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarStoriesHeader", resourceCulture);
}
}
/// <summary>
/// 查找类似 天赋 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarTanlentHeader {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarTanlentHeader", resourceCulture);
}
}
/// <summary>
/// 查找类似 搭配角色 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarTeamCombinationHeader {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarTeamCombinationHeader", resourceCulture);
}
}
/// <summary>
/// 查找类似 搭配武器 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiAvatarWeaponCombinationHeader {
get {
return ResourceManager.GetString("ViewPageWiKiAvatarWeaponCombinationHeader", resourceCulture);
}
}
/// <summary>
/// 查找类似 添加到养成计划 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiGeneralAddToDevPlanButtonLabel {
get {
return ResourceManager.GetString("ViewPageWiKiGeneralAddToDevPlanButtonLabel", resourceCulture);
}
}
/// <summary>
/// 查找类似 筛选怪物 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiMonsterAutoSuggestBoxPlaceHolder {
get {
return ResourceManager.GetString("ViewPageWiKiMonsterAutoSuggestBoxPlaceHolder", resourceCulture);
}
}
/// <summary>
/// 查找类似 掉落物品 的本地化字符串。
/// </summary>
@@ -4731,6 +4929,33 @@ namespace Snap.Hutao.Resource.Localization {
}
}
/// <summary>
/// 查找类似 突破后 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiWeaponAfterAscensionTitle {
get {
return ResourceManager.GetString("ViewPageWiKiWeaponAfterAscensionTitle", resourceCulture);
}
}
/// <summary>
/// 查找类似 筛选武器 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiWeaponAutoSuggestBoxPlaceHolder {
get {
return ResourceManager.GetString("ViewPageWiKiWeaponAutoSuggestBoxPlaceHolder", resourceCulture);
}
}
/// <summary>
/// 查找类似 突破前 的本地化字符串。
/// </summary>
internal static string ViewPageWiKiWeaponBeforeAscensionTitle {
get {
return ResourceManager.GetString("ViewPageWiKiWeaponBeforeAscensionTitle", resourceCulture);
}
}
/// <summary>
/// 查找类似 登录失败,请重新登录 的本地化字符串。
/// </summary>

View File

@@ -916,7 +916,7 @@
<value>切换服务器失败</value>
</data>
<data name="ViewModelLaunchGameMultiChannelReadFail" xml:space="preserve">
<value>无法读取游戏配置文件</value>
<value>无法读取游戏配置文件: {0}</value>
</data>
<data name="ViewModelLaunchGamePathInvalid" xml:space="preserve">
<value>游戏路径不正确,前往设置更改游戏路径</value>

View File

@@ -26,7 +26,6 @@ namespace Snap.Hutao.Service.Game;
/// </summary>
[HighQuality]
[Injection(InjectAs.Singleton, typeof(IGameService))]
[SuppressMessage("", "CA1001")]
internal sealed class GameService : IGameService
{
private const string GamePathKey = $"{nameof(GameService)}.Cache.{SettingEntry.GamePath}";
@@ -161,18 +160,20 @@ internal sealed class GameService : IGameService
{
if (parameter.Key == "channel")
{
if (parameter.Value != scheme.Channel)
string channel = scheme.Channel.ToString("D");
if (parameter.Value != channel)
{
parameter.Value = scheme.Channel;
parameter.Value = channel;
changed = true;
}
}
if (parameter.Key == "sub_channel")
{
if (parameter.Value != scheme.SubChannel)
string subChannel = scheme.SubChannel.ToString("D");
if (parameter.Value != subChannel)
{
parameter.Value = scheme.SubChannel;
parameter.Value = subChannel;
changed = true;
}
}

View File

@@ -1,6 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Model.Intrinsic;
using System.Collections.Immutable;
namespace Snap.Hutao.Service.Game;
@@ -16,54 +17,95 @@ internal sealed class LaunchScheme
/// </summary>
public static readonly ImmutableList<LaunchScheme> KnownSchemes = new List<LaunchScheme>()
{
new LaunchScheme(SH.ModelBindingLaunchGameLaunchSchemeChinese, "eYd89JmJ", "18", "1", "1"),
new LaunchScheme(SH.ModelBindingLaunchGameLaunchSchemeBilibili, "KAtdSsoQ", "17", "14", "0"),
new LaunchScheme(SH.ModelBindingLaunchGameLaunchSchemeOversea, "gcStgarh", "10", "1", "0"),
}.ToImmutableList();
// 官服
new()
{
DisplayName = SH.ModelBindingLaunchGameLaunchSchemeChinese,
LauncherId = "18",
Key = "eYd89JmJ",
Channel = ChannelType.Official,
SubChannel = SubChannelType.Default,
IsOversea = false,
},
/// <summary>
/// 构造一个新的启动方案
/// </summary>
/// <param name="displayName">名称</param>
/// <param name="channel">通道</param>
/// <param name="subChannel">子通道</param>
/// <param name="launcherId">启动器Id</param>
private LaunchScheme(string displayName, string key, string launcherId, string channel, string subChannel)
{
DisplayName = displayName;
Channel = channel;
SubChannel = subChannel;
LauncherId = launcherId;
Key = key;
}
// 渠道服
new()
{
DisplayName = SH.ModelBindingLaunchGameLaunchSchemeBilibili,
LauncherId = "17",
Key = "KAtdSsoQ",
Channel = ChannelType.Bili,
SubChannel = SubChannelType.Default,
IsOversea = false,
},
// 国际服
new()
{
DisplayName = SH.ModelBindingLaunchGameLaunchSchemeOversea,
LauncherId = "10",
Key = "gcStgarh",
Channel = ChannelType.Official,
SubChannel = SubChannelType.Default,
IsOversea = true,
},
new()
{
DisplayName = SH.ModelBindingLaunchGameLaunchSchemeOversea,
LauncherId = "10",
Key = "gcStgarh",
Channel = ChannelType.Official,
SubChannel = SubChannelType.Epic,
IsOversea = true,
},
new()
{
DisplayName = SH.ModelBindingLaunchGameLaunchSchemeOversea,
LauncherId = "10",
Key = "gcStgarh",
Channel = ChannelType.Official,
SubChannel = SubChannelType.Google,
IsOversea = true,
},
}.ToImmutableList();
/// <summary>
/// 名称
/// </summary>
public string DisplayName { get; }
public string DisplayName { get; private set; } = default!;
/// <summary>
/// 通道
/// </summary>
public string Channel { get; }
public ChannelType Channel { get; private set; }
/// <summary>
/// 子通道
/// </summary>
public string SubChannel { get; }
public SubChannelType SubChannel { get; private set; }
/// <summary>
/// 启动器Id
/// 启动器 Id
/// </summary>
public string LauncherId { get; }
public string LauncherId { get; private set; } = default!;
/// <summary>
/// API Key
/// </summary>
public string Key { get; }
public string Key { get; private set; } = default!;
/// <summary>
/// 是否为海外
/// </summary>
public bool IsOversea { get => LauncherId == "10" && Channel == "1" && SubChannel == "0"; }
public bool IsOversea { get; private set; }
/// <summary>
/// 多通道相等
/// </summary>
/// <param name="multiChannel">多通道</param>
/// <returns>是否相等</returns>
public bool MultiChannelEqual(MultiChannel multiChannel)
{
return Channel == multiChannel.Channel && SubChannel == multiChannel.SubChannel;
}
}

View File

@@ -1,28 +1,30 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Model.Intrinsic;
namespace Snap.Hutao.Service.Game;
/// <summary>
/// 多通道
/// </summary>
[HighQuality]
internal struct MultiChannel
internal readonly struct MultiChannel
{
/// <summary>
/// 通道
/// </summary>
public string Channel;
public readonly ChannelType Channel;
/// <summary>
/// 子通道
/// </summary>
public string SubChannel;
public readonly SubChannelType SubChannel;
/// <summary>
/// 配置文件路径 当不为 null 时则存在文件读写问题
/// </summary>
public string? ConfigFilePath;
public readonly string? ConfigFilePath;
/// <summary>
/// 构造一个新的多通道
@@ -32,8 +34,9 @@ internal struct MultiChannel
/// <param name="configFilePath">配置文件路径</param>
public MultiChannel(string? channel, string? subChannel, string? configFilePath = null)
{
Channel = channel ?? string.Empty;
SubChannel = subChannel ?? string.Empty;
Channel = string.IsNullOrEmpty(channel) ? ChannelType.Default : Enum.Parse<ChannelType>(channel);
SubChannel = string.IsNullOrEmpty(subChannel) ? SubChannelType.Default : Enum.Parse<SubChannelType>(subChannel);
ConfigFilePath = configFilePath;
}
}

View File

@@ -1,4 +1,4 @@
<Button
<Button
x:Class="Snap.Hutao.View.Card.GachaStatisticsCard"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@@ -14,6 +14,7 @@
VerticalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
d:DataContext="{d:DesignInstance shvg:GachaLogViewModelSlim}"
Command="{Binding NavigateCommand}"
Style="{ThemeResource DefaultButtonStyle}"
mc:Ignorable="d">
@@ -41,242 +42,252 @@
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" DataContext="{Binding AvatarWish}">
<TextBlock
Margin="0,0,0,6"
HorizontalAlignment="Center"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding Name}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<Border Grid.Column="0" Style="{StaticResource BorderCardStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressRing
Grid.Column="0"
Width="40"
Height="40"
Margin="4"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
Foreground="{StaticResource OrangeBrush}"
IsIndeterminate="False"
Maximum="{Binding GuaranteeOrangeThreshold}"
Value="{Binding LastOrangePull}"/>
<TextBlock
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource OrangeBrush}"
Style="{StaticResource BodyTextBlockStyle}"
Text="{Binding LastOrangePull}"/>
<TextBlock
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource OrangeBrush}"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardOrangeText}"/>
</Grid>
</Border>
<Border
Grid.Column="1"
Margin="0,6,0,0"
Style="{StaticResource BorderCardStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressRing
Grid.Column="0"
Width="40"
Height="40"
Margin="4"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
Foreground="{StaticResource PurpleBrush}"
IsIndeterminate="False"
Maximum="{Binding GuaranteePurpleThreshold}"
Value="{Binding LastPurplePull}"/>
<TextBlock
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource PurpleBrush}"
Style="{StaticResource BodyTextBlockStyle}"
Text="{Binding LastPurplePull}"/>
<TextBlock
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource PurpleBrush}"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardPurpleText}"/>
</Grid>
</Border>
</StackPanel>
<StackPanel Grid.Column="1" DataContext="{Binding WeaponWish}">
<TextBlock
Margin="0,0,0,6"
HorizontalAlignment="Center"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding Name}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<Border Grid.Column="0" Style="{StaticResource BorderCardStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressRing
Grid.Column="0"
Width="40"
Height="40"
Margin="4"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
Foreground="{StaticResource OrangeBrush}"
IsIndeterminate="False"
Maximum="{Binding GuaranteeOrangeThreshold}"
Value="{Binding LastOrangePull}"/>
<TextBlock
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource OrangeBrush}"
Style="{StaticResource BodyTextBlockStyle}"
Text="{Binding LastOrangePull}"/>
<TextBlock
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource OrangeBrush}"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardOrangeText}"/>
</Grid>
</Border>
<Border
Grid.Column="1"
Margin="0,6,0,0"
Style="{StaticResource BorderCardStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressRing
Grid.Column="0"
Width="40"
Height="40"
Margin="4"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
Foreground="{StaticResource PurpleBrush}"
IsIndeterminate="False"
Maximum="{Binding GuaranteePurpleThreshold}"
Value="{Binding LastPurplePull}"/>
<TextBlock
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource PurpleBrush}"
Style="{StaticResource BodyTextBlockStyle}"
Text="{Binding LastPurplePull}"/>
<TextBlock
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource PurpleBrush}"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardPurpleText}"/>
</Grid>
</Border>
</StackPanel>
<StackPanel Grid.Column="2" DataContext="{Binding StandardWish}">
<TextBlock
Margin="0,0,0,6"
HorizontalAlignment="Center"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding Name}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<Border Grid.Column="0" Style="{StaticResource BorderCardStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressRing
Grid.Column="0"
Width="40"
Height="40"
Margin="4"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
Foreground="{StaticResource OrangeBrush}"
IsIndeterminate="False"
Maximum="{Binding GuaranteeOrangeThreshold}"
Value="{Binding LastOrangePull}"/>
<TextBlock
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource OrangeBrush}"
Style="{StaticResource BodyTextBlockStyle}"
Text="{Binding LastOrangePull}"/>
<TextBlock
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource OrangeBrush}"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardOrangeText}"/>
</Grid>
</Border>
<Border
Grid.Column="1"
Margin="0,6,0,0"
Style="{StaticResource BorderCardStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressRing
Grid.Column="0"
Width="40"
Height="40"
Margin="4"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
Foreground="{StaticResource PurpleBrush}"
IsIndeterminate="False"
Maximum="{Binding GuaranteePurpleThreshold}"
Value="{Binding LastPurplePull}"/>
<TextBlock
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource PurpleBrush}"
Style="{StaticResource BodyTextBlockStyle}"
Text="{Binding LastPurplePull}"/>
<TextBlock
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource PurpleBrush}"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardPurpleText}"/>
</Grid>
</Border>
</StackPanel>
<TextBlock
Grid.Row="1"
Grid.Row="0"
Grid.ColumnSpan="3"
Text="{Binding Uid}"/>
<StackPanel
Grid.Row="1"
Grid.Column="0"
DataContext="{Binding AvatarWish}">
<TextBlock
Margin="0,0,0,6"
HorizontalAlignment="Center"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding Name}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<Border Grid.Column="0" Style="{StaticResource BorderCardStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressRing
Grid.Column="0"
Width="32"
Height="32"
Margin="4"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
Foreground="{StaticResource OrangeBrush}"
IsIndeterminate="False"
Maximum="{Binding GuaranteeOrangeThreshold}"
Value="{Binding LastOrangePull}"/>
<TextBlock
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource OrangeBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding LastOrangePull}"/>
<TextBlock
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource OrangeBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardOrangeText}"/>
</Grid>
</Border>
<Border
Grid.Column="1"
Margin="0,6,0,0"
Style="{StaticResource BorderCardStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressRing
Grid.Column="0"
Width="32"
Height="32"
Margin="4"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
Foreground="{StaticResource PurpleBrush}"
IsIndeterminate="False"
Maximum="{Binding GuaranteePurpleThreshold}"
Value="{Binding LastPurplePull}"/>
<TextBlock
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource PurpleBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding LastPurplePull}"/>
<TextBlock
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource PurpleBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardPurpleText}"/>
</Grid>
</Border>
</StackPanel>
<StackPanel
Grid.Row="1"
Grid.Column="1"
DataContext="{Binding WeaponWish}">
<TextBlock
Margin="0,0,0,6"
HorizontalAlignment="Center"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding Name}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<Border Grid.Column="0" Style="{StaticResource BorderCardStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressRing
Grid.Column="0"
Width="32"
Height="32"
Margin="4"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
Foreground="{StaticResource OrangeBrush}"
IsIndeterminate="False"
Maximum="{Binding GuaranteeOrangeThreshold}"
Value="{Binding LastOrangePull}"/>
<TextBlock
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource OrangeBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding LastOrangePull}"/>
<TextBlock
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource OrangeBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardOrangeText}"/>
</Grid>
</Border>
<Border
Grid.Column="1"
Margin="0,6,0,0"
Style="{StaticResource BorderCardStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressRing
Grid.Column="0"
Width="32"
Height="32"
Margin="4"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
Foreground="{StaticResource PurpleBrush}"
IsIndeterminate="False"
Maximum="{Binding GuaranteePurpleThreshold}"
Value="{Binding LastPurplePull}"/>
<TextBlock
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource PurpleBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding LastPurplePull}"/>
<TextBlock
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource PurpleBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardPurpleText}"/>
</Grid>
</Border>
</StackPanel>
<StackPanel
Grid.Row="1"
Grid.Column="2"
DataContext="{Binding StandardWish}">
<TextBlock
Margin="0,0,0,6"
HorizontalAlignment="Center"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding Name}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<Border Grid.Column="0" Style="{StaticResource BorderCardStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressRing
Grid.Column="0"
Width="32"
Height="32"
Margin="4"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
Foreground="{StaticResource OrangeBrush}"
IsIndeterminate="False"
Maximum="{Binding GuaranteeOrangeThreshold}"
Value="{Binding LastOrangePull}"/>
<TextBlock
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource OrangeBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding LastOrangePull}"/>
<TextBlock
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource OrangeBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardOrangeText}"/>
</Grid>
</Border>
<Border
Grid.Column="1"
Margin="0,6,0,0"
Style="{StaticResource BorderCardStyle}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ProgressRing
Grid.Column="0"
Width="32"
Height="32"
Margin="4"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
Foreground="{StaticResource PurpleBrush}"
IsIndeterminate="False"
Maximum="{Binding GuaranteePurpleThreshold}"
Value="{Binding LastPurplePull}"/>
<TextBlock
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource PurpleBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding LastPurplePull}"/>
<TextBlock
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource PurpleBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewControlStatisticsCardPurpleText}"/>
</Grid>
</Border>
</StackPanel>
</Grid>
</DataTemplate>
</FlipView.ItemTemplate>

View File

@@ -1,4 +1,4 @@
// Copyright (c) DGP Studio. All rights reserved.
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Microsoft.UI.Xaml.Controls;
@@ -6,12 +6,12 @@ using Microsoft.UI.Xaml.Controls;
namespace Snap.Hutao.View.Card;
/// <summary>
/// 祈愿记录卡片
/// 祈愿记录卡片
/// </summary>
internal sealed partial class GachaStatisticsCard : Button
{
/// <summary>
/// 构造一个新的祈愿记录卡片
/// 构造一个新的祈愿记录卡片
/// </summary>
public GachaStatisticsCard()
{

View File

@@ -169,7 +169,7 @@
DesiredWidth="300"
ItemContainerStyle="{StaticResource LargeGridViewItemStyle}"
SelectionMode="None">
<shvca:LaunchGameCard Height="186" DataContext="{Binding LaunchGameViewModelSlim}"/>
<shvca:LaunchGameCard Height="166" DataContext="{Binding LaunchGameViewModelSlim}"/>
<shvca:GachaStatisticsCard DataContext="{Binding GachaLogViewModelSlim}"/>
<Border Style="{StaticResource BorderCardStyle}">

View File

@@ -56,13 +56,13 @@ internal sealed partial class LoginHoyoverseUserPage : Microsoft.UI.Xaml.Control
await WebView.EnsureCoreWebView2Async();
CoreWebView2CookieManager manager = WebView.CoreWebView2.CookieManager;
IReadOnlyList<CoreWebView2Cookie> cookies = await manager.GetCookiesAsync("https://account.hoyolab.com");
IReadOnlyList<CoreWebView2Cookie> cookies = await manager.GetCookiesAsync("https://account.hoyoverse.com");
foreach (CoreWebView2Cookie item in cookies)
{
manager.DeleteCookie(item);
}
WebView.CoreWebView2.Navigate("https://account.hoyolab.com/#/login");
WebView.CoreWebView2.Navigate("https://account.hoyoverse.com/#/login");
}
catch (Exception ex)
{
@@ -73,7 +73,7 @@ internal sealed partial class LoginHoyoverseUserPage : Microsoft.UI.Xaml.Control
private async Task HandleCurrentCookieAsync(CancellationToken token = default)
{
CoreWebView2CookieManager manager = WebView.CoreWebView2.CookieManager;
IReadOnlyList<CoreWebView2Cookie> cookies = await manager.GetCookiesAsync("https://account.hoyolab.com");
IReadOnlyList<CoreWebView2Cookie> cookies = await manager.GetCookiesAsync("https://account.hoyoverse.com");
IInfoBarService infoBarService = Ioc.Default.GetRequiredService<IInfoBarService>();

View File

@@ -160,11 +160,19 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
MultiChannel multi = gameService.GetMultiChannel();
if (string.IsNullOrEmpty(multi.ConfigFilePath))
{
SelectedScheme = KnownSchemes.FirstOrDefault(s => s.Channel == multi.Channel && s.SubChannel == multi.SubChannel);
try
{
SelectedScheme = KnownSchemes.Single(scheme => scheme.MultiChannelEqual(multi));
}
catch (InvalidOperationException)
{
// 后台收集用
throw new NotSupportedException($"不支持的 MultiChannel: [ChannelType:{multi.Channel}] [SubChannel:{multi.SubChannel}]");
}
}
else
{
infoBarService.Warning(SH.ViewModelLaunchGameMultiChannelReadFail);
infoBarService.Warning(string.Format(SH.ViewModelLaunchGameMultiChannelReadFail, multi.ConfigFilePath));
}
ObservableCollection<GameAccount> accounts = await gameService.GetGameAccountCollectionAsync().ConfigureAwait(false);