private static bool ParseItems(Dictionary <ulong, Tuple <uint, Steam.Item.EType> > descriptions, List <KeyValue> input, HashSet <Steam.Item> output) { if ((descriptions == null) || (input == null) || (input.Count == 0) || (output == null)) { Logging.LogNullError(nameof(descriptions) + " || " + nameof(input) + " || " + nameof(output)); return(false); } foreach (KeyValue item in input) { uint appID = item["appid"].AsUnsignedInteger(); if (appID == 0) { Logging.LogNullError(nameof(appID)); return(false); } ulong contextID = item["contextid"].AsUnsignedLong(); if (contextID == 0) { Logging.LogNullError(nameof(contextID)); return(false); } ulong classID = item["classid"].AsUnsignedLong(); if (classID == 0) { Logging.LogNullError(nameof(classID)); return(false); } uint amount = item["amount"].AsUnsignedInteger(); if (amount == 0) { Logging.LogNullError(nameof(amount)); return(false); } uint realAppID = 0; Steam.Item.EType type = Steam.Item.EType.Unknown; Tuple <uint, Steam.Item.EType> description; if (descriptions.TryGetValue(classID, out description)) { realAppID = description.Item1; type = description.Item2; } Steam.Item steamItem = new Steam.Item(appID, contextID, classID, amount, realAppID, type); output.Add(steamItem); } return(true); }
internal async Task <HashSet <Steam.Item> > GetMySteamInventory(bool tradable) { if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) { return(null); } HashSet <Steam.Item> result = new HashSet <Steam.Item>(); string request = SteamCommunityURL + "/my/inventory/json/" + Steam.Item.SteamAppID + "/" + Steam.Item.SteamContextID + "?l=english&trading=" + (tradable ? "1" : "0") + "&start="; uint currentPage = 0; while (true) { JObject jObject = await WebBrowser.UrlGetToJObjectRetry(request + currentPage).ConfigureAwait(false); IEnumerable <JToken> descriptions = jObject?.SelectTokens("$.rgDescriptions.*"); if (descriptions == null) { return(null); // OK, empty inventory } Dictionary <ulong, Tuple <uint, Steam.Item.EType> > descriptionMap = new Dictionary <ulong, Tuple <uint, Steam.Item.EType> >(); foreach (JToken description in descriptions.Where(description => description != null)) { string classIDString = description["classid"].ToString(); if (string.IsNullOrEmpty(classIDString)) { Logging.LogNullError(nameof(classIDString), Bot.BotName); return(null); } ulong classID; if (!ulong.TryParse(classIDString, out classID) || (classID == 0)) { Logging.LogNullError(nameof(classID), Bot.BotName); return(null); } if (descriptionMap.ContainsKey(classID)) { continue; } uint appID = 0; string hashName = description["market_hash_name"].ToString(); if (!string.IsNullOrEmpty(hashName)) { appID = GetAppIDFromMarketHashName(hashName); } if (appID == 0) { string appIDString = description["appid"].ToString(); if (string.IsNullOrEmpty(appIDString)) { Logging.LogNullError(nameof(appIDString), Bot.BotName); return(null); } if (!uint.TryParse(appIDString, out appID)) { Logging.LogNullError(nameof(appID), Bot.BotName); return(null); } } Steam.Item.EType type = Steam.Item.EType.Unknown; string descriptionType = description["type"].ToString(); if (!string.IsNullOrEmpty(descriptionType)) { type = GetItemType(descriptionType); } descriptionMap[classID] = new Tuple <uint, Steam.Item.EType>(appID, type); } IEnumerable <JToken> items = jObject.SelectTokens("$.rgInventory.*"); if (items == null) { Logging.LogNullError(nameof(items), Bot.BotName); return(null); } foreach (JToken item in items.Where(item => item != null)) { Steam.Item steamItem; try { steamItem = item.ToObject <Steam.Item>(); } catch (JsonException e) { Logging.LogGenericException(e, Bot.BotName); return(null); } if (steamItem == null) { Logging.LogNullError(nameof(steamItem), Bot.BotName); return(null); } Tuple <uint, Steam.Item.EType> description; if (descriptionMap.TryGetValue(steamItem.ClassID, out description)) { steamItem.RealAppID = description.Item1; steamItem.Type = description.Item2; } result.Add(steamItem); } bool more; if (!bool.TryParse(jObject["more"].ToString(), out more) || !more) { break; // OK, last page } uint nextPage; if (!uint.TryParse(jObject["more_start"].ToString(), out nextPage) || (nextPage <= currentPage)) { Logging.LogNullError(nameof(nextPage), Bot.BotName); return(null); } currentPage = nextPage; } return(result); }
internal HashSet <Steam.TradeOffer> GetActiveTradeOffers() { if (string.IsNullOrEmpty(Bot.BotConfig.SteamApiKey)) { Logging.LogNullError(nameof(Bot.BotConfig.SteamApiKey), Bot.BotName); return(null); } KeyValue response = null; for (byte i = 0; (i < WebBrowser.MaxRetries) && (response == null); i++) { using (dynamic iEconService = WebAPI.GetInterface("IEconService", Bot.BotConfig.SteamApiKey)) { iEconService.Timeout = Timeout; try { response = iEconService.GetTradeOffers( get_received_offers: 1, active_only: 1, get_descriptions: 1, secure: !Program.GlobalConfig.ForceHttp ); } catch (Exception e) { Logging.LogGenericException(e, Bot.BotName); } } } if (response == null) { Logging.LogGenericWarning("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName); return(null); } Dictionary <ulong, Tuple <uint, Steam.Item.EType> > descriptions = new Dictionary <ulong, Tuple <uint, Steam.Item.EType> >(); foreach (KeyValue description in response["descriptions"].Children) { ulong classID = description["classid"].AsUnsignedLong(); if (classID == 0) { Logging.LogNullError(nameof(classID), Bot.BotName); return(null); } if (descriptions.ContainsKey(classID)) { continue; } uint appID = 0; string hashName = description["market_hash_name"].Value; if (!string.IsNullOrEmpty(hashName)) { appID = GetAppIDFromMarketHashName(hashName); } if (appID == 0) { appID = description["appid"].AsUnsignedInteger(); } Steam.Item.EType type = Steam.Item.EType.Unknown; string descriptionType = description["type"].Value; if (!string.IsNullOrEmpty(descriptionType)) { type = GetItemType(descriptionType); } descriptions[classID] = new Tuple <uint, Steam.Item.EType>(appID, type); } HashSet <Steam.TradeOffer> result = new HashSet <Steam.TradeOffer>(); foreach (KeyValue trade in response["trade_offers_received"].Children) { Steam.TradeOffer.ETradeOfferState state = trade["trade_offer_state"].AsEnum <Steam.TradeOffer.ETradeOfferState>(); if (state == Steam.TradeOffer.ETradeOfferState.Unknown) { Logging.LogNullError(nameof(state)); return(null); } if (state != Steam.TradeOffer.ETradeOfferState.Active) { continue; } ulong tradeOfferID = trade["tradeofferid"].AsUnsignedLong(); if (tradeOfferID == 0) { Logging.LogNullError(nameof(tradeOfferID)); return(null); } uint otherSteamID3 = trade["accountid_other"].AsUnsignedInteger(); if (otherSteamID3 == 0) { Logging.LogNullError(nameof(otherSteamID3)); return(null); } Steam.TradeOffer tradeOffer = new Steam.TradeOffer(tradeOfferID, otherSteamID3, state); List <KeyValue> itemsToGive = trade["items_to_give"].Children; if (itemsToGive.Count > 0) { if (!ParseItems(descriptions, itemsToGive, tradeOffer.ItemsToGive)) { Logging.LogGenericError("Parsing " + nameof(itemsToGive) + " failed!", Bot.BotName); return(null); } } List <KeyValue> itemsToReceive = trade["items_to_receive"].Children; if (itemsToReceive.Count > 0) { if (!ParseItems(descriptions, itemsToReceive, tradeOffer.ItemsToReceive)) { Logging.LogGenericError("Parsing " + nameof(itemsToReceive) + " failed!", Bot.BotName); return(null); } } result.Add(tradeOffer); } return(result); }
internal HashSet <Steam.TradeOffer> GetTradeOffers() { if (string.IsNullOrEmpty(Bot.BotConfig.SteamApiKey)) { // TODO: Correct this when Mono 4.4+ will be a latest stable one | https://bugzilla.xamarin.com/show_bug.cgi?id=39455 Logging.LogNullError("SteamApiKey", Bot.BotName); //Logging.LogNullError(nameof(Bot.BotConfig.SteamApiKey), Bot.BotName); return(null); } KeyValue response = null; using (dynamic iEconService = WebAPI.GetInterface("IEconService", Bot.BotConfig.SteamApiKey)) { iEconService.Timeout = Timeout; for (byte i = 0; (i < WebBrowser.MaxRetries) && (response == null); i++) { try { response = iEconService.GetTradeOffers( get_received_offers: 1, active_only: 1, get_descriptions: 1, secure: !Program.GlobalConfig.ForceHttp ); } catch (Exception e) { Logging.LogGenericException(e, Bot.BotName); } } } if (response == null) { Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName); return(null); } Dictionary <ulong, Tuple <uint, Steam.Item.EType> > descriptions = new Dictionary <ulong, Tuple <uint, Steam.Item.EType> >(); foreach (KeyValue description in response["descriptions"].Children) { ulong classID = description["classid"].AsUnsignedLong(); if (classID == 0) { Logging.LogNullError(nameof(classID), Bot.BotName); continue; } if (descriptions.ContainsKey(classID)) { continue; } uint appID = 0; string hashName = description["market_hash_name"].Value; if (!string.IsNullOrEmpty(hashName)) { appID = GetAppIDFromMarketHashName(hashName); } if (appID == 0) { appID = (uint)description["appid"].AsUnsignedLong(); } Steam.Item.EType type = Steam.Item.EType.Unknown; string descriptionType = description["type"].Value; if (!string.IsNullOrEmpty(descriptionType)) { type = GetItemType(descriptionType); } descriptions[classID] = new Tuple <uint, Steam.Item.EType>(appID, type); } HashSet <Steam.TradeOffer> result = new HashSet <Steam.TradeOffer>(); foreach (KeyValue trade in response["trade_offers_received"].Children) { Steam.TradeOffer tradeOffer = new Steam.TradeOffer { TradeOfferID = trade["tradeofferid"].AsUnsignedLong(), OtherSteamID3 = (uint)trade["accountid_other"].AsUnsignedLong(), State = trade["trade_offer_state"].AsEnum <Steam.TradeOffer.ETradeOfferState>() }; foreach (Steam.Item steamItem in trade["items_to_give"].Children.Select(item => new Steam.Item { AppID = (uint)item["appid"].AsUnsignedLong(), ContextID = item["contextid"].AsUnsignedLong(), AssetID = item["assetid"].AsUnsignedLong(), ClassID = item["classid"].AsUnsignedLong(), InstanceID = item["instanceid"].AsUnsignedLong(), Amount = (uint)item["amount"].AsUnsignedLong() })) { Tuple <uint, Steam.Item.EType> description; if (descriptions.TryGetValue(steamItem.ClassID, out description)) { steamItem.RealAppID = description.Item1; steamItem.Type = description.Item2; } tradeOffer.ItemsToGive.Add(steamItem); } foreach (Steam.Item steamItem in trade["items_to_receive"].Children.Select(item => new Steam.Item { AppID = (uint)item["appid"].AsUnsignedLong(), ContextID = item["contextid"].AsUnsignedLong(), AssetID = item["assetid"].AsUnsignedLong(), ClassID = item["classid"].AsUnsignedLong(), InstanceID = item["instanceid"].AsUnsignedLong(), Amount = (uint)item["amount"].AsUnsignedLong() })) { Tuple <uint, Steam.Item.EType> description; if (descriptions.TryGetValue(steamItem.ClassID, out description)) { steamItem.RealAppID = description.Item1; steamItem.Type = description.Item2; } tradeOffer.ItemsToReceive.Add(steamItem); } result.Add(tradeOffer); } return(result); }
internal async Task <HashSet <Steam.Item> > GetMyTradableInventory() { if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) { return(null); } HashSet <Steam.Item> result = new HashSet <Steam.Item>(); ushort nextPage = 0; while (true) { string request = SteamCommunityURL + "/my/inventory/json/" + Steam.Item.SteamAppID + "/" + Steam.Item.SteamContextID + "?trading=1&start=" + nextPage; JObject jObject = null; for (byte i = 0; (i < WebBrowser.MaxRetries) && (jObject == null); i++) { jObject = await WebBrowser.UrlGetToJObject(request).ConfigureAwait(false); } if (jObject == null) { Logging.LogGenericWTF("Request failed even after " + WebBrowser.MaxRetries + " tries", Bot.BotName); return(null); } IEnumerable <JToken> descriptions = jObject.SelectTokens("$.rgDescriptions.*"); if (descriptions == null) { return(null); } Dictionary <Tuple <ulong, ulong>, Tuple <uint, Steam.Item.EType> > descriptionMap = new Dictionary <Tuple <ulong, ulong>, Tuple <uint, Steam.Item.EType> >(); foreach (JToken description in descriptions) { string classIDString = description["classid"].ToString(); if (string.IsNullOrEmpty(classIDString)) { continue; } ulong classID; if (!ulong.TryParse(classIDString, out classID) || (classID == 0)) { continue; } string instanceIDString = description["instanceid"].ToString(); if (string.IsNullOrEmpty(instanceIDString)) { continue; } ulong instanceID; if (!ulong.TryParse(instanceIDString, out instanceID)) { continue; } Tuple <ulong, ulong> key = new Tuple <ulong, ulong>(classID, instanceID); if (descriptionMap.ContainsKey(key)) { continue; } uint appID = 0; Steam.Item.EType type = Steam.Item.EType.Unknown; string hashName = description["market_hash_name"].ToString(); if (!string.IsNullOrEmpty(hashName)) { appID = GetAppIDFromMarketHashName(hashName); } string descriptionType = description["type"].ToString(); if (!string.IsNullOrEmpty(descriptionType)) { type = GetItemType(descriptionType); } descriptionMap[key] = new Tuple <uint, Steam.Item.EType>(appID, type); } IEnumerable <JToken> items = jObject.SelectTokens("$.rgInventory.*"); if (items == null) { return(null); } foreach (JToken item in items) { Steam.Item steamItem; try { steamItem = JsonConvert.DeserializeObject <Steam.Item>(item.ToString()); } catch (JsonException e) { Logging.LogGenericException(e, Bot.BotName); continue; } if (steamItem == null) { continue; } Tuple <ulong, ulong> key = new Tuple <ulong, ulong>(steamItem.ClassID, steamItem.InstanceID); Tuple <uint, Steam.Item.EType> description; if (descriptionMap.TryGetValue(key, out description)) { steamItem.RealAppID = description.Item1; steamItem.Type = description.Item2; } result.Add(steamItem); } bool more; if (!bool.TryParse(jObject["more"].ToString(), out more) || !more) { break; } if (!ushort.TryParse(jObject["more_start"].ToString(), out nextPage)) { break; } } return(result); }