mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
refactor launchgame resources
This commit is contained in:
@@ -45,9 +45,9 @@ internal class LaunchScheme : IEquatable<ChannelOptions>
|
||||
/// </summary>
|
||||
public int LauncherId { get; private protected set; }
|
||||
|
||||
public string HoyoPlayLauncherId { get; private protected set; }
|
||||
public string HoyoPlayLauncherId { get; private protected set; } = default!;
|
||||
|
||||
public string HoyoPlayGameId { get; private protected set; }
|
||||
public string HoyoPlayGameId { get; private protected set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// API Key
|
||||
|
||||
@@ -6,12 +6,13 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||
xmlns:shwhshlr="using:Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource"
|
||||
xmlns:shwhhpc="using:Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect"
|
||||
xmlns:shwhhpcp="using:Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.Package"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
d:DataContext="{d:DesignInstance shwhshlr:Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource.Package}"
|
||||
d:DataContext="{d:DesignInstance shwhhpcp:Package}"
|
||||
IsExpanded="True"
|
||||
ItemsSource="{Binding VoicePacks}"
|
||||
ItemsSource="{Binding AllPackages}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<cwc:SettingsExpander.Resources>
|
||||
@@ -24,7 +25,7 @@
|
||||
</cwc:SettingsExpander.Resources>
|
||||
|
||||
<cwc:SettingsExpander.ItemTemplate>
|
||||
<DataTemplate x:DataType="shwhshlr:VoicePackage">
|
||||
<DataTemplate x:DataType="shwhhpc:PackageSegment">
|
||||
<cwc:SettingsCard
|
||||
Padding="{ThemeResource SettingsExpanderItemHasIconPadding}"
|
||||
ActionIcon="{shcm:FontIcon Glyph={StaticResource FontIconContentCopy}}"
|
||||
@@ -42,13 +43,13 @@
|
||||
Margin="8,0,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding PackageSize, Converter={StaticResource FileSizeToFriendlyStringConverter}}"/>
|
||||
Text="{Binding Size, Converter={StaticResource FileSizeToFriendlyStringConverter}}"/>
|
||||
<FontIcon FontSize="{StaticResource CaptionTextBlockFontSize}" Glyph="{StaticResource FontIconContentFolder}"/>
|
||||
<TextBlock
|
||||
Width="80"
|
||||
Margin="8,0,0,0"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding Size, Converter={StaticResource FileSizeToFriendlyStringConverter}}"/>
|
||||
Text="{Binding DecompressedSize, Converter={StaticResource FileSizeToFriendlyStringConverter}}"/>
|
||||
<FontIcon FontSize="{StaticResource CaptionTextBlockFontSize}" Glyph="{StaticResource FontIconContentAsteriskBadge12}"/>
|
||||
<TextBlock
|
||||
Margin="8,0,0,0"
|
||||
@@ -60,45 +61,4 @@
|
||||
</cwc:SettingsCard>
|
||||
</DataTemplate>
|
||||
</cwc:SettingsExpander.ItemTemplate>
|
||||
|
||||
<cwc:SettingsExpander.ItemsHeader>
|
||||
<cwc:SettingsCard
|
||||
MinHeight="52"
|
||||
Padding="{ThemeResource SettingsExpanderItemHasIconPadding}"
|
||||
ActionIcon="{shcm:FontIcon Glyph={StaticResource FontIconContentCopy}}"
|
||||
Background="{ThemeResource InfoBarInformationalSeverityBackgroundBrush}"
|
||||
BorderThickness="0"
|
||||
Command="{Binding CopyPathCommand}"
|
||||
CornerRadius="0"
|
||||
Header="{Binding DisplayName}"
|
||||
IsClickEnabled="True">
|
||||
<cwc:SettingsCard.Description>
|
||||
<StackPanel
|
||||
Grid.Row="1"
|
||||
Margin="0,4,0,0"
|
||||
Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource CaptionTextBlockFontSize}" Glyph="{StaticResource FontIconContentZipFolder}"/>
|
||||
<TextBlock
|
||||
Width="80"
|
||||
Margin="8,0,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding PackageSize, Converter={StaticResource FileSizeToFriendlyStringConverter}}"/>
|
||||
<FontIcon FontSize="{StaticResource CaptionTextBlockFontSize}" Glyph="{StaticResource FontIconContentFolder}"/>
|
||||
<TextBlock
|
||||
Width="80"
|
||||
Margin="8,0,0,0"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding Size, Converter={StaticResource FileSizeToFriendlyStringConverter}}"/>
|
||||
<FontIcon FontSize="{StaticResource CaptionTextBlockFontSize}" Glyph="{StaticResource FontIconContentAsteriskBadge12}"/>
|
||||
<TextBlock
|
||||
Margin="8,0,0,0"
|
||||
IsTextSelectionEnabled="True"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding Md5}"/>
|
||||
</StackPanel>
|
||||
</cwc:SettingsCard.Description>
|
||||
</cwc:SettingsCard>
|
||||
</cwc:SettingsExpander.ItemsHeader>
|
||||
|
||||
</cwc:SettingsExpander>
|
||||
|
||||
@@ -366,13 +366,13 @@
|
||||
</PivotItem>
|
||||
<PivotItem Header="{shcm:ResourceString Name=ViewPageLaunchGameResourceHeader}">
|
||||
<Grid>
|
||||
<ScrollViewer Visibility="{Binding GameResource, Converter={StaticResource EmptyObjectToBoolConverter}}">
|
||||
<ScrollViewer Visibility="{Binding GamePackage, Converter={StaticResource EmptyObjectToBoolConverter}}">
|
||||
<StackPanel>
|
||||
<Border Margin="16,16,16,0" cw:Effects.Shadow="{ThemeResource CompatCardShadow}">
|
||||
<Border Style="{ThemeResource AcrylicBorderCardStyle}">
|
||||
<shvc:LaunchGameResourceExpander
|
||||
cw:Effects.Shadow="{ThemeResource CompatCardShadow}"
|
||||
DataContext="{Binding GameResource.PreDownloadGame.Latest, Mode=OneWay}"
|
||||
DataContext="{Binding GamePackage.PreDownload.Major, Mode=OneWay}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameResourcePreDownloadHeader}"
|
||||
IsEnabled="{Binding FallbackValue=False, Converter={StaticResource EmptyObjectToBoolConverter}}"
|
||||
IsExpanded="{Binding FallbackValue=False, Converter={StaticResource EmptyObjectToBoolConverter}, Mode=OneTime}"/>
|
||||
@@ -382,22 +382,22 @@
|
||||
<ItemsControl
|
||||
Margin="0,0,0,0"
|
||||
ItemTemplate="{StaticResource GameResourceTemplate}"
|
||||
ItemsSource="{Binding GameResource.PreDownloadGame.Diffs, Mode=OneWay}"/>
|
||||
ItemsSource="{Binding GamePackage.PreDownload.Patches, Mode=OneWay}"/>
|
||||
<Border Margin="16,16,16,0" cw:Effects.Shadow="{ThemeResource CompatCardShadow}">
|
||||
<Border Style="{ThemeResource AcrylicBorderCardStyle}">
|
||||
<shvc:LaunchGameResourceExpander
|
||||
cw:Effects.Shadow="{ThemeResource CompatCardShadow}"
|
||||
DataContext="{Binding GameResource.Game.Latest, Mode=OneWay}"
|
||||
DataContext="{Binding GamePackage.Main.Major, Mode=OneWay}"
|
||||
Header="{shcm:ResourceString Name=ViewPageLaunchGameResourceLatestHeader}"/>
|
||||
</Border>
|
||||
</Border>
|
||||
<ItemsControl
|
||||
Margin="0,0,0,16"
|
||||
ItemTemplate="{StaticResource GameResourceTemplate}"
|
||||
ItemsSource="{Binding GameResource.Game.Diffs, Mode=OneWay}"/>
|
||||
ItemsSource="{Binding GamePackage.Main.Patches, Mode=OneWay}"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
<shvc:LoadingView IsLoading="{Binding GameResource, Converter={StaticResource EmptyObjectToBoolRevertConverter}}"/>
|
||||
<shvc:LoadingView IsLoading="{Binding GamePackage, Converter={StaticResource EmptyObjectToBoolRevertConverter}}"/>
|
||||
</Grid>
|
||||
</PivotItem>
|
||||
</Pivot>
|
||||
|
||||
@@ -15,8 +15,8 @@ using Snap.Hutao.Service.Game.PathAbstraction;
|
||||
using Snap.Hutao.Service.Game.Scheme;
|
||||
using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Service.User;
|
||||
using Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher;
|
||||
using Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource;
|
||||
using Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect;
|
||||
using Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.Package;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
|
||||
@@ -39,7 +39,6 @@ internal sealed partial class LaunchGameViewModel : Abstraction.ViewModel, IView
|
||||
private readonly IGameLocatorFactory gameLocatorFactory;
|
||||
private readonly LaunchGameShared launchGameShared;
|
||||
private readonly IInfoBarService infoBarService;
|
||||
private readonly ResourceClient resourceClient;
|
||||
private readonly RuntimeOptions runtimeOptions;
|
||||
private readonly LaunchOptions launchOptions;
|
||||
private readonly IUserService userService;
|
||||
@@ -47,11 +46,12 @@ internal sealed partial class LaunchGameViewModel : Abstraction.ViewModel, IView
|
||||
private readonly IGameServiceFacade gameService;
|
||||
private readonly IMemoryCache memoryCache;
|
||||
private readonly AppOptions appOptions;
|
||||
private readonly HoyoPlayClient hoyoPlayClient;
|
||||
|
||||
private LaunchScheme? selectedScheme;
|
||||
private AdvancedCollectionView<GameAccount>? gameAccountsView;
|
||||
private GameAccount? selectedGameAccount;
|
||||
private GameResource? gameResource;
|
||||
private GamePackage? gamePackage;
|
||||
private bool gamePathSelectedAndValid;
|
||||
private ImmutableList<GamePathEntry> gamePathEntries;
|
||||
private GamePathEntry? selectedGamePathEntry;
|
||||
@@ -69,7 +69,7 @@ internal sealed partial class LaunchGameViewModel : Abstraction.ViewModel, IView
|
||||
|
||||
public List<LaunchScheme> KnownSchemes { get; } = KnownLaunchSchemes.Get();
|
||||
|
||||
[AlsoAsyncSets(nameof(GameResource), nameof(GameAccountsView))]
|
||||
[AlsoAsyncSets(nameof(GameAccountsView), nameof(GamePackage))]
|
||||
public LaunchScheme? SelectedScheme
|
||||
{
|
||||
get => selectedScheme;
|
||||
@@ -80,7 +80,7 @@ internal sealed partial class LaunchGameViewModel : Abstraction.ViewModel, IView
|
||||
|
||||
public GameAccount? SelectedGameAccount { get => selectedGameAccount; set => SetProperty(ref selectedGameAccount, value); }
|
||||
|
||||
public GameResource? GameResource { get => gameResource; set => SetProperty(ref gameResource, value); }
|
||||
public GamePackage? GamePackage { get => gamePackage; set => SetProperty(ref gamePackage, value); }
|
||||
|
||||
public bool GamePathSelectedAndValid
|
||||
{
|
||||
@@ -301,10 +301,10 @@ internal sealed partial class LaunchGameViewModel : Abstraction.ViewModel, IView
|
||||
SelectedGameAccount = default;
|
||||
|
||||
await UpdateGameAccountsViewAsync().ConfigureAwait(false);
|
||||
UpdateGameResourceAsync(value).SafeForget();
|
||||
UpdateGamePackageAsync(value).SafeForget();
|
||||
}
|
||||
|
||||
async ValueTask UpdateGameResourceAsync(LaunchScheme? scheme)
|
||||
async ValueTask UpdateGamePackageAsync(LaunchScheme? scheme)
|
||||
{
|
||||
if (scheme is null)
|
||||
{
|
||||
@@ -312,14 +312,14 @@ internal sealed partial class LaunchGameViewModel : Abstraction.ViewModel, IView
|
||||
}
|
||||
|
||||
await taskContext.SwitchToBackgroundAsync();
|
||||
Web.Response.Response<GameResource> response = await resourceClient
|
||||
.GetResourceAsync(scheme)
|
||||
Web.Response.Response<GamePackages> response = await hoyoPlayClient
|
||||
.GetPackagesAsync(scheme)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (response.IsOk())
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
GameResource = response.Data;
|
||||
GamePackage = response.Data.Packages.Single();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ internal sealed partial class HoyoPlayClient
|
||||
private readonly HttpClient httpClient;
|
||||
private readonly ILogger<HoyoPlayClient> logger;
|
||||
|
||||
public async ValueTask<Response<GamePackage>> GetPackagesAsync(LaunchScheme scheme, CancellationToken token = default)
|
||||
public async ValueTask<Response<GamePackages>> GetPackagesAsync(LaunchScheme scheme, CancellationToken token = default)
|
||||
{
|
||||
string url = scheme.IsOversea
|
||||
? ApiOsEndpoints.SgHoyoPlayConnectGamePackages(scheme)
|
||||
@@ -31,8 +31,8 @@ internal sealed partial class HoyoPlayClient
|
||||
.SetRequestUri(url)
|
||||
.Get();
|
||||
|
||||
Response<GamePackage>? resp = await builder
|
||||
.SendAsync<Response<GamePackage>>(httpClient, logger, token)
|
||||
Response<GamePackages>? resp = await builder
|
||||
.SendAsync<Response<GamePackages>>(httpClient, logger, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Response.Response.DefaultIfNull(resp);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.Package;
|
||||
|
||||
internal sealed class GamePackages
|
||||
{
|
||||
[JsonPropertyName("game_packages")]
|
||||
public List<GamePackage> Packages { get; set; } = default!;
|
||||
}
|
||||
@@ -16,4 +16,10 @@ internal sealed class Package
|
||||
|
||||
[JsonPropertyName("res_list_url")]
|
||||
public string ResListUrl { get; set; } = default!;
|
||||
|
||||
[JsonIgnore]
|
||||
public List<PackageSegment> AllPackages
|
||||
{
|
||||
get => [.. GamePackages, .. AudioPackages];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Core.IO.DataTransfer;
|
||||
using Snap.Hutao.Service.Notification;
|
||||
|
||||
namespace Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect;
|
||||
|
||||
internal class PackageSegment
|
||||
internal partial class PackageSegment
|
||||
{
|
||||
[JsonPropertyName("url")]
|
||||
public string Url { get; set; } = default!;
|
||||
@@ -12,8 +15,19 @@ internal class PackageSegment
|
||||
public string Md5 { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("size")]
|
||||
public string Size { get; set; } = default!;
|
||||
public long Size { get; set; } = default!;
|
||||
|
||||
[JsonPropertyName("decompressed_size")]
|
||||
public string DecompressedSize { get; set; } = default!;
|
||||
public long DecompressedSize { get; set; } = default!;
|
||||
|
||||
[JsonIgnore]
|
||||
public string DisplayName { get => System.IO.Path.GetFileName(Url); }
|
||||
|
||||
[Command("CopyPathCommand")]
|
||||
private void CopyPathToClipboard()
|
||||
{
|
||||
IServiceProvider serviceProvider = Ioc.Default;
|
||||
serviceProvider.GetRequiredService<IClipboardProvider>().SetText(Url);
|
||||
serviceProvider.GetRequiredService<IInfoBarService>().Success(SH.WebGameResourcePathCopySucceed);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user