2023-07-12 08:32:57 +02:00
using System.Collections.ObjectModel ;
2024-02-06 18:59:39 -05:00
using System.Diagnostics ;
2023-08-03 18:02:38 -04:00
using System.Reflection ;
2023-07-12 08:32:57 +02:00
using System.Threading.Tasks ;
using System.Windows.Input ;
2023-08-23 22:45:41 -04:00
using Avalonia.Threading ;
2023-08-22 10:21:52 -04:00
using DialogHostAvalonia ;
2023-10-18 20:39:38 -04:00
using Gitea.Api ;
using Gitea.Client ;
2023-07-12 08:32:57 +02:00
using ReactiveUI ;
2023-07-29 14:26:45 -04:00
using Serilog ;
2023-05-11 23:11:39 -04:00
using SPTInstaller.Controllers ;
2023-08-25 23:46:11 -04:00
using SPTInstaller.CustomControls ;
2023-08-22 10:21:52 -04:00
using SPTInstaller.CustomControls.Dialogs ;
2023-05-11 23:11:39 -04:00
using SPTInstaller.Helpers ;
using SPTInstaller.Models ;
2023-07-12 08:32:57 +02:00
namespace SPTInstaller.ViewModels ;
public class PreChecksViewModel : ViewModelBase
2023-05-11 23:11:39 -04:00
{
2023-07-12 08:32:57 +02:00
public ObservableCollection < PreCheckBase > PreChecks { get ; set ; } = new ( ServiceHelper . GetAll < PreCheckBase > ( ) ) ;
public ICommand StartInstallCommand { get ; set ; }
2023-07-25 22:07:48 -04:00
public ICommand ShowDetailedViewCommand { get ; set ; }
2023-08-03 18:02:38 -04:00
public ICommand UpdateInstallerCommand { get ; set ; }
public ICommand DismissUpdateCommand { get ; set ; }
2024-02-06 18:59:39 -05:00
public ICommand LaunchWithDebug { get ; set ; }
2023-08-03 18:02:38 -04:00
2023-10-18 20:39:38 -04:00
public InstallerUpdateInfo UpdateInfo { get ; set ; } = new ( ) ;
2023-08-03 18:02:38 -04:00
2024-02-06 18:59:39 -05:00
private bool _debugging ;
public bool Debugging
{
get = > _debugging ;
set = > this . RaiseAndSetIfChanged ( ref _debugging , value ) ;
}
2023-08-03 18:02:38 -04:00
private string _installPath ;
2023-07-12 08:32:57 +02:00
public string InstallPath
{
get = > _installPath ;
set = > this . RaiseAndSetIfChanged ( ref _installPath , value ) ;
}
2023-10-18 20:39:38 -04:00
private string _installButtonText ;
public string InstallButtonText
{
get = > _installButtonText ;
set = > this . RaiseAndSetIfChanged ( ref _installButtonText , value ) ;
}
2023-07-12 09:00:00 +02:00
2023-08-03 18:02:38 -04:00
private bool _allowInstall ;
2023-07-30 16:15:52 -04:00
public bool AllowInstall
2023-07-12 09:00:00 +02:00
{
2023-07-12 16:39:37 +02:00
get = > _allowInstall ;
set = > this . RaiseAndSetIfChanged ( ref _allowInstall , value ) ;
2023-07-12 09:00:00 +02:00
}
2023-05-11 23:11:39 -04:00
2023-08-03 18:02:38 -04:00
private bool _allowDetailsButton = false ;
public bool AllowDetailsButton
{
get = > _allowDetailsButton ;
set = > this . RaiseAndSetIfChanged ( ref _allowDetailsButton , value ) ;
}
2023-08-25 23:46:11 -04:00
private string _cacheInfoText ;
public string CacheInfoText
{
get = > _cacheInfoText ;
set = > this . RaiseAndSetIfChanged ( ref _cacheInfoText , value ) ;
}
private StatusSpinner . SpinnerState _cacheCheckState ;
public StatusSpinner . SpinnerState CacheCheckState
{
get = > _cacheCheckState ;
set = > this . RaiseAndSetIfChanged ( ref _cacheCheckState , value ) ;
}
2023-10-18 20:39:38 -04:00
private StatusSpinner . SpinnerState _installButtonCheckState ;
public StatusSpinner . SpinnerState InstallButtonCheckState
{
get = > _installButtonCheckState ;
set = > this . RaiseAndSetIfChanged ( ref _installButtonCheckState , value ) ;
}
2023-08-25 23:46:11 -04:00
2023-11-09 10:32:36 -05:00
private void ReCheckRequested ( object? sender , EventArgs e )
{
Task . Run ( async ( ) = >
{
if ( sender is InstallController installer )
{
var result = await installer . RunPreChecks ( ) ;
AllowInstall = result . Succeeded ;
}
} ) ;
}
2024-02-06 18:59:39 -05:00
public PreChecksViewModel ( IScreen host , bool debugging ) : base ( host )
2023-07-12 08:32:57 +02:00
{
2024-02-06 18:59:39 -05:00
Debugging = debugging ;
2023-07-12 08:32:57 +02:00
var data = ServiceHelper . Get < InternalData ? > ( ) ;
var installer = ServiceHelper . Get < InstallController ? > ( ) ;
2023-05-11 23:11:39 -04:00
2023-11-09 10:32:36 -05:00
installer . RecheckRequested + = ReCheckRequested ;
2023-10-18 20:39:38 -04:00
InstallButtonText = "Please wait ..." ;
InstallButtonCheckState = StatusSpinner . SpinnerState . Pending ;
2023-07-12 08:32:57 +02:00
if ( data = = null | | installer = = null )
2023-05-11 23:11:39 -04:00
{
2023-07-12 08:32:57 +02:00
NavigateTo ( new MessageViewModel ( HostScreen , Result . FromError ( "Failed to get required service for prechecks" ) ) ) ;
return ;
}
2023-05-11 23:11:39 -04:00
2023-07-12 08:32:57 +02:00
data . OriginalGamePath = PreCheckHelper . DetectOriginalGamePath ( ) ;
2023-10-18 20:39:38 -04:00
data . TargetInstallPath = Environment . CurrentDirectory ;
InstallPath = data . TargetInstallPath ;
Log . Information ( $"Install Path: {FileHelper.GetRedactedPath(InstallPath)}" ) ;
2023-07-27 10:03:24 -04:00
2023-08-22 10:21:52 -04:00
#if ! TEST
2023-07-27 10:03:24 -04:00
if ( data . OriginalGamePath = = null )
{
NavigateTo ( new MessageViewModel ( HostScreen , Result . FromError ( "Could not find EFT install.\n\nDo you own and have the game installed?" ) ) ) ;
2023-09-16 16:49:24 -04:00
return ;
2023-07-27 10:03:24 -04:00
}
2023-08-22 10:21:52 -04:00
#endif
2023-07-27 10:03:24 -04:00
2023-09-16 16:49:24 -04:00
if ( data . OriginalGamePath = = data . TargetInstallPath )
{
Log . CloseAndFlush ( ) ;
var logFiles = Directory . GetFiles ( InstallPath , "spt-aki-installer_*.log" ) ;
// remove log file from original game path if they exist
foreach ( var file in logFiles )
{
try
{
File . Delete ( file ) ;
}
catch { }
}
NavigateTo ( new MessageViewModel ( HostScreen , Result . FromError ( "Installer is located in EFT's original directory. Please move the installer to a seperate folder as per the guide" ) , noLog : true ) ) ;
return ;
}
2023-08-23 22:45:41 -04:00
Task . Run ( async ( ) = >
2023-07-30 16:15:52 -04:00
{
2023-09-26 08:57:27 -04:00
if ( FileHelper . CheckPathForProblemLocations ( InstallPath , out var detectedName ) )
2023-08-22 10:21:52 -04:00
{
2023-08-23 22:45:41 -04:00
await Dispatcher . UIThread . InvokeAsync ( async ( ) = >
2023-08-22 10:21:52 -04:00
{
2023-08-23 22:45:41 -04:00
Log . Warning ( "Problem folder detected, confirming install path ..." ) ;
2023-09-26 08:57:27 -04:00
var confirmation = await DialogHost . Show ( new ConfirmationDialog ( $"We suspect you may be installing into a problematic folder: {detectedName}.\nYou might want to consider installing somewhere else to avoid issues.\n\nAre you sure you want to install to this path?\n{InstallPath}" ) ) ;
2023-08-23 22:45:41 -04:00
if ( confirmation = = null | | ! bool . TryParse ( confirmation . ToString ( ) , out var confirm ) | | ! confirm )
{
Log . Information ( "User declined install path, exiting" ) ;
Environment . Exit ( 0 ) ;
}
} ) ;
Log . Information ( "User accepted install path" ) ;
2023-08-22 10:21:52 -04:00
}
2023-08-23 22:45:41 -04:00
} ) ;
2023-08-22 10:21:52 -04:00
2024-02-06 18:59:39 -05:00
LaunchWithDebug = ReactiveCommand . Create ( async ( ) = >
{
try
{
var installerPath = Path . Join ( _installPath , "SPTInstaller.exe" ) ;
Process . Start ( new ProcessStartInfo ( )
{
FileName = installerPath ,
Arguments = "debug"
} ) ;
Environment . Exit ( 0 ) ;
}
catch ( Exception ex )
{
Log . Error ( ex , "Failed to enter debug mode" ) ;
}
} ) ;
2023-08-23 22:45:41 -04:00
StartInstallCommand = ReactiveCommand . Create ( async ( ) = >
{
2023-08-03 18:02:38 -04:00
UpdateInfo . ShowCard = false ;
2023-07-30 16:15:52 -04:00
NavigateTo ( new InstallViewModel ( HostScreen ) ) ;
} ) ;
2023-07-29 14:26:45 -04:00
ShowDetailedViewCommand = ReactiveCommand . Create ( ( ) = >
{
2023-08-03 18:02:38 -04:00
UpdateInfo . ShowCard = false ;
2023-07-29 14:26:45 -04:00
Log . Logger . Information ( "Opening Detailed PreCheck View" ) ;
2023-11-09 10:32:36 -05:00
installer . RecheckRequested - = ReCheckRequested ;
2024-02-06 18:59:39 -05:00
NavigateTo ( new DetailedPreChecksViewModel ( HostScreen , Debugging ) ) ;
2023-07-29 14:26:45 -04:00
} ) ;
2023-05-14 22:35:06 -04:00
2023-08-03 18:02:38 -04:00
UpdateInstallerCommand = ReactiveCommand . Create ( async ( ) = >
{
AllowDetailsButton = false ;
AllowInstall = false ;
await UpdateInfo . UpdateInstaller ( ) ;
} ) ;
DismissUpdateCommand = ReactiveCommand . Create ( ( ) = >
{
UpdateInfo . ShowCard = false ;
} ) ;
2023-07-12 08:32:57 +02:00
Task . Run ( async ( ) = >
{
2023-10-18 20:39:38 -04:00
// run prechecks
2023-07-12 08:32:57 +02:00
var result = await installer . RunPreChecks ( ) ;
2023-08-03 18:02:38 -04:00
2023-10-18 20:39:38 -04:00
// check for updates
2023-08-03 18:02:38 -04:00
await UpdateInfo . CheckForUpdates ( Assembly . GetExecutingAssembly ( ) . GetName ( ) ? . Version ) ;
2023-10-18 20:39:38 -04:00
// get latest spt version
InstallButtonText = "Getting latest release ..." ;
InstallButtonCheckState = StatusSpinner . SpinnerState . Running ;
var repo = new RepositoryApi ( Configuration . Default ) ;
var akiRepoReleases = await repo . RepoListReleasesAsync ( "SPT-AKI" , "Stable-releases" ) ;
if ( akiRepoReleases = = null | | akiRepoReleases . Count = = 0 )
{
InstallButtonText = "Could not get SPT releases from repo" ;
InstallButtonCheckState = StatusSpinner . SpinnerState . Error ;
return ;
}
var latestAkiRelease = akiRepoReleases . FindAll ( x = > ! x . Prerelease ) [ 0 ] ;
2023-08-03 18:02:38 -04:00
2023-10-18 20:39:38 -04:00
if ( latestAkiRelease = = null )
{
InstallButtonText = "Could not find the latest SPT release" ;
InstallButtonCheckState = StatusSpinner . SpinnerState . Error ;
return ;
}
InstallButtonText = $"Start Install: SPT v{latestAkiRelease.TagName}" ;
InstallButtonCheckState = StatusSpinner . SpinnerState . OK ;
2023-08-03 18:02:38 -04:00
AllowDetailsButton = true ;
2023-07-12 16:39:37 +02:00
AllowInstall = result . Succeeded ;
2023-07-12 08:32:57 +02:00
} ) ;
2023-08-25 23:46:11 -04:00
Task . Run ( ( ) = >
{
CacheInfoText = "Getting cache size ..." ;
CacheCheckState = StatusSpinner . SpinnerState . Running ;
CacheInfoText = $"Cache Size: {DownloadCacheHelper.GetCacheSizeText()}" ;
CacheCheckState = StatusSpinner . SpinnerState . OK ;
} ) ;
2023-05-11 23:11:39 -04:00
}
2023-07-12 08:32:57 +02:00
}