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); } }
/// <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); }