From 7c4d0fd5e99a897c0bbaa6ae2e819cf98e17185e Mon Sep 17 00:00:00 2001 From: cake Date: Wed, 29 Oct 2025 22:54:50 +0100 Subject: [PATCH] Added comments, clean-up --- LightlessSync/FileCache/CacheMonitor.cs | 12 ++++++--- LightlessSync/FileCache/FileCompactor.cs | 31 ++++++++++++------------ LightlessSync/Utils/Crypto.cs | 27 ++++++++++----------- LightlessSync/Utils/FileSystemHelper.cs | 14 ++++++----- 4 files changed, 45 insertions(+), 39 deletions(-) diff --git a/LightlessSync/FileCache/CacheMonitor.cs b/LightlessSync/FileCache/CacheMonitor.cs index 95c3150..64910f3 100644 --- a/LightlessSync/FileCache/CacheMonitor.cs +++ b/LightlessSync/FileCache/CacheMonitor.cs @@ -409,11 +409,17 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase return; } - FileCacheSize = -1; - DriveInfo di = new(new DirectoryInfo(_configService.Current.CacheFolder).Root.FullName); + FileCacheSize = -1; + + var drive = DriveInfo.GetDrives().FirstOrDefault(d => _configService.Current.CacheFolder.StartsWith(d.Name, StringComparison.Ordinal)); + if (drive == null) + { + return; + } + try { - FileCacheDriveFree = di.AvailableFreeSpace; + FileCacheDriveFree = drive.AvailableFreeSpace; } catch (Exception ex) { diff --git a/LightlessSync/FileCache/FileCompactor.cs b/LightlessSync/FileCache/FileCompactor.cs index d1aa60a..9a73e81 100644 --- a/LightlessSync/FileCache/FileCompactor.cs +++ b/LightlessSync/FileCache/FileCompactor.cs @@ -1,10 +1,8 @@ using LightlessSync.LightlessConfiguration; using LightlessSync.Services; -using LightlessSync.Utils; using Microsoft.Extensions.Logging; using System.Collections.Concurrent; using System.Diagnostics; -using System.IO; using System.Runtime.InteropServices; using System.Threading.Channels; using static LightlessSync.Utils.FileSystemHelper; @@ -106,6 +104,7 @@ public sealed class FileCompactor : IDisposable try { long blocks = RunStatGetBlocks(fileInfo.FullName); + //st_blocks are always calculated in 512-byte units, hence we use 512L return blocks * 512L; } catch (Exception ex) @@ -161,17 +160,17 @@ public sealed class FileCompactor : IDisposable [StructLayout(LayoutKind.Sequential)] private struct Statvfs { - public ulong f_bsize; - public ulong f_frsize; - public ulong f_blocks; - public ulong f_bfree; - public ulong f_bavail; - public ulong f_files; - public ulong f_ffree; - public ulong f_favail; - public ulong f_fsid; - public ulong f_flag; - public ulong f_namemax; + public ulong f_bsize; /* Filesystem block size */ + public ulong f_frsize; /* Fragment size */ + public ulong f_blocks; /* Size of fs in f_frsize units */ + public ulong f_bfree; /* Number of free blocks */ + public ulong f_bavail; /* Number of free blocks for unprivileged users */ + public ulong f_files; /* Number of inodes */ + public ulong f_ffree; /* Number of free inodes */ + public ulong f_favail; /* Number of free inodes for unprivileged users */ + public ulong f_fsid; /* Filesystem ID */ + public ulong f_flag; /* Mount flags */ + public ulong f_namemax; /* Maximum filename length */ } private static int GetLinuxBlockSize(string path) @@ -182,6 +181,7 @@ public sealed class FileCompactor : IDisposable if (result != 0) return -1; + //return fragment size of linux return (int)buf.f_frsize; } catch @@ -346,9 +346,7 @@ public sealed class FileCompactor : IDisposable var mountOptions = GetMountOptionsForPath(path); if (mountOptions.Contains("compress", StringComparison.OrdinalIgnoreCase)) { - _logger.LogWarning( - "Cannot safely decompress {file}: filesystem mounted with compression ({opts}). " + - "Remount with 'compress=no' before running decompression.", path, mountOptions); + _logger.LogWarning("Cannot safely decompress {file}: filesystem mounted with compression ({opts}). Remount with 'compress=no' before running decompression.", path, mountOptions); return; } @@ -369,6 +367,7 @@ public sealed class FileCompactor : IDisposable return; } + //End stream of process to read the files var stdout = proc.StandardOutput.ReadToEnd(); var stderr = proc.StandardError.ReadToEnd(); proc.WaitForExit(); diff --git a/LightlessSync/Utils/Crypto.cs b/LightlessSync/Utils/Crypto.cs index 87d6883..c31f82f 100644 --- a/LightlessSync/Utils/Crypto.cs +++ b/LightlessSync/Utils/Crypto.cs @@ -1,16 +1,15 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Security.Cryptography; +using System.Security.Cryptography; using System.Text; namespace LightlessSync.Utils; public static class Crypto { + //This buffersize seems to be the best sweetpoint for Linux and Windows + private const int _bufferSize = 65536; #pragma warning disable SYSLIB0021 // Type or member is obsolete - private static readonly Dictionary<(string, ushort), string> _hashListPlayersSHA256 = new(); + private static readonly Dictionary<(string, ushort), string> _hashListPlayersSHA256 = []; private static readonly Dictionary _hashListSHA256 = new(StringComparer.Ordinal); private static readonly SHA256CryptoServiceProvider _sha256CryptoProvider = new(); @@ -23,21 +22,21 @@ public static class Crypto public static async Task GetFileHashAsync(string filePath, CancellationToken cancellationToken = default) { - var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete, bufferSize: 65536, options: FileOptions.Asynchronous); + var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete, bufferSize: _bufferSize, 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); - } + 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); + sha1.TransformFinalBlock([], 0, 0); - return BitConverter.ToString(sha1.Hash!).Replace("-", "", StringComparison.Ordinal); + return Convert.ToHexString(sha1.Hash!); } } diff --git a/LightlessSync/Utils/FileSystemHelper.cs b/LightlessSync/Utils/FileSystemHelper.cs index a5bb427..cda36c3 100644 --- a/LightlessSync/Utils/FileSystemHelper.cs +++ b/LightlessSync/Utils/FileSystemHelper.cs @@ -8,17 +8,18 @@ namespace LightlessSync.Utils public enum FilesystemType { Unknown = 0, - NTFS, - Btrfs, + NTFS, // Compressable + Btrfs, // Compressable Ext4, Xfs, Apfs, HfsPlus, Fat, Exfat, - Zfs + Zfs // Compressable } + private const string _mountPath = "/proc/mounts"; private static readonly ConcurrentDictionary _filesystemTypeCache = new(StringComparer.OrdinalIgnoreCase); public static FilesystemType GetFilesystemType(string filePath, bool isWine = false) @@ -75,8 +76,8 @@ namespace LightlessSync.Utils try { var path = Path.GetFullPath(filePath); - if (!File.Exists("/proc/mounts")) return "/"; - var mounts = File.ReadAllLines("/proc/mounts"); + if (!File.Exists(_mountPath)) return "/"; + var mounts = File.ReadAllLines(_mountPath); string bestMount = "/"; foreach (var line in mounts) @@ -109,7 +110,7 @@ namespace LightlessSync.Utils try { var mountPoint = GetMountPoint(filePath); - var mounts = File.ReadAllLines("/proc/mounts"); + var mounts = File.ReadAllLines(_mountPath); foreach (var line in mounts) { @@ -140,6 +141,7 @@ namespace LightlessSync.Utils } } + //Extra check on private static bool IsProbablyWine() => Environment.GetEnvironmentVariable("WINELOADERNOEXEC") != null || Environment.GetEnvironmentVariable("WINEDLLPATH") != null || Directory.Exists("/proc/self") && File.Exists("/proc/mounts"); } }