mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
launch game phase 1
This commit is contained in:
@@ -2,7 +2,10 @@
|
|||||||
x:Class="Snap.Hutao.App"
|
x:Class="Snap.Hutao.App"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls">
|
xmlns:cwuc="using:CommunityToolkit.WinUI.UI.Converters"
|
||||||
|
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||||
|
xmlns:shmmc="using:Snap.Hutao.Model.Metadata.Converter"
|
||||||
|
xmlns:shvc="using:Snap.Hutao.View.Converter">
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
@@ -13,21 +16,36 @@
|
|||||||
<!--Modify Window title bar color-->
|
<!--Modify Window title bar color-->
|
||||||
<StaticResource x:Key="WindowCaptionBackground" ResourceKey="ControlFillColorTransparentBrush"/>
|
<StaticResource x:Key="WindowCaptionBackground" ResourceKey="ControlFillColorTransparentBrush"/>
|
||||||
<StaticResource x:Key="WindowCaptionBackgroundDisabled" ResourceKey="ControlFillColorTransparentBrush"/>
|
<StaticResource x:Key="WindowCaptionBackgroundDisabled" ResourceKey="ControlFillColorTransparentBrush"/>
|
||||||
|
<!--Page Transparent Background-->
|
||||||
<StaticResource x:Key="ApplicationPageBackgroundThemeBrush" ResourceKey="ControlFillColorTransparentBrush"/>
|
<StaticResource x:Key="ApplicationPageBackgroundThemeBrush" ResourceKey="ControlFillColorTransparentBrush"/>
|
||||||
|
<!--IconFont-->
|
||||||
<FontFamily x:Key="SymbolThemeFontFamily">ms-appx:///Resource/Font/Segoe Fluent Icons.ttf#Segoe Fluent Icons</FontFamily>
|
<FontFamily x:Key="SymbolThemeFontFamily">ms-appx:///Resource/Font/Segoe Fluent Icons.ttf#Segoe Fluent Icons</FontFamily>
|
||||||
|
<!--InfoBar Resource-->
|
||||||
<Thickness x:Key="InfoBarIconMargin">6,16,16,16</Thickness>
|
<Thickness x:Key="InfoBarIconMargin">6,16,16,16</Thickness>
|
||||||
<Thickness x:Key="InfoBarContentRootPadding">16,0,0,0</Thickness>
|
<Thickness x:Key="InfoBarContentRootPadding">16,0,0,0</Thickness>
|
||||||
|
<!--Pivot Resource-->
|
||||||
<x:Double x:Key="PivotHeaderItemFontSize">16</x:Double>
|
<x:Double x:Key="PivotHeaderItemFontSize">16</x:Double>
|
||||||
|
<!--CornerRadius-->
|
||||||
<CornerRadius x:Key="CompatCornerRadius">6</CornerRadius>
|
<CornerRadius x:Key="CompatCornerRadius">6</CornerRadius>
|
||||||
<CornerRadius x:Key="CompatCornerRadiusTop">6,6,0,0</CornerRadius>
|
<CornerRadius x:Key="CompatCornerRadiusTop">6,6,0,0</CornerRadius>
|
||||||
<CornerRadius x:Key="CompatCornerRadiusRight">0,6,6,0</CornerRadius>
|
<CornerRadius x:Key="CompatCornerRadiusRight">0,6,6,0</CornerRadius>
|
||||||
<CornerRadius x:Key="CompatCornerRadiusBottom">0,0,6,6</CornerRadius>
|
<CornerRadius x:Key="CompatCornerRadiusBottom">0,0,6,6</CornerRadius>
|
||||||
<CornerRadius x:Key="CompatCornerRadiusSmall">2</CornerRadius>
|
<CornerRadius x:Key="CompatCornerRadiusSmall">2</CornerRadius>
|
||||||
|
<!--Converters-->
|
||||||
|
<cwuc:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
|
||||||
|
<shmmc:AchievementIconConverter x:Key="AchievementIconConverter"/>
|
||||||
|
<shmmc:AvatarIconConverter x:Key="AvatarIconConverter"/>
|
||||||
|
<shmmc:AvatarNameCardPicConverter x:Key="AvatarNameCardPicConverter"/>
|
||||||
|
<shmmc:AvatarSideIconConverter x:Key="AvatarSideIconConverter"/>
|
||||||
|
<shmmc:DescParamDescriptor x:Key="DescParamDescriptor"/>
|
||||||
|
<shmmc:ElementNameIconConverter x:Key="ElementNameIconConverter"/>
|
||||||
|
<shmmc:GachaAvatarImgConverter x:Key="GachaAvatarImgConverter"/>
|
||||||
|
<shmmc:GachaAvatarIconConverter x:Key="GachaAvatarIconConverter"/>
|
||||||
|
<shmmc:ItemIconConverter x:Key="ItemIconConverter"/>
|
||||||
|
<shmmc:PropertyInfoDescriptor x:Key="PropertyDescriptor"/>
|
||||||
|
<shmmc:QualityColorConverter x:Key="QualityColorConverter"/>
|
||||||
|
<shmmc:WeaponTypeIconConverter x:Key="WeaponTypeIconConverter"/>
|
||||||
|
<shvc:BoolToVisibilityRevertConverter x:Key="BoolToVisibilityRevertConverter"/>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</Application.Resources>
|
</Application.Resources>
|
||||||
</Application>
|
</Application>
|
||||||
|
|||||||
@@ -54,13 +54,17 @@ public partial class App : Application
|
|||||||
logger.LogInformation(EventIds.CommonLog, "Snap Hutao : {version}", CoreEnvironment.Version);
|
logger.LogInformation(EventIds.CommonLog, "Snap Hutao : {version}", CoreEnvironment.Version);
|
||||||
logger.LogInformation(EventIds.CommonLog, "Cache folder : {folder}", ApplicationData.Current.TemporaryFolder.Path);
|
logger.LogInformation(EventIds.CommonLog, "Cache folder : {folder}", ApplicationData.Current.TemporaryFolder.Path);
|
||||||
|
|
||||||
|
JumpListHelper.ConfigAsync().SafeForget(logger);
|
||||||
|
|
||||||
Ioc.Default
|
Ioc.Default
|
||||||
.GetRequiredService<IMetadataService>()
|
.GetRequiredService<IMetadataService>()
|
||||||
.ImplictAs<IMetadataInitializer>()?
|
.ImplictAs<IMetadataInitializer>()?
|
||||||
.InitializeInternalAsync()
|
.InitializeInternalAsync()
|
||||||
.SafeForget(logger);
|
.SafeForget(logger);
|
||||||
|
|
||||||
Ioc.Default.GetRequiredService<AppCenter>().Initialize();
|
Ioc.Default
|
||||||
|
.GetRequiredService<AppCenter>()
|
||||||
|
.Initialize();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using CommunityToolkit.WinUI.UI.Behaviors;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Snap.Hutao.Core;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Control.Behavior;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 按给定比例自动调整高度的行为
|
||||||
|
/// </summary>
|
||||||
|
internal class AutoWidthBehavior : BehaviorBase<FrameworkElement>
|
||||||
|
{
|
||||||
|
private static readonly DependencyProperty TargetWidthProperty = Property<AutoWidthBehavior>.Depend(nameof(TargetWidth), 320D);
|
||||||
|
private static readonly DependencyProperty TargetHeightProperty = Property<AutoWidthBehavior>.Depend(nameof(TargetHeight), 1024D);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 目标宽度
|
||||||
|
/// </summary>
|
||||||
|
public double TargetWidth
|
||||||
|
{
|
||||||
|
get => (double)GetValue(TargetWidthProperty);
|
||||||
|
set => SetValue(TargetWidthProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 目标高度
|
||||||
|
/// </summary>
|
||||||
|
public double TargetHeight
|
||||||
|
{
|
||||||
|
get => (double)GetValue(TargetHeightProperty);
|
||||||
|
set => SetValue(TargetHeightProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
protected override void OnAssociatedObjectLoaded()
|
||||||
|
{
|
||||||
|
UpdateElementWidth();
|
||||||
|
AssociatedObject.SizeChanged += OnSizeChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
protected override void OnDetaching()
|
||||||
|
{
|
||||||
|
AssociatedObject.SizeChanged -= OnSizeChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSizeChanged(object sender, SizeChangedEventArgs e)
|
||||||
|
{
|
||||||
|
UpdateElementWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateElementWidth()
|
||||||
|
{
|
||||||
|
AssociatedObject.Width = (double)AssociatedObject.Height * (TargetWidth / TargetHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
63
src/Snap.Hutao/Snap.Hutao/Core/CommandLineBuilder.cs
Normal file
63
src/Snap.Hutao/Snap.Hutao/Core/CommandLineBuilder.cs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Core;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 命令行建造器
|
||||||
|
/// </summary>
|
||||||
|
public class CommandLineBuilder
|
||||||
|
{
|
||||||
|
private const char WhiteSpace = ' ';
|
||||||
|
private readonly Dictionary<string, string?> options = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当符合条件时添加参数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">参数名称</param>
|
||||||
|
/// <param name="condition">条件</param>
|
||||||
|
/// <param name="value">值</param>
|
||||||
|
/// <returns>命令行建造器</returns>
|
||||||
|
public CommandLineBuilder AppendIf(string name, bool condition, object? value = null)
|
||||||
|
{
|
||||||
|
return condition ? Append(name, value) : this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加参数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">参数名称</param>
|
||||||
|
/// <param name="value">值</param>
|
||||||
|
/// <returns>命令行建造器</returns>
|
||||||
|
public CommandLineBuilder Append(string name, object? value = null)
|
||||||
|
{
|
||||||
|
options.Add(name, value?.ToString());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ToString"/>
|
||||||
|
public string Build()
|
||||||
|
{
|
||||||
|
return ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
StringBuilder s = new();
|
||||||
|
foreach ((string key, string? value) in options)
|
||||||
|
{
|
||||||
|
s.Append(WhiteSpace);
|
||||||
|
s.Append(key);
|
||||||
|
if (!string.IsNullOrEmpty(value))
|
||||||
|
{
|
||||||
|
s.Append(WhiteSpace);
|
||||||
|
s.Append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/Snap.Hutao/Snap.Hutao/Core/JumpListHelper.cs
Normal file
35
src/Snap.Hutao/Snap.Hutao/Core/JumpListHelper.cs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Snap.Hutao.Core.LifeCycle;
|
||||||
|
using Windows.UI.StartScreen;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Core;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 跳转列表帮助类
|
||||||
|
/// </summary>
|
||||||
|
public static class JumpListHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 异步配置跳转列表
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>任务</returns>
|
||||||
|
public static async Task ConfigAsync()
|
||||||
|
{
|
||||||
|
if (JumpList.IsSupported())
|
||||||
|
{
|
||||||
|
JumpList list = await JumpList.LoadCurrentAsync();
|
||||||
|
|
||||||
|
list.Items.Clear();
|
||||||
|
|
||||||
|
JumpListItem launchGameItem = JumpListItem.CreateWithArguments(Activation.LaunchGame, "启动游戏");
|
||||||
|
launchGameItem.GroupName = "快捷操作";
|
||||||
|
launchGameItem.Logo = new("ms-appx:///Resource/Icon/UI_GuideIcon_PlayMethod.png");
|
||||||
|
|
||||||
|
list.Items.Add(launchGameItem);
|
||||||
|
|
||||||
|
await list.SaveAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,11 @@ namespace Snap.Hutao.Core.LifeCycle;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal static class Activation
|
internal static class Activation
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 启动游戏启动参数
|
||||||
|
/// </summary>
|
||||||
|
public const string LaunchGame = "LaunchGame";
|
||||||
|
|
||||||
private static readonly SemaphoreSlim ActivateSemaphore = new(1);
|
private static readonly SemaphoreSlim ActivateSemaphore = new(1);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -44,16 +49,36 @@ internal static class Activation
|
|||||||
|
|
||||||
private static async Task HandleActivationCoreAsync(AppActivationArguments args)
|
private static async Task HandleActivationCoreAsync(AppActivationArguments args)
|
||||||
{
|
{
|
||||||
_ = Ioc.Default.GetRequiredService<MainWindow>();
|
string argument = string.Empty;
|
||||||
|
|
||||||
IInfoBarService infoBarService = Ioc.Default.GetRequiredService<IInfoBarService>();
|
if (args.Kind == ExtendedActivationKind.Launch)
|
||||||
await infoBarService.WaitInitializationAsync().ConfigureAwait(false);
|
{
|
||||||
|
if (args.TryGetLaunchActivatedArgument(out string? arguments))
|
||||||
|
{
|
||||||
|
argument = arguments;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (argument)
|
||||||
|
{
|
||||||
|
case "":
|
||||||
|
{
|
||||||
|
_ = Ioc.Default.GetRequiredService<MainWindow>();
|
||||||
|
await Ioc.Default.GetRequiredService<IInfoBarService>().WaitInitializationAsync().ConfigureAwait(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LaunchGame:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (args.Kind == ExtendedActivationKind.Protocol)
|
if (args.Kind == ExtendedActivationKind.Protocol)
|
||||||
{
|
{
|
||||||
if (args.TryGetProtocolActivatedUri(out Uri? uri))
|
if (args.TryGetProtocolActivatedUri(out Uri? uri))
|
||||||
{
|
{
|
||||||
infoBarService.Information(uri.ToString());
|
Ioc.Default.GetRequiredService<IInfoBarService>().Information(uri.ToString());
|
||||||
await HandleUrlActivationAsync(uri).ConfigureAwait(false);
|
await HandleUrlActivationAsync(uri).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,4 +28,22 @@ public static class AppActivationArgumentsExtensions
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 尝试获取启动的参数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="activatedEventArgs">应用程序激活参数</param>
|
||||||
|
/// <param name="arguments">参数</param>
|
||||||
|
/// <returns>是否存在参数</returns>
|
||||||
|
public static bool TryGetLaunchActivatedArgument(this AppActivationArguments activatedEventArgs, [NotNullWhen(true)] out string? arguments)
|
||||||
|
{
|
||||||
|
arguments = null;
|
||||||
|
if (activatedEventArgs.Data is ILaunchActivatedEventArgs launchArgs)
|
||||||
|
{
|
||||||
|
arguments = launchArgs.Arguments;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,10 +10,6 @@ namespace Snap.Hutao.Core.Setting;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal static class LocalSetting
|
internal static class LocalSetting
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 由于 <see cref="Windows.Foundation.Collections.IPropertySet"/> 没有 nullable context,
|
|
||||||
/// 在处理引用类型时需要格外小心
|
|
||||||
/// </summary>
|
|
||||||
private static readonly ApplicationDataContainer Container;
|
private static readonly ApplicationDataContainer Container;
|
||||||
|
|
||||||
static LocalSetting()
|
static LocalSetting()
|
||||||
@@ -21,6 +17,198 @@ internal static class LocalSetting
|
|||||||
Container = ApplicationData.Current.LocalSettings;
|
Container = ApplicationData.Current.LocalSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Get{T}(string, T)"/>
|
||||||
|
public static byte Get(string key, byte defaultValue)
|
||||||
|
{
|
||||||
|
return Get<byte>(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Get{T}(string, T)"/>
|
||||||
|
public static short Get(string key, short defaultValue)
|
||||||
|
{
|
||||||
|
return Get<short>(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Get{T}(string, T)"/>
|
||||||
|
public static ushort Get(string key, ushort defaultValue)
|
||||||
|
{
|
||||||
|
return Get<ushort>(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Get{T}(string, T)"/>
|
||||||
|
public static int Get(string key, int defaultValue)
|
||||||
|
{
|
||||||
|
return Get<int>(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Get{T}(string, T)"/>
|
||||||
|
public static uint Get(string key, uint defaultValue)
|
||||||
|
{
|
||||||
|
return Get<uint>(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Get{T}(string, T)"/>
|
||||||
|
public static ulong Get(string key, ulong defaultValue)
|
||||||
|
{
|
||||||
|
return Get<ulong>(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Get{T}(string, T)"/>
|
||||||
|
public static float Get(string key, float defaultValue)
|
||||||
|
{
|
||||||
|
return Get<float>(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Get{T}(string, T)"/>
|
||||||
|
public static double Get(string key, double defaultValue)
|
||||||
|
{
|
||||||
|
return Get<double>(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Get{T}(string, T)"/>
|
||||||
|
public static bool Get(string key, bool defaultValue)
|
||||||
|
{
|
||||||
|
return Get<bool>(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Get{T}(string, T)"/>
|
||||||
|
public static char Get(string key, char defaultValue)
|
||||||
|
{
|
||||||
|
return Get<char>(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Get{T}(string, T)"/>
|
||||||
|
public static DateTimeOffset Get(string key, DateTimeOffset defaultValue)
|
||||||
|
{
|
||||||
|
return Get<DateTimeOffset>(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Get{T}(string, T)"/>
|
||||||
|
public static TimeSpan Get(string key, TimeSpan defaultValue)
|
||||||
|
{
|
||||||
|
return Get<TimeSpan>(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Get{T}(string, T)"/>
|
||||||
|
public static Guid Get(string key, Guid defaultValue)
|
||||||
|
{
|
||||||
|
return Get<Guid>(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Get{T}(string, T)"/>
|
||||||
|
public static Windows.Foundation.Point Get(string key, Windows.Foundation.Point defaultValue)
|
||||||
|
{
|
||||||
|
return Get<Windows.Foundation.Point>(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Get{T}(string, T)"/>
|
||||||
|
public static Windows.Foundation.Size Get(string key, Windows.Foundation.Size defaultValue)
|
||||||
|
{
|
||||||
|
return Get<Windows.Foundation.Size>(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Get{T}(string, T)"/>
|
||||||
|
public static Windows.Foundation.Rect Get(string key, Windows.Foundation.Rect defaultValue)
|
||||||
|
{
|
||||||
|
return Get<Windows.Foundation.Rect>(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Set{T}(string, T)"/>
|
||||||
|
public static void Set(string key, byte value)
|
||||||
|
{
|
||||||
|
Set<byte>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Set{T}(string, T)"/>
|
||||||
|
public static void Set(string key, short value)
|
||||||
|
{
|
||||||
|
Set<short>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Set{T}(string, T)"/>
|
||||||
|
public static void Set(string key, ushort value)
|
||||||
|
{
|
||||||
|
Set<ushort>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Set{T}(string, T)"/>
|
||||||
|
public static void Set(string key, int value)
|
||||||
|
{
|
||||||
|
Set<int>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Set{T}(string, T)"/>
|
||||||
|
public static void Set(string key, uint value)
|
||||||
|
{
|
||||||
|
Set<uint>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Set{T}(string, T)"/>
|
||||||
|
public static void Set(string key, ulong value)
|
||||||
|
{
|
||||||
|
Set<ulong>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Set{T}(string, T)"/>
|
||||||
|
public static void Set(string key, float value)
|
||||||
|
{
|
||||||
|
Set<float>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Set{T}(string, T)"/>
|
||||||
|
public static void Set(string key, double value)
|
||||||
|
{
|
||||||
|
Set<double>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Set{T}(string, T)"/>
|
||||||
|
public static void Set(string key, bool value)
|
||||||
|
{
|
||||||
|
Set<bool>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Set{T}(string, T)"/>
|
||||||
|
public static void Set(string key, char value)
|
||||||
|
{
|
||||||
|
Set<char>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Set{T}(string, T)"/>
|
||||||
|
public static void Set(string key, DateTimeOffset value)
|
||||||
|
{
|
||||||
|
Set<DateTimeOffset>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Set{T}(string, T)"/>
|
||||||
|
public static void Set(string key, TimeSpan value)
|
||||||
|
{
|
||||||
|
Set<TimeSpan>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Set{T}(string, T)"/>
|
||||||
|
public static void Set(string key, Guid value)
|
||||||
|
{
|
||||||
|
Set<Guid>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Set{T}(string, T)"/>
|
||||||
|
public static void Set(string key, Windows.Foundation.Point value)
|
||||||
|
{
|
||||||
|
Set<Windows.Foundation.Point>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Set{T}(string, T)"/>
|
||||||
|
public static void Set(string key, Windows.Foundation.Size value)
|
||||||
|
{
|
||||||
|
Set<Windows.Foundation.Size>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Set{T}(string, T)"/>
|
||||||
|
public static void Set(string key, Windows.Foundation.Rect value)
|
||||||
|
{
|
||||||
|
Set<Windows.Foundation.Rect>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取设置项的值
|
/// 获取设置项的值
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -28,8 +216,8 @@ internal static class LocalSetting
|
|||||||
/// <param name="key">键</param>
|
/// <param name="key">键</param>
|
||||||
/// <param name="defaultValue">默认值</param>
|
/// <param name="defaultValue">默认值</param>
|
||||||
/// <returns>获取的值</returns>
|
/// <returns>获取的值</returns>
|
||||||
[return: MaybeNull]
|
private static T Get<T>(string key, T defaultValue = default)
|
||||||
public static T Get<T>(string key, [AllowNull] T defaultValue = default)
|
where T : struct
|
||||||
{
|
{
|
||||||
if (Container.Values.TryGetValue(key, out object? value))
|
if (Container.Values.TryGetValue(key, out object? value))
|
||||||
{
|
{
|
||||||
@@ -49,9 +237,9 @@ internal static class LocalSetting
|
|||||||
/// <typeparam name="T">设置项的类型</typeparam>
|
/// <typeparam name="T">设置项的类型</typeparam>
|
||||||
/// <param name="key">键</param>
|
/// <param name="key">键</param>
|
||||||
/// <param name="value">值</param>
|
/// <param name="value">值</param>
|
||||||
/// <returns>设置的值</returns>
|
private static void Set<T>(string key, T value)
|
||||||
public static object? Set<T>(string key, T value)
|
where T : struct
|
||||||
{
|
{
|
||||||
return Container.Values[key] = value;
|
Container.Values[key] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ internal static class Persistence
|
|||||||
/// <param name="appWindow">应用窗体</param>
|
/// <param name="appWindow">应用窗体</param>
|
||||||
public static void Save(AppWindow appWindow)
|
public static void Save(AppWindow appWindow)
|
||||||
{
|
{
|
||||||
LocalSetting.Set(SettingKeys.WindowRect, (ulong)(CompactRect)appWindow.GetRect());
|
LocalSetting.Set(SettingKeys.WindowRect, (CompactRect)appWindow.GetRect());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -124,7 +124,7 @@ internal static class Persistence
|
|||||||
return new(rect.X, rect.Y, rect.Width, rect.Height);
|
return new(rect.X, rect.Y, rect.Width, rect.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static explicit operator ulong(CompactRect rect)
|
public static implicit operator ulong(CompactRect rect)
|
||||||
{
|
{
|
||||||
return rect.Value;
|
return rect.Value;
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/Snap.Hutao/Snap.Hutao/LaunchGameWindow.xaml
Normal file
12
src/Snap.Hutao/Snap.Hutao/LaunchGameWindow.xaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<Window
|
||||||
|
x:Class="Snap.Hutao.LaunchGameWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="using:Snap.Hutao"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
<Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
20
src/Snap.Hutao/Snap.Hutao/LaunchGameWindow.xaml.cs
Normal file
20
src/Snap.Hutao/Snap.Hutao/LaunchGameWindow.xaml.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
|
||||||
|
namespace Snap.Hutao;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启动游戏窗口
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class LaunchGameWindow : Window
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 构造一个新的启动游戏窗口
|
||||||
|
/// </summary>
|
||||||
|
public LaunchGameWindow()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,11 @@ namespace Snap.Hutao.Model.Binding.Gacha;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class HistoryWish : WishBase
|
public class HistoryWish : WishBase
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 版本
|
||||||
|
/// </summary>
|
||||||
|
public string Version { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 五星Up
|
/// 五星Up
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
// Copyright (c) DGP Studio. All rights reserved.
|
|
||||||
// Licensed under the MIT license.
|
|
||||||
|
|
||||||
namespace Snap.Hutao.Model.Metadata.Avatar;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 角色ID
|
|
||||||
/// </summary>
|
|
||||||
[SuppressMessage("", "SA1600")]
|
|
||||||
public static class AvatarIds
|
|
||||||
{
|
|
||||||
public const int Ayaka = 10000002;
|
|
||||||
public const int Qin = 10000003;
|
|
||||||
|
|
||||||
public const int Lisa = 10000006;
|
|
||||||
|
|
||||||
public const int Barbara = 10000014;
|
|
||||||
public const int Kaeya = 10000015;
|
|
||||||
public const int Diluc = 10000016;
|
|
||||||
|
|
||||||
public const int Razor = 10000020;
|
|
||||||
public const int Ambor = 10000021;
|
|
||||||
public const int Venti = 10000022;
|
|
||||||
public const int Xiangling = 10000023;
|
|
||||||
public const int Beidou = 10000024;
|
|
||||||
public const int Xingqiu = 10000025;
|
|
||||||
public const int Xiao = 10000026;
|
|
||||||
public const int Ningguang = 10000027;
|
|
||||||
|
|
||||||
public const int Klee = 10000029;
|
|
||||||
public const int Zhongli = 10000030;
|
|
||||||
public const int Fischl = 10000031;
|
|
||||||
public const int Bennett = 10000032;
|
|
||||||
public const int Tartaglia = 10000033;
|
|
||||||
public const int Noel = 10000034;
|
|
||||||
public const int Qiqi = 10000035;
|
|
||||||
public const int Chongyun = 10000036;
|
|
||||||
public const int Ganyu = 10000037;
|
|
||||||
public const int Albedo = 10000038;
|
|
||||||
public const int Diona = 10000039;
|
|
||||||
|
|
||||||
public const int Mona = 10000041;
|
|
||||||
public const int Keqing = 10000042;
|
|
||||||
public const int Sucrose = 10000043;
|
|
||||||
public const int Xinyan = 10000044;
|
|
||||||
public const int Rosaria = 10000045;
|
|
||||||
public const int Hutao = 10000046;
|
|
||||||
public const int Kazuha = 10000047;
|
|
||||||
public const int Feiyan = 10000048;
|
|
||||||
public const int Yoimiya = 10000049;
|
|
||||||
public const int Tohma = 10000050;
|
|
||||||
public const int Eula = 10000051;
|
|
||||||
public const int Shougun = 10000052;
|
|
||||||
public const int Sayu = 10000053;
|
|
||||||
public const int Kokomi = 10000054;
|
|
||||||
public const int Gorou = 10000055;
|
|
||||||
public const int Sara = 10000056;
|
|
||||||
public const int Itto = 10000057;
|
|
||||||
public const int Yae = 10000058;
|
|
||||||
public const int Heizou = 10000059;
|
|
||||||
public const int Yelan = 10000060;
|
|
||||||
|
|
||||||
public const int Aloy = 10000062;
|
|
||||||
public const int Shenhe = 10000063;
|
|
||||||
public const int Yunjin = 10000064;
|
|
||||||
public const int Shinobu = 10000065;
|
|
||||||
public const int Ayato = 10000066;
|
|
||||||
public const int Collei = 10000067;
|
|
||||||
public const int Dori = 10000068;
|
|
||||||
public const int Tighnari = 10000069;
|
|
||||||
public const int Nilou = 10000070;
|
|
||||||
public const int Cyno = 10000071;
|
|
||||||
public const int Candace = 10000072;
|
|
||||||
public const int Nahida = 10000073;
|
|
||||||
public const int Layla = 10000074;
|
|
||||||
}
|
|
||||||
57
src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/CookBonus.cs
Normal file
57
src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/CookBonus.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Snap.Hutao.Model.Intrinsic;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Model.Metadata.Avatar;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 料理奖励
|
||||||
|
/// </summary>
|
||||||
|
public class CookBonus
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 原型名称
|
||||||
|
/// </summary>
|
||||||
|
public string OriginName { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 原型描述
|
||||||
|
/// </summary>
|
||||||
|
public string OriginDescription { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 原型图标
|
||||||
|
/// </summary>
|
||||||
|
public string OriginIcon { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 名称
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 描述
|
||||||
|
/// </summary>
|
||||||
|
public string Description { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 效果描述
|
||||||
|
/// </summary>
|
||||||
|
public string EffectDescription { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 图标
|
||||||
|
/// </summary>
|
||||||
|
public string Icon { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 物品等级
|
||||||
|
/// </summary>
|
||||||
|
public ItemQuality RankLevel { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 材料列表
|
||||||
|
/// </summary>
|
||||||
|
public List<ItemWithCount> InputList { get; set; } = default!;
|
||||||
|
}
|
||||||
@@ -76,6 +76,11 @@ public class FetterInfo
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string CvKorean { get; set; } = default!;
|
public string CvKorean { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 料理
|
||||||
|
/// </summary>
|
||||||
|
public CookBonus? CookBonus { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 好感语音
|
/// 好感语音
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Snap.Hutao.Model.Intrinsic;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Model.Metadata.Avatar;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 带有个数的物品
|
||||||
|
/// </summary>
|
||||||
|
public class ItemWithCount
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 物品Id
|
||||||
|
/// </summary>
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 名称
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 图标
|
||||||
|
/// </summary>
|
||||||
|
public string Icon { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 物品等级
|
||||||
|
/// </summary>
|
||||||
|
public ItemQuality RankLevel { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 数量
|
||||||
|
/// </summary>
|
||||||
|
public int Count { get; set; }
|
||||||
|
}
|
||||||
78
src/Snap.Hutao/Snap.Hutao/Model/Metadata/AvatarIds.cs
Normal file
78
src/Snap.Hutao/Snap.Hutao/Model/Metadata/AvatarIds.cs
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Snap.Hutao.Model.Primitive;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Model.Metadata;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 角色ID
|
||||||
|
/// </summary>
|
||||||
|
[SuppressMessage("", "SA1600")]
|
||||||
|
public static class AvatarIds
|
||||||
|
{
|
||||||
|
public static readonly AvatarId Ayaka = 10000002;
|
||||||
|
public static readonly AvatarId Qin = 10000003;
|
||||||
|
|
||||||
|
public static readonly AvatarId Lisa = 10000006;
|
||||||
|
|
||||||
|
public static readonly AvatarId Barbara = 10000014;
|
||||||
|
public static readonly AvatarId Kaeya = 10000015;
|
||||||
|
public static readonly AvatarId Diluc = 10000016;
|
||||||
|
|
||||||
|
public static readonly AvatarId Razor = 10000020;
|
||||||
|
public static readonly AvatarId Ambor = 10000021;
|
||||||
|
public static readonly AvatarId Venti = 10000022;
|
||||||
|
public static readonly AvatarId Xiangling = 10000023;
|
||||||
|
public static readonly AvatarId Beidou = 10000024;
|
||||||
|
public static readonly AvatarId Xingqiu = 10000025;
|
||||||
|
public static readonly AvatarId Xiao = 10000026;
|
||||||
|
public static readonly AvatarId Ningguang = 10000027;
|
||||||
|
|
||||||
|
public static readonly AvatarId Klee = 10000029;
|
||||||
|
public static readonly AvatarId Zhongli = 10000030;
|
||||||
|
public static readonly AvatarId Fischl = 10000031;
|
||||||
|
public static readonly AvatarId Bennett = 10000032;
|
||||||
|
public static readonly AvatarId Tartaglia = 10000033;
|
||||||
|
public static readonly AvatarId Noel = 10000034;
|
||||||
|
public static readonly AvatarId Qiqi = 10000035;
|
||||||
|
public static readonly AvatarId Chongyun = 10000036;
|
||||||
|
public static readonly AvatarId Ganyu = 10000037;
|
||||||
|
public static readonly AvatarId Albedo = 10000038;
|
||||||
|
public static readonly AvatarId Diona = 10000039;
|
||||||
|
|
||||||
|
public static readonly AvatarId Mona = 10000041;
|
||||||
|
public static readonly AvatarId Keqing = 10000042;
|
||||||
|
public static readonly AvatarId Sucrose = 10000043;
|
||||||
|
public static readonly AvatarId Xinyan = 10000044;
|
||||||
|
public static readonly AvatarId Rosaria = 10000045;
|
||||||
|
public static readonly AvatarId Hutao = 10000046;
|
||||||
|
public static readonly AvatarId Kazuha = 10000047;
|
||||||
|
public static readonly AvatarId Feiyan = 10000048;
|
||||||
|
public static readonly AvatarId Yoimiya = 10000049;
|
||||||
|
public static readonly AvatarId Tohma = 10000050;
|
||||||
|
public static readonly AvatarId Eula = 10000051;
|
||||||
|
public static readonly AvatarId Shougun = 10000052;
|
||||||
|
public static readonly AvatarId Sayu = 10000053;
|
||||||
|
public static readonly AvatarId Kokomi = 10000054;
|
||||||
|
public static readonly AvatarId Gorou = 10000055;
|
||||||
|
public static readonly AvatarId Sara = 10000056;
|
||||||
|
public static readonly AvatarId Itto = 10000057;
|
||||||
|
public static readonly AvatarId Yae = 10000058;
|
||||||
|
public static readonly AvatarId Heizou = 10000059;
|
||||||
|
public static readonly AvatarId Yelan = 10000060;
|
||||||
|
|
||||||
|
public static readonly AvatarId Aloy = 10000062;
|
||||||
|
public static readonly AvatarId Shenhe = 10000063;
|
||||||
|
public static readonly AvatarId Yunjin = 10000064;
|
||||||
|
public static readonly AvatarId Shinobu = 10000065;
|
||||||
|
public static readonly AvatarId Ayato = 10000066;
|
||||||
|
public static readonly AvatarId Collei = 10000067;
|
||||||
|
public static readonly AvatarId Dori = 10000068;
|
||||||
|
public static readonly AvatarId Tighnari = 10000069;
|
||||||
|
public static readonly AvatarId Nilou = 10000070;
|
||||||
|
public static readonly AvatarId Cyno = 10000071;
|
||||||
|
public static readonly AvatarId Candace = 10000072;
|
||||||
|
public static readonly AvatarId Nahida = 10000073;
|
||||||
|
public static readonly AvatarId Layla = 10000074;
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Snap.Hutao.Control;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Model.Metadata.Converter;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 立绘图标转换器
|
||||||
|
/// </summary>
|
||||||
|
internal class GachaAvatarIconConverter : ValueConverterBase<string, Uri>
|
||||||
|
{
|
||||||
|
private const string BaseUrl = "https://static.snapgenshin.com/GachaAvatarIcon/UI_Gacha_AvatarIcon_{0}.png";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 名称转Uri
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">名称</param>
|
||||||
|
/// <returns>链接</returns>
|
||||||
|
public static Uri IconNameToUri(string name)
|
||||||
|
{
|
||||||
|
name = name["UI_AvatarIcon_".Length..];
|
||||||
|
return new Uri(string.Format(BaseUrl, name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override Uri Convert(string from)
|
||||||
|
{
|
||||||
|
return IconNameToUri(from);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ using Snap.Hutao.Control;
|
|||||||
namespace Snap.Hutao.Model.Metadata.Converter;
|
namespace Snap.Hutao.Model.Metadata.Converter;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 角色头像转换器
|
/// 立绘转换器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class GachaAvatarImgConverter : ValueConverterBase<string, Uri>
|
internal class GachaAvatarImgConverter : ValueConverterBase<string, Uri>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Snap.Hutao.Control;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Model.Metadata.Converter;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 物品图片转换器
|
||||||
|
/// </summary>
|
||||||
|
internal class ItemIconConverter : ValueConverterBase<string, Uri>
|
||||||
|
{
|
||||||
|
private const string BaseUrl = "https://static.snapgenshin.com/ItemIcon/{0}.png";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 名称转Uri
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">名称</param>
|
||||||
|
/// <returns>链接</returns>
|
||||||
|
public static Uri IconNameToUri(string name)
|
||||||
|
{
|
||||||
|
return new Uri(string.Format(BaseUrl, name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override Uri Convert(string from)
|
||||||
|
{
|
||||||
|
return IconNameToUri(from);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,11 @@ public class GachaEvent
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; set; } = default!;
|
public string Name { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 版本
|
||||||
|
/// </summary>
|
||||||
|
public string Version { get; set; } = default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 开始时间
|
/// 开始时间
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<Identity
|
<Identity
|
||||||
Name="7f0db578-026f-4e0b-a75b-d5d06bb0a74d"
|
Name="7f0db578-026f-4e0b-a75b-d5d06bb0a74d"
|
||||||
Publisher="CN=DGP Studio"
|
Publisher="CN=DGP Studio"
|
||||||
Version="1.1.13.0" />
|
Version="1.1.14.0" />
|
||||||
|
|
||||||
<Properties>
|
<Properties>
|
||||||
<DisplayName>胡桃</DisplayName>
|
<DisplayName>胡桃</DisplayName>
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using Microsoft.UI.Dispatching;
|
|||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
using Snap.Hutao.Core.Logging;
|
using Snap.Hutao.Core.Logging;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Windows.UI.ViewManagement;
|
|
||||||
using WinRT;
|
using WinRT;
|
||||||
|
|
||||||
namespace Snap.Hutao;
|
namespace Snap.Hutao;
|
||||||
@@ -32,6 +31,7 @@ public static partial class Program
|
|||||||
private static void Main(string[] args)
|
private static void Main(string[] args)
|
||||||
{
|
{
|
||||||
_ = args;
|
_ = args;
|
||||||
|
|
||||||
XamlCheckProcessRequirements();
|
XamlCheckProcessRequirements();
|
||||||
ComWrappersSupport.InitializeComWrappers();
|
ComWrappersSupport.InitializeComWrappers();
|
||||||
|
|
||||||
@@ -75,7 +75,6 @@ public static partial class Program
|
|||||||
|
|
||||||
// Discrete services
|
// Discrete services
|
||||||
.AddSingleton<IMessenger>(WeakReferenceMessenger.Default)
|
.AddSingleton<IMessenger>(WeakReferenceMessenger.Default)
|
||||||
.AddSingleton(new UISettings())
|
|
||||||
|
|
||||||
.BuildServiceProvider();
|
.BuildServiceProvider();
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
@@ -2,7 +2,7 @@
|
|||||||
// Licensed under the MIT license.
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
using Snap.Hutao.Model.Intrinsic;
|
using Snap.Hutao.Model.Intrinsic;
|
||||||
using Snap.Hutao.Model.Metadata.Avatar;
|
using Snap.Hutao.Model.Metadata;
|
||||||
|
|
||||||
namespace Snap.Hutao.Service.AvatarInfo.Factory;
|
namespace Snap.Hutao.Service.AvatarInfo.Factory;
|
||||||
|
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ internal class HistoryWishBuilder
|
|||||||
TotalCount = totalCountTracker,
|
TotalCount = totalCountTracker,
|
||||||
|
|
||||||
// fill
|
// fill
|
||||||
|
Version = gachaEvent.Version,
|
||||||
OrangeUpList = orangeUpCounter.ToStatisticsList(),
|
OrangeUpList = orangeUpCounter.ToStatisticsList(),
|
||||||
PurpleUpList = purpleUpCounter.ToStatisticsList(),
|
PurpleUpList = purpleUpCounter.ToStatisticsList(),
|
||||||
OrangeList = orangeCounter.ToStatisticsList(),
|
OrangeList = orangeCounter.ToStatisticsList(),
|
||||||
|
|||||||
@@ -1,82 +1,181 @@
|
|||||||
// Copyright (c) DGP Studio. All rights reserved.
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
// Licensed under the MIT license.
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Snap.Hutao.Context.Database;
|
using Snap.Hutao.Context.Database;
|
||||||
|
using Snap.Hutao.Core;
|
||||||
using Snap.Hutao.Core.Database;
|
using Snap.Hutao.Core.Database;
|
||||||
using Snap.Hutao.Core.Threading;
|
using Snap.Hutao.Core.Threading;
|
||||||
using Snap.Hutao.Model.Entity;
|
using Snap.Hutao.Model.Entity;
|
||||||
using Snap.Hutao.Service.Game.Locator;
|
using Snap.Hutao.Service.Game.Locator;
|
||||||
|
using Snap.Hutao.Service.Game.Unlocker;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace Snap.Hutao.Service.Game;
|
namespace Snap.Hutao.Service.Game;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 游戏服务
|
/// 游戏服务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Injection(InjectAs.Transient, typeof(IGameService))]
|
[Injection(InjectAs.Singleton, typeof(IGameService))]
|
||||||
internal class GameService : IGameService
|
internal class GameService : IGameService
|
||||||
{
|
{
|
||||||
private readonly AppDbContext appDbContext;
|
private const string GamePathKey = $"{nameof(GameService)}.Cache.{SettingEntry.GamePath}";
|
||||||
|
|
||||||
|
private readonly IServiceScopeFactory scopeFactory;
|
||||||
private readonly IMemoryCache memoryCache;
|
private readonly IMemoryCache memoryCache;
|
||||||
private readonly IEnumerable<IGameLocator> gameLocators;
|
private readonly SemaphoreSlim gameSemaphore = new(1);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构造一个新的游戏服务
|
/// 构造一个新的游戏服务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="appDbContext">数据库上下文</param>
|
/// <param name="scopeFactory">范围工厂</param>
|
||||||
/// <param name="memoryCache">内存缓存</param>
|
/// <param name="memoryCache">内存缓存</param>
|
||||||
/// <param name="gameLocators">游戏定位器集合</param>
|
/// <param name="gameLocators">游戏定位器集合</param>
|
||||||
public GameService(AppDbContext appDbContext, IMemoryCache memoryCache, IEnumerable<IGameLocator> gameLocators)
|
public GameService(IServiceScopeFactory scopeFactory, IMemoryCache memoryCache)
|
||||||
{
|
{
|
||||||
this.appDbContext = appDbContext;
|
this.scopeFactory = scopeFactory;
|
||||||
this.memoryCache = memoryCache;
|
this.memoryCache = memoryCache;
|
||||||
this.gameLocators = gameLocators;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public async ValueTask<ValueResult<bool, string>> GetGamePathAsync()
|
public async ValueTask<ValueResult<bool, string>> GetGamePathAsync()
|
||||||
{
|
{
|
||||||
string key = $"{nameof(GameService)}.Cache.{SettingEntry.GamePath}";
|
if (memoryCache.TryGetValue(GamePathKey, out object? value))
|
||||||
|
|
||||||
if (memoryCache.TryGetValue(key, out object? value))
|
|
||||||
{
|
{
|
||||||
return new(true, Must.NotNull((value as string)!));
|
return new(true, Must.NotNull((value as string)!));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SettingEntry entry = appDbContext.Settings.SingleOrAdd(e => e.Key == SettingEntry.GamePath, () => new(SettingEntry.GamePath, null), out bool added);
|
using (IServiceScope scope = scopeFactory.CreateScope())
|
||||||
|
|
||||||
// Cannot find in setting
|
|
||||||
if (added)
|
|
||||||
{
|
{
|
||||||
// Try locate by registry
|
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||||
IGameLocator locator = gameLocators.Single(l => l.Name == nameof(RegistryLauncherLocator));
|
|
||||||
ValueResult<bool, string> result = await locator.LocateGamePathAsync().ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (!result.IsOk)
|
SettingEntry entry = appDbContext.Settings.SingleOrAdd(e => e.Key == SettingEntry.GamePath, () => new(SettingEntry.GamePath, null), out bool added);
|
||||||
|
|
||||||
|
// Cannot find in setting
|
||||||
|
if (added)
|
||||||
{
|
{
|
||||||
// Try locate manually
|
IEnumerable<IGameLocator> gameLocators = scope.ServiceProvider.GetRequiredService<IEnumerable<IGameLocator>>();
|
||||||
locator = gameLocators.Single(l => l.Name == nameof(ManualGameLocator));
|
|
||||||
result = await locator.LocateGamePathAsync().ConfigureAwait(false);
|
// Try locate by registry
|
||||||
|
IGameLocator locator = gameLocators.Single(l => l.Name == nameof(RegistryLauncherLocator));
|
||||||
|
ValueResult<bool, string> result = await locator.LocateGamePathAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (!result.IsOk)
|
||||||
|
{
|
||||||
|
// Try locate manually
|
||||||
|
locator = gameLocators.Single(l => l.Name == nameof(ManualGameLocator));
|
||||||
|
result = await locator.LocateGamePathAsync().ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.IsOk)
|
||||||
|
{
|
||||||
|
// Save result.
|
||||||
|
entry.Value = result.Value;
|
||||||
|
appDbContext.Settings.UpdateAndSave(entry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new(false, null!);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.IsOk)
|
// Set cache and return.
|
||||||
|
string path = memoryCache.Set(GamePathKey, Must.NotNull(entry.Value!));
|
||||||
|
return new(true, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public string GetGamePathSkipLocator()
|
||||||
|
{
|
||||||
|
if (memoryCache.TryGetValue(GamePathKey, out object? value))
|
||||||
|
{
|
||||||
|
return (value as string)!;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
using (IServiceScope scope = scopeFactory.CreateScope())
|
||||||
|
{
|
||||||
|
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||||
|
SettingEntry entry = appDbContext.Settings.SingleOrAdd(e => e.Key == SettingEntry.GamePath, () => new(SettingEntry.GamePath, null), out bool added);
|
||||||
|
|
||||||
|
entry.Value ??= string.Empty;
|
||||||
|
appDbContext.Settings.UpdateAndSave(entry);
|
||||||
|
|
||||||
|
// Set cache and return.
|
||||||
|
return memoryCache.Set(GamePathKey, entry.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void OverwriteGamePath(string path)
|
||||||
|
{
|
||||||
|
// sync cache
|
||||||
|
memoryCache.Set(GamePathKey, path);
|
||||||
|
|
||||||
|
using (IServiceScope scope = scopeFactory.CreateScope())
|
||||||
|
{
|
||||||
|
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||||
|
|
||||||
|
SettingEntry entry = appDbContext.Settings.SingleOrAdd(e => e.Key == SettingEntry.GamePath, () => new(SettingEntry.GamePath, null), out _);
|
||||||
|
entry.Value = path;
|
||||||
|
appDbContext.Settings.UpdateAndSave(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public async ValueTask LaunchAsync(LaunchConfiguration configuration)
|
||||||
|
{
|
||||||
|
(bool isOk, string gamePath) = await GetGamePathAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (isOk)
|
||||||
|
{
|
||||||
|
if (gameSemaphore.CurrentCount == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string commandLine = new CommandLineBuilder()
|
||||||
|
.Append("-window-mode", configuration.WindowMode)
|
||||||
|
.Append("-screen-fullscreen", configuration.IsFullScreen ? 1 : 0)
|
||||||
|
.Append("-screen-width", configuration.ScreenWidth)
|
||||||
|
.Append("-screen-height", configuration.ScreenHeight)
|
||||||
|
.Append("-monitor", configuration.Monitor)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Process game = new()
|
||||||
|
{
|
||||||
|
StartInfo = new()
|
||||||
{
|
{
|
||||||
// Save result.
|
Arguments = commandLine,
|
||||||
entry.Value = result.Value;
|
FileName = gamePath,
|
||||||
appDbContext.Settings.Update(entry);
|
UseShellExecute = true,
|
||||||
await appDbContext.SaveChangesAsync().ConfigureAwait(false);
|
Verb = "runas",
|
||||||
|
WorkingDirectory = Path.GetDirectoryName(gamePath),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
using (await gameSemaphore.EnterAsync().ConfigureAwait(false))
|
||||||
|
{
|
||||||
|
if (configuration.UnlockFPS)
|
||||||
|
{
|
||||||
|
IGameFpsUnlocker unlocker = new GameFpsUnlocker(game, configuration.TargetFPS);
|
||||||
|
|
||||||
|
await unlocker.UnlockAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(10000), TimeSpan.FromMilliseconds(2000)).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new(false, null!);
|
if (game.Start())
|
||||||
|
{
|
||||||
|
await game.WaitForExitAsync().ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set cache and return.
|
|
||||||
string path = memoryCache.Set(key, Must.NotNull(entry.Value!));
|
|
||||||
return new(true, path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,4 +15,23 @@ internal interface IGameService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>结果</returns>
|
/// <returns>结果</returns>
|
||||||
ValueTask<ValueResult<bool, string>> GetGamePathAsync();
|
ValueTask<ValueResult<bool, string>> GetGamePathAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取游戏路径,跳过异步定位器
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>游戏路径,当路径无效时会设置并返回 <see cref="string.Empty"/></returns>
|
||||||
|
string GetGamePathSkipLocator();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步启动
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="configuration">启动配置</param>
|
||||||
|
/// <returns>任务</returns>
|
||||||
|
ValueTask LaunchAsync(LaunchConfiguration configuration);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重写游戏路径
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">路径</param>
|
||||||
|
void OverwriteGamePath(string path);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Service.Game;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启动游戏配置
|
||||||
|
/// </summary>
|
||||||
|
internal struct LaunchConfiguration
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 是否全屏,全屏时无边框设置将被覆盖
|
||||||
|
/// </summary>
|
||||||
|
public bool IsFullScreen { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Override fullscreen windowed mode. Accepted values are exclusive or borderless.
|
||||||
|
/// </summary>
|
||||||
|
public string WindowMode { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否启用解锁帧率
|
||||||
|
/// </summary>
|
||||||
|
public bool UnlockFPS { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 目标帧率
|
||||||
|
/// </summary>
|
||||||
|
public int TargetFPS { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 窗口宽度
|
||||||
|
/// </summary>
|
||||||
|
public int ScreenWidth { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 窗口高度
|
||||||
|
/// </summary>
|
||||||
|
public int ScreenHeight { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示器编号
|
||||||
|
/// </summary>
|
||||||
|
public int Monitor { get; private set; }
|
||||||
|
}
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="Control\Panel\PanelSelector.xaml" />
|
<None Remove="Control\Panel\PanelSelector.xaml" />
|
||||||
|
<None Remove="LaunchGameWindow.xaml" />
|
||||||
<None Remove="NativeMethods.json" />
|
<None Remove="NativeMethods.json" />
|
||||||
<None Remove="NativeMethods.txt" />
|
<None Remove="NativeMethods.txt" />
|
||||||
<None Remove="Resource\Icon\UI_BagTabIcon_Avatar.png" />
|
<None Remove="Resource\Icon\UI_BagTabIcon_Avatar.png" />
|
||||||
@@ -41,6 +42,7 @@
|
|||||||
<None Remove="Resource\Icon\UI_BtnIcon_ActivityEntry.png" />
|
<None Remove="Resource\Icon\UI_BtnIcon_ActivityEntry.png" />
|
||||||
<None Remove="Resource\Icon\UI_BtnIcon_Gacha.png" />
|
<None Remove="Resource\Icon\UI_BtnIcon_Gacha.png" />
|
||||||
<None Remove="Resource\Icon\UI_ChapterIcon_Hutao.png" />
|
<None Remove="Resource\Icon\UI_ChapterIcon_Hutao.png" />
|
||||||
|
<None Remove="Resource\Icon\UI_GuideIcon_PlayMethod.png" />
|
||||||
<None Remove="Resource\Icon\UI_Icon_Achievement.png" />
|
<None Remove="Resource\Icon\UI_Icon_Achievement.png" />
|
||||||
<None Remove="Resource\Icon\UI_Icon_BoostUp.png" />
|
<None Remove="Resource\Icon\UI_Icon_BoostUp.png" />
|
||||||
<None Remove="Resource\Icon\UI_Icon_Locked.png" />
|
<None Remove="Resource\Icon\UI_Icon_Locked.png" />
|
||||||
@@ -67,6 +69,7 @@
|
|||||||
<None Remove="View\Page\AvatarPropertyPage.xaml" />
|
<None Remove="View\Page\AvatarPropertyPage.xaml" />
|
||||||
<None Remove="View\Page\GachaLogPage.xaml" />
|
<None Remove="View\Page\GachaLogPage.xaml" />
|
||||||
<None Remove="View\Page\HutaoDatabasePage.xaml" />
|
<None Remove="View\Page\HutaoDatabasePage.xaml" />
|
||||||
|
<None Remove="View\Page\LaunchGamePage.xaml" />
|
||||||
<None Remove="View\Page\SettingPage.xaml" />
|
<None Remove="View\Page\SettingPage.xaml" />
|
||||||
<None Remove="View\Page\WikiAvatarPage.xaml" />
|
<None Remove="View\Page\WikiAvatarPage.xaml" />
|
||||||
<None Remove="View\TitleView.xaml" />
|
<None Remove="View\TitleView.xaml" />
|
||||||
@@ -93,6 +96,7 @@
|
|||||||
<Content Include="Resource\Icon\UI_BtnIcon_ActivityEntry.png" />
|
<Content Include="Resource\Icon\UI_BtnIcon_ActivityEntry.png" />
|
||||||
<Content Include="Resource\Icon\UI_BtnIcon_Gacha.png" />
|
<Content Include="Resource\Icon\UI_BtnIcon_Gacha.png" />
|
||||||
<Content Include="Resource\Icon\UI_ChapterIcon_Hutao.png" />
|
<Content Include="Resource\Icon\UI_ChapterIcon_Hutao.png" />
|
||||||
|
<Content Include="Resource\Icon\UI_GuideIcon_PlayMethod.png" />
|
||||||
<Content Include="Resource\Icon\UI_Icon_Achievement.png" />
|
<Content Include="Resource\Icon\UI_Icon_Achievement.png" />
|
||||||
<Content Include="Resource\Icon\UI_Icon_BoostUp.png" />
|
<Content Include="Resource\Icon\UI_Icon_BoostUp.png" />
|
||||||
<Content Include="Resource\Icon\UI_Icon_Locked.png" />
|
<Content Include="Resource\Icon\UI_Icon_Locked.png" />
|
||||||
@@ -144,6 +148,16 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\.editorconfig" Link=".editorconfig" />
|
<None Include="..\.editorconfig" Link=".editorconfig" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="LaunchGameWindow.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="View\Page\LaunchGamePage.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Page Update="View\Page\HutaoDatabasePage.xaml">
|
<Page Update="View\Page\HutaoDatabasePage.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
|||||||
@@ -28,6 +28,11 @@
|
|||||||
|
|
||||||
<NavigationViewItemHeader Content="工具"/>
|
<NavigationViewItemHeader Content="工具"/>
|
||||||
|
|
||||||
|
<NavigationViewItem
|
||||||
|
Content="启动游戏"
|
||||||
|
shvh:NavHelper.NavigateTo="shvp:LaunchGamePage"
|
||||||
|
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Icon/UI_GuideIcon_PlayMethod.png}"/>
|
||||||
|
|
||||||
<NavigationViewItem
|
<NavigationViewItem
|
||||||
Content="祈愿记录"
|
Content="祈愿记录"
|
||||||
shvh:NavHelper.NavigateTo="shvp:GachaLogPage"
|
shvh:NavHelper.NavigateTo="shvp:GachaLogPage"
|
||||||
|
|||||||
@@ -2,9 +2,6 @@
|
|||||||
// Licensed under the MIT license.
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
using Microsoft.UI.Xaml.Controls;
|
using Microsoft.UI.Xaml.Controls;
|
||||||
using Snap.Hutao.Core;
|
|
||||||
using Snap.Hutao.Core.Logging;
|
|
||||||
using Snap.Hutao.Core.Threading;
|
|
||||||
using Snap.Hutao.Service.Abstraction;
|
using Snap.Hutao.Service.Abstraction;
|
||||||
using Snap.Hutao.Service.Navigation;
|
using Snap.Hutao.Service.Navigation;
|
||||||
using Snap.Hutao.View.Page;
|
using Snap.Hutao.View.Page;
|
||||||
@@ -34,22 +31,4 @@ public sealed partial class MainView : UserControl
|
|||||||
|
|
||||||
navigationService.Navigate<AnnouncementPage>(INavigationAwaiter.Default, true);
|
navigationService.Navigate<AnnouncementPage>(INavigationAwaiter.Default, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UpdateThemeAsync()
|
|
||||||
{
|
|
||||||
// It seems that UISettings.ColorValuesChanged
|
|
||||||
// event can raise up on a background thread.
|
|
||||||
await ThreadHelper.SwitchToMainThreadAsync();
|
|
||||||
|
|
||||||
App current = Ioc.Default.GetRequiredService<App>();
|
|
||||||
|
|
||||||
if (!ThemeHelper.Equals(current.RequestedTheme, RequestedTheme))
|
|
||||||
{
|
|
||||||
ILogger<MainView> logger = Ioc.Default.GetRequiredService<ILogger<MainView>>();
|
|
||||||
logger.LogInformation(EventIds.CommonLog, "Element Theme [{element}] | App Theme [{app}]", RequestedTheme, current.RequestedTheme);
|
|
||||||
|
|
||||||
// Update controls' theme which presents in the PopupRoot
|
|
||||||
RequestedTheme = ThemeHelper.ApplicationToElement(current.RequestedTheme);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -4,24 +4,17 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:cwuc="using:CommunityToolkit.WinUI.UI.Converters"
|
|
||||||
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
|
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
|
||||||
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
||||||
xmlns:shc="using:Snap.Hutao.Control"
|
xmlns:shc="using:Snap.Hutao.Control"
|
||||||
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
|
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
|
||||||
xmlns:shci="using:Snap.Hutao.Control.Image"
|
xmlns:shci="using:Snap.Hutao.Control.Image"
|
||||||
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||||
xmlns:shmmc="using:Snap.Hutao.Model.Metadata.Converter"
|
|
||||||
xmlns:shv="using:Snap.Hutao.ViewModel"
|
xmlns:shv="using:Snap.Hutao.ViewModel"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||||
d:DataContext="{d:DesignInstance shv:AchievementViewModel}">
|
d:DataContext="{d:DesignInstance shv:AchievementViewModel}">
|
||||||
|
|
||||||
<shc:ScopedPage.Resources>
|
|
||||||
<shmmc:AchievementIconConverter x:Key="AchievementIconConverter"/>
|
|
||||||
<cwuc:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
|
|
||||||
</shc:ScopedPage.Resources>
|
|
||||||
|
|
||||||
<mxi:Interaction.Behaviors>
|
<mxi:Interaction.Behaviors>
|
||||||
<shcb:InvokeCommandOnLoadedBehavior Command="{Binding OpenUICommand}"/>
|
<shcb:InvokeCommandOnLoadedBehavior Command="{Binding OpenUICommand}"/>
|
||||||
</mxi:Interaction.Behaviors>
|
</mxi:Interaction.Behaviors>
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
xmlns:cwua="using:CommunityToolkit.WinUI.UI.Animations"
|
xmlns:cwua="using:CommunityToolkit.WinUI.UI.Animations"
|
||||||
xmlns:cwub="using:CommunityToolkit.WinUI.UI.Behaviors"
|
xmlns:cwub="using:CommunityToolkit.WinUI.UI.Behaviors"
|
||||||
xmlns:cwucont="using:CommunityToolkit.WinUI.UI.Controls"
|
xmlns:cwucont="using:CommunityToolkit.WinUI.UI.Controls"
|
||||||
xmlns:cwuconv="using:CommunityToolkit.WinUI.UI.Converters"
|
|
||||||
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
|
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
|
||||||
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
||||||
xmlns:shc="using:Snap.Hutao.Control"
|
xmlns:shc="using:Snap.Hutao.Control"
|
||||||
@@ -21,7 +20,6 @@
|
|||||||
<shcb:InvokeCommandOnLoadedBehavior Command="{Binding OpenUICommand}"/>
|
<shcb:InvokeCommandOnLoadedBehavior Command="{Binding OpenUICommand}"/>
|
||||||
</mxi:Interaction.Behaviors>
|
</mxi:Interaction.Behaviors>
|
||||||
<shc:ScopedPage.Resources>
|
<shc:ScopedPage.Resources>
|
||||||
<cwuconv:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
|
|
||||||
<shc:BindingProxy x:Key="BindingProxy" DataContext="{Binding}"/>
|
<shc:BindingProxy x:Key="BindingProxy" DataContext="{Binding}"/>
|
||||||
</shc:ScopedPage.Resources>
|
</shc:ScopedPage.Resources>
|
||||||
<Grid>
|
<Grid>
|
||||||
|
|||||||
@@ -36,8 +36,6 @@
|
|||||||
<x:Double>0.5</x:Double>
|
<x:Double>0.5</x:Double>
|
||||||
</cwuconv:BoolToObjectConverter.FalseValue>
|
</cwuconv:BoolToObjectConverter.FalseValue>
|
||||||
</cwuconv:BoolToObjectConverter>
|
</cwuconv:BoolToObjectConverter>
|
||||||
<shvconv:BoolToVisibilityRevertConverter x:Key="BoolToVisibilityRevertConverter"/>
|
|
||||||
<shmmc:QualityColorConverter x:Key="QualityColorConverter"/>
|
|
||||||
</Page.Resources>
|
</Page.Resources>
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
|
|||||||
@@ -140,10 +140,17 @@
|
|||||||
<RowDefinition/>
|
<RowDefinition/>
|
||||||
<RowDefinition/>
|
<RowDefinition/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<TextBlock
|
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
|
||||||
Margin="0,8,0,0"
|
<TextBlock
|
||||||
Text="{Binding Name}"
|
Width="32"
|
||||||
Style="{StaticResource BaseTextBlockStyle}"/>
|
Text="{Binding Version}"
|
||||||
|
Style="{StaticResource BaseTextBlockStyle}"/>
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,0,0"
|
||||||
|
Text="{Binding Name}"
|
||||||
|
Style="{StaticResource BaseTextBlockStyle}"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="0,8,0,0"
|
Margin="0,8,0,0"
|
||||||
Text="{Binding TotalCountFormatted}"
|
Text="{Binding TotalCountFormatted}"
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
|
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
|
||||||
xmlns:shvc="using:Snap.Hutao.View.Control"
|
xmlns:shvc="using:Snap.Hutao.View.Control"
|
||||||
xmlns:shv="using:Snap.Hutao.ViewModel"
|
xmlns:shv="using:Snap.Hutao.ViewModel"
|
||||||
|
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||||
|
xmlns:sc="using:SettingsUI.Controls"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DataContext="{d:DesignInstance shv:HutaoDatabaseViewModel}"
|
d:DataContext="{d:DesignInstance shv:HutaoDatabaseViewModel}"
|
||||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
@@ -26,11 +28,15 @@
|
|||||||
<Grid>
|
<Grid>
|
||||||
<Pivot>
|
<Pivot>
|
||||||
<Pivot.RightHeader>
|
<Pivot.RightHeader>
|
||||||
<CommandBar>
|
<CommandBar DefaultLabelPosition="Right">
|
||||||
<AppBarButton>
|
<AppBarButton Label="详情" Icon="{shcm:FontIcon Glyph=}">
|
||||||
<AppBarButton.Flyout>
|
<AppBarButton.Flyout>
|
||||||
<Flyout>
|
<Flyout Placement="BottomEdgeAlignedRight">
|
||||||
|
<sc:SettingsGroup Header="数据来自「胡桃数据库」" Margin="0,-32,0,0" MinWidth="240">
|
||||||
|
<sc:Setting Header="上传记录总数" Content="{Binding Overview.RecordTotal}"/>
|
||||||
|
<sc:Setting Header="深渊记录总数" Content="{Binding Overview.SpiralAbyssTotal}"/>
|
||||||
|
<sc:Setting Header="深渊记录满星数" Content="{Binding Overview.SpiralAbyssFullStar}"/>
|
||||||
|
</sc:SettingsGroup>
|
||||||
</Flyout>
|
</Flyout>
|
||||||
</AppBarButton.Flyout>
|
</AppBarButton.Flyout>
|
||||||
</AppBarButton>
|
</AppBarButton>
|
||||||
|
|||||||
132
src/Snap.Hutao/Snap.Hutao/View/Page/LaunchGamePage.xaml
Normal file
132
src/Snap.Hutao/Snap.Hutao/View/Page/LaunchGamePage.xaml
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
<control:ScopedPage
|
||||||
|
x:Class="Snap.Hutao.View.Page.LaunchGamePage"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:sc="using:SettingsUI.Controls"
|
||||||
|
xmlns:control="using:Snap.Hutao.Control"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
|
<Page.Resources>
|
||||||
|
<Style TargetType="Button" BasedOn="{StaticResource SettingButtonStyle}">
|
||||||
|
<Setter Property="MinWidth" Value="120"/>
|
||||||
|
</Style>
|
||||||
|
<Style TargetType="HyperlinkButton" BasedOn="{StaticResource HyperlinkButtonStyle}">
|
||||||
|
<Setter Property="MinWidth" Value="120"/>
|
||||||
|
</Style>
|
||||||
|
</Page.Resources>
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<ScrollViewer Grid.Column="0">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition MaxWidth="800"/>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<StackPanel Margin="32,0,24,24">
|
||||||
|
<sc:SettingsGroup Header="常规" Margin="0,0,0,0">
|
||||||
|
<sc:Setting
|
||||||
|
Icon=""
|
||||||
|
Header="服务器"
|
||||||
|
Description="切换游戏服务器,B服用户需要自备额外的 PCGameSDK.dll 文件">
|
||||||
|
<sc:Setting.ActionContent>
|
||||||
|
<ComboBox Width="120"/>
|
||||||
|
</sc:Setting.ActionContent>
|
||||||
|
</sc:Setting>
|
||||||
|
</sc:SettingsGroup>
|
||||||
|
<sc:SettingsGroup Header="外观">
|
||||||
|
<sc:Setting
|
||||||
|
Icon=""
|
||||||
|
Header="全屏"
|
||||||
|
Description="覆盖默认的全屏状态">
|
||||||
|
<sc:Setting.ActionContent>
|
||||||
|
<ToggleSwitch
|
||||||
|
Style="{StaticResource ToggleSwitchSettingStyle}"
|
||||||
|
Width="120"/>
|
||||||
|
</sc:Setting.ActionContent>
|
||||||
|
</sc:Setting>
|
||||||
|
<sc:Setting
|
||||||
|
Icon=""
|
||||||
|
Header="无边框"
|
||||||
|
Description="将窗口创建为弹出窗口,不带框架">
|
||||||
|
<sc:Setting.ActionContent>
|
||||||
|
<ToggleSwitch
|
||||||
|
Style="{StaticResource ToggleSwitchSettingStyle}"
|
||||||
|
Width="120"/>
|
||||||
|
</sc:Setting.ActionContent>
|
||||||
|
</sc:Setting>
|
||||||
|
|
||||||
|
<sc:Setting
|
||||||
|
Margin="0,6,0,0"
|
||||||
|
Icon=""
|
||||||
|
Header="宽度"
|
||||||
|
Description="覆盖默认屏幕宽度">
|
||||||
|
<sc:Setting.ActionContent>
|
||||||
|
<NumberBox
|
||||||
|
Width="120"/>
|
||||||
|
</sc:Setting.ActionContent>
|
||||||
|
</sc:Setting>
|
||||||
|
<sc:Setting
|
||||||
|
Icon=""
|
||||||
|
Header="高度"
|
||||||
|
Description="覆盖默认屏幕高度">
|
||||||
|
<sc:Setting.ActionContent>
|
||||||
|
<NumberBox
|
||||||
|
Width="120"/>
|
||||||
|
</sc:Setting.ActionContent>
|
||||||
|
</sc:Setting>
|
||||||
|
</sc:SettingsGroup>
|
||||||
|
|
||||||
|
<sc:SettingsGroup Header="Dangerous feature">
|
||||||
|
<sc:Setting
|
||||||
|
Icon=""
|
||||||
|
Header="Unlock frame rate limit"
|
||||||
|
Description="Requires administrator privilege. Otherwise the option does not take effect.">
|
||||||
|
<sc:Setting.ActionContent>
|
||||||
|
<ToggleSwitch
|
||||||
|
OnContent="Enable"
|
||||||
|
OffContent="Disable"
|
||||||
|
Style="{StaticResource ToggleSwitchSettingStyle}"
|
||||||
|
Width="120"/>
|
||||||
|
</sc:Setting.ActionContent>
|
||||||
|
</sc:Setting>
|
||||||
|
<sc:Setting
|
||||||
|
Header="Set frame rate"
|
||||||
|
Description="60">
|
||||||
|
<sc:Setting.ActionContent>
|
||||||
|
<Slider
|
||||||
|
Minimum="60"
|
||||||
|
Maximum="360"
|
||||||
|
Width="400"/>
|
||||||
|
</sc:Setting.ActionContent>
|
||||||
|
</sc:Setting>
|
||||||
|
</sc:SettingsGroup>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
|
<Grid
|
||||||
|
Grid.Row="1"
|
||||||
|
VerticalAlignment="Bottom"
|
||||||
|
Background="{StaticResource CardBackgroundFillColorSecondary}">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<ComboBox
|
||||||
|
Header="原神账号"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="32,24,0,24"
|
||||||
|
Width="160"/>
|
||||||
|
<Button
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="24"
|
||||||
|
Width="138"
|
||||||
|
Content="启动游戏"/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</control:ScopedPage>
|
||||||
22
src/Snap.Hutao/Snap.Hutao/View/Page/LaunchGamePage.xaml.cs
Normal file
22
src/Snap.Hutao/Snap.Hutao/View/Page/LaunchGamePage.xaml.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Snap.Hutao.Control;
|
||||||
|
using Snap.Hutao.ViewModel;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.View.Page;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启动游戏页面
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class LaunchGamePage : ScopedPage
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 构造一个新的启动游戏页面
|
||||||
|
/// </summary>
|
||||||
|
public LaunchGamePage()
|
||||||
|
{
|
||||||
|
InitializeWith<LaunchGameViewModel>();
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -95,6 +95,17 @@
|
|||||||
|
|
||||||
</sc:SettingsGroup>
|
</sc:SettingsGroup>
|
||||||
|
|
||||||
|
<sc:SettingsGroup Header="游戏">
|
||||||
|
<sc:Setting
|
||||||
|
Icon=""
|
||||||
|
Header="游戏路径"
|
||||||
|
Description="{Binding GamePath}">
|
||||||
|
<sc:Setting.ActionContent>
|
||||||
|
<Button Content="设置路径" Command="{Binding SetGamePathCommand}"/>
|
||||||
|
</sc:Setting.ActionContent>
|
||||||
|
</sc:Setting>
|
||||||
|
</sc:SettingsGroup>
|
||||||
|
|
||||||
<sc:SettingsGroup Header="测试功能">
|
<sc:SettingsGroup Header="测试功能">
|
||||||
<sc:Setting
|
<sc:Setting
|
||||||
Icon=""
|
Icon=""
|
||||||
|
|||||||
@@ -8,11 +8,11 @@
|
|||||||
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
||||||
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
|
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
|
||||||
xmlns:shci="using:Snap.Hutao.Control.Image"
|
xmlns:shci="using:Snap.Hutao.Control.Image"
|
||||||
xmlns:shct="using:Snap.Hutao.Control.Text"
|
|
||||||
xmlns:shmmc="using:Snap.Hutao.Model.Metadata.Converter"
|
|
||||||
xmlns:shvc="using:Snap.Hutao.View.Control"
|
|
||||||
xmlns:shcp="using:Snap.Hutao.Control.Panel"
|
xmlns:shcp="using:Snap.Hutao.Control.Panel"
|
||||||
|
xmlns:shct="using:Snap.Hutao.Control.Text"
|
||||||
|
xmlns:shvc="using:Snap.Hutao.View.Control"
|
||||||
xmlns:shv="using:Snap.Hutao.ViewModel"
|
xmlns:shv="using:Snap.Hutao.ViewModel"
|
||||||
|
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DataContext="{d:DesignInstance Type=shv:WikiAvatarViewModel}"
|
d:DataContext="{d:DesignInstance Type=shv:WikiAvatarViewModel}"
|
||||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
@@ -20,16 +20,6 @@
|
|||||||
<shcb:InvokeCommandOnLoadedBehavior Command="{Binding OpenUICommand}"/>
|
<shcb:InvokeCommandOnLoadedBehavior Command="{Binding OpenUICommand}"/>
|
||||||
</mxi:Interaction.Behaviors>
|
</mxi:Interaction.Behaviors>
|
||||||
<Page.Resources>
|
<Page.Resources>
|
||||||
<shmmc:AvatarIconConverter x:Key="AvatarIconConverter"/>
|
|
||||||
<shmmc:AvatarSideIconConverter x:Key="AvatarSideIconConverter"/>
|
|
||||||
<shmmc:ElementNameIconConverter x:Key="ElementNameIconConverter"/>
|
|
||||||
<shmmc:WeaponTypeIconConverter x:Key="WeaponTypeIconConverter"/>
|
|
||||||
<shmmc:AvatarNameCardPicConverter x:Key="AvatarNameCardPicConverter"/>
|
|
||||||
<shmmc:GachaAvatarImgConverter x:Key="GachaAvatarImgConverter"/>
|
|
||||||
|
|
||||||
<shmmc:DescParamDescriptor x:Key="DescParamDescriptor"/>
|
|
||||||
<shmmc:PropertyInfoDescriptor x:Key="PropertyDescriptor"/>
|
|
||||||
|
|
||||||
<DataTemplate x:Key="SkillDataTemplate">
|
<DataTemplate x:Key="SkillDataTemplate">
|
||||||
<Grid Margin="0,12,0,0">
|
<Grid Margin="0,12,0,0">
|
||||||
<StackPanel Grid.Column="0">
|
<StackPanel Grid.Column="0">
|
||||||
@@ -92,10 +82,7 @@
|
|||||||
<shcp:PanelSelector Margin="6,8,0,0" x:Name="ItemsPanelSelector"/>
|
<shcp:PanelSelector Margin="6,8,0,0" x:Name="ItemsPanelSelector"/>
|
||||||
</CommandBar.Content>
|
</CommandBar.Content>
|
||||||
|
|
||||||
<AppBarButton Label="筛选">
|
<AppBarButton Label="筛选" Icon="{shcm:FontIcon Glyph=}">
|
||||||
<AppBarButton.Icon>
|
|
||||||
<FontIcon Glyph=""/>
|
|
||||||
</AppBarButton.Icon>
|
|
||||||
<AppBarButton.Flyout>
|
<AppBarButton.Flyout>
|
||||||
<Flyout Placement="RightEdgeAlignedTop" LightDismissOverlayMode="On">
|
<Flyout Placement="RightEdgeAlignedTop" LightDismissOverlayMode="On">
|
||||||
<cwuc:UniformGrid Columns="3" RowSpacing="16">
|
<cwuc:UniformGrid Columns="3" RowSpacing="16">
|
||||||
@@ -465,6 +452,176 @@
|
|||||||
</GridView>
|
</GridView>
|
||||||
|
|
||||||
<TextBlock Text="其他" Style="{StaticResource BaseTextBlockStyle}" Margin="16,32,0,0"/>
|
<TextBlock Text="其他" Style="{StaticResource BaseTextBlockStyle}" Margin="16,32,0,0"/>
|
||||||
|
<Border
|
||||||
|
Margin="16,16,0,0"
|
||||||
|
Background="{StaticResource CardBackgroundFillColorDefault}"
|
||||||
|
BorderThickness="1"
|
||||||
|
BorderBrush="{StaticResource CardStrokeColorDefault}"
|
||||||
|
CornerRadius="{StaticResource CompatCornerRadius}">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<mxi:Interaction.Behaviors>
|
||||||
|
<shcb:AutoHeightBehavior TargetWidth="2048" TargetHeight="1024"/>
|
||||||
|
</mxi:Interaction.Behaviors>
|
||||||
|
<Border
|
||||||
|
Background="{StaticResource CardBackgroundFillColorDefault}"
|
||||||
|
BorderThickness="1"
|
||||||
|
BorderBrush="{StaticResource CardStrokeColorDefault}"
|
||||||
|
CornerRadius="{StaticResource CompatCornerRadius}"
|
||||||
|
Margin="16"
|
||||||
|
Grid.Column="0">
|
||||||
|
<shci:CachedImage
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Source="{Binding Selected.Icon,Converter={StaticResource GachaAvatarIconConverter}}"/>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
|
||||||
|
<shci:CachedImage
|
||||||
|
Grid.ColumnSpan="2"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
Source="{Binding Selected.Icon,Converter={StaticResource GachaAvatarImgConverter}}"/>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
<!--料理-->
|
||||||
|
<Expander
|
||||||
|
Margin="16,16,0,0"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
HorizontalContentAlignment="Stretch"
|
||||||
|
Header="料理">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock
|
||||||
|
Margin="16,16,0,0"
|
||||||
|
Text="特殊料理"
|
||||||
|
Grid.Column="0"
|
||||||
|
Style="{StaticResource BaseTextBlockStyle}"/>
|
||||||
|
<Border
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="16,16,0,16"
|
||||||
|
CornerRadius="{StaticResource CompatCornerRadius}"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Background="{StaticResource CardBackgroundFillColorDefault}"
|
||||||
|
BorderThickness="1"
|
||||||
|
BorderBrush="{StaticResource CardStrokeColorDefault}">
|
||||||
|
<StackPanel>
|
||||||
|
<shvc:ItemIcon
|
||||||
|
Icon="{Binding Selected.FetterInfo.CookBonus.Icon,Converter={StaticResource ItemIconConverter}}"
|
||||||
|
Quality="{Binding Selected.FetterInfo.CookBonus.RankLevel}"/>
|
||||||
|
<TextBlock
|
||||||
|
TextTrimming="CharacterEllipsis"
|
||||||
|
TextWrapping="NoWrap"
|
||||||
|
MaxWidth="80"
|
||||||
|
Margin="0,0,0,2"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Style="{StaticResource CaptionTextBlockStyle}"
|
||||||
|
Text="{Binding Selected.FetterInfo.CookBonus.Name}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
<TextBlock
|
||||||
|
Margin="16,16,0,0"
|
||||||
|
Text="原料理"
|
||||||
|
Grid.Column="1"
|
||||||
|
Style="{StaticResource BaseTextBlockStyle}"/>
|
||||||
|
<Border
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="16,16,0,16"
|
||||||
|
CornerRadius="{StaticResource CompatCornerRadius}"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Background="{StaticResource CardBackgroundFillColorDefault}"
|
||||||
|
BorderThickness="1"
|
||||||
|
BorderBrush="{StaticResource CardStrokeColorDefault}">
|
||||||
|
<StackPanel>
|
||||||
|
<shvc:ItemIcon
|
||||||
|
Icon="{Binding Selected.FetterInfo.CookBonus.OriginIcon,Converter={StaticResource ItemIconConverter}}"
|
||||||
|
Quality="{Binding Selected.FetterInfo.CookBonus.RankLevel}"/>
|
||||||
|
<TextBlock
|
||||||
|
TextWrapping="NoWrap"
|
||||||
|
TextTrimming="CharacterEllipsis"
|
||||||
|
MaxWidth="80"
|
||||||
|
Margin="0,0,0,2"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Style="{StaticResource CaptionTextBlockStyle}"
|
||||||
|
Text="{Binding Selected.FetterInfo.CookBonus.OriginName}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
<Rectangle
|
||||||
|
Grid.Column="2"
|
||||||
|
Grid.RowSpan="2"
|
||||||
|
Width="1"
|
||||||
|
Fill="{StaticResource SystemChromeHighColor}"
|
||||||
|
Margin="16,16,0,16"/>
|
||||||
|
<TextBlock
|
||||||
|
Margin="16,16,0,0"
|
||||||
|
Text="材料"
|
||||||
|
Grid.Column="3"
|
||||||
|
Style="{StaticResource BaseTextBlockStyle}"/>
|
||||||
|
<ItemsControl
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="3"
|
||||||
|
ItemsSource="{Binding Selected.FetterInfo.CookBonus.InputList}"
|
||||||
|
ItemsPanel="{StaticResource HorizontalStackPanelTemplate}">
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Border
|
||||||
|
ToolTipService.ToolTip="{Binding Name}"
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="16,16,0,16"
|
||||||
|
CornerRadius="{StaticResource CompatCornerRadius}"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Background="{StaticResource CardBackgroundFillColorDefault}"
|
||||||
|
BorderThickness="1"
|
||||||
|
BorderBrush="{StaticResource CardStrokeColorDefault}">
|
||||||
|
<StackPanel>
|
||||||
|
<shvc:ItemIcon
|
||||||
|
Icon="{Binding Icon,Converter={StaticResource ItemIconConverter}}"
|
||||||
|
Quality="{Binding RankLevel}"/>
|
||||||
|
<TextBlock
|
||||||
|
TextTrimming="CharacterEllipsis"
|
||||||
|
MaxWidth="80"
|
||||||
|
Margin="0,0,0,2"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Style="{StaticResource CaptionTextBlockStyle}"
|
||||||
|
Text="{Binding Count}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="2"
|
||||||
|
Grid.ColumnSpan="4"
|
||||||
|
Margin="16,0,16,16"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Text="{Binding Selected.FetterInfo.CookBonus.Description}"/>
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="3"
|
||||||
|
Grid.ColumnSpan="4"
|
||||||
|
Margin="16,0,16,16"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Text="{Binding Selected.FetterInfo.CookBonus.EffectDescription}"/>
|
||||||
|
</Grid>
|
||||||
|
</Expander>
|
||||||
<!--衣装-->
|
<!--衣装-->
|
||||||
<Expander
|
<Expander
|
||||||
Margin="16,16,0,0"
|
Margin="16,16,0,0"
|
||||||
@@ -516,10 +673,10 @@
|
|||||||
</Expander>
|
</Expander>
|
||||||
<!--故事-->
|
<!--故事-->
|
||||||
<Expander
|
<Expander
|
||||||
Margin="16,16,0,0"
|
Margin="16,16,0,0"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
HorizontalContentAlignment="Stretch"
|
HorizontalContentAlignment="Stretch"
|
||||||
Header="故事">
|
Header="故事">
|
||||||
<ItemsControl
|
<ItemsControl
|
||||||
ItemsSource="{Binding Selected.FetterInfo.FetterStories}">
|
ItemsSource="{Binding Selected.FetterInfo.FetterStories}">
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
@@ -538,17 +695,6 @@
|
|||||||
</ItemsControl.ItemTemplate>
|
</ItemsControl.ItemTemplate>
|
||||||
</ItemsControl>
|
</ItemsControl>
|
||||||
</Expander>
|
</Expander>
|
||||||
|
|
||||||
<Border
|
|
||||||
Margin="16,16,0,0"
|
|
||||||
Background="{StaticResource CardBackgroundFillColorDefault}"
|
|
||||||
BorderThickness="1"
|
|
||||||
BorderBrush="{StaticResource CardStrokeColorDefault}"
|
|
||||||
CornerRadius="{StaticResource CompatCornerRadius}">
|
|
||||||
<shci:CachedImage
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
Source="{Binding Selected.Icon,Converter={StaticResource GachaAvatarImgConverter}}"/>
|
|
||||||
</Border>
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
xmlns:mxim="using:Microsoft.Xaml.Interactions.Media"
|
xmlns:mxim="using:Microsoft.Xaml.Interactions.Media"
|
||||||
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
||||||
xmlns:shc="using:Snap.Hutao.Control"
|
xmlns:shc="using:Snap.Hutao.Control"
|
||||||
xmlns:shvm="using:Snap.Hutao.ViewModel"
|
|
||||||
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||||
|
xmlns:shvm="using:Snap.Hutao.ViewModel"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DataContext="{d:DesignInstance shvm:UserViewModel}">
|
d:DataContext="{d:DesignInstance shvm:UserViewModel}">
|
||||||
<mxi:Interaction.Behaviors>
|
<mxi:Interaction.Behaviors>
|
||||||
@@ -120,11 +120,19 @@
|
|||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Margin="0,0"
|
Margin="0,0"
|
||||||
Height="32"/>
|
Height="32"/>
|
||||||
<TextBlock
|
<StackPanel
|
||||||
Margin="12,0,0,0"
|
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
VerticalAlignment="Center"
|
Margin="12,0,0,0"
|
||||||
Text="{Binding UserInfo.Nickname}"/>
|
VerticalAlignment="Center">
|
||||||
|
<TextBlock Text="{Binding UserInfo.Nickname}"/>
|
||||||
|
<TextBlock
|
||||||
|
Text="Stoken"
|
||||||
|
Visibility="{Binding HasSToken,Converter={StaticResource BoolToVisibilityConverter}}"
|
||||||
|
Style="{StaticResource CaptionTextBlockStyle}"
|
||||||
|
Foreground="Green"
|
||||||
|
Opacity="0.6"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel
|
<StackPanel
|
||||||
x:Name="ButtonPanel"
|
x:Name="ButtonPanel"
|
||||||
Orientation="Horizontal"
|
Orientation="Horizontal"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Snap.Hutao.Control;
|
|||||||
using Snap.Hutao.Factory.Abstraction;
|
using Snap.Hutao.Factory.Abstraction;
|
||||||
using Snap.Hutao.Model.Binding.Hutao;
|
using Snap.Hutao.Model.Binding.Hutao;
|
||||||
using Snap.Hutao.Service.Hutao;
|
using Snap.Hutao.Service.Hutao;
|
||||||
|
using Snap.Hutao.Web.Hutao.Model;
|
||||||
|
|
||||||
namespace Snap.Hutao.ViewModel;
|
namespace Snap.Hutao.ViewModel;
|
||||||
|
|
||||||
@@ -21,6 +22,7 @@ internal class HutaoDatabaseViewModel : ObservableObject, ISupportCancellation
|
|||||||
private List<ComplexAvatarRank>? avatarAppearanceRanks;
|
private List<ComplexAvatarRank>? avatarAppearanceRanks;
|
||||||
private List<ComplexAvatarConstellationInfo>? avatarConstellationInfos;
|
private List<ComplexAvatarConstellationInfo>? avatarConstellationInfos;
|
||||||
private List<ComplexTeamRank>? teamAppearances;
|
private List<ComplexTeamRank>? teamAppearances;
|
||||||
|
private Overview? overview;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构造一个新的胡桃数据库视图模型
|
/// 构造一个新的胡桃数据库视图模型
|
||||||
@@ -58,6 +60,11 @@ internal class HutaoDatabaseViewModel : ObservableObject, ISupportCancellation
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public List<ComplexTeamRank>? TeamAppearances { get => teamAppearances; set => SetProperty(ref teamAppearances, value); }
|
public List<ComplexTeamRank>? TeamAppearances { get => teamAppearances; set => SetProperty(ref teamAppearances, value); }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 总览数据
|
||||||
|
/// </summary>
|
||||||
|
public Overview? Overview { get => overview; set => SetProperty(ref overview, value); }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 打开界面命令
|
/// 打开界面命令
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -71,6 +78,7 @@ internal class HutaoDatabaseViewModel : ObservableObject, ISupportCancellation
|
|||||||
AvatarUsageRanks = hutaoCache.AvatarUsageRanks;
|
AvatarUsageRanks = hutaoCache.AvatarUsageRanks;
|
||||||
AvatarConstellationInfos = hutaoCache.AvatarConstellationInfos;
|
AvatarConstellationInfos = hutaoCache.AvatarConstellationInfos;
|
||||||
TeamAppearances = hutaoCache.TeamAppearances;
|
TeamAppearances = hutaoCache.TeamAppearances;
|
||||||
|
Overview = hutaoCache.Overview;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/Snap.Hutao/Snap.Hutao/ViewModel/LaunchGameViewModel.cs
Normal file
17
src/Snap.Hutao/Snap.Hutao/ViewModel/LaunchGameViewModel.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using Snap.Hutao.Control;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.ViewModel;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启动游戏视图模型
|
||||||
|
/// </summary>
|
||||||
|
[Injection(InjectAs.Scoped)]
|
||||||
|
internal class LaunchGameViewModel : ObservableObject, ISupportCancellation
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public CancellationToken CancellationToken { get; set; }
|
||||||
|
}
|
||||||
@@ -4,7 +4,11 @@
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using Snap.Hutao.Context.Database;
|
using Snap.Hutao.Context.Database;
|
||||||
using Snap.Hutao.Core.Database;
|
using Snap.Hutao.Core.Database;
|
||||||
|
using Snap.Hutao.Core.Threading;
|
||||||
|
using Snap.Hutao.Factory.Abstraction;
|
||||||
using Snap.Hutao.Model.Entity;
|
using Snap.Hutao.Model.Entity;
|
||||||
|
using Snap.Hutao.Service.Game;
|
||||||
|
using Snap.Hutao.Service.Game.Locator;
|
||||||
|
|
||||||
namespace Snap.Hutao.ViewModel;
|
namespace Snap.Hutao.ViewModel;
|
||||||
|
|
||||||
@@ -15,23 +19,33 @@ namespace Snap.Hutao.ViewModel;
|
|||||||
internal class SettingViewModel : ObservableObject
|
internal class SettingViewModel : ObservableObject
|
||||||
{
|
{
|
||||||
private readonly AppDbContext appDbContext;
|
private readonly AppDbContext appDbContext;
|
||||||
|
private readonly IGameService gameService;
|
||||||
private readonly SettingEntry isEmptyHistoryWishVisibleEntry;
|
private readonly SettingEntry isEmptyHistoryWishVisibleEntry;
|
||||||
|
|
||||||
private bool isEmptyHistoryWishVisible;
|
private bool isEmptyHistoryWishVisible;
|
||||||
|
private string gamePath;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构造一个新的测试视图模型
|
/// 构造一个新的测试视图模型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="appDbContext">数据库上下文</param>
|
/// <param name="appDbContext">数据库上下文</param>
|
||||||
|
/// <param name="gameService">游戏服务</param>
|
||||||
|
/// <param name="asyncRelayCommandFactory">异步命令工厂</param>
|
||||||
/// <param name="experimental">实验性功能</param>
|
/// <param name="experimental">实验性功能</param>
|
||||||
public SettingViewModel(AppDbContext appDbContext, ExperimentalFeaturesViewModel experimental)
|
public SettingViewModel(AppDbContext appDbContext, IGameService gameService, IAsyncRelayCommandFactory asyncRelayCommandFactory, ExperimentalFeaturesViewModel experimental)
|
||||||
{
|
{
|
||||||
this.appDbContext = appDbContext;
|
this.appDbContext = appDbContext;
|
||||||
|
this.gameService = gameService;
|
||||||
|
|
||||||
Experimental = experimental;
|
Experimental = experimental;
|
||||||
|
|
||||||
isEmptyHistoryWishVisibleEntry = appDbContext.Settings
|
isEmptyHistoryWishVisibleEntry = appDbContext.Settings
|
||||||
.SingleOrAdd(e => e.Key == SettingEntry.IsEmptyHistoryWishVisible, () => new(SettingEntry.IsEmptyHistoryWishVisible, true.ToString()), out _);
|
.SingleOrAdd(e => e.Key == SettingEntry.IsEmptyHistoryWishVisible, () => new(SettingEntry.IsEmptyHistoryWishVisible, true.ToString()), out _);
|
||||||
IsEmptyHistoryWishVisible = bool.Parse(isEmptyHistoryWishVisibleEntry.Value!);
|
IsEmptyHistoryWishVisible = bool.Parse(isEmptyHistoryWishVisibleEntry.Value!);
|
||||||
|
|
||||||
|
GamePath = gameService.GetGamePathSkipLocator();
|
||||||
|
|
||||||
|
SetGamePathCommand = asyncRelayCommandFactory.Create(SetGamePathAsync);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -56,8 +70,37 @@ internal class SettingViewModel : ObservableObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 游戏路径
|
||||||
|
/// </summary>
|
||||||
|
public string GamePath
|
||||||
|
{
|
||||||
|
get => gamePath;
|
||||||
|
[MemberNotNull(nameof(gamePath))]
|
||||||
|
set => SetProperty(ref gamePath, value);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 实验性功能
|
/// 实验性功能
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExperimentalFeaturesViewModel Experimental { get; }
|
public ExperimentalFeaturesViewModel Experimental { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置游戏路径命令
|
||||||
|
/// </summary>
|
||||||
|
public ICommand SetGamePathCommand { get; }
|
||||||
|
|
||||||
|
private async Task SetGamePathAsync()
|
||||||
|
{
|
||||||
|
IGameLocator locator = Ioc.Default.GetRequiredService<IEnumerable<IGameLocator>>()
|
||||||
|
.Single(l => l.Name == nameof(ManualGameLocator));
|
||||||
|
|
||||||
|
(bool isOk, string path) = await locator.LocateGamePathAsync().ConfigureAwait(false);
|
||||||
|
if (isOk)
|
||||||
|
{
|
||||||
|
gameService.OverwriteGamePath(path);
|
||||||
|
await ThreadHelper.SwitchToMainThreadAsync();
|
||||||
|
GamePath = path;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user