Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closes #2840 #2843

Merged
merged 15 commits into from
Mar 17, 2023
6 changes: 6 additions & 0 deletions .github/renovate.json5
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
"allowedVersions": "<= 3.1",
"matchManagers": [ "nuget" ],
"matchPackageNames": [ "Microsoft.Extensions.Configuration.Json", "Microsoft.Extensions.Logging.Configuration" ]
},
{
// TODO: Stick with SK2 version until we can remove the submodule
"enabled": false,
"matchManagers": [ "nuget" ],
"matchPackageNames": [ "Microsoft.Win32.Registry", "protobuf-net" ]
}
]
}
7 changes: 6 additions & 1 deletion ArchiSteamFarm/ArchiSteamFarm.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,21 @@
<PackageReference Include="Humanizer" />
<PackageReference Include="JetBrains.Annotations" PrivateAssets="all" />
<PackageReference Include="Markdig.Signed" />
<PackageReference Include="Microsoft.Win32.Registry" />
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="Nito.AsyncEx.Coordination" />
<PackageReference Include="NLog.Web.AspNetCore" />
<PackageReference Include="SteamKit2" />
<PackageReference Include="protobuf-net" />
<PackageReference Include="Swashbuckle.AspNetCore" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" />
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" />
<PackageReference Include="System.Composition" />
<PackageReference Include="System.Linq.Async" />
<PackageReference Include="zxcvbn-core" />

<Reference Include="SteamKit2">
<HintPath>Temp\SteamKit2.dll</HintPath>
</Reference>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' != 'net481'">
Expand Down
2 changes: 1 addition & 1 deletion ArchiSteamFarm/Core/Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public static async void InBackground(Action action, bool longRunning = false) {
public static void InBackground<T>(Func<T> function, bool longRunning = false) {
ArgumentNullException.ThrowIfNull(function);

InBackground(void () => function(), longRunning);
InBackground(void() => function(), longRunning);
}

[PublicAPI]
Expand Down
509 changes: 293 additions & 216 deletions ArchiSteamFarm/Steam/Bot.cs

Large diffs are not rendered by default.

80 changes: 80 additions & 0 deletions ArchiSteamFarm/Steam/Integration/BotCredentialsProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// _ _ _ ____ _ _____
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
// |
// Copyright 2015-2023 Łukasz "JustArchi" Domeradzki
// Contact: [email protected]
// |
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// |
// http://www.apache.org/licenses/LICENSE-2.0
// |
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.ComponentModel;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using ArchiSteamFarm.Core;
using ArchiSteamFarm.Localization;
using SteamKit2;

namespace ArchiSteamFarm.Steam.Integration;

internal sealed class BotCredentialsProvider : IAuthenticator {
JustArchi marked this conversation as resolved.
Show resolved Hide resolved
private const byte MaxLoginFailures = 5;

private readonly Bot Bot;
private readonly CancellationTokenSource CancellationTokenSource;

private byte LoginFailures;

internal BotCredentialsProvider(Bot bot, CancellationTokenSource cancellationTokenSource) {
ArgumentNullException.ThrowIfNull(bot);
ArgumentNullException.ThrowIfNull(cancellationTokenSource);

Bot = bot;
CancellationTokenSource = cancellationTokenSource;
}

public Task<bool> AcceptDeviceConfirmation() => Task.FromResult(false);

public async Task<string> ProvideDeviceCode(bool previousCodeWasIncorrect) => await ProvideInput(ASF.EUserInputType.TwoFactorAuthentication, previousCodeWasIncorrect).ConfigureAwait(false);

public async Task<string> ProvideEmailCode(string email, bool previousCodeWasIncorrect) => await ProvideInput(ASF.EUserInputType.SteamGuard, previousCodeWasIncorrect).ConfigureAwait(false);

private async Task<string> ProvideInput(ASF.EUserInputType inputType, bool previousCodeWasIncorrect) {
if (!Enum.IsDefined(inputType)) {
throw new InvalidEnumArgumentException(nameof(inputType), (int) inputType, typeof(ASF.EUserInputType));
}

if (previousCodeWasIncorrect && (++LoginFailures >= MaxLoginFailures)) {
EResult reason = inputType == ASF.EUserInputType.TwoFactorAuthentication ? EResult.TwoFactorCodeMismatch : EResult.InvalidLoginAuthCode;

Bot.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.BotUnableToLogin, reason, reason));

if (++LoginFailures >= MaxLoginFailures) {
CancellationTokenSource.Cancel();

return "";
}
}

string? result = await Bot.RequestInput(inputType, previousCodeWasIncorrect).ConfigureAwait(false);

if (string.IsNullOrEmpty(result)) {
CancellationTokenSource.Cancel();
}

return result ?? "";
}
}
43 changes: 31 additions & 12 deletions ArchiSteamFarm/Steam/Storage/BotDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,38 +62,54 @@ internal uint GamesToRedeemInBackgroundCount {
[JsonProperty(Required = Required.DisallowNull)]
private readonly OrderedDictionary GamesToRedeemInBackground = new();

internal string? LoginKey {
get => BackingLoginKey;
internal MobileAuthenticator? MobileAuthenticator {
get => BackingMobileAuthenticator;

set {
if (BackingLoginKey == value) {
if (BackingMobileAuthenticator == value) {
return;
}

BackingLoginKey = value;
BackingMobileAuthenticator = value;
Utilities.InBackground(Save);
}
}

internal MobileAuthenticator? MobileAuthenticator {
get => BackingMobileAuthenticator;
internal string? RefreshToken {
get => BackingRefreshToken;

set {
if (BackingMobileAuthenticator == value) {
if (BackingRefreshToken == value) {
return;
}

BackingMobileAuthenticator = value;
BackingRefreshToken = value;
Utilities.InBackground(Save);
}
}

[JsonProperty($"_{nameof(LoginKey)}")]
private string? BackingLoginKey;
internal string? SteamGuardData {
get => BackingSteamGuardData;

set {
if (BackingSteamGuardData == value) {
return;
}

BackingSteamGuardData = value;
Utilities.InBackground(Save);
}
}

[JsonProperty($"_{nameof(MobileAuthenticator)}")]
private MobileAuthenticator? BackingMobileAuthenticator;

[JsonProperty]
private string? BackingRefreshToken;

[JsonProperty]
private string? BackingSteamGuardData;

private BotDatabase(string filePath) : this() {
if (string.IsNullOrEmpty(filePath)) {
throw new ArgumentNullException(nameof(filePath));
Expand All @@ -111,10 +127,13 @@ private BotDatabase() {
}

[UsedImplicitly]
public bool ShouldSerializeBackingLoginKey() => !string.IsNullOrEmpty(BackingLoginKey);
public bool ShouldSerializeBackingMobileAuthenticator() => BackingMobileAuthenticator != null;

[UsedImplicitly]
public bool ShouldSerializeBackingMobileAuthenticator() => BackingMobileAuthenticator != null;
public bool ShouldSerializeBackingRefreshToken() => !string.IsNullOrEmpty(BackingRefreshToken);

[UsedImplicitly]
public bool ShouldSerializeBackingSteamGuardData() => !string.IsNullOrEmpty(BackingSteamGuardData);

[UsedImplicitly]
public bool ShouldSerializeFarmingBlacklistAppIDs() => FarmingBlacklistAppIDs.Count > 0;
Expand Down
Binary file added ArchiSteamFarm/Temp/SteamKit2.dll
Binary file not shown.
2 changes: 2 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
<PackageVersion Include="JetBrains.Annotations" Version="2022.3.1" />
<PackageVersion Include="Markdig.Signed" Version="0.31.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageVersion Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageVersion Include="MSTest.TestAdapter" Version="3.0.2" />
<PackageVersion Include="MSTest.TestFramework" Version="3.0.2" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="Nito.AsyncEx.Coordination" Version="5.1.2" />
<PackageVersion Include="NLog.Web.AspNetCore" Version="5.2.2" />
<PackageVersion Include="protobuf-net" Version="3.1.17" />
<PackageVersion Include="SteamKit2" Version="2.4.1" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageVersion Include="Swashbuckle.AspNetCore.Annotations" Version="6.5.0" />
Expand Down