diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/Launching/Handler/LaunchExecutionEnsureGameResourceHandler.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/Launching/Handler/LaunchExecutionEnsureGameResourceHandler.cs index dd717a98..9047e496 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Game/Launching/Handler/LaunchExecutionEnsureGameResourceHandler.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/Launching/Handler/LaunchExecutionEnsureGameResourceHandler.cs @@ -10,8 +10,10 @@ using Snap.Hutao.Model.Intrinsic; using Snap.Hutao.Service.Game.Configuration; using Snap.Hutao.Service.Game.Package; using Snap.Hutao.View.Dialog; -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.ChannelSDK; +using Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.DeprecatedFile; +using Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.Package; using Snap.Hutao.Web.Response; using System.IO; @@ -43,7 +45,7 @@ internal sealed class LaunchExecutionEnsureGameResourceHandler : ILaunchExecutio return; } - // Backup config file, in order to prevent a incompatible launcher to delete it. + // Backup config file, recover when a incompatible launcher deleted it. context.ServiceProvider.GetRequiredService().Backup(gameFileSystem.GameConfigFilePath); await context.TaskContext.SwitchToMainThreadAsync(); @@ -96,13 +98,30 @@ internal sealed class LaunchExecutionEnsureGameResourceHandler : ILaunchExecutio progress.Report(new(SH.ServiceGameEnsureGameResourceQueryResourceInformation)); - ResourceClient resourceClient = context.ServiceProvider.GetRequiredService(); - Response response = await resourceClient.GetResourceAsync(context.Scheme).ConfigureAwait(false); + HoyoPlayClient hoyoPlayClient = context.ServiceProvider.GetRequiredService(); - if (!response.TryGetDataWithoutUINotification(out GameResource? resource)) + // We perform these requests before package conversion to ensure resources index is intact. + Response packagesResponse = await hoyoPlayClient.GetPackagesAsync(context.Scheme).ConfigureAwait(false); + if (!packagesResponse.TryGetDataWithoutUINotification(out GamePackagesWrapper? gamePackages)) { context.Result.Kind = LaunchExecutionResultKind.GameResourceIndexQueryInvalidResponse; - context.Result.ErrorMessage = SH.FormatServiceGameLaunchExecutionGameResourceQueryIndexFailed(response); + context.Result.ErrorMessage = SH.FormatServiceGameLaunchExecutionGameResourceQueryIndexFailed(packagesResponse); + return false; + } + + Response sdkResponse = await hoyoPlayClient.GetChannelSDKAsync(context.Scheme).ConfigureAwait(false); + if (!sdkResponse.TryGetDataWithoutUINotification(out GameChannelSDKsWrapper? channelSDKs)) + { + context.Result.Kind = LaunchExecutionResultKind.GameResourceIndexQueryInvalidResponse; + context.Result.ErrorMessage = SH.FormatServiceGameLaunchExecutionGameResourceQueryIndexFailed(sdkResponse); + return false; + } + + Response deprecatedFileResponse = await hoyoPlayClient.GetDeprecatedFileConfigurationsAsync(context.Scheme).ConfigureAwait(false); + if (!deprecatedFileResponse.TryGetDataWithoutUINotification(out DeprecatedFileConfigurationsWrapper? deprecatedFileConfigs)) + { + context.Result.Kind = LaunchExecutionResultKind.GameResourceIndexQueryInvalidResponse; + context.Result.ErrorMessage = SH.FormatServiceGameLaunchExecutionGameResourceQueryIndexFailed(deprecatedFileResponse); return false; } @@ -110,7 +129,7 @@ internal sealed class LaunchExecutionEnsureGameResourceHandler : ILaunchExecutio if (!context.Scheme.ExecutableMatches(gameFileName)) { - if (!await packageConverter.EnsureGameResourceAsync(context.Scheme, resource, gameFolder, progress).ConfigureAwait(false)) + if (!await packageConverter.EnsureGameResourceAsync(context.Scheme, gamePackages.GamePackages.Single(), gameFolder, progress).ConfigureAwait(false)) { context.Result.Kind = LaunchExecutionResultKind.GameResourcePackageConvertInternalError; context.Result.ErrorMessage = SH.ViewModelLaunchGameEnsureGameResourceFail; @@ -124,7 +143,7 @@ internal sealed class LaunchExecutionEnsureGameResourceHandler : ILaunchExecutio context.Options.UpdateGamePathAndRefreshEntries(Path.Combine(gameFolder, executableName)); } - await packageConverter.EnsureDeprecatedFilesAndSdkAsync(resource, gameFolder).ConfigureAwait(false); + await packageConverter.EnsureDeprecatedFilesAndSdkAsync(channelSDKs.GameChannelSDKs.SingleOrDefault(), deprecatedFileConfigs.DeprecatedFileConfigurations.SingleOrDefault(), gameFolder).ConfigureAwait(false); return true; } diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/Launching/Handler/LaunchExecutionSetChannelOptionsHandler.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/Launching/Handler/LaunchExecutionSetChannelOptionsHandler.cs index 7247b4ae..031c3b95 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Game/Launching/Handler/LaunchExecutionSetChannelOptionsHandler.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/Launching/Handler/LaunchExecutionSetChannelOptionsHandler.cs @@ -20,7 +20,7 @@ internal sealed class LaunchExecutionSetChannelOptionsHandler : ILaunchExecution string configPath = gameFileSystem.GameConfigFilePath; context.Logger.LogInformation("Game config file path: {ConfigPath}", configPath); - List elements = default!; + List elements; try { elements = [.. IniSerializer.DeserializeFromFile(configPath)]; diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/Package/PackageConverter.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/Package/PackageConverter.cs index ae992c04..c29862d6 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Game/Package/PackageConverter.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/Package/PackageConverter.cs @@ -8,7 +8,9 @@ using Snap.Hutao.Core.IO; using Snap.Hutao.Core.IO.Hashing; using Snap.Hutao.Core.IO.Http.Sharding; using Snap.Hutao.Service.Game.Scheme; -using Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource; +using Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.ChannelSDK; +using Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.DeprecatedFile; +using Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.Package; using System.Globalization; using System.IO; using System.IO.Compression; @@ -34,9 +36,9 @@ internal sealed partial class PackageConverter private readonly HttpClient httpClient; private readonly ILogger logger; - public async ValueTask EnsureGameResourceAsync(LaunchScheme targetScheme, GameResource gameResource, string gameFolder, IProgress progress) + public async ValueTask EnsureGameResourceAsync(LaunchScheme targetScheme, GamePackage gamePackage, string gameFolder, IProgress progress) { - // 以 国服 => 国际 为例 + // 以 国服 -> 国际服 为例 // 1. 下载国际服的 pkg_version 文件,转换为索引字典 // 获取本地对应 pkg_version 文件,转换为索引字典 // @@ -56,7 +58,7 @@ internal sealed partial class PackageConverter // 替换操作等于 先备份国服文件,随后新增国际服文件 // 准备下载链接 - string scatteredFilesUrl = gameResource.Game.Latest.DecompressedPath; + string scatteredFilesUrl = gamePackage.Main.Major.ResourceListUrl; string pkgVersionUrl = $"{scatteredFilesUrl}/{PackageVersion}"; PackageConverterFileSystemContext context = new(targetScheme.IsOversea, runtimeOptions.GetDataFolderServerCacheFolder(), gameFolder, scatteredFilesUrl); @@ -77,7 +79,7 @@ internal sealed partial class PackageConverter return await ReplaceGameResourceAsync(diffOperations, context, progress).ConfigureAwait(false); } - public async ValueTask EnsureDeprecatedFilesAndSdkAsync(GameResource resource, string gameFolder) + public async ValueTask EnsureDeprecatedFilesAndSdkAsync(GameChannelSDK? channelSDK, DeprecatedFilesWrapper? deprecatedFiles, string gameFolder) { string sdkDllBackup = Path.Combine(gameFolder, YuanShenData, "Plugins\\PCGameSDK.dll.backup"); string sdkDll = Path.Combine(gameFolder, YuanShenData, "Plugins\\PCGameSDK.dll"); @@ -86,9 +88,9 @@ internal sealed partial class PackageConverter string sdkVersion = Path.Combine(gameFolder, "sdk_pkg_version"); // Only bilibili's sdk is not null - if (resource.Sdk is not null) + if (channelSDK is not null) { - using (Stream sdkWebStream = await httpClient.GetStreamAsync(resource.Sdk.Path).ConfigureAwait(false)) + using (Stream sdkWebStream = await httpClient.GetStreamAsync(channelSDK.ChannelSdkPackage.Url).ConfigureAwait(false)) { ZipFile.ExtractToDirectory(sdkWebStream, gameFolder, true); } @@ -106,9 +108,9 @@ internal sealed partial class PackageConverter FileOperation.Move(sdkVersion, sdkVersionBackup, true); } - if (resource.DeprecatedFiles is not null) + if (deprecatedFiles is not null) { - foreach (NameMd5 file in resource.DeprecatedFiles) + foreach (DeprecatedFile file in deprecatedFiles.DeprecatedFiles) { string filePath = Path.Combine(gameFolder, file.Name); FileOperation.Move(filePath, $"{filePath}.backup", true); diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/Scheme/LaunchScheme.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/Scheme/LaunchScheme.cs index 30857085..e7947cc3 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Game/Scheme/LaunchScheme.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/Scheme/LaunchScheme.cs @@ -30,25 +30,13 @@ internal class LaunchScheme : IEquatable } } - /// - /// 通道 - /// public ChannelType Channel { get; private protected set; } - /// - /// 子通道 - /// public SubChannelType SubChannel { get; private protected set; } - /// - /// 启动器 Id - /// - public int LauncherId { get; private protected set; } + public string LauncherId { get; private protected set; } = default!; - /// - /// API Key - /// - public string Key { get; private protected set; } = default!; + public string GameId { get; private protected set; } = default!; /// /// 是否为海外 diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/Scheme/LaunchSchemeBilibili.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/Scheme/LaunchSchemeBilibili.cs index 1d96e21d..39af831f 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Game/Scheme/LaunchSchemeBilibili.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/Scheme/LaunchSchemeBilibili.cs @@ -7,13 +7,13 @@ namespace Snap.Hutao.Service.Game.Scheme; internal sealed class LaunchSchemeBilibili : LaunchScheme { - private const int SdkStaticLauncherBilibiliId = 17; - private const string SdkStaticLauncherBilibiliKey = "KAtdSsoQ"; + private const string HoyoPlayLauncherBilibiliId = "umfgRO5gh5"; + private const string HoyoPlayGameBilibiliId = "T2S0Gz4Dr2"; public LaunchSchemeBilibili(SubChannelType subChannel, bool isNotCompatOnly = true) { - LauncherId = SdkStaticLauncherBilibiliId; - Key = SdkStaticLauncherBilibiliKey; + LauncherId = HoyoPlayLauncherBilibiliId; + GameId = HoyoPlayGameBilibiliId; Channel = ChannelType.Bili; SubChannel = subChannel; IsOversea = false; diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/Scheme/LaunchSchemeChinese.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/Scheme/LaunchSchemeChinese.cs index e9d27c6d..e20fb922 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Game/Scheme/LaunchSchemeChinese.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/Scheme/LaunchSchemeChinese.cs @@ -7,13 +7,13 @@ namespace Snap.Hutao.Service.Game.Scheme; internal sealed class LaunchSchemeChinese : LaunchScheme { - private const int SdkStaticLauncherChineseId = 18; - private const string SdkStaticLauncherChineseKey = "eYd89JmJ"; + private const string HoyoPlayLauncherChineseId = "jGHBHlcOq1"; + private const string HoyoPlayGameChineseId = "1Z8W5NHUQb"; public LaunchSchemeChinese(ChannelType channel, SubChannelType subChannel, bool isNotCompatOnly = true) { - LauncherId = SdkStaticLauncherChineseId; - Key = SdkStaticLauncherChineseKey; + LauncherId = HoyoPlayLauncherChineseId; + GameId = HoyoPlayGameChineseId; Channel = channel; SubChannel = subChannel; IsOversea = false; diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/Scheme/LaunchSchemeOversea.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/Scheme/LaunchSchemeOversea.cs index 08b6799a..45df3e74 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Game/Scheme/LaunchSchemeOversea.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/Scheme/LaunchSchemeOversea.cs @@ -7,13 +7,13 @@ namespace Snap.Hutao.Service.Game.Scheme; internal sealed class LaunchSchemeOversea : LaunchScheme { - private const int SdkStaticLauncherOverseaId = 10; - private const string SdkStaticLauncherOverseaKey = "gcStgarh"; + private const string HoyoPlayLauncherOverseaId = "VYTpXlbWo8"; + private const string HoyoPlayGameOverseaId = "gopR6Cufr3"; public LaunchSchemeOversea(ChannelType channel, SubChannelType subChannel, bool isNotCompatOnly = true) { - LauncherId = SdkStaticLauncherOverseaId; - Key = SdkStaticLauncherOverseaKey; + LauncherId = HoyoPlayLauncherOverseaId; + GameId = HoyoPlayGameOverseaId; Channel = channel; SubChannel = subChannel; IsOversea = true; diff --git a/src/Snap.Hutao/Snap.Hutao/View/Card/AchievementCard.xaml b/src/Snap.Hutao/Snap.Hutao/View/Card/AchievementCard.xaml index 2a696ffa..5329fc04 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Card/AchievementCard.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Card/AchievementCard.xaml @@ -16,6 +16,7 @@ d:DataContext="{d:DesignInstance shva:AchievementViewModelSlim}" Background="Transparent" BorderBrush="{x:Null}" + BorderThickness="0" Command="{Binding NavigateCommand}" Style="{ThemeResource DefaultButtonStyle}" mc:Ignorable="d"> diff --git a/src/Snap.Hutao/Snap.Hutao/View/Card/DailyNoteCard.xaml b/src/Snap.Hutao/Snap.Hutao/View/Card/DailyNoteCard.xaml index 49cccddf..4e447c2b 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Card/DailyNoteCard.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Card/DailyNoteCard.xaml @@ -18,6 +18,7 @@ d:DataContext="{d:DesignInstance shvd:DailyNoteViewModelSlim}" Background="Transparent" BorderBrush="{x:Null}" + BorderThickness="0" Command="{Binding NavigateCommand}" Style="{ThemeResource DefaultButtonStyle}" mc:Ignorable="d"> diff --git a/src/Snap.Hutao/Snap.Hutao/View/Card/GachaStatisticsCard.xaml b/src/Snap.Hutao/Snap.Hutao/View/Card/GachaStatisticsCard.xaml index a773211b..aad73941 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Card/GachaStatisticsCard.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Card/GachaStatisticsCard.xaml @@ -17,6 +17,7 @@ d:DataContext="{d:DesignInstance shvg:GachaLogViewModelSlim}" Background="Transparent" BorderBrush="{x:Null}" + BorderThickness="0" Command="{Binding NavigateCommand}" Style="{ThemeResource DefaultButtonStyle}" mc:Ignorable="d"> diff --git a/src/Snap.Hutao/Snap.Hutao/View/Card/LaunchGameCard.xaml b/src/Snap.Hutao/Snap.Hutao/View/Card/LaunchGameCard.xaml index 9a0ecbc9..c1b6ca0f 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Card/LaunchGameCard.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Card/LaunchGameCard.xaml @@ -18,6 +18,7 @@ d:DataContext="{d:DesignInstance shvg:LaunchGameViewModelSlim}" Background="Transparent" BorderBrush="{x:Null}" + BorderThickness="0" Command="{Binding LaunchCommand}" Style="{ThemeResource DefaultButtonStyle}" mc:Ignorable="d"> diff --git a/src/Snap.Hutao/Snap.Hutao/View/Control/LaunchGameResourceExpander.xaml b/src/Snap.Hutao/Snap.Hutao/View/Control/LaunchGameResourceExpander.xaml index b937a820..b1e964fe 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Control/LaunchGameResourceExpander.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Control/LaunchGameResourceExpander.xaml @@ -6,12 +6,14 @@ 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}" + BorderThickness="0" IsExpanded="True" - ItemsSource="{Binding VoicePacks}" + ItemsSource="{Binding AllPackages}" mc:Ignorable="d"> @@ -24,7 +26,7 @@ - + + Orientation="Horizontal" + Spacing="8"> + Text="{Binding Size, Converter={StaticResource FileSizeToFriendlyStringConverter}}"/> + Text="{Binding DecompressedSize, Converter={StaticResource FileSizeToFriendlyStringConverter}}"/> + Text="{Binding MD5}"/> - - - - - - - - - - - - - - - - diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/LaunchGamePage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/LaunchGamePage.xaml index ac7d718c..307c3cac 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/LaunchGamePage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/LaunchGamePage.xaml @@ -366,13 +366,13 @@ - + @@ -382,22 +382,22 @@ + ItemsSource="{Binding GamePackage.PreDownload.Patches, Mode=OneWay}"/> + ItemsSource="{Binding GamePackage.Main.Patches, Mode=OneWay}"/> - + diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameLaunchExecution.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameLaunchExecution.cs index 0c0752a3..1a088757 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameLaunchExecution.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameLaunchExecution.cs @@ -11,26 +11,26 @@ internal static class LaunchGameLaunchExecution { public static async ValueTask LaunchExecutionAsync(this IViewModelSupportLaunchExecution launchExecution, LaunchScheme? targetScheme) { - IServiceProvider root = Ioc.Default; - IInfoBarService infoBarService = root.GetRequiredService(); - ILogger logger = root.GetRequiredService>(); - - // LaunchScheme? scheme = launchExecution.Shared.GetCurrentLaunchSchemeFromConfigFile(); - try + using (IServiceScope scope = Ioc.Default.CreateScope()) { - // Root service provider is required. - LaunchExecutionContext context = new(root, launchExecution, targetScheme, launchExecution.SelectedGameAccount); - LaunchExecutionResult result = await new LaunchExecutionInvoker().InvokeAsync(context).ConfigureAwait(false); + IInfoBarService infoBarService = scope.ServiceProvider.GetRequiredService(); + ILogger logger = scope.ServiceProvider.GetRequiredService>(); - if (result.Kind is not LaunchExecutionResultKind.Ok) + try { - infoBarService.Warning(result.ErrorMessage); + LaunchExecutionContext context = new(scope.ServiceProvider, launchExecution, targetScheme, launchExecution.SelectedGameAccount); + LaunchExecutionResult result = await new LaunchExecutionInvoker().InvokeAsync(context).ConfigureAwait(false); + + if (result.Kind is not LaunchExecutionResultKind.Ok) + { + infoBarService.Warning(result.ErrorMessage); + } + } + catch (Exception ex) + { + logger.LogCritical(ex, "Launch failed"); + infoBarService.Error(ex); } - } - catch (Exception ex) - { - logger.LogCritical(ex, "Launch failed"); - infoBarService.Error(ex); } } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameViewModel.cs index 79af1cd2..1a5984c4 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Game/LaunchGameViewModel.cs @@ -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,19 +39,19 @@ 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 IGameServiceFacade gameService; private readonly RuntimeOptions runtimeOptions; + private readonly HoyoPlayClient hoyoPlayClient; private readonly LaunchOptions launchOptions; private readonly IUserService userService; private readonly ITaskContext taskContext; - private readonly IGameServiceFacade gameService; private readonly IMemoryCache memoryCache; private readonly AppOptions appOptions; private LaunchScheme? selectedScheme; private AdvancedCollectionView? gameAccountsView; private GameAccount? selectedGameAccount; - private GameResource? gameResource; + private GamePackage? gamePackage; private bool gamePathSelectedAndValid; private ImmutableList gamePathEntries; private GamePathEntry? selectedGamePathEntry; @@ -69,7 +69,7 @@ internal sealed partial class LaunchGameViewModel : Abstraction.ViewModel, IView public List KnownSchemes { get; } = KnownLaunchSchemes.Get(); - [AlsoAsyncSets(nameof(GameResource), nameof(GameAccountsView))] + [AlsoAsyncSets(nameof(GamePackage), nameof(GameAccountsView))] 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 response = await resourceClient - .GetResourceAsync(scheme) + Web.Response.Response response = await hoyoPlayClient + .GetPackagesAsync(scheme) .ConfigureAwait(false); if (response.IsOk()) { await taskContext.SwitchToMainThreadAsync(); - GameResource = response.Data; + GamePackage = response.Data.GamePackages.Single(); } } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/ApiEndpoints.cs b/src/Snap.Hutao/Snap.Hutao/Web/ApiEndpoints.cs index fa053f12..ce9fb1e6 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/ApiEndpoints.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/ApiEndpoints.cs @@ -284,6 +284,25 @@ internal static class ApiEndpoints #endregion + #region HoyoPlayApi + + public static string HoyoPlayConnectGamePackages(LaunchScheme scheme) + { + return $"{HoyoPlayApiConnectApi}/getGamePackages?game_ids[]={scheme.GameId}&launcher_id={scheme.LauncherId}"; + } + + public static string HoyoPlayConnectGameChannelSDKs(LaunchScheme scheme) + { + return $"{HoyoPlayApiConnectApi}/getGameChannelSDKs?channel={scheme.Channel:D}&game_ids[]={scheme.GameId}&launcher_id={scheme.LauncherId}&sub_channel={scheme.SubChannel:D}"; + } + + public static string HoyoPlayConnectDeprecatedFileConfigs(LaunchScheme scheme) + { + return $"{HoyoPlayApiConnectApi}/getGameDeprecatedFileConfigs?channel={scheme.Channel:D}&game_ids[]={scheme.GameId}&launcher_id={scheme.LauncherId}&sub_channel={scheme.SubChannel:D}"; + } + + #endregion + #region PassportApi | PassportApiV4 /// @@ -348,26 +367,6 @@ internal static class ApiEndpoints } #endregion - #region SdkStaticLauncherApi - - /// - /// 启动器资源 - /// - /// 启动方案 - /// 启动器资源字符串 - public static string SdkStaticLauncherResource(LaunchScheme scheme) - { - return $"{SdkStaticLauncherApi}/resource?key={scheme.Key}&launcher_id={scheme.LauncherId}&channel_id={scheme.Channel:D}&sub_channel_id={scheme.SubChannel:D}"; - } - - public static string SdkStaticLauncherContent(LaunchScheme scheme, string languageCode, bool advOnly = true) - { - return advOnly - ? $"{SdkStaticLauncherApi}/content?filter_adv=true&key={scheme.Key}&launcher_id={scheme.LauncherId}&language={languageCode}" - : $"{SdkStaticLauncherApi}/content?key={scheme.Key}&launcher_id={scheme.LauncherId}&language={languageCode}"; - } - #endregion - #region Hosts | Queries private const string ApiTakumi = "https://api-takumi.mihoyo.com"; private const string ApiTakumiAuthApi = $"{ApiTakumi}/auth/api"; @@ -395,6 +394,9 @@ internal static class ApiEndpoints private const string Hk4eSdk = "https://hk4e-sdk.mihoyo.com"; + private const string HoyoPlayApi = "https://hyp-api.mihoyo.com"; + private const string HoyoPlayApiConnectApi = $"{HoyoPlayApi}/hyp/hyp-connect/api"; + private const string PassportApi = "https://passport-api.mihoyo.com"; private const string PassportApiAuthApi = $"{PassportApi}/account/auth/api"; private const string PassportApiV4 = "https://passport-api-v4.mihoyo.com"; diff --git a/src/Snap.Hutao/Snap.Hutao/Web/ApiOsEndpoints.cs b/src/Snap.Hutao/Snap.Hutao/Web/ApiOsEndpoints.cs index a9a8ffd7..41a50529 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/ApiOsEndpoints.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/ApiOsEndpoints.cs @@ -298,19 +298,23 @@ internal static class ApiOsEndpoints } #endregion - #region SdkOsStaticLauncherApi + #region SgHoyoPlayApi - public static string SdkOsStaticLauncherResource(LaunchScheme scheme) + public static string SgHoyoPlayConnectGamePackages(LaunchScheme scheme) { - return $"{SdkOsStaticLauncherApi}/resource?key={scheme.Key}&launcher_id={scheme.LauncherId}&channel_id={scheme.Channel:D}&sub_channel_id={scheme.SubChannel:D}"; + return $"{SgHoyoPlayApiConnectApi}/getGamePackages?game_ids[]={scheme.GameId}&launcher_id={scheme.LauncherId}"; } - public static string SdkOsStaticLauncherContent(LaunchScheme scheme, string languageCode, bool advOnly = true) + public static string SgHoyoPlayConnectGameChannelSDKs(LaunchScheme scheme) { - return advOnly - ? $"{SdkOsStaticLauncherApi}/content?filter_adv=true&key={scheme.Key}&launcher_id={scheme.LauncherId}&language={languageCode}" - : $"{SdkOsStaticLauncherApi}/content?key={scheme.Key}&launcher_id={scheme.LauncherId}&language={languageCode}"; + return $"{SgHoyoPlayApiConnectApi}/getGameChannelSDKs?channel={scheme.Channel:D}&game_ids[]={scheme.GameId}&launcher_id={scheme.LauncherId}&sub_channel={scheme.SubChannel:D}"; } + + public static string SgHoyoPlayConnectDeprecatedFileConfigs(LaunchScheme scheme) + { + return $"{SgHoyoPlayApiConnectApi}/getGameDeprecatedFileConfigs?channel={scheme.Channel:D}&game_ids[]={scheme.GameId}&launcher_id={scheme.LauncherId}&sub_channel={scheme.SubChannel:D}"; + } + #endregion #region WebApiOsAccountApi @@ -344,6 +348,9 @@ internal static class ApiOsEndpoints private const string SgPublicApi = "https://sg-public-api.hoyoverse.com"; private const string SgHk4eApi = "https://sg-hk4e-api.hoyoverse.com"; + private const string SgHoyoPlayApi = "https://sg-hyp-api.hoyoverse.com"; + private const string SgHoyoPlayApiConnectApi = $"{SgHoyoPlayApi}/hyp/hyp-connect/api"; + private const string WebApiOs = "https://webapi-os.account.hoyoverse.com"; private const string WebApiOsAccountApi = $"{WebApiOs}/Api"; diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/ChannelSDK/GameChannelSDK.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/ChannelSDK/GameChannelSDK.cs new file mode 100644 index 00000000..f7105a42 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/ChannelSDK/GameChannelSDK.cs @@ -0,0 +1,16 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.ChannelSDK; + +internal sealed class GameChannelSDK : GameIndexedObject +{ + [JsonPropertyName("channel_sdk_pkg")] + public PackageSegment ChannelSdkPackage { get; set; } = default!; + + [JsonPropertyName("pkg_version_file_name")] + public string PackageVersionFileName { get; set; } = default!; + + [JsonPropertyName("version")] + public string Version { get; set; } = default!; +} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/ChannelSDK/GameChannelSDKsWrapper.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/ChannelSDK/GameChannelSDKsWrapper.cs new file mode 100644 index 00000000..38aec5eb --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/ChannelSDK/GameChannelSDKsWrapper.cs @@ -0,0 +1,10 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.ChannelSDK; + +internal sealed class GameChannelSDKsWrapper +{ + [JsonPropertyName("game_channel_sdks")] + public List GameChannelSDKs { get; set; } = default!; +} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/DeprecatedFile/DeprecatedFile.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/DeprecatedFile/DeprecatedFile.cs new file mode 100644 index 00000000..e42f15df --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/DeprecatedFile/DeprecatedFile.cs @@ -0,0 +1,10 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.DeprecatedFile; + +internal sealed class DeprecatedFile +{ + [JsonPropertyName("name")] + public string Name { get; set; } = default!; +} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/DeprecatedFile/DeprecatedFileConfigurationsWrapper.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/DeprecatedFile/DeprecatedFileConfigurationsWrapper.cs new file mode 100644 index 00000000..06c33b07 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/DeprecatedFile/DeprecatedFileConfigurationsWrapper.cs @@ -0,0 +1,10 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.DeprecatedFile; + +internal sealed class DeprecatedFileConfigurationsWrapper +{ + [JsonPropertyName("deprecated_file_configs")] + public List DeprecatedFileConfigurations { get; set; } = default!; +} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/DeprecatedFile/DeprecatedFilesWrapper.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/DeprecatedFile/DeprecatedFilesWrapper.cs new file mode 100644 index 00000000..733001a1 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/DeprecatedFile/DeprecatedFilesWrapper.cs @@ -0,0 +1,10 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.DeprecatedFile; + +internal sealed class DeprecatedFilesWrapper : GameIndexedObject +{ + [JsonPropertyName("deprecated_files")] + public List DeprecatedFiles { get; set; } = default!; +} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Game.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Game.cs new file mode 100644 index 00000000..44f50099 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Game.cs @@ -0,0 +1,13 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect; + +internal sealed class Game +{ + [JsonPropertyName("id")] + public string Id { get; set; } = default!; + + [JsonPropertyName("biz")] + public string Biz { get; set; } = default!; +} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/GameIndexedObject.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/GameIndexedObject.cs new file mode 100644 index 00000000..9a2688fa --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/GameIndexedObject.cs @@ -0,0 +1,10 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect; + +internal abstract class GameIndexedObject +{ + [JsonPropertyName("game")] + public Game Game { get; set; } = default!; +} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/HoyoPlayClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/HoyoPlayClient.cs new file mode 100644 index 00000000..1d55037d --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/HoyoPlayClient.cs @@ -0,0 +1,74 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient; +using Snap.Hutao.Service.Game.Scheme; +using Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.ChannelSDK; +using Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.DeprecatedFile; +using Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.Package; +using Snap.Hutao.Web.Request.Builder; +using Snap.Hutao.Web.Request.Builder.Abstraction; +using Snap.Hutao.Web.Response; +using System.Net.Http; + +namespace Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect; + +[ConstructorGenerated(ResolveHttpClient = true)] +[HttpClient(HttpClientConfiguration.Default)] +internal sealed partial class HoyoPlayClient +{ + private readonly IHttpRequestMessageBuilderFactory httpRequestMessageBuilderFactory; + private readonly ILogger logger; + private readonly HttpClient httpClient; + + public async ValueTask> GetPackagesAsync(LaunchScheme scheme, CancellationToken token = default) + { + string url = scheme.IsOversea + ? ApiOsEndpoints.SgHoyoPlayConnectGamePackages(scheme) + : ApiEndpoints.HoyoPlayConnectGamePackages(scheme); + + HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create() + .SetRequestUri(url) + .Get(); + + Response? resp = await builder + .SendAsync>(httpClient, logger, token) + .ConfigureAwait(false); + + return Response.Response.DefaultIfNull(resp); + } + + public async ValueTask> GetChannelSDKAsync(LaunchScheme scheme, CancellationToken token = default) + { + string url = scheme.IsOversea + ? ApiOsEndpoints.SgHoyoPlayConnectGameChannelSDKs(scheme) + : ApiEndpoints.HoyoPlayConnectGameChannelSDKs(scheme); + + HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create() + .SetRequestUri(url) + .Get(); + + Response? resp = await builder + .SendAsync>(httpClient, logger, token) + .ConfigureAwait(false); + + return Response.Response.DefaultIfNull(resp); + } + + public async ValueTask> GetDeprecatedFileConfigurationsAsync(LaunchScheme scheme, CancellationToken token = default) + { + string url = scheme.IsOversea + ? ApiOsEndpoints.SgHoyoPlayConnectDeprecatedFileConfigs(scheme) + : ApiEndpoints.HoyoPlayConnectDeprecatedFileConfigs(scheme); + + HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create() + .SetRequestUri(url) + .Get(); + + Response? resp = await builder + .SendAsync>(httpClient, logger, token) + .ConfigureAwait(false); + + return Response.Response.DefaultIfNull(resp); + } +} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Package/AudioPackageSegment.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Package/AudioPackageSegment.cs new file mode 100644 index 00000000..451a7dcd --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Package/AudioPackageSegment.cs @@ -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 AudioPackageSegment : PackageSegment +{ + [JsonPropertyName("language")] + public string Language { get; set; } = default!; +} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Package/GameBranch.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Package/GameBranch.cs new file mode 100644 index 00000000..0e20f404 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Package/GameBranch.cs @@ -0,0 +1,13 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.Package; + +internal sealed class GameBranch +{ + [JsonPropertyName("major")] + public Package Major { get; set; } = default!; + + [JsonPropertyName("patches")] + public List Patches { get; set; } = default!; +} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Package/GamePackage.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Package/GamePackage.cs new file mode 100644 index 00000000..b93ff9e3 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Package/GamePackage.cs @@ -0,0 +1,13 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.Package; + +internal sealed class GamePackage : GameIndexedObject +{ + [JsonPropertyName("main")] + public GameBranch Main { get; set; } = default!; + + [JsonPropertyName("pre_download")] + public GameBranch PreDownload { get; set; } = default!; +} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Package/GamePackagesWrapper.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Package/GamePackagesWrapper.cs new file mode 100644 index 00000000..ae74e060 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Package/GamePackagesWrapper.cs @@ -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 GamePackagesWrapper +{ + [JsonPropertyName("game_packages")] + public List GamePackages { get; set; } = default!; +} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Package/Package.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Package/Package.cs new file mode 100644 index 00000000..7556587f --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/Package/Package.cs @@ -0,0 +1,25 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +namespace Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect.Package; + +internal sealed class Package +{ + [JsonPropertyName("version")] + public string Version { get; set; } = default!; + + [JsonPropertyName("game_pkgs")] + public List GamePackages { get; set; } = default!; + + [JsonPropertyName("audio_pkgs")] + public List AudioPackages { get; set; } = default!; + + [JsonPropertyName("res_list_url")] + public string ResourceListUrl { get; set; } = default!; + + [JsonIgnore] + public List AllPackages + { + get => [.. GamePackages, .. AudioPackages]; + } +} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/PathMd5.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/PackageSegment.cs similarity index 54% rename from src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/PathMd5.cs rename to src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/PackageSegment.cs index 1c355f28..c9499532 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/PathMd5.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/HoyoPlay/Connect/PackageSegment.cs @@ -4,36 +4,30 @@ using Snap.Hutao.Core.IO.DataTransfer; using Snap.Hutao.Service.Notification; -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource; +namespace Snap.Hutao.Web.Hoyolab.HoyoPlay.Connect; -/// -/// 下载的文件 -/// -[HighQuality] -internal partial class PathMd5 +internal partial class PackageSegment { - /// - /// 下载地址 - /// - [JsonPropertyName("path")] - public string Path { get; set; } = default!; + [JsonPropertyName("url")] + public string Url { get; set; } = default!; - /// - /// MD5校验 - /// [JsonPropertyName("md5")] - public string Md5 { get; set; } = default!; + public string MD5 { get; set; } = default!; - /// - /// 显示名称 - /// - public string DisplayName { get => System.IO.Path.GetFileName(Path); } + [JsonPropertyName("size")] + public long Size { get; set; } = default!; + + [JsonPropertyName("decompressed_size")] + 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().SetText(Path); + serviceProvider.GetRequiredService().SetText(Url); serviceProvider.GetRequiredService().Success(SH.WebGameResourcePathCopySucceed); } } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/Advertisement.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/Advertisement.cs deleted file mode 100644 index e71f6d41..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/Advertisement.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Content; - -internal sealed class Advertisement -{ - [JsonPropertyName("background")] - public string Background { get; set; } = default!; - - [JsonPropertyName("icon")] - public string Icon { get; set; } = default!; - - [JsonPropertyName("url")] - public string Url { get; set; } = default!; - - [JsonPropertyName("version")] - public string Version { get; set; } = default!; - - [JsonPropertyName("bg_checksum")] - public string BackgroundChecksum { get; set; } = default!; -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/Banner.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/Banner.cs deleted file mode 100644 index 08fc5bd8..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/Banner.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Content; - -internal sealed class Banner -{ - [JsonPropertyName("banner_id")] - public string BannerId { get; set; } = default!; - - [JsonPropertyName("name")] - public string Name { get; set; } = default!; - - [JsonPropertyName("img")] - public string Image { get; set; } = default!; - - [JsonPropertyName("url")] - public string Url { get; set; } = default!; - - [JsonPropertyName("order")] - public string Order { get; set; } = default!; -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/GameContent.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/GameContent.cs deleted file mode 100644 index 5138eb54..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/GameContent.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Content; - -internal sealed class GameContent -{ - [JsonPropertyName("adv")] - public Advertisement? Advertisement { get; set; } = default!; - - [JsonPropertyName("banner")] - public List Banners { get; set; } = default!; - - [JsonPropertyName("icon")] - public List Icons { get; set; } = default!; - - [JsonPropertyName("post")] - public List Posts { get; set; } = default!; - - [JsonPropertyName("qq")] - public List QQs { get; set; } = default!; - - [JsonPropertyName("more")] - public More More { get; set; } = default!; - - [JsonPropertyName("links")] - public Link Links { get; set; } = default!; -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/Icon.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/Icon.cs deleted file mode 100644 index 6d3378c5..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/Icon.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Content; - -internal sealed class Icon -{ - [JsonPropertyName("icon_id")] - public string IconId { get; set; } = default!; - - [JsonPropertyName("img")] - public string Image { get; set; } = default!; - - [JsonPropertyName("url")] - public string Url { get; set; } = default!; - - [JsonPropertyName("qr_img")] - public string QrImage { get; set; } = default!; - - [JsonPropertyName("qr_desc")] - public string QrDescription { get; set; } = default!; - - [JsonPropertyName("img_hover")] - public string ImageHover { get; set; } = default!; - - [JsonPropertyName("other_links")] - public List OtherLinks { get; set; } = default!; - - [JsonPropertyName("title")] - public string Title { get; set; } = default!; - - [JsonPropertyName("icon_link")] - public string IconLink { get; set; } = default!; - - [JsonPropertyName("links")] - public List Links { get; set; } = default!; - - [JsonPropertyName("enable_red_dot")] - public bool EnableRedDot { get; set; } - - [JsonPropertyName("red_dot_content")] - public string RedDotContent { get; set; } = default!; -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/IconLink.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/IconLink.cs deleted file mode 100644 index 3541817d..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/IconLink.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher; - -internal sealed class IconLink -{ - [JsonPropertyName("title")] - public string Title { get; set; } = default!; - - [JsonPropertyName("url")] - public string Url { get; set; } = default!; -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/Link.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/Link.cs deleted file mode 100644 index f2569131..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/Link.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Content; - -internal sealed class Link -{ - [JsonPropertyName("faq")] - public string FAQ { get; set; } = default!; - - [JsonPropertyName("version")] - public string Version { get; set; } = default!; -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/More.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/More.cs deleted file mode 100644 index 89c60cda..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/More.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Content; - -internal sealed class More -{ - [JsonPropertyName("activity_link")] - public string ActivityLink { get; set; } = default!; - - [JsonPropertyName("announce_link")] - public string AnnounceLink { get; set; } = default!; - - [JsonPropertyName("info_link")] - public string InfoLink { get; set; } = default!; - - [JsonPropertyName("news_link")] - public string NewsLink { get; set; } = default!; - - [JsonPropertyName("trends_link")] - public string TrendsLink { get; set; } = default!; - - [JsonPropertyName("supply_link")] - public string SupplyLink { get; set; } = default!; - - [JsonPropertyName("tools_link")] - public string ToolsLink { get; set; } = default!; -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/Post.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/Post.cs deleted file mode 100644 index b3de80e6..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/Post.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Content; - -internal sealed class Post -{ - [JsonPropertyName("post_id")] - public string PostId { get; set; } = default!; - - /// - /// POST_TYPE_ACTIVITY|POST_TYPE_ANNOUNCE|POST_TYPE_INFO - /// - [JsonPropertyName("type")] - public string Type { get; set; } = default!; - - [JsonPropertyName("url")] - public string Url { get; set; } = default!; - - /// - /// MM/dd format - /// - [JsonPropertyName("show_time")] - public string ShowTime { get; set; } = default!; - - [JsonPropertyName("order")] - public string Order { get; set; } = default!; - - [JsonPropertyName("title")] - public string Title { get; set; } = default!; -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/QQ.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/QQ.cs deleted file mode 100644 index 61af5e28..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Content/QQ.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Content; - -internal sealed class QQ -{ - [JsonPropertyName("qq_id")] - public string QQId { get; set; } = default!; - - [JsonPropertyName("name")] - public string Name { get; set; } = default!; - - [JsonPropertyName("number")] - public string Number { get; set; } = default!; - - [JsonPropertyName("code")] - public string Code { get; set; } = default!; -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/DiffPackage.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/DiffPackage.cs deleted file mode 100644 index 7e1e5624..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/DiffPackage.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource; - -/// -/// 差异文件 -/// -[HighQuality] -internal sealed class DiffPackage : Package -{ - /// - /// 是否为推荐更新 - /// - [JsonPropertyName("is_recommended_update")] - public bool IsRecommendedUpdate { get; set; } -} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/Game.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/Game.cs deleted file mode 100644 index 678cf2c8..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/Game.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource; - -/// -/// 游戏 -/// -[HighQuality] -internal sealed class Game -{ - /// - /// 最新客户端 - /// - [JsonPropertyName("latest")] - public LatestPackage Latest { get; set; } = default!; - - /// - /// 相对于当前版本的之前版本的差异文件(非预下载) - /// - [JsonPropertyName("diffs")] - public List Diffs { get; set; } = default!; -} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/GameResource.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/GameResource.cs deleted file mode 100644 index 36bcae0f..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/GameResource.cs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource; - -/// -/// 游戏资源 -/// -[HighQuality] -internal sealed class GameResource -{ - /// - /// 本体 - /// - [JsonPropertyName("game")] - public Game Game { get; set; } = default!; - - /// - /// 插件 - /// - [JsonPropertyName("plugin")] - public Plugin Plugin { get; set; } = default!; - - /// - /// 官网地址 https://ys.mihoyo.com/launcher - /// - [JsonPropertyName("web_url")] - public Uri WebUrl { get; set; } = default!; - - /// - /// 强制更新文件 null - /// - [JsonPropertyName("force_update")] - public object? ForceUpdate { get; set; } - - /// - /// 预下载 - /// - [JsonPropertyName("pre_download_game")] - public Game? PreDownloadGame { get; set; } - - /// - /// 过期更新包 - /// - [JsonPropertyName("deprecated_packages")] - public List DeprecatedPackages { get; set; } = default!; - - /// - /// 渠道服 sdk - /// - [JsonPropertyName("sdk")] - public Sdk? Sdk { get; set; } - - /// - /// 过期的单个文件 - /// - [JsonPropertyName("deprecated_files")] - public List? DeprecatedFiles { get; set; } -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/LatestPackage.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/LatestPackage.cs deleted file mode 100644 index f07250ff..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/LatestPackage.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource; - -internal sealed class LatestPackage : Package -{ - [JsonPropertyName("segments")] - public List Segments { get; set; } = default!; - - public new string DisplayName { get => Name; } -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/LatestPackageExtension.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/LatestPackageExtension.cs deleted file mode 100644 index e28ba674..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/LatestPackageExtension.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -using System.IO; -using System.Text; - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource; - -internal static class LatestPackageExtension -{ - public static void Patch(this LatestPackage latest) - { - StringBuilder pathBuilder = new(); - foreach (PackageSegment segment in latest.Segments) - { - pathBuilder.AppendLine(segment.Path); - } - - latest.Path = pathBuilder.ToStringTrimEndReturn(); - latest.Name = Path.GetFileName(latest.Segments[0].Path[..^4]); // .00X - } -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/NameMd5.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/NameMd5.cs deleted file mode 100644 index e31202c0..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/NameMd5.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource; - -/// -/// 资源文件 -/// -[HighQuality] -internal class NameMd5 -{ - /// - /// 文件名称 - /// 相对于 EXE 的路径,如 YuanShen_Data/Plugins/PCGameSDK.dll - /// - [JsonPropertyName("name")] - public string Name { get; set; } = default!; - - /// - /// Md5 校验值 - /// - [JsonPropertyName("md5")] - public string Md5 { get; set; } = default!; -} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/Package.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/Package.cs deleted file mode 100644 index 722f9c05..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/Package.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource; - -/// -/// 最新客户端 -/// -[HighQuality] -internal class Package : PathMd5 -{ - /// - /// 名称 空 - /// - [JsonPropertyName("name")] - public string Name { get; set; } = default!; - - /// - /// 版本 - /// - [JsonPropertyName("version")] - public string Version { get; set; } = default!; - - /// - /// 尺寸 - /// - [JsonPropertyName("size")] - public long Size { get; set; } = default!; - - /// - /// 主程序相对路径 YuanShen.exe - /// - public string Entry { get; set; } = default!; - - /// - /// 语音包 - /// - [JsonPropertyName("voice_packs")] - public List VoicePacks { get; set; } = default!; - - /// - /// 松散文件 - /// 用于校验完整性 - /// - [JsonPropertyName("decompressed_path")] - public string DecompressedPath { get; set; } = default!; - - /// - /// 包大小 bytes - /// - [JsonPropertyName("package_size")] - public long PackageSize { get; set; } = default!; -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/PackageSegment.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/PackageSegment.cs deleted file mode 100644 index 9b8a59fc..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/PackageSegment.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource; - -internal sealed class PackageSegment : PathMd5 -{ - [JsonPropertyName("package_size")] - [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)] - public long PackageSize { get; set; } = default!; -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/Plugin.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/Plugin.cs deleted file mode 100644 index b55f3741..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/Plugin.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource; - -/// -/// 插件 -/// -[HighQuality] -internal sealed class Plugin -{ - /// - /// 插件列表 - /// - [JsonPropertyName("plugins")] - public List Plugins { get; set; } = default!; - - /// - /// 一般为 1 - /// - [JsonPropertyName("version")] - public string Version { get; set; } = default!; -} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/PluginItem.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/PluginItem.cs deleted file mode 100644 index 2f757786..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/PluginItem.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource; - -/// -/// 插件项 -/// -[HighQuality] -internal sealed class PluginItem : NameMd5 -{ - /// - /// 版本 一般为空 - /// - [JsonPropertyName("version")] - public string Version { get; set; } = default!; - - /// - /// 下载地址 - /// - [JsonPropertyName("path")] - public Uri Path { get; set; } = default!; - - /// - /// 尺寸 - /// - [JsonPropertyName("size")] - public long Size { get; set; } = default!; - - /// - /// 一般为空 - /// - [JsonPropertyName("entry")] - public string Entry { get; set; } = default!; -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/Sdk.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/Sdk.cs deleted file mode 100644 index 447dd279..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/Sdk.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource; - -/// -/// Sdk -/// -[HighQuality] -internal sealed class Sdk : PathMd5 -{ - /// - /// 版本 - /// - [JsonPropertyName("version")] - public string Version { get; set; } = default!; - - /// - /// 常量 sdk_pkg_version - /// - [JsonPropertyName("pkg_version")] - public string PackageVersion { get; set; } = default!; - - /// - /// 描述 - /// - [JsonPropertyName("desc")] - public string Description { get; set; } = default!; -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/VoicePackage.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/VoicePackage.cs deleted file mode 100644 index 7a71c6e8..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/Resource/VoicePackage.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource; - -/// -/// 语音包 -/// -[HighQuality] -internal sealed class VoicePackage : PathMd5 -{ - /// - /// 语音 - /// - [JsonPropertyName("language")] - public string Language { get; set; } = default!; - - /// - /// 名称 一般为空 - /// - [JsonPropertyName("name")] - public string Name { get; set; } = default!; - - /// - /// 解压尺寸 - /// - [JsonPropertyName("size")] - public long Size { get; set; } - - /// - /// 包尺寸 - /// - [JsonPropertyName("package_size")] - public long PackageSize { get; set; } = default!; -} diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/ResourceClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/ResourceClient.cs deleted file mode 100644 index d2001da0..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/SdkStatic/Hk4e/Launcher/ResourceClient.cs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient; -using Snap.Hutao.Service.Game.Scheme; -using Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Content; -using Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Resource; -using Snap.Hutao.Web.Request.Builder; -using Snap.Hutao.Web.Request.Builder.Abstraction; -using Snap.Hutao.Web.Response; -using System.Net.Http; - -namespace Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher; - -/// -/// 游戏资源客户端 -/// -[HighQuality] -[ConstructorGenerated(ResolveHttpClient = true)] -[HttpClient(HttpClientConfiguration.Default)] -internal sealed partial class ResourceClient -{ - private readonly IHttpRequestMessageBuilderFactory httpRequestMessageBuilderFactory; - private readonly HttpClient httpClient; - private readonly ILogger logger; - - /// - /// 异步获取游戏资源 - /// - /// 方案 - /// 取消令牌 - /// 游戏资源 - public async ValueTask> GetResourceAsync(LaunchScheme scheme, CancellationToken token = default) - { - string url = scheme.IsOversea - ? ApiOsEndpoints.SdkOsStaticLauncherResource(scheme) - : ApiEndpoints.SdkStaticLauncherResource(scheme); - - HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create() - .SetRequestUri(url) - .Get(); - - Response? resp = await builder - .SendAsync>(httpClient, logger, token) - .ConfigureAwait(false); - - // 最新版完整包 - if (resp is { Data.Game.Latest: LatestPackage latest }) - { - latest.Patch(); - } - - // 预下载完整包 - if (resp is { Data.PreDownloadGame.Latest: LatestPackage preDownloadLatest }) - { - preDownloadLatest.Patch(); - } - - return Response.Response.DefaultIfNull(resp); - } - - public async ValueTask> GetContentAsync(LaunchScheme scheme, string languageCode, bool advOnly = true, CancellationToken token = default) - { - string url = scheme.IsOversea - ? ApiOsEndpoints.SdkOsStaticLauncherContent(scheme, languageCode, advOnly) - : ApiEndpoints.SdkStaticLauncherContent(scheme, languageCode, advOnly); - - HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create() - .SetRequestUri(url) - .Get(); - - Response? resp = await builder - .SendAsync>(httpClient, logger, token) - .ConfigureAwait(false); - - return Response.Response.DefaultIfNull(resp); - } -} \ No newline at end of file