Add global using directives and free space pre-check
Global System and System.IO usages have been replaced with global usings in GlobalUsings.cs for improved code readability. Alongside, a FreeSpacePreCheck has been added in FreeSpacePreCheck.cs to ensure enough drive space is available before installation. This check was initially taking place in InitializationTask.cs which has been removed for better separation of concerns. The PreCheckViewModel visibility is now dependent on the success status of PreChecks, enhancing user experience.
This commit is contained in:
parent
68e50cf5e5
commit
d3767a0344
3
SPTInstaller/GlobalUsings.cs
Normal file
3
SPTInstaller/GlobalUsings.cs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// Global using directives
|
||||||
|
global using System;
|
||||||
|
global using System.IO;
|
@ -1,14 +1,11 @@
|
|||||||
using System;
|
using System.Linq;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using SPTInstaller.Models;
|
|
||||||
|
|
||||||
namespace SPTInstaller.Helpers
|
namespace SPTInstaller.Helpers;
|
||||||
|
|
||||||
|
public static class DirectorySizeHelper
|
||||||
{
|
{
|
||||||
public static class DirectorySizeHelper
|
public static bool CheckAvailableSize(string eftSourceDirPath, string installTargetDirPath)
|
||||||
{
|
|
||||||
public static Result CheckAvailableSize(string eftSourceDirPath, string installTargetDirPath)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -18,29 +15,15 @@ namespace SPTInstaller.Helpers
|
|||||||
var eftSourceDirSize = GetSizeOfDirectory(eftSourceDirectoryInfo);
|
var eftSourceDirSize = GetSizeOfDirectory(eftSourceDirectoryInfo);
|
||||||
var availableSize = DriveInfo.GetDrives().FirstOrDefault(d => d.Name == installTargetDirectoryInfo.Root.Name)?.AvailableFreeSpace ?? 0;
|
var availableSize = DriveInfo.GetDrives().FirstOrDefault(d => d.Name == installTargetDirectoryInfo.Root.Name)?.AvailableFreeSpace ?? 0;
|
||||||
|
|
||||||
if (eftSourceDirSize > availableSize)
|
return eftSourceDirSize < availableSize;
|
||||||
{
|
|
||||||
return Result.FromError($"Not enough space on drive {installTargetDirectoryInfo.Root.Name}.\n\nRequired: {FormatFileSize(eftSourceDirSize)}\nAvailable: {FormatFileSize(availableSize)}");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result.FromSuccess();
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error(ex, "Error while checking available size");
|
Log.Error(ex, "Error while checking available size");
|
||||||
|
|
||||||
return Result.FromError(ex.Message);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long GetSizeOfDirectory(DirectoryInfo sourceDir) => sourceDir.EnumerateFiles("*", SearchOption.AllDirectories).Sum(fi => fi.Length);
|
private static long GetSizeOfDirectory(DirectoryInfo sourceDir) => sourceDir.EnumerateFiles("*", SearchOption.AllDirectories).Sum(fi => fi.Length);
|
||||||
|
|
||||||
private static string FormatFileSize(long bytes)
|
|
||||||
{
|
|
||||||
const int unit = 1024;
|
|
||||||
var exp = (int)(Math.Log(bytes) / Math.Log(unit));
|
|
||||||
|
|
||||||
return $"{bytes / Math.Pow(unit, exp):F2} {"KMGTPE"[exp - 1]}B";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -2,7 +2,6 @@
|
|||||||
using SPTInstaller.Interfaces;
|
using SPTInstaller.Interfaces;
|
||||||
using SPTInstaller.Models;
|
using SPTInstaller.Models;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using SPTInstaller.Helpers;
|
|
||||||
|
|
||||||
namespace SPTInstaller.Installer_Tasks
|
namespace SPTInstaller.Installer_Tasks
|
||||||
{
|
{
|
||||||
@ -28,12 +27,6 @@ namespace SPTInstaller.Installer_Tasks
|
|||||||
|
|
||||||
SetStatus(null, $"Installed EFT Game Path: {FileHelper.GetRedactedPath(_data.OriginalGamePath)}");
|
SetStatus(null, $"Installed EFT Game Path: {FileHelper.GetRedactedPath(_data.OriginalGamePath)}");
|
||||||
|
|
||||||
var directorySizeCheckResult = DirectorySizeHelper.CheckAvailableSize(_data.OriginalGamePath, _data.TargetInstallPath);
|
|
||||||
if (!directorySizeCheckResult.Succeeded)
|
|
||||||
{
|
|
||||||
return Result.FromError(directorySizeCheckResult.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = PreCheckHelper.DetectOriginalGameVersion(_data.OriginalGamePath);
|
var result = PreCheckHelper.DetectOriginalGameVersion(_data.OriginalGamePath);
|
||||||
|
|
||||||
if (!result.Succeeded)
|
if (!result.Succeeded)
|
||||||
|
25
SPTInstaller/Installer Tasks/PreChecks/FreeSpacePreCheck.cs
Normal file
25
SPTInstaller/Installer Tasks/PreChecks/FreeSpacePreCheck.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using SPTInstaller.Helpers;
|
||||||
|
using SPTInstaller.Models;
|
||||||
|
|
||||||
|
namespace SPTInstaller.Installer_Tasks.PreChecks;
|
||||||
|
|
||||||
|
public class FreeSpacePreCheck : PreCheckBase
|
||||||
|
{
|
||||||
|
private readonly InternalData _internalData;
|
||||||
|
|
||||||
|
public FreeSpacePreCheck(InternalData internalData) : base("Free Space", true)
|
||||||
|
{
|
||||||
|
_internalData = internalData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<bool> CheckOperation()
|
||||||
|
{
|
||||||
|
if (_internalData.OriginalGamePath is null || _internalData.TargetInstallPath is null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DirectorySizeHelper.CheckAvailableSize(_internalData.OriginalGamePath, _internalData.TargetInstallPath);
|
||||||
|
}
|
||||||
|
}
|
@ -8,12 +8,12 @@ namespace SPTInstaller.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The folder to install SPT into
|
/// The folder to install SPT into
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string TargetInstallPath { get; set; }
|
public string? TargetInstallPath { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The orginal EFT game path
|
/// The orginal EFT game path
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string OriginalGamePath { get; set; }
|
public string? OriginalGamePath { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The original EFT game version
|
/// The original EFT game version
|
||||||
|
@ -9,8 +9,6 @@ using SPTInstaller.Installer_Tasks;
|
|||||||
using SPTInstaller.Installer_Tasks.PreChecks;
|
using SPTInstaller.Installer_Tasks.PreChecks;
|
||||||
using SPTInstaller.Interfaces;
|
using SPTInstaller.Interfaces;
|
||||||
using SPTInstaller.Models;
|
using SPTInstaller.Models;
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
@ -35,8 +33,9 @@ namespace SPTInstaller
|
|||||||
ServiceHelper.Register<InternalData>();
|
ServiceHelper.Register<InternalData>();
|
||||||
ServiceHelper.Register<PreCheckBase, NetFramework472PreCheck>();
|
ServiceHelper.Register<PreCheckBase, NetFramework472PreCheck>();
|
||||||
ServiceHelper.Register<PreCheckBase, NetCore6PreCheck>();
|
ServiceHelper.Register<PreCheckBase, NetCore6PreCheck>();
|
||||||
|
ServiceHelper.Register<PreCheckBase, FreeSpacePreCheck>();
|
||||||
#if !TEST
|
#if !TEST
|
||||||
string logPath = Path.Join(Environment.CurrentDirectory, "spt-aki-installer_.log");
|
var logPath = Path.Join(Environment.CurrentDirectory, "spt-aki-installer_.log");
|
||||||
|
|
||||||
Log.Logger = new LoggerConfiguration()
|
Log.Logger = new LoggerConfiguration()
|
||||||
.MinimumLevel.Debug()
|
.MinimumLevel.Debug()
|
||||||
|
@ -1,59 +1,48 @@
|
|||||||
using ReactiveUI;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using ReactiveUI;
|
||||||
|
using SPTInstaller.Aki.Helper;
|
||||||
using SPTInstaller.Controllers;
|
using SPTInstaller.Controllers;
|
||||||
using SPTInstaller.Helpers;
|
using SPTInstaller.Helpers;
|
||||||
using SPTInstaller.Models;
|
using SPTInstaller.Models;
|
||||||
using System;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows.Input;
|
|
||||||
|
|
||||||
namespace SPTInstaller.ViewModels
|
namespace SPTInstaller.ViewModels;
|
||||||
|
|
||||||
|
public class PreChecksViewModel : ViewModelBase
|
||||||
{
|
{
|
||||||
public class PreChecksViewModel : ViewModelBase
|
private string _installPath;
|
||||||
{
|
|
||||||
private string _InstallPath;
|
public ObservableCollection<PreCheckBase> PreChecks { get; set; } = new(ServiceHelper.GetAll<PreCheckBase>());
|
||||||
|
public ICommand StartInstallCommand { get; set; }
|
||||||
|
public bool PreCheckSucceeded { get; set; }
|
||||||
public string InstallPath
|
public string InstallPath
|
||||||
{
|
{
|
||||||
get => _InstallPath;
|
get => _installPath;
|
||||||
set => this.RaiseAndSetIfChanged(ref _InstallPath, value);
|
set => this.RaiseAndSetIfChanged(ref _installPath, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObservableCollection<PreCheckBase> PreChecks { get; set; }
|
|
||||||
= new ObservableCollection<PreCheckBase>(ServiceHelper.GetAll<PreCheckBase>());
|
|
||||||
|
|
||||||
ICommand StartInstallCommand { get; set; }
|
|
||||||
|
|
||||||
public PreChecksViewModel(IScreen host) : base(host)
|
public PreChecksViewModel(IScreen host) : base(host)
|
||||||
{
|
{
|
||||||
var data = ServiceHelper.Get<InternalData>();
|
var data = ServiceHelper.Get<InternalData?>();
|
||||||
var installer = ServiceHelper.Get<InstallController>();
|
var installer = ServiceHelper.Get<InstallController?>();
|
||||||
|
|
||||||
if(data == null || installer == null)
|
if (data == null || installer == null)
|
||||||
{
|
{
|
||||||
NavigateTo(new MessageViewModel(HostScreen, Result.FromError("Failed to get required service for prechecks")));
|
NavigateTo(new MessageViewModel(HostScreen, Result.FromError("Failed to get required service for prechecks")));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data.OriginalGamePath = PreCheckHelper.DetectOriginalGamePath();
|
||||||
data.TargetInstallPath = Environment.CurrentDirectory;
|
data.TargetInstallPath = Environment.CurrentDirectory;
|
||||||
|
|
||||||
InstallPath = data.TargetInstallPath;
|
InstallPath = data.TargetInstallPath;
|
||||||
|
|
||||||
StartInstallCommand = ReactiveCommand.Create(() =>
|
StartInstallCommand = ReactiveCommand.Create(() => NavigateTo(new InstallViewModel(HostScreen)));
|
||||||
{
|
|
||||||
NavigateTo(new InstallViewModel(HostScreen));
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
var result = await installer.RunPreChecks();
|
var result = await installer.RunPreChecks();
|
||||||
|
PreCheckSucceeded = result.Succeeded;
|
||||||
if(!result.Succeeded)
|
|
||||||
{
|
|
||||||
//if a required precheck fails, abort to message view
|
|
||||||
NavigateTo(new MessageViewModel(HostScreen ,result));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
@ -23,6 +23,7 @@
|
|||||||
Margin="10"
|
Margin="10"
|
||||||
FontSize="15" FontWeight="SemiBold"
|
FontSize="15" FontWeight="SemiBold"
|
||||||
Classes="yellow"
|
Classes="yellow"
|
||||||
|
IsVisible="{Binding PreCheckSucceeded}"
|
||||||
Command="{Binding StartInstallCommand}"
|
Command="{Binding StartInstallCommand}"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user