Bugfixes + other types for STM

This commit is contained in:
JustArchi
2016-04-20 23:02:02 +02:00
parent 27464f6120
commit 1df9af08e6
3 changed files with 87 additions and 36 deletions

View File

@@ -281,12 +281,32 @@ namespace ArchiSteamFarm {
if (!typeMap.ContainsKey(key)) {
string type = description["type"].Value;
if (!string.IsNullOrEmpty(type)) {
if (type.EndsWith("Trading Card", StringComparison.Ordinal)) {
typeMap[key] = Steam.Item.EType.TradingCard;
} else if (type.EndsWith("Profile Background", StringComparison.Ordinal)) {
typeMap[key] = Steam.Item.EType.ProfileBackground;
} else {
typeMap[key] = Steam.Item.EType.Unknown;
switch (type) {
case "Booster Pack":
typeMap[key] = Steam.Item.EType.BoosterPack;
break;
case "Coupon":
typeMap[key] = Steam.Item.EType.Coupon;
break;
case "Gift":
typeMap[key] = Steam.Item.EType.Gift;
break;
case "Steam Gems":
typeMap[key] = Steam.Item.EType.SteamGems;
break;
default:
if (type.EndsWith("Emoticon", StringComparison.Ordinal)) {
typeMap[key] = Steam.Item.EType.Emoticon;
} else if (type.EndsWith("Foil Trading Card", StringComparison.Ordinal)) {
typeMap[key] = Steam.Item.EType.FoilTradingCard;
} else if (type.EndsWith("Profile Background", StringComparison.Ordinal)) {
typeMap[key] = Steam.Item.EType.ProfileBackground;
} else if (type.EndsWith("Trading Card", StringComparison.Ordinal)) {
typeMap[key] = Steam.Item.EType.TradingCard;
} else {
typeMap[key] = Steam.Item.EType.Unknown;
}
break;
}
}
}
@@ -308,7 +328,7 @@ namespace ArchiSteamFarm {
AssetID = item["assetid"].AsUnsignedLong(),
ClassID = item["classid"].AsUnsignedLong(),
InstanceID = item["instanceid"].AsUnsignedLong(),
Amount = (byte) item["amount"].AsUnsignedLong()
Amount = (uint) item["amount"].AsUnsignedLong()
};
Tuple<ulong, ulong> key = new Tuple<ulong, ulong>(steamItem.ClassID, steamItem.InstanceID);
@@ -333,7 +353,7 @@ namespace ArchiSteamFarm {
AssetID = item["assetid"].AsUnsignedLong(),
ClassID = item["classid"].AsUnsignedLong(),
InstanceID = item["instanceid"].AsUnsignedLong(),
Amount = (byte) item["amount"].AsUnsignedLong()
Amount = (uint) item["amount"].AsUnsignedLong()
};
Tuple<ulong, ulong> key = new Tuple<ulong, ulong>(steamItem.ClassID, steamItem.InstanceID);

View File

@@ -34,6 +34,14 @@ namespace ArchiSteamFarm {
internal enum EType : byte {
Unknown,
BoosterPack,
Coupon,
Gift,
SteamGems,
Emoticon,
FoilTradingCard,
ProfileBackground,
TradingCard
}
@@ -149,7 +157,7 @@ namespace ArchiSteamFarm {
}
}
internal byte Amount;
internal uint Amount;
[JsonProperty(PropertyName = "amount", Required = Required.Always)]
internal string AmountString {
@@ -161,8 +169,8 @@ namespace ArchiSteamFarm {
return;
}
byte result;
if (!byte.TryParse(value, out result)) {
uint result;
if (!uint.TryParse(value, out result)) {
return;
}
@@ -174,8 +182,7 @@ namespace ArchiSteamFarm {
internal EType Type { get; set; }
}
internal sealed class TradeOffer {
// REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_TradeOffer
internal sealed class TradeOffer { // REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_TradeOffer
internal enum ETradeOfferState : byte {
Unknown,
Invalid,
@@ -242,16 +249,16 @@ namespace ArchiSteamFarm {
}
}
internal bool IsSteamCardsOnlyTrade {
internal bool IsSteamOnlyTrade {
get {
foreach (Item item in ItemsToGive) {
if (item.AppID != Item.SteamAppID || item.ContextID != Item.SteamContextID || item.Type != Item.EType.TradingCard) {
if (item.AppID != Item.SteamAppID || item.ContextID != Item.SteamContextID) {
return false;
}
}
foreach (Item item in ItemsToReceive) {
if (item.AppID != Item.SteamAppID || item.ContextID != Item.SteamContextID || item.Type != Item.EType.TradingCard) {
if (item.AppID != Item.SteamAppID || item.ContextID != Item.SteamContextID) {
return false;
}
}
@@ -262,35 +269,56 @@ namespace ArchiSteamFarm {
internal bool IsPotentiallyDupesTrade {
get {
Dictionary<uint, byte> ItemsToGivePerGameAmount = new Dictionary<uint, byte>();
Dictionary<uint, Dictionary<Item.EType, uint>> ItemsToGivePerGame = new Dictionary<uint, Dictionary<Item.EType, uint>>();
foreach (Item item in ItemsToGive) {
byte amount;
if (ItemsToGivePerGameAmount.TryGetValue(item.RealAppID, out amount)) {
ItemsToGivePerGameAmount[item.RealAppID] = (byte) (amount + item.Amount);
Dictionary<Item.EType, uint> ItemsPerType;
if (ItemsToGivePerGame.TryGetValue(item.RealAppID, out ItemsPerType)) {
ItemsPerType = new Dictionary<Item.EType, uint>();
ItemsPerType[item.Type] = item.Amount;
ItemsToGivePerGame[item.RealAppID] = ItemsPerType;
} else {
ItemsToGivePerGameAmount[item.RealAppID] = item.Amount;
uint amount;
if (ItemsPerType.TryGetValue(item.Type, out amount)) {
ItemsPerType[item.Type] = amount + item.Amount;
} else {
ItemsPerType[item.Type] = item.Amount;
}
}
}
Dictionary<uint, byte> ItemsToReceivePerGameAmount = new Dictionary<uint, byte>();
Dictionary<uint, Dictionary<Item.EType, uint>> ItemsToReceivePerGame = new Dictionary<uint, Dictionary<Item.EType, uint>>();
foreach (Item item in ItemsToReceive) {
byte amount;
if (ItemsToReceivePerGameAmount.TryGetValue(item.RealAppID, out amount)) {
ItemsToReceivePerGameAmount[item.RealAppID] = (byte) (amount + item.Amount);
Dictionary<Item.EType, uint> ItemsPerType;
if (ItemsToReceivePerGame.TryGetValue(item.RealAppID, out ItemsPerType)) {
ItemsPerType = new Dictionary<Item.EType, uint>();
ItemsPerType[item.Type] = item.Amount;
ItemsToReceivePerGame[item.RealAppID] = ItemsPerType;
} else {
ItemsToReceivePerGameAmount[item.RealAppID] = item.Amount;
uint amount;
if (ItemsPerType.TryGetValue(item.Type, out amount)) {
ItemsPerType[item.Type] = amount + item.Amount;
} else {
ItemsPerType[item.Type] = item.Amount;
}
}
}
// Ensure that amounts are exactly the same
foreach (KeyValuePair<uint, byte> item in ItemsToGivePerGameAmount) {
byte otherValue;
if (!ItemsToReceivePerGameAmount.TryGetValue(item.Key, out otherValue)) {
// Ensure that amount per type and per game matches
foreach (KeyValuePair<uint, Dictionary<Item.EType, uint>> ItemsPerGame in ItemsToGivePerGame) {
Dictionary<Item.EType, uint> otherItemsPerType;
if (!ItemsToReceivePerGame.TryGetValue(ItemsPerGame.Key, out otherItemsPerType)) {
return false;
}
if (item.Value != otherValue) {
return false;
foreach (KeyValuePair<Item.EType, uint> ItemsPerType in ItemsPerGame.Value) {
uint otherAmount;
if (!otherItemsPerType.TryGetValue(ItemsPerType.Key, out otherAmount)) {
return false;
}
if (ItemsPerType.Value != otherAmount) {
return false;
}
}
}

View File

@@ -94,7 +94,10 @@ namespace ArchiSteamFarm {
return;
}
tradeOffers.RemoveWhere(trade => RecentlyParsedTrades.Contains(trade.TradeOfferID));
lock (RecentlyParsedTrades) {
tradeOffers.RemoveWhere(trade => RecentlyParsedTrades.Contains(trade.TradeOfferID));
}
if (tradeOffers.Count == 0) {
return;
}
@@ -150,13 +153,13 @@ namespace ArchiSteamFarm {
return false;
}
// Rule 2 - We always trade steam cards and only for the same set
if (!tradeOffer.IsSteamCardsOnlyTrade || !tradeOffer.IsPotentiallyDupesTrade) {
// Rule 2 - We always trade steam itmes and only for the same set
if (!tradeOffer.IsSteamOnlyTrade || !tradeOffer.IsPotentiallyDupesTrade) {
return false;
}
// This STM trade SHOULD be fine
// Potential TODO: Ensure that our inventory in fact has proper amount of both received and given cards
// Potential TODO: Ensure that our inventory in fact has proper amount of both received and given items
// This way we could calculate amounts before and after trade, ensuring that we're in fact trading dupes and not 1 + 2 -> 0 + 3
return true;
}