From 81761b6ee888dab09955ebdd8c96e8cc9c366826 Mon Sep 17 00:00:00 2001 From: Chomp Date: Tue, 14 Sep 2021 19:52:11 +0100 Subject: [PATCH] New project for generating a quest file --- GenerateQuestFile/GenerateQuestFile.csproj | 13 + GenerateQuestFile/Program.cs | 125 +++++++ QuestValidator.Common/Helpers/QuestHelper.cs | 338 +++++++++++------- QuestValidator.Common/JsonWriter.cs | 30 ++ .../Models/QuestRequirement.cs | 11 + QuestValidator.Models/Input/Quest.cs | 56 ++- QuestValidator.sln | 12 +- QuestValidator/Program.cs | 71 +++- 8 files changed, 517 insertions(+), 139 deletions(-) create mode 100644 GenerateQuestFile/GenerateQuestFile.csproj create mode 100644 GenerateQuestFile/Program.cs create mode 100644 QuestValidator.Common/JsonWriter.cs create mode 100644 QuestValidator.Common/Models/QuestRequirement.cs diff --git a/GenerateQuestFile/GenerateQuestFile.csproj b/GenerateQuestFile/GenerateQuestFile.csproj new file mode 100644 index 0000000..dea5e8f --- /dev/null +++ b/GenerateQuestFile/GenerateQuestFile.csproj @@ -0,0 +1,13 @@ + + + + Exe + netcoreapp3.1 + + + + + + + + diff --git a/GenerateQuestFile/Program.cs b/GenerateQuestFile/Program.cs new file mode 100644 index 0000000..8be80d5 --- /dev/null +++ b/GenerateQuestFile/Program.cs @@ -0,0 +1,125 @@ +using AssortGenerator.Common.Helpers; +using QuestValidator.Common; +using QuestValidator.Common.Helpers; +using QuestValidator.Helpers; +using QuestValidator.Models; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; + +namespace GenerateQuestFile +{ + class Program + { + /// + /// Generate a quests.json file in /output/ + /// Uses every quest from the live quest dump file + /// If any quests are missing, it will use the quests.json file to fill in the blanks + /// + /// + static void Main(string[] args) + { + var inputPath = DiskHelpers.CreateWorkingFolders(); + InputFileHelper.SetInputFiles(inputPath); + + //read in quest files + var questData = QuestHelper.GetQuestData(); + var liveQuestData = QuestHelper.GetLiveQuestData(); + //var oldQuestData = QuestHelper.GetQuestData("oldQuests"); + + // Find the quests that are missing from the live file + var missingQuests = new List(); + foreach (var quest in questData.Values) + { + if (quest._id == "5936da9e86f7742d65037edf") + { + + } + + var liveQuest = liveQuestData.data.Find(x => x._id == quest._id); + if (liveQuest == null) + { + missingQuests.Add(quest); + LoggingHelpers.LogError($"ERROR Quest {quest._id} {QuestHelper.GetQuestNameById(quest._id)} missing in live"); + } + } + + // Create a list of quests to output + // use all quests in live file + // Use quests from quests.json to fill in missing quests + var questsToOutputToFile = new Dictionary(); + //create live version of quests.json + foreach (var quest in liveQuestData.data) + { + var questName = QuestHelper.GetQuestNameById(quest._id); // special characters like ", brake the client when it parses it + var rgx = new Regex("[^a-zA-Z0-9 -]"); + quest.QuestName = rgx.Replace(questName, ""); + questsToOutputToFile.Add(quest._id, quest); + } + foreach (var missingQuest in missingQuests) + { + missingQuest.QuestName = QuestHelper.GetQuestNameById(missingQuest._id); + questsToOutputToFile.Add(missingQuest._id, missingQuest); + } + + + + foreach (var quest in questsToOutputToFile) + { + if (quest.Key == "5c0d4c12d09282029f539173") + { + + } + + var originalQuest = questData.FirstOrDefault(x => x.Key == quest.Key).Value; + if (originalQuest.conditions.AvailableForStart.Count > 0) + { + // Iterate over quest requirements in existing qeust file + foreach (var questRequirementToAdd in originalQuest.conditions.AvailableForStart.ToList()) + { + //Exists already + if (quest.Value.conditions.AvailableForStart.Any(x => x._parent == questRequirementToAdd._parent + && x._props.target?.ToString() == questRequirementToAdd._props.target?.ToString())) + { + continue; + } + + quest.Value.conditions.AvailableForStart.Add(questRequirementToAdd); + } + } + } + + // iterate over qeust objects a final time and add hard coded quest requirements if they dont already exist + foreach (var quest in questsToOutputToFile) + { + if (quest.Key == "5c0d4c12d09282029f539173") + { + //fishin gear + } + + var questRequirement = QuestHelper.GetQuestDependancy(quest.Key); + if (questRequirement != null + && !string.IsNullOrEmpty(questRequirement.PreceedingQuest) + && !quest.Value.conditions.AvailableForStart.Any(x => x._parent == "Quest" && x._props.target.ToString() == questRequirement.PreceedingQuest)) + { + quest.Value.conditions.AvailableForStart.Add(new AvailableFor + { + _parent = "Quest", + _props = new AvailableForProps + { + id = "", + index = quest.Value.conditions.AvailableForStart.Count, + parentId = "", + status = new[] { questRequirement.QuestStatus }, + target = questRequirement.PreceedingQuest + } + } + ); + } + } + + JsonWriter.WriteJson(questsToOutputToFile, "output", Directory.GetCurrentDirectory(), "quests"); + } + } +} diff --git a/QuestValidator.Common/Helpers/QuestHelper.cs b/QuestValidator.Common/Helpers/QuestHelper.cs index d93d0d4..97ff2b3 100644 --- a/QuestValidator.Common/Helpers/QuestHelper.cs +++ b/QuestValidator.Common/Helpers/QuestHelper.cs @@ -1,4 +1,5 @@ -using QuestValidator.Models; +using QuestValidator.Common.Models; +using QuestValidator.Models; using QuestValidator.Models.Other; using System.Collections.Generic; using System.IO; @@ -13,128 +14,128 @@ namespace AssortGenerator.Common.Helpers { { "5936d90786f7742b1420ba5b", "Debut" }, { "5936da9e86f7742d65037edf", "Checking"}, -{ "59674cd986f7744ab26e32f2", "Shootout picnic"}, -{ "59674eb386f774539f14813a", "Delivery from the past"}, -{ "5967530a86f77462ba22226b", "Bad rep evidence"}, -{ "59675d6c86f7740a842fc482", "Ice cream cones"}, -{ "59675ea386f77414b32bded2", "Postman Pat"}, -{ "596760e186f7741e11214d58", "Postman Pat, p. 2"}, -{ "5967725e86f774601a446662", "Shaking up teller"}, -{ "5967733e86f774602332fc84", "Shortage"}, -{ "59689ee586f7740d1570bbd5", "Sanitary Standards, p. 1"}, -{ "59689fbd86f7740d137ebfc4", "Operation Aquarius"}, -{ "5968eb3186f7741dde183a4d", "Operation Aquarius, p. 2"}, -{ "5969f90786f77420d2328015", "Painkiller"}, -{ "5969f9e986f7741dde183a50", "Pharmacist"}, -{ "596a0e1686f7741ddf17dbee", "Supply plans"}, -{ "596a101f86f7741ddb481582", "Kind of sabotage" }, -{ "596a1e6c86f7741ddc2d3206", "General wares"}, -{ "596a204686f774576d4c95de", "Sanitary Standards, p. 2"}, -{ "596a218586f77420d232807c", "Car repair"}, -{ "596b36c586f77450d6045ad2", "Supplier"}, -{ "596b43fb86f77457ca186186", "The Extortionist"}, -{ "596b455186f77457cb50eccb", "Stirrup"}, -{ "5979ed3886f77431307dc512", "What’s on the flash drive?"}, -{ "5979eee086f774311955e614", "Golden swag"}, -{ "5979f8bb86f7743ec214c7a6", "Polikhim hobo"}, -{ "5979f9ba86f7740f6c3fe9f2", "Chemical, p.1"}, -{ "597a0b2986f77426d66c0633", "Chemical, p. 2"}, -{ "597a0e5786f77426d66c0636", "Chemical, p. 3"}, -{ "597a0f5686f774273b74f676", "Chemical, p. 4"}, -{ "597a160786f77477531d39d2", "Out of curiosity"}, -{ "597a171586f77405ba6887d3", "Big customer"}, -{ "59c124d686f774189b3c843f", "BP depot"}, -{ "59c50a9e86f7745fef66f4ff", "The Punisher"}, -{ "59c50c8886f7745fed3193bf", "The Punisher. Part 2."}, -{ "59c512ad86f7741f0d09de9b", "The Punisher. Part 3."}, -{ "59c9392986f7742f6923add2", "Trust regain"}, -{ "59c93e8e86f7742a406989c4", "Loyalty buyout"}, -{ "59ca1a6286f774509a270942", "No offence"}, -{ "59ca264786f77445a80ed044", "The Punisher. Part 4."}, -{ "59ca29fb86f77445ab465c87", "The Punisher. Part 5."}, -{ "59ca2eb686f77445a80ed049", "The Punisher. Part 6."}, -{ "59f9da6786f774714230d751", ""}, -{ "5a03153686f77442d90e2171", "Spa Tour. Part 1"}, -{ "5a03173786f77451cb427172", "Spa Tour. Part 2"}, -{ "5a0327ba86f77456b9154236", "Spa Tour. Part 3" }, -{ "5a03296886f774569778596a", "Spa Tour. Part 4"}, -{ "5a0449d586f77474e66227b7", "Spa Tour. Part 5"}, -{ "5a27b75b86f7742e97191958", "Fishing Gear"}, -{ "5a27b7a786f774579c3eb376", "Tigr Safari"}, -{ "5a27b7d686f77460d847e6a6", " Scrap Metal"}, -{ "5a27b80086f774429a5d7e20", "Eagle Eye"}, -{ "5a27b87686f77460de0252a8", "Humanitarian Supplies"}, -{ "5a27b9de86f77464e5044585", "The Cult. Part 1"}, -{ "5a27ba1c86f77461ea5a3c56", "The Cult. Part 2"}, -{ "5a27ba9586f7741b543d8e85", "Spa Tour. Part 6"}, -{ "5a27bafb86f7741c73584017", "Spa Tour. Part 7"}, -{ "5a27bb1e86f7741f27621b7e", "Cargo X. Part 1"}, -{ "5a27bb3d86f77411ea361a21", "Cargo X. Part 2"}, -{ "5a27bb5986f7741dfb660900", "Cargo X. Part 3"}, -{ "5a27bb8386f7741c770d2d0a", "Wet Job. Part 1"}, -{ "5a27bbf886f774333a418eeb", "Wet Job. Part 2"}, -{ "5a27bc1586f7741f6d40fa2f", "Wet Job. Part 3"}, -{ "5a27bc3686f7741c73584026", "Wet Job. Part 4"}, -{ "5a27bc6986f7741c7358402b", "Wet Job. Part 5"}, -{ "5a27bc8586f7741b543d8ea4", "Wet Job. Part 6"}, -{ "5a27c99a86f7747d2c6bdd8e", "Friend from the West. Part 1"}, -{ "5a27d2af86f7744e1115b323", "Friend from the West. Part 2"}, -{ "5a5642ce86f77445c63c3419", "Hippocratic Vow"}, -{ "5a68661a86f774500f48afb0", "Health Care Privacy. Part 1"}, -{ "5a68663e86f774501078f78a", "Health Care Privacy. Part 2"}, -{ "5a68665c86f774255929b4c7", "Health Care Privacy. Part 3"}, -{ "5a68667486f7742607157d28", "Health Care Privacy. Part 4"}, -{ "5a68669a86f774255929b4d4", "Health Care Privacy. Part 5"}, -{ "5ac23c6186f7741247042bad", "Gunsmith. Part 1"}, -{ "5ac2426c86f774138762edfe", "Gunsmith. Part 2"}, -{ "5ac2428686f77412450b42bf", "Gunsmith. Part 3"}, -{ "5ac242ab86f77412464f68b4", "Gunsmith. Part 5"}, -{ "5ac244c486f77413e12cf945", "Gunsmith. Part 6"}, -{ "5ac244eb86f7741356335af1", "Gunsmith. Part 4"}, -{ "5ac345dc86f774288030817f", "Farming. Part 1" }, -{ "5ac3460c86f7742880308185", "Farming. Part 2" }, -{ "5ac3462b86f7741d6118b983", "Farming. Part 3" }, -{ "5ac3464c86f7741d651d6877", "Farming. Part 4" }, -{ "5ac3467986f7741d6224abc2", "Signal. Part 1" }, -{ "5ac346a886f7744e1b083d67", "Signal. Part 2" }, -{ "5ac346cf86f7741d63233a02", "Signal. Part 3" }, -{ "5ac346e886f7741d6118b99b", "Signal. Part 4" }, -{ "5ac3475486f7741d6224abd3", "Bad habit" }, -{ "5ac3477486f7741d651d6885", "Scout" }, -{ "5ac3479086f7742880308199", "Insider" }, -{ "5ae3267986f7742a413592fe", "Gunsmith. Part 7" }, -{ "5ae3270f86f77445ba41d4dd", "Gunsmith. Part 8" }, -{ "5ae3277186f7745973054106", "Gunsmith. Part 9" }, -{ "5ae327c886f7745c7b3f2f3f", "Gunsmith. Part 10" }, -{ "5ae3280386f7742a41359364", "Gunsmith. Part 11" }, -{ "5ae448a386f7744d3730fff0", "Only business" }, -{ "5ae448bf86f7744d733e55ee", "Make ULTRA Great Again" }, -{ "5ae448e586f7744dcf0c2a67", "Big sale" }, -{ "5ae448f286f77448d73c0131", "The Blood of War" }, -{ "5ae4490786f7744ca822adcc", "Dressed to kill" }, -{ "5ae4493486f7744efa289417", "Database. Part 1" }, -{ "5ae4493d86f7744b8e15aa8f", "Database. Part 2" }, -{ "5ae4495086f77443c122bc40", "Sew it good. Part 1" }, -{ "5ae4495c86f7744e87761355", "Sew it good. Part 2" }, -{ "5ae4496986f774459e77beb6", "Sew it good. Part 3" }, -{ "5ae4497b86f7744cf402ed00", "Sew it good. Part 4" }, -{ "5ae4498786f7744bde357695", "The key to success" }, -{ "5ae4499a86f77449783815db", "Charisma brings success" }, -{ "5ae449a586f7744bde357696", "No fuss needed" }, -{ "5ae449b386f77446d8741719", "Gratitude" }, -{ "5ae449c386f7744bde357697", "Sales Night" }, -{ "5ae449d986f774453a54a7e1", "Supervisor" }, -{ "5b47749f86f7746c5d6a5fd4", "Gunsmith. Part 12" }, -{ "5b47799d86f7746c5d6a5fd8", "Gunsmith. Part 13" }, -{ "5b477b6f86f7747290681823", "Gunsmith. Part 14" }, -{ "5b477f7686f7744d1b23c4d2", "Gunsmith. Part 15" }, -{ "5b47825886f77468074618d3", "Gunsmith. Part 16" }, -{ "5b47876e86f7744d1c353205", "The Blood of War Part 2" }, -{ "5b47891f86f7744d1b23c571", "Living high is not a crime" }, -{ "5b478b1886f7744d1b23c57d", "Hot delivery" }, -{ "5b478d0f86f7744d190d91b5", "Minibus" }, -{ "5b478eca86f7744642012254", "\"Vitamins\" p.1" }, -{ "5b478ff486f7744d184ecbbf", "\"Vitamins\" p. 2" }, + { "59674cd986f7744ab26e32f2", "Shootout picnic"}, + { "59674eb386f774539f14813a", "Delivery from the past"}, + { "5967530a86f77462ba22226b", "Bad rep evidence"}, + { "59675d6c86f7740a842fc482", "Ice cream cones"}, + { "59675ea386f77414b32bded2", "Postman Pat"}, + { "596760e186f7741e11214d58", "Postman Pat, p. 2"}, + { "5967725e86f774601a446662", "Shaking up teller"}, + { "5967733e86f774602332fc84", "Shortage"}, + { "59689ee586f7740d1570bbd5", "Sanitary Standards, p. 1"}, + { "59689fbd86f7740d137ebfc4", "Operation Aquarius"}, + { "5968eb3186f7741dde183a4d", "Operation Aquarius, p. 2"}, + { "5969f90786f77420d2328015", "Painkiller"}, + { "5969f9e986f7741dde183a50", "Pharmacist"}, + { "596a0e1686f7741ddf17dbee", "Supply plans"}, + { "596a101f86f7741ddb481582", "Kind of sabotage" }, + { "596a1e6c86f7741ddc2d3206", "General wares"}, + { "596a204686f774576d4c95de", "Sanitary Standards, p. 2"}, + { "596a218586f77420d232807c", "Car repair"}, + { "596b36c586f77450d6045ad2", "Supplier"}, + { "596b43fb86f77457ca186186", "The Extortionist"}, + { "596b455186f77457cb50eccb", "Stirrup"}, + { "5979ed3886f77431307dc512", "What’s on the flash drive?"}, + { "5979eee086f774311955e614", "Golden swag"}, + { "5979f8bb86f7743ec214c7a6", "Polikhim hobo"}, + { "5979f9ba86f7740f6c3fe9f2", "Chemical, p.1"}, + { "597a0b2986f77426d66c0633", "Chemical, p. 2"}, + { "597a0e5786f77426d66c0636", "Chemical, p. 3"}, + { "597a0f5686f774273b74f676", "Chemical, p. 4"}, + { "597a160786f77477531d39d2", "Out of curiosity"}, + { "597a171586f77405ba6887d3", "Big customer"}, + { "59c124d686f774189b3c843f", "BP depot"}, + { "59c50a9e86f7745fef66f4ff", "The Punisher"}, + { "59c50c8886f7745fed3193bf", "The Punisher. Part 2."}, + { "59c512ad86f7741f0d09de9b", "The Punisher. Part 3."}, + { "59c9392986f7742f6923add2", "Trust regain"}, + { "59c93e8e86f7742a406989c4", "Loyalty buyout"}, + { "59ca1a6286f774509a270942", "No offence"}, + { "59ca264786f77445a80ed044", "The Punisher. Part 4."}, + { "59ca29fb86f77445ab465c87", "The Punisher. Part 5."}, + { "59ca2eb686f77445a80ed049", "The Punisher. Part 6."}, + { "59f9da6786f774714230d751", ""}, + { "5a03153686f77442d90e2171", "Spa Tour. Part 1"}, + { "5a03173786f77451cb427172", "Spa Tour. Part 2"}, + { "5a0327ba86f77456b9154236", "Spa Tour. Part 3" }, + { "5a03296886f774569778596a", "Spa Tour. Part 4"}, + { "5a0449d586f77474e66227b7", "Spa Tour. Part 5"}, + { "5a27b75b86f7742e97191958", "Fishing Gear"}, + { "5a27b7a786f774579c3eb376", "Tigr Safari"}, + { "5a27b7d686f77460d847e6a6", " Scrap Metal"}, + { "5a27b80086f774429a5d7e20", "Eagle Eye"}, + { "5a27b87686f77460de0252a8", "Humanitarian Supplies"}, + { "5a27b9de86f77464e5044585", "The Cult. Part 1"}, + { "5a27ba1c86f77461ea5a3c56", "The Cult. Part 2"}, + { "5a27ba9586f7741b543d8e85", "Spa Tour. Part 6"}, + { "5a27bafb86f7741c73584017", "Spa Tour. Part 7"}, + { "5a27bb1e86f7741f27621b7e", "Cargo X. Part 1"}, + { "5a27bb3d86f77411ea361a21", "Cargo X. Part 2"}, + { "5a27bb5986f7741dfb660900", "Cargo X. Part 3"}, + { "5a27bb8386f7741c770d2d0a", "Wet Job. Part 1"}, + { "5a27bbf886f774333a418eeb", "Wet Job. Part 2"}, + { "5a27bc1586f7741f6d40fa2f", "Wet Job. Part 3"}, + { "5a27bc3686f7741c73584026", "Wet Job. Part 4"}, + { "5a27bc6986f7741c7358402b", "Wet Job. Part 5"}, + { "5a27bc8586f7741b543d8ea4", "Wet Job. Part 6"}, + { "5a27c99a86f7747d2c6bdd8e", "Friend from the West. Part 1"}, + { "5a27d2af86f7744e1115b323", "Friend from the West. Part 2"}, + { "5a5642ce86f77445c63c3419", "Hippocratic Vow"}, + { "5a68661a86f774500f48afb0", "Health Care Privacy. Part 1"}, + { "5a68663e86f774501078f78a", "Health Care Privacy. Part 2"}, + { "5a68665c86f774255929b4c7", "Health Care Privacy. Part 3"}, + { "5a68667486f7742607157d28", "Health Care Privacy. Part 4"}, + { "5a68669a86f774255929b4d4", "Health Care Privacy. Part 5"}, + { "5ac23c6186f7741247042bad", "Gunsmith. Part 1"}, + { "5ac2426c86f774138762edfe", "Gunsmith. Part 2"}, + { "5ac2428686f77412450b42bf", "Gunsmith. Part 3"}, + { "5ac242ab86f77412464f68b4", "Gunsmith. Part 5"}, + { "5ac244c486f77413e12cf945", "Gunsmith. Part 6"}, + { "5ac244eb86f7741356335af1", "Gunsmith. Part 4"}, + { "5ac345dc86f774288030817f", "Farming. Part 1" }, + { "5ac3460c86f7742880308185", "Farming. Part 2" }, + { "5ac3462b86f7741d6118b983", "Farming. Part 3" }, + { "5ac3464c86f7741d651d6877", "Farming. Part 4" }, + { "5ac3467986f7741d6224abc2", "Signal. Part 1" }, + { "5ac346a886f7744e1b083d67", "Signal. Part 2" }, + { "5ac346cf86f7741d63233a02", "Signal. Part 3" }, + { "5ac346e886f7741d6118b99b", "Signal. Part 4" }, + { "5ac3475486f7741d6224abd3", "Bad habit" }, + { "5ac3477486f7741d651d6885", "Scout" }, + { "5ac3479086f7742880308199", "Insider" }, + { "5ae3267986f7742a413592fe", "Gunsmith. Part 7" }, + { "5ae3270f86f77445ba41d4dd", "Gunsmith. Part 8" }, + { "5ae3277186f7745973054106", "Gunsmith. Part 9" }, + { "5ae327c886f7745c7b3f2f3f", "Gunsmith. Part 10" }, + { "5ae3280386f7742a41359364", "Gunsmith. Part 11" }, + { "5ae448a386f7744d3730fff0", "Only business" }, + { "5ae448bf86f7744d733e55ee", "Make ULTRA Great Again" }, + { "5ae448e586f7744dcf0c2a67", "Big sale" }, + { "5ae448f286f77448d73c0131", "The Blood of War" }, + { "5ae4490786f7744ca822adcc", "Dressed to kill" }, + { "5ae4493486f7744efa289417", "Database. Part 1" }, + { "5ae4493d86f7744b8e15aa8f", "Database. Part 2" }, + { "5ae4495086f77443c122bc40", "Sew it good. Part 1" }, + { "5ae4495c86f7744e87761355", "Sew it good. Part 2" }, + { "5ae4496986f774459e77beb6", "Sew it good. Part 3" }, + { "5ae4497b86f7744cf402ed00", "Sew it good. Part 4" }, + { "5ae4498786f7744bde357695", "The key to success" }, + { "5ae4499a86f77449783815db", "Charisma brings success" }, + { "5ae449a586f7744bde357696", "No fuss needed" }, + { "5ae449b386f77446d8741719", "Gratitude" }, + { "5ae449c386f7744bde357697", "Sales Night" }, + { "5ae449d986f774453a54a7e1", "Supervisor" }, + { "5b47749f86f7746c5d6a5fd4", "Gunsmith. Part 12" }, + { "5b47799d86f7746c5d6a5fd8", "Gunsmith. Part 13" }, + { "5b477b6f86f7747290681823", "Gunsmith. Part 14" }, + { "5b477f7686f7744d1b23c4d2", "Gunsmith. Part 15" }, + { "5b47825886f77468074618d3", "Gunsmith. Part 16" }, + { "5b47876e86f7744d1c353205", "The Blood of War Part 2" }, + { "5b47891f86f7744d1b23c571", "Living high is not a crime" }, + { "5b478b1886f7744d1b23c57d", "Hot delivery" }, + { "5b478d0f86f7744d190d91b5", "Minibus" }, + { "5b478eca86f7744642012254", "\"Vitamins\" p.1" }, + { "5b478ff486f7744d184ecbbf", "\"Vitamins\" p. 2" }, { "5b47926a86f7747ccc057c15", "Informed means armed" }, { "5b4794cb86f774598100d5d4", "Lend lease" }, { "5b4795fb86f7745876267770", "Chumming" }, @@ -242,6 +243,85 @@ namespace AssortGenerator.Common.Helpers { "60e71c9ad54b755a3b53eb66", "Mutual Interest" } }; + // Quest to lookup is key, previous quest is value + private static readonly Dictionary questWithPreceedingQuest = new Dictionary + { + //{ "5936d90786f7742b1420ba5b", "" }, // Debut + { "5936da9e86f7742d65037edf", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5936d90786f7742b1420ba5b"}}, // checking, debut + { "59674cd986f7744ab26e32f2", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5936da9e86f7742d65037edf"}}, //Shootout picnic, checking + { "59674eb386f774539f14813a", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5936da9e86f7742d65037edf"}}, //Delivery from the past, checking + { "5967530a86f77462ba22226b", new QuestRequirement{QuestStatus = 4, PreceedingQuest="59c124d686f774189b3c843f"}}, // Bad rep evidence, bp depot + { "59675d6c86f7740a842fc482", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5967530a86f77462ba22226b"}}, // Ice cream cones, Bad rep evidence + { "59675ea386f77414b32bded2", new QuestRequirement{QuestStatus = 4, PreceedingQuest="59675d6c86f7740a842fc482"}}, // Postman Pat pt 1, ice cream cones + { "596760e186f7741e11214d58", new QuestRequirement{QuestStatus = 4, PreceedingQuest="59675ea386f77414b32bded2" } }, // Postman Pat, p. 2 + { "5967725e86f774601a446662", new QuestRequirement{QuestStatus = 4, PreceedingQuest="59675ea386f77414b32bded2"} }, // Shaking up teller, postman part pt 1 + { "5967733e86f774602332fc84", new QuestRequirement{QuestStatus = 4, PreceedingQuest="" } }, // Shortage + { "59689ee586f7740d1570bbd5", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5967733e86f774602332fc84"}}, //Sanitary Standards, pt1, Shortage + { "59689fbd86f7740d137ebfc4", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5967733e86f774602332fc84"}}, // Operation Aquarius pt1, Shortage + { "5968eb3186f7741dde183a4d", new QuestRequirement{QuestStatus = 4, PreceedingQuest="59689fbd86f7740d137ebfc4"}}, // Operation Aquarius, pt2, Operation Aquarius pt1 + { "5969f90786f77420d2328015", new QuestRequirement{QuestStatus = 4, PreceedingQuest="596a204686f774576d4c95de"}}, // Painkiller, sanitary standards pt2 + { "5969f9e986f7741dde183a50", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5969f90786f77420d2328015"}}, // Pharmacist, Painkiller + { "596a0e1686f7741ddf17dbee", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5969f9e986f7741dde183a50"}}, // Supply plans, Pharmacist + { "596a101f86f7741ddb481582", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5969f9e986f7741dde183a50"}}, //Kind of sabotage, Pharmacist + { "596a1e6c86f7741ddc2d3206", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5969f9e986f7741dde183a50"}}, // General wares, Pharmacist + { "596a204686f774576d4c95de", new QuestRequirement{QuestStatus = 4, PreceedingQuest="59689ee586f7740d1570bbd5"}}, // Sanitary Standards, pt2 + { "596a218586f77420d232807c", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5969f9e986f7741dde183a50"} } , // Car repair + { "596b36c586f77450d6045ad2", new QuestRequirement{QuestStatus = 4, PreceedingQuest=""} }, // Supplier + { "596b43fb86f77457ca186186", new QuestRequirement{QuestStatus = 4, PreceedingQuest="596b36c586f77450d6045ad2"} }, // The Extortionist, Supplier + { "596b455186f77457cb50eccb", new QuestRequirement{QuestStatus = 4, PreceedingQuest="596b43fb86f77457ca186186"}}, // Stirrup, The Extortionist + { "5979ed3886f77431307dc512", new QuestRequirement{QuestStatus = 4, PreceedingQuest="596b43fb86f77457ca186186"}}, // What’s on the flash drive?, The Extortionist + { "5979eee086f774311955e614", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5979ed3886f77431307dc512"} }, // Golden swag, What’s on the flash drive? + { "5979f8bb86f7743ec214c7a6", new QuestRequirement{QuestStatus = 2, PreceedingQuest="5979f9ba86f7740f6c3fe9f2"} }, // Polikhim hobo + { "5979f9ba86f7740f6c3fe9f2", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5979eee086f774311955e614"}}, // Chemical pt1, Golden swag + { "597a0b2986f77426d66c0633", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5979f9ba86f7740f6c3fe9f2"}}, // Chemical pt2, Chemical, p.1 + { "597a0e5786f77426d66c0636", new QuestRequirement{QuestStatus = 4, PreceedingQuest="597a0b2986f77426d66c0633"}}, // Chemical pt3, Chemical, p. 2 + { "597a0f5686f774273b74f676", new QuestRequirement{QuestStatus = 4, PreceedingQuest="597a0e5786f77426d66c0636"}}, // Chemical pt4, Chemical, p. 3 + { "597a160786f77477531d39d2", new QuestRequirement{QuestStatus = 4, PreceedingQuest="597a0e5786f77426d66c0636"}}, // Out of curiosity, Chemical, p. 3 + { "597a171586f77405ba6887d3", new QuestRequirement{QuestStatus = 4, PreceedingQuest="597a0e5786f77426d66c0636"}}, // Big customer, Chemical, p. 3 + { "59c124d686f774189b3c843f", new QuestRequirement{QuestStatus = 4, PreceedingQuest="59674eb386f774539f14813a"}}, // bp depot, delivery from the past + { "59c50a9e86f7745fef66f4ff", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5967725e86f774601a446662"}}, // The Punisher part 1, shaking up teller + { "59c50c8886f7745fed3193bf", new QuestRequirement{QuestStatus = 4, PreceedingQuest="59c50a9e86f7745fef66f4ff"}}, // The Punisher. Part 2 + { "59c512ad86f7741f0d09de9b", new QuestRequirement{QuestStatus = 4, PreceedingQuest="59c50c8886f7745fed3193bf"}}, // The Punisher. Part 3, + { "59c9392986f7742f6923add2", new QuestRequirement{QuestStatus = 4, PreceedingQuest="597a0f5686f774273b74f676"}}, // Trust regain, chemical p4 + { "59c93e8e86f7742a406989c4", new QuestRequirement{QuestStatus = 4, PreceedingQuest="597a0e5786f77426d66c0636"}}, // Loyalty buyout, Chemical, pt3 + { "59ca1a6286f774509a270942", new QuestRequirement{QuestStatus = 4, PreceedingQuest="597a0f5686f774273b74f676"}}, // No offence, Chemical pt4 + { "59ca264786f77445a80ed044", new QuestRequirement{QuestStatus = 4, PreceedingQuest="59c512ad86f7741f0d09de9b"}}, // The Punisher. Part 4, The Punisher. Part 3 + { "59ca29fb86f77445ab465c87", new QuestRequirement{QuestStatus = 4, PreceedingQuest="59ca264786f77445a80ed044"}}, // The Punisher. Part 5, The Punisher. Part 4 + { "59ca2eb686f77445a80ed049", new QuestRequirement{QuestStatus = 4, PreceedingQuest="59ca29fb86f77445ab465c87"}}, // The Punisher. Part 6, The Punisher. Part 5 + { "59f9da6786f774714230d751", new QuestRequirement{QuestStatus = 4, PreceedingQuest=""} }, // no idea + { "5a03153686f77442d90e2171", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27b87686f77460de0252a8"}}, // Spa Tour. Part 1, Humanitarian Supplies + { "5a03173786f77451cb427172", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a03153686f77442d90e2171"}}, // Spa Tour. Part 2, Spa Tour. Part 1 + { "5a0327ba86f77456b9154236", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a03173786f77451cb427172"}},// Spa Tour. Part 3, Spa Tour. Part 2 + { "5a03296886f774569778596a", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a0327ba86f77456b9154236"}}, // Spa Tour. Part 4, Spa Tour. Part 3 + { "5a0449d586f77474e66227b7", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a03296886f774569778596a"}}, // Spa Tour. Part 5, Spa Tour. Part 4 + { "5a27b75b86f7742e97191958", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27d2af86f7744e1115b323"}}, // Fishing Gear, Friend from the west part 2 + { "5a27b7a786f774579c3eb376", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27b75b86f7742e97191958"}}, // Tigr Safari, Fishing Gear + { "5a27b7d686f77460d847e6a6", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27b7a786f774579c3eb376"}}, // Scrap Metal, Tigr Safari + { "5a27b80086f774429a5d7e20", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27b7d686f77460d847e6a6"}}, // Eagle Eye, Scrap Metal + { "5a27b87686f77460de0252a8", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27b80086f774429a5d7e20"}}, // Humanitarian Supplies, Eagle Eye + { "5a27b9de86f77464e5044585", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27b87686f77460de0252a8"}}, // The Cult. Part 1, Humanitarian Supplies + { "5a27ba1c86f77461ea5a3c56", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27b9de86f77464e5044585"}}, // The Cult. Part 2, The Cult. Part 1 + { "5a27ba9586f7741b543d8e85", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a0449d586f77474e66227b7"}}, // Spa Tour. Part 6, Spa Tour. Part 5 + { "5a27bafb86f7741c73584017", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27ba9586f7741b543d8e85"}}, // Spa Tour. Part 7, Spa Tour. Part 6 + { "5a27bb1e86f7741f27621b7e", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27bafb86f7741c73584017"}}, // Cargo X. Part 1, Spa Tour. Part 7 + { "5a27bb3d86f77411ea361a21", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27bb1e86f7741f27621b7e"}}, // Cargo X. Part 2, Cargo X. Part 1 + { "5a27bb5986f7741dfb660900", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27bb3d86f77411ea361a21"}}, // Cargo X. Part 3, Cargo X. Part 2 + { "5a27bb8386f7741c770d2d0a", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27bafb86f7741c73584017"}}, // Wet Job. Part 1, Spa Tour. Part 7 + { "5a27bbf886f774333a418eeb", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27bb8386f7741c770d2d0a"}}, // Wet Job. Part 2, Wet Job. Part 1 + { "5a27bc1586f7741f6d40fa2f", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27bbf886f774333a418eeb"}}, // Wet Job. Part 3, Wet Job. Part 2 + { "5a27bc3686f7741c73584026", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27bc1586f7741f6d40fa2f"}}, // Wet Job. Part 4, Wet Job. Part 3 + { "5a27bc6986f7741c7358402b", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27bc3686f7741c73584026"}}, // Wet Job. Part 5, Wet Job. Part 4 + { "5a27bc8586f7741b543d8ea4", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27bc6986f7741c7358402b"}}, // Wet Job. Part 6, Wet Job. Part 5 + { "5a27c99a86f7747d2c6bdd8e", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5979eee086f774311955e614"} }, // Friend from the West. Part 1, golden swag + { "5a27d2af86f7744e1115b323", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a27c99a86f7747d2c6bdd8e"} }, // Friend from the West. Part 2, Friend from the West. Part 1 + { "5a5642ce86f77445c63c3419", new QuestRequirement{QuestStatus = 4, PreceedingQuest=""} }, // Hippocratic Oath, + { "5a68661a86f774500f48afb0", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5969f9e986f7741dde183a50"}}, // Health Care Privacy. Part 1, + { "5a68663e86f774501078f78a", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a68661a86f774500f48afb0"}}, // Health Care Privacy. Part 2, Health Care Privacy. Part 1 + { "5a68665c86f774255929b4c7", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a68663e86f774501078f78a"}}, // Health Care Privacy. Part 3, Health Care Privacy. Part 2 + { "5a68667486f7742607157d28", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a68665c86f774255929b4c7"}}, // Health Care Privacy. Part 4, Health Care Privacy. Part 3 + { "5a68669a86f774255929b4d4", new QuestRequirement{QuestStatus = 4, PreceedingQuest="5a68667486f7742607157d28"} }, // Health Care Privacy. Part 5, Health Care Privacy. Part 4 + }; + private static QuestRoot _liveQuestData; private static Dictionary _questData; private static List _assortUnlocks; @@ -297,8 +377,6 @@ namespace AssortGenerator.Common.Helpers _assortUnlocks = new List(); foreach (var quest in GetQuestData()) { - - foreach (var reward in quest.Value.rewards.Success) { if (string.Equals(reward.type, "assortmentunlock", System.StringComparison.OrdinalIgnoreCase)) @@ -323,5 +401,15 @@ namespace AssortGenerator.Common.Helpers return _assortUnlocks; } + + public static QuestRequirement GetQuestDependancy(string questId) + { + if (questWithPreceedingQuest.ContainsKey(questId)) + { + return questWithPreceedingQuest[questId]; + } + + return null; + } } } diff --git a/QuestValidator.Common/JsonWriter.cs b/QuestValidator.Common/JsonWriter.cs new file mode 100644 index 0000000..1ffa70f --- /dev/null +++ b/QuestValidator.Common/JsonWriter.cs @@ -0,0 +1,30 @@ +using QuestValidator.Helpers; +using System; +using System.IO; +using System.Text.Encodings.Web; +using System.Text.Json; +using System.Text.Unicode; + +namespace QuestValidator.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); + + Console.WriteLine($"Writing json file to {outputPath}"); + + var options = new JsonSerializerOptions + { + WriteIndented = true, + IgnoreNullValues = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + + }; + var json = JsonSerializer.Serialize(itemToSerialise, options); + File.WriteAllText($"{outputPath}\\{fileName}.json", json); + } + } +} diff --git a/QuestValidator.Common/Models/QuestRequirement.cs b/QuestValidator.Common/Models/QuestRequirement.cs new file mode 100644 index 0000000..c1f1f0c --- /dev/null +++ b/QuestValidator.Common/Models/QuestRequirement.cs @@ -0,0 +1,11 @@ +namespace QuestValidator.Common.Models +{ + public class QuestRequirement + { + /// + /// // success = 4, fail = 5, started = 2 + /// + public int QuestStatus { get; set; } + public string PreceedingQuest { get; set; } + } +} diff --git a/QuestValidator.Models/Input/Quest.cs b/QuestValidator.Models/Input/Quest.cs index 828e1f7..2890e68 100644 --- a/QuestValidator.Models/Input/Quest.cs +++ b/QuestValidator.Models/Input/Quest.cs @@ -11,6 +11,7 @@ namespace QuestValidator.Models public class Quest { + public string QuestName { get; set; } public string _id { get; set; } public bool canShowNotificationsInGame { get; set; } public Conditions conditions { get; set; } @@ -32,7 +33,7 @@ namespace QuestValidator.Models public ConditionProps _props { get; set; } public List AvailableForFinish { get; set; } public List AvailableForStart { get; set; } - //public List Fail { get; set; } + public List Fail { get; set; } } public class ConditionProps @@ -54,7 +55,6 @@ namespace QuestValidator.Models public class Counter { - //public List conditions { get; set; } public string id { get; set; } } @@ -66,16 +66,46 @@ namespace QuestValidator.Models public class AvailableForProps { - public int dogtagLevel { get; set; } + public object counter { get; set;} + public int? dogtagLevel { get; set; } public string id { get; set; } public int? index { get; set; } public int? maxDurability { get; set; } public int? minDurability { get; set; } public string parentId { get; set; } - public bool resetOnSessionEnd { get; set; } + public bool? resetOnSessionEnd { get; set; } + public bool? onlyFoundInRaid { get; set; } + public bool? oneSessionOnly { get; set; } + public int? plantTime { get; set; } + public string zoneId { get; set; } public object target { get; set; } - //public int value { get; set; } + public string type { get;set;} + public object status { get; set;} + public bool? unknown { get; set; } + public bool? doNotResetIfCounterCompleted { get; set; } + public object value { get; set; } + public int? availableAfter { get; set; } + public string compareMethod { get;set;} public List visibilityConditions { get; set; } + public SkillCondition baseAccuracy { get;set;} + public SkillCondition durability { get; set; } + public SkillCondition effectiveDistance { get; set; } + public SkillCondition emptyTacticalSlot { get; set; } + public SkillCondition ergonomics { get; set; } + public SkillCondition height { get; set; } + public SkillCondition magazineCapacity { get; set; } + public SkillCondition muzzleVelocity { get; set; } + public SkillCondition recoil { get; set; } + public SkillCondition weight { get; set; } + public SkillCondition width { get; set; } + public object containsItems { get; set; } + public object hasItemFromCategory { get; set; } + } + + public class SkillCondition + { + public string compareMethod { get; set; } + public object value { get; set; } } public class Rewards @@ -92,6 +122,7 @@ namespace QuestValidator.Models public string type { get; set; } public int index { get; set; } public string target { get; set; } + public bool? unknown { get; set; } public List items { get; set; } public int? loyaltyLevel { get; set; } public string traderId { get; set; } @@ -108,6 +139,19 @@ namespace QuestValidator.Models public class QuestRewardUpd { - public int StackObjectsCount { get; set; } + public int? StackObjectsCount { get; set; } + public FireModeReward FireMode { get; set; } + public FoldeableReward Foldable { get; set; } } + + public class FireModeReward + { + public string FireMode { get; set; } + } + + public class FoldeableReward + { + public bool? Folded { get; set; } + } + } diff --git a/QuestValidator.sln b/QuestValidator.sln index 746a3fc..74305ac 100644 --- a/QuestValidator.sln +++ b/QuestValidator.sln @@ -3,11 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31624.102 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestValidator", "QuestValidator\QuestValidator.csproj", "{52D43AB5-26C2-4C82-82F2-F63ED911E7F4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QuestValidator", "QuestValidator\QuestValidator.csproj", "{52D43AB5-26C2-4C82-82F2-F63ED911E7F4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestValidator.Common", "QuestValidator.Common\QuestValidator.Common.csproj", "{3F753E26-069F-43EB-979C-B89EE07AB658}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QuestValidator.Common", "QuestValidator.Common\QuestValidator.Common.csproj", "{3F753E26-069F-43EB-979C-B89EE07AB658}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestValidator.Models", "QuestValidator.Models\QuestValidator.Models.csproj", "{5897813D-96DB-42E2-A436-0CF4472F9C40}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QuestValidator.Models", "QuestValidator.Models\QuestValidator.Models.csproj", "{5897813D-96DB-42E2-A436-0CF4472F9C40}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GenerateQuestFile", "GenerateQuestFile\GenerateQuestFile.csproj", "{ED2CDA5D-F4BC-4655-808A-F46B722437CD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -27,6 +29,10 @@ Global {5897813D-96DB-42E2-A436-0CF4472F9C40}.Debug|Any CPU.Build.0 = Debug|Any CPU {5897813D-96DB-42E2-A436-0CF4472F9C40}.Release|Any CPU.ActiveCfg = Release|Any CPU {5897813D-96DB-42E2-A436-0CF4472F9C40}.Release|Any CPU.Build.0 = Release|Any CPU + {ED2CDA5D-F4BC-4655-808A-F46B722437CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ED2CDA5D-F4BC-4655-808A-F46B722437CD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ED2CDA5D-F4BC-4655-808A-F46B722437CD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ED2CDA5D-F4BC-4655-808A-F46B722437CD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/QuestValidator/Program.cs b/QuestValidator/Program.cs index 0a377df..ea88849 100644 --- a/QuestValidator/Program.cs +++ b/QuestValidator/Program.cs @@ -26,6 +26,8 @@ namespace QuestValidator return; } + ListMissingQuestsInLive(questData, liveQuestData); + CheckForMissingQuestsInAkiFile(liveQuestData, questData); foreach (var item in questData) @@ -44,10 +46,11 @@ namespace QuestValidator CheckRootItemValues(quest, relatedLiveQuest); CheckSuccessRewardItems(quest, relatedLiveQuest); - CheckStartedRewardItems(quest, relatedLiveQuest); CheckAvailableForFinishConditionItems(quest, relatedLiveQuest); + CheckAvailableForStartConditionItems(quest, relatedLiveQuest); + CheckFailConditionItems(quest, relatedLiveQuest); LoggingHelpers.LogInfo(""); LoggingHelpers.LogInfo("-----"); @@ -55,6 +58,61 @@ namespace QuestValidator } } + private static void ListMissingQuestsInLive(Dictionary questData, QuestRoot liveQuestData) + { + var missingQuests = new List(); + foreach (var quest in questData.Values) + { + var liveQuest = liveQuestData.data.FirstOrDefault(x=>x._id == quest._id); + + if (liveQuest == null) + { + missingQuests.Add(quest); + LoggingHelpers.LogError($"ERROR Quest {quest._id} {QuestHelper.GetQuestNameById(quest._id)} missing in live"); + } + } + } + + private static void CheckFailConditionItems(Quest quest, Quest relatedLiveQuest) + { + var liveFailConditions = relatedLiveQuest.conditions.Fail; + + // Check count + CheckValuesMatch(quest.conditions.Fail.Count, liveFailConditions.Count, "FailCondition mismatch"); + + foreach (var failItem in quest.conditions.Fail) + { + var liveFailItem = liveFailConditions.FirstOrDefault(x => x._props.id == failItem._props.id); + if (!ItemExists(liveFailItem, "condition fail item", failItem._props.index.Value)) + { + continue; + } + + // Check parentId + CheckValuesMatch(failItem._props.parentId, liveFailItem._props.parentId, "AvailableForFinish parentId mismatch", failItem._props.id); + } + } + + private static void CheckAvailableForStartConditionItems(Quest quest, Quest relatedLiveQuest) + { + var liveStartConditions = relatedLiveQuest.conditions.AvailableForStart; + + // Check count + CheckValuesMatch(quest.conditions.AvailableForStart.Count, liveStartConditions.Count, "AvailableForStartCondition mismtch"); + + foreach (var availableForStartItem in quest.conditions.AvailableForStart) + { + var liveStartItem = liveStartConditions.FirstOrDefault(x=>x._props.id == availableForStartItem._props.id); + if (!ItemExists(liveStartItem, "AvailableForStart item", availableForStartItem._props.index.Value)) + { + continue; + } + + // Check parentId + CheckValuesMatch(availableForStartItem._props.parentId, liveStartItem._props.parentId, "AvailableForFinish parentId mismatch", availableForStartItem._props.id); + } + } + private static void LogQuestDetails(Quest quest) { var questName = QuestHelper.GetQuestNameById(quest._id); @@ -71,7 +129,7 @@ namespace QuestValidator //Check image id contains quest id if (!quest.image.Contains(quest._id)) { - LoggingHelpers.LogWarning($"WARNING Quest image path does not contain quest id"); + LoggingHelpers.LogInfo($"INFO Quest image path does not contain quest id"); } // Check started reward count matches @@ -126,7 +184,7 @@ namespace QuestValidator // Check item stack count if (questSuccessRewardItem.items[0]?.upd != null && relatedLiveRewardItem.items[0]?.upd != null) { - CheckValuesMatch(questSuccessRewardItem.items[0].upd.StackObjectsCount, relatedLiveRewardItem.items[0].upd.StackObjectsCount, "mismatch for success item StackObjectsCount", questSuccessRewardItem.items[0]._id); + CheckValuesMatch(questSuccessRewardItem.items[0].upd.StackObjectsCount.Value, relatedLiveRewardItem.items[0].upd.StackObjectsCount.Value, "mismatch for success item StackObjectsCount", questSuccessRewardItem.items[0]._id); } // check sub items match @@ -327,7 +385,7 @@ namespace QuestValidator // Check item stack count if (questStartedRewardItem.items[0] != null && questStartedRewardItem.items[0].upd != null) { - CheckValuesMatch(questStartedRewardItem.items[0].upd.StackObjectsCount, relatedLiveRewardItem.items[0].upd.StackObjectsCount, "mismatch for started item StackObjectsCount", questStartedRewardItem.items[0]._id); + CheckValuesMatch(questStartedRewardItem.items[0].upd.StackObjectsCount.Value, relatedLiveRewardItem.items[0].upd.StackObjectsCount.Value, "mismatch for started item StackObjectsCount", questStartedRewardItem.items[0]._id); } } @@ -362,6 +420,9 @@ namespace QuestValidator private static void CheckAvailableForFinishConditionItems(Quest quest, Quest relatedLiveQuest) { + // Check count + CheckValuesMatch(quest.conditions.AvailableForFinish.Count, relatedLiveQuest.conditions.AvailableForFinish.Count, "AvailableForFinish mismtch"); + foreach (var availableForFinishItem in quest.conditions.AvailableForFinish) { AvailableFor liveFinishItem = relatedLiveQuest.conditions.AvailableForFinish.Find(x => x._props.id == availableForFinishItem._props.id); @@ -374,7 +435,7 @@ namespace QuestValidator CheckValuesMatch(availableForFinishItem._props.parentId, liveFinishItem._props.parentId, "AvailableForFinish parentId mismatch", availableForFinishItem._props.id); // check AvailableForFinish resetOnSessionEnd - CheckValuesMatch(availableForFinishItem._props.resetOnSessionEnd, liveFinishItem._props.resetOnSessionEnd, "AvailableForFinish resetOnSessionEnd value mismatch", availableForFinishItem._props.id); + CheckValuesMatch(availableForFinishItem._props.resetOnSessionEnd.Value, liveFinishItem._props.resetOnSessionEnd.Value, "AvailableForFinish resetOnSessionEnd value mismatch", availableForFinishItem._props.id); // check AvailableForFinish target CheckValuesMatch(Convert.ToString(availableForFinishItem._props.target), Convert.ToString(liveFinishItem._props.target), "AvailableForFinish target value mismatch", availableForFinishItem._props.id);