stuff
This commit is contained in:
parent
8331080d85
commit
e01729554b
@ -1,4 +1,5 @@
|
||||
using SharpCompress;
|
||||
using Serilog;
|
||||
using SharpCompress;
|
||||
using SPTInstaller.Interfaces;
|
||||
using SPTInstaller.Models;
|
||||
using System;
|
||||
@ -22,6 +23,7 @@ namespace SPTInstaller.Controllers
|
||||
|
||||
public async Task<IResult> RunPreChecks()
|
||||
{
|
||||
Log.Information("-<>--<>- Running PreChecks -<>--<>-");
|
||||
var requiredResults = new List<IResult>();
|
||||
|
||||
_preChecks.ForEach(x => x.IsPending = true);
|
||||
@ -30,6 +32,8 @@ namespace SPTInstaller.Controllers
|
||||
{
|
||||
var result = await check.RunCheck();
|
||||
|
||||
Log.Information($"PreCheck: {check.Name} ({(check.IsRequired ? "Required" : "Optional")}) -> {(result.Succeeded ? "Passed" : "Failed")}");
|
||||
|
||||
if (check.IsRequired)
|
||||
{
|
||||
requiredResults.Add(result);
|
||||
@ -47,6 +51,8 @@ namespace SPTInstaller.Controllers
|
||||
|
||||
public async Task<IResult> RunTasks()
|
||||
{
|
||||
Log.Information("-<>--<>- Running Installer Tasks -<>--<>-");
|
||||
|
||||
foreach (var task in _tasks)
|
||||
{
|
||||
TaskChanged?.Invoke(null, task);
|
||||
|
@ -77,7 +77,7 @@ namespace SPTInstaller.CustomControls
|
||||
|
||||
for(; TaskProgress < progress;)
|
||||
{
|
||||
TaskProgress += 2;
|
||||
TaskProgress += 1;
|
||||
await Task.Delay(1);
|
||||
}
|
||||
});
|
||||
|
@ -28,11 +28,12 @@
|
||||
<ProgressBar IsVisible="{Binding ShowProgress, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
Value="{Binding Progress, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
HorizontalAlignment="Stretch"
|
||||
IsIndeterminate="{Binding IndeterminateProgress, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
/>
|
||||
|
||||
<Label Grid.Column="1"
|
||||
Content="{Binding Progress, RelativeSource={RelativeSource AncestorType=UserControl}, StringFormat='{}{0}%'}"
|
||||
IsVisible="{Binding ShowProgress, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
IsVisible="{Binding !IndeterminateProgress, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
@ -45,5 +45,14 @@ namespace SPTInstaller.CustomControls
|
||||
|
||||
public static readonly StyledProperty<bool> ShowProgressProperty =
|
||||
AvaloniaProperty.Register<TaskDetails, bool>(nameof(ShowProgress));
|
||||
|
||||
public bool IndeterminateProgress
|
||||
{
|
||||
get => GetValue(IndeterminateProgressProperty);
|
||||
set => SetValue(IndeterminateProgressProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<bool> IndeterminateProgressProperty =
|
||||
AvaloniaProperty.Register<TaskDetails, bool>(nameof(IndeterminateProgress));
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using ReactiveUI;
|
||||
using Serilog;
|
||||
using SPTInstaller.Models;
|
||||
using System;
|
||||
using System.IO;
|
||||
@ -19,6 +20,7 @@ namespace SPTInstaller.Aki.Helper
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error while creating directories");
|
||||
return Result.FromError(ex.Message);
|
||||
}
|
||||
}
|
||||
@ -42,6 +44,7 @@ namespace SPTInstaller.Aki.Helper
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error while copying files");
|
||||
return Result.FromError(ex.Message);
|
||||
}
|
||||
}
|
||||
@ -65,6 +68,7 @@ namespace SPTInstaller.Aki.Helper
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error during directory copy");
|
||||
return Result.FromError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using SPTInstaller.Aki.Helper;
|
||||
using Serilog;
|
||||
using SPTInstaller.Aki.Helper;
|
||||
using SPTInstaller.Interfaces;
|
||||
using SPTInstaller.Models;
|
||||
using System;
|
||||
@ -18,12 +19,12 @@ namespace SPTInstaller.Installer_Tasks
|
||||
|
||||
public override async Task<IResult> TaskOperation()
|
||||
{
|
||||
SetStatus("Copying Client Files", 0);
|
||||
SetStatus("Copying Client Files", "", 0);
|
||||
|
||||
var originalGameDirInfo = new DirectoryInfo(_data.OriginalGamePath);
|
||||
var targetInstallDirInfo = new DirectoryInfo(_data.TargetInstallPath);
|
||||
|
||||
return FileHelper.CopyDirectoryWithProgress(originalGameDirInfo, targetInstallDirInfo, (message, progress) => { SetStatus($"Copying Client Files", message, progress); });
|
||||
return FileHelper.CopyDirectoryWithProgress(originalGameDirInfo, targetInstallDirInfo, (message, progress) => { SetStatus($"Copying Client Files", message, progress, null, true); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ namespace SPTInstaller.Installer_Tasks
|
||||
|
||||
private async Task<IResult> BuildMirrorList()
|
||||
{
|
||||
var progress = new Progress<double>((d) => { SetStatus("Downloading Mirror List", (int)Math.Floor(d));});
|
||||
var progress = new Progress<double>((d) => { SetStatus("Downloading Mirror List", "", (int)Math.Floor(d));});
|
||||
|
||||
var file = await DownloadCacheHelper.GetOrDownloadFileAsync("mirrors.json", _data.PatcherMirrorsLink, progress);
|
||||
|
||||
@ -46,7 +46,7 @@ namespace SPTInstaller.Installer_Tasks
|
||||
{
|
||||
foreach (var mirror in _data.PatcherReleaseMirrors)
|
||||
{
|
||||
SetStatus($"Downloading Patcher: {mirror.Link}");
|
||||
SetStatus($"Downloading Patcher", mirror.Link);
|
||||
|
||||
// mega is a little weird since they use encryption, but thankfully there is a great library for their api :)
|
||||
if (mirror.Link.StartsWith("https://mega"))
|
||||
@ -90,7 +90,7 @@ namespace SPTInstaller.Installer_Tasks
|
||||
|
||||
public override async Task<IResult> TaskOperation()
|
||||
{
|
||||
var progress = new Progress<double>((d) => { SetStatus("", (int)Math.Floor(d)); });
|
||||
var progress = new Progress<double>((d) => { SetStatus("", "", (int)Math.Floor(d)); });
|
||||
|
||||
if (_data.PatchNeeded)
|
||||
{
|
||||
@ -101,7 +101,7 @@ namespace SPTInstaller.Installer_Tasks
|
||||
return buildResult;
|
||||
}
|
||||
|
||||
SetStatus("", 0);
|
||||
SetStatus("", "", 0);
|
||||
|
||||
var patcherDownloadRresult = await DownloadPatcherFromMirrors(progress);
|
||||
|
||||
@ -111,7 +111,7 @@ namespace SPTInstaller.Installer_Tasks
|
||||
}
|
||||
}
|
||||
|
||||
SetStatus("Downloading SPT-AKI", 0);
|
||||
SetStatus("Downloading SPT-AKI", "", 0);
|
||||
|
||||
_data.AkiZipInfo = await DownloadCacheHelper.GetOrDownloadFileAsync("sptaki.zip", _data.AkiReleaseDownloadLink, progress, _data.AkiReleaseHash);
|
||||
|
||||
|
@ -25,11 +25,11 @@ namespace SPTInstaller.Installer_Tasks
|
||||
|
||||
var repo = new RepositoryApi(Configuration.Default);
|
||||
|
||||
SetStatus("Checking SPT Releases");
|
||||
SetStatus("Checking SPT Releases", "", null, ProgressStyle.Indeterminate);
|
||||
|
||||
var akiRepoReleases = await repo.RepoListReleasesAsync("SPT-AKI", "Stable-releases");
|
||||
|
||||
SetStatus("Checking for Patches");
|
||||
SetStatus("Checking for Patches", "", null, ProgressStyle.Indeterminate);
|
||||
|
||||
var patchRepoReleases = await repo.RepoListReleasesAsync("SPT-AKI", "Downgrade-Patches");
|
||||
|
||||
@ -75,6 +75,8 @@ namespace SPTInstaller.Installer_Tasks
|
||||
status += " - Patch Available";
|
||||
}
|
||||
|
||||
SetStatus("", status);
|
||||
|
||||
return Result.FromSuccess(status);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -25,13 +25,13 @@ namespace SPTInstaller.Installer_Tasks
|
||||
|
||||
var patcherEXE = new FileInfo(Path.Join(_data.TargetInstallPath, "patcher.exe"));
|
||||
|
||||
var progress = new Progress<double>((d) => { SetStatus("", (int)Math.Floor(d)); });
|
||||
var progress = new Progress<double>((d) => { SetStatus("", "", (int)Math.Floor(d)); });
|
||||
|
||||
|
||||
if (_data.PatchNeeded)
|
||||
{
|
||||
// extract patcher files
|
||||
SetStatus("Extrating Patcher", 0);
|
||||
SetStatus("Extrating Patcher", "", 0);
|
||||
|
||||
var extractPatcherResult = ZipHelper.Decompress(_data.PatcherZipInfo, patcherOutputDir, progress);
|
||||
|
||||
@ -41,7 +41,7 @@ namespace SPTInstaller.Installer_Tasks
|
||||
}
|
||||
|
||||
// copy patcher files to install directory
|
||||
SetStatus("Copying Patcher", 0);
|
||||
SetStatus("Copying Patcher", "", 0);
|
||||
|
||||
var patcherDirInfo = patcherOutputDir.GetDirectories("Patcher*", SearchOption.TopDirectoryOnly).First();
|
||||
|
||||
@ -53,10 +53,7 @@ namespace SPTInstaller.Installer_Tasks
|
||||
}
|
||||
|
||||
// run patcher
|
||||
SetStatus("Running Patcher");
|
||||
|
||||
// TODO: indeterminate progress indicator
|
||||
//StartDrawingIndeterminateProgress();
|
||||
SetStatus("Running Patcher", "", null, ProgressStyle.Indeterminate);
|
||||
|
||||
var patchingResult = ProcessHelper.PatchClientFiles(patcherEXE, targetInstallDirInfo);
|
||||
|
||||
@ -67,7 +64,7 @@ namespace SPTInstaller.Installer_Tasks
|
||||
}
|
||||
|
||||
// extract release files
|
||||
SetStatus("Extracting Release", 0);
|
||||
SetStatus("Extracting Release", "", 0);
|
||||
|
||||
var extractReleaseResult = ZipHelper.Decompress(_data.AkiZipInfo, targetInstallDirInfo, progress);
|
||||
|
||||
@ -77,10 +74,7 @@ namespace SPTInstaller.Installer_Tasks
|
||||
}
|
||||
|
||||
// cleanup temp files
|
||||
SetStatus("Cleanup");
|
||||
|
||||
// TODO: indeterminate progress indicator
|
||||
//StartDrawingIndeterminateProgress();
|
||||
SetStatus("Cleanup", "almost done :)", null, ProgressStyle.Indeterminate);
|
||||
|
||||
if(_data.PatchNeeded)
|
||||
{
|
||||
|
@ -1,7 +1,10 @@
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using Serilog;
|
||||
using Splat;
|
||||
using SPTInstaller.Interfaces;
|
||||
using System;
|
||||
using System.Security;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SPTInstaller.Models
|
||||
@ -57,6 +60,13 @@ namespace SPTInstaller.Models
|
||||
private set => this.RaiseAndSetIfChanged(ref _showProgress, value);
|
||||
}
|
||||
|
||||
private bool _indeterminateProgress;
|
||||
public bool IndeterminateProgress
|
||||
{
|
||||
get => _indeterminateProgress;
|
||||
private set => this.RaiseAndSetIfChanged(ref _indeterminateProgress, value);
|
||||
}
|
||||
|
||||
private string _statusMessage;
|
||||
public string StatusMessage
|
||||
{
|
||||
@ -71,28 +81,65 @@ namespace SPTInstaller.Models
|
||||
private set => this.RaiseAndSetIfChanged(ref _statusDetails, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the status message and optionally a progress bar value
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="progress"></param>
|
||||
/// <remarks>If message is empty, it isn't updated. If progress is null, the progress bar will be hidden. Details is not touched with this method</remarks>
|
||||
public void SetStatus(string message, int? progress = null) => SetStatus(message, "", progress);
|
||||
public enum ProgressStyle
|
||||
{
|
||||
Hidden = 0,
|
||||
Shown,
|
||||
Indeterminate,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the status message, status details, and optionlly a progress bar value
|
||||
/// Update the status details of the task
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="progress"></param>
|
||||
/// <remarks>If message or details are empty, it isn't updated. If progress is null, the progress bar will be hidden</remarks>
|
||||
public void SetStatus(string message, string details, int? progress = null)
|
||||
/// <param name="message">The main message to display. Not updated if empty</param>
|
||||
/// <param name="details">The details of the task. Not updated if empty</param>
|
||||
/// <param name="progress">Progress of the task. Not empty if null. Overrides progressStyle if a non-null value is supplied</param>
|
||||
/// <param name="progressStyle">The style of the progress bar</param>
|
||||
public void SetStatus(string message, string details, int? progress = null, ProgressStyle? progressStyle = null, bool noLog = false)
|
||||
{
|
||||
StatusMessage = String.IsNullOrWhiteSpace(message) ? StatusMessage : message;
|
||||
StatusDetails = String.IsNullOrWhiteSpace(details) ? StatusDetails : details;
|
||||
ShowProgress = progress != null;
|
||||
if(!string.IsNullOrWhiteSpace(message) && message != StatusMessage)
|
||||
{
|
||||
if (!noLog)
|
||||
{
|
||||
Log.Information($" <===> {message} <===>");
|
||||
}
|
||||
|
||||
StatusMessage = message;
|
||||
}
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(details) && details != StatusDetails)
|
||||
{
|
||||
if (!noLog)
|
||||
{
|
||||
Log.Information(details);
|
||||
}
|
||||
|
||||
StatusDetails = details;
|
||||
}
|
||||
|
||||
if (progressStyle != null)
|
||||
{
|
||||
switch (progressStyle)
|
||||
{
|
||||
case ProgressStyle.Hidden:
|
||||
ShowProgress = false;
|
||||
IndeterminateProgress = false;
|
||||
break;
|
||||
case ProgressStyle.Shown:
|
||||
ShowProgress = true;
|
||||
IndeterminateProgress = false;
|
||||
break;
|
||||
case ProgressStyle.Indeterminate:
|
||||
ShowProgress = true;
|
||||
IndeterminateProgress = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (progress != null)
|
||||
{
|
||||
ShowProgress = true;
|
||||
IndeterminateProgress = false;
|
||||
Progress = progress.Value;
|
||||
}
|
||||
}
|
||||
@ -117,7 +164,9 @@ namespace SPTInstaller.Models
|
||||
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
// TODO: handle error state
|
||||
HasErrors = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
IsCompleted = true;
|
||||
|
@ -1,6 +1,7 @@
|
||||
using Avalonia;
|
||||
using Avalonia.ReactiveUI;
|
||||
using ReactiveUI;
|
||||
using Serilog;
|
||||
using Splat;
|
||||
using SPTInstaller.Controllers;
|
||||
using SPTInstaller.Helpers;
|
||||
@ -9,6 +10,7 @@ using SPTInstaller.Installer_Tasks.PreChecks;
|
||||
using SPTInstaller.Interfaces;
|
||||
using SPTInstaller.Models;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
@ -34,13 +36,23 @@ namespace SPTInstaller
|
||||
ServiceHelper.Register<PreCheckBase, NetFramework472PreCheck>();
|
||||
ServiceHelper.Register<PreCheckBase, NetCore6PreCheck>();
|
||||
#if !TEST
|
||||
string logPath = Path.Join(Environment.CurrentDirectory, "spt-aki-installer_.log");
|
||||
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Debug()
|
||||
.WriteTo
|
||||
.File(path: logPath,
|
||||
restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Debug,
|
||||
rollingInterval: RollingInterval.Day)
|
||||
.CreateLogger();
|
||||
|
||||
ServiceHelper.Register<InstallerTaskBase, InitializationTask>();
|
||||
ServiceHelper.Register<InstallerTaskBase, ReleaseCheckTask>();
|
||||
ServiceHelper.Register<InstallerTaskBase, DownloadTask>();
|
||||
ServiceHelper.Register<InstallerTaskBase, CopyClientTask>();
|
||||
ServiceHelper.Register<InstallerTaskBase, SetupClientTask>();
|
||||
#else
|
||||
for(int i = 0; i < 5; i++)
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
Locator.CurrentMutable.RegisterConstant<InstallerTaskBase>(TestTask.FromRandomName());
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
<PackageReference Include="FubarCoder.RestSharp.Portable.HttpClient" Version="4.0.8" />
|
||||
<PackageReference Include="MegaApiClient" Version="1.10.3" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.33.0" />
|
||||
<PackageReference Include="XamlNameReferenceGenerator" Version="1.6.1" />
|
||||
</ItemGroup>
|
||||
|
@ -1,5 +1,7 @@
|
||||
using Avalonia;
|
||||
using ReactiveUI;
|
||||
using Serilog;
|
||||
using System;
|
||||
|
||||
namespace SPTInstaller.ViewModels
|
||||
{
|
||||
@ -10,6 +12,9 @@ namespace SPTInstaller.ViewModels
|
||||
|
||||
public MainWindowViewModel()
|
||||
{
|
||||
Log.Information("========= LAUNCHER STARTED =========");
|
||||
Log.Information(Environment.OSVersion.VersionString);
|
||||
|
||||
Router.Navigate.Execute(new PreChecksViewModel(this));
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Avalonia;
|
||||
using ReactiveUI;
|
||||
using Serilog;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace SPTInstaller.ViewModels
|
||||
@ -24,6 +25,7 @@ namespace SPTInstaller.ViewModels
|
||||
public MessageViewModel(IScreen Host, string message) : base(Host)
|
||||
{
|
||||
Message = message;
|
||||
Log.Information(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,8 @@ namespace SPTInstaller.ViewModels
|
||||
|
||||
if(data == null || installer == null)
|
||||
{
|
||||
// TODO: abort to message view
|
||||
NavigateTo(new MessageViewModel(HostScreen, "Failed to get required service for prechecks"));
|
||||
return;
|
||||
}
|
||||
|
||||
data.TargetInstallPath = Environment.CurrentDirectory;
|
||||
@ -45,8 +46,13 @@ namespace SPTInstaller.ViewModels
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
// TODO: if a required precheck fails, abort to message view
|
||||
var result = await installer.RunPreChecks();
|
||||
|
||||
if(!result.Succeeded)
|
||||
{
|
||||
//if a required precheck fails, abort to message view
|
||||
NavigateTo(new MessageViewModel(HostScreen ,result.Message));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
Message="{Binding CurrentTask.StatusMessage}"
|
||||
Details="{Binding CurrentTask.StatusDetails}"
|
||||
Progress="{Binding CurrentTask.Progress}"
|
||||
IndeterminateProgress="{Binding CurrentTask.IndeterminateProgress}"
|
||||
ShowProgress="{Binding CurrentTask.ShowProgress}"
|
||||
/>
|
||||
</Grid>
|
||||
|
Loading…
x
Reference in New Issue
Block a user