pre-check filesystem permission before convert

This commit is contained in:
Lightczx
2023-12-05 10:58:41 +08:00
parent 57e8bc8bdf
commit 2679a68785
5 changed files with 42 additions and 37 deletions

View File

@@ -22,6 +22,7 @@ internal sealed partial class ScopedPageScopeReferenceTracker : IScopedPageScope
public IServiceScope CreateScope()
{
GC.Collect(GC.MaxGeneration, GCCollectionMode.Aggressive, true);
IServiceScope currentScope = serviceProvider.CreateScope();
// In case previous one is not disposed.

View File

@@ -863,6 +863,9 @@
<data name="ServiceGameDetectGameAccountMultiMatched" xml:space="preserve">
<value>存在多个匹配账号,请删除重复的账号</value>
</data>
<data name="ServiceGameEnsureGameResourceInsufficientDirectoryPermissions" xml:space="preserve">
<value>文件系统权限不足,无法转换服务器</value>
</data>
<data name="ServiceGameEnsureGameResourceQueryResourceInformation" xml:space="preserve">
<value>查询游戏资源信息</value>
</data>

View File

@@ -1,21 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
namespace Snap.Hutao.Service.Game.Package;
/// <summary>
/// 转换方向
/// </summary>
[HighQuality]
internal enum ConvertDirection
{
/// <summary>
/// 国际服转国服
/// </summary>
OverseaToChinese,
/// <summary>
/// 国服转国际服
/// </summary>
ChineseToOversea,
}

View File

@@ -1,6 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Microsoft.Win32.SafeHandles;
using Snap.Hutao.Service.Game.Scheme;
using Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher;
using Snap.Hutao.Web.Response;
@@ -25,6 +26,12 @@ internal sealed partial class GamePackageService : IGamePackageService
return false;
}
if (!CheckDirectoryPermissions(gameFolder))
{
progress.Report(new(SH.ServiceGameEnsureGameResourceInsufficientDirectoryPermissions));
return false;
}
progress.Report(new(SH.ServiceGameEnsureGameResourceQueryResourceInformation));
Response<GameResource> response = await serviceProvider
.GetRequiredService<ResourceClient>()
@@ -57,4 +64,33 @@ internal sealed partial class GamePackageService : IGamePackageService
await packageConverter.EnsureDeprecatedFilesAndSdkAsync(resource, gameFolder).ConfigureAwait(false);
return true;
}
private static bool CheckDirectoryPermissions(string folder)
{
try
{
string tempFilePath = Path.Combine(folder, $"{Guid.NewGuid():N}.tmp");
string tempFilePathMove = Path.Combine(folder, $"{Guid.NewGuid():N}.tmp");
// Test create file
using (SafeFileHandle handle = File.OpenHandle(tempFilePath, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None, preallocationSize: 32 * 1024))
{
// Test write file
RandomAccess.Write(handle, "SNAP HUTAO DIRECTORY PERMISSION CHECK"u8, 0);
RandomAccess.FlushToDisk(handle);
}
// Test move file
File.Move(tempFilePath, tempFilePathMove);
// Test delete file
File.Delete(tempFilePathMove);
return true;
}
catch (Exception)
{
return false;
}
}
}

View File

@@ -96,21 +96,7 @@ internal sealed partial class PackageConverter
{
using (Stream sdkWebStream = await httpClient.GetStreamAsync(resource.Sdk.Path).ConfigureAwait(false))
{
using (ZipArchive zip = new(sdkWebStream))
{
foreach (ZipArchiveEntry entry in zip.Entries)
{
// skip folder entry.
if (entry.Length != 0)
{
string targetPath = Path.Combine(gameFolder, entry.FullName);
string? directory = Path.GetDirectoryName(targetPath);
ArgumentException.ThrowIfNullOrEmpty(directory);
Directory.CreateDirectory(directory);
entry.ExtractToFile(targetPath, true);
}
}
}
ZipFile.ExtractToDirectory(sdkWebStream, gameFolder, true);
}
}
}
@@ -342,7 +328,7 @@ internal sealed partial class PackageConverter
{
string versionFileName = Path.GetFileName(versionFilePath);
if (versionFileName == "sdk_pkg_version")
if (string.Equals(versionFileName, "sdk_pkg_version", StringComparison.OrdinalIgnoreCase))
{
// Skipping the sdk_pkg_version file,
// it can't be claimed from remote.