Compare commits

..

No commits in common. "main" and "1.1.1" have entirely different histories.
main ... 1.1.1

2 changed files with 158 additions and 247 deletions

View File

@ -6,95 +6,54 @@ using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net;
using System.Runtime; using System.Runtime;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Jsarus namespace Jsarus
{ {
internal class Program internal class Program
{ {
public static string version = "1.3.0"; public static string version = "1.1.1";
public static string cd = Directory.GetCurrentDirectory(); public static string cd = Directory.GetCurrentDirectory();
public static Process p = new Process(); public static Process p = new Process();
private static ConsoleKeyInfo keyInfo;
static void Main(string[] args) static void Main(string[] args)
{ {
WebClient wc = new WebClient();
Message.Splash("Jsarus", "mikx"); Message.Splash("Jsarus", "mikx");
Message.CMW("Creating directories...", true, 1); Message.CMW("Creating directories...", true, 1);
if (!Directory.Exists($@"Data\Modded")) { Directory.CreateDirectory($@"Data\Modded"); } if (!Directory.Exists($@"Data\Modded")) { Directory.CreateDirectory($@"Data\Modded"); }
if (!Directory.Exists($@"Data\Modded\data")) { Directory.CreateDirectory($@"Data\Modded\data"); } 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")); JObject settings = JObject.Parse(File.ReadAllText("settings.json"));
string ModName = settings["ModName"].ToObject<string>(); string ModName = settings["ModName"].ToObject<string>();
string GameContentPath = settings["GameContentPath"].ToObject<string>(); string GameContentPath = settings["GameContentPath"].ToObject<string>();
bool KeepData = settings["KeepData"].ToObject<bool>();
string[] CopyList = settings["CopyList"].ToObject<string[]>(); string[] CopyList = settings["CopyList"].ToObject<string[]>();
if (!File.Exists("data.json")) { wc.DownloadFile("https://mxio.ovh/icarus/jsarus/data.json", "data.json"); } int ItemWeight = settings["D_Itemable"]["ItemWeight"].ToObject<int>();
int ItemStack = settings["D_Itemable"]["ItemStack"].ToObject<int>();
JObject data = JObject.Parse(File.ReadAllText("data.json")); int ExperienceMultiplier = settings["D_ExperienceEvents"]["ExperienceMultiplier"].ToObject<int>();
int DataVersion = data["version"].ToObject<int>();
JObject dataRemote = JObject.Parse(wc.DownloadString("https://mxio.ovh/icarus/jsarus/data.json"));
int DataVersionRemote = dataRemote["version"].ToObject<int>();
if (KeepData) string[] ActionList = settings["D_StaminaActionCosts"]["ActionList"].ToObject<string>().Split('|');
{ int DivideCostPer = settings["D_StaminaActionCosts"]["DivideCostPer"].ToObject<int>();
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");
}
int ItemWeight = data["D_Itemable"]["ItemWeight"].ToObject<int>(); string[] PickList = settings["D_ToolDamage"]["PickList"].ToObject<string>().Split('|');
int ItemStack = data["D_Itemable"]["ItemStack"].ToObject<int>(); string[] PickEfficiencyList = settings["D_ToolDamage"]["PickEfficiencyList"].ToObject<string>().Split('|');
int ExperienceMultiplier = data["D_ExperienceEvents"]["ExperienceMultiplier"].ToObject<int>(); string[] AxeList = settings["D_ToolDamage"]["AxeList"].ToObject<string>().Split('|');
string[] AxeEfficiencyList = settings["D_ToolDamage"]["AxeEfficiencyList"].ToObject<string>().Split('|');
string[] ActionList = data["D_StaminaActionCosts"]["ActionList"].ToObject<string>().Split('|'); string[] RecipeListOre = settings["D_ProcessorRecipes"]["RecipeListOre"].ToObject<string>().Split('|');
int DivideCostPer = data["D_StaminaActionCosts"]["DivideCostPer"].ToObject<int>(); string[] RecipeList = settings["D_ProcessorRecipes"]["RecipeList"].ToObject<string>().Split('|');
string[] RecipeListStack = settings["D_ProcessorRecipes"]["RecipeListStack"].ToObject<string>().Split('|');
int RequiredMillijoules = settings["D_ProcessorRecipes"]["RequiredMillijoules"].ToObject<int>();
int RequiredAmount = settings["D_ProcessorRecipes"]["RequiredAmount"].ToObject<int>();
int CraftedAmount = settings["D_ProcessorRecipes"]["CraftedAmount"].ToObject<int>();
string[] PickList = data["D_ToolDamage"]["PickList"].ToObject<string>().Split('|'); int ÞlayerInventorySize = settings["D_InventoryInfo"]["ÞlayerInventorySize"].ToObject<int>();
string[] PickEfficiencyList = data["D_ToolDamage"]["PickEfficiencyList"].ToObject<string>().Split('|');
string[] AxeList = data["D_ToolDamage"]["AxeList"].ToObject<string>().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[] AxeEfficiencyList = data["D_ToolDamage"]["AxeEfficiencyList"].ToObject<string>().Split('|');
string[] RecipeListOre = data["D_ProcessorRecipes"]["RecipeListOre"].ToObject<string>().Split('|');
string[] RecipeList = data["D_ProcessorRecipes"]["RecipeList"].ToObject<string>().Split('|');
string[] RecipeListStack = data["D_ProcessorRecipes"]["RecipeListStack"].ToObject<string>().Split('|');
int RequiredMillijoules = data["D_ProcessorRecipes"]["RequiredMillijoules"].ToObject<int>();
int RequiredAmount = data["D_ProcessorRecipes"]["RequiredAmount"].ToObject<int>();
int CraftedAmount = data["D_ProcessorRecipes"]["CraftedAmount"].ToObject<int>();
string[] InventoryList = data["D_InventoryInfo"]["InventoryList"].ToObject<string>().Split('|');
int InventorySize = data["D_InventoryInfo"]["InventorySize"].ToObject<int>();
string[] GeneratorList = data["D_Generator"]["GeneratorList"].ToObject<string>().Split('|');
int GenerationRate = data["D_Generator"]["GenerationRate"].ToObject<int>();
int GenerationRatio = data["D_Generator"]["GenerationRatio"].ToObject<int>();
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"); var dir = Directory.GetDirectories(@"Data\Vanilla");
@ -115,191 +74,153 @@ namespace Jsarus
Message.CMW($"Copied {sj.Split('\\')[1]}.", true, 2); Message.CMW($"Copied {sj.Split('\\')[1]}.", true, 2);
} }
Message.CMW("Generating the Item Database for dynamic modding...", true, 1); Message.CMW($"We extracted the data, should we continue and mod it? (y/n)", true, 1);
JArray itemsDB = new JArray(); ConsoleKeyInfo keyInfo = Console.ReadKey(true);
JObject items = new JObject(); if (keyInfo.Key == ConsoleKey.N) { return; } else
JObject item = JObject.Parse(File.ReadAllText(@"Data\Vanilla\Traits\D_Itemable.json"));
foreach (var i in item["Rows"])
{
string iname = i["Name"].ToObject<string>().Substring(5);
int iweight = 0;
if (i["Weight"] != null) { iweight = i["Weight"].ToObject<int>(); } else { iweight = 0; }
bool istack = false;
int istacksize = 1;
if (i["MaxStack"] != null) { istack = true; istacksize = i["MaxStack"].ToObject<int>(); }
items = new JObject()
{
{ "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) foreach (var d in dir)
{
var json = Directory.GetFiles(d);
foreach (var file in json)
{ {
string f = Path.GetFileName(file); var json = Directory.GetFiles(d);
Message.CMW($"Processing {f}...", true, 1); foreach (var file in json)
JObject job = JObject.Parse(File.ReadAllText(file));
switch (f)
{ {
case "D_Itemable.json": string f = Path.GetFileName(file);
foreach (var r in job["Rows"]) Message.CMW($"Processing {f}...", true, 1);
{ JObject job = JObject.Parse(File.ReadAllText(file));
r["Name"] = r["Name"].ToObject<string>(); switch (f)
r["DisplayName"] = r["DisplayName"].ToObject<string>(); {
if (r["Icon"] != null) case "D_Itemable.json":
foreach (var r in job["Rows"])
{ {
r["Icon"] = r["Icon"].ToObject<string>(); r["Name"] = r["Name"].ToObject<string>();
} r["DisplayName"] = r["DisplayName"].ToObject<string>();
if (r["Description"] != null) if (r["Icon"] != null)
{
r["Description"] = r["Description"].ToObject<string>();
}
if (r["FlavorText"] != null)
{
r["FlavorText"] = r["FlavorText"].ToObject<string>();
}
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<string>();
if (r["EventDescription"] != null)
{
r["EventDescription"] = r["EventDescription"].ToObject<string>();
}
if (r["SharedExperience"] != null)
{
r["SharedExperience"] = r["SharedExperience"].ToObject<bool>();
}
if (r["ExperienceGranted"] != null)
{
r["ExperienceGranted"] = r["ExperienceGranted"].ToObject<int>() * ExperienceMultiplier;
}
}
break;
case "D_StaminaActionCosts.json":
foreach (var r in job["Rows"])
{
if (ActionList.Contains(r["Name"].ToString()))
{
if (r["PerSecondCost"] != null)
{ {
r["PerSecondCost"] = r["PerSecondCost"].ToObject<int>() / DivideCostPer; r["Icon"] = r["Icon"].ToObject<string>();
} }
if (r["BeginActionCost"] != null) if (r["Description"] != null)
{ {
r["BeginActionCost"] = r["BeginActionCost"].ToObject<int>() / DivideCostPer; r["Description"] = r["Description"].ToObject<string>();
}
if (r["FlavorText"] != null)
{
r["FlavorText"] = r["FlavorText"].ToObject<string>();
}
r["Weight"] = ItemWeight;
if (r["MaxStack"] != null)
{
r["MaxStack"] = ItemStack;
} }
} }
} break;
break;
case "D_ToolDamage.json": case "D_ExperienceEvents.json":
foreach (var r in job["Rows"]) foreach (var r in job["Rows"])
{
if (PickList.Contains(r["Name"].ToString()))
{ {
int index = Array.IndexOf(PickList, r["Name"].ToString()); r["Name"] = r["Name"].ToObject<string>();
r["Mining_Efficiency"] = PickEfficiencyList[index]; if (r["EventDescription"] != null)
}
if (AxeList.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["RequiredMillijoules"] != null) r["EventDescription"] = r["EventDescription"].ToObject<string>();
}
if (r["SharedExperience"] != null)
{
r["SharedExperience"] = r["SharedExperience"].ToObject<bool>();
}
if (r["ExperienceGranted"] != null)
{
r["ExperienceGranted"] = r["ExperienceGranted"].ToObject<int>() * ExperienceMultiplier;
}
}
break;
case "D_StaminaActionCosts.json":
foreach (var r in job["Rows"])
{
if(ActionList.Contains(r["Name"].ToString()))
{
if (r["PerSecondCost"] != null)
{ {
r["RequiredMillijoules"] = RequiredMillijoules; r["PerSecondCost"] = r["PerSecondCost"].ToObject<int>() / DivideCostPer;
} }
foreach (var i in r["Inputs"]) if (r["BeginActionCost"] != null)
{ {
i["Count"] = RequiredAmount; r["BeginActionCost"] = r["BeginActionCost"].ToObject<int>() / DivideCostPer;
} }
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":
break; foreach (var r in job["Rows"])
case "D_InventoryInfo.json":
foreach (var r in job["Rows"])
{
if (InventoryList.Contains(r["Name"].ToString()))
{ {
r["StartingSlots"] = InventorySize; if (PickList.Contains(r["Name"].ToString()))
}
}
break;
case "D_Generator.json":
foreach (var r in job["Rows"])
{
if (GeneratorList.Contains(r["Name"].ToString()))
{
r["GenerationRate"] = GenerationRate;
if (r["GenerationRatio"] != null)
{ {
r["GenerationRatio"] = GenerationRatio; 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];
}
} }
} break;
break;
case "D_ProcessorRecipes.json":
foreach (var r in job["Rows"])
{
if (r["Inputs"].Count() > 0)
{
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;
}
}
}
break;
case "D_InventoryInfo.json":
foreach (var r in job["Rows"])
{
if (r["Name"].ToObject<string>() == "Backpack")
{
r["StartingSlots"] = ÞlayerInventorySize;
}
}
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);
} }
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"); } if (File.Exists($@"{cd}\Paks\{ModName}.txt")) { File.Delete($@"{cd}\Paks\{ModName}.txt"); }
File.WriteAllText($@"{cd}\Paks\{ModName}.txt", $@"""{cd}\Data\Modded\*.*"" ""..\..\..\Icarus\Content\*.*"""); File.WriteAllText($@"{cd}\Paks\{ModName}.txt", $@"""{cd}\Data\Modded\*.*"" ""..\..\..\Icarus\Content\*.*""");
@ -316,7 +237,7 @@ namespace Jsarus
{ {
File.Copy($@"{cd}\Paks\{ModName}_P.pak", $@"{p}\{ModName}_P.pak", true); File.Copy($@"{cd}\Paks\{ModName}_P.pak", $@"{p}\{ModName}_P.pak", true);
} }
} }
} }
} }
} }

View File

@ -4,29 +4,19 @@
Official MxIcarus Modding Tool for Icarus. Official MxIcarus Modding Tool for Icarus.
## Features ## Features
1. Extract json data from your client. * Extract json data from your client.
2. Mod your extracted json data according to the settings.json config. * Mod your extracted json data according to the settings.json config.
3. Create a pak file, ready to use on your client/server. * Create a pak file, ready to use on your client/server.
4. Can copy the created pak file to a user specified list of path. * Can copy the created pak file to a user specified list of path.
- Set all stackable item stack size and weight. (Edited in settings.json)
- Set all non-stackable item weight. (Edited in settings.json)
- Multiply all experience gain. (Edited in settings.json)
- Divide stamina cost of listed action list. (Edited in settings.json)
- Set efficiency of listed pickaxe and axe from a list. (Edited in settings.json)
- Set ore recipe crafting speed. (Edited in settings.json)
- 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 ## How-To
1. Download the latest [release](https://mxgit.ovh/Icarus/Jsarus/releases). 1. Download the latest release. (https://mxgit.ovh/Icarus/Jsarus/releases)
2. Copy the archive content in an empty folder on your disk. 2. Copy the archive content in an empty folder on your disk.
3. Open "settings.json" and edit the "ModName" and "GameContentPath". 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". 5. Save the "settings.json" file and run "Jsarus.exe".
6. Jsarus will extract your game data and mod it. 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. 7. Copy the created pak file from the "Paks" folder to your game "mods" folder.
8. "mods" location exemple: "C:\SteamLibrary\steamapps\common\Icarus\Icarus\Content\Paks\mods" 8. "mods" location exemple: "C:\SteamLibrary\steamapps\common\Icarus\Icarus\Content\Paks\mods"
9. If you don't have a "mods" folder, create one first. 9. If you don't have a "mods" folder, create one first.
10. Voila! 10. Voila!