Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RecipeManager v0.5.5
plugins/RecipeManager.dll
Decompiled 4 months 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, recover = val.m_recover }); } 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_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Invalid comparison between Unknown and I4 //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_0362: 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, m_recover = requirement.recover }); 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.5")] [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.5"; 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 += ValConfig.ReloadPieceFiles; MinimapManager.OnVanillaMapDataLoaded += RecipeUpdater.SecondaryRecipeSync; MinimapManager.OnVanillaMapDataLoaded += PieceUpdater.BuildPieceTracker; 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 val = 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 = val.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 val2 = ((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 = val2; recipe.m_craftingStation = val2; } 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."); } bool flag = true; Requirement[] resources = recipe.m_resources; foreach (Requirement val3 in resources) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(((Object)val3.m_resItem).name.Replace("JVLmock_", "")); if ((Object)(object)itemPrefab != (Object)null) { val3.m_resItem = itemPrefab.GetComponent<ItemDrop>(); continue; } flag = false; Logger.LogError((object)("Could not resolve itemdrop reference for: " + ((Object)val3.m_resItem).name.Replace("JVLmock_", "") + ". This Recipe modification will be skipped.")); } if (!flag) { continue; } trackedRecipe.updatedRecipe = recipe; trackedRecipe.updatedCustomRecipe = val; 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) { return Path.GetFileName(fullfilepath); } 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,