Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions FASTER/Models/Logger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.IO;

namespace FASTER.Models
{
public static class Logger
{
private static readonly string LogPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"FASTER", "faster.log");

public static bool IsEnabled => Properties.Settings.Default.enableDebugLog;

public static string LogFilePath => LogPath;

public static void Log(string message)
{
if (!IsEnabled) return;
try
{
Directory.CreateDirectory(Path.GetDirectoryName(LogPath)!);
File.AppendAllText(LogPath, $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {message}{Environment.NewLine}");
}
catch { }
}
}
}
12 changes: 12 additions & 0 deletions FASTER/Properties/Settings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions FASTER/Properties/Settings.settings
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,8 @@
<Setting Name="usingEFDlc" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="enableDebugLog" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
</Settings>
</SettingsFile>
159 changes: 80 additions & 79 deletions FASTER/ViewModel/SteamUpdaterViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -445,9 +445,86 @@ public async Task<int> RunModsUpdater(ObservableCollection<ArmaMod> mods)
Logger.Log($"RunModsUpdater: waiting semaphore for mod {mod.WorkshopId} ({mod.Name})");
await maxThread.WaitAsync();

_ = Task.Factory.StartNew(
() => ProcessModDownloadAsync(mod),
TaskCreationOptions.LongRunning).Unwrap().ContinueWith((t) =>
_ = Task.Factory.StartNew(async () =>
{
Logger.Log($" Task started: {mod.WorkshopId} ({mod.Name}), path={mod.Path}");
try
{
if (!Directory.Exists(mod.Path))
{
Logger.Log($" Creating dir: {mod.Path}");
Directory.CreateDirectory(mod.Path);
}

if (tokenSource.Token.IsCancellationRequested)
{
Logger.Log($" Cancellation requested before {mod.WorkshopId}, skipping.");
return;
}
Parameters.Output += $"\n Starting {mod.WorkshopId}";

Stopwatch sw = Stopwatch.StartNew();
try
{
ManifestId manifestId = default;

if(mod.LocalLastUpdated > mod.SteamLastUpdated && mod.Size > 0)
{
mod.Status = ArmaModStatus.UpToDate;
Parameters.Output += $"\n Mod{mod.WorkshopId} already up to date. Ignoring...";
Logger.Log($" {mod.WorkshopId} already up to date, skipping.");
return;
}

if (!SteamClient.Credentials.IsAnonymous)
{
Logger.Log($" Getting manifest for {mod.WorkshopId}");
Parameters.Output += $"\n Getting manifest for {mod.WorkshopId}";
manifestId = (await SteamContentClient.GetPublishedFileDetailsAsync(mod.WorkshopId)).hcontent_file;
Manifest manifest = await SteamContentClient.GetManifestAsync(107410, 107410, manifestId);
Parameters.Output += $"\n Manifest retrieved {mod.WorkshopId}";
Logger.Log($" Manifest retrieved for {mod.WorkshopId}, syncing deleted files...");
SyncDeleteRemovedFiles(mod.Path, manifest);
}

Logger.Log($" Requesting download handler for {mod.WorkshopId}");
Parameters.Output += $"\n Attempting to start download of item {mod.WorkshopId}... ";

var downloadHandler = await SteamContentClient.GetPublishedFileDataAsync(mod.WorkshopId, manifestId, tokenSource.Token);
Logger.Log($" Download handler obtained for {mod.WorkshopId}, starting download...");
await DownloadForMultiple(downloadHandler, mod.Path);
Logger.Log($" Download complete for {mod.WorkshopId}");

mod.Status = ArmaModStatus.UpToDate;
var nx = DateTime.UnixEpoch;
var ts = DateTime.UtcNow - nx;
mod.LocalLastUpdated = (ulong)ts.TotalSeconds;
}
catch (TaskCanceledException)
{
Logger.Log($" {mod.WorkshopId} task cancelled.");
sw.Stop();
mod.Status = ArmaModStatus.NotComplete;
}
catch (Exception ex)
{
Logger.Log($" ERROR downloading {mod.WorkshopId}: {ex.GetType().Name}: {ex.Message}{(ex.InnerException != null ? $" | Inner: {ex.InnerException.Message}" : "")}\n StackTrace: {ex.StackTrace}");
sw.Stop();
mod.Status = ArmaModStatus.NotComplete;
Parameters.Output += $"\nError: {ex.Message}{(ex.InnerException != null ? $" Inner Exception: {ex.InnerException.Message}" : "")}";
}
sw.Stop();

mod.CheckModSize();
Parameters.Output += $"\n Download {mod.WorkshopId} completed, it took {sw.Elapsed.Minutes + sw.Elapsed.Hours*60}m {sw.Elapsed.Seconds}s {sw.Elapsed.Milliseconds}ms";
}

if (!SteamClient.Credentials.IsAnonymous)
{
Logger.Log($" UNHANDLED ERROR in task for {mod.WorkshopId}: {ex.GetType().Name}: {ex.Message}\n StackTrace: {ex.StackTrace}");
}

}, TaskCreationOptions.LongRunning).Unwrap().ContinueWith((t) =>
{
if (t.IsFaulted)
Logger.Log($" ContinueWith: task for {mod.WorkshopId} faulted: {t.Exception}");
Expand Down Expand Up @@ -475,82 +552,6 @@ public async Task<int> RunModsUpdater(ObservableCollection<ArmaMod> mods)
return UpdateState.Success;
}

private async Task ProcessModDownloadAsync(ArmaMod mod)
{
Logger.Log($" Task started: {mod.WorkshopId} ({mod.Name}), path={mod.Path}");
try
{
if (!Directory.Exists(mod.Path))
{
Logger.Log($" Creating dir: {mod.Path}");
Directory.CreateDirectory(mod.Path);
}

if (tokenSource.Token.IsCancellationRequested)
{
Logger.Log($" Cancellation requested before {mod.WorkshopId}, skipping.");
return;
}
Parameters.Output += $"\n Starting {mod.WorkshopId}";

Stopwatch sw = Stopwatch.StartNew();
try
{
ManifestId manifestId = default;

if (mod.LocalLastUpdated > mod.SteamLastUpdated && mod.Size > 0)
{
mod.Status = ArmaModStatus.UpToDate;
Parameters.Output += $"\n Mod{mod.WorkshopId} already up to date. Ignoring...";
Logger.Log($" {mod.WorkshopId} already up to date, skipping.");
return;
}

if (!SteamClient.Credentials.IsAnonymous)
{
Logger.Log($" Getting manifest for {mod.WorkshopId}");
Parameters.Output += $"\n Getting manifest for {mod.WorkshopId}";
manifestId = (await SteamContentClient.GetPublishedFileDetailsAsync(mod.WorkshopId)).hcontent_file;
Manifest manifest = await SteamContentClient.GetManifestAsync(107410, 107410, manifestId);
Parameters.Output += $"\n Manifest retrieved {mod.WorkshopId}";
Logger.Log($" Manifest retrieved for {mod.WorkshopId}, syncing deleted files...");
SyncDeleteRemovedFiles(mod.Path, manifest);
}

Logger.Log($" Requesting download handler for {mod.WorkshopId}");
Parameters.Output += $"\n Attempting to start download of item {mod.WorkshopId}... ";

var downloadHandler = await SteamContentClient.GetPublishedFileDataAsync(mod.WorkshopId, manifestId, tokenSource.Token);
Logger.Log($" Download handler obtained for {mod.WorkshopId}, starting download...");
await DownloadForMultiple(downloadHandler, mod.Path);
Logger.Log($" Download complete for {mod.WorkshopId}");

mod.Status = ArmaModStatus.UpToDate;
mod.LocalLastUpdated = (ulong)(DateTime.UtcNow - DateTime.UnixEpoch).TotalSeconds;
}
catch (TaskCanceledException)
{
Logger.Log($" {mod.WorkshopId} task cancelled.");
sw.Stop();
mod.Status = ArmaModStatus.NotComplete;
}
catch (Exception ex)
{
Logger.Log($" ERROR downloading {mod.WorkshopId}: {ex.GetType().Name}: {ex.Message}{(ex.InnerException != null ? $" | Inner: {ex.InnerException.Message}" : "")}\n StackTrace: {ex.StackTrace}");
sw.Stop();
mod.Status = ArmaModStatus.NotComplete;
Parameters.Output += $"\nError: {ex.Message}{(ex.InnerException != null ? $" Inner Exception: {ex.InnerException.Message}" : "")}";
}
sw.Stop();
mod.CheckModSize();
Parameters.Output += $"\n Download {mod.WorkshopId} completed in {sw.Elapsed.Hours * 60 + sw.Elapsed.Minutes}m {sw.Elapsed.Seconds}s {sw.Elapsed.Milliseconds}ms";
}
catch (Exception ex)
{
Logger.Log($" UNHANDLED ERROR in task for {mod.WorkshopId}: {ex.GetType().Name}: {ex.Message}\n StackTrace: {ex.StackTrace}");
}
}

internal async Task<bool> SteamLogin()
{
Logger.Log("SteamLogin: start");
Expand Down
17 changes: 14 additions & 3 deletions FASTER/Views/Settings.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Grid.ColumnSpan="10">
Expand All @@ -50,7 +51,17 @@
<CheckBox Name="IModUpdatesOnLaunch" Grid.ColumnSpan="2" Grid.Row="1" Grid.Column="0" Content="Check for Steam Mod Updates on Launch" Click="IModUpdatesOnLaunch_Checked" IsChecked="True" Margin="10,0,10,10"/>
<CheckBox Name="IAppUpdatesOnLaunch" Grid.ColumnSpan="2" Grid.Row="2" Grid.Column="0" Content="Auto Update FASTER on Launch" Click="IAppUpdatesOnLaunch_Checked" IsChecked="False" Margin="10,0,10,10"/>

<Grid Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Margin="10,20">
<Grid Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="4" Margin="10,2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<CheckBox Name="IEnableDebugLog" Grid.Column="0" Content="Enable Debug Logging" Click="IEnableDebugLog_Checked" IsChecked="False" Margin="0,0,20,0" VerticalAlignment="Center"/>
<Button Name="IOpenLogFile" Grid.Column="1" Content="Open Log File" Click="IOpenLogFile_Click" Style="{DynamicResource MahApps.Styles.Button.MetroSquare.Accent}" BorderThickness="0" Padding="8,2" Height="24"/>
</Grid>

<Grid Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" Margin="10,20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
Expand All @@ -59,7 +70,7 @@
<Slider Name="Slider" Grid.Column="1" IsSnapToTickEnabled="True" Minimum="1" Maximum="50" SmallChange="1" LargeChange="0" ValueChanged="RangeBase_OnValueChanged"/>
</Grid>

<Grid Grid.Row="4" Grid.ColumnSpan="2" Grid.Column="0" Margin="5,10">
<Grid Grid.Row="5" Grid.ColumnSpan="2" Grid.Column="0" Margin="5,10">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="auto"/>
Expand All @@ -68,7 +79,7 @@
<Button Grid.Column="1" Name="IAPIKeyButton" Content="{iconPacks:Material Kind=Web}" Style="{DynamicResource MahApps.Styles.Button.MetroSquare.Accent}" BorderThickness="0" VerticalAlignment="Stretch" Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" Margin="5" Padding="2" Click="APIKeyButton_Click"/>
</Grid>

<Grid Grid.Row="5" Grid.ColumnSpan="4" Grid.Column="0">
<Grid Grid.Row="6" Grid.ColumnSpan="4" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
Expand Down
20 changes: 20 additions & 0 deletions FASTER/Views/Settings.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using FASTER.Models;

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
Expand Down Expand Up @@ -129,6 +131,7 @@ private void Settings_Initialized(object sender, EventArgs e)
{
IModUpdatesOnLaunch.IsChecked = Properties.Settings.Default?.checkForModUpdates;
IAppUpdatesOnLaunch.IsChecked = Properties.Settings.Default?.checkForAppUpdates;
IEnableDebugLog.IsChecked = Properties.Settings.Default?.enableDebugLog;
IAPIKeyBox.Text = Properties.Settings.Default?.SteamAPIKey ?? string.Empty;
Slider.Value = Properties.Settings.Default.CliWorkers;
NumericUpDown.Value = Slider.Value;
Expand All @@ -146,6 +149,22 @@ private void IAppUpdatesOnLaunch_Checked(object sender, RoutedEventArgs e)
Properties.Settings.Default.Save();
}

private void IEnableDebugLog_Checked(object sender, RoutedEventArgs e)
{
Properties.Settings.Default.enableDebugLog = IEnableDebugLog.IsChecked ?? false;
Properties.Settings.Default.Save();
Logger.Log("Debug logging enabled.");
}

private void IOpenLogFile_Click(object sender, RoutedEventArgs e)
{
var path = Logger.LogFilePath;
if (File.Exists(path))
Process.Start(new ProcessStartInfo(path) { UseShellExecute = true });
else
MainWindow.Instance.DisplayMessage($"No log file found at:\n{path}");
}

private void IUpdateApp_OnClick(object sender, RoutedEventArgs e)
{ AutoUpdater.Start("https://raw.githubusercontent.com/Foxlider/FASTER/master/FASTER_Version.xml"); }

Expand All @@ -158,6 +177,7 @@ private void ISaveSettings_Click(object sender, RoutedEventArgs e)
Properties.Settings.Default.SteamAPIKey = IAPIKeyBox.Text;
Properties.Settings.Default.checkForAppUpdates = IAppUpdatesOnLaunch.IsChecked ?? true;
Properties.Settings.Default.checkForModUpdates = IModUpdatesOnLaunch.IsChecked ?? true;
Properties.Settings.Default.enableDebugLog = IEnableDebugLog.IsChecked ?? false;
Properties.Settings.Default.Save();
}

Expand Down