Implemented compactor to work on BTRFS, redid cache a bit for better function on linux. Removed error for websockets, it will be forced on wine again.
This commit is contained in:
@@ -21,6 +21,26 @@ public static class Crypto
|
||||
return BitConverter.ToString(sha1.ComputeHash(stream)).Replace("-", "", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public static async Task<string> GetFileHashAsync(string filePath, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete, bufferSize: 65536, options: FileOptions.Asynchronous);
|
||||
await using (stream.ConfigureAwait(false))
|
||||
{
|
||||
using var sha1 = SHA1.Create();
|
||||
|
||||
var buffer = new byte[8192];
|
||||
int bytesRead;
|
||||
while ((bytesRead = await stream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false)) > 0)
|
||||
{
|
||||
sha1.TransformBlock(buffer, 0, bytesRead, outputBuffer: null, 0);
|
||||
}
|
||||
|
||||
sha1.TransformFinalBlock([], 0, 0);
|
||||
|
||||
return BitConverter.ToString(sha1.Hash!).Replace("-", "", StringComparison.Ordinal);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetHash256(this (string, ushort) playerToHash)
|
||||
{
|
||||
if (_hashListPlayersSHA256.TryGetValue(playerToHash, out var hash))
|
||||
|
||||
143
LightlessSync/Utils/FileSystemHelper.cs
Normal file
143
LightlessSync/Utils/FileSystemHelper.cs
Normal file
@@ -0,0 +1,143 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace LightlessSync.Utils
|
||||
{
|
||||
public static class FileSystemHelper
|
||||
{
|
||||
public enum FilesystemType
|
||||
{
|
||||
Unknown = 0,
|
||||
NTFS,
|
||||
Btrfs,
|
||||
Ext4,
|
||||
Xfs,
|
||||
Apfs,
|
||||
HfsPlus,
|
||||
Fat,
|
||||
Exfat,
|
||||
Zfs
|
||||
}
|
||||
|
||||
private static readonly ConcurrentDictionary<string, FilesystemType> _filesystemTypeCache = new(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public static FilesystemType GetFilesystemType(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
string rootPath;
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
var info = new FileInfo(filePath);
|
||||
var dir = info.Directory ?? new DirectoryInfo(filePath);
|
||||
rootPath = dir.Root.FullName;
|
||||
}
|
||||
else
|
||||
{
|
||||
rootPath = GetMountPoint(filePath);
|
||||
if (string.IsNullOrEmpty(rootPath))
|
||||
rootPath = "/";
|
||||
}
|
||||
|
||||
if (_filesystemTypeCache.TryGetValue(rootPath, out var cachedType))
|
||||
return cachedType;
|
||||
|
||||
FilesystemType detected;
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
var root = new DriveInfo(rootPath);
|
||||
var format = root.DriveFormat?.ToUpperInvariant() ?? string.Empty;
|
||||
detected = format switch
|
||||
{
|
||||
"NTFS" => FilesystemType.NTFS,
|
||||
"FAT32" => FilesystemType.Fat,
|
||||
"EXFAT" => FilesystemType.Exfat,
|
||||
_ => FilesystemType.Unknown
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
detected = GetLinuxFilesystemType(filePath);
|
||||
}
|
||||
|
||||
_filesystemTypeCache[rootPath] = detected;
|
||||
return detected;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return FilesystemType.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetMountPoint(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var path = Path.GetFullPath(filePath);
|
||||
if (!File.Exists("/proc/mounts")) return "/";
|
||||
var mounts = File.ReadAllLines("/proc/mounts");
|
||||
|
||||
string bestMount = "/";
|
||||
foreach (var line in mounts)
|
||||
{
|
||||
var parts = line.Split(' ');
|
||||
if (parts.Length < 3) continue;
|
||||
var mountPoint = parts[1].Replace("\\040", " "); // unescape spaces
|
||||
|
||||
string normalizedMount;
|
||||
try { normalizedMount = Path.GetFullPath(mountPoint); }
|
||||
catch { normalizedMount = mountPoint; }
|
||||
|
||||
if (path.StartsWith(normalizedMount, StringComparison.Ordinal) &&
|
||||
normalizedMount.Length > bestMount.Length)
|
||||
{
|
||||
bestMount = normalizedMount;
|
||||
}
|
||||
}
|
||||
|
||||
return bestMount;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "/";
|
||||
}
|
||||
}
|
||||
|
||||
private static FilesystemType GetLinuxFilesystemType(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var mountPoint = GetMountPoint(filePath);
|
||||
var mounts = File.ReadAllLines("/proc/mounts");
|
||||
|
||||
foreach (var line in mounts)
|
||||
{
|
||||
var parts = line.Split(' ');
|
||||
if (parts.Length < 3) continue;
|
||||
var mount = parts[1].Replace("\\040", " ");
|
||||
if (string.Equals(mount, mountPoint, StringComparison.Ordinal))
|
||||
{
|
||||
var fstype = parts[2].ToLowerInvariant();
|
||||
return fstype switch
|
||||
{
|
||||
"btrfs" => FilesystemType.Btrfs,
|
||||
"ext4" => FilesystemType.Ext4,
|
||||
"xfs" => FilesystemType.Xfs,
|
||||
"zfs" => FilesystemType.Zfs,
|
||||
"apfs" => FilesystemType.Apfs,
|
||||
"hfsplus" => FilesystemType.HfsPlus,
|
||||
_ => FilesystemType.Unknown
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return FilesystemType.Unknown;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return FilesystemType.Unknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user