diff --git a/README.md b/README.md index 403cf4f..9703d22 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ - Checks if .net 4.7.2 (or higher) is installed - Checks if .net 6 desktop runtime is installed - Checks if EFT is installed, +- Checks if there is enough space before install, - Checks installer is not in OG game directory, - Checks install folder does not have game files already in it, - Checks if gameversion matches aki version, if so skip patcher process, 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 new file mode 100644 index 0000000..59114d9 --- /dev/null +++ b/SPTInstaller/Helpers/DirectorySizeHelper.cs @@ -0,0 +1,29 @@ +using System.Linq; +using Serilog; + +namespace SPTInstaller.Helpers; + +public static class DirectorySizeHelper +{ + public static bool CheckAvailableSize(string eftSourceDirPath, string installTargetDirPath) + { + try + { + 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; + + return eftSourceDirSize < availableSize; + } + catch (Exception ex) + { + Log.Error(ex, "Error while checking available size"); + + 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 6fdafc8..28dae32 100644 --- a/SPTInstaller/Installer Tasks/IntializationTask.cs +++ b/SPTInstaller/Installer Tasks/IntializationTask.cs @@ -1,7 +1,6 @@ using SPTInstaller.Aki.Helper; using SPTInstaller.Interfaces; using SPTInstaller.Models; -using System.IO; using System.Threading.Tasks; namespace SPTInstaller.Installer_Tasks 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/SPTInstaller.csproj b/SPTInstaller/SPTInstaller.csproj index d6d32c4..7ae2630 100644 --- a/SPTInstaller/SPTInstaller.csproj +++ b/SPTInstaller/SPTInstaller.csproj @@ -9,8 +9,8 @@ icon.ico Assets\icon.ico Debug;Release;TEST - 2.2 - 2.2 + 2.3 + 2.3 diff --git a/SPTInstaller/ViewModels/PreChecksViewModel.cs b/SPTInstaller/ViewModels/PreChecksViewModel.cs index 4e8dbbf..5718b96 100644 --- a/SPTInstaller/ViewModels/PreChecksViewModel.cs +++ b/SPTInstaller/ViewModels/PreChecksViewModel.cs @@ -1,59 +1,54 @@ -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; + private bool _allowInstall; + + public ObservableCollection PreChecks { get; set; } = new(ServiceHelper.GetAll()); + public ICommand StartInstallCommand { 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 bool AllowInstall + { + get => _allowInstall; + set => this.RaiseAndSetIfChanged(ref _allowInstall, 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(); + AllowInstall = result.Succeeded; + }); + } +} \ No newline at end of file diff --git a/SPTInstaller/Views/PreChecksView.axaml b/SPTInstaller/Views/PreChecksView.axaml index 1058561..003e0d9 100644 --- a/SPTInstaller/Views/PreChecksView.axaml +++ b/SPTInstaller/Views/PreChecksView.axaml @@ -23,6 +23,7 @@ Margin="10" FontSize="15" FontWeight="SemiBold" Classes="yellow" + IsEnabled="{Binding AllowInstall}" Command="{Binding StartInstallCommand}" />