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 -->
|
||||
<cwuc:BoolNegationConverter x:Key="BoolNegationConverter"/>
|
||||
<cwuc:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
|
||||
<cwuc:FileSizeToFriendlyStringConverter x:Key="FileSizeToFriendlyStringConverter"/>
|
||||
<shmmc:AchievementIconConverter x:Key="AchievementIconConverter"/>
|
||||
<shmmc:AvatarCardConverter x:Key="AvatarCardConverter"/>
|
||||
<shmmc:AvatarIconConverter x:Key="AvatarIconConverter"/>
|
||||
|
||||
@@ -8,6 +8,7 @@ using Snap.Hutao.Core;
|
||||
using Snap.Hutao.Core.ExceptionService;
|
||||
using Snap.Hutao.Core.LifeCycle;
|
||||
using System.Diagnostics;
|
||||
using Windows.ApplicationModel.Background;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace Snap.Hutao;
|
||||
|
||||
@@ -10,7 +10,6 @@ using Snap.Hutao.Service.DailyNote;
|
||||
using Snap.Hutao.Service.Metadata;
|
||||
using Snap.Hutao.Service.Navigation;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Security.Principal;
|
||||
using Windows.ApplicationModel;
|
||||
|
||||
@@ -164,10 +163,7 @@ internal static class Activation
|
||||
|
||||
default:
|
||||
{
|
||||
// Increase launch times
|
||||
LocalSetting.Set(SettingKeys.LaunchTimes, LocalSetting.Get(SettingKeys.LaunchTimes, 0) + 1);
|
||||
|
||||
await WaitMainWindowAsync().ConfigureAwait(false);
|
||||
await HandleNormalLaunchActionAsync().ConfigureAwait(false);
|
||||
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()
|
||||
{
|
||||
await ThreadHelper.SwitchToMainThreadAsync();
|
||||
@@ -211,6 +215,12 @@ internal static class Activation
|
||||
await HandleDailyNoteActionAsync(action, parameter, isRedirected).ConfigureAwait(false);
|
||||
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>
|
||||
|
||||
@@ -1335,6 +1335,21 @@
|
||||
<data name="ViewPageLaunchGameMonitorsHeader" xml:space="preserve">
|
||||
<value>显示器</value>
|
||||
</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">
|
||||
<value>在游戏时可以随时调整</value>
|
||||
</data>
|
||||
|
||||
@@ -237,10 +237,14 @@ internal sealed class GameService : IGameService
|
||||
string gameFileName = Path.GetFileName(gamePath);
|
||||
|
||||
progress.Report(new(SH.ServiceGameEnsureGameResourceQueryResourceInformation));
|
||||
Response<GameResource> response = await Ioc.Default
|
||||
.GetRequiredService<ResourceClient>()
|
||||
.GetResourceAsync(launchScheme)
|
||||
.ConfigureAwait(false);
|
||||
Response<GameResource> response;
|
||||
using (IServiceScope scope = scopeFactory.CreateScope())
|
||||
{
|
||||
response = await scope.ServiceProvider
|
||||
.GetRequiredService<ResourceClient>()
|
||||
.GetResourceAsync(launchScheme)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (response.IsOk())
|
||||
{
|
||||
|
||||
@@ -40,14 +40,14 @@ internal sealed class PackageConverter
|
||||
/// 调用前需要确认本地文件与服务器上的不同
|
||||
/// </summary>
|
||||
/// <param name="targetScheme">目标启动方案</param>
|
||||
/// <param name="gameResouce">游戏资源</param>
|
||||
/// <param name="gameResource">游戏资源</param>
|
||||
/// <param name="gameFolder">游戏目录</param>
|
||||
/// <param name="progress">进度</param>
|
||||
/// <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();
|
||||
string scatteredFilesUrl = gameResouce.Game.Latest.DecompressedPath;
|
||||
string scatteredFilesUrl = gameResource.Game.Latest.DecompressedPath;
|
||||
Uri pkgVersionUri = $"{scatteredFilesUrl}/pkg_version".ToUri();
|
||||
ConvertDirection direction = targetScheme.IsOversea ? ConvertDirection.ChineseToOversea : ConvertDirection.OverseaToChinese;
|
||||
|
||||
@@ -68,7 +68,7 @@ internal sealed class PackageConverter
|
||||
Dictionary<string, VersionItem> localItems;
|
||||
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);
|
||||
@@ -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)
|
||||
{
|
||||
foreach ((string remoteName, VersionItem remoteItem) in remote)
|
||||
@@ -368,7 +352,7 @@ internal sealed class PackageConverter
|
||||
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();
|
||||
|
||||
@@ -379,7 +363,21 @@ internal sealed class PackageConverter
|
||||
if (!string.IsNullOrEmpty(raw))
|
||||
{
|
||||
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\DescParamComboBox.xaml" />
|
||||
<None Remove="View\Control\ItemIcon.xaml" />
|
||||
<None Remove="View\Control\LaunchGameResourceExpander.xaml" />
|
||||
<None Remove="View\Control\LoadingView.xaml" />
|
||||
<None Remove="View\Control\SkillPivot.xaml" />
|
||||
<None Remove="View\Control\StatisticsCard.xaml" />
|
||||
@@ -446,6 +447,11 @@
|
||||
<LastGenOutput>SH.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Control\LaunchGameResourceExpander.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\WikiMonsterPage.xaml">
|
||||
<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:shcm="using:Snap.Hutao.Control.Markup"
|
||||
xmlns:shv="using:Snap.Hutao.ViewModel"
|
||||
xmlns:shvc="using:Snap.Hutao.View.Control"
|
||||
xmlns:wsc="using:WinUICommunity.SettingsUI.Controls"
|
||||
d:DataContext="{d:DesignInstance shv:LaunchGameViewModel}"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||
@@ -23,13 +24,10 @@
|
||||
|
||||
<Page.Resources>
|
||||
<shc:BindingProxy x:Key="BindingProxy" DataContext="{Binding}"/>
|
||||
|
||||
<Visibility x:Key="VisibilityCollapsed">Collapsed</Visibility>
|
||||
<Style BasedOn="{StaticResource SettingButtonStyle}" TargetType="Button">
|
||||
<Setter Property="MinWidth" Value="156"/>
|
||||
</Style>
|
||||
<Style BasedOn="{StaticResource HyperlinkButtonStyle}" TargetType="HyperlinkButton">
|
||||
<Setter Property="MinWidth" Value="156"/>
|
||||
</Style>
|
||||
<Style BasedOn="{StaticResource DefaultComboBoxStyle}" TargetType="ComboBox">
|
||||
<Setter Property="MinWidth" Value="156"/>
|
||||
</Style>
|
||||
@@ -38,267 +36,291 @@
|
||||
</Style>
|
||||
</Page.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<ScrollViewer Grid.RowSpan="2">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition MaxWidth="800"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Margin="16">
|
||||
<InfoBar
|
||||
IsClosable="False"
|
||||
IsOpen="True"
|
||||
Message="{shcm:ResourceString Name=ViewPageLaunchGameConfigurationSaveHint}"
|
||||
Severity="Informational"/>
|
||||
<InfoBar
|
||||
Margin="0,2,0,0"
|
||||
IsClosable="False"
|
||||
IsOpen="{Binding IsElevated, Converter={StaticResource BoolNegationConverter}}"
|
||||
Message="{shcm:ResourceString Name=ViewPageLaunchGameElevationHint}"
|
||||
Severity="Warning"/>
|
||||
<wsc:SettingsGroup Margin="0,0,0,0" Header="{shcm:ResourceString Name=ViewPageLaunchGameCommonHeader}">
|
||||
<InfoBar
|
||||
IsClosable="False"
|
||||
IsOpen="{Binding IsElevated}"
|
||||
Message="{shcm:ResourceString Name=ViewPageLaunchGameSwitchSchemeHint}"
|
||||
Severity="Informational"/>
|
||||
<wsc:Setting
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameSwitchSchemeDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameSwitchSchemeHeader}"
|
||||
Icon=""
|
||||
IsEnabled="{Binding IsElevated}">
|
||||
<wsc:Setting.ActionContent>
|
||||
<ComboBox
|
||||
DisplayMemberPath="DisplayName"
|
||||
ItemsSource="{Binding KnownSchemes}"
|
||||
SelectedItem="{Binding SelectedScheme, Mode=TwoWay}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
<wsc:SettingExpander IsExpanded="True">
|
||||
<wsc:SettingExpander.Header>
|
||||
<Rectangle
|
||||
Height="48"
|
||||
VerticalAlignment="Top"
|
||||
Fill="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||
IsHitTestVisible="False"/>
|
||||
<Pivot>
|
||||
<Pivot.RightHeader>
|
||||
<CommandBar DefaultLabelPosition="Right">
|
||||
<AppBarButton
|
||||
Command="{Binding LaunchCommand}"
|
||||
Icon="{shcm:FontIcon Glyph=}"
|
||||
Label="{shcm:ResourceString Name=ViewPageLaunchGameAction}"/>
|
||||
</CommandBar>
|
||||
</Pivot.RightHeader>
|
||||
|
||||
<PivotItem Header="{shcm:ResourceString Name=ViewPageLaunchGameOptionsHeader}">
|
||||
<ScrollViewer Grid.RowSpan="2">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition MaxWidth="1000"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Margin="16">
|
||||
<InfoBar
|
||||
IsClosable="False"
|
||||
IsOpen="True"
|
||||
Message="{shcm:ResourceString Name=ViewPageLaunchGameConfigurationSaveHint}"
|
||||
Severity="Informational"/>
|
||||
<InfoBar
|
||||
Margin="0,2,0,0"
|
||||
IsClosable="False"
|
||||
IsOpen="{Binding IsElevated, Converter={StaticResource BoolNegationConverter}}"
|
||||
Message="{shcm:ResourceString Name=ViewPageLaunchGameElevationHint}"
|
||||
Severity="Warning"/>
|
||||
<wsc:SettingsGroup Margin="0,0,0,0" Header="{shcm:ResourceString Name=ViewPageLaunchGameCommonHeader}">
|
||||
<wsc:Setting
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountHeader}"
|
||||
Icon="">
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameSwitchSchemeDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameSwitchSchemeHeader}"
|
||||
Icon=""
|
||||
IsEnabled="{Binding IsElevated}">
|
||||
<wsc:Setting.ActionContent>
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
MinWidth="124"
|
||||
Margin="0,0,8,0"
|
||||
HorizontalAlignment="Right"
|
||||
Command="{Binding DetectGameAccountCommand}"
|
||||
Content="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountDetectAction}"/>
|
||||
<ComboBox
|
||||
DisplayMemberPath="DisplayName"
|
||||
ItemsSource="{Binding KnownSchemes}"
|
||||
SelectedItem="{Binding SelectedScheme, Mode=TwoWay}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
</wsc:SettingExpander.Header>
|
||||
<ListView ItemsSource="{Binding GameAccounts}" SelectedItem="{Binding SelectedGameAccount, Mode=TwoWay}">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<StackPanel Margin="0,12">
|
||||
<TextBlock Text="{Binding Name}"/>
|
||||
<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">
|
||||
<wsc:SettingExpander IsExpanded="True">
|
||||
<wsc:SettingExpander.Header>
|
||||
<wsc:Setting
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountHeader}"
|
||||
Icon="">
|
||||
<wsc:Setting.ActionContent>
|
||||
<Button
|
||||
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.Column="1"
|
||||
MinWidth="124"
|
||||
Margin="0,0,8,0"
|
||||
HorizontalAlignment="Right"
|
||||
Command="{Binding DetectGameAccountCommand}"
|
||||
Content="{shcm:ResourceString Name=ViewPageLaunchGameSwitchAccountDetectAction}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
</wsc:SettingExpander.Header>
|
||||
<ListView ItemsSource="{Binding GameAccounts}" SelectedItem="{Binding SelectedGameAccount, Mode=TwoWay}">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<StackPanel Margin="0,12">
|
||||
<TextBlock Text="{Binding Name}"/>
|
||||
<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
|
||||
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>
|
||||
<Storyboard x:Name="ButtonPanelVisibleStoryboard">
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonPanel" Storyboard.TargetProperty="Visibility">
|
||||
<DiscreteObjectKeyFrame KeyTime="0">
|
||||
<DiscreteObjectKeyFrame.Value>
|
||||
<Visibility>Visible</Visibility>
|
||||
</DiscreteObjectKeyFrame.Value>
|
||||
</DiscreteObjectKeyFrame>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
<Grid.Resources>
|
||||
<Storyboard x:Name="ButtonPanelVisibleStoryboard">
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonPanel" Storyboard.TargetProperty="Visibility">
|
||||
<DiscreteObjectKeyFrame KeyTime="0">
|
||||
<DiscreteObjectKeyFrame.Value>
|
||||
<Visibility>Visible</Visibility>
|
||||
</DiscreteObjectKeyFrame.Value>
|
||||
</DiscreteObjectKeyFrame>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
|
||||
<Storyboard x:Name="ButtonPanelCollapsedStoryboard">
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonPanel" Storyboard.TargetProperty="Visibility">
|
||||
<DiscreteObjectKeyFrame KeyTime="0">
|
||||
<DiscreteObjectKeyFrame.Value>
|
||||
<Visibility>Collapsed</Visibility>
|
||||
</DiscreteObjectKeyFrame.Value>
|
||||
</DiscreteObjectKeyFrame>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</Grid.Resources>
|
||||
<Storyboard x:Name="ButtonPanelCollapsedStoryboard">
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonPanel" Storyboard.TargetProperty="Visibility">
|
||||
<DiscreteObjectKeyFrame KeyTime="0">
|
||||
<DiscreteObjectKeyFrame.Value>
|
||||
<Visibility>Collapsed</Visibility>
|
||||
</DiscreteObjectKeyFrame.Value>
|
||||
</DiscreteObjectKeyFrame>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</Grid.Resources>
|
||||
|
||||
<mxi:Interaction.Behaviors>
|
||||
<mxic:EventTriggerBehavior EventName="PointerEntered">
|
||||
<mxim:ControlStoryboardAction Storyboard="{StaticResource ButtonPanelVisibleStoryboard}"/>
|
||||
</mxic:EventTriggerBehavior>
|
||||
<mxic:EventTriggerBehavior EventName="PointerExited">
|
||||
<mxim:ControlStoryboardAction Storyboard="{StaticResource ButtonPanelCollapsedStoryboard}"/>
|
||||
</mxic:EventTriggerBehavior>
|
||||
</mxi:Interaction.Behaviors>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</wsc:SettingExpander>
|
||||
</wsc:SettingsGroup>
|
||||
<wsc:SettingsGroup Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceHeader}">
|
||||
<wsc:Setting
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceExclusiveDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceExclusiveHeader}"
|
||||
Icon="">
|
||||
<wsc:Setting.ActionContent>
|
||||
<ToggleSwitch
|
||||
Width="120"
|
||||
IsOn="{Binding Options.IsExclusive, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchSettingStyle}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
<wsc:Setting
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceFullscreenDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceFullscreenHeader}"
|
||||
Icon="">
|
||||
<wsc:Setting.ActionContent>
|
||||
<ToggleSwitch
|
||||
Width="120"
|
||||
IsOn="{Binding Options.IsFullScreen, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchSettingStyle}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
<wsc:Setting
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceBorderlessDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceBorderlessHeader}"
|
||||
Icon="">
|
||||
<wsc:Setting.ActionContent>
|
||||
<ToggleSwitch
|
||||
Width="120"
|
||||
IsOn="{Binding Options.IsBorderless, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchSettingStyle}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
<mxi:Interaction.Behaviors>
|
||||
<mxic:EventTriggerBehavior EventName="PointerEntered">
|
||||
<mxim:ControlStoryboardAction Storyboard="{StaticResource ButtonPanelVisibleStoryboard}"/>
|
||||
</mxic:EventTriggerBehavior>
|
||||
<mxic:EventTriggerBehavior EventName="PointerExited">
|
||||
<mxim:ControlStoryboardAction Storyboard="{StaticResource ButtonPanelCollapsedStoryboard}"/>
|
||||
</mxic:EventTriggerBehavior>
|
||||
</mxi:Interaction.Behaviors>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</wsc:SettingExpander>
|
||||
</wsc:SettingsGroup>
|
||||
<wsc:SettingsGroup Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceHeader}">
|
||||
<wsc:Setting
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceExclusiveDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceExclusiveHeader}"
|
||||
Icon="">
|
||||
<wsc:Setting.ActionContent>
|
||||
<ToggleSwitch
|
||||
Width="120"
|
||||
IsOn="{Binding Options.IsExclusive, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchSettingStyle}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
<wsc:Setting
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceFullscreenDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceFullscreenHeader}"
|
||||
Icon="">
|
||||
<wsc:Setting.ActionContent>
|
||||
<ToggleSwitch
|
||||
Width="120"
|
||||
IsOn="{Binding Options.IsFullScreen, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchSettingStyle}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
<wsc:Setting
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceBorderlessDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceBorderlessHeader}"
|
||||
Icon="">
|
||||
<wsc:Setting.ActionContent>
|
||||
<ToggleSwitch
|
||||
Width="120"
|
||||
IsOn="{Binding Options.IsBorderless, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchSettingStyle}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
|
||||
<wsc:Setting
|
||||
Margin="0,6,0,0"
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenWidthDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenWidthHeader}"
|
||||
Icon="">
|
||||
<wsc:Setting.ActionContent>
|
||||
<NumberBox Width="156" Value="{Binding Options.ScreenWidth, Mode=TwoWay}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
<wsc:Setting
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenHeightDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenHeightHeader}"
|
||||
Icon="">
|
||||
<wsc:Setting.ActionContent>
|
||||
<NumberBox Width="156" Value="{Binding Options.ScreenHeight, Mode=TwoWay}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
<wsc:Setting
|
||||
Margin="0,6,0,0"
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenWidthDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenWidthHeader}"
|
||||
Icon="">
|
||||
<wsc:Setting.ActionContent>
|
||||
<NumberBox Width="156" Value="{Binding Options.ScreenWidth, Mode=TwoWay}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
<wsc:Setting
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenHeightDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameAppearanceScreenHeightHeader}"
|
||||
Icon="">
|
||||
<wsc:Setting.ActionContent>
|
||||
<NumberBox Width="156" Value="{Binding Options.ScreenHeight, Mode=TwoWay}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
|
||||
<wsc:Setting
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameMonitorsDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameMonitorsHeader}"
|
||||
Icon="">
|
||||
<wsc:Setting.ActionContent>
|
||||
<ComboBox
|
||||
DisplayMemberPath="Name"
|
||||
ItemsSource="{Binding Options.Monitors}"
|
||||
SelectedItem="{Binding Options.Monitor, Mode=TwoWay}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
</wsc:SettingsGroup>
|
||||
<wsc:Setting
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameMonitorsDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameMonitorsHeader}"
|
||||
Icon="">
|
||||
<wsc:Setting.ActionContent>
|
||||
<ComboBox
|
||||
DisplayMemberPath="Name"
|
||||
ItemsSource="{Binding Options.Monitors}"
|
||||
SelectedItem="{Binding Options.Monitor, Mode=TwoWay}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
</wsc:SettingsGroup>
|
||||
|
||||
<wsc:SettingsGroup Header="{shcm:ResourceString Name=ViewPageLaunchGameAdvanceHeader}" IsEnabled="{Binding IsElevated}">
|
||||
<InfoBar
|
||||
IsClosable="False"
|
||||
IsOpen="{Binding IsElevated}"
|
||||
Message="{shcm:ResourceString Name=ViewPageLaunchGameAdvanceHint}"
|
||||
Severity="Error"/>
|
||||
<wsc:Setting
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsHeader}"
|
||||
Icon="">
|
||||
<wsc:Setting.ActionContent>
|
||||
<ToggleSwitch
|
||||
Width="120"
|
||||
IsOn="{Binding Options.UnlockFps, Mode=TwoWay}"
|
||||
OffContent="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsOff}"
|
||||
OnContent="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsOn}"
|
||||
Style="{StaticResource ToggleSwitchSettingStyle}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
<wsc:Setting Header="{shcm:ResourceString Name=ViewPageLaunchGameSetFpsHeader}">
|
||||
<wsc:Setting.Description>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{shcm:ResourceString Name=ViewPageLaunchGameSetFpsDescription}"/>
|
||||
<TextBlock Text="{Binding Options.TargetFps}"/>
|
||||
</StackPanel>
|
||||
</wsc:Setting.Description>
|
||||
<wsc:Setting.ActionContent>
|
||||
<Slider
|
||||
Width="400"
|
||||
Maximum="360"
|
||||
Minimum="60"
|
||||
Value="{Binding Options.TargetFps, Mode=TwoWay}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
</wsc:SettingsGroup>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<mxi:Interaction.Behaviors>
|
||||
<cwub:AutoFocusBehavior/>
|
||||
</mxi:Interaction.Behaviors>
|
||||
</ScrollViewer>
|
||||
<Grid Grid.Row="1" VerticalAlignment="Bottom">
|
||||
<Button
|
||||
Grid.Column="3"
|
||||
Width="100"
|
||||
Height="80"
|
||||
MinWidth="80"
|
||||
Margin="24"
|
||||
HorizontalAlignment="Right"
|
||||
Command="{Binding LaunchCommand}"
|
||||
Style="{StaticResource AccentButtonStyle}">
|
||||
<StackPanel>
|
||||
<FontIcon FontSize="36" Glyph=""/>
|
||||
<TextBlock Margin="0,4,0,0" Text="{shcm:ResourceString Name=ViewPageLaunchGameAction}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</Grid>
|
||||
<wsc:SettingsGroup Header="{shcm:ResourceString Name=ViewPageLaunchGameAdvanceHeader}" IsEnabled="{Binding IsElevated}">
|
||||
<InfoBar
|
||||
IsClosable="False"
|
||||
IsOpen="{Binding IsElevated}"
|
||||
Message="{shcm:ResourceString Name=ViewPageLaunchGameAdvanceHint}"
|
||||
Severity="Error"/>
|
||||
<wsc:Setting
|
||||
Description="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsHeader}"
|
||||
Icon="">
|
||||
<wsc:Setting.ActionContent>
|
||||
<ToggleSwitch
|
||||
Width="120"
|
||||
IsOn="{Binding Options.UnlockFps, Mode=TwoWay}"
|
||||
OffContent="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsOff}"
|
||||
OnContent="{shcm:ResourceString Name=ViewPageLaunchGameUnlockFpsOn}"
|
||||
Style="{StaticResource ToggleSwitchSettingStyle}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
<wsc:Setting Header="{shcm:ResourceString Name=ViewPageLaunchGameSetFpsHeader}">
|
||||
<wsc:Setting.Description>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{shcm:ResourceString Name=ViewPageLaunchGameSetFpsDescription}"/>
|
||||
<TextBlock Text="{Binding Options.TargetFps}"/>
|
||||
</StackPanel>
|
||||
</wsc:Setting.Description>
|
||||
<wsc:Setting.ActionContent>
|
||||
<Slider
|
||||
Width="400"
|
||||
Maximum="360"
|
||||
Minimum="60"
|
||||
Value="{Binding Options.TargetFps, Mode=TwoWay}"/>
|
||||
</wsc:Setting.ActionContent>
|
||||
</wsc:Setting>
|
||||
</wsc:SettingsGroup>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</PivotItem>
|
||||
<PivotItem Header="{shcm:ResourceString Name=ViewPageLaunchGameResourceHeader}">
|
||||
<Grid>
|
||||
<ScrollViewer Visibility="{Binding GameResource, Converter={StaticResource EmptyObjectToBoolConverter}}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition MaxWidth="1000"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel>
|
||||
<shvc:LaunchGameResourceExpander
|
||||
Margin="16,16,16,0"
|
||||
DataContext="{Binding GameResource.PreDownloadGame.Latest, Mode=OneWay}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameResourcePreDownloadHeader}"
|
||||
Visibility="{Binding FallbackValue={StaticResource VisibilityCollapsed}, Converter={StaticResource EmptyObjectToVisibilityConverter}}"/>
|
||||
<shvc:LaunchGameResourceExpander
|
||||
Margin="16,16,16,0"
|
||||
DataContext="{Binding GameResource.Game.Latest, Mode=OneWay}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameResourceLatestHeader}"/>
|
||||
<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>
|
||||
|
||||
</shc:ScopedPage>
|
||||
@@ -15,6 +15,7 @@ using Snap.Hutao.Service.Game;
|
||||
using Snap.Hutao.Service.Navigation;
|
||||
using Snap.Hutao.Service.User;
|
||||
using Snap.Hutao.View.Dialog;
|
||||
using Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher;
|
||||
using Snap.Hutao.Web.Hoyolab.Takumi.Binding;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
@@ -35,7 +36,6 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
||||
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
private readonly IGameService gameService;
|
||||
private readonly AppDbContext appDbContext;
|
||||
private readonly IMemoryCache memoryCache;
|
||||
|
||||
private readonly List<LaunchScheme> knownSchemes = LaunchScheme.KnownSchemes.ToList();
|
||||
@@ -43,6 +43,7 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
||||
private LaunchScheme? selectedScheme;
|
||||
private ObservableCollection<GameAccount>? gameAccounts;
|
||||
private GameAccount? selectedGameAccount;
|
||||
private GameResource? gameResource;
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的启动游戏视图模型
|
||||
@@ -51,7 +52,6 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
||||
public LaunchGameViewModel(IServiceProvider serviceProvider)
|
||||
{
|
||||
gameService = serviceProvider.GetRequiredService<IGameService>();
|
||||
appDbContext = serviceProvider.GetRequiredService<AppDbContext>();
|
||||
memoryCache = serviceProvider.GetRequiredService<IMemoryCache>();
|
||||
Options = serviceProvider.GetRequiredService<LaunchOptions>();
|
||||
this.serviceProvider = serviceProvider;
|
||||
@@ -71,7 +71,19 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
||||
/// <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>
|
||||
/// 游戏账号集合
|
||||
@@ -88,6 +100,11 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
||||
/// </summary>
|
||||
public LaunchOptions Options { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 游戏资源
|
||||
/// </summary>
|
||||
public GameResource? GameResource { get => gameResource; set => SetProperty(ref gameResource, value); }
|
||||
|
||||
/// <summary>
|
||||
/// 是否提权
|
||||
/// </summary>
|
||||
@@ -122,6 +139,7 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
||||
/// <inheritdoc/>
|
||||
protected override async Task OpenUIAsync()
|
||||
{
|
||||
await ThreadHelper.SwitchToBackgroundAsync();
|
||||
if (File.Exists(gameService.GetGamePathSkipLocator()))
|
||||
{
|
||||
try
|
||||
@@ -131,6 +149,7 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
||||
MultiChannel multi = gameService.GetMultiChannel();
|
||||
if (string.IsNullOrEmpty(multi.ConfigFilePath))
|
||||
{
|
||||
await ThreadHelper.SwitchToMainThreadAsync();
|
||||
SelectedScheme = KnownSchemes.FirstOrDefault(s => s.Channel == multi.Channel && s.SubChannel == multi.SubChannel);
|
||||
}
|
||||
else
|
||||
@@ -138,8 +157,10 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
||||
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
|
||||
if (memoryCache.TryGetValue(DesiredUid, out object? value) && value is string uid)
|
||||
{
|
||||
@@ -155,12 +176,28 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
|
||||
else
|
||||
{
|
||||
serviceProvider.GetRequiredService<IInfoBarService>().Warning(SH.ViewModelLaunchGamePathInvalid);
|
||||
await ThreadHelper.SwitchToMainThreadAsync();
|
||||
await serviceProvider.GetRequiredService<INavigationService>()
|
||||
.NavigateAsync<View.Page.SettingPage>(INavigationAwaiter.Default, true)
|
||||
.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()
|
||||
{
|
||||
IInfoBarService infoBarService = serviceProvider.GetRequiredService<IInfoBarService>();
|
||||
|
||||
@@ -20,4 +20,9 @@ internal class PathMd5
|
||||
/// </summary>
|
||||
[JsonPropertyName("md5")]
|
||||
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.Runtime.CompilerServices;
|
||||
using Windows.Graphics;
|
||||
using Windows.Win32.Graphics.Gdi;
|
||||
using Windows.Win32.System.Diagnostics.ToolHelp;
|
||||
using Windows.Win32.UI.WindowsAndMessaging;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user