mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
support game resource download switch
This commit is contained in:
@@ -66,6 +66,7 @@
|
|||||||
<!-- Converters -->
|
<!-- Converters -->
|
||||||
<cwuc:BoolNegationConverter x:Key="BoolNegationConverter"/>
|
<cwuc:BoolNegationConverter x:Key="BoolNegationConverter"/>
|
||||||
<cwuc:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
|
<cwuc:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
|
||||||
|
<cwuc:FileSizeToFriendlyStringConverter x:Key="FileSizeToFriendlyStringConverter"/>
|
||||||
<shmmc:AchievementIconConverter x:Key="AchievementIconConverter"/>
|
<shmmc:AchievementIconConverter x:Key="AchievementIconConverter"/>
|
||||||
<shmmc:AvatarCardConverter x:Key="AvatarCardConverter"/>
|
<shmmc:AvatarCardConverter x:Key="AvatarCardConverter"/>
|
||||||
<shmmc:AvatarIconConverter x:Key="AvatarIconConverter"/>
|
<shmmc:AvatarIconConverter x:Key="AvatarIconConverter"/>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using Snap.Hutao.Core;
|
|||||||
using Snap.Hutao.Core.ExceptionService;
|
using Snap.Hutao.Core.ExceptionService;
|
||||||
using Snap.Hutao.Core.LifeCycle;
|
using Snap.Hutao.Core.LifeCycle;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using Windows.ApplicationModel.Background;
|
||||||
using Windows.Storage;
|
using Windows.Storage;
|
||||||
|
|
||||||
namespace Snap.Hutao;
|
namespace Snap.Hutao;
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ using Snap.Hutao.Service.DailyNote;
|
|||||||
using Snap.Hutao.Service.Metadata;
|
using Snap.Hutao.Service.Metadata;
|
||||||
using Snap.Hutao.Service.Navigation;
|
using Snap.Hutao.Service.Navigation;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using Windows.ApplicationModel;
|
using Windows.ApplicationModel;
|
||||||
|
|
||||||
@@ -164,10 +163,7 @@ internal static class Activation
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
// Increase launch times
|
await HandleNormalLaunchActionAsync().ConfigureAwait(false);
|
||||||
LocalSetting.Set(SettingKeys.LaunchTimes, LocalSetting.Get(SettingKeys.LaunchTimes, 0) + 1);
|
|
||||||
|
|
||||||
await WaitMainWindowAsync().ConfigureAwait(false);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,6 +171,14 @@ internal static class Activation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task HandleNormalLaunchActionAsync()
|
||||||
|
{
|
||||||
|
// Increase launch times
|
||||||
|
LocalSetting.Set(SettingKeys.LaunchTimes, LocalSetting.Get(SettingKeys.LaunchTimes, 0) + 1);
|
||||||
|
|
||||||
|
await WaitMainWindowAsync().ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
private static async Task WaitMainWindowAsync()
|
private static async Task WaitMainWindowAsync()
|
||||||
{
|
{
|
||||||
await ThreadHelper.SwitchToMainThreadAsync();
|
await ThreadHelper.SwitchToMainThreadAsync();
|
||||||
@@ -211,6 +215,12 @@ internal static class Activation
|
|||||||
await HandleDailyNoteActionAsync(action, parameter, isRedirected).ConfigureAwait(false);
|
await HandleDailyNoteActionAsync(action, parameter, isRedirected).ConfigureAwait(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
await HandleNormalLaunchActionAsync().ConfigureAwait(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3714,6 +3714,51 @@ namespace Snap.Hutao.Resource.Localization {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 游戏选项 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
internal static string ViewPageLaunchGameOptionsHeader {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ViewPageLaunchGameOptionsHeader", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 增量包 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
internal static string ViewPageLaunchGameResourceDiffHeader {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ViewPageLaunchGameResourceDiffHeader", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 资源下载 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
internal static string ViewPageLaunchGameResourceHeader {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ViewPageLaunchGameResourceHeader", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 客户端 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
internal static string ViewPageLaunchGameResourceLatestHeader {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ViewPageLaunchGameResourceLatestHeader", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 预下载 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
internal static string ViewPageLaunchGameResourcePreDownloadHeader {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ViewPageLaunchGameResourcePreDownloadHeader", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 在游戏时可以随时调整 的本地化字符串。
|
/// 查找类似 在游戏时可以随时调整 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1335,6 +1335,21 @@
|
|||||||
<data name="ViewPageLaunchGameMonitorsHeader" xml:space="preserve">
|
<data name="ViewPageLaunchGameMonitorsHeader" xml:space="preserve">
|
||||||
<value>显示器</value>
|
<value>显示器</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ViewPageLaunchGameOptionsHeader" xml:space="preserve">
|
||||||
|
<value>游戏选项</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewPageLaunchGameResourceDiffHeader" xml:space="preserve">
|
||||||
|
<value>增量包</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewPageLaunchGameResourceHeader" xml:space="preserve">
|
||||||
|
<value>资源下载</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewPageLaunchGameResourceLatestHeader" xml:space="preserve">
|
||||||
|
<value>客户端</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewPageLaunchGameResourcePreDownloadHeader" xml:space="preserve">
|
||||||
|
<value>预下载</value>
|
||||||
|
</data>
|
||||||
<data name="ViewPageLaunchGameSetFpsDescription" xml:space="preserve">
|
<data name="ViewPageLaunchGameSetFpsDescription" xml:space="preserve">
|
||||||
<value>在游戏时可以随时调整</value>
|
<value>在游戏时可以随时调整</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -237,10 +237,14 @@ internal sealed class GameService : IGameService
|
|||||||
string gameFileName = Path.GetFileName(gamePath);
|
string gameFileName = Path.GetFileName(gamePath);
|
||||||
|
|
||||||
progress.Report(new(SH.ServiceGameEnsureGameResourceQueryResourceInformation));
|
progress.Report(new(SH.ServiceGameEnsureGameResourceQueryResourceInformation));
|
||||||
Response<GameResource> response = await Ioc.Default
|
Response<GameResource> response;
|
||||||
.GetRequiredService<ResourceClient>()
|
using (IServiceScope scope = scopeFactory.CreateScope())
|
||||||
.GetResourceAsync(launchScheme)
|
{
|
||||||
.ConfigureAwait(false);
|
response = await scope.ServiceProvider
|
||||||
|
.GetRequiredService<ResourceClient>()
|
||||||
|
.GetResourceAsync(launchScheme)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
if (response.IsOk())
|
if (response.IsOk())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,14 +40,14 @@ internal sealed class PackageConverter
|
|||||||
/// 调用前需要确认本地文件与服务器上的不同
|
/// 调用前需要确认本地文件与服务器上的不同
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="targetScheme">目标启动方案</param>
|
/// <param name="targetScheme">目标启动方案</param>
|
||||||
/// <param name="gameResouce">游戏资源</param>
|
/// <param name="gameResource">游戏资源</param>
|
||||||
/// <param name="gameFolder">游戏目录</param>
|
/// <param name="gameFolder">游戏目录</param>
|
||||||
/// <param name="progress">进度</param>
|
/// <param name="progress">进度</param>
|
||||||
/// <returns>替换结果与资源</returns>
|
/// <returns>替换结果与资源</returns>
|
||||||
public async Task<bool> EnsureGameResourceAsync(LaunchScheme targetScheme, GameResource gameResouce, string gameFolder, IProgress<PackageReplaceStatus> progress)
|
public async Task<bool> EnsureGameResourceAsync(LaunchScheme targetScheme, GameResource gameResource, string gameFolder, IProgress<PackageReplaceStatus> progress)
|
||||||
{
|
{
|
||||||
await ThreadHelper.SwitchToBackgroundAsync();
|
await ThreadHelper.SwitchToBackgroundAsync();
|
||||||
string scatteredFilesUrl = gameResouce.Game.Latest.DecompressedPath;
|
string scatteredFilesUrl = gameResource.Game.Latest.DecompressedPath;
|
||||||
Uri pkgVersionUri = $"{scatteredFilesUrl}/pkg_version".ToUri();
|
Uri pkgVersionUri = $"{scatteredFilesUrl}/pkg_version".ToUri();
|
||||||
ConvertDirection direction = targetScheme.IsOversea ? ConvertDirection.ChineseToOversea : ConvertDirection.OverseaToChinese;
|
ConvertDirection direction = targetScheme.IsOversea ? ConvertDirection.ChineseToOversea : ConvertDirection.OverseaToChinese;
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ internal sealed class PackageConverter
|
|||||||
Dictionary<string, VersionItem> localItems;
|
Dictionary<string, VersionItem> localItems;
|
||||||
using (FileStream localSteam = File.OpenRead(Path.Combine(gameFolder, "pkg_version")))
|
using (FileStream localSteam = File.OpenRead(Path.Combine(gameFolder, "pkg_version")))
|
||||||
{
|
{
|
||||||
localItems = await GetLocalVersionItemsAsync(localSteam, direction, ConvertRemoteName).ConfigureAwait(false);
|
localItems = await GetLocalVersionItemsAsync(localSteam, direction).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<ItemOperationInfo> diffOperations = GetItemOperationInfos(remoteItems, localItems).OrderBy(i => (int)i.Type);
|
IEnumerable<ItemOperationInfo> diffOperations = GetItemOperationInfos(remoteItems, localItems).OrderBy(i => (int)i.Type);
|
||||||
@@ -134,22 +134,6 @@ internal sealed class PackageConverter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ConvertRemoteName(string remoteName, ConvertDirection direction)
|
|
||||||
{
|
|
||||||
// 我们已经提前重命名了整个 Data 文件夹 所以需要将 RemoteName 中的 Data 同样替换
|
|
||||||
if (remoteName.StartsWith(YuanShenData) || remoteName.StartsWith(GenshinImpactData))
|
|
||||||
{
|
|
||||||
return direction switch
|
|
||||||
{
|
|
||||||
ConvertDirection.OverseaToChinese => $"{YuanShenData}{remoteName[GenshinImpactData.Length..]}",
|
|
||||||
ConvertDirection.ChineseToOversea => $"{GenshinImpactData}{remoteName[YuanShenData.Length..]}",
|
|
||||||
_ => remoteName,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return remoteName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<ItemOperationInfo> GetItemOperationInfos(Dictionary<string, VersionItem> remote, Dictionary<string, VersionItem> local)
|
private static IEnumerable<ItemOperationInfo> GetItemOperationInfos(Dictionary<string, VersionItem> remote, Dictionary<string, VersionItem> local)
|
||||||
{
|
{
|
||||||
foreach ((string remoteName, VersionItem remoteItem) in remote)
|
foreach ((string remoteName, VersionItem remoteItem) in remote)
|
||||||
@@ -368,7 +352,7 @@ internal sealed class PackageConverter
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Dictionary<string, VersionItem>> GetLocalVersionItemsAsync(Stream stream, ConvertDirection direction, Func<string, ConvertDirection, string> nameConverter)
|
private async Task<Dictionary<string, VersionItem>> GetLocalVersionItemsAsync(Stream stream, ConvertDirection direction)
|
||||||
{
|
{
|
||||||
Dictionary<string, VersionItem> results = new();
|
Dictionary<string, VersionItem> results = new();
|
||||||
|
|
||||||
@@ -379,7 +363,21 @@ internal sealed class PackageConverter
|
|||||||
if (!string.IsNullOrEmpty(raw))
|
if (!string.IsNullOrEmpty(raw))
|
||||||
{
|
{
|
||||||
VersionItem item = JsonSerializer.Deserialize<VersionItem>(raw, options)!;
|
VersionItem item = JsonSerializer.Deserialize<VersionItem>(raw, options)!;
|
||||||
results.Add(nameConverter(item.RemoteName, direction), item);
|
|
||||||
|
string remoteName = item.RemoteName;
|
||||||
|
|
||||||
|
// 我们已经提前重命名了整个 Data 文件夹 所以需要将 RemoteName 中的 Data 同样替换
|
||||||
|
if (remoteName.StartsWith(YuanShenData) || remoteName.StartsWith(GenshinImpactData))
|
||||||
|
{
|
||||||
|
remoteName = direction switch
|
||||||
|
{
|
||||||
|
ConvertDirection.OverseaToChinese => $"{YuanShenData}{remoteName[GenshinImpactData.Length..]}",
|
||||||
|
ConvertDirection.ChineseToOversea => $"{GenshinImpactData}{remoteName[YuanShenData.Length..]}",
|
||||||
|
_ => remoteName,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
results.Add(remoteName, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,7 @@
|
|||||||
<None Remove="View\Control\BottomTextControl.xaml" />
|
<None Remove="View\Control\BottomTextControl.xaml" />
|
||||||
<None Remove="View\Control\DescParamComboBox.xaml" />
|
<None Remove="View\Control\DescParamComboBox.xaml" />
|
||||||
<None Remove="View\Control\ItemIcon.xaml" />
|
<None Remove="View\Control\ItemIcon.xaml" />
|
||||||
|
<None Remove="View\Control\LaunchGameResourceExpander.xaml" />
|
||||||
<None Remove="View\Control\LoadingView.xaml" />
|
<None Remove="View\Control\LoadingView.xaml" />
|
||||||
<None Remove="View\Control\SkillPivot.xaml" />
|
<None Remove="View\Control\SkillPivot.xaml" />
|
||||||
<None Remove="View\Control\StatisticsCard.xaml" />
|
<None Remove="View\Control\StatisticsCard.xaml" />
|
||||||
@@ -446,6 +447,11 @@
|
|||||||
<LastGenOutput>SH.Designer.cs</LastGenOutput>
|
<LastGenOutput>SH.Designer.cs</LastGenOutput>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="View\Control\LaunchGameResourceExpander.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Page Update="View\Page\WikiMonsterPage.xaml">
|
<Page Update="View\Page\WikiMonsterPage.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
<Expander
|
||||||
|
x:Class="Snap.Hutao.View.Control.LaunchGameResourceExpander"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
HorizontalContentAlignment="Stretch"
|
||||||
|
IsExpanded="True"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid Margin="16,16,16,16">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<TextBlock Text="{Binding DisplayName}"/>
|
||||||
|
<StackPanel
|
||||||
|
Grid.Row="1"
|
||||||
|
Margin="0,4,0,0"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<FontIcon FontSize="{StaticResource CaptionTextBlockFontSize}" Glyph=""/>
|
||||||
|
<TextBlock
|
||||||
|
Width="80"
|
||||||
|
Margin="8,0,0,0"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Style="{StaticResource CaptionTextBlockStyle}"
|
||||||
|
Text="{Binding PackageSize, Converter={StaticResource FileSizeToFriendlyStringConverter}}"/>
|
||||||
|
<FontIcon FontSize="{StaticResource CaptionTextBlockFontSize}" Glyph=""/>
|
||||||
|
<TextBlock
|
||||||
|
Width="80"
|
||||||
|
Margin="8,0,0,0"
|
||||||
|
Style="{StaticResource CaptionTextBlockStyle}"
|
||||||
|
Text="{Binding Size, Converter={StaticResource FileSizeToFriendlyStringConverter}}"/>
|
||||||
|
<FontIcon FontSize="{StaticResource CaptionTextBlockFontSize}" Glyph=""/>
|
||||||
|
<TextBlock
|
||||||
|
Margin="8,0,0,0"
|
||||||
|
IsTextSelectionEnabled="True"
|
||||||
|
Style="{StaticResource CaptionTextBlockStyle}"
|
||||||
|
Text="{Binding Md5}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<HyperlinkButton
|
||||||
|
Grid.RowSpan="2"
|
||||||
|
Height="38.4"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Content=""
|
||||||
|
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
||||||
|
NavigateUri="{Binding Path}"/>
|
||||||
|
<MenuFlyoutSeparator Grid.Row="2" Margin="4,16,4,0"/>
|
||||||
|
<ItemsControl Grid.Row="3" ItemsSource="{Binding VoicePacks}">
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Grid Margin="0,16,0,0">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<TextBlock Text="{Binding DisplayName}"/>
|
||||||
|
<StackPanel
|
||||||
|
Grid.Row="1"
|
||||||
|
Margin="0,4,0,0"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<FontIcon FontSize="{StaticResource CaptionTextBlockFontSize}" Glyph=""/>
|
||||||
|
<TextBlock
|
||||||
|
Width="80"
|
||||||
|
Margin="8,0,0,0"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Style="{StaticResource CaptionTextBlockStyle}"
|
||||||
|
Text="{Binding PackageSize, Converter={StaticResource FileSizeToFriendlyStringConverter}}"/>
|
||||||
|
<FontIcon FontSize="{StaticResource CaptionTextBlockFontSize}" Glyph=""/>
|
||||||
|
<TextBlock
|
||||||
|
Width="80"
|
||||||
|
Margin="8,0,0,0"
|
||||||
|
Style="{StaticResource CaptionTextBlockStyle}"
|
||||||
|
Text="{Binding Size, Converter={StaticResource FileSizeToFriendlyStringConverter}}"/>
|
||||||
|
<FontIcon FontSize="{StaticResource CaptionTextBlockFontSize}" Glyph=""/>
|
||||||
|
<TextBlock
|
||||||
|
Margin="8,0,0,0"
|
||||||
|
IsTextSelectionEnabled="True"
|
||||||
|
Style="{StaticResource CaptionTextBlockStyle}"
|
||||||
|
Text="{Binding Md5}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<HyperlinkButton
|
||||||
|
Grid.RowSpan="2"
|
||||||
|
Height="38.4"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Content=""
|
||||||
|
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
||||||
|
NavigateUri="{Binding Path}"/>
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</Grid>
|
||||||
|
</Expander>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.View.Control;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7>Դ Expander
|
||||||
|
/// </summary>
|
||||||
|
internal sealed partial class LaunchGameResourceExpander : Expander
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7>Դ Expander
|
||||||
|
/// </summary>
|
||||||
|
public LaunchGameResourceExpander()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
|
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
|
||||||
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||||
xmlns:shv="using:Snap.Hutao.ViewModel"
|
xmlns:shv="using:Snap.Hutao.ViewModel"
|
||||||
|
xmlns:shvc="using:Snap.Hutao.View.Control"
|
||||||
xmlns:wsc="using:WinUICommunity.SettingsUI.Controls"
|
xmlns:wsc="using:WinUICommunity.SettingsUI.Controls"
|
||||||
d:DataContext="{d:DesignInstance shv:LaunchGameViewModel}"
|
d:DataContext="{d:DesignInstance shv:LaunchGameViewModel}"
|
||||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||||
@@ -23,13 +24,10 @@
|
|||||||
|
|
||||||
<Page.Resources>
|
<Page.Resources>
|
||||||
<shc:BindingProxy x:Key="BindingProxy" DataContext="{Binding}"/>
|
<shc:BindingProxy x:Key="BindingProxy" DataContext="{Binding}"/>
|
||||||
|
<Visibility x:Key="VisibilityCollapsed">Collapsed</Visibility>
|
||||||
<Style BasedOn="{StaticResource SettingButtonStyle}" TargetType="Button">
|
<Style BasedOn="{StaticResource SettingButtonStyle}" TargetType="Button">
|
||||||
<Setter Property="MinWidth" Value="156"/>
|
<Setter Property="MinWidth" Value="156"/>
|
||||||
</Style>
|
</Style>
|
||||||
<Style BasedOn="{StaticResource HyperlinkButtonStyle}" TargetType="HyperlinkButton">
|
|
||||||
<Setter Property="MinWidth" Value="156"/>
|
|
||||||
</Style>
|
|
||||||
<Style BasedOn="{StaticResource DefaultComboBoxStyle}" TargetType="ComboBox">
|
<Style BasedOn="{StaticResource DefaultComboBoxStyle}" TargetType="ComboBox">
|
||||||
<Setter Property="MinWidth" Value="156"/>
|
<Setter Property="MinWidth" Value="156"/>
|
||||||
</Style>
|
</Style>
|
||||||
@@ -38,267 +36,291 @@
|
|||||||
</Style>
|
</Style>
|
||||||
</Page.Resources>
|
</Page.Resources>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Rectangle
|
||||||
<RowDefinition/>
|
Height="48"
|
||||||
<RowDefinition Height="auto"/>
|
VerticalAlignment="Top"
|
||||||
</Grid.RowDefinitions>
|
Fill="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||||
<ScrollViewer Grid.RowSpan="2">
|
IsHitTestVisible="False"/>
|
||||||
<Grid>
|
<Pivot>
|
||||||
<Grid.ColumnDefinitions>
|
<Pivot.RightHeader>
|
||||||
<ColumnDefinition MaxWidth="800"/>
|
<CommandBar DefaultLabelPosition="Right">
|
||||||
<ColumnDefinition Width="auto"/>
|
<AppBarButton
|
||||||
</Grid.ColumnDefinitions>
|
Command="{Binding LaunchCommand}"
|
||||||
<StackPanel Margin="16">
|
Icon="{shcm:FontIcon Glyph=}"
|
||||||
<InfoBar
|
Label="{shcm:ResourceString Name=ViewPageLaunchGameAction}"/>
|
||||||
IsClosable="False"
|
</CommandBar>
|
||||||
IsOpen="True"
|
</Pivot.RightHeader>
|
||||||
Message="{shcm:ResourceString Name=ViewPageLaunchGameConfigurationSaveHint}"
|
|
||||||
Severity="Informational"/>
|
<PivotItem Header="{shcm:ResourceString Name=ViewPageLaunchGameOptionsHeader}">
|
||||||
<InfoBar
|
<ScrollViewer Grid.RowSpan="2">
|
||||||
Margin="0,2,0,0"
|
<Grid>
|
||||||
IsClosable="False"
|
<Grid.ColumnDefinitions>
|
||||||
IsOpen="{Binding IsElevated, Converter={StaticResource BoolNegationConverter}}"
|
<ColumnDefinition MaxWidth="1000"/>
|
||||||
Message="{shcm:ResourceString Name=ViewPageLaunchGameElevationHint}"
|
<ColumnDefinition Width="auto"/>
|
||||||
Severity="Warning"/>
|
</Grid.ColumnDefinitions>
|
||||||
<wsc:SettingsGroup Margin="0,0,0,0" Header="{shcm:ResourceString Name=ViewPageLaunchGameCommonHeader}">
|
<StackPanel Margin="16">
|
||||||
<InfoBar
|
<InfoBar
|
||||||
IsClosable="False"
|
IsClosable="False"
|
||||||
IsOpen="{Binding IsElevated}"
|
IsOpen="True"
|
||||||
Message="{shcm:ResourceString Name=ViewPageLaunchGameSwitchSchemeHint}"
|
Message="{shcm:ResourceString Name=ViewPageLaunchGameConfigurationSaveHint}"
|
||||||
Severity="Informational"/>
|
Severity="Informational"/>
|
||||||
<wsc:Setting
|
<InfoBar
|
||||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameSwitchSchemeDescription}"
|
Margin="0,2,0,0"
|
||||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameSwitchSchemeHeader}"
|
IsClosable="False"
|
||||||
Icon=""
|
IsOpen="{Binding IsElevated, Converter={StaticResource BoolNegationConverter}}"
|
||||||
IsEnabled="{Binding IsElevated}">
|
Message="{shcm:ResourceString Name=ViewPageLaunchGameElevationHint}"
|
||||||
<wsc:Setting.ActionContent>
|
Severity="Warning"/>
|
||||||
<ComboBox
|
<wsc:SettingsGroup Margin="0,0,0,0" Header="{shcm:ResourceString Name=ViewPageLaunchGameCommonHeader}">
|
||||||
DisplayMemberPath="DisplayName"
|
|
||||||
ItemsSource="{Binding KnownSchemes}"
|
|
||||||
SelectedItem="{Binding SelectedScheme, Mode=TwoWay}"/>
|
|
||||||
</wsc:Setting.ActionContent>
|
|
||||||
</wsc:Setting>
|
|
||||||
<wsc:SettingExpander IsExpanded="True">
|
|
||||||
<wsc:SettingExpander.Header>
|
|
||||||
<wsc:Setting
|
<wsc:Setting
|
||||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountDescription}"
|
Description="{shcm:ResourceString Name=ViewPageLaunchGameSwitchSchemeDescription}"
|
||||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountHeader}"
|
Header="{shcm:ResourceString Name=ViewPageLaunchGameSwitchSchemeHeader}"
|
||||||
Icon="">
|
Icon=""
|
||||||
|
IsEnabled="{Binding IsElevated}">
|
||||||
<wsc:Setting.ActionContent>
|
<wsc:Setting.ActionContent>
|
||||||
<Button
|
<ComboBox
|
||||||
Grid.Column="1"
|
DisplayMemberPath="DisplayName"
|
||||||
MinWidth="124"
|
ItemsSource="{Binding KnownSchemes}"
|
||||||
Margin="0,0,8,0"
|
SelectedItem="{Binding SelectedScheme, Mode=TwoWay}"/>
|
||||||
HorizontalAlignment="Right"
|
|
||||||
Command="{Binding DetectGameAccountCommand}"
|
|
||||||
Content="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountDetectAction}"/>
|
|
||||||
</wsc:Setting.ActionContent>
|
</wsc:Setting.ActionContent>
|
||||||
</wsc:Setting>
|
</wsc:Setting>
|
||||||
</wsc:SettingExpander.Header>
|
<wsc:SettingExpander IsExpanded="True">
|
||||||
<ListView ItemsSource="{Binding GameAccounts}" SelectedItem="{Binding SelectedGameAccount, Mode=TwoWay}">
|
<wsc:SettingExpander.Header>
|
||||||
<ListView.ItemTemplate>
|
<wsc:Setting
|
||||||
<DataTemplate>
|
Description="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountDescription}"
|
||||||
<Grid>
|
Header="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountHeader}"
|
||||||
<StackPanel Margin="0,12">
|
Icon="">
|
||||||
<TextBlock Text="{Binding Name}"/>
|
<wsc:Setting.ActionContent>
|
||||||
<TextBlock
|
|
||||||
Opacity="0.8"
|
|
||||||
Style="{StaticResource CaptionTextBlockStyle}"
|
|
||||||
Text="{Binding AttachUid, TargetNullValue={shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountAttachUidNull}}"/>
|
|
||||||
</StackPanel>
|
|
||||||
<StackPanel
|
|
||||||
x:Name="ButtonPanel"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
Orientation="Horizontal"
|
|
||||||
Visibility="Collapsed">
|
|
||||||
<Button
|
<Button
|
||||||
MinWidth="48"
|
Grid.Column="1"
|
||||||
Margin="4,8"
|
MinWidth="124"
|
||||||
VerticalAlignment="Stretch"
|
Margin="0,0,8,0"
|
||||||
Command="{Binding DataContext.AttachGameAccountCommand, Source={StaticResource BindingProxy}}"
|
HorizontalAlignment="Right"
|
||||||
CommandParameter="{Binding}"
|
Command="{Binding DetectGameAccountCommand}"
|
||||||
Content=""
|
Content="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountDetectAction}"/>
|
||||||
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
</wsc:Setting.ActionContent>
|
||||||
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountAttachUidToolTip}"/>
|
</wsc:Setting>
|
||||||
<Button
|
</wsc:SettingExpander.Header>
|
||||||
MinWidth="48"
|
<ListView ItemsSource="{Binding GameAccounts}" SelectedItem="{Binding SelectedGameAccount, Mode=TwoWay}">
|
||||||
Margin="4,8"
|
<ListView.ItemTemplate>
|
||||||
VerticalAlignment="Stretch"
|
<DataTemplate>
|
||||||
Command="{Binding DataContext.ModifyGameAccountCommand, Source={StaticResource BindingProxy}}"
|
<Grid>
|
||||||
CommandParameter="{Binding}"
|
<StackPanel Margin="0,12">
|
||||||
Content=""
|
<TextBlock Text="{Binding Name}"/>
|
||||||
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
<TextBlock
|
||||||
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountRenameToolTip}"/>
|
Opacity="0.8"
|
||||||
<Button
|
Style="{StaticResource CaptionTextBlockStyle}"
|
||||||
MinWidth="48"
|
Text="{Binding AttachUid, TargetNullValue={shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountAttachUidNull}}"/>
|
||||||
Margin="4,8,0,8"
|
</StackPanel>
|
||||||
VerticalAlignment="Stretch"
|
<StackPanel
|
||||||
Command="{Binding DataContext.RemoveGameAccountCommand, Source={StaticResource BindingProxy}}"
|
x:Name="ButtonPanel"
|
||||||
CommandParameter="{Binding}"
|
HorizontalAlignment="Right"
|
||||||
Content=""
|
Orientation="Horizontal"
|
||||||
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
Visibility="Collapsed">
|
||||||
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountRemoveToolTip}"/>
|
<Button
|
||||||
</StackPanel>
|
MinWidth="48"
|
||||||
|
Margin="4,8"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
Command="{Binding DataContext.AttachGameAccountCommand, Source={StaticResource BindingProxy}}"
|
||||||
|
CommandParameter="{Binding}"
|
||||||
|
Content=""
|
||||||
|
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
||||||
|
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountAttachUidToolTip}"/>
|
||||||
|
<Button
|
||||||
|
MinWidth="48"
|
||||||
|
Margin="4,8"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
Command="{Binding DataContext.ModifyGameAccountCommand, Source={StaticResource BindingProxy}}"
|
||||||
|
CommandParameter="{Binding}"
|
||||||
|
Content=""
|
||||||
|
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
||||||
|
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountRenameToolTip}"/>
|
||||||
|
<Button
|
||||||
|
MinWidth="48"
|
||||||
|
Margin="4,8,0,8"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
Command="{Binding DataContext.RemoveGameAccountCommand, Source={StaticResource BindingProxy}}"
|
||||||
|
CommandParameter="{Binding}"
|
||||||
|
Content=""
|
||||||
|
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
||||||
|
ToolTipService.ToolTip="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountRemoveToolTip}"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
<Grid.Resources>
|
<Grid.Resources>
|
||||||
<Storyboard x:Name="ButtonPanelVisibleStoryboard">
|
<Storyboard x:Name="ButtonPanelVisibleStoryboard">
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonPanel" Storyboard.TargetProperty="Visibility">
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonPanel" Storyboard.TargetProperty="Visibility">
|
||||||
<DiscreteObjectKeyFrame KeyTime="0">
|
<DiscreteObjectKeyFrame KeyTime="0">
|
||||||
<DiscreteObjectKeyFrame.Value>
|
<DiscreteObjectKeyFrame.Value>
|
||||||
<Visibility>Visible</Visibility>
|
<Visibility>Visible</Visibility>
|
||||||
</DiscreteObjectKeyFrame.Value>
|
</DiscreteObjectKeyFrame.Value>
|
||||||
</DiscreteObjectKeyFrame>
|
</DiscreteObjectKeyFrame>
|
||||||
</ObjectAnimationUsingKeyFrames>
|
</ObjectAnimationUsingKeyFrames>
|
||||||
</Storyboard>
|
</Storyboard>
|
||||||
|
|
||||||
<Storyboard x:Name="ButtonPanelCollapsedStoryboard">
|
<Storyboard x:Name="ButtonPanelCollapsedStoryboard">
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonPanel" Storyboard.TargetProperty="Visibility">
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonPanel" Storyboard.TargetProperty="Visibility">
|
||||||
<DiscreteObjectKeyFrame KeyTime="0">
|
<DiscreteObjectKeyFrame KeyTime="0">
|
||||||
<DiscreteObjectKeyFrame.Value>
|
<DiscreteObjectKeyFrame.Value>
|
||||||
<Visibility>Collapsed</Visibility>
|
<Visibility>Collapsed</Visibility>
|
||||||
</DiscreteObjectKeyFrame.Value>
|
</DiscreteObjectKeyFrame.Value>
|
||||||
</DiscreteObjectKeyFrame>
|
</DiscreteObjectKeyFrame>
|
||||||
</ObjectAnimationUsingKeyFrames>
|
</ObjectAnimationUsingKeyFrames>
|
||||||
</Storyboard>
|
</Storyboard>
|
||||||
</Grid.Resources>
|
</Grid.Resources>
|
||||||
|
|
||||||
<mxi:Interaction.Behaviors>
|
<mxi:Interaction.Behaviors>
|
||||||
<mxic:EventTriggerBehavior EventName="PointerEntered">
|
<mxic:EventTriggerBehavior EventName="PointerEntered">
|
||||||
<mxim:ControlStoryboardAction Storyboard="{StaticResource ButtonPanelVisibleStoryboard}"/>
|
<mxim:ControlStoryboardAction Storyboard="{StaticResource ButtonPanelVisibleStoryboard}"/>
|
||||||
</mxic:EventTriggerBehavior>
|
</mxic:EventTriggerBehavior>
|
||||||
<mxic:EventTriggerBehavior EventName="PointerExited">
|
<mxic:EventTriggerBehavior EventName="PointerExited">
|
||||||
<mxim:ControlStoryboardAction Storyboard="{StaticResource ButtonPanelCollapsedStoryboard}"/>
|
<mxim:ControlStoryboardAction Storyboard="{StaticResource ButtonPanelCollapsedStoryboard}"/>
|
||||||
</mxic:EventTriggerBehavior>
|
</mxic:EventTriggerBehavior>
|
||||||
</mxi:Interaction.Behaviors>
|
</mxi:Interaction.Behaviors>
|
||||||
</Grid>
|
</Grid>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ListView.ItemTemplate>
|
</ListView.ItemTemplate>
|
||||||
</ListView>
|
</ListView>
|
||||||
</wsc:SettingExpander>
|
</wsc:SettingExpander>
|
||||||
</wsc:SettingsGroup>
|
</wsc:SettingsGroup>
|
||||||
<wsc:SettingsGroup Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceHeader}">
|
<wsc:SettingsGroup Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceHeader}">
|
||||||
<wsc:Setting
|
<wsc:Setting
|
||||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceExclusiveDescription}"
|
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceExclusiveDescription}"
|
||||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceExclusiveHeader}"
|
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceExclusiveHeader}"
|
||||||
Icon="">
|
Icon="">
|
||||||
<wsc:Setting.ActionContent>
|
<wsc:Setting.ActionContent>
|
||||||
<ToggleSwitch
|
<ToggleSwitch
|
||||||
Width="120"
|
Width="120"
|
||||||
IsOn="{Binding Options.IsExclusive, Mode=TwoWay}"
|
IsOn="{Binding Options.IsExclusive, Mode=TwoWay}"
|
||||||
Style="{StaticResource ToggleSwitchSettingStyle}"/>
|
Style="{StaticResource ToggleSwitchSettingStyle}"/>
|
||||||
</wsc:Setting.ActionContent>
|
</wsc:Setting.ActionContent>
|
||||||
</wsc:Setting>
|
</wsc:Setting>
|
||||||
<wsc:Setting
|
<wsc:Setting
|
||||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceFullscreenDescription}"
|
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceFullscreenDescription}"
|
||||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceFullscreenHeader}"
|
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceFullscreenHeader}"
|
||||||
Icon="">
|
Icon="">
|
||||||
<wsc:Setting.ActionContent>
|
<wsc:Setting.ActionContent>
|
||||||
<ToggleSwitch
|
<ToggleSwitch
|
||||||
Width="120"
|
Width="120"
|
||||||
IsOn="{Binding Options.IsFullScreen, Mode=TwoWay}"
|
IsOn="{Binding Options.IsFullScreen, Mode=TwoWay}"
|
||||||
Style="{StaticResource ToggleSwitchSettingStyle}"/>
|
Style="{StaticResource ToggleSwitchSettingStyle}"/>
|
||||||
</wsc:Setting.ActionContent>
|
</wsc:Setting.ActionContent>
|
||||||
</wsc:Setting>
|
</wsc:Setting>
|
||||||
<wsc:Setting
|
<wsc:Setting
|
||||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceBorderlessDescription}"
|
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceBorderlessDescription}"
|
||||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceBorderlessHeader}"
|
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceBorderlessHeader}"
|
||||||
Icon="">
|
Icon="">
|
||||||
<wsc:Setting.ActionContent>
|
<wsc:Setting.ActionContent>
|
||||||
<ToggleSwitch
|
<ToggleSwitch
|
||||||
Width="120"
|
Width="120"
|
||||||
IsOn="{Binding Options.IsBorderless, Mode=TwoWay}"
|
IsOn="{Binding Options.IsBorderless, Mode=TwoWay}"
|
||||||
Style="{StaticResource ToggleSwitchSettingStyle}"/>
|
Style="{StaticResource ToggleSwitchSettingStyle}"/>
|
||||||
</wsc:Setting.ActionContent>
|
</wsc:Setting.ActionContent>
|
||||||
</wsc:Setting>
|
</wsc:Setting>
|
||||||
|
|
||||||
<wsc:Setting
|
<wsc:Setting
|
||||||
Margin="0,6,0,0"
|
Margin="0,6,0,0"
|
||||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenWidthDescription}"
|
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenWidthDescription}"
|
||||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenWidthHeader}"
|
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenWidthHeader}"
|
||||||
Icon="">
|
Icon="">
|
||||||
<wsc:Setting.ActionContent>
|
<wsc:Setting.ActionContent>
|
||||||
<NumberBox Width="156" Value="{Binding Options.ScreenWidth, Mode=TwoWay}"/>
|
<NumberBox Width="156" Value="{Binding Options.ScreenWidth, Mode=TwoWay}"/>
|
||||||
</wsc:Setting.ActionContent>
|
</wsc:Setting.ActionContent>
|
||||||
</wsc:Setting>
|
</wsc:Setting>
|
||||||
<wsc:Setting
|
<wsc:Setting
|
||||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenHeightDescription}"
|
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenHeightDescription}"
|
||||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenHeightHeader}"
|
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenHeightHeader}"
|
||||||
Icon="">
|
Icon="">
|
||||||
<wsc:Setting.ActionContent>
|
<wsc:Setting.ActionContent>
|
||||||
<NumberBox Width="156" Value="{Binding Options.ScreenHeight, Mode=TwoWay}"/>
|
<NumberBox Width="156" Value="{Binding Options.ScreenHeight, Mode=TwoWay}"/>
|
||||||
</wsc:Setting.ActionContent>
|
</wsc:Setting.ActionContent>
|
||||||
</wsc:Setting>
|
</wsc:Setting>
|
||||||
|
|
||||||
<wsc:Setting
|
<wsc:Setting
|
||||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameMonitorsDescription}"
|
Description="{shcm:ResourceString Name=ViewPageLaunchGameMonitorsDescription}"
|
||||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameMonitorsHeader}"
|
Header="{shcm:ResourceString Name=ViewPageLaunchGameMonitorsHeader}"
|
||||||
Icon="">
|
Icon="">
|
||||||
<wsc:Setting.ActionContent>
|
<wsc:Setting.ActionContent>
|
||||||
<ComboBox
|
<ComboBox
|
||||||
DisplayMemberPath="Name"
|
DisplayMemberPath="Name"
|
||||||
ItemsSource="{Binding Options.Monitors}"
|
ItemsSource="{Binding Options.Monitors}"
|
||||||
SelectedItem="{Binding Options.Monitor, Mode=TwoWay}"/>
|
SelectedItem="{Binding Options.Monitor, Mode=TwoWay}"/>
|
||||||
</wsc:Setting.ActionContent>
|
</wsc:Setting.ActionContent>
|
||||||
</wsc:Setting>
|
</wsc:Setting>
|
||||||
</wsc:SettingsGroup>
|
</wsc:SettingsGroup>
|
||||||
|
|
||||||
<wsc:SettingsGroup Header="{shcm:ResourceString Name=ViewPageLaunchGameAdvanceHeader}" IsEnabled="{Binding IsElevated}">
|
<wsc:SettingsGroup Header="{shcm:ResourceString Name=ViewPageLaunchGameAdvanceHeader}" IsEnabled="{Binding IsElevated}">
|
||||||
<InfoBar
|
<InfoBar
|
||||||
IsClosable="False"
|
IsClosable="False"
|
||||||
IsOpen="{Binding IsElevated}"
|
IsOpen="{Binding IsElevated}"
|
||||||
Message="{shcm:ResourceString Name=ViewPageLaunchGameAdvanceHint}"
|
Message="{shcm:ResourceString Name=ViewPageLaunchGameAdvanceHint}"
|
||||||
Severity="Error"/>
|
Severity="Error"/>
|
||||||
<wsc:Setting
|
<wsc:Setting
|
||||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsDescription}"
|
Description="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsDescription}"
|
||||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsHeader}"
|
Header="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsHeader}"
|
||||||
Icon="">
|
Icon="">
|
||||||
<wsc:Setting.ActionContent>
|
<wsc:Setting.ActionContent>
|
||||||
<ToggleSwitch
|
<ToggleSwitch
|
||||||
Width="120"
|
Width="120"
|
||||||
IsOn="{Binding Options.UnlockFps, Mode=TwoWay}"
|
IsOn="{Binding Options.UnlockFps, Mode=TwoWay}"
|
||||||
OffContent="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsOff}"
|
OffContent="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsOff}"
|
||||||
OnContent="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsOn}"
|
OnContent="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsOn}"
|
||||||
Style="{StaticResource ToggleSwitchSettingStyle}"/>
|
Style="{StaticResource ToggleSwitchSettingStyle}"/>
|
||||||
</wsc:Setting.ActionContent>
|
</wsc:Setting.ActionContent>
|
||||||
</wsc:Setting>
|
</wsc:Setting>
|
||||||
<wsc:Setting Header="{shcm:ResourceString Name=ViewPageLaunchGameSetFpsHeader}">
|
<wsc:Setting Header="{shcm:ResourceString Name=ViewPageLaunchGameSetFpsHeader}">
|
||||||
<wsc:Setting.Description>
|
<wsc:Setting.Description>
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<TextBlock Text="{shcm:ResourceString Name=ViewPageLaunchGameSetFpsDescription}"/>
|
<TextBlock Text="{shcm:ResourceString Name=ViewPageLaunchGameSetFpsDescription}"/>
|
||||||
<TextBlock Text="{Binding Options.TargetFps}"/>
|
<TextBlock Text="{Binding Options.TargetFps}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</wsc:Setting.Description>
|
</wsc:Setting.Description>
|
||||||
<wsc:Setting.ActionContent>
|
<wsc:Setting.ActionContent>
|
||||||
<Slider
|
<Slider
|
||||||
Width="400"
|
Width="400"
|
||||||
Maximum="360"
|
Maximum="360"
|
||||||
Minimum="60"
|
Minimum="60"
|
||||||
Value="{Binding Options.TargetFps, Mode=TwoWay}"/>
|
Value="{Binding Options.TargetFps, Mode=TwoWay}"/>
|
||||||
</wsc:Setting.ActionContent>
|
</wsc:Setting.ActionContent>
|
||||||
</wsc:Setting>
|
</wsc:Setting>
|
||||||
</wsc:SettingsGroup>
|
</wsc:SettingsGroup>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
<mxi:Interaction.Behaviors>
|
</PivotItem>
|
||||||
<cwub:AutoFocusBehavior/>
|
<PivotItem Header="{shcm:ResourceString Name=ViewPageLaunchGameResourceHeader}">
|
||||||
</mxi:Interaction.Behaviors>
|
<Grid>
|
||||||
</ScrollViewer>
|
<ScrollViewer Visibility="{Binding GameResource, Converter={StaticResource EmptyObjectToBoolConverter}}">
|
||||||
<Grid Grid.Row="1" VerticalAlignment="Bottom">
|
<Grid>
|
||||||
<Button
|
<Grid.ColumnDefinitions>
|
||||||
Grid.Column="3"
|
<ColumnDefinition MaxWidth="1000"/>
|
||||||
Width="100"
|
<ColumnDefinition Width="auto"/>
|
||||||
Height="80"
|
</Grid.ColumnDefinitions>
|
||||||
MinWidth="80"
|
<StackPanel>
|
||||||
Margin="24"
|
<shvc:LaunchGameResourceExpander
|
||||||
HorizontalAlignment="Right"
|
Margin="16,16,16,0"
|
||||||
Command="{Binding LaunchCommand}"
|
DataContext="{Binding GameResource.PreDownloadGame.Latest, Mode=OneWay}"
|
||||||
Style="{StaticResource AccentButtonStyle}">
|
Header="{shcm:ResourceString Name=ViewPageLaunchGameResourcePreDownloadHeader}"
|
||||||
<StackPanel>
|
Visibility="{Binding FallbackValue={StaticResource VisibilityCollapsed}, Converter={StaticResource EmptyObjectToVisibilityConverter}}"/>
|
||||||
<FontIcon FontSize="36" Glyph=""/>
|
<shvc:LaunchGameResourceExpander
|
||||||
<TextBlock Margin="0,4,0,0" Text="{shcm:ResourceString Name=ViewPageLaunchGameAction}"/>
|
Margin="16,16,16,0"
|
||||||
</StackPanel>
|
DataContext="{Binding GameResource.Game.Latest, Mode=OneWay}"
|
||||||
</Button>
|
Header="{shcm:ResourceString Name=ViewPageLaunchGameResourceLatestHeader}"/>
|
||||||
</Grid>
|
<ItemsControl Margin="0,0,0,16" ItemsSource="{Binding GameResource.Game.Diffs, Mode=OneWay}">
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<shvc:LaunchGameResourceExpander
|
||||||
|
Margin="16,16,16,0"
|
||||||
|
DataContext="{Binding Mode=OneWay}"
|
||||||
|
Header="{shcm:ResourceString Name=ViewPageLaunchGameResourceDiffHeader}"/>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
|
<shvc:LoadingView IsLoading="{Binding GameResource, Converter={StaticResource EmptyObjectToBoolRevertConverter}}"/>
|
||||||
|
</Grid>
|
||||||
|
</PivotItem>
|
||||||
|
</Pivot>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
</shc:ScopedPage>
|
</shc:ScopedPage>
|
||||||
@@ -15,6 +15,7 @@ using Snap.Hutao.Service.Game;
|
|||||||
using Snap.Hutao.Service.Navigation;
|
using Snap.Hutao.Service.Navigation;
|
||||||
using Snap.Hutao.Service.User;
|
using Snap.Hutao.Service.User;
|
||||||
using Snap.Hutao.View.Dialog;
|
using Snap.Hutao.View.Dialog;
|
||||||
|
using Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher;
|
||||||
using Snap.Hutao.Web.Hoyolab.Takumi.Binding;
|
using Snap.Hutao.Web.Hoyolab.Takumi.Binding;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -35,7 +36,6 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
|||||||
|
|
||||||
private readonly IServiceProvider serviceProvider;
|
private readonly IServiceProvider serviceProvider;
|
||||||
private readonly IGameService gameService;
|
private readonly IGameService gameService;
|
||||||
private readonly AppDbContext appDbContext;
|
|
||||||
private readonly IMemoryCache memoryCache;
|
private readonly IMemoryCache memoryCache;
|
||||||
|
|
||||||
private readonly List<LaunchScheme> knownSchemes = LaunchScheme.KnownSchemes.ToList();
|
private readonly List<LaunchScheme> knownSchemes = LaunchScheme.KnownSchemes.ToList();
|
||||||
@@ -43,6 +43,7 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
|||||||
private LaunchScheme? selectedScheme;
|
private LaunchScheme? selectedScheme;
|
||||||
private ObservableCollection<GameAccount>? gameAccounts;
|
private ObservableCollection<GameAccount>? gameAccounts;
|
||||||
private GameAccount? selectedGameAccount;
|
private GameAccount? selectedGameAccount;
|
||||||
|
private GameResource? gameResource;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构造一个新的启动游戏视图模型
|
/// 构造一个新的启动游戏视图模型
|
||||||
@@ -51,7 +52,6 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
|||||||
public LaunchGameViewModel(IServiceProvider serviceProvider)
|
public LaunchGameViewModel(IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
gameService = serviceProvider.GetRequiredService<IGameService>();
|
gameService = serviceProvider.GetRequiredService<IGameService>();
|
||||||
appDbContext = serviceProvider.GetRequiredService<AppDbContext>();
|
|
||||||
memoryCache = serviceProvider.GetRequiredService<IMemoryCache>();
|
memoryCache = serviceProvider.GetRequiredService<IMemoryCache>();
|
||||||
Options = serviceProvider.GetRequiredService<LaunchOptions>();
|
Options = serviceProvider.GetRequiredService<LaunchOptions>();
|
||||||
this.serviceProvider = serviceProvider;
|
this.serviceProvider = serviceProvider;
|
||||||
@@ -71,7 +71,19 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前选择的服务器方案
|
/// 当前选择的服务器方案
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LaunchScheme? SelectedScheme { get => selectedScheme; set => SetProperty(ref selectedScheme, value); }
|
public LaunchScheme? SelectedScheme
|
||||||
|
{
|
||||||
|
get => selectedScheme; set
|
||||||
|
{
|
||||||
|
if (SetProperty(ref selectedScheme, value))
|
||||||
|
{
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
UpdateGameResourceAsync(value).SafeForget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 游戏账号集合
|
/// 游戏账号集合
|
||||||
@@ -88,6 +100,11 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public LaunchOptions Options { get; }
|
public LaunchOptions Options { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 游戏资源
|
||||||
|
/// </summary>
|
||||||
|
public GameResource? GameResource { get => gameResource; set => SetProperty(ref gameResource, value); }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否提权
|
/// 是否提权
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -122,6 +139,7 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
protected override async Task OpenUIAsync()
|
protected override async Task OpenUIAsync()
|
||||||
{
|
{
|
||||||
|
await ThreadHelper.SwitchToBackgroundAsync();
|
||||||
if (File.Exists(gameService.GetGamePathSkipLocator()))
|
if (File.Exists(gameService.GetGamePathSkipLocator()))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -131,6 +149,7 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
|||||||
MultiChannel multi = gameService.GetMultiChannel();
|
MultiChannel multi = gameService.GetMultiChannel();
|
||||||
if (string.IsNullOrEmpty(multi.ConfigFilePath))
|
if (string.IsNullOrEmpty(multi.ConfigFilePath))
|
||||||
{
|
{
|
||||||
|
await ThreadHelper.SwitchToMainThreadAsync();
|
||||||
SelectedScheme = KnownSchemes.FirstOrDefault(s => s.Channel == multi.Channel && s.SubChannel == multi.SubChannel);
|
SelectedScheme = KnownSchemes.FirstOrDefault(s => s.Channel == multi.Channel && s.SubChannel == multi.SubChannel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -138,8 +157,10 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
|||||||
serviceProvider.GetRequiredService<IInfoBarService>().Warning(SH.ViewModelLaunchGameMultiChannelReadFail);
|
serviceProvider.GetRequiredService<IInfoBarService>().Warning(SH.ViewModelLaunchGameMultiChannelReadFail);
|
||||||
}
|
}
|
||||||
|
|
||||||
GameAccounts = await gameService.GetGameAccountCollectionAsync().ConfigureAwait(true);
|
ObservableCollection<GameAccount> accounts = await gameService.GetGameAccountCollectionAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
await ThreadHelper.SwitchToMainThreadAsync();
|
||||||
|
GameAccounts = accounts;
|
||||||
// Sync uid
|
// Sync uid
|
||||||
if (memoryCache.TryGetValue(DesiredUid, out object? value) && value is string uid)
|
if (memoryCache.TryGetValue(DesiredUid, out object? value) && value is string uid)
|
||||||
{
|
{
|
||||||
@@ -155,12 +176,28 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
serviceProvider.GetRequiredService<IInfoBarService>().Warning(SH.ViewModelLaunchGamePathInvalid);
|
serviceProvider.GetRequiredService<IInfoBarService>().Warning(SH.ViewModelLaunchGamePathInvalid);
|
||||||
|
await ThreadHelper.SwitchToMainThreadAsync();
|
||||||
await serviceProvider.GetRequiredService<INavigationService>()
|
await serviceProvider.GetRequiredService<INavigationService>()
|
||||||
.NavigateAsync<View.Page.SettingPage>(INavigationAwaiter.Default, true)
|
.NavigateAsync<View.Page.SettingPage>(INavigationAwaiter.Default, true)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task UpdateGameResourceAsync(LaunchScheme scheme)
|
||||||
|
{
|
||||||
|
await ThreadHelper.SwitchToBackgroundAsync();
|
||||||
|
Web.Response.Response<GameResource> response = await serviceProvider
|
||||||
|
.GetRequiredService<ResourceClient>()
|
||||||
|
.GetResourceAsync(scheme)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (response.IsOk())
|
||||||
|
{
|
||||||
|
await ThreadHelper.SwitchToMainThreadAsync();
|
||||||
|
GameResource = response.Data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task LaunchAsync()
|
private async Task LaunchAsync()
|
||||||
{
|
{
|
||||||
IInfoBarService infoBarService = serviceProvider.GetRequiredService<IInfoBarService>();
|
IInfoBarService infoBarService = serviceProvider.GetRequiredService<IInfoBarService>();
|
||||||
|
|||||||
@@ -20,4 +20,9 @@ internal class PathMd5
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("md5")]
|
[JsonPropertyName("md5")]
|
||||||
public string Md5 { get; set; } = default!;
|
public string Md5 { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示名称
|
||||||
|
/// </summary>
|
||||||
|
public string DisplayName { get => System.IO.Path.GetFileName(Path.ToUri().LocalPath); }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using System.Buffers.Binary;
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using Windows.Graphics;
|
using Windows.Graphics;
|
||||||
using Windows.Win32.Graphics.Gdi;
|
|
||||||
using Windows.Win32.System.Diagnostics.ToolHelp;
|
using Windows.Win32.System.Diagnostics.ToolHelp;
|
||||||
using Windows.Win32.UI.WindowsAndMessaging;
|
using Windows.Win32.UI.WindowsAndMessaging;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user