From e6e82e19bd0ef7526e48ff1ac72bca6baddcaaa1 Mon Sep 17 00:00:00 2001 From: Archi Date: Sat, 14 Jan 2023 15:08:28 +0100 Subject: [PATCH] Cut excessive data from announcement Now that we don't need to transmit whole inventory to the backend anymore, we can cut it to matchable types only --- .../Backend.cs | 4 +- .../Data/AnnouncementRequest.cs | 16 +------- .../RemoteCommunication.cs | 41 +++++++++++++++---- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/Backend.cs b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/Backend.cs index 0588f5ad0..6437224ef 100644 --- a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/Backend.cs +++ b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/Backend.cs @@ -4,7 +4,7 @@ // / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | | // /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_| // | -// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki +// Copyright 2015-2023 Łukasz "JustArchi" Domeradzki // Contact: JustArchi@JustArchi.net // | // Licensed under the Apache License, Version 2.0 (the "License"); @@ -37,7 +37,7 @@ using ArchiSteamFarm.Web.Responses; namespace ArchiSteamFarm.OfficialPlugins.ItemsMatcher; internal static class Backend { - internal static async Task AnnounceForListing(Bot bot, WebBrowser webBrowser, IReadOnlyList inventory, IReadOnlyCollection acceptedMatchableTypes, string tradeToken, string? nickname = null, string? avatarHash = null) { + internal static async Task AnnounceForListing(Bot bot, WebBrowser webBrowser, IReadOnlyCollection inventory, IReadOnlyCollection acceptedMatchableTypes, string tradeToken, string? nickname = null, string? avatarHash = null) { ArgumentNullException.ThrowIfNull(bot); ArgumentNullException.ThrowIfNull(webBrowser); diff --git a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/Data/AnnouncementRequest.cs b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/Data/AnnouncementRequest.cs index bc089d719..b9440b730 100644 --- a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/Data/AnnouncementRequest.cs +++ b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/Data/AnnouncementRequest.cs @@ -58,7 +58,7 @@ internal sealed class AnnouncementRequest { [JsonProperty(Required = Required.Always)] private readonly string TradeToken; - internal AnnouncementRequest(Guid guid, ulong steamID, string tradeToken, IReadOnlyList inventory, IReadOnlyCollection matchableTypes, bool matchEverything, byte maxTradeHoldDuration, string? nickname = null, string? avatarHash = null) { + internal AnnouncementRequest(Guid guid, ulong steamID, string tradeToken, IReadOnlyCollection inventory, IReadOnlyCollection matchableTypes, bool matchEverything, byte maxTradeHoldDuration, string? nickname = null, string? avatarHash = null) { if (guid == Guid.Empty) { throw new ArgumentOutOfRangeException(nameof(guid)); } @@ -83,22 +83,10 @@ internal sealed class AnnouncementRequest { throw new ArgumentNullException(nameof(matchableTypes)); } - uint index = 0; - ulong previousAssetID = 0; - Guid = guid; SteamID = steamID; TradeToken = tradeToken; - - HashSet assetsForListing = new(inventory.Count); - - foreach (Asset asset in inventory) { - assetsForListing.Add(new AssetForListing(asset, index++, previousAssetID)); - - previousAssetID = asset.AssetID; - } - - Inventory = assetsForListing.ToImmutableHashSet(); + Inventory = inventory.ToImmutableHashSet(); MatchableTypes = matchableTypes.ToImmutableHashSet(); MatchEverything = matchEverything; MaxTradeHoldDuration = maxTradeHoldDuration; diff --git a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs index d3f112b9c..a6a93229d 100644 --- a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs +++ b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs @@ -4,7 +4,7 @@ // / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | | // /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_| // | -// Copyright 2015-2022 Łukasz "JustArchi" Domeradzki +// Copyright 2015-2023 Łukasz "JustArchi" Domeradzki // Contact: JustArchi@JustArchi.net // | // Licensed under the Apache License, Version 2.0 (the "License"); @@ -208,6 +208,7 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable { return; } + // We require to fetch whole inventory as a list here, as we need to know the order for calculating index and previousAssetID List inventory; try { @@ -228,8 +229,7 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable { return; } - // This is actual inventory - if (inventory.Count(item => item.Tradable && acceptedMatchableTypes.Contains(item.Type)) < MinItemsCount) { + if (inventory.Count < MinItemsCount) { // We're not eligible, record this as a valid check LastAnnouncement = DateTime.UtcNow; ShouldSendAnnouncementEarlier = ShouldSendHeartBeats = false; @@ -237,7 +237,34 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable { return; } - if ((inventory.Count == AnnouncedItems.Count) && inventory.All(item => AnnouncedItems.TryGetValue(item.AssetID, out uint amount) && (item.Amount == amount))) { + uint index = 0; + ulong previousAssetID = 0; + + HashSet assetsForListing = new(); + + uint tradableCount = 0; + + foreach (Asset asset in inventory) { + if (acceptedMatchableTypes.Contains(asset.Type)) { + if (asset.Tradable) { + tradableCount++; + } + + assetsForListing.Add(new AssetForListing(asset, index++, previousAssetID)); + } + + previousAssetID = asset.AssetID; + } + + if (tradableCount < MinItemsCount) { + // We're not eligible, record this as a valid check + LastAnnouncement = DateTime.UtcNow; + ShouldSendAnnouncementEarlier = ShouldSendHeartBeats = false; + + return; + } + + if (ShouldSendHeartBeats && (assetsForListing.Count == AnnouncedItems.Count) && assetsForListing.All(item => AnnouncedItems.TryGetValue(item.AssetID, out uint amount) && (item.Amount == amount))) { // There is nothing new to announce, this is fine, skip the request LastAnnouncement = DateTime.UtcNow; ShouldSendAnnouncementEarlier = false; @@ -266,10 +293,10 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable { SignedInWithSteam = true; } - Bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Localization.Strings.ListingAnnouncing, Bot.SteamID, nickname, inventory.Count)); + Bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Localization.Strings.ListingAnnouncing, Bot.SteamID, nickname, assetsForListing.Count)); // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - BasicResponse? response = await Backend.AnnounceForListing(Bot, WebBrowser, inventory, acceptedMatchableTypes, tradeToken!, nickname, avatarHash).ConfigureAwait(false); + BasicResponse? response = await Backend.AnnounceForListing(Bot, WebBrowser, assetsForListing, acceptedMatchableTypes, tradeToken!, nickname, avatarHash).ConfigureAwait(false); if (response == null) { // This is actually a network failure, so we'll stop sending heartbeats but not record it as valid check @@ -333,7 +360,7 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable { AnnouncedItems.Clear(); - foreach (Asset item in inventory) { + foreach (AssetForListing item in assetsForListing) { AnnouncedItems[item.AssetID] = item.Amount; }