The most significant changes in the code include the addition of a new HTML file changelog\1.4.8.html to the project NebulaAuth.sln, which displays the changelog for version 1.4.8 of the software. A new converter ProxyDataTextConverter was added to App.xaml and a new class ProxyDataTextConverter was added in ProxyTextConverter.cs. The ProxyTextConverter was also modified to include the port number in the return string.

Several methods were added and modified in `Storage.cs`, `MainVM_Groups.cs`, `MainVM_Proxy.cs`, and `ProxyManagerVM.cs` to validate if the data can be saved before performing various operations. The `SnackbarController.cs` was modified to increase the minimum snackbar time and adjust the duration calculation.

In `MafileSerializer_SessionData.cs`, the check for whether the refresh token is expired or not was moved to a different location within the code. New localization entries were added in `localization.loc.json`.

The changes are as follows:

1. Added a new HTML file `changelog\1.4.8.html` to the project `NebulaAuth.sln`.
2. Added a new converter `ProxyDataTextConverter` to `App.xaml`.
3. Imported `AchiesUtilities.Web.Proxy` in `ProxyTextConverter.cs`.
4. Modified the return string in `ProxyTextConverter` to include the port number.
5. Added a new class `ProxyDataTextConverter` in `ProxyTextConverter.cs`.
6. Increased the minimum snackbar time from 1000 to 1200 in `SnackbarController.cs`.
7. Modified the duration calculation in `GetSnackbarTime` method in `SnackbarController.cs`.
8. Added tooltips to ComboBoxes in `MainWindow.xaml`.
9. Added a new method `ValidateCanSave` in `Storage.cs` to validate if the data can be saved.
10. Added a new method `GetProxyString` in `ProxyStorage.cs` to get the proxy string.
11. Modified the `CompareProxy` method in `ProxyStorage.cs` to compare the address and port of the proxy data.
12. Removed a logger info line in `Shell.cs`.
13. Added a new property `DuplicateFound` in `Storage.cs`.
14. Modified the `CreatePathForMafile` method in `Storage.cs` to create a file name based on the account name or steam id.
15. Modified the `AddGroup` method in `MainVM_Groups.cs` to validate if the data can be saved before adding a group.
16. Modified the `AddToGroup` method in `MainVM_Groups.cs` to validate if the data can be saved before adding to a group.
17. Modified the `RemoveGroup` method in `MainVM_Groups.cs` to validate if the data can be saved before removing a group.
18. Modified the `PerformQuery` method in `MainVM_Groups.cs` to set `SelectedMafile` to the first item in `MaFiles`.
19. Modified the `RemoveProxy` method in `MainVM_Proxy.cs` to validate if the data can be saved before removing a proxy.
20. Modified the `SelectedProxyChanged` method in `MainVM_Proxy.cs` to validate if the data can be saved before changing the selected proxy.
21. Added a new method `ValidateCanSaveAndWarn` in `MainVM_Proxy.cs` to validate if the data can be saved and send a snackbar message if it can't.
22. Modified the `TimerCheckSeconds` property in `MainVM_Timer.cs` to send a snackbar message when the timer is changed.
23. Added a new method `RemoveProxy` in `LoginAgainOnImportVM.cs` to remove the selected proxy.
24. Modified the `AddProxy` method in `ProxyManagerVM.cs` to use the `DefaultScheme` to parse the proxy data.
25. Modified the `AddProxy` method in `ProxyManagerVM.cs` to use the `DefaultScheme` to parse the proxy data and get the proxy string.
26. Modified the `CopyProxy` method in `ProxyManagerVM.cs` to get the proxy string.
27. Added new localization entries in `localization.loc.json`.
28. The `update.xml` file was updated to reflect the new version of the software (1.4.8.0) and the corresponding download URL and changelog URL were updated accordingly.
29. In `AdmissionHelper.cs`, a new constant `SESSION_ID_COOKIE_NAME` was added to replace hardcoded "sessionid" strings. The same was done for `LANGUAGE_COOKIE_NAME` replacing "Steam_Language". This change was reflected in multiple methods within the `AdmissionHelper` class.
30. A new method `CloneCookie` was added to `AdmissionHelper.cs` to create a copy of a given cookie. This method was then used to replace repetitive code in the `TransferCommunityCookies` method.
31. In `MafileSerializer_SessionData.cs`, the check for whether the refresh token is expired or not was moved to a different location within the code. This change does not affect the functionality but may improve readability or maintainability of the code.
This commit is contained in:
Давид Чернопятов
2024-04-10 01:39:42 +03:00
parent 939fca31e9
commit a9fdb58cac
21 changed files with 280 additions and 83 deletions
+1
View File
@@ -19,6 +19,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "changelog", "changelog", "{
changelog\1.4.5.html = changelog\1.4.5.html changelog\1.4.5.html = changelog\1.4.5.html
changelog\1.4.6.html = changelog\1.4.6.html changelog\1.4.6.html = changelog\1.4.6.html
changelog\1.4.7.html = changelog\1.4.7.html changelog\1.4.7.html = changelog\1.4.7.html
changelog\1.4.8.html = changelog\1.4.8.html
EndProjectSection EndProjectSection
EndProject EndProject
Global Global
+1
View File
@@ -18,6 +18,7 @@
<converters:OnOffBoolTextConverter x:Key="OnOffBoolTextConverter"/> <converters:OnOffBoolTextConverter x:Key="OnOffBoolTextConverter"/>
<converters:SelectedProxyTextConverter x:Key="SelectedProxyTextConverter"/> <converters:SelectedProxyTextConverter x:Key="SelectedProxyTextConverter"/>
<converters:ProxyTextConverter x:Key="ProxyTextConverter"/> <converters:ProxyTextConverter x:Key="ProxyTextConverter"/>
<converters:ProxyDataTextConverter x:Key="ProxyDataTextConverter"/>
<converters:MultiCommandParameterConverter x:Key="MultiCommandParameterConverter"/> <converters:MultiCommandParameterConverter x:Key="MultiCommandParameterConverter"/>
<converters:ColorToBrushConverter x:Key="ColorToBrushConverter"/> <converters:ColorToBrushConverter x:Key="ColorToBrushConverter"/>
<!-- Background converters--> <!-- Background converters-->
+20 -1
View File
@@ -1,6 +1,7 @@
using System; using System;
using System.Globalization; using System.Globalization;
using System.Windows.Data; using System.Windows.Data;
using AchiesUtilities.Web.Proxy;
using NebulaAuth.Model.Entities; using NebulaAuth.Model.Entities;
namespace NebulaAuth.Converters; namespace NebulaAuth.Converters;
@@ -14,7 +15,25 @@ public class ProxyTextConverter : IValueConverter
return string.Empty; return string.Empty;
} }
return $"{p.Id}: {p.Data.Address}"; return $"{p.Id}: {p.Data.Address}:{p.Data.Port}";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class ProxyDataTextConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is not ProxyData p)
{
return string.Empty;
}
return $"{p.Address}:{p.Port}";
} }
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+7 -8
View File
@@ -7,11 +7,8 @@ public class SnackbarController
{ {
public static SnackbarMessageQueue MessageQueue { get; } = new() { DiscardDuplicates = true}; public static SnackbarMessageQueue MessageQueue { get; } = new() { DiscardDuplicates = true};
private const int MIN_SNACKBAR_TIME = 1000; private const int MIN_SNACKBAR_TIME = 1200;
public SnackbarController()
{
}
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -46,10 +43,12 @@ public class SnackbarController
private static TimeSpan GetSnackbarTime(string str) private static TimeSpan GetSnackbarTime(string str)
{ {
if (str.Length <= 100) return TimeSpan.FromMilliseconds(MIN_SNACKBAR_TIME); var duration = str.Length / 0.03;
if (duration < MIN_SNACKBAR_TIME)
var length = str.Length / 0.07; {
return TimeSpan.FromMilliseconds(length); duration = MIN_SNACKBAR_TIME;
}
return TimeSpan.FromMilliseconds(duration);
} }
+2 -2
View File
@@ -68,7 +68,7 @@
</MenuItem> </MenuItem>
</Menu> </Menu>
<Separator /> <Separator />
<ComboBox MinWidth="100" Margin="8,0,8,0" VerticalAlignment="Center" md:HintAssist.Hint="{Tr MainWindow.AppBar.GroupsHint}" md:TextFieldAssist.HasClearButton="True" IsEditable="True" ItemsSource="{Binding Groups}" SelectedValue="{Binding SelectedGroup}"> <ComboBox ToolTip="{Tr MainWindow.AppBar.GroupToolTip}" MinWidth="100" Margin="8,0,8,0" VerticalAlignment="Center" md:HintAssist.Hint="{Tr MainWindow.AppBar.GroupsHint}" md:TextFieldAssist.HasClearButton="True" IsEditable="True" ItemsSource="{Binding Groups}" SelectedValue="{Binding SelectedGroup}">
<FrameworkElement.Resources> <FrameworkElement.Resources>
<ResourceDictionary> <ResourceDictionary>
<Style TargetType="md:PackIcon"> <Style TargetType="md:PackIcon">
@@ -81,7 +81,7 @@
<KeyBinding Key="Enter" Command="{Binding AddGroupCommand}" CommandParameter="{Binding Path=Text, RelativeSource={RelativeSource AncestorType=ComboBox}}" /> <KeyBinding Key="Enter" Command="{Binding AddGroupCommand}" CommandParameter="{Binding Path=Text, RelativeSource={RelativeSource AncestorType=ComboBox}}" />
</UIElement.InputBindings> </UIElement.InputBindings>
</ComboBox> </ComboBox>
<ComboBox MinWidth="100" Margin="8,0,8,0" VerticalAlignment="Center" md:HintAssist.Hint="{Tr MainWindow.AppBar.Proxy.ProxyHint}" md:ComboBoxAssist.ShowSelectedItem="False" SelectedItem="{Binding SelectedProxy}" ItemsSource="{Binding Proxies}"> <ComboBox ToolTip="{Tr MainWindow.AppBar.Proxy.ProxyManipulateToolTip}" MinWidth="100" Margin="8,0,8,0" VerticalAlignment="Center" md:HintAssist.Hint="{Tr MainWindow.AppBar.Proxy.ProxyHint}" md:ComboBoxAssist.ShowSelectedItem="False" SelectedItem="{Binding SelectedProxy}" ItemsSource="{Binding Proxies}">
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type entities:MaProxy}"> <DataTemplate DataType="{x:Type entities:MaProxy}">
<TextBlock Text="{Binding Converter={StaticResource ProxyTextConverter}, Mode=OneWay}" /> <TextBlock Text="{Binding Converter={StaticResource ProxyTextConverter}, Mode=OneWay}" />
+16 -1
View File
@@ -3,6 +3,7 @@ using System.IO;
using AchiesUtilities.Collections; using AchiesUtilities.Collections;
using AchiesUtilities.Web.Proxy; using AchiesUtilities.Web.Proxy;
using System.Linq; using System.Linq;
using AchiesUtilities.Web.Proxy.Parsing;
using NebulaAuth.Core; using NebulaAuth.Core;
using Newtonsoft.Json; using Newtonsoft.Json;
@@ -12,6 +13,14 @@ public static class ProxyStorage
{ {
public const string FORMAT = ADDRESS_FORMAT + ":{USER}:{PASS}"; public const string FORMAT = ADDRESS_FORMAT + ":{USER}:{PASS}";
public const string ADDRESS_FORMAT = "{IP}:{PORT}"; public const string ADDRESS_FORMAT = "{IP}:{PORT}";
public static readonly ProxyScheme DefaultScheme = new ProxyScheme(
ProxyDefaultFormats.UniversalHostFirstColonDelimiter, false, ProxyProtocol.HTTP,
ProxyPatternProtocol.HTTP | ProxyPatternProtocol.HTTPs,
ProxyPatternHostFormat.Domain | ProxyPatternHostFormat.IPv4, PatternRequirement.Optional,
PatternRequirement.Optional);
public static ObservableDictionary<int, ProxyData> Proxies { get; } = new(); public static ObservableDictionary<int, ProxyData> Proxies { get; } = new();
@@ -68,7 +77,7 @@ public static class ProxyStorage
} }
public static bool CompareProxy(ProxyData proxyData1, ProxyData proxyData2) public static bool CompareProxy(ProxyData proxyData1, ProxyData proxyData2)
{ {
return proxyData1.ToString(FORMAT) == proxyData2.ToString(FORMAT); return proxyData1.Address == proxyData2.Address && proxyData1.Port == proxyData2.Port;
} }
@@ -79,6 +88,11 @@ public static class ProxyStorage
File.WriteAllText("proxies.json", json); File.WriteAllText("proxies.json", json);
} }
public static string GetProxyString(ProxyData proxyData)
{
return proxyData.AuthEnabled ? proxyData.ToString(FORMAT) : proxyData.ToString(ADDRESS_FORMAT);
}
private static Proxies Create() private static Proxies Create()
{ {
int? def = null; int? def = null;
@@ -98,6 +112,7 @@ public static class ProxyStorage
}; };
} }
} }
public class Proxies public class Proxies
-1
View File
@@ -32,7 +32,6 @@ public static class Shell
throw new CantAlignTimeException("", ex); throw new CantAlignTimeException("", ex);
} }
ExtensionsLogger.LogDebug("Application started"); ExtensionsLogger.LogDebug("Application started");
Logger.Info("Test");
} }
private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e) private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e)
+16 -7
View File
@@ -9,6 +9,7 @@ using SteamLib.Utility.MaFiles;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.DirectoryServices.ActiveDirectory;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@@ -23,6 +24,7 @@ public static class Storage
public static string RemovedMafileFolder { get; } = Path.GetFullPath(REMOVED_F); public static string RemovedMafileFolder { get; } = Path.GetFullPath(REMOVED_F);
public static ObservableCollection<Mafile> MaFiles { get; } = new(); public static ObservableCollection<Mafile> MaFiles { get; } = new();
public static readonly int DuplicateFound; public static readonly int DuplicateFound;
static Storage() static Storage()
{ {
@@ -217,16 +219,18 @@ public static class Storage
private static string CreatePathForMafile(Mafile data) private static string CreatePathForMafile(Mafile data)
{ {
if (data.SessionData == null) string fileName;
throw new NullReferenceException("SessionData was null can't retrieve SteamId"); //TODO: handle with login if (Settings.Instance.UseAccountNameAsMafileName)
var useAccountName = Settings.Instance.UseAccountNameAsMafileName;
if (!useAccountName && (data.SessionData.SteamId.Steam64 == 0 || data.SessionData.SteamId.Steam64 == SteamId64.SEED))
{ {
useAccountName = true; fileName = CreateFileNameWithAccountName(data.AccountName);
} }
else
{
if(data.SessionData == null)
throw new NullReferenceException("SessionData was null can't retrieve SteamId"); //FIXME: think about better way to handle
var fileName = useAccountName ? CreateFileNameWithAccountName(data.AccountName) : CreateFileNameWithSteamId(data.SessionData.SteamId); fileName = CreateFileNameWithSteamId(data.SessionData.SteamId);
}
return Path.Combine(MafileFolder, fileName); return Path.Combine(MafileFolder, fileName);
} }
@@ -257,6 +261,11 @@ public static class Storage
} }
return null; return null;
} }
public static bool ValidateCanSave(Mafile data)
{
return Settings.Instance.UseAccountNameAsMafileName || data.SessionData != null;
}
} }
internal class MafileNameComparer : IComparer<string> internal class MafileNameComparer : IComparer<string>
@@ -29,16 +29,19 @@
<Run FontWeight="Bold" Text="{Binding UserName}"/> <Run FontWeight="Bold" Text="{Binding UserName}"/>
</TextBlock> </TextBlock>
<TextBox Text="{Binding Password}" Margin="10,10,10,0" Grid.Row="1" Style="{StaticResource MaterialDesignFloatingHintTextBox}" materialDesign:HintAssist.Hint="{Tr LoginAgainDialog.PasswordBox}"></TextBox> <TextBox Text="{Binding Password}" Margin="10,10,10,0" Grid.Row="1" Style="{StaticResource MaterialDesignFloatingHintTextBox}" materialDesign:HintAssist.Hint="{Tr LoginAgainDialog.PasswordBox}"></TextBox>
<ComboBox Grid.Row="2" Margin="10,10,10,0" materialDesign:HintAssist.Hint="{Tr Common.Proxy}" ItemsSource="{Binding Proxies}" SelectedItem="{Binding SelectedProxy}" > <ComboBox ToolTip="{Tr LoginAgainDialog.ProxyToolTip}" Grid.Row="2" Margin="10,18,10,0" materialDesign:HintAssist.Hint="{Tr Common.Proxy}" ItemsSource="{Binding Proxies}" SelectedItem="{Binding SelectedProxy}" >
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type entities:MaProxy}"> <DataTemplate DataType="{x:Type entities:MaProxy}">
<TextBlock Text="{Binding Converter={StaticResource ProxyTextConverter}, Mode=OneWay}" /> <TextBlock Text="{Binding Converter={StaticResource ProxyTextConverter}, Mode=OneWay}" />
</DataTemplate> </DataTemplate>
</ItemsControl.ItemTemplate> </ItemsControl.ItemTemplate>
<UIElement.InputBindings>
<KeyBinding Key="Delete" Command="{Binding RemoveProxyCommand}" />
</UIElement.InputBindings>
</ComboBox> </ComboBox>
<CheckBox Grid.Row="3" Margin="10,10,10,0" IsEnabled="{Binding Source={x:Static model:PHandler.IsPasswordSet}}" IsChecked="{Binding SavePassword}" Content="{Tr LoginAgainDialog.SaveEncryptedPassword}"/> <CheckBox Grid.Row="3" Margin="10,10,10,0" IsEnabled="{Binding Source={x:Static model:PHandler.IsPasswordSet}}" IsChecked="{Binding SavePassword}" Content="{Tr LoginAgainDialog.SaveEncryptedPassword}"/>
<CheckBox Grid.Row="4" Margin="10,10,10,0" IsEnabled="{Binding MafileHasProxy}" Content="{Tr LoginAgainDialog.UseMafileProxy}" IsChecked="{Binding UseMafileProxy}"/> <CheckBox Grid.Row="4" Margin="10,10,10,0" IsEnabled="{Binding MafileHasProxy}" Content="{Tr LoginAgainDialog.UseMafileProxy}" IsChecked="{Binding UseMafileProxy}"/>
<Grid Grid.Row="5" Margin="10,0,10,0"> <Grid Grid.Row="5" Margin="10,10,10,0">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition/> <ColumnDefinition/>
<ColumnDefinition/> <ColumnDefinition/>
+7 -6
View File
@@ -21,7 +21,7 @@
</Style> </Style>
</d:DesignerProperties.DesignStyle> </d:DesignerProperties.DesignStyle>
<Grid Margin="15,10,15,15"> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
@@ -34,8 +34,8 @@
<ColumnDefinition/> <ColumnDefinition/>
<ColumnDefinition/> <ColumnDefinition/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock FontStyle="Normal" Foreground="DarkGray" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="18" Text="{Tr ProxyManagerDialog.Title}"/> <TextBlock Margin="10" FontStyle="Normal" Foreground="DarkGray" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="18" Text="{Tr ProxyManagerDialog.Title}"/>
<Button IsCancel="True" Grid.Column="1" Width="30" Height="30" Style="{StaticResource MaterialDesignIconForegroundButton}" HorizontalAlignment="Right" Command="{x:Static md:DialogHost.CloseDialogCommand}"> <Button Margin="0,0,10,0" IsCancel="True" Grid.Column="1" Width="30" Height="30" Style="{StaticResource MaterialDesignIconForegroundButton}" HorizontalAlignment="Right" Command="{x:Static md:DialogHost.CloseDialogCommand}">
<md:PackIcon Kind="Close" Width="24" Height="24" Foreground="IndianRed"></md:PackIcon> <md:PackIcon Kind="Close" Width="24" Height="24" Foreground="IndianRed"></md:PackIcon>
</Button> </Button>
@@ -51,8 +51,9 @@
Margin="15" FontSize="16"> Margin="15" FontSize="16">
<Run Text="{Tr ProxyManagerDialog.DefaultProxy, IsDynamic=False}"/> <Run Text="{Tr ProxyManagerDialog.DefaultProxy, IsDynamic=False}"/>
<Run Text="{Binding DefaultProxy.Key, StringFormat='&#x0a;0:', FallbackValue='X', Mode=OneWay}"/> <Run Text="{Binding DefaultProxy.Key, StringFormat='&#x0a;0:', FallbackValue='X', Mode=OneWay}"/>
<Run Text="{Binding DefaultProxy.Value.Address, Mode=OneWay, FallbackValue=''}"/> <Run Text="{Binding DefaultProxy.Value, Converter='{StaticResource ProxyDataTextConverter}', Mode=OneWay, FallbackValue=''}"/>
</TextBlock> </TextBlock>
<Button Grid.Column="1" Command="{Binding SetDefaultCommand}"> <Button Grid.Column="1" Command="{Binding SetDefaultCommand}">
<md:PackIcon Kind="HeartBoxOutline" Width="20" Height="20"></md:PackIcon> <md:PackIcon Kind="HeartBoxOutline" Width="20" Height="20"></md:PackIcon>
</Button> </Button>
@@ -61,7 +62,7 @@
</Button> </Button>
</Grid> </Grid>
<md:Card Grid.Row="3" Margin="10"> <md:Card Grid.Row="3" Margin="10">
<ListBox SelectedValue="{Binding SelectedProxy}" ItemsSource="{Binding Proxies}"> <ListBox FontSize="14" SelectedValue="{Binding SelectedProxy}" ItemsSource="{Binding Proxies}">
<ListBox.ItemContainerStyle> <ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem" BasedOn="{StaticResource MaterialDesignListBoxItem}"> <Style TargetType="ListBoxItem" BasedOn="{StaticResource MaterialDesignListBoxItem}">
<Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext}"/> <Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext}"/>
@@ -85,7 +86,7 @@
<DataTemplate> <DataTemplate>
<TextBlock> <TextBlock>
<Run Text="{Binding Key, Mode=OneWay}"/><Run Text=": "/> <Run Text="{Binding Key, Mode=OneWay}"/><Run Text=": "/>
<Run Text="{Binding Value.Address, Mode=OneWay}"/> <Run Text="{Binding Value, Mode=OneWay, Converter={StaticResource ProxyDataTextConverter}}"/>
</TextBlock> </TextBlock>
</DataTemplate> </DataTemplate>
+1 -1
View File
@@ -46,7 +46,7 @@ public partial class MainVM : ObservableObject
{ {
SnackbarController.SendSnackbar( SnackbarController.SendSnackbar(
GetLocalizationOrDefault("DuplicateMafilesFound") + " " + Storage.DuplicateFound, GetLocalizationOrDefault("DuplicateMafilesFound") + " " + Storage.DuplicateFound,
TimeSpan.FromSeconds(3)); TimeSpan.FromSeconds(4));
} }
} }
+6 -4
View File
@@ -5,6 +5,7 @@ using NebulaAuth.Model.Entities;
using System; using System;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
namespace NebulaAuth.ViewModel; namespace NebulaAuth.ViewModel;
@@ -47,6 +48,8 @@ public partial class MainVM //Groups
var mafile = SelectedMafile; var mafile = SelectedMafile;
if (mafile == null) return; if (mafile == null) return;
if (string.IsNullOrEmpty(value)) return; if (string.IsNullOrEmpty(value)) return;
if (!ValidateCanSaveAndWarn(mafile)) return;
mafile.Group = value; mafile.Group = value;
Storage.UpdateMafile(mafile); Storage.UpdateMafile(mafile);
QueryGroups(); QueryGroups();
@@ -60,10 +63,12 @@ public partial class MainVM //Groups
{ {
if (value == null) return; if (value == null) return;
if (value.Length < 2) return; if (value.Length < 2) return;
var group = (string?)value[0]; var group = (string?)value[0];
var mafile = (Mafile?)value[1]; var mafile = (Mafile?)value[1];
if (group == null || mafile == null) return; if (group == null || mafile == null) return;
if (!ValidateCanSaveAndWarn(mafile)) return;
mafile.Group = group; mafile.Group = group;
Storage.UpdateMafile(mafile); Storage.UpdateMafile(mafile);
QueryGroups(); QueryGroups();
@@ -75,6 +80,7 @@ public partial class MainVM //Groups
private void RemoveGroup(Mafile? mafile) private void RemoveGroup(Mafile? mafile)
{ {
if (mafile?.Group == null) return; if (mafile?.Group == null) return;
if (!ValidateCanSaveAndWarn(mafile)) return;
var mafGroup = mafile.Group; var mafGroup = mafile.Group;
mafile.Group = null; mafile.Group = null;
Storage.UpdateMafile(mafile); Storage.UpdateMafile(mafile);
@@ -125,11 +131,7 @@ public partial class MainVM //Groups
} }
var perform = query.ToList(); var perform = query.ToList();
MaFiles = new ObservableCollection<Mafile>(perform); MaFiles = new ObservableCollection<Mafile>(perform);
if (SelectedMafile != null && !MaFiles.Contains(SelectedMafile))
{
SelectedMafile = MaFiles.FirstOrDefault(); SelectedMafile = MaFiles.FirstOrDefault();
}
return; return;
bool SearchPredicate(Mafile mafile) bool SearchPredicate(Mafile mafile)
+13
View File
@@ -98,7 +98,9 @@ public partial class MainVM
[RelayCommand] [RelayCommand]
private void RemoveProxy() private void RemoveProxy()
{ {
if(SelectedProxy == null) return;
if (SelectedMafile == null) return; if (SelectedMafile == null) return;
if (!ValidateCanSaveAndWarn(SelectedMafile)) return;
SelectedMafile.Proxy = null; SelectedMafile.Proxy = null;
SelectedProxy = null; SelectedProxy = null;
Storage.UpdateMafile(SelectedMafile); Storage.UpdateMafile(SelectedMafile);
@@ -114,8 +116,19 @@ public partial class MainVM
} }
if (SelectedMafile == null) return; if (SelectedMafile == null) return;
if (!ValidateCanSaveAndWarn(SelectedMafile)) return;
ProxyExist = true; ProxyExist = true;
SelectedMafile.Proxy = SelectedProxy; SelectedMafile.Proxy = SelectedProxy;
Storage.UpdateMafile(SelectedMafile); Storage.UpdateMafile(SelectedMafile);
} }
private bool ValidateCanSaveAndWarn(Mafile data)
{
var canSave = Storage.ValidateCanSave(data);
if (!canSave)
{
SnackbarController.SendSnackbar(GetLocalizationOrDefault("CantRetrieveSteamIDToUpdate"));
}
return canSave;
}
} }
+1
View File
@@ -136,5 +136,6 @@ public partial class MainVM //Timer
_timerCheckSeconds = value; _timerCheckSeconds = value;
OnPropertyChanged(nameof(TimerCheckSeconds)); OnPropertyChanged(nameof(TimerCheckSeconds));
_confirmTimer.Change(value * 1000, value * 1000); _confirmTimer.Change(value * 1000, value * 1000);
SnackbarController.SendSnackbar(GetLocalizationOrDefault("TimerChanged"));
} }
} }
@@ -2,6 +2,8 @@
using NebulaAuth.Model.Entities; using NebulaAuth.Model.Entities;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Windows.Forms;
using CommunityToolkit.Mvvm.Input;
namespace NebulaAuth.ViewModel.Other; namespace NebulaAuth.ViewModel.Other;
@@ -51,4 +53,10 @@ public partial class LoginAgainOnImportVM : ObservableObject
public LoginAgainOnImportVM() public LoginAgainOnImportVM()
{ } { }
[RelayCommand]
private void RemoveProxy()
{
SelectedProxy = null;
}
} }
+18 -14
View File
@@ -1,5 +1,7 @@
using AchiesUtilities.Collections; using AchiesUtilities.Collections;
using AchiesUtilities.Web.Proxy; using AchiesUtilities.Web.Proxy;
using AutoUpdaterDotNET;
using CodingSeb.Localization.WPF;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using NebulaAuth.Core; using NebulaAuth.Core;
@@ -56,9 +58,8 @@ public partial class ProxyManagerVM : ObservableObject
try if (ProxyStorage.DefaultScheme.TryParse(str, out var proxy))
{ {
var proxy = ProxyData.Parse(str, ProxyStorage.FORMAT);
if (id != null && proxies.Any(kvp => kvp.Key == id)) if (id != null && proxies.Any(kvp => kvp.Key == id))
{ {
SnackbarController.SendSnackbar(string.Format(GetLocalizationOrDefault("DuplicateId"), id)); SnackbarController.SendSnackbar(string.Format(GetLocalizationOrDefault("DuplicateId"), id));
@@ -66,7 +67,7 @@ public partial class ProxyManagerVM : ObservableObject
} }
proxies.Add(new KeyValuePair<int?, ProxyData>(id, proxy)); proxies.Add(new KeyValuePair<int?, ProxyData>(id, proxy));
} }
catch (FormatException) else
{ {
SnackbarController.SendSnackbar(string.Format(GetLocalizationOrDefault("WrongFormatOnLine"), i)); SnackbarController.SendSnackbar(string.Format(GetLocalizationOrDefault("WrongFormatOnLine"), i));
return; return;
@@ -88,20 +89,15 @@ public partial class ProxyManagerVM : ObservableObject
input = IdRegex.Replace(input, ""); input = IdRegex.Replace(input, "");
} }
ProxyData data; if (ProxyStorage.DefaultScheme.TryParse(input, out var data))
try
{ {
data = ProxyData.Parse(input, ProxyStorage.FORMAT); ProxyStorage.SetProxy(id, data);
} }
catch (FormatException) else
{ {
SnackbarController.SendSnackbar(GetLocalizationOrDefault("WrongFormat")); SnackbarController.SendSnackbar(GetLocalizationOrDefault("WrongFormat"));
return; return;
} }
ProxyStorage.SetProxy(id, data);
} }
AddProxyField = string.Empty; AddProxyField = string.Empty;
CheckIfDefaultProxyStay(); CheckIfDefaultProxyStay();
@@ -140,10 +136,18 @@ public partial class ProxyManagerVM : ObservableObject
} }
[RelayCommand] [RelayCommand]
private void CopyProxy(ProxyData? obj) private void CopyProxy(ProxyData? data)
{ {
if (obj == null) return; if (data == null) return;
Clipboard.SetText(obj.ToString(ProxyStorage.FORMAT)); try
{
Clipboard.SetText(ProxyStorage.GetProxyString(data));
}
catch (Exception ex)
{
Shell.Logger.Error(ex);
}
} }
[RelayCommand] [RelayCommand]
+30 -2
View File
@@ -132,6 +132,11 @@
"ru": "Группы", "ru": "Группы",
"ua": "Групи" "ua": "Групи"
}, },
"GroupToolTip": {
"ru": "Введите новую группу и нажмите Enter. Управление группой - ПКМ на аккаунте",
"en": "Enter new group and press Enter. Group management - RMB on account",
"ua": "Введіть нову групу і натисніть Enter. Управління групою - ПКМ на акаунті"
},
"Proxy": { "Proxy": {
"ProxyHint": { "ProxyHint": {
"en": "Proxy", "en": "Proxy",
@@ -143,6 +148,11 @@
"ru": "Открыть менеджер прокси", "ru": "Открыть менеджер прокси",
"ua": "Відкрити менеджер проксі" "ua": "Відкрити менеджер проксі"
}, },
"ProxyManipulateToolTip": {
"en": "Right-click to open menu. DEL to remove",
"ru": "Правый клик для открытия меню. DEL для удаления",
"ua": "Правий клік для відкриття меню. DEL для видалення"
},
"ProxyAlert": { "ProxyAlert": {
"DefaultInUse": { "DefaultInUse": {
"en": "Default proxy is in use", "en": "Default proxy is in use",
@@ -156,7 +166,6 @@
} }
} }
}, },
"TradeTimerHint": { "TradeTimerHint": {
"en": "Trade", "en": "Trade",
"ru": "Трейд", "ru": "Трейд",
@@ -369,6 +378,11 @@
"en": "Use mafile proxy", "en": "Use mafile proxy",
"ru": "Использовать прокси из мафайла", "ru": "Использовать прокси из мафайла",
"ua": "Використовувати проксі з мафайла" "ua": "Використовувати проксі з мафайла"
},
"ProxyToolTip": {
"en": "Press 'DEL' to remove",
"ru": "Нажмите 'DEL' для удаления",
"ua": "Натисніть 'DEL' для видалення"
} }
}, },
"ProxyManagerDialog": { "ProxyManagerDialog": {
@@ -381,8 +395,12 @@
"en": "Default proxy:", "en": "Default proxy:",
"ru": "Прокси по умолчанию:", "ru": "Прокси по умолчанию:",
"ua": "Проксі за замовчуванням:" "ua": "Проксі за замовчуванням:"
},
"UseRandomDefaultProxy": {
"en": "Use random default proxy",
"ru": "Cлучайный прокси по умолчанию",
"ua": "Випадковий проксі за замовчуванням"
} }
}, },
"WaitLoginDialog": { "WaitLoginDialog": {
"Text": { "Text": {
@@ -596,6 +614,16 @@
"en": "Duplicate mafile(s) found and were not loaded. Check log to get lists of duplicate files.", "en": "Duplicate mafile(s) found and were not loaded. Check log to get lists of duplicate files.",
"ru": "Найдены дубликаты мафайлов, они не были загружены. Проверьте лог чтобы получить списки дубликатов.", "ru": "Найдены дубликаты мафайлов, они не были загружены. Проверьте лог чтобы получить списки дубликатов.",
"ua": "Знайдено дублікати мафайлів, вони не були завантажені. Перевірте лог щоб отримати списки дублікатів." "ua": "Знайдено дублікати мафайлів, вони не були завантажені. Перевірте лог щоб отримати списки дублікатів."
},
"TimerChanged": {
"en": "Timer changed",
"ru": "Таймер изменен",
"ua": "Таймер змінено"
},
"CantRetrieveSteamIDToUpdate": {
"ru": "Не удалось получить SteamID из мафайла и сохранить изменения. Необходимо сделать релогин. Отменено",
"en": "Can't retrieve SteamID from mafile to save changes. Need to relogin. Canceled",
"ua": "Не вдалося отримати SteamID з мафайла та зберегти зміни. Потрібно зробити релогін. Скасовано"
} }
}, },
"ErrorTranslator": { "ErrorTranslator": {
+3 -3
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<item> <item>
<version>1.4.7.0</version> <version>1.4.8.0</version>
<url>https://github.com/achiez/NebulaAuth-Steam-Desktop-Authenticator-by-Achies/releases/download/1.4.7/NebulaAuth.1.4.7.zip</url> <url>https://github.com/achiez/NebulaAuth-Steam-Desktop-Authenticator-by-Achies/releases/download/1.4.8/NebulaAuth.1.4.8.zip</url>
<changelog>https://achiez.github.io/NebulaAuth-Steam-Desktop-Authenticator-by-Achies/changelog/1.4.7.html</changelog> <changelog>https://achiez.github.io/NebulaAuth-Steam-Desktop-Authenticator-by-Achies/changelog/1.4.8.html</changelog>
<mandatory>false</mandatory> <mandatory>false</mandatory>
</item> </item>
@@ -14,6 +14,7 @@ public static class AdmissionHelper
public const string ACCESS_COOKIE_NAME = "steamLoginSecure"; public const string ACCESS_COOKIE_NAME = "steamLoginSecure";
public const string REFRESH_COOKIE_NAME = "steamRefresh_steam"; public const string REFRESH_COOKIE_NAME = "steamRefresh_steam";
public const string LANGUAGE_COOKIE_NAME = "Steam_Language"; public const string LANGUAGE_COOKIE_NAME = "Steam_Language";
public const string SESSION_ID_COOKIE_NAME = "sessionid";
#region Main #region Main
@@ -28,8 +29,8 @@ public static class AdmissionHelper
AddRefreshToken(container, sessionData.RefreshToken); AddRefreshToken(container, sessionData.RefreshToken);
var community = SteamDomains.GetDomainUri(SteamDomain.Community); var community = SteamDomains.GetDomainUri(SteamDomain.Community);
container.Add(community, new Cookie("sessionid", sessionData.SessionId, "/")); container.Add(community, new Cookie(SESSION_ID_COOKIE_NAME, sessionData.SessionId, "/"));
container.Add(community, new Cookie("Steam_Language", setLanguage, "/")); container.Add(community, new Cookie(LANGUAGE_COOKIE_NAME, setLanguage, "/"));
TransferCommunityCookies(container); TransferCommunityCookies(container);
foreach (var domain in SteamDomains.AllDomains) foreach (var domain in SteamDomains.AllDomains)
{ {
@@ -65,8 +66,8 @@ public static class AdmissionHelper
var community = SteamDomains.GetDomainUri(SteamDomain.Community); var community = SteamDomains.GetDomainUri(SteamDomain.Community);
container.Add(community, new Cookie("steamid", mobileSession.SteamId.Steam64.ToString())); container.Add(community, new Cookie("steamid", mobileSession.SteamId.Steam64.ToString()));
container.Add(community, new Cookie("sessionid", mobileSession.SessionId)); container.Add(community, new Cookie(SESSION_ID_COOKIE_NAME, mobileSession.SessionId));
container.Add(community, new Cookie("Steam_Language", setLanguage)); container.Add(community, new Cookie(LANGUAGE_COOKIE_NAME, setLanguage));
TransferCommunityCookies(container); TransferCommunityCookies(container);
foreach (var domain in SteamDomains.AllDomains) foreach (var domain in SteamDomains.AllDomains)
@@ -91,8 +92,8 @@ public static class AdmissionHelper
var community = SteamDomains.GetDomainUri(SteamDomain.Community); var community = SteamDomains.GetDomainUri(SteamDomain.Community);
container.Add(community, new Cookie("steamid", mobileSession.SteamId.Steam64.ToString())); container.Add(community, new Cookie("steamid", mobileSession.SteamId.Steam64.ToString()));
container.Add(community, new Cookie("sessionid", mobileSession.SessionId)); container.Add(community, new Cookie(SESSION_ID_COOKIE_NAME, mobileSession.SessionId));
container.Add(community, new Cookie("Steam_Language", setLanguage)); container.Add(community, new Cookie(LANGUAGE_COOKIE_NAME, setLanguage));
TransferCommunityCookies(container); TransferCommunityCookies(container);
var domainCookieSet = false; var domainCookieSet = false;
@@ -154,10 +155,15 @@ public static class AdmissionHelper
if (cookie.Domain.Contains("steamcommunity.com") == false || cookie.Expired || cookie.Name.EqualsIgnoreCase(ACCESS_COOKIE_NAME)) continue; if (cookie.Domain.Contains("steamcommunity.com") == false || cookie.Expired || cookie.Name.EqualsIgnoreCase(ACCESS_COOKIE_NAME)) continue;
container.Add(SteamDomains.GetDomainUri(SteamDomain.Store), new Cookie(cookie.Name, cookie.Value, cookie.Path) { Expires = cookie.Expires, Secure = cookie.Secure, HttpOnly = cookie.HttpOnly }); container.Add(SteamDomains.GetDomainUri(SteamDomain.Store), CloneCookie(cookie));
container.Add(SteamDomains.GetDomainUri(SteamDomain.Help), new Cookie(cookie.Name, cookie.Value, cookie.Path) { Expires = cookie.Expires, Secure = cookie.Secure, HttpOnly = cookie.HttpOnly }); container.Add(SteamDomains.GetDomainUri(SteamDomain.Help), CloneCookie(cookie));
container.Add(SteamDomains.GetDomainUri(SteamDomain.TV), new Cookie(cookie.Name, cookie.Value, cookie.Path) { Expires = cookie.Expires, Secure = cookie.Secure, HttpOnly = cookie.HttpOnly }); container.Add(SteamDomains.GetDomainUri(SteamDomain.TV), CloneCookie(cookie));
} }
return;
static Cookie CloneCookie(Cookie cookie)
=> new(cookie.Name, cookie.Value, cookie.Path) { Expires = cookie.Expires, Secure = cookie.Secure, HttpOnly = cookie.HttpOnly };
} }
public static void AddRefreshToken(CookieContainer container, SteamAuthToken token) public static void AddRefreshToken(CookieContainer container, SteamAuthToken token)
@@ -198,7 +204,7 @@ public static class AdmissionHelper
{ {
var cookies = container.GetAllCookies(); var cookies = container.GetAllCookies();
return cookies return cookies
.FirstOrDefault(c => c.Name.Equals("sessionid", StringComparison.InvariantCultureIgnoreCase) .FirstOrDefault(c => c.Name.Equals(SESSION_ID_COOKIE_NAME, StringComparison.InvariantCultureIgnoreCase)
&& c.Expired == false && c.Expired == false
&& c.Domain.Contains(domain, StringComparison.InvariantCultureIgnoreCase))? && c.Domain.Contains(domain, StringComparison.InvariantCultureIgnoreCase))?
.Value; .Value;
@@ -36,11 +36,6 @@ public partial class MafileSerializer //SessionData
return null; return null;
} }
if (refreshToken.IsExpired || refreshToken.Type != SteamAccessTokenType.MobileRefresh)
{
result = DeserializedMafileSessionResult.Expired;
return null;
}
var sessionId = GetString(j, "sessionid", "session_id", "session"); var sessionId = GetString(j, "sessionid", "session_id", "session");
var accessTokenToken = GetToken(j, "accesstoken", "access_token", "access"); var accessTokenToken = GetToken(j, "accesstoken", "access_token", "access");
@@ -75,7 +70,16 @@ public partial class MafileSerializer //SessionData
sessionData.IsValid = SessionDataValidator.Validate(null, sessionData).Succeeded; sessionData.IsValid = SessionDataValidator.Validate(null, sessionData).Succeeded;
if(sessionData.IsValid == false) if(sessionData.IsValid == false)
return null; return null;
if (refreshToken.IsExpired || refreshToken.Type != SteamAccessTokenType.MobileRefresh)
{
result = DeserializedMafileSessionResult.Expired;
}
else
{
result = DeserializedMafileSessionResult.Valid; result = DeserializedMafileSessionResult.Valid;
}
return sessionData; return sessionData;
} }
} }
+84
View File
@@ -0,0 +1,84 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Changelog</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #eeeeee;
color: #333;
line-height: 1.6;
}
.changelog-container {
background-color: #fff;
border-radius: 10px;
padding: 25px;
margin: 25px auto;
max-width: 800px;
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
.change {
margin-bottom: 20px;
padding: 0;
border-left: 4px solid #a50ec7;
background-color: #f9f9f9;
}
.version {
font-weight: 600;
font-size: 1.5em;
color: #a50ec7;
margin-left: 10px;
}
.date {
font-style: italic;
color: #888;
margin-bottom: 10px;
margin-left: 15px;
}
.description {
font-size: 1em;
padding: 0 15px;
}
.description ul {
list-style: inside square;
padding: 0;
}
@media only screen and (max-width: 600px) {
.changelog-container {
width: 90%;
margin: 25px auto;
padding: 25px;
}
}
</style>
</head>
<body>
<div class="changelog-container">
<!-- Changelog entry -->
<div class="change">
<div class="version">Version 1.4.8</div>
<div class="date">DATE</div>
<div class="description">
- Fixed crash when attempting to update/save mafile without SessionData on proxy and group change<br/>
- The account found through the search will be selected automatically<br>
- Added proxy support types: without authentication (no user and password), domain proxy (localhost, mydomain.com), with "http://" scheme<br>
- Added "Timer changed" snackbar to indicate that preferences was updated<br>
- Now the port is visible in the proxy text<br>
- Few tooltips added on "Groups" and "Proxy" fields"<br/>
- Small UI improvements<br/>
</div>
</div>
</div>
</body>
</html>