diff --git a/.editorconfig b/.editorconfig
index 2287241..d41de40 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,5 +1,4 @@
-
-[*]
+[*]
charset = utf-8-bom
end_of_line = crlf
trim_trailing_whitespace = false
@@ -8,7 +7,7 @@ indent_style = space
indent_size = 4
# Microsoft .NET properties
-csharp_style_namespace_declarations=file_scoped:error
+csharp_style_namespace_declarations = file_scoped:error
csharp_new_line_before_members_in_object_initializers = false
csharp_preferred_modifier_order = public, private, protected, internal, file, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async, required:warning
csharp_style_prefer_utf8_string_literals = true:suggestion
diff --git a/SPTInstaller/App.axaml b/SPTInstaller/App.axaml
index 1c0a3d8..fc2db57 100644
--- a/SPTInstaller/App.axaml
+++ b/SPTInstaller/App.axaml
@@ -5,7 +5,7 @@
xmlns:dialogHostAvalonia="clr-namespace:DialogHostAvalonia;assembly=DialogHost.Avalonia"
RequestedThemeVariant="Light">
-
+
@@ -13,38 +13,40 @@
-
+
-
- #121212
- #FFC107
- #FFFFFF
- #282828
- #323947
+
+ #121212
+ #FFC107
+ #FFFFFF
+ #282828
+ #323947
#444259
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+ FillRule="NonZero" />
+
+
\ No newline at end of file
diff --git a/SPTInstaller/App.axaml.cs b/SPTInstaller/App.axaml.cs
index a43aaa9..c1e97d9 100644
--- a/SPTInstaller/App.axaml.cs
+++ b/SPTInstaller/App.axaml.cs
@@ -13,6 +13,7 @@ namespace SPTInstaller;
public partial class App : Application
{
private readonly string _logPath = Path.Join(Environment.CurrentDirectory, "spt-aki-installer_.log");
+
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
@@ -24,14 +25,13 @@ public partial class App : Application
restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Information,
rollingInterval: RollingInterval.Day)
.CreateLogger();
-
+
RxApp.DefaultExceptionHandler = Observer.Create((exception) =>
{
Log.Error(exception, "An application exception occurred");
});
-
}
-
+
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
@@ -57,7 +57,7 @@ public partial class App : Application
DataContext = new MainWindowViewModel(debug),
};
}
-
+
base.OnFrameworkInitializationCompleted();
}
}
\ No newline at end of file
diff --git a/SPTInstaller/Assets/Styles.axaml b/SPTInstaller/Assets/Styles.axaml
index ce89e48..c1206e1 100644
--- a/SPTInstaller/Assets/Styles.axaml
+++ b/SPTInstaller/Assets/Styles.axaml
@@ -1,267 +1,268 @@
-
-
-
+
-
+
-
-
+
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
-
-
-
+
+
+
-
+
-
-
+
+
+ Classes.selected="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=UserControl}}">
-
-
-
+
+
+ ConverterParameter=Running}" />
-
+
\ No newline at end of file
diff --git a/SPTInstaller/CustomControls/PreCheckItem.axaml.cs b/SPTInstaller/CustomControls/PreCheckItem.axaml.cs
index 57ae999..f0efa91 100644
--- a/SPTInstaller/CustomControls/PreCheckItem.axaml.cs
+++ b/SPTInstaller/CustomControls/PreCheckItem.axaml.cs
@@ -10,47 +10,47 @@ public partial class PreCheckItem : UserControl
{
InitializeComponent();
}
-
+
public string PreCheckName
{
get => GetValue(PreCheckNameProperty);
set => SetValue(PreCheckNameProperty, value);
}
-
+
public static readonly StyledProperty PreCheckNameProperty =
AvaloniaProperty.Register(nameof(PreCheckName));
-
+
public bool IsRequired
{
get => GetValue(IsRequiredProperty);
set => SetValue(IsRequiredProperty, value);
}
-
+
public static readonly StyledProperty IsRequiredProperty =
AvaloniaProperty.Register(nameof(IsRequired));
-
+
public StatusSpinner.SpinnerState State
{
get => GetValue(StateProperty);
set => SetValue(StateProperty, value);
}
-
+
public static readonly StyledProperty StateProperty =
AvaloniaProperty.Register(nameof(State));
-
-
+
+
public static readonly StyledProperty IsSelectedProperty =
AvaloniaProperty.Register(nameof(IsSelected));
-
+
public bool IsSelected
{
get => GetValue(IsSelectedProperty);
set => SetValue(IsSelectedProperty, value);
}
-
+
public static readonly StyledProperty SelectCommandProperty =
AvaloniaProperty.Register(nameof(SelectCommand));
-
+
public ICommand SelectCommand
{
get => GetValue(SelectCommandProperty);
diff --git a/SPTInstaller/CustomControls/ProgressableTaskItem.axaml b/SPTInstaller/CustomControls/ProgressableTaskItem.axaml
index b96ece5..9b18c05 100644
--- a/SPTInstaller/CustomControls/ProgressableTaskItem.axaml
+++ b/SPTInstaller/CustomControls/ProgressableTaskItem.axaml
@@ -2,78 +2,83 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:vm="using:SPTInstaller.ViewModels"
+ xmlns:vm="using:SPTInstaller.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SPTInstaller.CustomControls.ProgressableTaskItem">
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SPTInstaller/CustomControls/ProgressableTaskItem.axaml.cs b/SPTInstaller/CustomControls/ProgressableTaskItem.axaml.cs
index ceaf72c..6d27b11 100644
--- a/SPTInstaller/CustomControls/ProgressableTaskItem.axaml.cs
+++ b/SPTInstaller/CustomControls/ProgressableTaskItem.axaml.cs
@@ -10,67 +10,67 @@ public partial class ProgressableTaskItem : UserControl
{
InitializeComponent();
}
-
+
public string TaskId
{
get => GetValue(TaskIdProperty);
set => SetValue(TaskIdProperty, value);
}
-
+
public static readonly StyledProperty TaskIdProperty =
AvaloniaProperty.Register(nameof(TaskId));
-
+
public string TaskName
{
get => GetValue(TaskNameProperty);
set => SetValue(TaskNameProperty, value);
}
-
+
public static readonly StyledProperty TaskNameProperty =
AvaloniaProperty.Register(nameof(TaskName));
-
+
public bool IsCompleted
{
get => GetValue(IsCompletedProperty);
set => SetValue(IsCompletedProperty, value);
}
-
+
public static readonly StyledProperty IsCompletedProperty =
AvaloniaProperty.Register(nameof(IsCompleted));
-
+
public bool IsRunning
{
get => GetValue(IsRunningProperty);
set => SetValue(IsRunningProperty, value);
}
-
+
public static readonly StyledProperty IsRunningProperty =
AvaloniaProperty.Register(nameof(IsRunning));
-
+
public IBrush PendingColor
{
get => GetValue(PendingColorProperty);
set => SetValue(PendingColorProperty, value);
}
-
+
public static readonly StyledProperty PendingColorProperty =
AvaloniaProperty.Register(nameof(PendingColor));
-
+
public IBrush RunningColor
{
get => GetValue(RunningColorProperty);
set => SetValue(RunningColorProperty, value);
}
-
+
public static readonly StyledProperty RunningColorProperty =
AvaloniaProperty.Register(nameof(PendingColor));
-
+
public IBrush CompletedColor
{
get => GetValue(CompletedColorProperty);
set => SetValue(CompletedColorProperty, value);
}
-
+
public static readonly StyledProperty CompletedColorProperty =
AvaloniaProperty.Register(nameof(PendingColor));
}
\ No newline at end of file
diff --git a/SPTInstaller/CustomControls/ProgressableTaskList.axaml b/SPTInstaller/CustomControls/ProgressableTaskList.axaml
index 5ca8c06..97d8832 100644
--- a/SPTInstaller/CustomControls/ProgressableTaskList.axaml
+++ b/SPTInstaller/CustomControls/ProgressableTaskList.axaml
@@ -2,15 +2,14 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:cc="using:SPTInstaller.CustomControls"
- xmlns:bh="using:SPTInstaller.Behaviors"
- xmlns:convt="using:SPTInstaller.Converters"
+ xmlns:cc="using:SPTInstaller.CustomControls"
+ xmlns:bh="using:SPTInstaller.Behaviors"
+ xmlns:convt="using:SPTInstaller.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- x:Class="SPTInstaller.CustomControls.ProgressableTaskList"
- >
-
-
-
+ x:Class="SPTInstaller.CustomControls.ProgressableTaskList">
+
+
+
-
+ Margin="25 20" />
+
-
+
@@ -36,10 +35,9 @@
IsCompleted="{Binding IsCompleted}"
PendingColor="{Binding PendingColor, RelativeSource={RelativeSource AncestorType=UserControl}}"
RunningColor="{Binding RunningColor, RelativeSource={RelativeSource AncestorType=UserControl}}"
- CompletedColor="{Binding CompletedColor, RelativeSource={RelativeSource AncestorType=UserControl}}"
- />
+ CompletedColor="{Binding CompletedColor, RelativeSource={RelativeSource AncestorType=UserControl}}" />
-
+
\ No newline at end of file
diff --git a/SPTInstaller/CustomControls/ProgressableTaskList.axaml.cs b/SPTInstaller/CustomControls/ProgressableTaskList.axaml.cs
index 6d85212..1dc0d6d 100644
--- a/SPTInstaller/CustomControls/ProgressableTaskList.axaml.cs
+++ b/SPTInstaller/CustomControls/ProgressableTaskList.axaml.cs
@@ -15,76 +15,77 @@ public partial class ProgressableTaskList : UserControl
public ProgressableTaskList()
{
InitializeComponent();
-
+
this.AttachedToVisualTree += ProgressableTaskList_AttachedToVisualTree;
}
-
+
private int _taskProgress;
+
public int TaskProgress
{
get => _taskProgress;
set => SetAndRaise(ProgressableTaskList.TaskProgressProperty, ref _taskProgress, value);
}
-
+
public static readonly DirectProperty TaskProgressProperty =
AvaloniaProperty.RegisterDirect(nameof(TaskProgress), o => o.TaskProgress);
-
+
public ObservableCollection Tasks
{
get => GetValue(TasksProperty);
set => SetValue(TasksProperty, value);
}
-
+
public static readonly StyledProperty> TasksProperty =
AvaloniaProperty.Register>(nameof(Tasks));
-
+
public IBrush PendingColor
{
get => GetValue(PendingColorProperty);
set => SetValue(PendingColorProperty, value);
}
-
+
public static readonly StyledProperty PendingColorProperty =
AvaloniaProperty.Register(nameof(PendingColor));
-
+
public IBrush RunningColor
{
get => GetValue(RunningColorProperty);
set => SetValue(RunningColorProperty, value);
}
-
+
public static readonly StyledProperty RunningColorProperty =
AvaloniaProperty.Register(nameof(PendingColor));
-
+
public IBrush CompletedColor
{
get => GetValue(CompletedColorProperty);
set => SetValue(CompletedColorProperty, value);
}
-
+
public static readonly StyledProperty CompletedColorProperty =
AvaloniaProperty.Register(nameof(PendingColor));
-
+
private void UpdateTaskProgress()
{
Dispatcher.UIThread.InvokeAsync(async () =>
{
var completedTasks = Tasks.Where(x => x.IsCompleted == true).Count();
-
+
var progress = (int)Math.Floor((double)completedTasks / (Tasks.Count - 1) * 100);
-
- for(; TaskProgress < progress;)
+
+ for (; TaskProgress < progress;)
{
TaskProgress += 1;
await Task.Delay(1);
}
});
}
-
+
private void ProgressableTaskList_AttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{
if (Tasks == null) return;
-
+
foreach (var task in Tasks)
{
task.WhenPropertyChanged(x => x.IsCompleted)
diff --git a/SPTInstaller/CustomControls/StatusSpinner.axaml b/SPTInstaller/CustomControls/StatusSpinner.axaml
index c10b421..2bea27d 100644
--- a/SPTInstaller/CustomControls/StatusSpinner.axaml
+++ b/SPTInstaller/CustomControls/StatusSpinner.axaml
@@ -4,56 +4,55 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:convt="using:SPTInstaller.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- x:Class="SPTInstaller.CustomControls.StatusSpinner"
- >
+ x:Class="SPTInstaller.CustomControls.StatusSpinner">
-
-
+
+
-
+
-
+
+ ConverterParameter=Running}" />
-
+
\ No newline at end of file
diff --git a/SPTInstaller/CustomControls/StatusSpinner.axaml.cs b/SPTInstaller/CustomControls/StatusSpinner.axaml.cs
index d845467..ce812cb 100644
--- a/SPTInstaller/CustomControls/StatusSpinner.axaml.cs
+++ b/SPTInstaller/CustomControls/StatusSpinner.axaml.cs
@@ -10,22 +10,22 @@ public partial class StatusSpinner : ReactiveUserControl
{
Pending = -1,
Running = 0,
- OK = 1,
+ OK = 1,
Warning = 2,
- Error = 3,
+ Error = 3,
}
-
+
public StatusSpinner()
{
InitializeComponent();
}
-
+
public SpinnerState State
{
get => GetValue(StateProperty);
set => SetValue(StateProperty, value);
}
-
+
public static readonly StyledProperty StateProperty =
AvaloniaProperty.Register(nameof(State));
-}
+}
\ No newline at end of file
diff --git a/SPTInstaller/CustomControls/TaskDetails.axaml b/SPTInstaller/CustomControls/TaskDetails.axaml
index b4f7186..b79e0bd 100644
--- a/SPTInstaller/CustomControls/TaskDetails.axaml
+++ b/SPTInstaller/CustomControls/TaskDetails.axaml
@@ -4,37 +4,33 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SPTInstaller.CustomControls.TaskDetails">
-
-
-
+
-
+
-
-
-
+
-
-
-
-
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SPTInstaller/CustomControls/TaskDetails.axaml.cs b/SPTInstaller/CustomControls/TaskDetails.axaml.cs
index 31132c4..0ca01fb 100644
--- a/SPTInstaller/CustomControls/TaskDetails.axaml.cs
+++ b/SPTInstaller/CustomControls/TaskDetails.axaml.cs
@@ -9,49 +9,49 @@ public partial class TaskDetails : UserControl
{
InitializeComponent();
}
-
+
public string Message
{
get => GetValue(MessageProperty);
set => SetValue(MessageProperty, value);
}
-
+
public static readonly StyledProperty MessageProperty =
AvaloniaProperty.Register(nameof(Message));
-
+
public string Details
{
get => GetValue(DetailsProperty);
set => SetValue(DetailsProperty, value);
}
-
+
public static readonly StyledProperty DetailsProperty =
AvaloniaProperty.Register(nameof(Details));
-
+
public int Progress
{
get => GetValue(ProgressProperty);
set => SetValue(ProgressProperty, value);
}
-
+
public static readonly StyledProperty ProgressProperty =
AvaloniaProperty.Register(nameof(Progress));
-
+
public bool ShowProgress
{
get => GetValue(ShowProgressProperty);
set => SetValue(ShowProgressProperty, value);
}
-
+
public static readonly StyledProperty ShowProgressProperty =
AvaloniaProperty.Register(nameof(ShowProgress));
-
+
public bool IndeterminateProgress
{
get => GetValue(IndeterminateProgressProperty);
set => SetValue(IndeterminateProgressProperty, value);
}
-
+
public static readonly StyledProperty IndeterminateProgressProperty =
AvaloniaProperty.Register(nameof(IndeterminateProgress));
}
\ No newline at end of file
diff --git a/SPTInstaller/CustomControls/TitleBar.axaml b/SPTInstaller/CustomControls/TitleBar.axaml
index e78e5c1..be6e3f4 100644
--- a/SPTInstaller/CustomControls/TitleBar.axaml
+++ b/SPTInstaller/CustomControls/TitleBar.axaml
@@ -5,72 +5,68 @@
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SPTInstaller.CustomControls.TitleBar">
-
+
-
+
-
+ Background="Transparent"
+ VerticalContentAlignment="Center" />
-
-
-
-
-
-
-
+ Background="Transparent"
+ HorizontalContentAlignment="Center"
+ VerticalContentAlignment="Center"
+ VerticalAlignment="Stretch"
+ FontFamily="Segoe MDL2 Assets"
+ CornerRadius="0"
+ Width="35">
+
+
+
+
+
-
-
-
-
-
-
-
+ Background="Transparent"
+ HorizontalContentAlignment="Center"
+ VerticalContentAlignment="Center"
+ VerticalAlignment="Stretch"
+ FontFamily="Segoe MDL2 Assets"
+ CornerRadius="0"
+ Width="35">
+
+
+
+
+
-
+
-
+
\ No newline at end of file
diff --git a/SPTInstaller/CustomControls/TitleBar.axaml.cs b/SPTInstaller/CustomControls/TitleBar.axaml.cs
index fc17d58..ff40a70 100644
--- a/SPTInstaller/CustomControls/TitleBar.axaml.cs
+++ b/SPTInstaller/CustomControls/TitleBar.axaml.cs
@@ -12,62 +12,62 @@ public partial class TitleBar : UserControl
{
InitializeComponent();
}
-
+
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
-
+
public static readonly StyledProperty TitleProperty =
AvaloniaProperty.Register(nameof(Title));
-
+
public string Title
{
get => GetValue(TitleProperty);
set => SetValue(TitleProperty, value);
}
-
+
public static readonly StyledProperty ButtonForegroundProperty =
AvaloniaProperty.Register(nameof(ButtonForeground));
-
+
public IBrush ButtonForeground
{
get => GetValue(ButtonForegroundProperty);
set => SetValue(ButtonForegroundProperty, value);
}
-
+
public static new readonly StyledProperty ForegroundProperty =
AvaloniaProperty.Register(nameof(Foreground));
-
+
public new IBrush Foreground
{
get => GetValue(ForegroundProperty);
set => SetValue(ForegroundProperty, value);
}
-
+
public static new readonly StyledProperty BackgroundProperty =
AvaloniaProperty.Register(nameof(Background));
-
+
public new IBrush Background
{
get => GetValue(BackgroundProperty);
set => SetValue(BackgroundProperty, value);
}
-
+
//Close Button Command (X Button) Property
public static readonly StyledProperty XButtonCommandProperty =
AvaloniaProperty.Register(nameof(XButtonCommand));
-
+
public ICommand XButtonCommand
{
get => GetValue(XButtonCommandProperty);
set => SetValue(XButtonCommandProperty, value);
}
-
+
//Minimize Button Command (- Button) Property
public static readonly StyledProperty MinButtonCommandProperty =
AvaloniaProperty.Register(nameof(MinButtonCommand));
-
+
public ICommand MinButtonCommand
{
get => GetValue(MinButtonCommandProperty);
diff --git a/SPTInstaller/CustomControls/UpdateButton.axaml b/SPTInstaller/CustomControls/UpdateButton.axaml
index 4b2f766..b2425a3 100644
--- a/SPTInstaller/CustomControls/UpdateButton.axaml
+++ b/SPTInstaller/CustomControls/UpdateButton.axaml
@@ -5,43 +5,43 @@
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SPTInstaller.CustomControls.UpdateButton">
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
\ No newline at end of file
diff --git a/SPTInstaller/CustomControls/UpdateButton.axaml.cs b/SPTInstaller/CustomControls/UpdateButton.axaml.cs
index 5dc37f4..4ea2783 100644
--- a/SPTInstaller/CustomControls/UpdateButton.axaml.cs
+++ b/SPTInstaller/CustomControls/UpdateButton.axaml.cs
@@ -10,73 +10,76 @@ public partial class UpdateButton : UserControl
{
InitializeComponent();
}
-
+
public static readonly StyledProperty InfoTextProperty = AvaloniaProperty.Register(
"InfoText");
-
+
public string InfoText
{
get => GetValue(InfoTextProperty);
set => SetValue(InfoTextProperty, value);
}
-
- public static readonly StyledProperty CheckingForUpdateProperty = AvaloniaProperty.Register(
- "CheckingForUpdate");
-
+
+ public static readonly StyledProperty CheckingForUpdateProperty =
+ AvaloniaProperty.Register(
+ "CheckingForUpdate");
+
public bool CheckingForUpdate
{
get => GetValue(CheckingForUpdateProperty);
set => SetValue(CheckingForUpdateProperty, value);
}
-
- public static readonly StyledProperty DismissCommandProperty = AvaloniaProperty.Register(
- "DismissCommand");
-
+
+ public static readonly StyledProperty DismissCommandProperty =
+ AvaloniaProperty.Register(
+ "DismissCommand");
+
public ICommand DismissCommand
{
get => GetValue(DismissCommandProperty);
set => SetValue(DismissCommandProperty, value);
}
-
- public static readonly StyledProperty UpdateCommandProperty = AvaloniaProperty.Register(
- "UpdateCommand");
-
+
+ public static readonly StyledProperty UpdateCommandProperty =
+ AvaloniaProperty.Register(
+ "UpdateCommand");
+
public ICommand UpdateCommand
{
get => GetValue(UpdateCommandProperty);
set => SetValue(UpdateCommandProperty, value);
}
-
+
public static readonly StyledProperty UpdatingProperty = AvaloniaProperty.Register(
"Updating");
-
+
public bool Updating
{
get => GetValue(UpdatingProperty);
set => SetValue(UpdatingProperty, value);
}
-
+
public static readonly StyledProperty DownloadProgressProperty = AvaloniaProperty.Register(
"DownloadProgress");
-
+
public int DownloadProgress
{
get => GetValue(DownloadProgressProperty);
set => SetValue(DownloadProgressProperty, value);
}
-
+
public static readonly StyledProperty IsIndeterminateProperty = AvaloniaProperty.Register(
"IsIndeterminate");
-
+
public bool IsIndeterminate
{
get => GetValue(IsIndeterminateProperty);
set => SetValue(IsIndeterminateProperty, value);
}
-
+
public static readonly StyledProperty UpdateAvailableProperty = AvaloniaProperty.Register(
"UpdateAvailable");
-
+
public bool UpdateAvailable
{
get => GetValue(UpdateAvailableProperty);
diff --git a/SPTInstaller/GlobalUsings.cs b/SPTInstaller/GlobalUsings.cs
index eee4b9d..90bfd12 100644
--- a/SPTInstaller/GlobalUsings.cs
+++ b/SPTInstaller/GlobalUsings.cs
@@ -1,3 +1,4 @@
// 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 52acdbd..feb9e0e 100644
--- a/SPTInstaller/Helpers/DirectorySizeHelper.cs
+++ b/SPTInstaller/Helpers/DirectorySizeHelper.cs
@@ -8,32 +8,32 @@ public static class DirectorySizeHelper
// SizeSuffix implementation found here:
// https://stackoverflow.com/a/14488941
static readonly string[] SizeSuffixes =
- { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
-
+ { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
+
public static string SizeSuffix(Int64 value, int decimalPlaces = 1)
{
if (decimalPlaces < 0)
{
throw new ArgumentOutOfRangeException("decimalPlaces");
}
-
+
if (value < 0)
{
return "-" + SizeSuffix(-value, decimalPlaces);
}
-
+
if (value == 0)
{
return string.Format("{0:n" + decimalPlaces + "} bytes", 0);
}
-
+
// mag is 0 for bytes, 1 for KB, 2, for MB, etc.
int mag = (int)Math.Log(value, 1024);
-
+
// 1L << (mag * 10) == 2 ^ (10 * mag)
// [i.e. the number of bytes in the unit corresponding to mag]
decimal adjustedSize = (decimal)value / (1L << (mag * 10));
-
+
// make adjustment when the value is large enough that
// it would round up to 1000 or more
if (Math.Round(adjustedSize, decimalPlaces) >= 1000)
@@ -41,12 +41,12 @@ public static class DirectorySizeHelper
mag += 1;
adjustedSize /= 1024;
}
-
+
return string.Format("{0:n" + decimalPlaces + "} {1}",
adjustedSize,
SizeSuffixes[mag]);
}
-
+
///
/// Gets the size of a directory in bytes
///
diff --git a/SPTInstaller/Helpers/FileHashHelper.cs b/SPTInstaller/Helpers/FileHashHelper.cs
index 0f6f2a3..f96ba87 100644
--- a/SPTInstaller/Helpers/FileHashHelper.cs
+++ b/SPTInstaller/Helpers/FileHashHelper.cs
@@ -17,7 +17,7 @@ public static class FileHashHelper
//
// return null;
// }
-
+
public static bool CheckHash(FileInfo file, string expectedHash)
{
using var md5Service = MD5.Create();
@@ -27,9 +27,9 @@ public static class FileHashHelper
var expectedHashBytes = Convert.FromBase64String(expectedHash);
Log.Information($"Comparing Hashes :: S: {Convert.ToBase64String(sourceHash)} - E: {expectedHash}");
-
+
var matched = Enumerable.SequenceEqual(sourceHash, expectedHashBytes);
-
+
return matched;
}
}
\ No newline at end of file
diff --git a/SPTInstaller/Helpers/FileHelper.cs b/SPTInstaller/Helpers/FileHelper.cs
index 531ae98..a0a45ba 100644
--- a/SPTInstaller/Helpers/FileHelper.cs
+++ b/SPTInstaller/Helpers/FileHelper.cs
@@ -16,24 +16,26 @@ public static class FileHelper
foreach (var dir in sourceDir.GetDirectories("*", SearchOption.AllDirectories))
{
var exclude = false;
-
+
foreach (var exclusion in exclusions)
{
var currentDirRelativePath = dir.FullName.Replace(sourceDir.FullName, "");
-
+
if (currentDirRelativePath.StartsWith(exclusion) || currentDirRelativePath == exclusion)
{
exclude = true;
- Log.Debug($"EXCLUSION FOUND :: DIR\nExclusion: '{exclusion}'\nPath: '{currentDirRelativePath}'");
+ Log.Debug(
+ $"EXCLUSION FOUND :: DIR\nExclusion: '{exclusion}'\nPath: '{currentDirRelativePath}'");
break;
}
}
-
+
if (exclude)
continue;
-
+
Directory.CreateDirectory(dir.FullName.Replace(sourceDir.FullName, targetDir.FullName));
}
+
return Result.FromSuccess();
}
catch (Exception ex)
@@ -42,44 +44,47 @@ public static class FileHelper
return Result.FromError(ex.Message);
}
}
-
- private static Result IterateFiles(DirectoryInfo sourceDir, DirectoryInfo targetDir, string[] exclusions, Action updateCallback = null)
+
+ private static Result IterateFiles(DirectoryInfo sourceDir, DirectoryInfo targetDir, string[] exclusions,
+ Action updateCallback = null)
{
try
{
int totalFiles = sourceDir.GetFiles("*.*", SearchOption.AllDirectories).Length;
int processedFiles = 0;
-
+
foreach (var file in sourceDir.GetFiles("*.*", SearchOption.AllDirectories))
{
var exclude = false;
-
+
updateCallback?.Invoke(file.Name, (int)Math.Floor(((double)processedFiles / totalFiles) * 100));
-
+
foreach (var exclusion in exclusions)
{
var currentFileRelativePath = file.FullName.Replace(sourceDir.FullName, "");
-
+
if (currentFileRelativePath.StartsWith(exclusion) || currentFileRelativePath == exclusion)
{
exclude = true;
- Log.Debug($"EXCLUSION FOUND :: FILE\nExclusion: '{exclusion}'\nPath: '{currentFileRelativePath}'");
+ Log.Debug(
+ $"EXCLUSION FOUND :: FILE\nExclusion: '{exclusion}'\nPath: '{currentFileRelativePath}'");
break;
}
}
-
+
if (exclude)
continue;
-
+
var targetFile = file.FullName.Replace(sourceDir.FullName, targetDir.FullName);
- Log.Debug($"COPY\nSourceDir: '{sourceDir.FullName}'\nTargetDir: '{targetDir.FullName}'\nNewPath: '{targetFile}'");
-
+ Log.Debug(
+ $"COPY\nSourceDir: '{sourceDir.FullName}'\nTargetDir: '{targetDir.FullName}'\nNewPath: '{targetFile}'");
+
File.Copy(file.FullName, targetFile, true);
processedFiles++;
}
-
+
return Result.FromSuccess();
}
catch (Exception ex)
@@ -88,35 +93,37 @@ public static class FileHelper
return Result.FromError(ex.Message);
}
}
-
+
public static string GetRedactedPath(string path)
{
var nameMatched = Regex.Match(path, @".:\\[uU]sers\\(?[^\\]+)");
-
+
if (nameMatched.Success)
{
var name = nameMatched.Groups["NAME"].Value;
return path.Replace(name, "-REDACTED-");
}
-
+
return path;
}
-
- public static Result CopyDirectoryWithProgress(DirectoryInfo sourceDir, DirectoryInfo targetDir, IProgress progress = null, string[] exclusions = null) =>
+
+ public static Result CopyDirectoryWithProgress(DirectoryInfo sourceDir, DirectoryInfo targetDir,
+ IProgress progress = null, string[] exclusions = null) =>
CopyDirectoryWithProgress(sourceDir, targetDir, (msg, prog) => progress?.Report(prog), exclusions);
-
- public static Result CopyDirectoryWithProgress(DirectoryInfo sourceDir, DirectoryInfo targetDir, Action updateCallback = null, string[] exclusions = null)
+
+ public static Result CopyDirectoryWithProgress(DirectoryInfo sourceDir, DirectoryInfo targetDir,
+ Action updateCallback = null, string[] exclusions = null)
{
try
{
var iterateDirectoriesResult = IterateDirectories(sourceDir, targetDir, exclusions ??= new string[0]);
-
- if(!iterateDirectoriesResult.Succeeded) return iterateDirectoriesResult;
-
+
+ if (!iterateDirectoriesResult.Succeeded) return iterateDirectoriesResult;
+
var iterateFilesResult = IterateFiles(sourceDir, targetDir, exclusions ??= new string[0], updateCallback);
-
+
if (!iterateFilesResult.Succeeded) return iterateDirectoriesResult;
-
+
return Result.FromSuccess();
}
catch (Exception ex)
@@ -125,33 +132,33 @@ public static class FileHelper
return Result.FromError(ex.Message);
}
}
-
+
public static bool StreamAssemblyResourceOut(string resourceName, string outputFilePath)
{
try
{
var assembly = Assembly.GetExecutingAssembly();
-
+
FileInfo outputFile = new FileInfo(outputFilePath);
-
+
if (outputFile.Exists)
{
outputFile.Delete();
}
-
+
if (!outputFile.Directory.Exists)
{
Directory.CreateDirectory(outputFile.Directory.FullName);
}
-
+
var resName = assembly.GetManifestResourceNames().First(x => x.EndsWith(resourceName));
-
+
using (FileStream fs = File.Create(outputFilePath))
using (Stream s = assembly.GetManifestResourceStream(resName))
{
s.CopyTo(fs);
}
-
+
outputFile.Refresh();
return outputFile.Exists;
}
@@ -161,11 +168,11 @@ public static class FileHelper
return false;
}
}
-
+
public static bool CheckPathForProblemLocations(string path, out PathCheck failedCheck)
{
failedCheck = new();
-
+
var problemPaths = new List()
{
new("Documents", PathCheckType.EndsWith, PathCheckAction.Warn),
@@ -182,8 +189,8 @@ public static class FileHelper
new("Program Files (x86", PathCheckType.Contains, PathCheckAction.Deny),
new("Drive Root", PathCheckType.DriveRoot, PathCheckAction.Deny)
};
-
- foreach (var check in problemPaths)
+
+ foreach (var check in problemPaths)
{
switch (check.CheckType)
{
@@ -193,6 +200,7 @@ public static class FileHelper
failedCheck = check;
return true;
}
+
break;
case PathCheckType.Contains:
if (path.ToLower().Contains(check.Target.ToLower()))
@@ -200,6 +208,7 @@ public static class FileHelper
failedCheck = check;
return true;
}
+
break;
case PathCheckType.DriveRoot:
if (Regex.Match(path.ToLower(), @"^\w:(\\|\/)$").Success)
@@ -207,11 +216,11 @@ public static class FileHelper
failedCheck = check;
return true;
}
+
break;
}
}
-
+
return false;
}
-
}
\ No newline at end of file
diff --git a/SPTInstaller/Helpers/HttpClientProgressExtensions.cs b/SPTInstaller/Helpers/HttpClientProgressExtensions.cs
index d77154d..f7868de 100644
--- a/SPTInstaller/Helpers/HttpClientProgressExtensions.cs
+++ b/SPTInstaller/Helpers/HttpClientProgressExtensions.cs
@@ -6,7 +6,8 @@ namespace SPTInstaller.Helpers;
public static class HttpClientProgressExtensions
{
- public static async Task DownloadDataAsync(this HttpClient client, string requestUrl, Stream destination, IProgress progress = null, CancellationToken cancellationToken = default(CancellationToken))
+ public static async Task DownloadDataAsync(this HttpClient client, string requestUrl, Stream destination,
+ IProgress progress = null, CancellationToken cancellationToken = default(CancellationToken))
{
using (var response = await client.GetAsync(requestUrl, HttpCompletionOption.ResponseHeadersRead))
{
@@ -19,16 +20,19 @@ public static class HttpClientProgressExtensions
await download.CopyToAsync(destination);
return;
}
+
// Such progress and contentLength much reporting Wow!
- var progressWrapper = new Progress(totalBytes => progress.Report(GetProgressPercentage(totalBytes, contentLength.Value)));
+ var progressWrapper = new Progress(totalBytes =>
+ progress.Report(GetProgressPercentage(totalBytes, contentLength.Value)));
await download.CopyToAsync(destination, 81920, progressWrapper, cancellationToken);
}
}
-
+
float GetProgressPercentage(float totalBytes, float currentBytes) => (totalBytes / currentBytes) * 100f;
}
-
- static async Task CopyToAsync(this Stream source, Stream destination, int bufferSize, IProgress progress = null, CancellationToken cancellationToken = default(CancellationToken))
+
+ static async Task CopyToAsync(this Stream source, Stream destination, int bufferSize,
+ IProgress progress = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (bufferSize < 0)
throw new ArgumentOutOfRangeException(nameof(bufferSize));
@@ -40,11 +44,12 @@ public static class HttpClientProgressExtensions
throw new ArgumentNullException(nameof(destination));
if (!destination.CanWrite)
throw new InvalidOperationException($"'{nameof(destination)}' is not writable.");
-
+
var buffer = new byte[bufferSize];
long totalBytesRead = 0;
int bytesRead;
- while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0)
+ while ((bytesRead =
+ await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0)
{
await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
totalBytesRead += bytesRead;
diff --git a/SPTInstaller/Helpers/PreCheckHelper.cs b/SPTInstaller/Helpers/PreCheckHelper.cs
index 166df6f..15713bf 100644
--- a/SPTInstaller/Helpers/PreCheckHelper.cs
+++ b/SPTInstaller/Helpers/PreCheckHelper.cs
@@ -7,26 +7,28 @@ namespace SPTInstaller.Helpers;
public static class PreCheckHelper
{
- private const string registryInstall = @"Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\EscapeFromTarkov";
-
+ private const string registryInstall =
+ @"Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\EscapeFromTarkov";
+
public static string DetectOriginalGamePath()
{
// We can't detect the installed path on non-Windows
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return null;
-
+
var uninstallStringValue = Registry.LocalMachine.OpenSubKey(registryInstall, false)
?.GetValue("InstallLocation");
var info = (uninstallStringValue is string key) ? new DirectoryInfo(key) : null;
-
+
return info?.FullName;
}
-
+
public static Result DetectOriginalGameVersion(string gamePath)
{
try
{
- string version = FileVersionInfo.GetVersionInfo(Path.Join(gamePath, "/EscapeFromTarkov.exe")).ProductVersion.Replace('-', '.').Split('.')[^2];
+ string version = FileVersionInfo.GetVersionInfo(Path.Join(gamePath, "/EscapeFromTarkov.exe")).ProductVersion
+ .Replace('-', '.').Split('.')[^2];
return Result.FromSuccess(version);
}
catch (Exception ex)
diff --git a/SPTInstaller/Helpers/ProcessHelper.cs b/SPTInstaller/Helpers/ProcessHelper.cs
index c2ee41a..dd925bb 100644
--- a/SPTInstaller/Helpers/ProcessHelper.cs
+++ b/SPTInstaller/Helpers/ProcessHelper.cs
@@ -25,45 +25,45 @@ public static class ProcessHelper
return Result.FromError(
$"Could not find executable ({executable.Name}) or working directory ({workingDir.Name})");
}
-
+
var process = new Process();
process.StartInfo.FileName = executable.FullName;
process.StartInfo.WorkingDirectory = workingDir.FullName;
process.EnableRaisingEvents = true;
process.StartInfo.Arguments = "autoclose";
process.Start();
-
+
process.WaitForExit();
-
+
switch ((PatcherExitCode)process.ExitCode)
{
case PatcherExitCode.Success:
return Result.FromSuccess("Patcher Finished Successfully, extracting Aki");
-
+
case PatcherExitCode.ProgramClosed:
return Result.FromError("Patcher was closed before completing!");
-
+
case PatcherExitCode.EftExeNotFound:
return Result.FromError("EscapeFromTarkov.exe is missing from the install Path");
-
+
case PatcherExitCode.NoPatchFolder:
return Result.FromError("Patchers Folder called 'Aki_Patches' is missing");
-
+
case PatcherExitCode.MissingFile:
return Result.FromError("EFT files was missing a Vital file to continue");
-
+
case PatcherExitCode.PatchFailed:
return Result.FromError("A patch failed to apply");
-
+
default:
return Result.FromError("an unknown error occurred in the patcher");
}
}
-
+
public static ReadProcessResult RunAndReadProcessOutputs(string fileName, string args, int timeout = 5000)
{
using var proc = new Process();
-
+
proc.StartInfo = new ProcessStartInfo
{
FileName = fileName,
@@ -72,13 +72,13 @@ public static class ProcessHelper
RedirectStandardError = true,
CreateNoWindow = true
};
-
+
var outputBuilder = new StringBuilder();
var errorBuilder = new StringBuilder();
-
+
using AutoResetEvent outputWaitHandle = new AutoResetEvent(false);
using AutoResetEvent errorWaitHandle = new AutoResetEvent(false);
-
+
proc.OutputDataReceived += (s, e) =>
{
if (e.Data == null)
@@ -90,7 +90,7 @@ public static class ProcessHelper
outputBuilder.AppendLine(e.Data);
}
};
-
+
proc.ErrorDataReceived += (s, e) =>
{
if (e.Data == null)
@@ -102,7 +102,7 @@ public static class ProcessHelper
errorBuilder.AppendLine(e.Data);
}
};
-
+
try
{
proc.Start();
@@ -111,10 +111,10 @@ public static class ProcessHelper
{
return ReadProcessResult.FromError(ex.Message);
}
-
+
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
-
+
if (!proc.WaitForExit(timeout) || !outputWaitHandle.WaitOne(timeout) || !errorWaitHandle.WaitOne(timeout))
{
return ReadProcessResult.FromError("Process timed out");
diff --git a/SPTInstaller/Helpers/ServiceHelper.cs b/SPTInstaller/Helpers/ServiceHelper.cs
index 021eb26..c2515ae 100644
--- a/SPTInstaller/Helpers/ServiceHelper.cs
+++ b/SPTInstaller/Helpers/ServiceHelper.cs
@@ -14,22 +14,22 @@ internal static class ServiceHelper
private static bool TryRegisterInstance(object[] parameters = null)
{
var instance = Activator.CreateInstance(typeof(T2), parameters);
-
+
if (instance != null)
{
Locator.CurrentMutable.RegisterConstant((T)instance);
return true;
}
-
+
return false;
}
-
+
///
/// Register a class as a service
///
/// class to register
public static void Register() where T : class => Register();
-
+
///
/// Register a class as a service by another type
///
@@ -38,33 +38,33 @@ internal static class ServiceHelper
public static void Register() where T : class
{
var constructors = typeof(T2).GetConstructors();
-
- foreach(var constructor in constructors)
+
+ foreach (var constructor in constructors)
{
var parmesan = constructor.GetParameters();
-
- if(parmesan.Length == 0)
+
+ if (parmesan.Length == 0)
{
if (TryRegisterInstance()) return;
-
+
continue;
}
-
+
List