Decompiled source of HIJOS DE FREYJA ROLEPLAY v0.0.2

Bepinex/plugins/CraftByProfession/CraftByProfession.dll

Decompiled 18 hours ago
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Buffers.Text;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Tracing;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.IO.Pipelines;
using System.Linq;
using System.Numerics;
using System.Numerics.Hashing;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Reflection;
using System.Text.Json.Schema;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Converters;
using System.Text.Json.Serialization.Metadata;
using System.Text.RegularExpressions;
using System.Text.Unicode;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Sources;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CraftByProfession.Loaders;
using CraftByProfession.Managers;
using CraftByProfession.Patches;
using CraftByProfession.UISelection;
using FxResources.System.Buffers;
using FxResources.System.IO.Pipelines;
using FxResources.System.Memory;
using FxResources.System.Numerics.Vectors;
using FxResources.System.Text.Encodings.Web;
using FxResources.System.Text.Json;
using FxResources.System.ValueTuple;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using ServerSync;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("CraftByProfession")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CraftByProfession")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9d7b5d97-1586-4682-8c7b-b1174633c18e")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace CraftByProfession
{
	internal class ConfigurationFile
	{
		private static ConfigEntry<bool> _serverConfigLocked = null;

		public static ConfigEntry<bool> debug;

		public static string path_to_your_mod_folder;

		public static ConfigEntry<KeyCode> compendiumHotKey;

		public static ConfigEntry<bool> bypassAdmins;

		public static ConfigEntry<bool> showAllInCompendium;

		public static ConfigEntry<string> professions;

		public static ConfigEntry<KeyCode> professionsHotKey;

		public static ConfigEntry<string> profession;

		public static ConfigEntry<string> professionsSprites;

		public static ConfigEntry<bool> allowProfessionChange;

		public static ConfigEntry<string> beehiveProfession;

		public static ConfigEntry<string> beehiveUsageForbidden;

		public static ConfigEntry<string> fermenterProfession;

		public static ConfigEntry<string> fermenterUsageForbidden;

		public static ConfigEntry<string> smelterProfession;

		public static ConfigEntry<string> smelterUsageForbidden;

		public static ConfigEntry<string> blastfurnaceProfession;

		public static ConfigEntry<string> blastfurnaceUsageForbidden;

		public static ConfigEntry<string> eitrrefineryProfession;

		public static ConfigEntry<string> eitrrefineryUsageForbidden;

		public static ConfigEntry<string> actions;

		public static ConfigEntry<string> unavailablePieceMessage;

		public static ConfigEntry<string> unavailablePieceLevelMessage;

		public static ConfigEntry<string> unavailableRecipeMessage;

		public static ConfigEntry<string> unavailableRecipeLevelMessage;

		public static ConfigEntry<string> unremovablePieceMessage;

		public static ConfigEntry<string> unremovablePieceLevelMessage;

		public static ConfigFile configFile;

		private static readonly string ConfigFileName = "Turbero.ValheimProfessionRoleplay.cfg";

		private static readonly string ConfigFileFullPath;

		private static readonly ConfigSync ConfigSync;

		internal static void LoadConfig(BaseUnityPlugin plugin)
		{
			configFile = plugin.Config;
			_serverConfigLocked = config("1 - General", "Lock Configuration", value: true, "If on, the configuration is locked and can be changed by server admins only.");
			ConfigSync.AddLockingConfigEntry<bool>(_serverConfigLocked);
			string text = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\professions";
			path_to_your_mod_folder = text;
			debug = config("1 - General", "DebugMode", value: false, "Enabling/Disabling the debugging in the console (default = false)", synchronizedSetting: false);
			compendiumHotKey = config<KeyCode>("2 - Config", "CompendiumHotKey", (KeyCode)284, "Hot key to open the compendium (default = F3)", synchronizedSetting: false);
			bypassAdmins = config("2 - Config", "BypassAdmins", value: false, "Admins ignore profession conditions (default = true)");
			showAllInCompendium = config("2 - Config", "ShowAllInCompendium", value: true, "Shows all objects your profession can manage in Compendium or only those you have learnt until now (default = false)");
			professionsHotKey = config<KeyCode>("3 - Assignments", "ProfessionsHotKey", (KeyCode)112, "Hoy key for professions panel", synchronizedSetting: false);
			professions = config("3 - Assignments", "Professions", "", "Comma-separated list of professions.");
			professionsSprites = config("3 - Assignments", "ProfessionsSprites", "", "Comma-separated list of sprites for professions.");
			allowProfessionChange = config("3 - Assignments", "AllowProfessionChange", value: false, "Allow changing professions after selecting for first time (default = false).");
			beehiveProfession = config("4 - Exclusive pieces", "BeehiveProfession", "", "Exclusive profession for using the beehive. Leave blank to allow to everyone to use it.");
			beehiveUsageForbidden = config("4 - Exclusive pieces", "BeehiveUsageForbidden", "You can't use the beehive with your current profession!", "Message to show when beehive cannot be used");
			fermenterProfession = config("4 - Exclusive pieces", "FermenterProfession", "", "Exclusive profession for using the fermenter. Leave blank to allow to everyone to use it.");
			fermenterUsageForbidden = config("4 - Exclusive pieces", "FermenterUsageForbidden", "You can't use the fermenter with your current profession!", "Message to show when the fermenter cannot be used");
			smelterProfession = config("4 - Exclusive pieces", "SmelterProfession", "", "Exclusive profession for using the smelter. Leave blank to allow to everyone to use it.");
			smelterUsageForbidden = config("4 - Exclusive pieces", "SmelterUsageForbidden", "You can't use the smelter with your current profession!", "Message to show when the smelter cannot be used");
			blastfurnaceProfession = config("4 - Exclusive pieces", "BlastFurnaceProfession", "", "Exclusive profession for using the blast furnace. Leave blank to allow to everyone to use it.");
			blastfurnaceUsageForbidden = config("4 - Exclusive pieces", "BlastfurnaceUsageForbidden", "You can't use the blast furnace with your current profession!", "Message to show when the blast furnace cannot be used");
			eitrrefineryProfession = config("4 - Exclusive pieces", "EitrRefineryProfession", "", "Exclusive profession for using the eitr refinery. Leave blank to allow to everyone to use it.");
			eitrrefineryUsageForbidden = config("4 - Exclusive pieces", "EitrRefineryUsageForbidden", "You can't use the eitr refinery with your current profession!", "Message to show when the eitr refinery cannot be used");
			profession = config("5 - Language", "Profession", "Profession", "Profession.");
			actions = config("5 - Language", "Actions", "Actions", "Actions section in compendium.");
			unavailablePieceMessage = config("5 - Language", "UnavailablePieceMessage", "You don't have the profession {0} to place that object", "Message to show when piece cannot be placed ({0} = profession)");
			unavailablePieceLevelMessage = config("5 - Language", "UnavailablePieceLevelMessage", "You don't have the necessary skill level {0} in {1} to place that object", "Message to show when piece cannot be placed ({0} = level, {1} = profession)");
			unavailableRecipeMessage = config("5 - Language", "UnavailableRecipeMessage", "You don't have the profession {0} to create that object", "Message to show when recipe cannot be crafted ({0} = profession)");
			unavailableRecipeLevelMessage = config("5 - Language", "UnavailableRecipeLevelMessage", "You don't have the necessary skill level {0} in {1} to create that object", "Message to show when recipe cannot be crafted ({0} = level, {1} = profession)");
			unremovablePieceMessage = config("5 - Language", "UnremovablePieceMessage", "You don't have the profession {0} to remove that object", "Message to show when piece cannot be removed ({0} = profession)");
			unremovablePieceLevelMessage = config("5 - Language", "UnremovablePieceLevelMessage", "You don't have the necessary skill level {0} in {1} to remove that object", "Message to show when piece cannot be removed ({0} = level, {1} = profession");
			bypassAdmins.SettingChanged += OnSettingChanged;
			showAllInCompendium.SettingChanged += OnSettingChanged;
			professions.SettingChanged += OnSettingChanged;
			professionsSprites.SettingChanged += OnSettingChanged;
			allowProfessionChange.SettingChanged += OnSettingChanged;
			SetupWatcher();
		}

		private static void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private static void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				Logger.Log("Attempting to reload configuration...");
				configFile.Reload();
			}
			catch
			{
				Logger.LogError("There was an issue loading " + ConfigFileName);
			}
		}

		private static void OnSettingChanged(object sender, EventArgs e)
		{
			if ((Object)(object)ZNetScene.instance != (Object)null)
			{
				LoaderPiecePatch.Postfix(ZNetScene.instance);
				LoaderRecipePatch.Postfix(ZNetScene.instance);
			}
			CraftStationDescriptionsPatch.updated = false;
			if ((Object)(object)ProfessionUI.professionUIResetButton != (Object)null)
			{
				((Component)ProfessionUI.professionUIResetButton).gameObject.SetActive(bypassAdmins.Value || allowProfessionChange.Value);
			}
		}

		private static ConfigEntry<T> config<T>(string group, string name, T value, string description, bool synchronizedSetting = true)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
		}

		private static ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags);
			ConfigEntry<T> val2 = configFile.Bind<T>(group, name, value, val);
			SyncedConfigEntry<T> syncedConfigEntry = ConfigSync.AddConfigEntry<T>(val2);
			syncedConfigEntry.SynchronizedConfig = synchronizedSetting;
			return val2;
		}

		static ConfigurationFile()
		{
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
			ConfigSync = new ConfigSync("Turbero.ValheimProfessionRoleplay")
			{
				DisplayName = "Valheim Profession Roleplay",
				CurrentVersion = "1.0.0",
				MinimumRequiredVersion = "1.0.0"
			};
		}
	}
	public static class Logger
	{
		public static ManualLogSource logger = Logger.CreateLogSource("Valheim Profession Roleplay");

		internal static void Log(object s)
		{
			if (ConfigurationFile.debug.Value)
			{
				logger.LogInfo((object)s?.ToString());
			}
		}

		internal static void LogInfo(object s)
		{
			logger.LogInfo((object)s?.ToString());
		}

		internal static void LogWarning(object s)
		{
			logger.LogWarning((object)s?.ToString());
		}

		internal static void LogError(object s)
		{
			logger.LogError((object)s?.ToString());
		}
	}
	public class ProfessionData
	{
		public string professionName;

		[JsonPropertyName("objectName")]
		public string ObjectName { get; set; }

		[JsonPropertyName("itemName")]
		public string ItemName { get; set; }

		[JsonPropertyName("skillType")]
		public SkillType SkillType { get; set; } = (SkillType)0;


		[JsonPropertyName("minSkillLevel")]
		public int MinSkillLevel { get; set; } = 0;


		public override string ToString()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			return $"[objectName: {ObjectName}, itemName: {ItemName}, professionName: {professionName}, skillType: {SkillType}, minSkillLevel: {MinSkillLevel}]";
		}
	}
	public class ProfessionDataComponent : MonoBehaviour
	{
		public string objectName;

		public string itemName;

		public string professionName;

		public SkillType skillType = (SkillType)0;

		public int minSkillLevel = 0;

		public ProfessionData getProfessionData()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			return new ProfessionData
			{
				ObjectName = objectName,
				ItemName = itemName,
				professionName = professionName,
				SkillType = skillType,
				MinSkillLevel = minSkillLevel
			};
		}

		public override string ToString()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			return $"[objectName: {objectName}, itemName: {itemName}, professionName: {professionName}, skillType: {skillType}, minSkillLevel: {minSkillLevel}]";
		}
	}
	[BepInPlugin("Turbero.ValheimProfessionRoleplay", "Valheim Profession Roleplay", "1.0.0")]
	public class CraftByProfession : BaseUnityPlugin
	{
		public const string GUID = "Turbero.ValheimProfessionRoleplay";

		public const string NAME = "Valheim Profession Roleplay";

		public const string VERSION = "1.0.0";

		private readonly Harmony harmony = new Harmony("Turbero.ValheimProfessionRoleplay");

		private void Awake()
		{
			ConfigurationFile.LoadConfig((BaseUnityPlugin)(object)this);
			harmony.PatchAll();
		}

		private void onDestroy()
		{
			ConfigurationFile.configFile.Save();
			harmony.UnpatchSelf();
		}

		public void Update()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || !Object.op_Implicit((Object)(object)InventoryGui.instance))
			{
				return;
			}
			if (Input.GetKeyDown((KeyCode)27) || Input.GetKeyDown((KeyCode)9) || ((Character)Player.m_localPlayer).IsDead())
			{
				ProfessionUI.Hide();
				((Component)InventoryGui.instance.m_textsDialog).gameObject.SetActive(false);
			}
			else if (Input.GetKeyDown(ConfigurationFile.compendiumHotKey.Value) && IsKeyActionAllowed())
			{
				if (((Component)InventoryGui.instance.m_textsDialog).gameObject.activeSelf)
				{
					ProfessionUI.Hide();
					UIManager.CloseInventoryGui();
				}
				else
				{
					InventoryGui.instance.Show((Container)null, 1);
					WaitForSecondsAsync(0.15f);
				}
			}
			else if (Input.GetKeyDown(ConfigurationFile.professionsHotKey.Value) && IsKeyActionAllowed())
			{
				if (ProfessionUI.IsVisible())
				{
					ProfessionUI.Hide();
					UIManager.CloseInventoryGui();
				}
				else
				{
					InventoryGui.instance.Show((Container)null, 1);
					WaitForSecondsAsync(0.15f, openProfessions: true);
				}
			}
		}

		private static bool IsKeyActionAllowed()
		{
			GameObject val = GameObject.Find("_GameMain/LoadingGUI/PixelFix/IngameGui/EasySpawnerMenu(Clone)/SearchInputField");
			InputField val2 = ((val != null) ? val.GetComponent<InputField>() : null);
			return !Chat.instance.HasFocus() && !Console.IsVisible() && Time.timeScale > 0f && ((Object)(object)val2 == (Object)null || !val2.isFocused);
		}

		private static async Task WaitForSecondsAsync(float seconds, bool openProfessions = false)
		{
			await Task.Delay((int)(Math.Max(0f, seconds) * 1000f));
			InventoryGui.instance.m_textsDialog.Setup(Player.m_localPlayer);
			((Component)InventoryGui.instance.m_textsDialog).gameObject.SetActive(true);
			if (openProfessions)
			{
				ProfessionUI.Show();
			}
		}
	}
	[HarmonyPatch(typeof(Player), "OnSpawned")]
	public static class InstantiateSelectPanel
	{
		private static void Postfix(Player __instance)
		{
			if (ProfessionUI.professionsPanel == null)
			{
				ProfessionUI.professionsPanel = new ProfessionsPanel();
				ProfessionUI.professionsPanel.getPanel().SetActive(false);
			}
			if (ProfessionUI.selectedProfessionPanel == null)
			{
				ProfessionUI.selectedProfessionPanel = new SelectedProfessionPanel();
				ProfessionUI.selectedProfessionPanel.getPanel().SetActive(false);
			}
		}
	}
}
namespace CraftByProfession.UISelection
{
	[HarmonyPatch]
	public class CompendiumPatch
	{
		private static readonly List<ProfessionData> detectedActions = new List<ProfessionData>();

		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(TextsDialog), "AddActiveEffects", (Type[])null, (Type[])null);
		}

		private static void Postfix(ref TextsDialog __instance)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			List<TextInfo> list = (List<TextInfo>)GameManager.GetPrivateValue(__instance, "m_texts");
			string playerProfession = PlayerInfoManager.GetPlayerProfession();
			detectedActions.Clear();
			StringBuilder stringBuilder = new StringBuilder(256);
			stringBuilder.Append("<color=orange>" + ConfigurationFile.profession.Value + "</color>\n");
			stringBuilder.Append(playerProfession);
			AddPlayerPieces(stringBuilder, playerProfession);
			AddPlayerRecipes(stringBuilder, playerProfession);
			AddPlayerActions(stringBuilder, playerProfession);
			list.Insert(0, new TextInfo("Valheim Profession Roleplay", stringBuilder.ToString()));
			ProfessionUI.createProfessionUI();
		}

		private static void AddPlayerPieces(StringBuilder stringBuilder, string playerProfession)
		{
			string path = ConfigurationFile.path_to_your_mod_folder + "\\pieces_" + playerProfession + ".json";
			if (!File.Exists(path))
			{
				return;
			}
			Logger.Log("**Adding pieces");
			string json = File.ReadAllText(path);
			List<ProfessionData> data = JsonSerializer.Deserialize<List<ProfessionData>>(json);
			SortedSet<string> items = GetItems(data);
			if (items.Count <= 0)
			{
				return;
			}
			string text = Localization.instance.Localize("$item_parts");
			string text2 = text.ToCharArray()[0].ToString().ToUpper() + text.Substring(1);
			stringBuilder.Append("\n<color=orange>" + text2 + "</color>\n");
			foreach (string item in items)
			{
				stringBuilder.Append(item);
			}
		}

		private static void AddPlayerRecipes(StringBuilder stringBuilder, string playerProfession)
		{
			string path = ConfigurationFile.path_to_your_mod_folder + "\\recipes_" + playerProfession + ".json";
			if (!File.Exists(path))
			{
				return;
			}
			Logger.Log("**Adding recipes");
			string json = File.ReadAllText(path);
			List<ProfessionData> data = JsonSerializer.Deserialize<List<ProfessionData>>(json);
			SortedSet<string> items = GetItems(data);
			if (items.Count <= 0)
			{
				return;
			}
			stringBuilder.Append("\n<color=orange>$inventory_recipes</color>\n");
			foreach (string item in items)
			{
				stringBuilder.Append(item);
			}
		}

		private static void AddPlayerActions(StringBuilder stringBuilder, string playerProfession)
		{
			Logger.Log("**Adding actions");
			SortedSet<string> sortedSet = new SortedSet<string>();
			foreach (ProfessionData detectedAction in detectedActions)
			{
				if (detectedAction.professionName == playerProfession)
				{
					sortedSet.Add(Localization.instance.Localize(detectedAction.ItemName));
				}
			}
			if (sortedSet.Count <= 0)
			{
				return;
			}
			stringBuilder.Append("\n<color=orange>" + ConfigurationFile.actions.Value + "</color>");
			foreach (string item in sortedSet)
			{
				stringBuilder.Append("\n" + item);
			}
		}

		private static SortedSet<string> GetItems(List<ProfessionData> data)
		{
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			SortedSet<string> sortedSet = new SortedSet<string>();
			HashSet<string> hashSet = (HashSet<string>)GameManager.GetPrivateValue(Player.m_localPlayer, "m_knownRecipes");
			foreach (ProfessionData datum in data)
			{
				if (IsATool(datum) || datum.ObjectName == "Recipe_Bronze5")
				{
					continue;
				}
				string text = datum.ObjectName.Replace("Recipe_", "").ToLower();
				if (ConfigurationFile.showAllInCompendium.Value || hashSet.Contains("$" + text) || hashSet.Contains("$piece_" + text) || hashSet.Contains("$item_" + text) || hashSet.Contains(datum.ItemName))
				{
					string text2 = ((datum.ItemName == null) ? datum.ObjectName : ((Localization.instance.Localize(datum.ItemName) != null) ? Localization.instance.Localize(datum.ItemName) : datum.ItemName));
					if ((int)datum.SkillType != 0 && datum.MinSkillLevel > 0)
					{
						SkillType skillType = datum.SkillType;
						sortedSet.Add($"{text2} (skill = $skill_{((object)(SkillType)(ref skillType)).ToString().ToLower()}, $msg_level >= {datum.MinSkillLevel})\n");
					}
					else
					{
						sortedSet.Add(text2 + "\n");
					}
				}
				else
				{
					Logger.Log(datum.ObjectName + " not learnt yet.");
				}
			}
			return sortedSet;
		}

		private static bool IsATool(ProfessionData jsonData)
		{
			if (jsonData.ObjectName == LoaderPiecePatch.TOOL_CULTIVATE)
			{
				detectedActions.Add(LoaderPiecePatch.cultivate);
				return true;
			}
			if (jsonData.ObjectName == LoaderPiecePatch.TOOL_REPLANT)
			{
				detectedActions.Add(LoaderPiecePatch.replant);
				return true;
			}
			if (jsonData.ObjectName == LoaderPiecePatch.TOOL_PAVE)
			{
				detectedActions.Add(LoaderPiecePatch.paved);
				return true;
			}
			if (jsonData.ObjectName == LoaderPiecePatch.TOOL_RAISE)
			{
				detectedActions.Add(LoaderPiecePatch.raise);
				return true;
			}
			return false;
		}
	}
	public class SelectedProfessionPanel
	{
		private GameObject currentProfessionPanel;

		private TextMeshProUGUI selectedProfessionText;

		private Image imageProfessionLogo;

		public SelectedProfessionPanel()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: 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_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			currentProfessionPanel = new GameObject("CurrentProfessionPanel", new Type[1] { typeof(RectTransform) });
			currentProfessionPanel.SetActive(false);
			currentProfessionPanel.transform.SetParent(((Component)((Component)InventoryGui.instance).transform.Find("root/Texts/Texts_frame")).transform, false);
			RectTransform component = currentProfessionPanel.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(512f, 512f);
			component.anchoredPosition = Vector2.zero;
			Image val = currentProfessionPanel.AddComponent<Image>();
			val.sprite = ResourcesManager.getSprite("woodpanel_512x512");
			val.type = (Type)1;
			TextMeshProUGUI val2 = UIManager.createUIText("Title", currentProfessionPanel.transform, new Vector2(0f, 220f), "Profesión", 36, "Valheim-Norsebold");
			((Graphic)val2).color = Color.yellow;
			((TMP_Text)val2).alignment = (TextAlignmentOptions)514;
			Button val3 = UIManager.createUIButton("ProfessionOptionsCloseButton", ((Component)InventoryGui.instance.m_skillsDialog).transform.Find("SkillsFrame/Closebutton"), currentProfessionPanel.transform, new Vector2(0f, 40f), Localization.instance.Localize("$menu_close"));
			((UnityEvent)val3.onClick).AddListener((UnityAction)delegate
			{
				currentProfessionPanel.SetActive(false);
			});
			Sprite sprite = UIManager.LoadSpriteFromEmbedded("icons.hijos-de-freyja.png");
			Image val4 = UIManager.createUIImage("LogoHDFEmbedded", currentProfessionPanel.transform, new Vector2(200f, 200f), new Vector2(0f, 110f), sprite);
			val4.preserveAspect = true;
			string playerProfession = PlayerInfoManager.GetPlayerProfession();
			selectedProfessionText = UIManager.createUIText("SelectedProfessionTextGo", currentProfessionPanel.transform, Vector2.zero, playerProfession, 20);
			((Graphic)selectedProfessionText).color = Color.green;
			((TMP_Text)selectedProfessionText).alignment = (TextAlignmentOptions)514;
			Sprite professionSprite = getProfessionSprite(playerProfession);
			imageProfessionLogo = UIManager.createUIImage("LogoProfession", currentProfessionPanel.transform, new Vector2(150f, 150f), new Vector2(0f, -100f), professionSprite);
			imageProfessionLogo.preserveAspect = true;
		}

		private Sprite getProfessionSprite(string selectedProfession)
		{
			string[] array = ConfigurationFile.professions.Value.Split(new char[1] { ',' });
			string[] array2 = ConfigurationFile.professionsSprites.Value.Split(new char[1] { ',' });
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i] == selectedProfession)
				{
					return ResourcesManager.getSprite(array2[i]);
				}
			}
			Logger.LogError("Sprite for Profession '" + selectedProfession + "' not found");
			return null;
		}

		public GameObject getPanel()
		{
			return currentProfessionPanel;
		}

		public void refreshContent()
		{
			((TMP_Text)selectedProfessionText).text = PlayerInfoManager.GetPlayerProfession();
			imageProfessionLogo.sprite = getProfessionSprite(PlayerInfoManager.GetPlayerProfession());
		}
	}
	public class ProfessionsPanel
	{
		private GameObject customProfessionsPanel;

		private Dictionary<string, GameObject> selectProfessionGoBtns = new Dictionary<string, GameObject>();

		private Dictionary<string, TextMeshProUGUI> professionTexts = new Dictionary<string, TextMeshProUGUI>();

		public ProfessionsPanel()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: 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_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Expected O, but got Unknown
			customProfessionsPanel = new GameObject("CustomProfessionsPanel", new Type[1] { typeof(RectTransform) });
			customProfessionsPanel.SetActive(false);
			customProfessionsPanel.transform.SetParent(((Component)((Component)InventoryGui.instance).transform.Find("root/Texts/Texts_frame")).transform, false);
			RectTransform component = customProfessionsPanel.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(512f, 512f);
			component.anchoredPosition = Vector2.zero;
			Image val = customProfessionsPanel.AddComponent<Image>();
			val.sprite = ResourcesManager.getSprite("woodpanel_512x512");
			val.type = (Type)1;
			TextMeshProUGUI val2 = UIManager.createUIText("Title", customProfessionsPanel.transform, new Vector2(0f, 223f), "Profesiones", 36, "Valheim-Norsebold");
			((Graphic)val2).color = Color.yellow;
			((TMP_Text)val2).alignment = (TextAlignmentOptions)514;
			Button val3 = UIManager.createUIButton("ProfessionOptionsCloseButton", ((Component)InventoryGui.instance.m_skillsDialog).transform.Find("SkillsFrame/Closebutton"), customProfessionsPanel.transform, new Vector2(0f, 40f), Localization.instance.Localize("$menu_close"));
			((UnityEvent)val3.onClick).AddListener((UnityAction)delegate
			{
				customProfessionsPanel.SetActive(false);
			});
			TextMeshProUGUI val4 = UIManager.createUIText("AlertText", customProfessionsPanel.transform, new Vector2(0f, 165f), "ADVERTENCIA: Elegir profesión es permanente.\n sólo se podrá cambiar borrando el personaje\ny empezando desde cero.", 24, "Valheim-Norsebold");
			((Graphic)val4).color = Color.white;
			((TMP_Text)val4).autoSizeTextContainer = true;
			((TMP_Text)val4).alignment = (TextAlignmentOptions)514;
			string[] array = ConfigurationFile.professions.Value.Split(new char[1] { ',' });
			int num = 100;
			int num2 = 355;
			string[] array2 = array;
			foreach (string profession in array2)
			{
				Transform copyFrom = ((Component)InventoryGui.instance.m_skillsDialog).transform.Find("SkillsFrame/Closebutton");
				Button val5 = UIManager.createUIButton("ProfessionBtnGo", copyFrom, customProfessionsPanel.transform, new Vector2(0f, (float)num2), profession);
				((UnityEvent)val5.onClick).AddListener((UnityAction)delegate
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "Ya no puedes cambiar de profesión.\nA partir de ahora serás: " + profession, 0, (Sprite)null);
					((Humanoid)Player.m_localPlayer).AddUniqueKey("HDF_" + profession);
					customProfessionsPanel.SetActive(false);
					UIManager.CloseInventoryGui();
					CraftStationDescriptionsPatch.updated = false;
					ResourcesManager.TriggerLightningEffect();
				});
				((Component)val5).gameObject.SetActive(true);
				selectProfessionGoBtns.Add(profession, ((Component)val5).gameObject);
				num -= 50;
				num2 -= 50;
			}
		}

		public GameObject getPanel()
		{
			return customProfessionsPanel;
		}
	}
	[HarmonyPatch]
	public class ProfessionUI
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__4_0;

			public static UnityAction <>9__4_1;

			internal void <createProfessionUI>b__4_0()
			{
				Logger.Log("ProfessionUIOpenButton clicked.");
				string playerProfession = PlayerInfoManager.GetPlayerProfession();
				if (playerProfession == null)
				{
					professionsPanel.getPanel().SetActive(true);
					selectedProfessionPanel.getPanel().SetActive(false);
				}
				else
				{
					professionsPanel.getPanel().SetActive(false);
					selectedProfessionPanel.refreshContent();
					selectedProfessionPanel.getPanel().SetActive(true);
				}
			}

			internal void <createProfessionUI>b__4_1()
			{
				Logger.Log("ProfessionUIResetButton clicked.");
				string[] array = ConfigurationFile.professions.Value.Split(new char[1] { ',' });
				string[] array2 = array;
				foreach (string text in array2)
				{
					((Humanoid)Player.m_localPlayer).RemoveUniqueKey("HDF_" + text);
				}
				CraftStationDescriptionsPatch.updated = false;
				Hide();
				UIManager.CloseInventoryGui();
				ResourcesManager.TriggerLightningEffect();
			}
		}

		private static Button professionUIOpenButton;

		public static Button professionUIResetButton;

		public static ProfessionsPanel professionsPanel;

		public static SelectedProfessionPanel selectedProfessionPanel;

		public static void createProfessionUI()
		{
			//IL_0078: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Expected O, but got Unknown
			if (professionsPanel == null)
			{
				professionsPanel = new ProfessionsPanel();
				professionsPanel.getPanel().SetActive(false);
			}
			if (selectedProfessionPanel == null)
			{
				selectedProfessionPanel = new SelectedProfessionPanel();
				selectedProfessionPanel.getPanel().SetActive(false);
			}
			Transform val = ((Component)InventoryGui.instance).transform.Find("root/Texts/Texts_frame/Closebutton");
			((Component)val).GetComponent<RectTransform>().anchoredPosition = new Vector2(170f, 55f);
			if ((Object)(object)professionUIOpenButton == (Object)null)
			{
				professionUIOpenButton = UIManager.createUIButton("ProfessionUIOpenButton", val, val.parent, new Vector2(-95f, 55f), "Profesiones");
				ButtonClickedEvent onClick = professionUIOpenButton.onClick;
				object obj = <>c.<>9__4_0;
				if (obj == null)
				{
					UnityAction val2 = delegate
					{
						Logger.Log("ProfessionUIOpenButton clicked.");
						string playerProfession = PlayerInfoManager.GetPlayerProfession();
						if (playerProfession == null)
						{
							professionsPanel.getPanel().SetActive(true);
							selectedProfessionPanel.getPanel().SetActive(false);
						}
						else
						{
							professionsPanel.getPanel().SetActive(false);
							selectedProfessionPanel.refreshContent();
							selectedProfessionPanel.getPanel().SetActive(true);
						}
					};
					<>c.<>9__4_0 = val2;
					obj = (object)val2;
				}
				((UnityEvent)onClick).AddListener((UnityAction)obj);
			}
			if (!((Object)(object)professionUIResetButton == (Object)null))
			{
				return;
			}
			professionUIResetButton = UIManager.createUIButton("ProfessionUIResetButton", val, val.parent, new Vector2(435f, 55f), "Reset profesión");
			ButtonClickedEvent onClick2 = professionUIResetButton.onClick;
			object obj2 = <>c.<>9__4_1;
			if (obj2 == null)
			{
				UnityAction val3 = delegate
				{
					Logger.Log("ProfessionUIResetButton clicked.");
					string[] array = ConfigurationFile.professions.Value.Split(new char[1] { ',' });
					string[] array2 = array;
					foreach (string text in array2)
					{
						((Humanoid)Player.m_localPlayer).RemoveUniqueKey("HDF_" + text);
					}
					CraftStationDescriptionsPatch.updated = false;
					Hide();
					UIManager.CloseInventoryGui();
					ResourcesManager.TriggerLightningEffect();
				};
				<>c.<>9__4_1 = val3;
				obj2 = (object)val3;
			}
			((UnityEvent)onClick2).AddListener((UnityAction)obj2);
			Logger.Log("ProfessionUIResetButton bypassAdmins: " + ConfigurationFile.bypassAdmins.Value);
			Logger.Log("ProfessionUIResetButton allowProfessionChange: " + ConfigurationFile.allowProfessionChange.Value);
			((Component)professionUIResetButton).gameObject.SetActive(ConfigurationFile.bypassAdmins.Value || ConfigurationFile.allowProfessionChange.Value);
		}

		public static bool IsVisible()
		{
			return professionsPanel.getPanel().activeSelf || selectedProfessionPanel.getPanel().activeSelf;
		}

		public static void Hide()
		{
			professionsPanel.getPanel().SetActive(false);
			selectedProfessionPanel.getPanel().SetActive(false);
		}

		public static void Show()
		{
			string playerProfession = PlayerInfoManager.GetPlayerProfession();
			if (playerProfession == null)
			{
				professionsPanel.getPanel().SetActive(true);
				selectedProfessionPanel.getPanel().SetActive(false);
			}
			else
			{
				professionsPanel.getPanel().SetActive(false);
				selectedProfessionPanel.refreshContent();
				selectedProfessionPanel.getPanel().SetActive(true);
			}
		}
	}
}
namespace CraftByProfession.Loaders
{
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	public static class LoaderPiecePatch
	{
		public static readonly string TOOL_CULTIVATE = "cultivate_v2";

		public static readonly string TOOL_REPLANT = "replant_v2";

		public static readonly string TOOL_PAVE = "paved_road_v2";

		public static readonly string TOOL_RAISE = "raise_v2";

		public static ProfessionData cultivate;

		public static ProfessionData replant;

		public static ProfessionData paved;

		public static ProfessionData raise;

		private static void init()
		{
			cultivate = null;
			replant = null;
			paved = null;
			raise = null;
		}

		public static void Postfix(ZNetScene __instance)
		{
			init();
			string[] array = ConfigurationFile.professions.Value.Split(new char[1] { ',' });
			string[] array2 = array;
			foreach (string professionName in array2)
			{
				LoadFilePieces(professionName);
			}
		}

		private static void LoadFilePieces(string professionName)
		{
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			string text = ConfigurationFile.path_to_your_mod_folder + "\\pieces_" + professionName + ".json";
			if (!File.Exists(text))
			{
				Logger.Log("Path " + text + " doesn't exit. Skipping.");
				return;
			}
			string json = File.ReadAllText(text);
			List<ProfessionData> list = JsonSerializer.Deserialize<List<ProfessionData>>(json);
			Logger.Log("** Loading Pieces for " + professionName + "...");
			foreach (ProfessionData dataItem in list)
			{
				if (!foundATool(dataItem, professionName))
				{
					GameObject val = ZNetScene.instance.m_prefabs.Find((GameObject i) => ((Object)i).name == dataItem.ObjectName);
					if ((Object)(object)val != (Object)null)
					{
						ProfessionDataComponent professionDataComponent = (((Object)(object)val.GetComponent<ProfessionDataComponent>() != (Object)null) ? val.GetComponent<ProfessionDataComponent>() : val.AddComponent<ProfessionDataComponent>());
						professionDataComponent.objectName = dataItem.ObjectName;
						professionDataComponent.itemName = dataItem.ItemName;
						professionDataComponent.professionName = professionName;
						professionDataComponent.skillType = dataItem.SkillType;
						professionDataComponent.minSkillLevel = dataItem.MinSkillLevel;
						Logger.Log("Prefab profession added to " + professionDataComponent.objectName + " for profession " + professionDataComponent.professionName + ".");
					}
					else
					{
						Logger.LogWarning("Prefab not found with name " + dataItem.ObjectName + ". Skipping.");
					}
				}
			}
		}

		private static bool foundATool(ProfessionData dataItem, string professionName)
		{
			if (dataItem.ObjectName == TOOL_CULTIVATE)
			{
				Logger.Log(TOOL_CULTIVATE + " found");
				dataItem.professionName = professionName;
				cultivate = dataItem;
				return true;
			}
			if (dataItem.ObjectName == TOOL_REPLANT)
			{
				Logger.Log(TOOL_REPLANT + " found");
				dataItem.professionName = professionName;
				replant = dataItem;
				return true;
			}
			if (dataItem.ObjectName == TOOL_PAVE)
			{
				Logger.Log(TOOL_PAVE + " found");
				dataItem.professionName = professionName;
				paved = dataItem;
				return true;
			}
			if (dataItem.ObjectName == TOOL_RAISE)
			{
				Logger.Log(TOOL_RAISE + " found");
				dataItem.professionName = professionName;
				raise = dataItem;
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	public static class LoaderRecipePatch
	{
		public static void Postfix(ZNetScene __instance)
		{
			RecipeManager.recipesProfessionData.Clear();
			string[] array = ConfigurationFile.professions.Value.Split(new char[1] { ',' });
			string[] array2 = array;
			foreach (string professionName in array2)
			{
				loadRecipes(professionName);
			}
		}

		private static void loadRecipes(string professionName)
		{
			string text = ConfigurationFile.path_to_your_mod_folder + "\\recipes_" + professionName + ".json";
			if (!File.Exists(text))
			{
				Logger.Log("Path " + text + " doesn't exit. Skipping.");
				return;
			}
			Logger.Log("** Loading recipes for " + professionName + "...");
			string json = File.ReadAllText(text);
			List<ProfessionData> list = JsonSerializer.Deserialize<List<ProfessionData>>(json);
			foreach (ProfessionData item in list)
			{
				if (!RecipeManager.recipesProfessionData.ContainsKey(item.ObjectName))
				{
					item.professionName = professionName;
					RecipeManager.recipesProfessionData.Add(item.ObjectName, item);
					Logger.Log("Profession Data from json added: " + item.ObjectName + " for profession " + item.professionName);
				}
				else
				{
					Logger.LogWarning("Profession Data repeatedKey " + item.ObjectName);
				}
			}
		}
	}
}
namespace CraftByProfession.Patches
{
	[HarmonyPatch(typeof(Player), "Interact")]
	public static class PlayerInteractPatch
	{
		private static bool Prefix(Player __instance, GameObject go, bool hold, bool alt)
		{
			Logger.Log("**PlayerInteractPatch Interact PREFIX");
			if (ConfigurationFile.bypassAdmins.Value)
			{
				bool flag = PlayerInfoManager.IsPlayerLocalAdmin();
				Logger.Log($"PlayerInteractPatch isAdmin: {flag}");
				if (flag)
				{
					return true;
				}
				string steamID = PlayerInfoManager.GetSteamID(__instance);
				Logger.Log("steamId = " + steamID);
				if (steamID == null)
				{
					return true;
				}
				flag = PlayerInfoManager.IsAdmin(steamID);
				Logger.Log("PlayerInteractPatch " + steamID + " isAdmin: " + flag);
				if (flag)
				{
					return true;
				}
			}
			Transform parent = go.transform.parent;
			string text = ((parent != null) ? ((Object)((Component)parent).gameObject).name : null);
			if (text == null)
			{
				return true;
			}
			Logger.Log("gameObject name: " + ((Object)go).name);
			Logger.Log("gameObject parent name: " + text);
			if (text.ToLower().StartsWith("piece_beehive"))
			{
				return checkPiece(__instance, ConfigurationFile.beehiveProfession.Value, ConfigurationFile.beehiveUsageForbidden.Value);
			}
			if (text.ToLower().StartsWith("smelter"))
			{
				return checkPiece(__instance, ConfigurationFile.smelterProfession.Value, ConfigurationFile.smelterUsageForbidden.Value);
			}
			if (text.ToLower().StartsWith("blastfurnace"))
			{
				return checkPiece(__instance, ConfigurationFile.blastfurnaceProfession.Value, ConfigurationFile.blastfurnaceUsageForbidden.Value);
			}
			if (text.ToLower().StartsWith("eitrrefinery"))
			{
				return checkPiece(__instance, ConfigurationFile.eitrrefineryProfession.Value, ConfigurationFile.eitrrefineryUsageForbidden.Value);
			}
			Transform parent2 = go.transform.parent;
			if ((Object)(object)((parent2 != null) ? parent2.parent : null) != (Object)null)
			{
				Transform parent3 = go.transform.parent;
				object obj;
				if (parent3 == null)
				{
					obj = null;
				}
				else
				{
					Transform parent4 = parent3.parent;
					obj = ((parent4 != null) ? ((Component)parent4).gameObject : null);
				}
				if ((Object)obj != (Object)null)
				{
					Logger.Log("Checking last option");
					Transform parent5 = go.transform.parent;
					object obj2;
					if (parent5 == null)
					{
						obj2 = null;
					}
					else
					{
						Transform parent6 = parent5.parent;
						obj2 = ((parent6 != null) ? ((Object)((Component)parent6).gameObject).name : null);
					}
					string text2 = (string)obj2;
					Logger.Log("gameObject parent parent name: " + text2);
					if (text2.ToLower().StartsWith("fermenter"))
					{
						return checkPiece(__instance, ConfigurationFile.fermenterProfession.Value, ConfigurationFile.fermenterUsageForbidden.Value);
					}
				}
			}
			return true;
		}

		private static bool checkPiece(Player __instance, string professionName, string unavailableMessage)
		{
			if (professionName != PlayerInfoManager.GetPlayerProfession())
			{
				Logger.Log("Interact bloqueado");
				((Character)__instance).Message((MessageType)2, unavailableMessage, 0, (Sprite)null);
				return false;
			}
			Logger.Log("Interact permitido");
			return true;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "Show")]
	public static class CraftStationDescriptionsPatch
	{
		public static bool updated;

		public static bool Prefix(Container container, int activeGroup)
		{
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: 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)
			if (updated)
			{
				return true;
			}
			foreach (Recipe recipe in ObjectDB.instance.m_recipes)
			{
				if (RecipeManager.recipesProfessionData.ContainsKey(((Object)recipe).name))
				{
					string playerProfession = PlayerInfoManager.GetPlayerProfession();
					ProfessionData valueSafe = GeneralExtensions.GetValueSafe<string, ProfessionData>(RecipeManager.recipesProfessionData, ((Object)recipe).name);
					string professionName = valueSafe.professionName;
					string text = ((playerProfession == professionName) ? "green" : "red");
					string text2 = recipe.m_item.m_itemData.m_shared.m_description.Split(new char[1] { '\n' })[0];
					SharedData shared = recipe.m_item.m_itemData.m_shared;
					string[] obj = new string[9]
					{
						text2,
						"\n",
						ConfigurationFile.profession.Value,
						": <color=",
						text,
						">",
						professionName,
						"</color>",
						null
					};
					object obj2;
					if ((int)valueSafe.SkillType == 0 || valueSafe.MinSkillLevel <= 0)
					{
						obj2 = "";
					}
					else
					{
						SkillType skillType = valueSafe.SkillType;
						obj2 = $"\n(Skill = $skill_{((object)(SkillType)(ref skillType)).ToString().ToLower()}, $msg_level = {valueSafe.MinSkillLevel})";
					}
					obj[8] = (string)obj2;
					shared.m_description = string.Concat(obj);
				}
			}
			updated = true;
			return true;
		}
	}
	[HarmonyPatch(typeof(UITooltip), "UpdateTextElements")]
	public static class UITooltipPatch
	{
		public static void Postfix(UITooltip __instance)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = (GameObject)GameManager.GetPrivateValue(__instance, "m_tooltip", BindingFlags.Static | BindingFlags.NonPublic);
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			Transform val2 = Utils.FindChild(val.transform, "Text", (IterativeSearchType)0);
			if (!((Object)(object)val2 != (Object)null))
			{
				return;
			}
			ProfessionData professionData = RecipeManager.FindRecipeByItemName(__instance.m_topic);
			if (professionData?.ObjectName == null)
			{
				return;
			}
			string playerProfession = PlayerInfoManager.GetPlayerProfession();
			string professionName = professionData.professionName;
			string text = ((playerProfession == professionName) ? "green" : "red");
			if (!__instance.m_text.Contains(ConfigurationFile.profession.Value))
			{
				string[] obj = new string[8]
				{
					"\n",
					ConfigurationFile.profession.Value,
					": <color=",
					text,
					">",
					professionName,
					"</color>",
					null
				};
				object obj2;
				if ((int)professionData.SkillType == 0 || professionData.MinSkillLevel <= 0)
				{
					obj2 = "";
				}
				else
				{
					SkillType skillType = professionData.SkillType;
					obj2 = $"\n(Skill = $skill_{((object)(SkillType)(ref skillType)).ToString().ToLower()}, $msg_level = {professionData.MinSkillLevel})";
				}
				obj[7] = (string)obj2;
				string text2 = string.Concat(obj);
				__instance.m_text = __instance.m_text.Replace("_description", "_description " + text2);
			}
			((Component)val2).GetComponent<TMP_Text>().text = Localization.instance.Localize(__instance.m_text);
		}
	}
	[HarmonyPatch(typeof(Player), "TryPlacePiece")]
	public static class PlacePiecePatch
	{
		private static bool Prefix(Player __instance, Piece piece)
		{
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			Logger.Log("**PlacePiecePatch TryPlacePiece PREFIX");
			string steamID = PlayerInfoManager.GetSteamID(__instance);
			if (steamID == null)
			{
				return true;
			}
			Logger.Log("steamId = " + steamID);
			if (ConfigurationFile.bypassAdmins.Value)
			{
				bool flag = PlayerInfoManager.IsPlayerLocalAdmin();
				Logger.Log($"isAdmin: {flag}");
				if (flag)
				{
					return true;
				}
				flag = PlayerInfoManager.IsAdmin(steamID);
				Logger.Log($"{steamID} isAdmin: {flag}");
				if (flag)
				{
					return true;
				}
			}
			if (!IsAllowed(steamID, piece))
			{
				ProfessionData professionData = PlayerInfoManager.GetProfessionData(piece);
				string errorMessage = GetErrorMessage(ConfigurationFile.unavailablePieceMessage.Value, professionData.professionName);
				((Character)__instance).Message((MessageType)2, errorMessage, 0, (Sprite)null);
				return false;
			}
			if (!IsAllowedByLevel(__instance, piece))
			{
				ProfessionData professionData2 = PlayerInfoManager.GetProfessionData(piece);
				string value = ConfigurationFile.unavailablePieceLevelMessage.Value;
				string replace = professionData2.MinSkillLevel.ToString();
				Localization instance = Localization.instance;
				SkillType skillType = professionData2.SkillType;
				string errorMessage2 = GetErrorMessage(value, replace, instance.Localize("$skill_" + ((object)(SkillType)(ref skillType)).ToString().ToLower()));
				((Character)__instance).Message((MessageType)2, errorMessage2, 0, (Sprite)null);
				return false;
			}
			Logger.Log("**Player IS PIECE ALLOWED");
			return true;
		}

		public static bool IsAllowed(string steamId, Piece piece)
		{
			Logger.Log("Piece.m_name: " + piece.m_name + ", Piece.name: " + ((Object)piece).name);
			ProfessionData professionData = PlayerInfoManager.GetProfessionData(piece);
			Logger.Log($"Condition: {professionData == null}");
			Logger.Log("pieceProfessionData = " + professionData);
			if (professionData?.ObjectName == null)
			{
				return true;
			}
			string playerProfession = PlayerInfoManager.GetPlayerProfession();
			bool flag = playerProfession != null;
			Logger.Log(steamId + " hasAProfession: " + flag);
			if (!flag)
			{
				return false;
			}
			bool flag2 = professionData.professionName.ToLower().Contains(playerProfession.ToLower());
			Logger.Log($"professionMatching: {professionData.professionName.ToLower()} vs {playerProfession.ToLower()} = {flag2}");
			return flag2;
		}

		public static bool IsAllowedByLevel(Player player, Piece piece)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			ProfessionData professionData = PlayerInfoManager.GetProfessionData(piece);
			if (professionData != null && professionData.MinSkillLevel > 0 && (int)professionData.SkillType > 0)
			{
				List<Skill> skillList = ((Character)player).GetSkills().GetSkillList();
				for (int i = 0; i < skillList.Count; i++)
				{
					Skill val = skillList[i];
					if (val.m_info.m_skill == professionData.SkillType)
					{
						int num = (int)val.m_level;
						bool flag = num >= professionData.MinSkillLevel;
						Logger.Log($"currentLevel {num} necessaryLevel {professionData.MinSkillLevel} professionMatching: {flag}");
						return flag;
					}
				}
			}
			return true;
		}

		private static string GetErrorMessage(string message, string replace0 = null, string replace1 = null)
		{
			if (replace0 != null)
			{
				message = message.Replace("{0}", replace0);
			}
			if (replace1 != null)
			{
				message = message.Replace("{1}", replace1);
			}
			return message;
		}
	}
	[HarmonyPatch(typeof(Player), "CheckCanRemovePiece")]
	public static class CheckCanRemovePiecePatch
	{
		private static bool Prefix(Player __instance, Piece piece)
		{
			//IL_0119: 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)
			Logger.Log("**CheckCanRemovePiecePatch CheckCanRemovePiece PREFIX");
			string steamID = PlayerInfoManager.GetSteamID(__instance);
			if (steamID == null)
			{
				return true;
			}
			Logger.Log("steamId = " + steamID);
			if (ConfigurationFile.bypassAdmins.Value)
			{
				bool flag = PlayerInfoManager.IsPlayerLocalAdmin();
				Logger.Log($"CheckCanRemovePiece.Prefix IsPlayerLocalAdmin: {flag}");
				if (flag)
				{
					return true;
				}
				Logger.Log("CheckCanRemovePiece.Prefix " + steamID + " IsAdmin: " + PlayerInfoManager.IsAdmin(steamID));
			}
			if (!PlacePiecePatch.IsAllowed(steamID, piece))
			{
				ProfessionData professionData = PlayerInfoManager.GetProfessionData(piece);
				string errorMessage = GetErrorMessage(ConfigurationFile.unremovablePieceMessage.Value, professionData.professionName);
				((Character)__instance).Message((MessageType)2, errorMessage, 0, (Sprite)null);
				return false;
			}
			if (!PlacePiecePatch.IsAllowedByLevel(__instance, piece))
			{
				ProfessionData professionData2 = PlayerInfoManager.GetProfessionData(piece);
				string value = ConfigurationFile.unremovablePieceLevelMessage.Value;
				string replace = professionData2.MinSkillLevel.ToString();
				Localization instance = Localization.instance;
				SkillType skillType = professionData2.SkillType;
				string errorMessage2 = GetErrorMessage(value, replace, instance.Localize("$skill_" + ((object)(SkillType)(ref skillType)).ToString().ToLower()));
				((Character)__instance).Message((MessageType)2, errorMessage2, 0, (Sprite)null);
				return false;
			}
			Logger.Log("**Player IS ALLOWED TO REMOVE PIECE");
			return true;
		}

		private static string GetErrorMessage(string message, string replace0 = null, string replace1 = null)
		{
			if (replace0 != null)
			{
				message = message.Replace("{0}", replace0);
			}
			if (replace1 != null)
			{
				message = message.Replace("{1}", replace1);
			}
			return message;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnCraftPressed")]
	public static class RecipeCraftPatch
	{
		private static bool Prefix(InventoryGui __instance)
		{
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			Logger.Log("**RecipeCraftPatch OnCraftPressed PREFIX");
			Recipe selectedRecipe = GetSelectedRecipe(__instance);
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)selectedRecipe == (Object)null || (Object)(object)localPlayer == (Object)null)
			{
				Logger.LogError("Error detecting recipe or player. Continue as vanilla.");
				return true;
			}
			ProfessionData professionData = PlayerInfoManager.GetProfessionData(selectedRecipe);
			string text = professionData?.professionName;
			Logger.Log("professionData.professionName = " + text);
			if (text == null)
			{
				Logger.Log("No profession assigned to recipe. Skipping.");
				return true;
			}
			Logger.Log("ProfessionData for recipe " + ((Object)selectedRecipe).name + " with professionName: " + text);
			Logger.Log("ProfessionData: " + professionData.ToString());
			if (!PlayerMeetsProfessionRequirement(professionData))
			{
				string errorMessage = GetErrorMessage(ConfigurationFile.unavailableRecipeMessage.Value, text);
				((Character)localPlayer).Message((MessageType)2, errorMessage, 0, (Sprite)null);
				return false;
			}
			if (!PlayerMeetsProfessionLevelRequirement(localPlayer, professionData))
			{
				string value = ConfigurationFile.unavailableRecipeLevelMessage.Value;
				string replace = professionData.MinSkillLevel.ToString();
				Localization instance = Localization.instance;
				SkillType skillType = professionData.SkillType;
				string errorMessage2 = GetErrorMessage(value, replace, instance.Localize("$skill_" + ((object)(SkillType)(ref skillType)).ToString().ToLower()));
				((Character)localPlayer).Message((MessageType)2, errorMessage2, 0, (Sprite)null);
				return false;
			}
			Logger.Log("**Player IS RECIPE ALLOWED");
			return true;
		}

		private static string GetErrorMessage(string message, string replace0 = null, string replace1 = null)
		{
			if (replace0 != null)
			{
				message = message.Replace("{0}", replace0);
			}
			if (replace1 != null)
			{
				message = message.Replace("{1}", replace1);
			}
			return message;
		}

		private static Recipe GetSelectedRecipe(InventoryGui instance)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			object privateValue = GameManager.GetPrivateValue(instance, "m_selectedRecipe");
			FieldInfo[] fields = privateValue.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			FieldInfo fieldInfo = null;
			FieldInfo[] array = fields;
			foreach (FieldInfo fieldInfo2 in array)
			{
				if (fieldInfo2.Name.Contains("Recipe"))
				{
					Logger.Log("Recipe attribute found");
					fieldInfo = fieldInfo2;
					break;
				}
			}
			Recipe val = (Recipe)(fieldInfo?.GetValue(privateValue));
			Logger.Log("recipe: " + (object)val);
			return val;
		}

		private static bool PlayerMeetsProfessionRequirement(ProfessionData professionData)
		{
			string playerProfession = PlayerInfoManager.GetPlayerProfession();
			Logger.Log("PlayerMeetsProfessionRequirement: " + playerProfession + " vs " + professionData.professionName);
			return playerProfession == professionData.professionName;
		}

		private static bool PlayerMeetsProfessionLevelRequirement(Player player, ProfessionData professionData)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (!ConfigurationFile.bypassAdmins.Value && professionData != null && professionData.ObjectName != null && professionData.MinSkillLevel > 0 && (int)professionData.SkillType > 0)
			{
				List<Skill> skillList = ((Character)player).GetSkills().GetSkillList();
				for (int i = 0; i < skillList.Count; i++)
				{
					Skill val = skillList[i];
					if (val.m_info.m_skill == professionData.SkillType)
					{
						int num = (int)val.m_level;
						bool flag = num >= professionData.MinSkillLevel;
						Logger.Log($"PlayerMeetsProfessionLevelRequirement: currentLevel {num} necessaryLevel {professionData.MinSkillLevel}. meets: {flag}");
						return flag;
					}
				}
			}
			return true;
		}
	}
}
namespace CraftByProfession.Managers
{
	public class GameManager
	{
		public static object GetPrivateValue(object obj, string name, BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.NonPublic)
		{
			return obj.GetType().GetField(name, bindingAttr).GetValue(obj);
		}
	}
	public class ResourcesManager
	{
		private static Dictionary<string, Sprite> cachedSprites = new Dictionary<string, Sprite>();

		private static Dictionary<string, TMP_FontAsset> cachedFonts = new Dictionary<string, TMP_FontAsset>();

		public static Sprite getSprite(string name)
		{
			if (!cachedSprites.ContainsKey(name))
			{
				Logger.Log("Finding " + name + " sprite...");
				Sprite[] array = Resources.FindObjectsOfTypeAll<Sprite>();
				foreach (Sprite val in array)
				{
					if (((Object)val).name == name)
					{
						Logger.Log(name + " sprite found.");
						cachedSprites.Add(name, val);
						return val;
					}
				}
				Logger.Log(name + " sprite NOT found.");
				return null;
			}
			return GeneralExtensions.GetValueSafe<string, Sprite>(cachedSprites, name);
		}

		public static TMP_FontAsset getFontAsset(string name)
		{
			if (!cachedFonts.ContainsKey(name))
			{
				Logger.Log("Finding " + name + " font...");
				TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
				foreach (TMP_FontAsset val in array)
				{
					if (((Object)val).name == name)
					{
						Logger.Log(name + " font found.");
						cachedFonts.Add(name, val);
						return val;
					}
				}
				Logger.Log(name + " font NOT found.");
				return null;
			}
			return GeneralExtensions.GetValueSafe<string, TMP_FontAsset>(cachedFonts, name);
		}

		public static void TriggerLightningEffect()
		{
			SEMan sEMan = ((Character)Player.m_localPlayer).GetSEMan();
			if ((Object)(object)sEMan.GetStatusEffect("Lightning".GetHashCode()) == (Object)null)
			{
				StatusEffect val = sEMan.AddStatusEffect("Lightning".GetHashCode(), false, 0, 0f);
				val.m_ttl = 5f;
			}
		}
	}
	public class UIManager
	{
		private static readonly Color BUTTON_VANILLA_COLOR = new Color(1f, 0.7176f, 0.3603f);

		public static TextMeshProUGUI createUIText(string goName, Transform parent, Vector2 pos, string text, int fontSize, string fontName = null)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(goName, new Type[1] { typeof(TextMeshProUGUI) });
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchoredPosition = pos;
			TextMeshProUGUI component2 = val.GetComponent<TextMeshProUGUI>();
			if (fontName != null)
			{
				((TMP_Text)component2).font = ResourcesManager.getFontAsset(fontName);
			}
			((TMP_Text)component2).fontSize = fontSize;
			((TMP_Text)component2).text = text;
			return component2;
		}

		public static Button createUIButton(string goName, Transform copyFrom, Transform parent, Vector2 pos, string text)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(((Component)copyFrom).gameObject, parent);
			((Object)val).name = goName;
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchoredPosition = pos;
			TextMeshProUGUI componentInChildren = val.GetComponentInChildren<TextMeshProUGUI>();
			((TMP_Text)componentInChildren).text = text;
			((TMP_Text)componentInChildren).fontStyle = (FontStyles)0;
			((Graphic)componentInChildren).color = BUTTON_VANILLA_COLOR;
			((TMP_Text)componentInChildren).alignment = (TextAlignmentOptions)514;
			Button component2 = val.GetComponent<Button>();
			component2.onClick = new ButtonClickedEvent();
			return component2;
		}

		public static Image createUIImage(string goName, Transform parent, Vector2 size, Vector2 pos, Sprite sprite, bool shadowBkg = false)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(goName);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.sizeDelta = size;
			val2.anchoredPosition = pos;
			if (shadowBkg)
			{
				Image val3 = createUIImage(goName + "Bkg", val.transform, size, Vector2.zero, null);
				((Graphic)val3).color = new Color(0f, 0f, 0f, 0.5f);
			}
			Image val4 = val.AddComponent<Image>();
			val4.sprite = sprite;
			return val4;
		}

		private static byte[] ReadEmbeddedFileBytes(string name)
		{
			using MemoryStream memoryStream = new MemoryStream();
			Assembly.GetExecutingAssembly().GetManifestResourceStream("CraftByProfession." + name)?.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		private static Texture2D loadTexture(string name)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			Texture2D val = new Texture2D(0, 0);
			ImageConversion.LoadImage(val, ReadEmbeddedFileBytes("icons." + name));
			return val;
		}

		public static Sprite loadSprite(string name, int width, int height)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			return Sprite.Create(loadTexture(name), new Rect(0f, 0f, (float)width, (float)height), Vector2.zero);
		}

		public static Sprite LoadSpriteFromFile(string filePath)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0071: 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)
			if (!File.Exists(filePath))
			{
				Debug.LogError((object)("File not found at path: " + filePath));
				return null;
			}
			try
			{
				byte[] array = File.ReadAllBytes(filePath);
				Texture2D val = new Texture2D(2, 2);
				if (!ImageConversion.LoadImage(val, array))
				{
					Debug.LogError((object)"Failed to load texture from image data.");
					return null;
				}
				return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("Failed to load image from file: " + ex.Message));
				return null;
			}
		}

		public static Sprite LoadSpriteFromEmbedded(string embeddedPath)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				byte[] array = ReadEmbeddedFileBytes(embeddedPath);
				Texture2D val = new Texture2D(2, 2);
				if (!ImageConversion.LoadImage(val, array))
				{
					Debug.LogError((object)"Failed to load texture from image data.");
					return null;
				}
				return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("Failed to load image from file: " + ex.Message));
				return null;
			}
		}

		public static void CloseInventoryGui()
		{
			((Component)InventoryGui.instance.m_textsDialog).gameObject.SetActive(false);
			InventoryGui.instance.Hide();
		}
	}
	public class PlayerInfoManager
	{
		public static ProfessionData GetProfessionData(Piece piece)
		{
			if (LoaderPiecePatch.TOOL_CULTIVATE == ((Object)piece).name)
			{
				return LoaderPiecePatch.cultivate;
			}
			if (LoaderPiecePatch.TOOL_REPLANT == ((Object)piece).name)
			{
				return LoaderPiecePatch.replant;
			}
			if (LoaderPiecePatch.TOOL_PAVE == ((Object)piece).name)
			{
				return LoaderPiecePatch.paved;
			}
			if (LoaderPiecePatch.TOOL_RAISE == ((Object)piece).name)
			{
				return LoaderPiecePatch.paved;
			}
			string name = ((Object)piece).name.Replace("$", "").Replace("(Clone)", "");
			Logger.Log("Finding gameObject starting with " + name);
			GameObject val = ZNetScene.instance.m_prefabs.Find((GameObject i) => ((Object)i).name.StartsWith(name));
			ProfessionDataComponent professionDataComponent = ((val != null) ? val.GetComponent<ProfessionDataComponent>() : null);
			if ((Object)(object)professionDataComponent == (Object)null)
			{
				return null;
			}
			return professionDataComponent.getProfessionData();
		}

		public static string GetPlayerProfession()
		{
			string[] array = ConfigurationFile.professions.Value.Split(new char[1] { ',' });
			List<string> list = new List<string>();
			for (int i = 0; i < array.Length; i++)
			{
				list.Add(array[i]);
			}
			foreach (string uniqueKey in Player.m_localPlayer.GetUniqueKeys())
			{
				string text = uniqueKey.Replace("HDF_", "");
				if (list.Contains(text))
				{
					return text;
				}
			}
			return null;
		}

		public static string GetSteamID(Player player)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//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_00a7: Unknown result type (might be due to invalid IL or missing references)
			ZNetView val = (ZNetView)GameManager.GetPrivateValue(player, "m_nview");
			string text = ((object)val.GetZDO()).ToString();
			Logger.Log("characterIDToFind = " + text);
			List<PlayerInfo> playerList = ZNet.instance.GetPlayerList();
			foreach (PlayerInfo item in playerList)
			{
				ZDOID characterID = item.m_characterID;
				Logger.Log("playerInfo.m_characterID.ToString() = " + ((object)(ZDOID)(ref characterID)).ToString());
				characterID = item.m_characterID;
				if (((object)(ZDOID)(ref characterID)).ToString() == text)
				{
					Logger.Log("Match characterIDToFind!");
					string host = item.m_host;
					Logger.Log("steamID found: " + host);
					return host;
				}
			}
			return "";
		}

		public static ProfessionData GetProfessionData(Recipe recipe)
		{
			Logger.Log("recipe.name " + ((Object)recipe).name + " firstPart " + ((Object)recipe).name.Split(new char[1] { ' ' })[0]);
			ProfessionData value;
			return RecipeManager.recipesProfessionData.TryGetValue(((Object)recipe).name.Split(new char[1] { ' ' })[0], out value) ? value : null;
		}

		public static bool IsPlayerLocalAdmin()
		{
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				Logger.LogWarning("ZNet is not initialized in IsAdmin. returning false.");
				return false;
			}
			try
			{
				return ZNet.instance.LocalPlayerIsAdminOrHost();
			}
			catch (Exception s)
			{
				Logger.LogWarning(s);
			}
			return false;
		}

		public static bool IsAdmin(string steamId)
		{
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				Logger.LogWarning("ZNet is not initialized in IsAdmin. returning false.");
				return false;
			}
			try
			{
				return ZNet.instance.IsAdmin(steamId);
			}
			catch (Exception s)
			{
				Logger.LogWarning(s);
			}
			return false;
		}
	}
	public class RecipeManager
	{
		public static Dictionary<string, ProfessionData> recipesProfessionData = new Dictionary<string, ProfessionData>();

		public static ProfessionData FindRecipeByItemName(string itemName)
		{
			foreach (ProfessionData value in recipesProfessionData.Values)
			{
				if (value.ItemName == itemName)
				{
					return value;
				}
			}
			return null;
		}
	}
}
namespace FxResources.System.Buffers
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class <f389ca43-32bf-4e24-ad8c-a6ed5efddff3>SR
	{
		private static ResourceManager s_resourceManager;

		private static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(ResourceType));

		internal static Type ResourceType { get; } = typeof(FxResources.System.Buffers.SR);


		internal static string ArgumentException_BufferNotFromPool => GetResourceString("ArgumentException_BufferNotFromPool", null);

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool UsingResourceKeys()
		{
			return false;
		}

		internal static string GetResourceString(string resourceKey, string defaultString)
		{
			string text = null;
			try
			{
				text = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			if (defaultString != null && resourceKey.Equals(text, StringComparison.Ordinal))
			{
				return defaultString;
			}
			return text;
		}

		internal static string Format(string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}
	}
}
namespace System.Buffers
{
	internal abstract class ArrayPool<T>
	{
		private static ArrayPool<T> s_sharedInstance;

		public static ArrayPool<T> Shared
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return Volatile.Read(ref s_sharedInstance) ?? EnsureSharedCreated();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static ArrayPool<T> EnsureSharedCreated()
		{
			Interlocked.CompareExchange(ref s_sharedInstance, Create(), null);
			return s_sharedInstance;
		}

		public static ArrayPool<T> Create()
		{
			return new DefaultArrayPool<T>();
		}

		public static ArrayPool<T> Create(int maxArrayLength, int maxArraysPerBucket)
		{
			return new DefaultArrayPool<T>(maxArrayLength, maxArraysPerBucket);
		}

		public abstract T[] Rent(int minimumLength);

		public abstract void Return(T[] array, bool clearArray = false);
	}
	[EventSource(Name = "System.Buffers.ArrayPoolEventSource")]
	internal sealed class ArrayPoolEventSource : EventSource
	{
		internal enum BufferAllocatedReason
		{
			Pooled,
			OverMaximumSize,
			PoolExhausted
		}

		internal static readonly System.Buffers.ArrayPoolEventSource Log = new System.Buffers.ArrayPoolEventSource();

		[Event(1, Level = EventLevel.Verbose)]
		internal unsafe void BufferRented(int bufferId, int bufferSize, int poolId, int bucketId)
		{
			EventData* ptr = stackalloc EventData[4];
			*ptr = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferId)
			};
			ptr[1] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferSize)
			};
			ptr[2] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&poolId)
			};
			ptr[3] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bucketId)
			};
			WriteEventCore(1, 4, ptr);
		}

		[Event(2, Level = EventLevel.Informational)]
		internal unsafe void BufferAllocated(int bufferId, int bufferSize, int poolId, int bucketId, BufferAllocatedReason reason)
		{
			EventData* ptr = stackalloc EventData[5];
			*ptr = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferId)
			};
			ptr[1] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferSize)
			};
			ptr[2] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&poolId)
			};
			ptr[3] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bucketId)
			};
			ptr[4] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&reason)
			};
			WriteEventCore(2, 5, ptr);
		}

		[Event(3, Level = EventLevel.Verbose)]
		internal void BufferReturned(int bufferId, int bufferSize, int poolId)
		{
			WriteEvent(3, bufferId, bufferSize, poolId);
		}
	}
	internal sealed class DefaultArrayPool<T> : ArrayPool<T>
	{
		private sealed class Bucket
		{
			internal readonly int _bufferLength;

			private readonly T[][] _buffers;

			private readonly int _poolId;

			private SpinLock _lock;

			private int _index;

			internal int Id => GetHashCode();

			internal Bucket(int bufferLength, int numberOfBuffers, int poolId)
			{
				_lock = new SpinLock(Debugger.IsAttached);
				_buffers = new T[numberOfBuffers][];
				_bufferLength = bufferLength;
				_poolId = poolId;
			}

			internal T[] Rent()
			{
				T[][] buffers = _buffers;
				T[] array = null;
				bool lockTaken = false;
				bool flag = false;
				try
				{
					_lock.Enter(ref lockTaken);
					if (_index < buffers.Length)
					{
						array = buffers[_index];
						buffers[_index++] = null;
						flag = array == null;
					}
				}
				finally
				{
					if (lockTaken)
					{
						_lock.Exit(useMemoryBarrier: false);
					}
				}
				if (flag)
				{
					array = new T[_bufferLength];
					System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
					if (log.IsEnabled())
					{
						log.BufferAllocated(array.GetHashCode(), _bufferLength, _poolId, Id, System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.Pooled);
					}
				}
				return array;
			}

			internal void Return(T[] array)
			{
				if (array.Length != _bufferLength)
				{
					throw new ArgumentException(<f389ca43-32bf-4e24-ad8c-a6ed5efddff3>SR.ArgumentException_BufferNotFromPool, "array");
				}
				bool lockTaken = false;
				try
				{
					_lock.Enter(ref lockTaken);
					if (_index != 0)
					{
						_buffers[--_index] = array;
					}
				}
				finally
				{
					if (lockTaken)
					{
						_lock.Exit(useMemoryBarrier: false);
					}
				}
			}
		}

		private const int DefaultMaxArrayLength = 1048576;

		private const int DefaultMaxNumberOfArraysPerBucket = 50;

		private static T[] s_emptyArray;

		private readonly Bucket[] _buckets;

		private int Id => GetHashCode();

		internal DefaultArrayPool()
			: this(1048576, 50)
		{
		}

		internal DefaultArrayPool(int maxArrayLength, int maxArraysPerBucket)
		{
			if (maxArrayLength <= 0)
			{
				throw new ArgumentOutOfRangeException("maxArrayLength");
			}
			if (maxArraysPerBucket <= 0)
			{
				throw new ArgumentOutOfRangeException("maxArraysPerBucket");
			}
			if (maxArrayLength > 1073741824)
			{
				maxArrayLength = 1073741824;
			}
			else if (maxArrayLength < 16)
			{
				maxArrayLength = 16;
			}
			int id = Id;
			int num = System.Buffers.Utilities.SelectBucketIndex(maxArrayLength);
			Bucket[] array = new Bucket[num + 1];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new Bucket(System.Buffers.Utilities.GetMaxSizeForBucket(i), maxArraysPerBucket, id);
			}
			_buckets = array;
		}

		public override T[] Rent(int minimumLength)
		{
			if (minimumLength < 0)
			{
				throw new ArgumentOutOfRangeException("minimumLength");
			}
			if (minimumLength == 0)
			{
				return s_emptyArray ?? (s_emptyArray = new T[0]);
			}
			System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
			T[] array = null;
			int num = System.Buffers.Utilities.SelectBucketIndex(minimumLength);
			if (num < _buckets.Length)
			{
				int num2 = num;
				do
				{
					array = _buckets[num2].Rent();
					if (array != null)
					{
						if (log.IsEnabled())
						{
							log.BufferRented(array.GetHashCode(), array.Length, Id, _buckets[num2].Id);
						}
						return array;
					}
				}
				while (++num2 < _buckets.Length && num2 != num + 2);
				array = new T[_buckets[num]._bufferLength];
			}
			else
			{
				array = new T[minimumLength];
			}
			if (log.IsEnabled())
			{
				int hashCode = array.GetHashCode();
				int bucketId = -1;
				log.BufferRented(hashCode, array.Length, Id, bucketId);
				log.BufferAllocated(hashCode, array.Length, Id, bucketId, (num >= _buckets.Length) ? System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.OverMaximumSize : System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.PoolExhausted);
			}
			return array;
		}

		public override void Return(T[] array, bool clearArray = false)
		{
			if (array == null)
			{
				throw new ArgumentNullException("array");
			}
			if (array.Length == 0)
			{
				return;
			}
			int num = System.Buffers.Utilities.SelectBucketIndex(array.Length);
			if (num < _buckets.Length)
			{
				if (clearArray)
				{
					Array.Clear(array, 0, array.Length);
				}
				_buckets[num].Return(array);
			}
			System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
			if (log.IsEnabled())
			{
				log.BufferReturned(array.GetHashCode(), array.Length, Id);
			}
		}
	}
	internal static class Utilities
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static int SelectBucketIndex(int bufferSize)
		{
			uint num = (uint)(bufferSize - 1) >> 4;
			int num2 = 0;
			if (num > 65535)
			{
				num >>= 16;
				num2 = 16;
			}
			if (num > 255)
			{
				num >>= 8;
				num2 += 8;
			}
			if (num > 15)
			{
				num >>= 4;
				num2 += 4;
			}
			if (num > 3)
			{
				num >>= 2;
				num2 += 2;
			}
			if (num > 1)
			{
				num >>= 1;
				num2++;
			}
			return num2 + (int)num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static int GetMaxSizeForBucket(int binIndex)
		{
			return 16 << binIndex;
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class NullablePublicOnlyAttribute : Attribute
	{
		public readonly bool IncludesInternals;

		public NullablePublicOnlyAttribute(bool P_0)
		{
			IncludesInternals = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FxResources.System.IO.Pipelines
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class <51b2773e-ed85-4f48-bea9-0bd26c07cd62>SR
	{
		private static readonly bool s_usingResourceKeys = GetUsingResourceKeysSwitchValue();

		private static ResourceManager s_resourceManager;

		internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(FxResources.System.IO.Pipelines.SR)));

		internal static string AdvanceToInvalidCursor => GetResourceString("AdvanceToInvalidCursor");

		internal static string ArgumentOutOfRange_NeedPosNum => GetResourceString("ArgumentOutOfRange_NeedPosNum");

		internal static string ConcurrentOperationsNotSupported => GetResourceString("ConcurrentOperationsNotSupported");

		internal static string FlushCanceledOnPipeWriter => GetResourceString("FlushCanceledOnPipeWriter");

		internal static string GetResultBeforeCompleted => GetResourceString("GetResultBeforeCompleted");

		internal static string InvalidExaminedOrConsumedPosition => GetResourceString("InvalidExaminedOrConsumedPosition");

		internal static string InvalidExaminedPosition => GetResourceString("InvalidExaminedPosition");

		internal static string InvalidZeroByteRead => GetResourceString("InvalidZeroByteRead");

		internal static string ObjectDisposed_StreamClosed => GetResourceString("ObjectDisposed_StreamClosed");

		internal static string NoReadingOperationToComplete => GetResourceString("NoReadingOperationToComplete");

		internal static string NotSupported_UnreadableStream => GetResourceString("NotSupported_UnreadableStream");

		internal static string NotSupported_UnwritableStream => GetResourceString("NotSupported_UnwritableStream");

		internal static string ReadCanceledOnPipeReader => GetResourceString("ReadCanceledOnPipeReader");

		internal static string ReaderAndWriterHasToBeCompleted => GetResourceString("ReaderAndWriterHasToBeCompleted");

		internal static string ReadingAfterCompleted => GetResourceString("ReadingAfterCompleted");

		internal static string ReadingIsInProgress => GetResourceString("ReadingIsInProgress");

		internal static string WritingAfterCompleted => GetResourceString("WritingAfterCompleted");

		internal static string UnflushedBytesNotSupported => GetResourceString("UnflushedBytesNotSupported");

		private static bool GetUsingResourceKeysSwitchValue()
		{
			if (!AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled))
			{
				return false;
			}
			return isEnabled;
		}

		internal static bool UsingResourceKeys()
		{
			return s_usingResourceKeys;
		}

		private static string GetResourceString(string resourceKey)
		{
			if (UsingResourceKeys())
			{
				return resourceKey;
			}
			string result = null;
			try
			{
				result = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			return result;
		}

		private static string GetResourceString(string resourceKey, string defaultString)
		{
			string resourceString = GetResourceString(resourceKey);
			if (!(resourceKey == resourceString) && resourceString != null)
			{
				return resourceString;
			}
			return defaultString;
		}

		internal static string Format(string resourceFormat, object? p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object? p1, object? p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object? p1, object? p2, object? p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}

		internal static string Format(string resourceFormat, params object?[]? args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(provider, resourceFormat, p1);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(provider, resourceFormat, p1, p2);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2, object? p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(provider, resourceFormat, p1, p2, p3);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, params object?[]? args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(provider, resourceFormat, args);
			}
			return resourceFormat;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class <51b2773e-ed85-4f48-bea9-0bd26c07cd62>AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class <51b2773e-ed85-4f48-bea9-0bd26c07cd62>DisallowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class <51b2773e-ed85-4f48-bea9-0bd26c07cd62>MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class <51b2773e-ed85-4f48-bea9-0bd26c07cd62>NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class <51b2773e-ed85-4f48-bea9-0bd26c07cd62>MaybeNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public <51b2773e-ed85-4f48-bea9-0bd26c07cd62>MaybeNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class <51b2773e-ed85-4f48-bea9-0bd26c07cd62>NotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public <51b2773e-ed85-4f48-bea9-0bd26c07cd62>NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
	internal sealed class <51b2773e-ed85-4f48-bea9-0bd26c07cd62>NotNullIfNotNullAttribute : Attribute
	{
		public string ParameterName { get; }

		public <51b2773e-ed85-4f48-bea9-0bd26c07cd62>NotNullIfNotNullAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	internal sealed class <51b2773e-ed85-4f48-bea9-0bd26c07cd62>DoesNotReturnAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class <51b2773e-ed85-4f48-bea9-0bd26c07cd62>DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

		public <51b2773e-ed85-4f48-bea9-0bd26c07cd62>DoesNotReturnIfAttribute(bool parameterValue)
		{
			ParameterValue = parameterValue;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class <51b2773e-ed85-4f48-bea9-0bd26c07cd62>MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public <51b2773e-ed85-4f48-bea9-0bd26c07cd62>MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public <51b2773e-ed85-4f48-bea9-0bd26c07cd62>MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class <51b2773e-ed85-4f48-bea9-0bd26c07cd62>MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public <51b2773e-ed85-4f48-bea9-0bd26c07cd62>MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public <51b2773e-ed85-4f48-bea9-0bd26c07cd62>MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
}
namespace System.Runtime.InteropServices
{
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	internal sealed class <51b2773e-ed85-4f48-bea9-0bd26c07cd62>LibraryImportAttribute : Attribute
	{
		public string LibraryName { get; }

		public string? EntryPoint { get; set; }

		public <51b2773e-ed85-4f48-bea9-0bd26c07cd62>StringMarshalling StringMarshalling { get; set; }

		public Type? StringMarshallingCustomType { get; set; }

		public bool SetLastError { get; set; }

		public <51b2773e-ed85-4f48-bea9-0bd26c07cd62>LibraryImportAttribute(string libraryName)
		{
			LibraryName = libraryName;
		}
	}
	internal enum <51b2773e-ed85-4f48-bea9-0bd26c07cd62>StringMarshalling
	{
		Custom,
		Utf8,
		Utf16
	}
}
namespace System.Threading
{
	internal static class CancellationTokenExtensions
	{
		internal static CancellationTokenRegistration UnsafeRegister(this CancellationToken cancellationToken, Action<object> callback, object state)
		{
			return cancellationToken.Register(callback, state);
		}
	}
}
namespace System.Threading.Tasks
{
	internal static class TaskToAsyncResult
	{
		private sealed class TaskAsyncResult : IAsyncResult
		{
			internal readonly Task _task;

			private readonly AsyncCallback _callback;

			public object AsyncState { get; }

			public bool CompletedSynchronously { get; }

			public bool IsCompleted => _task.IsCompleted;

			public WaitHandle AsyncWaitHandle => ((IAsyncResult)_task).AsyncWaitHandle;

			internal TaskAsyncResult(Task task, object state, AsyncCallback callback)
			{
				_task = task;
				AsyncState = state;
				if (task.IsCompleted)
				{
					CompletedSynchronously = true;
					callback?.Invoke(this);
				}
				else if (callback != null)
				{
					_callback = callback;
					_task.ConfigureAwait(continueOnCapturedContext: false).GetAwaiter().OnCompleted(delegate
					{
						_callback(this);
					});
				}
			}
		}

		public static IAsyncResult Begin(Task task, AsyncCallback? callback, object? state)
		{
			if (task == null)
			{
				throw new ArgumentNullException("task");
			}
			return new TaskAsyncResult(task, state, callback);
		}

		public static void End(IAsyncResult asyncResult)
		{
			Unwrap(asyncResult).GetAwaiter().GetResult();
		}

		public static TResult End<TResult>(IAsyncResult asyncResult)
		{
			return Unwrap<TResult>(asyncResult).GetAwaiter().GetResult();
		}

		public static Task Unwrap(IAsyncResult asyncResult)
		{
			if (asyncResult == null)
			{
				throw new ArgumentNullException("asyncResult");
			}
			return (asyncResult as TaskAsyncResult)?._task ?? throw new ArgumentException(null, "asyncResult");
		}

		public static Task<TResult> Unwrap<TResult>(IAsyncResult asyncResult)
		{
			if (asyncResult == null)
			{
				throw new ArgumentNullException("asyncResult");
			}
			return ((asyncResult as TaskAsyncResult)?._task as Task<TResult>) ?? throw new ArgumentException(null, "asyncResult");
		}
	}
}
namespace System.IO
{
	internal static class StreamHelpers
	{
		public static void ValidateCopyToArgs(Stream source, Stream destination, int bufferSize)
		{
			if (destination == null)
			{
				throw new ArgumentNullException("destination");
			}
			if (bufferSize <= 0)
			{
				throw new ArgumentOutOfRangeException("bufferSize", bufferSize, <51b2773e-ed85-4f48-bea9-0bd26c07cd62>SR.ArgumentOutOfRange_NeedPosNum);
			}
			bool canRead = source.CanRead;
			if (!canRead && !source.CanWrite)
			{
				throw new ObjectDisposedException(null, <51b2773e-ed85-4f48-bea9-0bd26c07cd62>SR.ObjectDisposed_StreamClosed);
			}
			bool canWrite = destination.CanWrite;
			if (!canWrite && !destination.CanRead)
			{
				throw new ObjectDisposedException("destination", <51b2773e-ed85-4f48-bea9-0bd26c07cd62>SR.ObjectDisposed_StreamClosed);
			}
			if (!canRead)
			{
				throw new NotSupportedException(<51b2773e-ed85-4f48-bea9-0bd26c07cd62>SR.NotSupported_UnreadableStream);
			}
			if (!canWrite)
			{
				throw new NotSupportedException(<51b2773e-ed85-4f48-bea9-0bd26c07cd62>SR.NotSupported_UnwritableStream);
			}
		}
	}
}
namespace System.IO.Pipelines
{
	internal sealed class BufferSegment : ReadOnlySequenceSegment<byte>
	{
		private IMemoryOwner<byte> _memoryOwner;

		private byte[] _array;

		private BufferSegment _next;

		private int _end;

		public int End
		{
			get
			{
				return _end;
			}
			set
			{
				_end = value;
				base.Memory = AvailableMemory.Slice(0, value);
			}
		}

		public BufferSegment? NextSegment
		{
			get
			{
				return _next;
			}
			set
			{
				base.Next = value;
				_next = value;
			}
		}

		internal object? MemoryOwner => ((object)_memoryOwner) ?? ((object)_array);

		public Memory<byte> AvailableMemory { get; private set; }

		public int Length => End;

		public int WritableBytes
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return AvailableMemory.Length - End;
			}
		}

		public void SetOwnedMemory(IMemoryOwner<byte> memoryOwner)
		{
			_memoryOwner = memoryOwner;
			AvailableMemory = memoryOwner.Memory;
		}

		public void SetOwnedMemory(byte[] arrayPoolBuffer)
		{
			_array = arrayPoolBuffer;
			AvailableMemory = arrayPoolBuffer;
		}

		public void Reset()
		{
			ResetMemory();
			base.Next = null;
			base.RunningIndex = 0L;
			_next = null;
		}

		public void ResetMemory()
		{
			IMemoryOwner<byte> memoryOwner = _memoryOwner;
			if (memoryOwner != null)
			{
				_memoryOwner = null;
				memoryOwner.Dispose();
			}
			else
			{
				ArrayPool<byte>.Shared.Return(_array);
				_array = null;
			}
			base.Memory = default(ReadOnlyMemory<byte>);
			_end = 0;
			AvailableMemory = default(Memory<byte>);
		}

		public void SetNext(BufferSegment segment)
		{
			NextSegment = segment;
			segment = this;
			while (segment.Next != null)
			{
				segment.NextSegment.RunningIndex = segment.RunningIndex + segment.Length;
				segment = segment.NextSegment;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static long GetLength(BufferSegment startSegment, int startIndex, BufferSegment endSegment, int endIndex)
		{
			return endSegment.RunningIndex + (uint)endIndex - (startSegment.RunningIndex + (uint)startIndex);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static long GetLength(long startPosition, BufferSegment endSegment, int endIndex)
		{
			return endSegment.RunningIndex + (uint)endIndex - startPosition;
		}
	}
	internal readonly struct CompletionData
	{
		public Action<object?> Completion { get; }

		public object? CompletionState { get; }

		public ExecutionContext? ExecutionContext { get; }

		public SynchronizationContext? SynchronizationContext { get; }

		public CompletionData(Action<object?> completion, object? completionState, ExecutionContext? executionContext, SynchronizationContext? synchronizationContext)
		{
			Completion = completion;
			CompletionState = completionState;
			ExecutionContext = executionContext;
			SynchronizationContext = synchronizationContext;
		}
	}
	internal struct FlushResult
	{
		internal ResultFlags _resultFlags;

		public bool IsCanceled => (_resultFlags & ResultFlags.Cance