public async Task <IEnumerable <StashTab> > GetStashTabsAsync(string league, CancellationToken cancellationToken = default)
        {
            ProgressBar progress = new ProgressBar("Downloading stash data...");

            progress.Start();
            progress.Update(0);

            // prepare request
            Log.Debug("Requesting stash tabs info for account {Account} in league {League}", AccountName, league);
            Dictionary <string, object> query = new Dictionary <string, object>(5)
            {
                { "accountName", this.AccountName },
                { "league", league },
                { "realm", this.Realm },
                { "tabs", 1 }
            };
            string url = $"https://www.pathofexile.com/character-window/get-stash-items?" +
                         string.Join('&', query.Select(pair => $"{pair.Key}={pair.Value}"));

            using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);

            // send
            using HttpResponseMessage response = await SendAsync(request, cancellationToken).ConfigureAwait(false);

            response.EnsureSuccessStatusCode();

            // read content
            Log.Verbose("Parsing stash info");
            JObject data = JObject.Parse(await response.Content.ReadAsStringAsync().ConfigureAwait(false));

            StashTab[] tabs = data["tabs"].ToObject <StashTab[]>(SerializationHelper.DefaultSerializer);
            for (int i = 0; i < tabs.Length; i++)
            {
                progress.Update(i, tabs.Length);
                StashTab tab   = tabs[i];
                JToken   items = await GetStashTabContentsInternalAsync(league, tab.Index, cancellationToken).ConfigureAwait(false);

                items.PopulateObject(tab);
            }
            progress.Update(tabs.Length, tabs.Length, "Stash data download complete.");
            Log.Verbose("Done parsing stash info");
            return(tabs);
        }
Exemple #2
0
        private void CheckRecipe(IEnumerable <Item> items, StashTab tab, CombinationRequirements requirements)
        {
            LogLargeWarning(items.Count(), tab.Name);
            this._stopwatch.Restart();

            // prepare qualities and combinations
            IReadOnlyDictionary <Item, int> qualities = RecipeCombination.ExtractItemQualities(items);

            Log.Verbose("Generating permutations");
            IEnumerable <IEnumerable <KeyValuePair <Item, int> > > permutations = Permutator.GetCombinations(qualities, requirements.MaxItems);

            // track already done just to reduce spam in output
            HashSet <RecipeCombination> alreadyDone = new HashSet <RecipeCombination>();
            // only output tab name the first time
            bool tabNameShown = false;
            // skip showing invalid if capacity is exceeded
            bool exceedsCapacity = permutations.LongCount() > int.MaxValue / 2;

            if (exceedsCapacity && _options.ShowInvalid)
            {
                Log.Warning("Possible combinations count exceed capacity - logging of invalid combinations will be disabled");
            }
            Log.Verbose("Permutations generated in {Time} ms", this._stopwatch.ElapsedMilliseconds);

            // calculate total quality of each combination
            Log.Verbose("Calculating combinations");
            foreach (IEnumerable <KeyValuePair <Item, int> > sequence in permutations)
            {
                RecipeCombination combination = RecipeCombination.Calculate(sequence, requirements.TargetQuality);

                // determine if set should be shown
                if (_options.OnlyExact && combination.TotalQuality != requirements.TargetQuality)
                {
                    continue;
                }
                if ((!_options.ShowInvalid || exceedsCapacity) && combination.TotalQuality < requirements.TargetQuality)
                {
                    continue;
                }

                // ensure this set wasn't already calculated, based just on items qualities
                if (!alreadyDone.Add(combination))
                {
                    continue;
                }

                // for the first item in set, notify user what tab it's in
                if (!tabNameShown)
                {
                    Log.Information("Found possible trades with items from tab {TabName}", tab);
                    tabNameShown = true;
                }

                // output the set and total quality
                Console.Write(combination.ToString() + ": ");
                ConsoleColor previousColor = Console.ForegroundColor;
                if (combination.TotalQuality == requirements.TargetQuality)
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                }
                else if (combination.TotalQuality > requirements.TargetQuality)
                {
                    Console.ForegroundColor = ConsoleColor.DarkGreen;
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                }
                Console.Write(combination.TotalQuality);
                Console.ForegroundColor = previousColor;
                if (_options.ShowItemNames)
                {
                    Console.Write($" ({string.Join(", ", combination.Items)})");
                }
                Console.WriteLine();
            }

            Log.Verbose("Done checking stash tab {TabName} ({Time} ms)", tab.Name, this._stopwatch.ElapsedMilliseconds);
        }