mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
fix convert cache
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
<Identity
|
||||
Name="7f0db578-026f-4e0b-a75b-d5d06bb0a74d"
|
||||
Publisher="CN=DGP Studio&comma DissmissedLight"
|
||||
Version="1.3.13.0" />
|
||||
Version="1.4.0.0" />
|
||||
|
||||
<Properties>
|
||||
<DisplayName>胡桃</DisplayName>
|
||||
|
||||
35
src/Snap.Hutao/Snap.Hutao/Service/Game/GameConstants.cs
Normal file
35
src/Snap.Hutao/Snap.Hutao/Service/Game/GameConstants.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Service.Game;
|
||||
|
||||
/// <summary>
|
||||
/// 游戏常量
|
||||
/// </summary>
|
||||
internal static class GameConstants
|
||||
{
|
||||
/// <summary>
|
||||
/// 设置文件
|
||||
/// </summary>
|
||||
public const string ConfigFileName = "config.ini";
|
||||
|
||||
/// <summary>
|
||||
/// 国服文件名
|
||||
/// </summary>
|
||||
public const string YuanShenFileName = "YuanShen.exe";
|
||||
|
||||
/// <summary>
|
||||
/// 外服文件名
|
||||
/// </summary>
|
||||
public const string GenshinImpactFileName = "GenshinImpact.exe";
|
||||
|
||||
/// <summary>
|
||||
/// 国服数据文件夹
|
||||
/// </summary>
|
||||
public const string YuanShenData = "YuanShen_Data";
|
||||
|
||||
/// <summary>
|
||||
/// 国际服数据文件夹
|
||||
/// </summary>
|
||||
public const string GenshinImpactData = "GenshinImpact_Data";
|
||||
}
|
||||
@@ -20,6 +20,7 @@ using Snap.Hutao.Web.Response;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using static Snap.Hutao.Service.Game.GameConstants;
|
||||
|
||||
namespace Snap.Hutao.Service.Game;
|
||||
|
||||
@@ -31,7 +32,6 @@ namespace Snap.Hutao.Service.Game;
|
||||
internal class GameService : IGameService
|
||||
{
|
||||
private const string GamePathKey = $"{nameof(GameService)}.Cache.{SettingEntry.GamePath}";
|
||||
private const string ConfigFile = "config.ini";
|
||||
|
||||
private readonly IServiceScopeFactory scopeFactory;
|
||||
private readonly IMemoryCache memoryCache;
|
||||
@@ -148,7 +148,7 @@ internal class GameService : IGameService
|
||||
public MultiChannel GetMultiChannel()
|
||||
{
|
||||
string gamePath = GetGamePathSkipLocator();
|
||||
string configPath = Path.Combine(Path.GetDirectoryName(gamePath) ?? string.Empty, ConfigFile);
|
||||
string configPath = Path.Combine(Path.GetDirectoryName(gamePath) ?? string.Empty, ConfigFileName);
|
||||
|
||||
if (!File.Exists(configPath))
|
||||
{
|
||||
@@ -169,7 +169,7 @@ internal class GameService : IGameService
|
||||
public bool SetMultiChannel(LaunchScheme scheme)
|
||||
{
|
||||
string gamePath = GetGamePathSkipLocator();
|
||||
string configPath = Path.Combine(Path.GetDirectoryName(gamePath)!, ConfigFile);
|
||||
string configPath = Path.Combine(Path.GetDirectoryName(gamePath)!, ConfigFileName);
|
||||
|
||||
List<IniElement> elements;
|
||||
try
|
||||
@@ -226,28 +226,39 @@ internal class GameService : IGameService
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<bool> ReplaceGameResourceAsync(LaunchScheme launchScheme, IProgress<PackageReplaceStatus> progress)
|
||||
public async Task<bool> EnsureGameResourceAsync(LaunchScheme launchScheme, IProgress<PackageReplaceStatus> progress)
|
||||
{
|
||||
string gamePath = GetGamePathSkipLocator();
|
||||
string gameFolder = Path.GetDirectoryName(gamePath)!;
|
||||
string gameFileName = Path.GetFileName(gamePath);
|
||||
|
||||
if (launchScheme.IsOversea && gameFileName == "GenshinImpact.exe")
|
||||
progress.Report(new("查询游戏资源信息"));
|
||||
Response<GameResource> response = await Ioc.Default
|
||||
.GetRequiredService<ResourceClient>()
|
||||
.GetResourceAsync(launchScheme)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (response.IsOk())
|
||||
{
|
||||
// Already that scheme, no need to replace files
|
||||
return true;
|
||||
}
|
||||
else if (!launchScheme.IsOversea && gameFileName == "YuanShen.exe")
|
||||
{
|
||||
// Already that scheme, no need to replace files
|
||||
GameResource resource = response.Data;
|
||||
|
||||
if (!LaunchSchemeMatchesExecutable(launchScheme, gameFileName))
|
||||
{
|
||||
await packageConverter.EnsureGameResourceAsync(launchScheme, resource, gameFolder, progress).ConfigureAwait(false);
|
||||
|
||||
// We need to change the gamePath if we switched.
|
||||
OverwriteGamePath(Path.Combine(gameFolder, launchScheme.IsOversea ? GenshinImpactFileName : YuanShenFileName));
|
||||
}
|
||||
|
||||
if (!launchScheme.IsOversea)
|
||||
{
|
||||
await packageConverter.EnsureDeprecatedFilesAndSdkAsync(resource, gameFolder).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: we still need to handle the Bilibili scheme.
|
||||
await packageConverter.ReplaceGameResourceAsync(launchScheme, gameFolder, progress).ConfigureAwait(false);
|
||||
// We need to change the gamePath if we switch.
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -258,19 +269,19 @@ internal class GameService : IGameService
|
||||
return true;
|
||||
}
|
||||
|
||||
return Process.GetProcessesByName("YuanShen.exe").Any()
|
||||
|| Process.GetProcessesByName("GenshinImpact.exe").Any();
|
||||
return Process.GetProcessesByName(YuanShenFileName).Any()
|
||||
|| Process.GetProcessesByName(GenshinImpactFileName).Any();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<ObservableCollection<GameAccount>> GetGameAccountCollectionAsync()
|
||||
{
|
||||
await ThreadHelper.SwitchToMainThreadAsync();
|
||||
if (gameAccounts == null)
|
||||
{
|
||||
using (IServiceScope scope = scopeFactory.CreateScope())
|
||||
{
|
||||
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||
await ThreadHelper.SwitchToMainThreadAsync();
|
||||
gameAccounts = appDbContext.GameAccounts.AsNoTracking().ToObservableCollection();
|
||||
}
|
||||
}
|
||||
@@ -431,4 +442,10 @@ internal class GameService : IGameService
|
||||
await scope.ServiceProvider.GetRequiredService<AppDbContext>().GameAccounts.RemoveAndSaveAsync(gameAccount).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool LaunchSchemeMatchesExecutable(LaunchScheme launchScheme, string gameFileName)
|
||||
{
|
||||
return (launchScheme.IsOversea && gameFileName == GenshinImpactFileName)
|
||||
|| (!launchScheme.IsOversea && gameFileName == YuanShenFileName);
|
||||
}
|
||||
}
|
||||
@@ -90,7 +90,7 @@ internal interface IGameService
|
||||
/// <param name="launchScheme">目标启动方案</param>
|
||||
/// <param name="progress">进度</param>
|
||||
/// <returns>是否替换成功</returns>
|
||||
Task<bool> ReplaceGameResourceAsync(LaunchScheme launchScheme, IProgress<PackageReplaceStatus> progress);
|
||||
Task<bool> EnsureGameResourceAsync(LaunchScheme launchScheme, IProgress<PackageReplaceStatus> progress);
|
||||
|
||||
/// <summary>
|
||||
/// 修改注册表中的账号信息
|
||||
|
||||
@@ -21,7 +21,7 @@ internal class ItemOperationInfo
|
||||
{
|
||||
Type = type;
|
||||
Target = target.RemoteName;
|
||||
Cache = cache.RemoteName;
|
||||
MoveTo = cache.RemoteName;
|
||||
Md5 = target.Md5;
|
||||
TotalBytes = target.FileSize;
|
||||
}
|
||||
@@ -39,7 +39,7 @@ internal class ItemOperationInfo
|
||||
/// <summary>
|
||||
/// 移动至中时的名称
|
||||
/// </summary>
|
||||
public string Cache { get; set; }
|
||||
public string MoveTo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件的目标Md5
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Core.IO;
|
||||
using Snap.Hutao.Extension;
|
||||
using Snap.Hutao.Model.Binding.LaunchGame;
|
||||
using Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher;
|
||||
using Snap.Hutao.Web.Response;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Net.Http;
|
||||
using static Snap.Hutao.Service.Game.GameConstants;
|
||||
|
||||
namespace Snap.Hutao.Service.Game.Package;
|
||||
|
||||
@@ -17,9 +20,6 @@ namespace Snap.Hutao.Service.Game.Package;
|
||||
[HttpClient(HttpClientConfigration.Default)]
|
||||
internal class PackageConverter
|
||||
{
|
||||
private const string GenshinImpactData = "GenshinImpact_Data";
|
||||
private const string YuanShenData = "YuanShen_Data";
|
||||
|
||||
private readonly ResourceClient resourceClient;
|
||||
private readonly JsonSerializerOptions options;
|
||||
private readonly HttpClient httpClient;
|
||||
@@ -38,47 +38,102 @@ internal class PackageConverter
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步替换游戏资源
|
||||
/// 异步检查替换游戏资源
|
||||
/// 调用前需要确认本地文件与服务器上的不同
|
||||
/// </summary>
|
||||
/// <param name="targetScheme">目标启动方案</param>
|
||||
/// <param name="gameResouce">游戏资源</param>
|
||||
/// <param name="gameFolder">游戏目录</param>
|
||||
/// <param name="progress">进度</param>
|
||||
/// <returns>任务</returns>
|
||||
public async Task<bool> ReplaceGameResourceAsync(LaunchScheme targetScheme, string gameFolder, IProgress<PackageReplaceStatus> progress)
|
||||
/// <returns>替换结果与资源</returns>
|
||||
public async Task EnsureGameResourceAsync(LaunchScheme targetScheme, GameResource gameResouce, string gameFolder, IProgress<PackageReplaceStatus> progress)
|
||||
{
|
||||
await ThreadHelper.SwitchToBackgroundAsync();
|
||||
progress.Report(new("查询游戏资源信息"));
|
||||
Response<GameResource> response = await resourceClient.GetResourceAsync(targetScheme).ConfigureAwait(false);
|
||||
string scatteredFilesUrl = gameResouce.Game.Latest.DecompressedPath;
|
||||
Uri pkgVersionUri = new($"{scatteredFilesUrl}/pkg_version");
|
||||
ConvertDirection direction = targetScheme.IsOversea ? ConvertDirection.ChineseToOversea : ConvertDirection.OverseaToChinese;
|
||||
|
||||
if (response.IsOk())
|
||||
progress.Report(new("下载包版本信息"));
|
||||
Dictionary<string, VersionItem> remoteItems;
|
||||
using (Stream remoteSteam = await httpClient.GetStreamAsync(pkgVersionUri).ConfigureAwait(false))
|
||||
{
|
||||
GameResource remoteGameResouce = response.Data;
|
||||
|
||||
string scatteredFilesUrl = remoteGameResouce.Game.Latest.DecompressedPath;
|
||||
Uri pkgVersionUri = new($"{scatteredFilesUrl}/pkg_version");
|
||||
ConvertDirection direction = targetScheme.IsOversea ? ConvertDirection.ChineseToOversea : ConvertDirection.OverseaToChinese;
|
||||
|
||||
progress.Report(new("下载包版本信息"));
|
||||
Dictionary<string, VersionItem> remoteItems;
|
||||
using (Stream remoteSteam = await httpClient.GetStreamAsync(pkgVersionUri).ConfigureAwait(false))
|
||||
{
|
||||
remoteItems = await GetVersionItemsAsync(remoteSteam).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
Dictionary<string, VersionItem> localItems;
|
||||
using (FileStream localSteam = File.OpenRead(Path.Combine(gameFolder, "pkg_version")))
|
||||
{
|
||||
localItems = await GetVersionItemsAsync(localSteam, direction, ConvertRemoteName).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
IEnumerable<ItemOperationInfo> diffOperations = GetItemOperationInfos(remoteItems, localItems);
|
||||
var a = diffOperations.ToList();
|
||||
await ReplaceGameResourceCoreAsync(diffOperations, gameFolder, scatteredFilesUrl, direction, progress).ConfigureAwait(false);
|
||||
return true;
|
||||
remoteItems = await GetVersionItemsAsync(remoteSteam).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return false;
|
||||
Dictionary<string, VersionItem> localItems;
|
||||
using (FileStream localSteam = File.OpenRead(Path.Combine(gameFolder, "pkg_version")))
|
||||
{
|
||||
localItems = await GetVersionItemsAsync(localSteam, direction, ConvertRemoteName).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
IEnumerable<ItemOperationInfo> diffOperations = GetItemOperationInfos(remoteItems, localItems);
|
||||
await ReplaceGameResourceAsync(diffOperations, gameFolder, scatteredFilesUrl, direction, progress).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查过时文件与Sdk
|
||||
/// </summary>
|
||||
/// <param name="resource">游戏资源</param>
|
||||
/// <param name="gameFolder">游戏文件夹</param>
|
||||
/// <returns>任务</returns>
|
||||
public async Task EnsureDeprecatedFilesAndSdkAsync(GameResource resource, string gameFolder)
|
||||
{
|
||||
if (resource.DeprecatedFiles != null)
|
||||
{
|
||||
foreach (NameMd5 file in resource.DeprecatedFiles)
|
||||
{
|
||||
string filePath = Path.Combine(gameFolder, file.Name);
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
File.Move(filePath, $"{filePath}.backup");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string sdkDllBackup = Path.Combine(gameFolder, YuanShenData, "Plugins\\PCGameSDK.dll.backup");
|
||||
string sdkDll = Path.Combine(gameFolder, YuanShenData, "Plugins\\PCGameSDK.dll");
|
||||
string sdkVersionBackup = Path.Combine(gameFolder, YuanShenData, "sdk_pkg_version.backup");
|
||||
string sdkVersion = Path.Combine(gameFolder, YuanShenData, "sdk_pkg_version");
|
||||
|
||||
// Only bilibili's sdk is not null
|
||||
if (resource.Sdk != null)
|
||||
{
|
||||
if (File.Exists(sdkDllBackup) && File.Exists(sdkVersionBackup))
|
||||
{
|
||||
File.Move(sdkDllBackup, sdkDll, false);
|
||||
File.Move(sdkVersionBackup, sdkVersion, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
using (Stream sdkWebStream = await httpClient.GetStreamAsync(resource.Sdk.Path).ConfigureAwait(false))
|
||||
{
|
||||
using (ZipArchive zip = new(sdkWebStream))
|
||||
{
|
||||
foreach (ZipArchiveEntry entry in zip.Entries)
|
||||
{
|
||||
if (entry.CompressedLength != 0)
|
||||
{
|
||||
string targetPath = Path.Combine(gameFolder, entry.FullName);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(targetPath)!);
|
||||
entry.ExtractToFile(targetPath, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (File.Exists(sdkDll))
|
||||
{
|
||||
File.Move(sdkDll, sdkDllBackup, true);
|
||||
}
|
||||
|
||||
if (File.Exists(sdkVersion))
|
||||
{
|
||||
File.Move(sdkVersion, sdkVersionBackup, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string ConvertRemoteName(string remoteName, ConvertDirection direction)
|
||||
@@ -143,14 +198,13 @@ internal class PackageConverter
|
||||
}
|
||||
}
|
||||
|
||||
private static void MoveToCache(string cacheFolder, string cacheName, string targetFullPath)
|
||||
private static void MoveToCache(string cacheFilePath, string targetFullPath)
|
||||
{
|
||||
string cacheFilePath = Path.Combine(cacheFolder, cacheName);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath)!);
|
||||
File.Move(targetFullPath, cacheFilePath, true);
|
||||
}
|
||||
|
||||
private async Task ReplaceGameResourceCoreAsync(IEnumerable<ItemOperationInfo> operations, string gameFolder, string scatteredFilesUrl, ConvertDirection direction, IProgress<PackageReplaceStatus> progress)
|
||||
private async Task ReplaceGameResourceAsync(IEnumerable<ItemOperationInfo> operations, string gameFolder, string scatteredFilesUrl, ConvertDirection direction, IProgress<PackageReplaceStatus> progress)
|
||||
{
|
||||
// 重命名 _Data 目录
|
||||
RenameDataFolder(gameFolder, direction);
|
||||
@@ -164,7 +218,8 @@ internal class PackageConverter
|
||||
progress.Report(new($"{info.Target}"));
|
||||
|
||||
string targetFilePath = Path.Combine(gameFolder, info.Target);
|
||||
string cacheFilePath = Path.Combine(cacheFolder, info.Cache);
|
||||
string cacheFilePath = Path.Combine(cacheFolder, info.Target);
|
||||
string moveToFilePath = Path.Combine(cacheFolder, info.MoveTo);
|
||||
|
||||
switch (info.Type)
|
||||
{
|
||||
@@ -173,14 +228,14 @@ internal class PackageConverter
|
||||
break;
|
||||
case ItemOperationType.Replace:
|
||||
{
|
||||
MoveToCache(cacheFolder, info.Cache, targetFilePath);
|
||||
MoveToCache(moveToFilePath, targetFilePath);
|
||||
await ReplaceFromCacheOrWebAsync(cacheFilePath, targetFilePath, scatteredFilesUrl, info).ConfigureAwait(false);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ItemOperationType.Remove:
|
||||
MoveToCache(cacheFolder, info.Cache, targetFilePath);
|
||||
MoveToCache(moveToFilePath, targetFilePath);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -223,14 +278,22 @@ internal class PackageConverter
|
||||
|
||||
private async Task ReplacePackageVersionsAsync(string scatteredFilesUrl, string gameFolder)
|
||||
{
|
||||
foreach (string audioPkgVersionFilePath in Directory.EnumerateFiles(gameFolder, "*pkg_version"))
|
||||
foreach (string versionFilePath in Directory.EnumerateFiles(gameFolder, "*pkg_version"))
|
||||
{
|
||||
string audioPkgVersionFileName = Path.GetFileName(audioPkgVersionFilePath);
|
||||
using (FileStream audioPkgVersionFileStream = File.Create(audioPkgVersionFilePath))
|
||||
string versionFileName = Path.GetFileName(versionFilePath);
|
||||
|
||||
if (versionFileName == "sdk_pkg_version")
|
||||
{
|
||||
using (Stream webStream = await httpClient.GetStreamAsync($"{scatteredFilesUrl}/{audioPkgVersionFileName}").ConfigureAwait(false))
|
||||
// Skiping the sdk_pkg_version file,
|
||||
// it can't be claimed from remote.
|
||||
continue;
|
||||
}
|
||||
|
||||
using (FileStream versionFileStream = File.Create(versionFilePath))
|
||||
{
|
||||
using (Stream webStream = await httpClient.GetStreamAsync($"{scatteredFilesUrl}/{versionFileName}").ConfigureAwait(false))
|
||||
{
|
||||
await webStream.CopyToAsync(audioPkgVersionFileStream).ConfigureAwait(false);
|
||||
await webStream.CopyToAsync(versionFileStream).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
|
||||
<PackageCertificateThumbprint>F8C2255969BEA4A681CED102771BF807856AEC02</PackageCertificateThumbprint>
|
||||
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
|
||||
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
|
||||
<AppxAutoIncrementPackageRevision>False</AppxAutoIncrementPackageRevision>
|
||||
<AppxSymbolPackageEnabled>True</AppxSymbolPackageEnabled>
|
||||
<GenerateTestArtifacts>True</GenerateTestArtifacts>
|
||||
<AppxBundle>Never</AppxBundle>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!-- Copyright (c) Microsoft Corporation and Contributors. -->
|
||||
<!-- Copyright (c) Microsoft Corporation and Contributors. -->
|
||||
<!-- Licensed under the MIT License. -->
|
||||
|
||||
<ContentDialog
|
||||
@@ -8,16 +8,16 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:shvd="using:Snap.Hutao.View.Dialog"
|
||||
Title="转换客户端"
|
||||
Title="转换客户端"
|
||||
d:DataContext="{d:DesignInstance shvd:LaunchGamePackageConvertDialog}"
|
||||
Style="{StaticResource DefaultContentDialogStyle}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="转换可能需要花费一段时间"/>
|
||||
<TextBlock Text="转换可能需要花费一段时间,请勿关闭胡桃"/>
|
||||
<TextBlock
|
||||
MinWidth="480"
|
||||
Margin="0,8,0,2"
|
||||
MinWidth="360"
|
||||
Margin="0,8,0,16"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding Description}"/>
|
||||
<ProgressBar IsIndeterminate="True"/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml;
|
||||
@@ -8,14 +8,14 @@ using Snap.Hutao.Control;
|
||||
namespace Snap.Hutao.View.Dialog;
|
||||
|
||||
/// <summary>
|
||||
/// 启动游戏客户端转换对话框
|
||||
/// 启动游戏客户端转换对话框
|
||||
/// </summary>
|
||||
public sealed partial class LaunchGamePackageConvertDialog : ContentDialog
|
||||
{
|
||||
private static readonly DependencyProperty DescriptionProperty = Property<LaunchGamePackageConvertDialog>.Depend(nameof(Description), "请稍候");
|
||||
private static readonly DependencyProperty DescriptionProperty = Property<LaunchGamePackageConvertDialog>.Depend(nameof(Description), "请稍候");
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的启动游戏客户端转换对话框
|
||||
/// 构造一个新的启动游戏客户端转换对话框
|
||||
/// </summary>
|
||||
public LaunchGamePackageConvertDialog()
|
||||
{
|
||||
@@ -25,7 +25,7 @@ public sealed partial class LaunchGamePackageConvertDialog : ContentDialog
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 描述
|
||||
/// 描述
|
||||
/// </summary>
|
||||
public string Description
|
||||
{
|
||||
|
||||
@@ -52,11 +52,23 @@
|
||||
IsOpen="True"
|
||||
Message="所有选项仅会在启动游戏成功后保存"
|
||||
Severity="Informational"/>
|
||||
<InfoBar
|
||||
Margin="0,2,0,0"
|
||||
IsClosable="False"
|
||||
IsOpen="{Binding IsElevated, Converter={StaticResource BoolNegationConverter}}"
|
||||
Message="某些选项处于禁用状态,它们只在管理员模式下生效!"
|
||||
Severity="Warning"/>
|
||||
<wsc:SettingsGroup Margin="0,0,0,0" Header="常规">
|
||||
<InfoBar
|
||||
IsClosable="False"
|
||||
IsOpen="{Binding IsElevated}"
|
||||
Message="切换国际服功能尚处于测试阶段,可能出现未预料的问题,请注意备份游戏资源!"
|
||||
Severity="Error"/>
|
||||
<wsc:Setting
|
||||
Description="切换游戏服务器,B服用户需要自备额外的 PCGameSDK.dll 文件"
|
||||
Description="切换游戏服务器(国服/渠道服/国际服)"
|
||||
Header="服务器"
|
||||
Icon="">
|
||||
Icon=""
|
||||
IsEnabled="{Binding IsElevated}">
|
||||
<wsc:Setting.ActionContent>
|
||||
<ComboBox
|
||||
DisplayMemberPath="DisplayName"
|
||||
@@ -217,11 +229,6 @@
|
||||
</wsc:SettingsGroup>
|
||||
|
||||
<wsc:SettingsGroup Header="高级功能" IsEnabled="{Binding IsElevated}">
|
||||
<InfoBar
|
||||
IsClosable="False"
|
||||
IsOpen="True"
|
||||
Message="需要读写游戏进程或与游戏窗体交互,因此只在管理员模式下生效!"
|
||||
Severity="Warning"/>
|
||||
<wsc:Setting
|
||||
Description="在启动游戏前尝试终止运行中的游戏进程"
|
||||
Header="快速切换账号"
|
||||
@@ -236,7 +243,7 @@
|
||||
</wsc:Setting>
|
||||
<InfoBar
|
||||
IsClosable="False"
|
||||
IsOpen="True"
|
||||
IsOpen="{Binding IsElevated}"
|
||||
Message="下面的功能十分危险,如果您不愿承担因此可能带来的后果,请勿启用!"
|
||||
Severity="Error"/>
|
||||
<wsc:Setting
|
||||
|
||||
@@ -308,7 +308,7 @@ internal class LaunchGameViewModel : Abstraction.ViewModel
|
||||
await using (await dialog.BlockAsync().ConfigureAwait(false))
|
||||
{
|
||||
Progress<Service.Game.Package.PackageReplaceStatus> progress = new(s => dialog.Description = s.Description);
|
||||
await gameService.ReplaceGameResourceAsync(SelectedScheme, progress).ConfigureAwait(false);
|
||||
await gameService.EnsureGameResourceAsync(SelectedScheme, progress).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user