Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
1081ca7
feat&style: 优化游戏版本存储结构并实现可比接口,同时改正了亿些拼错的单词
AMagicPear May 8, 2025
695dfaa
feat: 添加设置视图及相关视图模型
AMagicPear May 8, 2025
37f3856
feat: 添加了Java列表的UI,但是出现了诡异现象
AMagicPear May 8, 2025
767cde3
feat&fix: 更新Java列表的UI,使用更具描述性的字段并优化数据绑定,修复了诡异现象
AMagicPear May 8, 2025
9af5e0d
feat: 把Java显示和手动添加的ViewModel部分做好啦
AMagicPear May 8, 2025
830ea69
fix: 小问题
AMagicPear May 8, 2025
a772cb2
Merge branch 'feature/game' into feature/rename
AMagicPear May 9, 2025
276b975
refactor(MainWindow): use simpler approach for animating left panel
LaoSparrow May 8, 2025
2ac0868
Merge remote-tracking branch 'upstream/main' into feature/game
AMagicPear May 10, 2025
7c8d5c5
fix: 修复分离Core项目后带来的问题
AMagicPear May 10, 2025
533b6b4
fix: 依赖包修正
AMagicPear May 10, 2025
a5a1b9b
Merge branch 'test/LaoSparrow' into feature/frontend-dev
AMagicPear May 11, 2025
4baf429
Merge branch 'main' into feature/frontend-dev
AMagicPear May 11, 2025
aaaa986
style: 开始清理
AMagicPear May 11, 2025
8a93598
Merge branch 'pr/lhx077/82' into feature/game
AMagicPear May 12, 2025
26c69cc
refactor: 使用已有的Java逻辑而非另起炉灶
AMagicPear May 12, 2025
42c9758
Merge branch 'feature/frontend-dev' into feature/game
AMagicPear May 12, 2025
d5d4ee8
optimize: 删删删
AMagicPear May 12, 2025
d5faa58
refactor: 独立DownloadService并随之带来一系列更改
AMagicPear May 12, 2025
64c6b52
fix: 修复错误
AMagicPear May 12, 2025
21ec83c
refactor: 优化导航按钮状态管理
AMagicPear May 12, 2025
c85087e
refactor: 继续优化导航状态管理
AMagicPear May 12, 2025
9f20f86
feat: 自动设置默认的三种版本指向
AMagicPear May 12, 2025
625ab65
fix: 修复不显示默认SubView
AMagicPear May 13, 2025
46de64b
fix: 修复异步加载导致的第一页初始加载不完全的问题
AMagicPear May 13, 2025
15b764c
feat: 部分完成待办更改
AMagicPear May 13, 2025
e45a921
fix: 回退Refresh,不知道为什么会有问题,可能是因为逻辑和UI不在一个线程的问题。
AMagicPear May 13, 2025
0868046
refactor: 重写DefaultJavaRuntimes的get算法,只遍历一次出结果
AMagicPear May 14, 2025
337b962
feat: 添加或刷新后清除 _defaultJavaRuntimes缓存
AMagicPear May 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions PCL.Neo.Core/FileExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using PCL.Neo.Core.Utils;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;

namespace PCL.Neo.Core;

/// <summary>
/// 一些文件操作和下载请求之类的
/// </summary>
public static class FileExtension
{
/// <summary>
/// 校验文件流与SHA-1是否匹配
/// </summary>
/// <param name="fileStream">文件流</param>
/// <param name="sha1">SHA-1</param>
/// <returns>是否匹配</returns>
public static async Task<bool> CheckSha1(this FileStream fileStream, string sha1)
{
using var sha1Provider = System.Security.Cryptography.SHA1.Create();
fileStream.Position = 0; // 重置文件流位置
var computedHash = await sha1Provider.ComputeHashAsync(fileStream);
var computedHashString = Convert.ToHexStringLower(computedHash);
return string.Equals(computedHashString, sha1, StringComparison.OrdinalIgnoreCase);
}

/// <summary>
/// 在 Unix 系统中给予可执行文件运行权限
/// </summary>
/// <param name="path">文件路径</param>
[SupportedOSPlatform(nameof(OSPlatform.OSX))]
[SupportedOSPlatform(nameof(OSPlatform.Linux))]
public static void SetFileExecutableUnix(this string path)
{
if (SystemUtils.Os is SystemUtils.RunningOs.Windows) return;
try
{
var currentMode = File.GetUnixFileMode(path);
var newMode = currentMode | UnixFileMode.UserExecute | UnixFileMode.GroupExecute |
UnixFileMode.OtherExecute;
File.SetUnixFileMode(path, newMode);
}
catch (Exception e)
{
Console.WriteLine($"无法设置可执行权限:{e.Message}");
throw;
}
}

/// <summary>
/// 从某个地方抄来的很像 C 语言风格的解压 LZMA 压缩算法的函数
/// </summary>
/// <param name="inStream">被压缩的文件流</param>
/// <param name="outputFile">输出文件路径</param>
/// <returns>解压后的文件流</returns>
public static FileStream? DecompressLZMA(this FileStream inStream, string outputFile)
{
inStream.Position = 0;
var outStream = new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite);
byte[] decodeProperties = new byte[5];
int n = inStream.Read(decodeProperties, 0, 5);
Debug.Assert(n == 5);
SevenZip.Compression.LZMA.Decoder decoder = new();
decoder.SetDecoderProperties(decodeProperties);
long outSize = 0;
for (int i = 0; i < 8; i++)
{
int v = inStream.ReadByte();
if (v < 0)
{
Console.WriteLine("read outSize error.");
return null;
}

outSize |= (long)(byte)v << (8 * i);
}

long compressedSize = inStream.Length - inStream.Position;
decoder.Code(inStream, outStream, compressedSize, outSize, null);
inStream.Close();
return outStream;
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;

namespace PCL.Neo.Core.Helpers;
namespace PCL.Neo.Core.Models;

/// <summary>
/// 一些文件操作和下载请求之类的
/// 下载任务管理器
/// 之所以不static是因为后续可能需要接入进度显示和下载统计
/// </summary>
public static class FileHelper
public class DownloadService
{
public static readonly HttpClient HttpClient = new();
/// <summary>
/// 一个static的HttpClient,以便在任何地方调用
/// </summary>
public static HttpClient HttpClient { get; } = new();

/// <summary>
/// 从某个 URL 下载并保存文件
Expand All @@ -21,7 +21,7 @@ public static class FileHelper
/// <param name="maxRetries">最大重试次数</param>
/// <param name="cancellationToken">用于取消</param>
/// <returns>向外传递的文件流</returns>
public static async Task<FileStream?> DownloadFileAsync(
public async Task<FileStream?> DownloadFileAsync(
Uri uri, string localFilePath, string? sha1 = null, bool passStreamDown = false, int maxRetries = 3,
CancellationToken cancellationToken = default)
{
Expand All @@ -40,6 +40,7 @@ public static class FileHelper
try
{
await response.Content.CopyToAsync(fileStream, cancellationToken);
response.EnsureSuccessStatusCode();
if (!string.IsNullOrEmpty(sha1))
{
fileStream.Position = 0;
Expand Down Expand Up @@ -73,82 +74,10 @@ public static class FileHelper
}
}

/// <summary>
/// 校验文件流与SHA-1是否匹配
/// </summary>
/// <param name="fileStream">文件流</param>
/// <param name="sha1">SHA-1</param>
/// <returns>是否匹配</returns>
private static async Task<bool> CheckSha1(this FileStream fileStream, string sha1)
{
using var sha1Provider = System.Security.Cryptography.SHA1.Create();
fileStream.Position = 0; // 重置文件流位置
var computedHash = await sha1Provider.ComputeHashAsync(fileStream);
var computedHashString = Convert.ToHexStringLower(computedHash);
return string.Equals(computedHashString, sha1, StringComparison.OrdinalIgnoreCase);
}

/// <summary>
/// 在 Unix 系统中给予可执行文件运行权限
/// </summary>
/// <param name="path">文件路径</param>
[SupportedOSPlatform(nameof(OSPlatform.OSX))]
[SupportedOSPlatform(nameof(OSPlatform.Linux))]
public static void SetFileExecutableUnix(this string path)
{
if (Const.Os is Const.RunningOs.Windows) return;
try
{
var currentMode = File.GetUnixFileMode(path);
var newMode = currentMode | UnixFileMode.UserExecute | UnixFileMode.GroupExecute |
UnixFileMode.OtherExecute;
File.SetUnixFileMode(path, newMode);
}
catch (Exception e)
{
Console.WriteLine($"无法设置可执行权限:{e.Message}");
throw;
}
}

/// <summary>
/// 从某个地方抄来的很像 C 语言风格的解压 LZMA 压缩算法的函数
/// </summary>
/// <param name="inStream">被压缩的文件流</param>
/// <param name="outputFile">输出文件路径</param>
/// <returns>解压后的文件流</returns>
private static FileStream? DecompressLZMA(this FileStream inStream, string outputFile)
{
inStream.Position = 0;
var outStream = new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite);
byte[] decodeProperties = new byte[5];
int n = inStream.Read(decodeProperties, 0, 5);
Debug.Assert(n == 5);
SevenZip.Compression.LZMA.Decoder decoder = new();
decoder.SetDecoderProperties(decodeProperties);
long outSize = 0;
for (int i = 0; i < 8; i++)
{
int v = inStream.ReadByte();
if (v < 0)
{
Console.WriteLine("read outSize error.");
return null;
}

outSize |= (long)(byte)v << (8 * i);
}

long compressedSize = inStream.Length - inStream.Position;
decoder.Code(inStream, outStream, compressedSize, outSize, null);
inStream.Close();
return outStream;
}

/// <summary>
/// 整合函数:下载并解压,然后删去原压缩文件
/// </summary>
public static async Task DownloadAndDeCompressFileAsync(Uri uri, string localFilePath, string sha1Raw,
public async Task DownloadAndDeCompressFileAsync(Uri uri, string localFilePath, string sha1Raw,
string sha1Lzma, CancellationToken cancellationToken = default)
{
var stream = await DownloadFileAsync(uri, localFilePath + ".lzma", sha1Lzma, true,
Expand Down
Loading
Loading