Decompiled source of RecipeManager v0.5.1
plugins/RecipeManager.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using RecipeManager.Common; using UnityEngine; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("RecipeManager")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("RecipeManager")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: AssemblyFileVersion("0.0.1.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.1.0")] namespace RecipeManager { internal class ConversionPrintCommand : ConsoleCommand { public override string Name => "RM_Conversion_PrintAll"; public override string Help => "Prints all conversions."; public override bool IsCheat => true; public override void Run(string[] args) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo("Starting to dump conversion list"); } string path = Path.Combine(Paths.ConfigPath, "RecipeManager", "AllConversionsDebug.yaml"); DataObjects.ConversionModificationCollection conversionModificationCollection = new DataObjects.ConversionModificationCollection(); List<Smelter> list = (from pc in Resources.FindObjectsOfTypeAll<Smelter>() where !((Object)pc).name.EndsWith("(Clone)") && !Regex.IsMatch(((Object)pc).name.Trim(), "\\(\\d+\\)") select pc).ToList(); List<Fermenter> list2 = (from pc in Resources.FindObjectsOfTypeAll<Fermenter>() where !((Object)pc).name.EndsWith("(Clone)") && !Regex.IsMatch(((Object)pc).name.Trim(), "\\(\\d+\\)") select pc).ToList(); List<CookingStation> list3 = (from pc in Resources.FindObjectsOfTypeAll<CookingStation>() where !((Object)pc).name.EndsWith("(Clone)") && !Regex.IsMatch(((Object)pc).name.Trim(), "\\(\\d+\\)") select pc).ToList(); foreach (Smelter item in list) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo("Building Smelter definition " + ((Object)((Component)item).gameObject).name); } DataObjects.ConversionModification conversionModification = new DataObjects.ConversionModification(); Logger.LogInfo("Set name " + ((Object)((Component)item).gameObject).name); conversionModification.prefab = ((Object)((Component)item).gameObject).name; conversionModification.action = DataObjects.ConversionAction.Modify; Logger.LogInfo($"Set fuelPerProduct {item.m_fuelPerProduct}"); conversionModification.fuelPerProduct = item.m_fuelPerProduct; Logger.LogInfo($"Set maxFuel {item.m_maxFuel}"); conversionModification.maxFuel = item.m_maxFuel; Logger.LogInfo($"Set maxOres {item.m_maxOre}"); conversionModification.maxOres = item.m_maxOre; if ((Object)(object)item.m_fuelItem != (Object)null) { Logger.LogInfo("Set fuelItem " + ((Object)((Component)item.m_fuelItem).gameObject).name); conversionModification.fuelItem = ((Object)((Component)item.m_fuelItem).gameObject).name; } Logger.LogInfo($"Set requiresFuel {(Object)(object)item.m_fuelItem != (Object)null}"); Logger.LogInfo($"Set conversionTime {item.m_secPerProduct}"); conversionModification.conversionTime = item.m_secPerProduct; List<DataObjects.ConversionDef> list4 = new List<DataObjects.ConversionDef>(); if (item.m_conversion != null && item.m_conversion.Count > 0) { foreach (ItemConversion item2 in item.m_conversion) { if (item2 != null) { DataObjects.ConversionDef conversionDef = new DataObjects.ConversionDef(); if ((Object)(object)item2.m_from != (Object)null) { conversionDef.fromPrefab = ((Object)((Component)item2.m_from).gameObject).name; Logger.LogInfo("Convert From: " + ((Object)((Component)item2.m_from).gameObject).name); } if ((Object)(object)item2.m_to != (Object)null) { conversionDef.toPrefab = ((Object)((Component)item2.m_to).gameObject).name; Logger.LogInfo("Convert To: " + ((Object)((Component)item2.m_to).gameObject).name); } list4.Add(conversionDef); } } } conversionModification.conversions = list4; Logger.LogInfo("Added."); conversionModificationCollection.ConversionModifications.Add(((Object)((Component)item).gameObject).name, conversionModification); } foreach (Fermenter item3 in list2) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo("Building Fermenter definition " + item3.m_name); } DataObjects.ConversionModification conversionModification2 = new DataObjects.ConversionModification(); conversionModification2.prefab = ((Object)((Component)item3).gameObject).name; conversionModification2.action = DataObjects.ConversionAction.Modify; conversionModification2.conversionTime = item3.m_fermentationDuration; List<DataObjects.ConversionDef> list5 = new List<DataObjects.ConversionDef>(); foreach (ItemConversion item4 in item3.m_conversion) { if (item4 != null) { DataObjects.ConversionDef conversionDef2 = new DataObjects.ConversionDef(); conversionDef2.fromPrefab = ((Object)item4.m_from).name; conversionDef2.toPrefab = ((Object)item4.m_to).name; conversionDef2.amount = item4.m_producedItems; list5.Add(conversionDef2); } } conversionModification2.conversions = list5; conversionModificationCollection.ConversionModifications.Add(((Object)((Component)item3).gameObject).name, conversionModification2); } foreach (CookingStation item5 in list3) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo("Building Cooking Station definition " + item5.m_name); } DataObjects.ConversionModification conversionModification3 = new DataObjects.ConversionModification(); conversionModification3.prefab = ((Object)((Component)item5).gameObject).name; conversionModification3.action = DataObjects.ConversionAction.Modify; if ((Object)(object)item5.m_fuelItem != (Object)null) { conversionModification3.fuelItem = ((Object)item5.m_fuelItem).name; } if (conversionModification3.overCookedItem != null) { conversionModification3.overCookedItem = ((Object)item5.m_overCookedItem).name; } conversionModification3.secPerFuel = item5.m_secPerFuel; conversionModification3.maxFuel = item5.m_maxFuel; List<DataObjects.ConversionDef> list6 = new List<DataObjects.ConversionDef>(); foreach (ItemConversion item6 in item5.m_conversion) { if (item6 != null) { DataObjects.ConversionDef conversionDef3 = new DataObjects.ConversionDef(); if ((Object)(object)item6.m_from != (Object)null) { conversionDef3.fromPrefab = ((Object)item6.m_from).name; } if ((Object)(object)item6.m_to != (Object)null) { conversionDef3.toPrefab = ((Object)item6.m_to).name; } conversionDef3.cookTime = item6.m_cookTime; list6.Add(conversionDef3); } } conversionModification3.conversions = list6; conversionModificationCollection.ConversionModifications.Add(((Object)((Component)item5).gameObject).name, conversionModification3); } if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo("Serializing and printing conversions."); } string value = ValConfig.yamlserializer.Serialize((object)conversionModificationCollection); using StreamWriter streamWriter = new StreamWriter(path); streamWriter.WriteLine(value); } } internal class ConversionReloadCommand : ConsoleCommand { public override string Name => "RM_Conversion_Reload"; public override string Help => "Resynchronizes conversion modifications."; public override bool IsCheat => true; public override void Run(string[] args) { ConversionUpdater.RevertConversionModifications(); ValConfig.ReloadConversionFiles(); ConversionUpdater.BuildConversionTracker(); ConversionUpdater.ConversionUpdateRunner(); } } internal class ConversionUpdater { public static Dictionary<string, DataObjects.ConversionModification> ConversionsToModify = new Dictionary<string, DataObjects.ConversionModification>(); public static List<DataObjects.TrackedConversion> TrackedConversions = new List<DataObjects.TrackedConversion>(); public static void InitialSychronization() { BuildConversionTracker(); ConversionUpdateRunner(); } public static void ConversionUpdateRunner() { Logger.LogInfo($"Applying {TrackedConversions.Count} conversion modifications"); foreach (DataObjects.TrackedConversion trackedConversion in TrackedConversions) { ApplyConversionModifications(trackedConversion); } } public static void ApplyConversionModifications(DataObjects.TrackedConversion conv) { Logger.LogDebug($"Applying conversion ({((Object)conv.prefab).name}) modification action: {conv.action}"); IEnumerable<GameObject> enumerable = from obj in Resources.FindObjectsOfTypeAll<GameObject>() where ((Object)obj).name.StartsWith(((Object)conv.prefab).name) select obj; if (enumerable == null) { Logger.LogWarning("No Prefabs found for conversion " + ((Object)conv.prefab).name + ", skipping modification."); return; } foreach (GameObject item in enumerable) { if (!((Object)(object)item == (Object)null)) { switch (conv.action) { case DataObjects.ConversionAction.Modify: ModifyConversion(conv, item); break; case DataObjects.ConversionAction.Add: AddConversion(conv, item); break; case DataObjects.ConversionAction.Remove: RemoveConversion(conv, item); break; } } } } public static void RevertConversionModifications() { Logger.LogInfo($"Reverting {TrackedConversions.Count} conversion modifications"); foreach (DataObjects.TrackedConversion conv in TrackedConversions) { Logger.LogDebug($"Applying conversion ({((Object)conv.prefab).name}) modification action: {conv.action}"); foreach (GameObject item in from obj in Resources.FindObjectsOfTypeAll<GameObject>() where ((Object)obj).name.StartsWith(((Object)conv.prefab).name) select obj) { if (!((Object)(object)item == (Object)null)) { switch (conv.action) { case DataObjects.ConversionAction.Modify: ModifyConversion(conv, item); break; case DataObjects.ConversionAction.Add: RemoveConversion(conv, item); break; case DataObjects.ConversionAction.Remove: AddConversion(conv, item); break; } } } } } private static void ModifyConversion(DataObjects.TrackedConversion conversion, GameObject go) { switch (conversion.convertType) { case DataObjects.ConversionType.Smelter: { Smelter component3 = go.GetComponent<Smelter>(); if ((Object)(object)component3 == (Object)null) { Logger.LogInfo("Smelter component not found on " + ((Object)go).name + ", cannot apply conversion modifications."); break; } if (conversion.updatedSmelterConversions != null) { component3.m_conversion = conversion.updatedSmelterConversions; } if ((Object)(object)conversion.fuelItem != (Object)null) { component3.m_fuelItem = conversion.fuelItem; } if (conversion.fuelPerProduct > 0) { component3.m_fuelPerProduct = conversion.fuelPerProduct; } if (conversion.conversionTime > 0f) { component3.m_secPerProduct = conversion.conversionTime; } if (conversion.maxOres > 0) { component3.m_maxOre = conversion.maxOres; } if (conversion.maxFuel > 0) { component3.m_maxFuel = conversion.maxFuel; } break; } case DataObjects.ConversionType.Fermenter: { Fermenter component2 = go.GetComponent<Fermenter>(); if ((Object)(object)component2 == (Object)null) { Logger.LogInfo("Fermenter component not found on " + ((Object)go).name + ", cannot apply conversion modifications."); break; } if (conversion.updatedFermenterConversions != null) { component2.m_conversion = conversion.updatedFermenterConversions; } if (conversion.conversionTime > 0f) { component2.m_fermentationDuration = conversion.conversionTime; } break; } case DataObjects.ConversionType.CookingStation: { CookingStation component = go.GetComponent<CookingStation>(); if ((Object)(object)component == (Object)null) { Logger.LogInfo("CookingStation component not found on " + ((Object)go).name + ", cannot apply conversion modifications."); break; } if (conversion.updatedCookingConversions != null) { component.m_conversion = conversion.updatedCookingConversions; } if (conversion.maxFuel > 0) { component.m_maxFuel = conversion.maxFuel; } if ((Object)(object)conversion.fuelItem != (Object)null) { component.m_fuelItem = conversion.fuelItem; } component.m_useFuel = conversion.requiresFuel; component.m_requireFire = conversion.requiresFire; if (conversion.secPerFuel > 0f) { component.m_secPerFuel = (int)conversion.secPerFuel; } break; } } } public static void AddConversion(DataObjects.TrackedConversion conversion, GameObject go) { switch (conversion.convertType) { case DataObjects.ConversionType.Smelter: { Smelter component3 = go.GetComponent<Smelter>(); { foreach (ItemConversion updatedSmelterConversion in conversion.updatedSmelterConversions) { if (!component3.m_conversion.Contains(updatedSmelterConversion)) { component3.m_conversion.Add(updatedSmelterConversion); } } break; } } case DataObjects.ConversionType.Fermenter: { Fermenter component2 = go.GetComponent<Fermenter>(); { foreach (ItemConversion updatedFermenterConversion in conversion.updatedFermenterConversions) { if (!component2.m_conversion.Contains(updatedFermenterConversion)) { component2.m_conversion.Add(updatedFermenterConversion); } } break; } } case DataObjects.ConversionType.CookingStation: { CookingStation component = go.GetComponent<CookingStation>(); { foreach (ItemConversion updatedCookingConversion in conversion.updatedCookingConversions) { if (!component.m_conversion.Contains(updatedCookingConversion)) { component.m_conversion.Add(updatedCookingConversion); } } break; } } } } public static void RemoveConversion(DataObjects.TrackedConversion conversion, GameObject go) { switch (conversion.convertType) { case DataObjects.ConversionType.Smelter: { Smelter component3 = go.GetComponent<Smelter>(); { foreach (ItemConversion updatedSmelterConversion in conversion.updatedSmelterConversions) { if (component3.m_conversion.Contains(updatedSmelterConversion)) { component3.m_conversion.Remove(updatedSmelterConversion); } } break; } } case DataObjects.ConversionType.Fermenter: { Fermenter component2 = go.GetComponent<Fermenter>(); { foreach (ItemConversion updatedFermenterConversion in conversion.updatedFermenterConversions) { if (component2.m_conversion.Contains(updatedFermenterConversion)) { component2.m_conversion.Remove(updatedFermenterConversion); } } break; } } case DataObjects.ConversionType.CookingStation: { CookingStation component = go.GetComponent<CookingStation>(); { foreach (ItemConversion updatedCookingConversion in conversion.updatedCookingConversions) { if (component.m_conversion.Contains(updatedCookingConversion)) { component.m_conversion.Remove(updatedCookingConversion); } } break; } } } } public static void BuildConversionTracker() { //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Expected O, but got Unknown //IL_04af: Unknown result type (might be due to invalid IL or missing references) //IL_04b6: Expected O, but got Unknown //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Expected O, but got Unknown TrackedConversions.Clear(); foreach (KeyValuePair<string, DataObjects.ConversionModification> item in ConversionsToModify) { if (item.Key == null) { continue; } Logger.LogDebug("Constructing Conversion modifications for " + item.Key); bool flag = true; DataObjects.TrackedConversion trackedConversion = new DataObjects.TrackedConversion(); trackedConversion.action = item.Value.action; if (item.Value.conversionTime > 0f) { trackedConversion.conversionTime = item.Value.conversionTime; } try { GameObject prefab = PrefabManager.Instance.GetPrefab(item.Value.prefab); if ((Object)(object)prefab == (Object)null) { Logger.LogWarning("Could not find piece with name: " + item.Value.prefab + ", this modification will be skipped."); continue; } trackedConversion.prefab = prefab; object obj = prefab.GetComponent<Smelter>() ?? prefab.GetComponentInChildren<Smelter>(); if (obj == null) { obj = prefab.GetComponentInParent<Smelter>(); } Smelter val = (Smelter)obj; if ((Object)(object)val != (Object)null) { trackedConversion.originalSmelter = val; trackedConversion.convertType = DataObjects.ConversionType.Smelter; } Fermenter val2 = (prefab.GetComponent<Fermenter>() ?? prefab.GetComponentInChildren<Fermenter>()) ?? prefab.GetComponentInParent<Fermenter>(); if ((Object)(object)val2 != (Object)null) { trackedConversion.originalFermenter = val2; trackedConversion.convertType = DataObjects.ConversionType.Fermenter; } CookingStation val3 = (prefab.GetComponent<CookingStation>() ?? prefab.GetComponentInChildren<CookingStation>()) ?? prefab.GetComponentInParent<CookingStation>(); if ((Object)(object)val3 != (Object)null) { trackedConversion.originalCookingStation = val3; trackedConversion.convertType = DataObjects.ConversionType.CookingStation; } goto IL_018a; } catch (Exception) { Logger.LogWarning("Could not find entries referenced prefab, this modification will be skipped. Define a prefab to modify to fix this."); goto IL_018a; } IL_018a: if ((Object)(object)trackedConversion.originalCookingStation == (Object)null && (Object)(object)trackedConversion.originalFermenter == (Object)null && (Object)(object)trackedConversion.originalSmelter == (Object)null) { Logger.LogWarning(((Object)trackedConversion.prefab).name + " did not have an attached Fermenter, Smelter, or CookingStation. This modification will be skipped."); continue; } switch (trackedConversion.convertType) { case DataObjects.ConversionType.Fermenter: { Logger.LogDebug("Setting Fermenter"); List<ItemConversion> list3 = new List<ItemConversion>(); if (item.Value.conversions != null && item.Value.conversions.Count > 0) { foreach (DataObjects.ConversionDef conversion in item.Value.conversions) { Logger.LogDebug("Creating Conversion " + conversion.fromPrefab + " to " + conversion.toPrefab); GetConversionGOs(conversion, out var togo4, out var fromgo4); if (!((Object)(object)togo4 == (Object)null) && !((Object)(object)fromgo4 == (Object)null)) { ItemConversion val6 = new ItemConversion(); val6.m_to = togo4.GetComponent<ItemDrop>(); val6.m_from = fromgo4.GetComponent<ItemDrop>(); val6.m_producedItems = conversion.amount; list3.Add(val6); } } } trackedConversion.updatedFermenterConversions = list3; break; } case DataObjects.ConversionType.CookingStation: { Logger.LogDebug("Setting CookingStation"); List<ItemConversion> list2 = new List<ItemConversion>(); if (item.Value.conversions != null && item.Value.conversions.Count > 0) { foreach (DataObjects.ConversionDef conversion2 in item.Value.conversions) { Logger.LogDebug("Creating Conversion " + conversion2.fromPrefab + " to " + conversion2.toPrefab); GetConversionGOs(conversion2, out var togo3, out var fromgo3); if (!((Object)(object)togo3 == (Object)null) && !((Object)(object)fromgo3 == (Object)null)) { ItemConversion val5 = new ItemConversion(); val5.m_to = togo3.GetComponent<ItemDrop>(); val5.m_from = fromgo3.GetComponent<ItemDrop>(); val5.m_cookTime = conversion2.cookTime; list2.Add(val5); } } } trackedConversion.updatedCookingConversions = list2; if (item.Value.overCookedTime > 0f) { trackedConversion.overCookedTime = item.Value.overCookedTime; } break; } case DataObjects.ConversionType.Smelter: { Logger.LogDebug("Setting Smelter"); List<ItemConversion> list = new List<ItemConversion>(); if (item.Value.conversions != null && item.Value.conversions.Count > 0) { foreach (DataObjects.ConversionDef conversion3 in item.Value.conversions) { Logger.LogDebug("Creating Conversion " + conversion3.fromPrefab + " to " + conversion3.toPrefab); GetConversionGOs(conversion3, out var togo2, out var fromgo2); if (!((Object)(object)togo2 == (Object)null) && !((Object)(object)fromgo2 == (Object)null)) { ItemConversion val4 = new ItemConversion(); val4.m_to = togo2.GetComponent<ItemDrop>(); val4.m_from = fromgo2.GetComponent<ItemDrop>(); list.Add(val4); } } } trackedConversion.updatedSmelterConversions = list; trackedConversion.fuelPerProduct = item.Value.fuelPerProduct; if (item.Value.maxOres > 0) { trackedConversion.maxOres = item.Value.maxOres; } if (item.Value.maxFuel > 0) { trackedConversion.maxFuel = item.Value.maxFuel; } if (item.Value.fuelItem != null && item.Value.fuelItem != "") { GameObject prefab2 = PrefabManager.Instance.GetPrefab(item.Value.fuelItem); if ((Object)(object)prefab2 != (Object)null && Object.op_Implicit((Object)(object)prefab2.GetComponent<ItemDrop>())) { trackedConversion.requiresFuel = true; } } break; } } if (!flag) { Logger.LogWarning("Conversion request was not valid, skipping."); } else { TrackedConversions.Add(trackedConversion); } } static void GetConversionGOs(DataObjects.ConversionDef conv, out GameObject togo, out GameObject fromgo) { fromgo = PrefabManager.Instance.GetPrefab(conv.fromPrefab); togo = PrefabManager.Instance.GetPrefab(conv.toPrefab); if ((Object)(object)fromgo == (Object)null) { Logger.LogWarning("Conversion could not find " + conv.fromPrefab + ", this conversion will be skipped."); } if ((Object)(object)togo == (Object)null) { Logger.LogWarning("Conversion could not find " + conv.toPrefab + ", this conversion will be skipped."); } } } public static void UpdateConversionModifications(DataObjects.ConversionModificationCollection convMods) { ConversionsToModify.Clear(); foreach (KeyValuePair<string, DataObjects.ConversionModification> conversionModification in convMods.ConversionModifications) { ConversionsToModify.Add(conversionModification.Key, conversionModification.Value); } } public static void UpdateConversionModificationsFromRPC(string rpcRecieved) { Logger.LogInfo("RPC Recieved: " + rpcRecieved); Logger.LogInfo($"RPC Data: {rpcRecieved.Length}"); UpdateConversionModifications(ValConfig.yamldeserializer.Deserialize<DataObjects.ConversionModificationCollection>(rpcRecieved)); } public static void UpdateConversionModificationsFromList(List<DataObjects.ConversionModificationCollection> convMods) { ConversionsToModify.Clear(); foreach (DataObjects.ConversionModificationCollection convMod in convMods) { foreach (KeyValuePair<string, DataObjects.ConversionModification> conversionModification in convMod.ConversionModifications) { ConversionsToModify.Add(conversionModification.Key, conversionModification.Value); } } } } internal class PieceReloadCommand : ConsoleCommand { public override string Name => "RM_Pieces_Reload"; public override string Help => "Resynchronizes piece modifications."; public override bool IsCheat => true; public override void Run(string[] args) { PieceUpdater.RevertPieceModifications(); ValConfig.ReloadPieceFiles(); PieceUpdater.BuildPieceTracker(); PieceUpdater.PieceUpdateRunner(); ValConfig.SendUpdatedPieceConfigs(); } } internal class PiecePrintCommand : ConsoleCommand { public override string Name => "RM_Pieces_PrintAll"; public override string Help => "Prints all the Pieces found."; public override void Run(string[] args) { //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Starting to dump piece list"); } string text = Path.Combine(Paths.ConfigPath, "RecipeManager", "AllPiecesDebug.yaml"); DataObjects.PieceModificationCollection pieceModificationCollection = new DataObjects.PieceModificationCollection(); using StreamWriter streamWriter = new StreamWriter(text); if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Gathering Pieces"); } foreach (Piece item in (from pc in Resources.FindObjectsOfTypeAll<Piece>() where !((Object)pc).name.EndsWith("(Clone)") && !Regex.IsMatch(((Object)pc).name.Trim(), "\\(\\d+\\)") select pc).ToList()) { if ((Object)(object)item == (Object)null || ((Object)item).name == null) { continue; } if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)("Building Piece definition " + item.m_name)); } DataObjects.PieceModification pieceModification = new DataObjects.PieceModification(); pieceModification.action = DataObjects.PieceAction.Enable; pieceModification.EnablePiece = ((Behaviour)item).enabled; pieceModification.CanBeDeconstructed = item.m_canBeRemoved; pieceModification.CultivatedGroundOnly = item.m_cultivatedGroundOnly; pieceModification.ComfortGroup = item.m_comfortGroup; pieceModification.ComfortAmount = item.m_comfort; pieceModification.GroundPlacement = item.m_groundPiece; pieceModification.SpaceRequired = item.m_spaceRequirement; pieceModification.AllowedInDungeon = item.m_allowedInDungeons; pieceModification.CraftingStationConnectionRadius = item.m_connectRadius; pieceModification.MustBeAvobeConnectedStation = item.m_mustBeAboveConnected; pieceModification.OnlyInSelectBiome = item.m_onlyInBiome; pieceModification.PieceCategory = item.m_category; pieceModification.PieceDescription = item.m_description; pieceModification.PieceName = item.m_name; pieceModification.prefab = ((Object)((Component)item).gameObject).name; if ((Object)(object)item.m_craftingStation != (Object)null) { pieceModification.RequiredToPlaceCraftingStation = ((Object)item.m_craftingStation).name; } pieceModification.IsUpgradeForStation = item.m_isUpgrade; List<DataObjects.SimpleRequirement> list = new List<DataObjects.SimpleRequirement>(); if (item.m_resources != null && item.m_resources.Length != 0) { Requirement[] resources = item.m_resources; foreach (Requirement val in resources) { try { list.Add(new DataObjects.SimpleRequirement { amount = val.m_amount, Prefab = ((Object)val.m_resItem).name }); } catch (Exception arg) { if (ValConfig.EnableDebugMode.Value) { Logger.LogWarning((object)$"Piece requirement setup error {val} \n{arg}"); } } } } pieceModification.requirements = list; if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)("Adding " + pieceModification.prefab + " to collection.")); } if (!pieceModificationCollection.PieceModifications.ContainsKey(pieceModification.prefab)) { pieceModificationCollection.PieceModifications.Add(pieceModification.prefab, pieceModification); } if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)("Piece " + pieceModification.prefab + " Added.")); } } if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Serializing and printing recipes."); } string value = ValConfig.yamlserializer.Serialize((object)pieceModificationCollection); streamWriter.WriteLine(value); Logger.LogInfo((object)("Recipes dumped to file " + text)); } } internal class PieceUpdater { public static Dictionary<string, DataObjects.PieceModification> PiecesToModify = new Dictionary<string, DataObjects.PieceModification>(); public static List<DataObjects.TrackedPiece> TrackedPieces = new List<DataObjects.TrackedPiece>(); public static void InitialSychronization() { BuildPieceTracker(); PieceUpdateRunner(); } public static void PieceUpdateRunner() { Logger.LogInfo($"Applying {TrackedPieces.Count} piece modifications"); foreach (DataObjects.TrackedPiece trackedPiece in TrackedPieces) { ApplyPieceModifications(trackedPiece); } } public static void ApplyPieceModifications(DataObjects.TrackedPiece piece) { Logger.LogDebug($"Applying piece ({piece.prefab}) modification action: {piece.action}"); switch (piece.action) { case DataObjects.PieceAction.Disable: DisablePiece(piece); break; case DataObjects.PieceAction.Modify: ModifyPiece(piece); break; case DataObjects.PieceAction.Enable: EnablePiece(piece); break; } } public static void RevertPieceModifications() { foreach (DataObjects.TrackedPiece trackedPiece in TrackedPieces) { RevertPiece(trackedPiece); } } public static void EnablePiece(DataObjects.TrackedPiece piece) { Logger.LogDebug("Enabling " + piece.prefab); PrefabManager.Instance.GetPrefab(piece.prefab).GetComponent<Piece>().m_enabled = true; } private static void RevertPiece(DataObjects.TrackedPiece tpiece) { PrefabManager.Instance.GetPrefab(tpiece.prefab).GetComponent<Piece>(); _ = tpiece.originalPiece; } private static void ModifyPiece(DataObjects.TrackedPiece piece) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) Logger.LogDebug("Modifying " + piece.prefab); Piece component = PrefabManager.Instance.GetPrefab(piece.prefab).GetComponent<Piece>(); if ((Object)(object)component != (Object)null) { if (piece.updatedRequirements != null) { component.m_resources = piece.updatedRequirements; } component.m_craftingStation = piece.RequiredToPlaceCraftingStation; component.m_allowedInDungeons = piece.AllowedInDungeon; component.m_canBeRemoved = piece.CanBeDeconstructed; component.m_category = piece.PieceCategory; if (piece.ComfortAmount != -1) { component.m_comfort = piece.ComfortAmount; } if ((int)piece.ComfortGroup != 0) { component.m_comfortGroup = piece.ComfortGroup; } if (piece.CraftingStationConnectionRadius != -1f) { component.m_connectRadius = piece.CraftingStationConnectionRadius; } if (piece.PieceDescription != null) { component.m_description = piece.PieceDescription; } component.m_enabled = piece.EnablePiece; if (piece.PieceName != null) { component.m_name = piece.PieceName; } component.m_onlyInBiome = piece.OnlyInBiome; component.m_isUpgrade = piece.IsUpgradeForStation; component.m_cultivatedGroundOnly = piece.CultivatedGroundOnly; component.m_mustBeAboveConnected = piece.MustBeAvobeConnectedStation; if (piece.SpaceRequired != -1f) { component.m_spaceRequirement = piece.SpaceRequired; } component.m_groundPiece = piece.GroundPlacement; } } private static void DisablePiece(DataObjects.TrackedPiece piece) { Logger.LogDebug("Modifying " + piece.prefab); PrefabManager.Instance.GetPrefab(piece.prefab).GetComponent<Piece>().m_enabled = false; } public static void BuildPieceTracker() { //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Invalid comparison between Unknown and I4 //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) TrackedPieces.Clear(); foreach (KeyValuePair<string, DataObjects.PieceModification> item in PiecesToModify) { if (item.Key == null) { continue; } Logger.LogInfo("Constructing piece modification for " + item.Key); DataObjects.TrackedPiece trackedPiece = new DataObjects.TrackedPiece(); trackedPiece.action = item.Value.action; trackedPiece.prefab = item.Value.prefab; try { Piece component = PrefabManager.Instance.GetPrefab(item.Value.prefab).GetComponent<Piece>(); trackedPiece.originalPiece = component; } catch (Exception) { Logger.LogWarning("Could not find entries referenced piece, this modification will be skipped. Define a prefab to modify to fix this."); } if (item.Value.action == DataObjects.PieceAction.Enable || item.Value.action == DataObjects.PieceAction.Disable) { TrackedPieces.Add(trackedPiece); continue; } List<Requirement> list = new List<Requirement>(); foreach (DataObjects.SimpleRequirement requirement in item.Value.requirements) { try { ItemDrop component2 = PrefabManager.Instance.GetPrefab(requirement.Prefab).GetComponent<ItemDrop>(); list.Add(new Requirement { m_amount = requirement.amount, m_resItem = component2 }); Logger.LogInfo($"Building requirement with res:{((Object)component2).name} amount:{requirement.amount}"); } catch { Logger.LogWarning("Could not find an itemDrop for resource with name: " + requirement.Prefab); } } trackedPiece.updatedRequirements = list.ToArray(); if (item.Value.RequiredToPlaceCraftingStation != null && item.Value.RequiredToPlaceCraftingStation != "") { if (item.Value.RequiredToPlaceCraftingStation.ToLower() == "none") { trackedPiece.RequiredToPlaceCraftingStation = null; } else { GameObject prefab = PrefabManager.Instance.GetPrefab(item.Value.RequiredToPlaceCraftingStation); CraftingStation val = ((prefab != null) ? prefab.GetComponent<CraftingStation>() : null); if ((Object)(object)val != (Object)null) { trackedPiece.RequiredToPlaceCraftingStation = val; } else { Logger.LogWarning($"Could not link required crafting station, are you sure a crafting station exists with piecename: {val}"); } } } else { trackedPiece.RequiredToPlaceCraftingStation = PrefabManager.Instance.GetPrefab(item.Value.prefab).GetComponent<Piece>().m_craftingStation; } trackedPiece.IsUpgradeForStation = item.Value.IsUpgradeForStation; trackedPiece.AllowedInDungeon = item.Value.AllowedInDungeon; trackedPiece.CanBeDeconstructed = item.Value.CanBeDeconstructed; trackedPiece.ComfortAmount = item.Value.ComfortAmount; trackedPiece.ComfortGroup = item.Value.ComfortGroup; trackedPiece.CraftingStationConnectionRadius = item.Value.CraftingStationConnectionRadius; trackedPiece.PieceDescription = item.Value.PieceDescription; trackedPiece.PieceName = item.Value.PieceName; trackedPiece.EnablePiece = item.Value.EnablePiece; trackedPiece.CultivatedGroundOnly = item.Value.CultivatedGroundOnly; trackedPiece.MustBeAvobeConnectedStation = item.Value.MustBeAvobeConnectedStation; trackedPiece.SpaceRequired = item.Value.SpaceRequired; trackedPiece.GroundPlacement = item.Value.GroundPlacement; if ((int)item.Value.PieceCategory != 100) { trackedPiece.PieceCategory = item.Value.PieceCategory; } else { trackedPiece.PieceCategory = trackedPiece.originalPiece.m_category; } TrackedPieces.Add(trackedPiece); } } public static void UpdatePieceModificationsFromList(List<DataObjects.PieceModificationCollection> lPieceMods) { PiecesToModify.Clear(); foreach (DataObjects.PieceModificationCollection lPieceMod in lPieceMods) { foreach (KeyValuePair<string, DataObjects.PieceModification> pieceModification in lPieceMod.PieceModifications) { PiecesToModify.Add(pieceModification.Key, pieceModification.Value); } } } public static void UpdatePieceModificationsFromRPC(string rpcRecieved) { Logger.LogInfo("RPC Recieved: " + rpcRecieved); Logger.LogInfo($"RPC Data: {rpcRecieved.Length}"); UpdatePieceModifications(ValConfig.yamldeserializer.Deserialize<DataObjects.PieceModificationCollection>(rpcRecieved)); } public static void UpdatePieceModifications(DataObjects.PieceModificationCollection PieceMods) { PiecesToModify.Clear(); foreach (KeyValuePair<string, DataObjects.PieceModification> pieceModification in PieceMods.PieceModifications) { PiecesToModify.Add(pieceModification.Key, pieceModification.Value); } } } internal class RecipeReloadCommand : ConsoleCommand { public override string Name => "RM_Recipes_Reload"; public override string Help => "Resynchronizes recipes."; public override bool IsCheat => true; public override void Run(string[] args) { RecipeUpdater.RecipeRevert(); ValConfig.ReloadRecipeFiles(); RecipeUpdater.BuildRecipesForTracking(); RecipeUpdater.SecondaryRecipeSync(); ValConfig.SendUpdatedRecipeConfigs(); } } internal class RecipeUnapplyCommand : ConsoleCommand { public override string Name => "RM_Recipes_Unapply"; public override string Help => "Removes recipe modifications."; public override bool IsCheat => true; public override void Run(string[] args) { RecipeUpdater.RecipeRevert(); } } internal class RecipePrintCommand : ConsoleCommand { public override string Name => "RM_Recipes_PrintAll"; public override string Help => "Prints all the recipes stored in the Object DB"; public override void Run(string[] args) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Starting to dump recipes"); } string text = Path.Combine(Paths.ConfigPath, "RecipeManager", "ObjectDBRecipes.yaml"); DataObjects.RecipeModificationCollection recipeModificationCollection = new DataObjects.RecipeModificationCollection(); using StreamWriter streamWriter = new StreamWriter(text); if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Loading recipes from ODB"); } foreach (Recipe item in ObjectDB.instance.m_recipes.ToList()) { if ((Object)(object)item == (Object)null || ((Object)item).name == null) { continue; } if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)("Building Recipe " + ((Object)item).name)); } DataObjects.RecipeModification recipeModification = new DataObjects.RecipeModification(); recipeModification.recipeName = ((Object)item).name; recipeModification.minStationLevel = (short)item.m_minStationLevel; recipeModification.craftAmount = (short)item.m_amount; recipeModification.action = DataObjects.Action.Enable; if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Checking for empty referenced objects"); } if ((Object)(object)item.m_craftingStation != (Object)null) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Adding crafting station"); } recipeModification.craftedAt = ((Object)item.m_craftingStation).name; } if ((Object)(object)item.m_repairStation != (Object)null) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Adding repair station"); } recipeModification.repairAt = ((Object)item.m_repairStation).name; } if ((Object)(object)item.m_item != (Object)null) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Adding prefab"); } recipeModification.prefab = ((Object)item.m_item).name; } DataObjects.SimpleRecipe simpleRecipe = new DataObjects.SimpleRecipe(); if (item.m_resources != null && item.m_resources.Length != 0) { simpleRecipe.anyOneResource = item.m_requireOnlyOneIngredient; if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Building resource requirements"); } Requirement[] resources = item.m_resources; foreach (Requirement val in resources) { try { DataObjects.Ingrediant ingrediant = new DataObjects.Ingrediant(); if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Setting crafting cost"); } ingrediant.craftCost = (short)val.m_amount; if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Setting upgrade cost"); } ingrediant.upgradeCost = (short)val.m_amountPerLevel; if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Setting prefab name"); } if ((Object)(object)val.m_resItem != (Object)null) { ingrediant.prefab = ((Object)val.m_resItem).name; } if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Adding to ingrediants list"); } simpleRecipe.ingredients.Add(ingrediant); } catch (Exception arg) { if (ValConfig.EnableDebugMode.Value) { Logger.LogWarning((object)$"Requirement did not contain all of the details required to set an ingrediant {val} \n{arg}"); } } } } if (simpleRecipe.ingredients != null && simpleRecipe.ingredients.Count > 0) { recipeModification.recipe = simpleRecipe; } if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)("Adding " + ((Object)item).name + " to collection.")); } if (recipeModificationCollection.RecipeModifications.ContainsKey(((Object)item).name)) { try { int num = Random.Range(0, 1000); recipeModificationCollection.RecipeModifications.Add(((Object)item).name + $"_{num}", recipeModification); Logger.LogWarning((object)$"{((Object)item).name} was already added to the list of recipes and will be renamed {((Object)item).name}_{num}, please use unique recipe names."); } catch { Logger.LogWarning((object)(((Object)item).name + " was already added to the list of recipes and will be skipped, please use unique recipe names.")); } } else { recipeModificationCollection.RecipeModifications.Add(((Object)item).name, recipeModification); } if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)("Recipe " + ((Object)item).name + " Added.")); } } if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Serializing and printing recipes."); } string value = ValConfig.yamlserializer.Serialize((object)recipeModificationCollection); streamWriter.WriteLine(value); Logger.LogInfo((object)("Recipes dumped to file " + text)); } } [BepInPlugin("MidnightsFX.RecipeManager", "RecipeManager", "0.5.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] internal class RecipeManager : BaseUnityPlugin { public const string PluginGUID = "MidnightsFX.RecipeManager"; public const string PluginName = "RecipeManager"; public const string PluginVersion = "0.5.1"; public ValConfig cfg; public static ManualLogSource Log; public void Awake() { Log = ((BaseUnityPlugin)this).Logger; cfg = new ValConfig(((BaseUnityPlugin)this).Config); ItemManager.OnItemsRegistered += RecipeUpdater.InitialRecipesAndSynchronize; ItemManager.OnItemsRegistered += PieceUpdater.InitialSychronization; ItemManager.OnItemsRegistered += ConversionUpdater.InitialSychronization; MinimapManager.OnVanillaMapDataLoaded += RecipeUpdater.SecondaryRecipeSync; MinimapManager.OnVanillaMapDataLoaded += PieceUpdater.PieceUpdateRunner; MinimapManager.OnVanillaMapDataLoaded += ConversionUpdater.ConversionUpdateRunner; CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new RecipeReloadCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new RecipePrintCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new RecipeUnapplyCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new PiecePrintCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new PieceReloadCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ConversionPrintCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ConversionReloadCommand()); } } internal class RecipeUpdater { public static Dictionary<string, DataObjects.RecipeModification> RecipesToModify = new Dictionary<string, DataObjects.RecipeModification>(); public static List<DataObjects.TrackedRecipe> TrackedRecipes = new List<DataObjects.TrackedRecipe>(); public static void SecondaryRecipeSync() { if (TrackedRecipes.Count == 0) { return; } foreach (DataObjects.TrackedRecipe trackedRecipe in TrackedRecipes) { if (!CheckIfRecipeWasModified(trackedRecipe)) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)("Tracked " + trackedRecipe.prefab + " recipe still has its original recipe in the db. Modifying.")); } ApplyRecipeModifcations(trackedRecipe); } } } public static void RecipeRevert() { foreach (DataObjects.TrackedRecipe trackedRecipe in TrackedRecipes) { ReverseRecipeModifications(trackedRecipe); } } public static void InitialRecipesAndSynchronize() { BuildRecipesForTracking(); RecipeUpdateRunner(); } public static void RecipeUpdateRunner() { foreach (DataObjects.TrackedRecipe trackedRecipe in TrackedRecipes) { ApplyRecipeModifcations(trackedRecipe); } } public static void ApplyRecipeModifcations(DataObjects.TrackedRecipe tracked_recipe) { if (ValConfig.EnableDebugMode.Value) { if ((Object)(object)tracked_recipe.updatedRecipe != (Object)null) { string text = ""; Requirement[] resources = tracked_recipe.updatedRecipe.m_resources; foreach (Requirement val in resources) { text += $" {val.m_resItem},{val.m_amount},{val.m_amountPerLevel}"; } Logger.LogInfo((object)("Applying Updated Recipe: " + ((Object)tracked_recipe.updatedRecipe).name + "\n" + $"amount:{tracked_recipe.updatedRecipe.m_amount}\n" + $"enabled:{tracked_recipe.updatedRecipe.m_enabled}\n" + $"craftingStation:{tracked_recipe.updatedRecipe.m_craftingStation}\n" + $"reqStationLevel:{tracked_recipe.updatedRecipe.m_minStationLevel}\n" + $"reqOneIngrediant:{tracked_recipe.updatedRecipe.m_requireOnlyOneIngredient}\n" + "resources:" + text)); } if ((Object)(object)tracked_recipe.originalRecipe != (Object)null) { string text2 = ""; Requirement[] resources = tracked_recipe.originalRecipe.m_resources; foreach (Requirement val2 in resources) { text2 += $" {val2.m_resItem},{val2.m_amount},{val2.m_amountPerLevel}"; } Logger.LogInfo((object)("Targeting Original Recipe: " + ((Object)tracked_recipe.originalRecipe).name + "\n" + $"amount:{tracked_recipe.originalRecipe.m_amount}\n" + $"enabled:{tracked_recipe.originalRecipe.m_enabled}\n" + $"amount:{tracked_recipe.originalRecipe.m_amount}\n" + $"craftingStation:{tracked_recipe.originalRecipe.m_craftingStation}\n" + $"reqStationLevel:{tracked_recipe.originalRecipe.m_minStationLevel}\n" + $"reqOneIngrediant:{tracked_recipe.originalRecipe.m_requireOnlyOneIngredient}\n" + "resources:" + text2)); } } bool flag = false; if (tracked_recipe.action == DataObjects.Action.Disable) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)("Disable Action called for " + tracked_recipe.prefab + " recipe")); } flag = DisableRecipe(tracked_recipe.originalRecipe); } if (tracked_recipe.action == DataObjects.Action.Delete) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)("Delete Action called for " + tracked_recipe.prefab + " recipe")); } flag = DeleteRecipe(tracked_recipe.originalRecipe); } if (tracked_recipe.action == DataObjects.Action.Modify) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)("Modify Action called for " + tracked_recipe.prefab + " recipe")); } if (ObjectDB.instance.m_recipes.Contains(tracked_recipe.updatedRecipe)) { DeleteRecipe(tracked_recipe.originalRecipe); flag = true; } else if (ObjectDB.instance.m_recipes.Contains(tracked_recipe.originalRecipe)) { flag = ModifyRecipeInODB(tracked_recipe.originalRecipe, tracked_recipe.updatedRecipe); ModifyRecipeInJotunnManager(tracked_recipe.originalCustomRecipe, tracked_recipe.updatedCustomRecipe); } } if (tracked_recipe.action == DataObjects.Action.Add) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)("Add Action called for " + tracked_recipe.prefab + " recipe")); } flag = AddRecipe(tracked_recipe.updatedRecipe); } if (tracked_recipe.action == DataObjects.Action.Enable) { if (ValConfig.EnableDebugMode.Value) { Logger.LogWarning((object)("Enable Action called for " + tracked_recipe.prefab + " recipe. Are you sure you wanted that? Most recipes are already enabled.")); } flag = EnableRecipe(tracked_recipe.originalRecipe); } if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)$"{tracked_recipe.prefab} recipe update applied? {flag}"); } } public static void ReverseRecipeModifications(DataObjects.TrackedRecipe tracked_recipe) { bool flag = false; if (tracked_recipe.action == DataObjects.Action.Disable) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)("Reverting disable for " + tracked_recipe.prefab + " recipe")); } flag = EnableRecipe(tracked_recipe.originalRecipe); } if (tracked_recipe.action == DataObjects.Action.Delete) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)("Reverting delete for " + tracked_recipe.prefab + " recipe")); } flag = AddRecipe(tracked_recipe.originalRecipe); } if (tracked_recipe.action == DataObjects.Action.Modify) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)("Reversing modify for " + tracked_recipe.prefab + " recipe")); } flag = ModifyRecipeInODB(tracked_recipe.updatedRecipe, tracked_recipe.originalRecipe); ModifyRecipeInJotunnManager(tracked_recipe.updatedCustomRecipe, tracked_recipe.originalCustomRecipe); } if (tracked_recipe.action == DataObjects.Action.Add) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)("Reverting add for " + tracked_recipe.prefab + " recipe")); } flag = DeleteRecipe(tracked_recipe.updatedRecipe); } if (tracked_recipe.action == DataObjects.Action.Enable) { flag = DisableRecipe(tracked_recipe.originalRecipe); } if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)$"{tracked_recipe.prefab} recipe modification reverted? {flag}"); } } public static bool CheckIfRecipeWasModified(DataObjects.TrackedRecipe trackedRecipe) { bool flag = true; if ((trackedRecipe.action == DataObjects.Action.Modify || trackedRecipe.action == DataObjects.Action.Delete) && ObjectDB.instance.m_recipes.IndexOf(trackedRecipe.originalRecipe) > 0) { flag = false; } if (trackedRecipe.action == DataObjects.Action.Add && ObjectDB.instance.m_recipes.IndexOf(trackedRecipe.updatedRecipe) < 0) { flag = false; } if (trackedRecipe.action == DataObjects.Action.Enable || trackedRecipe.action == DataObjects.Action.Disable) { flag = false; } if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)$"recipe {trackedRecipe.recipeName} already modified? {flag}"); } return flag; } public static void BuildRecipesForTracking() { //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Expected O, but got Unknown //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Expected O, but got Unknown //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Expected O, but got Unknown if (RecipesToModify.Count == 0) { return; } TrackedRecipes.Clear(); foreach (KeyValuePair<string, DataObjects.RecipeModification> item2 in RecipesToModify) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)("Constructing modification details for " + item2.Key)); } DataObjects.TrackedRecipe trackedRecipe = new DataObjects.TrackedRecipe(); trackedRecipe.action = item2.Value.action; trackedRecipe.prefab = item2.Value.prefab; int num = -1; if (item2.Value.recipeName != null) { num = RecipeIndexForRecipeName(item2.Value.recipeName); trackedRecipe.recipeName = item2.Value.recipeName; } if (num == -1) { num = RecipeIndexForPrefab(item2.Value.prefab); } if (num > -1) { trackedRecipe.originalRecipe = ObjectDB.instance.m_recipes[num]; } else if (ValConfig.EnableDebugMode.Value) { Logger.LogWarning((object)("Could not find recipe for: " + item2.Value.prefab)); } if (item2.Value.recipe != null) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Found custom recipe modifications, building out definition."); } RequirementConfig[] array = (RequirementConfig[])(object)new RequirementConfig[0]; if (!item2.Value.recipe.noRecipeCost) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Setting recipe cost requirements."); } array = (RequirementConfig[])(object)new RequirementConfig[item2.Value.recipe.ingredients.Count]; int num2 = 0; foreach (DataObjects.Ingrediant ingredient in item2.Value.recipe.ingredients) { array[num2] = new RequirementConfig { Item = ingredient.prefab, Amount = ingredient.craftCost, AmountPerLevel = ingredient.upgradeCost, Recover = false }; num2++; } } if (item2.Value.repairAt == null) { item2.Value.repairAt = item2.Value.craftedAt; } CustomRecipe val2 = new CustomRecipe(new RecipeConfig { Name = ((trackedRecipe.recipeName != null) ? trackedRecipe.recipeName : ("Recipe_" + item2.Value.prefab)), Amount = item2.Value.craftAmount, CraftingStation = item2.Value.craftedAt, RepairStation = item2.Value.repairAt, MinStationLevel = item2.Value.minStationLevel, Enabled = (item2.Value.action != DataObjects.Action.Disable), RequireOnlyOneIngredient = item2.Value.recipe.anyOneResource, Requirements = array }); if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Built new custom recipe."); } Recipe recipe = val2.Recipe; CustomItem item = ItemManager.Instance.GetItem(item2.Value.prefab); if (item != null) { if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Found existing custom item, storing for comparision."); } trackedRecipe.originalCustomRecipe = item.Recipe; } if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Resolving references on custom recipe."); } if (item2.Value.craftedAt != null) { try { GameObject prefab = PrefabManager.Instance.GetPrefab(item2.Value.craftedAt); CraftingStation val3 = ((prefab != null) ? prefab.GetComponent<CraftingStation>() : null); if (item2.Value.craftedAt != item2.Value.repairAt) { GameObject prefab2 = PrefabManager.Instance.GetPrefab(item2.Value.repairAt); if (prefab2 != null) { prefab2.GetComponent<CraftingStation>(); } } recipe.m_repairStation = val3; recipe.m_craftingStation = val3; } catch { Logger.LogWarning((object)("Crafting station (" + item2.Value.craftedAt + ") or repair station (" + item2.Value.repairAt + ") could not be resolved or did not have a craftingStation component")); } } if (item2.Value.repairAt != null) { try { GameObject prefab3 = PrefabManager.Instance.GetPrefab(item2.Value.repairAt); CraftingStation repairStation = ((prefab3 != null) ? prefab3.GetComponent<CraftingStation>() : null); recipe.m_repairStation = repairStation; } catch { Logger.LogWarning((object)("Repair station (" + item2.Value.repairAt + ") could not be resolved or did not have a craftingStation component")); } } try { GameObject prefab4 = PrefabManager.Instance.GetPrefab(item2.Value.prefab); ItemDrop component = prefab4.GetComponent<ItemDrop>(); if (!((Object)(object)component != (Object)null)) { Logger.LogWarning((object)$"Could not find a prefab ({item2.Value.prefab}) GO ({prefab4}) with an ItemDrop ({component}) component to reference. This recipe will not have a target and will be skipped."); continue; } recipe.m_item = component; } catch { Logger.LogWarning((object)("Could not find a prefab (" + item2.Value.prefab + ") with an ItemDrop component to reference. This recipe will not have a target and will be skipped.")); continue; } ((Object)recipe).name = "Recipe_" + item2.Key; if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Resolving resource requirement references."); } Requirement[] resources = recipe.m_resources; foreach (Requirement val4 in resources) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(((Object)val4.m_resItem).name.Replace("JVLmock_", "")); if ((Object)(object)itemPrefab != (Object)null) { val4.m_resItem = itemPrefab.GetComponent<ItemDrop>(); } else { Logger.LogWarning((object)("Could not resolve itemdrop reference for: " + ((Object)val4.m_resItem).name + ". This requirement will be deleted.")); } } recipe.m_resources.Where((Requirement val) => ((object)val.m_resItem).GetType() == typeof(ItemDrop)).ToArray(); trackedRecipe.updatedRecipe = recipe; trackedRecipe.updatedCustomRecipe = val2; if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Set updated recipe and updatedCustomRecipe."); } } if (ValConfig.EnableDebugMode.Value) { Logger.LogInfo((object)"Adding tracked Recipe"); } TrackedRecipes.Add(trackedRecipe); } } public static int RecipeIndexForPrefab(string prefab) { return ObjectDB.instance.m_recipes.FindIndex((Recipe m) => (Object)(object)m.m_item != (Object)null && ((Object)m.m_item).name == prefab); } public static int RecipeIndexForRecipeName(string recipe_name) { return ObjectDB.instance.m_recipes.FindIndex((Recipe m) => ((Object)m).name != null && ((Object)m).name == recipe_name); } public static bool ModifyRecipeInJotunnManager(CustomRecipe recipe, CustomRecipe newRecipe) { if (AccessTools.Field(typeof(ItemManager), "Recipes").GetValue(ItemManager.Instance) is HashSet<CustomRecipe> hashSet) { if (hashSet.Contains(newRecipe)) { return true; } if (hashSet.Contains(recipe)) { hashSet.Remove(recipe); hashSet.Add(newRecipe); } return true; } return false; } public static bool ModifyRecipeInODB(Recipe recipe, Recipe newRecipe) { int num = ObjectDB.instance.m_recipes.IndexOf(recipe); if (num > -1) { ObjectDB.instance.m_recipes[num] = newRecipe; return true; } return false; } public static bool DisableRecipe(Recipe recipe) { int num = ObjectDB.instance.m_recipes.IndexOf(recipe); if (num > -1) { ObjectDB.instance.m_recipes[num].m_enabled = false; return true; } return false; } public static bool EnableRecipe(Recipe recipe) { int num = ObjectDB.instance.m_recipes.IndexOf(recipe); if (num > -1) { ObjectDB.instance.m_recipes[num].m_enabled = true; return true; } return false; } public static bool DeleteRecipe(Recipe recipe) { return ObjectDB.instance.m_recipes.Remove(recipe); } public static bool AddRecipe(Recipe recipe) { if (!ObjectDB.instance.m_recipes.Contains(recipe)) { ObjectDB.instance.m_recipes.Add(recipe); } return true; } public static void UpdateRecipeModifications(DataObjects.RecipeModificationCollection recipeMods) { RecipesToModify.Clear(); foreach (KeyValuePair<string, DataObjects.RecipeModification> recipeModification in recipeMods.RecipeModifications) { RecipesToModify.Add(recipeModification.Key, recipeModification.Value); } } public static void UpdateRecipeModificationsFromList(List<DataObjects.RecipeModificationCollection> lRecipeMods) { RecipesToModify.Clear(); foreach (DataObjects.RecipeModificationCollection lRecipeMod in lRecipeMods) { foreach (KeyValuePair<string, DataObjects.RecipeModification> recipeModification in lRecipeMod.RecipeModifications) { RecipesToModify.Add(recipeModification.Key, recipeModification.Value); } } } } } namespace RecipeManager.Common { internal class ValConfig { [CompilerGenerated] private sealed class <OnClientReceiveConversionConfigs>d__35 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ZPackage package; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnClientReceiveConversionConfigs>d__35(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; string rpcRecieved = package.ReadString(); ConversionUpdater.RevertConversionModifications(); try { ConversionUpdater.UpdateConversionModificationsFromRPC(rpcRecieved); } catch { Logger.LogWarning("Recieved invalid configuration, conversions changes ignored."); } ConversionUpdater.BuildConversionTracker(); ConversionUpdater.ConversionUpdateRunner(); <>2__current = null; <>1__state = 1; return true; } case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <OnClientReceivePieceConfigs>d__34 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ZPackage package; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnClientReceivePieceConfigs>d__34(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; string text = package.ReadString(); PieceUpdater.RevertPieceModifications(); try { PieceUpdater.UpdatePieceModificationsFromRPC(text); PieceUpdater.UpdatePieceModifications(yamldeserializer.Deserialize<DataObjects.PieceModificationCollection>(text)); } catch { Logger.LogWarning("Recieved invalid configuration, pieces changes ignored."); } PieceUpdater.BuildPieceTracker(); PieceUpdater.PieceUpdateRunner(); <>2__current = null; <>1__state = 1; return true; } case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <OnClientReceiveRecipeConfigs>d__33 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ZPackage package; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnClientReceiveRecipeConfigs>d__33(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; string text = package.ReadString(); RecipeUpdater.RecipeRevert(); try { RecipeUpdater.UpdateRecipeModifications(yamldeserializer.Deserialize<DataObjects.RecipeModificationCollection>(text)); } catch { Logger.LogWarning("Recieved invalid configuration, all recipes reverted."); } RecipeUpdater.BuildRecipesForTracking(); RecipeUpdater.SecondaryRecipeSync(); <>2__current = null; <>1__state = 1; return true; } case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <OnServerRecieveConfigs>d__25 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnServerRecieveConfigs>d__25(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (EnableDebugMode.Value) { Logger.LogInfo("Server recieved config from client, rejecting due to being the server."); } <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static ConfigFile cfg; public static ConfigEntry<bool> EnableDebugMode; public static string recipeConfigFilePath = Path.Combine(Paths.ConfigPath, "RecipeManager", "Recipes.yaml"); public static List<string> RecipeConfigFilePaths = new List<string>(); public static string pieceConfigFilePath = Path.Combine(Paths.ConfigPath, "RecipeManager", "Pieces.yaml"); public static List<string> PieceConfigFilePaths = new List<string>(); public static string ConversionConfigFilePath = Path.Combine(Paths.ConfigPath, "RecipeManager", "Conversions.yaml"); public static List<string> ConversionConfigFilePaths = new List<string>(); public static IDeserializer yamldeserializer = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); public static ISerializer yamlserializer = ((BuilderSkeleton<SerializerBuilder>)new SerializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).ConfigureDefaultValuesHandling((DefaultValuesHandling)2).Build(); private static CustomRPC RecipeConfigRPC; private static CustomRPC PiecesConfigRPC; private static CustomRPC ConversionConfigRPC; public ValConfig(ConfigFile cfgref) { cfg = cfgref; cfg.SaveOnConfigSet = true; CreateConfigValues(cfgref); SetupSecondaryConfigFile(); SetupConfigRPCs(); } private void CreateConfigValues(ConfigFile Config) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown EnableDebugMode = Config.Bind<bool>("Client config", "EnableDebugMode", false, new ConfigDescription("Enables Debug logging for Recipe Manager. This is client side and is not syncd with the server.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdvanced = true } })); EnableDebugMode.SettingChanged += Logger.enableDebugLogging; Logger.CheckEnableDebugLogging(); } private static void SetupSecondaryConfigFile() { string secondaryConfigDirectoryPath = GetSecondaryConfigDirectoryPath(); bool flag = false; bool flag2 = false; bool flag3 = false; string[] files = Directory.GetFiles(secondaryConfigDirectoryPath); foreach (string text in files) { if (text.Contains("Recipes.yaml") && !text.Contains("ObjectDBRecipes.yaml")) { if (EnableDebugMode.Value) { Logger.LogInfo("Found recipe configuration yaml: " + text); } RecipeConfigFilePaths.Add(text); flag = true; } if (text.Contains("Pieces.yaml")) { if (EnableDebugMode.Value) { Logger.LogInfo("Found pieces configuration yaml: " + text); } PieceConfigFilePaths.Add(text); flag2 = true; } if (text.Contains("Conversions.yaml")) { if (EnableDebugMode.Value) { Logger.LogInfo("Found Conversion configuration yaml: " + text); } ConversionConfigFilePaths.Add(text); flag3 = true; } } if (!flag) { Logger.LogInfo("Recipe file missing, recreating."); using StreamWriter streamWriter = new StreamWriter(recipeConfigFilePath); string value = "#################################################\n# Recipe Manipulation Config\n#################################################\n# recipeModifications: # <- This is the top level key, all modifications live under this, it is required.\n# DisableWoodArrow: # <- This is the modification name, its primarily for you to understand what this modification does SHOULD BE UNIQUE\n# action: Disable # <- This is the action it should be one of [Disable, Delete, Modify, Add, Enable]\n# prefab: ArrowWood # <- This is the prefab that the modification will target\n# AddNewWoodArrowRecipe:\n# action: Add\n# prefab: ArrowWood\n# recipeName: Recipe_ArrowWood # <- optional, specifying the recipe name allows matching and mutating multiple recipes targeting the same prefab\n# craftedAt: Workbench # <- The crafting station that should craft this recipe, leave it empty or invalid for handcrafting\n# minStationLevel: 2 # <- This is the required crafting station level for discovery AND crafting\n# recipe: # <- When performing [Modify] or [Add] you should define a recipe\n# anyOneResource: false # <- This makes the recipe only require one ingrediant, first from the top will be used.\n# noRecipeCost: false # <- This makes the recipe not require any resources to craft, if this is used the ingredients list will be ignored\n# ingredients: # <- Ingrediants in the recipe, is an array\n# - prefab: Wood # <- Prefab that this ingrediant requires\n# craftCost: 2 # <- The amount of this ingrediant it takes to craft the recipe \n# upgradeCost: 0 # <- The amount of this ingrediant it takes to upgrade the item \n# - prefab: Feathers\n# craftCost: 2\n# upgradeCost: 0\n# DeleteTrollHideArmorRecipe:\n# action: Delete\n# prefab: CapeTrollHide\n# ModifyTrollHideChestRecipe:\n# action: Modify\n# prefab: ArmorTrollLeatherChest\n# craftedAt: Workbench\n# minStationLevel: 1\n# recipe:\n# anyOneResource: false\n# ingredients:\n# - prefab: TrollHide\n# craftCost: 4\n# upgradeCost: 2\n"; streamWriter.WriteLine(value); streamWriter.WriteLine(YamlRecipeConfigDefinition()); } if (!flag2) { Logger.LogInfo("Pieces file missing, recreating."); using StreamWriter streamWriter2 = new StreamWriter(pieceConfigFilePath); string value2 = "############################################################################\n# Piece Manipulation Config\n############################################################################\n# pieceModifications: # <- This is the top level key, it is required\n# modify_the_bed: # <- REQUIRED The name of this modification, it should be unique but is for your information\n# action: Enable # <- REQUIRED This is the action applied can be [Enable, Disable, Modify]\n# prefab: bed # <- REQUIRED This is the prefab that the action will be applied to\n# requirements: # <- If the piece is being modified, you can set requirements which will be the cost to build this\n# - prefab: Wood # <- Each requirement entry requires a prefab name, you can find item prefabs on the valheim wiki\n# amount: 8 # <- The amount of the prefab required\n# requiredToPlaceCraftingStation: piece_workbench # <- The crafting station used to place this item, if it is set to 'none' it will remove the station requirement\n# allowedInDungeon: false # <- If you can build this inside dungeons\n# canBeDeconstructed: true # <- If this can be broken with middle mouse\n# pieceCategory: Furniture # <- The category tab this will be placed in. This can be any of the categories across any available tools\n# comfortAmount: 1 # <- If above 0 this item will provide comfort\n# comfortGroup: Bed # <- The comfort group this is a part of\n# isUpgradeForStation: false # <- If this piece is considered an upgrade for a crafting station\n# craftingStationConnectionRadius: 0 # <- The radius that this will connect to a crafting station\n# mustBeAvobeConnectedStation: false # <- If this upgrade must be placed ABOVE its crafting station- this is normally only used for hanging upgrades for the cooking station\n# spaceRequired: 0 # <- How much space is required for this item\n# pieceName: $piece_bed # <- The localizable name for this, setting \"My Bed\" will make this piece called \"My Bed\"\n# pieceDescription: '' # <- The description for this piece, many pieces do not have this\n# enablePiece: true # <- Whether or not this piece is enabled\n# onlyInSelectBiome: None # <- Whether or not this can be placed in only one biome, in vanilla this is used for plants\n# cultivatedGroundOnly: false # <- Whether this piece needs to be placed on cultivated ground\n# groundPlacement: false # <- Whether this piece needs to be placed on ground (stone is also considered ground)"; streamWriter2.WriteLine(value2); streamWriter2.WriteLine(YamlPieceConfigDefinition()); } if (!flag3) { Logger.LogInfo("Conversion file missing, recreating."); using StreamWriter streamWriter3 = new StreamWriter(ConversionConfigFilePath); string value3 = "############################################################################\n# Conversion Manipulation Config\n############################################################################\n"; streamWriter3.WriteLine(value3); streamWriter3.WriteLine(YamlConversionConfigDefinition()); } List<DataObjects.RecipeModificationCollection> list = new List<DataObjects.RecipeModificationCollection>(); foreach (string recipeConfigFilePath in RecipeConfigFilePaths) { string text2 = File.ReadAllText(recipeConfigFilePath); try { DataObjects.RecipeModificationCollection item = yamldeserializer.Deserialize<DataObjects.RecipeModificationCollection>(text2); list.Add(item); } catch (Exception arg) { Logger.LogError($"There was an error reading recipe data from {recipeConfigFilePath}, it will not be used. Error: {arg}"); } FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(); fileSystemWatcher.Path = secondaryConfigDirectoryPath; fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite; fileSystemWatcher.Filter = DetermineFileName(recipeConfigFilePath) ?? ""; fileSystemWatcher.Changed += UpdateRecipeConfigFilesOnChange; fileSystemWatcher.Created += UpdateRecipeConfigFilesOnChange; fileSystemWatcher.Renamed += UpdateRecipeConfigFilesOnChange; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } RecipeUpdater.UpdateRecipeModificationsFromList(list); List<DataObjects.PieceModificationCollection> list2 = new List<DataObjects.PieceModificationCollection>(); foreach (string pieceConfigFilePath in PieceConfigFilePaths) { string text3 = File.ReadAllText(pieceConfigFilePath); try { DataObjects.PieceModificationCollection item2 = yamldeserializer.Deserialize<DataObjects.PieceModificationCollection>(text3); list2.Add(item2); } catch (Exception arg2) { Logger.LogError($"There was an error reading piece data from {pieceConfigFilePath}, it will not be used. Error: {arg2}"); } FileSystemWatcher fileSystemWatcher2 = new FileSystemWatcher(); fileSystemWatcher2.Path = secondaryConfigDirectoryPath; fileSystemWatcher2.NotifyFilter = NotifyFilters.LastWrite; fileSystemWatcher2.Filter = DetermineFileName(pieceConfigFilePath) ?? ""; fileSystemWatcher2.Changed += UpdatePieceConfigFilesOnChange; fileSystemWatcher2.Created += UpdatePieceConfigFilesOnChange; fileSystemWatcher2.Renamed += UpdatePieceConfigFilesOnChange; fileSystemWatcher2.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher2.EnableRaisingEvents = true; } PieceUpdater.UpdatePieceModificationsFromList(list2); List<DataObjects.ConversionModificationCollection> list3 = new List<DataObjects.ConversionModificationCollection>(); foreach (string conversionConfigFilePath in ConversionConfigFilePaths) { string text4 = File.ReadAllText(conversionConfigFilePath); try { DataObjects.ConversionModificationCollection item3 = yamldeserializer.Deserialize<DataObjects.ConversionModificationCollection>(text4); list3.Add(item3); } catch (Exception arg3) { Logger.LogError($"There was an error reading conversion data from {conversionConfigFilePath}, it will not be used. Error: {arg3}"); } FileSystemWatcher fileSystemWatcher3 = new FileSystemWatcher(); fileSystemWatcher3.Path = secondaryConfigDirectoryPath; fileSystemWatcher3.NotifyFilter = NotifyFilters.LastWrite; fileSystemWatcher3.Filter = DetermineFileName(conversionConfigFilePath) ?? ""; fileSystemWatcher3.Changed += UpdateConversionConfigFilesOnChange; fileSystemWatcher3.Created += UpdateConversionConfigFilesOnChange; fileSystemWatcher3.Renamed += UpdateConversionConfigFilesOnChange; fileSystemWatcher3.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher3.EnableRaisingEvents = true; } ConversionUpdater.UpdateConversionModificationsFromList(list3); } internal static void ReloadPieceFiles() { List<DataObjects.PieceModificationCollection> list = new List<DataObjects.PieceModificationCollection>(); foreach (string pieceConfigFilePath in PieceConfigFilePaths) { string text = File.ReadAllText(pieceConfigFilePath); try { DataObjects.PieceModificationCollection item = yamldeserializer.Deserialize<DataObjects.PieceModificationCollection>(text); list.Add(item); } catch (Exception arg) { Logger.LogError($"There was an error reading piece data from {pieceConfigFilePath}, it will not be used. Error: {arg}"); } } PieceUpdater.UpdatePieceModificationsFromList(list); } internal static void ReloadConversionFiles() { List<DataObjects.ConversionModificationCollection> list = new List<DataObjects.ConversionModificationCollection>(); foreach (string conversionConfigFilePath in ConversionConfigFilePaths) { string text = File.ReadAllText(conversionConfigFilePath); try { DataObjects.ConversionModificationCollection item = yamldeserializer.Deserialize<DataObjects.ConversionModificationCollection>(text); list.Add(item); } catch (Exception arg) { Logger.LogError($"There was an error reading piece data from {conversionConfigFilePath}, it will not be used. Error: {arg}"); } } ConversionUpdater.UpdateConversionModificationsFromList(list); } internal static void ReloadRecipeFiles() { List<DataObjects.RecipeModificationCollection> list = new List<DataObjects.RecipeModificationCollection>(); foreach (string recipeConfigFilePath in RecipeConfigFilePaths) { string text = File.ReadAllText(recipeConfigFilePath); try { DataObjects.RecipeModificationCollection item = yamldeserializer.Deserialize<DataObjects.RecipeModificationCollection>(text); list.Add(item); } catch (Exception arg) { Logger.LogError($"There was an error reading recipe data from {recipeConfigFilePath}, it will not be used. Error: {arg}"); } } RecipeUpdater.UpdateRecipeModificationsFromList(list); } private static string DetermineFileName(string fullfilepath) { string[] array = fullfilepath.Split(new char[1] { '\\' }); if (array.Length < 2) { array = fullfilepath.Split(new char[1] { '/' }); } Logger.LogInfo("File name check: " + string.Join(",", array)); return array[^2]; } private static void UpdateRecipeConfigFilesOnChange(object sender, FileSystemEventArgs e) { if (!File.Exists(recipeConfigFilePath)) { return; } if (EnableDebugMode.Value) { Logger.LogInfo($"{e} Recipe filewatcher called, updating recipe Modification values."); } RecipeUpdater.RecipeRevert(); RecipeUpdater.UpdateRecipeModifications(ReadAllRecipeConfigs()); RecipeUpdater.BuildRecipesForTracking(); RecipeUpdater.SecondaryRecipeSync(); if (EnableDebugMode.Value) { Logger.LogInfo("Updated RecipeModifications in-memory values."); } if (GUIManager.IsHeadless()) { try { RecipeConfigRPC.SendPackage(ZNet.instance.m_peers, SendRecipeConfigs()); if (EnableDebugMode.Value) { Logger.LogInfo("Sent recipe configs to clients."); } return; } catch (Exception arg) { Logger.LogError($"Error while server syncing recipeModification configs: {arg}"); return; } } if (EnableDebugMode.Value) { Logger.LogDebug("Instance is not a server, and will not send znet recipeModification updates."); } } private static void UpdatePieceConfigFilesOnChange(object sender, FileSystemEventArgs e) { if (!File.Exists(pieceConfigFilePath)) { return; } if (EnableDebugMode.Value) { Logger.LogInfo($"{e} Piece filewatcher called, updating piece Modification values."); } PieceUpdater.RevertPieceModifications(); PieceUpdater.UpdatePieceModifications(ReadAllPieceConfigs()); PieceUpdater.BuildPieceTracker(); PieceUpdater.PieceUpdateRunner(); if (EnableDebugMode.Value) { Logger.LogInfo("Updated RecipeModifications in-memory values."); } if (GUIManager.IsHeadless()) { try { RecipeConfigRPC.SendPackage(ZNet.instance.m_peers, SendPieceConfigs()); if (EnableDebugMode.Value) { Logger.LogInfo("Sent levels configs to clients."); } return; } catch (Exception arg) { Logger.LogError($"Error while server syncing recipeModification configs: {arg}"); return; } } if (EnableDebugMode.Value) { Logger.LogDebug("Instance is not a server, and will not send znet recipeModification updates."); } } private static void UpdateConversionConfigFilesOnChange(object sender, FileSystemEventArgs e) { if (EnableDebugMode.Value) { Logger.LogInfo($"{e} Piece filewatcher called, updating piece Modification values."); } ConversionUpdater.RevertConversionModifications(); ConversionUpdater.UpdateConversionModifications(ReadAllConversionConfigs()); ConversionUpdater.BuildConversionTracker(); ConversionUpdater.ConversionUpdateRunner(); if (EnableDebugMode.Value) { Logger.LogInfo("Updated ConversionModifications in-memory values."); } if (GUIManager.IsHeadless()) { try { ConversionConfigRPC.SendPackage(ZNet.instance.m_peers, SendPieceConfigs()); if (EnableDebugMode.Value) { Logger.LogInfo("Sent levels configs to clients."); } return; } catch (Exception arg) { Logger.LogError($"Error while server syncing recipeModification configs: {arg}"); return; } } if (EnableDebugMode.Value) { Logger.LogDebug("Instance is not a server, and will not send znet recipeModification updates."); } } public static string GetSecondaryConfigDirectoryPath() { return Directory.CreateDirectory(Path.Combine(Paths.ConfigPath, "RecipeManager")).FullName; } public void SetupConfigRPCs() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0027: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_006e: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_00b5: Expected O, but got Unknown RecipeConfigRPC = NetworkManager.Instance.AddRPC("recipeManager_recipes_rpc", new CoroutineHandler(OnServerRecieveConfigs), new CoroutineHandler(OnClientReceiveRecipeConfigs)); SynchronizationManager.Instance.AddInitialSynchronization(RecipeConfigRPC, (Func<ZPackage>)SendRecipeConfigs); PiecesConfigRPC = NetworkManager.Instance.AddRPC("recipeManager_pieces_rpc", new CoroutineHandler(OnServerRecieveConfigs), new CoroutineHandler(OnClientReceivePieceConfigs)); SynchronizationManager.Instance.AddInitialSynchronization(PiecesConfigRPC, (Func<ZPackage>)SendPieceConfigs); ConversionConfigRPC = NetworkManager.Instance.AddRPC("recipeManager_conversion_rpc", new CoroutineHandler(OnServerRecieveConfigs), new CoroutineHandler(OnClientReceiveConversionConfigs)); } [IteratorStateMachine(typeof(<OnServerRecieveConfigs>d__25))] public static IEnumerator OnServerRecieveConfigs(long sender, ZPackage package) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnServerRecieveConfigs>d__25(0); } private static ZPackage SendRecipeConfigs() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(yamlserializer.Serialize((object)ReadAllRecipeConfigs())); return val; } private static ZPackage SendPieceConfigs() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(yamlserializer.Serialize((object)ReadAllPieceConfigs())); return val; } public static void SendUpdatedPieceConfigs() { PiecesConfigRPC.SendPackage(ZNet.instance.m_peers, SendPieceConfigs()); } public static void SendUpdatedRecipeConfigs() { RecipeConfigRPC.SendPackage(ZNet.instance.m_peers, SendRecipeConfigs()); } private static DataObjects.RecipeModificationCollection ReadAllRecipeConfigs() { List<DataObjects.RecipeModificationCollection> list = new List<DataObjects.RecipeModificationCollection>(); foreach (string recipeConfigFilePath in RecipeConfigFilePaths) { if (EnableDebugMode.Value) { Logger.LogDebug("Loading values from " + recipeConfigFilePath + "."); } string text = File.ReadAllText(recipeConfigFilePath); try { DataObjects.RecipeModificationCollection item = yamldeserializer.Deserialize<DataObjects.RecipeModificationCollection>(text); list.Add(item); } catch (Exception arg) { Logger.LogError($"There was an error reading recipe data from {recipeConfigFilePath}, it will not be used. Error: {arg}"); } } DataObjects.RecipeModificationCollection recipeModificationCollection = new DataObjects.RecipeModificationCollection(); foreach (DataObjects.RecipeModificationCollection item2 in list) { foreach (KeyValuePair<string, DataObjects.RecipeModification> recipeModification in item2.RecipeModifications) { recipeModificationCollection.RecipeModifications.Add(recipeModification.Key, recipeModification.Value); } } return recipeModificationCollection; } private static DataObjects.PieceModificationCollection ReadAllPieceConfigs() { List<DataObjects.PieceModificationCollection> list = new List<DataObjects.PieceModificationCollection>(); foreach (string pieceConfigFilePath in PieceConfigFilePaths) { if (EnableDebugMode.Value) { Logger.LogDebug("Loading values from " + pieceConfigFilePath + "."); } string text = File.ReadAllText(pieceConfigFilePath); try { DataObjects.PieceModificationCollection item = yamldeserializer.Deserialize<DataObjects.PieceModificationCollection>(text); list.Add(item); } catch (Exception arg) { Logger.LogError($"There was an error reading piece data from {pieceConfigFilePath}, it will not be used. Error: {arg}"); } } DataObjects.PieceModificationCollection pieceModificationCollection = new DataObjects.PieceModificationCollection(); foreach (DataObjects.PieceModificationCollection item2 in list) { foreach (KeyValuePair<string, DataObjects.PieceModification> pieceModification in item2.PieceModifications) { pieceModificationCollection.PieceModifications.Add(pieceModification.Key, pieceModification.Value); } } return pieceModificationCollection; } private static DataObjects.ConversionModificationCollection ReadAllConversionConfigs() { List<DataObjects.ConversionModificationCollection> list = new List<DataObjects.ConversionModificationCollection>(); foreach (string pieceConfigFilePath in PieceConfigFilePaths) { if (EnableDebugMode.Value) { Logger.LogDebug("Loading values from " + pieceConfigFilePath + "."); } string text = File.ReadAllText(pieceConfigFilePath); try { DataObjects.ConversionModificationCollection item = yamldeserializer.Deserialize<DataObjects.ConversionModificationCollection>(text); list.Add(item); } catch (Exception arg) { Logger.LogError($"There was an error reading conversion data from {pieceConfigFilePath}, it will not be used. Error: {arg}"); } } DataObjects.ConversionModificationCollection conversionModificationCollection = new DataObjects.ConversionModificationCollection(); foreach (DataObjects.ConversionModificationCollection item2 in list) { foreach (KeyValuePair<string, DataObjects.ConversionModification> conversionModification in item2.ConversionModifications) { conversionModificationCollection.ConversionModifications.Add(conversionModification.Key, conversionModification.Value); } } return conversionModificationCollection; } [IteratorStateMachine(typeof(<OnClientReceiveRecipeConfigs>d__33))] private static IEnumerator OnClientReceiveRecipeConfigs(long sender, ZPackage package) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnClientReceiveRecipeConfigs>d__33(0) { package = package }; } [IteratorStateMachine(typeof(<OnClientReceivePieceConfigs>d__34))] private static IEnumerator OnClientReceivePieceConfigs(long sender, ZPackage package) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnClientReceivePieceConfigs>d__34(0) { package = package }; } [IteratorStateMachine(typeof(<OnClientReceiveConversionConfigs>d__35))] private static IEnumerator OnClientReceiveConversionConfigs(long sender, ZPackage package) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnClientReceiveConversionConfigs>d__35(0) { package = package }; } public static string YamlRecipeConfigDefinition() { DataObjects.RecipeModificationCollection recipeModificationCollection = new DataObjects.RecipeModificationCollection(); recipeModificationCollection.RecipeModifications = RecipeUpdater.RecipesToModify; return yamlserializer.Serialize((object)recipeModificationCollection); } public static string YamlPieceConfigDefinition() { DataObjects.PieceModificationCollection pieceModificationCollection = new DataObjects.PieceModificationCollection(); pieceModificationCollection.PieceModifications = PieceUpdater.PiecesToModify; return yamlserializer.Serialize((object)pieceModificationCollection); } public static string YamlConversionConfigDefinition() { DataObjects.ConversionModificationCollection conversionModificationCollection = new DataObjects.ConversionModificationCollection(); conversionModificationCollection.ConversionModifications = ConversionUpdater.ConversionsToModify; return yamlserializer.Serialize((object)conversionModificationCollection); } public ConfigEntry<bool> BindServerConfig(string catagory, string key, bool value, string description, bool advanced = false) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown return cfg.Bind<bool>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true, IsAdvanced = advanced } })); } public ConfigEntry<string> BindServerConfig(string catagory, string key, string value, string description, bool advanced = false) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown return cfg.Bind<string>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true, IsAdvanced = advanced } })); } public ConfigEntry<short> BindServerConfig(string catagory, string key, short value, string description, bool advanced = false, short valmin = 0, short valmax = 150) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown return cfg.Bind<short>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<sho