Added wine checks, path fixing on wine -> linux

This commit is contained in:
cake
2025-10-30 03:34:56 +01:00
parent bf139c128b
commit c1770528f3

View File

@@ -1,6 +1,5 @@
using LightlessSync.LightlessConfiguration;
using LightlessSync.Services;
using LightlessSync.Utils;
using Microsoft.Extensions.Logging;
using System.Collections.Concurrent;
using System.Diagnostics;
@@ -191,6 +190,16 @@ public sealed class FileCompactor : IDisposable
}
}
private static string ConvertWinePathToLinux(string winePath)
{
if (winePath.StartsWith("Z:\\", StringComparison.OrdinalIgnoreCase))
return "/" + winePath.Substring(3).Replace('\\', '/');
if (winePath.StartsWith("C:\\", StringComparison.OrdinalIgnoreCase))
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal),
winePath.Substring(3).Replace('\\', '/')).Replace('\\', '/');
return winePath.Replace('\\', '/');
}
[DllImport("kernel32.dll")]
private static extern int DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, IntPtr lpOutBuffer, uint nOutBufferSize, out IntPtr lpBytesReturned, out IntPtr lpOverlapped);
@@ -347,18 +356,42 @@ 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;
}
_logger.LogDebug("Rewriting {file} to remove btrfs compression...", path);
var psi = new ProcessStartInfo("btrfs", $"filesystem defragment -- \"{path}\"")
string realPath = path;
bool isWine = _dalamudUtilService?.IsWine ?? false;
if (isWine)
{
if (path.StartsWith("Z:\\", StringComparison.OrdinalIgnoreCase))
{
realPath = "/" + path.Substring(3).Replace('\\', '/');
}
else if (path.StartsWith("C:\\", StringComparison.OrdinalIgnoreCase))
{
// fallback for Wine's C:\ mapping
realPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Personal),
path.Substring(3).Replace('\\', '/')
).Replace('\\', '/');
}
_logger.LogTrace("Detected Wine environment. Converted path for decompression: {realPath}", realPath);
}
string command = $"btrfs filesystem defragment -- \"{realPath}\"";
var psi = new ProcessStartInfo
{
FileName = isWine ? "/bin/bash" : "btrfs",
Arguments = isWine ? $"-c \"{command}\"" : $"filesystem defragment -- \"{realPath}\"",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
CreateNoWindow = true,
WorkingDirectory = "/"
};
using var proc = Process.Start(psi);
@@ -368,7 +401,7 @@ public sealed class FileCompactor : IDisposable
return;
}
//End stream of process to read the files
// 4⃣ Read process output
var stdout = proc.StandardOutput.ReadToEnd();
var stderr = proc.StandardError.ReadToEnd();
proc.WaitForExit();
@@ -495,12 +528,36 @@ public sealed class FileCompactor : IDisposable
{
try
{
var psi = new ProcessStartInfo("filefrag", $"-v \"{path}\"")
bool isWine = _dalamudUtilService?.IsWine ?? false;
string realPath = path;
if (isWine)
{
if (path.StartsWith("Z:\\", StringComparison.OrdinalIgnoreCase))
{
realPath = "/" + path.Substring(3).Replace('\\', '/');
}
else if (path.StartsWith("C:\\", StringComparison.OrdinalIgnoreCase))
{
realPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Personal),
path.Substring(3).Replace('\\', '/')
).Replace('\\', '/');
}
_logger.LogTrace("Detected Wine environment. Converted path for filefrag: {realPath}", realPath);
}
string command = $"filefrag -v -- \"{realPath}\"";
var psi = new ProcessStartInfo
{
FileName = isWine ? "/bin/bash" : "filefrag",
Arguments = isWine ? $"-c \"{command}\"" : $"-v -- \"{realPath}\"",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
CreateNoWindow = true,
WorkingDirectory = "/"
};
using var proc = Process.Start(psi);
@@ -511,10 +568,17 @@ public sealed class FileCompactor : IDisposable
}
string output = proc.StandardOutput.ReadToEnd();
string stderr = proc.StandardError.ReadToEnd();
proc.WaitForExit();
bool compressed = output.Contains("flags: compressed", StringComparison.OrdinalIgnoreCase);
if (proc.ExitCode != 0)
{
_logger.LogDebug("filefrag exited with {code} for {file}. stderr: {stderr}",
proc.ExitCode, path, stderr);
return false;
}
bool compressed = output.Contains("flags: compressed", StringComparison.OrdinalIgnoreCase);
_logger.LogTrace("Btrfs compression check for {file}: {compressed}", path, compressed);
return compressed;
}
@@ -567,7 +631,20 @@ public sealed class FileCompactor : IDisposable
{
try
{
var psi = new ProcessStartInfo("btrfs", $"filesystem defragment -czstd -- \"{path}\"")
string realPath = path;
if (_dalamudUtilService.IsWine)
{
realPath = ConvertWinePathToLinux(path);
_logger.LogTrace("Detected Wine environment, remapped path: {realPath}", realPath);
}
if (!File.Exists("/usr/bin/btrfs") && !File.Exists("/bin/btrfs"))
{
_logger.LogWarning("Skipping Btrfs compression — btrfs binary not found");
return false;
}
var psi = new ProcessStartInfo("btrfs", $"filesystem defragment -czstd -- \"{realPath}\"")
{
RedirectStandardOutput = true,
RedirectStandardError = true,
@@ -578,7 +655,7 @@ public sealed class FileCompactor : IDisposable
using var proc = Process.Start(psi);
if (proc == null)
{
_logger.LogWarning("Failed to start btrfs process for {file}", path);
_logger.LogWarning("Failed to start btrfs process for {file}", realPath);
return false;
}
@@ -588,7 +665,7 @@ public sealed class FileCompactor : IDisposable
if (proc.ExitCode != 0)
{
_logger.LogWarning("btrfs defrag returned {code} for {file}: {err}", proc.ExitCode, path, stderr);
_logger.LogWarning("btrfs defrag returned {code} for {file}: {err}", proc.ExitCode, realPath, stderr);
return false;
}
@@ -597,7 +674,7 @@ public sealed class FileCompactor : IDisposable
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Error running btrfs defragment for {file}", path);
_logger.LogWarning(ex, "Error running btrfs defragment for {file}", realPath);
return false;
}
}