Add support for automatically rejecting trade offers from bad bots

With special dedication to the guy who attempted to DDoS ASF STM listing today, hope your business will truly expand from now on! <3
This commit is contained in:
Archi
2022-12-17 02:39:37 +01:00
parent e6ac3f7daf
commit e3545660dc
3 changed files with 47 additions and 0 deletions

View File

@@ -20,15 +20,20 @@
// limitations under the License.
using System;
using System.Collections.Immutable;
using System.Threading.Tasks;
using ArchiSteamFarm.Helpers;
using ArchiSteamFarm.IPC.Responses;
using ArchiSteamFarm.Web.Responses;
using SteamKit2;
namespace ArchiSteamFarm.Core;
internal static class ArchiNet {
internal static Uri URL => new("https://asf.JustArchi.net");
private static readonly ArchiCacheable<ImmutableHashSet<ulong>> CachedBadBots = new(ResolveCachedBadBots, TimeSpan.FromDays(1));
internal static async Task<string?> FetchBuildChecksum(Version version, string variant) {
ArgumentNullException.ThrowIfNull(version);
@@ -50,4 +55,26 @@ internal static class ArchiNet {
return response.Content.Result ?? "";
}
internal static async Task<bool?> IsBadBot(ulong steamID) {
if ((steamID == 0) || !new SteamID(steamID).IsIndividualAccount) {
throw new ArgumentOutOfRangeException(nameof(steamID));
}
(_, ImmutableHashSet<ulong>? badBots) = await CachedBadBots.GetValue(ArchiCacheable<ImmutableHashSet<ulong>>.EFallback.SuccessPreviously).ConfigureAwait(false);
return badBots?.Contains(steamID);
}
private static async Task<(bool Success, ImmutableHashSet<ulong>? Result)> ResolveCachedBadBots() {
if (ASF.WebBrowser == null) {
throw new InvalidOperationException(nameof(ASF.WebBrowser));
}
Uri request = new(URL, "/Api/BadBots");
ObjectResponse<GenericResponse<ImmutableHashSet<ulong>>>? response = await ASF.WebBrowser.UrlGetToJsonObject<GenericResponse<ImmutableHashSet<ulong>>>(request).ConfigureAwait(false);
return response?.Content != null ? (true, response.Content.Result) : (false, null);
}
}

View File

@@ -547,6 +547,17 @@ public sealed class Trading : IDisposable {
return ParseTradeResult.EResult.Blacklisted;
}
// Deny trades from bad steamIDs if user wishes to do so
if (ASF.GlobalConfig?.FilterBadBots ?? GlobalConfig.DefaultFilterBadBots) {
bool? isBadBot = await ArchiNet.IsBadBot(tradeOffer.OtherSteamID64).ConfigureAwait(false);
if (isBadBot == true) {
Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Blacklisted, $"{nameof(tradeOffer.OtherSteamID64)} {tradeOffer.OtherSteamID64}"));
return ParseTradeResult.EResult.Blacklisted;
}
}
}
// Check if it's donation trade

View File

@@ -63,6 +63,9 @@ public sealed class GlobalConfig {
[PublicAPI]
public const byte DefaultFarmingDelay = 15;
[PublicAPI]
public const bool DefaultFilterBadBots = true;
[PublicAPI]
public const byte DefaultGiftsLimiterDelay = 1;
@@ -209,6 +212,9 @@ public sealed class GlobalConfig {
[Range(1, byte.MaxValue)]
public byte FarmingDelay { get; private set; } = DefaultFarmingDelay;
[JsonProperty(Required = Required.DisallowNull)]
public bool FilterBadBots { get; private set; } = DefaultFilterBadBots;
[JsonProperty(Required = Required.DisallowNull)]
[Range(byte.MinValue, byte.MaxValue)]
public byte GiftsLimiterDelay { get; private set; } = DefaultGiftsLimiterDelay;
@@ -360,6 +366,9 @@ public sealed class GlobalConfig {
[UsedImplicitly]
public bool ShouldSerializeFarmingDelay() => !Saving || (FarmingDelay != DefaultFarmingDelay);
[UsedImplicitly]
public bool ShouldSerializeFilterBadBots() => !Saving || (FilterBadBots != DefaultFilterBadBots);
[UsedImplicitly]
public bool ShouldSerializeGiftsLimiterDelay() => !Saving || (GiftsLimiterDelay != DefaultGiftsLimiterDelay);