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.SteamCommunityContextID + "?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)) {
Bot.ArchiLogger.LogNullError(nameof(classIDString));
continue;
}
ulong classID;
if (!ulong.TryParse(classIDString, out classID) || (classID == 0)) {
Bot.ArchiLogger.LogNullError(nameof(classID));
continue;
}
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)) {
Bot.ArchiLogger.LogNullError(nameof(appIDString));
continue;
}
if (!uint.TryParse(appIDString, out appID) || (appID == 0)) {
Bot.ArchiLogger.LogNullError(nameof(appID));
continue;
}
}
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) {
Bot.ArchiLogger.LogNullError(nameof(items));
return null;
}
foreach (JToken item in items.Where(item => item != null)) {
Steam.Item steamItem;
try {
steamItem = item.ToObject<Steam.Item>();
} catch (JsonException e) {
Bot.ArchiLogger.LogGenericException(e);
return null;
}
if (steamItem == null) {
Bot.ArchiLogger.LogNullError(nameof(steamItem));
return null;
}
steamItem.AppID = Steam.Item.SteamAppID;
steamItem.ContextID = Steam.Item.SteamCommunityContextID;
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)) {
Bot.ArchiLogger.LogNullError(nameof(nextPage));
return null;
}
currentPage = nextPage;
}
return result;
}