Skip to content
Open
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
18 changes: 18 additions & 0 deletions FASTER/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@

using FASTER.Models;

using Microsoft.AppCenter;
using Microsoft.AppCenter.Analytics;
using Microsoft.AppCenter.Crashes;

using System;
using System.Globalization;
using System.Threading.Tasks;
using System.Windows;
using ControlzEx.Theming;

Expand All @@ -19,6 +22,21 @@ protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);

AppDomain.CurrentDomain.UnhandledException += (_, args) =>
Logger.Log($"[FATAL] Unhandled exception (CLR): {args.ExceptionObject}");

DispatcherUnhandledException += (_, args) =>
{
Logger.Log($"[FATAL] Unhandled dispatcher exception: {args.Exception}");
args.Handled = true;
};

TaskScheduler.UnobservedTaskException += (_, args) =>
{
Logger.Log($"[FATAL] Unobserved task exception: {args.Exception}");
args.SetObserved();
};

var countryCode = RegionInfo.CurrentRegion.TwoLetterISORegionName;
var userID = AppCenter.GetInstallIdAsync();

Expand Down
14 changes: 14 additions & 0 deletions FASTER/Models/ArmaMod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ public class ArmaMod : INotifyPropertyChanged
private long _size;
private bool _isLoading;
private bool _isSelected;
private static bool _apiKeyWarningShown = false;

private static bool TryShowApiKeyWarning()
{
if (_apiKeyWarningShown) return false;
_apiKeyWarningShown = true;
return true;
}


public uint WorkshopId
Expand Down Expand Up @@ -337,6 +345,12 @@ internal void UpdateInfos(bool checkFileSize = true)
success = true;
} while (failNum < 3 && !success);

if (!success && TryShowApiKeyWarning())
{
MainWindow.Instance?.Dispatcher.Invoke(() =>
MainWindow.Instance.DisplayMessage("Could not fetch mod info. Please check your Steam API Key in Settings."));
}

if (checkFileSize)
CheckModSize();

Expand Down
41 changes: 27 additions & 14 deletions FASTER/Models/BasicCfg.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public static class BasicCfgArrays
{
public static string[] PerfPresets { get; } = {"Custom", "Arma3 Defaults", "1Mb Preset", "250Mb Preset", "1Gb Preset"};
public static double[] TerrainGrids { get; } = { 50, 25, 12.5, 6.25, 3.125 };
public static string[] Languages { get; } = { "English", "Czech", "French", "German", "Italian", "Polish", "Portuguese", "Russian", "Spanish", "Turkish", "Hungarian" };
}

[Serializable]
Expand All @@ -27,15 +28,26 @@ public class BasicCfg : INotifyPropertyChanged
private ushort maxCustomFileSize = 1024;
private ushort maxPacketSize = 1400;

private string _language = "English";
private string basicContent;

public string Language
{
get => _language;
set
{
_language = value;
RaisePropertyChanged(nameof(Language));
}
}

public string BasicContent
{
get => basicContent;
set
{
basicContent = value;
RaisePropertyChanged("BasicContent");
RaisePropertyChanged(nameof(BasicContent));
}
}

Expand All @@ -45,7 +57,7 @@ public uint ViewDistance
set
{
viewDistance = value;
RaisePropertyChanged("ViewDistance");
RaisePropertyChanged(nameof(ViewDistance));
}
}

Expand All @@ -55,7 +67,7 @@ public double TerrainGrid
set
{
terrainGrid = value;
RaisePropertyChanged("TerrainGrid");
RaisePropertyChanged(nameof(TerrainGrid));
}
}

Expand All @@ -65,7 +77,7 @@ public ushort MaxSizeGuaranteed
set
{
maxSizeGuaranteed = value;
RaisePropertyChanged("MaxSizeGuaranteed");
RaisePropertyChanged(nameof(MaxSizeGuaranteed));
}
}

Expand All @@ -75,7 +87,7 @@ public ushort MaxSizeNonGuaranteed
set
{
maxSizeNonguaranteed = value;
RaisePropertyChanged("MaxSizeNonGuaranteed");
RaisePropertyChanged(nameof(MaxSizeNonGuaranteed));
}
}

Expand All @@ -85,7 +97,7 @@ public ushort MaxMsgSend
set
{
maxMsgSend = value;
RaisePropertyChanged("MaxMsgSend");
RaisePropertyChanged(nameof(MaxMsgSend));
}
}

Expand All @@ -95,7 +107,7 @@ public ulong MinBandwidth
set
{
minBandwidth = value;
RaisePropertyChanged("MinBandwidth");
RaisePropertyChanged(nameof(MinBandwidth));
}
}

Expand All @@ -105,7 +117,7 @@ public ulong MaxBandwidth
set
{
maxBandwidth = value;
RaisePropertyChanged("MaxBandwidth");
RaisePropertyChanged(nameof(MaxBandwidth));
}
}

Expand All @@ -115,7 +127,7 @@ public ushort MaxPacketSize
set
{
maxPacketSize = value;
RaisePropertyChanged("MaxPacketSize");
RaisePropertyChanged(nameof(MaxPacketSize));
}
}

Expand All @@ -125,7 +137,7 @@ public double MinErrorToSend
set
{
minErrorToSend = value;
RaisePropertyChanged("MinErrorToSend");
RaisePropertyChanged(nameof(MinErrorToSend));
}
}

Expand All @@ -135,7 +147,7 @@ public double MinErrorToSendNear
set
{
minErrorToSendNear = value;
RaisePropertyChanged("MinErrorToSendNear");
RaisePropertyChanged(nameof(MinErrorToSendNear));
}
}

Expand All @@ -145,11 +157,12 @@ public ushort MaxCustomFileSize
set
{
maxCustomFileSize = value;
RaisePropertyChanged("MaxCustomFileSize");
RaisePropertyChanged(nameof(MaxCustomFileSize));
}
}

[XmlIgnore]
[Newtonsoft.Json.JsonIgnore]
public string PerfPreset
{
get => "Custom";
Expand Down Expand Up @@ -181,7 +194,7 @@ public string PerfPreset
MinBandwidth = 1000000000;
break;
}
RaisePropertyChanged("PerfPreset");
RaisePropertyChanged(nameof(PerfPreset));
}
}

Expand All @@ -191,7 +204,7 @@ public BasicCfg()
public string ProcessFile()
{
string output = "// These options are created by default\r\n"
+ "language=\"English\";\r\n"
+ $"language=\"{_language}\";\r\n"
+ "adapter=-1;\r\n"
+ "3D_Performance=1.000000;\r\n"
+ "Resolution_W=800;\r\n"
Expand Down
10 changes: 7 additions & 3 deletions FASTER/Models/SteamWebApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,13 @@ private static JObject ApiCall(string uri)
// Display the status.
Console.WriteLine((response)?.StatusCode);

return response == null
? null
: JObject.Parse(response.Content.ReadAsStringAsync().Result);
if (response == null)
return null;

if (!response.IsSuccessStatusCode)
throw new HttpRequestException($"Steam API returned HTTP {(int)response.StatusCode} {response.StatusCode}. Please check your Steam API Key in Settings.");

return JObject.Parse(response.Content.ReadAsStringAsync().Result);

// Return the response
}
Expand Down
45 changes: 42 additions & 3 deletions FASTER/ViewModel/DeploymentViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,25 @@ public void DeployAll()
{"Name", Settings.Default.steamUserName}
});

Logger.Log($"DeployAll: installPath={Deployment.InstallPath}, mods={Deployment.DeployMods.Count}");

if (!Directory.Exists(Deployment.InstallPath))
{
Logger.Log("DeployAll: install path not found, aborting.");
DisplayMessage("Arma Install Path is empty.\nMake sure you have entered a valid path before deploying mods.");
return;
}

foreach (var mod in Deployment.DeployMods)
{
var linkPath = Path.Combine(Deployment.InstallPath, $"@{Functions.SafeName(mod.Name)}");
mod.Marked = true;
Logger.Log($" Linking {mod.Name}: {mod.Path} -> {linkPath}");
LinkMod(mod, linkPath);
}
Settings.Default.Deployments = Deployment;
Settings.Default.Save();
Logger.Log("DeployAll: done.");
}

/// <summary>
Expand Down Expand Up @@ -204,15 +217,36 @@ public void OpenModPage(DeploymentMod mod)
/// <param name="linkPath"></param>
private void LinkMod(DeploymentMod mod, string linkPath)
{
Logger.Log($"LinkMod: {mod.Name} ({mod.WorkshopId}) -> {linkPath}");
try
{
if(Directory.Exists(linkPath))
Directory.Delete(linkPath, true);
{
if (new DirectoryInfo(linkPath).Attributes.HasFlag(FileAttributes.ReparsePoint))
{
Logger.Log($" Removing existing symlink: {linkPath}");
Directory.Delete(linkPath);
}
else
{
Logger.Log($" Removing existing real dir: {linkPath}");
Directory.Delete(linkPath, true);
}
}

Directory.CreateSymbolicLink(linkPath ?? throw new ArgumentNullException(nameof(linkPath)), mod.Path);
Logger.Log($" Symlink created OK.");
}
catch (UnauthorizedAccessException)
{
Logger.Log($" ERROR: UnauthorizedAccessException creating symlink.");
DisplayMessage("Could not create symlink: Access denied.\n\nTo deploy mods, enable Windows Developer Mode in Settings → Update & Security → For Developers, or run FASTER as Administrator.");
}
catch (Exception ex)
{ DisplayMessage("An exception occurred: \n\n" + ex.Message); }
{
Logger.Log($" ERROR: {ex.Message}");
DisplayMessage("An exception occurred: \n\n" + ex.Message);
}
}

/// <summary>
Expand All @@ -224,7 +258,12 @@ private void DeleteLink(string linkPath)
try
{
if (Directory.Exists(linkPath))
Directory.Delete(linkPath, true);
{
if (new DirectoryInfo(linkPath).Attributes.HasFlag(FileAttributes.ReparsePoint))
Directory.Delete(linkPath);
else
Directory.Delete(linkPath, true);
}
}
catch (Exception ex)
{ DisplayMessage("An exception occurred: \n\n" + ex.Message); }
Expand Down
Loading