Decompiled source of MoreJewelry v1.0.6

plugins\MoreJewelry.dll

Decompiled 3 weeks ago
using System;
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.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using ItemManager;
using JetBrains.Annotations;
using Jewelcrafting;
using LocalizationManager;
using Managers;
using Microsoft.CodeAnalysis;
using MockManager;
using MoreJewelry.Data;
using ServerSync;
using SoftReferenceableAssets;
using TMPro;
using UnityEngine;
using UnityEngine.Audio;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.BufferedDeserialization;
using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators;
using YamlDotNet.Serialization.Callbacks;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: Guid("964752f0-09df-446a-9c20-88bf895c6178")]
[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCopyright("Copyright probablykory © 2024")]
[assembly: AssemblyProduct("MoreJewelry")]
[assembly: AssemblyCompany("probablykory")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyDescription("https://valheim.thunderstore.io/package/probablykory/MoreJewelry/")]
[assembly: AssemblyTitle("MoreJewelry")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyFileVersion("1.0.6")]
[assembly: AssemblyConfiguration("")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.6.0")]
[module: <a1a3925d-6012-4308-8e58-ce1063ffffa4>RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<3ca4d439-25b9-42a6-beda-2261507b6b1c>Embedded]
	internal sealed class <3ca4d439-25b9-42a6-beda-2261507b6b1c>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[<3ca4d439-25b9-42a6-beda-2261507b6b1c>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class <269482ad-a4af-4c0a-bc50-c46c6ba7af92>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <269482ad-a4af-4c0a-bc50-c46c6ba7af92>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <269482ad-a4af-4c0a-bc50-c46c6ba7af92>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[<3ca4d439-25b9-42a6-beda-2261507b6b1c>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class <7fadffcb-e7f7-4e27-b64c-2043e30ccf25>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <7fadffcb-e7f7-4e27-b64c-2043e30ccf25>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	[<3ca4d439-25b9-42a6-beda-2261507b6b1c>Embedded]
	[CompilerGenerated]
	internal sealed class <a1a3925d-6012-4308-8e58-ce1063ffffa4>RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public <a1a3925d-6012-4308-8e58-ce1063ffffa4>RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MoreJewelry
{
	public static class ConfigDrawers
	{
		public static Action<ConfigEntryBase> DrawLocationsConfigTable()
		{
			if (!CmAPI.IsLoaded())
			{
				return null;
			}
			return delegate(ConfigEntryBase cfg)
			{
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Expected O, but got Unknown
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Expected O, but got Unknown
				//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
				//IL_0105: Expected O, but got Unknown
				List<string> list = new List<string>();
				bool flag = false;
				_ = CmAPI.RightColumnWidth;
				GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
				foreach (string item in ((string)cfg.BoxedValue).Split(new char[1] { ':' }).ToList())
				{
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					string text = GUILayout.TextField(item, new GUIStyle(GUI.skin.textField)
					{
						fixedWidth = CmAPI.RightColumnWidth - 21 - 21 - 9
					}, Array.Empty<GUILayoutOption>());
					string text2 = (string.IsNullOrEmpty(text) ? item : text);
					flag = flag || text2 != item;
					if (GUILayout.Button("x", new GUIStyle(GUI.skin.button)
					{
						fixedWidth = 21f
					}, Array.Empty<GUILayoutOption>()))
					{
						flag = true;
					}
					else
					{
						list.Add(text2);
					}
					if (GUILayout.Button("+", new GUIStyle(GUI.skin.button)
					{
						fixedWidth = 21f
					}, Array.Empty<GUILayoutOption>()))
					{
						flag = true;
						list.Add("<Location Name>");
					}
					GUILayout.EndHorizontal();
				}
				GUILayout.EndVertical();
				if (flag)
				{
					cfg.BoxedValue = string.Join(":", list);
				}
			};
		}
	}
	[Flags]
	public enum GemLocation : ulong
	{
		Head = 1uL,
		Cloak = 2uL,
		Legs = 4uL,
		Chest = 8uL,
		Sword = 0x20uL,
		Knife = 0x40uL,
		Club = 0x80uL,
		Polearm = 0x100uL,
		Spear = 0x200uL,
		Axe = 0x400uL,
		Bow = 0x800uL,
		Crossbow = 0x1000uL,
		Weapon = 0x2000uL,
		ElementalMagic = 0x4000uL,
		BloodMagic = 0x8000uL,
		Magic = 0x10000uL,
		Tool = 0x20000uL,
		Shield = 0x40000uL,
		Utility = 0x80000uL,
		All = 0x100000uL
	}
	public static class JcPatches
	{
		public static void DoPatches(Harmony harmony)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			Assembly assembly = typeof(API.GemInfo).Assembly;
			MethodInfo method = assembly.GetType("Jewelcrafting.Utils").GetMethod("GetGemLocation");
			MethodInfo method2 = typeof(JcPatches).GetMethod("GetGemLocationPrefix", BindingFlags.Static | BindingFlags.NonPublic);
			if (method != null && method2 != null)
			{
				harmony.Patch((MethodBase)method, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Logger.LogError($"Unable to patch Jewelcrafting.Utils.GetGemLocation:  target = {method}, method = {method2}");
			}
			method = assembly.GetType("Jewelcrafting.GemEffects.Warmth+PreventColdNights").GetMethod("RemoveColdInColdNights", BindingFlags.Static | BindingFlags.NonPublic);
			method2 = typeof(JcPatches).GetMethod("RemoveColdInColdNightsPrefix", BindingFlags.Static | BindingFlags.NonPublic);
			if (method != null && method2 != null)
			{
				harmony.Patch((MethodBase)method, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Logger.LogError($"Unable to patch Jewelcrafting.GemEffects.Warmth+PreventColdNights.RemoveColdInColdNights: target = {method}, method = {method2}");
			}
			method = assembly.GetType("Jewelcrafting.Visual+EquipItem").GetMethod("Equip", BindingFlags.Static | BindingFlags.NonPublic);
			method2 = typeof(JcPatches).GetMethod("OnJCEquipPostfix", BindingFlags.Static | BindingFlags.NonPublic);
			if (method != null && method2 != null)
			{
				harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Logger.LogError($"Unable to patch Jewelcrafting.Visual+EquipItem.Equip: target = {method}, method = {method2}");
			}
		}

		[UsedImplicitly]
		private static bool GetGemLocationPrefix(SharedData item, [<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)] Player player, ref object __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected I4, but got Unknown
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected I4, but got Unknown
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Invalid comparison between Unknown and I4
			ItemType itemType = item.m_itemType;
			GemLocation gemLocation;
			if ((int)itemType <= 7)
			{
				if ((int)itemType != 6)
				{
					if ((int)itemType != 7)
					{
						goto IL_0069;
					}
					gemLocation = GemLocation.Chest;
				}
				else
				{
					gemLocation = GemLocation.Head;
				}
			}
			else if ((int)itemType != 11)
			{
				switch (itemType - 17)
				{
				case 1:
					break;
				case 0:
					goto IL_0055;
				case 2:
					goto IL_005d;
				default:
					goto IL_0069;
				}
				gemLocation = GemLocation.Utility;
			}
			else
			{
				gemLocation = GemLocation.Legs;
			}
			goto IL_015a;
			IL_0055:
			gemLocation = GemLocation.Cloak;
			goto IL_015a;
			IL_0069:
			SkillType skillType = item.m_skillType;
			GemLocation gemLocation2;
			switch (skillType - 1)
			{
			case 0:
				gemLocation2 = GemLocation.Sword;
				break;
			case 1:
				gemLocation2 = GemLocation.Knife;
				break;
			case 2:
				gemLocation2 = GemLocation.Club;
				break;
			case 3:
				gemLocation2 = GemLocation.Polearm;
				break;
			case 4:
				gemLocation2 = GemLocation.Spear;
				break;
			case 5:
				gemLocation2 = GemLocation.Shield;
				break;
			case 6:
				gemLocation2 = (GemLocation)(((Object)(object)player != (Object)null && JewelryManager.IsEffectItemEquipped(player, Effects.Lumberjack)) ? 131072 : 1024);
				break;
			case 7:
				gemLocation2 = GemLocation.Bow;
				break;
			case 13:
				gemLocation2 = GemLocation.Crossbow;
				break;
			case 11:
				gemLocation2 = GemLocation.Tool;
				break;
			case 10:
				if ((int)item.m_itemType == 14)
				{
					gemLocation2 = GemLocation.Knife;
					break;
				}
				goto default;
			case 9:
				gemLocation2 = GemLocation.BloodMagic;
				break;
			case 8:
				gemLocation2 = GemLocation.ElementalMagic;
				break;
			default:
				gemLocation2 = GemLocation.Sword;
				break;
			}
			gemLocation = gemLocation2;
			goto IL_015a;
			IL_005d:
			gemLocation = GemLocation.Tool;
			goto IL_015a;
			IL_015a:
			GemLocation gemLocation3 = gemLocation;
			__result = gemLocation3;
			return false;
		}

		[UsedImplicitly]
		private static bool RemoveColdInColdNightsPrefix(bool cold, Player player, ref bool __result)
		{
			if (cold && EnvMan.instance.GetCurrentEnvironment().m_isColdAtNight && JewelryManager.IsEffectItemEquipped(player, Effects.Warmth))
			{
				cold = false;
			}
			__result = cold;
			return false;
		}

		[UsedImplicitly]
		private static void OnJCEquipPostfix(Humanoid humanoid, ItemData item, ref bool __result)
		{
			if (__result && (Object)(object)item.m_shared?.m_equipStatusEffect != (Object)null && JewelryManager.AvailableEffects.ContainsValue(item.m_shared.m_equipStatusEffect))
			{
				item.m_shared.m_equipStatusEffect.m_icon = item.GetIcon();
			}
		}
	}
	public class YamlConfig
	{
		public class ParsedResult
		{
			public List<JewelryData> Jewelry;
		}

		private static string separator;

		private string filePath = "";

		private string fileName = "";

		private Watcher watcher;

		[<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)]
		private object deserializedYaml;

		private bool isLocalChange;

		private bool isRebroadcast;

		[<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)]
		private static IDeserializer deserializer;

		[<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)]
		private static ISerializer serializer;

		public bool SkipSavingOfValueChange { get; set; }

		public bool UseBuiltinConfig { get; set; }

		public bool EnableRaisingFileEvents
		{
			get
			{
				if (watcher != null)
				{
					return watcher.EnableRaisingEvents;
				}
				return false;
			}
			set
			{
				if (watcher != null)
				{
					watcher.EnableRaisingEvents = value;
				}
			}
		}

		public CustomSyncedValue<string> SyncedValue { get; private set; }

		public ParsedResult Config { get; private set; }

		[<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)]
		[method: <7fadffcb-e7f7-4e27-b64c-2043e30ccf25>NullableContext(2)]
		[field: <269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)]
		public event Action YamlConfigChanged;

		private string GetYamlFullPath()
		{
			return filePath + separator + fileName + ".yml";
		}

		private bool IsSourceOfTruth()
		{
			return MoreJewelry.ConfigSync.IsSourceOfTruth;
		}

		public YamlConfig(string path, string file)
		{
			if (string.IsNullOrWhiteSpace(path))
			{
				throw new ArgumentNullException("path");
			}
			if (string.IsNullOrWhiteSpace(file))
			{
				throw new ArgumentNullException("file");
			}
			filePath = path;
			fileName = file;
			SkipSavingOfValueChange = true;
			watcher = new Watcher(filePath, fileName + ".yml");
			watcher.EnableRaisingEvents = false;
			watcher.FileChanged += WatcherOnFileChanged;
			SyncedValue = new CustomSyncedValue<string>(MoreJewelry.ConfigSync, fileName, "");
			SyncedValue.ValueChanged += OnSyncedValueChanged;
		}

		private void WatcherOnFileChanged(object arg1, FileSystemEventArgs arg2)
		{
			isLocalChange = true;
			OnLoadConfigFile();
			isLocalChange = false;
		}

		private void RebroadcastSyncedValue()
		{
			isRebroadcast = true;
			Extensions.Delay(delegate
			{
				SkipSavingOfValueChange = true;
				SyncedValue.Value = SyncedValue.Value;
				SkipSavingOfValueChange = false;
			})();
		}

		private void OnSyncedValueChanged()
		{
			Logger.LogDebugOnly($"OnSyncedValueChanged: isLocalChange {isLocalChange}, isSourceTruth {IsSourceOfTruth()}, value hash {StringExtensionMethods.GetStableHashCode(SyncedValue.Value)}");
			if (IsSourceOfTruth() && isLocalChange)
			{
				return;
			}
			if (isRebroadcast)
			{
				isRebroadcast = false;
				return;
			}
			if (IsSourceOfTruth() && !isLocalChange)
			{
				if (ZNet.instance != null && ZNet.instance.IsServer())
				{
					Logger.LogDebugOnly("server, nonlocal change, isSourceTruth, queue a rebroadcast of synced value.");
					RebroadcastSyncedValue();
				}
				OnSaveConfigFile(SyncedValue.Value);
				return;
			}
			string text = "remote yaml";
			if (TryParseConfig(text, SyncedValue.Value, out var result))
			{
				if (ZNet.instance != null && ZNet.instance.IsServer() && !isLocalChange)
				{
					Logger.LogDebugOnly("server, nonlocal change, NOT SourceTruth, queue a rebroadcast of synced value.");
					RebroadcastSyncedValue();
				}
				SkipSavingOfValueChange = true;
				SyncedValue.AssignLocalValue(SyncedValue.Value);
				SkipSavingOfValueChange = false;
				Config = result;
				this.YamlConfigChanged?.Invoke();
				Logger.LogInfo("Successfully loaded " + text);
			}
			else
			{
				Logger.LogWarning("Ignoring the changed config file, retaining the originally loaded file.");
			}
		}

		public void LoadInitialConfig(bool enabled)
		{
			watcher.EnableRaisingEvents = enabled;
			UseBuiltinConfig = !enabled;
			isLocalChange = true;
			OnLoadConfigFile();
			isLocalChange = false;
		}

		public void ReloadConfig(bool isLocal)
		{
			isLocalChange = isLocal;
			if (!IsSourceOfTruth())
			{
				OnSyncedValueChanged();
				return;
			}
			if (!UseBuiltinConfig && !File.Exists(GetYamlFullPath()))
			{
				Logger.LogDebugOnly(GetYamlFullPath() + " does not exist. Writing defaults to disk.");
				File.Create(GetYamlFullPath()).Close();
				string contents = ReadTextFromBuiltinFile();
				WriteTextToFile(contents);
			}
			OnLoadConfigFile();
		}

		private void OnLoadConfigFile()
		{
			string text = ReadTextFromFile();
			if (TryParseConfig(fileName + ".yml", text, out var result))
			{
				SkipSavingOfValueChange = true;
				SyncedValue.AssignLocalValue(text);
				SkipSavingOfValueChange = false;
				Config = result;
				if (IsSourceOfTruth())
				{
					this.YamlConfigChanged?.Invoke();
				}
				string text2 = "Successfully loaded ";
				text2 = ((!UseBuiltinConfig) ? (text2 + fileName + ".yml") : (text2 + "the built-in " + fileName + ".defaults.yml"));
				if (!IsSourceOfTruth())
				{
					text2 += ", but skipped applying as remote configuration is active";
				}
				Logger.LogInfo(text2);
			}
			else
			{
				Logger.LogWarning("Ignoring the changed config file, retaining the originally loaded file.");
			}
		}

		private bool TryParseConfig(string source, string text, out ParsedResult result)
		{
			bool flag = false;
			result = null;
			try
			{
				deserializedYaml = ReadYaml<Dictionary<string, JewelryDataUnparsed>>(text);
				result = Parse(deserializedYaml, out var errors);
				if (errors.Count > 0)
				{
					Logger.LogWarning("Found errors in " + source + " config. Please review the syntax of your file:\n" + string.Join("\n", errors));
					flag = true;
				}
			}
			catch (YamlException ex)
			{
				Logger.LogWarning("Parsing " + source + " config failed with an error:\n" + ex.Message + ((ex.InnerException != null) ? (": " + ex.InnerException.Message) : ""));
				flag = true;
			}
			return !flag;
		}

		private void OnSaveConfigFile(object contents)
		{
			if (!SkipSavingOfValueChange && IsSourceOfTruth())
			{
				watcher.EnableRaisingEvents = false;
				WriteTextToFile($"{contents}");
				watcher.EnableRaisingEvents = true;
			}
		}

		private string ReadTextFromBuiltinFile()
		{
			return Encoding.UTF8.GetString(Localizer.ReadEmbeddedFileBytes(fileName + ".defaults.yml"));
		}

		private string ReadTextFromFile()
		{
			string result = "";
			string path = filePath + separator + fileName + ".yml";
			if (UseBuiltinConfig)
			{
				result = ReadTextFromBuiltinFile();
			}
			else
			{
				try
				{
					Logger.LogDebugOnly("attempting to read from " + fileName);
					result = File.ReadAllText(path);
				}
				catch (IOException ex)
				{
					Logger.LogError("Failed reading from " + fileName + " config in " + filePath + ", message:\n " + ex.Message);
				}
			}
			return result;
		}

		private void WriteTextToFile(string contents)
		{
			string yamlFullPath = GetYamlFullPath();
			string text = fileName + ".temp";
			try
			{
				Logger.LogDebugOnly("attempting to write to " + text);
				File.WriteAllText(text, contents);
				File.Replace(text, yamlFullPath, null);
			}
			catch (IOException ex)
			{
				Logger.LogError("Failed writing config back to " + yamlFullPath + ", message: \n" + ex.Message);
			}
		}

		public static T RereadYaml<T>([<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)] object obj)
		{
			return ReadYaml<T>(WriteYaml(obj));
		}

		public static T ReadYaml<T>(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return default(T);
			}
			if (deserializer == null)
			{
				deserializer = new DeserializerBuilder().WithNamingConvention(LowerCaseNamingConvention.Instance).Build();
			}
			return deserializer.Deserialize<T>(text);
		}

		public static string WriteYaml([<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)] object obj)
		{
			if (serializer == null)
			{
				serializer = new SerializerBuilder().WithNamingConvention(LowerCaseNamingConvention.Instance).Build();
			}
			return serializer.Serialize(obj);
		}

		public static List<string> ErrorCheck(string text)
		{
			Parse(ReadYaml<Dictionary<string, JewelryDataUnparsed>>(text), out var errors);
			return errors;
		}

		[return: <269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(new byte[] { 0, 0, 2 })]
		private static Dictionary<string, object> castToStringDict([<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(new byte[] { 0, 0, 2 })] Dictionary<object, object> dict)
		{
			return new Dictionary<string, object>(dict.ToDictionary((KeyValuePair<object, object> kv) => kv.Key.ToString(), (KeyValuePair<object, object> kv) => kv.Value), StringComparer.InvariantCultureIgnoreCase);
		}

		public static ParsedResult Parse([<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)] object root, out List<string> errors)
		{
			ParsedResult parsedResult = new ParsedResult
			{
				Jewelry = new List<JewelryData>()
			};
			errors = new List<string>();
			if (!(root is Dictionary<string, JewelryDataUnparsed> dictionary))
			{
				if (root != null)
				{
					errors.Add($"All top-level keys must be a mapping. Got unexpected {root.GetType()}.");
				}
				return parsedResult;
			}
			foreach (KeyValuePair<string, JewelryDataUnparsed> item in dictionary)
			{
				string text = ((item.Key != null) ? item.Key : item.Key.ToString());
				if (item.Value != null && item.Value != null)
				{
					JewelryData jewelryData = new JewelryData();
					jewelryData.Name = text;
					jewelryData.Description = item.Value.Description;
					if (string.IsNullOrWhiteSpace(item.Value.Prefab))
					{
						errors.Add("Prefab of " + text + " was empty: Prefab must contain a value.");
					}
					else
					{
						jewelryData.Prefab = item.Value.Prefab;
					}
					VisualData visualData2;
					string text2 = parseGemColor(item.Value.Gem, out visualData2);
					if (text2 != null)
					{
						errors.Add(text2);
					}
					else
					{
						jewelryData.Gem = visualData2;
					}
					CraftingData craftingData2;
					string text3 = parseCrafting(item.Value.Crafting, out craftingData2);
					if (text3 != null)
					{
						errors.Add(text3);
					}
					else
					{
						jewelryData.Crafting = craftingData2;
					}
					UpgradeData upgradeData2;
					string text4 = parseUpgrade(item.Value.Upgrade, out upgradeData2);
					if (text4 != null)
					{
						errors.Add(text4);
					}
					else
					{
						jewelryData.Upgrade = upgradeData2;
					}
					EffectData effect2;
					string text5 = parseEffect(item.Value.effect, out effect2);
					if (text5 != null)
					{
						errors.Add(text5);
					}
					else
					{
						jewelryData.effect = effect2;
					}
					parsedResult.Jewelry.Add(jewelryData);
					continue;
				}
				errors.Add($"Expected value to be of type JewelryDataUnparsed, instead got {item.GetType()}.");
				return parsedResult;
			}
			return parsedResult;
			[return: <269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)]
			static string parseCosts(object costsObj, out List<CostData> costData)
			{
				costData = new List<CostData>();
				if (!(costsObj is Dictionary<object, object> dictionary3))
				{
					return string.Format("Costs value must be a mapping of property names & values, got unexpected {0} of type {1}", costsObj, costsObj?.GetType().ToString() ?? "null");
				}
				foreach (KeyValuePair<object, object> item2 in dictionary3)
				{
					CostData costData3 = new CostData
					{
						Name = item2.Key.ToString()
					};
					string[] array = item2.Value?.ToString().Split(new char[1] { ',' });
					if (array == null || array.Length == 0)
					{
						return $"Found costs but failed parsing value {item2.Value} for key {item2.Key}";
					}
					costData3.Amount = ((array.Length == 0 || !int.TryParse(array[0], out var result2)) ? 1 : result2);
					costData3.AmountPerLevel = ((array.Length > 1 && int.TryParse(array[1], out var result3)) ? result3 : 0);
					costData.Add(costData3);
				}
				return null;
			}
			static string parseCrafting(object craftingObj, out CraftingData craftingData)
			{
				craftingData = new CraftingData();
				if (!(craftingObj is IDictionary) || !(craftingObj is Dictionary<object, object>))
				{
					return string.Format("Crafting must be a mapping of property names & values, got unexpected {0} of type {1}", craftingObj, craftingObj?.GetType().ToString() ?? "null");
				}
				Dictionary<string, object> dictionary4 = castToStringDict(craftingObj as Dictionary<object, object>);
				if (!dictionary4.TryGetValue("craftingstation", out var value) || !(value is string))
				{
					return $"Crafting must contain a valid craftingstation: {value}";
				}
				craftingData.CraftingStation = (string)value;
				if (dictionary4.TryGetValue("stationlevel", out var value2) && value2 is string && int.TryParse((string)value2, out var result4))
				{
					craftingData.StationLevel = result4;
				}
				else
				{
					craftingData.StationLevel = 1;
				}
				if (dictionary4.TryGetValue("maxquality", out var value3) && value3 is string && int.TryParse((string)value3, out var result5))
				{
					craftingData.MaxQuality = result5;
				}
				else
				{
					craftingData.MaxQuality = -1;
				}
				if (dictionary4.TryGetValue("costs", out var value4))
				{
					List<CostData> costData4;
					string text7 = parseCosts(value4, out costData4);
					if (text7 != null)
					{
						return text7;
					}
					craftingData.Costs = costData4;
				}
				return null;
			}
			[return: <269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)]
			static string parseEffect(object effectObj, out EffectData effect)
			{
				effect = new EffectData();
				if (effectObj is IDictionary obj)
				{
					StatusEffectData seData;
					try
					{
						seData = RereadYaml<StatusEffectData>(obj);
					}
					catch (YamlException ex)
					{
						return "Found an effect definition but, but parsing failed with an error:\n" + ex.Message + ((ex.InnerException != null) ? (": " + ex.InnerException.Message) : "");
					}
					effect.SeData = seData;
				}
				else if (effectObj is string nameToResolve)
				{
					effect.NameToResolve = nameToResolve;
				}
				else
				{
					if (effectObj != null)
					{
						return string.Format("Effect value must be either a string or a mapping of property names & values, got unexpected {0} of type {1}", effectObj, effectObj?.GetType().ToString() ?? "null");
					}
					effect = null;
				}
				return null;
			}
			[return: <269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)]
			static string parseGemColor(object colorObj, out VisualData visualData)
			{
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				visualData = new VisualData
				{
					Color = null
				};
				if (colorObj == null)
				{
					visualData.Visible = true;
				}
				else
				{
					if (!(colorObj is string text8))
					{
						return string.Format("Color value must be a string value either of 'visible', 'hidden' or an html color, got unexpected {0} of type {1}", colorObj, colorObj?.GetType().ToString() ?? "null");
					}
					if (string.Equals("hidden", text8, StringComparison.InvariantCultureIgnoreCase))
					{
						visualData.Visible = false;
					}
					else if (string.Equals("visible", text8, StringComparison.InvariantCultureIgnoreCase))
					{
						visualData.Visible = true;
					}
					else
					{
						Color value5 = default(Color);
						if (!ColorUtility.TryParseHtmlString(text8, ref value5) && !ColorUtility.TryParseHtmlString("#" + text8, ref value5))
						{
							return $"Color value must be a string value either of 'visible', 'hidden' or an html color, got unexpected {colorObj}";
						}
						visualData.Color = value5;
						visualData.Visible = true;
					}
				}
				return null;
			}
			[return: <269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)]
			static string parseUpgrade(object upgradeOjb, out UpgradeData upgradeData)
			{
				upgradeData = new UpgradeData
				{
					Costs = new Dictionary<int, List<CostData>>()
				};
				if (upgradeOjb is Dictionary<object, object> dictionary2)
				{
					foreach (KeyValuePair<object, object> item3 in dictionary2)
					{
						if (!int.TryParse(item3.Key.ToString(), out var result))
						{
							return $"Found upgrade but failed parsing level key {item3.Key}";
						}
						List<CostData> costData2;
						string text6 = parseCosts(item3.Value, out costData2);
						if (text6 != null)
						{
							return text6;
						}
						upgradeData.Costs[result] = costData2;
					}
				}
				else
				{
					if (upgradeOjb != null)
					{
						return string.Format("Upgrade value must be a mapping of an integer level starting at 1 for the first upgrade, got unexpected {0} of type {1}", upgradeOjb, upgradeOjb?.GetType().ToString() ?? "null");
					}
					upgradeData = null;
				}
				return null;
			}
		}

		static YamlConfig()
		{
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			separator = directorySeparatorChar.ToString();
			deserializer = null;
			serializer = null;
		}
	}
	public static class Extensions
	{
		public static Action Delay(this Action func, int milliseconds = 100)
		{
			CancellationTokenSource cancelTokenSource = null;
			return delegate
			{
				cancelTokenSource?.Cancel();
				cancelTokenSource = new CancellationTokenSource();
				Task.Delay(milliseconds, cancelTokenSource.Token).ContinueWith(delegate(Task t)
				{
					if (!t.IsCanceled)
					{
						func();
					}
				}, TaskScheduler.Default);
			};
		}
	}
	public static class Aquatic
	{
		[HarmonyPatch(typeof(SE_Wet), "UpdateStatusEffect")]
		private static class ApplyAquatic
		{
			private static void Postfix(SE_Wet __instance)
			{
				if ((Object)(object)((StatusEffect)__instance).m_character != (Object)(object)Player.m_localPlayer || !JewelryManager.IsEffectItemEquipped(Player.m_localPlayer, Effects.Aquatic))
				{
					return;
				}
				SE_Stats gemEffect = JcAPI.GetGemEffect<SE_Stats>(Effects.Aquatic);
				if (!((Object)(object)gemEffect != (Object)null))
				{
					return;
				}
				StatusEffect val = ((Character)Player.m_localPlayer).GetSEMan().GetStatusEffect(StringExtensionMethods.GetStableHashCode(((Object)gemEffect).name));
				if ((Object)(object)val == (Object)null)
				{
					ItemData equippedItemByEffect = JewelryManager.GetEquippedItemByEffect(Player.m_localPlayer, Effects.Aquatic);
					if (equippedItemByEffect != null)
					{
						((StatusEffect)gemEffect).m_icon = equippedItemByEffect.GetIcon();
					}
					val = ((Character)Player.m_localPlayer).GetSEMan().AddStatusEffect((StatusEffect)(object)gemEffect, false, 0, 0f);
				}
				val.m_ttl = ((StatusEffect)__instance).m_ttl;
				val.m_time = ((StatusEffect)__instance).m_time;
			}
		}

		static Aquatic()
		{
			JcAPI.AddOnEffectRecalc(delegate
			{
				if (!JewelryManager.IsEffectItemEquipped(Player.m_localPlayer, Effects.Aquatic))
				{
					SE_Stats gemEffect = JcAPI.GetGemEffect<SE_Stats>(Effects.Aquatic);
					if ((Object)(object)gemEffect != (Object)null)
					{
						((Character)Player.m_localPlayer).m_seman.RemoveStatusEffect((StatusEffect)(object)gemEffect, false);
					}
				}
			});
		}
	}
	public static class Effects
	{
		public static string None => string.Empty;

		public static string Aquatic => "aquatic";

		public static string Awareness => "awareness";

		public static string Guidance => "guidance";

		public static string Headhunter => "headhunter";

		public static string Legacy => "legacy";

		public static string Lumberjack => "lumberjack";

		public static string MagicRepair => "magicRepair";

		public static string ModersBlessing => "modersBlessing";

		public static string RigidFinger => "rigidFinger";

		public static string Warmth => "warmth";

		public static string Perception => "perception";

		public static string GetEffectNameFromJcName(string jcName)
		{
			return jcName switch
			{
				"JC_Necklace_Red" => Awareness, 
				"JC_Necklace_Green" => MagicRepair, 
				"JC_Necklace_Blue" => Aquatic, 
				"JC_Necklace_Yellow" => Lumberjack, 
				"JC_Necklace_Purple" => Guidance, 
				"JC_Ring_Purple" => RigidFinger, 
				"JC_Ring_Green" => Headhunter, 
				"JC_Ring_Red" => Warmth, 
				"JC_Ring_Blue" => ModersBlessing, 
				"JC_Ring_Black" => Legacy, 
				_ => None, 
			};
		}
	}
	public static class Headhunter
	{
		[HarmonyPatch(typeof(Character), "Damage")]
		private static class ApplyHeadHunter
		{
			private static void Postfix(Character __instance, HitData hit)
			{
				if (!__instance.IsBoss())
				{
					return;
				}
				Character attacker = hit.GetAttacker();
				Player val = (Player)(object)((attacker is Player) ? attacker : null);
				if (val == null || !JewelryManager.IsEffectItemEquipped(val, Effects.Headhunter) || __instance.m_nview.GetZDO().GetBool($"Jewelcrafting HeadHunter {val.GetPlayerID()}", false))
				{
					return;
				}
				SE_Stats gemEffect = JcAPI.GetGemEffect<SE_Stats>(Effects.Headhunter);
				if ((Object)(object)gemEffect != (Object)null)
				{
					ItemData equippedItemByEffect = JewelryManager.GetEquippedItemByEffect(Player.m_localPlayer, Effects.Headhunter);
					if (equippedItemByEffect != null)
					{
						((StatusEffect)gemEffect).m_icon = equippedItemByEffect.GetIcon();
					}
					((Character)val).m_seman.AddStatusEffect((StatusEffect)(object)gemEffect, true, 0, 0f);
					__instance.m_nview.GetZDO().Set($"Jewelcrafting HeadHunter {val.GetPlayerID()}", true);
				}
			}
		}

		static Headhunter()
		{
			JcAPI.AddOnEffectRecalc(delegate
			{
				if (!JewelryManager.IsEffectItemEquipped(Player.m_localPlayer, Effects.Headhunter))
				{
					SE_Stats gemEffect = JcAPI.GetGemEffect<SE_Stats>(Effects.Headhunter);
					if ((Object)(object)gemEffect != (Object)null)
					{
						((Character)Player.m_localPlayer).m_seman.RemoveStatusEffect((StatusEffect)(object)gemEffect, false);
					}
				}
			});
		}
	}
	public class Perception : SE_Stats
	{
		private static GameObject questObjectiveVfx;

		private static List<string> Locations;

		static Perception()
		{
			questObjectiveVfx = null;
			Locations = new List<string> { "Vendor_BlackForest", "Hildir_camp" };
			object? obj = AccessTools.Field(typeof(API.GemInfo).Assembly.GetType("Jewelcrafting.GemEffectSetup"), "legacyRingHildirQuest")?.GetValue(null);
			questObjectiveVfx = (GameObject)((obj is GameObject) ? obj : null);
		}

		public Perception()
		{
			((StatusEffect)this).m_name = "$jc_se_perception";
			((StatusEffect)this).m_tooltip = ((StatusEffect)this).m_name + "_description";
		}

		public static void SetLocations(string locations)
		{
			if (!string.IsNullOrWhiteSpace(locations))
			{
				Locations = locations.Split(new char[1] { ':' }).ToList();
			}
		}

		public override void UpdateStatusEffect(float dt)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: 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)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			base.m_tickTimer += dt;
			if (base.m_tickTimer >= MoreJewelry.perceptionCooldown.Value)
			{
				Transform transform = ((Component)Player.m_localPlayer).transform;
				if (transform.position.y < 3500f && Locations.Count > 0)
				{
					Dictionary<Vector3, string> dictionary = new Dictionary<Vector3, string>();
					LocationInstance val = default(LocationInstance);
					foreach (string location in Locations)
					{
						if (ZoneSystem.instance.FindClosestLocation(location, transform.position, ref val))
						{
							dictionary.Add(val.m_position, location);
						}
					}
					Vector3 key = default(Vector3);
					((Vector3)(ref key))..ctor(1000000f, 1000000f, 1000000f);
					foreach (KeyValuePair<Vector3, string> item in dictionary)
					{
						if (Locations.Contains(item.Value) && Utils.DistanceXZ(key, transform.position) > Utils.DistanceXZ(item.Key, transform.position))
						{
							key = item.Key;
						}
					}
					if (Utils.DistanceXZ(key, transform.position) < MoreJewelry.perceptionMinDistance.Value)
					{
						Vector3 val2 = key - transform.position;
						val2.y = 0f;
						Object.Instantiate<GameObject>(questObjectiveVfx, transform.position + transform.forward * 2f + transform.up, Quaternion.LookRotation(val2));
					}
				}
				base.m_tickTimer = 0f;
			}
			((SE_Stats)this).UpdateStatusEffect(dt);
		}
	}
	public static class Icons
	{
		public static void SnapshotItem(ItemDrop item, Quaternion? quat = null)
		{
			MoreJewelry instance = MoreJewelry.Instance;
			if (instance != null)
			{
				((MonoBehaviour)instance).StartCoroutine(Do());
			}
			IEnumerator Do()
			{
				yield return null;
				Quaternion rotation = (quat.HasValue ? quat.Value : Quaternion.Euler(20f, -150f, 40f));
				Camera component = new GameObject("Camera", new Type[1] { typeof(Camera) }).GetComponent<Camera>();
				component.backgroundColor = Color.clear;
				component.clearFlags = (CameraClearFlags)2;
				component.fieldOfView = 0.5f;
				component.farClipPlane = 10000000f;
				component.cullingMask = 1073741824;
				Light component2 = new GameObject("Light", new Type[1] { typeof(Light) }).GetComponent<Light>();
				((Component)component2).transform.rotation = Quaternion.Euler(5f, -5f, 5f);
				component2.type = (LightType)1;
				component2.cullingMask = 1073741824;
				component2.intensity = 1.25f;
				Rect val = default(Rect);
				((Rect)(ref val))..ctor(0f, 0f, 64f, 64f);
				GameObject val2 = Object.Instantiate<GameObject>(((Component)((Component)item).transform.Find("attach")).gameObject);
				val2.transform.rotation = rotation;
				Transform[] componentsInChildren = val2.GetComponentsInChildren<Transform>();
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					((Component)componentsInChildren[i]).gameObject.layer = 30;
				}
				Renderer[] componentsInChildren2 = val2.GetComponentsInChildren<Renderer>();
				Vector3 val3 = componentsInChildren2.Aggregate<Renderer, Vector3>(Vector3.positiveInfinity, delegate(Vector3 cur, Renderer renderer)
				{
					//IL_001d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Unknown result type (might be due to invalid IL or missing references)
					//IL_000a: Unknown result type (might be due to invalid IL or missing references)
					//IL_000f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0012: Unknown result type (might be due to invalid IL or missing references)
					//IL_0017: Unknown result type (might be due to invalid IL or missing references)
					if (!(renderer is ParticleSystemRenderer))
					{
						Bounds bounds2 = renderer.bounds;
						return Vector3.Min(cur, ((Bounds)(ref bounds2)).min);
					}
					return cur;
				});
				Vector3 val4 = componentsInChildren2.Aggregate<Renderer, Vector3>(Vector3.negativeInfinity, delegate(Vector3 cur, Renderer renderer)
				{
					//IL_001d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Unknown result type (might be due to invalid IL or missing references)
					//IL_000a: Unknown result type (might be due to invalid IL or missing references)
					//IL_000f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0012: Unknown result type (might be due to invalid IL or missing references)
					//IL_0017: Unknown result type (might be due to invalid IL or missing references)
					if (!(renderer is ParticleSystemRenderer))
					{
						Bounds bounds = renderer.bounds;
						return Vector3.Max(cur, ((Bounds)(ref bounds)).max);
					}
					return cur;
				});
				Vector3 val5 = val4 - val3;
				component.targetTexture = RenderTexture.GetTemporary((int)((Rect)(ref val)).width, (int)((Rect)(ref val)).height, 0, (RenderTextureFormat)7, (RenderTextureReadWrite)1);
				float num = Mathf.Max(val5.x, val5.y) * 1.05f / Mathf.Tan(component.fieldOfView * ((float)Math.PI / 180f));
				((Component)component).transform.position = (val3 + val4) / 2f + new Vector3(0f, 0f, 0f - num);
				component.Render();
				RenderTexture active = RenderTexture.active;
				RenderTexture.active = component.targetTexture;
				Texture2D val6 = new Texture2D((int)((Rect)(ref val)).width, (int)((Rect)(ref val)).height, (TextureFormat)5, false);
				val6.ReadPixels(val, 0, 0);
				val6.Apply();
				RenderTexture.active = active;
				item.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { Sprite.Create(val6, val, new Vector2(0.5f, 0.5f)) };
				if ((Object)(object)item.m_itemData.m_shared.m_equipStatusEffect != (Object)null)
				{
					item.m_itemData.m_shared.m_equipStatusEffect.m_icon = item.m_itemData.m_shared.m_icons[0];
				}
				Object.DestroyImmediate((Object)(object)val2);
				component.targetTexture.Release();
				Object.Destroy((Object)(object)component);
				Object.Destroy((Object)(object)component2);
			}
		}
	}
	public enum GemStyle
	{
		None,
		Default,
		Color
	}
	public static class JcAPI
	{
		private static Type visualType;

		private static IDictionary visualsDict;

		public static bool IsLoaded()
		{
			return API.IsLoaded();
		}

		public static GameObject GetGemcuttersTable()
		{
			return API.GetGemcuttersTable();
		}

		public static void AddOnEffectRecalc(Action action)
		{
			if (action != null)
			{
				API.OnEffectRecalc += action;
			}
		}

		public static void RemoveOnEffectRecalc(Action action)
		{
			if (action != null)
			{
				API.OnEffectRecalc -= action;
			}
		}

		public static T GetGemEffect<T>(string name) where T : Object
		{
			object? obj = AccessTools.Field(typeof(API.GemInfo).Assembly.GetType("Jewelcrafting.GemEffectSetup"), name)?.GetValue(null);
			return (T)((obj is T) ? obj : null);
		}

		public static bool IsJewelryEquipped(Player player, string prefabName)
		{
			return API.IsJewelryEquipped(player, prefabName);
		}

		public static GameObject CreateNecklaceFromTemplate(string colorName, Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return API.CreateNecklaceFromTemplate(colorName, color);
		}

		public static GameObject CreateNecklaceFromTemplate(string colorName, Material material)
		{
			return API.CreateNecklaceFromTemplate(colorName, material);
		}

		public static GameObject CreateRingFromTemplate(string colorName, Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return API.CreateRingFromTemplate(colorName, color);
		}

		public static GameObject CreateRingFromTemplate(string colorName, Material material)
		{
			return API.CreateRingFromTemplate(colorName, material);
		}

		public static GameObject CreateItemFromTemplate(GameObject template, string prefabName, string localizationName, Color color)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			return CreateItemFromTemplate(template, prefabName, localizationName, GemStyle.Color, color);
		}

		public static GameObject CreateItemFromTemplate(GameObject template, string prefabName, string localizationName, GemStyle style = GemStyle.Default, Color? color = null)
		{
			prefabName = "JC_" + prefabName.Replace(" ", "_");
			localizationName = localizationName.Replace(" ", "_");
			GameObject obj = Object.Instantiate<GameObject>(template, MoreJewelry.Instance.Container.transform);
			((Object)obj).name = prefabName;
			SharedData shared = obj.GetComponent<ItemDrop>().m_itemData.m_shared;
			shared.m_name = "$" + localizationName;
			shared.m_description = "$" + localizationName + "_description";
			SetItemStyle(obj, style, color);
			API.MarkJewelry(obj);
			return obj;
		}

		public static void SetItemStyle(GameObject gameObject, GemStyle style, Color? color)
		{
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			switch (style)
			{
			case GemStyle.None:
				((Component)gameObject.transform.Find("attach/Custom_Color_Mesh")).gameObject.SetActive(false);
				break;
			case GemStyle.Default:
				((Component)gameObject.transform.Find("attach/Custom_Color_Mesh")).gameObject.SetActive(true);
				break;
			case GemStyle.Color:
				if (color.HasValue)
				{
					MeshRenderer component = ((Component)gameObject.transform.Find("attach/Custom_Color_Mesh")).GetComponent<MeshRenderer>();
					int? num = AccessTools.Field(typeof(API.GemInfo).Assembly.GetType("Jewelcrafting.GemStoneSetup"), "ShaderColorKey")?.GetValue(null) as int?;
					int? num2 = AccessTools.Field(typeof(API.GemInfo).Assembly.GetType("Jewelcrafting.GemStoneSetup"), "EmissionColor")?.GetValue(null) as int?;
					if (num.HasValue && num2.HasValue)
					{
						((Renderer)component).material.SetColor(num.Value, color.Value);
						((Renderer)component).material.SetColor(num2.Value, color.Value);
					}
				}
				break;
			}
			Icons.SnapshotItem(gameObject.GetComponent<ItemDrop>());
		}

		private static object GetFieldFromVisualsDictByName(Player player, string fieldname)
		{
			object result = null;
			if (visualsDict == null)
			{
				visualType = typeof(API.GemInfo).Assembly.GetType("Jewelcrafting.Visual");
				visualsDict = AccessTools.Field(visualType, "visuals").GetValue(null) as IDictionary;
			}
			if (visualsDict.Contains(((Humanoid)player).m_visEquipment))
			{
				object obj = visualsDict[((Humanoid)player).m_visEquipment];
				result = AccessTools.Field(visualType, fieldname).GetValue(obj);
			}
			return result;
		}

		public static ItemData GetEquippedFingerItem(Player player)
		{
			object fieldFromVisualsDictByName = GetFieldFromVisualsDictByName(player, "equippedFingerItem");
			return (ItemData)((fieldFromVisualsDictByName is ItemData) ? fieldFromVisualsDictByName : null);
		}

		public static ItemData GetEquippedNeckItem(Player player)
		{
			object fieldFromVisualsDictByName = GetFieldFromVisualsDictByName(player, "equippedNeckItem");
			return (ItemData)((fieldFromVisualsDictByName is ItemData) ? fieldFromVisualsDictByName : null);
		}
	}
	public enum JewelryKind
	{
		None,
		DefaultNecklace,
		CustomNecklace,
		LeatherNecklace,
		SilverNecklace,
		DefaultRing,
		CustomRing,
		StoneRing,
		BoneRing,
		SilverRing
	}
	public static class JewelryManager
	{
		public static readonly Dictionary<string, StatusEffect> AvailableEffects = new Dictionary<string, StatusEffect>(StringComparer.InvariantCultureIgnoreCase);

		public static readonly Dictionary<string, List<string>> EffectItemMap = new Dictionary<string, List<string>>(StringComparer.InvariantCultureIgnoreCase);

		public static readonly Dictionary<JewelryKind, GameObject> AvailablePrefabs = new Dictionary<JewelryKind, GameObject>();

		private static bool initialized = false;

		public static bool IsInitialized()
		{
			return initialized;
		}

		public static void Initialize()
		{
			if (initialized)
			{
				return;
			}
			foreach (string item in new List<string> { "JC_Necklace_Red", "JC_Necklace_Green", "JC_Necklace_Yellow", "JC_Necklace_Purple", "JC_Ring_Purple", "JC_Ring_Red", "JC_Ring_Blue", "JC_Ring_Black" })
			{
				string effectNameFromJcName = Effects.GetEffectNameFromJcName(item);
				if (!AvailableEffects.TryGetValue(effectNameFromJcName, out var value))
				{
					value = fetchEffectFor(item);
					if ((Object)(object)value != (Object)null)
					{
						AvailableEffects.Add(effectNameFromJcName, value);
						AddItemToEffectItemMap(item, effectNameFromJcName);
						Logger.LogDebugOnly("Found " + item + ", extracted " + effectNameFromJcName);
					}
					else
					{
						Logger.LogDebug("Could not find " + item + " prefab for effect extraction.");
					}
				}
			}
			AvailableEffects.Add(Effects.Perception, (StatusEffect)(object)ScriptableObject.CreateInstance<Perception>());
			AddItemToEffectItemMap("JC_Necklace_Blue", Effects.Aquatic);
			AddItemToEffectItemMap("JC_Ring_Green", Effects.Headhunter);
			initialized = true;
			static StatusEffect fetchEffectFor(string prefabName)
			{
				GameObject prefab = PrefabManager.GetPrefab(prefabName);
				return ((prefab == null) ? null : prefab.GetComponent<ItemDrop>()?.m_itemData.m_shared)?.m_equipStatusEffect;
			}
		}

		private static void AddItemToEffectItemMap(string prefabName, string effectName)
		{
			if (!EffectItemMap.TryGetValue(effectName, out var value) || value == null)
			{
				value = new List<string>();
				EffectItemMap.Add(effectName, value);
			}
			if (!value.Contains(prefabName))
			{
				value.Add(prefabName);
			}
		}

		public static void AddAvailablePrefab(JewelryKind kind, GameObject prefab)
		{
			AvailablePrefabs.Add(kind, prefab);
		}

		public static bool IsEffectItemEquipped(Player player, string effectName)
		{
			if (!initialized)
			{
				return false;
			}
			bool flag = false;
			if (EffectItemMap.TryGetValue(effectName, out var value) && value != null && value.Count > 0)
			{
				foreach (string item in value)
				{
					flag = flag || JcAPI.IsJewelryEquipped(player, item);
				}
			}
			return flag;
		}

		public static ItemData GetEquippedItemByEffect(Player player, string effectName)
		{
			if (!initialized)
			{
				return null;
			}
			ItemData val = null;
			if (EffectItemMap.TryGetValue(effectName, out var value) && value != null && value.Count > 0)
			{
				val = JcAPI.GetEquippedFingerItem(player);
				if (val != null)
				{
					List<string> list = value;
					GameObject dropPrefab = val.m_dropPrefab;
					if (list.Contains((dropPrefab != null) ? ((Object)dropPrefab).name : null))
					{
						return val;
					}
				}
				val = JcAPI.GetEquippedNeckItem(player);
				if (val != null)
				{
					List<string> list2 = value;
					GameObject dropPrefab2 = val.m_dropPrefab;
					if (list2.Contains((dropPrefab2 != null) ? ((Object)dropPrefab2).name : null))
					{
						return val;
					}
				}
			}
			return null;
		}

		public static bool IsItemMappedToEffect(GameObject prefab, string effectName)
		{
			if (!initialized)
			{
				return false;
			}
			if (EffectItemMap.TryGetValue(effectName, out var value) && value == null)
			{
				return value.Contains(((Object)prefab).name);
			}
			return false;
		}

		public static void RemoveItemFromEffectItemMap(string prefabName, string effectName)
		{
			if (initialized && EffectItemMap.TryGetValue(effectName, out var value) && value != null)
			{
				if (value.Contains(prefabName))
				{
					value.Remove(prefabName);
				}
				if (value.Count == 0)
				{
					EffectItemMap.Remove(effectName);
				}
			}
		}

		public static void AddEffectToItem(Item item, string effectName)
		{
			if (!initialized)
			{
				return;
			}
			AddItemToEffectItemMap(((Object)item.Prefab).name, effectName);
			StatusEffect value;
			if (Effects.Aquatic.Equals(effectName) || Effects.Headhunter.Equals(effectName))
			{
				SE_Stats gemEffect = JcAPI.GetGemEffect<SE_Stats>(effectName);
				if (gemEffect != null)
				{
					item.Description.English(item.Description.English() + "\n\n<color=orange>" + Localization.instance.Localize(((StatusEffect)gemEffect).m_name) + "</color>\n" + Localization.instance.Localize(((StatusEffect)gemEffect).GetTooltipString()).Replace(".", "").Replace("\n", " ") + Localization.instance.Localize(((StatusEffect)gemEffect).m_name + "_effect"));
				}
			}
			else if (AvailableEffects.TryGetValue(effectName, out value) && (Object)(object)value != (Object)null)
			{
				item.Prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_equipStatusEffect = value;
			}
		}

		public static void ClearAllEffectsFromItem(Item item)
		{
			if (!initialized)
			{
				return;
			}
			item.Prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_equipStatusEffect = null;
			foreach (string item2 in EffectItemMap.Keys.ToList())
			{
				RemoveItemFromEffectItemMap(((Object)item.Prefab).name, item2);
			}
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("probablykory.MoreJewelry", "MoreJewelry", "1.0.6")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class MoreJewelry : BaseUnityPlugin, IPlugin
	{
		public enum Toggle
		{
			On = 1,
			Off = 0
		}

		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public int? Order;

			[UsedImplicitly]
			public bool? Browsable;

			[UsedImplicitly]
			[<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)]
			public string Category;

			[UsedImplicitly]
			public bool? HideSettingName;

			[UsedImplicitly]
			public bool? HideDefaultButton;

			[UsedImplicitly]
			public bool? IsAdvanced;

			[UsedImplicitly]
			[<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(new byte[] { 2, 0 })]
			public Action<ConfigEntryBase> CustomDrawer;
		}

		internal const string PluginName = "MoreJewelry";

		internal const string PluginVersion = "1.0.6";

		internal const string PluginAuthor = "probablykory";

		internal const string PluginGUID = "probablykory.MoreJewelry";

		internal static string ConnectionError = "";

		internal static MoreJewelry Instance = null;

		private readonly Harmony harmony = new Harmony("probablykory.MoreJewelry");

		private AssetBundle assetBundle;

		private GameObject rootContainer;

		internal static readonly ConfigSync ConfigSync = new ConfigSync("probablykory.MoreJewelry")
		{
			DisplayName = "MoreJewelry",
			CurrentVersion = "1.0.6",
			MinimumRequiredVersion = "1.0.6"
		};

		private static ConfigEntry<Toggle> serverConfigLocked = null;

		private static ConfigEntry<Toggle> isDebugEnabled = null;

		private static SyncedConfigEntry<Toggle> useExternalYaml = null;

		private static ConfigEntry<int> yamlAnchor = null;

		private static YamlConfig yamlConfig;

		private static YamlConfigEditor yamlEditor;

		private static ConfigEntry<string> perceptionLocations = null;

		internal static ConfigEntry<float> perceptionCooldown = null;

		internal static ConfigEntry<float> perceptionMinDistance = null;

		private bool yamlParsed;

		private bool assetsLoaded;

		private static readonly Dictionary<string, string> stationMap = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)
		{
			{
				"None",
				string.Empty
			},
			{ "Workbench", "Workbench" },
			{ "Forge", "Forge" },
			{ "Stonecutter", "Stonecutter" },
			{ "Cauldron", "Cauldron" },
			{ "ArtisanTable", "ArtisanTable" },
			{ "BlackForge", "BlackForge" },
			{ "GaldrTable", "GaldrTable" },
			{
				"GemcutterTable",
				((Object)JcAPI.GetGemcuttersTable()).name
			},
			{
				"Gemcutter",
				((Object)JcAPI.GetGemcuttersTable()).name
			}
		};

		private static readonly Dictionary<string, Item> loadedItems = new Dictionary<string, Item>();

		public string GUID => "probablykory.MoreJewelry";

		public Logger Logger => Logger.Instance;

		public ManualLogSource LogSource { get; private set; } = Logger.CreateLogSource("MoreJewelry");


		public bool Debug
		{
			get
			{
				if (isDebugEnabled == null)
				{
					return false;
				}
				return isDebugEnabled.Value == Toggle.On;
			}
		}

		public Harmony Harmony => harmony;

		internal GameObject Container => rootContainer;

		public void Awake()
		{
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Expected O, but got Unknown
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Expected O, but got Unknown
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Expected O, but got Unknown
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Expected O, but got Unknown
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Expected O, but got Unknown
			Instance = this;
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
			if (!JcAPI.IsLoaded())
			{
				Logger.LogFatal("Jewelcrafting mod is missing, unable to load MoreJewelry.");
				return;
			}
			yamlConfig = new YamlConfig(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), "MoreJewelry");
			yamlConfig.YamlConfigChanged += OnYamlConfigChanged;
			yamlEditor = ((Component)this).gameObject.AddComponent<YamlConfigEditor>();
			yamlEditor.Initialize("MoreJewelry", ConfigSync, yamlConfig, YamlConfig.ErrorCheck);
			int num = 0;
			serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, "If on, the configuration is locked and can be changed by server admins only.");
			ConfigSync.AddLockingConfigEntry<Toggle>(serverConfigLocked);
			isDebugEnabled = config("1 - General", "Debugging Enabled", Toggle.Off, new ConfigDescription("If on, mod will output alot more information in the debug log level.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					IsAdvanced = true
				}
			}));
			useExternalYaml = ConfigSync.AddConfigEntry<Toggle>(((BaseUnityPlugin)this).Config.Bind<Toggle>("2 - Jewelry", "Use External YAML", Toggle.Off, new ConfigDescription("If set to on, the YAML file from your config folder will be used to configure custom jewelry.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			})));
			useExternalYaml.SourceConfig.SettingChanged += OnExternalYamlSettingChanged;
			yamlAnchor = config("2 - Jewelry", "YAML Editor Anchor", 0, new ConfigDescription("Just ignore this.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					HideSettingName = true,
					HideDefaultButton = true,
					CustomDrawer = yamlEditor.DrawYamlEditorButton,
					Order = (num -= 1),
					Browsable = false
				}
			}), synchronizedSetting: false);
			perceptionLocations = config("2 - Jewelry", "Perception Locations", "Vendor_BlackForest:Hildir_camp", new ConfigDescription("The list of locations Perception will lead the wearer towards.", (AcceptableValueBase)(object)new AcceptableValueConfigNote("You must use valid location names, separated by a colon."), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					CustomDrawer = ConfigDrawers.DrawLocationsConfigTable(),
					Order = (num -= 1)
				}
			}));
			perceptionLocations.SettingChanged += delegate
			{
				Perception.SetLocations(perceptionLocations.Value);
			};
			perceptionCooldown = config("2 - Jewelry", "Perception Cooldown", 30f, new ConfigDescription("The interval in seconds the effect will trigger.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			perceptionMinDistance = config("2 - Jewelry", "Perception Minimum Distance", 1000f, new ConfigDescription("The minimum distance to a location required to trigger the effect.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = (num -= 1)
				}
			}));
			Localizer.Load();
			harmony.PatchAll();
			JcPatches.DoPatches(harmony);
			rootContainer = new GameObject("jewelryPrefabs");
			rootContainer.transform.parent = Main.GetRootObject().transform;
			rootContainer.SetActive(false);
			assetBundle = PrefabManager.RegisterAssetBundle("jewelry");
			Logger.LogDebugOnly($"assetbundle loaded {assetBundle}");
			yamlConfig.LoadInitialConfig(useExternalYaml.Value == Toggle.On);
			OnExternalYamlSettingChanged();
			LoadAssets();
			Main.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable;
			new ConfigWatcher(this);
		}

		private void OnExternalYamlSettingChanged(object sender = null, EventArgs e = null)
		{
			bool isLocal = true;
			if (useExternalYaml.SynchronizedConfig && useExternalYaml.LocalBaseValue != null)
			{
				isLocal = (Toggle)useExternalYaml.LocalBaseValue == useExternalYaml.Value;
			}
			bool flag = useExternalYaml.Value == Toggle.On;
			yamlConfig.EnableRaisingFileEvents = flag;
			yamlConfig.UseBuiltinConfig = !flag;
			(((ConfigEntryBase)yamlAnchor).Description.Tags.Where((object o) => o is ConfigurationManagerAttributes).FirstOrDefault() as ConfigurationManagerAttributes).Browsable = flag;
			if (CmAPI.IsLoaded())
			{
				CmAPI.ReloadConfigDisplay();
			}
			if (sender != null)
			{
				yamlConfig.ReloadConfig(isLocal);
			}
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val);
			ConfigSync.AddConfigEntry<T>(val2).SynchronizedConfig = synchronizedSetting;
			return val2;
		}

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

		private void OnConfigReloaded(object sender, EventArgs e)
		{
			Logger.LogDebugOnly("Config reloaded received.");
		}

		private void OnVanillaPrefabsAvailable()
		{
			Logger.LogDebugOnly("OnVanillaPrefabsAvailable fired.");
			JewelryManager.Initialize();
			((ICollection<GameObject>)JewelryManager.AvailablePrefabs.Values).FixReferences(recursive: true);
			CollectionExtensions.Do<Item>((IEnumerable<Item>)loadedItems.Values, (Action<Item>)delegate(Item i)
			{
				i.Prefab.FixReferences(recursive: true);
				Icons.SnapshotItem(i.Prefab.GetComponent<ItemDrop>());
			});
			ApplyYamlConfig();
		}

		private void OnYamlConfigChanged()
		{
			Logger.LogDebugOnly($"YamlConfigChanged fired, contains {yamlConfig.Config}");
			yamlParsed = true;
			ApplyYamlConfig();
		}

		private void LoadAssets()
		{
			Dictionary<string, JewelryKind> prefabs = new Dictionary<string, JewelryKind>
			{
				{
					"Custom_Necklace_Default_PK",
					JewelryKind.DefaultNecklace
				},
				{
					"Custom_Necklace_Wrought_PK",
					JewelryKind.CustomNecklace
				},
				{
					"Custom_Necklace_Leather_PK",
					JewelryKind.LeatherNecklace
				},
				{
					"Custom_Necklace_Silver_PK",
					JewelryKind.SilverNecklace
				},
				{
					"Custom_Ring_Default_PK",
					JewelryKind.DefaultRing
				},
				{
					"Custom_Ring_Wrought_PK",
					JewelryKind.CustomRing
				},
				{
					"Custom_Ring_Stone_PK",
					JewelryKind.StoneRing
				},
				{
					"Custom_Ring_Bone_PK",
					JewelryKind.BoneRing
				},
				{
					"Custom_Ring_Silver_PK",
					JewelryKind.SilverRing
				}
			};
			foreach (KeyValuePair<string, JewelryKind> item in prefabs)
			{
				GameObject prefab = PrefabManager.RegisterPrefab(assetBundle, item.Key);
				JewelryManager.AddAvailablePrefab(item.Value, prefab);
			}
			if (VneiAPI.IsLoaded())
			{
				VneiAPI.AfterDisableItems += delegate
				{
					Logger.LogDebugOnly("VNEI detected, disabling template prefabs.");
					CollectionExtensions.Do<string>((IEnumerable<string>)prefabs.Keys, (Action<string>)delegate(string name)
					{
						VneiAPI.DisableItem(name, "MoreJewelry");
					});
				};
			}
			assetsLoaded = true;
			ApplyYamlConfig();
		}

		private static string SanitizeName(string name)
		{
			return name.Replace("  ", " ").Trim().Replace(" ", "_");
		}

		private static string getStation(string station)
		{
			if (stationMap.TryGetValue(station, out var value))
			{
				return value;
			}
			return station;
		}

		private static JewelryKind mapNameToJewelryKind(string prefab)
		{
			StringComparison comparisonType = StringComparison.InvariantCultureIgnoreCase;
			if (prefab != null)
			{
				if (prefab.IndexOf("jc_ring_", comparisonType) >= 0)
				{
					return JewelryKind.DefaultRing;
				}
				if (prefab.IndexOf("defaultring", comparisonType) >= 0)
				{
					return JewelryKind.DefaultRing;
				}
				if (prefab.IndexOf("jc_necklace_", comparisonType) >= 0)
				{
					return JewelryKind.DefaultNecklace;
				}
				if (prefab.IndexOf("defaultneck", comparisonType) >= 0)
				{
					return JewelryKind.DefaultNecklace;
				}
				if (prefab.IndexOf("defaultnecklace", comparisonType) >= 0)
				{
					return JewelryKind.DefaultNecklace;
				}
				if (prefab.IndexOf("jc_custom_ring", comparisonType) >= 0)
				{
					return JewelryKind.CustomRing;
				}
				if (prefab.IndexOf("customring", comparisonType) >= 0)
				{
					return JewelryKind.CustomRing;
				}
				if (prefab.IndexOf("jc_custom_necklace", comparisonType) >= 0)
				{
					return JewelryKind.CustomNecklace;
				}
				if (prefab.IndexOf("customneck", comparisonType) >= 0)
				{
					return JewelryKind.CustomNecklace;
				}
				if (prefab.IndexOf("customnecklace", comparisonType) >= 0)
				{
					return JewelryKind.CustomNecklace;
				}
				if (prefab.IndexOf("leathernecklace", comparisonType) >= 0)
				{
					return JewelryKind.LeatherNecklace;
				}
				if (prefab.IndexOf("leatherneck", comparisonType) >= 0)
				{
					return JewelryKind.LeatherNecklace;
				}
				if (prefab.IndexOf("leather", comparisonType) >= 0)
				{
					return JewelryKind.LeatherNecklace;
				}
				if (prefab.IndexOf("silvernecklace", comparisonType) >= 0)
				{
					return JewelryKind.LeatherNecklace;
				}
				if (prefab.IndexOf("silverneck", comparisonType) >= 0)
				{
					return JewelryKind.SilverNecklace;
				}
				if (prefab.IndexOf("stonering", comparisonType) >= 0)
				{
					return JewelryKind.StoneRing;
				}
				if (prefab.IndexOf("bonering", comparisonType) >= 0)
				{
					return JewelryKind.BoneRing;
				}
				if (prefab.IndexOf("silverring", comparisonType) >= 0)
				{
					return JewelryKind.SilverRing;
				}
			}
			return JewelryKind.None;
		}

		private GemStyle determineStyle(VisualData config)
		{
			GemStyle result = GemStyle.None;
			if (config.Visible && config.Color.HasValue)
			{
				result = GemStyle.Color;
			}
			else if (config.Visible)
			{
				result = GemStyle.Default;
			}
			return result;
		}

		private string getItemName(JewelryData data)
		{
			string text = SanitizeName(data.Name);
			JewelryKind jewelryKind = mapNameToJewelryKind(data.Prefab);
			if (JewelryManager.AvailablePrefabs.ContainsKey(jewelryKind))
			{
				text = ((jewelryKind != JewelryKind.DefaultNecklace && jewelryKind != JewelryKind.CustomNecklace && jewelryKind != JewelryKind.LeatherNecklace && jewelryKind != JewelryKind.SilverNecklace) ? ("Ring_" + text) : ("Necklace_" + text));
				return "JC_" + text;
			}
			return null;
		}

		private GameObject getItemPrefab(JewelryData data)
		{
			string text = SanitizeName(data.Name);
			JewelryKind jewelryKind = mapNameToJewelryKind(data.Prefab);
			GemStyle style = determineStyle(data.Gem);
			if (JewelryManager.AvailablePrefabs.TryGetValue(jewelryKind, out var value))
			{
				string localizationName;
				if (jewelryKind == JewelryKind.DefaultNecklace || jewelryKind == JewelryKind.CustomNecklace || jewelryKind == JewelryKind.LeatherNecklace || jewelryKind == JewelryKind.SilverNecklace)
				{
					localizationName = "jc_necklace_" + text.ToLower();
					text = "Necklace_" + text;
				}
				else
				{
					localizationName = "jc_ring_" + text.ToLower();
					text = "Ring_" + text;
				}
				return JcAPI.CreateItemFromTemplate(value, text, localizationName, style, data.Gem.Color);
			}
			return null;
		}

		private void ApplyYamlConfig()
		{
			if (!assetsLoaded || !yamlParsed)
			{
				return;
			}
			HashSet<string> hashSet = new HashSet<string>();
			foreach (JewelryData item3 in yamlConfig.Config.Jewelry)
			{
				string itemName = getItemName(item3);
				if (itemName == null)
				{
					Logger.LogWarning("Name " + item3.Prefab + " could not be matched to a valid prefab.  Skipping.");
					continue;
				}
				hashSet.Add(itemName);
				if (!loadedItems.TryGetValue(itemName, out var value))
				{
					if (PrefabManager.GetPrefab(item3.Name) != null)
					{
						Logger.LogWarning("Could not add " + item3.Name + " as an internal entity named such already exists.");
						continue;
					}
					GameObject itemPrefab = getItemPrefab(item3);
					if ((Object)(object)itemPrefab == (Object)null)
					{
						Logger.LogWarning($"Name {value.Prefab} could not be matched to a valid prefab.  Skipping.");
						continue;
					}
					Dictionary<string, Item> dictionary = loadedItems;
					Item obj = new Item(itemPrefab)
					{
						Configurable = Configurability.Disabled
					};
					((Object)obj.Prefab).name = itemName;
					Item item2 = obj;
					dictionary[itemName] = obj;
					value = item2;
				}
				value.Name.English(item3.Name);
				value.Description.English(item3.Description ?? "A random trinket.");
				mapNameToJewelryKind(item3.Prefab);
				JcAPI.SetItemStyle(value.Prefab, determineStyle(item3.Gem), item3.Gem.Color);
				SharedData shared = value.Prefab.GetComponent<ItemDrop>().m_itemData.m_shared;
				if (JewelryManager.IsInitialized())
				{
					JewelryManager.ClearAllEffectsFromItem(value);
					string text = item3.effect?.NameToResolve ?? null;
					if (text != null)
					{
						if (JewelryManager.AvailableEffects.ContainsKey(text))
						{
							JewelryManager.AddEffectToItem(value, text);
						}
						else if (text.Equals(Effects.Aquatic) || text.Equals(Effects.Headhunter))
						{
							JewelryManager.AddEffectToItem(value, text);
						}
						else
						{
							Logger.LogWarning(text + " isn't among the built-in effects, & StatusEffect lookup isn't supported yet. ");
						}
					}
					else
					{
						StatusEffectData statusEffectData = item3.effect?.SeData;
						if (statusEffectData != null)
						{
							string text2 = ((Object)value.Prefab).name.Replace("JC_", "JC_Se_");
							if ((Object)(object)shared.m_equipStatusEffect == (Object)null || !text2.Equals(((Object)shared.m_equipStatusEffect).name))
							{
								StatusEffect val = statusEffectData.ToStatusEffect();
								val.m_name = (string.IsNullOrWhiteSpace(statusEffectData.Name) ? item3.Name : statusEffectData.Name);
								((Object)val).name = text2;
								val.m_icon = shared.m_icons[0];
								shared.m_equipStatusEffect = val;
							}
						}
					}
				}
				value.Crafting.Stations.Clear();
				value.RequiredItems.Requirements.Clear();
				value.RequiredUpgradeItems.Requirements.Clear();
				value.Crafting.Add(getStation(item3.Crafting.CraftingStation), item3.Crafting.StationLevel);
				if (item3.Crafting.Costs.Count > 0)
				{
					value.RequiredItems.Requirements.AddRange(item3.Crafting.Costs.Select(delegate(CostData c)
					{
						Requirement result3 = default(Requirement);
						result3.itemName = c.Name;
						result3.amount = c.Amount;
						result3.quality = 0;
						return result3;
					}).ToArray());
				}
				int maxQuality = 1;
				UpgradeData upgrade = item3.Upgrade;
				if (upgrade != null && upgrade.Costs?.Count > 0)
				{
					foreach (KeyValuePair<int, List<CostData>> kvp in item3.Upgrade.Costs)
					{
						value.RequiredUpgradeItems.Requirements.AddRange(kvp.Value.Select(delegate(CostData c)
						{
							Requirement result2 = default(Requirement);
							result2.itemName = c.Name;
							result2.amount = c.Amount;
							result2.quality = kvp.Key + 1;
							return result2;
						}));
					}
					maxQuality = ((item3.Crafting.Costs.Count > 0) ? 1 : 0) + item3.Upgrade.Costs.Count;
				}
				else if (item3.Crafting.MaxQuality > 1 && item3.Crafting.MaxQuality <= 10 && item3.Crafting.Costs.Any((CostData c) => c.AmountPerLevel > 0))
				{
					maxQuality = item3.Crafting.MaxQuality;
					int i;
					for (i = 2; i <= maxQuality; i++)
					{
						value.RequiredUpgradeItems.Requirements.AddRange(item3.Crafting.Costs.Select(delegate(CostData c)
						{
							Requirement result = default(Requirement);
							result.itemName = c.Name;
							result.amount = c.AmountPerLevel * (i - 1);
							result.quality = i;
							return result;
						}).ToArray());
					}
				}
				shared.m_maxQuality = maxQuality;
				ZNetScene instance = ZNetScene.instance;
				if ((Object)(object)((instance != null) ? instance.GetPrefab("_ZoneCtrl") : null) != (Object)null)
				{
					value.ReloadCraftingConfiguration();
					value.ApplyToAllInstances(delegate(ItemData item)
					{
						item.m_shared = shared;
						item.m_shared.m_maxQuality = maxQuality;
					});
				}
			}
			foreach (KeyValuePair<string, Item> loadedItem in loadedItems)
			{
				if (!hashSet.Contains(loadedItem.Key) && loadedItem.Value != null)
				{
					Item.RecipesEnabled activeRecipesEnabled = loadedItem.Value.GetActiveRecipesEnabled();
					if (activeRecipesEnabled == Item.RecipesEnabled.True || activeRecipesEnabled == Item.RecipesEnabled.Mixed)
					{
						loadedItem.Value.ToggleAllActiveRecipes(isEnabled: false);
					}
					JewelryManager.ClearAllEffectsFromItem(loadedItem.Value);
				}
			}
		}

		private void testCreateJewelry()
		{
			Item item = new Item(JcAPI.CreateItemFromTemplate(JewelryManager.AvailablePrefabs[JewelryKind.LeatherNecklace], "Necklace Leather", "jc_necklace_leather_one"));
			item.Name.English("Leather necklace");
			item.Description.English("Que?");
			item.Crafting.Add(((Object)JcAPI.GetGemcuttersTable()).name, 1);
			item.RequiredItems.Add("Stone", 1);
			item.MaximumRequiredStationLevel = 3;
			JewelryManager.AddEffectToItem(item, Effects.Aquatic);
			Item item2 = new Item(JcAPI.CreateItemFromTemplate(JewelryManager.AvailablePrefabs[JewelryKind.SilverRing], "Ring Silver", "jc_ring_silver_one"));
			item2.Name.English("Silver ring");
			item2.Description.English("Que?");
			item2.Crafting.Add(((Object)JcAPI.GetGemcuttersTable()).name, 1);
			item2.RequiredItems.Add("Stone", 1);
			item2.MaximumRequiredStationLevel = 3;
			JewelryManager.AddEffectToItem(item2, Effects.Headhunter);
		}

		ConfigFile IPlugin.get_Config()
		{
			return ((BaseUnityPlugin)this).Config;
		}
	}
	public class YamlConfigEditor : MonoBehaviour
	{
		private const int WindowId = -669;

		private static Rect yamlWindowRect;

		private string currentYamlInput;

		private bool collapsed;

		private Vector2 yamlTextareaScrollPosition;

		private Vector2 yamlErrorsScrollPosition;

		private bool hasErrors;

		private YamlConfig yamlConfig;

		[<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(new byte[] { 2, 0 })]
		private CustomSyncedValue<string> activeConfig;

		private Func<string, List<string>> errorChecker;

		private ConfigSync configSync;

		private string modName;

		public static string EditButtonName => Localization.instance.Localize("$mj_yaml_editor_edit");

		public void Initialize(string modName, ConfigSync configSync, YamlConfig yaml, Func<string, List<string>> errorCheck)
		{
			if (CmAPI.IsLoaded())
			{
				this.modName = modName;
				this.configSync = configSync;
				yamlConfig = yaml;
				activeConfig = yaml.SyncedValue;
				errorChecker = errorCheck;
				Logger.LogDebugOnly("Setting up " + modName + " YAML Editor");
			}
			else
			{
				Logger.LogDebugOnly("No CM pressent, skipping YAML Editor setup.");
			}
		}

		public void DrawYamlEditorButton(ConfigEntryBase _)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if (CmAPI.IsLoaded())
			{
				GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Space((float)CmAPI.LeftColumnWidth + 2f);
				if (!string.IsNullOrWhiteSpace(activeConfig.Value) && GUILayout.Button(EditButtonName, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
				{
					currentYamlInput = activeConfig.Value;
					yamlTextareaScrollPosition = default(Vector2);
				}
				GUILayout.Space(59f);
				GUILayout.EndHorizontal();
				GUILayout.EndVertical();
			}
		}

		private void Update()
		{
			if (currentYamlInput != null)
			{
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
			}
		}

		private void LateUpdate()
		{
			Update();
		}

		private void OnGUI()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_005f: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			if (currentYamlInput != null)
			{
				Update();
				yamlWindowRect = new Rect(10f, 10f, (float)(Screen.width - 20), (float)(Screen.height - 20));
				GUI.Box(yamlWindowRect, GUIContent.none, new GUIStyle
				{
					normal = new GUIStyleState
					{
						background = CmAPI.WindowBackground
					}
				});
				GUI.backgroundColor = CmAPI._windowBackgroundColor;
				GUILayout.Window(-669, yamlWindowRect, new WindowFunction(yamlWindowDrawer), modName + " YAML Editor", Array.Empty<GUILayoutOption>());
			}
		}

		private void yamlWindowDrawer(int id)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_0469: Unknown result type (might be due to invalid IL or missing references)
			//IL_0485: Unknown result type (might be due to invalid IL or missing references)
			//IL_048a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Expected O, but got Unknown
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Invalid comparison between Unknown and I4
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Invalid comparison between Unknown and I4
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Invalid comparison between Unknown and I4
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Invalid comparison between Unknown and I4
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Expected O, but got Unknown
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Invalid comparison between Unknown and I4
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Invalid comparison between Unknown and I4
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Invalid comparison between Unknown and I4
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(GUI.skin.box);
			val.normal.textColor = CmAPI._fontColor;
			val.normal.background = CmAPI.EntryBackground;
			val.fontSize = CmAPI.fontSize;
			GUI.backgroundColor = CmAPI._entryBackgroundColor;
			GUILayout.BeginHorizontal(val, Array.Empty<GUILayoutOption>());
			GUI.enabled = !hasErrors && (!configSync.IsLocked || configSync.IsSourceOfTruth);
			Color backgroundColor = GUI.backgroundColor;
			GUI.backgroundColor = CmAPI._widgetBackgroundColor;
			if (GUILayout.Button(Localization.instance.Localize("$mj_yaml_editor_save"), (GUILayoutOption[])(object)new GUILayoutOption[0]) && !hasErrors)
			{
				save();
				currentYamlInput = null;
			}
			if (configSync.IsSourceOfTruth && GUILayout.Button(Localization.instance.Localize("$mj_yaml_editor_apply"), Array.Empty<GUILayoutOption>()) && !hasErrors)
			{
				yamlConfig.SkipSavingOfValueChange = true;
				save();
				yamlConfig.SkipSavingOfValueChange = false;
				currentYamlInput = null;
			}
			GUI.backgroundColor = backgroundColor;
			GUI.enabled = true;
			if (GUILayout.Button(Localization.instance.Localize("$mj_yaml_editor_discard"), Array.Empty<GUILayoutOption>()))
			{
				currentYamlInput = null;
			}
			GUILayout.EndHorizontal();
			hasErrors = false;
			string text = "";
			if (GUI.GetNameOfFocusedControl() == modName + " yaml textarea")
			{
				EventType type = Event.current.type;
				if (((int)type == 4 || (int)type == 5) && Event.current.isKey)
				{
					if ((int)Event.current.keyCode == 9 || Event.current.character == '\t')
					{
						if ((int)Event.current.type == 5)
						{
							TextEditor val2 = (TextEditor)GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl);
							val2.Insert(' ');
							val2.Insert(' ');
							currentYamlInput = val2.text;
						}
						Event.current.Use();
					}
					if ((int)Event.current.keyCode == 271 || (int)Event.current.keyCode == 13 || Event.current.character == '\n')
					{
						if ((int)Event.current.type == 5)
						{
							TextEditor val3 = (TextEditor)GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl);
							string text2 = val3.text;
							int num = val3.cursorIndex;
							if (num > 0)
							{
								while (text2[num - 1] != '\n' && --num > 0)
								{
								}
							}
							int num2 = num;
							if (num2 < text2.Length && text2[num2] == ' ')
							{
								while (true)
								{
									if (num2 >= text2.Length || text2[num2] == '\n')
									{
										num2 = num;
										break;
									}
									if (text2[num2] != ' ')
									{
										break;
									}
									num2++;
								}
							}
							if (num2 > val3.cursorIndex)
							{
								num2 = num;
							}
							val3.Insert('\n');
							for (int num3 = num2 - num; num3 > 0; num3--)
							{
								val3.Insert(' ');
							}
							currentYamlInput = val3.text;
						}
						Event.current.Use();
					}
				}
			}
			if (currentYamlInput != null)
			{
				GUILayout.BeginVertical(val, Array.Empty<GUILayoutOption>());
				yamlTextareaScrollPosition = GUILayout.BeginScrollView(yamlTextareaScrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
				GUI.SetNextControlName(modName + " yaml textarea");
				currentYamlInput = GUILayout.TextArea(currentYamlInput, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.ExpandWidth(true),
					GUILayout.ExpandHeight(true)
				});
				GUILayout.EndScrollView();
				GUILayout.EndVertical();
			}
			try
			{
				List<string> list = errorChecker(currentYamlInput);
				if (list.Count > 0)
				{
					hasErrors = true;
					text = text + "There are errors in your yaml config:\n" + string.Join("\n", list) + "\n";
				}
			}
			catch (YamlException ex)
			{
				text = "Parsing your yaml config failed with an error:\n" + ex.Message + ((ex.InnerException != null) ? (": " + ex.InnerException.Message) : "");
				hasErrors = true;
			}
			val.normal.background = CmAPI.WindowBackground;
			GUI.backgroundColor = CmAPI._entryBackgroundColor;
			GUILayout.BeginVertical(val, Array.Empty<GUILayoutOption>());
			yamlErrorsScrollPosition = GUILayout.BeginScrollView(yamlErrorsScrollPosition, val, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(100f) });
			if (text != "")
			{
				GUIStyle val4 = new GUIStyle(GUI.skin.label);
				val4.normal.textColor = new Color(0.8f, 0.14f, 0.14f, 1f);
				GUIStyle val5 = val4;
				Color contentColor = GUI.contentColor;
				GUI.contentColor = new Color(0.8f, 0.14f, 0.14f, 1f);
				GUILayout.Label(text, val5, Array.Empty<GUILayoutOption>());
				GUI.contentColor = contentColor;
			}
			else
			{
				GUILayout.Label("Configuration syntax is valid.", Array.Empty<GUILayoutOption>());
			}
			GUILayout.EndScrollView();
			GUILayout.EndVertical();
			void save()
			{
				activeConfig.Value = currentYamlInput;
			}
		}
	}
}
namespace MoreJewelry.Data
{
	[<7fadffcb-e7f7-4e27-b64c-2043e30ccf25>NullableContext(2)]
	[<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(0)]
	public class JewelryDataUnparsed
	{
		public string Name;

		public string Description;

		public string Prefab;

		public object Gem;

		public object Crafting;

		public object Upgrade;

		public object effect;
	}
	[Serializable]
	[CanBeNull]
	public class JewelryData
	{
		public string Name = "";

		public string Description = "";

		public string Prefab = "";

		public VisualData Gem;

		public CraftingData Crafting;

		public UpgradeData Upgrade;

		public EffectData effect;
	}
	[Serializable]
	[CanBeNull]
	public class CraftingData
	{
		public string CraftingStation;

		public int StationLevel;

		public int MaxQuality = -1;

		public List<CostData> Costs;
	}
	[Serializable]
	[CanBeNull]
	public class UpgradeData
	{
		public Dictionary<int, List<CostData>> Costs;
	}
	[Serializable]
	[CanBeNull]
	public class CostData
	{
		public string Name;

		public int Amount;

		public int AmountPerLevel;
	}
	[Serializable]
	[<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(0)]
	[CanBeNull]
	[<7fadffcb-e7f7-4e27-b64c-2043e30ccf25>NullableContext(2)]
	public class EffectData
	{
		public string NameToResolve;

		public StatusEffectData SeData;
	}
	[Serializable]
	[CanBeNull]
	public class VisualData
	{
		public bool Visible;

		public Color? Color;
	}
	public static class SkillUtils
	{
		public static string FromSkill(SkillType skill)
		{
			return Localization.instance.Localize("$skill_" + ((object)(SkillType)(ref skill)).ToString().ToLower());
		}

		public static SkillType FromName(string englishName)
		{
			return (SkillType)Math.Abs(StringExtensionMethods.GetStableHashCode(englishName));
		}
	}
	[Serializable]
	[CanBeNull]
	public class DamageModifierData
	{
		public string Type { get; set; }

		public string Modifier { get; set; }

		public DamageModifierData()
		{
		}

		public DamageModifierData(string type, string mod)
		{
			Type = type;
			Modifier = mod;
		}
	}
	[Serializable]
	[CanBeNull]
	public class SkillModifierData
	{
		public string Type { get; set; }

		public float Modifier { get; set; }

		public SkillModifierData()
		{
		}

		public SkillModifierData(string type, float mod)
		{
			Type = type;
			Modifier = mod;
		}
	}
	[Serializable]
	[CanBeNull]
	public class StatusEffectData
	{
		[<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)]
		public string Name;

		[<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)]
		public string Tooltip;

		[YamlMember(Alias = "StartMsgLoc")]
		public MessageType? StartMessageLoc;

		[YamlMember(Alias = "StartMsg")]
		[<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)]
		public string StartMessage;

		[YamlMember(Alias = "StopMsgLoc")]
		public MessageType? StopMessageLoc;

		[YamlMember(Alias = "StopMsg")]
		[<269482ad-a4af-4c0a-bc50-c46c6ba7af92>Nullable(2)]
		public string StopMessage;

		[YamlMember(Alias = "RunStaminaModifier")]
		public float? m_runStaminaDrainModifier;

		[YamlMember(Alias = "JumpStaminaModifier")]
		public float? m_jumpStaminaUseModifier;

		[YamlMember(Alias = "HealthRegen")]
		public float? m_healthRegenMultiplier = 1f;

		[YamlMember(Alias = "StaminaRegen")]
		public float? m_staminaRegenMultiplier = 1f;

		[YamlMember(Alias = "EitrRegen")]
		public float? m_eitrRegenMultiplier = 1f;

		[YamlMember(Alias = "RaiseSkill")]
		public SkillModifierData RaiseSkillMod;

		[YamlMember(Alias = "SkillLevel")]
		public SkillModifierData SkillLevelMod;

		[YamlMember(Alias = "SkillLevelTwo")]
		public SkillModifierData SkillLevel2Mod;

		[YamlMember(Alias = "DamageModifiers")]
		public List<DamageModifierData> DamageMods = new List<DamageModifierData>();

		[YamlMember(Alias = "AttackSkill")]
		public SkillModifierData AttackSkillMod;

		[YamlMember(Alias = "MaxCarry")]
		public float? m_addMaxCarryWeight;

		[YamlMember(Alias = "MoveSpeed")]
		public float? m_speedModifier;

		[YamlMember(Alias = "FallSpeed")]
		public float? m_maxMaxFallSpeed;

		[YamlMember(Alias = "FallDamage")]
		public float? m_fallDamageModifier;

		public StatusEffect ToStatusEffect()
		{
			//IL_0065: 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)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			SE_Stats val = ScriptableObject.CreateInstance<SE_Stats>();
			if (hasValue(Name))
			{
				((StatusEffect)val).m_name = Name;
			}
			if (hasValue(Tooltip))
			{
				((StatusEffect)val).m_tooltip = Tooltip;
			}
			if (hasValue(StartMessage))
			{
				((StatusEffect)val).m_startMessage = StartMessage;
			}
			if (StartMessageLoc.HasValue)
			{
				((StatusEffect)val).m_startMessageType = StartMessageLoc.Value;
			}
			if (hasValue(StopMessage))
			{
				((StatusEffect)val).m_stopMessage = StopMessage;
			}
			if (StopMessageLoc.HasValue)
			{
				((StatusEffect)val).m_stopMessageType = StopMessageLoc.Value;
			}
			if (m_runStaminaDrainModifier.HasValue)
			{
				val.m_runStaminaDrainModifier = m_runStaminaDrainModifier.Value;
			}
			if (m_jumpStaminaUseModifier.HasValue)
			{
				val.m_jumpStaminaUseModifier = m_jumpStaminaUseModifier.Value;
			}
			if (m_healthRegenMultiplier.HasValue)
			{
				val.m_healthRegenMultiplier = m_healthRegenMultiplier.Value;
			}
			if (m_staminaRegenMultiplier.HasValue)
			{
				val.m_staminaRegenMultiplier = m_staminaRegenMultiplier.Value;
			}
			if (m_eitrRegenMultiplier.HasValue)
			{
				val.m_eitrRegenMultiplier = m_eitrRegenMultiplier.Value;
			}
			if (RaiseSkillMod != null)
			{
				val.m_raiseSkill = GetSkillType(RaiseSkillMod.Type);
				val.m_raiseSkillModifier = RaiseSkillMod.Modifier;
			}
			if (SkillLevelMod != null)
			{
				val.m_skillLevel = GetSkillType(SkillLevelMod.Type);
				val.m_skillLevelModifier = SkillLevelMod.Modifier;
			}
			if (SkillLevel2Mod != null)
			{
				val.m_skillLevel2 = GetSkillType(SkillLevel2Mod.Type);
				val.m_skillLevelModifier2 = SkillLevel2Mod.Modifier;
			}
			List<DamageModifierData> damageMods = DamageMods;
			if (damageMods != null && damageMods.Count > 0)
			{
				val.m_mods = DamageMods.Select(delegate(DamageModifierData m)
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					//IL_0015: Unknown result type (might be due to invalid IL or missing references)
					//IL_0022: Unknown result type (might be due to invalid IL or missing references)
					//IL_0027: Unknown result type (might be due to invalid IL or missing references)
					//IL_002c: Unknown result type (might be due to invalid IL or missing references)
					DamageModPair result = default(DamageModPair);
					result.m_type = GetDamageType(m.Type);
					result.m_modifier = GetDamageModifier(m.Modifier);
					return result;
				}).ToList();
			}
			if (AttackSkillMod != null)
			{
				val.m_modifyAttackSkill = GetSkillType(AttackSkillMod.Type);
				val.m_damageModifier = AttackSkillMod.Modifier;
			}
			if (m_addMaxCarryWeight.HasValue)
			{
				val.m_addMaxCarryWeight = m_addMaxCarryWeight.Value;
			}
			if (m_speedModifier.HasValue)
			{
				val.m_speedModifier = m_speedModifier.Value;
			}
			if (m_maxMaxFallSpeed.HasValue)
			{
				val.m_maxMaxFallSpeed = m_maxMaxFallSpeed.Value;
			}
			if (m_fallDamageModifier.HasValue)
			{
				val.m_fallDamageModifier = m_fallDamageModifier.Value;
			}
			return (StatusEffect)(object)val;
			static bool hasValue(string input)
			{
				return !string.IsNullOrEmpty(input);
			}
		}

		public static string GetItemTypeString(string type)
		{
			if (string.Equals(type, "back", StringComparison.InvariantCultureIgnoreCase))
			{
				return "shoulder";
			}
			return type.ToLower();
		}

		public static string GetDamageModString(string type)
		{
			if (string.Equals(type, "very resistant", StringComparison.InvariantCultureIgnoreCase))
			{
				return "veryresistant";
			}
			if (string.Equals(type, "very weak", StringComparison.InvariantCultureIgnoreCase))
			{
				return "veryweak";
			}
			return type.ToLower();
		}

		public static string GetSkillTypeString(string type)
		{
			if (string.Equals(type, "fists", StringComparison.InvariantCultureIgnoreCase))
			{
				return "Unarmed";
			}
			if (string.Equals(type, "wood-cutting", StringComparison.InvariantCultureIgnoreCase))
			{
				return "WoodCutting";
			}
			if (string.Equals(type, "wood cutting", StringComparison.InvariantCultureIgnoreCase))
			{
				return "WoodCutting";
			}
			if (string.Equals(type, "elemental magic", StringComparison.InvariantCultureIgnoreCase))
			{
				return "ElementalMagic";
			}
			if (string.Equals(type, "blood magic", StringComparison.InvariantCultureIgnoreCase))
			{
				return "BloodMagic";
			}
			return type;
		}

		public static DamageType GetDamageType(string type)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (Enum.TryParse<DamageType>(type, ignoreCase: true, out DamageType result))
			{
				return result;
			}
			return (DamageType)0;
		}

		public static DamageModifier GetDamageModifier(string type)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (Enum.TryParse<DamageModifier>(GetDamageModString(type), ignoreCase: true, out DamageModifier result))
			{
				return result;
			}
			return (DamageModifier)0;
		}

		public static SkillType GetSkillType(string type)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			type = GetSkillTypeString(type);
			if (Enum.TryParse<SkillType>(type, ignoreCase: true, out SkillType result))
			{
				return result;
			}
			return SkillUtils.FromName(type);
		}
	}
}
[CompilerGenerated]
internal sealed class <a0da5b08-8a4e-40cb-8ae2-4268afc5b028><PrivateImplementationDetails>
{
	internal static uint ComputeStringHash(string s)
	{
		uint num = default(uint);
		if (s != null)
		{
			num = 2166136261u;
			for (int i = 0; i < s.Length; i++)
			{
				num = (s[i] ^ num) * 16777619;
			}
		}
		return num;
	}
}
namespace Microsoft.CodeAnalysis
{
	[<7222e4a6-29fd-4239-9d69-21a1809ee24e>Embedded]
	[CompilerGenerated]
	internal sealed class <7222e4a6-29fd-4239-9d69-21a1809ee24e>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[<7222e4a6-29fd-4239-9d69-21a1809ee24e>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class <31d74ac3-826c-4b55-bc9d-d4bf0b77a2dc>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <31d74ac3-826c-4b55-bc9d-d4bf0b77a2dc>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <31d74ac3-826c-4b55-bc9d-d4bf0b77a2dc>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[<7222e4a6-29fd-4239-9d69-21a1809ee24e>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class <bc90a89b-f3f8-47de-a1c5-ad9d9997b0ad>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <bc90a89b-f3f8-47de-a1c5-ad9d9997b0ad>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[Compil