From 379bd96fa4793a47b3cb0d513a0317e1ccd19811 Mon Sep 17 00:00:00 2001 From: Chomp Date: Sat, 25 Jan 2025 20:28:08 +0000 Subject: [PATCH] Second part to `ReplaceIDs` rewrite --- Libraries/Core/Helpers/ItemHelper.cs | 171 +++++++++++---------------- 1 file changed, 70 insertions(+), 101 deletions(-) diff --git a/Libraries/Core/Helpers/ItemHelper.cs b/Libraries/Core/Helpers/ItemHelper.cs index 92c93dc2..e283f731 100644 --- a/Libraries/Core/Helpers/ItemHelper.cs +++ b/Libraries/Core/Helpers/ItemHelper.cs @@ -989,6 +989,31 @@ public class ItemHelper( } } + public List ReplaceIDs(List items) + { + foreach (var item in items) + { + + // Generate new id + var newId = _hashUtil.Generate(); + + // Keep copy of original id + var originalId = item.Id; + + // Update items id to new one we generated + item.Id = newId; + + // Find all children of item and update their parent ids to match + var childItems = items.Where(x => x.ParentId == originalId); + foreach (var childItem in childItems) + { + childItem.ParentId = newId; + } + } + + return items; + } + /// /// Regenerate all GUIDs with new IDs, with the exception of special item types (e.g. quest, sorting table, etc.) This /// function will not mutate the original items list, but will return a new list with new GUIDs. @@ -1000,128 +1025,72 @@ public class ItemHelper( /// List public List ReplaceIDs( List originalItems, - PmcData pmcData = null, + PmcData? pmcData = null, List? insuredItems = null, Dictionary? fastPanel = null) { - var serialisedInventory = _jsonUtil.Serialize(originalItems); - var hideoutAreaStashes = pmcData?.Inventory?.HideoutAreaStashes ?? []; + // Blacklist + var itemIdBlacklist = new HashSet(); + + if (pmcData != null) + { + itemIdBlacklist.UnionWith( + new List{ + pmcData.Inventory.Equipment, + pmcData.Inventory.QuestRaidItems, + pmcData.Inventory.QuestStashItems, + pmcData.Inventory.SortingTable, + pmcData.Inventory.Stash, + pmcData.Inventory.HideoutCustomizationStashId + }); + itemIdBlacklist.UnionWith(pmcData.Inventory.HideoutAreaStashes.Keys); + } + + + // Add insured items ids to blacklist + if (insuredItems is not null) + { + itemIdBlacklist.UnionWith(insuredItems.Select(x => x.ItemId)); + } + foreach (var item in originalItems) { - if (pmcData != null) - { - // Insured items should not be renamed. Only works for PMCs. - if (insuredItems?.FirstOrDefault(i => i.ItemId == item.Id) != null) - continue; - - // Do not replace the IDs of specific types of items. - if (item.Id == pmcData?.Inventory?.Equipment || - item.Id == pmcData?.Inventory?.QuestRaidItems || - item.Id == pmcData?.Inventory?.QuestStashItems || - item.Id == pmcData?.Inventory?.SortingTable || - item.Id == pmcData?.Inventory?.Stash || - item.Id == pmcData?.Inventory?.HideoutCustomizationStashId || - (hideoutAreaStashes?.ContainsKey(item.Id) ?? false)) - { - continue; - } - } - - // Replace the ID of the item in the serialised inventory using a regular expression. - var oldId = item.Id; - var newId = _hashUtil.Generate(); - serialisedInventory = serialisedInventory.Replace(oldId, newId); // Node uses regex with "g" flag to replace all instances - - // Also replace in quick slot if the old ID exists. - if (fastPanel != null) - { - foreach (var itemSlot in fastPanel) - { - if (fastPanel[itemSlot.Key] == oldId) - fastPanel[itemSlot.Key] = fastPanel[itemSlot.Key].Replace(oldId, newId); // Node uses regex with "g" flag to replace all instances - } - } - } - - var items = _jsonUtil.Deserialize>(serialisedInventory); - - // fix dupe id's - var dupes = new Dictionary(); - var newParents = new Dictionary>(); - var childrenMapping = new Dictionary>(); - var oldToNewIds = new Dictionary>(); - - // Finding duplicate IDs involves scanning the item three times. - // First scan - Check which ids are duplicated. - // Second scan - Map parents to items. - // Third scan - Resolve IDs. - foreach (var item in items) - { - if (!dupes.TryAdd(item.Id, 0)) - { - dupes[item.Id] += 1; - } - } - - foreach (var item in items) - { - if (!(dupes[item.Id] > 1)) + if (itemIdBlacklist.Contains(item.Id)) { continue; } + // Generate new id var newId = _hashUtil.Generate(); - if (!newParents.ContainsKey(item.ParentId)) + + // Keep copy of original id + var originalId = item.Id; + + // Update items id to new one we generated + item.Id = newId; + + // Find all children of item and update their parent ids to match + var childItems = originalItems.Where(x => x.ParentId == originalId); + foreach (var childItem in childItems) { - newParents.Add(item.ParentId, []); + childItem.ParentId = newId; } - var newParentsItems = newParents.GetValueOrDefault(item.ParentId); - newParentsItems.Add(item); - - if (!oldToNewIds.ContainsKey(item.Id)) + // Also replace in quick slot if the old ID exists. + if (pmcData.Inventory.FastPanel is null) { - oldToNewIds.Add(item.Id, []); + continue; } - var oldToNewIdsItems = oldToNewIds.GetValueOrDefault(item.Id); - oldToNewIdsItems.Add(newId); - } - - foreach (var item in items) - { - if (dupes[item.Id] > 1) + // Update quickslot id + if (pmcData.Inventory.FastPanel.ContainsKey(originalId)) { - var oldId = item.Id; - var newId = oldToNewIds[oldId][0]; - oldToNewIds[oldId].RemoveAt(0); - item.Id = newId; - - // Extract one of the children that's also duplicated. - if (newParents.ContainsKey(oldId) && newParents[oldId].Count > 0) - { - childrenMapping[newId] = new(); - for (int i = 0; i < newParents[oldId].Count; i++) - { - // Make sure we haven't already assigned another duplicate child of - // same slot and location to this parent. - var childId = GetChildId(newParents[oldId][i]); - - if (!childrenMapping.ContainsKey(childId)) - { - childrenMapping[newId][childId] = 1; - newParents[oldId][i].ParentId = newId; - // Some very fucking sketchy stuff on this childIndex - // No clue wth was that childIndex supposed to be, but its not - newParents[oldId].RemoveAt(i); - } - } - } + pmcData.Inventory.FastPanel[originalId] = newId; } } - return items; + return originalItems; } ///