diff --git a/ArchiSteamFarm.Tests/ArchiSteamFarm.Tests.csproj b/ArchiSteamFarm.Tests/ArchiSteamFarm.Tests.csproj
new file mode 100644
index 000000000..201aa7a0b
--- /dev/null
+++ b/ArchiSteamFarm.Tests/ArchiSteamFarm.Tests.csproj
@@ -0,0 +1,29 @@
+
+
+
+ Exe
+ netcoreapp2.0
+ latest
+ none
+
+
+
+ none
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ArchiSteamFarm.Tests/Trading.cs b/ArchiSteamFarm.Tests/Trading.cs
new file mode 100644
index 000000000..220854d92
--- /dev/null
+++ b/ArchiSteamFarm.Tests/Trading.cs
@@ -0,0 +1,151 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using ArchiSteamFarm.JSON;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace ArchiSteamFarm.Tests {
+ [TestClass]
+ public sealed class Trading {
+ [TestMethod]
+ public void TradingMultiGameBadReject() {
+ Steam.Item item1Game1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
+ Steam.Item item1Game1X9 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 9, 570, Steam.Item.EType.TradingCard);
+ Steam.Item item2Game1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
+
+ Steam.Item item1Game2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 3, 1, 730, Steam.Item.EType.TradingCard);
+ Steam.Item item2Game2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 4, 1, 730, Steam.Item.EType.TradingCard);
+
+ HashSet inventory = new HashSet { item1Game1X9, item1Game2, item2Game2 };
+ HashSet itemsToGive = new HashSet { item1Game1, item1Game2 };
+ HashSet itemsToReceive = new HashSet { item2Game1, item2Game2 };
+
+ Assert.IsFalse(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
+ }
+
+ [TestMethod]
+ public void TradingMultiGameMultiTypeBadReject() {
+ Steam.Item item1Type1Game1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
+ Steam.Item item1Type1Game1X9 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 9, 570, Steam.Item.EType.TradingCard);
+ Steam.Item item2Type1Game1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
+
+ Steam.Item item3Type2Game2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 3, 1, 730, Steam.Item.EType.Emoticon);
+ Steam.Item item3Type2Game2X9 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 3, 9, 730, Steam.Item.EType.Emoticon);
+ Steam.Item item4Type2Game2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 4, 1, 730, Steam.Item.EType.Emoticon);
+
+ HashSet inventory = new HashSet { item1Type1Game1X9, item3Type2Game2X9, item4Type2Game2 };
+ HashSet itemsToGive = new HashSet { item1Type1Game1, item4Type2Game2 };
+ HashSet itemsToReceive = new HashSet { item2Type1Game1, item3Type2Game2 };
+
+ Assert.IsFalse(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
+ }
+
+ [TestMethod]
+ public void TradingMultiGameMultiTypeNeutralAccept() {
+ Steam.Item item1Type1Game1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
+ Steam.Item item1Type1Game1X9 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 9, 570, Steam.Item.EType.TradingCard);
+ Steam.Item item2Type1Game1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
+
+ Steam.Item item3Type2Game2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 3, 1, 730, Steam.Item.EType.Emoticon);
+ Steam.Item item4Type2Game2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 4, 1, 730, Steam.Item.EType.Emoticon);
+
+ HashSet inventory = new HashSet { item1Type1Game1X9, item3Type2Game2 };
+ HashSet itemsToGive = new HashSet { item1Type1Game1, item3Type2Game2 };
+ HashSet itemsToReceive = new HashSet { item2Type1Game1, item4Type2Game2 };
+
+ Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
+ }
+
+ [TestMethod]
+ public void TradingMultiGameNeutralAccept() {
+ Steam.Item item1Game1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
+ Steam.Item item1Game1X2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 2, 570, Steam.Item.EType.TradingCard);
+ Steam.Item item2Game1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
+
+ Steam.Item item1Game2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 730, Steam.Item.EType.TradingCard);
+ Steam.Item item2Game2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 730, Steam.Item.EType.TradingCard);
+
+ HashSet inventory = new HashSet { item1Game1X2, item1Game2 };
+ HashSet itemsToGive = new HashSet { item1Game1, item1Game2 };
+ HashSet itemsToReceive = new HashSet { item2Game1, item2Game2 };
+
+ Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
+ }
+
+ [TestMethod]
+ public void TradingSingleGameBadReject() {
+ Steam.Item item1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
+ Steam.Item item2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
+
+ HashSet inventory = new HashSet { item1, item2 };
+ HashSet itemsToGive = new HashSet { item1 };
+ HashSet itemsToReceive = new HashSet { item2 };
+
+ Assert.IsFalse(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
+ }
+
+ [TestMethod]
+ public void TradingSingleGameGoodAccept() {
+ Steam.Item item1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
+ Steam.Item item1X2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 2, 570, Steam.Item.EType.TradingCard);
+ Steam.Item item2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
+
+ HashSet inventory = new HashSet { item1X2 };
+ HashSet itemsToGive = new HashSet { item1 };
+ HashSet itemsToReceive = new HashSet { item2 };
+
+ Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
+ }
+
+ [TestMethod]
+ public void TradingSingleGameMultiTypeBadReject() {
+ Steam.Item item1Type1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
+ Steam.Item item1Type1X9 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 9, 570, Steam.Item.EType.TradingCard);
+ Steam.Item item2Type1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
+
+ Steam.Item item3Type2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 3, 1, 570, Steam.Item.EType.Emoticon);
+ Steam.Item item3Type2X9 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 3, 9, 570, Steam.Item.EType.Emoticon);
+ Steam.Item item4Type2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 4, 1, 570, Steam.Item.EType.Emoticon);
+
+ HashSet inventory = new HashSet { item1Type1X9, item3Type2X9, item4Type2 };
+ HashSet itemsToGive = new HashSet { item1Type1, item4Type2 };
+ HashSet itemsToReceive = new HashSet { item2Type1, item3Type2 };
+
+ Assert.IsFalse(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
+ }
+
+ [TestMethod]
+ public void TradingSingleGameMultiTypeNeutralAccept() {
+ Steam.Item item1Type1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
+ Steam.Item item1Type1X9 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 9, 570, Steam.Item.EType.TradingCard);
+ Steam.Item item2Type1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
+
+ Steam.Item item3Type2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 3, 1, 570, Steam.Item.EType.Emoticon);
+ Steam.Item item4Type2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 4, 1, 570, Steam.Item.EType.Emoticon);
+
+ HashSet inventory = new HashSet { item1Type1X9, item3Type2 };
+ HashSet itemsToGive = new HashSet { item1Type1, item3Type2 };
+ HashSet itemsToReceive = new HashSet { item2Type1, item4Type2 };
+
+ Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
+ }
+
+ [TestMethod]
+ public void TradingSingleGameNeutralAccept() {
+ Steam.Item item1 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 1, 1, 570, Steam.Item.EType.TradingCard);
+ Steam.Item item2 = new Steam.Item(Steam.Item.SteamAppID, Steam.Item.SteamCommunityContextID, 2, 1, 570, Steam.Item.EType.TradingCard);
+
+ HashSet inventory = new HashSet { item1 };
+ HashSet itemsToGive = new HashSet { item1 };
+ HashSet itemsToReceive = new HashSet { item2 };
+
+ Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
+ }
+
+ private static bool AcceptsTrade(HashSet inventory, HashSet itemsToGive, HashSet itemsToReceive) {
+ Type trading = typeof(ArchiSteamFarm.Trading);
+ MethodInfo method = trading.GetMethod("IsTradeNeutralOrBetter", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
+ return (bool) method.Invoke(null, new object[] { inventory, itemsToGive, itemsToReceive });
+ }
+ }
+}
\ No newline at end of file
diff --git a/ArchiSteamFarm.sln b/ArchiSteamFarm.sln
index 79803db10..f14b7fbc9 100644
--- a/ArchiSteamFarm.sln
+++ b/ArchiSteamFarm.sln
@@ -1,10 +1,12 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
-VisualStudioVersion = 15.0.26608.5
+VisualStudioVersion = 15.0.26621.2
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArchiSteamFarm", "ArchiSteamFarm\ArchiSteamFarm.csproj", "{CF84911C-2C4C-4195-8AF3-ABBB6D3DE9AA}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArchiSteamFarm.Tests", "ArchiSteamFarm.Tests\ArchiSteamFarm.Tests.csproj", "{91DC4C4F-3C23-4716-8CB2-BC7EAB65D759}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -15,8 +17,15 @@ Global
{CF84911C-2C4C-4195-8AF3-ABBB6D3DE9AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CF84911C-2C4C-4195-8AF3-ABBB6D3DE9AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CF84911C-2C4C-4195-8AF3-ABBB6D3DE9AA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {91DC4C4F-3C23-4716-8CB2-BC7EAB65D759}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {91DC4C4F-3C23-4716-8CB2-BC7EAB65D759}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {91DC4C4F-3C23-4716-8CB2-BC7EAB65D759}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {91DC4C4F-3C23-4716-8CB2-BC7EAB65D759}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {D7D54143-C857-4B76-A219-0E98C5BC4895}
+ EndGlobalSection
EndGlobal
diff --git a/ArchiSteamFarm.sln.DotSettings b/ArchiSteamFarm.sln.DotSettings
index 5e7032060..8ec2e26f3 100644
--- a/ArchiSteamFarm.sln.DotSettings
+++ b/ArchiSteamFarm.sln.DotSettings
@@ -384,4 +384,5 @@
True
True
True
- True
\ No newline at end of file
+ True
+ 8
\ No newline at end of file
diff --git a/ArchiSteamFarm/AssemblyInfo.cs b/ArchiSteamFarm/AssemblyInfo.cs
new file mode 100644
index 000000000..0dbdad1c6
--- /dev/null
+++ b/ArchiSteamFarm/AssemblyInfo.cs
@@ -0,0 +1,27 @@
+/*
+ _ _ _ ____ _ _____
+ / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
+ / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
+ / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
+/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
+
+ Copyright 2015-2017 Łukasz "JustArchi" Domeradzki
+ Contact: JustArchi@JustArchi.net
+
+ 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.Runtime.CompilerServices;
+
+[assembly: InternalsVisibleTo("ArchiSteamFarm.Tests")]
diff --git a/ArchiSteamFarm/BotConfig.cs b/ArchiSteamFarm/BotConfig.cs
index 76872ac51..b1b645667 100644
--- a/ArchiSteamFarm/BotConfig.cs
+++ b/ArchiSteamFarm/BotConfig.cs
@@ -92,6 +92,12 @@ namespace ArchiSteamFarm {
Steam.Item.EType.TradingCard
};
+ [JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace, Required = Required.DisallowNull)]
+ internal readonly HashSet MatchableTypes = new HashSet {
+ Steam.Item.EType.FoilTradingCard,
+ Steam.Item.EType.TradingCard
+ };
+
[JsonProperty(Required = Required.DisallowNull)]
internal readonly CryptoHelper.ECryptoMethod PasswordFormat = CryptoHelper.ECryptoMethod.PlainText;
diff --git a/ArchiSteamFarm/JSON/Steam.cs b/ArchiSteamFarm/JSON/Steam.cs
index 6f905c354..9177169cb 100644
--- a/ArchiSteamFarm/JSON/Steam.cs
+++ b/ArchiSteamFarm/JSON/Steam.cs
@@ -486,7 +486,15 @@ namespace ArchiSteamFarm.JSON {
return true;
}
- internal bool IsSteamCardsRequest() => ItemsToGive.All(item => (item.AppID == Item.SteamAppID) && (item.ContextID == Item.SteamCommunityContextID) && (item.Type == Item.EType.TradingCard));
+ internal bool IsValidSteamItemsRequest(HashSet acceptedTypes) {
+ if ((acceptedTypes == null) || (acceptedTypes.Count == 0)) {
+ ASF.ArchiLogger.LogNullError(nameof(acceptedTypes));
+ return false;
+ }
+
+ bool result = ItemsToGive.All(item => (item.AppID == Item.SteamAppID) && (item.ContextID == Item.SteamCommunityContextID) && acceptedTypes.Contains(item.Type));
+ return result;
+ }
[SuppressMessage("ReSharper", "UnusedMember.Global")]
internal enum ETradeOfferState : byte {
diff --git a/ArchiSteamFarm/Trading.cs b/ArchiSteamFarm/Trading.cs
index 0b09307a8..49c307632 100644
--- a/ArchiSteamFarm/Trading.cs
+++ b/ArchiSteamFarm/Trading.cs
@@ -173,7 +173,7 @@ namespace ArchiSteamFarm {
return new ParseTradeResult(tradeOffer.TradeOfferID, tradeOffer.ItemsToGive.Count > 0 ? ParseTradeResult.EResult.AcceptedWithItemLose : ParseTradeResult.EResult.AcceptedWithoutItemLose);
}
- // Always deny trades from blacklistem steamIDs
+ // Always deny trades from blacklisted steamIDs
if (Bot.IsBlacklistedFromTrades(tradeOffer.OtherSteamID64)) {
return new ParseTradeResult(tradeOffer.TradeOfferID, ParseTradeResult.EResult.RejectedPermanently);
}
@@ -214,8 +214,8 @@ namespace ArchiSteamFarm {
return new ParseTradeResult(tradeOffer.TradeOfferID, ParseTradeResult.EResult.RejectedPermanently);
}
- // Decline trade if we're losing anything but steam cards, or if it's non-dupes trade
- if (!tradeOffer.IsSteamCardsRequest() || !tradeOffer.IsFairTypesExchange()) {
+ // Decline trade if it's not fair games/types exchange or if we're requested to handle any not-accepted item type
+ if (!tradeOffer.IsFairTypesExchange() || !tradeOffer.IsValidSteamItemsRequest(Bot.BotConfig.MatchableTypes)) {
return new ParseTradeResult(tradeOffer.TradeOfferID, ParseTradeResult.EResult.RejectedPermanently);
}
@@ -241,17 +241,35 @@ namespace ArchiSteamFarm {
return new ParseTradeResult(tradeOffer.TradeOfferID, ParseTradeResult.EResult.AcceptedWithItemLose);
}
- // Get appIDs we're interested in
- HashSet appIDs = new HashSet(tradeOffer.ItemsToGive.Select(item => item.RealAppID));
+ // Get appIDs/types we're interested in
+ HashSet appIDs = new HashSet();
+ HashSet types = new HashSet();
+
+ foreach (Steam.Item item in tradeOffer.ItemsToGive) {
+ appIDs.Add(item.RealAppID);
+ types.Add(item.Type);
+ }
// Now check if it's worth for us to do the trade
- HashSet inventory = await Bot.ArchiWebHandler.GetMySteamInventory(false, new HashSet { Steam.Item.EType.TradingCard }, appIDs).ConfigureAwait(false);
+ HashSet inventory = await Bot.ArchiWebHandler.GetMySteamInventory(false, types, appIDs).ConfigureAwait(false);
if ((inventory == null) || (inventory.Count == 0)) {
// If we can't check our inventory when not using MatchEverything, this is a temporary failure
Bot.ArchiLogger.LogGenericWarning(string.Format(Strings.ErrorIsEmpty, nameof(inventory)));
return new ParseTradeResult(tradeOffer.TradeOfferID, ParseTradeResult.EResult.RejectedTemporarily);
}
+ bool accept = IsTradeNeutralOrBetter(inventory, tradeOffer.ItemsToGive, tradeOffer.ItemsToReceive);
+
+ // Even if trade is not neutral+ for us right now, it might be in the future, unless we're bot account where we assume that inventory doesn't change
+ return new ParseTradeResult(tradeOffer.TradeOfferID, accept ? ParseTradeResult.EResult.AcceptedWithItemLose : (Bot.BotConfig.IsBotAccount ? ParseTradeResult.EResult.RejectedPermanently : ParseTradeResult.EResult.RejectedTemporarily));
+ }
+
+ private static bool IsTradeNeutralOrBetter(HashSet inventory, HashSet itemsToGive, HashSet itemsToReceive) {
+ if ((inventory == null) || (inventory.Count == 0) || (itemsToGive == null) || (itemsToGive.Count == 0) || (itemsToReceive == null) || (itemsToReceive.Count == 0)) {
+ ASF.ArchiLogger.LogNullError(nameof(inventory) + " || " + nameof(itemsToGive) + " || " + nameof(itemsToReceive));
+ return false;
+ }
+
// Now let's create a map which maps items to their amount in our EQ
// This has to be done as we might have multiple items of given ClassID with multiple amounts
Dictionary itemAmounts = new Dictionary();
@@ -264,12 +282,12 @@ namespace ArchiSteamFarm {
}
// Calculate our value of items to give on per-game basis
- Dictionary> itemAmountToGivePerGame = new Dictionary>(appIDs.Count);
+ Dictionary<(Steam.Item.EType Type, uint AppID), List> itemAmountToGivePerGame = new Dictionary<(Steam.Item.EType Type, uint AppID), List>();
Dictionary itemAmountsToGive = new Dictionary(itemAmounts);
- foreach (Steam.Item item in tradeOffer.ItemsToGive) {
- if (!itemAmountToGivePerGame.TryGetValue(item.RealAppID, out List amountsToGive)) {
+ foreach (Steam.Item item in itemsToGive) {
+ if (!itemAmountToGivePerGame.TryGetValue((item.Type, item.RealAppID), out List amountsToGive)) {
amountsToGive = new List();
- itemAmountToGivePerGame[item.RealAppID] = amountsToGive;
+ itemAmountToGivePerGame[(item.Type, item.RealAppID)] = amountsToGive;
}
if (!itemAmountsToGive.TryGetValue(item.ClassID, out uint amount)) {
@@ -287,12 +305,12 @@ namespace ArchiSteamFarm {
}
// Calculate our value of items to receive on per-game basis
- Dictionary> itemAmountToReceivePerGame = new Dictionary>(appIDs.Count);
+ Dictionary<(Steam.Item.EType Type, uint AppID), List> itemAmountToReceivePerGame = new Dictionary<(Steam.Item.EType Type, uint AppID), List>();
Dictionary itemAmountsToReceive = new Dictionary(itemAmounts);
- foreach (Steam.Item item in tradeOffer.ItemsToReceive) {
- if (!itemAmountToReceivePerGame.TryGetValue(item.RealAppID, out List amountsToReceive)) {
+ foreach (Steam.Item item in itemsToReceive) {
+ if (!itemAmountToReceivePerGame.TryGetValue((item.Type, item.RealAppID), out List amountsToReceive)) {
amountsToReceive = new List();
- itemAmountToReceivePerGame[item.RealAppID] = amountsToReceive;
+ itemAmountToReceivePerGame[(item.Type, item.RealAppID)] = amountsToReceive;
}
if (!itemAmountsToReceive.TryGetValue(item.ClassID, out uint amount)) {
@@ -313,10 +331,7 @@ namespace ArchiSteamFarm {
// This is quite complex operation of taking minimum difference from all differences on per-game basis
// When calculating per-game difference, we sum only amounts at proper indexes, because user might be overpaying
int difference = itemAmountToGivePerGame.Min(kv => kv.Value.Select((t, i) => (int) (t - itemAmountToReceivePerGame[kv.Key][i])).Sum());
-
- // Trade is neutral+ for us if the difference is greater than 0
- // If not, we assume that the trade might be good for us in the future, unless we're bot account where we assume that inventory doesn't change
- return new ParseTradeResult(tradeOffer.TradeOfferID, difference > 0 ? ParseTradeResult.EResult.AcceptedWithItemLose : (Bot.BotConfig.IsBotAccount ? ParseTradeResult.EResult.RejectedPermanently : ParseTradeResult.EResult.RejectedTemporarily));
+ return difference > 0;
}
private sealed class ParseTradeResult {
diff --git a/ArchiSteamFarm/config/example.json b/ArchiSteamFarm/config/example.json
index 69f1bea62..a7c7de859 100644
--- a/ArchiSteamFarm/config/example.json
+++ b/ArchiSteamFarm/config/example.json
@@ -15,6 +15,10 @@
3,
5
],
+ "MatchableTypes": [
+ 3,
+ 5
+ ],
"PasswordFormat": 0,
"Paused": false,
"RedeemingPreferences": 0,