Ejemplo n.º 1
0
        public List <UserFeedback> Loot(string transferFile)
        {
            Logger.Info($"Checking {transferFile} for items to loot");
            lock (_fileLock) {
                var(stash, errors) = Load(transferFile);
                if (errors.Count > 0)
                {
                    return(errors); // Cannot recover from any of these
                }

                // TODO: Delegate the stash to the crafting service
                List <UserFeedback> feedbacks = new List <UserFeedback>();
                var lootFromStashIdx          = _transferStashService.GetStashToLootFrom(stash);
                if (HasItems(stash, lootFromStashIdx))
                {
                    var classifiedItems = Classify(stash.Tabs[lootFromStashIdx]);

                    // Warn or auto delete bugged duplicates
                    if (classifiedItems.Duplicates.Count > 0)
                    {
                        if (_settings.GetPersistent().DeleteDuplicates)
                        {
                            stash.Tabs[lootFromStashIdx].Items.RemoveAll(e => classifiedItems.Duplicates.Any(m => m.Equals(e)));

                            // No items to loot, so just delete the duplicates.
                            if (classifiedItems.Remaining.Count == 0)
                            {
                                if (!_stashWriter.SafelyWriteStash(transferFile, stash))
                                {
                                    Logger.Error("Fatal error deleting items from Grim Dawn, items has been duplicated.");
                                }
                            }
                        }
                        else
                        {
                            classifiedItems.Duplicates.ForEach(item => Logger.Debug($"NotLootedDuplicate: {item}"));
                            feedbacks.Add(new UserFeedback(UserFeedbackLevel.Warning,
                                                           RuntimeSettings.Language.GetTag("iatag_feedback_duplicates_not_looted", classifiedItems.Duplicates.Count),
                                                           HelpService.GetUrl(HelpService.HelpType.DuplicateItem)
                                                           ));
                        }
                    }

                    if (classifiedItems.Stacked.Count > 0)
                    {
                        classifiedItems.Stacked.ForEach(item => Logger.Debug($"NotLootedStacked: {item}"));
                        feedbacks.Add(new UserFeedback(RuntimeSettings.Language.GetTag("iatag_feedback_stacked_not_looted", classifiedItems.Stacked.Count)));
                    }

                    // Unknown items, database not parsed for these items, IA can't deal with them.
                    if (classifiedItems.Unknown.Count > 0)
                    {
                        classifiedItems.Unknown.ForEach(item => Logger.Debug($"NotLootedUnknown: {item}"));
                        feedbacks.Add(new UserFeedback(
                                          UserFeedbackLevel.Warning,
                                          RuntimeSettings.Language.GetTag("iatag_feedback_unknown_not_looted", classifiedItems.Unknown.Count),
                                          HelpService.GetUrl(HelpService.HelpType.NotLootingUnidentified)
                                          ));
                    }

                    // The items we can actually loot (or delete duplicates)
                    if (classifiedItems.Remaining.Count > 0)
                    {
                        OnUpdate?.Invoke(this, null);

                        stash.Tabs[lootFromStashIdx].Items.RemoveAll(e => classifiedItems.Remaining.Any(m => m.Equals(e)));

                        var isHardcore = GlobalPaths.IsHardcore(transferFile);
                        if (StoreItemsToDatabase(classifiedItems.Remaining, stash.ModLabel, isHardcore))
                        {
                            feedbacks.Add(new UserFeedback(RuntimeSettings.Language.GetTag("iatag_looted_from_stash", classifiedItems.Remaining.Count, lootFromStashIdx + 1)));

                            if (!_stashWriter.SafelyWriteStash(transferFile, stash))
                            {
                                Logger.Error("Fatal error deleting items from Grim Dawn, items has been duplicated.");
                            }

                            // TODO: Do a quick check to see if the items are TRUUUULY gone from the stash?
                        }
                        else
                        {
                            feedbacks.Add(UserFeedback.FromTag("iatag_feedback_unable_to_loot_stash")); // TODO: Not sure what to report here..
                        }
                    }
                }
                else
                {
                    Logger.Info($"No items found in transfer stash {lootFromStashIdx + 1}.");
                    feedbacks.Add(UserFeedback.FromTag("iatag_feedback_no_items_to_loot"));
                }

                return(feedbacks);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     Loot all the items stored on page X, and store them to the local database
        /// </summary>
        /// <param name="filename"></param>
        private string EmptyPageX(string filename)
        {
            Logger.InfoFormat("Looting {0}", filename);

            var pCrypto = new GDCryptoDataBuffer(DataBuffer.ReadBytesFromDisk(filename));
            var stash   = new Stash();

            if (stash.Read(pCrypto))
            {
                var lootFromIndex = GetStashToLootFrom(stash);
                var isHardcore    = GlobalPaths.IsHardcore(filename);

#if DEBUG
                if (stash.Tabs.Count < 5)
                {
                    while (stash.Tabs.Count < 5)
                    {
                        stash.Tabs.Add(new StashTab());
                    }

                    SafelyWriteStash(filename, stash);
                    Logger.Info("Upgraded stash to 5 pages.");

                    return(string.Empty);
                }
#endif

                // Update the internal listing of unlooted items (in other stash tabs)
                var unlootedLocal = new List <Item>();

                for (var idx = 0; idx < stash.Tabs.Count; idx++)
                {
                    if (idx != lootFromIndex)
                    {
                        unlootedLocal.AddRange(stash.Tabs[idx].Items);
                    }
                }

                Interlocked.Exchange(ref _unlootedItems, new ConcurrentBag <Item>(unlootedLocal));
                StashUpdated?.Invoke(null, null);

                if (stash.Tabs.Count < 2)
                {
                    Logger.WarnFormat($"File \"{filename}\" only contains {stash.Tabs.Count} pages. IA requires at least 2 stash pages to function properly.");
                    return(GlobalSettings.Language.GetTag("iatag_not_enough_stash", filename, stash.Tabs.Count));
                }

                if (stash.Tabs.Count < lootFromIndex + 1)
                {
                    Logger.Warn($"You have configured IA to loot from stash {lootFromIndex + 1} but you only have {stash.Tabs.Count} pages");
                    return(GlobalSettings.Language.GetTag("iatag_invalid_loot_stash_number", lootFromIndex + 1, stash.Tabs.Count));
                }

                if (stash.Tabs[lootFromIndex].Items.Count > 0)
                {
                    HasLootedItemsOnceThisSession = true;

                    // Grab the items and clear the tab
                    var items = stash.Tabs[lootFromIndex].Items
                                .Where(m => m.StackCount <= 1)
                                .Where(m => !_playerItemDao.Exists(Map(m, stash.ModLabel, isHardcore)))
                                .ToList();
                    var notLootedDueToStackSize = stash.Tabs[lootFromIndex].Items.Where(m => m.StackCount > 1).ToList();

                    if (notLootedDueToStackSize.Count > 0)
                    {
                        notLootedDueToStackSize.ForEach(item => Logger.Debug($"NotLootedStacksize: {item}"));
                        _setFeedback(
                            "Warning",
                            GlobalSettings.Language.GetTag("iatag_feedback_stacked_not_looted", notLootedDueToStackSize.Count),
                            HelpService.GetUrl(HelpService.HelpType.NoStacks)
                            );
                    }

                    var notLootedDueToDuplicate = stash.Tabs[lootFromIndex].Items.ToList();
                    notLootedDueToDuplicate.RemoveAll(m => items.Contains(m) || m.StackCount > 1);

                    if (notLootedDueToDuplicate.Count > 0)
                    {
                        notLootedDueToDuplicate.ForEach(item => Logger.Debug($"NotLootedDuplicate: {item}"));
                        _setFeedback(
                            "Warning",
                            GlobalSettings.Language.GetTag("iatag_feedback_duplicates_not_looted", notLootedDueToDuplicate.Count),
                            HelpService.GetUrl(HelpService.HelpType.DuplicateItem)
                            );
                    }

                    stash.Tabs[lootFromIndex].Items.RemoveAll(e => items.Any(m => m.Equals(e)));

                    var storedItems = StoreItemsToDatabase(items, stash.ModLabel, isHardcore, stash.IsExpansion1);
                    var message     = GlobalSettings.Language.GetTag("iatag_looted_from_stash", items.Count, lootFromIndex + 1);

                    if (storedItems != null)
                    {
                        Logger.Info(message);

                        // Delete items from IA if we failed to remove them from GD.
                        if (!SafelyWriteStash(filename, stash))
                        {
                            _playerItemDao.Remove(storedItems);
                        }
                    }

                    _performedLootCallback();

                    return(message);
                }

                Logger.Info($"Looting of stash {lootFromIndex + 1} halted, no items available.");

                return(GlobalSettings.Language.GetTag("iatag_feedback_no_items_to_loot"));
            }

            Logger.Error("Could not load stash file.");
            Logger.Error("An update from the developer is most likely required.");

            return(string.Empty);
        }