From d3767a0344e81986a1ecd34dd125121f2c69548b Mon Sep 17 00:00:00 2001 From: Philipp Heenemann Date: Wed, 12 Jul 2023 08:32:57 +0200 Subject: [PATCH] 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. --- SPTInstaller/GlobalUsings.cs | 3 + SPTInstaller/Helpers/DirectorySizeHelper.cs | 49 ++++------ .../Installer Tasks/IntializationTask.cs | 7 -- .../PreChecks/FreeSpacePreCheck.cs | 25 +++++ SPTInstaller/Models/InternalData.cs | 4 +- SPTInstaller/Program.cs | 5 +- SPTInstaller/ViewModels/PreChecksViewModel.cs | 93 ++++++++----------- SPTInstaller/Views/PreChecksView.axaml | 1 + 8 files changed, 90 insertions(+), 97 deletions(-) create mode 100644 SPTInstaller/GlobalUsings.cs create mode 100644 SPTInstaller/Installer Tasks/PreChecks/FreeSpacePreCheck.cs diff --git a/SPTInstaller/GlobalUsings.cs b/SPTInstaller/GlobalUsings.cs new file mode 100644 index 0000000..eee4b9d --- /dev/null +++ b/SPTInstaller/GlobalUsings.cs @@ -0,0 +1,3 @@ +// Global using directives +global using System; +global using System.IO; \ No newline at end of file diff --git a/SPTInstaller/Helpers/DirectorySizeHelper.cs b/SPTInstaller/Helpers/DirectorySizeHelper.cs index 9aef26b..59114d9 100644 --- a/SPTInstaller/Helpers/DirectorySizeHelper.cs +++ b/SPTInstaller/Helpers/DirectorySizeHelper.cs @@ -1,46 +1,29 @@ -using System; -using System.IO; -using System.Linq; +using System.Linq; 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 - { - var eftSourceDirectoryInfo = new DirectoryInfo(eftSourceDirPath); - var installTargetDirectoryInfo = new DirectoryInfo(installTargetDirPath); + var eftSourceDirectoryInfo = new DirectoryInfo(eftSourceDirPath); + var installTargetDirectoryInfo = new DirectoryInfo(installTargetDirPath); - var eftSourceDirSize = GetSizeOfDirectory(eftSourceDirectoryInfo); - var availableSize = DriveInfo.GetDrives().FirstOrDefault(d => d.Name == installTargetDirectoryInfo.Root.Name)?.AvailableFreeSpace ?? 0; + var eftSourceDirSize = GetSizeOfDirectory(eftSourceDirectoryInfo); + var availableSize = DriveInfo.GetDrives().FirstOrDefault(d => d.Name == installTargetDirectoryInfo.Root.Name)?.AvailableFreeSpace ?? 0; - if (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) - { - Log.Error(ex, "Error while checking available size"); - - return Result.FromError(ex.Message); - } + return eftSourceDirSize < availableSize; } - - private static long GetSizeOfDirectory(DirectoryInfo sourceDir) => sourceDir.EnumerateFiles("*", SearchOption.AllDirectories).Sum(fi => fi.Length); - - private static string FormatFileSize(long bytes) + catch (Exception ex) { - const int unit = 1024; - var exp = (int)(Math.Log(bytes) / Math.Log(unit)); + Log.Error(ex, "Error while checking available size"); - return $"{bytes / Math.Pow(unit, exp):F2} {"KMGTPE"[exp - 1]}B"; + return false; } } + + private static long GetSizeOfDirectory(DirectoryInfo sourceDir) => sourceDir.EnumerateFiles("*", SearchOption.AllDirectories).Sum(fi => fi.Length); } \ No newline at end of file diff --git a/SPTInstaller/Installer Tasks/IntializationTask.cs b/SPTInstaller/Installer Tasks/IntializationTask.cs index 4223bf2..28dae32 100644 --- a/SPTInstaller/Installer Tasks/IntializationTask.cs +++ b/SPTInstaller/Installer Tasks/IntializationTask.cs @@ -2,7 +2,6 @@ using SPTInstaller.Interfaces; using SPTInstaller.Models; using System.Threading.Tasks; -using SPTInstaller.Helpers; namespace SPTInstaller.Installer_Tasks { @@ -28,12 +27,6 @@ namespace SPTInstaller.Installer_Tasks 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); if (!result.Succeeded) diff --git a/SPTInstaller/Installer Tasks/PreChecks/FreeSpacePreCheck.cs b/SPTInstaller/Installer Tasks/PreChecks/FreeSpacePreCheck.cs new file mode 100644 index 0000000..f894265 --- /dev/null +++ b/SPTInstaller/Installer Tasks/PreChecks/FreeSpacePreCheck.cs @@ -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 CheckOperation() + { + if (_internalData.OriginalGamePath is null || _internalData.TargetInstallPath is null) + { + return false; + } + + return DirectorySizeHelper.CheckAvailableSize(_internalData.OriginalGamePath, _internalData.TargetInstallPath); + } +} \ No newline at end of file diff --git a/SPTInstaller/Models/InternalData.cs b/SPTInstaller/Models/InternalData.cs index 0ea2914..0c93498 100644 --- a/SPTInstaller/Models/InternalData.cs +++ b/SPTInstaller/Models/InternalData.cs @@ -8,12 +8,12 @@ namespace SPTInstaller.Models /// /// The folder to install SPT into /// - public string TargetInstallPath { get; set; } + public string? TargetInstallPath { get; set; } /// /// The orginal EFT game path /// - public string OriginalGamePath { get; set; } + public string? OriginalGamePath { get; set; } /// /// The original EFT game version diff --git a/SPTInstaller/Program.cs b/SPTInstaller/Program.cs index 64ec82f..78e8dc9 100644 --- a/SPTInstaller/Program.cs +++ b/SPTInstaller/Program.cs @@ -9,8 +9,6 @@ using SPTInstaller.Installer_Tasks; using SPTInstaller.Installer_Tasks.PreChecks; using SPTInstaller.Interfaces; using SPTInstaller.Models; -using System; -using System.IO; using System.Linq; using System.Reflection; @@ -35,8 +33,9 @@ namespace SPTInstaller ServiceHelper.Register(); ServiceHelper.Register(); ServiceHelper.Register(); + ServiceHelper.Register(); #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() .MinimumLevel.Debug() diff --git a/SPTInstaller/ViewModels/PreChecksViewModel.cs b/SPTInstaller/ViewModels/PreChecksViewModel.cs index 4e8dbbf..0193e6e 100644 --- a/SPTInstaller/ViewModels/PreChecksViewModel.cs +++ b/SPTInstaller/ViewModels/PreChecksViewModel.cs @@ -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.Helpers; 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; + + public ObservableCollection PreChecks { get; set; } = new(ServiceHelper.GetAll()); + public ICommand StartInstallCommand { get; set; } + public bool PreCheckSucceeded { get; set; } + public string InstallPath { - private string _InstallPath; - public string InstallPath - { - get => _InstallPath; - set => this.RaiseAndSetIfChanged(ref _InstallPath, value); - } - - ObservableCollection PreChecks { get; set; } - = new ObservableCollection(ServiceHelper.GetAll()); - - ICommand StartInstallCommand { get; set; } - - public PreChecksViewModel(IScreen host) : base(host) - { - var data = ServiceHelper.Get(); - var installer = ServiceHelper.Get(); - - if(data == null || installer == null) - { - NavigateTo(new MessageViewModel(HostScreen, Result.FromError("Failed to get required service for prechecks"))); - return; - } - - data.TargetInstallPath = Environment.CurrentDirectory; - - InstallPath = data.TargetInstallPath; - - StartInstallCommand = ReactiveCommand.Create(() => - { - NavigateTo(new InstallViewModel(HostScreen)); - }); - - - Task.Run(async () => - { - var result = await installer.RunPreChecks(); - - if(!result.Succeeded) - { - //if a required precheck fails, abort to message view - NavigateTo(new MessageViewModel(HostScreen ,result)); - } - }); - } + get => _installPath; + set => this.RaiseAndSetIfChanged(ref _installPath, value); } -} + + public PreChecksViewModel(IScreen host) : base(host) + { + var data = ServiceHelper.Get(); + var installer = ServiceHelper.Get(); + + if (data == null || installer == null) + { + NavigateTo(new MessageViewModel(HostScreen, Result.FromError("Failed to get required service for prechecks"))); + return; + } + + data.OriginalGamePath = PreCheckHelper.DetectOriginalGamePath(); + data.TargetInstallPath = Environment.CurrentDirectory; + InstallPath = data.TargetInstallPath; + + StartInstallCommand = ReactiveCommand.Create(() => NavigateTo(new InstallViewModel(HostScreen))); + + Task.Run(async () => + { + var result = await installer.RunPreChecks(); + PreCheckSucceeded = result.Succeeded; + }); + } +} \ No newline at end of file diff --git a/SPTInstaller/Views/PreChecksView.axaml b/SPTInstaller/Views/PreChecksView.axaml index 1058561..aa78b82 100644 --- a/SPTInstaller/Views/PreChecksView.axaml +++ b/SPTInstaller/Views/PreChecksView.axaml @@ -23,6 +23,7 @@ Margin="10" FontSize="15" FontWeight="SemiBold" Classes="yellow" + IsVisible="{Binding PreCheckSucceeded}" Command="{Binding StartInstallCommand}" />