From a0401a3962933664aa4b191187a92c122b96de88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Domeradzki?= Date: Thu, 17 Jul 2025 13:40:35 +0200 Subject: [PATCH] Improve efficiency of MatchActively Trade hold duration check made sense, but back when we were fetching inventories ourselves. Now, it's much better to find match first, as we have the full data loaded, and only if match is found, check user next. --- .../RemoteCommunication.cs | 44 +++++++++++++------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs index 890225dc7..91840048d 100644 --- a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs +++ b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs @@ -1276,20 +1276,7 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable { Bot.ArchiLogger.LogGenericTrace($"{listedUser.SteamID}..."); - byte? tradeHoldDuration = await Bot.ArchiWebHandler.GetCombinedTradeHoldDurationAgainstUser(listedUser.SteamID, listedUser.TradeToken).ConfigureAwait(false); - - switch (tradeHoldDuration) { - case null: - Bot.ArchiLogger.LogGenericTrace(Strings.FormatErrorIsEmpty(nameof(tradeHoldDuration))); - - continue; - case > 0 when (tradeHoldDuration.Value > maxTradeHoldDuration) || (tradeHoldDuration.Value > listedUser.MaxTradeHoldDuration): - Bot.ArchiLogger.LogGenericTrace($"{tradeHoldDuration.Value} > {maxTradeHoldDuration} || {listedUser.MaxTradeHoldDuration}"); - - continue; - } - - HashSet theirInventory = listedUser.Assets.Where(item => (!listedUser.MatchEverything || item.Tradable) && wantedSets.Contains((item.RealAppID, item.Type, item.Rarity)) && ((tradeHoldDuration.Value == 0) || !(item.Type is EAssetType.FoilTradingCard or EAssetType.TradingCard && CardsFarmer.SalesBlacklist.Contains(item.RealAppID)))).Select(static asset => asset.ToAsset()).ToHashSet(); + HashSet theirInventory = listedUser.Assets.Where(item => (!listedUser.MatchEverything || item.Tradable) && wantedSets.Contains((item.RealAppID, item.Type, item.Rarity))).Select(static asset => asset.ToAsset()).ToHashSet(); if (theirInventory.Count == 0) { continue; @@ -1297,6 +1284,8 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable { skippedSetsThisUser.Clear(); + byte? tradeHoldDuration = null; + Dictionary<(uint RealAppID, EAssetType Type, EAssetRarity Rarity), Dictionary> theirTradableState = MatchingUtilities.GetTradableInventoryState(theirInventory); for (byte i = 0; i < Trading.MaxTradesPerAccount; i++) { @@ -1335,6 +1324,10 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable { match = false; foreach ((ulong ourItem, uint ourFullAmount) in ourFullSet.Where(static item => item.Value > 1).OrderByDescending(static item => item.Value)) { + if ((tradeHoldDuration > maxTradeHoldDuration) || (tradeHoldDuration > listedUser.MaxTradeHoldDuration)) { + break; + } + if (!ourTradableSet.TryGetValue(ourItem, out uint ourTradableAmount) || (ourTradableAmount == 0)) { continue; } @@ -1378,6 +1371,29 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable { } } + // Now that we have a match, check trade hold to ensure user is valid to match against + // Since it involves remote call, we didn't do it previously, to skip checking against users with no matches for us + if (tradeHoldDuration == null) { + tradeHoldDuration = await Bot.ArchiWebHandler.GetCombinedTradeHoldDurationAgainstUser(listedUser.SteamID, listedUser.TradeToken).ConfigureAwait(false); + + if (tradeHoldDuration == null) { + Bot.ArchiLogger.LogGenericTrace(Strings.FormatErrorIsEmpty(nameof(tradeHoldDuration))); + + break; + } + + if ((tradeHoldDuration.Value > maxTradeHoldDuration) || (tradeHoldDuration.Value > listedUser.MaxTradeHoldDuration)) { + Bot.ArchiLogger.LogGenericTrace($"{tradeHoldDuration.Value} > {maxTradeHoldDuration} || {listedUser.MaxTradeHoldDuration}"); + + break; + } + } + + if ((tradeHoldDuration.Value > 0) && set.Type is EAssetType.FoilTradingCard or EAssetType.TradingCard && CardsFarmer.SalesBlacklist.Contains(set.RealAppID)) { + // We're not considering this set for matching due to trade hold + continue; + } + // Skip this set from the remaining of this round skippedSetsThisTrade.Add(set);