This commit is contained in:
achiez
2025-05-02 19:57:11 +03:00
parent 64f79703b2
commit 31c38ac8ad
27 changed files with 394 additions and 139 deletions
+56 -12
View File
@@ -8,9 +8,6 @@
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<SolidColorBrush x:Key="MaterialDesignPaper">#1E2025</SolidColorBrush>
<FontFamily x:Key="Roboto">pack://application:,,,/Fonts/Roboto/#Roboto</FontFamily>
<FontFamily x:Key="RobotoSymbols">pack://application:,,,/Fonts/Roboto/#Roboto Symbols</FontFamily>
<converters:CoefficientConverter x:Key="CoefficientConverter"/>
<converters:ReverseBooleanConverter x:Key="ReverseBooleanConverter"/>
<converters:ProxyTextConverter x:Key="ProxyTextConverter"/>
@@ -19,27 +16,74 @@
<converters:ColorToBrushConverter x:Key="ColorToBrushConverter"/>
<converters:AnyMafilesToVisibilityConverter x:Key="AnyMafilesToVisibilityConverter"/>
<converters:PortableMaClientStatusToColorConverter x:Key="PortableMaClientStatusToColorConverter"/>
<converters:NullableToBooleanConverter x:Key="NullableToBooleanConverter"/>
<!-- Background converters-->
<background:BackgroundImageVisibleConverter x:Key="BackgroundImageVisibleConverter"/>
<background:BackgroundSourceConverter x:Key="BackgroundSourceConverter"/>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<materialDesign:NullableToVisibilityConverter x:Key="NullableToVisibilityConverter"/>
<system:Boolean x:Key="True">True</system:Boolean>
<system:Boolean x:Key="False">False</system:Boolean>
<ResourceDictionary.MergedDictionaries>
<materialDesign:BundledTheme BaseTheme="Dark" PrimaryColor="LightGreen" SecondaryColor="Purple" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.snackbar.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.Dark.xaml" />
<!-- Theme-->
<ResourceDictionary Source="Theme/Brushes.xaml"/>
<ResourceDictionary Source="Theme/WindowStyle/WindowStyle.xaml"/>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesign3.Defaults.xaml" />
<!--primary color-->
<ResourceDictionary>
<!--include your primary palette-->
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Theme/Brushes.xaml" />
</ResourceDictionary.MergedDictionaries>
<SolidColorBrush x:Key="MaterialDesign.Brush.Primary.Light" Color="{StaticResource PrimaryColor}"/>
<SolidColorBrush x:Key="MaterialDesign.Brush.Primary.Light.Foreground" Color="{StaticResource BaseContentColor}"/>
<SolidColorBrush x:Key="MaterialDesign.Brush.Primary" Color="{StaticResource PrimaryColor}"/>
<SolidColorBrush x:Key="MaterialDesign.Brush.Primary.Foreground" Color="{StaticResource BaseContentColor}"/>
<SolidColorBrush x:Key="MaterialDesign.Brush.Primary.Dark" Color="{StaticResource PrimaryColor}"/>
<SolidColorBrush x:Key="MaterialDesign.Brush.Primary.Dark.Foreground" Color="{StaticResource BaseContentColor}"/>
<SolidColorBrush x:Key="MaterialDesign.Brush.Card.Background" Color="{StaticResource Base100Color}"/>
<SolidColorBrush x:Key="MaterialDesign.Brush.Background" Color="{StaticResource BackgroundColor}"/>
<SolidColorBrush x:Key="MaterialDesign.Brush.Foreground" Color="{StaticResource BaseContentColor}"/>
<SolidColorBrush x:Key="MaterialDesign.Brush.ToolBar.Item.Background" Color="{StaticResource Base300Color}" />
<SolidColorBrush x:Key="MaterialDesign.Brush.ToolBar.Item.Foreground" Color="{StaticResource BaseContentColor}" />
</ResourceDictionary>
<!--secondary colour-->
<ResourceDictionary>
<!--include your secondary pallette-->
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Theme/Brushes.xaml" />
</ResourceDictionary.MergedDictionaries>
<SolidColorBrush x:Key="MaterialDesign.Brush.Secondary.Light" Color="{StaticResource SecondaryColor}" />
<SolidColorBrush x:Key="MaterialDesign.Brush.Secondary.Light.Foreground" Color="{StaticResource BaseContentColor}" />
<SolidColorBrush x:Key="MaterialDesign.Brush.Secondary" Color="{StaticResource SecondaryColor}" />
<SolidColorBrush x:Key="MaterialDesign.Brush.Secondary.Foreground" Color="{StaticResource BaseContentColor}" />
<SolidColorBrush x:Key="MaterialDesign.Brush.Secondary.Dark" Color="{StaticResource SecondaryColor}" />
<SolidColorBrush x:Key="MaterialDesign.Brush.Secondary.Dark.Foreground" Color="{StaticResource BaseContentColor}" />
</ResourceDictionary>
<!--Controls-->
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.snackbar.xaml" />
<ResourceDictionary Source="View/ConfirmationTemplates.xaml"/>
<!--Theme-->
<ResourceDictionary Source="Theme/WindowStyle/WindowStyle.xaml"/>
<ResourceDictionary Source="Theme/MaterialDesignThemes.Overrides.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
@@ -0,0 +1,19 @@
using System.Globalization;
using System.Windows.Data;
using System;
namespace NebulaAuth.Converters;
public class NullableToBooleanConverter : IValueConverter
{
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
return value != null;
}
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
+19 -2
View File
@@ -2,6 +2,7 @@
using System;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
@@ -58,10 +59,26 @@ public static class ThemeManager
private static void UpdateBackground()
{
var color = Settings.Instance.BackgroundColor ?? DefaultBackgroundColor;
Application.Current.Resources["WindowBackground"] = new SolidColorBrush(color);
Application.Current.Resources["Background"] = color;
ApplyTheme();
}
private static void ApplyTheme()
{
var keysToGenerate = Application.Current.Resources.Keys
.OfType<string>()
.Where(k => Application.Current.Resources[k] is System.Windows.Media.Color);
foreach (var key in keysToGenerate)
{
string brushKey = key + "Brush"; // Генерируем имя для Brush
var color = (System.Windows.Media.Color)Application.Current.Resources[key];
Application.Current.Resources[brushKey] = new SolidColorBrush(color);
}
}
public static void InitializeTheme()
{
UpdateIcon();
+27 -34
View File
@@ -9,16 +9,17 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:entities="clr-namespace:NebulaAuth.Model.Entities"
xmlns:viewModel="clr-namespace:NebulaAuth.ViewModel"
xmlns:controls="clr-namespace:NebulaAuth.Theme.Controls"
WindowStartupLocation="CenterScreen"
MinHeight="500" MinWidth="500" DefaultFontSize="18" ScaleCoefficient="0.4"
Title="NebulaAuth" Height="800" Width="730" Style="{StaticResource MainWindow}"
Title="NebulaAuth" Height="800" Width="730"
Style="{StaticResource MainWindow}"
RenderOptions.BitmapScalingMode="HighQuality" Foreground="#FFF5F5F5"
FontFamily="{md:MaterialDesignFont}"
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
TextElement.Foreground="{DynamicResource BaseContentBrush}"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance viewModel:MainVM}"
>
<b:Interaction.Behaviors>
<windowStyle:WindowChromeRenderedBehavior />
@@ -38,7 +39,7 @@
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Grid.RowSpan="2" Opacity="0.6" Stretch="UniformToFill" RenderOptions.BitmapScalingMode="LowQuality" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="{Binding Settings.BackgroundMode, Converter={StaticResource BackgroundImageVisibleConverter}}" Source="{Binding Settings.BackgroundMode, Mode=OneWay, Converter={StaticResource BackgroundSourceConverter}}" />
<Rectangle Grid.Row="0" Grid.RowSpan="2" Opacity="0.5" Fill="#FF1F1D1D" Visibility="{Binding Settings.BackgroundMode, Converter={StaticResource BackgroundImageVisibleConverter}}" />
<!--<Rectangle Grid.Row="0" Grid.RowSpan="2" Opacity="0.5" Fill="#FF1F1D1D" Visibility="{Binding Settings.BackgroundMode, Converter={StaticResource BackgroundImageVisibleConverter}}" />-->
<Rectangle Name="DragNDropOverlay" Grid.Row="0" Grid.RowSpan="3" Panel.ZIndex="1" Fill="#242123" Opacity="0.9" Visibility="Hidden" />
<StackPanel Name="DragNDropPanel" Grid.Row="0" ZIndex="2" w:FontScaleWindow.Scale="1" w:FontScaleWindow.ResizeFont="True" Grid.RowSpan="3" Visibility="Hidden" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock FontWeight="Bold" Foreground="#9a65b8" Text="{Tr MainWindow.Global.DragNDropHint}"/>
@@ -46,9 +47,10 @@
</StackPanel>
<ToolBarTray IsLocked="True" Grid.Row="0" >
<ToolBarTray.Background>
<SolidColorBrush Opacity="0.6" Color="#FF1A1C25" />
<!--<SolidColorBrush Opacity="0.6" Color="{DynamicResource Base300Color}" />-->
<SolidColorBrush Opacity="1" Color="{DynamicResource Base300Color}" />
</ToolBarTray.Background>
<ToolBar Background="#00FFFFFF" ClipToBounds="False" Style="{StaticResource MaterialDesignToolBar}" w:FontScaleWindow.Scale="0.68" w:FontScaleWindow.ResizeFont="True">
<ToolBar ClipToBounds="False" Style="{StaticResource MaterialDesignToolBar}" w:FontScaleWindow.Scale="0.68" w:FontScaleWindow.ResizeFont="True">
<Menu w:FontScaleWindow.Scale="0.68" w:FontScaleWindow.ResizeFont="True">
<MenuItem Header="{Tr MainWindow.Menu.File.Caption}">
<MenuItem Header="{Tr MainWindow.Menu.File.Import}" Command="{Binding AddMafileCommand}" />
@@ -127,7 +129,7 @@
</UIElement.Visibility>
</md:PackIcon>
<md:PackIcon Kind="StopAlert" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="#FFFFA500" Margin="3" ToolTip="{Tr MainWindow.AppBar.Proxy.ProxyAlert.DefaultInUse}" ToolTipService.InitialShowDelay="300" Visibility="{Binding IsDefaultProxy, Converter={StaticResource BooleanToVisibilityConverter}}" />
<ToggleButton ToolTip="{Tr MainWindow.AppBar.MarketTimerHint}" Foreground="{DynamicResource PrimaryHueDarkForegroundBrush}" IsEnabled="{Binding IsMafileSelected}" Margin="2" Style="{StaticResource MaterialDesignFlatToggleButton}" IsChecked="{Binding MarketTimerEnabled}" >
<ToggleButton ToolTip="{Tr MainWindow.AppBar.MarketTimerHint}" IsEnabled="{Binding IsMafileSelected}" Margin="2" Style="{StaticResource MaterialDesignFlatToggleButton}" IsChecked="{Binding MarketTimerEnabled}" >
<md:PackIcon Kind="ShoppingCart"/>
<FrameworkElement.ContextMenu>
<ContextMenu>
@@ -136,7 +138,7 @@
</ContextMenu>
</FrameworkElement.ContextMenu>
</ToggleButton>
<ToggleButton ToolTip="{Tr MainWindow.AppBar.TradeTimerHint}" Foreground="{DynamicResource PrimaryHueDarkForegroundBrush}" IsEnabled="{Binding IsMafileSelected}" Margin="2" Style="{StaticResource MaterialDesignFlatToggleButton}" IsChecked="{Binding TradeTimerEnabled}" >
<ToggleButton ToolTip="{Tr MainWindow.AppBar.TradeTimerHint}" IsEnabled="{Binding IsMafileSelected}" Margin="2" Style="{StaticResource MaterialDesignFlatToggleButton}" IsChecked="{Binding TradeTimerEnabled}" >
<md:PackIcon Kind="AccountArrowRight" />
<FrameworkElement.ContextMenu>
<ContextMenu>
@@ -178,10 +180,8 @@
</Grid.ColumnDefinitions>
<TextBlock HorizontalAlignment="Stretch" Text="{Binding AccountName}">
<TextBlock.Foreground>
<Binding Mode="OneWay" Path="LinkedClient.IsError" Converter="{StaticResource PortableMaClientStatusToColorConverter}">
<Binding.FallbackValue>
<SolidColorBrush Color="WhiteSmoke"/>
</Binding.FallbackValue>
<Binding Mode="OneWay" Path="LinkedClient.IsError" Converter="{StaticResource PortableMaClientStatusToColorConverter}" FallbackValue="{StaticResource PrimaryContentBrush}">
</Binding>
</TextBlock.Foreground>
</TextBlock>
@@ -221,7 +221,7 @@
<MenuItem Header="{Tr MainWindow.ContextMenus.Mafile.RemoveFromGroup}" Command="{Binding Path=RemoveGroupCommand}" CommandParameter="{Binding Path=PlacementTarget.SelectedValue, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}" />
</ContextMenu>
</FrameworkElement.ContextMenu>
</ListBox>
<Border Grid.Row="0" Margin="10" Padding="5" Visibility="{Binding MaFiles.Count, Converter={StaticResource AnyMafilesToVisibilityConverter}, Mode=OneWay}">
<Border.Background>
@@ -231,15 +231,13 @@
</Border>
<TextBox Style="{StaticResource MaterialDesignFloatingHintTextBox}" md:TextFieldAssist.HasClearButton="True" w:FontScaleWindow.Scale="0.7" w:FontScaleWindow.ResizeFont="True" Grid.Row="1" Margin="10,5,10,10" md:HintAssist.Hint="{Tr MainWindow.LeftPart.SearchBoxHint}" Text="{Binding SearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
<md:Card Grid.Column="1" Margin="10,10,15,10" UniformCornerRadius="15">
<Control.Background>
<SolidColorBrush Color="#FF1A1D25" Opacity="0.6" />
</Control.Background>
<md:Card BorderThickness="1" Style="{StaticResource MaterialDesignOutlinedCard}" Grid.Column="1" Margin="10,10,15,10" UniformCornerRadius="15">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="115*" />
<RowDefinition Height="436*"/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Row="0">
@@ -247,41 +245,36 @@
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBox w:FontScaleWindow.Scale="1.1" w:FontScaleWindow.ResizeFont="True" IsReadOnly="True" HorizontalContentAlignment="Center" Background="#00FFFFFF" Style="{StaticResource MaterialDesignFilledTextBox}" Text="{Binding Code, FallbackValue=Code}">
<TextBox w:FontScaleWindow.Scale="1.1" w:FontScaleWindow.ResizeFont="True" IsReadOnly="True" HorizontalContentAlignment="Center" Background="#00FFFFFF" Style="{StaticResource MaterialDesignTextBox}" Text="{Binding Code, FallbackValue=Code}">
<TextBox.InputBindings>
<MouseBinding Gesture="LeftClick" Command="{Binding CopyCodeCommand}" />
</TextBox.InputBindings>
</TextBox>
<Grid Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ProgressBar Margin="5" Foreground="#FF9932CC" Height="15" md:TransitionAssist.DisableTransitions="True" Value="{Binding CodeProgress}" />
</Grid>
<controls:CodeProgressBar Visibility="{Binding SelectedMafile, Converter={StaticResource NullableToVisibilityConverter}}" Grid.Row="1" Height="4" Style="{StaticResource MaterialDesignLinearProgressBar}" MaxTime="30" TimeRemaining="{Binding CodeProgress, Mode=OneWay}"/>
</Grid>
<Button IsEnabled="{Binding IsMafileSelected}" w:FontScaleWindow.Scale="0.7" w:FontScaleWindow.ResizeFont="True" Grid.Row="1" Style="{StaticResource MaterialDesignOutlinedButton}" Margin="10" Command="{Binding GetConfirmationsCommand}" Width="{Binding Path=ActualWidth, Converter={StaticResource CoefficientConverter}, ConverterParameter=0.6, RelativeSource={RelativeSource AncestorType=md:Card}}">
<Button IsEnabled="{Binding IsMafileSelected}" w:FontScaleWindow.Scale="0.7" w:FontScaleWindow.ResizeFont="True" Grid.Row="1" Style="{StaticResource MaterialDesignOutlinedButton}" Margin="82,10,82,10" Command="{Binding GetConfirmationsCommand}" Width="{Binding Path=ActualWidth, Converter={StaticResource CoefficientConverter}, ConverterParameter=0.6, RelativeSource={RelativeSource AncestorType=md:Card}}">
<TextBlock TextWrapping="Wrap" TextTrimming="WordEllipsis" Text="{Tr MainWindow.RightPart.LoadConfirmations}"/>
</Button>
<ItemsControl md:RippleAssist.IsDisabled="True" Focusable="False" Grid.Row="2" w:FontScaleWindow.Scale="0.72" w:FontScaleWindow.ResizeFont="True" Margin="10" Visibility="{Binding ConfirmationsVisible, Converter={StaticResource BooleanToVisibilityConverter}}" ItemsSource="{Binding Confirmations}"/>
<Button Grid.Row="3" Margin="1,0,1,3" w:FontScaleWindow.Scale="0.8" w:FontScaleWindow.ResizeFont="True" Command="{Binding ConfirmLoginCommand}" Content="{Tr MainWindow.RightPart.ConfirmLogin}"/>
<ItemsControl md:RippleAssist.IsDisabled="True" Focusable="False" Grid.Row="2" w:FontScaleWindow.Scale="0.72" w:FontScaleWindow.ResizeFont="True" Margin="10,10,10,10" Visibility="{Binding ConfirmationsVisible, Converter={StaticResource BooleanToVisibilityConverter}}" ItemsSource="{Binding Confirmations}" Grid.RowSpan="2"/>
<Button Style="{StaticResource MaterialDesignFlatButton}" Grid.Row="4" Margin="1,0,1,3" w:FontScaleWindow.Scale="0.8" w:FontScaleWindow.ResizeFont="True" Command="{Binding ConfirmLoginCommand}" Content="{Tr MainWindow.RightPart.ConfirmLogin}"/>
</Grid>
</md:Card>
</Grid>
<Border Grid.Row="2" BorderBrush="#FF696969">
<Border Grid.Row="2" BorderBrush="{DynamicResource Base100Brush}" >
<Border.Background>
<SolidColorBrush Opacity="0.5" Color="DimGray" />
<SolidColorBrush Opacity="0.5" Color="{DynamicResource Base300Color}" />
</Border.Background>
<Grid>
<ToolBarPanel Orientation="Horizontal" Margin="5" w:FontScaleWindow.Scale="0.73" w:FontScaleWindow.ResizeFont="True">
<ToolBarPanel TextElement.Foreground="{DynamicResource BaseContentBrush}" Orientation="Horizontal" Margin="5" w:FontScaleWindow.Scale="0.73" w:FontScaleWindow.ResizeFont="True">
<TextBlock FontWeight="Bold" Text="{Tr MainWindow.Footer.Account}" />
<TextBlock Text="{Binding SelectedMafile.AccountName}" />
<TextBlock Text="|" Margin="10,0,10,0" />
<TextBlock FontWeight="Bold" Text="{Tr MainWindow.Footer.Group}" />
<TextBlock FontWeight="Normal" Text="{Binding SelectedMafile.Group, TargetNullValue=' ', FallbackValue=' ', Mode=OneWay}" />
<Button Command="{Binding DebugCommand}">Debug</Button>
</ToolBarPanel>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Right" w:FontScaleWindow.Scale="0.7" w:FontScaleWindow.ResizeFont="True" Margin="0,0,10,0">
<Hyperlink NavigateUri="https://github.com/achiez/NebulaAuth-Steam-Desktop-Authenticator-by-Achies" Foreground="{DynamicResource PrimaryHueMidBrush}" RequestNavigate="Hyperlink_OnRequestNavigate">by achies</Hyperlink>
<Hyperlink NavigateUri="https://github.com/achiez/NebulaAuth-Steam-Desktop-Authenticator-by-Achies" Foreground="{DynamicResource PrimaryBrush}" RequestNavigate="Hyperlink_OnRequestNavigate">by achies</Hyperlink>
</TextBlock>
</Grid>
</Border>
+3 -2
View File
@@ -17,6 +17,7 @@ using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using AchiesUtilities.Web.Models;
using SteamLib.Utility;
namespace NebulaAuth.Model.MAAC;
@@ -24,7 +25,7 @@ public partial class PortableMaClient : ObservableObject, IDisposable
{
public Mafile Mafile { get; }
private HttpClient Client { get; }
private HttpClientHandler ClientHandler { get; }
private SocketsHttpHandler ClientHandler { get; }
private DynamicProxy Proxy { get; }
[ObservableProperty] private bool _autoConfirmTrades;
@@ -169,7 +170,7 @@ public partial class PortableMaClient : ObservableObject, IDisposable
}
private HttpClientHandlerPair Chp() => new(Client, ClientHandler);
private SocketsClientHandlerPair Chp() => new(Client, ClientHandler);
private static string GetLocalization(string key)
{
+4 -2
View File
@@ -13,20 +13,22 @@ using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using SteamLib.Utility;
namespace NebulaAuth.Model;
public static class MaClient
{
private static HttpClientHandler ClientHandler { get; }
private static SocketsHttpHandler ClientHandler { get; }
private static HttpClient Client { get; }
private static DynamicProxy Proxy { get; }
public static ProxyData? DefaultProxy { get; set; }
public static HttpClientHandlerPair Chp => new(Client, ClientHandler);
public static SocketsClientHandlerPair Chp => new(Client, ClientHandler);
static MaClient()
{
+5 -4
View File
@@ -8,6 +8,7 @@ using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using NebulaAuth.View.Dialogs;
using SteamLib.Utility;
namespace NebulaAuth.Model;
@@ -17,7 +18,7 @@ public static partial class SessionHandler
private static readonly SemaphoreSlim Semaphore = new(1, 1);
public static async Task<T> Handle<T>(Func<Task<T>> func, Mafile mafile,
HttpClientHandlerPair? chp = null, string? snackbarPrefix = null)
SocketsClientHandlerPair? chp = null, string? snackbarPrefix = null)
{
chp ??= MaClient.Chp;
await Semaphore.WaitAsync();
@@ -31,7 +32,7 @@ public static partial class SessionHandler
}
}
private static async Task<T> HandleInternal<T>(Func<Task<T>> func, HttpClientHandlerPair chp, Mafile mafile,
private static async Task<T> HandleInternal<T>(Func<Task<T>> func, SocketsClientHandlerPair chp, Mafile mafile,
string? snackbarPrefix = null)
{
using var scope = Shell.Logger.PushScopeProperty("Scope", "SessionHandler");
@@ -129,7 +130,7 @@ public static partial class SessionHandler
}
private static async Task<bool> RefreshInternal(HttpClientHandlerPair chp, Mafile mafile)
private static async Task<bool> RefreshInternal(SocketsClientHandlerPair chp, Mafile mafile)
{
try
{
@@ -143,7 +144,7 @@ public static partial class SessionHandler
}
}
private static async Task<bool> LoginAgainInternal(HttpClientHandlerPair chp, Mafile mafile, string password,
private static async Task<bool> LoginAgainInternal(SocketsClientHandlerPair chp, Mafile mafile, string password,
bool savePassword)
{
var t = Task.Run(OnLoginStarted);
+3 -2
View File
@@ -7,12 +7,13 @@ using SteamLib.Authentication.LoginV2;
using SteamLib.Exceptions;
using SteamLib.SteamMobile;
using System.Threading.Tasks;
using SteamLib.Utility;
namespace NebulaAuth.Model;
public partial class SessionHandler //API
{
public static async Task RefreshMobileToken(HttpClientHandlerPair chp, Mafile mafile)
public static async Task RefreshMobileToken(SocketsClientHandlerPair chp, Mafile mafile)
{
if (mafile.SessionData is not { RefreshToken.IsExpired: false })
throw new SessionPermanentlyExpiredException(SessionInvalidException.SESSION_NULL_MSG);
@@ -30,7 +31,7 @@ public partial class SessionHandler //API
chp.Handler.CookieContainer.SetSteamMobileCookiesWithMobileToken(mafile.SessionData);
}
public static async Task LoginAgain(HttpClientHandlerPair chp, Mafile mafile, string password, bool savePassword)
public static async Task LoginAgain(SocketsClientHandlerPair chp, Mafile mafile, string password, bool savePassword)
{
var sgGenerator = new SteamGuardCodeGenerator(mafile.SharedSecret);
var options = new LoginV2ExecutorOptions(LoginV2Executor.NullConsumer, chp.Client)
+51 -52
View File
@@ -1,48 +1,47 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows7.0</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
<LangVersion>latest</LangVersion>
<SatelliteResourceLanguages>en;ru;ua</SatelliteResourceLanguages>
<ApplicationIcon>Theme\lock.ico</ApplicationIcon>
<SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion>
<AssemblyVersion>1.5.5</AssemblyVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<None Remove="Theme\1140x641.jpg" />
<None Remove="Theme\Background.jpg" />
<None Remove="Theme\lock.ico" />
<None Remove="Theme\SplashScreen.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autoupdater.NET.Official" Version="1.9.2" />
<PackageReference Include="CodingSeb.Localization.JsonFileLoader" Version="1.3.1" />
<PackageReference Include="CodingSeb.Localization.WPF" Version="1.3.3" />
<PackageReference Include="CodingSebLocalization.Fody" Version="1.3.1" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.3.2" />
<PackageReference Include="MaterialDesignColors" Version="2.1.4" />
<PackageReference Include="MaterialDesignThemes" Version="4.9.0" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.122" />
<PackageReference Include="NLog" Version="5.3.4" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.14" />
</ItemGroup>
<ItemGroup>
<Resource Include="Theme\Background.jpg">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Resource>
<Resource Include="Theme\lock.ico" />
</ItemGroup>
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows7.0</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
<LangVersion>latest</LangVersion>
<SatelliteResourceLanguages>en;ru;ua</SatelliteResourceLanguages>
<ApplicationIcon>Theme\lock.ico</ApplicationIcon>
<SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion>
<AssemblyVersion>1.5.5</AssemblyVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SteamLibForked\SteamLibForked.csproj" />
<None Remove="Theme\1140x641.jpg" />
<None Remove="Theme\Background.jpg" />
<None Remove="Theme\lock.ico" />
<None Remove="Theme\SplashScreen.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autoupdater.NET.Official" Version="1.9.2" />
<PackageReference Include="CodingSeb.Localization.JsonFileLoader" Version="1.3.1" />
<PackageReference Include="CodingSeb.Localization.WPF" Version="1.3.3" />
<PackageReference Include="CodingSebLocalization.Fody" Version="1.3.1" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="MaterialDesignThemes" Version="5.2.1" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
<PackageReference Include="NLog" Version="5.4.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.4.0" />
</ItemGroup>
<ItemGroup>
<Resource Include="Theme\Background.jpg">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Resource>
<Resource Include="Theme\lock.ico" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SteamLibForked\SteamLibForked.csproj" />
</ItemGroup>
<ItemGroup>
@@ -50,19 +49,19 @@
</ItemGroup>
<ItemGroup>
<Compile Update="View\Dialogs\LoginAgainOnImportDialog.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="View\Dialogs\LoginAgainOnImportDialog.xaml.cs">
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="NLog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="localization.loc.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Update="NLog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="localization.loc.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
+5 -1
View File
@@ -6,4 +6,8 @@
• Добавить запоминание пароля при привязке мафайла
• Функция переноса гуарда с мобильного устройства на ПК с созданием мафайла
• Добавить полное шифрование мафайлов по аналогии с SDA
• Сделать автоматический билд и загрузку обновления на Github при изменении в мастер ветке
• Сделать автоматический билд и загрузку обновления на Github при изменении в мастер ветке
• Антик-окно как в MarketApp, возможность сразу открыть браузер напр. на CefSharp с залогиненым аккаунтом
• Стабильность авто-подтверждений, возможность задать пользователю порог времени когда льются ошибки и только тогда выключать авто-подтверждение
• Безопасное сохранение мафайлов через .tmp / .bak
• Создание механизма накопления ошибок, чтобы исправить Patch Tuesday, условно аккаунт может игнорировать ошибки 1-2 часа (настриавемо)
+59 -2
View File
@@ -1,9 +1,66 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Color x:Key="PrimaryColor">#794DFF</Color>
<Color x:Key="PrimaryContentColor">#eae7ff</Color>
<Color x:Key="SecondaryColor">#76717f</Color>
<Color x:Key="SecondaryContentColor">#ffffff</Color>
<Color x:Key="AccentColor">#3b82f6</Color>
<Color x:Key="AccentContentColor">#dbeafe</Color>
<Color x:Key="NeutralColor">#928f9e</Color>
<Color x:Key="NeutralContentColor">#141119</Color>
<Color x:Key="Base100Color">#282332</Color>
<Color x:Key="Base200Color">#1d1a26</Color>
<Color x:Key="Base300Color">#4a4456</Color>
<Color x:Key="BackgroundColor">#231f2c</Color>
<Color x:Key="BaseContentColor">#b8b6c0</Color>
<Color x:Key="BaseShadowColor">#1e1e24</Color>
<Color x:Key="InfoColor">#06b6d4</Color>
<Color x:Key="InfoContentColor">#cffafe</Color>
<Color x:Key="SuccessColor">#02ca4b</Color>
<Color x:Key="SuccessContentColor">#e1faf1</Color>
<Color x:Key="WarningColor">#fcaa1d</Color>
<Color x:Key="WarningContentColor">#fffae8</Color>
<Color x:Key="ErrorColor">#fb4141</Color>
<Color x:Key="ErrorContentColor">#fff5ed</Color>
<Color x:Key="DummyColor">#d66d1c</Color>
<!--Theme-->
<SolidColorBrush x:Key="PrimaryBrush" Color="{DynamicResource PrimaryColor}"/>
<SolidColorBrush x:Key="PrimaryContentBrush" Color="{DynamicResource PrimaryContentColor}"/>
<SolidColorBrush x:Key="SecondaryBrush" Color="{DynamicResource SecondaryColor}"/>
<SolidColorBrush x:Key="SecondaryContentBrush" Color="{DynamicResource SecondaryContentColor}"/>
<SolidColorBrush x:Key="AccentBrush" Color="{DynamicResource AccentColor}"/>
<SolidColorBrush x:Key="AccentContentBrush" Color="{DynamicResource AccentContentColor}"/>
<SolidColorBrush x:Key="NeutralBrush" Color="{DynamicResource NeutralColor}"/>
<SolidColorBrush x:Key="NeutralContentBrush" Color="{DynamicResource NeutralContentColor}"/>
<SolidColorBrush x:Key="Base100Brush" Color="{DynamicResource Base100Color}"/>
<SolidColorBrush x:Key="Base200Brush" Color="{DynamicResource Base200Color}"/>
<SolidColorBrush x:Key="Base300Brush" Color="{DynamicResource Base300Color}"/>
<SolidColorBrush x:Key="BackgroundBrush" Color="{DynamicResource BackgroundColor}"/>
<!--BackgroundBrush conflict-->
<SolidColorBrush x:Key="BaseContentBrush" Color="{DynamicResource BaseContentColor}"/>
<SolidColorBrush x:Key="BaseShadowBrush" Color="{DynamicResource BaseShadowColor}"/>
<SolidColorBrush x:Key="InfoBrush" Color="{DynamicResource InfoColor}"/>
<SolidColorBrush x:Key="InfoContentBrush" Color="{DynamicResource InfoContentColor}"/>
<SolidColorBrush x:Key="SuccessBrush" Color="{DynamicResource SuccessColor}"/>
<SolidColorBrush x:Key="SuccessContentBrush" Color="{DynamicResource SuccessContentColor}"/>
<SolidColorBrush x:Key="WarningBrush" Color="{DynamicResource WarningColor}"/>
<SolidColorBrush x:Key="WarningContentBrush" Color="{DynamicResource WarningContentColor}"/>
<SolidColorBrush x:Key="ErrorBrush" Color="{DynamicResource ErrorColor}"/>
<SolidColorBrush x:Key="ErrorContentBrush" Color="{DynamicResource ErrorContentColor}"/>
<SolidColorBrush x:Key="DummyBrush" Color="{DynamicResource DummyColor}"></SolidColorBrush>
<!--Card-->
<SolidColorBrush x:Key="MaterialDesignCardBackground" Color="#26292E" />
<SolidColorBrush x:Key="PrimaryHueMidBrush" Color="#FF9056B1" />
<!--<SolidColorBrush x:Key="MaterialDesignCardBackground" Color="#26292E" />-->
<!--<SolidColorBrush x:Key="PrimaryHueMidBrush" Color="#FF9056B1" />
<SolidColorBrush x:Key="PrimaryHueLightBrush" Color="#FF9C70B5" />
<SolidColorBrush x:Key="PrimaryHueDarkForegroundBrush" Color="#FF851BC1" />
<SolidColorBrush x:Key="MaterialDesign.Brush.Card.Background" Color="{DynamicResource Base100}"></SolidColorBrush>
<SolidColorBrush x:Key="DynamicResource MaterialDesign.Brush.Card.Border" Color="#b8b6c0"></SolidColorBrush>-->
</ResourceDictionary>
@@ -0,0 +1,53 @@
namespace NebulaAuth.Theme.Controls;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
public class CodeProgressBar : ProgressBar
{
public static readonly DependencyProperty TimeRemainingProperty =
DependencyProperty.Register(nameof(TimeRemaining), typeof(double), typeof(CodeProgressBar),
new PropertyMetadata(-1.0, OnTimeRemainingChanged));
public static readonly DependencyProperty MaxTimeProperty =
DependencyProperty.Register(nameof(MaxTime), typeof(double), typeof(CodeProgressBar),
new PropertyMetadata(30.0)); // По умолчанию 30 сек
public double TimeRemaining
{
get => (double)GetValue(TimeRemainingProperty);
set => SetValue(TimeRemainingProperty, value);
}
public double MaxTime
{
get => (double)GetValue(MaxTimeProperty);
set => SetValue(MaxTimeProperty, value);
}
private static void OnTimeRemainingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is CodeProgressBar progressBar)
{
var newValue = (double)e.NewValue;
progressBar.StartProgressAnimation(newValue);
}
}
private void StartProgressAnimation(double timeRemaining)
{
if (timeRemaining <= 0 || MaxTime <= 0) return;
var progress = (1 - (timeRemaining / MaxTime)) * 100;
var animation = new DoubleAnimation
{
From = progress,
To = 100,
Duration = TimeSpan.FromSeconds(timeRemaining),
};
BeginAnimation(ValueProperty, animation);
}
}
@@ -0,0 +1,17 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:materialDesign="clr-namespace:MaterialDesignThemes.Wpf;assembly=MaterialDesignThemes.Wpf">
<Style BasedOn="{StaticResource MaterialDesignLinearProgressBar}" TargetType="{x:Type ProgressBar}">
<Setter Property="Background" Value="{DynamicResource Base200Brush}" />
<Setter Property="BorderThickness" Value="0" />
</Style>
<Style x:Key="MaterialDesignLinearProgressBar" BasedOn="{StaticResource MaterialDesignLinearProgressBar}" TargetType="{x:Type ProgressBar}">
<Setter Property="Background" Value="{DynamicResource Base200Brush}" />
<Setter Property="BorderThickness" Value="0" />
</Style>
<!--If style is not default like above, x:key must be provided (the same as BasedOn)-->
</ResourceDictionary>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 365 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.
+11 -4
View File
@@ -17,7 +17,9 @@
Margin="{x:Static local:WindowChromeHelper.LayoutOffsetThickness}"
BorderBrush="Transparent"
BorderThickness="1"
Background="{DynamicResource WindowBackground}">
Background="{DynamicResource BackgroundBrush}"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
@@ -26,10 +28,11 @@
<Grid x:Name="TitleBar"
Grid.Row="0"
Height="28"
Background="{DynamicResource WindowBackground}">
Background="{DynamicResource Base100Brush}">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"
Foreground="{DynamicResource PrimaryHueMidBrush}"
Foreground="{DynamicResource PrimaryBrush}"
Text="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Title}" FontSize="17"/>
<!-- Window Buttons -->
<StackPanel
HorizontalAlignment="Right"
@@ -42,16 +45,20 @@
</StackPanel.Resources>
<Button x:Name="MinimizeButton"
Click="OnMinimizeClick"
>
<materialDesign:PackIcon Kind="WindowMinimize"/>
</Button>
<Button x:Name="MaximizeRestoreButton"
Click="OnMaximizeRestoreClick"
>
<materialDesign:PackIcon Kind="WindowMaximize"/>
</Button>
<Button x:Name="CloseButton"
Click="OnCloseClick">
Click="OnCloseClick"
>
<materialDesign:PackIcon Kind="WindowClose"/>
</Button>
</StackPanel>
Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 906 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 906 KiB

@@ -7,9 +7,7 @@
xmlns:theme="clr-namespace:NebulaAuth.Theme"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
Foreground="WhiteSmoke"
d:DataContext="{d:DesignInstance other:LoginAgainVM}"
Background="{DynamicResource WindowBackground}">
d:DataContext="{d:DesignInstance other:LoginAgainVM}">
<Grid MinHeight="100" MinWidth="300" MaxWidth="400" Margin="20">
<Grid.RowDefinitions>
+1 -2
View File
@@ -7,13 +7,12 @@
xmlns:other="clr-namespace:NebulaAuth.ViewModel.Other"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="400"
Foreground="WhiteSmoke"
FontFamily="{md:MaterialDesignFont}"
MinHeight="500"
MinWidth="400"
MaxHeight="550"
d:DataContext="{d:DesignInstance other:ProxyManagerVM}"
Background="{DynamicResource WindowBackground}">
Background="{DynamicResource BackgroundBrush1}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
+16
View File
@@ -14,6 +14,8 @@ using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Media;
namespace NebulaAuth.ViewModel;
@@ -52,6 +54,20 @@ public partial class MainVM : ObservableObject
}
}
[RelayCommand]
public void Debug()
{
var ph = new PaletteHelper();
var t = new MaterialDesignThemes.Wpf.Theme();
var cur = ph.GetTheme();
t.SetDarkTheme();
ph.SetTheme(t);
return;
}
private void SetMafile(Mafile? mafile)
{
+21 -12
View File
@@ -4,10 +4,12 @@ using NebulaAuth.Core;
using NebulaAuth.Model;
using SteamLib.SteamMobile;
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Animation;
using System.Windows.Threading;
namespace NebulaAuth.ViewModel;
@@ -22,6 +24,7 @@ public partial class MainVM
[MemberNotNull(nameof(_codeTimer))]
private void CreateCodeTimer()
{
CodeProgress = CalculateCodeProgress();
_codeTimer = new Timer(UpdateCode, null, 0, 1000);
}
@@ -31,24 +34,30 @@ public partial class MainVM
{
var currentTime = TimeAligner.GetSteamTime();
var untilChange = currentTime % 30;
var codeProgress = untilChange / 30D * 100;
string? code = null;
if (untilChange == 0 && SelectedMafile != null)
{
code = SteamGuardCodeGenerator.GenerateCode(SelectedMafile!.SharedSecret);
}
if (untilChange != 0) return;
if (Application.Current == null) return;
Application.Current.Dispatcher.BeginInvoke((string? c) =>
Application.Current.Dispatcher.BeginInvoke(() =>
{
CodeProgress = -1;
CodeProgress = 30;
if (Application.Current.MainWindow?.WindowState == WindowState.Minimized) return;
CodeProgress = codeProgress;
if (c != null) Code = c;
}, DispatcherPriority.DataBind, code);
if (SelectedMafile == null) return;
Code = SteamGuardCodeGenerator.GenerateCode(SelectedMafile.SharedSecret);
}, DispatcherPriority.DataBind);
}
private long CalculateCodeProgress()
{
var currentTime = TimeAligner.GetSteamTime();
var untilChange = currentTime % 30;
return 30 - untilChange;
}
[RelayCommand(AllowConcurrentExecutions = false)]
private async Task CopyCode()
{
+1 -1
View File
@@ -79,7 +79,7 @@ public partial class LinkAccountVM : ObservableObject, IEmailProvider, IPhoneNum
#region HttpClient
private static HttpClient Client { get; }
private static HttpClientHandler Handler { get; }
private static SocketsHttpHandler Handler { get; }
private static DynamicProxy Proxy { get; }
public ObservableDictionary<int, ProxyData> Proxies => ProxyStorage.Proxies;
@@ -0,0 +1,17 @@
namespace SteamLib.Utility;
public readonly struct SocketsClientHandlerPair
{
public SocketsHttpHandler Handler { get; }
public HttpClient Client { get; }
public SocketsClientHandlerPair(HttpClient client, SocketsHttpHandler handler)
{
Handler = handler;
Client = client;
}
public (SocketsHttpHandler, HttpClient) Deconstruct()
{
return (Handler, Client);
}
}
+5 -4
View File
@@ -3,15 +3,16 @@ using System.Net.Http.Headers;
using AchiesUtilities.Web.Models;
using SteamLib.Authentication;
using SteamLib.Core.Interfaces;
using SteamLib.Utility;
namespace SteamLib.Web;
public static class ClientBuilder
{
public static HttpClientHandlerPair BuildMobileClient(IWebProxy? proxy, IMobileSessionData? sessionData, bool disposeHandler = true)
public static SocketsClientHandlerPair BuildMobileClient(IWebProxy? proxy, IMobileSessionData? sessionData, bool disposeHandler = true)
{
sessionData?.EnsureValidated();
var handler = new HttpClientHandler();
var handler = new SocketsHttpHandler();
var client = new HttpClient(handler, disposeHandler);
client.DefaultRequestHeaders.Accept.ParseAdd("application/json, text/javascript, text/html, application/xml, text/xml, */*");
@@ -33,12 +34,12 @@ public static class ClientBuilder
}
ConfigureCommon(handler, client);
return new HttpClientHandlerPair(client, handler);
return new SocketsClientHandlerPair(client, handler);
}
private static void ConfigureCommon(HttpClientHandler handler, HttpClient client)
private static void ConfigureCommon(SocketsHttpHandler handler, HttpClient client)
{
ConfigureCommonClient(client);
handler.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;