diff --git a/Jsarus/Program.cs b/Jsarus/Program.cs index 461a186..1aaff24 100644 --- a/Jsarus/Program.cs +++ b/Jsarus/Program.cs @@ -6,55 +6,95 @@ using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; +using System.Net; using System.Runtime; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; namespace Jsarus { internal class Program { - public static string version = "1.2.0"; + public static string version = "1.3.0"; public static string cd = Directory.GetCurrentDirectory(); public static Process p = new Process(); + private static ConsoleKeyInfo keyInfo; static void Main(string[] args) { + WebClient wc = new WebClient(); Message.Splash("Jsarus", "mikx"); Message.CMW("Creating directories...", true, 1); if (!Directory.Exists($@"Data\Modded")) { Directory.CreateDirectory($@"Data\Modded"); } if (!Directory.Exists($@"Data\Modded\data")) { Directory.CreateDirectory($@"Data\Modded\data"); } - Message.CMW("Preparing variables...",true,1); + Message.CMW("Preparing variables...", true, 1); JObject settings = JObject.Parse(File.ReadAllText("settings.json")); string ModName = settings["ModName"].ToObject(); string GameContentPath = settings["GameContentPath"].ToObject(); + bool KeepData = settings["KeepData"].ToObject(); string[] CopyList = settings["CopyList"].ToObject(); - int ItemWeight = settings["D_Itemable"]["ItemWeight"].ToObject(); - int ItemStack = settings["D_Itemable"]["ItemStack"].ToObject(); + if (!File.Exists("data.json")) { wc.DownloadFile("https://mxio.ovh/icarus/jsarus/data.json", "data.json"); } - int ExperienceMultiplier = settings["D_ExperienceEvents"]["ExperienceMultiplier"].ToObject(); + JObject data = JObject.Parse(File.ReadAllText("data.json")); + int DataVersion = data["version"].ToObject(); + JObject dataRemote = JObject.Parse(wc.DownloadString("https://mxio.ovh/icarus/jsarus/data.json")); + int DataVersionRemote = dataRemote["version"].ToObject(); - string[] ActionList = settings["D_StaminaActionCosts"]["ActionList"].ToObject().Split('|'); - int DivideCostPer = settings["D_StaminaActionCosts"]["DivideCostPer"].ToObject(); + if (KeepData) + { + Message.CMW("Keeping your custom data.", true, 1); + if (DataVersion < DataVersionRemote) + { + Message.CMW("Consider setting \"KeepData\" to \"true\" in your \"settings.json\"!", true, 1); + Message.CMW("Your data is outdated. Should we update it? (y/n)", true, 3); + Message.CMW("If you are not sure, answer \"y\".", true, 1); + keyInfo = Console.ReadKey(true); + if (keyInfo.Key == ConsoleKey.Y) + { + Message.CMW("Getting the latest data...", true, 1); + if (File.Exists("data.json")) { File.Copy("data.json", "data.backup.json", true); } + Message.CMW("A backup has been made to \"data.backup.json\".", true, 1); + wc.DownloadFile("https://mxio.ovh/icarus/jsarus/data.json", "data.json"); + } + } + } + else + { + Message.CMW("Getting the latest data...", true, 1); + wc.DownloadFile("https://mxio.ovh/icarus/jsarus/data.json", "data.json"); + } - string[] PickList = settings["D_ToolDamage"]["PickList"].ToObject().Split('|'); - string[] PickEfficiencyList = settings["D_ToolDamage"]["PickEfficiencyList"].ToObject().Split('|'); + int ItemWeight = data["D_Itemable"]["ItemWeight"].ToObject(); + int ItemStack = data["D_Itemable"]["ItemStack"].ToObject(); - string[] AxeList = settings["D_ToolDamage"]["AxeList"].ToObject().Split('|'); - string[] AxeEfficiencyList = settings["D_ToolDamage"]["AxeEfficiencyList"].ToObject().Split('|'); + int ExperienceMultiplier = data["D_ExperienceEvents"]["ExperienceMultiplier"].ToObject(); - string[] RecipeListOre = settings["D_ProcessorRecipes"]["RecipeListOre"].ToObject().Split('|'); - string[] RecipeList = settings["D_ProcessorRecipes"]["RecipeList"].ToObject().Split('|'); - string[] RecipeListStack = settings["D_ProcessorRecipes"]["RecipeListStack"].ToObject().Split('|'); - int RequiredMillijoules = settings["D_ProcessorRecipes"]["RequiredMillijoules"].ToObject(); - int RequiredAmount = settings["D_ProcessorRecipes"]["RequiredAmount"].ToObject(); - int CraftedAmount = settings["D_ProcessorRecipes"]["CraftedAmount"].ToObject(); + string[] ActionList = data["D_StaminaActionCosts"]["ActionList"].ToObject().Split('|'); + int DivideCostPer = data["D_StaminaActionCosts"]["DivideCostPer"].ToObject(); - string[] InventoryList = settings["D_InventoryInfo"]["InventoryList"].ToObject().Split('|'); - int InventorySize = settings["D_InventoryInfo"]["InventorySize"].ToObject(); + string[] PickList = data["D_ToolDamage"]["PickList"].ToObject().Split('|'); + string[] PickEfficiencyList = data["D_ToolDamage"]["PickEfficiencyList"].ToObject().Split('|'); - string[] supportedJson = { @"Traits\D_Itemable.json", @"Experience\D_ExperienceEvents.json", @"Tools\D_StaminaActionCosts.json", @"Tools\D_ToolDamage.json", @"Crafting\D_ProcessorRecipes.json", @"Inventory\D_InventoryInfo.json" }; + string[] AxeList = data["D_ToolDamage"]["AxeList"].ToObject().Split('|'); + string[] AxeEfficiencyList = data["D_ToolDamage"]["AxeEfficiencyList"].ToObject().Split('|'); + + string[] RecipeListOre = data["D_ProcessorRecipes"]["RecipeListOre"].ToObject().Split('|'); + string[] RecipeList = data["D_ProcessorRecipes"]["RecipeList"].ToObject().Split('|'); + string[] RecipeListStack = data["D_ProcessorRecipes"]["RecipeListStack"].ToObject().Split('|'); + int RequiredMillijoules = data["D_ProcessorRecipes"]["RequiredMillijoules"].ToObject(); + int RequiredAmount = data["D_ProcessorRecipes"]["RequiredAmount"].ToObject(); + int CraftedAmount = data["D_ProcessorRecipes"]["CraftedAmount"].ToObject(); + + string[] InventoryList = data["D_InventoryInfo"]["InventoryList"].ToObject().Split('|'); + int InventorySize = data["D_InventoryInfo"]["InventorySize"].ToObject(); + + string[] GeneratorList = data["D_Generator"]["GeneratorList"].ToObject().Split('|'); + int GenerationRate = data["D_Generator"]["GenerationRate"].ToObject(); + int GenerationRatio = data["D_Generator"]["GenerationRatio"].ToObject(); + + string[] supportedJson = { @"Traits\D_Itemable.json", @"Experience\D_ExperienceEvents.json", @"Tools\D_StaminaActionCosts.json", @"Tools\D_ToolDamage.json", @"Crafting\D_ProcessorRecipes.json", @"Inventory\D_InventoryInfo.json", @"Traits\D_Generator.json" }; var dir = Directory.GetDirectories(@"Data\Vanilla"); @@ -75,153 +115,191 @@ namespace Jsarus Message.CMW($"Copied {sj.Split('\\')[1]}.", true, 2); } - Message.CMW($"We extracted the data, should we continue and mod it? (y/n)", true, 1); - ConsoleKeyInfo keyInfo = Console.ReadKey(true); - if (keyInfo.Key == ConsoleKey.N) { return; } else - - foreach (var d in dir) - { - var json = Directory.GetFiles(d); - foreach (var file in json) + Message.CMW("Generating the Item Database for dynamic modding...", true, 1); + JArray itemsDB = new JArray(); + JObject items = new JObject(); + JObject item = JObject.Parse(File.ReadAllText(@"Data\Vanilla\Traits\D_Itemable.json")); + foreach (var i in item["Rows"]) + { + string iname = i["Name"].ToObject().Substring(5); + int iweight = 0; + if (i["Weight"] != null) { iweight = i["Weight"].ToObject(); } else { iweight = 0; } + bool istack = false; + int istacksize = 1; + if (i["MaxStack"] != null) { istack = true; istacksize = i["MaxStack"].ToObject(); } + items = new JObject() { - string f = Path.GetFileName(file); - Message.CMW($"Processing {f}...", true, 1); - JObject job = JObject.Parse(File.ReadAllText(file)); - switch (f) - { - case "D_Itemable.json": - foreach (var r in job["Rows"]) + { "name", iname }, + { "weight", iweight }, + { "dostack", istack }, + { "stack", istacksize } + }; + itemsDB.Add(items); + } + var rawDB = JsonConvert.SerializeObject(itemsDB, Formatting.Indented); + File.WriteAllText($@"Data/itemDB.json", rawDB); + + foreach (var d in dir) + { + var json = Directory.GetFiles(d); + foreach (var file in json) + { + string f = Path.GetFileName(file); + Message.CMW($"Processing {f}...", true, 1); + JObject job = JObject.Parse(File.ReadAllText(file)); + switch (f) + { + case "D_Itemable.json": + foreach (var r in job["Rows"]) + { + r["Name"] = r["Name"].ToObject(); + r["DisplayName"] = r["DisplayName"].ToObject(); + if (r["Icon"] != null) { - r["Name"] = r["Name"].ToObject(); - r["DisplayName"] = r["DisplayName"].ToObject(); - if (r["Icon"] != null) + r["Icon"] = r["Icon"].ToObject(); + } + if (r["Description"] != null) + { + r["Description"] = r["Description"].ToObject(); + } + if (r["FlavorText"] != null) + { + r["FlavorText"] = r["FlavorText"].ToObject(); + } + r["Weight"] = ItemWeight; + if (r["MaxStack"] != null) + { + r["MaxStack"] = ItemStack; + } + } + break; + + case "D_ExperienceEvents.json": + foreach (var r in job["Rows"]) + { + r["Name"] = r["Name"].ToObject(); + if (r["EventDescription"] != null) + { + r["EventDescription"] = r["EventDescription"].ToObject(); + } + if (r["SharedExperience"] != null) + { + r["SharedExperience"] = r["SharedExperience"].ToObject(); + } + if (r["ExperienceGranted"] != null) + { + r["ExperienceGranted"] = r["ExperienceGranted"].ToObject() * ExperienceMultiplier; + } + } + break; + + case "D_StaminaActionCosts.json": + foreach (var r in job["Rows"]) + { + if (ActionList.Contains(r["Name"].ToString())) + { + if (r["PerSecondCost"] != null) { - r["Icon"] = r["Icon"].ToObject(); + r["PerSecondCost"] = r["PerSecondCost"].ToObject() / DivideCostPer; } - if (r["Description"] != null) + if (r["BeginActionCost"] != null) { - r["Description"] = r["Description"].ToObject(); - } - if (r["FlavorText"] != null) - { - r["FlavorText"] = r["FlavorText"].ToObject(); - } - r["Weight"] = ItemWeight; - if (r["MaxStack"] != null) - { - r["MaxStack"] = ItemStack; + r["BeginActionCost"] = r["BeginActionCost"].ToObject() / DivideCostPer; } } - break; + } + break; - case "D_ExperienceEvents.json": - foreach (var r in job["Rows"]) + case "D_ToolDamage.json": + foreach (var r in job["Rows"]) + { + if (PickList.Contains(r["Name"].ToString())) { - r["Name"] = r["Name"].ToObject(); - if (r["EventDescription"] != null) - { - r["EventDescription"] = r["EventDescription"].ToObject(); - } - if (r["SharedExperience"] != null) - { - r["SharedExperience"] = r["SharedExperience"].ToObject(); - } - if (r["ExperienceGranted"] != null) - { - r["ExperienceGranted"] = r["ExperienceGranted"].ToObject() * ExperienceMultiplier; - } + int index = Array.IndexOf(PickList, r["Name"].ToString()); + r["Mining_Efficiency"] = PickEfficiencyList[index]; } - break; - case "D_StaminaActionCosts.json": - foreach (var r in job["Rows"]) + if (AxeList.Contains(r["Name"].ToString())) { - if(ActionList.Contains(r["Name"].ToString())) + int index = Array.IndexOf(AxeList, r["Name"].ToString()); + r["Felling_Efficiency"] = AxeEfficiencyList[index]; + } + } + break; + + case "D_ProcessorRecipes.json": + JArray itemDB = JArray.Parse(File.ReadAllText(@"Data\itemDB.json")); + foreach (var r in job["Rows"]) + { + //JToken entry = itemDB.FirstOrDefault(t => (bool)(t["name"]?.ToString().Contains(r["Name"]?.ToString()))); + + if (r["Inputs"].Count() > 0) + { + if (RecipeListOre.Contains(r["Name"].ToString())) { - if (r["PerSecondCost"] != null) + if (r["RequiredMillijoules"] != null) { - r["PerSecondCost"] = r["PerSecondCost"].ToObject() / DivideCostPer; + r["RequiredMillijoules"] = RequiredMillijoules; } - if (r["BeginActionCost"] != null) + foreach (var i in r["Inputs"]) { - r["BeginActionCost"] = r["BeginActionCost"].ToObject() / DivideCostPer; + i["Count"] = RequiredAmount; } + r["Outputs"][0]["Count"] = CraftedAmount; + } + + if (RecipeList.Contains(r["Name"].ToString())) + { + foreach (var i in r["Inputs"]) + { + i["Count"] = RequiredAmount; + } + r["Outputs"][0]["Count"] = 1; + } + + if (RecipeListStack.Contains(r["Name"].ToString())) + { + foreach (var i in r["Inputs"]) + { + i["Count"] = RequiredAmount; + } + r["Outputs"][0]["Count"] = CraftedAmount; } } - break; - case "D_ToolDamage.json": - foreach (var r in job["Rows"]) + } + break; + + case "D_InventoryInfo.json": + foreach (var r in job["Rows"]) + { + if (InventoryList.Contains(r["Name"].ToString())) { - if (PickList.Contains(r["Name"].ToString())) - { - int index = Array.IndexOf(PickList, r["Name"].ToString()); - r["Mining_Efficiency"] = PickEfficiencyList[index]; - } - - if (AxeList.Contains(r["Name"].ToString())) - { - int index = Array.IndexOf(AxeList, r["Name"].ToString()); - r["Felling_Efficiency"] = AxeEfficiencyList[index]; - } + r["StartingSlots"] = InventorySize; } - break; + } + break; - case "D_ProcessorRecipes.json": - foreach (var r in job["Rows"]) + case "D_Generator.json": + foreach (var r in job["Rows"]) + { + if (GeneratorList.Contains(r["Name"].ToString())) { - if (r["Inputs"].Count() > 0) + r["GenerationRate"] = GenerationRate; + if (r["GenerationRatio"] != null) { - if (RecipeListOre.Contains(r["Name"].ToString())) - { - if (r["RequiredMillijoules"] != null) - { - r["RequiredMillijoules"] = RequiredMillijoules; - } - foreach (var i in r["Inputs"]) - { - i["Count"] = RequiredAmount; - } - r["Outputs"][0]["Count"] = CraftedAmount; - } - - if (RecipeList.Contains(r["Name"].ToString())) - { - foreach (var i in r["Inputs"]) - { - i["Count"] = RequiredAmount; - } - r["Outputs"][0]["Count"] = 1; - } - - if (RecipeListStack.Contains(r["Name"].ToString())) - { - foreach (var i in r["Inputs"]) - { - i["Count"] = RequiredAmount; - } - r["Outputs"][0]["Count"] = CraftedAmount; - } - } + r["GenerationRatio"] = GenerationRatio; + } } - break; - - case "D_InventoryInfo.json": - foreach (var r in job["Rows"]) - { - if (InventoryList.Contains(r["Name"].ToString())) - { - r["StartingSlots"] = InventorySize; - } - } - break; - } - Message.CMW($"Saving {f}...", true, 1); - var raw = JsonConvert.SerializeObject(job, Formatting.Indented); - if (!Directory.Exists($@"{cd}\Data\Modded\data\{Path.GetFileName(d)}")) { Directory.CreateDirectory($@"{cd}\Data\Modded\data\{Path.GetFileName(d)}"); } - File.WriteAllText($@"Data/Modded/data/{Path.GetFileName(d)}/{f}", raw); + } + break; } + Message.CMW($"Saving {f}...", true, 1); + var raw = JsonConvert.SerializeObject(job, Formatting.Indented); + if (!Directory.Exists($@"{cd}\Data\Modded\data\{Path.GetFileName(d)}")) { Directory.CreateDirectory($@"{cd}\Data\Modded\data\{Path.GetFileName(d)}"); } + File.WriteAllText($@"Data/Modded/data/{Path.GetFileName(d)}/{f}", raw); } + } if (File.Exists($@"{cd}\Paks\{ModName}.txt")) { File.Delete($@"{cd}\Paks\{ModName}.txt"); } File.WriteAllText($@"{cd}\Paks\{ModName}.txt", $@"""{cd}\Data\Modded\*.*"" ""..\..\..\Icarus\Content\*.*"""); @@ -238,7 +316,7 @@ namespace Jsarus { File.Copy($@"{cd}\Paks\{ModName}_P.pak", $@"{p}\{ModName}_P.pak", true); } - } - } + } + } } } diff --git a/README.md b/README.md index ecdcf57..809c208 100644 --- a/README.md +++ b/README.md @@ -17,12 +17,13 @@ Official MxIcarus Modding Tool for Icarus. - Reduce all required mats of a recipe to 1, using a list. (Edited in settings.json) - Set output of all stacking recipes to a specified value. (Edited in settings.json) - Adjust the size of all inventory specified in a list. (Edited in settings.json) +- Adjust the energy produced and the biofuel consumed by all specified generator in a list. (Edited in settings.json) ## How-To 1. Download the latest [release](https://mxgit.ovh/Icarus/Jsarus/releases). 2. Copy the archive content in an empty folder on your disk. 3. Open "settings.json" and edit the "ModName" and "GameContentPath". -4. IMPORTANT: Escape "\" in your path with "/". Ex.: "C:\/SteamLibrary\/steamapps\/common\/Icarus\/Icarus\/Content" +4. IMPORTANT: Escape "\\" in your path with "\\\\". Ex.: "C:\\\\SteamLibrary\\\\steamapps\\\\common\\\\Icarus\\\\Icarus\\\\Content" 5. Save the "settings.json" file and run "Jsarus.exe". 6. Jsarus will extract your game data, press "y" when asked to mod it and generate a mod pak. 7. Copy the created pak file from the "Paks" folder to your game "mods" folder.