Decompiled source of RecipeManager v0.4.4

plugins/RecipeManager.dll

Decompiled 3 days ago
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 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();
		}
	}
	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 Recipe " + 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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Invalid comparison between Unknown and I4
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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;
				if ((int)piece.PieceCategory != 100)
				{
					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)
			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;
				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}");
		}

		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();
		}
	}
	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.4.3")]
	[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.4.3";

		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;
			MinimapManager.OnVanillaMapDataLoaded += RecipeUpdater.SecondaryRecipeSync;
			MinimapManager.OnVanillaMapDataLoaded += PieceUpdater.PieceUpdateRunner;
			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());
		}
	}
	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 <OnClientReceivePieceConfigs>d__26 : 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__26(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, all pieces reverted.");
					}
					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__25 : 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__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;
					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__20 : 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__20(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 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;

		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;
			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 (!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());
			}
			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);
		}

		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 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.");
			}
		}

		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
			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);
		}

		[IteratorStateMachine(typeof(<OnServerRecieveConfigs>d__20))]
		public static IEnumerator OnServerRecieveConfigs(long sender, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <OnServerRecieveConfigs>d__20(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;
		}

		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;
		}

		[IteratorStateMachine(typeof(<OnClientReceiveRecipeConfigs>d__25))]
		private static IEnumerator OnClientReceiveRecipeConfigs(long sender, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <OnClientReceiveRecipeConfigs>d__25(0)
			{
				package = package
			};
		}

		[IteratorStateMachine(typeof(<OnClientReceivePieceConfigs>d__26))]
		private static IEnumerator OnClientReceivePieceConfigs(long sender, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <OnClientReceivePieceConfigs>d__26(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 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<short>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public ConfigEntry<float> BindServerConfig(string catagory, string key, float value, string description, bool advanced = false, float valmin = 0f, float valmax = 150f)
		{
			//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<float>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}
	}
	internal class DataObjects
	{
		public enum Action
		{
			Disable,
			Delete,
			Modify,
			Add,
			Enable
		}

		public enum PieceAction
		{
			Disable,
			Modify,
			Enable
		}

		public class TrackedPiece
		{
			public PieceAction action { get; set; }

			public string prefab { get; set; }

			public Piece originalPiece { get; set; }

			public Requirement[] updatedRequirements { get; set; }

			public CraftingStation RequiredToPlaceCraftingStation { get; set; }

			public bool AllowedInDungeon { get; set; }

			public bool CanBeDeconstructed { get; set; } = true;


			public PieceCategory PieceCategory { get; set; } = (PieceCategory)100;


			public int ComfortAmount { get; set; } = -1;


			public ComfortGroup ComfortGroup { get; set; }

			public bool IsUpgradeForStation { get; set; }

			public float CraftingStationConnectionRadius { get; set; } = -1f;


			public bool MustBeAvobeConnectedStation { get; set; }

			public float SpaceRequired { get; set; } = -1f;


			public string PieceName { get; set; }

			public string PieceDescription { get; set; }

			public bool EnablePiece { get; set; } = true;


			public Biome OnlyInBiome { get; set; } = (Biome)895;


			public bool CultivatedGroundOnly { get; set; }

			public bool GroundPlacement { get; set; } = true;

		}

		[DataContract]
		public class PieceModificationCollection
		{
			public Dictionary<string, PieceModification> PieceModifications { get; set; } = new Dictionary<string, PieceModification>();

		}

		[DataContract]
		public class PieceModification
		{
			public PieceAction action { get; set; }

			public string prefab { get; set; }

			public List<SimpleRequirement> requirements { get; set; } = new List<SimpleRequirement>();


			public string RequiredToPlaceCraftingStation { get; set; }

			public bool AllowedInDungeon { get; set; }

			public bool CanBeDeconstructed { get; set; } = true;


			public PieceCategory PieceCategory { get; set; } = (PieceCategory)100;


			public int ComfortAmount { get; set; } = -1;


			public ComfortGroup ComfortGroup { get; set; }

			public bool IsUpgradeForStation { get; set; }

			public float CraftingStationConnectionRadius { get; set; } = -1f;


			public bool MustBeAvobeConnectedStation { get; set; }

			public float SpaceRequired { get; set; } = -1f;


			public string PieceName { get; set; }

			public string PieceDescription { get; set; }

			public bool EnablePiece { get; set; } = true;


			public Biome OnlyInSelectBiome { get; set; } = (Biome)895;


			public bool CultivatedGroundOnly { get; set; }

			public bool GroundPlacement { get; set; }
		}

		[DataContract]
		public class SimpleRequirement
		{
			public string Prefab { get; set; }

			public int amount { get; set; }
		}

		public class TrackedRecipe
		{
			public Action action { get; set; }

			public string prefab { get; set; }

			public string recipeName { get; set; }

			public Recipe originalRecipe { get; set; }

			public Recipe updatedRecipe { get; set; }

			public CustomRecipe updatedCustomRecipe { get; set; }

			public CustomRecipe originalCustomRecipe { get; set; }
		}

		[DataContract]
		public class RecipeModificationCollection
		{
			public Dictionary<string, RecipeModification> RecipeModifications { get; set; } = new Dictionary<string, RecipeModification>();

		}

		[DataContract]
		public class RecipeModification
		{
			public Action action { get; set; }

			public string prefab { get; set; }

			public string recipeName { get; set; }

			public string craftedAt { get; set; }

			public string repairAt { get; set; }

			public short minStationLevel { get; set; } = 1;


			public short craftAmount { get; set; } = 1;


			public SimpleRecipe recipe { get; set; }
		}

		[DataContract]
		public class SimpleRecipe
		{
			public bool anyOneResource { get; set; }

			public bool noRecipeCost { get; set; }

			public List<Ingrediant> ingredients { get; set; } = new List<Ingrediant>();

		}

		[DataContract]
		public class Ingrediant
		{
			public string prefab { get; set; }

			public short craftCost { get; set; }

			public short upgradeCost { get; set; }
		}
	}
	internal class Logger
	{
		public static LogLevel Level = (LogLevel)16;

		public static void enableDebugLogging(object sender, EventArgs e)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (ValConfig.EnableDebugMode.Value)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void CheckEnableDebugLogging()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (ValConfig.EnableDebugMode.Value)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void LogDebug(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 32)
			{
				RecipeManager.Log.LogInfo((object)message);
			}
		}

		public static void LogInfo(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 16)
			{
				RecipeManager.Log.LogInfo((object)message);
			}
		}

		public static void LogWarning(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Level >= 4)
			{
				RecipeManager.Log.LogWarning((object)message);
			}
		}

		public static void LogError(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Level >= 2)
			{
				RecipeManager.Log.LogError((object)message);
			}
		}
	}
}