Compare commits

...

11 Commits

Author SHA1 Message Date
achiez a56757302e Resolved issue where a "Confirmation Error" notification appeared despite the confirmation being successful 2025-07-19 00:11:42 +03:00
achiez 1ad30ba49d 1.7.3 Add automatic ack on confirming Trades accordingly to new update 2025-07-17 22:49:22 +03:00
achiez 04e2188437 bump version to 1.7.2 2025-07-10 13:35:56 +03:00
achiez b4c4f52fd1 Fix: reintroduce bug from incorrect merge, now fully resolved
Previously fixed bug was unintentionally reintroduced due to merging the wrong branch. This commit properly resolves the issue.
2025-07-10 13:31:44 +03:00
achiez f079488840 temporary return old update.xml path 2025-07-09 22:39:08 +03:00
achiez 4bae3f0250 Merge 1.7.1 to master 2025-07-09 22:33:33 +03:00
achiez 4c9ec85d6f bump version to 1.7.1 2025-07-09 22:27:49 +03:00
achiez 4761fc70fe 1.7.1: Merge 1.7.0 version to release versions 2025-07-09 22:26:00 +03:00
achiez 3abc12f4bc Add support to new confirmation type (Purchase) and improve localization and snackbars 2025-07-09 22:19:21 +03:00
achiez 99982cacb6 Fix "Load Confirmations" crash caused by wrong order in resource dictionaries 2025-07-02 00:56:28 +03:00
achiez 2a641e99ae Update version to 1.5.7
- Changed session ID retrieval method in `LoginV2Executor` for avoiding 429 errors
2025-05-23 16:32:50 +03:00
30 changed files with 664 additions and 91 deletions
+4
View File
@@ -19,6 +19,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "changelog", "changelog", "{
changelog\1.5.4.html = changelog\1.5.4.html
changelog\1.5.5.html = changelog\1.5.5.html
changelog\1.5.6.html = changelog\1.5.6.html
changelog\1.7.1.html = changelog\1.7.1.html
changelog\1.7.2.html = changelog\1.7.2.html
changelog\1.7.3.html = changelog\1.7.3.html
changelog\1.7.4.html = changelog\1.7.4.html
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SteamLibForked", "src\SteamLibForked\SteamLibForked.csproj", "{224F9DB0-3D20-A614-BA2A-12F22B13A2C6}"
+3 -3
View File
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>1.5.6.0</version>
<url>https://github.com/achiez/NebulaAuth-Steam-Desktop-Authenticator-by-Achies/releases/download/1.5.6/NebulaAuth.1.5.6.zip</url>
<changelog>https://achiez.github.io/NebulaAuth-Steam-Desktop-Authenticator-by-Achies/changelog/1.5.6.html</changelog>
<version>1.7.4.0</version>
<url>https://github.com/achiez/NebulaAuth-Steam-Desktop-Authenticator-by-Achies/releases/download/1.7.4/NebulaAuth.1.7.4.zip</url>
<changelog>https://achiez.github.io/NebulaAuth-Steam-Desktop-Authenticator-by-Achies/changelog/1.7.4.html</changelog>
<mandatory>false</mandatory>
</item>
+85
View File
@@ -0,0 +1,85 @@
<!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.5.7</div>
<div class="date">23.05.2025</div>
<div class="description">
<ul>
<li>
<b>NEWS:</b> Official Telegram group now available! Join us at
<b>
<a href="https://t.me/nebulaauth">t.me/nebulaauth</a>
</b>
</li>
<li><b>FIX:</b>Removed request to /market/ upon login to prevent 429 error on banned IP</li>
</ul>
</div>
</div>
</div>
</body>
</html>
+89
View File
@@ -0,0 +1,89 @@
<!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.7.1</div>
<div class="date">09.07.2025</div>
<div class="description">
<ul>
<li>
<b>NEWS:</b> Official Telegram group now available! Join us at
<b>
<a href="https://t.me/nebulaauth">t.me/nebulaauth</a>
</b>
</li>
<li><b>UPDATE:</b> Added support for a new confirmation type — Purchase.</li>
<li><b>UPDATE:</b> Merged Global 1.7.0 updates into the release version (<a href="https://t.me/nebulaauth/32">patch notes</a>).</li>
<li><b>FIX:</b> Fixed a crash occurring during confirmation loading.</li>
<li><b>ENHANCEMENT:</b> Improved localization and system messages.</li>
</ul>
</div>
</div>
</div>
</body>
</html>
+86
View File
@@ -0,0 +1,86 @@
<!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.7.2</div>
<div class="date">10.07.2025</div>
<div class="description">
<ul>
<li>
<b>NEWS:</b> Official Telegram group now available! Join us at
<b>
<a href="https://t.me/nebulaauth">t.me/nebulaauth</a>
</b>
</li>
<li><b>FIX:</b> Crash on loading trade confirmations</li>
</ul>
</div>
</div>
</div>
</body>
</html>
+87
View File
@@ -0,0 +1,87 @@
<!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.7.3</div>
<div class="date">17.07.2025</div>
<div class="description">
<ul>
<li>
<b>NEWS:</b> Official Telegram group now available! Join us at
<b>
<a href="https://t.me/nebulaauth">t.me/nebulaauth</a>
</b>
</li>
<li><b>UPDATE:</b> Added automatic acknowledgment request for sending trade confirmation</li>
<li><b>FIX:</b> Fixed notifications text in auto-confirm timer</li>
</ul>
</div>
</div>
</div>
</body>
</html>
+86
View File
@@ -0,0 +1,86 @@
<!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.7.4</div>
<div class="date">19.07.2025</div>
<div class="description">
<ul>
<li>
<b>NEWS:</b> Official Telegram group now available! Join us at
<b>
<a href="https://t.me/nebulaauth">t.me/nebulaauth</a>
</b>
</li>
<li><b>FIX:</b> Resolved issue where a "Confirmation Error" notification appeared despite the confirmation being successful.</li>
</ul>
</div>
</div>
</div>
</body>
</html>
+2 -25
View File
@@ -1,36 +1,13 @@
<Application x:Class="NebulaAuth.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:converters="clr-namespace:NebulaAuth.Converters"
xmlns:system="clr-namespace:System;assembly=System.Runtime"
xmlns:background="clr-namespace:NebulaAuth.Converters.Background">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<converters:CoefficientConverter x:Key="CoefficientConverter" />
<converters:ReverseBooleanConverter x:Key="ReverseBooleanConverter" />
<converters:ProxyTextConverter x:Key="ProxyTextConverter" />
<converters:ProxyDataTextConverter x:Key="ProxyDataTextConverter" />
<converters:MultiCommandParameterConverter x:Key="MultiCommandParameterConverter" />
<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>
<ResourceDictionary Source="/Converters/Converters.xaml" />
<ResourceDictionary Source="Theme/Themes/DefaultTheme.xaml" />
<ResourceDictionary
Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesign3.Defaults.xaml" />
+28
View File
@@ -0,0 +1,28 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=System.Runtime"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:converters="clr-namespace:NebulaAuth.Converters"
xmlns:background="clr-namespace:NebulaAuth.Converters.Background">
<converters:CoefficientConverter x:Key="CoefficientConverter" />
<converters:ReverseBooleanConverter x:Key="ReverseBooleanConverter" />
<converters:ProxyTextConverter x:Key="ProxyTextConverter" />
<converters:ProxyDataTextConverter x:Key="ProxyDataTextConverter" />
<converters:MultiCommandParameterConverter x:Key="MultiCommandParameterConverter" />
<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>
+1 -1
View File
@@ -44,7 +44,7 @@ public class SnackbarController
private static TimeSpan GetSnackbarTime(string str)
{
var duration = str.Length / 0.03;
var duration = str.Length / 0.022;
if (duration < MIN_SNACKBAR_TIME)
{
duration = MIN_SNACKBAR_TIME;
+1 -1
View File
@@ -8,7 +8,7 @@ namespace NebulaAuth.Core;
public static class UpdateManager
{
private const string UPDATE_URL =
"https://raw.githubusercontent.com/achiez/NebulaAuth-Steam-Desktop-Authenticator-by-Achies/master/misc/update.xml";
"https://raw.githubusercontent.com/achiez/NebulaAuth-Steam-Desktop-Authenticator-by-Achies/master/NebulaAuth/update.xml";
public static void CheckForUpdates()
{
+21 -2
View File
@@ -13,6 +13,7 @@ using NebulaAuth.Core;
using NebulaAuth.Model.Entities;
using NebulaAuth.Utility;
using SteamLib.Api.Mobile;
using SteamLib.Api.Trade;
using SteamLib.Authentication;
using SteamLib.Exceptions.Authorization;
using SteamLib.SteamMobile.Confirmations;
@@ -90,7 +91,8 @@ public partial class PortableMaClient : ObservableObject, IDisposable
var toConfirm = new List<Confirmation>();
if (AutoConfirmMarket)
{
var market = conf.Where(c => c.ConfType == ConfirmationType.MarketSellTransaction);
var market = conf.Where(c =>
c.ConfType is ConfirmationType.MarketSellTransaction or ConfirmationType.Purchase);
toConfirm.AddRange(market);
}
@@ -106,6 +108,7 @@ public partial class PortableMaClient : ObservableObject, IDisposable
Shell.Logger.Debug("Timer {accountName}: Sending confirmations. Count: {count}", Mafile.AccountName,
toConfirm.Count);
var success = await HandleTimerRequest(() => SendConfirmations(toConfirm));
//TODO: handle success == false
Shell.Logger.Debug("Timer {accountName}: Confirmation sent: {confirmResult}", Mafile.AccountName, success);
return toConfirm.Count;
}
@@ -125,7 +128,23 @@ public partial class PortableMaClient : ObservableObject, IDisposable
private async Task<bool> SendConfirmations(IEnumerable<Confirmation> confirmations)
{
return await SteamMobileConfirmationsApi.SendMultipleConfirmations(Client, confirmations,
var conf = confirmations.ToList();
var res = await SteamMobileConfirmationsApi.SendMultipleConfirmations(Client, conf,
Mafile.SessionData!.SteamId, Mafile, true, _cts.Token);
if (!res && conf.Any(c => c.ConfType == ConfirmationType.Trade))
{
Shell.Logger.Warn("Timer {accountName}: Failed to send trade confirmations. Sending ack",
Mafile.AccountName);
await SteamTradeApi.Acknowledge(Client, Mafile.SessionData!.SessionId, _cts.Token);
await Task.Delay(10, _cts.Token);
}
else
{
return res;
}
return await SteamMobileConfirmationsApi.SendMultipleConfirmations(Client, conf,
Mafile.SessionData!.SteamId, Mafile, true, _cts.Token);
}
+38 -5
View File
@@ -8,6 +8,7 @@ using AchiesUtilities.Web.Proxy;
using NebulaAuth.Model.Entities;
using SteamLib.Api.Mobile;
using SteamLib.Api.Services;
using SteamLib.Api.Trade;
using SteamLib.Authentication;
using SteamLib.Exceptions.Authorization;
using SteamLib.ProtoCore.Services;
@@ -78,26 +79,58 @@ public static class MaClient
return SessionHandler.RefreshMobileToken(new HttpClientHandlerPair(Client, ClientHandler), mafile);
}
public static Task<bool> SendConfirmation(Mafile mafile, Confirmation confirmation, bool confirm)
public static async Task<bool> SendConfirmation(Mafile mafile, Confirmation confirmation, bool confirm)
{
ValidateMafile(mafile);
SetProxy(mafile);
return SteamMobileConfirmationsApi.SendConfirmation(Client, confirmation, mafile.SessionData!.SteamId, mafile,
var res = await SteamMobileConfirmationsApi.SendConfirmation(Client, confirmation, mafile.SessionData!.SteamId,
mafile,
confirm);
if (!res && confirmation.ConfType == ConfirmationType.Trade)
{
Shell.Logger.Warn("Failed to send trade confirmation for {accountName}. Sending ack", mafile.AccountName);
await SteamTradeApi.Acknowledge(Client, mafile.SessionData.SessionId);
await Task.Delay(10);
}
else
{
return res;
}
return await SteamMobileConfirmationsApi.SendConfirmation(Client, confirmation, mafile.SessionData!.SteamId,
mafile,
confirm);
}
public static Task<bool> SendMultipleConfirmation(Mafile mafile, IEnumerable<Confirmation> confirmations,
public static async Task<bool> SendMultipleConfirmation(Mafile mafile, IEnumerable<Confirmation> confirmations,
bool confirm)
{
var enumerable = confirmations.ToList();
if (enumerable.Count == 0)
{
return Task.FromResult(false);
return false;
}
ValidateMafile(mafile);
SetProxy(mafile);
return SteamMobileConfirmationsApi.SendMultipleConfirmations(Client, enumerable, mafile.SessionData!.SteamId,
var res = await SteamMobileConfirmationsApi.SendMultipleConfirmations(Client, enumerable,
mafile.SessionData!.SteamId,
mafile, confirm);
if (!res && enumerable.Any(c => c.ConfType == ConfirmationType.Trade))
{
Shell.Logger.Warn("Failed to send trade confirmations for {accountName}. Sending ack", mafile.AccountName);
await SteamTradeApi.Acknowledge(Client, mafile.SessionData.SessionId);
await Task.Delay(10);
}
else
{
return res;
}
return await SteamMobileConfirmationsApi.SendMultipleConfirmations(Client, enumerable,
mafile.SessionData!.SteamId,
mafile, confirm);
}
+1
View File
@@ -40,5 +40,6 @@ public static class Shell
private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Logger.Fatal((Exception) e.ExceptionObject);
LogManager.Shutdown();
}
}
+2 -2
View File
@@ -10,7 +10,7 @@
<SatelliteResourceLanguages>en;ru;ua</SatelliteResourceLanguages>
<ApplicationIcon>Theme\lock.ico</ApplicationIcon>
<SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion>
<AssemblyVersion>1.7.0</AssemblyVersion>
<AssemblyVersion>1.7.4</AssemblyVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
@@ -36,7 +36,7 @@
<ItemGroup>
<Resource Include="Theme\Background.png">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Resource>
<Resource Include="Theme\Background_Old.jpg">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
+4 -6
View File
@@ -1,13 +1,11 @@
Есть люди которым нужна функция просмотра и завершения сессий аккаунта. Скорее всего в следующей версии это будет реализовано
• Сейчас, при наличии новой версии, отображается стандартное окно обновлений из библиотеки. Планируется сделать кастомный дизайн, для соответствия общему стилю.
Сейчас, при наличии новой версии, отображается стандартное окно обновлений из библиотеки. Планируется сделать кастомный дизайн, для соответствия общему стилю.
• В приложении реализованы "совмещённые" подтверждения для торговой площадки. Т.е. при наличии более одного предмета, ожидающего подтверждение, можно либо отменить, либо подтвердить все. В планах добавить расширенный функционал, с возможностью точечного управления.
• Добавить кнопку "открыть мафайл" в меню "Файл" по аналогии с открытием папки
• Ускорить появление подсказок в интерфейсе
• Добавить запоминание пароля при привязке мафайла
• Функция переноса гуарда с мобильного устройства на ПК с созданием мафайла
• Добавить полное шифрование мафайлов по аналогии с SDA
• Сделать автоматический билд и загрузку обновления на Github при изменении в мастер ветке
• Антик-окно как в MarketApp, возможность сразу открыть браузер напр. на CefSharp с залогиненым аккаунтом
• Стабильность авто-подтверждений, возможность задать пользователю порог времени когда льются ошибки и только тогда выключать авто-подтверждение
• Безопасное сохранение мафайлов через .tmp / .bak
• Создание механизма накопления ошибок, чтобы исправить Patch Tuesday, условно аккаунт может игнорировать ошибки 1-2 часа (настриавемо)
• Создание механизма накопления ошибок, чтобы исправить Patch Tuesday, условно аккаунт может игнорировать ошибки 1-2 часа (настриавемо)
• Исправить "Перенос гуарда". Иногда не хочет принимать код / подтверждение
@@ -207,4 +207,31 @@
</Button>
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type confirmations:PurchaseConfirmation}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<materialDesign:PackIcon Width="20" Height="20" VerticalAlignment="Center" DockPanel.Dock="Left"
Kind="ShopComplete" Margin="0,0,10,0" />
<TextBlock VerticalAlignment="Center" Grid.Column="1" Text="{Tr MainWindow.ConfirmationTemplates.Purchase}" />
<TextBlock VerticalAlignment="Center" Grid.Column="2" HorizontalAlignment="Right"
Text="{Binding Time, StringFormat=t}" />
<Button Margin="5,0,0,0" VerticalAlignment="Center" Grid.Column="3"
Style="{StaticResource MaterialDesignIconButton}"
Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.(vm:MainVM.ConfirmCommand)}"
CommandParameter="{Binding }">
<materialDesign:PackIcon Kind="Check" />
</Button>
<Button Grid.Column="4" Style="{StaticResource MaterialDesignIconButton}"
Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.(vm:MainVM.CancelCommand)}"
CommandParameter="{Binding }">
<materialDesign:PackIcon Kind="Close" />
</Button>
</Grid>
</DataTemplate>
</ResourceDictionary>
+40 -35
View File
@@ -255,6 +255,11 @@
"en": "Market",
"ru": "Маркет",
"ua": "Маркет"
},
"Purchase": {
"en": "Purchase",
"ru": "Покупка",
"ua": "Покупка"
}
},
"CodeCopied": {
@@ -1098,14 +1103,14 @@
},
"ExceptionHandler": {
"SessionInvalidException": {
"ru": "Сессия истекла. Попробуйте обновить ее через меню или залогиниться заново",
"en": "Session expired. Try to refresh it through menu or login again",
"ua": "Сесія прострочена. Спробуйте оновити її через меню або залогінитися знову"
"ru": "Сессия истекла. Попробуйте обновить ее или залогиниться заново (Аккаунт → войти)",
"en": "Session expired. Try to refresh it or login again (Account → Login)",
"ua": "Сесія прострочена. Спробуйте оновити її через меню або залогінитися знову (Акаунт → Увійти)"
},
"SessionExpiredException": {
"ru": "Сессия полностью истекла. Нужно залогиниться заново",
"en": "Session fully expired. Need to login again",
"ua": "Сесія повніст'ю прострочена'. Потрібно залогінитися знову"
"ru": "Сессия полностью истекла. Нужно залогиниться заново (Аккаунт → Войти)",
"en": "Session fully expired. Need to login again (Account → Login)",
"ua": "Сесія повніст'ю прострочена'. Потрібно залогінитися знову (Акаунт → Увійти)"
},
"TaskCanceledException": {
"ru": "Произошла отмена операции",
@@ -1281,36 +1286,36 @@
"ru": "Ошибка SMS-кода, попробуйте еще раз",
"ua": "Помилка SMS-коду, спробуйте ще раз"
}
}
},
"MAAC": {
"TimerConfirmed": {
"ru": "Авто: подтверждено ",
"en": "Auto: confirmed ",
"ua": "Авто: підтверджено "
},
"TimerNotConfirmed": {
"ru": "Авто: подтверждение не сработало",
"en": "Auto: confirmation was unsuccessful",
"ua": "Авто: підтвердження не спрацювало"
},
"TimerSessionError": {
"ru": "необходимо обновить сессию или перелогиниться",
"en": "need to refresh session or relogin",
"ua": "необхідно оновити сесію або перелогінитися"
},
"TimerPrefix": {
"ru": "Авто ",
"en": "Auto ",
"ua": "Авто "
},
"TimerPreventedOverlap": {
"ru":
"Авто: таймер подтверждений пытался начать новый цикл, когда предыдущий еще не завершился. Советуем увеличить задержку",
"en":
"Auto: confirmation timer tried to start new cycle when previous one was not finished yet. We recommend to increase delay",
"ua":
"Авто: таймер підтверджень намагався запустити новий цикл, коли попередній ще не закінчився. Рекомендуємо збільшити затримку"
"MAAC": {
"TimerConfirmed": {
"ru": "Авто: подтверждено ",
"en": "Auto: confirmed ",
"ua": "Авто: підтверджено "
},
"TimerNotConfirmed": {
"ru": "Авто: подтверждение не сработало",
"en": "Auto: confirmation was unsuccessful",
"ua": "Авто: підтвердження не спрацювало"
},
"TimerSessionError": {
"ru": "необходимо обновить сессию или перелогиниться",
"en": "need to refresh session or relogin",
"ua": "необхідно оновити сесію або перелогінитися"
},
"TimerPrefix": {
"ru": "Авто ",
"en": "Auto ",
"ua": "Авто "
},
"TimerPreventedOverlap": {
"ru":
"Авто: таймер подтверждений пытался начать новый цикл, когда предыдущий еще не завершился. Советуем увеличить задержку",
"en":
"Auto: confirmation timer tried to start new cycle when previous one was not finished yet. We recommend to increase delay",
"ua":
"Авто: таймер підтверджень намагався запустити новий цикл, коли попередній ще не закінчився. Рекомендуємо збільшити затримку"
}
}
},
"CantAlignTimeError": {
@@ -72,8 +72,8 @@ public static class SteamMobileConfirmationsApi
var op = confirm ? "allow" : "cancel";
var query = GetConfirmationKvp(steamId, data.DeviceId, data.IdentitySecret, op).ToList();
query.Insert(0, new KeyValuePair<string, string>("op", op));
foreach (var confirmation in confirmations)
var list = confirmations.ToList();
foreach (var confirmation in list)
{
query.Add(new KeyValuePair<string, string>("cid[]", confirmation.Id.ToString()));
query.Add(new KeyValuePair<string, string>("ck[]", confirmation.Nonce.ToString()));
@@ -0,0 +1,27 @@
using SteamLib.Core;
namespace SteamLib.Api.Trade;
public static class SteamTradeApi
{
public static async Task<bool> Acknowledge(HttpClient client, string sessionId,
CancellationToken cancellationToken = default)
{
var data = new Dictionary<string, string>
{
{"sessionid", sessionId},
{"message", "1"}
};
var req = new HttpRequestMessage(HttpMethod.Post, Routes.ACKNOWLEDGE);
req.Content = new FormUrlEncodedContent(data);
var resp = await client.SendAsync(req, cancellationToken);
var cont = await resp.EnsureSuccessStatusCode().Content.ReadAsStringAsync(cancellationToken);
return cont == "[]";
//{"success":false} - unauthenticated
}
public static class Routes
{
public const string ACKNOWLEDGE = SteamConstants.STEAM_COMMUNITY + "//trade/new/acknowledge"; //Not a typo
}
}
@@ -2,7 +2,7 @@
public class AccountRecoveryConfirmation : Confirmation
{
public AccountRecoveryConfirmation(long id, ulong nonce, long creator, string typeName) : base(id, nonce, 6,
public AccountRecoveryConfirmation(long id, ulong nonce, ulong creator, string typeName) : base(id, nonce, 6,
creator, ConfirmationType.AccountRecovery, typeName)
{
}
@@ -12,7 +12,7 @@ public class Confirmation
/// <summary>
/// Represents either the Trade Offer ID or market transaction ID that caused this confirmation to be created.
/// </summary>
public long CreatorId { get; }
public ulong CreatorId { get; }
public string TypeName { get; init; }
public string HeadLine { get; init; } = string.Empty;
@@ -31,7 +31,7 @@ public class Confirmation
/// </summary>
public int IntType;
public Confirmation(long id, ulong nonce, int intType, long creatorId, ConfirmationType confType, string typeName)
public Confirmation(long id, ulong nonce, int intType, ulong creatorId, ConfirmationType confType, string typeName)
{
Id = id;
Nonce = nonce;
@@ -6,7 +6,7 @@ public class MarketConfirmation : Confirmation
public string ItemName { get; init; } = string.Empty;
public string PriceString { get; init; } = string.Empty;
public MarketConfirmation(long id, ulong key, long creator, string typeName) : base(id, key, 3, creator,
public MarketConfirmation(long id, ulong key, ulong creator, string typeName) : base(id, key, 3, creator,
ConfirmationType.MarketSellTransaction, typeName)
{
}
@@ -0,0 +1,9 @@
namespace SteamLib.SteamMobile.Confirmations;
public class PurchaseConfirmation : Confirmation
{
public PurchaseConfirmation(long id, ulong nonce, ulong creatorId, string typeName) : base(id, nonce, 12, creatorId,
ConfirmationType.Purchase, typeName)
{
}
}
@@ -2,7 +2,7 @@
public class RegisterApiKeyConfirmation : Confirmation
{
public RegisterApiKeyConfirmation(long id, ulong nonce, long creatorId, string typeName) : base(id, nonce, 8,
public RegisterApiKeyConfirmation(long id, ulong nonce, ulong creatorId, string typeName) : base(id, nonce, 8,
creatorId, ConfirmationType.RegisterApiKey, typeName)
{
}
@@ -7,9 +7,9 @@ public class TradeConfirmation : Confirmation
public bool IsReceiveNothing { get; set; }
public override TradeConfirmationDetails? Details { get; }
public long TradeId => CreatorId;
public ulong TradeId => CreatorId;
public TradeConfirmation(long id, ulong nonce, long creator, string typeName) : base(id, nonce, 1, creator,
public TradeConfirmation(long id, ulong nonce, ulong creator, string typeName) : base(id, nonce, 1, creator,
ConfirmationType.Trade, typeName)
{
}
@@ -6,5 +6,6 @@ public enum ConfirmationType
Trade = 2,
MarketSellTransaction = 3,
AccountRecovery = 6,
RegisterApiKey = 9
RegisterApiKey = 9,
Purchase = 12
}
+1
View File
@@ -33,6 +33,7 @@ public static class ClientBuilder
{
container.SetSteamMobileCookiesWithMobileToken(sessionData);
}
//Nebula tweak:
handler.CookieContainer.InjectWebTradeEligibilityCookie();
ConfigureCommon(handler, client);
@@ -23,7 +23,7 @@ public class ConfirmationJson
[JsonProperty("type")] public ConfirmationType Type { get; set; }
[JsonProperty("type_name")] public string TypeName { get; set; } = string.Empty;
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("creator_id")] public long CreatorId { get; set; }
[JsonProperty("creator_id")] public ulong CreatorId { get; set; }
[JsonProperty("nonce")] public ulong Nonce { get; set; }
[JsonProperty("creation_time")] public UnixTimeStamp CreationTime { get; set; }
[JsonProperty("cancel")] public string Cancel { get; set; } = string.Empty;
@@ -77,6 +77,7 @@ public static class MobileConfirmationScrapper
ConfirmationType.AccountRecovery => GetAccountRecoveryConfirmation(json),
ConfirmationType.MarketSellTransaction => GetMarketConfirmation(json),
ConfirmationType.RegisterApiKey => GetRegisterApiKeyConfirmation(json),
ConfirmationType.Purchase => GetPurchaseConfirmation(json),
_ => new Confirmation(json.Id, json.Nonce, (int) json.Type, json.CreatorId, json.Type, json.TypeName)
{
Time = json.CreationTime.ToLocalDateTime()
@@ -166,4 +167,13 @@ public static class MobileConfirmationScrapper
PriceString = string.Empty //TODO:
};
}
private static PurchaseConfirmation GetPurchaseConfirmation(ConfirmationJson confirmation)
{
return new PurchaseConfirmation(confirmation.Id, confirmation.Nonce,
confirmation.CreatorId, confirmation.TypeName)
{
Time = confirmation.CreationTime.ToLocalDateTime()
};
}
}