diff --git a/ArchiSteamFarm.Tests/Trading.cs b/ArchiSteamFarm.Tests/Trading.cs index 0d7908143..094f1ab41 100644 --- a/ArchiSteamFarm.Tests/Trading.cs +++ b/ArchiSteamFarm.Tests/Trading.cs @@ -303,6 +303,23 @@ namespace ArchiSteamFarm.Tests { Assert.IsFalse(AcceptsTrade(inventory, itemsToGive, itemsToReceive)); } + [TestMethod] + public void SingleGameSingleTypeBigDifferenceAccept() { + Steam.Asset item2X1 = GenerateSteamCommunityItem(2, 1, 570, Steam.Asset.EType.TradingCard); + Steam.Asset item2X5 = GenerateSteamCommunityItem(2, 5, 570, Steam.Asset.EType.TradingCard); + Steam.Asset item3X1 = GenerateSteamCommunityItem(3, 1, 570, Steam.Asset.EType.TradingCard); + + HashSet inventory = new HashSet { + item2X5, + item3X1 + }; + + HashSet itemsToGive = new HashSet { item2X1 }; + HashSet itemsToReceive = new HashSet { item3X1 }; + + Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive)); + } + [TestMethod] public void SingleGameSingleTypeGoodAccept() { Steam.Asset item1 = GenerateSteamCommunityItem(1, 1, 570, Steam.Asset.EType.TradingCard); diff --git a/ArchiSteamFarm/Trading.cs b/ArchiSteamFarm/Trading.cs index 0ec287c5c..7bc2fedd9 100644 --- a/ArchiSteamFarm/Trading.cs +++ b/ArchiSteamFarm/Trading.cs @@ -89,7 +89,7 @@ namespace ArchiSteamFarm { } } - return sets.ToDictionary(set => set.Key, set => set.Value.Values.OrderByDescending(amount => amount).ToList()); + return sets.ToDictionary(set => set.Key, set => set.Value.Values.OrderBy(amount => amount).ToList()); } private static bool IsTradeNeutralOrBetter(HashSet inventory, IReadOnlyCollection itemsToGive, IReadOnlyCollection itemsToReceive) { @@ -161,9 +161,9 @@ namespace ArchiSteamFarm { } // At this point we're sure that amount of unique items stays the same, so we can evaluate actual sets - // We make use of the fact that our amounts are already sorted in descending order, so we can just take the last value instead of calculating ourselves - uint beforeSets = beforeAmounts[beforeAmounts.Count - 1]; - uint afterSets = afterAmounts[afterAmounts.Count - 1]; + // We make use of the fact that our amounts are already sorted in ascending order, so we can just take the first value instead of calculating ourselves + uint beforeSets = beforeAmounts[0]; + uint afterSets = afterAmounts[0]; // If amount of our sets for this game decreases, this is always a bad trade (e.g. 2 2 2 -> 3 2 1) if (afterSets < beforeSets) { @@ -176,12 +176,10 @@ namespace ArchiSteamFarm { } // At this point we're sure that both number of unique items in the set stays the same, as well as number of our actual sets - // We need to ensure set progress here, so we'll check if no final amount of a single item is lower than initial one - // We also need to remember about overpaying, so we'll compare only appropriate indexes from a list (that is already sorted in descending order) - for (byte i = 0; i < afterAmounts.Count; i++) { - if (afterAmounts[i] < beforeAmounts[i]) { - return false; - } + // We need to ensure set progress here and keep in mind overpaying, so we'll calculate neutrality as a difference in amounts on appropriate indexes + // The higher the neutrality the better the trade, with 0 being the absolute minimum we're willing to accept + if (afterAmounts.Select((t, i) => (int) (t - beforeAmounts[i])).Sum() < 0) { + return false; } }