using AssortValidator.Common.Helpers; using static AssortUpdater.AssortFlattener; namespace AssortUpdater { public static class AssortMerger { public static List CreateMergedFlattenedAssorts(string trader, List flattenedLiveAssorts, List flattenedExistingAssorts) { var completeAssorts = new List(); // Add live assorts to merged list foreach (var liveAssort in flattenedLiveAssorts) { completeAssorts.Add(liveAssort); } LoggingHelpers.LogSuccess($"{trader} Added {flattenedLiveAssorts.Count} items from live"); LoggingHelpers.LogNewLine(); // Check for missing existing assorts and add those var ExistingItemCount = 0; foreach (var existingAssort in flattenedExistingAssorts) { var matchInCompleteAssorts = GetMatchingAssortFromCompleteList(trader, existingAssort, completeAssorts); if (matchInCompleteAssorts != null) { // Match found, dont add dupe item continue; } // no assort found, add LoggingHelpers.LogWarning($"{trader} Adding Item found in existing assorts but not live: {existingAssort.ItemId} {existingAssort.ItemName} Level: {existingAssort.Level}"); completeAssorts.Add(existingAssort); ExistingItemCount++; } LoggingHelpers.LogNewLine(); LoggingHelpers.LogSuccess($"{trader} Added {ExistingItemCount} existing items"); return completeAssorts; } private static FlatAssort? GetMatchingAssortFromCompleteList(string traderName, FlatAssort assortToFind, List completeAssorts) { IEnumerable? existingAssort = GetAssortByItemId(assortToFind, completeAssorts); if (existingAssort.Any() && existingAssort.Count() == 1) { // one match found by id, dont add return existingAssort.First(); } existingAssort = GetAssortByItemIdAndLevel(assortToFind, completeAssorts); if (SingleAssortFound(existingAssort)) { //LoggingHelpers.LogSuccess($"{traderName} match found for item: {assortToFind.ItemId} {assortToFind.ItemName} Level: {assortToFind.Level}"); return existingAssort.First(); } if (MultipleAssortsFound(existingAssort)) { // Multiple matches found, be more specific existingAssort = GetAssortByItemIdLevelAndMoney(assortToFind, completeAssorts); if (SingleAssortFound(existingAssort)) { return existingAssort.First(); } if (MultipleAssortsFound(existingAssort)) { // Multiple matches found, be more specific...again existingAssort = GetAssortByItemIdLevelMoneySubItemCountAndCostItemCount(assortToFind, completeAssorts); if (SingleAssortFound(existingAssort)) { return existingAssort.First(); } } } existingAssort = GetAssortByBarterCostAndCount(assortToFind, completeAssorts); if (SingleAssortFound(existingAssort)) { return existingAssort.First(); } //LoggingHelpers.LogError($"{traderName} No match found for item: {assortToFind.ItemId} {assortToFind.ItemName} Level: {assortToFind.Level}"); // No matches found, probably doesnt exist return null; } private static bool SingleAssortFound(IEnumerable existingAssort) { return existingAssort?.Count() == 1; } private static bool MultipleAssortsFound(IEnumerable? existingAssort) { return existingAssort?.Count() > 1; } private static IEnumerable GetAssortByItemIdLevelMoneySubItemCountAndCostItemCount(FlatAssort assortToFind, List completeAssorts) { return completeAssorts.Where(x => x.ItemId == assortToFind.ItemId && x.Level == assortToFind.Level && x.IsMoney == assortToFind.IsMoney && x.SubItems.Count == assortToFind.SubItems.Count && x.BarterDetails[0].count == assortToFind.BarterDetails[0].count); } private static IEnumerable GetAssortByItemId(FlatAssort assortToFind, List completeAssorts) { return completeAssorts.Where(x => x.ItemId == assortToFind.ItemId); } private static IEnumerable GetAssortByItemIdAndLevel(FlatAssort assortToFind, List completeAssorts) { return completeAssorts.Where(x => x.ItemId == assortToFind.ItemId && x.Level == assortToFind.Level); } private static IEnumerable GetAssortByItemIdLevelAndMoney(FlatAssort assortToFind, List completeAssorts) { return completeAssorts.Where(x => x.ItemId == assortToFind.ItemId && x.Level == assortToFind.Level && x.IsMoney == assortToFind.IsMoney); } private static IEnumerable? GetAssortByBarterCostAndCount(FlatAssort assortToFind, List completeAssorts) { var itemsThatHaveSameCost = completeAssorts.Where(x => x.ItemId == assortToFind.ItemId && x.Level == assortToFind.Level); foreach (var item in itemsThatHaveSameCost) { var matches = 0; foreach (var barter in item.BarterDetails) { var match = assortToFind.BarterDetails.Any(x => x._tpl == barter._tpl && x.count == barter.count); if (match) { matches++; // collection already has item } } if (matches == assortToFind.BarterDetails.Count) { //LoggingHelpers.LogSuccess($"{traderName} item found with same cost: {assortToFind.ItemId} {assortToFind.ItemName} Level: {assortToFind.Level}"); return new List() { item }; } } return null; } public static void ListDuplicatesInMergedAssorts(List flatAssorts) { foreach (var item in flatAssorts) { var dupes = flatAssorts.Where(x => x.ItemId == item.ItemId && x.Level == item.Level && x.IsMoney == item.IsMoney && x.AssortId != item.AssortId); if (dupes.Any()) { LoggingHelpers.LogError($"{dupes.Count()} Dupes found for assort {item.AssortId} item: {item.ItemName} id:{item.ItemId} level: {item.Level} isMoney: {item.IsMoney}"); foreach (var dupeItem in dupes) { LoggingHelpers.LogError($"Dupe assort{dupeItem.AssortId}: {dupeItem.ItemId} - {dupeItem.ItemName} id:{item.ItemId} level: {dupeItem.Level} isMoney:{dupeItem.IsMoney}"); } } } } } }