From 593f68f8122135b42118a29fb36a436f98ae5165 Mon Sep 17 00:00:00 2001 From: Chomp Date: Wed, 12 Jan 2022 23:30:51 +0000 Subject: [PATCH] Add assort code to generate assorts - PoC --- AssortUpdater/AssortFlattener.cs | 114 ++++++++++++++ AssortUpdater/AssortUpdater.csproj | 14 ++ AssortUpdater/Program.cs | 194 ++++++++++++++++++++++++ AssortValidator.Common/JsonWriter.cs | 30 ++++ AssortValidator.Common/Models/Assort.cs | 1 + 5 files changed, 353 insertions(+) create mode 100644 AssortUpdater/AssortFlattener.cs create mode 100644 AssortUpdater/AssortUpdater.csproj create mode 100644 AssortUpdater/Program.cs create mode 100644 AssortValidator.Common/JsonWriter.cs diff --git a/AssortUpdater/AssortFlattener.cs b/AssortUpdater/AssortFlattener.cs new file mode 100644 index 0000000..3900c20 --- /dev/null +++ b/AssortUpdater/AssortFlattener.cs @@ -0,0 +1,114 @@ +using AssortValidator.Common; +using AssortValidator.Common.Models; + +namespace AssortUpdater +{ + public static class AssortFlattener + { + + public static List FlattenExistingAssorts(Assort existingAssorts) + { + var results = new List(); + + foreach (var assort in existingAssorts.items.Where(x => x.slotId == "hideout")) + { + var level = existingAssorts.loyal_level_items.FirstOrDefault(x => x.Key == assort._id); + var barterDetails = existingAssorts.barter_scheme.FirstOrDefault(x => x.Key == assort._id); + var firstBarterDetails = barterDetails.Value[0].First(); + + results.Add(new FlatAssort + { + AssortId = assort._id, + ItemId = assort._tpl, + ItemName = ItemTemplateHelper.GetNameById(assort._tpl), + Level = level.Value, + IsMoney = barterDetails.Value.Count == 1 && ItemTemplateHelper.IsMoney(firstBarterDetails._tpl), + BarterDetails = barterDetails.Value.First(), + }); + } + + // Add in sub items + foreach (var subAssort in existingAssorts.items.Where(x => x.slotId != "hideout")) + { + // find parent item in assort list we created + var assortToAddTo = results.Find(x => x.AssortId == subAssort.parentId); + if (assortToAddTo is null) + { + // check items subitems as some have mods of their own + foreach (var result in results) + { + if (result.SubItems.Any(x => x._id == subAssort.parentId)) + { + assortToAddTo = result; + break; + } + } + } + assortToAddTo.SubItems.Add(subAssort); + } + + return results; + } + + public static List FlattenLiveAssorts(Assort liveAssorts) + { + var results = new List(); + foreach (var assort in liveAssorts.items.Where(x => x.slotId == "hideout")) + { + var level = liveAssorts.loyal_level_items.FirstOrDefault(x => x.Key == assort._id); + var barterDetails = liveAssorts.barter_scheme.FirstOrDefault(x => x.Key == assort._id); + var firstBarterDetails = barterDetails.Value[0].First(); + + results.Add(new FlatAssort + { + AssortId = assort._id, + ItemId = assort._tpl, + ItemName = ItemTemplateHelper.GetNameById(assort._tpl), + Level = level.Value, + IsMoney = barterDetails.Value.Count == 1 && ItemTemplateHelper.IsMoney(firstBarterDetails._tpl), + BarterDetails = barterDetails.Value.First(), + }); + } + + // Add in sub items + foreach (var subAssort in liveAssorts.items.Where(x => x.slotId != "hideout")) + { + // find parent item in assort list we created + var assortToAddTo = results.Find(x => x.AssortId == subAssort.parentId); + if (assortToAddTo is null) + { + // check items subitems as some have mods of their own + foreach (var result in results) + { + if (result.SubItems.Any(x => x._id == subAssort.parentId)) + { + assortToAddTo = result; + break; + } + } + } + assortToAddTo.SubItems.Add(subAssort); + } + + return results; + } + + public class FlatAssort + { + public FlatAssort() + { + SubItems = new List(); + BarterDetails = new List(); + } + + public string AssortId { get; set; } + public string ItemId { get; set; } + public string ItemName { get; set; } + public List SubItems { get; set; } + public int Level { get; set; } + public bool IsMoney { get; set; } + public List BarterDetails { get; set; } + } + + } +} diff --git a/AssortUpdater/AssortUpdater.csproj b/AssortUpdater/AssortUpdater.csproj new file mode 100644 index 0000000..b551360 --- /dev/null +++ b/AssortUpdater/AssortUpdater.csproj @@ -0,0 +1,14 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + diff --git a/AssortUpdater/Program.cs b/AssortUpdater/Program.cs new file mode 100644 index 0000000..e02140b --- /dev/null +++ b/AssortUpdater/Program.cs @@ -0,0 +1,194 @@ +using AssortHelpers.Common.Helpers; +using AssortHelpers.Helpers; +using AssortUpdater; +using AssortValidator.Common.Helpers; +using static AssortUpdater.AssortFlattener; + +class Program +{ + static void Main(string[] args) + { + var inputPath = CreateWorkingFolders(); + InputFileHelper.SetInputFiles(inputPath); + + var existingAssortData = AssortHelper.GetAssortData(); + var liveAssortData = AssortHelper.GetLiveAssortData(); + + var questData = QuestHelper.GetQuestData("quests"); + var questAssortData = QuestHelper.GetQuestAssortUnlocks(questData.Values.ToList()); + + foreach (var trader in liveAssortData) + { + var traderId = TraderHelper.GetTraderIdByName(trader.Key); + var traderQuests = questData.Where(x=>x.Value.traderId == traderId); + var traderAssortData = questAssortData.Where(x => x.TraderId == traderId); + + var liveAssorts = trader.Value; + var existingAssorts = existingAssortData[trader.Key]; + var mergedAssortData = liveAssorts; + + var flattenedLiveAssorts = AssortFlattener.FlattenLiveAssorts(liveAssorts); + var flattenedExistingAssorts = AssortFlattener.FlattenExistingAssorts(existingAssorts); + + //LogItemsMissingInLiveAssorts(trader.Key.ToString(), flattenedExistingAssorts, flattenedLiveAssorts); + + //LogItemsMissingInExistingAssorts(trader.Key.ToString(), flattenedExistingAssorts, flattenedLiveAssorts); + + + var result = CreateMergedFlattenedAssorts(trader.Key.ToString(), flattenedLiveAssorts, flattenedExistingAssorts); + + + // generate trader specific assort quest data, write out to file + var questAssorts = QuestHelper.CreateQuestAssortsList(traderAssortData); + //JsonWriter.WriteJson(questAssorts, traderId, Directory.GetCurrentDirectory(), "questassort"); + } + } + + private static List CreateMergedFlattenedAssorts(string trader, List flattenedLiveAssorts, List flattenedExistingAssorts) + { + var completeAssorts = new List(); + + // Add live assorts + foreach (var liveAssort in flattenedLiveAssorts) + { + completeAssorts.Add(liveAssort); + } + LoggingHelpers.LogSuccess($"{trader} Added {flattenedLiveAssorts.Count} items from live"); + + + // Check for missing existing assorts and add those + var ExistingItemCount = 0; + foreach (var existingAssort in flattenedExistingAssorts) + { + var matchInCompleteAssorts = GetMatchingAssortFromCompleteList(trader, existingAssort, completeAssorts); + if (matchInCompleteAssorts is null) + { + // 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.LogSuccess($"{trader} Added {ExistingItemCount} existing items"); + return completeAssorts; + } + + private static FlatAssort GetMatchingAssortFromCompleteList(string traderName, FlatAssort assortToFind, List completeAssorts) + { + var existingAssort = completeAssorts.Where(x => x.ItemId == assortToFind.ItemId + && x.Level == assortToFind.Level); + + // check only one item found + if (existingAssort?.Count() == 1) + { + //LoggingHelpers.LogSuccess($"{traderName} match found for item: {assortToFind.ItemId} {assortToFind.ItemName} Level: {assortToFind.Level}"); + return existingAssort.First(); + } + + if (existingAssort?.Count() > 1) + { + // try and get it by money + existingAssort = completeAssorts.Where( x=> x.ItemId == assortToFind.ItemId + && x.Level == assortToFind.Level + && x.IsMoney == assortToFind.IsMoney); + + if (existingAssort?.Count() == 1) + { + return existingAssort.First(); + } + if (existingAssort?.Count() > 1) + { + existingAssort = 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); + + if ( existingAssort?.Count() == 1) + { + return existingAssort.First(); + } + } + } + + //LoggingHelpers.LogError($"{traderName} No match found for item: {assortToFind.ItemId} {assortToFind.ItemName} Level: {assortToFind.Level}"); + return null; + } + + private static void LogItemsMissingInExistingAssorts(string traderName, List flattenedExistingAssorts, List flattenedLiveAssorts) + { + foreach (var liveAssort in flattenedLiveAssorts) + { + // get live assort, match by level and item tpl + var existingAssort = flattenedExistingAssorts.Where(x => x.ItemId == liveAssort.ItemId && x.Level == liveAssort.Level); + + if (existingAssort.Count() > 1) + { + // we have multiple matches, lets compare by number of rewards + existingAssort = flattenedExistingAssorts.Where(x => x.ItemId == liveAssort.ItemId + && x.Level == liveAssort.Level + && x.BarterDetails.Count == liveAssort.BarterDetails.Count + && x.SubItems.Count == liveAssort.SubItems.Count + && x.IsMoney == liveAssort.IsMoney); + if (existingAssort is null) + { + LoggingHelpers.LogError($"{traderName} multiple matches found for item: {liveAssort.ItemId} {liveAssort.ItemName} Level: {liveAssort.Level}"); + continue; + } + } + + if (liveAssort is null) + { + LoggingHelpers.LogError($"{traderName} unable to find matching live assort for item: {liveAssort.ItemId} {liveAssort.ItemName} Level: {liveAssort.Level}"); + } + else + { + LoggingHelpers.LogSuccess($"{traderName} found matching live assort for item: {liveAssort.ItemId} {liveAssort.ItemName} Level: {liveAssort.Level}"); + } + } + } + + private static void LogItemsMissingInLiveAssorts(string traderName, List flattenedExistingAssorts, List flattenedLiveAssorts) + { + foreach (var existingAssort in flattenedExistingAssorts) + { + // get live assort, match by level and item tpl + var liveAssort = flattenedLiveAssorts.Where(x => x.ItemId == existingAssort.ItemId && x.Level == existingAssort.Level); + + if (liveAssort.Count() > 1) + { + // we have multiple matches, lets compare by number of rewards + liveAssort = flattenedLiveAssorts.Where(x => x.ItemId == existingAssort.ItemId + && x.Level == existingAssort.Level + && x.BarterDetails.Count == existingAssort.BarterDetails.Count + && x.SubItems.Count == existingAssort.SubItems.Count + && x.IsMoney == existingAssort.IsMoney); + if (liveAssort.Count() > 1) + { + LoggingHelpers.LogError($"{traderName} multiple matches found for item: {existingAssort.ItemId} {existingAssort.ItemName} Level: {existingAssort.Level}"); + continue; + } + } + + if (liveAssort is null) + { + LoggingHelpers.LogError($"{traderName} unable to find matching existing assort for item: {existingAssort.ItemId} {existingAssort.ItemName} Level: {existingAssort.Level}"); + } + else + { + LoggingHelpers.LogSuccess($"{traderName} found matching existing assort for item: {existingAssort.ItemId} {existingAssort.ItemName} Level: {existingAssort.Level}"); + } + } + } + + private static string CreateWorkingFolders() + { + var workingPath = Directory.GetCurrentDirectory(); + // create input folder + var inputPath = $"{workingPath}//input"; + DiskHelpers.CreateDirIfDoesntExist(inputPath); + + return inputPath; + } +} diff --git a/AssortValidator.Common/JsonWriter.cs b/AssortValidator.Common/JsonWriter.cs new file mode 100644 index 0000000..46c13e1 --- /dev/null +++ b/AssortValidator.Common/JsonWriter.cs @@ -0,0 +1,30 @@ +using AssortHelpers.Helpers; +using System; +using System.IO; +using System.Text.Encodings.Web; +using System.Text.Json; + +namespace AssortValidator.Common +{ + public static class JsonWriter + { + public static void WriteJson(T itemToSerialise, string outputFolderName, string workingPath, string fileName) + { + var outputPath = $"{workingPath}\\output\\{outputFolderName}"; + DiskHelpers.CreateDirIfDoesntExist(outputPath); + + var options = new JsonSerializerOptions + { + WriteIndented = true, + IgnoreNullValues = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + + }; + var json = JsonSerializer.Serialize(itemToSerialise, options); + File.WriteAllText($"{outputPath}\\{fileName}.json", json); + + + Console.WriteLine($"wrote {fileName}.json file to {outputPath}"); + } + } +} diff --git a/AssortValidator.Common/Models/Assort.cs b/AssortValidator.Common/Models/Assort.cs index 470bb70..d085807 100644 --- a/AssortValidator.Common/Models/Assort.cs +++ b/AssortValidator.Common/Models/Assort.cs @@ -27,6 +27,7 @@ namespace AssortValidator.Common.Models { public string _id { get; set; } public string _tpl { get; set; } + public string ItemName { get; set; } public string parentId { get; set; } public string slotId { get; set; } public Upd upd { get; set; }