diff --git a/AssortUpdater/AssortFlattener.cs b/AssortUpdater/AssortFlattener.cs index d34d9e6..0eb6ae1 100644 --- a/AssortUpdater/AssortFlattener.cs +++ b/AssortUpdater/AssortFlattener.cs @@ -51,6 +51,9 @@ namespace AssortUpdater return results; } + /// + /// Turn bsg format into a flat list of assorts that are easier to work with + /// public static List FlattenLiveAssorts(Assort liveAssorts) { var results = new List(); @@ -95,6 +98,9 @@ namespace AssortUpdater return results; } + /// + /// Turn flattened assorts list into bsg format + /// public static Assort UnFlatten(List flatAssorts) { var result = new Assort(); diff --git a/AssortUpdater/Program.cs b/AssortUpdater/Program.cs index 4b40f32..d50fffc 100644 --- a/AssortUpdater/Program.cs +++ b/AssortUpdater/Program.cs @@ -42,13 +42,13 @@ class Program Assort unflattenedAssorts = AssortFlattener.UnFlatten(flatAssorts); JsonWriter.WriteJson(unflattenedAssorts, traderId, Directory.GetCurrentDirectory(), "assort"); - var questAssorts = QuestHelper.CreateQuestAssortsList(trader.Key, traderQuestAssortUnlocks, flatAssorts); + var questAssorts = QuestAssortGenerator.CreateQuestAssorts(trader.Key, traderQuestAssortUnlocks, flatAssorts); LogQuestUnlocks(questAssorts, unflattenedAssorts); JsonWriter.WriteJson(questAssorts, traderId, Directory.GetCurrentDirectory(), "questassort"); } } - private static void LogQuestUnlocks(QuestHelper.QuestAssorts questAssorts, Assort unflattenedAssorts) + private static void LogQuestUnlocks(QuestAssorts questAssorts, Assort unflattenedAssorts) { foreach (var item in questAssorts.success) { diff --git a/AssortUpdater/QuestAssortGenerator.cs b/AssortUpdater/QuestAssortGenerator.cs new file mode 100644 index 0000000..1b7f714 --- /dev/null +++ b/AssortUpdater/QuestAssortGenerator.cs @@ -0,0 +1,99 @@ +using AssortValidator.Common.Helpers; +using AssortValidator.Common.Helpers.Models; +using AssortValidator.Common.Models; + +namespace AssortUpdater +{ + public static class QuestAssortGenerator + { + public static QuestAssorts CreateQuestAssorts(Trader trader, IEnumerable questAssortData, List flatAssorts) + { + var result = new QuestAssorts(); + int count = 1; + foreach (var questAssortUnlock in questAssortData) + { + // find assort by item tpl and level + IEnumerable associatedAssort = flatAssorts.Where(x => x.ItemId == questAssortUnlock.AssortItems[0]._tpl + && x.Level == questAssortUnlock.LoyaltyLevel); + + // no assort found + if (associatedAssort?.Any() != true) + { + // Add a filler item + result.success.Add($"MISSING{count}", questAssortUnlock.QuestId); + count++; + continue; + } + + // One match found, woo yeah + if (associatedAssort.Count() == 1) + { + result.success.Add(associatedAssort.Single().AssortId, questAssortUnlock.QuestId); + continue; + } + + // multiple found, use hand-made data from QuestAssortMappingHelper + if (associatedAssort.Count() > 1) + { + var matchingAssort = GetMatchingAssortUsingManualMapping(trader, associatedAssort, questAssortUnlock); + if (matchingAssort.Count == 1) + { + result.success.Add(matchingAssort.Single().AssortId, questAssortUnlock.QuestId); + continue; + } + + if (matchingAssort.Count == 0) + { + result.success.Add($"none found {count}", questAssortUnlock.QuestId); + count++; + continue; + } + + result.success.Add($"too many {count}", questAssortUnlock.QuestId); + count++; + } + } + + return result; + } + + private static List GetMatchingAssortUsingManualMapping(Trader trader, IEnumerable possibleAssorts, QuestAssortUnlock questToFindAssortFor) + { + var assorts = new List(); + + // Get manually made mappings to help us find the assort we want + var manualAssortMappings = QuestAssortMappingHelper.GetQuestAssortMappingDetails(questToFindAssortFor.QuestId); + manualAssortMappings = manualAssortMappings.Where(x => x.Trader == trader + && x.ItemTplId == questToFindAssortFor.AssortTemplateId + && x.Level == questToFindAssortFor.LoyaltyLevel).ToList(); + + // there may be multiple mappings for a quest, try and filter it down by subitem count + QuestAssortMapping singleMapping; + if (manualAssortMappings.Count != 1) + { + singleMapping = manualAssortMappings.Single(x => (x.SubItemCount ?? 0) == questToFindAssortFor.AssortItems.Count - 1); // remove base item from count + } + else + { + singleMapping = manualAssortMappings[0]; + } + + // Find matching assort + assorts = possibleAssorts.Where(x => x.IsMoney == singleMapping.IsMoneyBarter + && trader == singleMapping.Trader + && x.Level == singleMapping.Level + && x.RawItem._tpl == singleMapping.ItemTplId).ToList(); + + // Filter assort on subitem count + if (assorts.Count > 1) + { + assorts = assorts.Where(x => x.SubItems.Count == singleMapping.SubItemCount).ToList(); + } + + // Hopefully just one + return assorts; + } + + + } +} diff --git a/AssortValidator.Common/Helpers/QuestHelper.cs b/AssortValidator.Common/Helpers/QuestHelper.cs index d4a54fe..5c36257 100644 --- a/AssortValidator.Common/Helpers/QuestHelper.cs +++ b/AssortValidator.Common/Helpers/QuestHelper.cs @@ -261,14 +261,16 @@ namespace AssortValidator.Common.Helpers { "6179afd0bca27a099552e040", "Lost Contact"}, { "613708a7f8333a5d15594368", "Action Test"} }; + private static Dictionary _liveQuestData; public static Quest GetQuestById(string questId) { return _liveQuestData[questId]; } - private static Dictionary _liveQuestData; - + /// + /// use when the quest data is in bsgs format + /// public static Dictionary GetQuestDataFromDump(string filename = "resp.client.quest.list") { if (_liveQuestData == null) @@ -282,6 +284,9 @@ namespace AssortValidator.Common.Helpers return _liveQuestData; } + /// + /// use when the qeust data is in spt format + /// public static Dictionary GetQuestData(string filename = "quest") { if (_liveQuestData == null) @@ -294,6 +299,9 @@ namespace AssortValidator.Common.Helpers return _liveQuestData; } + /// + /// Get a list of quests and their associated assort item unlocks + /// public static List GetQuestAssortUnlocks(IEnumerable quests) { var results = new List(); @@ -310,7 +318,7 @@ namespace AssortValidator.Common.Helpers TraderType = TraderHelper.GetTraderTypeById(assortUnlockReward.traderId), AssortItems = assortUnlockReward.items, AssortTemplateId = assortUnlockReward.items[0]._tpl, - LoyaltyLevel = assortUnlockReward.loyaltyLevel.GetValueOrDefault(1), + LoyaltyLevel = assortUnlockReward.loyaltyLevel ?? 1, QuestState = "success" }); } @@ -319,109 +327,6 @@ namespace AssortValidator.Common.Helpers return results; } - public static QuestAssorts CreateQuestAssortsList(Trader trader, IEnumerable questAssortData, List flatAssorts) - { - var result = new QuestAssorts(); - int count = 1; - foreach (var questAssortUnlock in questAssortData) - { - if (questAssortUnlock.QuestId == "5c0bbaa886f7746941031d82") - { - var x = 1; - } - - // find assort by item tpl and level - IEnumerable associatedAssort = flatAssorts.Where(x => x.ItemId == questAssortUnlock.AssortItems[0]._tpl && x.Level == questAssortUnlock.LoyaltyLevel); - - if (associatedAssort is null || !associatedAssort.Any()) - { - result.success.Add($"MISSING{count}", questAssortUnlock.QuestId); - count++; - continue; - } - - // just one item found, woo yeah - if (associatedAssort.Count() == 1) - { - result.success.Add(associatedAssort.Single().AssortId, questAssortUnlock.QuestId); - continue; - } - - // multiple found, use hand-made data from QuestAssortMappingHelper - if (associatedAssort.Count() > 1) - { - var matchingAssort = GetMatchingAssortUsingManualMapping(trader, associatedAssort, questAssortUnlock); - - if (matchingAssort.Count == 1) - { - result.success.Add(matchingAssort.Single().AssortId, questAssortUnlock.QuestId); - continue; - } - - if (matchingAssort.Count == 0) - { - result.success.Add($"none found {Guid.NewGuid()}", questAssortUnlock.QuestId); - continue; - } - - result.success.Add($"too many {Guid.NewGuid()}", questAssortUnlock.QuestId); - } - } - - return result; - } - - private static List GetMatchingAssortUsingManualMapping(Trader trader, IEnumerable possibleAssorts, QuestAssortUnlock questToFindAssortFor) - { - var results = new List(); - - List manualAssortMappings = QuestAssortMappingHelper.GetQuestAssortMappingDetails(questToFindAssortFor.QuestId); - var mappings = manualAssortMappings.Where(x => x.Trader == trader - && x.ItemTplId == questToFindAssortFor.AssortTemplateId - && x.Level == questToFindAssortFor.LoyaltyLevel).ToList(); - QuestAssortMapping singleMapping; - if (mappings.Count != 1) - { - // last resort, find by sub item count - singleMapping = mappings.Single(x => (x.SubItemCount ?? 0) == questToFindAssortFor.AssortItems.Count - 1); - } - else - { - singleMapping = mappings[0]; - } - - results = possibleAssorts.Where(x => x.IsMoney == singleMapping.IsMoneyBarter - && trader == singleMapping.Trader - && x.Level == singleMapping.Level - && x.RawItem._tpl == singleMapping.ItemTplId).ToList(); - - if (results.Any(x => x.AssortId == "61e0a291033bdc459438c2b7")) - { - var x = 2; - } - - if (results.Count > 1) - { - results = results.Where(x => x.SubItems.Count == singleMapping.SubItemCount).ToList(); - } - - return results; - } - - public class QuestAssorts - { - public QuestAssorts() - { - started = new Dictionary(); - success = new Dictionary(); - fail = new Dictionary(); - } - - public Dictionary started { get; set; } - public Dictionary success { get; set; } - public Dictionary fail { get; set; } - } - private static string GetQuestNameById(string id) { if (questNames.ContainsKey(id)) diff --git a/AssortValidator.Common/Models/QuestAssorts.cs b/AssortValidator.Common/Models/QuestAssorts.cs new file mode 100644 index 0000000..e0e01f4 --- /dev/null +++ b/AssortValidator.Common/Models/QuestAssorts.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AssortValidator.Common.Models +{ + public class QuestAssorts + { + public QuestAssorts() + { + started = new Dictionary(); + success = new Dictionary(); + fail = new Dictionary(); + } + + public Dictionary started { get; set; } + public Dictionary success { get; set; } + public Dictionary fail { get; set; } + } +}