diff --git a/.gitignore b/.gitignore
index 584fc7c3..e370b7cc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -331,4 +331,5 @@ ASALocalRun/
# VS Code User Files
-.vscode/
\ No newline at end of file
+.vscode/
+.sonarlint/
diff --git a/.sonarlint/FASTER.slconfig b/.sonarlint/FASTER.slconfig
deleted file mode 100644
index 12a5d18d..00000000
--- a/.sonarlint/FASTER.slconfig
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "ServerUri": "https://sonarcloud.io/",
- "Organization": {
- "Key": "foxlicorp",
- "Name": "Keelah"
- },
- "ProjectKey": "Foxlider_FASTER",
- "ProjectName": "FASTER",
- "Profiles": {
- "CSharp": {
- "ProfileKey": "AW7Rfkrd6A1-kc3fchk2",
- "ProfileTimestamp": "2021-11-28T14:54:48Z"
- }
- }
-}
\ No newline at end of file
diff --git a/.sonarlint/foxlider_faster/CSharp/SonarLint.xml b/.sonarlint/foxlider_faster/CSharp/SonarLint.xml
deleted file mode 100644
index ffa3aa13..00000000
--- a/.sonarlint/foxlider_faster/CSharp/SonarLint.xml
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
- sonar.cs.analyzeGeneratedCode
- false
-
-
- sonar.cs.file.suffixes
- .cs
-
-
- sonar.cs.ignoreHeaderComments
- true
-
-
- sonar.cs.roslyn.ignoreIssues
- false
-
-
-
-
- S107
-
-
- max
- 7
-
-
-
-
- S110
-
-
- max
- 5
-
-
-
-
- S1479
-
-
- maximum
- 30
-
-
-
-
- S2342
-
-
- flagsAttributeFormat
- ^([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?s$
-
-
- format
- ^([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?$
-
-
-
-
- S2436
-
-
- max
- 2
-
-
- maxMethod
- 3
-
-
-
-
- S3776
-
-
- propertyThreshold
- 3
-
-
- threshold
- 25
-
-
-
-
-
\ No newline at end of file
diff --git a/.sonarlint/foxlider_fastercsharp.ruleset b/.sonarlint/foxlider_fastercsharp.ruleset
deleted file mode 100644
index 19d72398..00000000
--- a/.sonarlint/foxlider_fastercsharp.ruleset
+++ /dev/null
@@ -1,368 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/FASTER/FASTER.csproj b/FASTER/FASTER.csproj
index 9e911826..410d5f9c 100644
--- a/FASTER/FASTER.csproj
+++ b/FASTER/FASTER.csproj
@@ -7,7 +7,7 @@
win-x64
true
true
- 1.8.6.1
+ 1.8.7.1
Keelah Fox
FoxliCorp.
Fox's Arma Server Tool Extended Rewrite
@@ -51,17 +51,17 @@
-
-
+
+
-
-
-
-
+
+
+
+
diff --git a/FASTER/MainWindow.xaml.cs b/FASTER/MainWindow.xaml.cs
index b2d5f0db..0b24bde7 100644
--- a/FASTER/MainWindow.xaml.cs
+++ b/FASTER/MainWindow.xaml.cs
@@ -218,6 +218,9 @@ private void ToggleButton_Click(object sender, RoutedEventArgs e)
default:
if (IServerProfilesMenu.Items.Cast().FirstOrDefault(p => p.Name == nav.Name) != null)
{
+ var profile = new Profile();
+ MainContent.Content = profile;
+
ContentProfile.DataContext = ContentProfileViews.First(p => p.Profile.Id == nav.Name);
ContentProfile.Refresh();
MainContent.Content = ContentProfile;
diff --git a/FASTER/Models/SteamWebApi.cs b/FASTER/Models/SteamWebApi.cs
index bda808e2..330fb915 100644
--- a/FASTER/Models/SteamWebApi.cs
+++ b/FASTER/Models/SteamWebApi.cs
@@ -1,11 +1,16 @@
using BytexDigital.Steam.Core;
+using MahApps.Metro.Controls.Dialogs;
+
using Newtonsoft.Json.Linq;
using System;
using System.Diagnostics;
+using System.IO;
using System.Net;
using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
using System.Windows;
namespace FASTER.Models
@@ -94,29 +99,112 @@ private static string GetApiKey()
}
}
- internal class AuthCodeProvider : SteamAuthenticationCodesProvider
+ internal class AuthCodeProvider : SteamAuthenticator
{
- public override string GetEmailAuthenticationCode(SteamCredentials steamCredentials)
+
+ private readonly string _persistenceDirectory;
+ private readonly string _uniqueStorageName;
+ public string AccessToken { get; protected set; }
+ public string GuardData { get; protected set; }
+
+
+ public AuthCodeProvider(string uniqueStorageName, string persistenceDirectory)
+ {
+ _uniqueStorageName = uniqueStorageName;
+ _persistenceDirectory = persistenceDirectory;
+ }
+
+ public override Task GetEmailAuthenticationCodeAsync(string accountEmail, bool previousCodeWasIncorrect, CancellationToken cancellationToken = default)
{
- MainWindow.Instance.SteamUpdaterViewModel.Parameters.Output += "\nPlease enter your email auth code: ";
+ if (previousCodeWasIncorrect)
+ MainWindow.Instance.SteamUpdaterViewModel.Parameters.Output += "\nPreviously entered email code was incorrect!";
+
+ MainWindow.Instance.SteamUpdaterViewModel.Parameters.Output += "\nPlease enter your 2FA code: ";
var input = MainWindow.Instance.SteamUpdaterViewModel.SteamGuardInput().Result;
MainWindow.Instance.SteamUpdaterViewModel.Parameters.Output += "\nRetrying... ";
- return input;
+ return Task.FromResult(input);
}
- public override string GetTwoFactorAuthenticationCode(SteamCredentials steamCredentials)
+ public override Task GetTwoFactorAuthenticationCodeAsync(bool previousCodeWasIncorrect, CancellationToken cancellationToken = default)
{
+ if (previousCodeWasIncorrect)
+ MainWindow.Instance.SteamUpdaterViewModel.Parameters.Output += "\nPreviously entered 2FA code was incorrect!";
+
+
MainWindow.Instance.SteamUpdaterViewModel.Parameters.Output += "\nPlease enter your 2FA code: ";
var input = MainWindow.Instance.SteamUpdaterViewModel.SteamGuardInput().Result;
MainWindow.Instance.SteamUpdaterViewModel.Parameters.Output += "\nRetrying... ";
- return input;
+ return Task.FromResult(input);
+ }
+
+ public override Task NotifyMobileNotificationAsync(CancellationToken cancellationToken = default)
+ {
+ MainWindow.Instance.SteamUpdaterViewModel.Parameters.Output += "\nMobile notification sent. Answer \"y\" once you've authorized this login. If no notification was received or you'd like to enter a traditional 2FA code, enter \"n\": ";
+
+ MessageDialogResult response;
+
+ do
+ {
+ response = MainWindow.Instance.SteamUpdaterViewModel.SteamGuardInputPhone().Result;
+ } while (response != MessageDialogResult.Affirmative);
+
+ return Task.FromResult(true);
+ }
+
+ public override Task PersistAccessTokenAsync(string token, CancellationToken cancellationToken = default)
+ {
+ AccessToken = token;
+
+ if (string.IsNullOrEmpty(_persistenceDirectory)) return Task.CompletedTask;
+
+ Directory.CreateDirectory(_persistenceDirectory);
+ File.WriteAllText(Path.Combine(_persistenceDirectory, $"{_uniqueStorageName}_accesstoken"), AccessToken);
+
+ return Task.CompletedTask;
+ }
+
+
+ public override Task GetAccessTokenAsync(CancellationToken cancellationToken = default)
+ {
+ if (string.IsNullOrEmpty(_persistenceDirectory))
+ {
+ return Task.FromResult(AccessToken);
+ }
+
+ var path = Path.Combine(_persistenceDirectory, $"{_uniqueStorageName}_accesstoken");
+
+ return Task.FromResult(File.Exists(path) ? File.ReadAllText(path) : AccessToken);
+ }
+
+ public override Task PersistGuardDataAsync(string data, CancellationToken cancellationToken = default)
+ {
+ GuardData = data;
+
+ if (string.IsNullOrEmpty(_persistenceDirectory)) return Task.CompletedTask;
+
+ Directory.CreateDirectory(_persistenceDirectory);
+ File.WriteAllText(Path.Combine(_persistenceDirectory, $"{_uniqueStorageName}_guarddata"), GuardData);
+
+ return Task.CompletedTask;
+ }
+
+ public override Task GetGuardDataAsync(CancellationToken cancellationToken = default)
+ {
+ if (string.IsNullOrEmpty(_persistenceDirectory))
+ {
+ return Task.FromResult(GuardData);
+ }
+
+ var path = Path.Combine(_persistenceDirectory, $"{_uniqueStorageName}_guarddata");
+
+ return Task.FromResult(File.Exists(path) ? File.ReadAllText(path) : GuardData);
}
}
diff --git a/FASTER/ViewModel/SteamUpdaterViewModel.cs b/FASTER/ViewModel/SteamUpdaterViewModel.cs
index 2dcb1e50..f64ea72f 100644
--- a/FASTER/ViewModel/SteamUpdaterViewModel.cs
+++ b/FASTER/ViewModel/SteamUpdaterViewModel.cs
@@ -3,7 +3,6 @@
using BytexDigital.Steam.ContentDelivery.Models;
using BytexDigital.Steam.ContentDelivery.Models.Downloading;
using BytexDigital.Steam.Core;
-using BytexDigital.Steam.Core.Enumerations;
using BytexDigital.Steam.Core.Structs;
using FASTER.Models;
@@ -113,7 +112,6 @@ public bool IsDlOverride
internal SteamClient SteamClient;
internal SteamContentClient SteamContentClient;
- private SteamCredentials _steamCredentials;
public void PasswordChanged(string password)
{
@@ -293,20 +291,18 @@ internal async Task RunServerUpdater(string path, uint appId, List<(uint id
if (!await SteamLogin())
return UpdateState.LoginFailed;
- var _OS = SteamClient?.GetSteamOs().Identifier;
Stopwatch sw = Stopwatch.StartNew();
foreach (var depot in depots)
{
try
{
- SteamOs steamOs = new(_OS);
ManifestId manifestId;
+ manifestId = await SteamContentClient.GetDepotManifestIdAsync(appId, depot.id, depot.branch, depot.pass);
- manifestId = await SteamContentClient.GetDepotDefaultManifestIdAsync(appId, depot.id, depot.branch, depot.pass);
+ Parameters.Output += $"\nFetching infor;ations of app {appId}, depot {depot.id} from Steam ({depots.IndexOf(depot)+1}/{depots.Count})... ";
+ var downloadHandler = await SteamContentClient.GetAppDataAsync(appId, depot.id, manifestId, tokenSource.Token);
- Parameters.Output += $"\nAttempting to start download of app {appId}, depot {depot.id} ({depots.IndexOf(depot)+1}/{depots.Count})... ";
- var downloadHandler = await SteamContentClient.GetAppDataAsync(appId, depot.id, manifestId, depot.branch, depot.pass, steamOs);
await Download(downloadHandler, path);
}
catch (Exception ex)
@@ -341,12 +337,10 @@ public async Task RunModUpdater(ulong modId, string path)
return UpdateState.LoginFailed;
}
- var _OS = SteamClient.GetSteamOs().Identifier;
Stopwatch sw = Stopwatch.StartNew();
try
{
- SteamOs steamOs = new(_OS);
ManifestId manifestId = default;
Parameters.Output += $"\nFetching mod {modId} infos... ";
@@ -361,12 +355,7 @@ public async Task RunModUpdater(ulong modId, string path)
Parameters.Output += $"\nAttempting to start download of item {modId}... ";
- var downloadHandler = await SteamContentClient.GetPublishedFileDataAsync(
- modId,
- manifestId,
- null,
- null,
- steamOs);
+ var downloadHandler = await SteamContentClient.GetPublishedFileDataAsync(modId, manifestId, tokenSource.Token);
await Download(downloadHandler, path);
}
@@ -404,8 +393,6 @@ public async Task RunModsUpdater(ObservableCollection mods)
return UpdateState.LoginFailed;
}
- var _OS = SteamClient.GetSteamOs().Identifier;
-
Parameters.Output += "\nAdding mods to download list...";
SemaphoreSlim maxThread = new(1);
@@ -432,7 +419,6 @@ public async Task RunModsUpdater(ObservableCollection mods)
Stopwatch sw = Stopwatch.StartNew();
try
{
- SteamOs steamOs = new(_OS);
ManifestId manifestId = default;
if(mod.LocalLastUpdated > mod.SteamLastUpdated)
@@ -453,11 +439,7 @@ public async Task RunModsUpdater(ObservableCollection mods)
Parameters.Output += $"\n Attempting to start download of item {mod.WorkshopId}... ";
- var downloadHandler = SteamContentClient.GetPublishedFileDataAsync(mod.WorkshopId,
- manifestId,
- null,
- null,
- steamOs);
+ var downloadHandler = SteamContentClient.GetPublishedFileDataAsync(mod.WorkshopId, manifestId, tokenSource.Token);
DownloadForMultiple(downloadHandler.Result, mod.Path).Wait();
}
catch (TaskCanceledException)
@@ -505,11 +487,10 @@ internal async Task SteamLogin()
{
IsLoggingIn = true;
var path = Path.Combine(Path.GetDirectoryName(ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath) ?? string.Empty, "sentries");
- SteamAuthenticationFilesProvider sentryFileProvider = new DirectorySteamAuthenticationFilesProvider(path);
- if (_steamCredentials == null || _steamCredentials.IsAnonymous)
- _steamCredentials = new SteamCredentials(Parameters.Username, Encryption.Instance.DecryptData(Parameters.Password), Parameters.ApiKey);
- SteamClient ??= new SteamClient(_steamCredentials, new AuthCodeProvider(), sentryFileProvider);
+ SteamCredentials _steamCredentials = new SteamCredentials(Parameters.Username, Encryption.Instance.DecryptData(Parameters.Password), Parameters.ApiKey);
+
+ SteamClient ??= new SteamClient(_steamCredentials, new AuthCodeProvider(_steamCredentials.Username, path));
if (!SteamClient.IsConnected || SteamClient.IsFaulted)
{
@@ -694,6 +675,9 @@ private async Task DownloadForMultiple(IDownloadHandler downloadHandler, string
public async Task SteamGuardInput()
{ return await DialogCoordinator.ShowInputAsync(this, "Steam Guard", "Please enter your 2FA code"); }
+ public async Task SteamGuardInputPhone()
+ { return await DialogCoordinator.ShowMessageAsync(this, "Steam Guard", "Press OK after accepting authentification on mobile", MessageDialogStyle.Affirmative); }
+
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
diff --git a/FASTER_Version.xml b/FASTER_Version.xml
index ed1c7076..82ee33d4 100644
--- a/FASTER_Version.xml
+++ b/FASTER_Version.xml
@@ -1,6 +1,6 @@
-
- 1.8.6.1
+ 1.8.7.1
https://github.com/Foxlider/FASTER/releases/latest/download/Release_x64.zip
https://github.com/Foxlider/FASTER/releases
true